# HG changeset patch # User Mike Pavone # Date 1354085012 28800 # Node ID c0f339564819bfbf26fce6eee7544ef19709605b # Parent 2bdad0f52f42f7f8937255e7878be317b07d533d Make x86 generator generic with respect to operand size for immediate parameters. diff -r 2bdad0f52f42 -r c0f339564819 68kinst.c --- a/68kinst.c Tue Nov 27 09:28:13 2012 -0800 +++ b/68kinst.c Tue Nov 27 22:43:32 2012 -0800 @@ -39,12 +39,12 @@ case 0: dst->addr_mode = MODE_ABSOLUTE_SHORT; ext = *(++cur); - dst->params.u32 = sign_extend16(ext); + dst->params.immed = sign_extend16(ext); break; case 1: dst->addr_mode = MODE_ABSOLUTE; ext = *(++cur); - dst->params.u32 = ext << 16 | *(++cur); + dst->params.immed = ext << 16 | *(++cur); break; case 2: dst->addr_mode = MODE_PC_DISPLACE; @@ -57,13 +57,13 @@ switch (size) { case OPSIZE_BYTE: - dst->params.u8 = ext; + dst->params.immed = ext & 0xFF; break; case OPSIZE_WORD: - dst->params.u16 = ext; + dst->params.immed = ext; break; case OPSIZE_LONG: - dst->params.u32 = ext << 16 | *(++cur); + dst->params.immed = ext << 16 | *(++cur); break; } break; @@ -145,7 +145,7 @@ opmode = (*istream >> 3) & 0x7; reg = *istream & 0x7; decoded->src.addr_mode = MODE_IMMEDIATE; - decoded->src.params.u8 = *(++istream); + decoded->src.params.immed = *(++istream) & 0xFF; decoded->extra.size = OPSIZE_BYTE; istream = m68k_decode_op_ex(istream, opmode, reg, OPSIZE_BYTE, &(decoded->dst)); } else if ((*istream & 0xC0) == 0xC0) { @@ -160,12 +160,12 @@ decoded->op = M68K_ORI_CCR; decoded->extra.size = OPSIZE_BYTE; decoded->src.addr_mode = MODE_IMMEDIATE; - decoded->src.params.u8 = *(++istream); + decoded->src.params.immed = *(++istream) & 0xFF; } else if((*istream & 0xFF) == 0x7C) { decoded->op = M68K_ORI_SR; decoded->extra.size = OPSIZE_WORD; decoded->src.addr_mode = MODE_IMMEDIATE; - decoded->src.params.u16 = *(++istream); + decoded->src.params.immed = *(++istream); } else { decoded->op = M68K_OR; decoded->variant = VAR_IMMEDIATE; @@ -176,14 +176,14 @@ switch (size) { case OPSIZE_BYTE: - decoded->src.params.u8 = *(++istream); + decoded->src.params.immed = *(++istream) & 0xFF; break; case OPSIZE_WORD: - decoded->src.params.u16 = *(++istream); + decoded->src.params.immed = *(++istream); break; case OPSIZE_LONG: immed = *(++istream); - decoded->src.params.u32 = immed << 16 | *(++istream); + decoded->src.params.immed = immed << 16 | *(++istream); break; } istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); @@ -195,12 +195,12 @@ decoded->op = M68K_ANDI_CCR; decoded->extra.size = OPSIZE_BYTE; decoded->src.addr_mode = MODE_IMMEDIATE; - decoded->src.params.u8 = *(++istream); + decoded->src.params.immed = *(++istream) & 0xFF; } else if((*istream & 0xFF) == 0x7C) { decoded->op = M68K_ANDI_SR; decoded->extra.size = OPSIZE_WORD; decoded->src.addr_mode = MODE_IMMEDIATE; - decoded->src.params.u16 = *(++istream); + decoded->src.params.immed = *(++istream); } else { decoded->op = M68K_AND; decoded->variant = VAR_IMMEDIATE; @@ -211,14 +211,14 @@ switch (size) { case OPSIZE_BYTE: - decoded->src.params.u8 = *(++istream); + decoded->src.params.immed = *(++istream) & 0xFF; break; case OPSIZE_WORD: - decoded->src.params.u16 = *(++istream); + decoded->src.params.immed = *(++istream); break; case OPSIZE_LONG: immed = *(++istream); - decoded->src.params.u32 = immed << 16 | *(++istream); + decoded->src.params.immed = immed << 16 | *(++istream); break; } istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); @@ -234,14 +234,14 @@ switch (size) { case OPSIZE_BYTE: - decoded->src.params.u8 = *(++istream); + decoded->src.params.immed = *(++istream) & 0xFF; break; case OPSIZE_WORD: - decoded->src.params.u16 = *(++istream); + decoded->src.params.immed = *(++istream); break; case OPSIZE_LONG: immed = *(++istream); - decoded->src.params.u32 = immed << 16 | *(++istream); + decoded->src.params.immed = immed << 16 | *(++istream); break; } istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); @@ -256,14 +256,14 @@ switch (size) { case OPSIZE_BYTE: - decoded->src.params.u8 = *(++istream); + decoded->src.params.immed = *(++istream) & 0xFF; break; case OPSIZE_WORD: - decoded->src.params.u16 = *(++istream); + decoded->src.params.immed = *(++istream); break; case OPSIZE_LONG: immed = *(++istream); - decoded->src.params.u32 = immed << 16 | *(++istream); + decoded->src.params.immed = immed << 16 | *(++istream); break; } istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); @@ -286,7 +286,7 @@ break; } decoded->src.addr_mode = MODE_IMMEDIATE; - decoded->src.params.u8 = *(++istream); + decoded->src.params.immed = *(++istream) & 0xFF; istream = m68k_decode_op(istream, OPSIZE_BYTE, &(decoded->dst)); break; case 5: @@ -295,12 +295,12 @@ decoded->op = M68K_EORI_CCR; decoded->extra.size = OPSIZE_BYTE; decoded->src.addr_mode = MODE_IMMEDIATE; - decoded->src.params.u8 = *(++istream); + decoded->src.params.immed = *(++istream) & 0xFF; } else if((*istream & 0xFF) == 0x7C) { decoded->op = M68K_EORI_SR; decoded->extra.size = OPSIZE_WORD; decoded->src.addr_mode = MODE_IMMEDIATE; - decoded->src.params.u16 = *(++istream); + decoded->src.params.immed = *(++istream); } else { decoded->op = M68K_EOR; decoded->variant = VAR_IMMEDIATE; @@ -311,14 +311,14 @@ switch (size) { case OPSIZE_BYTE: - decoded->src.params.u8 = *(++istream); + decoded->src.params.immed = *(++istream) & 0xFF; break; case OPSIZE_WORD: - decoded->src.params.u16 = *(++istream); + decoded->src.params.immed = *(++istream); break; case OPSIZE_LONG: immed = *(++istream); - decoded->src.params.u32 = immed << 16 | *(++istream); + decoded->src.params.immed = immed << 16 | *(++istream); break; } istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); @@ -334,14 +334,14 @@ switch (decoded->extra.size) { case OPSIZE_BYTE: - decoded->src.params.u8 = *(++istream); + decoded->src.params.immed = *(++istream) & 0xFF; break; case OPSIZE_WORD: - decoded->src.params.u16 = *(++istream); + decoded->src.params.immed = *(++istream); break; case OPSIZE_LONG: immed = *(++istream); - decoded->src.params.u32 = (immed << 16) | *(++istream); + decoded->src.params.immed = (immed << 16) | *(++istream); break; } istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); @@ -411,11 +411,11 @@ immed = *(++istream); if(*istream & 0x400) { decoded->dst.addr_mode = MODE_REG; - decoded->dst.params.u16 = immed; + decoded->dst.params.immed = immed; istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->src)); } else { decoded->src.addr_mode = MODE_REG; - decoded->src.params.u16 = immed; + decoded->src.params.immed = immed; istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->dst)); } } else { @@ -497,7 +497,7 @@ decoded->op = M68K_BKPT; decoded->src.addr_mode = MODE_IMMEDIATE; decoded->extra.size = OPSIZE_UNSIZED; - decoded->src.params.u32 = *istream & 0x7; + decoded->src.params.immed = *istream & 0x7; #endif break; case 0x10: @@ -573,7 +573,7 @@ decoded->op = M68K_TRAP; decoded->extra.size = OPSIZE_UNSIZED; decoded->src.addr_mode = MODE_IMMEDIATE; - decoded->src.params.u32 = *istream & 0xF; + decoded->src.params.immed = *istream & 0xF; break; case 2: //LINK.w @@ -582,7 +582,7 @@ decoded->src.addr_mode = MODE_AREG; decoded->src.params.regs.pri = *istream & 0x7; decoded->dst.addr_mode = MODE_IMMEDIATE; - decoded->dst.params.u16 = *(++istream); + decoded->dst.params.immed = *(++istream); break; case 3: //UNLK @@ -616,7 +616,7 @@ case 2: decoded->op = M68K_STOP; decoded->src.addr_mode = MODE_IMMEDIATE; - decoded->src.params.u32 =*(++istream); + decoded->src.params.immed =*(++istream); break; case 3: decoded->op = M68K_RTE; @@ -625,7 +625,7 @@ #ifdef M68010 decoded->op = M68K_RTD; decoded->src.addr_mode = MODE_IMMEDIATE; - decoded->src.params.u32 =*(++istream); + decoded->src.params.immed =*(++istream); #endif break; case 5: @@ -662,7 +662,7 @@ case 1: //DBcc decoded->op = M68K_DBCC; decoded->src.addr_mode = MODE_IMMEDIATE; - decoded->src.params.u16 = *(++istream); + decoded->src.params.immed = *(++istream); decoded->dst.addr_mode = MODE_REG; decoded->dst.params.regs.pri = *istream & 0x7; break; @@ -688,18 +688,7 @@ if (!immed) { immed = 8; } - switch (size) - { - case OPSIZE_BYTE: - decoded->src.params.u8 = immed; - break; - case OPSIZE_WORD: - decoded->src.params.u16 = immed; - break; - case OPSIZE_LONG: - decoded->src.params.u32 = immed; - break; - } + decoded->src.params.immed = immed; if (*istream & 0x100) { decoded->op = M68K_SUB; } else { @@ -724,13 +713,14 @@ decoded->variant = VAR_BYTE; immed = sign_extend8(immed); } - decoded->src.params.u32 = immed; + decoded->src.params.immed = immed; break; case MOVEQ: decoded->op = M68K_MOVE; decoded->variant = VAR_QUICK; + decoded->extra.size = OPSIZE_LONG; decoded->src.addr_mode = MODE_IMMEDIATE; - decoded->src.params.u32 = sign_extend8(*istream & 0xFF); + decoded->src.params.immed = sign_extend8(*istream & 0xFF); decoded->dst.addr_mode = MODE_REG; decoded->dst.params.regs.pri = m68K_reg_quick_field(*istream); immed = *istream & 0xFF; @@ -1012,18 +1002,7 @@ immed = (*istream >> 9) & 0x7; if (*istream & 0x100) { decoded->src.addr_mode = MODE_IMMEDIATE; - switch(decoded->extra.size) - { - case OPSIZE_BYTE: - decoded->src.params.u8 = immed; - break; - case OPSIZE_WORD: - decoded->src.params.u16 = immed; - break; - case OPSIZE_LONG: - decoded->src.params.u32 = immed; - break; - } + decoded->src.params.immed = immed; } else { decoded->src.addr_mode = MODE_REG; decoded->src.params.regs.pri = immed; @@ -1136,7 +1115,7 @@ "le" }; -int m68k_disasm_op(m68k_op_info *decoded, uint8_t size, char *dst, int need_comma) +int m68k_disasm_op(m68k_op_info *decoded, char *dst, int need_comma) { char * c = need_comma ? "," : ""; switch(decoded->addr_mode) @@ -1154,11 +1133,11 @@ case MODE_AREG_DISPLACE: return sprintf(dst, "%s (a%d, %d)", c, decoded->params.regs.pri, decoded->params.regs.displacement); case MODE_IMMEDIATE: - return sprintf(dst, "%s #%d", c, (size == OPSIZE_LONG || size == OPSIZE_UNSIZED) ? decoded->params.u32 : (size == OPSIZE_WORD ? decoded->params.u16 : decoded->params.u8)); + return sprintf(dst, "%s #%d", c, decoded->params.immed); case MODE_ABSOLUTE_SHORT: - return sprintf(dst, "%s $%X.w", c, decoded->params.u32); + return sprintf(dst, "%s $%X.w", c, decoded->params.immed); case MODE_ABSOLUTE: - return sprintf(dst, "%s $%X", c, decoded->params.u32); + return sprintf(dst, "%s $%X", c, decoded->params.immed); case MODE_PC_DISPLACE: return sprintf(dst, "%s (pc, %d)", c, decoded->params.regs.displacement); default: @@ -1166,7 +1145,7 @@ } } -int m68k_disasm_movem_op(m68k_op_info *decoded, m68k_op_info *other, uint8_t size, char *dst, int need_comma) +int m68k_disasm_movem_op(m68k_op_info *decoded, m68k_op_info *other, char *dst, int need_comma) { int8_t dir, reg, bit, regnum, last=-1, lastreg, first=-1; char *rtype, *last_rtype; @@ -1181,7 +1160,7 @@ } strcat(dst, " "); for (oplen = 1, reg=0; bit < 16 && bit > -1; bit += dir, reg++) { - if (decoded->params.u16 & (1 << bit)) { + if (decoded->params.immed & (1 << bit)) { if (reg > 7) { rtype = "a"; regnum = reg - 8; @@ -1214,7 +1193,7 @@ } return oplen; } else { - return m68k_disasm_op(decoded, size, dst, need_comma); + return m68k_disasm_op(decoded, dst, need_comma); } } @@ -1233,16 +1212,14 @@ dst[ret] = 0; strcat(dst, cond_mnem[decoded->extra.cond]); ret = strlen(dst); - size = decoded->op = M68K_BCC ? OPSIZE_LONG : OPSIZE_WORD; break; case M68K_BSR: - size = OPSIZE_LONG; ret = sprintf(dst, "bsr%s", decoded->variant == VAR_BYTE ? ".s" : ""); break; case M68K_MOVE_FROM_SR: ret = sprintf(dst, "%s", mnemonics[decoded->op]); ret += sprintf(dst + ret, " SR"); - ret += m68k_disasm_op(&(decoded->dst), decoded->extra.size, dst + ret, 1); + ret += m68k_disasm_op(&(decoded->dst), dst + ret, 1); return ret; case M68K_ANDI_SR: case M68K_EORI_SR: @@ -1254,7 +1231,7 @@ case M68K_MOVE_CCR: case M68K_ORI_CCR: ret = sprintf(dst, "%s", mnemonics[decoded->op]); - ret += m68k_disasm_op(&(decoded->src), decoded->extra.size, dst + ret, 0); + ret += m68k_disasm_op(&(decoded->src), dst + ret, 0); ret += sprintf(dst + ret, ", %s", special_op); return ret; default: @@ -1265,13 +1242,13 @@ size == OPSIZE_BYTE ? ".b" : (size == OPSIZE_WORD ? ".w" : (size == OPSIZE_LONG ? ".l" : ""))); } if (decoded->op == M68K_MOVEM) { - op1len = m68k_disasm_movem_op(&(decoded->src), &(decoded->dst), size, dst + ret, 0); + op1len = m68k_disasm_movem_op(&(decoded->src), &(decoded->dst), dst + ret, 0); ret += op1len; - ret += m68k_disasm_movem_op(&(decoded->dst), &(decoded->src), size, dst + ret, op1len); + ret += m68k_disasm_movem_op(&(decoded->dst), &(decoded->src), dst + ret, op1len); } else { - op1len = m68k_disasm_op(&(decoded->src), size, dst + ret, 0); + op1len = m68k_disasm_op(&(decoded->src), dst + ret, 0); ret += op1len; - ret += m68k_disasm_op(&(decoded->dst), size, dst + ret, op1len); + ret += m68k_disasm_op(&(decoded->dst), dst + ret, op1len); } return ret; } diff -r 2bdad0f52f42 -r c0f339564819 68kinst.h --- a/68kinst.h Tue Nov 27 09:28:13 2012 -0800 +++ b/68kinst.h Tue Nov 27 22:43:32 2012 -0800 @@ -158,9 +158,7 @@ uint8_t sec; int32_t displacement; } regs; - uint8_t u8; - uint16_t u16; - uint32_t u32; + uint32_t immed; } params; } m68k_op_info; diff -r 2bdad0f52f42 -r c0f339564819 gen_x86.c --- a/gen_x86.c Tue Nov 27 09:28:13 2012 -0800 +++ b/gen_x86.c Tue Nov 27 22:43:32 2012 -0800 @@ -29,6 +29,7 @@ #define OP_MOV_I8R 0xB0 #define OP_MOV_IR 0xB8 #define OP_RETN 0xC3 +#define OP_MOV_IEA 0xC6 #define OP_CALL 0xE8 #define OP_CALL_EA 0xFF @@ -197,79 +198,77 @@ return out; } -uint8_t * x86_i8r(uint8_t * out, uint8_t opcode, uint8_t op_ex, uint8_t al_opcode, uint8_t val, uint8_t dst) +uint8_t * x86_ir(uint8_t * out, uint8_t opcode, uint8_t op_ex, uint8_t al_opcode, int32_t val, uint8_t dst, uint8_t size) { - if (dst == RAX) { + uint8_t sign_extend = 0; + if ((size == SZ_D || size == SZ_Q) && val <= 0x7F && val >= -0x80) { + sign_extend = 1; + opcode |= BIT_DIR; + } + if (size == SZ_W) { + *(out++) = PRE_SIZE; + } + if (dst == RAX && !sign_extend) { + if (size != SZ_B) { + al_opcode |= BIT_SIZE; + if (size == SZ_Q) { + *out = PRE_REX | REX_QUAD; + } + } *(out++) = al_opcode | BIT_IMMED_RAX; } else { + if (size == SZ_Q || dst >= R8 || (size == SZ_B && dst >= RSP && dst <= RDI)) { + *out = PRE_REX; + if (size == SZ_Q) { + *out |= REX_QUAD; + } + if (dst >= R8) { + *out |= REX_RM_FIELD; + dst -= (R8 - X86_R8); + } + out++; + } if (dst >= AH && dst <= BH) { dst -= (AH-X86_AH); - } else if(dst >= R8) { - *(out++) = PRE_REX | REX_RM_FIELD; + } + if (size != SZ_B) { + opcode |= BIT_SIZE; } *(out++) = opcode; *(out++) = MODE_REG_DIRECT | dst | (op_ex << 3); } *(out++) = val; + if (size != SZ_B && !sign_extend) { + val >>= 8; + *(out++) = val; + if (size != SZ_W) { + val >>= 8; + *(out++) = val; + val >>= 8; + *(out++) = val; + } + } return out; } -uint8_t * x86_i32r(uint8_t * out, uint8_t opcode, uint8_t op_ex, uint8_t al_opcode, int32_t val, uint8_t dst) -{ - uint8_t sign_extend = 0; - if (val <= 0x7F && val >= -0x80) { - sign_extend = 1; - opcode |= BIT_DIR; - } - if (dst == RAX && !sign_extend) { - *(out++) = al_opcode | BIT_IMMED_RAX | BIT_SIZE; - } else { - if(dst >= R8) { - *(out++) = PRE_REX | REX_RM_FIELD; - } - *(out++) = opcode | BIT_SIZE; - *(out++) = MODE_REG_DIRECT | dst | (op_ex << 3); - } - *(out++) = val; - if (!sign_extend) { - val >>= 8; - *(out++) = val; - val >>= 8; - *(out++) = val; - val >>= 8; - *(out++) = val; - } - return out; -} uint8_t * add_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) { return x86_rr_sizedir(out, OP_ADD, src, dst, size); } -uint8_t * add_i8r(uint8_t * out, uint8_t val, uint8_t dst) +uint8_t * add_ir(uint8_t * out, int32_t val, uint8_t dst, uint8_t size) { - return x86_i8r(out, OP_IMMED_ARITH, OP_EX_ADDI, OP_ADD, val, dst); -} - -uint8_t * add_i32r(uint8_t * out, int32_t val, uint8_t dst) -{ - return x86_i32r(out, OP_IMMED_ARITH, OP_EX_ADDI, OP_ADD, val, dst); + return x86_ir(out, OP_IMMED_ARITH, OP_EX_ADDI, OP_ADD, val, dst, size); } uint8_t * or_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) { return x86_rr_sizedir(out, OP_OR, src, dst, size); } - -uint8_t * or_i8r(uint8_t * out, uint8_t val, uint8_t dst) +uint8_t * or_ir(uint8_t * out, int32_t val, uint8_t dst, uint8_t size) { - return x86_i8r(out, OP_IMMED_ARITH, OP_EX_ORI, OP_OR, val, dst); -} - -uint8_t * or_i32r(uint8_t * out, int32_t val, uint8_t dst) -{ - return x86_i32r(out, OP_IMMED_ARITH, OP_EX_ORI, OP_OR, val, dst); + return x86_ir(out, OP_IMMED_ARITH, OP_EX_ORI, OP_OR, val, dst, size); } uint8_t * and_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) @@ -277,14 +276,9 @@ return x86_rr_sizedir(out, OP_AND, src, dst, size); } -uint8_t * and_i8r(uint8_t * out, uint8_t val, uint8_t dst) +uint8_t * and_ir(uint8_t * out, int32_t val, uint8_t dst, uint8_t size) { - return x86_i8r(out, OP_IMMED_ARITH, OP_EX_ANDI, OP_AND, val, dst); -} - -uint8_t * and_i32r(uint8_t * out, int32_t val, uint8_t dst) -{ - return x86_i32r(out, OP_IMMED_ARITH, OP_EX_ANDI, OP_AND, val, dst); + return x86_ir(out, OP_IMMED_ARITH, OP_EX_ANDI, OP_AND, val, dst, size); } uint8_t * xor_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) @@ -292,14 +286,9 @@ return x86_rr_sizedir(out, OP_XOR, src, dst, size); } -uint8_t * xor_i8r(uint8_t * out, uint8_t val, uint8_t dst) +uint8_t * xor_ir(uint8_t * out, int32_t val, uint8_t dst, uint8_t size) { - return x86_i8r(out, OP_IMMED_ARITH, OP_EX_XORI, OP_XOR, val, dst); -} - -uint8_t * xor_i32r(uint8_t * out, int32_t val, uint8_t dst) -{ - return x86_i32r(out, OP_IMMED_ARITH, OP_EX_XORI, OP_XOR, val, dst); + return x86_ir(out, OP_IMMED_ARITH, OP_EX_XORI, OP_XOR, val, dst, size); } uint8_t * sub_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) @@ -307,30 +296,19 @@ return x86_rr_sizedir(out, OP_SUB, src, dst, size); } -uint8_t * sub_i8r(uint8_t * out, uint8_t val, uint8_t dst) +uint8_t * sub_ir(uint8_t * out, int32_t val, uint8_t dst, uint8_t size) { - return x86_i8r(out, OP_IMMED_ARITH, OP_EX_SUBI, OP_SUB, val, dst); + return x86_ir(out, OP_IMMED_ARITH, OP_EX_SUBI, OP_SUB, val, dst, size); } -uint8_t * sub_i32r(uint8_t * out, int32_t val, uint8_t dst) -{ - return x86_i32r(out, OP_IMMED_ARITH, OP_EX_SUBI, OP_SUB, val, dst); -} - - uint8_t * cmp_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) { return x86_rr_sizedir(out, OP_CMP, src, dst, size); } -uint8_t * cmp_i8r(uint8_t * out, uint8_t val, uint8_t dst) +uint8_t * cmp_ir(uint8_t * out, int32_t val, uint8_t dst, uint8_t size) { - return x86_i8r(out, OP_IMMED_ARITH, OP_EX_CMPI, OP_CMP, val, dst); -} - -uint8_t * cmp_i32r(uint8_t * out, int32_t val, uint8_t dst) -{ - return x86_i32r(out, OP_IMMED_ARITH, OP_EX_CMPI, OP_CMP, val, dst); + return x86_ir(out, OP_IMMED_ARITH, OP_EX_CMPI, OP_CMP, val, dst, size); } uint8_t * mov_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) @@ -358,49 +336,58 @@ return x86_rrind_sizedir(out, OP_MOV, dst, src, size, BIT_DIR); } -uint8_t * mov_i8r(uint8_t * out, uint8_t val, uint8_t dst) -{ - if (dst >= AH && dst <= BH) { - dst -= AH - X86_AH; - } else if (dst >= RSP && dst <= RDI) { - *(out++) = PRE_REX; - } else if (dst >= R8) { - *(out++) = PRE_REX | REX_RM_FIELD; - dst -= R8 - X86_R8; +uint8_t * mov_ir(uint8_t * out, int64_t val, uint8_t dst, uint8_t size) +{ + uint8_t sign_extend = 0; + if (size == SZ_Q && val <= 0x7FFFFFFF && val >= -2147483648) { + sign_extend = 1; + } + if (size == SZ_W) { + *(out++) = PRE_SIZE; } - *(out++) = OP_MOV_I8R | dst; - *(out++) = val; - return out; -} - -uint8_t * mov_i16r(uint8_t * out, uint16_t val, uint8_t dst) -{ - *(out++) = PRE_SIZE; - if (dst >= R8) { - *(out++) = PRE_REX | REX_RM_FIELD; - dst -= R8 - X86_R8; + if (size == SZ_Q || dst >= R8 || (size == SZ_B && dst >= RSP && dst <= RDI)) { + *out = PRE_REX; + if (size == SZ_Q) { + *out |= REX_QUAD; + } + if (dst >= R8) { + *out |= REX_RM_FIELD; + dst -= (R8 - X86_R8); + } + out++; + } + if (dst >= AH && dst <= BH) { + dst -= (AH-X86_AH); } - *(out++) = OP_MOV_IR | dst; - *(out++) = val; - val >>= 8; + if (size == SZ_B) { + *(out++) = OP_MOV_I8R; + } else if (size == SZ_Q && sign_extend) { + *(out++) = OP_MOV_IEA | BIT_SIZE; + *(out++) = MODE_REG_DIRECT | dst; + } else { + *(out++) = OP_MOV_IR; + } *(out++) = val; - return out; -} - -uint8_t * mov_i32r(uint8_t * out, uint32_t val, uint8_t dst) -{ - if (dst >= R8) { - *(out++) = PRE_REX | REX_RM_FIELD; - dst -= R8 - X86_R8; + if (size != SZ_B) { + val >>= 8; + *(out++) = val; + if (size != SZ_W) { + val >>= 8; + *(out++) = val; + val >>= 8; + *(out++) = val; + if (size == SZ_Q && !sign_extend) { + val >>= 8; + *(out++) = val; + val >>= 8; + *(out++) = val; + val >>= 8; + *(out++) = val; + val >>= 8; + *(out++) = val; + } + } } - *(out++) = OP_MOV_IR | dst; - *(out++) = val; - val >>= 8; - *(out++) = val; - val >>= 8; - *(out++) = val; - val >>= 8; - *(out++) = val; return out; } diff -r 2bdad0f52f42 -r c0f339564819 gen_x86.h --- a/gen_x86.h Tue Nov 27 09:28:13 2012 -0800 +++ b/gen_x86.h Tue Nov 27 22:43:32 2012 -0800 @@ -58,26 +58,18 @@ uint8_t * and_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size); uint8_t * sub_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size); uint8_t * cmp_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size); -uint8_t * add_i8r(uint8_t * out, uint8_t val, uint8_t dst); -uint8_t * or_i8r(uint8_t * out, uint8_t val, uint8_t dst); -uint8_t * xor_i8r(uint8_t * out, uint8_t val, uint8_t dst); -uint8_t * and_i8r(uint8_t * out, uint8_t val, uint8_t dst); -uint8_t * sub_i8r(uint8_t * out, uint8_t val, uint8_t dst); -uint8_t * cmp_i8r(uint8_t * out, uint8_t val, uint8_t dst); -uint8_t * add_i32r(uint8_t * out, int32_t val, uint8_t dst); -uint8_t * or_i32r(uint8_t * out, int32_t val, uint8_t dst); -uint8_t * xor_i32r(uint8_t * out, int32_t val, uint8_t dst); -uint8_t * and_i32r(uint8_t * out, int32_t val, uint8_t dst); -uint8_t * sub_i32r(uint8_t * out, int32_t val, uint8_t dst); -uint8_t * cmp_i32r(uint8_t * out, int32_t val, uint8_t dst); +uint8_t * add_ir(uint8_t * out, int32_t val, uint8_t dst, uint8_t size); +uint8_t * or_ir(uint8_t * out, int32_t val, uint8_t dst, uint8_t size); +uint8_t * xor_ir(uint8_t * out, int32_t val, uint8_t dst, uint8_t size); +uint8_t * and_ir(uint8_t * out, int32_t val, uint8_t dst, uint8_t size); +uint8_t * sub_ir(uint8_t * out, int32_t val, uint8_t dst, uint8_t size); +uint8_t * cmp_ir(uint8_t * out, int32_t val, uint8_t dst, uint8_t size); uint8_t * mov_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size); uint8_t * mov_rrdisp8(uint8_t * out, uint8_t src, uint8_t dst_base, int8_t disp, uint8_t size); uint8_t * mov_rdisp8r(uint8_t * out, uint8_t src_base, int8_t disp, uint8_t dst, uint8_t size); uint8_t * mov_rrind(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size); uint8_t * mov_rindr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size); -uint8_t * mov_i8r(uint8_t * out, uint8_t val, uint8_t dst); -uint8_t * mov_i16r(uint8_t * out, uint16_t val, uint8_t dst); -uint8_t * mov_i32r(uint8_t * out, uint32_t val, uint8_t dst); +uint8_t * mov_ir(uint8_t * out, int64_t val, uint8_t dst, uint8_t size); uint8_t * pushf(uint8_t * out); uint8_t * popf(uint8_t * out); uint8_t * push_r(uint8_t * out, uint8_t reg); diff -r 2bdad0f52f42 -r c0f339564819 test_x86.c --- a/test_x86.c Tue Nov 27 09:28:13 2012 -0800 +++ b/test_x86.c Tue Nov 27 22:43:32 2012 -0800 @@ -1,4 +1,5 @@ #include "gen_x86.h" +#include "m68k_to_x86.h" #include #include @@ -14,12 +15,13 @@ cur = mov_rr(cur, R11, R12, SZ_W); cur = mov_rr(cur, RAX, RBX, SZ_D); cur = mov_rr(cur, RAX, RBX, SZ_Q); - cur = mov_i32r(cur, 5, RAX); - cur = mov_i32r(cur, 3, R8); - cur = mov_i8r(cur, 4, RSP); + cur = mov_ir(cur, 5, RAX, SZ_D); + cur = mov_ir(cur, 3, R8, SZ_D); + cur = mov_ir(cur, 4, RSP, SZ_B); cur = add_rr(cur, RAX, RBX, SZ_D); - cur = add_i8r(cur, 5, RAX); - cur = add_i8r(cur, 5, RBX); + cur = add_ir(cur, 5, RAX, SZ_B); + cur = add_ir(cur, 5, RBX, SZ_B); + cur = add_ir(cur, 5, RBP, SZ_B); cur = pushf(cur); cur = popf(cur); cur = setcc_r(cur, CC_S, RBX);