diff options
author | 2013-02-07 03:26:05 +0000 | |
---|---|---|
committer | 2013-02-07 03:26:05 +0000 | |
commit | 26be77fad06299e7b9e8fb22f80bccb1be0f2a8a (patch) | |
tree | c1382fbf9029a15c171aa83f99ac1b220a254b1e /src | |
parent | 0f7b44526c2040c681c81aa784fd8857cd687c6c (diff) |
arm7ops.c: Fix SMULW, SMLAW opcodes [MooglyGuy]
Diffstat (limited to 'src')
-rw-r--r-- | src/emu/cpu/arm7/arm7drc.c | 58 | ||||
-rw-r--r-- | src/emu/cpu/arm7/arm7ops.c | 44 |
2 files changed, 40 insertions, 62 deletions
diff --git a/src/emu/cpu/arm7/arm7drc.c b/src/emu/cpu/arm7/arm7drc.c index 38cbe42c261..858173f88a5 100644 --- a/src/emu/cpu/arm7/arm7drc.c +++ b/src/emu/cpu/arm7/arm7drc.c @@ -2421,34 +2421,19 @@ const bool drcarm7ops_0123(arm_state *arm, drcuml_block *block, compiler_state * 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) - { - UML_SHR(block, I0, I0, 16); - } - UML_SEXT(block, I0, I0, SIZE_WORD); - - if (insn & 0x40) - { - UML_SHR(block, I1, I1, 16); - } - UML_SEXT(block, I0, I0, SIZE_WORD); - + UML_DSEXT(block, I0, DRC_REG(rm), SIZE_DWORD); + UML_DSEXT(block, I1, DRC_REG(rn), SIZE_DWORD); // 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; + UML_DMULS(block, I2, I3, I0, I1); - // do the multiply and accumulate - 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)); + UML_MOV(block, I0, DRC_REG(rdh)); + UML_MOV(block, I1, DRC_REG(rdl)); + UML_DSHL(block, I0, I0, 32); + UML_DOR(block, I0, I0, I1); + UML_DADD(block, I0, I0, I2); + UML_MOV(block, DRC_REG(rdl), I0); + UML_DSHR(block, I0, I0, 32); + UML_MOV(block, DRC_REG(rdh), I0); } else if ((insn & 0x0ff00090) == 0x01600080) // SMULxy - v5 { @@ -2461,30 +2446,27 @@ const bool drcarm7ops_0123(arm_state *arm, drcuml_block *block, compiler_state * { src1 >>= 16; } - else + + src1 &= 0xffff; + if (src1 & 0x8000) { - src1 &= 0xffff; - if (src1 & 0x8000) - { - src1 |= 0xffff; - } + src1 |= 0xffff0000; } if (insn & 0x40) { src2 >>= 16; } - else + + src2 &= 0xffff; + if (src2 & 0x8000) { - src2 &= 0xffff; - if (src2 & 0x8000) - { - src2 |= 0xffff; - } + src2 |= 0xffff0000; } res = src1 * src2; SET_REGISTER(cpustart, (insn>>16)&0xf, res); + R15 += 4; } else if ((insn & 0x0ff000b0) == 0x012000a0) // SMULWy - v5 { diff --git a/src/emu/cpu/arm7/arm7ops.c b/src/emu/cpu/arm7/arm7ops.c index 35a65f569c5..a839faabfa2 100644 --- a/src/emu/cpu/arm7/arm7ops.c +++ b/src/emu/cpu/arm7/arm7ops.c @@ -1661,6 +1661,7 @@ const void arm7ops_0123(arm_state *arm, UINT32 insn) // write back the result SET_REGISTER(cpustart, (insn>>12)&0xf, (UINT32)dst); SET_REGISTER(cpustart, (insn>>16)&0xf, (UINT32)(dst >> 32)); + R15 += 4; } else if ((insn & 0x0ff00090) == 0x01600080) // SMULxy - v5 { @@ -1673,30 +1674,27 @@ const void arm7ops_0123(arm_state *arm, UINT32 insn) { src1 >>= 16; } - else + + src1 &= 0xffff; + if (src1 & 0x8000) { - src1 &= 0xffff; - if (src1 & 0x8000) - { - src1 |= 0xffff; - } + src1 |= 0xffff0000; } if (insn & 0x40) { src2 >>= 16; } - else + + src2 &= 0xffff; + if (src2 & 0x8000) { - src2 &= 0xffff; - if (src2 & 0x8000) - { - src2 |= 0xffff; - } + src2 |= 0xffff0000; } res = src1 * src2; SET_REGISTER(cpustart, (insn>>16)&0xf, res); + R15 += 4; } else if ((insn & 0x0ff000b0) == 0x012000a0) // SMULWy - v5 { @@ -1708,18 +1706,17 @@ const void arm7ops_0123(arm_state *arm, UINT32 insn) { src2 >>= 16; } - else + + src2 &= 0xffff; + if (src2 & 0x8000) { - src2 &= 0xffff; - if (src2 & 0x8000) - { - src2 |= 0xffff; - } + src2 |= 0xffff0000; } res = (INT64)src1 * (INT64)src2; res >>= 16; SET_REGISTER(cpustart, (insn>>16)&0xf, (UINT32)res); + R15 += 4; } else if ((insn & 0x0ff000b0) == 0x01200080) // SMLAWy - v5 { @@ -1732,13 +1729,11 @@ const void arm7ops_0123(arm_state *arm, UINT32 insn) { src2 >>= 16; } - else + + src2 &= 0xffff; + if (src2 & 0x8000) { - src2 &= 0xffff; - if (src2 & 0x8000) - { - src2 |= 0xffff; - } + src2 |= 0xffff0000; } res = (INT64)src1 * (INT64)src2; @@ -1752,6 +1747,7 @@ const void arm7ops_0123(arm_state *arm, UINT32 insn) // write the result back SET_REGISTER(cpustart, (insn>>16)&0xf, (UINT32)res); + R15 += 4; } else /* Multiply OR Swap OR Half Word Data Transfer */ |