00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "pipe/p_config.h"
00025
00026 #if defined(PIPE_ARCH_X86)
00027
00028 #include "pipe/p_compiler.h"
00029 #include "pipe/p_debug.h"
00030 #include "util/u_pointer.h"
00031
00032 #include "rtasm_execmem.h"
00033 #include "rtasm_x86sse.h"
00034
00035 #define DISASSEM 0
00036 #define X86_TWOB 0x0f
00037
00038
00039 #define DUMP_SSE 0
00040
00041
00042 void x86_print_reg( struct x86_reg reg )
00043 {
00044 if (reg.mod != mod_REG)
00045 debug_printf( "[" );
00046
00047 switch( reg.file ) {
00048 case file_REG32:
00049 switch( reg.idx ) {
00050 case reg_AX: debug_printf( "EAX" ); break;
00051 case reg_CX: debug_printf( "ECX" ); break;
00052 case reg_DX: debug_printf( "EDX" ); break;
00053 case reg_BX: debug_printf( "EBX" ); break;
00054 case reg_SP: debug_printf( "ESP" ); break;
00055 case reg_BP: debug_printf( "EBP" ); break;
00056 case reg_SI: debug_printf( "ESI" ); break;
00057 case reg_DI: debug_printf( "EDI" ); break;
00058 }
00059 break;
00060 case file_MMX:
00061 debug_printf( "MMX%u", reg.idx );
00062 break;
00063 case file_XMM:
00064 debug_printf( "XMM%u", reg.idx );
00065 break;
00066 case file_x87:
00067 debug_printf( "fp%u", reg.idx );
00068 break;
00069 }
00070
00071 if (reg.mod == mod_DISP8 ||
00072 reg.mod == mod_DISP32)
00073 debug_printf("+%d", reg.disp);
00074
00075 if (reg.mod != mod_REG)
00076 debug_printf( "]" );
00077 }
00078
00079 #if DUMP_SSE
00080
00081 #define DUMP_START() debug_printf( "\n" )
00082 #define DUMP_END() debug_printf( "\n" )
00083
00084 #define DUMP() do { \
00085 const char *foo = __FUNCTION__; \
00086 while (*foo && *foo != '_') \
00087 foo++; \
00088 if (*foo) \
00089 foo++; \
00090 debug_printf( "\n% 4x% 15s ", p->csr - p->store, foo ); \
00091 } while (0)
00092
00093 #define DUMP_I( I ) do { \
00094 DUMP(); \
00095 debug_printf( "%u", I ); \
00096 } while( 0 )
00097
00098 #define DUMP_R( R0 ) do { \
00099 DUMP(); \
00100 x86_print_reg( R0 ); \
00101 } while( 0 )
00102
00103 #define DUMP_RR( R0, R1 ) do { \
00104 DUMP(); \
00105 x86_print_reg( R0 ); \
00106 debug_printf( ", " ); \
00107 x86_print_reg( R1 ); \
00108 } while( 0 )
00109
00110 #define DUMP_RI( R0, I ) do { \
00111 DUMP(); \
00112 x86_print_reg( R0 ); \
00113 debug_printf( ", %u", I ); \
00114 } while( 0 )
00115
00116 #define DUMP_RRI( R0, R1, I ) do { \
00117 DUMP(); \
00118 x86_print_reg( R0 ); \
00119 debug_printf( ", " ); \
00120 x86_print_reg( R1 ); \
00121 debug_printf( ", %u", I ); \
00122 } while( 0 )
00123
00124 #else
00125
00126 #define DUMP_START()
00127 #define DUMP_END()
00128 #define DUMP( )
00129 #define DUMP_I( I )
00130 #define DUMP_R( R0 )
00131 #define DUMP_RR( R0, R1 )
00132 #define DUMP_RI( R0, I )
00133 #define DUMP_RRI( R0, R1, I )
00134
00135 #endif
00136
00137
00138 static void do_realloc( struct x86_function *p )
00139 {
00140 if (p->store == p->error_overflow) {
00141 p->csr = p->store;
00142 }
00143 else if (p->size == 0) {
00144 p->size = 1024;
00145 p->store = rtasm_exec_malloc(p->size);
00146 p->csr = p->store;
00147 }
00148 else {
00149 uintptr_t used = pointer_to_uintptr( p->csr ) - pointer_to_uintptr( p->store );
00150 unsigned char *tmp = p->store;
00151 p->size *= 2;
00152 p->store = rtasm_exec_malloc(p->size);
00153
00154 if (p->store) {
00155 memcpy(p->store, tmp, used);
00156 p->csr = p->store + used;
00157 }
00158 else {
00159 p->csr = p->store;
00160 }
00161
00162 rtasm_exec_free(tmp);
00163 }
00164
00165 if (p->store == NULL) {
00166 p->store = p->csr = p->error_overflow;
00167 p->size = sizeof(p->error_overflow);
00168 }
00169 }
00170
00171
00172
00173 static unsigned char *reserve( struct x86_function *p, int bytes )
00174 {
00175 if (p->csr + bytes - p->store > (int) p->size)
00176 do_realloc(p);
00177
00178 {
00179 unsigned char *csr = p->csr;
00180 p->csr += bytes;
00181 return csr;
00182 }
00183 }
00184
00185
00186
00187 static void emit_1b( struct x86_function *p, char b0 )
00188 {
00189 char *csr = (char *)reserve(p, 1);
00190 *csr = b0;
00191 }
00192
00193 static void emit_1i( struct x86_function *p, int i0 )
00194 {
00195 int *icsr = (int *)reserve(p, sizeof(i0));
00196 *icsr = i0;
00197 }
00198
00199 static void emit_1ub( struct x86_function *p, unsigned char b0 )
00200 {
00201 unsigned char *csr = reserve(p, 1);
00202 *csr++ = b0;
00203 }
00204
00205 static void emit_2ub( struct x86_function *p, unsigned char b0, unsigned char b1 )
00206 {
00207 unsigned char *csr = reserve(p, 2);
00208 *csr++ = b0;
00209 *csr++ = b1;
00210 }
00211
00212 static void emit_3ub( struct x86_function *p, unsigned char b0, unsigned char b1, unsigned char b2 )
00213 {
00214 unsigned char *csr = reserve(p, 3);
00215 *csr++ = b0;
00216 *csr++ = b1;
00217 *csr++ = b2;
00218 }
00219
00220
00221
00222
00223
00224
00225
00226 static void emit_modrm( struct x86_function *p,
00227 struct x86_reg reg,
00228 struct x86_reg regmem )
00229 {
00230 unsigned char val = 0;
00231
00232 assert(reg.mod == mod_REG);
00233
00234 val |= regmem.mod << 6;
00235 val |= reg.idx << 3;
00236 val |= regmem.idx;
00237
00238 emit_1ub(p, val);
00239
00240
00241
00242 if (regmem.file == file_REG32 &&
00243 regmem.idx == reg_SP) {
00244 emit_1ub(p, 0x24);
00245 }
00246
00247 switch (regmem.mod) {
00248 case mod_REG:
00249 case mod_INDIRECT:
00250 break;
00251 case mod_DISP8:
00252 emit_1b(p, (char) regmem.disp);
00253 break;
00254 case mod_DISP32:
00255 emit_1i(p, regmem.disp);
00256 break;
00257 default:
00258 assert(0);
00259 break;
00260 }
00261 }
00262
00263
00264
00265 static void emit_modrm_noreg( struct x86_function *p,
00266 unsigned op,
00267 struct x86_reg regmem )
00268 {
00269 struct x86_reg dummy = x86_make_reg(file_REG32, op);
00270 emit_modrm(p, dummy, regmem);
00271 }
00272
00273
00274
00275
00276
00277
00278 static void emit_op_modrm( struct x86_function *p,
00279 unsigned char op_dst_is_reg,
00280 unsigned char op_dst_is_mem,
00281 struct x86_reg dst,
00282 struct x86_reg src )
00283 {
00284 switch (dst.mod) {
00285 case mod_REG:
00286 emit_1ub(p, op_dst_is_reg);
00287 emit_modrm(p, dst, src);
00288 break;
00289 case mod_INDIRECT:
00290 case mod_DISP32:
00291 case mod_DISP8:
00292 assert(src.mod == mod_REG);
00293 emit_1ub(p, op_dst_is_mem);
00294 emit_modrm(p, src, dst);
00295 break;
00296 default:
00297 assert(0);
00298 break;
00299 }
00300 }
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310 struct x86_reg x86_make_reg( enum x86_reg_file file,
00311 enum x86_reg_name idx )
00312 {
00313 struct x86_reg reg;
00314
00315 reg.file = file;
00316 reg.idx = idx;
00317 reg.mod = mod_REG;
00318 reg.disp = 0;
00319
00320 return reg;
00321 }
00322
00323 struct x86_reg x86_make_disp( struct x86_reg reg,
00324 int disp )
00325 {
00326 assert(reg.file == file_REG32);
00327
00328 if (reg.mod == mod_REG)
00329 reg.disp = disp;
00330 else
00331 reg.disp += disp;
00332
00333 if (reg.disp == 0 && reg.idx != reg_BP)
00334 reg.mod = mod_INDIRECT;
00335 else if (reg.disp <= 127 && reg.disp >= -128)
00336 reg.mod = mod_DISP8;
00337 else
00338 reg.mod = mod_DISP32;
00339
00340 return reg;
00341 }
00342
00343 struct x86_reg x86_deref( struct x86_reg reg )
00344 {
00345 return x86_make_disp(reg, 0);
00346 }
00347
00348 struct x86_reg x86_get_base_reg( struct x86_reg reg )
00349 {
00350 return x86_make_reg( reg.file, reg.idx );
00351 }
00352
00353 int x86_get_label( struct x86_function *p )
00354 {
00355 return p->csr - p->store;
00356 }
00357
00358
00359
00360
00361
00362
00363
00364
00365 void x86_jcc( struct x86_function *p,
00366 enum x86_cc cc,
00367 int label )
00368 {
00369 int offset = label - (x86_get_label(p) + 2);
00370 DUMP_I(cc);
00371
00372 if (offset < 0) {
00373
00374 if (p->csr - p->store <= -offset) {
00375
00376 return;
00377 }
00378 }
00379
00380 if (offset <= 127 && offset >= -128) {
00381 emit_1ub(p, 0x70 + cc);
00382 emit_1b(p, (char) offset);
00383 }
00384 else {
00385 offset = label - (x86_get_label(p) + 6);
00386 emit_2ub(p, 0x0f, 0x80 + cc);
00387 emit_1i(p, offset);
00388 }
00389 }
00390
00391
00392
00393 int x86_jcc_forward( struct x86_function *p,
00394 enum x86_cc cc )
00395 {
00396 DUMP_I(cc);
00397 emit_2ub(p, 0x0f, 0x80 + cc);
00398 emit_1i(p, 0);
00399 return x86_get_label(p);
00400 }
00401
00402 int x86_jmp_forward( struct x86_function *p)
00403 {
00404 DUMP();
00405 emit_1ub(p, 0xe9);
00406 emit_1i(p, 0);
00407 return x86_get_label(p);
00408 }
00409
00410 int x86_call_forward( struct x86_function *p)
00411 {
00412 DUMP();
00413
00414 emit_1ub(p, 0xe8);
00415 emit_1i(p, 0);
00416 return x86_get_label(p);
00417 }
00418
00419
00420
00421 void x86_fixup_fwd_jump( struct x86_function *p,
00422 int fixup )
00423 {
00424 *(int *)(p->store + fixup - 4) = x86_get_label(p) - fixup;
00425 }
00426
00427 void x86_jmp( struct x86_function *p, int label)
00428 {
00429 DUMP_I( label );
00430 emit_1ub(p, 0xe9);
00431 emit_1i(p, label - x86_get_label(p) - 4);
00432 }
00433
00434 void x86_call( struct x86_function *p, struct x86_reg reg)
00435 {
00436 DUMP_R( reg );
00437 emit_1ub(p, 0xff);
00438 emit_modrm_noreg(p, 2, reg);
00439 }
00440
00441
00442
00443
00444
00445
00446 void x86_mov_reg_imm( struct x86_function *p, struct x86_reg dst, int imm )
00447 {
00448 DUMP_RI( dst, imm );
00449 assert(dst.mod == mod_REG);
00450 emit_1ub(p, 0xb8 + dst.idx);
00451 emit_1i(p, imm);
00452 }
00453
00454 void x86_add_reg_imm8( struct x86_function *p, struct x86_reg dst, ubyte imm )
00455 {
00456 DUMP_RI( dst, imm );
00457 assert(dst.mod == mod_REG);
00458 emit_1ub(p, 0x80);
00459 emit_modrm_noreg(p, 0, dst);
00460 emit_1ub(p, imm);
00461 }
00462
00463
00464 void x86_push( struct x86_function *p,
00465 struct x86_reg reg )
00466 {
00467 DUMP_R( reg );
00468 if (reg.mod == mod_REG)
00469 emit_1ub(p, 0x50 + reg.idx);
00470 else
00471 {
00472 emit_1ub(p, 0xff);
00473 emit_modrm_noreg(p, 6, reg);
00474 }
00475
00476
00477 p->stack_offset += 4;
00478 }
00479
00480 void x86_push_imm32( struct x86_function *p,
00481 int imm32 )
00482 {
00483 DUMP_I( imm32 );
00484 emit_1ub(p, 0x68);
00485 emit_1i(p, imm32);
00486
00487 p->stack_offset += 4;
00488 }
00489
00490
00491 void x86_pop( struct x86_function *p,
00492 struct x86_reg reg )
00493 {
00494 DUMP_R( reg );
00495 assert(reg.mod == mod_REG);
00496 emit_1ub(p, 0x58 + reg.idx);
00497 p->stack_offset -= 4;
00498 }
00499
00500 void x86_inc( struct x86_function *p,
00501 struct x86_reg reg )
00502 {
00503 DUMP_R( reg );
00504 assert(reg.mod == mod_REG);
00505 emit_1ub(p, 0x40 + reg.idx);
00506 }
00507
00508 void x86_dec( struct x86_function *p,
00509 struct x86_reg reg )
00510 {
00511 DUMP_R( reg );
00512 assert(reg.mod == mod_REG);
00513 emit_1ub(p, 0x48 + reg.idx);
00514 }
00515
00516 void x86_ret( struct x86_function *p )
00517 {
00518 DUMP();
00519 assert(p->stack_offset == 0);
00520 emit_1ub(p, 0xc3);
00521 }
00522
00523 void x86_retw( struct x86_function *p, unsigned short imm )
00524 {
00525 DUMP();
00526 emit_3ub(p, 0xc2, imm & 0xff, (imm >> 8) & 0xff);
00527 }
00528
00529 void x86_sahf( struct x86_function *p )
00530 {
00531 DUMP();
00532 emit_1ub(p, 0x9e);
00533 }
00534
00535 void x86_mov( struct x86_function *p,
00536 struct x86_reg dst,
00537 struct x86_reg src )
00538 {
00539 DUMP_RR( dst, src );
00540 emit_op_modrm( p, 0x8b, 0x89, dst, src );
00541 }
00542
00543 void x86_xor( struct x86_function *p,
00544 struct x86_reg dst,
00545 struct x86_reg src )
00546 {
00547 DUMP_RR( dst, src );
00548 emit_op_modrm( p, 0x33, 0x31, dst, src );
00549 }
00550
00551 void x86_cmp( struct x86_function *p,
00552 struct x86_reg dst,
00553 struct x86_reg src )
00554 {
00555 DUMP_RR( dst, src );
00556 emit_op_modrm( p, 0x3b, 0x39, dst, src );
00557 }
00558
00559 void x86_lea( struct x86_function *p,
00560 struct x86_reg dst,
00561 struct x86_reg src )
00562 {
00563 DUMP_RR( dst, src );
00564 emit_1ub(p, 0x8d);
00565 emit_modrm( p, dst, src );
00566 }
00567
00568 void x86_test( struct x86_function *p,
00569 struct x86_reg dst,
00570 struct x86_reg src )
00571 {
00572 DUMP_RR( dst, src );
00573 emit_1ub(p, 0x85);
00574 emit_modrm( p, dst, src );
00575 }
00576
00577 void x86_add( struct x86_function *p,
00578 struct x86_reg dst,
00579 struct x86_reg src )
00580 {
00581 DUMP_RR( dst, src );
00582 emit_op_modrm(p, 0x03, 0x01, dst, src );
00583 }
00584
00585
00586
00587 void x86_mul( struct x86_function *p,
00588 struct x86_reg src )
00589 {
00590 DUMP_R( src );
00591 emit_1ub(p, 0xf7);
00592 emit_modrm_noreg(p, 4, src );
00593 }
00594
00595
00596 void x86_imul( struct x86_function *p,
00597 struct x86_reg dst,
00598 struct x86_reg src )
00599 {
00600 DUMP_RR( dst, src );
00601 emit_2ub(p, X86_TWOB, 0xAF);
00602 emit_modrm(p, dst, src);
00603 }
00604
00605
00606 void x86_sub( struct x86_function *p,
00607 struct x86_reg dst,
00608 struct x86_reg src )
00609 {
00610 DUMP_RR( dst, src );
00611 emit_op_modrm(p, 0x2b, 0x29, dst, src );
00612 }
00613
00614 void x86_or( struct x86_function *p,
00615 struct x86_reg dst,
00616 struct x86_reg src )
00617 {
00618 DUMP_RR( dst, src );
00619 emit_op_modrm( p, 0x0b, 0x09, dst, src );
00620 }
00621
00622 void x86_and( struct x86_function *p,
00623 struct x86_reg dst,
00624 struct x86_reg src )
00625 {
00626 DUMP_RR( dst, src );
00627 emit_op_modrm( p, 0x23, 0x21, dst, src );
00628 }
00629
00630
00631
00632
00633
00634
00635
00636 void sse_prefetchnta( struct x86_function *p, struct x86_reg ptr)
00637 {
00638 DUMP_R( ptr );
00639 assert(ptr.mod != mod_REG);
00640 emit_2ub(p, 0x0f, 0x18);
00641 emit_modrm_noreg(p, 0, ptr);
00642 }
00643
00644 void sse_prefetch0( struct x86_function *p, struct x86_reg ptr)
00645 {
00646 DUMP_R( ptr );
00647 assert(ptr.mod != mod_REG);
00648 emit_2ub(p, 0x0f, 0x18);
00649 emit_modrm_noreg(p, 1, ptr);
00650 }
00651
00652 void sse_prefetch1( struct x86_function *p, struct x86_reg ptr)
00653 {
00654 DUMP_R( ptr );
00655 assert(ptr.mod != mod_REG);
00656 emit_2ub(p, 0x0f, 0x18);
00657 emit_modrm_noreg(p, 2, ptr);
00658 }
00659
00660 void sse_movntps( struct x86_function *p,
00661 struct x86_reg dst,
00662 struct x86_reg src)
00663 {
00664 DUMP_RR( dst, src );
00665
00666 assert(dst.mod != mod_REG);
00667 assert(src.mod == mod_REG);
00668 emit_2ub(p, 0x0f, 0x2b);
00669 emit_modrm(p, src, dst);
00670 }
00671
00672
00673
00674
00675 void sse_movss( struct x86_function *p,
00676 struct x86_reg dst,
00677 struct x86_reg src )
00678 {
00679 DUMP_RR( dst, src );
00680 emit_2ub(p, 0xF3, X86_TWOB);
00681 emit_op_modrm( p, 0x10, 0x11, dst, src );
00682 }
00683
00684 void sse_movaps( struct x86_function *p,
00685 struct x86_reg dst,
00686 struct x86_reg src )
00687 {
00688 DUMP_RR( dst, src );
00689 emit_1ub(p, X86_TWOB);
00690 emit_op_modrm( p, 0x28, 0x29, dst, src );
00691 }
00692
00693 void sse_movups( struct x86_function *p,
00694 struct x86_reg dst,
00695 struct x86_reg src )
00696 {
00697 DUMP_RR( dst, src );
00698 emit_1ub(p, X86_TWOB);
00699 emit_op_modrm( p, 0x10, 0x11, dst, src );
00700 }
00701
00702 void sse_movhps( struct x86_function *p,
00703 struct x86_reg dst,
00704 struct x86_reg src )
00705 {
00706 DUMP_RR( dst, src );
00707 assert(dst.mod != mod_REG || src.mod != mod_REG);
00708 emit_1ub(p, X86_TWOB);
00709 emit_op_modrm( p, 0x16, 0x17, dst, src );
00710 }
00711
00712 void sse_movlps( struct x86_function *p,
00713 struct x86_reg dst,
00714 struct x86_reg src )
00715 {
00716 DUMP_RR( dst, src );
00717 assert(dst.mod != mod_REG || src.mod != mod_REG);
00718 emit_1ub(p, X86_TWOB);
00719 emit_op_modrm( p, 0x12, 0x13, dst, src );
00720 }
00721
00722 void sse_maxps( struct x86_function *p,
00723 struct x86_reg dst,
00724 struct x86_reg src )
00725 {
00726 DUMP_RR( dst, src );
00727 emit_2ub(p, X86_TWOB, 0x5F);
00728 emit_modrm( p, dst, src );
00729 }
00730
00731 void sse_maxss( struct x86_function *p,
00732 struct x86_reg dst,
00733 struct x86_reg src )
00734 {
00735 DUMP_RR( dst, src );
00736 emit_3ub(p, 0xF3, X86_TWOB, 0x5F);
00737 emit_modrm( p, dst, src );
00738 }
00739
00740 void sse_divss( struct x86_function *p,
00741 struct x86_reg dst,
00742 struct x86_reg src )
00743 {
00744 DUMP_RR( dst, src );
00745 emit_3ub(p, 0xF3, X86_TWOB, 0x5E);
00746 emit_modrm( p, dst, src );
00747 }
00748
00749 void sse_minps( struct x86_function *p,
00750 struct x86_reg dst,
00751 struct x86_reg src )
00752 {
00753 DUMP_RR( dst, src );
00754 emit_2ub(p, X86_TWOB, 0x5D);
00755 emit_modrm( p, dst, src );
00756 }
00757
00758 void sse_subps( struct x86_function *p,
00759 struct x86_reg dst,
00760 struct x86_reg src )
00761 {
00762 DUMP_RR( dst, src );
00763 emit_2ub(p, X86_TWOB, 0x5C);
00764 emit_modrm( p, dst, src );
00765 }
00766
00767 void sse_mulps( struct x86_function *p,
00768 struct x86_reg dst,
00769 struct x86_reg src )
00770 {
00771 DUMP_RR( dst, src );
00772 emit_2ub(p, X86_TWOB, 0x59);
00773 emit_modrm( p, dst, src );
00774 }
00775
00776 void sse_mulss( struct x86_function *p,
00777 struct x86_reg dst,
00778 struct x86_reg src )
00779 {
00780 DUMP_RR( dst, src );
00781 emit_3ub(p, 0xF3, X86_TWOB, 0x59);
00782 emit_modrm( p, dst, src );
00783 }
00784
00785 void sse_addps( struct x86_function *p,
00786 struct x86_reg dst,
00787 struct x86_reg src )
00788 {
00789 DUMP_RR( dst, src );
00790 emit_2ub(p, X86_TWOB, 0x58);
00791 emit_modrm( p, dst, src );
00792 }
00793
00794 void sse_addss( struct x86_function *p,
00795 struct x86_reg dst,
00796 struct x86_reg src )
00797 {
00798 DUMP_RR( dst, src );
00799 emit_3ub(p, 0xF3, X86_TWOB, 0x58);
00800 emit_modrm( p, dst, src );
00801 }
00802
00803 void sse_andnps( struct x86_function *p,
00804 struct x86_reg dst,
00805 struct x86_reg src )
00806 {
00807 DUMP_RR( dst, src );
00808 emit_2ub(p, X86_TWOB, 0x55);
00809 emit_modrm( p, dst, src );
00810 }
00811
00812 void sse_andps( struct x86_function *p,
00813 struct x86_reg dst,
00814 struct x86_reg src )
00815 {
00816 DUMP_RR( dst, src );
00817 emit_2ub(p, X86_TWOB, 0x54);
00818 emit_modrm( p, dst, src );
00819 }
00820
00821 void sse_rsqrtps( struct x86_function *p,
00822 struct x86_reg dst,
00823 struct x86_reg src )
00824 {
00825 DUMP_RR( dst, src );
00826 emit_2ub(p, X86_TWOB, 0x52);
00827 emit_modrm( p, dst, src );
00828 }
00829
00830 void sse_rsqrtss( struct x86_function *p,
00831 struct x86_reg dst,
00832 struct x86_reg src )
00833 {
00834 DUMP_RR( dst, src );
00835 emit_3ub(p, 0xF3, X86_TWOB, 0x52);
00836 emit_modrm( p, dst, src );
00837
00838 }
00839
00840 void sse_movhlps( struct x86_function *p,
00841 struct x86_reg dst,
00842 struct x86_reg src )
00843 {
00844 DUMP_RR( dst, src );
00845 assert(dst.mod == mod_REG && src.mod == mod_REG);
00846 emit_2ub(p, X86_TWOB, 0x12);
00847 emit_modrm( p, dst, src );
00848 }
00849
00850 void sse_movlhps( struct x86_function *p,
00851 struct x86_reg dst,
00852 struct x86_reg src )
00853 {
00854 DUMP_RR( dst, src );
00855 assert(dst.mod == mod_REG && src.mod == mod_REG);
00856 emit_2ub(p, X86_TWOB, 0x16);
00857 emit_modrm( p, dst, src );
00858 }
00859
00860 void sse_orps( struct x86_function *p,
00861 struct x86_reg dst,
00862 struct x86_reg src )
00863 {
00864 DUMP_RR( dst, src );
00865 emit_2ub(p, X86_TWOB, 0x56);
00866 emit_modrm( p, dst, src );
00867 }
00868
00869 void sse_xorps( struct x86_function *p,
00870 struct x86_reg dst,
00871 struct x86_reg src )
00872 {
00873 DUMP_RR( dst, src );
00874 emit_2ub(p, X86_TWOB, 0x57);
00875 emit_modrm( p, dst, src );
00876 }
00877
00878 void sse_cvtps2pi( struct x86_function *p,
00879 struct x86_reg dst,
00880 struct x86_reg src )
00881 {
00882 DUMP_RR( dst, src );
00883 assert(dst.file == file_MMX &&
00884 (src.file == file_XMM || src.mod != mod_REG));
00885
00886 p->need_emms = 1;
00887
00888 emit_2ub(p, X86_TWOB, 0x2d);
00889 emit_modrm( p, dst, src );
00890 }
00891
00892 void sse2_cvtdq2ps( struct x86_function *p,
00893 struct x86_reg dst,
00894 struct x86_reg src )
00895 {
00896 DUMP_RR( dst, src );
00897 emit_2ub(p, X86_TWOB, 0x5b);
00898 emit_modrm( p, dst, src );
00899 }
00900
00901
00902
00903
00904
00905 void sse_shufps( struct x86_function *p,
00906 struct x86_reg dst,
00907 struct x86_reg src,
00908 unsigned char shuf)
00909 {
00910 DUMP_RRI( dst, src, shuf );
00911 emit_2ub(p, X86_TWOB, 0xC6);
00912 emit_modrm(p, dst, src);
00913 emit_1ub(p, shuf);
00914 }
00915
00916 void sse_unpckhps( struct x86_function *p, struct x86_reg dst, struct x86_reg src )
00917 {
00918 DUMP_RR( dst, src );
00919 emit_2ub( p, X86_TWOB, 0x15 );
00920 emit_modrm( p, dst, src );
00921 }
00922
00923 void sse_unpcklps( struct x86_function *p, struct x86_reg dst, struct x86_reg src )
00924 {
00925 DUMP_RR( dst, src );
00926 emit_2ub( p, X86_TWOB, 0x14 );
00927 emit_modrm( p, dst, src );
00928 }
00929
00930 void sse_cmpps( struct x86_function *p,
00931 struct x86_reg dst,
00932 struct x86_reg src,
00933 enum sse_cc cc)
00934 {
00935 DUMP_RRI( dst, src, cc );
00936 emit_2ub(p, X86_TWOB, 0xC2);
00937 emit_modrm(p, dst, src);
00938 emit_1ub(p, cc);
00939 }
00940
00941 void sse_pmovmskb( struct x86_function *p,
00942 struct x86_reg dst,
00943 struct x86_reg src)
00944 {
00945 DUMP_RR( dst, src );
00946 emit_3ub(p, 0x66, X86_TWOB, 0xD7);
00947 emit_modrm(p, dst, src);
00948 }
00949
00950
00951
00952
00953
00957 void sse2_pshufd( struct x86_function *p,
00958 struct x86_reg dst,
00959 struct x86_reg src,
00960 unsigned char shuf)
00961 {
00962 DUMP_RRI( dst, src, shuf );
00963 emit_3ub(p, 0x66, X86_TWOB, 0x70);
00964 emit_modrm(p, dst, src);
00965 emit_1ub(p, shuf);
00966 }
00967
00968 void sse2_cvttps2dq( struct x86_function *p,
00969 struct x86_reg dst,
00970 struct x86_reg src )
00971 {
00972 DUMP_RR( dst, src );
00973 emit_3ub( p, 0xF3, X86_TWOB, 0x5B );
00974 emit_modrm( p, dst, src );
00975 }
00976
00977 void sse2_cvtps2dq( struct x86_function *p,
00978 struct x86_reg dst,
00979 struct x86_reg src )
00980 {
00981 DUMP_RR( dst, src );
00982 emit_3ub(p, 0x66, X86_TWOB, 0x5B);
00983 emit_modrm( p, dst, src );
00984 }
00985
00986 void sse2_packssdw( struct x86_function *p,
00987 struct x86_reg dst,
00988 struct x86_reg src )
00989 {
00990 DUMP_RR( dst, src );
00991 emit_3ub(p, 0x66, X86_TWOB, 0x6B);
00992 emit_modrm( p, dst, src );
00993 }
00994
00995 void sse2_packsswb( struct x86_function *p,
00996 struct x86_reg dst,
00997 struct x86_reg src )
00998 {
00999 DUMP_RR( dst, src );
01000 emit_3ub(p, 0x66, X86_TWOB, 0x63);
01001 emit_modrm( p, dst, src );
01002 }
01003
01004 void sse2_packuswb( struct x86_function *p,
01005 struct x86_reg dst,
01006 struct x86_reg src )
01007 {
01008 DUMP_RR( dst, src );
01009 emit_3ub(p, 0x66, X86_TWOB, 0x67);
01010 emit_modrm( p, dst, src );
01011 }
01012
01013 void sse2_punpcklbw( struct x86_function *p,
01014 struct x86_reg dst,
01015 struct x86_reg src )
01016 {
01017 DUMP_RR( dst, src );
01018 emit_3ub(p, 0x66, X86_TWOB, 0x60);
01019 emit_modrm( p, dst, src );
01020 }
01021
01022
01023 void sse2_rcpps( struct x86_function *p,
01024 struct x86_reg dst,
01025 struct x86_reg src )
01026 {
01027 DUMP_RR( dst, src );
01028 emit_2ub(p, X86_TWOB, 0x53);
01029 emit_modrm( p, dst, src );
01030 }
01031
01032 void sse2_rcpss( struct x86_function *p,
01033 struct x86_reg dst,
01034 struct x86_reg src )
01035 {
01036 DUMP_RR( dst, src );
01037 emit_3ub(p, 0xF3, X86_TWOB, 0x53);
01038 emit_modrm( p, dst, src );
01039 }
01040
01041 void sse2_movd( struct x86_function *p,
01042 struct x86_reg dst,
01043 struct x86_reg src )
01044 {
01045 DUMP_RR( dst, src );
01046 emit_2ub(p, 0x66, X86_TWOB);
01047 emit_op_modrm( p, 0x6e, 0x7e, dst, src );
01048 }
01049
01050
01051
01052
01053
01054
01055
01056 static void note_x87_pop( struct x86_function *p )
01057 {
01058 p->x87_stack--;
01059 assert(p->x87_stack >= 0);
01060 }
01061
01062 static void note_x87_push( struct x86_function *p )
01063 {
01064 p->x87_stack++;
01065 assert(p->x87_stack <= 7);
01066 }
01067
01068 void x87_assert_stack_empty( struct x86_function *p )
01069 {
01070 assert (p->x87_stack == 0);
01071 }
01072
01073
01074 void x87_fist( struct x86_function *p, struct x86_reg dst )
01075 {
01076 DUMP_R( dst );
01077 emit_1ub(p, 0xdb);
01078 emit_modrm_noreg(p, 2, dst);
01079 }
01080
01081 void x87_fistp( struct x86_function *p, struct x86_reg dst )
01082 {
01083 DUMP_R( dst );
01084 emit_1ub(p, 0xdb);
01085 emit_modrm_noreg(p, 3, dst);
01086 note_x87_pop(p);
01087 }
01088
01089 void x87_fild( struct x86_function *p, struct x86_reg arg )
01090 {
01091 DUMP_R( arg );
01092 emit_1ub(p, 0xdf);
01093 emit_modrm_noreg(p, 0, arg);
01094 note_x87_push(p);
01095 }
01096
01097 void x87_fldz( struct x86_function *p )
01098 {
01099 DUMP();
01100 emit_2ub(p, 0xd9, 0xee);
01101 note_x87_push(p);
01102 }
01103
01104
01105 void x87_fldcw( struct x86_function *p, struct x86_reg arg )
01106 {
01107 DUMP_R( arg );
01108 assert(arg.file == file_REG32);
01109 assert(arg.mod != mod_REG);
01110 emit_1ub(p, 0xd9);
01111 emit_modrm_noreg(p, 5, arg);
01112 }
01113
01114 void x87_fld1( struct x86_function *p )
01115 {
01116 DUMP();
01117 emit_2ub(p, 0xd9, 0xe8);
01118 note_x87_push(p);
01119 }
01120
01121 void x87_fldl2e( struct x86_function *p )
01122 {
01123 DUMP();
01124 emit_2ub(p, 0xd9, 0xea);
01125 note_x87_push(p);
01126 }
01127
01128 void x87_fldln2( struct x86_function *p )
01129 {
01130 DUMP();
01131 emit_2ub(p, 0xd9, 0xed);
01132 note_x87_push(p);
01133 }
01134
01135 void x87_fwait( struct x86_function *p )
01136 {
01137 DUMP();
01138 emit_1ub(p, 0x9b);
01139 }
01140
01141 void x87_fnclex( struct x86_function *p )
01142 {
01143 DUMP();
01144 emit_2ub(p, 0xdb, 0xe2);
01145 }
01146
01147 void x87_fclex( struct x86_function *p )
01148 {
01149 x87_fwait(p);
01150 x87_fnclex(p);
01151 }
01152
01153 void x87_fcmovb( struct x86_function *p, struct x86_reg arg )
01154 {
01155 DUMP_R( arg );
01156 assert(arg.file == file_x87);
01157 emit_2ub(p, 0xda, 0xc0+arg.idx);
01158 }
01159
01160 void x87_fcmove( struct x86_function *p, struct x86_reg arg )
01161 {
01162 DUMP_R( arg );
01163 assert(arg.file == file_x87);
01164 emit_2ub(p, 0xda, 0xc8+arg.idx);
01165 }
01166
01167 void x87_fcmovbe( struct x86_function *p, struct x86_reg arg )
01168 {
01169 DUMP_R( arg );
01170 assert(arg.file == file_x87);
01171 emit_2ub(p, 0xda, 0xd0+arg.idx);
01172 }
01173
01174 void x87_fcmovnb( struct x86_function *p, struct x86_reg arg )
01175 {
01176 DUMP_R( arg );
01177 assert(arg.file == file_x87);
01178 emit_2ub(p, 0xdb, 0xc0+arg.idx);
01179 }
01180
01181 void x87_fcmovne( struct x86_function *p, struct x86_reg arg )
01182 {
01183 DUMP_R( arg );
01184 assert(arg.file == file_x87);
01185 emit_2ub(p, 0xdb, 0xc8+arg.idx);
01186 }
01187
01188 void x87_fcmovnbe( struct x86_function *p, struct x86_reg arg )
01189 {
01190 DUMP_R( arg );
01191 assert(arg.file == file_x87);
01192 emit_2ub(p, 0xdb, 0xd0+arg.idx);
01193 }
01194
01195
01196
01197 static void x87_arith_op( struct x86_function *p, struct x86_reg dst, struct x86_reg arg,
01198 unsigned char dst0ub0,
01199 unsigned char dst0ub1,
01200 unsigned char arg0ub0,
01201 unsigned char arg0ub1,
01202 unsigned char argmem_noreg)
01203 {
01204 assert(dst.file == file_x87);
01205
01206 if (arg.file == file_x87) {
01207 if (dst.idx == 0)
01208 emit_2ub(p, dst0ub0, dst0ub1+arg.idx);
01209 else if (arg.idx == 0)
01210 emit_2ub(p, arg0ub0, arg0ub1+arg.idx);
01211 else
01212 assert(0);
01213 }
01214 else if (dst.idx == 0) {
01215 assert(arg.file == file_REG32);
01216 emit_1ub(p, 0xd8);
01217 emit_modrm_noreg(p, argmem_noreg, arg);
01218 }
01219 else
01220 assert(0);
01221 }
01222
01223 void x87_fmul( struct x86_function *p, struct x86_reg dst, struct x86_reg src )
01224 {
01225 DUMP_RR( dst, src );
01226 x87_arith_op(p, dst, src,
01227 0xd8, 0xc8,
01228 0xdc, 0xc8,
01229 4);
01230 }
01231
01232 void x87_fsub( struct x86_function *p, struct x86_reg dst, struct x86_reg src )
01233 {
01234 DUMP_RR( dst, src );
01235 x87_arith_op(p, dst, src,
01236 0xd8, 0xe0,
01237 0xdc, 0xe8,
01238 4);
01239 }
01240
01241 void x87_fsubr( struct x86_function *p, struct x86_reg dst, struct x86_reg src )
01242 {
01243 DUMP_RR( dst, src );
01244 x87_arith_op(p, dst, src,
01245 0xd8, 0xe8,
01246 0xdc, 0xe0,
01247 5);
01248 }
01249
01250 void x87_fadd( struct x86_function *p, struct x86_reg dst, struct x86_reg src )
01251 {
01252 DUMP_RR( dst, src );
01253 x87_arith_op(p, dst, src,
01254 0xd8, 0xc0,
01255 0xdc, 0xc0,
01256 0);
01257 }
01258
01259 void x87_fdiv( struct x86_function *p, struct x86_reg dst, struct x86_reg src )
01260 {
01261 DUMP_RR( dst, src );
01262 x87_arith_op(p, dst, src,
01263 0xd8, 0xf0,
01264 0xdc, 0xf8,
01265 6);
01266 }
01267
01268 void x87_fdivr( struct x86_function *p, struct x86_reg dst, struct x86_reg src )
01269 {
01270 DUMP_RR( dst, src );
01271 x87_arith_op(p, dst, src,
01272 0xd8, 0xf8,
01273 0xdc, 0xf0,
01274 7);
01275 }
01276
01277 void x87_fmulp( struct x86_function *p, struct x86_reg dst )
01278 {
01279 DUMP_R( dst );
01280 assert(dst.file == file_x87);
01281 assert(dst.idx >= 1);
01282 emit_2ub(p, 0xde, 0xc8+dst.idx);
01283 note_x87_pop(p);
01284 }
01285
01286 void x87_fsubp( struct x86_function *p, struct x86_reg dst )
01287 {
01288 DUMP_R( dst );
01289 assert(dst.file == file_x87);
01290 assert(dst.idx >= 1);
01291 emit_2ub(p, 0xde, 0xe8+dst.idx);
01292 note_x87_pop(p);
01293 }
01294
01295 void x87_fsubrp( struct x86_function *p, struct x86_reg dst )
01296 {
01297 DUMP_R( dst );
01298 assert(dst.file == file_x87);
01299 assert(dst.idx >= 1);
01300 emit_2ub(p, 0xde, 0xe0+dst.idx);
01301 note_x87_pop(p);
01302 }
01303
01304 void x87_faddp( struct x86_function *p, struct x86_reg dst )
01305 {
01306 DUMP_R( dst );
01307 assert(dst.file == file_x87);
01308 assert(dst.idx >= 1);
01309 emit_2ub(p, 0xde, 0xc0+dst.idx);
01310 note_x87_pop(p);
01311 }
01312
01313 void x87_fdivp( struct x86_function *p, struct x86_reg dst )
01314 {
01315 DUMP_R( dst );
01316 assert(dst.file == file_x87);
01317 assert(dst.idx >= 1);
01318 emit_2ub(p, 0xde, 0xf8+dst.idx);
01319 note_x87_pop(p);
01320 }
01321
01322 void x87_fdivrp( struct x86_function *p, struct x86_reg dst )
01323 {
01324 DUMP_R( dst );
01325 assert(dst.file == file_x87);
01326 assert(dst.idx >= 1);
01327 emit_2ub(p, 0xde, 0xf0+dst.idx);
01328 note_x87_pop(p);
01329 }
01330
01331 void x87_ftst( struct x86_function *p )
01332 {
01333 DUMP();
01334 emit_2ub(p, 0xd9, 0xe4);
01335 }
01336
01337 void x87_fucom( struct x86_function *p, struct x86_reg arg )
01338 {
01339 DUMP_R( arg );
01340 assert(arg.file == file_x87);
01341 emit_2ub(p, 0xdd, 0xe0+arg.idx);
01342 }
01343
01344 void x87_fucomp( struct x86_function *p, struct x86_reg arg )
01345 {
01346 DUMP_R( arg );
01347 assert(arg.file == file_x87);
01348 emit_2ub(p, 0xdd, 0xe8+arg.idx);
01349 note_x87_pop(p);
01350 }
01351
01352 void x87_fucompp( struct x86_function *p )
01353 {
01354 DUMP();
01355 emit_2ub(p, 0xda, 0xe9);
01356 note_x87_pop(p);
01357 note_x87_pop(p);
01358 }
01359
01360 void x87_fxch( struct x86_function *p, struct x86_reg arg )
01361 {
01362 DUMP_R( arg );
01363 assert(arg.file == file_x87);
01364 emit_2ub(p, 0xd9, 0xc8+arg.idx);
01365 }
01366
01367 void x87_fabs( struct x86_function *p )
01368 {
01369 DUMP();
01370 emit_2ub(p, 0xd9, 0xe1);
01371 }
01372
01373 void x87_fchs( struct x86_function *p )
01374 {
01375 DUMP();
01376 emit_2ub(p, 0xd9, 0xe0);
01377 }
01378
01379 void x87_fcos( struct x86_function *p )
01380 {
01381 DUMP();
01382 emit_2ub(p, 0xd9, 0xff);
01383 }
01384
01385
01386 void x87_fprndint( struct x86_function *p )
01387 {
01388 DUMP();
01389 emit_2ub(p, 0xd9, 0xfc);
01390 }
01391
01392 void x87_fscale( struct x86_function *p )
01393 {
01394 DUMP();
01395 emit_2ub(p, 0xd9, 0xfd);
01396 }
01397
01398 void x87_fsin( struct x86_function *p )
01399 {
01400 DUMP();
01401 emit_2ub(p, 0xd9, 0xfe);
01402 }
01403
01404 void x87_fsincos( struct x86_function *p )
01405 {
01406 DUMP();
01407 emit_2ub(p, 0xd9, 0xfb);
01408 }
01409
01410 void x87_fsqrt( struct x86_function *p )
01411 {
01412 DUMP();
01413 emit_2ub(p, 0xd9, 0xfa);
01414 }
01415
01416 void x87_fxtract( struct x86_function *p )
01417 {
01418 DUMP();
01419 emit_2ub(p, 0xd9, 0xf4);
01420 }
01421
01422
01423
01424
01425
01426 void x87_f2xm1( struct x86_function *p )
01427 {
01428 DUMP();
01429 emit_2ub(p, 0xd9, 0xf0);
01430 }
01431
01432
01433
01434
01435 void x87_fyl2x( struct x86_function *p )
01436 {
01437 DUMP();
01438 emit_2ub(p, 0xd9, 0xf1);
01439 note_x87_pop(p);
01440 }
01441
01442
01443
01444
01445
01446
01447 void x87_fyl2xp1( struct x86_function *p )
01448 {
01449 DUMP();
01450 emit_2ub(p, 0xd9, 0xf9);
01451 note_x87_pop(p);
01452 }
01453
01454
01455 void x87_fld( struct x86_function *p, struct x86_reg arg )
01456 {
01457 DUMP_R( arg );
01458 if (arg.file == file_x87)
01459 emit_2ub(p, 0xd9, 0xc0 + arg.idx);
01460 else {
01461 emit_1ub(p, 0xd9);
01462 emit_modrm_noreg(p, 0, arg);
01463 }
01464 note_x87_push(p);
01465 }
01466
01467 void x87_fst( struct x86_function *p, struct x86_reg dst )
01468 {
01469 DUMP_R( dst );
01470 if (dst.file == file_x87)
01471 emit_2ub(p, 0xdd, 0xd0 + dst.idx);
01472 else {
01473 emit_1ub(p, 0xd9);
01474 emit_modrm_noreg(p, 2, dst);
01475 }
01476 }
01477
01478 void x87_fstp( struct x86_function *p, struct x86_reg dst )
01479 {
01480 DUMP_R( dst );
01481 if (dst.file == file_x87)
01482 emit_2ub(p, 0xdd, 0xd8 + dst.idx);
01483 else {
01484 emit_1ub(p, 0xd9);
01485 emit_modrm_noreg(p, 3, dst);
01486 }
01487 note_x87_pop(p);
01488 }
01489
01490 void x87_fpop( struct x86_function *p )
01491 {
01492 x87_fstp( p, x86_make_reg( file_x87, 0 ));
01493 }
01494
01495
01496 void x87_fcom( struct x86_function *p, struct x86_reg dst )
01497 {
01498 DUMP_R( dst );
01499 if (dst.file == file_x87)
01500 emit_2ub(p, 0xd8, 0xd0 + dst.idx);
01501 else {
01502 emit_1ub(p, 0xd8);
01503 emit_modrm_noreg(p, 2, dst);
01504 }
01505 }
01506
01507
01508 void x87_fcomp( struct x86_function *p, struct x86_reg dst )
01509 {
01510 DUMP_R( dst );
01511 if (dst.file == file_x87)
01512 emit_2ub(p, 0xd8, 0xd8 + dst.idx);
01513 else {
01514 emit_1ub(p, 0xd8);
01515 emit_modrm_noreg(p, 3, dst);
01516 }
01517 note_x87_pop(p);
01518 }
01519
01520 void x87_fcomi( struct x86_function *p, struct x86_reg arg )
01521 {
01522 DUMP_R( arg );
01523 emit_2ub(p, 0xdb, 0xf0+arg.idx);
01524 }
01525
01526 void x87_fcomip( struct x86_function *p, struct x86_reg arg )
01527 {
01528 DUMP_R( arg );
01529 emit_2ub(p, 0xdb, 0xf0+arg.idx);
01530 note_x87_pop(p);
01531 }
01532
01533
01534 void x87_fnstsw( struct x86_function *p, struct x86_reg dst )
01535 {
01536 DUMP_R( dst );
01537 assert(dst.file == file_REG32);
01538
01539 if (dst.idx == reg_AX &&
01540 dst.mod == mod_REG)
01541 emit_2ub(p, 0xdf, 0xe0);
01542 else {
01543 emit_1ub(p, 0xdd);
01544 emit_modrm_noreg(p, 7, dst);
01545 }
01546 }
01547
01548
01549 void x87_fnstcw( struct x86_function *p, struct x86_reg dst )
01550 {
01551 DUMP_R( dst );
01552 assert(dst.file == file_REG32);
01553
01554 emit_1ub(p, 0x9b);
01555 emit_1ub(p, 0xd9);
01556 emit_modrm_noreg(p, 7, dst);
01557 }
01558
01559
01560
01561
01562
01563
01564
01565
01566 void mmx_emms( struct x86_function *p )
01567 {
01568 DUMP();
01569 assert(p->need_emms);
01570 emit_2ub(p, 0x0f, 0x77);
01571 p->need_emms = 0;
01572 }
01573
01574 void mmx_packssdw( struct x86_function *p,
01575 struct x86_reg dst,
01576 struct x86_reg src )
01577 {
01578 DUMP_RR( dst, src );
01579 assert(dst.file == file_MMX &&
01580 (src.file == file_MMX || src.mod != mod_REG));
01581
01582 p->need_emms = 1;
01583
01584 emit_2ub(p, X86_TWOB, 0x6b);
01585 emit_modrm( p, dst, src );
01586 }
01587
01588 void mmx_packuswb( struct x86_function *p,
01589 struct x86_reg dst,
01590 struct x86_reg src )
01591 {
01592 DUMP_RR( dst, src );
01593 assert(dst.file == file_MMX &&
01594 (src.file == file_MMX || src.mod != mod_REG));
01595
01596 p->need_emms = 1;
01597
01598 emit_2ub(p, X86_TWOB, 0x67);
01599 emit_modrm( p, dst, src );
01600 }
01601
01602 void mmx_movd( struct x86_function *p,
01603 struct x86_reg dst,
01604 struct x86_reg src )
01605 {
01606 DUMP_RR( dst, src );
01607 p->need_emms = 1;
01608 emit_1ub(p, X86_TWOB);
01609 emit_op_modrm( p, 0x6e, 0x7e, dst, src );
01610 }
01611
01612 void mmx_movq( struct x86_function *p,
01613 struct x86_reg dst,
01614 struct x86_reg src )
01615 {
01616 DUMP_RR( dst, src );
01617 p->need_emms = 1;
01618 emit_1ub(p, X86_TWOB);
01619 emit_op_modrm( p, 0x6f, 0x7f, dst, src );
01620 }
01621
01622
01623
01624
01625
01626
01627
01628 void x86_cdecl_caller_push_regs( struct x86_function *p )
01629 {
01630 x86_push(p, x86_make_reg(file_REG32, reg_AX));
01631 x86_push(p, x86_make_reg(file_REG32, reg_CX));
01632 x86_push(p, x86_make_reg(file_REG32, reg_DX));
01633 }
01634
01635 void x86_cdecl_caller_pop_regs( struct x86_function *p )
01636 {
01637 x86_pop(p, x86_make_reg(file_REG32, reg_DX));
01638 x86_pop(p, x86_make_reg(file_REG32, reg_CX));
01639 x86_pop(p, x86_make_reg(file_REG32, reg_AX));
01640 }
01641
01642
01643
01644
01645
01646 struct x86_reg x86_fn_arg( struct x86_function *p,
01647 unsigned arg )
01648 {
01649 return x86_make_disp(x86_make_reg(file_REG32, reg_SP),
01650 p->stack_offset + arg * 4);
01651 }
01652
01653
01654 void x86_init_func( struct x86_function *p )
01655 {
01656 p->size = 0;
01657 p->store = NULL;
01658 p->csr = p->store;
01659 DUMP_START();
01660 }
01661
01662 void x86_init_func_size( struct x86_function *p, unsigned code_size )
01663 {
01664 p->size = code_size;
01665 p->store = rtasm_exec_malloc(code_size);
01666 if (p->store == NULL) {
01667 p->store = p->error_overflow;
01668 }
01669 p->csr = p->store;
01670 DUMP_START();
01671 }
01672
01673 void x86_release_func( struct x86_function *p )
01674 {
01675 if (p->store && p->store != p->error_overflow)
01676 rtasm_exec_free(p->store);
01677
01678 p->store = NULL;
01679 p->csr = NULL;
01680 p->size = 0;
01681 }
01682
01683
01684 void (*x86_get_func( struct x86_function *p ))(void)
01685 {
01686 DUMP_END();
01687 if (DISASSEM && p->store)
01688 debug_printf("disassemble %p %p\n", p->store, p->csr);
01689
01690 if (p->store == p->error_overflow)
01691 return (void (*)(void)) NULL;
01692 else
01693 return (void (*)(void)) p->store;
01694 }
01695
01696 #else
01697
01698 void x86sse_dummy( void )
01699 {
01700 }
01701
01702 #endif