void x87_fnstcw( struct x86_function *p, struct x86_reg dst ) { DUMP_R( dst ); assert(dst.file == file_REG32); emit_1ub(p, 0x9b); /* WAIT -- needed? */ emit_1ub(p, 0xd9); emit_modrm_noreg(p, 7, dst); }
void x86_mov16_imm( struct x86_function *p, struct x86_reg dst, uint16_t imm ) { DUMP_RI( dst, imm ); emit_1ub(p, 0x66); if(dst.mod == mod_REG) { emit_1ub(p, 0xb8 + dst.idx); emit_2ub(p, imm & 0xff, imm >> 8); }
void x86_push( struct x86_function *p, struct x86_reg reg ) { DUMP_R( reg ); if (reg.mod == mod_REG) emit_1ub(p, 0x50 + reg.idx); else { emit_1ub(p, 0xff); emit_modrm_noreg(p, 6, reg); } p->stack_offset += 4; }
void x87_fistp( struct x86_function *p, struct x86_reg dst ) { DUMP_R( dst ); emit_1ub(p, 0xdb); emit_modrm_noreg(p, 3, dst); note_x87_pop(p); }
void x87_fild( struct x86_function *p, struct x86_reg arg ) { DUMP_R( arg ); emit_1ub(p, 0xdf); emit_modrm_noreg(p, 0, arg); note_x87_push(p); }
void sse_movups( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { emit_1ub(p, X86_TWOB); emit_op_modrm( p, 0x10, 0x11, dst, src ); }
void x86_test( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { emit_1ub(p, 0x85); emit_modrm( p, dst, src ); }
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); }
void x87_fldcw( struct x86_function *p, struct x86_reg arg ) { assert(arg.file == file_REG32); assert(arg.mod != mod_REG); emit_1ub(p, 0xd9); emit_modrm_noreg(p, 5, arg); }
/* Calculate EAX * src, results in EDX:EAX. */ void x86_mul( struct x86_function *p, struct x86_reg src ) { DUMP_R( src ); emit_1ub(p, 0xf7); emit_modrm_noreg(p, 4, src ); }
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 x86_dec( struct x86_function *p, struct x86_reg reg ) { DUMP_R( reg ); assert(reg.mod == mod_REG); emit_1ub(p, 0x48 + reg.idx); }
int x86_jmp_forward( struct x86_function *p) { DUMP(); emit_1ub(p, 0xe9); emit_1i(p, 0); return x86_get_label(p); }
void x86_pop( struct x86_function *p, struct x86_reg reg ) { assert(reg.mod == mod_REG); emit_1ub(p, 0x58 + reg.idx); p->stack_offset -= 4; }
void x86_lea( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { emit_1ub(p, 0x8d); emit_modrm( p, dst, src ); }
void sse_movaps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { DUMP_RR( dst, src ); emit_1ub(p, X86_TWOB); emit_op_modrm( p, 0x28, 0x29, dst, src ); }
void mmx_movq( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { p->need_emms = 1; emit_1ub(p, X86_TWOB); emit_op_modrm( p, 0x6f, 0x7f, dst, src ); }
void x86_mov_reg_imm( struct x86_function *p, struct x86_reg dst, int imm ) { DUMP_RI( dst, imm ); assert(dst.file == file_REG32); assert(dst.mod == mod_REG); emit_1ub(p, 0xb8 + dst.idx); emit_1i(p, imm); }
/** * Immediate group 1 instructions. */ static INLINE void x86_group1_imm( struct x86_function *p, unsigned op, struct x86_reg dst, int imm ) { assert(dst.file == file_REG32); assert(dst.mod == mod_REG); if(-0x80 <= imm && imm < 0x80) { emit_1ub(p, 0x83); emit_modrm_noreg(p, op, dst); emit_1b(p, (char)imm); } else { emit_1ub(p, 0x81); emit_modrm_noreg(p, op, dst); emit_1i(p, imm); } }
void sse_movlps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { assert(dst.mod != mod_REG || src.mod != mod_REG); emit_1ub(p, X86_TWOB); emit_op_modrm( p, 0x12, 0x13, dst, src ); /* cf movhlps */ }
void x86_push_imm32( struct x86_function *p, int imm32 ) { DUMP_I( imm32 ); emit_1ub(p, 0x68); emit_1i(p, imm32); p->stack_offset += 4; }
void sse_movhps( 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_1ub(p, X86_TWOB); emit_op_modrm( p, 0x16, 0x17, dst, src ); /* cf movlhps */ }
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); } }
/** * Perform a reduced swizzle: */ void sse2_pshufd( struct x86_function *p, struct x86_reg dest, struct x86_reg arg0, unsigned char shuf) { emit_3ub(p, 0x66, X86_TWOB, 0x70); emit_modrm(p, dest, arg0); emit_1ub(p, shuf); }
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_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 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 mmx_movd( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { DUMP_RR( dst, src ); p->need_emms = 1; emit_1ub(p, X86_TWOB); emit_op_modrm( p, 0x6e, 0x7e, dst, src ); }
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); }