Minor optimisation to x86 recompiler versions of JL/JNL/JLE/JNLE/JBE/JNBE.
This commit is contained in:
parent
7bc0f3c54e
commit
a2bef57491
1 changed files with 197 additions and 74 deletions
|
|
@ -1487,6 +1487,45 @@ static void TEST_NONZERO_JUMP_L(int host_reg, uint32_t new_pc, int taken_cycles)
|
||||||
|
|
||||||
static int BRANCH_COND_BE(int pc_offset, uint32_t op_pc, uint32_t offset, int not)
|
static int BRANCH_COND_BE(int pc_offset, uint32_t op_pc, uint32_t offset, int not)
|
||||||
{
|
{
|
||||||
|
switch (codegen_flags_changed ? flags_op : FLAGS_UNKNOWN)
|
||||||
|
{
|
||||||
|
case FLAGS_SUB8:
|
||||||
|
addbyte(0xa0); /*MOV AL, flags_op1*/
|
||||||
|
addlong((uint32_t)&flags_op1);
|
||||||
|
addbyte(0x3a); /*CMP AL, flags_op2*/
|
||||||
|
addbyte(0x05);
|
||||||
|
addlong((uint32_t)&flags_op2);
|
||||||
|
if (not)
|
||||||
|
addbyte(0x76); /*JBE*/
|
||||||
|
else
|
||||||
|
addbyte(0x77); /*JNBE*/
|
||||||
|
break;
|
||||||
|
case FLAGS_SUB16:
|
||||||
|
addbyte(0x66); /*MOV AX, flags_op1*/
|
||||||
|
addbyte(0xa1);
|
||||||
|
addlong((uint32_t)&flags_op1);
|
||||||
|
addbyte(0x66); /*CMP AX, flags_op2*/
|
||||||
|
addbyte(0x3b);
|
||||||
|
addbyte(0x05);
|
||||||
|
addlong((uint32_t)&flags_op2);
|
||||||
|
if (not)
|
||||||
|
addbyte(0x76); /*JBE*/
|
||||||
|
else
|
||||||
|
addbyte(0x77); /*JNBE*/
|
||||||
|
break;
|
||||||
|
case FLAGS_SUB32:
|
||||||
|
addbyte(0xa1); /*MOV EAX, flags_op1*/
|
||||||
|
addlong((uint32_t)&flags_op1);
|
||||||
|
addbyte(0x3b); /*CMP EAX, flags_op2*/
|
||||||
|
addbyte(0x05);
|
||||||
|
addlong((uint32_t)&flags_op2);
|
||||||
|
if (not)
|
||||||
|
addbyte(0x76); /*JBE*/
|
||||||
|
else
|
||||||
|
addbyte(0x77); /*JNBE*/
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
if (codegen_flags_changed && flags_op != FLAGS_UNKNOWN)
|
if (codegen_flags_changed && flags_op != FLAGS_UNKNOWN)
|
||||||
{
|
{
|
||||||
addbyte(0x83); /*CMP flags_res, 0*/
|
addbyte(0x83); /*CMP flags_res, 0*/
|
||||||
|
|
@ -1513,6 +1552,8 @@ static int BRANCH_COND_BE(int pc_offset, uint32_t op_pc, uint32_t offset, int no
|
||||||
addbyte(0x75); /*JNZ +*/
|
addbyte(0x75); /*JNZ +*/
|
||||||
else
|
else
|
||||||
addbyte(0x74); /*JZ +*/
|
addbyte(0x74); /*JZ +*/
|
||||||
|
break;
|
||||||
|
}
|
||||||
addbyte(10+5+(timing_bt ? 7 : 0));
|
addbyte(10+5+(timing_bt ? 7 : 0));
|
||||||
addbyte(0xC7); /*MOVL [pc], new_pc*/
|
addbyte(0xC7); /*MOVL [pc], new_pc*/
|
||||||
addbyte(0x05);
|
addbyte(0x05);
|
||||||
|
|
@ -1531,6 +1572,45 @@ static int BRANCH_COND_BE(int pc_offset, uint32_t op_pc, uint32_t offset, int no
|
||||||
|
|
||||||
static int BRANCH_COND_L(int pc_offset, uint32_t op_pc, uint32_t offset, int not)
|
static int BRANCH_COND_L(int pc_offset, uint32_t op_pc, uint32_t offset, int not)
|
||||||
{
|
{
|
||||||
|
switch (codegen_flags_changed ? flags_op : FLAGS_UNKNOWN)
|
||||||
|
{
|
||||||
|
case FLAGS_SUB8:
|
||||||
|
addbyte(0xa0); /*MOV AL, flags_op1*/
|
||||||
|
addlong((uint32_t)&flags_op1);
|
||||||
|
addbyte(0x3a); /*CMP AL, flags_op2*/
|
||||||
|
addbyte(0x05);
|
||||||
|
addlong((uint32_t)&flags_op2);
|
||||||
|
if (not)
|
||||||
|
addbyte(0x7c); /*JL*/
|
||||||
|
else
|
||||||
|
addbyte(0x7d); /*JNL*/
|
||||||
|
break;
|
||||||
|
case FLAGS_SUB16:
|
||||||
|
addbyte(0x66); /*MOV AX, flags_op1*/
|
||||||
|
addbyte(0xa1);
|
||||||
|
addlong((uint32_t)&flags_op1);
|
||||||
|
addbyte(0x66); /*CMP AX, flags_op2*/
|
||||||
|
addbyte(0x3b);
|
||||||
|
addbyte(0x05);
|
||||||
|
addlong((uint32_t)&flags_op2);
|
||||||
|
if (not)
|
||||||
|
addbyte(0x7c); /*JL*/
|
||||||
|
else
|
||||||
|
addbyte(0x7d); /*JNL*/
|
||||||
|
break;
|
||||||
|
case FLAGS_SUB32:
|
||||||
|
addbyte(0xa1); /*MOV EAX, flags_op1*/
|
||||||
|
addlong((uint32_t)&flags_op1);
|
||||||
|
addbyte(0x3b); /*CMP EAX, flags_op2*/
|
||||||
|
addbyte(0x05);
|
||||||
|
addlong((uint32_t)&flags_op2);
|
||||||
|
if (not)
|
||||||
|
addbyte(0x7c); /*JL*/
|
||||||
|
else
|
||||||
|
addbyte(0x7d); /*JNL*/
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
CALL_FUNC(NF_SET);
|
CALL_FUNC(NF_SET);
|
||||||
addbyte(0x85); /*TEST EAX,EAX*/
|
addbyte(0x85); /*TEST EAX,EAX*/
|
||||||
addbyte(0xc0);
|
addbyte(0xc0);
|
||||||
|
|
@ -1549,6 +1629,8 @@ static int BRANCH_COND_L(int pc_offset, uint32_t op_pc, uint32_t offset, int not
|
||||||
addbyte(0x75); /*JNZ +*/
|
addbyte(0x75); /*JNZ +*/
|
||||||
else
|
else
|
||||||
addbyte(0x74); /*JZ +*/
|
addbyte(0x74); /*JZ +*/
|
||||||
|
break;
|
||||||
|
}
|
||||||
addbyte(10+5+(timing_bt ? 7 : 0));
|
addbyte(10+5+(timing_bt ? 7 : 0));
|
||||||
addbyte(0xC7); /*MOVL [pc], new_pc*/
|
addbyte(0xC7); /*MOVL [pc], new_pc*/
|
||||||
addbyte(0x05);
|
addbyte(0x05);
|
||||||
|
|
@ -1567,6 +1649,45 @@ static int BRANCH_COND_L(int pc_offset, uint32_t op_pc, uint32_t offset, int not
|
||||||
|
|
||||||
static int BRANCH_COND_LE(int pc_offset, uint32_t op_pc, uint32_t offset, int not)
|
static int BRANCH_COND_LE(int pc_offset, uint32_t op_pc, uint32_t offset, int not)
|
||||||
{
|
{
|
||||||
|
switch (codegen_flags_changed ? flags_op : FLAGS_UNKNOWN)
|
||||||
|
{
|
||||||
|
case FLAGS_SUB8:
|
||||||
|
addbyte(0xa0); /*MOV AL, flags_op1*/
|
||||||
|
addlong((uint32_t)&flags_op1);
|
||||||
|
addbyte(0x3a); /*CMP AL, flags_op2*/
|
||||||
|
addbyte(0x05);
|
||||||
|
addlong((uint32_t)&flags_op2);
|
||||||
|
if (not)
|
||||||
|
addbyte(0x7e); /*JLE*/
|
||||||
|
else
|
||||||
|
addbyte(0x7f); /*JNLE*/
|
||||||
|
break;
|
||||||
|
case FLAGS_SUB16:
|
||||||
|
addbyte(0x66); /*MOV AX, flags_op1*/
|
||||||
|
addbyte(0xa1);
|
||||||
|
addlong((uint32_t)&flags_op1);
|
||||||
|
addbyte(0x66); /*CMP AX, flags_op2*/
|
||||||
|
addbyte(0x3b);
|
||||||
|
addbyte(0x05);
|
||||||
|
addlong((uint32_t)&flags_op2);
|
||||||
|
if (not)
|
||||||
|
addbyte(0x7e); /*JLE*/
|
||||||
|
else
|
||||||
|
addbyte(0x7f); /*JNLE*/
|
||||||
|
break;
|
||||||
|
case FLAGS_SUB32:
|
||||||
|
addbyte(0xa1); /*MOV EAX, flags_op1*/
|
||||||
|
addlong((uint32_t)&flags_op1);
|
||||||
|
addbyte(0x3b); /*CMP EAX, flags_op2*/
|
||||||
|
addbyte(0x05);
|
||||||
|
addlong((uint32_t)&flags_op2);
|
||||||
|
if (not)
|
||||||
|
addbyte(0x7e); /*JLE*/
|
||||||
|
else
|
||||||
|
addbyte(0x7f); /*JNLE*/
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
if (codegen_flags_changed && flags_op != FLAGS_UNKNOWN)
|
if (codegen_flags_changed && flags_op != FLAGS_UNKNOWN)
|
||||||
{
|
{
|
||||||
addbyte(0x83); /*CMP flags_res, 0*/
|
addbyte(0x83); /*CMP flags_res, 0*/
|
||||||
|
|
@ -1605,6 +1726,8 @@ static int BRANCH_COND_LE(int pc_offset, uint32_t op_pc, uint32_t offset, int no
|
||||||
addbyte(0x75); /*JNZ +*/
|
addbyte(0x75); /*JNZ +*/
|
||||||
else
|
else
|
||||||
addbyte(0x74); /*JZ +*/
|
addbyte(0x74); /*JZ +*/
|
||||||
|
break;
|
||||||
|
}
|
||||||
addbyte(10+5+(timing_bt ? 7 : 0));
|
addbyte(10+5+(timing_bt ? 7 : 0));
|
||||||
addbyte(0xC7); /*MOVL [pc], new_pc*/
|
addbyte(0xC7); /*MOVL [pc], new_pc*/
|
||||||
addbyte(0x05);
|
addbyte(0x05);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue