Explicitly sign-extend 32-bit indexes for load/loads/store on 64-bit

machines to prevent overflow issues. Fixes DRC crash in mtetrisc.
This commit is contained in:
Aaron Giles 2009-12-30 06:51:42 +00:00
parent 31c7c2c219
commit 152d8a7db0

View File

@ -1249,6 +1249,29 @@ static void emit_mov_r32_p32(drcbe_state *drcbe, x86code **dst, UINT8 reg, const
} }
/*-------------------------------------------------
emit_movsx_r64_p32 - move a 32-bit parameter
sign-extended into a register
-------------------------------------------------*/
static void emit_movsx_r64_p32(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param)
{
if (param->type == DRCUML_PTYPE_IMMEDIATE)
{
if (param->value == 0)
emit_xor_r32_r32(dst, reg, reg); // xor reg,reg
else if ((INT32)param->value >= 0)
emit_mov_r32_imm(dst, reg, param->value); // mov reg,param
else
emit_mov_r64_imm(dst, reg, (INT32)param->value); // mov reg,param
}
else if (param->type == DRCUML_PTYPE_MEMORY)
emit_movsxd_r64_m32(dst, reg, MABS(drcbe, param->value)); // movsxd reg,[param]
else if (param->type == DRCUML_PTYPE_INT_REGISTER)
emit_movsxd_r64_r32(dst, reg, param->value); // movsdx reg,param
}
/*------------------------------------------------- /*-------------------------------------------------
emit_mov_r32_p32_keepflags - move a 32-bit emit_mov_r32_p32_keepflags - move a 32-bit
parameter into a register without affecting parameter into a register without affecting
@ -3849,7 +3872,7 @@ static x86code *op_load(drcbe_state *drcbe, x86code *dst, const drcuml_instructi
else else
{ {
int indreg = param_select_register(REG_ECX, &indp, NULL); int indreg = param_select_register(REG_ECX, &indp, NULL);
emit_mov_r32_p32(drcbe, &dst, indreg, &indp); emit_movsx_r64_p32(drcbe, &dst, indreg, &indp);
if (size == DRCUML_SIZE_BYTE) if (size == DRCUML_SIZE_BYTE)
emit_movzx_r32_m8(&dst, dstreg, MBISD(basereg, indreg, scale, baseoffs)); // movzx dstreg,[basep + scale*indp] emit_movzx_r32_m8(&dst, dstreg, MBISD(basereg, indreg, scale, baseoffs)); // movzx dstreg,[basep + scale*indp]
else if (size == DRCUML_SIZE_WORD) else if (size == DRCUML_SIZE_WORD)
@ -3925,7 +3948,7 @@ static x86code *op_loads(drcbe_state *drcbe, x86code *dst, const drcuml_instruct
else else
{ {
int indreg = param_select_register(REG_ECX, &indp, NULL); int indreg = param_select_register(REG_ECX, &indp, NULL);
emit_mov_r32_p32(drcbe, &dst, indreg, &indp); emit_movsx_r64_p32(drcbe, &dst, indreg, &indp);
if (inst->size == 4) if (inst->size == 4)
{ {
if (size == DRCUML_SIZE_BYTE) if (size == DRCUML_SIZE_BYTE)
@ -4031,7 +4054,7 @@ static x86code *op_store(drcbe_state *drcbe, x86code *dst, const drcuml_instruct
else else
{ {
int indreg = param_select_register(REG_ECX, &indp, NULL); int indreg = param_select_register(REG_ECX, &indp, NULL);
emit_mov_r32_p32(drcbe, &dst, indreg, &indp); // mov indreg,indp emit_movsx_r64_p32(drcbe, &dst, indreg, &indp); // mov indreg,indp
/* immediate source */ /* immediate source */
if (srcp.type == DRCUML_PTYPE_IMMEDIATE) if (srcp.type == DRCUML_PTYPE_IMMEDIATE)