Move GPF and early exit routines out of individual code blocks and into the common helper block.
This commit is contained in:
parent
966e74261b
commit
8998024225
21 changed files with 213 additions and 213 deletions
|
|
@ -61,7 +61,7 @@ void codegen_check_seg_read(codeblock_t *block, ir_data_t *ir, x86seg *seg)
|
|||
if (seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS))
|
||||
return;
|
||||
|
||||
uop_CMP_IMM_JZ(ir, ireg_seg_base(seg), (uint32_t)-1, &block->data[BLOCK_GPF_OFFSET]);
|
||||
uop_CMP_IMM_JZ(ir, ireg_seg_base(seg), (uint32_t)-1, codegen_gpf_rout);
|
||||
|
||||
seg->checked = 1;
|
||||
}
|
||||
|
|
@ -78,7 +78,7 @@ void codegen_check_seg_write(codeblock_t *block, ir_data_t *ir, x86seg *seg)
|
|||
if (seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS))
|
||||
return;
|
||||
|
||||
uop_CMP_IMM_JZ(ir, ireg_seg_base(seg), (uint32_t)-1, &block->data[BLOCK_GPF_OFFSET]);
|
||||
uop_CMP_IMM_JZ(ir, ireg_seg_base(seg), (uint32_t)-1, codegen_gpf_rout);
|
||||
|
||||
seg->checked = 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,6 +35,9 @@ void *codegen_mem_store_double;
|
|||
|
||||
void *codegen_fp_round;
|
||||
|
||||
void *codegen_gpf_rout;
|
||||
void *codegen_exit_rout;
|
||||
|
||||
int codegen_host_reg_list[CODEGEN_HOST_REGS] =
|
||||
{
|
||||
REG_R4,
|
||||
|
|
@ -78,6 +81,7 @@ static void build_load_routine(codeblock_t *block, int size, int is_float)
|
|||
LDRB R1, cpu_state.abrt
|
||||
LDR PC, [SP], #4
|
||||
*/
|
||||
codegen_alloc(block, 80);
|
||||
host_arm_MOV_REG_LSR(block, REG_R1, REG_R0, 12);
|
||||
host_arm_MOV_IMM(block, REG_R2, (uint32_t)readlookup2);
|
||||
host_arm_LDR_REG_LSL(block, REG_R1, REG_R2, REG_R1, 2);
|
||||
|
|
@ -107,9 +111,9 @@ static void build_load_routine(codeblock_t *block, int size, int is_float)
|
|||
host_arm_MOV_IMM(block, REG_R1, 0);
|
||||
host_arm_MOV_REG(block, REG_PC, REG_LR);
|
||||
|
||||
*branch_offset |= ((((uintptr_t)&block->data[block_pos] - (uintptr_t)branch_offset) - 8) & 0x3fffffc) >> 2;
|
||||
*branch_offset |= ((((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 8) & 0x3fffffc) >> 2;
|
||||
if (size != 1)
|
||||
*misaligned_offset |= ((((uintptr_t)&block->data[block_pos] - (uintptr_t)misaligned_offset) - 8) & 0x3fffffc) >> 2;
|
||||
*misaligned_offset |= ((((uintptr_t)&block_write_data[block_pos] - (uintptr_t)misaligned_offset) - 8) & 0x3fffffc) >> 2;
|
||||
host_arm_STR_IMM_WB(block, REG_LR, REG_HOST_SP, -4);
|
||||
if (size == 1)
|
||||
host_arm_BL(block, (uintptr_t)readmemb386l);
|
||||
|
|
@ -149,6 +153,7 @@ static void build_store_routine(codeblock_t *block, int size, int is_float)
|
|||
LDRB R1, cpu_state.abrt
|
||||
LDR PC, [SP], #4
|
||||
*/
|
||||
codegen_alloc(block, 80);
|
||||
host_arm_MOV_REG_LSR(block, REG_R2, REG_R0, 12);
|
||||
host_arm_MOV_IMM(block, REG_R3, (uint32_t)writelookup2);
|
||||
host_arm_LDR_REG_LSL(block, REG_R2, REG_R3, REG_R2, 2);
|
||||
|
|
@ -178,9 +183,9 @@ static void build_store_routine(codeblock_t *block, int size, int is_float)
|
|||
host_arm_MOV_IMM(block, REG_R1, 0);
|
||||
host_arm_MOV_REG(block, REG_PC, REG_LR);
|
||||
|
||||
*branch_offset |= ((((uintptr_t)&block->data[block_pos] - (uintptr_t)branch_offset) - 8) & 0x3fffffc) >> 2;
|
||||
*branch_offset |= ((((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 8) & 0x3fffffc) >> 2;
|
||||
if (size != 1)
|
||||
*misaligned_offset |= ((((uintptr_t)&block->data[block_pos] - (uintptr_t)misaligned_offset) - 8) & 0x3fffffc) >> 2;
|
||||
*misaligned_offset |= ((((uintptr_t)&block_write_data[block_pos] - (uintptr_t)misaligned_offset) - 8) & 0x3fffffc) >> 2;
|
||||
host_arm_STR_IMM_WB(block, REG_LR, REG_HOST_SP, -4);
|
||||
if (size == 4 && is_float)
|
||||
host_arm_VMOV_32_S(block, REG_R1, REG_D_TEMP);
|
||||
|
|
@ -202,30 +207,30 @@ static void build_store_routine(codeblock_t *block, int size, int is_float)
|
|||
|
||||
static void build_loadstore_routines(codeblock_t *block)
|
||||
{
|
||||
codegen_mem_load_byte = &codeblock[block_current].data[block_pos];
|
||||
codegen_mem_load_byte = &block_write_data[block_pos];
|
||||
build_load_routine(block, 1, 0);
|
||||
codegen_mem_load_word = &codeblock[block_current].data[block_pos];
|
||||
codegen_mem_load_word = &block_write_data[block_pos];
|
||||
build_load_routine(block, 2, 0);
|
||||
codegen_mem_load_long = &codeblock[block_current].data[block_pos];
|
||||
codegen_mem_load_long = &block_write_data[block_pos];
|
||||
build_load_routine(block, 4, 0);
|
||||
codegen_mem_load_quad = &codeblock[block_current].data[block_pos];
|
||||
codegen_mem_load_quad = &block_write_data[block_pos];
|
||||
build_load_routine(block, 8, 0);
|
||||
codegen_mem_load_single = &codeblock[block_current].data[block_pos];
|
||||
codegen_mem_load_single = &block_write_data[block_pos];
|
||||
build_load_routine(block, 4, 1);
|
||||
codegen_mem_load_double = &codeblock[block_current].data[block_pos];
|
||||
codegen_mem_load_double = &block_write_data[block_pos];
|
||||
build_load_routine(block, 8, 1);
|
||||
|
||||
codegen_mem_store_byte = &codeblock[block_current].data[block_pos];
|
||||
codegen_mem_store_byte = &block_write_data[block_pos];
|
||||
build_store_routine(block, 1, 0);
|
||||
codegen_mem_store_word = &codeblock[block_current].data[block_pos];
|
||||
codegen_mem_store_word = &block_write_data[block_pos];
|
||||
build_store_routine(block, 2, 0);
|
||||
codegen_mem_store_long = &codeblock[block_current].data[block_pos];
|
||||
codegen_mem_store_long = &block_write_data[block_pos];
|
||||
build_store_routine(block, 4, 0);
|
||||
codegen_mem_store_quad = &codeblock[block_current].data[block_pos];
|
||||
codegen_mem_store_quad = &block_write_data[block_pos];
|
||||
build_store_routine(block, 8, 0);
|
||||
codegen_mem_store_single = &codeblock[block_current].data[block_pos];
|
||||
codegen_mem_store_single = &block_write_data[block_pos];
|
||||
build_store_routine(block, 4, 1);
|
||||
codegen_mem_store_double = &codeblock[block_current].data[block_pos];
|
||||
codegen_mem_store_double = &block_write_data[block_pos];
|
||||
build_store_routine(block, 8, 1);
|
||||
}
|
||||
|
||||
|
|
@ -239,23 +244,25 @@ static void build_fp_round_routine(codeblock_t *block)
|
|||
{
|
||||
uint32_t *jump_table;
|
||||
|
||||
codegen_alloc(block, 80);
|
||||
|
||||
host_arm_MOV_REG(block, REG_TEMP2, REG_LR);
|
||||
host_arm_MOV_REG(block, REG_LR, REG_TEMP2);
|
||||
host_arm_LDR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.new_fp_control - (uintptr_t)&cpu_state);
|
||||
host_arm_LDR_REG(block, REG_PC, REG_PC, REG_TEMP);
|
||||
host_arm_NOP(block);
|
||||
|
||||
jump_table = (uint32_t *)&block->data[block_pos];
|
||||
jump_table = (uint32_t *)&block_write_data[block_pos];
|
||||
host_arm_NOP(block);
|
||||
host_arm_NOP(block);
|
||||
host_arm_NOP(block);
|
||||
host_arm_NOP(block);
|
||||
|
||||
jump_table[X87_ROUNDING_NEAREST] = (uint64_t)(uintptr_t)&block->data[block_pos]; //tie even
|
||||
jump_table[X87_ROUNDING_NEAREST] = (uint64_t)(uintptr_t)&block_write_data[block_pos]; //tie even
|
||||
host_arm_VCVTR_IS_D(block, REG_D_TEMP, REG_D_TEMP);
|
||||
host_arm_MOV_REG(block, REG_PC, REG_LR);
|
||||
|
||||
jump_table[X87_ROUNDING_UP] = (uint64_t)(uintptr_t)&block->data[block_pos]; //pos inf
|
||||
jump_table[X87_ROUNDING_UP] = (uint64_t)(uintptr_t)&block_write_data[block_pos]; //pos inf
|
||||
host_arm_LDR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.old_fp_control - (uintptr_t)&cpu_state);
|
||||
host_arm_BIC_IMM(block, REG_TEMP2, REG_TEMP, FPCSR_ROUNDING_MASK);
|
||||
host_arm_ORR_IMM(block, REG_TEMP2, REG_TEMP2, FPCSR_ROUNDING_UP);
|
||||
|
|
@ -264,7 +271,7 @@ static void build_fp_round_routine(codeblock_t *block)
|
|||
host_arm_VMSR_FPSCR(block, REG_TEMP);
|
||||
host_arm_MOV_REG(block, REG_PC, REG_LR);
|
||||
|
||||
jump_table[X87_ROUNDING_DOWN] = (uint64_t)(uintptr_t)&block->data[block_pos]; //neg inf
|
||||
jump_table[X87_ROUNDING_DOWN] = (uint64_t)(uintptr_t)&block_write_data[block_pos]; //neg inf
|
||||
host_arm_LDR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.old_fp_control - (uintptr_t)&cpu_state);
|
||||
host_arm_BIC_IMM(block, REG_TEMP2, REG_TEMP, FPCSR_ROUNDING_MASK);
|
||||
host_arm_ORR_IMM(block, REG_TEMP2, REG_TEMP, FPCSR_ROUNDING_DOWN);
|
||||
|
|
@ -273,7 +280,7 @@ static void build_fp_round_routine(codeblock_t *block)
|
|||
host_arm_VMSR_FPSCR(block, REG_TEMP);
|
||||
host_arm_MOV_REG(block, REG_PC, REG_LR);
|
||||
|
||||
jump_table[X87_ROUNDING_CHOP] = (uint64_t)(uintptr_t)&block->data[block_pos]; //zero
|
||||
jump_table[X87_ROUNDING_CHOP] = (uint64_t)(uintptr_t)&block_write_data[block_pos]; //zero
|
||||
host_arm_VCVT_IS_D(block, REG_D_TEMP, REG_D_TEMP);
|
||||
host_arm_MOV_REG(block, REG_PC, REG_LR);
|
||||
}
|
||||
|
|
@ -282,12 +289,6 @@ void codegen_backend_init()
|
|||
{
|
||||
codeblock_t *block;
|
||||
int c;
|
||||
#if defined(__linux__) || defined(__APPLE__)
|
||||
void *start;
|
||||
size_t len;
|
||||
long pagesize = sysconf(_SC_PAGESIZE);
|
||||
long pagemask = ~(pagesize - 1);
|
||||
#endif
|
||||
|
||||
codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t));
|
||||
codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *));
|
||||
|
|
@ -309,11 +310,21 @@ void codegen_backend_init()
|
|||
build_loadstore_routines(&codeblock[block_current]);
|
||||
printf("block_pos=%i\n", block_pos);
|
||||
|
||||
codegen_fp_round = &codeblock[block_current].data[block_pos];
|
||||
codegen_fp_round = &block_write_data[block_pos];
|
||||
build_fp_round_routine(&codeblock[block_current]);
|
||||
|
||||
block_write_data = NULL;
|
||||
codegen_alloc(block, 80);
|
||||
codegen_gpf_rout = &block_write_data[block_pos];
|
||||
host_arm_MOV_IMM(block, REG_R0, 0);
|
||||
host_arm_MOV_IMM(block, REG_R1, 0);
|
||||
host_arm_call(block, x86gpf);
|
||||
|
||||
codegen_exit_rout = &block_write_data[block_pos];
|
||||
host_arm_ADD_IMM(block, REG_HOST_SP, REG_HOST_SP, 0x40);
|
||||
host_arm_LDMIA_WB(block, REG_HOST_SP, REG_MASK_LOCAL | REG_MASK_PC);
|
||||
|
||||
block_write_data = NULL;
|
||||
//fatal("block_pos=%i\n", block_pos);
|
||||
asm("vmrs %0, fpscr\n"
|
||||
: "=r" (cpu_state.old_fp_control)
|
||||
);
|
||||
|
|
@ -331,20 +342,7 @@ void codegen_set_rounding_mode(int mode)
|
|||
/*R10 - cpu_state*/
|
||||
void codegen_backend_prologue(codeblock_t *block)
|
||||
{
|
||||
block_pos = 0;
|
||||
|
||||
block_pos = BLOCK_GPF_OFFSET;
|
||||
host_arm_MOV_IMM(block, REG_R0, 0);
|
||||
host_arm_MOV_IMM(block, REG_R1, 0);
|
||||
host_arm_call(block, x86gpf);
|
||||
while (block_pos != BLOCK_EXIT_OFFSET)
|
||||
host_arm_nop(block);
|
||||
|
||||
block_pos = BLOCK_EXIT_OFFSET; /*Exit code*/
|
||||
host_arm_ADD_IMM(block, REG_HOST_SP, REG_HOST_SP, 0x40);
|
||||
host_arm_LDMIA_WB(block, REG_HOST_SP, REG_MASK_LOCAL | REG_MASK_PC);
|
||||
while (block_pos != BLOCK_START)
|
||||
host_arm_nop(block);
|
||||
block_pos = BLOCK_START;
|
||||
|
||||
/*Entry code*/
|
||||
|
||||
|
|
|
|||
|
|
@ -9,9 +9,6 @@
|
|||
|
||||
#define HASH(l) ((l) & 0x1ffff)
|
||||
|
||||
#define BLOCK_GPF_OFFSET 0
|
||||
#define BLOCK_EXIT_OFFSET 32
|
||||
|
||||
#define BLOCK_MAX 0x3c0
|
||||
|
||||
void host_arm_ADD_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm);
|
||||
|
|
@ -23,3 +20,5 @@ void host_arm_SUB_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm
|
|||
|
||||
void host_arm_call(codeblock_t *block, void *dst_addr);
|
||||
void host_arm_nop(codeblock_t *block);
|
||||
|
||||
void codegen_alloc(codeblock_t *block, int size);
|
||||
|
|
@ -36,6 +36,9 @@ void *codegen_mem_store_double;
|
|||
void *codegen_fp_round;
|
||||
void *codegen_fp_round_quad;
|
||||
|
||||
void *codegen_gpf_rout;
|
||||
void *codegen_exit_rout;
|
||||
|
||||
int codegen_host_reg_list[CODEGEN_HOST_REGS] =
|
||||
{
|
||||
REG_X19,
|
||||
|
|
@ -308,8 +311,25 @@ void codegen_backend_init()
|
|||
codegen_fp_round_quad = &block_write_data[block_pos];
|
||||
build_fp_round_routine(block, 1);
|
||||
|
||||
codegen_alloc(block, 80);
|
||||
codegen_gpf_rout = &block_write_data[block_pos];
|
||||
host_arm64_mov_imm(block, REG_ARG0, 0);
|
||||
host_arm64_mov_imm(block, REG_ARG1, 0);
|
||||
host_arm64_call(block, x86gpf);
|
||||
|
||||
codegen_exit_rout = &block_write_data[block_pos];
|
||||
host_arm64_LDP_POSTIDX_X(block, REG_X19, REG_X20, REG_SP, 64);
|
||||
host_arm64_LDP_POSTIDX_X(block, REG_X21, REG_X22, REG_SP, 16);
|
||||
host_arm64_LDP_POSTIDX_X(block, REG_X23, REG_X24, REG_SP, 16);
|
||||
host_arm64_LDP_POSTIDX_X(block, REG_X25, REG_X26, REG_SP, 16);
|
||||
host_arm64_LDP_POSTIDX_X(block, REG_X27, REG_X28, REG_SP, 16);
|
||||
host_arm64_LDP_POSTIDX_X(block, REG_X29, REG_X30, REG_SP, 16);
|
||||
host_arm64_RET(block, REG_X30);
|
||||
|
||||
block_write_data = NULL;
|
||||
|
||||
codegen_allocator_clean_blocks(block->head_mem_block);
|
||||
|
||||
asm("mrs %0, fpcr\n"
|
||||
: "=r" (cpu_state.old_fp_control)
|
||||
);
|
||||
|
|
@ -325,28 +345,7 @@ void codegen_set_rounding_mode(int mode)
|
|||
/*R10 - cpu_state*/
|
||||
void codegen_backend_prologue(codeblock_t *block)
|
||||
{
|
||||
int offset;
|
||||
|
||||
block_pos = 0;
|
||||
|
||||
block_pos = BLOCK_GPF_OFFSET;
|
||||
host_arm64_mov_imm(block, REG_ARG0, 0);
|
||||
host_arm64_mov_imm(block, REG_ARG1, 0);
|
||||
host_arm64_call(block, x86gpf);
|
||||
while (block_pos != BLOCK_EXIT_OFFSET)
|
||||
host_arm64_NOP(block);
|
||||
|
||||
block_pos = BLOCK_EXIT_OFFSET; /*Exit code*/
|
||||
host_arm64_LDP_POSTIDX_X(block, REG_X19, REG_X20, REG_SP, 64);
|
||||
host_arm64_LDP_POSTIDX_X(block, REG_X21, REG_X22, REG_SP, 16);
|
||||
host_arm64_LDP_POSTIDX_X(block, REG_X23, REG_X24, REG_SP, 16);
|
||||
host_arm64_LDP_POSTIDX_X(block, REG_X25, REG_X26, REG_SP, 16);
|
||||
host_arm64_LDP_POSTIDX_X(block, REG_X27, REG_X28, REG_SP, 16);
|
||||
host_arm64_LDP_POSTIDX_X(block, REG_X29, REG_X30, REG_SP, 16);
|
||||
host_arm64_RET(block, REG_X30);
|
||||
|
||||
while (block_pos != BLOCK_START)
|
||||
host_arm64_NOP(block);
|
||||
block_pos = BLOCK_START;
|
||||
|
||||
/*Entry code*/
|
||||
|
||||
|
|
|
|||
|
|
@ -9,9 +9,6 @@
|
|||
|
||||
#define HASH(l) ((l) & 0x1ffff)
|
||||
|
||||
#define BLOCK_GPF_OFFSET 0
|
||||
#define BLOCK_EXIT_OFFSET 32
|
||||
|
||||
#define BLOCK_MAX 0x3c0
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -129,4 +129,7 @@ extern void *codegen_mem_store_single;
|
|||
extern void *codegen_mem_store_double;
|
||||
|
||||
extern void *codegen_fp_round;
|
||||
extern void *codegen_fp_round_quad;
|
||||
extern void *codegen_fp_round_quad;
|
||||
|
||||
extern void *codegen_gpf_rout;
|
||||
extern void *codegen_exit_rout;
|
||||
|
|
@ -599,9 +599,14 @@ void host_arm64_BIC_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int sr
|
|||
|
||||
void host_arm64_CBNZ(codeblock_t *block, int reg, uintptr_t dest)
|
||||
{
|
||||
int offset = dest - (uintptr_t)&block_write_data[block_pos];
|
||||
int offset;
|
||||
|
||||
codegen_alloc(block, 4);
|
||||
offset = dest - (uintptr_t)&block_write_data[block_pos];
|
||||
if (offset_is_19bit(offset))
|
||||
{
|
||||
codegen_addlong(block, OPCODE_CBNZ | OFFSET19(offset) | Rt(reg));
|
||||
}
|
||||
else
|
||||
{
|
||||
codegen_alloc(block, 12);
|
||||
|
|
|
|||
|
|
@ -242,7 +242,7 @@ static int codegen_CALL_FUNC_RESULT(codeblock_t *block, uop_t *uop)
|
|||
static int codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_arm64_call(block, uop->p);
|
||||
host_arm64_CBNZ(block, REG_X0, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_arm64_CBNZ(block, REG_X0, (uintptr_t)codegen_exit_rout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -777,7 +777,7 @@ static int codegen_FP_ENTER(codeblock_t *block, uop_t *uop)
|
|||
host_arm64_STR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.oldpc - (uintptr_t)&cpu_state);
|
||||
host_arm64_mov_imm(block, REG_ARG0, 7);
|
||||
host_arm64_call(block, x86_int);
|
||||
host_arm64_B(block, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_arm64_B(block, codegen_exit_rout);
|
||||
|
||||
host_arm64_branch_set_offset(branch_ptr, &block_write_data[block_pos]);
|
||||
|
||||
|
|
@ -798,7 +798,7 @@ static int codegen_MMX_ENTER(codeblock_t *block, uop_t *uop)
|
|||
host_arm64_STR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.oldpc - (uintptr_t)&cpu_state);
|
||||
host_arm64_mov_imm(block, REG_ARG0, 7);
|
||||
host_arm64_call(block, x86_int);
|
||||
host_arm64_B(block, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_arm64_B(block, codegen_exit_rout);
|
||||
|
||||
host_arm64_branch_set_offset(branch_ptr, &block->data[block_pos]);
|
||||
|
||||
|
|
@ -883,7 +883,7 @@ static int codegen_LOAD_SEG(codeblock_t *block, uop_t *uop)
|
|||
host_arm64_MOVX_IMM(block, REG_ARG1, (uint64_t)uop->p);
|
||||
host_arm64_AND_IMM(block, REG_ARG0, src_reg, 0xffff);
|
||||
host_arm64_call(block, (void *)loadseg);
|
||||
host_arm64_CBNZ(block, REG_X0, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_arm64_CBNZ(block, REG_X0, (uintptr_t)codegen_exit_rout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -908,7 +908,7 @@ static int codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop)
|
|||
}
|
||||
else
|
||||
fatal("MEM_LOAD_ABS - %02x\n", uop->dest_reg_a_real);
|
||||
host_arm64_CBNZ(block, REG_X1, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout);
|
||||
if (REG_IS_B(dest_size))
|
||||
{
|
||||
host_arm64_BFI(block, dest_reg, REG_X0, 0, 8);
|
||||
|
|
@ -954,7 +954,7 @@ static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop)
|
|||
}
|
||||
else
|
||||
fatal("MEM_LOAD_REG - %02x\n", uop->dest_reg_a_real);
|
||||
host_arm64_CBNZ(block, REG_X1, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout);
|
||||
if (REG_IS_B(dest_size))
|
||||
{
|
||||
host_arm64_BFI(block, dest_reg, REG_X0, 0, 8);
|
||||
|
|
@ -990,7 +990,7 @@ static int codegen_MEM_LOAD_DOUBLE(codeblock_t *block, uop_t *uop)
|
|||
if (uop->imm_data)
|
||||
host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data);
|
||||
host_arm64_call(block, codegen_mem_load_double);
|
||||
host_arm64_CBNZ(block, REG_X1, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout);
|
||||
host_arm64_FMOV_D_D(block, dest_reg, REG_V_TEMP);
|
||||
|
||||
return 0;
|
||||
|
|
@ -1007,7 +1007,7 @@ static int codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop)
|
|||
if (uop->imm_data)
|
||||
host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data);
|
||||
host_arm64_call(block, codegen_mem_load_single);
|
||||
host_arm64_CBNZ(block, REG_X1, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout);
|
||||
host_arm64_FCVT_D_S(block, dest_reg, REG_V_TEMP);
|
||||
|
||||
return 0;
|
||||
|
|
@ -1041,7 +1041,7 @@ static int codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop)
|
|||
}
|
||||
else
|
||||
fatal("MEM_STORE_ABS - %02x\n", uop->dest_reg_a_real);
|
||||
host_arm64_CBNZ(block, REG_X1, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1080,7 +1080,7 @@ static int codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop)
|
|||
}
|
||||
else
|
||||
fatal("MEM_STORE_REG - %02x\n", uop->src_reg_c_real);
|
||||
host_arm64_CBNZ(block, REG_X1, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1092,7 +1092,7 @@ static int codegen_MEM_STORE_IMM_8(codeblock_t *block, uop_t *uop)
|
|||
host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0);
|
||||
host_arm64_mov_imm(block, REG_W1, uop->imm_data);
|
||||
host_arm64_call(block, codegen_mem_store_byte);
|
||||
host_arm64_CBNZ(block, REG_X1, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1103,7 +1103,7 @@ static int codegen_MEM_STORE_IMM_16(codeblock_t *block, uop_t *uop)
|
|||
host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0);
|
||||
host_arm64_mov_imm(block, REG_W1, uop->imm_data);
|
||||
host_arm64_call(block, codegen_mem_store_word);
|
||||
host_arm64_CBNZ(block, REG_X1, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1114,7 +1114,7 @@ static int codegen_MEM_STORE_IMM_32(codeblock_t *block, uop_t *uop)
|
|||
host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0);
|
||||
host_arm64_mov_imm(block, REG_W1, uop->imm_data);
|
||||
host_arm64_call(block, codegen_mem_store_long);
|
||||
host_arm64_CBNZ(block, REG_X1, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1132,7 +1132,7 @@ static int codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop)
|
|||
host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data);
|
||||
host_arm64_FCVT_S_D(block, REG_V_TEMP, src_reg);
|
||||
host_arm64_call(block, codegen_mem_store_single);
|
||||
host_arm64_CBNZ(block, REG_X1, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1149,7 +1149,7 @@ static int codegen_MEM_STORE_DOUBLE(codeblock_t *block, uop_t *uop)
|
|||
host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data);
|
||||
host_arm64_FMOV_D_D(block, REG_V_TEMP, src_reg);
|
||||
host_arm64_call(block, codegen_mem_store_double);
|
||||
host_arm64_CBNZ(block, REG_X1, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,4 +83,7 @@ extern void *codegen_mem_store_quad;
|
|||
extern void *codegen_mem_store_single;
|
||||
extern void *codegen_mem_store_double;
|
||||
|
||||
extern void *codegen_fp_round;
|
||||
extern void *codegen_fp_round;
|
||||
|
||||
extern void *codegen_gpf_rout;
|
||||
extern void *codegen_exit_rout;
|
||||
|
|
|
|||
|
|
@ -230,6 +230,12 @@ static inline void codegen_alloc_4(codeblock_t *block)
|
|||
codegen_allocate_new_block(block);
|
||||
}
|
||||
|
||||
void codegen_alloc(codeblock_t *block, int size)
|
||||
{
|
||||
if (block_pos >= (BLOCK_MAX-size))
|
||||
codegen_allocate_new_block(block);
|
||||
}
|
||||
|
||||
static inline uint32_t arm_data_offset(int offset)
|
||||
{
|
||||
if (offset < -0xffc || offset > 0xffc)
|
||||
|
|
|
|||
|
|
@ -317,7 +317,7 @@ static int codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop)
|
|||
{
|
||||
host_arm_call(block, uop->p);
|
||||
host_arm_TST_REG(block, REG_R0, REG_R0);
|
||||
host_arm_BNE(block, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_arm_BNE(block, (uintptr_t)codegen_exit_rout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -848,7 +848,7 @@ static int codegen_FP_ENTER(codeblock_t *block, uop_t *uop)
|
|||
host_arm_STR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.oldpc - (uintptr_t)&cpu_state);
|
||||
host_arm_MOV_IMM(block, REG_ARG0, 7);
|
||||
host_arm_call(block, x86_int);
|
||||
host_arm_B(block, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_arm_B(block, (uintptr_t)codegen_exit_rout);
|
||||
|
||||
*branch_ptr |= ((((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_ptr) - 8) & 0x3fffffc) >> 2;
|
||||
|
||||
|
|
@ -869,7 +869,7 @@ static int codegen_MMX_ENTER(codeblock_t *block, uop_t *uop)
|
|||
host_arm_STR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.oldpc - (uintptr_t)&cpu_state);
|
||||
host_arm_MOV_IMM(block, REG_ARG0, 7);
|
||||
host_arm_call(block, x86_int);
|
||||
host_arm_B(block, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_arm_B(block, (uintptr_t)codegen_exit_rout);
|
||||
|
||||
*branch_ptr |= ((((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_ptr) - 8) & 0x3fffffc) >> 2;
|
||||
|
||||
|
|
@ -951,7 +951,7 @@ static int codegen_LOAD_SEG(codeblock_t *block, uop_t *uop)
|
|||
host_arm_MOV_IMM(block, REG_ARG1, (uint32_t)uop->p);
|
||||
host_arm_call(block, loadseg);
|
||||
host_arm_TST_REG(block, REG_R0, REG_R0);
|
||||
host_arm_BNE(block, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_arm_BNE(block, (uintptr_t)codegen_exit_rout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -977,7 +977,7 @@ static int codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop)
|
|||
else
|
||||
fatal("MEM_LOAD_ABS - %02x\n", uop->dest_reg_a_real);
|
||||
host_arm_TST_REG(block, REG_R1, REG_R1);
|
||||
host_arm_BNE(block, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_arm_BNE(block, (uintptr_t)codegen_exit_rout);
|
||||
if (REG_IS_B(dest_size))
|
||||
{
|
||||
host_arm_BFI(block, dest_reg, REG_R0, 0, 8);
|
||||
|
|
@ -1025,7 +1025,7 @@ static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop)
|
|||
else
|
||||
fatal("MEM_LOAD_REG - %02x\n", uop->dest_reg_a_real);
|
||||
host_arm_TST_REG(block, REG_R1, REG_R1);
|
||||
host_arm_BNE(block, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_arm_BNE(block, (uintptr_t)codegen_exit_rout);
|
||||
if (REG_IS_B(dest_size))
|
||||
{
|
||||
host_arm_BFI(block, dest_reg, REG_R0, 0, 8);
|
||||
|
|
@ -1062,7 +1062,7 @@ static int codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop)
|
|||
host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data);
|
||||
host_arm_BL(block, (uintptr_t)codegen_mem_load_single);
|
||||
host_arm_TST_REG(block, REG_R1, REG_R1);
|
||||
host_arm_BNE(block, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_arm_BNE(block, (uintptr_t)codegen_exit_rout);
|
||||
host_arm_VCVT_D_S(block, dest_reg, REG_D_TEMP);
|
||||
|
||||
return 0;
|
||||
|
|
@ -1080,7 +1080,7 @@ static int codegen_MEM_LOAD_DOUBLE(codeblock_t *block, uop_t *uop)
|
|||
host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data);
|
||||
host_arm_BL(block, (uintptr_t)codegen_mem_load_double);
|
||||
host_arm_TST_REG(block, REG_R1, REG_R1);
|
||||
host_arm_BNE(block, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_arm_BNE(block, (uintptr_t)codegen_exit_rout);
|
||||
host_arm_VMOV_D_D(block, dest_reg, REG_D_TEMP);
|
||||
|
||||
return 0;
|
||||
|
|
@ -1110,7 +1110,7 @@ static int codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop)
|
|||
else
|
||||
fatal("MEM_STORE_ABS - %02x\n", uop->src_reg_b_real);
|
||||
host_arm_TST_REG(block, REG_R1, REG_R1);
|
||||
host_arm_BNE(block, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_arm_BNE(block, (uintptr_t)codegen_exit_rout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1151,7 +1151,7 @@ static int codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop)
|
|||
else
|
||||
fatal("MEM_STORE_REG - %02x\n", uop->src_reg_c_real);
|
||||
host_arm_TST_REG(block, REG_R1, REG_R1);
|
||||
host_arm_BNE(block, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_arm_BNE(block, (uintptr_t)codegen_exit_rout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1164,7 +1164,7 @@ static int codegen_MEM_STORE_IMM_8(codeblock_t *block, uop_t *uop)
|
|||
host_arm_MOV_IMM(block, REG_R1, uop->imm_data);
|
||||
host_arm_BL(block, (uintptr_t)codegen_mem_store_byte);
|
||||
host_arm_TST_REG(block, REG_R1, REG_R1);
|
||||
host_arm_BNE(block, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_arm_BNE(block, (uintptr_t)codegen_exit_rout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1176,7 +1176,7 @@ static int codegen_MEM_STORE_IMM_16(codeblock_t *block, uop_t *uop)
|
|||
host_arm_MOV_IMM(block, REG_R1, uop->imm_data);
|
||||
host_arm_BL(block, (uintptr_t)codegen_mem_store_word);
|
||||
host_arm_TST_REG(block, REG_R1, REG_R1);
|
||||
host_arm_BNE(block, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_arm_BNE(block, (uintptr_t)codegen_exit_rout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1188,7 +1188,7 @@ static int codegen_MEM_STORE_IMM_32(codeblock_t *block, uop_t *uop)
|
|||
host_arm_MOV_IMM(block, REG_R1, uop->imm_data);
|
||||
host_arm_BL(block, (uintptr_t)codegen_mem_store_long);
|
||||
host_arm_TST_REG(block, REG_R1, REG_R1);
|
||||
host_arm_BNE(block, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_arm_BNE(block, (uintptr_t)codegen_exit_rout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1206,7 +1206,7 @@ static int codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop)
|
|||
host_arm_VCVT_S_D(block, REG_D_TEMP, src_reg);
|
||||
host_arm_BL(block, (uintptr_t)codegen_mem_store_single);
|
||||
host_arm_TST_REG(block, REG_R1, REG_R1);
|
||||
host_arm_BNE(block, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_arm_BNE(block, (uintptr_t)codegen_exit_rout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1224,7 +1224,7 @@ static int codegen_MEM_STORE_DOUBLE(codeblock_t *block, uop_t *uop)
|
|||
host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg);
|
||||
host_arm_BL(block, (uintptr_t)codegen_mem_store_double);
|
||||
host_arm_TST_REG(block, REG_R1, REG_R1);
|
||||
host_arm_BNE(block, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_arm_BNE(block, (uintptr_t)codegen_exit_rout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,9 @@ void *codegen_mem_store_quad;
|
|||
void *codegen_mem_store_single;
|
||||
void *codegen_mem_store_double;
|
||||
|
||||
void *codegen_gpf_rout;
|
||||
void *codegen_exit_rout;
|
||||
|
||||
int codegen_host_reg_list[CODEGEN_HOST_REGS] =
|
||||
{
|
||||
REG_EAX,
|
||||
|
|
@ -49,8 +52,6 @@ int codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] =
|
|||
REG_XMM6
|
||||
};
|
||||
|
||||
static void *mem_abrt_rout;
|
||||
|
||||
static void build_load_routine(codeblock_t *block, int size, int is_float)
|
||||
{
|
||||
uint8_t *branch_offset;
|
||||
|
|
@ -274,6 +275,7 @@ static void build_loadstore_routines(codeblock_t *block)
|
|||
|
||||
void codegen_backend_init()
|
||||
{
|
||||
codeblock_t *block;
|
||||
int c;
|
||||
#if defined(__linux__) || defined(__APPLE__)
|
||||
void *start;
|
||||
|
|
@ -295,10 +297,33 @@ void codegen_backend_init()
|
|||
|
||||
block_current = 0;
|
||||
block_pos = 0;
|
||||
block = &codeblock[block_current];
|
||||
codeblock[block_current].head_mem_block = codegen_allocator_allocate(NULL);
|
||||
codeblock[block_current].data = codeblock_allocator_get_ptr(codeblock[block_current].head_mem_block);
|
||||
block_write_data = codeblock[block_current].data;
|
||||
build_loadstore_routines(&codeblock[block_current]);
|
||||
|
||||
codegen_gpf_rout = &codeblock[block_current].data[block_pos];
|
||||
#if WIN64
|
||||
host_x86_XOR32_REG_REG(block, REG_ECX, REG_ECX, REG_ECX);
|
||||
host_x86_XOR32_REG_REG(block, REG_EDX, REG_EDX, REG_EDX);
|
||||
#else
|
||||
host_x86_XOR32_REG_REG(block, REG_EDI, REG_EDI, REG_EDI);
|
||||
host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI, REG_ESI);
|
||||
#endif
|
||||
host_x86_CALL(block, (uintptr_t)x86gpf);
|
||||
codegen_exit_rout = &codeblock[block_current].data[block_pos];
|
||||
host_x86_ADD32_REG_IMM(block, REG_ESP, REG_ESP, 0x38);
|
||||
host_x86_POP(block, REG_R15);
|
||||
host_x86_POP(block, REG_R14);
|
||||
host_x86_POP(block, REG_R13);
|
||||
host_x86_POP(block, REG_R12);
|
||||
host_x86_POP(block, REG_RDI);
|
||||
host_x86_POP(block, REG_RSI);
|
||||
host_x86_POP(block, REG_RBP);
|
||||
host_x86_POP(block, REG_RDX);
|
||||
host_x86_RET(block);
|
||||
|
||||
block_write_data = NULL;
|
||||
|
||||
asm(
|
||||
|
|
@ -315,33 +340,6 @@ void codegen_set_rounding_mode(int mode)
|
|||
|
||||
void codegen_backend_prologue(codeblock_t *block)
|
||||
{
|
||||
block_pos = BLOCK_GPF_OFFSET;
|
||||
#if WIN64
|
||||
host_x86_XOR32_REG_REG(block, REG_ECX, REG_ECX, REG_ECX);
|
||||
host_x86_XOR32_REG_REG(block, REG_EDX, REG_EDX, REG_EDX);
|
||||
#else
|
||||
host_x86_XOR32_REG_REG(block, REG_EDI, REG_EDI, REG_EDI);
|
||||
host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI, REG_ESI);
|
||||
#endif
|
||||
host_x86_CALL(block, (uintptr_t)x86gpf);
|
||||
while (block_pos < BLOCK_EXIT_OFFSET)
|
||||
host_x86_NOP(block);
|
||||
if (block_pos > BLOCK_EXIT_OFFSET)
|
||||
fatal("block_pos > BLOCK_EXIT_OFFSET\n");
|
||||
block_pos = BLOCK_EXIT_OFFSET; /*Exit code*/
|
||||
host_x86_ADD32_REG_IMM(block, REG_ESP, REG_ESP, 0x38);
|
||||
host_x86_POP(block, REG_R15);
|
||||
host_x86_POP(block, REG_R14);
|
||||
host_x86_POP(block, REG_R13);
|
||||
host_x86_POP(block, REG_R12);
|
||||
host_x86_POP(block, REG_RDI);
|
||||
host_x86_POP(block, REG_RSI);
|
||||
host_x86_POP(block, REG_RBP);
|
||||
host_x86_POP(block, REG_RDX);
|
||||
host_x86_RET(block);
|
||||
if (block_pos > BLOCK_START)
|
||||
fatal("block_pos > BLOCK_START\n");
|
||||
|
||||
block_pos = BLOCK_START; /*Entry code*/
|
||||
host_x86_PUSH(block, REG_RBX);
|
||||
host_x86_PUSH(block, REG_RBP);
|
||||
|
|
|
|||
|
|
@ -2,14 +2,11 @@
|
|||
|
||||
#define BLOCK_SIZE 0x4000
|
||||
#define BLOCK_MASK 0x3fff
|
||||
#define BLOCK_START 40
|
||||
#define BLOCK_START 0
|
||||
|
||||
#define HASH_SIZE 0x20000
|
||||
#define HASH_MASK 0x1ffff
|
||||
|
||||
#define HASH(l) ((l) & 0x1ffff)
|
||||
|
||||
#define BLOCK_EXIT_OFFSET 20
|
||||
#define BLOCK_GPF_OFFSET 0
|
||||
|
||||
#define BLOCK_MAX 0x3c0
|
||||
|
|
|
|||
|
|
@ -60,3 +60,6 @@ extern void *codegen_mem_store_long;
|
|||
extern void *codegen_mem_store_quad;
|
||||
extern void *codegen_mem_store_single;
|
||||
extern void *codegen_mem_store_double;
|
||||
|
||||
extern void *codegen_gpf_rout;
|
||||
extern void *codegen_exit_rout;
|
||||
|
|
|
|||
|
|
@ -197,7 +197,7 @@ static int codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop)
|
|||
{
|
||||
host_x86_CALL(block, uop->p);
|
||||
host_x86_TEST32_REG(block, REG_EAX, REG_EAX);
|
||||
host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_x86_JNZ(block, codegen_exit_rout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -727,7 +727,7 @@ static int codegen_FP_ENTER(codeblock_t *block, uop_t *uop)
|
|||
host_x86_MOV32_REG_IMM(block, REG_EDI, 7);
|
||||
#endif
|
||||
host_x86_CALL(block, x86_int);
|
||||
host_x86_JMP(block, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_x86_JMP(block, codegen_exit_rout);
|
||||
*branch_offset = (uint32_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 4;
|
||||
|
||||
return 0;
|
||||
|
|
@ -746,7 +746,7 @@ static int codegen_MMX_ENTER(codeblock_t *block, uop_t *uop)
|
|||
host_x86_MOV32_REG_IMM(block, REG_EDI, 7);
|
||||
#endif
|
||||
host_x86_CALL(block, x86_int);
|
||||
host_x86_JMP(block, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_x86_JMP(block, codegen_exit_rout);
|
||||
*branch_offset = (uint32_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 4;
|
||||
host_x86_MOV32_ABS_IMM(block, &cpu_state.tag[0], 0);
|
||||
host_x86_MOV32_ABS_IMM(block, &cpu_state.tag[4], 0);
|
||||
|
|
@ -842,7 +842,7 @@ static int codegen_LOAD_SEG(codeblock_t *block, uop_t *uop)
|
|||
#endif
|
||||
host_x86_CALL(block, (void *)loadseg);
|
||||
host_x86_TEST32_REG(block, REG_EAX, REG_EAX);
|
||||
host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_x86_JNZ(block, codegen_exit_rout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -868,7 +868,7 @@ static int codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop)
|
|||
else
|
||||
fatal("MEM_LOAD_ABS - %02x\n", uop->dest_reg_a_real);
|
||||
host_x86_TEST32_REG(block, REG_ESI, REG_ESI);
|
||||
host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_x86_JNZ(block, codegen_exit_rout);
|
||||
if (REG_IS_B(dest_size))
|
||||
{
|
||||
host_x86_MOV8_REG_REG(block, dest_reg, REG_ECX);
|
||||
|
|
@ -911,7 +911,7 @@ static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop)
|
|||
else
|
||||
fatal("MEM_LOAD_REG - %02x\n", uop->dest_reg_a_real);
|
||||
host_x86_TEST32_REG(block, REG_ESI, REG_ESI);
|
||||
host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_x86_JNZ(block, codegen_exit_rout);
|
||||
if (REG_IS_B(dest_size))
|
||||
{
|
||||
host_x86_MOV8_REG_REG(block, dest_reg, REG_ECX);
|
||||
|
|
@ -944,7 +944,7 @@ static int codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop)
|
|||
host_x86_ADD32_REG_IMM(block, REG_ESI, REG_ESI, uop->imm_data);
|
||||
host_x86_CALL(block, codegen_mem_load_single);
|
||||
host_x86_TEST32_REG(block, REG_ESI, REG_ESI);
|
||||
host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_x86_JNZ(block, codegen_exit_rout);
|
||||
host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP);
|
||||
|
||||
return 0;
|
||||
|
|
@ -962,7 +962,7 @@ static int codegen_MEM_LOAD_DOUBLE(codeblock_t *block, uop_t *uop)
|
|||
host_x86_ADD32_REG_IMM(block, REG_ESI, REG_ESI, uop->imm_data);
|
||||
host_x86_CALL(block, codegen_mem_load_double);
|
||||
host_x86_TEST32_REG(block, REG_ESI, REG_ESI);
|
||||
host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_x86_JNZ(block, codegen_exit_rout);
|
||||
host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP);
|
||||
|
||||
return 0;
|
||||
|
|
@ -992,7 +992,7 @@ static int codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop)
|
|||
else
|
||||
fatal("MEM_STORE_ABS - %02x\n", uop->src_reg_b_real);
|
||||
host_x86_TEST32_REG(block, REG_ESI, REG_ESI);
|
||||
host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_x86_JNZ(block, codegen_exit_rout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1005,7 +1005,7 @@ static int codegen_MEM_STORE_IMM_8(codeblock_t *block, uop_t *uop)
|
|||
host_x86_MOV8_REG_IMM(block, REG_ECX, uop->imm_data);
|
||||
host_x86_CALL(block, codegen_mem_store_byte);
|
||||
host_x86_TEST32_REG(block, REG_ESI, REG_ESI);
|
||||
host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_x86_JNZ(block, codegen_exit_rout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1017,7 +1017,7 @@ static int codegen_MEM_STORE_IMM_16(codeblock_t *block, uop_t *uop)
|
|||
host_x86_MOV16_REG_IMM(block, REG_ECX, uop->imm_data);
|
||||
host_x86_CALL(block, codegen_mem_store_word);
|
||||
host_x86_TEST32_REG(block, REG_ESI, REG_ESI);
|
||||
host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_x86_JNZ(block, codegen_exit_rout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1029,7 +1029,7 @@ static int codegen_MEM_STORE_IMM_32(codeblock_t *block, uop_t *uop)
|
|||
host_x86_MOV32_REG_IMM(block, REG_ECX, uop->imm_data);
|
||||
host_x86_CALL(block, codegen_mem_store_long);
|
||||
host_x86_TEST32_REG(block, REG_ESI, REG_ESI);
|
||||
host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_x86_JNZ(block, codegen_exit_rout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1065,7 +1065,7 @@ static int codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop)
|
|||
else
|
||||
fatal("MEM_STORE_REG - %02x\n", uop->src_reg_b_real);
|
||||
host_x86_TEST32_REG(block, REG_ESI, REG_ESI);
|
||||
host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_x86_JNZ(block, codegen_exit_rout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1084,7 +1084,7 @@ static int codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop)
|
|||
host_x86_CVTSD2SS_XREG_XREG(block, REG_XMM_TEMP, src_reg);
|
||||
host_x86_CALL(block, codegen_mem_store_single);
|
||||
host_x86_TEST32_REG(block, REG_ESI, REG_ESI);
|
||||
host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_x86_JNZ(block, codegen_exit_rout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1102,7 +1102,7 @@ static int codegen_MEM_STORE_DOUBLE(codeblock_t *block, uop_t *uop)
|
|||
host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg);
|
||||
host_x86_CALL(block, codegen_mem_store_double);
|
||||
host_x86_TEST32_REG(block, REG_ESI, REG_ESI);
|
||||
host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_x86_JNZ(block, codegen_exit_rout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,9 @@ void *codegen_mem_store_quad;
|
|||
void *codegen_mem_store_single;
|
||||
void *codegen_mem_store_double;
|
||||
|
||||
void *codegen_gpf_rout;
|
||||
void *codegen_exit_rout;
|
||||
|
||||
int codegen_host_reg_list[CODEGEN_HOST_REGS] =
|
||||
{
|
||||
REG_EAX,
|
||||
|
|
@ -49,8 +52,6 @@ int codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] =
|
|||
REG_XMM5
|
||||
};
|
||||
|
||||
static void *mem_abrt_rout;
|
||||
|
||||
static void build_load_routine(codeblock_t *block, int size, int is_float)
|
||||
{
|
||||
uint8_t *branch_offset;
|
||||
|
|
@ -301,16 +302,19 @@ pclog(" offsetof(codeblock_t, next_2)=%i\n", offsetof(codeblock_t, next_2));
|
|||
block->head_mem_block = codegen_allocator_allocate(NULL);
|
||||
block->data = codeblock_allocator_get_ptr(block->head_mem_block);
|
||||
block_write_data = block->data;
|
||||
mem_abrt_rout = &block->data[block_pos];
|
||||
host_x86_ADD32_REG_IMM(block, REG_ESP, REG_ESP, 0x10+4);
|
||||
build_loadstore_routines(block);
|
||||
|
||||
codegen_gpf_rout = &codeblock[block_current].data[block_pos];
|
||||
host_x86_MOV32_STACK_IMM(block, STACK_ARG0, 0);
|
||||
host_x86_MOV32_STACK_IMM(block, STACK_ARG1, 0);
|
||||
host_x86_CALL(block, (void *)x86gpf);
|
||||
codegen_exit_rout = &codeblock[block_current].data[block_pos];
|
||||
host_x86_ADD32_REG_IMM(block, REG_ESP, REG_ESP, 64);
|
||||
host_x86_POP(block, REG_EDI);
|
||||
host_x86_POP(block, REG_ESI);
|
||||
host_x86_POP(block, REG_EBP);
|
||||
host_x86_POP(block, REG_EDX);
|
||||
host_x86_RET(block);
|
||||
|
||||
block_pos = 64;
|
||||
build_loadstore_routines(block);
|
||||
block_write_data = NULL;
|
||||
|
||||
cpu_state.old_fp_control = 0;
|
||||
|
|
@ -333,18 +337,6 @@ void codegen_set_rounding_mode(int mode)
|
|||
|
||||
void codegen_backend_prologue(codeblock_t *block)
|
||||
{
|
||||
block_pos = BLOCK_GPF_OFFSET;
|
||||
host_x86_MOV32_STACK_IMM(block, STACK_ARG0, 0);
|
||||
host_x86_MOV32_STACK_IMM(block, STACK_ARG1, 0);
|
||||
host_x86_CALL(block, (void *)x86gpf);
|
||||
block_pos = BLOCK_EXIT_OFFSET; /*Exit code*/
|
||||
host_x86_ADD32_REG_IMM(block, REG_ESP, REG_ESP, 64);
|
||||
host_x86_POP(block, REG_EDI);
|
||||
host_x86_POP(block, REG_ESI);
|
||||
host_x86_POP(block, REG_EBP);
|
||||
host_x86_POP(block, REG_EDX);
|
||||
host_x86_RET(block);
|
||||
|
||||
block_pos = BLOCK_START; /*Entry code*/
|
||||
host_x86_PUSH(block, REG_EBX);
|
||||
host_x86_PUSH(block, REG_EBP);
|
||||
|
|
|
|||
|
|
@ -2,14 +2,11 @@
|
|||
|
||||
#define BLOCK_SIZE 0x4000
|
||||
#define BLOCK_MASK 0x3fff
|
||||
#define BLOCK_START 32
|
||||
#define BLOCK_START 0
|
||||
|
||||
#define HASH_SIZE 0x20000
|
||||
#define HASH_MASK 0x1ffff
|
||||
|
||||
#define HASH(l) ((l) & 0x1ffff)
|
||||
|
||||
#define BLOCK_EXIT_OFFSET 20
|
||||
#define BLOCK_GPF_OFFSET 0
|
||||
|
||||
#define BLOCK_MAX 0x3c0
|
||||
|
|
|
|||
|
|
@ -39,6 +39,9 @@ extern void *codegen_mem_store_quad;
|
|||
extern void *codegen_mem_store_single;
|
||||
extern void *codegen_mem_store_double;
|
||||
|
||||
extern void *codegen_gpf_rout;
|
||||
extern void *codegen_exit_rout;
|
||||
|
||||
#define STACK_ARG0 (0)
|
||||
#define STACK_ARG1 (4)
|
||||
#define STACK_ARG2 (8)
|
||||
|
|
|
|||
|
|
@ -203,7 +203,7 @@ static int codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop)
|
|||
{
|
||||
host_x86_CALL(block, uop->p);
|
||||
host_x86_TEST32_REG(block, REG_EAX, REG_EAX);
|
||||
host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_x86_JNZ(block, codegen_exit_rout);
|
||||
// host_x86_CALL(block, codegen_debug);
|
||||
|
||||
return 0;
|
||||
|
|
@ -730,7 +730,7 @@ static int codegen_FP_ENTER(codeblock_t *block, uop_t *uop)
|
|||
host_x86_MOV32_ABS_IMM(block, &cpu_state.oldpc, uop->imm_data);
|
||||
host_x86_MOV32_STACK_IMM(block, STACK_ARG0, 7);
|
||||
host_x86_CALL(block, x86_int);
|
||||
host_x86_JMP(block, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_x86_JMP(block, codegen_exit_rout);
|
||||
*branch_offset = (uint32_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 4;
|
||||
|
||||
return 0;
|
||||
|
|
@ -746,7 +746,7 @@ static int codegen_MMX_ENTER(codeblock_t *block, uop_t *uop)
|
|||
host_x86_MOV32_ABS_IMM(block, &cpu_state.oldpc, uop->imm_data);
|
||||
host_x86_MOV32_STACK_IMM(block, STACK_ARG0, 7);
|
||||
host_x86_CALL(block, x86_int);
|
||||
host_x86_JMP(block, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_x86_JMP(block, codegen_exit_rout);
|
||||
*branch_offset = (uint32_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 4;
|
||||
host_x86_MOV32_ABS_IMM(block, &cpu_state.tag[0], 0);
|
||||
host_x86_MOV32_ABS_IMM(block, &cpu_state.tag[4], 0);
|
||||
|
|
@ -831,7 +831,7 @@ static int codegen_LOAD_SEG(codeblock_t *block, uop_t *uop)
|
|||
host_x86_MOV32_STACK_IMM(block, STACK_ARG1, (uint32_t)uop->p);
|
||||
host_x86_CALL(block, loadseg);
|
||||
host_x86_TEST32_REG(block, REG_EAX, REG_EAX);
|
||||
host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_x86_JNZ(block, codegen_exit_rout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -857,7 +857,7 @@ static int codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop)
|
|||
else
|
||||
fatal("MEM_LOAD_ABS - %02x\n", uop->dest_reg_a_real);
|
||||
host_x86_TEST32_REG(block, REG_ESI, REG_ESI);
|
||||
host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_x86_JNZ(block, codegen_exit_rout);
|
||||
if (REG_IS_B(dest_size))
|
||||
{
|
||||
host_x86_MOV8_REG_REG(block, dest_reg, REG_ECX);
|
||||
|
|
@ -900,7 +900,7 @@ static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop)
|
|||
else
|
||||
fatal("MEM_LOAD_REG - %02x\n", uop->dest_reg_a_real);
|
||||
host_x86_TEST32_REG(block, REG_ESI, REG_ESI);
|
||||
host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_x86_JNZ(block, codegen_exit_rout);
|
||||
if (REG_IS_B(dest_size))
|
||||
{
|
||||
host_x86_MOV8_REG_REG(block, dest_reg, REG_ECX);
|
||||
|
|
@ -933,7 +933,7 @@ static int codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop)
|
|||
host_x86_ADD32_REG_IMM(block, REG_ESI, REG_ESI, uop->imm_data);
|
||||
host_x86_CALL(block, codegen_mem_load_single);
|
||||
host_x86_TEST32_REG(block, REG_ESI, REG_ESI);
|
||||
host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_x86_JNZ(block, codegen_exit_rout);
|
||||
host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP);
|
||||
|
||||
return 0;
|
||||
|
|
@ -952,7 +952,7 @@ static int codegen_MEM_LOAD_DOUBLE(codeblock_t *block, uop_t *uop)
|
|||
host_x86_ADD32_REG_IMM(block, REG_ESI, REG_ESI, uop->imm_data);
|
||||
host_x86_CALL(block, codegen_mem_load_double);
|
||||
host_x86_TEST32_REG(block, REG_ESI, REG_ESI);
|
||||
host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_x86_JNZ(block, codegen_exit_rout);
|
||||
host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP);
|
||||
|
||||
return 0;
|
||||
|
|
@ -982,7 +982,7 @@ static int codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop)
|
|||
else
|
||||
fatal("MEM_STORE_ABS - %02x\n", uop->src_reg_b_real);
|
||||
host_x86_TEST32_REG(block, REG_ESI, REG_ESI);
|
||||
host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_x86_JNZ(block, codegen_exit_rout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1018,7 +1018,7 @@ static int codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop)
|
|||
else
|
||||
fatal("MEM_STORE_REG - %02x\n", uop->src_reg_b_real);
|
||||
host_x86_TEST32_REG(block, REG_ESI, REG_ESI);
|
||||
host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_x86_JNZ(block, codegen_exit_rout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1031,7 +1031,7 @@ static int codegen_MEM_STORE_IMM_8(codeblock_t *block, uop_t *uop)
|
|||
host_x86_MOV8_REG_IMM(block, REG_ECX, uop->imm_data);
|
||||
host_x86_CALL(block, codegen_mem_store_byte);
|
||||
host_x86_TEST32_REG(block, REG_ESI, REG_ESI);
|
||||
host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_x86_JNZ(block, codegen_exit_rout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1043,7 +1043,7 @@ static int codegen_MEM_STORE_IMM_16(codeblock_t *block, uop_t *uop)
|
|||
host_x86_MOV16_REG_IMM(block, REG_ECX, uop->imm_data);
|
||||
host_x86_CALL(block, codegen_mem_store_word);
|
||||
host_x86_TEST32_REG(block, REG_ESI, REG_ESI);
|
||||
host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_x86_JNZ(block, codegen_exit_rout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1055,7 +1055,7 @@ static int codegen_MEM_STORE_IMM_32(codeblock_t *block, uop_t *uop)
|
|||
host_x86_MOV32_REG_IMM(block, REG_ECX, uop->imm_data);
|
||||
host_x86_CALL(block, codegen_mem_store_long);
|
||||
host_x86_TEST32_REG(block, REG_ESI, REG_ESI);
|
||||
host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_x86_JNZ(block, codegen_exit_rout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1074,7 +1074,7 @@ static int codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop)
|
|||
host_x86_CVTSD2SS_XREG_XREG(block, REG_XMM_TEMP, src_reg);
|
||||
host_x86_CALL(block, codegen_mem_store_single);
|
||||
host_x86_TEST32_REG(block, REG_ESI, REG_ESI);
|
||||
host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_x86_JNZ(block, codegen_exit_rout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1092,7 +1092,7 @@ static int codegen_MEM_STORE_DOUBLE(codeblock_t *block, uop_t *uop)
|
|||
host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg);
|
||||
host_x86_CALL(block, codegen_mem_store_double);
|
||||
host_x86_TEST32_REG(block, REG_ESI, REG_ESI);
|
||||
host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
host_x86_JNZ(block, codegen_exit_rout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ static void ropJO_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, ui
|
|||
break;
|
||||
}
|
||||
uop_MOV_IMM(ir, IREG_pc, base_pc + offset);
|
||||
uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
uop_JMP(ir, codegen_exit_rout);
|
||||
uop_set_jump_dest(ir, jump_uop);
|
||||
}
|
||||
static void ropJNO_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset)
|
||||
|
|
@ -60,7 +60,7 @@ static void ropJNO_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, u
|
|||
case FLAGS_ZN8: case FLAGS_ZN16: case FLAGS_ZN32:
|
||||
/*Overflow is always zero*/
|
||||
uop_MOV_IMM(ir, IREG_pc, base_pc + offset);
|
||||
uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
uop_JMP(ir, codegen_exit_rout);
|
||||
return;
|
||||
|
||||
case FLAGS_SUB8: case FLAGS_DEC8:
|
||||
|
|
@ -82,7 +82,7 @@ static void ropJNO_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, u
|
|||
break;
|
||||
}
|
||||
uop_MOV_IMM(ir, IREG_pc, base_pc + offset);
|
||||
uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
uop_JMP(ir, codegen_exit_rout);
|
||||
uop_set_jump_dest(ir, jump_uop);
|
||||
}
|
||||
|
||||
|
|
@ -115,7 +115,7 @@ static void ropJB_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, ui
|
|||
break;
|
||||
}
|
||||
uop_MOV_IMM(ir, IREG_pc, base_pc + offset);
|
||||
uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
uop_JMP(ir, codegen_exit_rout);
|
||||
uop_set_jump_dest(ir, jump_uop);
|
||||
}
|
||||
static void ropJNB_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset)
|
||||
|
|
@ -127,7 +127,7 @@ static void ropJNB_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, u
|
|||
case FLAGS_ZN8: case FLAGS_ZN16: case FLAGS_ZN32:
|
||||
/*Carry is always zero*/
|
||||
uop_MOV_IMM(ir, IREG_pc, base_pc + offset);
|
||||
uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
uop_JMP(ir, codegen_exit_rout);
|
||||
return;
|
||||
|
||||
case FLAGS_SUB8:
|
||||
|
|
@ -149,7 +149,7 @@ static void ropJNB_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, u
|
|||
break;
|
||||
}
|
||||
uop_MOV_IMM(ir, IREG_pc, base_pc + offset);
|
||||
uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
uop_JMP(ir, codegen_exit_rout);
|
||||
uop_set_jump_dest(ir, jump_uop);
|
||||
}
|
||||
|
||||
|
|
@ -167,7 +167,7 @@ static void ropJE_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, ui
|
|||
jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_flags_res, 0);
|
||||
}
|
||||
uop_MOV_IMM(ir, IREG_pc, base_pc + offset);
|
||||
uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
uop_JMP(ir, codegen_exit_rout);
|
||||
uop_set_jump_dest(ir, jump_uop);
|
||||
}
|
||||
void ropJNE_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset)
|
||||
|
|
@ -184,7 +184,7 @@ void ropJNE_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t
|
|||
jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_flags_res, 0);
|
||||
}
|
||||
uop_MOV_IMM(ir, IREG_pc, base_pc + offset);
|
||||
uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
uop_JMP(ir, codegen_exit_rout);
|
||||
uop_set_jump_dest(ir, jump_uop);
|
||||
}
|
||||
|
||||
|
|
@ -220,7 +220,7 @@ static void ropJBE_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, u
|
|||
if (jump_uop2 != -1)
|
||||
uop_set_jump_dest(ir, jump_uop2);
|
||||
uop_MOV_IMM(ir, IREG_pc, base_pc + offset);
|
||||
uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
uop_JMP(ir, codegen_exit_rout);
|
||||
uop_set_jump_dest(ir, jump_uop);
|
||||
}
|
||||
static void ropJNBE_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset)
|
||||
|
|
@ -253,7 +253,7 @@ static void ropJNBE_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc,
|
|||
break;
|
||||
}
|
||||
uop_MOV_IMM(ir, IREG_pc, base_pc + offset);
|
||||
uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
uop_JMP(ir, codegen_exit_rout);
|
||||
uop_set_jump_dest(ir, jump_uop);
|
||||
if (jump_uop2 != -1)
|
||||
uop_set_jump_dest(ir, jump_uop2);
|
||||
|
|
@ -305,7 +305,7 @@ static void ropJS_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, ui
|
|||
break;
|
||||
}
|
||||
uop_MOV_IMM(ir, IREG_pc, base_pc + offset);
|
||||
uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
uop_JMP(ir, codegen_exit_rout);
|
||||
uop_set_jump_dest(ir, jump_uop);
|
||||
}
|
||||
static void ropJNS_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset)
|
||||
|
|
@ -354,7 +354,7 @@ static void ropJNS_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, u
|
|||
break;
|
||||
}
|
||||
uop_MOV_IMM(ir, IREG_pc, base_pc + offset);
|
||||
uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
uop_JMP(ir, codegen_exit_rout);
|
||||
uop_set_jump_dest(ir, jump_uop);
|
||||
}
|
||||
|
||||
|
|
@ -365,7 +365,7 @@ static void ropJP_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, ui
|
|||
uop_CALL_FUNC_RESULT(ir, IREG_temp0, PF_SET);
|
||||
jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0);
|
||||
uop_MOV_IMM(ir, IREG_pc, base_pc + offset);
|
||||
uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
uop_JMP(ir, codegen_exit_rout);
|
||||
uop_set_jump_dest(ir, jump_uop);
|
||||
}
|
||||
static void ropJNP_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset)
|
||||
|
|
@ -375,7 +375,7 @@ static void ropJNP_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, u
|
|||
uop_CALL_FUNC_RESULT(ir, IREG_temp0, PF_SET);
|
||||
jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0);
|
||||
uop_MOV_IMM(ir, IREG_pc, base_pc + offset);
|
||||
uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
uop_JMP(ir, codegen_exit_rout);
|
||||
uop_set_jump_dest(ir, jump_uop);
|
||||
}
|
||||
|
||||
|
|
@ -414,7 +414,7 @@ static void ropJL_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, ui
|
|||
break;
|
||||
}
|
||||
uop_MOV_IMM(ir, IREG_pc, base_pc + offset);
|
||||
uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
uop_JMP(ir, codegen_exit_rout);
|
||||
uop_set_jump_dest(ir, jump_uop);
|
||||
}
|
||||
static void ropJNL_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset)
|
||||
|
|
@ -452,7 +452,7 @@ static void ropJNL_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, u
|
|||
break;
|
||||
}
|
||||
uop_MOV_IMM(ir, IREG_pc, base_pc + offset);
|
||||
uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
uop_JMP(ir, codegen_exit_rout);
|
||||
uop_set_jump_dest(ir, jump_uop);
|
||||
}
|
||||
|
||||
|
|
@ -484,7 +484,7 @@ static void ropJLE_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, u
|
|||
if (jump_uop2 != -1)
|
||||
uop_set_jump_dest(ir, jump_uop2);
|
||||
uop_MOV_IMM(ir, IREG_pc, base_pc + offset);
|
||||
uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
uop_JMP(ir, codegen_exit_rout);
|
||||
uop_set_jump_dest(ir, jump_uop);
|
||||
}
|
||||
static void ropJNLE_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset)
|
||||
|
|
@ -513,7 +513,7 @@ static void ropJNLE_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc,
|
|||
break;
|
||||
}
|
||||
uop_MOV_IMM(ir, IREG_pc, base_pc + offset);
|
||||
uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
uop_JMP(ir, codegen_exit_rout);
|
||||
uop_set_jump_dest(ir, jump_uop);
|
||||
if (jump_uop2 != -1)
|
||||
uop_set_jump_dest(ir, jump_uop2);
|
||||
|
|
@ -570,7 +570,7 @@ uint32_t ropJCXZ(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet
|
|||
else
|
||||
jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_CX, 0);
|
||||
uop_MOV_IMM(ir, IREG_pc, op_pc + 1 + offset);
|
||||
uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
uop_JMP(ir, codegen_exit_rout);
|
||||
uop_set_jump_dest(ir, jump_uop);
|
||||
|
||||
return op_pc+1;
|
||||
|
|
@ -592,7 +592,7 @@ uint32_t ropLOOP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet
|
|||
jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_CX, 0);
|
||||
}
|
||||
uop_MOV_IMM(ir, IREG_pc, op_pc + 1 + offset);
|
||||
uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
uop_JMP(ir, codegen_exit_rout);
|
||||
uop_set_jump_dest(ir, jump_uop);
|
||||
|
||||
return op_pc+1;
|
||||
|
|
@ -623,7 +623,7 @@ uint32_t ropLOOPE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe
|
|||
jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_flags_res, 0);
|
||||
}
|
||||
uop_MOV_IMM(ir, IREG_pc, op_pc + 1 + offset);
|
||||
uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
uop_JMP(ir, codegen_exit_rout);
|
||||
uop_set_jump_dest(ir, jump_uop);
|
||||
uop_set_jump_dest(ir, jump_uop2);
|
||||
|
||||
|
|
@ -654,7 +654,7 @@ uint32_t ropLOOPNE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t f
|
|||
jump_uop2 = uop_CMP_IMM_JZ_DEST(ir, IREG_flags_res, 0);
|
||||
}
|
||||
uop_MOV_IMM(ir, IREG_pc, op_pc + 1 + offset);
|
||||
uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
uop_JMP(ir, codegen_exit_rout);
|
||||
uop_set_jump_dest(ir, jump_uop);
|
||||
uop_set_jump_dest(ir, jump_uop2);
|
||||
|
||||
|
|
|
|||
|
|
@ -362,7 +362,7 @@ uint32_t ropD2(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetch
|
|||
return 0;
|
||||
|
||||
uop_AND_IMM(ir, IREG_temp2, REG_ECX, 0x1f);
|
||||
uop_CMP_IMM_JZ(ir, IREG_temp2, 0, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
uop_CMP_IMM_JZ(ir, IREG_temp2, 0, codegen_exit_rout);
|
||||
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
{
|
||||
|
|
@ -453,7 +453,7 @@ uint32_t ropD3_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet
|
|||
return 0;
|
||||
|
||||
uop_AND_IMM(ir, IREG_temp2, REG_ECX, 0x1f);
|
||||
uop_CMP_IMM_JZ(ir, IREG_temp2, 0, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
uop_CMP_IMM_JZ(ir, IREG_temp2, 0, codegen_exit_rout);
|
||||
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
{
|
||||
|
|
@ -544,7 +544,7 @@ uint32_t ropD3_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet
|
|||
return 0;
|
||||
|
||||
uop_AND_IMM(ir, IREG_temp2, REG_ECX, 0x1f);
|
||||
uop_CMP_IMM_JZ(ir, IREG_temp2, 0, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
uop_CMP_IMM_JZ(ir, IREG_temp2, 0, codegen_exit_rout);
|
||||
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue