Added segment limit checking to some instructions.

This commit is contained in:
SarahW 2019-02-03 17:48:11 +00:00
commit 095cf53265
11 changed files with 272 additions and 1 deletions

View file

@ -306,6 +306,43 @@ static int codegen_CMP_IMM_JZ_DEST(codeblock_t *block, uop_t *uop)
return 0; return 0;
} }
static int codegen_CMP_JB(codeblock_t *block, uop_t *uop)
{
int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real);
uint32_t *jump_p;
if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b))
{
host_arm64_CMP_REG(block, src_reg_a, src_reg_b);
}
else
fatal("CMP_JB %02x\n", uop->src_reg_a_real);
jump_p = host_arm64_BCC_(block);
host_arm64_branch_set_offset(jump_p, uop->p);
return 0;
}
static int codegen_CMP_JNBE(codeblock_t *block, uop_t *uop)
{
int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real);
uint32_t *jump_p;
if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b))
{
host_arm64_CMP_REG(block, src_reg_a, src_reg_b);
}
else
fatal("CMP_JNBE %02x\n", uop->src_reg_a_real);
jump_p = host_arm64_BHI_(block);
host_arm64_branch_set_offset(jump_p, uop->p);
return 0;
}
static int codegen_CMP_JNB_DEST(codeblock_t *block, uop_t *uop) static int codegen_CMP_JNB_DEST(codeblock_t *block, uop_t *uop)
{ {
int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
@ -2751,6 +2788,9 @@ const uOpFn uop_handlers[UOP_MAX] =
[UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ, [UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ,
[UOP_CMP_JB & UOP_MASK] = codegen_CMP_JB,
[UOP_CMP_JNBE & UOP_MASK] = codegen_CMP_JNBE,
[UOP_CMP_JNB_DEST & UOP_MASK] = codegen_CMP_JNB_DEST, [UOP_CMP_JNB_DEST & UOP_MASK] = codegen_CMP_JNB_DEST,
[UOP_CMP_JNBE_DEST & UOP_MASK] = codegen_CMP_JNBE_DEST, [UOP_CMP_JNBE_DEST & UOP_MASK] = codegen_CMP_JNBE_DEST,
[UOP_CMP_JNL_DEST & UOP_MASK] = codegen_CMP_JNL_DEST, [UOP_CMP_JNL_DEST & UOP_MASK] = codegen_CMP_JNL_DEST,

View file

@ -381,6 +381,43 @@ static int codegen_CMP_IMM_JZ_DEST(codeblock_t *block, uop_t *uop)
return 0; return 0;
} }
static int codegen_CMP_JB(codeblock_t *block, uop_t *uop)
{
int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real);
uint32_t *jump_p;
if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b))
{
host_arm_CMP_REG(block, src_reg_a, src_reg_b);
}
else
fatal("CMP_JB %02x\n", uop->src_reg_a_real);
jump_p = host_arm_BCC_(block);
*jump_p |= ((((uintptr_t)uop->p - (uintptr_t)jump_p) - 8) & 0x3fffffc) >> 2;
return 0;
}
static int codegen_CMP_JNBE(codeblock_t *block, uop_t *uop)
{
int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real);
uint32_t *jump_p;
if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b))
{
host_arm_CMP_REG(block, src_reg_a, src_reg_b);
}
else
fatal("CMP_JNBE %02x\n", uop->src_reg_a_real);
jump_p = host_arm_BHI_(block);
*jump_p |= ((((uintptr_t)uop->p - (uintptr_t)jump_p) - 8) & 0x3fffffc) >> 2;
return 0;
}
static int codegen_CMP_JNB_DEST(codeblock_t *block, uop_t *uop) static int codegen_CMP_JNB_DEST(codeblock_t *block, uop_t *uop)
{ {
int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
@ -2900,6 +2937,9 @@ const uOpFn uop_handlers[UOP_MAX] =
[UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ, [UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ,
[UOP_CMP_JB & UOP_MASK] = codegen_CMP_JB,
[UOP_CMP_JNBE & UOP_MASK] = codegen_CMP_JNBE,
[UOP_CMP_JNB_DEST & UOP_MASK] = codegen_CMP_JNB_DEST, [UOP_CMP_JNB_DEST & UOP_MASK] = codegen_CMP_JNB_DEST,
[UOP_CMP_JNBE_DEST & UOP_MASK] = codegen_CMP_JNBE_DEST, [UOP_CMP_JNBE_DEST & UOP_MASK] = codegen_CMP_JNBE_DEST,
[UOP_CMP_JNL_DEST & UOP_MASK] = codegen_CMP_JNL_DEST, [UOP_CMP_JNL_DEST & UOP_MASK] = codegen_CMP_JNL_DEST,

View file

@ -277,6 +277,45 @@ static int codegen_CMP_IMM_JZ_DEST(codeblock_t *block, uop_t *uop)
return 0; return 0;
} }
static int codegen_CMP_JB(codeblock_t *block, uop_t *uop)
{
int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real);
uint32_t *jump_p;
if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b))
{
host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b);
}
#ifdef RECOMPILER_DEBUG
else
fatal("CMP_JB %02x\n", uop->src_reg_a_real);
#endif
jump_p = host_x86_JB_long(block);
*jump_p = (uintptr_t)uop->p - ((uintptr_t)jump_p + 4);
return 0;
}
static int codegen_CMP_JNBE(codeblock_t *block, uop_t *uop)
{
int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real);
uint32_t *jump_p;
if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b))
{
host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b);
}
#ifdef RECOMPILER_DEBUG
else
fatal("CMP_JNBE %02x\n", uop->src_reg_a_real);
#endif
jump_p = host_x86_JNBE_long(block);
*jump_p = (uintptr_t)uop->p - ((uintptr_t)jump_p + 4);
return 0;
}
static int codegen_CMP_JNB_DEST(codeblock_t *block, uop_t *uop) static int codegen_CMP_JNB_DEST(codeblock_t *block, uop_t *uop)
{ {
int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
@ -2665,6 +2704,9 @@ const uOpFn uop_handlers[UOP_MAX] =
[UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ, [UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ,
[UOP_CMP_JB & UOP_MASK] = codegen_CMP_JB,
[UOP_CMP_JNBE & UOP_MASK] = codegen_CMP_JNBE,
[UOP_CMP_JNB_DEST & UOP_MASK] = codegen_CMP_JNB_DEST, [UOP_CMP_JNB_DEST & UOP_MASK] = codegen_CMP_JNB_DEST,
[UOP_CMP_JNBE_DEST & UOP_MASK] = codegen_CMP_JNBE_DEST, [UOP_CMP_JNBE_DEST & UOP_MASK] = codegen_CMP_JNBE_DEST,
[UOP_CMP_JNL_DEST & UOP_MASK] = codegen_CMP_JNL_DEST, [UOP_CMP_JNL_DEST & UOP_MASK] = codegen_CMP_JNL_DEST,

View file

@ -285,6 +285,45 @@ static int codegen_CMP_IMM_JZ_DEST(codeblock_t *block, uop_t *uop)
return 0; return 0;
} }
static int codegen_CMP_JB(codeblock_t *block, uop_t *uop)
{
int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real);
uint32_t *jump_p;
if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b))
{
host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b);
}
#ifdef RECOMPILER_DEBUG
else
fatal("CMP_JB %02x\n", uop->src_reg_a_real);
#endif
jump_p = host_x86_JB_long(block);
*jump_p = (uintptr_t)uop->p - ((uintptr_t)jump_p + 4);
return 0;
}
static int codegen_CMP_JNBE(codeblock_t *block, uop_t *uop)
{
int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real);
uint32_t *jump_p;
if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b))
{
host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b);
}
#ifdef RECOMPILER_DEBUG
else
fatal("CMP_JNBE %02x\n", uop->src_reg_a_real);
#endif
jump_p = host_x86_JNBE_long(block);
*jump_p = (uintptr_t)uop->p - ((uintptr_t)jump_p + 4);
return 0;
}
static int codegen_CMP_JNB_DEST(codeblock_t *block, uop_t *uop) static int codegen_CMP_JNB_DEST(codeblock_t *block, uop_t *uop)
{ {
int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
@ -2664,6 +2703,9 @@ const uOpFn uop_handlers[UOP_MAX] =
[UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ, [UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ,
[UOP_CMP_JB & UOP_MASK] = codegen_CMP_JB,
[UOP_CMP_JNBE & UOP_MASK] = codegen_CMP_JNBE,
[UOP_CMP_JNB_DEST & UOP_MASK] = codegen_CMP_JNB_DEST, [UOP_CMP_JNB_DEST & UOP_MASK] = codegen_CMP_JNB_DEST,
[UOP_CMP_JNBE_DEST & UOP_MASK] = codegen_CMP_JNBE_DEST, [UOP_CMP_JNBE_DEST & UOP_MASK] = codegen_CMP_JNBE_DEST,
[UOP_CMP_JNL_DEST & UOP_MASK] = codegen_CMP_JNL_DEST, [UOP_CMP_JNL_DEST & UOP_MASK] = codegen_CMP_JNL_DEST,

View file

@ -125,6 +125,10 @@
#define UOP_MEM_STORE_SINGLE (UOP_TYPE_PARAMS_REGS | 0x4a | UOP_TYPE_ORDER_BARRIER) #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*/ /*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) #define UOP_MEM_STORE_DOUBLE (UOP_TYPE_PARAMS_REGS | 0x4b | UOP_TYPE_ORDER_BARRIER)
/*UOP_CMP_JB - if (src_reg_a < src_reg_b) then jump to ptr*/
#define UOP_CMP_JB (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x4c | UOP_TYPE_ORDER_BARRIER)
/*UOP_CMP_JNBE - if (src_reg_a > src_reg_b) then jump to ptr*/
#define UOP_CMP_JNBE (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x4d | UOP_TYPE_ORDER_BARRIER)
/*UOP_SAR - dest_reg = src_reg_a >> src_reg_b*/ /*UOP_SAR - dest_reg = src_reg_a >> src_reg_b*/
#define UOP_SAR (UOP_TYPE_PARAMS_REGS | 0x50) #define UOP_SAR (UOP_TYPE_PARAMS_REGS | 0x50)
@ -563,6 +567,16 @@ static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir,
uop->imm_data = imm; uop->imm_data = imm;
} }
static inline void uop_gen_reg_src2_pointer(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int src_reg_b, void *p)
{
uop_t *uop = uop_alloc(ir);
uop->type = uop_type;
uop->src_reg_a = codegen_reg_read(src_reg_a);
uop->src_reg_b = codegen_reg_read(src_reg_b);
uop->p = p;
}
#define uop_LOAD_FUNC_ARG_REG(ir, arg, reg) uop_gen_reg_src1(UOP_LOAD_FUNC_ARG_0 + arg, ir, reg) #define uop_LOAD_FUNC_ARG_REG(ir, arg, reg) uop_gen_reg_src1(UOP_LOAD_FUNC_ARG_0 + arg, ir, reg)
#define uop_LOAD_FUNC_ARG_IMM(ir, arg, imm) uop_gen_imm(UOP_LOAD_FUNC_ARG_0_IMM + arg, ir, imm) #define uop_LOAD_FUNC_ARG_IMM(ir, arg, imm) uop_gen_imm(UOP_LOAD_FUNC_ARG_0_IMM + arg, ir, imm)
@ -596,6 +610,9 @@ static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir,
#define uop_CMP_IMM_JNZ_DEST(ir, src_reg, imm) uop_gen_reg_src1_imm(UOP_CMP_IMM_JNZ_DEST, ir, src_reg, imm) #define uop_CMP_IMM_JNZ_DEST(ir, src_reg, imm) uop_gen_reg_src1_imm(UOP_CMP_IMM_JNZ_DEST, ir, src_reg, imm)
#define uop_CMP_IMM_JZ_DEST(ir, src_reg, imm) uop_gen_reg_src1_imm(UOP_CMP_IMM_JZ_DEST, ir, src_reg, imm) #define uop_CMP_IMM_JZ_DEST(ir, src_reg, imm) uop_gen_reg_src1_imm(UOP_CMP_IMM_JZ_DEST, ir, src_reg, imm)
#define uop_CMP_JB(ir, src_reg_a, src_reg_b, p) uop_gen_reg_src2_pointer(UOP_CMP_JB, ir, src_reg_a, src_reg_b, p)
#define uop_CMP_JNBE(ir, src_reg_a, src_reg_b, p) uop_gen_reg_src2_pointer(UOP_CMP_JNBE, ir, src_reg_a, src_reg_b, p)
#define uop_CMP_JNB_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JNB_DEST, ir, src_reg_a, src_reg_b) #define uop_CMP_JNB_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JNB_DEST, ir, src_reg_a, src_reg_b)
#define uop_CMP_JNBE_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JNBE_DEST, ir, src_reg_a, src_reg_b) #define uop_CMP_JNBE_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JNBE_DEST, ir, src_reg_a, src_reg_b)
#define uop_CMP_JNL_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JNL_DEST, ir, src_reg_a, src_reg_b) #define uop_CMP_JNL_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JNL_DEST, ir, src_reg_a, src_reg_b)

View file

@ -79,6 +79,7 @@ uint32_t ropFSTd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet
op_pc--; op_pc--;
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); 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); codegen_check_seg_write(block, ir, target_seg);
CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 7);
uop_MEM_STORE_DOUBLE(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_ST(0)); uop_MEM_STORE_DOUBLE(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_ST(0));
return op_pc+1; return op_pc+1;
@ -92,6 +93,7 @@ uint32_t ropFSTPd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe
op_pc--; op_pc--;
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); 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); codegen_check_seg_write(block, ir, target_seg);
CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 7);
uop_MEM_STORE_DOUBLE(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_ST(0)); uop_MEM_STORE_DOUBLE(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_ST(0));
uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY);
fpu_POP(block, ir); fpu_POP(block, ir);

View file

@ -1,3 +1,5 @@
#include "codegen_backend.h"
static inline int LOAD_SP_WITH_OFFSET(ir_data_t *ir, int offset) static inline int LOAD_SP_WITH_OFFSET(ir_data_t *ir, int offset)
{ {
if (stack32) if (stack32)
@ -67,3 +69,19 @@ static inline void fpu_PUSH(codeblock_t *block, ir_data_t *ir)
else else
uop_SUB_IMM(ir, IREG_FPU_TOP, IREG_FPU_TOP, 1); uop_SUB_IMM(ir, IREG_FPU_TOP, IREG_FPU_TOP, 1);
} }
static inline void CHECK_SEG_LIMITS(codeblock_t *block, ir_data_t *ir, x86seg *seg, int addr_reg, int end_offset)
{
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) ||
(seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
return;
uop_CMP_JB(ir, addr_reg, ireg_seg_limit_low(seg), codegen_gpf_rout);
if (end_offset)
{
uop_ADD_IMM(ir, IREG_temp3, addr_reg, end_offset);
uop_CMP_JNBE(ir, IREG_temp3, ireg_seg_limit_high(seg), codegen_gpf_rout);
}
else
uop_CMP_JNBE(ir, addr_reg, ireg_seg_limit_high(seg), codegen_gpf_rout);
}

View file

@ -51,6 +51,7 @@ uint32_t ropMOVD_d_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); 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); codegen_check_seg_write(block, ir, target_seg);
CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 3);
uop_MOVZX(ir, IREG_temp0, IREG_MM(src_reg)); uop_MOVZX(ir, IREG_temp0, IREG_MM(src_reg));
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0);
} }
@ -99,6 +100,7 @@ uint32_t ropMOVQ_q_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); 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); codegen_check_seg_write(block, ir, target_seg);
CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 7);
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_MM(src_reg)); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_MM(src_reg));
} }

View file

@ -5,6 +5,7 @@
#include "codegen.h" #include "codegen.h"
#include "codegen_ir.h" #include "codegen_ir.h"
#include "codegen_ops.h" #include "codegen_ops.h"
#include "codegen_ops_helpers.h"
#include "codegen_ops_mov.h" #include "codegen_ops_mov.h"
uint32_t ropMOV_rb_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) uint32_t ropMOV_rb_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
@ -50,6 +51,7 @@ uint32_t ropMOV_b_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); 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); codegen_check_seg_write(block, ir, target_seg);
CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 0);
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_8(src_reg)); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_8(src_reg));
} }
@ -71,6 +73,7 @@ uint32_t ropMOV_w_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); 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); codegen_check_seg_write(block, ir, target_seg);
CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 1);
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_16(src_reg)); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_16(src_reg));
} }
@ -92,6 +95,7 @@ uint32_t ropMOV_l_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); 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); codegen_check_seg_write(block, ir, target_seg);
CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 3);
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_32(src_reg)); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_32(src_reg));
} }
@ -363,6 +367,7 @@ uint32_t ropMOV_w_seg(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); 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); codegen_check_seg_write(block, ir, target_seg);
CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 1);
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, src_reg); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, src_reg);
} }

