Add recompiled versions of ROL and ROR.

This commit is contained in:
SarahW 2019-03-30 16:10:00 +00:00
commit e8f39da459
8 changed files with 665 additions and 9 deletions

View file

@ -15,6 +15,8 @@
#define RM_OP_XOR 0x30
#define RM_OP_CMP 0x38
#define RM_OP_ROL 0x00
#define RM_OP_ROR 0x08
#define RM_OP_SHL 0x20
#define RM_OP_SHR 0x28
#define RM_OP_SAR 0x38
@ -1263,6 +1265,94 @@ void host_x86_RET(codeblock_t *block)
codegen_addbyte(block, 0xc3); /*RET*/
}
void host_x86_ROL8_CL(codeblock_t *block, int dst_reg)
{
if (dst_reg & 8)
fatal("ROL8 CL & 8\n");
codegen_alloc_bytes(block, 2);
codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_ROL | dst_reg); /*SHL dst_reg, CL*/
}
void host_x86_ROL16_CL(codeblock_t *block, int dst_reg)
{
if (dst_reg & 8)
fatal("ROL16 CL & 8\n");
codegen_alloc_bytes(block, 3);
codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_ROL | dst_reg); /*SHL dst_reg, CL*/
}
void host_x86_ROL32_CL(codeblock_t *block, int dst_reg)
{
if (dst_reg & 8)
fatal("ROL32 CL & 8\n");
codegen_alloc_bytes(block, 2);
codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_ROL | dst_reg); /*SHL dst_reg, CL*/
}
void host_x86_ROL8_IMM(codeblock_t *block, int dst_reg, int shift)
{
if (dst_reg & 8)
fatal("ROL8 imm & 8\n");
codegen_alloc_bytes(block, 3);
codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_ROL | dst_reg, shift); /*SHL dst_reg, shift*/
}
void host_x86_ROL16_IMM(codeblock_t *block, int dst_reg, int shift)
{
if (dst_reg & 8)
fatal("ROL16 imm & 8\n");
codegen_alloc_bytes(block, 4);
codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_ROL | dst_reg, shift); /*SHL dst_reg, shift*/
}
void host_x86_ROL32_IMM(codeblock_t *block, int dst_reg, int shift)
{
if (dst_reg & 8)
fatal("ROL32 imm & 8\n");
codegen_alloc_bytes(block, 3);
codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_ROL | dst_reg, shift); /*SHL dst_reg, shift*/
}
void host_x86_ROR8_CL(codeblock_t *block, int dst_reg)
{
if (dst_reg & 8)
fatal("ROR8 CL & 8\n");
codegen_alloc_bytes(block, 2);
codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_ROR | dst_reg); /*SHR dst_reg, CL*/
}
void host_x86_ROR16_CL(codeblock_t *block, int dst_reg)
{
if (dst_reg & 8)
fatal("ROR16 CL & 8\n");
codegen_alloc_bytes(block, 3);
codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_ROR | dst_reg); /*SHR dst_reg, CL*/
}
void host_x86_ROR32_CL(codeblock_t *block, int dst_reg)
{
if (dst_reg & 8)
fatal("ROR32 CL & 8\n");
codegen_alloc_bytes(block, 2);
codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_ROR | dst_reg); /*SHR dst_reg, CL*/
}
void host_x86_ROR8_IMM(codeblock_t *block, int dst_reg, int shift)
{
if (dst_reg & 8)
fatal("ROR8 imm & 8\n");
codegen_alloc_bytes(block, 3);
codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_ROR | dst_reg, shift); /*SHR dst_reg, shift*/
}
void host_x86_ROR16_IMM(codeblock_t *block, int dst_reg, int shift)
{
if (dst_reg & 8)
fatal("ROR16 imm & 8\n");
codegen_alloc_bytes(block, 4);
codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_ROR | dst_reg, shift); /*SHR dst_reg, shift*/
}
void host_x86_ROR32_IMM(codeblock_t *block, int dst_reg, int shift)
{
if (dst_reg & 8)
fatal("ROR32 im & 8\n");
codegen_alloc_bytes(block, 3);
codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_ROR | dst_reg, shift); /*SHR dst_reg, shift*/
}
void host_x86_SAR8_CL(codeblock_t *block, int dst_reg)
{
if (dst_reg & 8)

View file

@ -130,6 +130,22 @@ void host_x86_PUSH(codeblock_t *block, int src_reg);
void host_x86_RET(codeblock_t *block);
void host_x86_ROL8_IMM(codeblock_t *block, int dst_reg, int shift);
void host_x86_ROL16_IMM(codeblock_t *block, int dst_reg, int shift);
void host_x86_ROL32_IMM(codeblock_t *block, int dst_reg, int shift);
void host_x86_ROL8_CL(codeblock_t *block, int dst_reg);
void host_x86_ROL16_CL(codeblock_t *block, int dst_reg);
void host_x86_ROL32_CL(codeblock_t *block, int dst_reg);
void host_x86_ROR8_IMM(codeblock_t *block, int dst_reg, int shift);
void host_x86_ROR16_IMM(codeblock_t *block, int dst_reg, int shift);
void host_x86_ROR32_IMM(codeblock_t *block, int dst_reg, int shift);
void host_x86_ROR8_CL(codeblock_t *block, int dst_reg);
void host_x86_ROR16_CL(codeblock_t *block, int dst_reg);
void host_x86_ROR32_CL(codeblock_t *block, int dst_reg);
void host_x86_SAR8_CL(codeblock_t *block, int dst_reg);
void host_x86_SAR16_CL(codeblock_t *block, int dst_reg);
void host_x86_SAR32_CL(codeblock_t *block, int dst_reg);

View file

@ -2333,6 +2333,125 @@ static int codegen_PUNPCKLDQ(codeblock_t *block, uop_t *uop)
return 0;
}
static int codegen_ROL(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), shift_reg = HOST_REG_GET(uop->src_reg_b_real);
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg);
if (REG_IS_L(dest_size) && REG_IS_L(src_size))
{
if (uop->dest_reg_a_real != uop->src_reg_a_real)
host_x86_MOV32_REG_REG(block, dest_reg, src_reg);
host_x86_ROL32_CL(block, dest_reg);
}
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
{
if (uop->dest_reg_a_real != uop->src_reg_a_real)
host_x86_MOV16_REG_REG(block, dest_reg, src_reg);
host_x86_ROL16_CL(block, dest_reg);
}
else if (REG_IS_B(dest_size) && REG_IS_B(src_size))
{
if (uop->dest_reg_a_real != uop->src_reg_a_real)
host_x86_MOV8_REG_REG(block, dest_reg, src_reg);
host_x86_ROL8_CL(block, dest_reg);
}
#ifdef RECOMPILER_DEBUG
else
fatal("ROL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
#endif
return 0;
}
static int codegen_ROL_IMM(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_L(src_size))
{
if (uop->dest_reg_a_real != uop->src_reg_a_real)
host_x86_MOV32_REG_REG(block, dest_reg, src_reg);
host_x86_ROL32_IMM(block, dest_reg, uop->imm_data);
}
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
{
if (uop->dest_reg_a_real != uop->src_reg_a_real)
host_x86_MOV16_REG_REG(block, dest_reg, src_reg);
host_x86_ROL16_IMM(block, dest_reg, uop->imm_data);
}
else if (REG_IS_B(dest_size) && REG_IS_B(src_size))
{
if (uop->dest_reg_a_real != uop->src_reg_a_real)
host_x86_MOV8_REG_REG(block, dest_reg, src_reg);
host_x86_ROL8_IMM(block, dest_reg, uop->imm_data);
}
#ifdef RECOMPILER_DEBUG
else
fatal("ROL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
#endif
return 0;
}
static int codegen_ROR(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), shift_reg = HOST_REG_GET(uop->src_reg_b_real);
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg);
if (REG_IS_L(dest_size) && REG_IS_L(src_size))
{
if (uop->dest_reg_a_real != uop->src_reg_a_real)
host_x86_MOV32_REG_REG(block, dest_reg, src_reg);
host_x86_ROR32_CL(block, dest_reg);
}
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
{
if (uop->dest_reg_a_real != uop->src_reg_a_real)
host_x86_MOV16_REG_REG(block, dest_reg, src_reg);
host_x86_ROR16_CL(block, dest_reg);
}
else if (REG_IS_B(dest_size) && REG_IS_B(src_size))
{
if (uop->dest_reg_a_real != uop->src_reg_a_real)
host_x86_MOV8_REG_REG(block, dest_reg, src_reg);
host_x86_ROR8_CL(block, dest_reg);
}
#ifdef RECOMPILER_DEBUG
else
fatal("ROR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
#endif
return 0;
}
static int codegen_ROR_IMM(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_L(src_size))
{
if (uop->dest_reg_a_real != uop->src_reg_a_real)
host_x86_MOV32_REG_REG(block, dest_reg, src_reg);
host_x86_ROR32_IMM(block, dest_reg, uop->imm_data);
}
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
{
if (uop->dest_reg_a_real != uop->src_reg_a_real)
host_x86_MOV16_REG_REG(block, dest_reg, src_reg);
host_x86_ROR16_IMM(block, dest_reg, uop->imm_data);
}
else if (REG_IS_B(dest_size) && REG_IS_B(src_size))
{
if (uop->dest_reg_a_real != uop->src_reg_a_real)
host_x86_MOV8_REG_REG(block, dest_reg, src_reg);
host_x86_ROR8_IMM(block, dest_reg, uop->imm_data);
}
#ifdef RECOMPILER_DEBUG
else
fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
#endif
return 0;
}
static int codegen_SAR(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), shift_reg = HOST_REG_GET(uop->src_reg_b_real);
@ -2758,6 +2877,10 @@ const uOpFn uop_handlers[UOP_MAX] =
[UOP_SHL_IMM & UOP_MASK] = codegen_SHL_IMM,
[UOP_SHR & UOP_MASK] = codegen_SHR,
[UOP_SHR_IMM & UOP_MASK] = codegen_SHR_IMM,
[UOP_ROL & UOP_MASK] = codegen_ROL,
[UOP_ROL_IMM & UOP_MASK] = codegen_ROL_IMM,
[UOP_ROR & UOP_MASK] = codegen_ROR,
[UOP_ROR_IMM & UOP_MASK] = codegen_ROR_IMM,
[UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ,

View file

@ -15,6 +15,8 @@
#define RM_OP_XOR 0x30
#define RM_OP_CMP 0x38
#define RM_OP_ROL 0x00
#define RM_OP_ROR 0x08
#define RM_OP_SHL 0x20
#define RM_OP_SHR 0x28
#define RM_OP_SAR 0x38
@ -953,6 +955,70 @@ void host_x86_RET(codeblock_t *block)
codegen_addbyte(block, 0xc3); /*RET*/
}
void host_x86_ROL8_CL(codeblock_t *block, int dst_reg)
{
codegen_alloc_bytes(block, 2);
codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_ROL | dst_reg); /*SHL dst_reg, CL*/
}
void host_x86_ROL16_CL(codeblock_t *block, int dst_reg)
{
codegen_alloc_bytes(block, 3);
codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_ROL | dst_reg); /*SHL dst_reg, CL*/
}
void host_x86_ROL32_CL(codeblock_t *block, int dst_reg)
{
codegen_alloc_bytes(block, 2);
codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_ROL | dst_reg); /*SHL dst_reg, CL*/
}
void host_x86_ROL8_IMM(codeblock_t *block, int dst_reg, int shift)
{
codegen_alloc_bytes(block, 3);
codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_ROL | dst_reg, shift); /*SHL dst_reg, shift*/
}
void host_x86_ROL16_IMM(codeblock_t *block, int dst_reg, int shift)
{
codegen_alloc_bytes(block, 4);
codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_ROL | dst_reg, shift); /*SHL dst_reg, shift*/
}
void host_x86_ROL32_IMM(codeblock_t *block, int dst_reg, int shift)
{
codegen_alloc_bytes(block, 3);
codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_ROL | dst_reg, shift); /*SHL dst_reg, shift*/
}
void host_x86_ROR8_CL(codeblock_t *block, int dst_reg)
{
codegen_alloc_bytes(block, 2);
codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_ROR | dst_reg); /*SHR dst_reg, CL*/
}
void host_x86_ROR16_CL(codeblock_t *block, int dst_reg)
{
codegen_alloc_bytes(block, 3);
codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_ROR | dst_reg); /*SHR dst_reg, CL*/
}
void host_x86_ROR32_CL(codeblock_t *block, int dst_reg)
{
codegen_alloc_bytes(block, 2);
codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_ROR | dst_reg); /*SHR dst_reg, CL*/
}
void host_x86_ROR8_IMM(codeblock_t *block, int dst_reg, int shift)
{
codegen_alloc_bytes(block, 3);
codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_ROR | dst_reg, shift); /*SHR dst_reg, shift*/
}
void host_x86_ROR16_IMM(codeblock_t *block, int dst_reg, int shift)
{
codegen_alloc_bytes(block, 4);
codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_ROR | dst_reg, shift); /*SHR dst_reg, shift*/
}
void host_x86_ROR32_IMM(codeblock_t *block, int dst_reg, int shift)
{
codegen_alloc_bytes(block, 3);
codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_ROR | dst_reg, shift); /*SHR dst_reg, shift*/
}
#define MODRM_MOD_REG(rm, reg) (0xc0 | reg | (rm << 3))
void host_x86_SAR8_CL(codeblock_t *block, int dst_reg)

