Added code generation for :

- TEST immediate
- register versions of NOT and NEG
- fixed shift versions of SHL, SHR and SAR
- MOVZX and MOVSX
- LEA
- CMP with memory destination
- JL, JNL, JLE, JNLE, JBE, JNBE
This commit is contained in:
TomW 2015-05-30 17:08:54 +01:00
commit 9061c5d2fc
8 changed files with 683 additions and 36 deletions

View file

@ -277,3 +277,159 @@ static uint32_t ropXOR_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32
return op_pc + 4;
}
static uint32_t ropF6(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
x86seg *target_seg;
int host_reg, imm_reg;
uint8_t imm;
switch (fetchdat & 0x38)
{
case 0x00: /*TEST b,#8*/
if ((fetchdat & 0xc0) == 0xc0)
{
host_reg = LOAD_REG_B(fetchdat & 7);
imm = (fetchdat >> 8) & 0xff;
}
else
{
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
imm = fastreadb(cs + op_pc + 1);
STORE_IMM_ADDR_L((uintptr_t)&oldpc, op_old_pc);
MEM_LOAD_ADDR_EA_B(target_seg);
host_reg = 0;
}
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN8);
AND_HOST_REG_IMM(host_reg, imm);
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
RELEASE_REG(host_reg);
return op_pc + 2;
case 0x10: /*NOT b*/
if ((fetchdat & 0xc0) != 0xc0)
return 0;
host_reg = LOAD_REG_B(fetchdat & 7);
XOR_HOST_REG_IMM(host_reg, 0xff);
STORE_REG_B_RELEASE(host_reg);
return op_pc + 1;
case 0x18: /*NEG b*/
if ((fetchdat & 0xc0) != 0xc0)
return 0;
imm_reg = LOAD_REG_IMM(0);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB8);
host_reg = LOAD_REG_B(fetchdat & 7);
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, imm_reg);
SUB_HOST_REG_B(imm_reg, host_reg);
STORE_HOST_REG_ADDR((uint32_t)&flags_op2, host_reg);
STORE_REG_TARGET_B_RELEASE(imm_reg, fetchdat & 7);
STORE_HOST_REG_ADDR((uint32_t)&flags_res, imm_reg);
return op_pc + 1;
}
return 0;
}
static uint32_t ropF7_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
x86seg *target_seg;
int host_reg, imm_reg;
uint16_t imm;
switch (fetchdat & 0x38)
{
case 0x00: /*TEST w,#*/
if ((fetchdat & 0xc0) == 0xc0)
{
host_reg = LOAD_REG_W(fetchdat & 7);
imm = (fetchdat >> 8) & 0xffff;
}
else
{
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
imm = fastreadw(cs + op_pc + 1);
STORE_IMM_ADDR_L((uintptr_t)&oldpc, op_old_pc);
MEM_LOAD_ADDR_EA_W(target_seg);
host_reg = 0;
}
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN16);
AND_HOST_REG_IMM(host_reg, imm);
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
RELEASE_REG(host_reg);
return op_pc + 3;
case 0x10: /*NOT w*/
if ((fetchdat & 0xc0) != 0xc0)
return 0;
host_reg = LOAD_REG_W(fetchdat & 7);
XOR_HOST_REG_IMM(host_reg, 0xffff);
STORE_REG_W_RELEASE(host_reg);
return op_pc + 1;
case 0x18: /*NEG w*/
if ((fetchdat & 0xc0) != 0xc0)
return 0;
imm_reg = LOAD_REG_IMM(0);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB16);
host_reg = LOAD_REG_W(fetchdat & 7);
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, imm_reg);
SUB_HOST_REG_W(imm_reg, host_reg);
STORE_HOST_REG_ADDR((uint32_t)&flags_op2, host_reg);
STORE_REG_TARGET_W_RELEASE(imm_reg, fetchdat & 7);
STORE_HOST_REG_ADDR((uint32_t)&flags_res, imm_reg);
return op_pc + 1;
}
return 0;
}
static uint32_t ropF7_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
x86seg *target_seg;
int host_reg, imm_reg;
uint32_t imm;
switch (fetchdat & 0x38)
{
case 0x00: /*TEST l,#*/
if ((fetchdat & 0xc0) == 0xc0)
{
host_reg = LOAD_REG_L(fetchdat & 7);
imm = fastreadl(cs + op_pc + 1);
}
else
{
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
imm = fastreadl(cs + op_pc + 1);
STORE_IMM_ADDR_L((uintptr_t)&oldpc, op_old_pc);
MEM_LOAD_ADDR_EA_L(target_seg);
host_reg = 0;
}
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN32);
AND_HOST_REG_IMM(host_reg, imm);
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
RELEASE_REG(host_reg);
return op_pc + 5;
case 0x10: /*NOT l*/
if ((fetchdat & 0xc0) != 0xc0)
return 0;
host_reg = LOAD_REG_L(fetchdat & 7);
XOR_HOST_REG_IMM(host_reg, 0xffffffff);
STORE_REG_L_RELEASE(host_reg);
return op_pc + 1;
case 0x18: /*NEG l*/
if ((fetchdat & 0xc0) != 0xc0)
return 0;
imm_reg = LOAD_REG_IMM(0);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB32);
host_reg = LOAD_REG_L(fetchdat & 7);
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, imm_reg);
SUB_HOST_REG_L(imm_reg, host_reg);
STORE_HOST_REG_ADDR((uint32_t)&flags_op2, host_reg);
STORE_REG_TARGET_L_RELEASE(imm_reg, fetchdat & 7);
STORE_HOST_REG_ADDR((uint32_t)&flags_res, imm_reg);
return op_pc + 1;
}
return 0;
}