View file

@ -149,6 +149,20 @@ struct
[IREG_flagsx] = {REG_WORD, &cpu_state.flags, REG_INTEGER, REG_PERMANENT}, [IREG_flagsx] = {REG_WORD, &cpu_state.flags, REG_INTEGER, REG_PERMANENT},
[IREG_eflagsx] = {REG_WORD, &cpu_state.eflags, REG_INTEGER, REG_PERMANENT}, [IREG_eflagsx] = {REG_WORD, &cpu_state.eflags, REG_INTEGER, REG_PERMANENT},
[IREG_CS_limit_low] = {REG_DWORD, &cpu_state.seg_cs.limit_low, REG_INTEGER, REG_PERMANENT},
[IREG_DS_limit_low] = {REG_DWORD, &cpu_state.seg_ds.limit_low, REG_INTEGER, REG_PERMANENT},
[IREG_ES_limit_low] = {REG_DWORD, &cpu_state.seg_es.limit_low, REG_INTEGER, REG_PERMANENT},
[IREG_FS_limit_low] = {REG_DWORD, &cpu_state.seg_fs.limit_low, REG_INTEGER, REG_PERMANENT},
[IREG_GS_limit_low] = {REG_DWORD, &cpu_state.seg_gs.limit_low, REG_INTEGER, REG_PERMANENT},
[IREG_SS_limit_low] = {REG_DWORD, &cpu_state.seg_ss.limit_low, REG_INTEGER, REG_PERMANENT},
[IREG_CS_limit_high] = {REG_DWORD, &cpu_state.seg_cs.limit_high, REG_INTEGER, REG_PERMANENT},
[IREG_DS_limit_high] = {REG_DWORD, &cpu_state.seg_ds.limit_high, REG_INTEGER, REG_PERMANENT},
[IREG_ES_limit_high] = {REG_DWORD, &cpu_state.seg_es.limit_high, REG_INTEGER, REG_PERMANENT},
[IREG_FS_limit_high] = {REG_DWORD, &cpu_state.seg_fs.limit_high, REG_INTEGER, REG_PERMANENT},
[IREG_GS_limit_high] = {REG_DWORD, &cpu_state.seg_gs.limit_high, REG_INTEGER, REG_PERMANENT},
[IREG_SS_limit_high] = {REG_DWORD, &cpu_state.seg_ss.limit_high, REG_INTEGER, REG_PERMANENT},
/*Temporary registers are stored on the stack, and are not guaranteed to /*Temporary registers are stored on the stack, and are not guaranteed to
be preserved across uOPs. They will not be written back if they will be preserved across uOPs. They will not be written back if they will
not be read again.*/ not be read again.*/

View file

@ -119,7 +119,21 @@ enum
IREG_flagsx = 74, IREG_flagsx = 74,
IREG_eflagsx = 75, IREG_eflagsx = 75,
IREG_COUNT = 76, IREG_CS_limit_low = 76,
IREG_DS_limit_low = 77,
IREG_ES_limit_low = 78,
IREG_FS_limit_low = 79,
IREG_GS_limit_low = 80,
IREG_SS_limit_low = 81,
IREG_CS_limit_high = 82,
IREG_DS_limit_high = 83,
IREG_ES_limit_high = 84,
IREG_FS_limit_high = 85,
IREG_GS_limit_high = 86,
IREG_SS_limit_high = 87,
IREG_COUNT = 88,
IREG_INVALID = 255, IREG_INVALID = 255,
@ -221,6 +235,41 @@ static inline int ireg_seg_base(x86seg *seg)
return 0; return 0;
} }
static inline int ireg_seg_limit_low(x86seg *seg)
{
if (seg == &cpu_state.seg_cs)
return IREG_CS_limit_low;
if (seg == &cpu_state.seg_ds)
return IREG_DS_limit_low;
if (seg == &cpu_state.seg_es)
return IREG_ES_limit_low;
if (seg == &cpu_state.seg_fs)
return IREG_FS_limit_low;
if (seg == &cpu_state.seg_gs)
return IREG_GS_limit_low;
if (seg == &cpu_state.seg_ss)
return IREG_SS_limit_low;
fatal("ireg_seg_limit_low : unknown segment\n");
return 0;
}
static inline int ireg_seg_limit_high(x86seg *seg)
{
if (seg == &cpu_state.seg_cs)
return IREG_CS_limit_high;
if (seg == &cpu_state.seg_ds)
return IREG_DS_limit_high;
if (seg == &cpu_state.seg_es)
return IREG_ES_limit_high;
if (seg == &cpu_state.seg_fs)
return IREG_FS_limit_high;
if (seg == &cpu_state.seg_gs)
return IREG_GS_limit_high;
if (seg == &cpu_state.seg_ss)
return IREG_SS_limit_high;
fatal("ireg_seg_limit_high : unknown segment\n");
return 0;
}
extern uint8_t reg_last_version[IREG_COUNT]; extern uint8_t reg_last_version[IREG_COUNT];
extern uint8_t reg_version_refcount[IREG_COUNT][256]; extern uint8_t reg_version_refcount[IREG_COUNT][256];