View file

@ -129,6 +129,22 @@ void host_x86_PUSH(codeblock_t *block, int src_reg);
void host_x86_RET(codeblock_t *block);
void host_x86_ROL8_IMM(codeblock_t *block, int dst_reg, int shift);
void host_x86_ROL16_IMM(codeblock_t *block, int dst_reg, int shift);
void host_x86_ROL32_IMM(codeblock_t *block, int dst_reg, int shift);
void host_x86_ROL8_CL(codeblock_t *block, int dst_reg);
void host_x86_ROL16_CL(codeblock_t *block, int dst_reg);
void host_x86_ROL32_CL(codeblock_t *block, int dst_reg);
void host_x86_ROR8_IMM(codeblock_t *block, int dst_reg, int shift);
void host_x86_ROR16_IMM(codeblock_t *block, int dst_reg, int shift);
void host_x86_ROR32_IMM(codeblock_t *block, int dst_reg, int shift);
void host_x86_ROR8_CL(codeblock_t *block, int dst_reg);
void host_x86_ROR16_CL(codeblock_t *block, int dst_reg);
void host_x86_ROR32_CL(codeblock_t *block, int dst_reg);
void host_x86_SAR8_CL(codeblock_t *block, int dst_reg);
void host_x86_SAR16_CL(codeblock_t *block, int dst_reg);
void host_x86_SAR32_CL(codeblock_t *block, int dst_reg);

