Added recompiled versions of FLD, FILD, FST and FSTP.
This commit is contained in:
parent
e17a94a409
commit
8a516df476
28 changed files with 1401 additions and 152 deletions
|
|
@ -370,7 +370,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;//recomp_opcodes_d9;
|
||||
recomp_op_table = recomp_opcodes_d9;
|
||||
opcode_mask = 0xff;
|
||||
over = 1;
|
||||
pc_off = -1;
|
||||
|
|
@ -388,7 +388,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;//recomp_opcodes_db;
|
||||
recomp_op_table = recomp_opcodes_db;
|
||||
opcode_mask = 0xff;
|
||||
over = 1;
|
||||
pc_off = -1;
|
||||
|
|
@ -407,7 +407,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;//recomp_opcodes_dd;
|
||||
recomp_op_table = recomp_opcodes_dd;
|
||||
opcode_mask = 0xff;
|
||||
over = 1;
|
||||
pc_off = -1;
|
||||
|
|
@ -425,7 +425,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;//recomp_opcodes_df;
|
||||
recomp_op_table = recomp_opcodes_df;
|
||||
opcode_mask = 0xff;
|
||||
over = 1;
|
||||
pc_off = -1;
|
||||
|
|
|
|||
|
|
@ -20,10 +20,14 @@
|
|||
void *codegen_mem_load_byte;
|
||||
void *codegen_mem_load_word;
|
||||
void *codegen_mem_load_long;
|
||||
void *codegen_mem_load_single;
|
||||
void *codegen_mem_load_double;
|
||||
|
||||
void *codegen_mem_store_byte;
|
||||
void *codegen_mem_store_word;
|
||||
void *codegen_mem_store_long;
|
||||
void *codegen_mem_store_single;
|
||||
void *codegen_mem_store_double;
|
||||
|
||||
int codegen_host_reg_list[CODEGEN_HOST_REGS] =
|
||||
{
|
||||
|
|
@ -48,7 +52,7 @@ int codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] =
|
|||
REG_D15
|
||||
};
|
||||
|
||||
static void build_load_routine(codeblock_t *block, int size)
|
||||
static void build_load_routine(codeblock_t *block, int size, int is_float)
|
||||
{
|
||||
uint32_t *branch_offset;
|
||||
uint32_t *misaligned_offset;
|
||||
|
|
@ -78,12 +82,22 @@ static void build_load_routine(codeblock_t *block, int size)
|
|||
}
|
||||
host_arm_CMP_IMM(block, REG_R1, -1);
|
||||
branch_offset = host_arm_BEQ_(block);
|
||||
if (size == 1)
|
||||
if (size == 1 && !is_float)
|
||||
host_arm_LDRB_REG(block, REG_R0, REG_R1, REG_R0);
|
||||
else if (size == 2)
|
||||
else if (size == 2 && !is_float)
|
||||
host_arm_LDRH_REG(block, REG_R0, REG_R1, REG_R0);
|
||||
else if (size == 4)
|
||||
else if (size == 4 && !is_float)
|
||||
host_arm_LDR_REG(block, REG_R0, REG_R1, REG_R0);
|
||||
else if (size == 4 && is_float)
|
||||
{
|
||||
host_arm_ADD_REG(block, REG_R0, REG_R0, REG_R1);
|
||||
host_arm_VLDR_S(block, REG_D_TEMP, REG_R0, 0);
|
||||
}
|
||||
else if (size == 8 && is_float)
|
||||
{
|
||||
host_arm_ADD_REG(block, REG_R0, REG_R0, REG_R1);
|
||||
host_arm_VLDR_D(block, REG_D_TEMP, REG_R0, 0);
|
||||
}
|
||||
host_arm_MOV_IMM(block, REG_R1, 0);
|
||||
host_arm_MOV_REG(block, REG_PC, REG_LR);
|
||||
|
||||
|
|
@ -97,15 +111,21 @@ static void build_load_routine(codeblock_t *block, int size)
|
|||
host_arm_BL(block, (uintptr_t)readmemwl);
|
||||
else if (size == 4)
|
||||
host_arm_BL(block, (uintptr_t)readmemll);
|
||||
else if (size == 8)
|
||||
host_arm_BL(block, (uintptr_t)readmemql);
|
||||
else
|
||||
fatal("build_load_routine - unknown size %i\n", size);
|
||||
if (size == 4 && is_float)
|
||||
host_arm_VMOV_S_32(block, REG_D_TEMP, REG_R0);
|
||||
else if (size == 8 && is_float)
|
||||
host_arm_VMOV_D_64(block, REG_D_TEMP, REG_R0, REG_R1);
|
||||
host_arm_LDRB_ABS(block, REG_R1, &cpu_state.abrt);
|
||||
host_arm_LDR_IMM_POST(block, REG_PC, REG_HOST_SP, 4);
|
||||
|
||||
block_pos = (block_pos + 63) & ~63;
|
||||
}
|
||||
|
||||
static void build_store_routine(codeblock_t *block, int size)
|
||||
static void build_store_routine(codeblock_t *block, int size, int is_float)
|
||||
{
|
||||
uint32_t *branch_offset;
|
||||
uint32_t *misaligned_offset;
|
||||
|
|
@ -135,12 +155,22 @@ static void build_store_routine(codeblock_t *block, int size)
|
|||
}
|
||||
host_arm_CMP_IMM(block, REG_R2, -1);
|
||||
branch_offset = host_arm_BEQ_(block);
|
||||
if (size == 1)
|
||||
if (size == 1 && !is_float)
|
||||
host_arm_STRB_REG(block, REG_R1, REG_R2, REG_R0);
|
||||
else if (size == 2)
|
||||
else if (size == 2 && !is_float)
|
||||
host_arm_STRH_REG(block, REG_R1, REG_R2, REG_R0);
|
||||
else if (size == 4)
|
||||
else if (size == 4 && !is_float)
|
||||
host_arm_STR_REG(block, REG_R1, REG_R2, REG_R0);
|
||||
else if (size == 4 && is_float)
|
||||
{
|
||||
host_arm_ADD_REG(block, REG_R0, REG_R0, REG_R2);
|
||||
host_arm_VSTR_S(block, REG_D_TEMP, REG_R0, 0);
|
||||
}
|
||||
else if (size == 8 && is_float)
|
||||
{
|
||||
host_arm_ADD_REG(block, REG_R0, REG_R0, REG_R2);
|
||||
host_arm_VSTR_D(block, REG_D_TEMP, REG_R0, 0);
|
||||
}
|
||||
host_arm_MOV_IMM(block, REG_R1, 0);
|
||||
host_arm_MOV_REG(block, REG_PC, REG_LR);
|
||||
|
||||
|
|
@ -148,12 +178,18 @@ static void build_store_routine(codeblock_t *block, int size)
|
|||
if (size != 1)
|
||||
*misaligned_offset |= ((((uintptr_t)&block->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);
|
||||
else if (size == 8 && is_float)
|
||||
host_arm_VMOV_64_D(block, REG_R2, REG_R3, REG_D_TEMP);
|
||||
if (size == 1)
|
||||
host_arm_BL(block, (uintptr_t)writememb386l);
|
||||
else if (size == 2)
|
||||
host_arm_BL(block, (uintptr_t)writememwl);
|
||||
else if (size == 4)
|
||||
host_arm_BL(block, (uintptr_t)writememll);
|
||||
else if (size == 8)
|
||||
host_arm_BL_r1(block, (uintptr_t)writememql);
|
||||
else
|
||||
fatal("build_store_routine - unknown size %i\n", size);
|
||||
host_arm_LDRB_ABS(block, REG_R1, &cpu_state.abrt);
|
||||
|
|
@ -165,18 +201,26 @@ static void build_store_routine(codeblock_t *block, int size)
|
|||
static void build_loadstore_routines(codeblock_t *block)
|
||||
{
|
||||
codegen_mem_load_byte = &codeblock[block_current].data[block_pos];
|
||||
build_load_routine(block, 1);
|
||||
build_load_routine(block, 1, 0);
|
||||
codegen_mem_load_word = &codeblock[block_current].data[block_pos];
|
||||
build_load_routine(block, 2);
|
||||
build_load_routine(block, 2, 0);
|
||||
codegen_mem_load_long = &codeblock[block_current].data[block_pos];
|
||||
build_load_routine(block, 4);
|
||||
build_load_routine(block, 4, 0);
|
||||
codegen_mem_load_single = &codeblock[block_current].data[block_pos];
|
||||
build_load_routine(block, 4, 1);
|
||||
codegen_mem_load_double = &codeblock[block_current].data[block_pos];
|
||||
build_load_routine(block, 8, 1);
|
||||
|
||||
codegen_mem_store_byte = &codeblock[block_current].data[block_pos];
|
||||
build_store_routine(block, 1);
|
||||
build_store_routine(block, 1, 0);
|
||||
codegen_mem_store_word = &codeblock[block_current].data[block_pos];
|
||||
build_store_routine(block, 2);
|
||||
build_store_routine(block, 2, 0);
|
||||
codegen_mem_store_long = &codeblock[block_current].data[block_pos];
|
||||
build_store_routine(block, 4);
|
||||
build_store_routine(block, 4, 0);
|
||||
codegen_mem_store_single = &codeblock[block_current].data[block_pos];
|
||||
build_store_routine(block, 4, 1);
|
||||
codegen_mem_store_double = &codeblock[block_current].data[block_pos];
|
||||
build_store_routine(block, 8, 1);
|
||||
}
|
||||
|
||||
void codegen_backend_init()
|
||||
|
|
|
|||
|
|
@ -20,10 +20,14 @@
|
|||
void *codegen_mem_load_byte;
|
||||
void *codegen_mem_load_word;
|
||||
void *codegen_mem_load_long;
|
||||
void *codegen_mem_load_single;
|
||||
void *codegen_mem_load_double;
|
||||
|
||||
void *codegen_mem_store_byte;
|
||||
void *codegen_mem_store_word;
|
||||
void *codegen_mem_store_long;
|
||||
void *codegen_mem_store_single;
|
||||
void *codegen_mem_store_double;
|
||||
|
||||
int codegen_host_reg_list[CODEGEN_HOST_REGS] =
|
||||
{
|
||||
|
|
@ -51,7 +55,7 @@ int codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] =
|
|||
REG_V15
|
||||
};
|
||||
|
||||
static void build_load_routine(codeblock_t *block, int size)
|
||||
static void build_load_routine(codeblock_t *block, int size, int is_float)
|
||||
{
|
||||
uint32_t *branch_offset;
|
||||
uint8_t *misaligned_offset;
|
||||
|
|
@ -84,12 +88,16 @@ static void build_load_routine(codeblock_t *block, int size)
|
|||
}
|
||||
host_arm64_CMPX_IMM(block, REG_X1, -1);
|
||||
branch_offset = host_arm64_BEQ_(block);
|
||||
if (size == 1)
|
||||
if (size == 1 && !is_float)
|
||||
host_arm64_LDRB_REG(block, REG_W0, REG_W1, REG_W0);
|
||||
else if (size == 2)
|
||||
else if (size == 2 && !is_float)
|
||||
host_arm64_LDRH_REG(block, REG_W0, REG_W1, REG_W0);
|
||||
else if (size == 4)
|
||||
else if (size == 4 && !is_float)
|
||||
host_arm64_LDR_REG(block, REG_W0, REG_W1, REG_W0);
|
||||
else if (size == 4 && is_float)
|
||||
host_arm64_LDR_REG_F32(block, REG_V_TEMP, REG_W1, REG_W0);
|
||||
else if (size == 8 && is_float)
|
||||
host_arm64_LDR_REG_F64(block, REG_V_TEMP, REG_W1, REG_W0);
|
||||
host_arm64_MOVZ_IMM(block, REG_W1, 0);
|
||||
host_arm64_RET(block, REG_X30);
|
||||
|
||||
|
|
@ -103,16 +111,22 @@ static void build_load_routine(codeblock_t *block, int size)
|
|||
host_arm64_call(block, (uintptr_t)readmemwl);
|
||||
else if (size == 4)
|
||||
host_arm64_call(block, (uintptr_t)readmemll);
|
||||
else if (size == 8)
|
||||
host_arm64_call(block, (uintptr_t)readmemql);
|
||||
else
|
||||
fatal("build_load_routine - unknown size %i\n", size);
|
||||
codegen_direct_read_8(block, REG_W1, &cpu_state.abrt);
|
||||
if (size == 4 && is_float)
|
||||
host_arm64_FMOV_S_W(block, REG_V_TEMP, REG_W0);
|
||||
else if (size == 8 && is_float)
|
||||
host_arm64_FMOV_D_Q(block, REG_V_TEMP, REG_X0);
|
||||
host_arm64_LDP_POSTIDX_X(block, REG_X29, REG_X30, REG_SP, 16);
|
||||
host_arm64_RET(block, REG_X30);
|
||||
|
||||
block_pos = (block_pos + 63) & ~63;
|
||||
}
|
||||
|
||||
static void build_store_routine(codeblock_t *block, int size)
|
||||
static void build_store_routine(codeblock_t *block, int size, int is_float)
|
||||
{
|
||||
uint8_t *branch_offset;
|
||||
uint8_t *misaligned_offset;
|
||||
|
|
@ -145,12 +159,16 @@ static void build_store_routine(codeblock_t *block, int size)
|
|||
}
|
||||
host_arm64_CMPX_IMM(block, REG_X2, -1);
|
||||
branch_offset = host_arm64_BEQ_(block);
|
||||
if (size == 1)
|
||||
if (size == 1 && !is_float)
|
||||
host_arm64_STRB_REG(block, REG_X1, REG_X2, REG_X0);
|
||||
else if (size == 2)
|
||||
else if (size == 2 && !is_float)
|
||||
host_arm64_STRH_REG(block, REG_X1, REG_X2, REG_X0);
|
||||
else if (size == 4)
|
||||
else if (size == 4 && !is_float)
|
||||
host_arm64_STR_REG(block, REG_X1, REG_X2, REG_X0);
|
||||
else if (size == 4 && is_float)
|
||||
host_arm64_STR_REG_F32(block, REG_V_TEMP, REG_X2, REG_X0);
|
||||
else if (size == 8 && is_float)
|
||||
host_arm64_STR_REG_F64(block, REG_V_TEMP, REG_X2, REG_X0);
|
||||
host_arm64_MOVZ_IMM(block, REG_X1, 0);
|
||||
host_arm64_RET(block, REG_X30);
|
||||
|
||||
|
|
@ -158,12 +176,18 @@ static void build_store_routine(codeblock_t *block, int size)
|
|||
if (size != 1)
|
||||
host_arm64_branch_set_offset(misaligned_offset, &block->data[block_pos]);
|
||||
host_arm64_STP_PREIDX_X(block, REG_X29, REG_X30, REG_SP, -16);
|
||||
if (size == 4 && is_float)
|
||||
host_arm64_FMOV_W_S(block, REG_W1, REG_V_TEMP);
|
||||
else if (size == 8 && is_float)
|
||||
host_arm64_FMOV_Q_D(block, REG_X1, REG_V_TEMP);
|
||||
if (size == 1)
|
||||
host_arm64_call(block, (uintptr_t)writememb386l);
|
||||
else if (size == 2)
|
||||
host_arm64_call(block, (uintptr_t)writememwl);
|
||||
else if (size == 4)
|
||||
host_arm64_call(block, (uintptr_t)writememll);
|
||||
else if (size == 8)
|
||||
host_arm64_call(block, (uintptr_t)writememql);
|
||||
else
|
||||
fatal("build_store_routine - unknown size %i\n", size);
|
||||
codegen_direct_read_8(block, REG_W1, &cpu_state.abrt);
|
||||
|
|
@ -176,18 +200,26 @@ static void build_store_routine(codeblock_t *block, int size)
|
|||
static void build_loadstore_routines(codeblock_t *block)
|
||||
{
|
||||
codegen_mem_load_byte = &codeblock[block_current].data[block_pos];
|
||||
build_load_routine(block, 1);
|
||||
build_load_routine(block, 1, 0);
|
||||
codegen_mem_load_word = &codeblock[block_current].data[block_pos];
|
||||
build_load_routine(block, 2);
|
||||
build_load_routine(block, 2, 0);
|
||||
codegen_mem_load_long = &codeblock[block_current].data[block_pos];
|
||||
build_load_routine(block, 4);
|
||||
build_load_routine(block, 4, 0);
|
||||
codegen_mem_load_single = &codeblock[block_current].data[block_pos];
|
||||
build_load_routine(block, 4, 1);
|
||||
codegen_mem_load_double = &codeblock[block_current].data[block_pos];
|
||||
build_load_routine(block, 8, 1);
|
||||
|
||||
codegen_mem_store_byte = &codeblock[block_current].data[block_pos];
|
||||
build_store_routine(block, 1);
|
||||
build_store_routine(block, 1, 0);
|
||||
codegen_mem_store_word = &codeblock[block_current].data[block_pos];
|
||||
build_store_routine(block, 2);
|
||||
build_store_routine(block, 2, 0);
|
||||
codegen_mem_store_long = &codeblock[block_current].data[block_pos];
|
||||
build_store_routine(block, 4);
|
||||
build_store_routine(block, 4, 0);
|
||||
codegen_mem_store_single = &codeblock[block_current].data[block_pos];
|
||||
build_store_routine(block, 4, 1);
|
||||
codegen_mem_store_double = &codeblock[block_current].data[block_pos];
|
||||
build_store_routine(block, 8, 1);
|
||||
}
|
||||
|
||||
void codegen_backend_init()
|
||||
|
|
|
|||
|
|
@ -109,13 +109,19 @@
|
|||
#define REG_TEMP REG_X7
|
||||
#define REG_TEMP2 REG_X6
|
||||
|
||||
#define REG_V_TEMP REG_V0
|
||||
|
||||
#define CODEGEN_HOST_REGS 10
|
||||
#define CODEGEN_HOST_FP_REGS 8
|
||||
|
||||
extern void *codegen_mem_load_byte;
|
||||
extern void *codegen_mem_load_word;
|
||||
extern void *codegen_mem_load_long;
|
||||
extern void *codegen_mem_load_single;
|
||||
extern void *codegen_mem_load_double;
|
||||
|
||||
extern void *codegen_mem_store_byte;
|
||||
extern void *codegen_mem_store_word;
|
||||
extern void *codegen_mem_store_long;
|
||||
extern void *codegen_mem_store_long;
|
||||
extern void *codegen_mem_store_single;
|
||||
extern void *codegen_mem_store_double;
|
||||
|
|
@ -103,21 +103,33 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val)
|
|||
#define OPCODE_BLR (0xd63f0000)
|
||||
#define OPCODE_BR (0xd61f0000)
|
||||
#define OPCODE_FADD_D (0x1e602800)
|
||||
#define OPCODE_FCVT_D_S (0x1e22c000)
|
||||
#define OPCODE_FCVT_S_D (0x1e624000)
|
||||
#define OPCODE_FDIV_D (0x1e601800)
|
||||
#define OPCODE_FMOV_D_D (0x1e604000)
|
||||
#define OPCODE_FMOV_D_Q (0x9e670000)
|
||||
#define OPCODE_FMOV_Q_D (0x9e660000)
|
||||
#define OPCODE_FMOV_S_W (0x1e270000)
|
||||
#define OPCODE_FMOV_W_S (0x1e260000)
|
||||
#define OPCODE_FMUL_D (0x1e600800)
|
||||
#define OPCODE_FSUB_D (0x1e603800)
|
||||
#define OPCODE_LDR_REG (0xb8606800)
|
||||
#define OPCODE_LDRB_REG (0x38606800)
|
||||
#define OPCODE_LDRH_REG (0x78606800)
|
||||
#define OPCODE_LDRX_REG_LSL3 (0xf8607800)
|
||||
#define OPCODE_LDR_REG_F32 (0xbc606800)
|
||||
#define OPCODE_LDR_REG_F64 (0xfc606800)
|
||||
#define OPCODE_LDR_REG_F64_S (0xfc607800)
|
||||
#define OPCODE_LSL (0x1ac02000)
|
||||
#define OPCODE_LSR (0x1ac02400)
|
||||
#define OPCODE_NOP (0xd503201f)
|
||||
#define OPCODE_RET (0xd65f0000)
|
||||
#define OPCODE_SCVTF_D_W (0x1e620000)
|
||||
#define OPCODE_STR_REG (0xb8206800)
|
||||
#define OPCODE_STRB_REG (0x38206800)
|
||||
#define OPCODE_STRH_REG (0x78206800)
|
||||
#define OPCODE_STR_REG_F32 (0xbc206800)
|
||||
#define OPCODE_STR_REG_F64 (0xfc206800)
|
||||
#define OPCODE_STR_REG_F64_S (0xfc207800)
|
||||
|
||||
#define DATPROC_SHIFT(sh) (sh << 10)
|
||||
|
|
@ -490,11 +502,37 @@ void host_arm64_CMP_REG_LSL(codeblock_t *block, int src_n_reg, int src_m_reg, in
|
|||
codegen_addlong(block, OPCODE_CMP_LSL | Rd(0x1f) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift));
|
||||
}
|
||||
|
||||
void host_arm64_EOR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data)
|
||||
{
|
||||
if (imm_data == 0xffff) /*Quick hack until proper immediate generation is written */
|
||||
{
|
||||
codegen_addlong(block, OPCODE_EOR_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(0) | IMMS(0x0f));
|
||||
}
|
||||
else
|
||||
{
|
||||
host_arm64_mov_imm(block, REG_W16, imm_data);
|
||||
codegen_addlong(block, OPCODE_EOR_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0));
|
||||
}
|
||||
}
|
||||
void host_arm64_EOR_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift)
|
||||
{
|
||||
codegen_addlong(block, OPCODE_EOR_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift));
|
||||
}
|
||||
|
||||
void host_arm64_FADD_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg)
|
||||
{
|
||||
codegen_addlong(block, OPCODE_FADD_D | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg));
|
||||
}
|
||||
|
||||
void host_arm64_FCVT_D_S(codeblock_t *block, int dst_reg, int src_reg)
|
||||
{
|
||||
codegen_addlong(block, OPCODE_FCVT_D_S | Rd(dst_reg) | Rn(src_reg));
|
||||
}
|
||||
void host_arm64_FCVT_S_D(codeblock_t *block, int dst_reg, int src_reg)
|
||||
{
|
||||
codegen_addlong(block, OPCODE_FCVT_S_D | Rd(dst_reg) | Rn(src_reg));
|
||||
}
|
||||
|
||||
void host_arm64_FDIV_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg)
|
||||
{
|
||||
codegen_addlong(block, OPCODE_FDIV_D | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg));
|
||||
|
|
@ -510,21 +548,25 @@ void host_arm64_FSUB_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m
|
|||
codegen_addlong(block, OPCODE_FSUB_D | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg));
|
||||
}
|
||||
|
||||
void host_arm64_EOR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data)
|
||||
void host_arm64_FMOV_D_D(codeblock_t *block, int dst_reg, int src_reg)
|
||||
{
|
||||
if (imm_data == 0xffff) /*Quick hack until proper immediate generation is written */
|
||||
{
|
||||
codegen_addlong(block, OPCODE_EOR_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(0) | IMMS(0x0f));
|
||||
}
|
||||
else
|
||||
{
|
||||
host_arm64_mov_imm(block, REG_W16, imm_data);
|
||||
codegen_addlong(block, OPCODE_EOR_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0));
|
||||
}
|
||||
codegen_addlong(block, OPCODE_FMOV_D_D | Rd(dst_reg) | Rn(src_reg));
|
||||
}
|
||||
void host_arm64_EOR_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift)
|
||||
void host_arm64_FMOV_D_Q(codeblock_t *block, int dst_reg, int src_reg)
|
||||
{
|
||||
codegen_addlong(block, OPCODE_EOR_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift));
|
||||
codegen_addlong(block, OPCODE_FMOV_D_Q | Rd(dst_reg) | Rn(src_reg));
|
||||
}
|
||||
void host_arm64_FMOV_Q_D(codeblock_t *block, int dst_reg, int src_reg)
|
||||
{
|
||||
codegen_addlong(block, OPCODE_FMOV_Q_D | Rd(dst_reg) | Rn(src_reg));
|
||||
}
|
||||
void host_arm64_FMOV_S_W(codeblock_t *block, int dst_reg, int src_reg)
|
||||
{
|
||||
codegen_addlong(block, OPCODE_FMOV_S_W | Rd(dst_reg) | Rn(src_reg));
|
||||
}
|
||||
void host_arm64_FMOV_W_S(codeblock_t *block, int dst_reg, int src_reg)
|
||||
{
|
||||
codegen_addlong(block, OPCODE_FMOV_W_S | Rd(dst_reg) | Rn(src_reg));
|
||||
}
|
||||
|
||||
void host_arm64_LDP_POSTIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset)
|
||||
|
|
@ -564,10 +606,18 @@ void host_arm64_LDR_REG(codeblock_t *block, int dest_reg, int base_reg, int offs
|
|||
codegen_addlong(block, OPCODE_LDR_REG | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg));
|
||||
}
|
||||
|
||||
void host_arm64_LDR_REG_F32(codeblock_t *block, int dest_reg, int base_reg, int offset_reg)
|
||||
{
|
||||
codegen_addlong(block, OPCODE_LDR_REG_F32 | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg));
|
||||
}
|
||||
void host_arm64_LDR_IMM_F64(codeblock_t *block, int dest_reg, int base_reg, int offset)
|
||||
{
|
||||
codegen_addlong(block, OPCODE_LDR_IMM_F64 | OFFSET12_Q(offset) | Rn(base_reg) | Rt(dest_reg));
|
||||
}
|
||||
void host_arm64_LDR_REG_F64(codeblock_t *block, int dest_reg, int base_reg, int offset_reg)
|
||||
{
|
||||
codegen_addlong(block, OPCODE_LDR_REG_F64 | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg));
|
||||
}
|
||||
void host_arm64_LDR_REG_F64_S(codeblock_t *block, int dest_reg, int base_reg, int offset_reg)
|
||||
{
|
||||
codegen_addlong(block, OPCODE_LDR_REG_F64_S | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg));
|
||||
|
|
@ -704,6 +754,11 @@ void host_arm64_SBFX(codeblock_t *block, int dst_reg, int src_reg, int lsb, int
|
|||
codegen_addlong(block, OPCODE_SBFX | Rd(dst_reg) | Rn(src_reg) | IMMN(0) | IMMR(lsb) | IMMS((lsb+width-1) & 31));
|
||||
}
|
||||
|
||||
void host_arm64_SCVTF_D_W(codeblock_t *block, int dst_reg, int src_reg)
|
||||
{
|
||||
codegen_addlong(block, OPCODE_SCVTF_D_W | Rd(dst_reg) | Rn(src_reg));
|
||||
}
|
||||
|
||||
void host_arm64_STP_PREIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset)
|
||||
{
|
||||
if (!in_range7_x(offset))
|
||||
|
|
@ -728,10 +783,18 @@ void host_arm64_STR_REG(codeblock_t *block, int src_reg, int base_reg, int offse
|
|||
codegen_addlong(block, OPCODE_STR_REG | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg));
|
||||
}
|
||||
|
||||
void host_arm64_STR_REG_F32(codeblock_t *block, int src_reg, int base_reg, int offset_reg)
|
||||
{
|
||||
codegen_addlong(block, OPCODE_STR_REG_F32 | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg));
|
||||
}
|
||||
void host_arm64_STR_IMM_F64(codeblock_t *block, int src_reg, int base_reg, int offset)
|
||||
{
|
||||
codegen_addlong(block, OPCODE_STR_IMM_F64 | OFFSET12_Q(offset) | Rn(base_reg) | Rt(src_reg));
|
||||
}
|
||||
void host_arm64_STR_REG_F64(codeblock_t *block, int src_reg, int base_reg, int offset_reg)
|
||||
{
|
||||
codegen_addlong(block, OPCODE_STR_REG_F64 | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg));
|
||||
}
|
||||
void host_arm64_STR_REG_F64_S(codeblock_t *block, int src_reg, int base_reg, int offset_reg)
|
||||
{
|
||||
codegen_addlong(block, OPCODE_STR_REG_F64_S | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg));
|
||||
|
|
|
|||
|
|
@ -56,6 +56,15 @@ void host_arm64_FDIV_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m
|
|||
void host_arm64_FMUL_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg);
|
||||
void host_arm64_FSUB_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg);
|
||||
|
||||
void host_arm64_FCVT_D_S(codeblock_t *block, int dst_reg, int src_reg);
|
||||
void host_arm64_FCVT_S_D(codeblock_t *block, int dst_reg, int src_reg);
|
||||
|
||||
void host_arm64_FMOV_D_D(codeblock_t *block, int dst_reg, int src_reg);
|
||||
void host_arm64_FMOV_D_Q(codeblock_t *block, int dst_reg, int src_reg);
|
||||
void host_arm64_FMOV_Q_D(codeblock_t *block, int dst_reg, int src_reg);
|
||||
void host_arm64_FMOV_S_W(codeblock_t *block, int dst_reg, int src_reg);
|
||||
void host_arm64_FMOV_W_S(codeblock_t *block, int dst_reg, int src_reg);
|
||||
|
||||
void host_arm64_LDP_POSTIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset);
|
||||
|
||||
void host_arm64_LDR_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int offset);
|
||||
|
|
@ -63,7 +72,9 @@ void host_arm64_LDR_LITERAL_W(codeblock_t *block, int dest_reg, int literal_offs
|
|||
void host_arm64_LDR_LITERAL_X(codeblock_t *block, int dest_reg, int literal_offset);
|
||||
void host_arm64_LDR_REG(codeblock_t *block, int dest_reg, int base_reg, int offset_reg);
|
||||
|
||||
void host_arm64_LDR_REG_F32(codeblock_t *block, int dest_reg, int base_reg, int offset_reg);
|
||||
void host_arm64_LDR_IMM_F64(codeblock_t *block, int dest_reg, int base_reg, int offset);
|
||||
void host_arm64_LDR_REG_F64(codeblock_t *block, int dest_reg, int base_reg, int offset_reg);
|
||||
void host_arm64_LDR_REG_F64_S(codeblock_t *block, int dest_reg, int base_reg, int offset_reg);
|
||||
|
||||
void host_arm64_LDRB_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int offset);
|
||||
|
|
@ -95,13 +106,17 @@ void host_arm64_RET(codeblock_t *block, int reg);
|
|||
|
||||
void host_arm64_SBFX(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width);
|
||||
|
||||
void host_arm64_SCVTF_D_W(codeblock_t *block, int dst_reg, int src_reg);
|
||||
|
||||
void host_arm64_STP_PREIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset);
|
||||
|
||||
void host_arm64_STR_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int offset);
|
||||
void host_arm64_STR_IMM_Q(codeblock_t *block, int dest_reg, int base_reg, int offset);
|
||||
void host_arm64_STR_REG(codeblock_t *block, int src_reg, int base_reg, int offset_reg);
|
||||
|
||||
void host_arm64_STR_REG_F32(codeblock_t *block, int src_reg, int base_reg, int offset_reg);
|
||||
void host_arm64_STR_IMM_F64(codeblock_t *block, int src_reg, int base_reg, int offset);
|
||||
void host_arm64_STR_REG_F64(codeblock_t *block, int src_reg, int base_reg, int offset_reg);
|
||||
void host_arm64_STR_REG_F64_S(codeblock_t *block, int src_reg, int base_reg, int offset_reg);
|
||||
|
||||
void host_arm64_STRB_IMM(codeblock_t *block, int dest_reg, int base_reg, int offset);
|
||||
|
|
|
|||
|
|
@ -838,6 +838,40 @@ static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop)
|
|||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_MEM_LOAD_DOUBLE(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real);
|
||||
|
||||
if (!REG_IS_D(dest_size))
|
||||
fatal("MEM_LOAD_DOUBLE - %02x\n", uop->dest_reg_a_real);
|
||||
|
||||
host_arm64_ADD_REG(block, REG_X0, seg_reg, addr_reg, 0);
|
||||
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_FMOV_D_D(block, dest_reg, REG_V_TEMP);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real);
|
||||
|
||||
if (!REG_IS_D(dest_size))
|
||||
fatal("MEM_LOAD_DOUBLE - %02x\n", uop->dest_reg_a_real);
|
||||
|
||||
host_arm64_ADD_REG(block, REG_X0, seg_reg, addr_reg, 0);
|
||||
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_FCVT_D_S(block, dest_reg, REG_V_TEMP);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
|
|
@ -940,6 +974,41 @@ static int codegen_MEM_STORE_IMM_32(codeblock_t *block, uop_t *uop)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real);
|
||||
int src_size = IREG_GET_SIZE(uop->src_reg_c_real);
|
||||
|
||||
if (!REG_IS_D(src_size))
|
||||
fatal("MEM_STORE_REG - %02x\n", uop->dest_reg_a_real);
|
||||
|
||||
host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0);
|
||||
if (uop->imm_data)
|
||||
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]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_MEM_STORE_DOUBLE(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real);
|
||||
int src_size = IREG_GET_SIZE(uop->src_reg_c_real);
|
||||
|
||||
if (!REG_IS_D(src_size))
|
||||
fatal("MEM_STORE_REG - %02x\n", uop->dest_reg_a_real);
|
||||
|
||||
host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0);
|
||||
if (uop->imm_data)
|
||||
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]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_MOV(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real);
|
||||
|
|
@ -1077,6 +1146,26 @@ static int codegen_MOVZX(codeblock_t *block, uop_t *uop)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
|
||||
|
||||
if (REG_IS_D(dest_size) && REG_IS_L(src_size))
|
||||
{
|
||||
host_arm64_SCVTF_D_W(block, dest_reg, src_reg);
|
||||
}
|
||||
else if (REG_IS_D(dest_size) && REG_IS_W(src_size))
|
||||
{
|
||||
host_arm64_SBFX(block, REG_TEMP, src_reg, 0, 16);
|
||||
host_arm64_SCVTF_D_W(block, dest_reg, REG_TEMP);
|
||||
}
|
||||
else
|
||||
fatal("MOV_DOUBLE_INT %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_OR(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
|
||||
|
|
@ -1591,18 +1680,23 @@ const uOpFn uop_handlers[UOP_MAX] =
|
|||
|
||||
[UOP_MEM_LOAD_ABS & UOP_MASK] = codegen_MEM_LOAD_ABS,
|
||||
[UOP_MEM_LOAD_REG & UOP_MASK] = codegen_MEM_LOAD_REG,
|
||||
[UOP_MEM_LOAD_SINGLE & UOP_MASK] = codegen_MEM_LOAD_SINGLE,
|
||||
[UOP_MEM_LOAD_DOUBLE & UOP_MASK] = codegen_MEM_LOAD_DOUBLE,
|
||||
|
||||
[UOP_MEM_STORE_ABS & UOP_MASK] = codegen_MEM_STORE_ABS,
|
||||
[UOP_MEM_STORE_REG & UOP_MASK] = codegen_MEM_STORE_REG,
|
||||
[UOP_MEM_STORE_IMM_8 & UOP_MASK] = codegen_MEM_STORE_IMM_8,
|
||||
[UOP_MEM_STORE_IMM_16 & UOP_MASK] = codegen_MEM_STORE_IMM_16,
|
||||
[UOP_MEM_STORE_IMM_32 & UOP_MASK] = codegen_MEM_STORE_IMM_32,
|
||||
[UOP_MEM_STORE_SINGLE & UOP_MASK] = codegen_MEM_STORE_SINGLE,
|
||||
[UOP_MEM_STORE_DOUBLE & UOP_MASK] = codegen_MEM_STORE_DOUBLE,
|
||||
|
||||
[UOP_MOV & UOP_MASK] = codegen_MOV,
|
||||
[UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR,
|
||||
[UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM,
|
||||
[UOP_MOVSX & UOP_MASK] = codegen_MOVSX,
|
||||
[UOP_MOVZX & UOP_MASK] = codegen_MOVZX,
|
||||
[UOP_MOV_DOUBLE_INT & UOP_MASK] = codegen_MOV_DOUBLE_INT,
|
||||
|
||||
[UOP_ADD & UOP_MASK] = codegen_ADD,
|
||||
[UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM,
|
||||
|
|
|
|||
|
|
@ -41,6 +41,8 @@
|
|||
#define REG_D14 14
|
||||
#define REG_D15 15
|
||||
|
||||
#define REG_D_TEMP REG_D0
|
||||
|
||||
#define REG_MASK_R0 (1 << REG_R0)
|
||||
#define REG_MASK_R1 (1 << REG_R1)
|
||||
#define REG_MASK_R2 (1 << REG_R2)
|
||||
|
|
@ -67,7 +69,11 @@
|
|||
extern void *codegen_mem_load_byte;
|
||||
extern void *codegen_mem_load_word;
|
||||
extern void *codegen_mem_load_long;
|
||||
extern void *codegen_mem_load_single;
|
||||
extern void *codegen_mem_load_double;
|
||||
|
||||
extern void *codegen_mem_store_byte;
|
||||
extern void *codegen_mem_store_word;
|
||||
extern void *codegen_mem_store_long;
|
||||
extern void *codegen_mem_store_single;
|
||||
extern void *codegen_mem_store_double;
|
||||
|
|
|
|||
|
|
@ -17,10 +17,16 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val)
|
|||
}
|
||||
}
|
||||
|
||||
#define Rm(x) (x)
|
||||
#define Rs(x) ((x) << 8)
|
||||
#define Rd(x) ((x) << 12)
|
||||
#define Rn(x) ((x) << 16)
|
||||
#define Rm(x) (x)
|
||||
#define Rs(x) ((x) << 8)
|
||||
#define Rd(x) ((x) << 12)
|
||||
#define Rt(x) ((x) << 12)
|
||||
#define Rn(x) ((x) << 16)
|
||||
#define Rt2(x) ((x) << 16)
|
||||
|
||||
#define Vm(x) (x)
|
||||
#define Vd(x) ((x) << 12)
|
||||
#define Vn(x) ((x) << 16)
|
||||
|
||||
#define DATA_OFFSET_UP (1 << 23)
|
||||
#define DATA_OFFSET_DOWN (0 << 23)
|
||||
|
|
@ -98,10 +104,20 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val)
|
|||
#define OPCODE_UXTB 0xe6ef0070
|
||||
#define OPCODE_UXTH 0xe6ff0070
|
||||
#define OPCODE_VADD 0xee300b00
|
||||
#define OPCODE_VCVT_D_IS 0xeeb80bc0
|
||||
#define OPCODE_VCVT_D_S 0xeeb70ac0
|
||||
#define OPCODE_VCVT_S_D 0xeeb70bc0
|
||||
#define OPCODE_VDIV 0xee800b00
|
||||
#define OPCODE_VLDR 0xed900b00
|
||||
#define OPCODE_VLDR_D 0xed900b00
|
||||
#define OPCODE_VLDR_S 0xed900a00
|
||||
#define OPCODE_VMOV_32_S 0xee100a10
|
||||
#define OPCODE_VMOV_64_D 0xec500b10
|
||||
#define OPCODE_VMOV_D_64 0xec400b10
|
||||
#define OPCODE_VMOV_S_32 0xee000a10
|
||||
#define OPCODE_VMOV_D_D 0xeeb00b40
|
||||
#define OPCODE_VMUL 0xee200b00
|
||||
#define OPCODE_VSTR 0xed800b00
|
||||
#define OPCODE_VSTR_D 0xed800b00
|
||||
#define OPCODE_VSTR_S 0xed800a00
|
||||
#define OPCODE_VSUB 0xee300b40
|
||||
|
||||
#define B_OFFSET(x) (((x) >> 2) & 0xffffff)
|
||||
|
|
@ -305,6 +321,18 @@ void host_arm_BL(codeblock_t *block, uintptr_t dest_addr)
|
|||
else
|
||||
codegen_addlong(block, COND_AL | OPCODE_BL | B_OFFSET(offset));
|
||||
}
|
||||
void host_arm_BL_r1(codeblock_t *block, uintptr_t dest_addr)
|
||||
{
|
||||
uint32_t offset = (dest_addr - (uintptr_t)&block->data[block_pos]) - 8;
|
||||
|
||||
if ((offset & 0xfe000000) && (offset & 0xfe000000) != 0xfe000000)
|
||||
{
|
||||
host_arm_MOV_IMM(block, REG_R1, dest_addr);
|
||||
host_arm_BLX(block, REG_R1);
|
||||
}
|
||||
else
|
||||
codegen_addlong(block, COND_AL | OPCODE_BL | B_OFFSET(offset));
|
||||
}
|
||||
void host_arm_BLX(codeblock_t *block, int addr_reg)
|
||||
{
|
||||
codegen_addlong(block, OPCODE_BLX | Rm(addr_reg));
|
||||
|
|
@ -734,6 +762,18 @@ void host_arm_VADD_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg
|
|||
{
|
||||
codegen_addlong(block, COND_AL | OPCODE_VADD | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m));
|
||||
}
|
||||
void host_arm_VCVT_D_IS(codeblock_t *block, int dest_reg, int src_reg)
|
||||
{
|
||||
codegen_addlong(block, COND_AL | OPCODE_VCVT_D_IS | Vd(dest_reg) | Vm(src_reg));
|
||||
}
|
||||
void host_arm_VCVT_D_S(codeblock_t *block, int dest_reg, int src_reg)
|
||||
{
|
||||
codegen_addlong(block, COND_AL | OPCODE_VCVT_D_S | Vd(dest_reg) | Vm(src_reg));
|
||||
}
|
||||
void host_arm_VCVT_S_D(codeblock_t *block, int dest_reg, int src_reg)
|
||||
{
|
||||
codegen_addlong(block, COND_AL | OPCODE_VCVT_S_D | Vd(dest_reg) | Vm(src_reg));
|
||||
}
|
||||
void host_arm_VDIV_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m)
|
||||
{
|
||||
codegen_addlong(block, COND_AL | OPCODE_VDIV | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m));
|
||||
|
|
@ -741,8 +781,34 @@ void host_arm_VDIV_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg
|
|||
void host_arm_VLDR_D(codeblock_t *block, int dest_reg, int base_reg, int offset)
|
||||
{
|
||||
if ((offset > 1020) || (offset & 3))
|
||||
fatal("VLDR bad offset %i\n", offset);
|
||||
codegen_addlong(block, COND_AL | OPCODE_VLDR | Rd(dest_reg) | Rn(base_reg) | (offset >> 2));
|
||||
fatal("VLDR_D bad offset %i\n", offset);
|
||||
codegen_addlong(block, COND_AL | OPCODE_VLDR_D | Rd(dest_reg) | Rn(base_reg) | (offset >> 2));
|
||||
}
|
||||
void host_arm_VLDR_S(codeblock_t *block, int dest_reg, int base_reg, int offset)
|
||||
{
|
||||
if ((offset > 1020) || (offset & 3))
|
||||
fatal("VLDR_S bad offset %i\n", offset);
|
||||
codegen_addlong(block, COND_AL | OPCODE_VLDR_S | Rd(dest_reg) | Rn(base_reg) | (offset >> 2));
|
||||
}
|
||||
void host_arm_VMOV_32_S(codeblock_t *block, int dest_reg, int src_reg)
|
||||
{
|
||||
codegen_addlong(block, COND_AL | OPCODE_VMOV_32_S | Rt(dest_reg) | Vn(src_reg));
|
||||
}
|
||||
void host_arm_VMOV_64_D(codeblock_t *block, int dest_reg_low, int dest_reg_high, int src_reg)
|
||||
{
|
||||
codegen_addlong(block, COND_AL | OPCODE_VMOV_64_D | Rt(dest_reg_low) | Rt2(dest_reg_high) | Vm(src_reg));
|
||||
}
|
||||
void host_arm_VMOV_D_64(codeblock_t *block, int dest_reg, int src_reg_low, int src_reg_high)
|
||||
{
|
||||
codegen_addlong(block, COND_AL | OPCODE_VMOV_D_64 | Vm(dest_reg) | Rt(src_reg_low) | Rt2(src_reg_high));
|
||||
}
|
||||
void host_arm_VMOV_S_32(codeblock_t *block, int dest_reg, int src_reg)
|
||||
{
|
||||
codegen_addlong(block, COND_AL | OPCODE_VMOV_S_32 | Vn(dest_reg) | Rt(src_reg));
|
||||
}
|
||||
void host_arm_VMOV_D_D(codeblock_t *block, int dest_reg, int src_reg)
|
||||
{
|
||||
codegen_addlong(block, COND_AL | OPCODE_VMOV_D_D | Vd(dest_reg) | Vm(src_reg));
|
||||
}
|
||||
void host_arm_VMUL_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m)
|
||||
{
|
||||
|
|
@ -751,8 +817,14 @@ void host_arm_VMUL_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg
|
|||
void host_arm_VSTR_D(codeblock_t *block, int src_reg, int base_reg, int offset)
|
||||
{
|
||||
if ((offset > 1020) || (offset & 3))
|
||||
fatal("VSTR bad offset %i\n", offset);
|
||||
codegen_addlong(block, COND_AL | OPCODE_VSTR | Rd(src_reg) | Rn(base_reg) | (offset >> 2));
|
||||
fatal("VSTR_D bad offset %i\n", offset);
|
||||
codegen_addlong(block, COND_AL | OPCODE_VSTR_D | Rd(src_reg) | Rn(base_reg) | (offset >> 2));
|
||||
}
|
||||
void host_arm_VSTR_S(codeblock_t *block, int src_reg, int base_reg, int offset)
|
||||
{
|
||||
if ((offset > 1020) || (offset & 3))
|
||||
fatal("VSTR_S bad offset %i\n", offset);
|
||||
codegen_addlong(block, COND_AL | OPCODE_VSTR_S | Rd(src_reg) | Rn(base_reg) | (offset >> 2));
|
||||
}
|
||||
void host_arm_VSUB_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ void host_arm_BIC_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int sr
|
|||
void host_arm_BIC_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift);
|
||||
|
||||
void host_arm_BL(codeblock_t *block, uintptr_t dest_addr);
|
||||
void host_arm_BL_r1(codeblock_t *block, uintptr_t dest_addr);
|
||||
void host_arm_BLX(codeblock_t *block, int addr_reg);
|
||||
|
||||
uint32_t *host_arm_BCC_(codeblock_t *block);
|
||||
|
|
@ -115,8 +116,18 @@ void host_arm_UXTB(codeblock_t *block, int dst_reg, int src_reg, int rotate);
|
|||
void host_arm_UXTH(codeblock_t *block, int dst_reg, int src_reg, int rotate);
|
||||
|
||||
void host_arm_VADD_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m);
|
||||
void host_arm_VCVT_D_IS(codeblock_t *block, int dest_reg, int src_reg);
|
||||
void host_arm_VCVT_D_S(codeblock_t *block, int dest_reg, int src_reg);
|
||||
void host_arm_VCVT_S_D(codeblock_t *block, int dest_reg, int src_reg);
|
||||
void host_arm_VDIV_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m);
|
||||
void host_arm_VLDR_D(codeblock_t *block, int dest_reg, int base_reg, int offset);
|
||||
void host_arm_VLDR_S(codeblock_t *block, int dest_reg, int base_reg, int offset);
|
||||
void host_arm_VMOV_32_S(codeblock_t *block, int dest_reg, int src_reg);
|
||||
void host_arm_VMOV_64_D(codeblock_t *block, int dest_reg_low, int dest_reg_high, int src_reg);
|
||||
void host_arm_VMOV_D_64(codeblock_t *block, int dest_reg, int src_reg_low, int src_reg_high);
|
||||
void host_arm_VMOV_S_32(codeblock_t *block, int dest_reg, int src_reg);
|
||||
void host_arm_VMOV_D_D(codeblock_t *block, int dest_reg, int src_reg);
|
||||
void host_arm_VMUL_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m);
|
||||
void host_arm_VSTR_D(codeblock_t *block, int src_reg, int base_reg, int offset);
|
||||
void host_arm_VSTR_S(codeblock_t *block, int src_reg, int base_reg, int offset);
|
||||
void host_arm_VSUB_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m);
|
||||
|
|
|
|||
|
|
@ -910,6 +910,42 @@ static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop)
|
|||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real);
|
||||
|
||||
if (!REG_IS_D(dest_size))
|
||||
fatal("MEM_LOAD_SINGLE - %02x\n", uop->dest_reg_a_real);
|
||||
|
||||
host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg);
|
||||
if (uop->imm_data)
|
||||
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_VCVT_D_S(block, dest_reg, REG_D_TEMP);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_MEM_LOAD_DOUBLE(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real);
|
||||
|
||||
if (!REG_IS_D(dest_size))
|
||||
fatal("MEM_LOAD_DOUBLE - %02x\n", uop->dest_reg_a_real);
|
||||
|
||||
host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg);
|
||||
if (uop->imm_data)
|
||||
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_VMOV_D_D(block, dest_reg, REG_D_TEMP);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
|
|
@ -1012,6 +1048,42 @@ static int codegen_MEM_STORE_IMM_32(codeblock_t *block, uop_t *uop)
|
|||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real);
|
||||
int src_size = IREG_GET_SIZE(uop->src_reg_c_real);
|
||||
|
||||
if (!REG_IS_D(src_size))
|
||||
fatal("MEM_STORE_REG - %02x\n", uop->dest_reg_a_real);
|
||||
|
||||
host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg);
|
||||
if (uop->imm_data)
|
||||
host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data);
|
||||
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]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_MEM_STORE_DOUBLE(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real);
|
||||
int src_size = IREG_GET_SIZE(uop->src_reg_c_real);
|
||||
|
||||
if (!REG_IS_D(src_size))
|
||||
fatal("MEM_STORE_REG - %02x\n", uop->dest_reg_a_real);
|
||||
|
||||
host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg);
|
||||
if (uop->imm_data)
|
||||
host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data);
|
||||
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]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_MOV(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
|
|
@ -1156,6 +1228,27 @@ static int codegen_MOVZX(codeblock_t *block, uop_t *uop)
|
|||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
|
||||
|
||||
if (REG_IS_D(dest_size) && REG_IS_L(src_size))
|
||||
{
|
||||
host_arm_VMOV_S_32(block, REG_D_TEMP, src_reg);
|
||||
host_arm_VCVT_D_IS(block, dest_reg, REG_D_TEMP);
|
||||
}
|
||||
else if (REG_IS_D(dest_size) && REG_IS_W(src_size))
|
||||
{
|
||||
host_arm_SXTH(block, REG_TEMP, src_reg, 0);
|
||||
host_arm_VMOV_S_32(block, REG_D_TEMP, REG_TEMP);
|
||||
host_arm_VCVT_D_IS(block, dest_reg, REG_D_TEMP);
|
||||
}
|
||||
else
|
||||
fatal("MOV_DOUBLE_INT %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_OR(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
|
|
@ -1671,18 +1764,23 @@ const uOpFn uop_handlers[UOP_MAX] =
|
|||
|
||||
[UOP_MEM_LOAD_ABS & UOP_MASK] = codegen_MEM_LOAD_ABS,
|
||||
[UOP_MEM_LOAD_REG & UOP_MASK] = codegen_MEM_LOAD_REG,
|
||||
[UOP_MEM_LOAD_SINGLE & UOP_MASK] = codegen_MEM_LOAD_SINGLE,
|
||||
[UOP_MEM_LOAD_DOUBLE & UOP_MASK] = codegen_MEM_LOAD_DOUBLE,
|
||||
|
||||
[UOP_MEM_STORE_ABS & UOP_MASK] = codegen_MEM_STORE_ABS,
|
||||
[UOP_MEM_STORE_REG & UOP_MASK] = codegen_MEM_STORE_REG,
|
||||
[UOP_MEM_STORE_IMM_8 & UOP_MASK] = codegen_MEM_STORE_IMM_8,
|
||||
[UOP_MEM_STORE_IMM_16 & UOP_MASK] = codegen_MEM_STORE_IMM_16,
|
||||
[UOP_MEM_STORE_IMM_32 & UOP_MASK] = codegen_MEM_STORE_IMM_32,
|
||||
[UOP_MEM_STORE_SINGLE & UOP_MASK] = codegen_MEM_STORE_SINGLE,
|
||||
[UOP_MEM_STORE_DOUBLE & UOP_MASK] = codegen_MEM_STORE_DOUBLE,
|
||||
|
||||
[UOP_MOV & UOP_MASK] = codegen_MOV,
|
||||
[UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR,
|
||||
[UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM,
|
||||
[UOP_MOVSX & UOP_MASK] = codegen_MOVSX,
|
||||
[UOP_MOVZX & UOP_MASK] = codegen_MOVZX,
|
||||
[UOP_MOV_DOUBLE_INT & UOP_MASK] = codegen_MOV_DOUBLE_INT,
|
||||
|
||||
[UOP_ADD & UOP_MASK] = codegen_ADD,
|
||||
[UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM,
|
||||
|
|
|
|||
|
|
@ -19,10 +19,14 @@
|
|||
void *codegen_mem_load_byte;
|
||||
void *codegen_mem_load_word;
|
||||
void *codegen_mem_load_long;
|
||||
void *codegen_mem_load_single;
|
||||
void *codegen_mem_load_double;
|
||||
|
||||
void *codegen_mem_store_byte;
|
||||
void *codegen_mem_store_word;
|
||||
void *codegen_mem_store_long;
|
||||
void *codegen_mem_store_single;
|
||||
void *codegen_mem_store_double;
|
||||
|
||||
int codegen_host_reg_list[CODEGEN_HOST_REGS] =
|
||||
{
|
||||
|
|
@ -44,7 +48,7 @@ int codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] =
|
|||
|
||||
static void *mem_abrt_rout;
|
||||
|
||||
static void build_load_routine(codeblock_t *block, int size)
|
||||
static void build_load_routine(codeblock_t *block, int size, int is_float)
|
||||
{
|
||||
uint8_t *branch_offset;
|
||||
uint8_t *misaligned_offset;
|
||||
|
|
@ -80,12 +84,16 @@ static void build_load_routine(codeblock_t *block, int size)
|
|||
}
|
||||
host_x86_CMP64_REG_IMM(block, REG_RSI, (uint32_t)-1);
|
||||
branch_offset = host_x86_JZ_short(block);
|
||||
if (size == 1)
|
||||
if (size == 1 && !is_float)
|
||||
host_x86_MOVZX_BASE_INDEX_32_8(block, REG_ECX, REG_RSI, REG_RCX);
|
||||
else if (size == 2)
|
||||
else if (size == 2 && !is_float)
|
||||
host_x86_MOVZX_BASE_INDEX_32_16(block, REG_ECX, REG_RSI, REG_RCX);
|
||||
else if (size == 4)
|
||||
else if (size == 4 && !is_float)
|
||||
host_x86_MOV32_REG_BASE_INDEX(block, REG_ECX, REG_RSI, REG_RCX);
|
||||
else if (size == 4 && is_float)
|
||||
host_x86_CVTSS2SD_XREG_BASE_INDEX(block, REG_XMM_TEMP, REG_RSI, REG_RCX);
|
||||
else if (size == 8 && is_float)
|
||||
host_x86_MOVQ_XREG_BASE_INDEX(block, REG_XMM_TEMP, REG_RSI, REG_RCX);
|
||||
else
|
||||
fatal("build_load_routine: size=%i\n", size);
|
||||
host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI, REG_ESI);
|
||||
|
|
@ -102,21 +110,32 @@ static void build_load_routine(codeblock_t *block, int size)
|
|||
#else
|
||||
host_x86_MOV32_REG_REG(block, REG_EDI, REG_ECX);
|
||||
#endif
|
||||
if (size == 1)
|
||||
if (size == 1 && !is_float)
|
||||
{
|
||||
host_x86_CALL(block, (void *)readmemb386l);
|
||||
host_x86_MOVZX_REG_32_8(block, REG_ECX, REG_EAX);
|
||||
}
|
||||
else if (size == 2)
|
||||
else if (size == 2 && !is_float)
|
||||
{
|
||||
host_x86_CALL(block, (void *)readmemwl);
|
||||
host_x86_MOVZX_REG_32_16(block, REG_ECX, REG_EAX);
|
||||
}
|
||||
else if (size == 4)
|
||||
else if (size == 4 && !is_float)
|
||||
{
|
||||
host_x86_CALL(block, (void *)readmemll);
|
||||
host_x86_MOV32_REG_REG(block, REG_ECX, REG_EAX);
|
||||
}
|
||||
else if (size == 4 && is_float)
|
||||
{
|
||||
host_x86_CALL(block, (void *)readmemll);
|
||||
host_x86_MOVD_XREG_REG(block, REG_XMM_TEMP, REG_EAX);
|
||||
host_x86_CVTSS2SD_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP);
|
||||
}
|
||||
else if (size == 8 && is_float)
|
||||
{
|
||||
host_x86_CALL(block, (void *)readmemql);
|
||||
host_x86_MOVQ_XREG_REG(block, REG_XMM_TEMP, REG_RAX);
|
||||
}
|
||||
#if WIN64
|
||||
host_x86_ADD64_REG_IMM(block, REG_RSP, 0x20);
|
||||
#endif
|
||||
|
|
@ -127,7 +146,7 @@ static void build_load_routine(codeblock_t *block, int size)
|
|||
block_pos = (block_pos + 63) & ~63;
|
||||
}
|
||||
|
||||
static void build_store_routine(codeblock_t *block, int size)
|
||||
static void build_store_routine(codeblock_t *block, int size, int is_float)
|
||||
{
|
||||
uint8_t *branch_offset;
|
||||
uint8_t *misaligned_offset;
|
||||
|
|
@ -164,12 +183,16 @@ static void build_store_routine(codeblock_t *block, int size)
|
|||
}
|
||||
host_x86_CMP64_REG_IMM(block, REG_RSI, (uint32_t)-1);
|
||||
branch_offset = host_x86_JZ_short(block);
|
||||
if (size == 1)
|
||||
if (size == 1 && !is_float)
|
||||
host_x86_MOV8_BASE_INDEX_REG(block, REG_RSI, REG_RDI, REG_ECX);
|
||||
else if (size == 2)
|
||||
else if (size == 2 && !is_float)
|
||||
host_x86_MOV16_BASE_INDEX_REG(block, REG_RSI, REG_RDI, REG_ECX);
|
||||
else if (size == 4)
|
||||
else if (size == 4 && !is_float)
|
||||
host_x86_MOV32_BASE_INDEX_REG(block, REG_RSI, REG_RDI, REG_ECX);
|
||||
else if (size == 4 && is_float)
|
||||
host_x86_MOVD_BASE_INDEX_XREG(block, REG_RSI, REG_RDI, REG_XMM_TEMP);
|
||||
else if (size == 8 && is_float)
|
||||
host_x86_MOVQ_BASE_INDEX_XREG(block, REG_RSI, REG_RDI, REG_XMM_TEMP);
|
||||
else
|
||||
fatal("build_store_routine: size=%i\n", size);
|
||||
host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI, REG_ESI);
|
||||
|
|
@ -182,7 +205,12 @@ static void build_store_routine(codeblock_t *block, int size)
|
|||
host_x86_PUSH(block, REG_RDX);
|
||||
#if WIN64
|
||||
host_x86_SUB64_REG_IMM(block, REG_RSP, 0x20);
|
||||
host_x86_MOV32_REG_REG(block, REG_EDX, REG_ECX); //data
|
||||
if (size == 4 && is_float)
|
||||
host_x86_MOVD_REG_XREG(block, REG_EDX, REG_XMM_TEMP); //data
|
||||
else if (size == 8 && is_float)
|
||||
host_x86_MOVQ_REG_XREG(block, REG_RDX, REG_XMM_TEMP); //data
|
||||
else
|
||||
host_x86_MOV32_REG_REG(block, REG_EDX, REG_ECX); //data
|
||||
host_x86_MOV32_REG_REG(block, REG_ECX, REG_EDI); //address
|
||||
#else
|
||||
//host_x86_MOV32_REG_REG(block, REG_EDI, REG_ECX); //address
|
||||
|
|
@ -194,6 +222,8 @@ static void build_store_routine(codeblock_t *block, int size)
|
|||
host_x86_CALL(block, (void *)writememwl);
|
||||
else if (size == 4)
|
||||
host_x86_CALL(block, (void *)writememll);
|
||||
else if (size == 8)
|
||||
host_x86_CALL(block, (void *)writememql);
|
||||
#if WIN64
|
||||
host_x86_ADD64_REG_IMM(block, REG_RSP, 0x20);
|
||||
#endif
|
||||
|
|
@ -207,18 +237,26 @@ static void build_store_routine(codeblock_t *block, int size)
|
|||
static void build_loadstore_routines(codeblock_t *block)
|
||||
{
|
||||
codegen_mem_load_byte = &codeblock[block_current].data[block_pos];
|
||||
build_load_routine(block, 1);
|
||||
build_load_routine(block, 1, 0);
|
||||
codegen_mem_load_word = &codeblock[block_current].data[block_pos];
|
||||
build_load_routine(block, 2);
|
||||
build_load_routine(block, 2, 0);
|
||||
codegen_mem_load_long = &codeblock[block_current].data[block_pos];
|
||||
build_load_routine(block, 4);
|
||||
build_load_routine(block, 4, 0);
|
||||
codegen_mem_load_single = &codeblock[block_current].data[block_pos];
|
||||
build_load_routine(block, 4, 1);
|
||||
codegen_mem_load_double = &codeblock[block_current].data[block_pos];
|
||||
build_load_routine(block, 8, 1);
|
||||
|
||||
codegen_mem_store_byte = &codeblock[block_current].data[block_pos];
|
||||
build_store_routine(block, 1);
|
||||
build_store_routine(block, 1, 0);
|
||||
codegen_mem_store_word = &codeblock[block_current].data[block_pos];
|
||||
build_store_routine(block, 2);
|
||||
build_store_routine(block, 2, 0);
|
||||
codegen_mem_store_long = &codeblock[block_current].data[block_pos];
|
||||
build_store_routine(block, 4);
|
||||
build_store_routine(block, 4, 0);
|
||||
codegen_mem_store_single = &codeblock[block_current].data[block_pos];
|
||||
build_store_routine(block, 4, 1);
|
||||
codegen_mem_store_double = &codeblock[block_current].data[block_pos];
|
||||
build_store_routine(block, 8, 1);
|
||||
}
|
||||
|
||||
void codegen_backend_init()
|
||||
|
|
|
|||
|
|
@ -50,7 +50,11 @@
|
|||
extern void *codegen_mem_load_byte;
|
||||
extern void *codegen_mem_load_word;
|
||||
extern void *codegen_mem_load_long;
|
||||
extern void *codegen_mem_load_single;
|
||||
extern void *codegen_mem_load_double;
|
||||
|
||||
extern void *codegen_mem_store_byte;
|
||||
extern void *codegen_mem_store_word;
|
||||
extern void *codegen_mem_store_long;
|
||||
extern void *codegen_mem_store_single;
|
||||
extern void *codegen_mem_store_double;
|
||||
|
|
|
|||
|
|
@ -341,6 +341,26 @@ void host_x86_CMP32_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b)
|
|||
codegen_addbyte2(block, 0x39, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/
|
||||
}
|
||||
|
||||
void host_x86_CVTSD2SS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg)
|
||||
{
|
||||
codegen_addbyte4(block, 0xf2, 0x0f, 0x5a, 0xc0 | src_reg | (dst_reg << 3));
|
||||
}
|
||||
|
||||
void host_x86_CVTSI2SD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg)
|
||||
{
|
||||
codegen_addbyte4(block, 0xf2, 0x0f, 0x2a, 0xc0 | src_reg | (dst_reg << 3));
|
||||
}
|
||||
|
||||
void host_x86_CVTSS2SD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg)
|
||||
{
|
||||
codegen_addbyte4(block, 0xf3, 0x0f, 0x5a, 0xc0 | src_reg | (dst_reg << 3));
|
||||
}
|
||||
void host_x86_CVTSS2SD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg)
|
||||
{
|
||||
codegen_addbyte4(block, 0xf3, 0x0f, 0x5a, 0x04 | (dst_reg << 3)); /*CVTSS2SD XMMx, [base_reg + idx_reg]*/
|
||||
codegen_addbyte(block, base_reg | (idx_reg << 3));
|
||||
}
|
||||
|
||||
void host_x86_DIVSD_REG_REG(codeblock_t *block, int dst_reg, int src_reg)
|
||||
{
|
||||
codegen_addbyte4(block, 0xf2, 0x0f, 0x5e, 0xc0 | src_reg | (dst_reg << 3));
|
||||
|
|
@ -837,6 +857,25 @@ void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_d
|
|||
}
|
||||
}
|
||||
|
||||
void host_x86_MOVD_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg)
|
||||
{
|
||||
codegen_addbyte4(block, 0x66, 0x0f, 0x7e, 0x04 | (src_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/
|
||||
codegen_addbyte(block, base_reg | (idx_reg << 3));
|
||||
}
|
||||
void host_x86_MOVD_REG_XREG(codeblock_t *block, int dst_reg, int src_reg)
|
||||
{
|
||||
codegen_addbyte4(block, 0x66, 0x0f, 0x7e, 0xc0 | dst_reg | (src_reg << 3));
|
||||
}
|
||||
void host_x86_MOVD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg)
|
||||
{
|
||||
codegen_addbyte4(block, 0x66, 0x0f, 0x6e, 0x04 | (dst_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/
|
||||
codegen_addbyte(block, base_reg | (idx_reg << 3));
|
||||
}
|
||||
void host_x86_MOVD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg)
|
||||
{
|
||||
codegen_addbyte4(block, 0x66, 0x0f, 0x6e, 0xc0 | src_reg | (dst_reg << 3));
|
||||
}
|
||||
|
||||
void host_x86_MOVQ_ABS_REG(codeblock_t *block, void *p, int src_reg)
|
||||
{
|
||||
int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128);
|
||||
|
|
@ -875,6 +914,12 @@ void host_x86_MOVQ_ABS_REG_REG_SHIFT_REG(codeblock_t *block, uint32_t addr, int
|
|||
}
|
||||
}
|
||||
|
||||
void host_x86_MOVQ_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg)
|
||||
{
|
||||
codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x04 | (src_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/
|
||||
codegen_addbyte(block, base_reg | (idx_reg << 3));
|
||||
}
|
||||
|
||||
void host_x86_MOVQ_REG_ABS(codeblock_t *block, int dst_reg, void *p)
|
||||
{
|
||||
int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128);
|
||||
|
|
@ -912,11 +957,28 @@ void host_x86_MOVQ_REG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32
|
|||
codegen_addlong(block, addr);
|
||||
}
|
||||
}
|
||||
|
||||
void host_x86_MOVQ_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg)
|
||||
{
|
||||
codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x04 | (dst_reg << 3)); /*MOVQ XMMx, [base_reg + idx_reg]*/
|
||||
codegen_addbyte(block, base_reg | (idx_reg << 3));
|
||||
}
|
||||
void host_x86_MOVQ_REG_REG(codeblock_t *block, int dst_reg, int src_reg)
|
||||
{
|
||||
codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0xc0 | src_reg | (dst_reg << 3)); /*MOVQ dst_reg, src_reg*/
|
||||
}
|
||||
|
||||
void host_x86_MOVQ_REG_XREG(codeblock_t *block, int dst_reg, int src_reg)
|
||||
{
|
||||
codegen_addbyte4(block, 0x66, 0x48, 0x0f, 0x7e); /*MOVQ dst_reg, src_reg*/
|
||||
codegen_addbyte(block, 0xc0 | dst_reg | (src_reg << 3));
|
||||
}
|
||||
void host_x86_MOVQ_XREG_REG(codeblock_t *block, int dst_reg, int src_reg)
|
||||
{
|
||||
codegen_addbyte4(block, 0x66, 0x48, 0x0f, 0x6e); /*MOVQ dst_reg, src_reg*/
|
||||
codegen_addbyte(block, 0xc0 | src_reg | (dst_reg << 3));
|
||||
}
|
||||
|
||||
void host_x86_MOVSX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg)
|
||||
{
|
||||
codegen_addbyte4(block, 0x66, 0x0f, 0xbe, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/
|
||||
|
|
|
|||
|
|
@ -27,6 +27,11 @@ void host_x86_CMP8_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b);
|
|||
void host_x86_CMP16_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b);
|
||||
void host_x86_CMP32_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b);
|
||||
|
||||
void host_x86_CVTSD2SS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg);
|
||||
void host_x86_CVTSI2SD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg);
|
||||
void host_x86_CVTSS2SD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg);
|
||||
void host_x86_CVTSS2SD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg);
|
||||
|
||||
void host_x86_DIVSD_REG_REG(codeblock_t *block, int dst_reg, int src_reg);
|
||||
|
||||
void host_x86_JMP(codeblock_t *block, void *p);
|
||||
|
|
@ -92,6 +97,14 @@ void host_x86_MOV32_REG_REG(codeblock_t *block, int dst_reg, int src_reg);
|
|||
|
||||
void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_data);
|
||||
|
||||
void host_x86_MOVD_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg);
|
||||
void host_x86_MOVD_REG_XREG(codeblock_t *block, int dst_reg, int src_reg);
|
||||
void host_x86_MOVD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg);
|
||||
void host_x86_MOVD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg);
|
||||
|
||||
void host_x86_MOVQ_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg);
|
||||
void host_x86_MOVQ_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg);
|
||||
|
||||
void host_x86_MOVQ_REG_REG(codeblock_t *block, int dst_reg, int src_reg);
|
||||
|
||||
void host_x86_MOVQ_REG_ABS(codeblock_t *block, int dst_reg, void *p);
|
||||
|
|
@ -99,6 +112,9 @@ void host_x86_MOVQ_REG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32
|
|||
void host_x86_MOVQ_ABS_REG(codeblock_t *block, void *p, int src_reg);
|
||||
void host_x86_MOVQ_ABS_REG_REG_SHIFT_REG(codeblock_t *block, uint32_t addr, int src_reg_a, int src_reg_b, int shift, int src_reg);
|
||||
|
||||
void host_x86_MOVQ_REG_XREG(codeblock_t *block, int dst_reg, int src_reg);
|
||||
void host_x86_MOVQ_XREG_REG(codeblock_t *block, int dst_reg, int src_reg);
|
||||
|
||||
void host_x86_MOVSX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg);
|
||||
void host_x86_MOVSX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg);
|
||||
void host_x86_MOVSX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg);
|
||||
|
|
|
|||
|
|
@ -771,7 +771,6 @@ static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop)
|
|||
if (REG_IS_B(dest_size))
|
||||
{
|
||||
host_x86_MOV8_REG_REG(block, dest_reg, REG_ECX);
|
||||
// fatal("Here\n");
|
||||
}
|
||||
else if (REG_IS_W(dest_size))
|
||||
{
|
||||
|
|
@ -784,6 +783,42 @@ static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop)
|
|||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real);
|
||||
|
||||
if (!REG_IS_D(dest_size))
|
||||
fatal("MEM_LOAD_SINGLE - %02x\n", uop->dest_reg_a_real);
|
||||
|
||||
host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg);
|
||||
if (uop->imm_data)
|
||||
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_MOVQ_REG_REG(block, dest_reg, REG_XMM_TEMP);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_MEM_LOAD_DOUBLE(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real);
|
||||
|
||||
if (!REG_IS_D(dest_size))
|
||||
fatal("MEM_LOAD_DOUBLE - %02x\n", uop->dest_reg_a_real);
|
||||
|
||||
host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg);
|
||||
if (uop->imm_data)
|
||||
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_MOVQ_REG_REG(block, dest_reg, REG_XMM_TEMP);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
|
|
@ -882,6 +917,43 @@ static int codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real);
|
||||
int src_size = IREG_GET_SIZE(uop->src_reg_c_real);
|
||||
|
||||
if (!REG_IS_D(src_size))
|
||||
fatal("MEM_STORE_SINGLE - %02x\n", uop->src_reg_b_real);
|
||||
|
||||
host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg);
|
||||
if (uop->imm_data)
|
||||
host_x86_ADD32_REG_IMM(block, REG_ESI, REG_ESI, uop->imm_data);
|
||||
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]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_MEM_STORE_DOUBLE(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real);
|
||||
int src_size = IREG_GET_SIZE(uop->src_reg_c_real);
|
||||
|
||||
if (!REG_IS_D(src_size))
|
||||
fatal("MEM_STORE_DOUBLE - %02x\n", uop->src_reg_b_real);
|
||||
|
||||
host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg);
|
||||
if (uop->imm_data)
|
||||
host_x86_ADD32_REG_IMM(block, REG_ESI, REG_ESI, uop->imm_data);
|
||||
host_x86_MOVQ_REG_REG(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]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_MOV(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real);
|
||||
|
|
@ -974,6 +1046,26 @@ static int codegen_MOVZX(codeblock_t *block, uop_t *uop)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
|
||||
|
||||
if (REG_IS_D(dest_size) && REG_IS_L(src_size))
|
||||
{
|
||||
host_x86_CVTSI2SD_XREG_REG(block, dest_reg, src_reg);
|
||||
}
|
||||
else if (REG_IS_D(dest_size) && REG_IS_W(src_size))
|
||||
{
|
||||
host_x86_MOVSX_REG_32_16(block, REG_ECX, src_reg);
|
||||
host_x86_CVTSI2SD_XREG_REG(block, dest_reg, REG_ECX);
|
||||
}
|
||||
else
|
||||
fatal("MOV_DOUBLE_INT %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_OR(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
|
||||
|
|
@ -1386,18 +1478,23 @@ const uOpFn uop_handlers[UOP_MAX] =
|
|||
|
||||
[UOP_MEM_LOAD_ABS & UOP_MASK] = codegen_MEM_LOAD_ABS,
|
||||
[UOP_MEM_LOAD_REG & UOP_MASK] = codegen_MEM_LOAD_REG,
|
||||
[UOP_MEM_LOAD_SINGLE & UOP_MASK] = codegen_MEM_LOAD_SINGLE,
|
||||
[UOP_MEM_LOAD_DOUBLE & UOP_MASK] = codegen_MEM_LOAD_DOUBLE,
|
||||
|
||||
[UOP_MEM_STORE_ABS & UOP_MASK] = codegen_MEM_STORE_ABS,
|
||||
[UOP_MEM_STORE_REG & UOP_MASK] = codegen_MEM_STORE_REG,
|
||||
[UOP_MEM_STORE_IMM_8 & UOP_MASK] = codegen_MEM_STORE_IMM_8,
|
||||
[UOP_MEM_STORE_IMM_16 & UOP_MASK] = codegen_MEM_STORE_IMM_16,
|
||||
[UOP_MEM_STORE_IMM_32 & UOP_MASK] = codegen_MEM_STORE_IMM_32,
|
||||
[UOP_MEM_STORE_SINGLE & UOP_MASK] = codegen_MEM_STORE_SINGLE,
|
||||
[UOP_MEM_STORE_DOUBLE & UOP_MASK] = codegen_MEM_STORE_DOUBLE,
|
||||
|
||||
[UOP_MOV & UOP_MASK] = codegen_MOV,
|
||||
[UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR,
|
||||
[UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM,
|
||||
[UOP_MOVSX & UOP_MASK] = codegen_MOVSX,
|
||||
[UOP_MOVZX & UOP_MASK] = codegen_MOVZX,
|
||||
[UOP_MOV_DOUBLE_INT & UOP_MASK] = codegen_MOV_DOUBLE_INT,
|
||||
|
||||
[UOP_ADD & UOP_MASK] = codegen_ADD,
|
||||
[UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM,
|
||||
|
|
|
|||
|
|
@ -19,10 +19,14 @@
|
|||
void *codegen_mem_load_byte;
|
||||
void *codegen_mem_load_word;
|
||||
void *codegen_mem_load_long;
|
||||
void *codegen_mem_load_single;
|
||||
void *codegen_mem_load_double;
|
||||
|
||||
void *codegen_mem_store_byte;
|
||||
void *codegen_mem_store_word;
|
||||
void *codegen_mem_store_long;
|
||||
void *codegen_mem_store_single;
|
||||
void *codegen_mem_store_double;
|
||||
|
||||
int codegen_host_reg_list[CODEGEN_HOST_REGS] =
|
||||
{
|
||||
|
|
@ -38,13 +42,12 @@ int codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] =
|
|||
REG_XMM2,
|
||||
REG_XMM3,
|
||||
REG_XMM4,
|
||||
REG_XMM5,
|
||||
REG_XMM6
|
||||
REG_XMM5
|
||||
};
|
||||
|
||||
static void *mem_abrt_rout;
|
||||
|
||||
static void build_load_routine(codeblock_t *block, int size)
|
||||
static void build_load_routine(codeblock_t *block, int size, int is_float)
|
||||
{
|
||||
uint8_t *branch_offset;
|
||||
uint8_t *misaligned_offset = NULL;
|
||||
|
|
@ -79,12 +82,16 @@ static void build_load_routine(codeblock_t *block, int size)
|
|||
}
|
||||
host_x86_CMP32_REG_IMM(block, REG_ESI, (uint32_t)-1);
|
||||
branch_offset = host_x86_JZ_short(block);
|
||||
if (size == 1)
|
||||
if (size == 1 && !is_float)
|
||||
host_x86_MOVZX_BASE_INDEX_32_8(block, REG_ECX, REG_ESI, REG_ECX);
|
||||
else if (size == 2)
|
||||
else if (size == 2 && !is_float)
|
||||
host_x86_MOVZX_BASE_INDEX_32_16(block, REG_ECX, REG_ESI, REG_ECX);
|
||||
else if (size == 4)
|
||||
else if (size == 4 && !is_float)
|
||||
host_x86_MOV32_REG_BASE_INDEX(block, REG_ECX, REG_ESI, REG_ECX);
|
||||
else if (size == 4 && is_float)
|
||||
host_x86_CVTSS2SD_XREG_BASE_INDEX(block, REG_XMM_TEMP, REG_ESI, REG_ECX);
|
||||
else if (size == 8 && is_float)
|
||||
host_x86_MOVQ_XREG_BASE_INDEX(block, REG_XMM_TEMP, REG_ESI, REG_ECX);
|
||||
else
|
||||
fatal("build_load_routine: size=%i\n", size);
|
||||
host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI, REG_ESI);
|
||||
|
|
@ -102,13 +109,26 @@ static void build_load_routine(codeblock_t *block, int size)
|
|||
host_x86_CALL(block, (void *)readmemwl);
|
||||
else if (size == 4)
|
||||
host_x86_CALL(block, (void *)readmemll);
|
||||
else if (size == 8)
|
||||
host_x86_CALL(block, (void *)readmemql);
|
||||
host_x86_POP(block, REG_ECX);
|
||||
if (size == 1)
|
||||
if (size == 1 && !is_float)
|
||||
host_x86_MOVZX_REG_32_8(block, REG_ECX, REG_EAX);
|
||||
else if (size == 2)
|
||||
else if (size == 2 && !is_float)
|
||||
host_x86_MOVZX_REG_32_16(block, REG_ECX, REG_EAX);
|
||||
else if (size == 4)
|
||||
else if (size == 4 && !is_float)
|
||||
host_x86_MOV32_REG_REG(block, REG_ECX, REG_EAX);
|
||||
else if (size == 4 && is_float)
|
||||
{
|
||||
host_x86_MOVD_XREG_REG(block, REG_XMM_TEMP, REG_EAX);
|
||||
host_x86_CVTSS2SD_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP);
|
||||
}
|
||||
else if (size == 8 && is_float)
|
||||
{
|
||||
host_x86_MOVD_XREG_REG(block, REG_XMM_TEMP, REG_EAX);
|
||||
host_x86_MOVD_XREG_REG(block, REG_XMM_TEMP2, REG_EDX);
|
||||
host_x86_UNPCKLPS_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP2);
|
||||
}
|
||||
host_x86_POP(block, REG_EDX);
|
||||
host_x86_POP(block, REG_EAX);
|
||||
host_x86_MOVZX_REG_ABS_32_8(block, REG_ESI, &cpu_state.abrt);
|
||||
|
|
@ -116,7 +136,7 @@ static void build_load_routine(codeblock_t *block, int size)
|
|||
block_pos = (block_pos + 63) & ~63;
|
||||
}
|
||||
|
||||
static void build_store_routine(codeblock_t *block, int size)
|
||||
static void build_store_routine(codeblock_t *block, int size, int is_float)
|
||||
{
|
||||
uint8_t *branch_offset;
|
||||
uint8_t *misaligned_offset = NULL;
|
||||
|
|
@ -152,23 +172,34 @@ static void build_store_routine(codeblock_t *block, int size)
|
|||
}
|
||||
host_x86_CMP32_REG_IMM(block, REG_ESI, (uint32_t)-1);
|
||||
branch_offset = host_x86_JZ_short(block);
|
||||
if (size == 1)
|
||||
if (size == 1 && !is_float)
|
||||
host_x86_MOV8_BASE_INDEX_REG(block, REG_ESI, REG_EDI, REG_ECX);
|
||||
else if (size == 2)
|
||||
else if (size == 2 && !is_float)
|
||||
host_x86_MOV16_BASE_INDEX_REG(block, REG_ESI, REG_EDI, REG_ECX);
|
||||
else if (size == 4)
|
||||
else if (size == 4 && !is_float)
|
||||
host_x86_MOV32_BASE_INDEX_REG(block, REG_ESI, REG_EDI, REG_ECX);
|
||||
else if (size == 4 && is_float)
|
||||
host_x86_MOVD_BASE_INDEX_XREG(block, REG_ESI, REG_EDI, REG_XMM_TEMP);
|
||||
else if (size == 8 && is_float)
|
||||
host_x86_MOVQ_BASE_INDEX_XREG(block, REG_ESI, REG_EDI, REG_XMM_TEMP);
|
||||
else
|
||||
fatal("build_store_routine: size=%i\n", size);
|
||||
fatal("build_store_routine: size=%i is_float=%i\n", size, is_float);
|
||||
host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI, REG_ESI);
|
||||
host_x86_RET(block);
|
||||
|
||||
*branch_offset = (uint8_t)((uintptr_t)&block->data[block_pos] - (uintptr_t)branch_offset) - 1;
|
||||
if (size != 1)
|
||||
*misaligned_offset = (uint8_t)((uintptr_t)&block->data[block_pos] - (uintptr_t)misaligned_offset) - 1;
|
||||
if (size == 4 && is_float)
|
||||
host_x86_MOVD_REG_XREG(block, REG_ECX, REG_XMM_TEMP);
|
||||
host_x86_PUSH(block, REG_EAX);
|
||||
host_x86_PUSH(block, REG_EDX);
|
||||
host_x86_PUSH(block, REG_ECX);
|
||||
if (size == 8 && is_float)
|
||||
{
|
||||
host_x86_MOVQ_STACK_OFFSET_XREG(block, -8, REG_XMM_TEMP);
|
||||
host_x86_SUB32_REG_IMM(block, REG_ESP, REG_ESP, 8);
|
||||
}
|
||||
host_x86_PUSH(block, REG_EDI);
|
||||
if (size == 1)
|
||||
host_x86_CALL(block, (void *)writememb386l);
|
||||
|
|
@ -176,7 +207,11 @@ static void build_store_routine(codeblock_t *block, int size)
|
|||
host_x86_CALL(block, (void *)writememwl);
|
||||
else if (size == 4)
|
||||
host_x86_CALL(block, (void *)writememll);
|
||||
else if (size == 8)
|
||||
host_x86_CALL(block, (void *)writememql);
|
||||
host_x86_POP(block, REG_EDI);
|
||||
if (size == 8 && is_float)
|
||||
host_x86_ADD32_REG_IMM(block, REG_ESP, REG_ESP, 8);
|
||||
host_x86_POP(block, REG_ECX);
|
||||
host_x86_POP(block, REG_EDX);
|
||||
host_x86_POP(block, REG_EAX);
|
||||
|
|
@ -188,18 +223,26 @@ static void build_store_routine(codeblock_t *block, int size)
|
|||
static void build_loadstore_routines(codeblock_t *block)
|
||||
{
|
||||
codegen_mem_load_byte = &codeblock[block_current].data[block_pos];
|
||||
build_load_routine(block, 1);
|
||||
build_load_routine(block, 1, 0);
|
||||
codegen_mem_load_word = &codeblock[block_current].data[block_pos];
|
||||
build_load_routine(block, 2);
|
||||
build_load_routine(block, 2, 0);
|
||||
codegen_mem_load_long = &codeblock[block_current].data[block_pos];
|
||||
build_load_routine(block, 4);
|
||||
build_load_routine(block, 4, 0);
|
||||
codegen_mem_load_single = &codeblock[block_current].data[block_pos];
|
||||
build_load_routine(block, 4, 1);
|
||||
codegen_mem_load_double = &codeblock[block_current].data[block_pos];
|
||||
build_load_routine(block, 8, 1);
|
||||
|
||||
codegen_mem_store_byte = &codeblock[block_current].data[block_pos];
|
||||
build_store_routine(block, 1);
|
||||
build_store_routine(block, 1, 0);
|
||||
codegen_mem_store_word = &codeblock[block_current].data[block_pos];
|
||||
build_store_routine(block, 2);
|
||||
build_store_routine(block, 2, 0);
|
||||
codegen_mem_store_long = &codeblock[block_current].data[block_pos];
|
||||
build_store_routine(block, 4);
|
||||
build_store_routine(block, 4, 0);
|
||||
codegen_mem_store_single = &codeblock[block_current].data[block_pos];
|
||||
build_store_routine(block, 4, 1);
|
||||
codegen_mem_store_double = &codeblock[block_current].data[block_pos];
|
||||
build_store_routine(block, 8, 1);
|
||||
}
|
||||
|
||||
void codegen_backend_init()
|
||||
|
|
|
|||
|
|
@ -19,17 +19,22 @@
|
|||
#define REG_XMM6 6
|
||||
#define REG_XMM7 7
|
||||
|
||||
#define REG_XMM_TEMP REG_XMM7
|
||||
#define REG_XMM_TEMP REG_XMM7
|
||||
#define REG_XMM_TEMP2 REG_XMM6
|
||||
|
||||
#define CODEGEN_HOST_REGS 3
|
||||
#define CODEGEN_HOST_FP_REGS 7
|
||||
#define CODEGEN_HOST_FP_REGS 6
|
||||
|
||||
extern void *codegen_mem_load_byte;
|
||||
extern void *codegen_mem_load_word;
|
||||
extern void *codegen_mem_load_long;
|
||||
extern void *codegen_mem_load_single;
|
||||
extern void *codegen_mem_load_double;
|
||||
|
||||
extern void *codegen_mem_store_byte;
|
||||
extern void *codegen_mem_store_word;
|
||||
extern void *codegen_mem_store_long;
|
||||
extern void *codegen_mem_store_single;
|
||||
extern void *codegen_mem_store_double;
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -185,7 +185,7 @@ void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int
|
|||
codegen_addbyte2(block, 0x01, 0xc0 | dst_reg | (src_reg_b << 3)); /*ADD dst_reg, src_reg_b*/
|
||||
}
|
||||
|
||||
void host_x86_ADDSD_REG_REG(codeblock_t *block, int dst_reg, int src_reg)
|
||||
void host_x86_ADDSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg)
|
||||
{
|
||||
codegen_addbyte4(block, 0xf2, 0x0f, 0x58, 0xc0 | src_reg | (dst_reg << 3));
|
||||
}
|
||||
|
|
@ -309,7 +309,27 @@ void host_x86_CMP32_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b)
|
|||
codegen_addbyte2(block, 0x39, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/
|
||||
}
|
||||
|
||||
void host_x86_DIVSD_REG_REG(codeblock_t *block, int dst_reg, int src_reg)
|
||||
void host_x86_CVTSD2SS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg)
|
||||
{
|
||||
codegen_addbyte4(block, 0xf2, 0x0f, 0x5a, 0xc0 | src_reg | (dst_reg << 3));
|
||||
}
|
||||
|
||||
void host_x86_CVTSI2SD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg)
|
||||
{
|
||||
codegen_addbyte4(block, 0xf2, 0x0f, 0x2a, 0xc0 | src_reg | (dst_reg << 3));
|
||||
}
|
||||
|
||||
void host_x86_CVTSS2SD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg)
|
||||
{
|
||||
codegen_addbyte4(block, 0xf3, 0x0f, 0x5a, 0xc0 | src_reg | (dst_reg << 3));
|
||||
}
|
||||
void host_x86_CVTSS2SD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg)
|
||||
{
|
||||
codegen_addbyte4(block, 0xf3, 0x0f, 0x5a, 0x04 | (dst_reg << 3)); /*CVTSS2SD XMMx, [base_reg + idx_reg]*/
|
||||
codegen_addbyte(block, base_reg | (idx_reg << 3));
|
||||
}
|
||||
|
||||
void host_x86_DIVSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg)
|
||||
{
|
||||
codegen_addbyte4(block, 0xf2, 0x0f, 0x5e, 0xc0 | src_reg | (dst_reg << 3));
|
||||
}
|
||||
|
|
@ -714,7 +734,26 @@ void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_d
|
|||
}
|
||||
}
|
||||
|
||||
void host_x86_MOVQ_ABS_REG(codeblock_t *block, void *p, int src_reg)
|
||||
void host_x86_MOVD_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg)
|
||||
{
|
||||
codegen_addbyte4(block, 0x66, 0x0f, 0x7e, 0x04 | (src_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/
|
||||
codegen_addbyte(block, base_reg | (idx_reg << 3));
|
||||
}
|
||||
void host_x86_MOVD_REG_XREG(codeblock_t *block, int dst_reg, int src_reg)
|
||||
{
|
||||
codegen_addbyte4(block, 0x66, 0x0f, 0x7e, 0xc0 | dst_reg | (src_reg << 3));
|
||||
}
|
||||
void host_x86_MOVD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg)
|
||||
{
|
||||
codegen_addbyte4(block, 0x66, 0x0f, 0x6e, 0x04 | (dst_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/
|
||||
codegen_addbyte(block, base_reg | (idx_reg << 3));
|
||||
}
|
||||
void host_x86_MOVD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg)
|
||||
{
|
||||
codegen_addbyte4(block, 0x66, 0x0f, 0x6e, 0xc0 | src_reg | (dst_reg << 3));
|
||||
}
|
||||
|
||||
void host_x86_MOVQ_ABS_XREG(codeblock_t *block, void *p, int src_reg)
|
||||
{
|
||||
int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128);
|
||||
|
||||
|
|
@ -729,7 +768,7 @@ void host_x86_MOVQ_ABS_REG(codeblock_t *block, void *p, int src_reg)
|
|||
codegen_addlong(block, (uint32_t)p);
|
||||
}
|
||||
}
|
||||
void host_x86_MOVQ_ABS_REG_REG_SHIFT_REG(codeblock_t *block, uint32_t addr, int src_reg_a, int src_reg_b, int shift, int src_reg)
|
||||
void host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(codeblock_t *block, uint32_t addr, int src_reg_a, int src_reg_b, int shift, int src_reg)
|
||||
{
|
||||
codegen_addbyte3(block, 0x66, 0x0f, 0xd6); /*MOVQ addr[src_reg_a + src_reg_b << shift], XMMx*/
|
||||
if (addr < 0x80 || addr >= 0xffffff80)
|
||||
|
|
@ -742,8 +781,33 @@ void host_x86_MOVQ_ABS_REG_REG_SHIFT_REG(codeblock_t *block, uint32_t addr, int
|
|||
codegen_addlong(block, addr);
|
||||
}
|
||||
}
|
||||
void host_x86_MOVQ_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg)
|
||||
{
|
||||
codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x04 | (src_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/
|
||||
codegen_addbyte(block, base_reg | (idx_reg << 3));
|
||||
}
|
||||
void host_x86_MOVQ_STACK_OFFSET_XREG(codeblock_t *block, int offset, int src_reg)
|
||||
{
|
||||
if (!offset)
|
||||
{
|
||||
codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x04 | (src_reg << 3)); /*MOVQ [ESP], src_reg*/
|
||||
codegen_addbyte(block, 0x24);
|
||||
}
|
||||
else if (offset >= -80 || offset < 0x80)
|
||||
{
|
||||
codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x44 | (src_reg << 3)); /*MOVQ offset[ESP], src_reg*/
|
||||
codegen_addbyte2(block, 0x24, offset & 0xff);
|
||||
}
|
||||
else
|
||||
{
|
||||
codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x84 | (src_reg << 3)); /*MOVQ offset[ESP], src_reg*/
|
||||
codegen_addbyte(block, 0x24);
|
||||
codegen_addlong(block, offset);
|
||||
}
|
||||
|
||||
void host_x86_MOVQ_REG_ABS(codeblock_t *block, int dst_reg, void *p)
|
||||
}
|
||||
|
||||
void host_x86_MOVQ_XREG_ABS(codeblock_t *block, int dst_reg, void *p)
|
||||
{
|
||||
int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128);
|
||||
|
||||
|
|
@ -758,7 +822,7 @@ void host_x86_MOVQ_REG_ABS(codeblock_t *block, int dst_reg, void *p)
|
|||
codegen_addlong(block, (uint32_t)p);
|
||||
}
|
||||
}
|
||||
void host_x86_MOVQ_REG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int src_reg_a, int src_reg_b, int shift)
|
||||
void host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int src_reg_a, int src_reg_b, int shift)
|
||||
{
|
||||
codegen_addbyte3(block, 0xf3, 0x0f, 0x7e); /*MOVQ XMMx, addr[src_reg_a + src_reg_b << shift]*/
|
||||
if (addr < 0x80 || addr >= 0xffffff80)
|
||||
|
|
@ -771,7 +835,12 @@ void host_x86_MOVQ_REG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32
|
|||
codegen_addlong(block, addr);
|
||||
}
|
||||
}
|
||||
void host_x86_MOVQ_REG_REG(codeblock_t *block, int dst_reg, int src_reg)
|
||||
void host_x86_MOVQ_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg)
|
||||
{
|
||||
codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x04 | (dst_reg << 3)); /*MOVQ XMMx, [base_reg + idx_reg]*/
|
||||
codegen_addbyte(block, base_reg | (idx_reg << 3));
|
||||
}
|
||||
void host_x86_MOVQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg)
|
||||
{
|
||||
codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0xc0 | src_reg | (dst_reg << 3)); /*MOVQ dst_reg, src_reg*/
|
||||
}
|
||||
|
|
@ -840,7 +909,7 @@ void host_x86_MOVZX_BASE_INDEX_32_16(codeblock_t *block, int dst_reg, int base_r
|
|||
codegen_addbyte4(block, 0x0f, 0xb7, 0x04 | (dst_reg << 3), base_reg | (idx_reg << 3)); /*MOVZX dst_reg, W[base_reg + idx_reg]*/
|
||||
}
|
||||
|
||||
void host_x86_MULSD_REG_REG(codeblock_t *block, int dst_reg, int src_reg)
|
||||
void host_x86_MULSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg)
|
||||
{
|
||||
codegen_addbyte4(block, 0xf2, 0x0f, 0x59, 0xc0 | src_reg | (dst_reg << 3));
|
||||
}
|
||||
|
|
@ -1078,7 +1147,7 @@ void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int
|
|||
codegen_addbyte2(block, 0x29, 0xc0 | dst_reg | (src_reg_b << 3)); /*SUB dst_reg, src_reg_b*/
|
||||
}
|
||||
|
||||
void host_x86_SUBSD_REG_REG(codeblock_t *block, int dst_reg, int src_reg)
|
||||
void host_x86_SUBSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg)
|
||||
{
|
||||
codegen_addbyte4(block, 0xf2, 0x0f, 0x5c, 0xc0 | src_reg | (dst_reg << 3));
|
||||
}
|
||||
|
|
@ -1109,6 +1178,11 @@ void host_x86_TEST32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data)
|
|||
}
|
||||
}
|
||||
|
||||
void host_x86_UNPCKLPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg)
|
||||
{
|
||||
codegen_addbyte3(block, 0x0f, 0x14, 0xc0 | src_reg | (dst_reg << 3));
|
||||
}
|
||||
|
||||
void host_x86_XOR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b)
|
||||
{
|
||||
if (dst_reg != src_reg_a)
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ void host_x86_ADD8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int s
|
|||
void host_x86_ADD16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b);
|
||||
void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b);
|
||||
|
||||
void host_x86_ADDSD_REG_REG(codeblock_t *block, int dst_reg, int src_reg);
|
||||
void host_x86_ADDSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg);
|
||||
|
||||
void host_x86_AND8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data);
|
||||
void host_x86_AND16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data);
|
||||
|
|
@ -27,7 +27,14 @@ void host_x86_CMP8_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b);
|
|||
void host_x86_CMP16_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b);
|
||||
void host_x86_CMP32_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b);
|
||||
|
||||
void host_x86_DIVSD_REG_REG(codeblock_t *block, int dst_reg, int src_reg);
|
||||
void host_x86_CVTSD2SS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg);
|
||||
|
||||
void host_x86_CVTSI2SD_XREG_REG(codeblock_t *block, int dest_reg, int src_reg);
|
||||
|
||||
void host_x86_CVTSS2SD_XREG_XREG(codeblock_t *block, int dest_reg, int src_reg);
|
||||
void host_x86_CVTSS2SD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg);
|
||||
|
||||
void host_x86_DIVSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg);
|
||||
|
||||
void host_x86_JMP(codeblock_t *block, void *p);
|
||||
|
||||
|
|
@ -94,12 +101,20 @@ void host_x86_MOV32_REG_REG(codeblock_t *block, int dst_reg, int src_reg);
|
|||
|
||||
void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_data);
|
||||
|
||||
void host_x86_MOVQ_REG_REG(codeblock_t *block, int dst_reg, int src_reg);
|
||||
void host_x86_MOVD_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg);
|
||||
void host_x86_MOVD_REG_XREG(codeblock_t *block, int dst_reg, int src_reg);
|
||||
void host_x86_MOVD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg);
|
||||
void host_x86_MOVD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg);
|
||||
|
||||
void host_x86_MOVQ_REG_ABS(codeblock_t *block, int dst_reg, void *p);
|
||||
void host_x86_MOVQ_REG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int src_reg_a, int src_reg_b, int shift);
|
||||
void host_x86_MOVQ_ABS_REG(codeblock_t *block, void *p, int src_reg);
|
||||
void host_x86_MOVQ_ABS_REG_REG_SHIFT_REG(codeblock_t *block, uint32_t addr, int src_reg_a, int src_reg_b, int shift, int src_reg);
|
||||
void host_x86_MOVQ_ABS_XREG(codeblock_t *block, void *p, int src_reg);
|
||||
void host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(codeblock_t *block, uint32_t addr, int src_reg_a, int src_reg_b, int shift, int src_reg);
|
||||
void host_x86_MOVQ_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg);
|
||||
void host_x86_MOVQ_STACK_OFFSET_XREG(codeblock_t *block, int offset, int src_reg);
|
||||
|
||||
void host_x86_MOVQ_XREG_ABS(codeblock_t *block, int dst_reg, void *p);
|
||||
void host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int src_reg_a, int src_reg_b, int shift);
|
||||
void host_x86_MOVQ_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg);
|
||||
void host_x86_MOVQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg);
|
||||
|
||||
void host_x86_MOVSX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg);
|
||||
void host_x86_MOVSX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg);
|
||||
|
|
@ -114,7 +129,7 @@ void host_x86_MOVZX_REG_ABS_32_8(codeblock_t *block, int dst_reg, void *p);
|
|||
void host_x86_MOVZX_BASE_INDEX_32_8(codeblock_t *block, int dst_reg, int base_reg, int idx_reg);
|
||||
void host_x86_MOVZX_BASE_INDEX_32_16(codeblock_t *block, int dst_reg, int base_reg, int idx_reg);
|
||||
|
||||
void host_x86_MULSD_REG_REG(codeblock_t *block, int dst_reg, int src_reg);
|
||||
void host_x86_MULSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg);
|
||||
|
||||
void host_x86_OR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b);
|
||||
void host_x86_OR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b);
|
||||
|
|
@ -162,7 +177,7 @@ void host_x86_SUB8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int s
|
|||
void host_x86_SUB16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b);
|
||||
void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b);
|
||||
|
||||
void host_x86_SUBSD_REG_REG(codeblock_t *block, int dst_reg, int src_reg);
|
||||
void host_x86_SUBSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg);
|
||||
|
||||
void host_x86_TEST8_REG(codeblock_t *block, int src_host_reg, int dst_host_reg);
|
||||
void host_x86_TEST16_REG(codeblock_t *block, int src_host_reg, int dst_host_reg);
|
||||
|
|
@ -170,6 +185,8 @@ void host_x86_TEST32_REG(codeblock_t *block, int src_host_reg, int dst_host_reg)
|
|||
|
||||
void host_x86_TEST32_REG_IMM(codeblock_t *block, int src_host_reg, uint32_t imm_data);
|
||||
|
||||
void host_x86_UNPCKLPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg);
|
||||
|
||||
void host_x86_XOR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b);
|
||||
void host_x86_XOR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b);
|
||||
void host_x86_XOR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b);
|
||||
|
|
|
|||
|
|
@ -545,7 +545,7 @@ static int codegen_FADD(codeblock_t *block, uop_t *uop)
|
|||
|
||||
if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a)
|
||||
{
|
||||
host_x86_ADDSD_REG_REG(block, dest_reg, src_reg_b);
|
||||
host_x86_ADDSD_XREG_XREG(block, dest_reg, src_reg_b);
|
||||
}
|
||||
else
|
||||
fatal("codegen_FADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
|
||||
|
|
@ -559,13 +559,13 @@ static int codegen_FDIV(codeblock_t *block, uop_t *uop)
|
|||
|
||||
if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a)
|
||||
{
|
||||
host_x86_DIVSD_REG_REG(block, dest_reg, src_reg_b);
|
||||
host_x86_DIVSD_XREG_XREG(block, dest_reg, src_reg_b);
|
||||
}
|
||||
else if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b))
|
||||
{
|
||||
host_x86_MOVQ_REG_REG(block, REG_XMM_TEMP, src_reg_a);
|
||||
host_x86_DIVSD_REG_REG(block, REG_XMM_TEMP, src_reg_b);
|
||||
host_x86_MOVQ_REG_REG(block, dest_reg, REG_XMM_TEMP);
|
||||
host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a);
|
||||
host_x86_DIVSD_XREG_XREG(block, REG_XMM_TEMP, src_reg_b);
|
||||
host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP);
|
||||
}
|
||||
else
|
||||
fatal("codegen_FDIV %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
|
||||
|
|
@ -579,7 +579,7 @@ static int codegen_FMUL(codeblock_t *block, uop_t *uop)
|
|||
|
||||
if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a)
|
||||
{
|
||||
host_x86_MULSD_REG_REG(block, dest_reg, src_reg_b);
|
||||
host_x86_MULSD_XREG_XREG(block, dest_reg, src_reg_b);
|
||||
}
|
||||
else
|
||||
fatal("codegen_FMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
|
||||
|
|
@ -593,13 +593,13 @@ static int codegen_FSUB(codeblock_t *block, uop_t *uop)
|
|||
|
||||
if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a)
|
||||
{
|
||||
host_x86_SUBSD_REG_REG(block, dest_reg, src_reg_b);
|
||||
host_x86_SUBSD_XREG_XREG(block, dest_reg, src_reg_b);
|
||||
}
|
||||
else if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b))
|
||||
{
|
||||
host_x86_MOVQ_REG_REG(block, REG_XMM_TEMP, src_reg_a);
|
||||
host_x86_SUBSD_REG_REG(block, REG_XMM_TEMP, src_reg_b);
|
||||
host_x86_MOVQ_REG_REG(block, dest_reg, REG_XMM_TEMP);
|
||||
host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a);
|
||||
host_x86_SUBSD_XREG_XREG(block, REG_XMM_TEMP, src_reg_b);
|
||||
host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP);
|
||||
}
|
||||
else
|
||||
fatal("codegen_FSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
|
||||
|
|
@ -773,6 +773,43 @@ static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop)
|
|||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real);
|
||||
|
||||
if (!REG_IS_D(dest_size))
|
||||
fatal("MEM_LOAD_SINGLE - %02x\n", uop->dest_reg_a_real);
|
||||
|
||||
host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg);
|
||||
if (uop->imm_data)
|
||||
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_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_MEM_LOAD_DOUBLE(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real);
|
||||
|
||||
if (!REG_IS_D(dest_size))
|
||||
fatal("MEM_LOAD_DOUBLE - %02x\n", uop->dest_reg_a_real);
|
||||
|
||||
host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg);
|
||||
if (uop->imm_data)
|
||||
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_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
|
|
@ -871,6 +908,43 @@ static int codegen_MEM_STORE_IMM_32(codeblock_t *block, uop_t *uop)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real);
|
||||
int src_size = IREG_GET_SIZE(uop->src_reg_c_real);
|
||||
|
||||
if (!REG_IS_D(src_size))
|
||||
fatal("MEM_STORE_SINGLE - %02x\n", uop->src_reg_b_real);
|
||||
|
||||
host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg);
|
||||
if (uop->imm_data)
|
||||
host_x86_ADD32_REG_IMM(block, REG_ESI, REG_ESI, uop->imm_data);
|
||||
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]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_MEM_STORE_DOUBLE(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real);
|
||||
int src_size = IREG_GET_SIZE(uop->src_reg_c_real);
|
||||
|
||||
if (!REG_IS_D(src_size))
|
||||
fatal("MEM_STORE_DOUBLE - %02x\n", uop->src_reg_b_real);
|
||||
|
||||
host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg);
|
||||
if (uop->imm_data)
|
||||
host_x86_ADD32_REG_IMM(block, REG_ESI, REG_ESI, uop->imm_data);
|
||||
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]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_MOV(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real);
|
||||
|
|
@ -963,6 +1037,26 @@ static int codegen_MOVZX(codeblock_t *block, uop_t *uop)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
|
||||
|
||||
if (REG_IS_D(dest_size) && REG_IS_L(src_size))
|
||||
{
|
||||
host_x86_CVTSI2SD_XREG_REG(block, dest_reg, src_reg);
|
||||
}
|
||||
else if (REG_IS_D(dest_size) && REG_IS_W(src_size))
|
||||
{
|
||||
host_x86_MOVSX_REG_32_16(block, REG_ECX, src_reg);
|
||||
host_x86_CVTSI2SD_XREG_REG(block, dest_reg, REG_ECX);
|
||||
}
|
||||
else
|
||||
fatal("MOV_DOUBLE_INT %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_OR(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
|
||||
|
|
@ -1369,20 +1463,25 @@ const uOpFn uop_handlers[UOP_MAX] =
|
|||
[UOP_STORE_P_IMM & UOP_MASK] = codegen_STORE_PTR_IMM,
|
||||
[UOP_STORE_P_IMM_8 & UOP_MASK] = codegen_STORE_PTR_IMM_8,
|
||||
|
||||
[UOP_MEM_LOAD_ABS & UOP_MASK] = codegen_MEM_LOAD_ABS,
|
||||
[UOP_MEM_LOAD_REG & UOP_MASK] = codegen_MEM_LOAD_REG,
|
||||
[UOP_MEM_LOAD_ABS & UOP_MASK] = codegen_MEM_LOAD_ABS,
|
||||
[UOP_MEM_LOAD_REG & UOP_MASK] = codegen_MEM_LOAD_REG,
|
||||
[UOP_MEM_LOAD_SINGLE & UOP_MASK] = codegen_MEM_LOAD_SINGLE,
|
||||
[UOP_MEM_LOAD_DOUBLE & UOP_MASK] = codegen_MEM_LOAD_DOUBLE,
|
||||
|
||||
[UOP_MEM_STORE_ABS & UOP_MASK] = codegen_MEM_STORE_ABS,
|
||||
[UOP_MEM_STORE_REG & UOP_MASK] = codegen_MEM_STORE_REG,
|
||||
[UOP_MEM_STORE_IMM_8 & UOP_MASK] = codegen_MEM_STORE_IMM_8,
|
||||
[UOP_MEM_STORE_IMM_16 & UOP_MASK] = codegen_MEM_STORE_IMM_16,
|
||||
[UOP_MEM_STORE_IMM_32 & UOP_MASK] = codegen_MEM_STORE_IMM_32,
|
||||
[UOP_MEM_STORE_SINGLE & UOP_MASK] = codegen_MEM_STORE_SINGLE,
|
||||
[UOP_MEM_STORE_DOUBLE & UOP_MASK] = codegen_MEM_STORE_DOUBLE,
|
||||
|
||||
[UOP_MOV & UOP_MASK] = codegen_MOV,
|
||||
[UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR,
|
||||
[UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM,
|
||||
[UOP_MOVSX & UOP_MASK] = codegen_MOVSX,
|
||||
[UOP_MOVZX & UOP_MASK] = codegen_MOVZX,
|
||||
[UOP_MOV & UOP_MASK] = codegen_MOV,
|
||||
[UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR,
|
||||
[UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM,
|
||||
[UOP_MOVSX & UOP_MASK] = codegen_MOVSX,
|
||||
[UOP_MOVZX & UOP_MASK] = codegen_MOVZX,
|
||||
[UOP_MOV_DOUBLE_INT & UOP_MASK] = codegen_MOV_DOUBLE_INT,
|
||||
|
||||
[UOP_ADD & UOP_MASK] = codegen_ADD,
|
||||
[UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM,
|
||||
|
|
@ -1442,7 +1541,7 @@ void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p)
|
|||
}
|
||||
void codegen_direct_read_double(codeblock_t *block, int host_reg, void *p)
|
||||
{
|
||||
host_x86_MOVQ_REG_ABS(block, host_reg, p);
|
||||
host_x86_MOVQ_XREG_ABS(block, host_reg, p);
|
||||
}
|
||||
void codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, int reg_idx)
|
||||
{
|
||||
|
|
@ -1451,7 +1550,7 @@ void codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base,
|
|||
host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset);
|
||||
host_x86_ADD32_REG_IMM(block, REG_ECX, REG_ECX, reg_idx);
|
||||
host_x86_AND32_REG_IMM(block, REG_ECX, REG_ECX, 7);
|
||||
host_x86_MOVQ_REG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_EBP, REG_ECX, 3);
|
||||
host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_EBP, REG_ECX, 3);
|
||||
}
|
||||
|
||||
void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg)
|
||||
|
|
@ -1477,7 +1576,7 @@ void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int
|
|||
}
|
||||
void codegen_direct_write_double(codeblock_t *block, void *p, int host_reg)
|
||||
{
|
||||
host_x86_MOVQ_ABS_REG(block, p, host_reg);
|
||||
host_x86_MOVQ_ABS_XREG(block, p, host_reg);
|
||||
}
|
||||
void codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, int host_reg)
|
||||
{
|
||||
|
|
@ -1486,7 +1585,7 @@ void codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx,
|
|||
host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset);
|
||||
host_x86_ADD32_REG_IMM(block, REG_ECX, REG_ECX, reg_idx);
|
||||
host_x86_AND32_REG_IMM(block, REG_ECX, REG_ECX, 7);
|
||||
host_x86_MOVQ_ABS_REG_REG_SHIFT_REG(block, offset, REG_EBP, REG_ECX, 3, host_reg);
|
||||
host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(block, offset, REG_EBP, REG_ECX, 3, host_reg);
|
||||
}
|
||||
|
||||
void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg)
|
||||
|
|
|
|||
|
|
@ -62,6 +62,8 @@
|
|||
#define UOP_MOVZX (UOP_TYPE_PARAMS_REGS | 0x23)
|
||||
/*UOP_MOVSX - dest_reg = sign_extend(src_reg_a)*/
|
||||
#define UOP_MOVSX (UOP_TYPE_PARAMS_REGS | 0x24)
|
||||
/*UOP_MOV_DOUBLE_INT - dest_reg = (double)src_reg_a*/
|
||||
#define UOP_MOV_DOUBLE_INT (UOP_TYPE_PARAMS_REGS | 0x25)
|
||||
/*UOP_ADD - dest_reg = src_reg_a + src_reg_b*/
|
||||
#define UOP_ADD (UOP_TYPE_PARAMS_REGS | 0x30)
|
||||
/*UOP_ADD_IMM - dest_reg = src_reg_a + immediate*/
|
||||
|
|
@ -99,8 +101,16 @@
|
|||
#define UOP_MEM_STORE_IMM_16 (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x45 | UOP_TYPE_ORDER_BARRIER)
|
||||
/*UOP_MEM_STORE_IMM_32 - long src_reg_a:[src_reg_b] = imm_data*/
|
||||
#define UOP_MEM_STORE_IMM_32 (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x46 | UOP_TYPE_ORDER_BARRIER)
|
||||
/*UOP_MEM_LOAD_SINGLE - dest_reg = (float)src_reg_a:[src_reg_b]*/
|
||||
#define UOP_MEM_LOAD_SINGLE (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x47 | UOP_TYPE_ORDER_BARRIER)
|
||||
/*UOP_CMP_IMM_JZ - if (src_reg_a == imm_data) then jump to ptr*/
|
||||
#define UOP_CMP_IMM_JZ (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x48 | UOP_TYPE_ORDER_BARRIER)
|
||||
/*UOP_MEM_LOAD_DOUBLE - dest_reg = (double)src_reg_a:[src_reg_b]*/
|
||||
#define UOP_MEM_LOAD_DOUBLE (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x49 | UOP_TYPE_ORDER_BARRIER)
|
||||
/*UOP_MEM_STORE_SINGLE - src_reg_a:[src_reg_b] = src_reg_c*/
|
||||
#define UOP_MEM_STORE_SINGLE (UOP_TYPE_PARAMS_REGS | 0x4a | UOP_TYPE_ORDER_BARRIER)
|
||||
/*UOP_MEM_STORE_DOUBLE - src_reg_a:[src_reg_b] = src_reg_c*/
|
||||
#define UOP_MEM_STORE_DOUBLE (UOP_TYPE_PARAMS_REGS | 0x4b | UOP_TYPE_ORDER_BARRIER)
|
||||
|
||||
/*UOP_SAR - dest_reg = src_reg_a >> src_reg_b*/
|
||||
#define UOP_SAR (UOP_TYPE_PARAMS_REGS | 0x50)
|
||||
|
|
@ -467,18 +477,23 @@ static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir,
|
|||
#define uop_MEM_LOAD_ABS(ir, dst_reg, seg_reg, imm) uop_gen_reg_dst_src_imm(UOP_MEM_LOAD_ABS, ir, dst_reg, seg_reg, imm)
|
||||
#define uop_MEM_LOAD_REG(ir, dst_reg, seg_reg, addr_reg) uop_gen_reg_dst_src2_imm(UOP_MEM_LOAD_REG, ir, dst_reg, seg_reg, addr_reg, 0)
|
||||
#define uop_MEM_LOAD_REG_OFFSET(ir, dst_reg, seg_reg, addr_reg, offset) uop_gen_reg_dst_src2_imm(UOP_MEM_LOAD_REG, ir, dst_reg, seg_reg, addr_reg, offset)
|
||||
#define uop_MEM_LOAD_SINGLE(ir, dst_reg, seg_reg, addr_reg) uop_gen_reg_dst_src2_imm(UOP_MEM_LOAD_SINGLE, ir, dst_reg, seg_reg, addr_reg, 0)
|
||||
#define uop_MEM_LOAD_DOUBLE(ir, dst_reg, seg_reg, addr_reg) uop_gen_reg_dst_src2_imm(UOP_MEM_LOAD_DOUBLE, ir, dst_reg, seg_reg, addr_reg, 0)
|
||||
#define uop_MEM_STORE_ABS(ir, seg_reg, imm, src_reg) uop_gen_reg_src2_imm(UOP_MEM_STORE_ABS, ir, seg_reg, src_reg, imm)
|
||||
#define uop_MEM_STORE_REG(ir, seg_reg, addr_reg, src_reg) uop_gen_reg_src3_imm(UOP_MEM_STORE_REG, ir, seg_reg, addr_reg, src_reg, 0)
|
||||
#define uop_MEM_STORE_REG_OFFSET(ir, seg_reg, addr_reg, offset, src_reg) uop_gen_reg_src3_imm(UOP_MEM_STORE_REG, ir, seg_reg, addr_reg, src_reg, offset)
|
||||
#define uop_MEM_STORE_IMM_8(ir, seg_reg, addr_reg, imm) uop_gen_reg_src2_imm(UOP_MEM_STORE_IMM_8, ir, seg_reg, addr_reg, imm)
|
||||
#define uop_MEM_STORE_IMM_16(ir, seg_reg, addr_reg, imm) uop_gen_reg_src2_imm(UOP_MEM_STORE_IMM_16, ir, seg_reg, addr_reg, imm)
|
||||
#define uop_MEM_STORE_IMM_32(ir, seg_reg, addr_reg, imm) uop_gen_reg_src2_imm(UOP_MEM_STORE_IMM_32, ir, seg_reg, addr_reg, imm)
|
||||
#define uop_MEM_STORE_SINGLE(ir, seg_reg, addr_reg, src_reg) uop_gen_reg_src3_imm(UOP_MEM_STORE_SINGLE, ir, seg_reg, addr_reg, src_reg, 0)
|
||||
#define uop_MEM_STORE_DOUBLE(ir, seg_reg, addr_reg, src_reg) uop_gen_reg_src3_imm(UOP_MEM_STORE_DOUBLE, ir, seg_reg, addr_reg, src_reg, 0)
|
||||
|
||||
#define uop_MOV(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOV, ir, dst_reg, src_reg)
|
||||
#define uop_MOV_IMM(ir, reg, imm) uop_gen_reg_dst_imm(UOP_MOV_IMM, ir, reg, imm)
|
||||
#define uop_MOV_PTR(ir, reg, p) uop_gen_reg_dst_pointer(UOP_MOV_PTR, ir, reg, p)
|
||||
#define uop_MOVSX(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOVSX, ir, dst_reg, src_reg)
|
||||
#define uop_MOVZX(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOVZX, ir, dst_reg, src_reg)
|
||||
#define uop_MOV(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOV, ir, dst_reg, src_reg)
|
||||
#define uop_MOV_IMM(ir, reg, imm) uop_gen_reg_dst_imm(UOP_MOV_IMM, ir, reg, imm)
|
||||
#define uop_MOV_PTR(ir, reg, p) uop_gen_reg_dst_pointer(UOP_MOV_PTR, ir, reg, p)
|
||||
#define uop_MOVSX(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOVSX, ir, dst_reg, src_reg)
|
||||
#define uop_MOVZX(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOVZX, ir, dst_reg, src_reg)
|
||||
#define uop_MOV_DOUBLE_INT(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOV_DOUBLE_INT, ir, dst_reg, src_reg)
|
||||
|
||||
#define uop_STORE_PTR_IMM(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM, ir, p, imm)
|
||||
#define uop_STORE_PTR_IMM_8(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM_8, ir, p, imm)
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include "codegen_ops_arith.h"
|
||||
#include "codegen_ops_branch.h"
|
||||
#include "codegen_ops_fpu_arith.h"
|
||||
#include "codegen_ops_fpu_loadstore.h"
|
||||
#include "codegen_ops_jump.h"
|
||||
#include "codegen_ops_logic.h"
|
||||
#include "codegen_ops_misc.h"
|
||||
|
|
@ -154,6 +155,100 @@ RecompOpFn recomp_opcodes_d8[512] =
|
|||
/*f0*/ ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR,
|
||||
};
|
||||
|
||||
RecompOpFn recomp_opcodes_d9[512] =
|
||||
{
|
||||
/*16-bit data*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*10*/ ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs,
|
||||
/*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*/ ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*50*/ ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs,
|
||||
/*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*/ ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*90*/ ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs,
|
||||
/*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*/ ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*10*/ ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs,
|
||||
/*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*/ ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*50*/ ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs,
|
||||
/*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*/ ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*90*/ ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs,
|
||||
/*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,
|
||||
};
|
||||
|
||||
RecompOpFn recomp_opcodes_db[512] =
|
||||
{
|
||||
/*16-bit data*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, 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*/ ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, 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*/ ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, NULL, NULL, NULL, NULL, 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*/ ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, 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*/ ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, 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*/ ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, NULL, NULL, NULL, NULL, 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,
|
||||
};
|
||||
|
||||
RecompOpFn recomp_opcodes_dc[512] =
|
||||
{
|
||||
/*16-bit data*/
|
||||
|
|
@ -201,6 +296,53 @@ RecompOpFn recomp_opcodes_dc[512] =
|
|||
/*f0*/ ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr,
|
||||
};
|
||||
|
||||
RecompOpFn recomp_opcodes_dd[512] =
|
||||
{
|
||||
/*16-bit data*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*10*/ ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd,
|
||||
/*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*/ ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*50*/ ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd,
|
||||
/*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*/ ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*90*/ ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd,
|
||||
/*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*/ ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*10*/ ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd,
|
||||
/*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*/ ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*50*/ ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd,
|
||||
/*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*/ ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*90*/ ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd,
|
||||
/*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,
|
||||
};
|
||||
|
||||
RecompOpFn recomp_opcodes_de[512] =
|
||||
{
|
||||
/*16-bit data*/
|
||||
|
|
@ -247,3 +389,50 @@ RecompOpFn recomp_opcodes_de[512] =
|
|||
/*e0*/ ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP,
|
||||
/*f0*/ ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP,
|
||||
};
|
||||
|
||||
RecompOpFn recomp_opcodes_df[512] =
|
||||
{
|
||||
/*16-bit data*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, 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*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, 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*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, 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*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, 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*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, 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*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, 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,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -10,14 +10,14 @@ typedef uint32_t (*RecompOpFn)(codeblock_t *block, struct ir_data_t *ir, uint8_t
|
|||
extern RecompOpFn recomp_opcodes[512];
|
||||
extern RecompOpFn recomp_opcodes_0f[512];
|
||||
extern RecompOpFn recomp_opcodes_d8[512];
|
||||
/*extern RecompOpFn recomp_opcodes_d9[512];
|
||||
extern RecompOpFn recomp_opcodes_da[512];
|
||||
extern RecompOpFn recomp_opcodes_db[512];*/
|
||||
extern RecompOpFn recomp_opcodes_d9[512];
|
||||
/*extern RecompOpFn recomp_opcodes_da[512];*/
|
||||
extern RecompOpFn recomp_opcodes_db[512];
|
||||
extern RecompOpFn recomp_opcodes_dc[512];
|
||||
/*extern RecompOpFn recomp_opcodes_dd[512];*/
|
||||
extern RecompOpFn recomp_opcodes_dd[512];
|
||||
extern RecompOpFn recomp_opcodes_de[512];
|
||||
/*extern RecompOpFn recomp_opcodes_df[512];
|
||||
extern RecompOpFn recomp_opcodes_REPE[512];
|
||||
extern RecompOpFn recomp_opcodes_df[512];
|
||||
/*extern RecompOpFn recomp_opcodes_REPE[512];
|
||||
extern RecompOpFn recomp_opcodes_REPNE[512];*/
|
||||
|
||||
#define REG_EAX 0
|
||||
|
|
|
|||
|
|
@ -9,11 +9,7 @@
|
|||
#include "codegen_ir.h"
|
||||
#include "codegen_ops.h"
|
||||
#include "codegen_ops_fpu_arith.h"
|
||||
|
||||
static void fpu_POP(ir_data_t *ir)
|
||||
{
|
||||
uop_ADD_IMM(ir, IREG_FPU_TOP, IREG_FPU_TOP, 1);
|
||||
}
|
||||
#include "codegen_ops_helpers.h"
|
||||
|
||||
uint32_t ropFADD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
|
|
|
|||
134
src/codegen_ops_fpu_loadstore.c
Normal file
134
src/codegen_ops_fpu_loadstore.c
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
#include "ibm.h"
|
||||
|
||||
#include "x86.h"
|
||||
#include "x86_flags.h"
|
||||
#include "386_common.h"
|
||||
#include "x87.h"
|
||||
#include "codegen.h"
|
||||
#include "codegen_accumulate.h"
|
||||
#include "codegen_ir.h"
|
||||
#include "codegen_ops.h"
|
||||
#include "codegen_ops_fpu_arith.h"
|
||||
#include "codegen_ops_helpers.h"
|
||||
|
||||
uint32_t ropFLDs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
x86seg *target_seg;
|
||||
|
||||
uop_FP_ENTER(ir);
|
||||
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
|
||||
op_pc--;
|
||||
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0);
|
||||
codegen_check_seg_read(block, ir, target_seg);
|
||||
uop_MEM_LOAD_SINGLE(ir, IREG_ST(-1), ireg_seg_base(target_seg), IREG_eaaddr);
|
||||
uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID);
|
||||
fpu_PUSH(ir);
|
||||
|
||||
return op_pc+1;
|
||||
}
|
||||
uint32_t ropFLDd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
x86seg *target_seg;
|
||||
|
||||
uop_FP_ENTER(ir);
|
||||
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
|
||||
op_pc--;
|
||||
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0);
|
||||
codegen_check_seg_read(block, ir, target_seg);
|
||||
uop_MEM_LOAD_DOUBLE(ir, IREG_ST(-1), ireg_seg_base(target_seg), IREG_eaaddr);
|
||||
uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID);
|
||||
fpu_PUSH(ir);
|
||||
|
||||
return op_pc+1;
|
||||
}
|
||||
|
||||
uint32_t ropFSTs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
x86seg *target_seg;
|
||||
|
||||
uop_FP_ENTER(ir);
|
||||
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
|
||||
op_pc--;
|
||||
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0);
|
||||
codegen_check_seg_write(block, ir, target_seg);
|
||||
uop_MEM_STORE_SINGLE(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_ST(0));
|
||||
|
||||
return op_pc+1;
|
||||
}
|
||||
uint32_t ropFSTPs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
x86seg *target_seg;
|
||||
|
||||
uop_FP_ENTER(ir);
|
||||
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
|
||||
op_pc--;
|
||||
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0);
|
||||
codegen_check_seg_write(block, ir, target_seg);
|
||||
uop_MEM_STORE_SINGLE(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_ST(0));
|
||||
uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY);
|
||||
fpu_POP(ir);
|
||||
|
||||
return op_pc+1;
|
||||
}
|
||||
uint32_t ropFSTd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
x86seg *target_seg;
|
||||
|
||||
uop_FP_ENTER(ir);
|
||||
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
|
||||
op_pc--;
|
||||
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0);
|
||||
codegen_check_seg_write(block, ir, target_seg);
|
||||
uop_MEM_STORE_DOUBLE(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_ST(0));
|
||||
|
||||
return op_pc+1;
|
||||
}
|
||||
uint32_t ropFSTPd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
x86seg *target_seg;
|
||||
|
||||
uop_FP_ENTER(ir);
|
||||
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
|
||||
op_pc--;
|
||||
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0);
|
||||
codegen_check_seg_write(block, ir, target_seg);
|
||||
uop_MEM_STORE_DOUBLE(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_ST(0));
|
||||
uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY);
|
||||
fpu_POP(ir);
|
||||
|
||||
return op_pc+1;
|
||||
}
|
||||
|
||||
|
||||
uint32_t ropFILDw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
x86seg *target_seg;
|
||||
|
||||
uop_FP_ENTER(ir);
|
||||
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
|
||||
op_pc--;
|
||||
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0);
|
||||
codegen_check_seg_read(block, ir, target_seg);
|
||||
uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr);
|
||||
uop_MOV_DOUBLE_INT(ir, IREG_ST(-1), IREG_temp0_W);
|
||||
uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID);
|
||||
fpu_PUSH(ir);
|
||||
|
||||
return op_pc+1;
|
||||
}
|
||||
uint32_t ropFILDl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
x86seg *target_seg;
|
||||
|
||||
uop_FP_ENTER(ir);
|
||||
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
|
||||
op_pc--;
|
||||
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0);
|
||||
codegen_check_seg_read(block, ir, target_seg);
|
||||
uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr);
|
||||
uop_MOV_DOUBLE_INT(ir, IREG_ST(-1), IREG_temp0);
|
||||
uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID);
|
||||
fpu_PUSH(ir);
|
||||
|
||||
return op_pc+1;
|
||||
}
|
||||
10
src/codegen_ops_fpu_loadstore.h
Normal file
10
src/codegen_ops_fpu_loadstore.h
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
uint32_t ropFLDs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropFLDd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
|
||||
uint32_t ropFSTs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropFSTPs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropFSTd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropFSTPd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
|
||||
uint32_t ropFILDw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropFILDl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
|
|
@ -41,3 +41,12 @@ static inline void SUB_SP(ir_data_t *ir, int offset)
|
|||
else
|
||||
uop_SUB_IMM(ir, IREG_SP, IREG_SP, offset);
|
||||
}
|
||||
|
||||
static inline void fpu_POP(ir_data_t *ir)
|
||||
{
|
||||
uop_ADD_IMM(ir, IREG_FPU_TOP, IREG_FPU_TOP, 1);
|
||||
}
|
||||
static inline void fpu_PUSH(ir_data_t *ir)
|
||||
{
|
||||
uop_SUB_IMM(ir, IREG_FPU_TOP, IREG_FPU_TOP, 1);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue