static void x87_arith_op( struct x86_function *p, struct x86_reg dst, struct x86_reg arg, unsigned char dst0ub0, unsigned char dst0ub1, unsigned char arg0ub0, unsigned char arg0ub1, unsigned char argmem_noreg) { assert(dst.file == file_x87); if (arg.file == file_x87) { if (dst.idx == 0) emit_2ub(p, dst0ub0, dst0ub1+arg.idx); else if (arg.idx == 0) emit_2ub(p, arg0ub0, arg0ub1+arg.idx); else assert(0); } else if (dst.idx == 0) { assert(arg.file == file_REG32); emit_1ub(p, 0xd8); emit_modrm_noreg(p, argmem_noreg, arg); } else assert(0); }
/* Always use a 32bit offset for forward jumps: */ unsigned char *x86_jcc_forward( struct x86_function *p, enum x86_cc cc ) { emit_2ub(p, 0x0f, 0x80 + cc); emit_1i(p, 0); return x86_get_label(p); }
void sse_movss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { emit_2ub(p, 0xF3, X86_TWOB); emit_op_modrm( p, 0x10, 0x11, dst, src ); }
void sse_rsqrtps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { emit_2ub(p, X86_TWOB, 0x52); emit_modrm( p, dst, src ); }
void sse2_rcpps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { emit_2ub(p, X86_TWOB, 0x53); emit_modrm( p, dst, src ); }
void sse2_movd( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { emit_2ub(p, 0x66, X86_TWOB); emit_op_modrm( p, 0x6e, 0x7e, dst, src ); }
void sse_prefetch1( struct x86_function *p, struct x86_reg ptr) { DUMP_R( ptr ); assert(ptr.mod != mod_REG); emit_2ub(p, 0x0f, 0x18); emit_modrm_noreg(p, 2, ptr); }
void mmx_emms( struct x86_function *p ) { DUMP(); assert(p->need_emms); emit_2ub(p, 0x0f, 0x77); p->need_emms = 0; }
void x86_jcc( struct x86_function *p, enum x86_cc cc, int label ) { int offset = label - (x86_get_label(p) + 2); DUMP_I(cc); if (offset < 0) { /*assert(p->csr - p->store > -offset);*/ if (p->csr - p->store <= -offset) { /* probably out of memory (using the error_overflow buffer) */ return; } } if (offset <= 127 && offset >= -128) { emit_1ub(p, 0x70 + cc); emit_1b(p, (char) offset); } else { offset = label - (x86_get_label(p) + 6); emit_2ub(p, 0x0f, 0x80 + cc); emit_1i(p, offset); } }
void x87_fucompp( struct x86_function *p ) { DUMP(); emit_2ub(p, 0xda, 0xe9); note_x87_pop(p); /* pop twice */ note_x87_pop(p); /* pop twice */ }
void x87_fucomp( struct x86_function *p, struct x86_reg arg ) { DUMP_R( arg ); assert(arg.file == file_x87); emit_2ub(p, 0xdd, 0xe8+arg.idx); note_x87_pop(p); }
void sse2_cvtdq2ps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { DUMP_RR( dst, src ); emit_2ub(p, X86_TWOB, 0x5b); emit_modrm( p, dst, src ); }
void sse_xorps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { DUMP_RR( dst, src ); emit_2ub(p, X86_TWOB, 0x57); emit_modrm( p, dst, src ); }
void x86_imul( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { DUMP_RR( dst, src ); emit_2ub(p, X86_TWOB, 0xAF); emit_modrm(p, dst, src); }
/* Always use a 32bit offset for forward jumps: */ int x86_jcc_forward( struct x86_function *p, enum x86_cc cc ) { DUMP_I(cc); emit_2ub(p, 0x0f, 0x80 + cc); emit_1i(p, 0); return x86_get_label(p); }
void x87_fdivrp( struct x86_function *p, struct x86_reg dst ) { DUMP_R( dst ); assert(dst.file == file_x87); assert(dst.idx >= 1); emit_2ub(p, 0xde, 0xf0+dst.idx); note_x87_pop(p); }
void sse_movlhps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { assert(dst.mod == mod_REG && src.mod == mod_REG); emit_2ub(p, X86_TWOB, 0x16); emit_modrm( p, dst, src ); }
void x87_fst( struct x86_function *p, struct x86_reg dst ) { if (dst.file == file_x87) emit_2ub(p, 0xdd, 0xd0 + dst.idx); else { emit_1ub(p, 0xd9); emit_modrm_noreg(p, 2, dst); } }
void sse_movhlps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { DUMP_RR( dst, src ); assert(dst.mod == mod_REG && src.mod == mod_REG); emit_2ub(p, X86_TWOB, 0x12); emit_modrm( p, dst, src ); }
void sse_cmpps( struct x86_function *p, struct x86_reg dest, struct x86_reg arg0, unsigned char cc) { emit_2ub(p, X86_TWOB, 0xC2); emit_modrm(p, dest, arg0); emit_1ub(p, cc); }
/* Shufps can also be used to implement a reduced swizzle when dest == * arg0. */ void sse_shufps( struct x86_function *p, struct x86_reg dest, struct x86_reg arg0, unsigned char shuf) { emit_2ub(p, X86_TWOB, 0xC6); emit_modrm(p, dest, arg0); emit_1ub(p, shuf); }
void x87_fld( struct x86_function *p, struct x86_reg arg ) { if (arg.file == file_x87) emit_2ub(p, 0xd9, 0xc0 + arg.idx); else { emit_1ub(p, 0xd9); emit_modrm_noreg(p, 0, arg); } }
void x87_fcomp( struct x86_function *p, struct x86_reg dst ) { if (dst.file == file_x87) emit_2ub(p, 0xd8, 0xd8 + dst.idx); else { emit_1ub(p, 0xd8); emit_modrm_noreg(p, 3, dst); } }
void x87_fcom( struct x86_function *p, struct x86_reg dst ) { DUMP_R( dst ); if (dst.file == file_x87) emit_2ub(p, 0xd8, 0xd0 + dst.idx); else { emit_1ub(p, 0xd8); emit_modrm_noreg(p, 2, dst); } }
/* Shufps can also be used to implement a reduced swizzle when dest == * arg0. */ void sse_shufps( struct x86_function *p, struct x86_reg dst, struct x86_reg src, unsigned char shuf) { DUMP_RRI( dst, src, shuf ); emit_2ub(p, X86_TWOB, 0xC6); emit_modrm(p, dst, src); emit_1ub(p, shuf); }
void sse_cmpps( struct x86_function *p, struct x86_reg dst, struct x86_reg src, enum sse_cc cc) { DUMP_RRI( dst, src, cc ); emit_2ub(p, X86_TWOB, 0xC2); emit_modrm(p, dst, src); emit_1ub(p, cc); }
void x87_fstp( struct x86_function *p, struct x86_reg dst ) { DUMP_R( dst ); if (dst.file == file_x87) emit_2ub(p, 0xdd, 0xd8 + dst.idx); else { emit_1ub(p, 0xd9); emit_modrm_noreg(p, 3, dst); } note_x87_pop(p); }
void sse_movntps( struct x86_function *p, struct x86_reg dst, struct x86_reg src) { DUMP_RR( dst, src ); assert(dst.mod != mod_REG); assert(src.mod == mod_REG); emit_2ub(p, 0x0f, 0x2b); emit_modrm(p, src, dst); }
void sse_cvtps2pi( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { assert(dst.file == file_MMX && (src.file == file_XMM || src.mod != mod_REG)); p->need_emms = 1; emit_2ub(p, X86_TWOB, 0x2d); emit_modrm( p, dst, src ); }
void mmx_packuswb( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { assert(dst.file == file_MMX && (src.file == file_MMX || src.mod != mod_REG)); p->need_emms = 1; emit_2ub(p, X86_TWOB, 0x67); emit_modrm( p, dst, src ); }