void x86_print_reg( struct x86_reg reg )
{
- if (reg.mod != mod_REG)
+ if (reg.mod != mod_REG)
debug_printf( "[" );
-
+
switch( reg.file ) {
case file_REG32:
switch( reg.idx ) {
reg.mod == mod_DISP32)
debug_printf("+%d", reg.disp);
- if (reg.mod != mod_REG)
+ if (reg.mod != mod_REG)
debug_printf( "]" );
}
*
* This is the "/r" field in the x86 manuals...
*/
-static void emit_modrm( struct x86_function *p,
- struct x86_reg reg,
- struct x86_reg regmem )
+static void emit_modrm( struct x86_function *p,
+ struct x86_reg reg,
+ struct x86_reg regmem )
{
unsigned char val = 0;
-
+
assert(reg.mod == mod_REG);
-
+
/* TODO: support extended x86-64 registers */
assert(reg.idx < 8);
assert(regmem.idx < 8);
- val |= regmem.mod << 6; /* mod field */
- val |= reg.idx << 3; /* reg field */
- val |= regmem.idx; /* r/m field */
-
+ val |= regmem.mod << 6; /* mod field */
+ val |= reg.idx << 3; /* reg field */
+ val |= regmem.idx; /* r/m field */
+
emit_1ub(p, val);
/* Oh-oh we've stumbled into the SIB thing.
if (regmem.file == file_REG32 &&
regmem.idx == reg_SP &&
regmem.mod != mod_REG) {
- emit_1ub(p, 0x24); /* simplistic! */
+ emit_1ub(p, 0x24); /* simplistic! */
}
switch (regmem.mod) {
/* Emits the "/0".."/7" specialized versions of the modrm ("/r") bytes.
*/
static void emit_modrm_noreg( struct x86_function *p,
- unsigned op,
- struct x86_reg regmem )
+ unsigned op,
+ struct x86_reg regmem )
{
struct x86_reg dummy = x86_make_reg(file_REG32, op);
emit_modrm(p, dummy, regmem);
* the arguments presented.
*/
static void emit_op_modrm( struct x86_function *p,
- unsigned char op_dst_is_reg,
- unsigned char op_dst_is_mem,
- struct x86_reg dst,
- struct x86_reg src )
-{
+ unsigned char op_dst_is_reg,
+ unsigned char op_dst_is_mem,
+ struct x86_reg dst,
+ struct x86_reg src )
+{
switch (dst.mod) {
case mod_REG:
emit_1ub(p, op_dst_is_reg);
/* Create and manipulate registers and regmem values:
*/
struct x86_reg x86_make_reg( enum x86_reg_file file,
- enum x86_reg_name idx )
+ enum x86_reg_name idx )
{
struct x86_reg reg;
}
struct x86_reg x86_make_disp( struct x86_reg reg,
- int disp )
+ int disp )
{
assert(reg.file == file_REG32);
}
void x86_jcc( struct x86_function *p,
- enum x86_cc cc,
- int label )
+ 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) {
/* Fixup offset from forward jump:
*/
void x86_fixup_fwd_jump( struct x86_function *p,
- int fixup )
+ int fixup )
{
*(int *)(p->store + fixup - 4) = x86_get_label(p) - fixup;
}
/**
* Immediate group 1 instructions.
*/
-static inline void
-x86_group1_imm( struct x86_function *p,
+static inline void
+x86_group1_imm( struct x86_function *p,
unsigned op, struct x86_reg dst, int imm )
{
assert(dst.file == file_REG32);
void x86_push( struct x86_function *p,
- struct x86_reg reg )
+ struct x86_reg reg )
{
DUMP_R( reg );
if (reg.mod == mod_REG)
emit_1ub(p, 0x50 + reg.idx);
- else
+ else
{
emit_1ub(p, 0xff);
emit_modrm_noreg(p, 6, reg);
void x86_pop( struct x86_function *p,
- struct x86_reg reg )
+ struct x86_reg reg )
{
DUMP_R( reg );
assert(reg.mod == mod_REG);
}
void x86_inc( struct x86_function *p,
- struct x86_reg reg )
+ struct x86_reg reg )
{
DUMP_R( reg );
if(x86_target(p) == X86_32 && reg.mod == mod_REG)
}
void x86_dec( struct x86_function *p,
- struct x86_reg reg )
+ struct x86_reg reg )
{
DUMP_R( reg );
if(x86_target(p) == X86_32 && reg.mod == mod_REG)
}
void x86_mov( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
+ struct x86_reg dst,
+ struct x86_reg src )
{
DUMP_RR( dst, src );
/* special hack for reading arguments until we support x86-64 registers everywhere */
}
void x86_mov16( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
+ struct x86_reg dst,
+ struct x86_reg src )
{
DUMP_RR( dst, src );
emit_1ub(p, 0x66);
}
void x86_mov8( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
+ struct x86_reg dst,
+ struct x86_reg src )
{
DUMP_RR( dst, src );
emit_op_modrm( p, 0x8a, 0x88, dst, src );
}
void x64_mov64( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
+ struct x86_reg dst,
+ struct x86_reg src )
{
uint8_t rex = 0x48;
DUMP_RR( dst, src );
}
void x86_xor( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
+ struct x86_reg dst,
+ struct x86_reg src )
{
DUMP_RR( dst, src );
emit_op_modrm( p, 0x33, 0x31, dst, src );
}
void x86_cmp( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
+ struct x86_reg dst,
+ struct x86_reg src )
{
DUMP_RR( dst, src );
emit_op_modrm( p, 0x3b, 0x39, dst, src );
}
void x86_lea( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
+ struct x86_reg dst,
+ struct x86_reg src )
{
DUMP_RR( dst, src );
emit_1ub(p, 0x8d);
}
void x86_test( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
+ struct x86_reg dst,
+ struct x86_reg src )
{
DUMP_RR( dst, src );
emit_1ub(p, 0x85);
}
void x86_add( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
+ struct x86_reg dst,
+ struct x86_reg src )
{
DUMP_RR( dst, src );
emit_op_modrm(p, 0x03, 0x01, dst, src );
/* Calculate EAX * src, results in EDX:EAX.
*/
void x86_mul( struct x86_function *p,
- struct x86_reg src )
+ struct x86_reg src )
{
DUMP_R( src );
emit_1ub(p, 0xf7);
void x86_imul( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
+ struct x86_reg dst,
+ struct x86_reg src )
{
DUMP_RR( dst, src );
emit_2ub(p, X86_TWOB, 0xAF);
void x86_sub( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
+ struct x86_reg dst,
+ struct x86_reg src )
{
DUMP_RR( dst, src );
emit_op_modrm(p, 0x2b, 0x29, dst, src );
emit_modrm_noreg(p, 2, ptr);
}
-void sse_movntps( struct x86_function *p,
+void sse_movntps( struct x86_function *p,
struct x86_reg dst,
struct x86_reg src)
{
void sse_movss( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
+ struct x86_reg dst,
+ struct x86_reg src )
{
DUMP_RR( dst, src );
emit_2ub(p, 0xF3, X86_TWOB);
}
void sse_movaps( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
+ struct x86_reg dst,
+ struct x86_reg src )
{
DUMP_RR( dst, src );
emit_1ub(p, X86_TWOB);
}
void sse_movups( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
+ struct x86_reg dst,
+ struct x86_reg src )
{
DUMP_RR( dst, src );
emit_1ub(p, X86_TWOB);
}
void sse_movhps( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
+ struct x86_reg dst,
+ struct x86_reg src )
{
DUMP_RR( dst, src );
assert(dst.mod != mod_REG || src.mod != mod_REG);
}
void sse_movlps( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
+ struct x86_reg dst,
+ struct x86_reg src )
{
DUMP_RR( dst, src );
assert(dst.mod != mod_REG || src.mod != mod_REG);
}
void sse_maxps( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
+ struct x86_reg dst,
+ struct x86_reg src )
{
DUMP_RR( dst, src );
emit_2ub(p, X86_TWOB, 0x5F);
}
void sse_maxss( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
+ struct x86_reg dst,
+ struct x86_reg src )
{
DUMP_RR( dst, src );
emit_3ub(p, 0xF3, X86_TWOB, 0x5F);
}
void sse_divss( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
+ struct x86_reg dst,
+ struct x86_reg src )
{
DUMP_RR( dst, src );
emit_3ub(p, 0xF3, X86_TWOB, 0x5E);
}
void sse_minps( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
+ struct x86_reg dst,
+ struct x86_reg src )
{
DUMP_RR( dst, src );
emit_2ub(p, X86_TWOB, 0x5D);
}
void sse_subps( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
+ struct x86_reg dst,
+ struct x86_reg src )
{
DUMP_RR( dst, src );
emit_2ub(p, X86_TWOB, 0x5C);
}
void sse_mulps( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
+ struct x86_reg dst,
+ struct x86_reg src )
{
DUMP_RR( dst, src );
emit_2ub(p, X86_TWOB, 0x59);
}
void sse_mulss( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
+ struct x86_reg dst,
+ struct x86_reg src )
{
DUMP_RR( dst, src );
emit_3ub(p, 0xF3, X86_TWOB, 0x59);
}
void sse_addps( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
+ struct x86_reg dst,
+ struct x86_reg src )
{
DUMP_RR( dst, src );
emit_2ub(p, X86_TWOB, 0x58);
}
void sse_addss( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
+ struct x86_reg dst,
+ struct x86_reg src )
{
DUMP_RR( dst, src );
emit_3ub(p, 0xF3, X86_TWOB, 0x58);
}
void sse_andps( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
+ struct x86_reg dst,
+ struct x86_reg src )
{
DUMP_RR( dst, src );
emit_2ub(p, X86_TWOB, 0x54);
}
void sse_rsqrtss( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
+ struct x86_reg dst,
+ struct x86_reg src )
{
DUMP_RR( dst, src );
emit_3ub(p, 0xF3, X86_TWOB, 0x52);
}
void sse_movhlps( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
+ struct x86_reg dst,
+ struct x86_reg src )
{
DUMP_RR( dst, src );
assert(dst.mod == mod_REG && src.mod == mod_REG);
}
void sse_movlhps( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
+ struct x86_reg dst,
+ struct x86_reg src )
{
DUMP_RR( dst, src );
assert(dst.mod == mod_REG && src.mod == mod_REG);
}
void sse_cvtps2pi( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
+ struct x86_reg dst,
+ struct x86_reg src )
{
DUMP_RR( dst, src );
- assert(dst.file == file_MMX &&
- (src.file == file_XMM || src.mod != mod_REG));
+ assert(dst.file == file_MMX &&
+ (src.file == file_XMM || src.mod != mod_REG));
p->need_emms = 1;
}
void sse2_cvtdq2ps( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
+ struct x86_reg dst,
+ struct x86_reg src )
{
DUMP_RR( dst, src );
emit_2ub(p, X86_TWOB, 0x5b);
* arg0.
*/
void sse_shufps( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src,
- unsigned char shuf)
+ 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);
+ emit_1ub(p, shuf);
}
void sse_unpckhps( struct x86_function *p, struct x86_reg dst, struct x86_reg src )
}
void sse_cmpps( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src,
- enum sse_cc cc)
+ 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);
+ emit_1ub(p, cc);
}
void sse_pmovmskb( struct x86_function *p,
* Perform a reduced swizzle:
*/
void sse2_pshufd( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src,
- unsigned char shuf)
+ struct x86_reg dst,
+ struct x86_reg src,
+ unsigned char shuf)
{
DUMP_RRI( dst, src, shuf );
emit_3ub(p, 0x66, X86_TWOB, 0x70);
emit_modrm(p, dst, src);
- emit_1ub(p, shuf);
+ emit_1ub(p, shuf);
}
void sse2_pshuflw( struct x86_function *p,
}
void sse2_cvtps2dq( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
+ struct x86_reg dst,
+ struct x86_reg src )
{
DUMP_RR( dst, src );
emit_3ub(p, 0x66, X86_TWOB, 0x5B);
}
void sse2_packssdw( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
+ struct x86_reg dst,
+ struct x86_reg src )
{
DUMP_RR( dst, src );
emit_3ub(p, 0x66, X86_TWOB, 0x6B);
}
void sse2_packsswb( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
+ struct x86_reg dst,
+ struct x86_reg src )
{
DUMP_RR( dst, src );
emit_3ub(p, 0x66, X86_TWOB, 0x63);
}
void sse2_packuswb( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
+ struct x86_reg dst,
+ struct x86_reg src )
{
DUMP_RR( dst, src );
emit_3ub(p, 0x66, X86_TWOB, 0x67);
}
void sse2_punpcklbw( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
+ struct x86_reg dst,
+ struct x86_reg src )
{
DUMP_RR( dst, src );
emit_3ub(p, 0x66, X86_TWOB, 0x60);
}
void sse2_rcpss( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
+ struct x86_reg dst,
+ struct x86_reg src )
{
DUMP_RR( dst, src );
emit_3ub(p, 0xF3, X86_TWOB, 0x53);
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)
+ 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);
+ 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);
+ assert(0);
}
else if (dst.idx == 0) {
assert(arg.file == file_REG32);
void x87_fmul( struct x86_function *p, struct x86_reg dst, struct x86_reg src )
{
DUMP_RR( dst, src );
- x87_arith_op(p, dst, src,
- 0xd8, 0xc8,
- 0xdc, 0xc8,
- 4);
+ x87_arith_op(p, dst, src,
+ 0xd8, 0xc8,
+ 0xdc, 0xc8,
+ 4);
}
void x87_fsub( struct x86_function *p, struct x86_reg dst, struct x86_reg src )
{
DUMP_RR( dst, src );
- x87_arith_op(p, dst, src,
- 0xd8, 0xe0,
- 0xdc, 0xe8,
- 4);
+ x87_arith_op(p, dst, src,
+ 0xd8, 0xe0,
+ 0xdc, 0xe8,
+ 4);
}
void x87_fsubr( struct x86_function *p, struct x86_reg dst, struct x86_reg src )
{
DUMP_RR( dst, src );
- x87_arith_op(p, dst, src,
- 0xd8, 0xe8,
- 0xdc, 0xe0,
- 5);
+ x87_arith_op(p, dst, src,
+ 0xd8, 0xe8,
+ 0xdc, 0xe0,
+ 5);
}
void x87_fadd( struct x86_function *p, struct x86_reg dst, struct x86_reg src )
{
DUMP_RR( dst, src );
- x87_arith_op(p, dst, src,
- 0xd8, 0xc0,
- 0xdc, 0xc0,
- 0);
+ x87_arith_op(p, dst, src,
+ 0xd8, 0xc0,
+ 0xdc, 0xc0,
+ 0);
}
void x87_fdiv( struct x86_function *p, struct x86_reg dst, struct x86_reg src )
{
DUMP_RR( dst, src );
- x87_arith_op(p, dst, src,
- 0xd8, 0xf0,
- 0xdc, 0xf8,
- 6);
+ x87_arith_op(p, dst, src,
+ 0xd8, 0xf0,
+ 0xdc, 0xf8,
+ 6);
}
void x87_fdivr( struct x86_function *p, struct x86_reg dst, struct x86_reg src )
{
DUMP_RR( dst, src );
- x87_arith_op(p, dst, src,
- 0xd8, 0xf8,
- 0xdc, 0xf0,
- 7);
+ x87_arith_op(p, dst, src,
+ 0xd8, 0xf8,
+ 0xdc, 0xf0,
+ 7);
}
void x87_fmulp( struct x86_function *p, struct x86_reg dst )
/* st1 = st1 * log2(st0 + 1.0);
* pop_stack;
*
- * A fast operation, with restrictions: -.29 < st0 < .29
+ * A fast operation, with restrictions: -.29 < st0 < .29
*/
void x87_fyl2xp1( struct x86_function *p )
{
void x87_fld( struct x86_function *p, struct x86_reg arg )
{
DUMP_R( arg );
- if (arg.file == file_x87)
+ if (arg.file == file_x87)
emit_2ub(p, 0xd9, 0xc0 + arg.idx);
else {
emit_1ub(p, 0xd9);
void x87_fst( struct x86_function *p, struct x86_reg dst )
{
DUMP_R( dst );
- if (dst.file == file_x87)
+ if (dst.file == file_x87)
emit_2ub(p, 0xdd, 0xd0 + dst.idx);
else {
emit_1ub(p, 0xd9);
void x87_fstp( struct x86_function *p, struct x86_reg dst )
{
DUMP_R( dst );
- if (dst.file == file_x87)
+ if (dst.file == file_x87)
emit_2ub(p, 0xdd, 0xd8 + dst.idx);
else {
emit_1ub(p, 0xd9);
void x87_fcom( struct x86_function *p, struct x86_reg dst )
{
DUMP_R( dst );
- if (dst.file == file_x87)
+ if (dst.file == file_x87)
emit_2ub(p, 0xd8, 0xd0 + dst.idx);
else {
emit_1ub(p, 0xd8);
void x87_fcomp( struct x86_function *p, struct x86_reg dst )
{
DUMP_R( dst );
- if (dst.file == file_x87)
+ if (dst.file == file_x87)
emit_2ub(p, 0xd8, 0xd8 + dst.idx);
else {
emit_1ub(p, 0xd8);
assert(dst.file == file_REG32);
if (dst.idx == reg_AX &&
- dst.mod == mod_REG)
+ dst.mod == mod_REG)
emit_2ub(p, 0xdf, 0xe0);
else {
emit_1ub(p, 0xdd);
}
void mmx_packssdw( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
+ struct x86_reg dst,
+ struct x86_reg src )
{
DUMP_RR( dst, src );
- assert(dst.file == file_MMX &&
- (src.file == file_MMX || src.mod != mod_REG));
+ assert(dst.file == file_MMX &&
+ (src.file == file_MMX || src.mod != mod_REG));
p->need_emms = 1;
}
void mmx_packuswb( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
+ struct x86_reg dst,
+ struct x86_reg src )
{
DUMP_RR( dst, src );
- assert(dst.file == file_MMX &&
- (src.file == file_MMX || src.mod != mod_REG));
+ assert(dst.file == file_MMX &&
+ (src.file == file_MMX || src.mod != mod_REG));
p->need_emms = 1;
}
void mmx_movd( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
+ struct x86_reg dst,
+ struct x86_reg src )
{
DUMP_RR( dst, src );
p->need_emms = 1;
}
void mmx_movq( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
+ struct x86_reg dst,
+ struct x86_reg src )
{
DUMP_RR( dst, src );
p->need_emms = 1;
case 4:
return x86_make_reg(file_REG32, reg_R9);
default:
- /* Win64 allocates stack slots as if it pushed the first 4 arguments too */
+ /* Win64 allocates stack slots as if it pushed the first 4 arguments too */
return x86_make_disp(x86_make_reg(file_REG32, reg_SP),
p->stack_offset + arg * 8);
}
}
case X86_32:
return x86_make_disp(x86_make_reg(file_REG32, reg_SP),
- p->stack_offset + arg * 4); /* ??? */
+ p->stack_offset + arg * 4); /* ??? */
default:
assert(0 && "Unexpected x86 target ABI in x86_fn_arg");
return x86_make_reg(file_REG32, reg_CX); /* not used / silence warning */