View file

@ -2329,6 +2329,125 @@ static int codegen_PUNPCKLDQ(codeblock_t *block, uop_t *uop)
return 0;
}
static int codegen_ROL(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), shift_reg = HOST_REG_GET(uop->src_reg_b_real);
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg);
if (REG_IS_L(dest_size) && REG_IS_L(src_size))
{
if (uop->dest_reg_a_real != uop->src_reg_a_real)
host_x86_MOV32_REG_REG(block, dest_reg, src_reg);
host_x86_ROL32_CL(block, dest_reg);
}
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
{
if (uop->dest_reg_a_real != uop->src_reg_a_real)
host_x86_MOV16_REG_REG(block, dest_reg, src_reg);
host_x86_ROL16_CL(block, dest_reg);
}
else if (REG_IS_B(dest_size) && REG_IS_B(src_size))
{
if (uop->dest_reg_a_real != uop->src_reg_a_real)
host_x86_MOV8_REG_REG(block, dest_reg, src_reg);
host_x86_ROL8_CL(block, dest_reg);
}
#ifdef RECOMPILER_DEBUG
else
fatal("ROL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
#endif
return 0;
}
static int codegen_ROL_IMM(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_L(src_size))
{
if (uop->dest_reg_a_real != uop->src_reg_a_real)
host_x86_MOV32_REG_REG(block, dest_reg, src_reg);
host_x86_ROL32_IMM(block, dest_reg, uop->imm_data);
}
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
{
if (uop->dest_reg_a_real != uop->src_reg_a_real)
host_x86_MOV16_REG_REG(block, dest_reg, src_reg);
host_x86_ROL16_IMM(block, dest_reg, uop->imm_data);
}
else if (REG_IS_B(dest_size) && REG_IS_B(src_size))
{
if (uop->dest_reg_a_real != uop->src_reg_a_real)
host_x86_MOV8_REG_REG(block, dest_reg, src_reg);
host_x86_ROL8_IMM(block, dest_reg, uop->imm_data);
}
#ifdef RECOMPILER_DEBUG
else
fatal("ROL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
#endif
return 0;
}
static int codegen_ROR(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), shift_reg = HOST_REG_GET(uop->src_reg_b_real);
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg);
if (REG_IS_L(dest_size) && REG_IS_L(src_size))
{
if (uop->dest_reg_a_real != uop->src_reg_a_real)
host_x86_MOV32_REG_REG(block, dest_reg, src_reg);
host_x86_ROR32_CL(block, dest_reg);
}
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
{
if (uop->dest_reg_a_real != uop->src_reg_a_real)
host_x86_MOV16_REG_REG(block, dest_reg, src_reg);
host_x86_ROR16_CL(block, dest_reg);
}
else if (REG_IS_B(dest_size) && REG_IS_B(src_size))
{
if (uop->dest_reg_a_real != uop->src_reg_a_real)
host_x86_MOV8_REG_REG(block, dest_reg, src_reg);
host_x86_ROR8_CL(block, dest_reg);
}
#ifdef RECOMPILER_DEBUG
else
fatal("ROR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
#endif
return 0;
}
static int codegen_ROR_IMM(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_L(src_size))
{
if (uop->dest_reg_a_real != uop->src_reg_a_real)
host_x86_MOV32_REG_REG(block, dest_reg, src_reg);
host_x86_ROR32_IMM(block, dest_reg, uop->imm_data);
}
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
{
if (uop->dest_reg_a_real != uop->src_reg_a_real)
host_x86_MOV16_REG_REG(block, dest_reg, src_reg);
host_x86_ROR16_IMM(block, dest_reg, uop->imm_data);
}
else if (REG_IS_B(dest_size) && REG_IS_B(src_size))
{
if (uop->dest_reg_a_real != uop->src_reg_a_real)
host_x86_MOV8_REG_REG(block, dest_reg, src_reg);
host_x86_ROR8_IMM(block, dest_reg, uop->imm_data);
}
#ifdef RECOMPILER_DEBUG
else
fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
#endif
return 0;
}
static int codegen_SAR(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), shift_reg = HOST_REG_GET(uop->src_reg_b_real);
@ -2757,6 +2876,10 @@ const uOpFn uop_handlers[UOP_MAX] =
[UOP_SHL_IMM & UOP_MASK] = codegen_SHL_IMM,
[UOP_SHR & UOP_MASK] = codegen_SHR,
[UOP_SHR_IMM & UOP_MASK] = codegen_SHR_IMM,
[UOP_ROL & UOP_MASK] = codegen_ROL,
[UOP_ROL_IMM & UOP_MASK] = codegen_ROL_IMM,
[UOP_ROR & UOP_MASK] = codegen_ROR,
[UOP_ROR_IMM & UOP_MASK] = codegen_ROR_IMM,
[UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ,

View file

@ -148,6 +148,14 @@
#define UOP_SHR (UOP_TYPE_PARAMS_REGS | 0x54)
/*UOP_SHR_IMM - dest_reg = src_reg_a >> immediate*/
#define UOP_SHR_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x55)
/*UOP_ROL - dest_reg = src_reg_a rotate<< src_reg_b*/
#define UOP_ROL (UOP_TYPE_PARAMS_REGS | 0x56)
/*UOP_ROL_IMM - dest_reg = src_reg_a rotate<< immediate*/
#define UOP_ROL_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x57)
/*UOP_ROR - dest_reg = src_reg_a rotate>> src_reg_b*/
#define UOP_ROR (UOP_TYPE_PARAMS_REGS | 0x58)
/*UOP_ROR_IMM - dest_reg = src_reg_a rotate>> immediate*/
#define UOP_ROR_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x59)
/*UOP_CMP_IMM_JZ_DEST - if (src_reg_a == imm_data) then jump to ptr*/
#define UOP_CMP_IMM_JZ_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x60 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP)
@ -616,6 +624,10 @@ static inline void uop_gen_reg_src2_pointer(uint32_t uop_type, ir_data_t *ir, in
#define uop_SHL_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_SHL_IMM, ir, dst_reg, src_reg, imm)
#define uop_SHR(ir, dst_reg, src_reg, shift_reg) uop_gen_reg_dst_src2(UOP_SHR, ir, dst_reg, src_reg, shift_reg)
#define uop_SHR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_SHR_IMM, ir, dst_reg, src_reg, imm)
#define uop_ROL(ir, dst_reg, src_reg, shift_reg) uop_gen_reg_dst_src2(UOP_ROL, ir, dst_reg, src_reg, shift_reg)
#define uop_ROL_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_ROL_IMM, ir, dst_reg, src_reg, imm)
#define uop_ROR(ir, dst_reg, src_reg, shift_reg) uop_gen_reg_dst_src2(UOP_ROR, ir, dst_reg, src_reg, shift_reg)
#define uop_ROR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_ROR_IMM, ir, dst_reg, src_reg, imm)
#define uop_CALL_FUNC(ir, p) uop_gen_pointer(UOP_CALL_FUNC, ir, p)
#define uop_CALL_FUNC_RESULT(ir, dst_reg, p) uop_gen_reg_dst_pointer(UOP_CALL_FUNC_RESULT, ir, dst_reg, p)

View file

@ -18,6 +18,20 @@ static uint32_t shift_common_8(ir_data_t *ir, uint32_t fetchdat, uint32_t op_pc,
switch (fetchdat & 0x38)
{
case 0x00: /*ROL*/
uop_CALL_FUNC(ir, flags_rebuild);
uop_ROL_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), count);
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL8);
uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg));
break;
case 0x08: /*ROR*/
uop_CALL_FUNC(ir, flags_rebuild);
uop_ROR_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), count);
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR8);
uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg));
break;
case 0x20: case 0x30: /*SHL*/
uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg));
uop_SHL_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), count);
@ -50,6 +64,22 @@ static uint32_t shift_common_8(ir_data_t *ir, uint32_t fetchdat, uint32_t op_pc,
{
switch (fetchdat & 0x38)
{
case 0x00: /*ROL*/
uop_CALL_FUNC(ir, flags_rebuild);
uop_ROL_IMM(ir, IREG_temp0_B, IREG_temp0_B, count);
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B);
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL8);
uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B);
break;
case 0x08: /*ROR*/
uop_CALL_FUNC(ir, flags_rebuild);
uop_ROR_IMM(ir, IREG_temp0_B, IREG_temp0_B, count);
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B);
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR8);
uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B);
break;
case 0x20: case 0x30: /*SHL*/
uop_SHL_IMM(ir, IREG_temp1_B, IREG_temp0_B, count);
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B);
@ -94,6 +124,20 @@ static uint32_t shift_common_16(ir_data_t *ir, uint32_t fetchdat, uint32_t op_pc
switch (fetchdat & 0x38)
{
case 0x00: /*ROL*/
uop_CALL_FUNC(ir, flags_rebuild);
uop_ROL_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), count);
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL16);
uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg));
break;
case 0x08: /*ROR*/
uop_CALL_FUNC(ir, flags_rebuild);
uop_ROR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), count);
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR16);
uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg));
break;
case 0x20: case 0x30: /*SHL*/
uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg));
uop_SHL_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), count);
@ -126,6 +170,22 @@ static uint32_t shift_common_16(ir_data_t *ir, uint32_t fetchdat, uint32_t op_pc
{
switch (fetchdat & 0x38)
{
case 0x00: /*ROL*/
uop_CALL_FUNC(ir, flags_rebuild);
uop_ROL_IMM(ir, IREG_temp0_W, IREG_temp0_W, count);
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W);
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL16);
uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W);
break;
case 0x08: /*ROR*/
uop_CALL_FUNC(ir, flags_rebuild);
uop_ROR_IMM(ir, IREG_temp0_W, IREG_temp0_W, count);
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W);
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR16);
uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W);
break;
case 0x20: case 0x30: /*SHL*/
uop_SHL_IMM(ir, IREG_temp1_W, IREG_temp0_W, count);
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W);
@ -169,6 +229,20 @@ static uint32_t shift_common_32(ir_data_t *ir, uint32_t fetchdat, uint32_t op_pc
switch (fetchdat & 0x38)
{
case 0x00: /*ROL*/
uop_CALL_FUNC(ir, flags_rebuild);
uop_ROL_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), count);
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL32);
uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg));
break;
case 0x08: /*ROR*/
uop_CALL_FUNC(ir, flags_rebuild);
uop_ROR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), count);
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR32);
uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg));
break;
case 0x20: case 0x30: /*SHL*/
uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg));
uop_SHL_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), count);
@ -201,6 +275,22 @@ static uint32_t shift_common_32(ir_data_t *ir, uint32_t fetchdat, uint32_t op_pc
{
switch (fetchdat & 0x38)
{
case 0x00: /*ROL*/
uop_CALL_FUNC(ir, flags_rebuild);
uop_ROL_IMM(ir, IREG_temp0, IREG_temp0, count);
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0);
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL32);
uop_MOV(ir, IREG_flags_res, IREG_temp0);
break;
case 0x08: /*ROR*/
uop_CALL_FUNC(ir, flags_rebuild);
uop_ROR_IMM(ir, IREG_temp0, IREG_temp0, count);
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0);
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR32);
uop_MOV(ir, IREG_flags_res, IREG_temp0);
break;
case 0x20: case 0x30: /*SHL*/
uop_SHL_IMM(ir, IREG_temp1, IREG_temp0, count);
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1);
@ -245,6 +335,20 @@ static uint32_t shift_common_variable_32(ir_data_t *ir, uint32_t fetchdat, uint3
switch (fetchdat & 0x38)
{
case 0x00: /*ROL*/
uop_CALL_FUNC(ir, flags_rebuild);
uop_ROL(ir, IREG_32(dest_reg), IREG_32(dest_reg), count_reg);
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL32);
uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg));
break;
case 0x08: /*ROR*/
uop_CALL_FUNC(ir, flags_rebuild);
uop_ROR(ir, IREG_32(dest_reg), IREG_32(dest_reg), count_reg);
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR32);
uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg));
break;
case 0x20: case 0x30: /*SHL*/
uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg));
uop_SHL(ir, IREG_32(dest_reg), IREG_32(dest_reg), count_reg);
@ -277,6 +381,22 @@ static uint32_t shift_common_variable_32(ir_data_t *ir, uint32_t fetchdat, uint3
{
switch (fetchdat & 0x38)
{
case 0x00: /*ROL*/
uop_CALL_FUNC(ir, flags_rebuild);
uop_ROL(ir, IREG_temp0, IREG_temp0, count_reg);
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0);
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL32);
uop_MOV(ir, IREG_flags_res, IREG_temp0);
break;
case 0x08: /*ROR*/
uop_CALL_FUNC(ir, flags_rebuild);
uop_ROR(ir, IREG_temp0, IREG_temp0, count_reg);
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0);
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR32);
uop_MOV(ir, IREG_flags_res, IREG_temp0);
break;
case 0x20: case 0x30: /*SHL*/
uop_SHL(ir, IREG_temp1, IREG_temp0, count_reg);
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1);
@ -318,7 +438,7 @@ uint32_t ropC0(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetch
x86seg *target_seg = NULL;
uint8_t imm;
if (!(fetchdat & 0x20)) /*ROL/ROR/RCL/RCR*/
if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/
return 0;
codegen_mark_code_present(block, cs+op_pc, 1);
@ -341,7 +461,7 @@ uint32_t ropC1_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet
x86seg *target_seg = NULL;
uint8_t imm;
if (!(fetchdat & 0x20)) /*ROL/ROR/RCL/RCR*/
if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/
return 0;
codegen_mark_code_present(block, cs+op_pc, 1);
@ -363,7 +483,7 @@ uint32_t ropC1_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet
{
x86seg *target_seg = NULL;
if (!(fetchdat & 0x20)) /*ROL/ROR/RCL/RCR*/
if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/
return 0;
codegen_mark_code_present(block, cs+op_pc, 1);
@ -398,7 +518,7 @@ uint32_t ropD0(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetch
{
x86seg *target_seg = NULL;
if (!(fetchdat & 0x20)) /*ROL/ROR/RCL/RCR*/
if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/
return 0;
codegen_mark_code_present(block, cs+op_pc, 1);
@ -416,7 +536,7 @@ uint32_t ropD1_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet
{
x86seg *target_seg = NULL;
if (!(fetchdat & 0x20)) /*ROL/ROR/RCL/RCR*/
if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/
return 0;
codegen_mark_code_present(block, cs+op_pc, 1);
@ -434,7 +554,7 @@ uint32_t ropD1_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet
{
x86seg *target_seg = NULL;
if (!(fetchdat & 0x20)) /*ROL/ROR/RCL/RCR*/
if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/
return 0;
codegen_mark_code_present(block, cs+op_pc, 1);
@ -451,7 +571,7 @@ uint32_t ropD1_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet
uint32_t ropD2(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
{
if (!(fetchdat & 0x20)) /*ROL/ROR/RCL/RCR*/
if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/
return 0;
if (!(CL & 0x1f) || !block->ins)
@ -467,6 +587,20 @@ uint32_t ropD2(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetch
switch (fetchdat & 0x38)
{
case 0x00: /*ROL*/
uop_CALL_FUNC(ir, flags_rebuild);
uop_ROL(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp2);
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL8);
uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg));
break;
case 0x08: /*ROR*/
uop_CALL_FUNC(ir, flags_rebuild);
uop_ROR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp2);
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR8);
uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg));
break;
case 0x20: case 0x30: /*SHL*/
uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg));
uop_SHL(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp2);
@ -506,6 +640,22 @@ uint32_t ropD2(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetch
switch (fetchdat & 0x38)
{
case 0x00: /*ROL*/
uop_CALL_FUNC(ir, flags_rebuild);
uop_ROL(ir, IREG_temp0_B, IREG_temp0_B, IREG_temp2);
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B);
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL8);
uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B);
break;
case 0x08: /*ROR*/
uop_CALL_FUNC(ir, flags_rebuild);
uop_ROR(ir, IREG_temp0_B, IREG_temp0_B, IREG_temp2);
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B);
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR8);
uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B);
break;
case 0x20: case 0x30: /*SHL*/
uop_SHL(ir, IREG_temp1_B, IREG_temp0_B, IREG_temp2);
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B);
@ -543,7 +693,7 @@ uint32_t ropD2(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetch
}
uint32_t ropD3_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
{
if (!(fetchdat & 0x20)) /*ROL/ROR/RCL/RCR*/
if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/
return 0;
if (!(CL & 0x1f) || !block->ins)
@ -559,6 +709,20 @@ uint32_t ropD3_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet
switch (fetchdat & 0x38)
{
case 0x00: /*ROL*/
uop_CALL_FUNC(ir, flags_rebuild);
uop_ROL(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp2);
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL16);
uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg));
break;
case 0x08: /*ROR*/
uop_CALL_FUNC(ir, flags_rebuild);
uop_ROR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp2);
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR16);
uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg));
break;
case 0x20: case 0x30: /*SHL*/
uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg));
uop_SHL(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp2);
@ -598,6 +762,22 @@ uint32_t ropD3_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet
switch (fetchdat & 0x38)
{
case 0x00: /*ROL*/
uop_CALL_FUNC(ir, flags_rebuild);
uop_ROL(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp2);
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W);
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL16);
uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W);
break;
case 0x08: /*ROR*/
uop_CALL_FUNC(ir, flags_rebuild);
uop_ROR(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp2);
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W);
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR16);
uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W);
break;
case 0x20: case 0x30: /*SHL*/
uop_SHL(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2);
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W);
@ -635,7 +815,7 @@ uint32_t ropD3_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet
}
uint32_t ropD3_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
{
if (!(fetchdat & 0x20)) /*ROL/ROR/RCL/RCR*/
if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/
return 0;
if (!(CL & 0x1f) || !block->ins)
@ -651,6 +831,20 @@ uint32_t ropD3_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet
switch (fetchdat & 0x38)
{
case 0x00: /*ROL*/
uop_CALL_FUNC(ir, flags_rebuild);
uop_ROL(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp2);
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL32);
uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg));
break;
case 0x08: /*ROR*/
uop_CALL_FUNC(ir, flags_rebuild);
uop_ROR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp2);
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR32);
uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg));
break;
case 0x20: case 0x30: /*SHL*/
uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg));
uop_SHL(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp2);
@ -690,6 +884,22 @@ uint32_t ropD3_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet
switch (fetchdat & 0x38)
{
case 0x00: /*ROL*/
uop_CALL_FUNC(ir, flags_rebuild);
uop_ROL(ir, IREG_temp0, IREG_temp0, IREG_temp2);
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0);
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL32);
uop_MOV(ir, IREG_flags_res, IREG_temp0);
break;
case 0x08: /*ROR*/
uop_CALL_FUNC(ir, flags_rebuild);
uop_ROR(ir, IREG_temp0, IREG_temp0, IREG_temp2);
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0);
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR32);
uop_MOV(ir, IREG_flags_res, IREG_temp0);
break;
case 0x20: case 0x30: /*SHL*/
uop_SHL(ir, IREG_temp1, IREG_temp0, IREG_temp2);
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1);