diff options
author | 2013-02-07 03:01:34 +0000 | |
---|---|---|
committer | 2013-02-07 03:01:34 +0000 | |
commit | 0f7b44526c2040c681c81aa784fd8857cd687c6c (patch) | |
tree | 38702a34059cf36bb924e4f03e0cb85159a513b7 /src/emu/cpu/arm7 | |
parent | 78fb968dfa276baff83e0026d264f2f362fa4810 (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.c | 81 | ||||
-rw-r--r-- | src/emu/cpu/arm7/arm7ops.c | 31 |
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 { |