arm7ops.c: Fix SMLAL opcode. [MooglyGuy]

nw - looks like another dodgy one.
This commit is contained in:
Ryan Holtz 2013-02-07 03:01:34 +00:00
parent 78fb968dfa
commit 0f7b44526c
2 changed files with 31 additions and 81 deletions

View File

@ -2383,85 +2383,62 @@ const bool drcarm7ops_0123(arm_state *arm, drcuml_block *block, compiler_state *
else if ((insn & 0x0ff00090) == 0x01000080) // SMLAxy - v5
{
UINT32 rm = insn&0xf;
UINT32 rn = (insn>>16)&0xf;
UINT32 rd = (insn>>12)&0xf;
UINT32 rr = (insn>>8)&0xf;
INT32 src1 = GET_REGISTER(arm, insn&0xf);
INT32 src2 = GET_REGISTER(arm, (insn>>8)&0xf);
INT32 res1;
UINT32 rn = (insn>>8)&0xf;
UINT32 rd = (insn>>16)&0xf;
UINT32 ra = (insn>>12)&0xf;
UML_MOV(block, I0, DRC_REG(rm));
UML_MOV(block, I1, DRC_REG(rr));
UML_MOV(block, I1, DRC_REG(rn));
// select top and bottom halves of src1/src2 and sign extend if necessary
if (insn & 0x20)
{
UML_SHR(block, I0, I0, 16);
}
else
{
UML_SEXT(block, I1, I1, SIZE_WORD);
src1 &= 0xffff;
if (src1 & 0x8000)
{
src1 |= 0xffff;
}
}
UML_SEXT(block, I0, I0, SIZE_WORD);
if (insn & 0x40)
{
src2 >>= 16;
}
else
{
src2 &= 0xffff;
if (src2 & 0x8000)
{
src2 |= 0xffff;
}
UML_SHR(block, I1, I1, 16);
}
UML_SEXT(block, I0, I0, SIZE_WORD);
// do the signed multiply
res1 = src1 * src2;
UML_MULS(block, I0, I1, I0, I1);
UML_DSHL(block, I0, I0, 32);
UML_DOR(block, I0, I0, I1);
UML_MOV(block, I1, DRC_REG(ra));
UML_DADD(block, I0, I0, I1);
// and the accumulate. NOTE: only the accumulate can cause an overflow, which is why we do it this way.
saturate_qbit_overflow(arm, (INT64)res1 + (INT64)GET_REGISTER(arm, (insn>>12)&0xf));
SET_REGISTER(arm, (insn>>16)&0xf, res1 + GET_REGISTER(arm, (insn>>12)&0xf));
R15 += 4;
saturate_qbit_overflow(arm, block);
UML_MOV(block, DRC_REG(rd), I0);
UML_ADD(block, DRC_PC, DRC_PC, 4);
}
else if ((insn & 0x0ff00090) == 0x01400080) // SMLALxy - v5
{
INT32 src1 = GET_REGISTER(arm, insn&0xf);
INT32 src2 = GET_REGISTER(arm, (insn>>8)&0xf);
INT64 dst;
UINT32 rm = insn&0xf;
UINT32 rn = (insn>>8)&0xf;
UINT32 rdh = (insn>>16)&0xf;
UINT32 rdl = (insn>>12)&0xf;
UML_MOV(block, I0, DRC_REG(rm));
UML_MOV(block, I1, DRC_REG(rn));
// select top and bottom halves of src1/src2 and sign extend if necessary
if (insn & 0x20)
{
src1 >>= 16;
}
else
{
src1 &= 0xffff;
if (src1 & 0x8000)
{
src1 |= 0xffff;
}
UML_SHR(block, I0, I0, 16);
}
UML_SEXT(block, I0, I0, SIZE_WORD);
if (insn & 0x40)
{
src2 >>= 16;
}
else
{
src2 &= 0xffff;
if (src2 & 0x8000)
{
src2 |= 0xffff;
}
UML_SHR(block, I1, I1, 16);
}
UML_SEXT(block, I0, I0, SIZE_WORD);
// do the signed multiply
UML_MULS(block, I0, I1, I0, I1);
dst = (INT64)GET_REGISTER(arm, (insn>>12)&0xf);
dst |= (INT64)GET_REGISTER(arm, (insn>>16)&0xf)<<32;

View File

@ -1652,33 +1652,6 @@ const void arm7ops_0123(arm_state *arm, UINT32 insn)
INT32 src2 = GET_REGISTER(arm, (insn>>8)&0xf);
INT64 dst;
// select top and bottom halves of src1/src2 and sign extend if necessary
if (insn & 0x20)
{
src1 >>= 16;
}
else
{
src1 &= 0xffff;
if (src1 & 0x8000)
{
src1 |= 0xffff;
}
}
if (insn & 0x40)
{
src2 >>= 16;
}
else
{
src2 &= 0xffff;
if (src2 & 0x8000)
{
src2 |= 0xffff;
}
}
dst = (INT64)GET_REGISTER(arm, (insn>>12)&0xf);
dst |= (INT64)GET_REGISTER(arm, (insn>>16)&0xf)<<32;
@ -1686,8 +1659,8 @@ const void arm7ops_0123(arm_state *arm, UINT32 insn)
dst += (INT64)src1 * (INT64)src2;
// write back the result
SET_REGISTER(cpustart, (insn>>12)&0xf, (UINT32)(dst&0xffffffff));
SET_REGISTER(cpustart, (insn>>16)&0xf, (UINT32)(dst>>32));
SET_REGISTER(cpustart, (insn>>12)&0xf, (UINT32)dst);
SET_REGISTER(cpustart, (insn>>16)&0xf, (UINT32)(dst >> 32));
}
else if ((insn & 0x0ff00090) == 0x01600080) // SMULxy - v5
{