Added recompiled versions of immediate->reg and reg->reg versions of MOV, ADD, SUB, CMP, AND, OR and XOR.
This commit is contained in:
parent
67804322b6
commit
fc27be592c
17 changed files with 1150 additions and 52 deletions
|
|
@ -11,6 +11,12 @@
|
|||
#define STACK_ARG2 (8)
|
||||
#define STACK_ARG3 (12)
|
||||
|
||||
#define RM_OP_ADD 0x00
|
||||
#define RM_OP_OR 0x08
|
||||
#define RM_OP_AND 0x20
|
||||
#define RM_OP_SUB 0x28
|
||||
#define RM_OP_XOR 0x30
|
||||
|
||||
static inline void codegen_addbyte(codeblock_t *block, uint8_t val)
|
||||
{
|
||||
block->data[block_pos++] = val;
|
||||
|
|
@ -118,7 +124,7 @@ static void host_x86_ADD32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg,
|
|||
|
||||
if (is_imm8(imm_data))
|
||||
{
|
||||
codegen_addbyte3(block, 0x83, 0xc0 | (dst_reg & 7), imm_data & 0xff); /*ADD dst_reg, imm_data*/
|
||||
codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_ADD | (dst_reg & 7), imm_data & 0xff); /*ADD dst_reg, imm_data*/
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -129,11 +135,18 @@ static void host_x86_ADD32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg,
|
|||
}
|
||||
else
|
||||
{
|
||||
codegen_addbyte2(block, 0x81, 0xc0 | (dst_reg & 7)); /*ADD dst_reg, imm_data*/
|
||||
codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_ADD | (dst_reg & 7)); /*ADD dst_reg, imm_data*/
|
||||
codegen_addlong(block, imm_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
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 || (dst_reg & 8) || (src_reg_b & 8))
|
||||
fatal("host_x86_ADD32_REG_IMM - dst_reg != src_reg_a\n");
|
||||
|
||||
codegen_addbyte2(block, 0x01, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*ADD dst_reg, src_reg_b*/
|
||||
}
|
||||
|
||||
static void host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data)
|
||||
{
|
||||
|
|
@ -142,7 +155,7 @@ static void host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg,
|
|||
|
||||
if (is_imm8(imm_data))
|
||||
{
|
||||
codegen_addbyte3(block, 0x83, 0xe0 | (dst_reg & 7), imm_data & 0xff); /*AND dst_reg, imm_data*/
|
||||
codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_AND | (dst_reg & 7), imm_data & 0xff); /*AND dst_reg, imm_data*/
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -153,18 +166,17 @@ static void host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg,
|
|||
}
|
||||
else
|
||||
{
|
||||
codegen_addbyte2(block, 0x81, 0xe0 | (dst_reg & 7)); /*AND dst_reg, imm_data*/
|
||||
codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_AND | (dst_reg & 7)); /*AND dst_reg, imm_data*/
|
||||
codegen_addlong(block, imm_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int 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 || (dst_reg & 8) || (src_reg_b & 8))
|
||||
fatal("host_x86_ADD32_REG_IMM - dst_reg != src_reg_a\n");
|
||||
fatal("host_x86_AND32_REG_IMM - dst_reg != src_reg_a\n");
|
||||
|
||||
codegen_addbyte2(block, 0x01, 0xc0 | (dst_reg & 7) | (src_reg_b & 7)); /*ADD dst_reg, src_reg_b*/
|
||||
codegen_addbyte2(block, 0x21, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*AND dst_reg, src_reg_b*/
|
||||
}
|
||||
|
||||
static void host_x86_CALL(codeblock_t *block, void *p)
|
||||
|
|
@ -348,6 +360,68 @@ static void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_
|
|||
}
|
||||
}
|
||||
|
||||
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 || (dst_reg & 8) || (src_reg & 8))
|
||||
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 & 7), 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
|
||||
{
|
||||
codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_OR | (dst_reg & 7)); /*OR dst_reg, imm_data*/
|
||||
codegen_addlong(block, imm_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
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 || (dst_reg & 8) || (src_reg_b & 8))
|
||||
fatal("host_x86_OR32_REG_IMM - dst_reg != src_reg_a\n");
|
||||
|
||||
codegen_addbyte2(block, 0x09, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*OR dst_reg, src_reg_b*/
|
||||
}
|
||||
|
||||
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 || (dst_reg & 8) || (src_reg & 8))
|
||||
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 & 7), 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
|
||||
{
|
||||
codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_SUB | (dst_reg & 7)); /*SUB dst_reg, imm_data*/
|
||||
codegen_addlong(block, imm_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
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 || (dst_reg & 8) || (src_reg_b & 8))
|
||||
fatal("host_x86_ADD32_REG_IMM - dst_reg != src_reg_a\n");
|
||||
|
||||
codegen_addbyte2(block, 0x29, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*SUB dst_reg, src_reg_b*/
|
||||
}
|
||||
|
||||
#define MODRM_MOD_REG(rm, reg) (0xc0 | reg | (rm << 3))
|
||||
|
||||
static void host_x86_TEST32_REG(codeblock_t *block, int src_reg, int dst_reg)
|
||||
|
|
@ -357,6 +431,37 @@ static void host_x86_TEST32_REG(codeblock_t *block, int src_reg, int dst_reg)
|
|||
codegen_addbyte2(block, 0x85, MODRM_MOD_REG(dst_reg, src_reg)); /*TEST dst_host_reg, src_host_reg*/
|
||||
}
|
||||
|
||||
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 || (dst_reg & 8) || (src_reg & 8))
|
||||
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 & 7), 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
|
||||
{
|
||||
codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_XOR | (dst_reg & 7)); /*XOR dst_reg, imm_data*/
|
||||
codegen_addlong(block, imm_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
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 || (dst_reg & 8) || (src_reg_b & 8))
|
||||
fatal("host_x86_XOR32_REG_IMM - dst_reg != src_reg_a\n");
|
||||
|
||||
codegen_addbyte2(block, 0x31, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*XOR dst_reg, src_reg_b*/
|
||||
}
|
||||
|
||||
|
||||
static int codegen_ADD(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
|
|
@ -382,6 +487,12 @@ static int codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop)
|
|||
return 0;
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
|
|
@ -442,6 +553,17 @@ static int codegen_MOV_PTR(codeblock_t *block, uop_t *uop)
|
|||
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);
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
if (((uintptr_t)uop->p) >> 32)
|
||||
|
|
@ -457,6 +579,34 @@ static int codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop)
|
|||
return 0;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const uOpFn uop_handlers[UOP_MAX] =
|
||||
{
|
||||
[UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC,
|
||||
|
|
@ -476,7 +626,14 @@ const uOpFn uop_handlers[UOP_MAX] =
|
|||
[UOP_ADD & UOP_MASK] = codegen_ADD,
|
||||
[UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM,
|
||||
[UOP_ADD_LSHIFT & UOP_MASK] = codegen_ADD_LSHIFT,
|
||||
[UOP_AND_IMM & UOP_MASK] = codegen_AND_IMM
|
||||
[UOP_AND & UOP_MASK] = codegen_AND,
|
||||
[UOP_AND_IMM & UOP_MASK] = codegen_AND_IMM,
|
||||
[UOP_OR & UOP_MASK] = codegen_OR,
|
||||
[UOP_OR_IMM & UOP_MASK] = codegen_OR_IMM,
|
||||
[UOP_SUB & UOP_MASK] = codegen_SUB,
|
||||
[UOP_SUB_IMM & UOP_MASK] = codegen_SUB_IMM,
|
||||
[UOP_XOR & UOP_MASK] = codegen_XOR,
|
||||
[UOP_XOR_IMM & UOP_MASK] = codegen_XOR_IMM
|
||||
};
|
||||
|
||||
void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p)
|
||||
|
|
|
|||
Loading…
Reference in a new issue