Added recompiled versions of 8 and 16 bit immediate->reg and reg->reg versions of MOV, ADD, SUB, CMP, AND, OR and XOR.

This commit is contained in:
SarahW 2018-07-17 22:08:25 +01:00
commit 648aa0e3e8
17 changed files with 3006 additions and 231 deletions

View file

@ -100,30 +100,67 @@ static int is_imm8(uint32_t imm_data)
return 0;
}
static void host_x86_ADD8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data)
{
if (dst_reg != src_reg)
fatal("host_x86_ADD8_REG_IMM - dst_reg != src_reg\n");
if (dst_reg == REG_EAX)
codegen_addbyte2(block, 0x04, imm_data); /*ADD AL, imm_data*/
else
codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_ADD | dst_reg, imm_data); /*ADD dst_reg, imm_data*/
}
static void host_x86_ADD16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data)
{
if (dst_reg != src_reg)
fatal("host_x86_ADD16_REG_IMM - dst_reg != src_reg\n");
if (is_imm8(imm_data))
codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_ADD | dst_reg, imm_data & 0xff); /*ADD dst_reg, imm_data*/
else if (dst_reg == REG_EAX)
{
codegen_addbyte2(block, 0x66, 0x05); /*ADD AX, imm_data*/
codegen_addword(block, imm_data);
}
else
{
codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_ADD | dst_reg); /*ADD dst_reg, imm_data*/
codegen_addword(block, imm_data);
}
}
static void host_x86_ADD32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data)
{
if (dst_reg != src_reg)
fatal("host_x86_ADD32_REG_IMM - dst_reg != src_reg\n");
if (is_imm8(imm_data))
{
codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_ADD | dst_reg, imm_data & 0xff); /*ADD dst_reg, imm_data*/
else if (dst_reg == REG_EAX)
{
codegen_addbyte(block, 0x05); /*ADD EAX, imm_data*/
codegen_addlong(block, imm_data);
}
else
{
if (dst_reg == REG_EAX)
{
codegen_addbyte(block, 0x05); /*ADD EAX, imm_data*/
codegen_addlong(block, imm_data);
}
else
{
codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_ADD | dst_reg); /*ADD dst_reg, imm_data*/
codegen_addlong(block, imm_data);
}
codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_ADD | dst_reg); /*ADD dst_reg, imm_data*/
codegen_addlong(block, imm_data);
}
}
static void host_x86_ADD8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b)
{
if (dst_reg != src_reg_a)
fatal("host_x86_ADD8_REG_IMM - dst_reg != src_reg_a\n");
codegen_addbyte2(block, 0x00, 0xc0 | dst_reg | (src_reg_b << 3)); /*ADD dst_reg, src_reg_b*/
}
static void host_x86_ADD16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b)
{
if (dst_reg != src_reg_a)
fatal("host_x86_ADD16_REG_IMM - dst_reg != src_reg_a\n");
codegen_addbyte3(block, 0x66, 0x01, 0xc0 | dst_reg | (src_reg_b << 3)); /*ADD dst_reg, src_reg_b*/
}
static void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b)
{
if (dst_reg != src_reg_a)
@ -132,30 +169,67 @@ static void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_
codegen_addbyte2(block, 0x01, 0xc0 | dst_reg | (src_reg_b << 3)); /*ADD dst_reg, src_reg_b*/
}
static void host_x86_AND8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data)
{
if (dst_reg != src_reg)
fatal("host_x86_AND8_REG_IMM - dst_reg != src_reg\n");
if (dst_reg == REG_EAX)
codegen_addbyte2(block, 0x24, imm_data); /*AND AL, imm_data*/
else
codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_AND | dst_reg, imm_data); /*AND dst_reg, imm_data*/
}
static void host_x86_AND16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data)
{
if (dst_reg != src_reg)
fatal("host_x86_AND16_REG_IMM - dst_reg != src_reg\n");
if (is_imm8(imm_data))
codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_AND | dst_reg, imm_data & 0xff); /*AND dst_reg, imm_data*/
else if (dst_reg == REG_EAX)
{
codegen_addbyte2(block, 0x66, 0x25); /*AND AX, imm_data*/
codegen_addword(block, imm_data);
}
else
{
codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_AND | dst_reg); /*AND dst_reg, imm_data*/
codegen_addword(block, imm_data);
}
}
static void host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data)
{
if (dst_reg != src_reg)
fatal("host_x86_AND32_REG_IMM - dst_reg != src_reg\n");
if (is_imm8(imm_data))
{
codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_AND | dst_reg, imm_data & 0xff); /*AND dst_reg, imm_data*/
else if (dst_reg == REG_EAX)
{
codegen_addbyte(block, 0x25); /*AND EAX, imm_data*/
codegen_addlong(block, imm_data);
}
else
{
if (dst_reg == REG_EAX)
{
codegen_addbyte(block, 0x25); /*AND EAX, imm_data*/
codegen_addlong(block, imm_data);
}
else
{
codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_AND | dst_reg); /*AND dst_reg, imm_data*/
codegen_addlong(block, imm_data);
}
codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_AND | dst_reg); /*AND dst_reg, imm_data*/
codegen_addlong(block, imm_data);
}
}
static void host_x86_AND8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b)
{
if (dst_reg != src_reg_a)
fatal("host_x86_AND8_REG_REG - dst_reg != src_reg_a\n");
codegen_addbyte2(block, 0x20, 0xc0 | dst_reg | (src_reg_b << 3)); /*AND dst_reg, src_reg_b*/
}
static void host_x86_AND16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b)
{
if (dst_reg != src_reg_a)
fatal("host_x86_AND16_REG_REG - dst_reg != src_reg_a\n");
codegen_addbyte3(block, 0x66, 0x21, 0xc0 | dst_reg | (src_reg_b << 3)); /*AND dst_reg, src_reg_b*/
}
static void host_x86_AND32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b)
{
if (dst_reg != src_reg_a)
@ -260,6 +334,23 @@ static void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p)
codegen_addlong(block, (uint32_t)p);
}
}
static void host_x86_MOV8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data)
{
codegen_addbyte2(block, 0xb0 + dst_reg, imm_data); /*MOV reg, imm_data*/
}
static void host_x86_MOV16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data)
{
if (!imm_data)
{
codegen_addbyte3(block, 0x66, 0x31, 0xc0 | dst_reg | (dst_reg << 3)); /*XOR dst_reg, dst_reg*/
}
else
{
codegen_addbyte2(block, 0x66, 0xb8 + dst_reg); /*MOV reg, imm_data*/
codegen_addword(block, imm_data);
}
}
static void host_x86_MOV32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data)
{
if (!imm_data)
@ -273,6 +364,14 @@ static void host_x86_MOV32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm
}
}
static void host_x86_MOV8_REG_REG(codeblock_t *block, int dst_reg, int src_reg)
{
codegen_addbyte2(block, 0x88, 0xc0 | dst_reg | (src_reg << 3));
}
static void host_x86_MOV16_REG_REG(codeblock_t *block, int dst_reg, int src_reg)
{
codegen_addbyte3(block, 0x66, 0x89, 0xc0 | dst_reg | (src_reg << 3));
}
static void host_x86_MOV32_REG_REG(codeblock_t *block, int dst_reg, int src_reg)
{
codegen_addbyte2(block, 0x89, 0xc0 | dst_reg | (src_reg << 3));
@ -298,6 +397,29 @@ static void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_
}
}
static void host_x86_MOVZX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg)
{
codegen_addbyte3(block, 0x0f, 0xb6, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/
}
static void host_x86_MOVZX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg)
{
codegen_addbyte3(block, 0x0f, 0xb7, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/
}
static void host_x86_OR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b)
{
if (dst_reg != src_reg_a)
fatal("host_x86_OR8_REG_REG - dst_reg != src_reg_a\n");
codegen_addbyte2(block, 0x08, 0xc0 | dst_reg | (src_reg_b << 3)); /*OR dst_reg, src_reg_b*/
}
static void host_x86_OR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b)
{
if (dst_reg != src_reg_a)
fatal("host_x86_OR16_REG_REG - dst_reg != src_reg_a\n");
codegen_addbyte3(block, 0x66, 0x09, 0xc0 | dst_reg | (src_reg_b << 3)); /*OR dst_reg, src_reg_b*/
}
static void host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b)
{
if (dst_reg != src_reg_a)
@ -305,60 +427,121 @@ static void host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a
codegen_addbyte2(block, 0x09, 0xc0 | dst_reg | (src_reg_b << 3)); /*OR dst_reg, src_reg_b*/
}
static void host_x86_OR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data)
{
if (dst_reg != src_reg)
fatal("host_x86_OR8_REG_IMM - dst_reg != src_reg\n");
if (dst_reg == REG_EAX)
codegen_addbyte2(block, 0x0c, imm_data); /*OR AL, imm_data*/
else
codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_OR | dst_reg, imm_data); /*OR dst_reg, imm_data*/
}
static void host_x86_OR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data)
{
if (dst_reg != src_reg)
fatal("host_x86_OR16_REG_IMM - dst_reg != src_reg\n");
if (is_imm8(imm_data))
codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_OR | dst_reg, imm_data & 0xff); /*OR dst_reg, imm_data*/
else if (dst_reg == REG_EAX)
{
codegen_addbyte2(block, 0x66, 0x0d); /*OR AX, imm_data*/
codegen_addword(block, imm_data);
}
else
{
codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_OR | dst_reg); /*OR dst_reg, imm_data*/
codegen_addword(block, imm_data);
}
}
static void host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data)
{
if (dst_reg != src_reg)
fatal("host_x86_OR32_REG_IMM - dst_reg != src_reg\n");
if (is_imm8(imm_data))
{
codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_OR | dst_reg, imm_data & 0xff); /*OR dst_reg, imm_data*/
else if (dst_reg == REG_EAX)
{
codegen_addbyte(block, 0x0d); /*OR EAX, imm_data*/
codegen_addlong(block, imm_data);
}
else
{
if (dst_reg == REG_EAX)
{
codegen_addbyte(block, 0x0d); /*OR EAX, imm_data*/
codegen_addlong(block, imm_data);
}
else
{
codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_OR | dst_reg); /*OR dst_reg, imm_data*/
codegen_addlong(block, imm_data);
}
codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_OR | dst_reg); /*OR dst_reg, imm_data*/
codegen_addlong(block, imm_data);
}
}
#define MODRM_MOD_REG(rm, reg) (0xc0 | reg | (rm << 3))
static void host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data)
{
if (dst_reg != src_reg)
fatal("host_x86_SUB8_REG_IMM - dst_reg != src_reg\n");
if (dst_reg == REG_EAX)
codegen_addbyte2(block, 0x2c, imm_data); /*SUB AL, imm_data*/
else
codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_SUB | dst_reg, imm_data); /*SUB dst_reg, imm_data*/
}
static void host_x86_SUB16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data)
{
if (dst_reg != src_reg)
fatal("host_x86_SUB16_REG_IMM - dst_reg != src_reg\n");
if (is_imm8(imm_data))
codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_SUB | dst_reg, imm_data & 0xff); /*SUB dst_reg, imm_data*/
else if (dst_reg == REG_EAX)
{
codegen_addbyte2(block, 0x66, 0x2d); /*SUB AX, imm_data*/
codegen_addword(block, imm_data);
}
else
{
codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_SUB | dst_reg); /*SUB dst_reg, imm_data*/
codegen_addword(block, imm_data);
}
}
static void host_x86_SUB32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data)
{
if (dst_reg != src_reg)
fatal("host_x86_SUB32_REG_IMM - dst_reg != src_reg\n");
if (is_imm8(imm_data))
{
codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_SUB | dst_reg, imm_data & 0xff); /*SUB dst_reg, imm_data*/
else if (dst_reg == REG_EAX)
{
codegen_addbyte(block, 0x2d); /*SUB EAX, imm_data*/
codegen_addlong(block, imm_data);
}
else
{
if (dst_reg == REG_EAX)
{
codegen_addbyte(block, 0x2d); /*SUB EAX, imm_data*/
codegen_addlong(block, imm_data);
}
else
{
codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_SUB | dst_reg); /*SUB dst_reg, imm_data*/
codegen_addlong(block, imm_data);
}
codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_SUB | dst_reg); /*SUB dst_reg, imm_data*/
codegen_addlong(block, imm_data);
}
}
static void host_x86_SUB8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b)
{
if (dst_reg != src_reg_a)
fatal("host_x86_SUB8_REG_REG - dst_reg != src_reg_a\n");
codegen_addbyte2(block, 0x28, 0xc0 | dst_reg | (src_reg_b << 3)); /*SUB dst_reg, src_reg_b*/
}
static void host_x86_SUB16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b)
{
if (dst_reg != src_reg_a)
fatal("host_x86_SUB16_REG_REG - dst_reg != src_reg_a\n");
codegen_addbyte3(block, 0x66, 0x29, 0xc0 | dst_reg | (src_reg_b << 3)); /*SUB dst_reg, src_reg_b*/
}
static void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b)
{
if (dst_reg != src_reg_a)
fatal("host_x86_SUB32_REG_IMM - dst_reg != src_reg_a\n");
fatal("host_x86_SUB32_REG_REG - dst_reg != src_reg_a\n");
codegen_addbyte2(block, 0x29, 0xc0 | dst_reg | (src_reg_b << 3)); /*SUB dst_reg, src_reg_b*/
}
@ -368,6 +551,20 @@ static void host_x86_TEST32_REG(codeblock_t *block, int src_host_reg, int dst_ho
codegen_addbyte2(block, 0x85, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/
}
static void host_x86_XOR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b)
{
if (dst_reg != src_reg_a)
fatal("host_x86_XOR8_REG_REG - dst_reg != src_reg_a\n");
codegen_addbyte2(block, 0x30, 0xc0 | dst_reg | (src_reg_b << 3)); /*XOR dst_reg, src_reg_b*/
}
static void host_x86_XOR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b)
{
if (dst_reg != src_reg_a)
fatal("host_x86_XOR16_REG_REG - dst_reg != src_reg_a\n");
codegen_addbyte3(block, 0x66, 0x31, 0xc0 | dst_reg | (src_reg_b << 3)); /*XOR dst_reg, src_reg_b*/
}
static void host_x86_XOR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b)
{
if (dst_reg != src_reg_a)
@ -376,27 +573,50 @@ static void host_x86_XOR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_
codegen_addbyte2(block, 0x31, 0xc0 | dst_reg | (src_reg_b << 3)); /*XOR dst_reg, src_reg_b*/
}
static void host_x86_XOR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data)
{
if (dst_reg != src_reg)
fatal("host_x86_XOR8_REG_IMM - dst_reg != src_reg\n");
if (dst_reg == REG_EAX)
codegen_addbyte2(block, 0x34, imm_data); /*XOR AL, imm_data*/
else
codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_XOR | dst_reg, imm_data); /*XOR dst_reg, imm_data*/
}
static void host_x86_XOR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data)
{
if (dst_reg != src_reg)
fatal("host_x86_XOR16_REG_IMM - dst_reg != src_reg\n");
if (is_imm8(imm_data))
codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_XOR | dst_reg, imm_data & 0xff); /*XOR dst_reg, imm_data*/
else if (dst_reg == REG_EAX)
{
codegen_addbyte2(block, 0x66, 0x35); /*XOR AX, imm_data*/
codegen_addword(block, imm_data);
}
else
{
codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_XOR | dst_reg); /*XOR dst_reg, imm_data*/
codegen_addword(block, imm_data);
}
}
static void host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data)
{
if (dst_reg != src_reg)
fatal("host_x86_XOR32_REG_IMM - dst_reg != src_reg\n");
if (is_imm8(imm_data))
{
codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_XOR | dst_reg, imm_data & 0xff); /*XOR dst_reg, imm_data*/
else if (dst_reg == REG_EAX)
{
codegen_addbyte(block, 0x35); /*XOR EAX, imm_data*/
codegen_addlong(block, imm_data);
}
else
{
if (dst_reg == REG_EAX)
{
codegen_addbyte(block, 0x35); /*XOR EAX, imm_data*/
codegen_addlong(block, imm_data);
}
else
{
codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_XOR | dst_reg); /*XOR dst_reg, imm_data*/
codegen_addlong(block, imm_data);
}
codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_XOR | dst_reg); /*XOR dst_reg, imm_data*/
codegen_addlong(block, imm_data);
}
}
@ -406,15 +626,61 @@ static void host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg,
pclog(" %04x:%04x : %08x %08x %08x %08x\n", CS, cpu_state.pc, AX, BX, CX, DX);
}*/
#define HOST_REG_IS_L(reg) (IREG_GET_SIZE(reg) == IREG_SIZE_L)
#define HOST_REG_IS_W(reg) (IREG_GET_SIZE(reg) == IREG_SIZE_W)
#define HOST_REG_IS_B(reg) (IREG_GET_SIZE(reg) == IREG_SIZE_B && IREG_GET_REG(reg) < 4)
#define HOST_REG_IS_BH(reg) (IREG_GET_SIZE(reg) == IREG_SIZE_BH && IREG_GET_REG(reg) < 4)
#define HOST_REG_GET(reg) ((IREG_GET_SIZE(reg) == IREG_SIZE_BH) ? (IREG_GET_REG((reg) & 3) | 4) : (IREG_GET_REG(reg) & 7))
#define REG_IS_L(size) (size == IREG_SIZE_L)
#define REG_IS_W(size) (size == IREG_SIZE_W)
#define REG_IS_B(size) (size == IREG_SIZE_B || size == IREG_SIZE_BH)
#define REG_IS_BH(size) (size == IREG_SIZE_BH)
static int codegen_ADD(codeblock_t *block, uop_t *uop)
{
host_x86_ADD32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real);
if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b))
{
host_x86_ADD32_REG_REG(block, dest_reg, src_reg_a, src_reg_b);
}
else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b))
{
host_x86_ADD16_REG_REG(block, dest_reg, src_reg_a, src_reg_b);
}
else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b))
{
host_x86_ADD8_REG_REG(block, dest_reg, src_reg_a, src_reg_b);
}
else
fatal("ADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
return 0;
}
static int codegen_ADD_IMM(codeblock_t *block, uop_t *uop)
{
host_x86_ADD32_REG_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data);
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real);
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
if (REG_IS_L(dest_size) && REG_IS_L(src_size))
{
host_x86_ADD32_REG_IMM(block, dest_reg, src_reg, uop->imm_data);
}
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
{
host_x86_ADD16_REG_IMM(block, dest_reg, src_reg, uop->imm_data);
}
else if (REG_IS_B(dest_size) && REG_IS_B(src_size))
{
host_x86_ADD8_REG_IMM(block, dest_reg, src_reg, uop->imm_data);
}
else
fatal("ADD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
return 0;
}
@ -432,13 +698,47 @@ static int codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop)
static int codegen_AND(codeblock_t *block, uop_t *uop)
{
host_x86_AND32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real);
if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b))
{
host_x86_AND32_REG_REG(block, dest_reg, src_reg_a, src_reg_b);
}
else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b))
{
host_x86_AND16_REG_REG(block, dest_reg, src_reg_a, src_reg_b);
}
else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b))
{
host_x86_AND8_REG_REG(block, dest_reg, src_reg_a, src_reg_b);
}
else
fatal("AND %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
return 0;
}
static int codegen_AND_IMM(codeblock_t *block, uop_t *uop)
{
host_x86_AND32_REG_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data);
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real);
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
if (REG_IS_L(dest_size) && REG_IS_L(src_size))
{
host_x86_AND32_REG_IMM(block, dest_reg, src_reg, uop->imm_data);
}
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
{
host_x86_AND16_REG_IMM(block, dest_reg, src_reg, uop->imm_data);
}
else if (REG_IS_B(dest_size) && REG_IS_B(src_size))
{
host_x86_AND8_REG_IMM(block, dest_reg, src_reg, uop->imm_data);
}
else
fatal("AND_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
return 0;
}
@ -475,12 +775,46 @@ static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop)
static int codegen_MOV(codeblock_t *block, uop_t *uop)
{
host_x86_MOV32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real);
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real);
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
if (REG_IS_L(dest_size) && REG_IS_L(src_size))
{
host_x86_MOV32_REG_REG(block, dest_reg, src_reg);
}
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
{
host_x86_MOV16_REG_REG(block, dest_reg, src_reg);
}
else if (REG_IS_B(dest_size) && REG_IS_B(src_size))
{
host_x86_MOV8_REG_REG(block, dest_reg, src_reg);
}
else
fatal("MOV %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
return 0;
}
static int codegen_MOV_IMM(codeblock_t *block, uop_t *uop)
{
host_x86_MOV32_REG_IMM(block, uop->dest_reg_a_real, uop->imm_data);
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real);
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real);
if (REG_IS_L(dest_size))
{
host_x86_MOV32_REG_IMM(block, dest_reg, uop->imm_data);
}
else if (REG_IS_W(dest_size))
{
host_x86_MOV16_REG_IMM(block, dest_reg, uop->imm_data);
}
else if (REG_IS_B(dest_size))
{
host_x86_MOV8_REG_IMM(block, dest_reg, uop->imm_data);
}
else
fatal("MOV_IMM %02x\n", uop->dest_reg_a_real);
return 0;
}
static int codegen_MOV_PTR(codeblock_t *block, uop_t *uop)
@ -488,15 +822,66 @@ static int codegen_MOV_PTR(codeblock_t *block, uop_t *uop)
host_x86_MOV32_REG_IMM(block, uop->dest_reg_a_real, (uint32_t)uop->p);
return 0;
}
static int codegen_MOVZX(codeblock_t *block, uop_t *uop)
{
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real);
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
if (REG_IS_L(dest_size) && REG_IS_W(src_size))
{
host_x86_MOVZX_REG_32_16(block, dest_reg, src_reg);
}
else if (REG_IS_L(dest_size) && REG_IS_B(src_size))
{
host_x86_MOVZX_REG_32_8(block, dest_reg, src_reg);
}
else
fatal("MOVZX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
return 0;
}
static int codegen_OR(codeblock_t *block, uop_t *uop)
{
host_x86_OR32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real);
if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b))
{
host_x86_OR32_REG_REG(block, dest_reg, src_reg_a, src_reg_b);
}
else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b))
{
host_x86_OR16_REG_REG(block, dest_reg, src_reg_a, src_reg_b);
}
else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b))
{
host_x86_OR8_REG_REG(block, dest_reg, src_reg_a, src_reg_b);
}
else
fatal("OR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
return 0;
}
static int codegen_OR_IMM(codeblock_t *block, uop_t *uop)
{
host_x86_OR32_REG_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data);
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real);
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
if (REG_IS_L(dest_size) && REG_IS_L(src_size))
{
host_x86_OR32_REG_IMM(block, dest_reg, src_reg, uop->imm_data);
}
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
{
host_x86_OR16_REG_IMM(block, dest_reg, src_reg, uop->imm_data);
}
else if (REG_IS_B(dest_size) && REG_IS_B(src_size))
{
host_x86_OR8_REG_IMM(block, dest_reg, src_reg, uop->imm_data);
}
else
fatal("OR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
return 0;
}
@ -513,29 +898,103 @@ static int codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop)
static int codegen_SUB(codeblock_t *block, uop_t *uop)
{
if (uop->dest_reg_a_real != uop->src_reg_a_real)
host_x86_MOV32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real);
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real);
if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b))
{
if (uop->dest_reg_a_real != uop->src_reg_a_real)
host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a);
host_x86_SUB32_REG_REG(block, dest_reg, dest_reg, src_reg_b);
}
else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b))
{
if (uop->dest_reg_a_real != uop->src_reg_a_real)
host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a);
host_x86_SUB16_REG_REG(block, dest_reg, dest_reg, src_reg_b);
}
else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b))
{
if (uop->dest_reg_a_real != uop->src_reg_a_real)
host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a);
host_x86_SUB8_REG_REG(block, dest_reg, dest_reg, src_reg_b);
}
else
fatal("SUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
host_x86_SUB32_REG_REG(block, uop->dest_reg_a_real, uop->dest_reg_a_real, uop->src_reg_b_real);
return 0;
}
static int codegen_SUB_IMM(codeblock_t *block, uop_t *uop)
{
if (uop->dest_reg_a_real != uop->src_reg_a_real)
host_x86_MOV32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real);
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real);
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
if (REG_IS_L(dest_size) && REG_IS_L(src_size))
{
if (dest_reg != src_reg)
host_x86_MOV32_REG_REG(block, dest_reg, src_reg);
host_x86_SUB32_REG_IMM(block, dest_reg, dest_reg, uop->imm_data);
}
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
{
if (dest_reg != src_reg)
host_x86_MOV16_REG_REG(block, dest_reg, src_reg);
host_x86_SUB16_REG_IMM(block, dest_reg, dest_reg, uop->imm_data);
}
else if (REG_IS_B(dest_size) && REG_IS_B(src_size))
{
if (dest_reg != src_reg)
host_x86_MOV8_REG_REG(block, dest_reg, src_reg);
host_x86_SUB8_REG_IMM(block, dest_reg, dest_reg, uop->imm_data);
}
else
fatal("SUB_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
host_x86_SUB32_REG_IMM(block, uop->dest_reg_a_real, uop->dest_reg_a_real, uop->imm_data);
return 0;
}
static int codegen_XOR(codeblock_t *block, uop_t *uop)
{
host_x86_XOR32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real);
if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b))
{
host_x86_XOR32_REG_REG(block, dest_reg, src_reg_a, src_reg_b);
}
else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b))
{
host_x86_XOR16_REG_REG(block, dest_reg, src_reg_a, src_reg_b);
}
else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b))
{
host_x86_XOR8_REG_REG(block, dest_reg, src_reg_a, src_reg_b);
}
else
fatal("OR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
return 0;
}
static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop)
{
host_x86_XOR32_REG_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data);
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real);
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
if (REG_IS_L(dest_size) && REG_IS_L(src_size))
{
host_x86_XOR32_REG_IMM(block, dest_reg, src_reg, uop->imm_data);
}
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
{
host_x86_XOR16_REG_IMM(block, dest_reg, src_reg, uop->imm_data);
}
else if (REG_IS_B(dest_size) && REG_IS_B(src_size))
{
host_x86_XOR8_REG_IMM(block, dest_reg, src_reg, uop->imm_data);
}
else
fatal("XOR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
return 0;
}
@ -554,6 +1013,7 @@ const uOpFn uop_handlers[UOP_MAX] =
[UOP_MOV & UOP_MASK] = codegen_MOV,
[UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR,
[UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM,
[UOP_MOVZX & UOP_MASK] = codegen_MOVZX,
[UOP_ADD & UOP_MASK] = codegen_ADD,
[UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM,