summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/cpu/arm7
diff options
context:
space:
mode:
author Ryan Holtz <rholtz@batcountryentertainment.com>2013-02-07 03:01:34 +0000
committer Ryan Holtz <rholtz@batcountryentertainment.com>2013-02-07 03:01:34 +0000
commit0f7b44526c2040c681c81aa784fd8857cd687c6c (patch)
tree38702a34059cf36bb924e4f03e0cb85159a513b7 /src/emu/cpu/arm7
parent78fb968dfa276baff83e0026d264f2f362fa4810 (diff)
arm7ops.c: Fix SMLAL opcode. [MooglyGuy]
nw - looks like another dodgy one.
Diffstat (limited to 'src/emu/cpu/arm7')
-rw-r--r--src/emu/cpu/arm7/arm7drc.c81
-rw-r--r--src/emu/cpu/arm7/arm7ops.c31
2 files changed, 31 insertions, 81 deletions
diff --git a/src/emu/cpu/arm7/arm7drc.c b/src/emu/cpu/arm7/arm7drc.c
index cc6d989e036..38cbe42c261 100644
--- a/src/emu/cpu/arm7/arm7drc.c
+++ b/src/emu/cpu/arm7/arm7drc.c
@@ -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;
diff --git a/src/emu/cpu/arm7/arm7ops.c b/src/emu/cpu/arm7/arm7ops.c
index 682ffc62e12..35a65f569c5 100644
--- a/src/emu/cpu/arm7/arm7ops.c
+++ b/src/emu/cpu/arm7/arm7ops.c
@@ -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
{