Added segment limit checking to some instructions.
This commit is contained in:
parent
4c523a5fe2
commit
095cf53265
11 changed files with 272 additions and 1 deletions
|
|
@ -306,6 +306,43 @@ static int codegen_CMP_IMM_JZ_DEST(codeblock_t *block, uop_t *uop)
|
|||
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)
|
||||
{
|
||||
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_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_JNBE_DEST & UOP_MASK] = codegen_CMP_JNBE_DEST,
|
||||
[UOP_CMP_JNL_DEST & UOP_MASK] = codegen_CMP_JNL_DEST,
|
||||
|
|
|
|||
|
|
@ -381,6 +381,43 @@ static int codegen_CMP_IMM_JZ_DEST(codeblock_t *block, uop_t *uop)
|
|||
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)
|
||||
{
|
||||
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_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_JNBE_DEST & UOP_MASK] = codegen_CMP_JNBE_DEST,
|
||||
[UOP_CMP_JNL_DEST & UOP_MASK] = codegen_CMP_JNL_DEST,
|
||||
|
|
|
|||
|
|
@ -277,6 +277,45 @@ static int codegen_CMP_IMM_JZ_DEST(codeblock_t *block, uop_t *uop)
|
|||
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)
|
||||
{
|
||||
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_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_JNBE_DEST & UOP_MASK] = codegen_CMP_JNBE_DEST,
|
||||
[UOP_CMP_JNL_DEST & UOP_MASK] = codegen_CMP_JNL_DEST,
|
||||
|
|
|
|||
|
|
@ -285,6 +285,45 @@ static int codegen_CMP_IMM_JZ_DEST(codeblock_t *block, uop_t *uop)
|
|||
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)
|
||||
{
|
||||
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_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_JNBE_DEST & UOP_MASK] = codegen_CMP_JNBE_DEST,
|
||||
[UOP_CMP_JNL_DEST & UOP_MASK] = codegen_CMP_JNL_DEST,
|
||||
|
|
|
|||
|
|
@ -125,6 +125,10 @@
|
|||
#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_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*/
|
||||
#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;
|
||||
}
|
||||
|
||||
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_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_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_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)
|
||||
|
|
|
|||
|
|
@ -79,6 +79,7 @@ uint32_t ropFSTd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet
|
|||
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);
|
||||
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));
|
||||
|
||||
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--;
|
||||
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);
|
||||
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_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY);
|
||||
fpu_POP(block, ir);
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
#include "codegen_backend.h"
|
||||
|
||||
static inline int LOAD_SP_WITH_OFFSET(ir_data_t *ir, int offset)
|
||||
{
|
||||
if (stack32)
|
||||
|
|
@ -67,3 +69,19 @@ static inline void fpu_PUSH(codeblock_t *block, ir_data_t *ir)
|
|||
else
|
||||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
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);
|
||||
CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 3);
|
||||
uop_MOVZX(ir, IREG_temp0, IREG_MM(src_reg));
|
||||
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);
|
||||
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);
|
||||
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));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include "codegen.h"
|
||||
#include "codegen_ir.h"
|
||||
#include "codegen_ops.h"
|
||||
#include "codegen_ops_helpers.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)
|
||||
|
|
@ -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);
|
||||
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);
|
||||
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));
|
||||
}
|
||||
|
||||
|
|
@ -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);
|
||||
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);
|
||||
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));
|
||||
}
|
||||
|
||||
|
|
@ -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);
|
||||
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);
|
||||
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));
|
||||
}
|
||||
|
||||
|
|
@ -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);
|
||||
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);
|
||||
CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 1);
|
||||
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, src_reg);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -149,6 +149,20 @@ struct
|
|||
[IREG_flagsx] = {REG_WORD, &cpu_state.flags, 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
|
||||
be preserved across uOPs. They will not be written back if they will
|
||||
not be read again.*/
|
||||
|
|
|
|||
|
|
@ -119,7 +119,21 @@ enum
|
|||
IREG_flagsx = 74,
|
||||
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,
|
||||
|
||||
|
|
@ -221,6 +235,41 @@ static inline int ireg_seg_base(x86seg *seg)
|
|||
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_version_refcount[IREG_COUNT][256];
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue