Added code generation for JCXZ, LOOP, JE, JNE, JS, JNS, JB, JNB, JO, JNO, JP and JNP.
This commit is contained in:
parent
1fb4de4507
commit
bbf0011e95
8 changed files with 485 additions and 42 deletions
|
|
@ -144,4 +144,9 @@ extern uint32_t recomp_page;
|
|||
extern x86seg *op_ea_seg;
|
||||
extern int op_ssegs;
|
||||
extern uint32_t op_old_pc;
|
||||
|
||||
/*Set to 1 if flags have been changed in the block being recompiled, and hence
|
||||
flags_op is known and can be relied on */
|
||||
extern int codegen_flags_changed;
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include "x86_ops.h"
|
||||
#include "x86_flags.h"
|
||||
#include "386_common.h"
|
||||
#include "cpu.h"
|
||||
#include "codegen.h"
|
||||
#include "codegen_ops.h"
|
||||
#include "codegen_ops_x86.h"
|
||||
|
|
@ -28,7 +29,7 @@ RecompOpFn recomp_opcodes[512] =
|
|||
/*40*/ ropINC_rw, ropINC_rw, ropINC_rw, ropINC_rw, ropINC_rw, ropINC_rw, ropINC_rw, ropINC_rw, ropDEC_rw, ropDEC_rw, ropDEC_rw, ropDEC_rw, ropDEC_rw, ropDEC_rw, ropDEC_rw, ropDEC_rw,
|
||||
/*50*/ ropPUSH_16, ropPUSH_16, ropPUSH_16, ropPUSH_16, ropPUSH_16, ropPUSH_16, ropPUSH_16, ropPUSH_16, ropPOP_16, ropPOP_16, ropPOP_16, ropPOP_16, ropPOP_16, ropPOP_16, ropPOP_16, ropPOP_16,
|
||||
/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_imm_16, NULL, ropPUSH_imm_b16,NULL, NULL, NULL, NULL, NULL,
|
||||
/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*70*/ ropJO, ropJNO, ropJB, ropJNB, ropJE, ropJNE, NULL, NULL, ropJS, ropJNS, ropJP, ropJNP, NULL, NULL, NULL, NULL,
|
||||
|
||||
/*80*/ rop80, rop81_w, rop80, rop83_w, ropTEST_b_rm, ropTEST_w_rm, ropXCHG_b, ropXCHG_w, ropMOV_b_r, ropMOV_w_r, ropMOV_r_b, ropMOV_r_w, NULL, NULL, NULL, NULL,
|
||||
/*90*/ NULL, ropXCHG_AX_CX, ropXCHG_AX_DX, ropXCHG_AX_BX, ropXCHG_AX_SP, ropXCHG_AX_BP, ropXCHG_AX_SI, ropXCHG_AX_DI, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
|
@ -37,7 +38,7 @@ RecompOpFn recomp_opcodes[512] =
|
|||
|
||||
/*c0*/ NULL, NULL, ropRET_imm_16, ropRET_16, NULL, NULL, ropMOV_b_imm, ropMOV_w_imm, NULL, ropLEAVE_16, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropCALL_r16, ropJMP_r16, NULL, ropJMP_r8, NULL, NULL, NULL, NULL,
|
||||
/*e0*/ NULL, NULL, ropLOOP, ropJCXZ, NULL, NULL, NULL, NULL, ropCALL_r16, ropJMP_r16, NULL, ropJMP_r8, NULL, NULL, NULL, NULL,
|
||||
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
||||
/*32-bit data*/
|
||||
|
|
@ -50,7 +51,7 @@ RecompOpFn recomp_opcodes[512] =
|
|||
/*40*/ ropINC_rl, ropINC_rl, ropINC_rl, ropINC_rl, ropINC_rl, ropINC_rl, ropINC_rl, ropINC_rl, ropDEC_rl, ropDEC_rl, ropDEC_rl, ropDEC_rl, ropDEC_rl, ropDEC_rl, ropDEC_rl, ropDEC_rl,
|
||||
/*50*/ ropPUSH_32, ropPUSH_32, ropPUSH_32, ropPUSH_32, ropPUSH_32, ropPUSH_32, ropPUSH_32, ropPUSH_32, ropPOP_32, ropPOP_32, ropPOP_32, ropPOP_32, ropPOP_32, ropPOP_32, ropPOP_32, ropPOP_32,
|
||||
/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_imm_32, NULL, ropPUSH_imm_b32,NULL, NULL, NULL, NULL, NULL,
|
||||
/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*70*/ ropJO, ropJNO, ropJB, ropJNB, ropJE, ropJNE, NULL, NULL, ropJS, ropJNS, ropJP, ropJNP, NULL, NULL, NULL, NULL,
|
||||
|
||||
/*80*/ rop80, rop81_l, rop80, rop83_l, ropTEST_b_rm, ropTEST_l_rm, ropXCHG_b, ropXCHG_l, ropMOV_b_r, ropMOV_l_r, ropMOV_r_b, ropMOV_r_l, NULL, NULL, NULL, NULL,
|
||||
/*90*/ NULL, ropXCHG_EAX_ECX,ropXCHG_EAX_EDX,ropXCHG_EAX_EBX,ropXCHG_EAX_ESP,ropXCHG_EAX_EBP,ropXCHG_EAX_ESI,ropXCHG_EAX_EDI,NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
|
@ -59,7 +60,54 @@ RecompOpFn recomp_opcodes[512] =
|
|||
|
||||
/*c0*/ NULL, NULL, ropRET_imm_32, ropRET_32, NULL, NULL, ropMOV_b_imm, ropMOV_l_imm, NULL, ropLEAVE_32, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropCALL_r32, ropJMP_r32, NULL, ropJMP_r8, NULL, NULL, NULL, NULL,
|
||||
/*e0*/ NULL, NULL, ropLOOP, ropJCXZ, NULL, NULL, NULL, NULL, ropCALL_r32, ropJMP_r32, NULL, ropJMP_r8, NULL, NULL, NULL, NULL,
|
||||
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
};
|
||||
|
||||
RecompOpFn recomp_opcodes_0f[512] =
|
||||
{
|
||||
/*16-bit data*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
||||
/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
||||
/*80*/ ropJO_w, ropJNO_w, ropJB_w, ropJNB_w, ropJE_w, ropJNE_w, NULL, NULL, ropJS_w, ropJNS_w, ropJP_w, ropJNP_w, NULL, NULL, NULL, NULL,
|
||||
/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
||||
/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
||||
/*32-bit data*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
||||
/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
||||
/*80*/ ropJO_l, ropJNO_l, ropJB_l, ropJNB_l, ropJE_l, ropJNE_l, NULL, NULL, ropJS_l, ropJNS_l, ropJP_l, ropJNP_l, NULL, NULL, NULL, NULL,
|
||||
/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
||||
/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
typedef uint32_t (*RecompOpFn)(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block);
|
||||
|
||||
extern RecompOpFn recomp_opcodes[512];
|
||||
extern RecompOpFn recomp_opcodes_0f[512];
|
||||
|
||||
#define REG_EAX 0
|
||||
#define REG_ECX 1
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ static uint32_t ropINC_rw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin
|
|||
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_INC16);
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
|
||||
STORE_REG_W_RELEASE(host_reg);
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
|
||||
return op_pc;
|
||||
}
|
||||
|
|
@ -31,6 +33,8 @@ static uint32_t ropINC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin
|
|||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
|
||||
STORE_REG_L_RELEASE(host_reg);
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropDEC_rw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
|
|
@ -49,6 +53,8 @@ static uint32_t ropDEC_rw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin
|
|||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
|
||||
STORE_REG_W_RELEASE(host_reg);
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
|
|
@ -66,6 +72,8 @@ static uint32_t ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin
|
|||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
|
||||
STORE_REG_L_RELEASE(host_reg);
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
|
||||
return op_pc;
|
||||
}
|
||||
|
||||
|
|
@ -88,6 +96,7 @@ static uint32_t ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin
|
|||
else RELEASE_REG(dst_reg); \
|
||||
RELEASE_REG(src_reg); \
|
||||
\
|
||||
codegen_flags_changed = 1; \
|
||||
return op_pc + 1; \
|
||||
} \
|
||||
static uint32_t rop ## name ## _w_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
|
|
@ -108,6 +117,7 @@ static uint32_t ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin
|
|||
else RELEASE_REG(dst_reg); \
|
||||
RELEASE_REG(src_reg); \
|
||||
\
|
||||
codegen_flags_changed = 1; \
|
||||
return op_pc + 1; \
|
||||
} \
|
||||
static uint32_t rop ## name ## _l_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
|
|
@ -128,6 +138,7 @@ static uint32_t ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin
|
|||
else RELEASE_REG(dst_reg); \
|
||||
RELEASE_REG(src_reg); \
|
||||
\
|
||||
codegen_flags_changed = 1; \
|
||||
return op_pc + 1; \
|
||||
} \
|
||||
static uint32_t rop ## name ## _b_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
|
|
@ -156,6 +167,7 @@ static uint32_t ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin
|
|||
else RELEASE_REG(dst_reg); \
|
||||
RELEASE_REG(src_reg); \
|
||||
\
|
||||
codegen_flags_changed = 1; \
|
||||
return op_pc + 1; \
|
||||
} \
|
||||
static uint32_t rop ## name ## _w_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
|
|
@ -184,6 +196,7 @@ static uint32_t ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin
|
|||
else RELEASE_REG(dst_reg); \
|
||||
RELEASE_REG(src_reg); \
|
||||
\
|
||||
codegen_flags_changed = 1; \
|
||||
return op_pc + 1; \
|
||||
} \
|
||||
static uint32_t rop ## name ## _l_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
|
|
@ -212,6 +225,7 @@ static uint32_t ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin
|
|||
else RELEASE_REG(dst_reg); \
|
||||
RELEASE_REG(src_reg); \
|
||||
\
|
||||
codegen_flags_changed = 1; \
|
||||
return op_pc + 1; \
|
||||
}
|
||||
|
||||
|
|
@ -229,7 +243,8 @@ static uint32_t ropADD_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32,
|
|||
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ADD8);
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
|
||||
STORE_REG_B_RELEASE(host_reg);
|
||||
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
static uint32_t ropADD_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
|
|
@ -243,6 +258,7 @@ static uint32_t ropADD_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32,
|
|||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
|
||||
STORE_REG_W_RELEASE(host_reg);
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 2;
|
||||
}
|
||||
static uint32_t ropADD_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
|
|
@ -257,6 +273,7 @@ static uint32_t ropADD_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32
|
|||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
|
||||
STORE_REG_L_RELEASE(host_reg);
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 4;
|
||||
}
|
||||
|
||||
|
|
@ -271,6 +288,7 @@ static uint32_t ropCMP_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32,
|
|||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
|
||||
RELEASE_REG(host_reg);
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
static uint32_t ropCMP_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
|
|
@ -284,6 +302,7 @@ static uint32_t ropCMP_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32,
|
|||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
|
||||
RELEASE_REG(host_reg);
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 2;
|
||||
}
|
||||
static uint32_t ropCMP_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
|
|
@ -298,6 +317,7 @@ static uint32_t ropCMP_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32
|
|||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
|
||||
RELEASE_REG(host_reg);
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 4;
|
||||
}
|
||||
|
||||
|
|
@ -312,6 +332,7 @@ static uint32_t ropSUB_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32,
|
|||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
|
||||
STORE_REG_B_RELEASE(host_reg);
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
static uint32_t ropSUB_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
|
|
@ -325,6 +346,7 @@ static uint32_t ropSUB_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32,
|
|||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
|
||||
STORE_REG_W_RELEASE(host_reg);
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 2;
|
||||
}
|
||||
static uint32_t ropSUB_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
|
|
@ -339,6 +361,7 @@ static uint32_t ropSUB_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32
|
|||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
|
||||
STORE_REG_L_RELEASE(host_reg);
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 4;
|
||||
}
|
||||
|
||||
|
|
@ -393,6 +416,7 @@ static uint32_t rop80(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_
|
|||
else
|
||||
RELEASE_REG(host_reg);
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 2;
|
||||
}
|
||||
|
||||
|
|
@ -447,6 +471,7 @@ static uint32_t rop81_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3
|
|||
else
|
||||
RELEASE_REG(host_reg);
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 3;
|
||||
}
|
||||
static uint32_t rop81_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
|
|
@ -501,6 +526,7 @@ static uint32_t rop81_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3
|
|||
else
|
||||
RELEASE_REG(host_reg);
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 5;
|
||||
}
|
||||
|
||||
|
|
@ -557,6 +583,7 @@ static uint32_t rop83_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3
|
|||
else
|
||||
RELEASE_REG(host_reg);
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 2;
|
||||
}
|
||||
static uint32_t rop83_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
|
|
@ -612,5 +639,6 @@ static uint32_t rop83_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3
|
|||
else
|
||||
RELEASE_REG(host_reg);
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 2;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,3 +27,238 @@ static uint32_t ropJMP_r32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, ui
|
|||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static uint32_t ropJCXZ(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
uint32_t offset = fetchdat & 0xff;
|
||||
|
||||
if (offset & 0x80)
|
||||
offset |= 0xffffff00;
|
||||
|
||||
if (op_32 & 0x200)
|
||||
{
|
||||
int host_reg = LOAD_REG_L(REG_ECX);
|
||||
TEST_ZERO_JUMP_L(host_reg, op_pc+1+offset, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
int host_reg = LOAD_REG_W(REG_CX);
|
||||
TEST_ZERO_JUMP_W(host_reg, op_pc+1+offset, 0);
|
||||
}
|
||||
|
||||
return op_pc+1;
|
||||
}
|
||||
|
||||
static uint32_t ropLOOP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
uint32_t offset = fetchdat & 0xff;
|
||||
|
||||
if (offset & 0x80)
|
||||
offset |= 0xffffff00;
|
||||
|
||||
if (op_32 & 0x200)
|
||||
{
|
||||
int host_reg = LOAD_REG_L(REG_ECX);
|
||||
SUB_HOST_REG_IMM(host_reg, 1);
|
||||
STORE_REG_L_RELEASE(host_reg);
|
||||
TEST_NONZERO_JUMP_L(host_reg, op_pc+1+offset, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
int host_reg = LOAD_REG_W(REG_CX);
|
||||
SUB_HOST_REG_IMM(host_reg, 1);
|
||||
STORE_REG_W_RELEASE(host_reg);
|
||||
TEST_NONZERO_JUMP_W(host_reg, op_pc+1+offset, 0);
|
||||
}
|
||||
|
||||
return op_pc+1;
|
||||
}
|
||||
|
||||
static int BRANCH_COND_B(int pc_offset, uint32_t op_pc, uint32_t offset, int not)
|
||||
{
|
||||
CALL_FUNC(CF_SET);
|
||||
if (not)
|
||||
TEST_ZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt);
|
||||
else
|
||||
TEST_NONZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt);
|
||||
}
|
||||
|
||||
static int BRANCH_COND_E(int pc_offset, uint32_t op_pc, uint32_t offset, int not)
|
||||
{
|
||||
int host_reg;
|
||||
|
||||
switch (codegen_flags_changed ? flags_op : FLAGS_UNKNOWN)
|
||||
{
|
||||
case FLAGS_ZN8:
|
||||
case FLAGS_ZN16:
|
||||
case FLAGS_ZN32:
|
||||
case FLAGS_ADD8:
|
||||
case FLAGS_ADD16:
|
||||
case FLAGS_ADD32:
|
||||
case FLAGS_SUB8:
|
||||
case FLAGS_SUB16:
|
||||
case FLAGS_SUB32:
|
||||
case FLAGS_SHL8:
|
||||
case FLAGS_SHL16:
|
||||
case FLAGS_SHL32:
|
||||
case FLAGS_SHR8:
|
||||
case FLAGS_SHR16:
|
||||
case FLAGS_SHR32:
|
||||
case FLAGS_SAR8:
|
||||
case FLAGS_SAR16:
|
||||
case FLAGS_SAR32:
|
||||
case FLAGS_INC8:
|
||||
case FLAGS_INC16:
|
||||
case FLAGS_INC32:
|
||||
case FLAGS_DEC8:
|
||||
case FLAGS_DEC16:
|
||||
case FLAGS_DEC32:
|
||||
host_reg = LOAD_VAR_L(&flags_res);
|
||||
if (not)
|
||||
TEST_NONZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt);
|
||||
else
|
||||
TEST_ZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt);
|
||||
break;
|
||||
|
||||
case FLAGS_UNKNOWN:
|
||||
CALL_FUNC(ZF_SET);
|
||||
if (not)
|
||||
TEST_ZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt);
|
||||
else
|
||||
TEST_NONZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int BRANCH_COND_O(int pc_offset, uint32_t op_pc, uint32_t offset, int not)
|
||||
{
|
||||
CALL_FUNC(VF_SET);
|
||||
if (not)
|
||||
TEST_ZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt);
|
||||
else
|
||||
TEST_NONZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt);
|
||||
}
|
||||
|
||||
static int BRANCH_COND_P(int pc_offset, uint32_t op_pc, uint32_t offset, int not)
|
||||
{
|
||||
CALL_FUNC(PF_SET);
|
||||
if (not)
|
||||
TEST_ZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt);
|
||||
else
|
||||
TEST_NONZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt);
|
||||
}
|
||||
|
||||
static int BRANCH_COND_S(int pc_offset, uint32_t op_pc, uint32_t offset, int not)
|
||||
{
|
||||
int host_reg;
|
||||
|
||||
switch (codegen_flags_changed ? flags_op : FLAGS_UNKNOWN)
|
||||
{
|
||||
case FLAGS_ZN8:
|
||||
case FLAGS_ADD8:
|
||||
case FLAGS_SUB8:
|
||||
case FLAGS_SHL8:
|
||||
case FLAGS_SHR8:
|
||||
case FLAGS_SAR8:
|
||||
case FLAGS_INC8:
|
||||
case FLAGS_DEC8:
|
||||
host_reg = LOAD_VAR_L(&flags_res);
|
||||
AND_HOST_REG_IMM(host_reg, 0x80);
|
||||
if (not)
|
||||
TEST_ZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt);
|
||||
else
|
||||
TEST_NONZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt);
|
||||
break;
|
||||
|
||||
case FLAGS_ZN16:
|
||||
case FLAGS_ADD16:
|
||||
case FLAGS_SUB16:
|
||||
case FLAGS_SHL16:
|
||||
case FLAGS_SHR16:
|
||||
case FLAGS_SAR16:
|
||||
case FLAGS_INC16:
|
||||
case FLAGS_DEC16:
|
||||
host_reg = LOAD_VAR_L(&flags_res);
|
||||
AND_HOST_REG_IMM(host_reg, 0x8000);
|
||||
if (not)
|
||||
TEST_ZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt);
|
||||
else
|
||||
TEST_NONZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt);
|
||||
break;
|
||||
|
||||
case FLAGS_ZN32:
|
||||
case FLAGS_ADD32:
|
||||
case FLAGS_SUB32:
|
||||
case FLAGS_SHL32:
|
||||
case FLAGS_SHR32:
|
||||
case FLAGS_SAR32:
|
||||
case FLAGS_INC32:
|
||||
case FLAGS_DEC32:
|
||||
host_reg = LOAD_VAR_L(&flags_res);
|
||||
AND_HOST_REG_IMM(host_reg, 0x80000000);
|
||||
if (not)
|
||||
TEST_ZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt);
|
||||
else
|
||||
TEST_NONZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt);
|
||||
break;
|
||||
|
||||
case FLAGS_UNKNOWN:
|
||||
CALL_FUNC(NF_SET);
|
||||
if (not)
|
||||
TEST_ZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt);
|
||||
else
|
||||
TEST_NONZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define ropBRANCH(name, func, not) \
|
||||
static uint32_t rop ## name(uint8_t opcode, uint32_t fetchdat, \
|
||||
uint32_t op_32, uint32_t op_pc, \
|
||||
codeblock_t *block) \
|
||||
{ \
|
||||
uint32_t offset = fetchdat & 0xff; \
|
||||
\
|
||||
if (offset & 0x80) \
|
||||
offset |= 0xffffff00; \
|
||||
\
|
||||
func(1, op_pc, offset, not); \
|
||||
\
|
||||
return op_pc+1; \
|
||||
} \
|
||||
static uint32_t rop ## name ## _w(uint8_t opcode, \
|
||||
uint32_t fetchdat, uint32_t op_32, \
|
||||
uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
uint32_t offset = fetchdat & 0xffff; \
|
||||
\
|
||||
if (offset & 0x8000) \
|
||||
offset |= 0xffff0000; \
|
||||
\
|
||||
func(2, op_pc, offset, not); \
|
||||
\
|
||||
return op_pc+2; \
|
||||
} \
|
||||
static uint32_t rop ## name ## _l(uint8_t opcode, \
|
||||
uint32_t fetchdat, uint32_t op_32, \
|
||||
uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
uint32_t offset = fastreadl(cs + op_pc); \
|
||||
\
|
||||
func(4, op_pc, offset, not); \
|
||||
\
|
||||
return op_pc+4; \
|
||||
}
|
||||
|
||||
ropBRANCH(JB, BRANCH_COND_B, 0)
|
||||
ropBRANCH(JNB, BRANCH_COND_B, 1)
|
||||
ropBRANCH(JE, BRANCH_COND_E, 0)
|
||||
ropBRANCH(JNE, BRANCH_COND_E, 1)
|
||||
ropBRANCH(JO, BRANCH_COND_O, 0)
|
||||
ropBRANCH(JNO, BRANCH_COND_O, 1)
|
||||
ropBRANCH(JP, BRANCH_COND_P, 0)
|
||||
ropBRANCH(JNP, BRANCH_COND_P, 1)
|
||||
ropBRANCH(JS, BRANCH_COND_S, 0)
|
||||
ropBRANCH(JNS, BRANCH_COND_S, 1)
|
||||
|
|
|
|||
|
|
@ -108,6 +108,18 @@ static int LOAD_REG_L(int reg)
|
|||
return host_reg;
|
||||
}
|
||||
|
||||
static int LOAD_VAR_L(uintptr_t addr)
|
||||
{
|
||||
int host_reg = find_host_reg();
|
||||
host_reg_mapping[host_reg] = reg;
|
||||
|
||||
addbyte(0x8b); /*MOVL host_reg,[reg]*/
|
||||
addbyte(0x05 | (host_reg << 3));
|
||||
addlong((uint32_t)addr);
|
||||
|
||||
return host_reg;
|
||||
}
|
||||
|
||||
static int LOAD_REG_IMM(uint32_t imm)
|
||||
{
|
||||
int host_reg = find_host_reg();
|
||||
|
|
@ -1101,3 +1113,92 @@ static void SP_MODIFY(int off)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void TEST_ZERO_JUMP_W(int host_reg, uint32_t new_pc, int taken_cycles)
|
||||
{
|
||||
addbyte(0x66); /*CMPW host_reg, 0*/
|
||||
addbyte(0x83);
|
||||
addbyte(0xc0 | 0x38 | host_reg);
|
||||
addbyte(0);
|
||||
addbyte(0x75); /*JNZ +*/
|
||||
addbyte(10+5+(taken_cycles ? 7 : 0));
|
||||
addbyte(0xC7); /*MOVL [pc], new_pc*/
|
||||
addbyte(0x05);
|
||||
addlong((uintptr_t)&pc);
|
||||
addlong(new_pc);
|
||||
if (taken_cycles)
|
||||
{
|
||||
addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/
|
||||
addbyte(0x2d);
|
||||
addlong((uintptr_t)&cycles);
|
||||
addbyte(taken_cycles);
|
||||
}
|
||||
addbyte(0xe9); /*JMP end*/
|
||||
addlong(BLOCK_EXIT_OFFSET - (block_pos + 4));
|
||||
}
|
||||
static void TEST_ZERO_JUMP_L(int host_reg, uint32_t new_pc, int taken_cycles)
|
||||
{
|
||||
addbyte(0x83); /*CMPW host_reg, 0*/
|
||||
addbyte(0xc0 | 0x38 | host_reg);
|
||||
addbyte(0);
|
||||
addbyte(0x75); /*JNZ +*/
|
||||
addbyte(10+5+(taken_cycles ? 7 : 0));
|
||||
addbyte(0xC7); /*MOVL [pc], new_pc*/
|
||||
addbyte(0x05);
|
||||
addlong((uintptr_t)&pc);
|
||||
addlong(new_pc);
|
||||
if (taken_cycles)
|
||||
{
|
||||
addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/
|
||||
addbyte(0x2d);
|
||||
addlong((uintptr_t)&cycles);
|
||||
addbyte(taken_cycles);
|
||||
}
|
||||
addbyte(0xe9); /*JMP end*/
|
||||
addlong(BLOCK_EXIT_OFFSET - (block_pos + 4));
|
||||
}
|
||||
|
||||
static void TEST_NONZERO_JUMP_W(int host_reg, uint32_t new_pc, int taken_cycles)
|
||||
{
|
||||
addbyte(0x66); /*CMPW host_reg, 0*/
|
||||
addbyte(0x83);
|
||||
addbyte(0xc0 | 0x38 | host_reg);
|
||||
addbyte(0);
|
||||
addbyte(0x74); /*JZ +*/
|
||||
addbyte(10+5+(taken_cycles ? 7 : 0));
|
||||
addbyte(0xC7); /*MOVL [pc], new_pc*/
|
||||
addbyte(0x05);
|
||||
addlong((uintptr_t)&pc);
|
||||
addlong(new_pc);
|
||||
if (taken_cycles)
|
||||
{
|
||||
addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/
|
||||
addbyte(0x2d);
|
||||
addlong((uintptr_t)&cycles);
|
||||
addbyte(taken_cycles);
|
||||
}
|
||||
addbyte(0xe9); /*JMP end*/
|
||||
addlong(BLOCK_EXIT_OFFSET - (block_pos + 4));
|
||||
}
|
||||
static void TEST_NONZERO_JUMP_L(int host_reg, uint32_t new_pc, int taken_cycles)
|
||||
{
|
||||
addbyte(0x83); /*CMPW host_reg, 0*/
|
||||
addbyte(0xc0 | 0x38 | host_reg);
|
||||
addbyte(0);
|
||||
addbyte(0x74); /*JZ +*/
|
||||
addbyte(10+5+(taken_cycles ? 7 : 0));
|
||||
addbyte(0xC7); /*MOVL [pc], new_pc*/
|
||||
addbyte(0x05);
|
||||
addlong((uintptr_t)&pc);
|
||||
addlong(new_pc);
|
||||
if (taken_cycles)
|
||||
{
|
||||
addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/
|
||||
addbyte(0x2d);
|
||||
addlong((uintptr_t)&cycles);
|
||||
addbyte(taken_cycles);
|
||||
}
|
||||
addbyte(0xe9); /*JMP end*/
|
||||
addlong(BLOCK_EXIT_OFFSET - (block_pos + 4));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
int codegen_flags_changed = 0;
|
||||
x86seg *op_ea_seg;
|
||||
int op_ssegs;
|
||||
uint32_t op_old_pc;
|
||||
|
|
@ -250,6 +251,8 @@ void codegen_block_init(uint32_t phys_addr)
|
|||
codegen_block_full_ins = 0;
|
||||
|
||||
recomp_page = phys_addr & ~0xfff;
|
||||
|
||||
codegen_flags_changed = 0;
|
||||
}
|
||||
|
||||
void codegen_block_remove()
|
||||
|
|
@ -686,6 +689,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
|
|||
uint32_t op_32 = use32;
|
||||
uint32_t op_pc = new_pc;
|
||||
OpFn *op_table = x86_dynarec_opcodes;
|
||||
RecompOpFn *recomp_op_table = recomp_opcodes;
|
||||
int opcode_shift = 0;
|
||||
int opcode_mask = 0x3ff;
|
||||
int over = 0;
|
||||
|
|
@ -708,6 +712,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
|
|||
{
|
||||
case 0x0f:
|
||||
op_table = x86_dynarec_opcodes_0f;
|
||||
recomp_op_table = recomp_opcodes_0f;
|
||||
over = 1;
|
||||
break;
|
||||
|
||||
|
|
@ -745,6 +750,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
|
|||
|
||||
case 0xd8:
|
||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d8_a32 : x86_dynarec_opcodes_d8_a16;
|
||||
recomp_op_table = NULL;
|
||||
opcode_shift = 3;
|
||||
opcode_mask = 0x1f;
|
||||
over = 1;
|
||||
|
|
@ -753,6 +759,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
|
|||
break;
|
||||
case 0xd9:
|
||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d9_a32 : x86_dynarec_opcodes_d9_a16;
|
||||
recomp_op_table = NULL;
|
||||
opcode_mask = 0xff;
|
||||
over = 1;
|
||||
pc_off = -1;
|
||||
|
|
@ -760,6 +767,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
|
|||
break;
|
||||
case 0xda:
|
||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_da_a32 : x86_dynarec_opcodes_da_a16;
|
||||
recomp_op_table = NULL;
|
||||
opcode_mask = 0xff;
|
||||
over = 1;
|
||||
pc_off = -1;
|
||||
|
|
@ -767,6 +775,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
|
|||
break;
|
||||
case 0xdb:
|
||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_db_a32 : x86_dynarec_opcodes_db_a16;
|
||||
recomp_op_table = NULL;
|
||||
opcode_mask = 0xff;
|
||||
over = 1;
|
||||
pc_off = -1;
|
||||
|
|
@ -774,6 +783,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
|
|||
break;
|
||||
case 0xdc:
|
||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dc_a32 : x86_dynarec_opcodes_dc_a16;
|
||||
recomp_op_table = NULL;
|
||||
opcode_shift = 3;
|
||||
opcode_mask = 0x1f;
|
||||
over = 1;
|
||||
|
|
@ -782,6 +792,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
|
|||
break;
|
||||
case 0xdd:
|
||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dd_a32 : x86_dynarec_opcodes_dd_a16;
|
||||
recomp_op_table = NULL;
|
||||
opcode_mask = 0xff;
|
||||
over = 1;
|
||||
pc_off = -1;
|
||||
|
|
@ -789,6 +800,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
|
|||
break;
|
||||
case 0xde:
|
||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_de_a32 : x86_dynarec_opcodes_de_a16;
|
||||
recomp_op_table = NULL;
|
||||
opcode_mask = 0xff;
|
||||
over = 1;
|
||||
pc_off = -1;
|
||||
|
|
@ -796,6 +808,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
|
|||
break;
|
||||
case 0xdf:
|
||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_df_a32 : x86_dynarec_opcodes_df_a16;
|
||||
recomp_op_table = NULL;
|
||||
opcode_mask = 0xff;
|
||||
over = 1;
|
||||
pc_off = -1;
|
||||
|
|
@ -822,11 +835,46 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
|
|||
generate_call:
|
||||
codegen_timing_opcode(opcode, fetchdat, op_32);
|
||||
|
||||
if ((op_table == x86_dynarec_opcodes &&
|
||||
((opcode & 0xf0) == 0x70 || (opcode & 0xfc) == 0xe0 || opcode == 0xc2 ||
|
||||
(opcode & 0xfe) == 0xca || (opcode & 0xfc) == 0xcc || (opcode & 0xfc) == 0xe8 ||
|
||||
(opcode == 0xff && ((fetchdat & 0x38) >= 0x10 && (fetchdat & 0x38) < 0x30))) ||
|
||||
(op_table == x86_dynarec_opcodes_0f && ((opcode & 0xf0) == 0x80))))
|
||||
{
|
||||
/*Opcode is likely to cause block to exit, update cycle count*/
|
||||
if (codegen_block_cycles)
|
||||
{
|
||||
addbyte(0x81); /*SUB $codegen_block_cycles, cyclcs*/
|
||||
addbyte(0x2d);
|
||||
addlong((uint32_t)&cycles);
|
||||
addlong((uint32_t)codegen_block_cycles);
|
||||
codegen_block_cycles = 0;
|
||||
}
|
||||
if (codegen_block_ins)
|
||||
{
|
||||
addbyte(0x81); /*ADD $codegen_block_ins,ins*/
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t)&cpu_recomp_ins);
|
||||
addlong(codegen_block_ins);
|
||||
codegen_block_ins = 0;
|
||||
}
|
||||
#if 0
|
||||
if (codegen_block_full_ins)
|
||||
{
|
||||
addbyte(0x81); /*ADD $codegen_block_ins,ins*/
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t)&cpu_recomp_full_ins);
|
||||
addlong(codegen_block_full_ins);
|
||||
codegen_block_full_ins = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
addbyte(0xBD); /*MOVL EBP, &EAX*/
|
||||
addlong((uint32_t)&EAX);
|
||||
if (op_table == x86_dynarec_opcodes && recomp_opcodes[(opcode | op_32) & 0x1ff])
|
||||
if (recomp_op_table && recomp_op_table[(opcode | op_32) & 0x1ff])
|
||||
{
|
||||
uint32_t new_pc = recomp_opcodes[(opcode | op_32) & 0x1ff](opcode, fetchdat, op_32, op_pc, block);
|
||||
uint32_t new_pc = recomp_op_table[(opcode | op_32) & 0x1ff](opcode, fetchdat, op_32, op_pc, block);
|
||||
if (new_pc)
|
||||
{
|
||||
if (new_pc != -1)
|
||||
|
|
@ -933,41 +981,6 @@ generate_call:
|
|||
addlong(((uint8_t *)op - (uint8_t *)(&block->data[block_pos + 4])));
|
||||
|
||||
codegen_block_ins++;
|
||||
|
||||
if ((op_table == x86_dynarec_opcodes &&
|
||||
((opcode & 0xf0) == 0x70 || (opcode & 0xfc) == 0xe0 || opcode == 0xc2 ||
|
||||
(opcode & 0xfe) == 0xca || (opcode & 0xfc) == 0xcc || (opcode & 0xfc) == 0xe8 ||
|
||||
(opcode == 0xff && ((fetchdat & 0x38) >= 0x10 && (fetchdat & 0x38) < 0x30))) ||
|
||||
(op_table == x86_dynarec_opcodes_0f && ((opcode & 0xf0) == 0x80))))
|
||||
{
|
||||
/*Opcode is likely to cause block to exit, update cycle count*/
|
||||
if (codegen_block_cycles)
|
||||
{
|
||||
addbyte(0x81); /*SUB $codegen_block_cycles, cyclcs*/
|
||||
addbyte(0x2d);
|
||||
addlong((uint32_t)&cycles);
|
||||
addlong((uint32_t)codegen_block_cycles);
|
||||
codegen_block_cycles = 0;
|
||||
}
|
||||
if (codegen_block_ins)
|
||||
{
|
||||
addbyte(0x81); /*ADD $codegen_block_ins,ins*/
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t)&cpu_recomp_ins);
|
||||
addlong(codegen_block_ins);
|
||||
codegen_block_ins = 0;
|
||||
}
|
||||
#if 0
|
||||
if (codegen_block_full_ins)
|
||||
{
|
||||
addbyte(0x81); /*ADD $codegen_block_ins,ins*/
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t)&cpu_recomp_full_ins);
|
||||
addlong(codegen_block_full_ins);
|
||||
codegen_block_full_ins = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
block->ins++;
|
||||
|
||||
|
|
|
|||
|
|
@ -70,6 +70,9 @@ static int opSAHF(uint32_t fetchdat)
|
|||
flags_rebuild();
|
||||
flags = (flags & 0xff00) | (AH & 0xd5) | 2;
|
||||
CLOCK_CYCLES(3);
|
||||
#ifdef DYNAREC
|
||||
codegen_flags_changed = 0;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
static int opLAHF(uint32_t fetchdat)
|
||||
|
|
@ -127,6 +130,9 @@ static int opPOPF_286(uint32_t fetchdat)
|
|||
flags_extract();
|
||||
|
||||
CLOCK_CYCLES(5);
|
||||
#ifdef DYNAREC
|
||||
codegen_flags_changed = 0;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
static int opPOPF(uint32_t fetchdat)
|
||||
|
|
@ -147,6 +153,9 @@ static int opPOPF(uint32_t fetchdat)
|
|||
flags_extract();
|
||||
|
||||
CLOCK_CYCLES(5);
|
||||
#ifdef DYNAREC
|
||||
codegen_flags_changed = 0;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
static int opPOPFD(uint32_t fetchdat)
|
||||
|
|
@ -174,5 +183,8 @@ static int opPOPFD(uint32_t fetchdat)
|
|||
flags_extract();
|
||||
|
||||
CLOCK_CYCLES(5);
|
||||
#ifdef DYNAREC
|
||||
codegen_flags_changed = 0;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue