mirror of
https://github.com/holub/mame
synced 2025-10-06 17:08:28 +03:00
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:
parent
31c7c2c219
commit
152d8a7db0
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user