summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/arm7/arm7ops.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/arm7/arm7ops.cpp')
-rw-r--r--src/devices/cpu/arm7/arm7ops.cpp309
1 files changed, 130 insertions, 179 deletions
diff --git a/src/devices/cpu/arm7/arm7ops.cpp b/src/devices/cpu/arm7/arm7ops.cpp
index ab5bd9243aa..416789a1e19 100644
--- a/src/devices/cpu/arm7/arm7ops.cpp
+++ b/src/devices/cpu/arm7/arm7ops.cpp
@@ -5,6 +5,11 @@
#include "arm7core.h"
#include "arm7help.h"
+#define LOG_OPS (1U << 1)
+
+#define VERBOSE (0)
+#include "logmacro.h"
+
int64_t arm7_cpu_device::saturate_qbit_overflow(int64_t res)
{
if (res > 2147483647) // INT32_MAX
@@ -61,17 +66,17 @@ uint32_t arm7_cpu_device::decodeShift(uint32_t insn, uint32_t *pCarry)
/* All shift types ending in 1 are Rk, not #k */
if (t & 1)
{
-// LOG(("%08x: RegShift %02x %02x\n", R15, k >> 1, GetRegister(k >> 1)));
+// LOGMASKED(LOG_OPS, "%08x: RegShift %02x %02x\n", R15, k >> 1, GetRegister(k >> 1));
#if ARM7_DEBUG_CORE
if ((insn & 0x80) == 0x80)
- LOG(("%08x: RegShift ERROR (p36)\n", R15));
+ LOGMASKED(LOG_OPS, "%08x: RegShift ERROR (p36)\n", R15);
#endif
// Keep only the bottom 8 bits for a Register Shift
k = GetRegister(k >> 1) & 0xff;
if (k == 0) /* Register shift by 0 is a no-op */
{
-// LOG(("%08x: NO-OP Regshift\n", R15));
+// LOGMASKED(LOG_OPS, "%08x: NO-OP Regshift\n", R15);
if (pCarry)
*pCarry = GET_CPSR & C_MASK;
return rm;
@@ -97,7 +102,7 @@ uint32_t arm7_cpu_device::decodeShift(uint32_t insn, uint32_t *pCarry)
// LSL (0,31) = Result shifted, least significant bit is in carry out
*pCarry = k ? (rm & (1 << (32 - k))) : (GET_CPSR & C_MASK);
}
- return k ? LSL(rm, k) : rm;
+ return k ? (rm << k) : rm;
}
case 1: /* LSR */
@@ -117,7 +122,7 @@ uint32_t arm7_cpu_device::decodeShift(uint32_t insn, uint32_t *pCarry)
{
if (pCarry)
*pCarry = (rm & (1 << (k - 1)));
- return LSR(rm, k);
+ return rm >> k;
}
case 2: /* ASR */
@@ -131,9 +136,9 @@ uint32_t arm7_cpu_device::decodeShift(uint32_t insn, uint32_t *pCarry)
else
{
if (rm & SIGN_BIT)
- return LSR(rm, k) | (0xffffffffu << (32 - k));
+ return (rm >> k) | (0xffffffffu << (32 - k));
else
- return LSR(rm, k);
+ return rm >> k;
}
case 3: /* ROR and RRX */
@@ -144,7 +149,7 @@ uint32_t arm7_cpu_device::decodeShift(uint32_t insn, uint32_t *pCarry)
{
if (pCarry)
*pCarry = rm & (1 << (k - 1));
- return ROR(rm, k);
+ return rotr_32(rm, k);
}
else
{
@@ -158,11 +163,11 @@ uint32_t arm7_cpu_device::decodeShift(uint32_t insn, uint32_t *pCarry)
/* RRX */
if (pCarry)
*pCarry = (rm & 1);
- return LSR(rm, 1) | ((GET_CPSR & C_MASK) << 2);
+ return (rm >> 1) | ((GET_CPSR & C_MASK) << 2);
}
}
- LOG(("%08x: Decodeshift error\n", R15));
+ LOGMASKED(LOG_OPS, "%08x: Decodeshift error\n", R15);
return 0;
} /* decodeShift */
@@ -178,25 +183,24 @@ int arm7_cpu_device::loadInc(uint32_t pat, uint32_t rbv, uint32_t s, int mode)
{
if ((pat >> i) & 1)
{
- if (!m_pendingAbtD) // "Overwriting of registers stops when the abort happens."
+ data = READ32(rbv += 4);
+ if (m_pendingAbtD) // "Overwriting of registers stops when the abort happens."
+ return result;
+ if (i == 15)
{
- data = READ32(rbv += 4);
- if (i == 15)
- {
- if (s) /* Pull full contents from stack */
- SetModeRegister(mode, 15, data);
- else if (MODE32) /* Pull only address, preserve mode & status flags */
- SetModeRegister(mode, 15, data);
- else
- {
- SetModeRegister(mode, 15, (GetModeRegister(mode, 15) & ~0x03FFFFFC) | (data & 0x03FFFFFC));
- }
- }
+ if (s) /* Pull full contents from stack */
+ SetModeRegister(mode, 15, data);
+ else if (MODE32) /* Pull only address, preserve mode & status flags */
+ SetModeRegister(mode, 15, data);
else
{
- SetModeRegister(mode, i, data);
+ SetModeRegister(mode, 15, (GetModeRegister(mode, 15) & ~0x03FFFFFC) | (data & 0x03FFFFFC));
}
}
+ else
+ {
+ SetModeRegister(mode, i, data);
+ }
result++;
}
}
@@ -215,25 +219,24 @@ int arm7_cpu_device::loadDec(uint32_t pat, uint32_t rbv, uint32_t s, int mode)
{
if ((pat >> i) & 1)
{
- if (!m_pendingAbtD) // "Overwriting of registers stops when the abort happens."
+ data = READ32(rbv -= 4);
+ if (m_pendingAbtD) // "Overwriting of registers stops when the abort happens."
+ return result;
+ if (i == 15)
{
- data = READ32(rbv -= 4);
- if (i == 15)
- {
- if (s) /* Pull full contents from stack */
- SetModeRegister(mode, 15, data);
- else if (MODE32) /* Pull only address, preserve mode & status flags */
- SetModeRegister(mode, 15, data);
- else
- {
- SetModeRegister(mode, 15, (GetModeRegister(mode, 15) & ~0x03FFFFFC) | (data & 0x03FFFFFC));
- }
- }
+ if (s) /* Pull full contents from stack */
+ SetModeRegister(mode, 15, data);
+ else if (MODE32) /* Pull only address, preserve mode & status flags */
+ SetModeRegister(mode, 15, data);
else
{
- SetModeRegister(mode, i, data);
+ SetModeRegister(mode, 15, (GetModeRegister(mode, 15) & ~0x03FFFFFC) | (data & 0x03FFFFFC));
}
}
+ else
+ {
+ SetModeRegister(mode, i, data);
+ }
result++;
}
}
@@ -252,9 +255,11 @@ int arm7_cpu_device::storeInc(uint32_t pat, uint32_t rbv, int mode)
{
#if ARM7_DEBUG_CORE
if (i == 15) /* R15 is plus 12 from address of STM */
- LOG(("%08x: StoreInc on R15\n", R15));
+ LOGMASKED(LOG_OPS, "%08x: StoreInc on R15\n", R15);
#endif
WRITE32(rbv += 4, GetModeRegister(mode, i));
+ if (m_pendingAbtD)
+ return result;
result++;
}
}
@@ -266,6 +271,7 @@ int arm7_cpu_device::storeDec(uint32_t pat, uint32_t rbv, int mode)
{
// pre-count the # of registers being stored
int const result = population_count_32(pat & 0x0000ffff);
+ int actual_result = 0;
// adjust starting address
rbv -= (result << 2);
@@ -276,10 +282,13 @@ int arm7_cpu_device::storeDec(uint32_t pat, uint32_t rbv, int mode)
{
#if ARM7_DEBUG_CORE
if (i == 15) /* R15 is plus 12 from address of STM */
- LOG(("%08x: StoreDec on R15\n", R15));
+ LOGMASKED(LOG_OPS, "%08x: StoreDec on R15\n", R15);
#endif
WRITE32(rbv, GetModeRegister(mode, i));
+ if (m_pendingAbtD)
+ return actual_result;
rbv += 4;
+ actual_result++;
}
}
return result;
@@ -294,7 +303,7 @@ int arm7_cpu_device::storeDec(uint32_t pat, uint32_t rbv, int mode)
void arm7_cpu_device::HandleCoProcDO(uint32_t insn)
{
// This instruction simply instructs the co-processor to do something, no data is returned to ARM7 core
- arm7_do_callback(*m_program, insn, 0, 0); // simply pass entire opcode to callback - since data format is actually dependent on co-proc implementation
+ arm7_do_callback(0); // simply pass entire opcode to callback - since data format is actually dependent on co-proc implementation
}
// Co-Processor Register Transfer - To/From Arm to Co-Proc
@@ -305,7 +314,7 @@ void arm7_cpu_device::HandleCoProcRT(uint32_t insn)
// Load (MRC) data from Co-Proc to ARM7 register
if (insn & 0x00100000) // Bit 20 = Load or Store
{
- uint32_t res = arm7_rt_r_callback(*m_program, insn, 0); // RT Read handler must parse opcode & return appropriate result
+ uint32_t res = arm7_rt_r_callback(insn); // RT Read handler must parse opcode & return appropriate result
if (!m_pendingUnd)
{
SetRegister((insn >> 12) & 0xf, res);
@@ -314,7 +323,7 @@ void arm7_cpu_device::HandleCoProcRT(uint32_t insn)
// Store (MCR) data from ARM7 to Co-Proc register
else
{
- arm7_rt_w_callback(*m_program, insn, GetRegister((insn >> 12) & 0xf), 0);
+ arm7_rt_w_callback(insn, GetRegister((insn >> 12) & 0xf));
}
}
@@ -340,7 +349,7 @@ void arm7_cpu_device::HandleCoProcDT(uint32_t insn)
#if ARM7_DEBUG_CORE
if (((insn >> 16) & 0xf) == 15 && (insn & 0x200000))
- LOG(("%08x: Illegal use of R15 as base for write back value!\n", R15));
+ LOGMASKED(LOG_OPS, "%08x: Illegal use of R15 as base for write back value!\n", R15);
#endif
// Pre-Increment base address (IF POST INCREMENT - CALL BACK FUNCTION MUST DO IT)
@@ -387,20 +396,10 @@ void arm7_cpu_device::HandleBranch(uint32_t insn, bool h_bit)
}
/* Sign-extend the 24-bit offset in our calculations */
- if (off & 0x2000000u)
- {
- if (MODE32)
- R15 -= ((~(off | 0xfc000000u)) + 1) - 8;
- else
- R15 = ((R15 - (((~(off | 0xfc000000u)) + 1) - 8)) & 0x03FFFFFC) | (R15 & ~0x03FFFFFC);
- }
+ if (MODE32)
+ R15 += util::sext(off, 26) + 8;
else
- {
- if (MODE32)
- R15 += off + 8;
- else
- R15 = ((R15 + (off + 8)) & 0x03FFFFFC) | (R15 & ~0x03FFFFFC);
- }
+ R15 = ((R15 + (util::sext(off, 26) + 8)) & 0x03FFFFFC) | (R15 & ~0x03FFFFFC);
}
void arm7_cpu_device::HandleMemSingle(uint32_t insn)
@@ -513,8 +512,8 @@ void arm7_cpu_device::HandleMemSingle(uint32_t insn)
if (insn & INSN_SDT_B)
{
#if ARM7_DEBUG_CORE
- if (rd == eR15)
- LOG(("Wrote R15 in byte mode\n"));
+ if (rd == eR15)
+ LOGMASKED(LOG_OPS, "Wrote R15 in byte mode\n");
#endif
WRITE8(rnv, (uint8_t) GetRegister(rd) & 0xffu);
@@ -522,8 +521,8 @@ void arm7_cpu_device::HandleMemSingle(uint32_t insn)
else
{
#if ARM7_DEBUG_CORE
- if (rd == eR15)
- LOG(("Wrote R15 in 32bit mode\n"));
+ if (rd == eR15)
+ LOGMASKED(LOG_OPS, "Wrote R15 in 32bit mode\n");
#endif
//WRITE32(rnv, rd == eR15 ? R15 + 8 : GetRegister(rd));
@@ -555,7 +554,7 @@ void arm7_cpu_device::HandleMemSingle(uint32_t insn)
}
else {
if ((insn & INSN_SDT_W) != 0)
- LOG(("%08x: RegisterWritebackIncrement %d %d %d\n", R15, (insn & INSN_SDT_P) != 0, (insn & INSN_SDT_W) != 0, (insn & INSN_SDT_U) != 0));
+ LOGMASKED(LOG_OPS, "%08x: RegisterWritebackIncrement %d %d %d\n", R15, (insn & INSN_SDT_P) != 0, (insn & INSN_SDT_W) != 0, (insn & INSN_SDT_U) != 0);
SetRegister(rn, (rnv + off));
}
@@ -571,7 +570,7 @@ void arm7_cpu_device::HandleMemSingle(uint32_t insn)
SetRegister(rn, (rnv - off));
if ((insn & INSN_SDT_W) != 0)
- LOG(("%08x: RegisterWritebackDecrement %d %d %d\n", R15, (insn & INSN_SDT_P) != 0, (insn & INSN_SDT_W) != 0, (insn & INSN_SDT_U) != 0));
+ LOGMASKED(LOG_OPS, "%08x: RegisterWritebackDecrement %d %d %d\n", R15, (insn & INSN_SDT_P) != 0, (insn & INSN_SDT_W) != 0, (insn & INSN_SDT_U) != 0);
}
}
}
@@ -768,7 +767,7 @@ void arm7_cpu_device::HandleHalfWordDT(uint32_t insn)
}
else {
if ((insn & INSN_SDT_W) != 0)
- LOG(("%08x: RegisterWritebackIncrement %d %d %d\n", R15, (insn & INSN_SDT_P) != 0, (insn & INSN_SDT_W) != 0, (insn & INSN_SDT_U) != 0));
+ LOGMASKED(LOG_OPS, "%08x: RegisterWritebackIncrement %d %d %d\n", R15, (insn & INSN_SDT_P) != 0, (insn & INSN_SDT_W) != 0, (insn & INSN_SDT_U) != 0);
SetRegister(rn, (rnv + off));
}
@@ -784,7 +783,7 @@ void arm7_cpu_device::HandleHalfWordDT(uint32_t insn)
SetRegister(rn, (rnv - off));
if ((insn & INSN_SDT_W) != 0)
- LOG(("%08x: RegisterWritebackDecrement %d %d %d\n", R15, (insn & INSN_SDT_P) != 0, (insn & INSN_SDT_W) != 0, (insn & INSN_SDT_U) != 0));
+ LOGMASKED(LOG_OPS, "%08x: RegisterWritebackDecrement %d %d %d\n", R15, (insn & INSN_SDT_P) != 0, (insn & INSN_SDT_W) != 0, (insn & INSN_SDT_U) != 0);
}
}
}
@@ -803,21 +802,27 @@ void arm7_cpu_device::HandleSwap(uint32_t insn)
#if ARM7_DEBUG_CORE
if (rn == 15 || rm == 15 || rd == 15)
- LOG(("%08x: Illegal use of R15 in Swap Instruction\n", R15));
+ LOGMASKED(LOG_OPS, "%08x: Illegal use of R15 in Swap Instruction\n", R15);
#endif
// can be byte or word
if (insn & 0x400000)
{
tmp = READ8(rn);
- WRITE8(rn, rm);
- SetRegister(rd, tmp);
+ if (!m_pendingAbtD)
+ {
+ WRITE8(rn, rm);
+ SetRegister(rd, tmp);
+ }
}
else
{
tmp = READ32(rn);
- WRITE32(rn, rm);
- SetRegister(rd, tmp);
+ if (!m_pendingAbtD)
+ {
+ WRITE32(rn, rm);
+ SetRegister(rd, tmp);
+ }
}
R15 += 4;
@@ -842,7 +847,7 @@ void arm7_cpu_device::HandlePSRTransfer(uint32_t insn)
// Value can be specified for a Right Rotate, 2x the value specified.
int by = (insn & INSN_OP2_ROTATE) >> INSN_OP2_ROTATE_SHIFT;
if (by)
- val = ROR(insn & INSN_OP2_IMM, by << 1);
+ val = rotr_32(insn & INSN_OP2_IMM, by << 1);
else
val = insn & INSN_OP2_IMM;
}
@@ -952,7 +957,7 @@ void arm7_cpu_device::HandleALU(uint32_t insn)
by = (insn & INSN_OP2_ROTATE) >> INSN_OP2_ROTATE_SHIFT;
if (by)
{
- op2 = ROR(insn & INSN_OP2_IMM, by << 1);
+ op2 = rotr_32(insn & INSN_OP2_IMM, by << 1);
sc = op2 & SIGN_BIT;
}
else
@@ -981,7 +986,7 @@ void arm7_cpu_device::HandleALU(uint32_t insn)
if ((rn = (insn & INSN_RN) >> INSN_RN_SHIFT) == eR15)
{
#if ARM7_DEBUG_CORE
- LOG(("%08x: Pipelined R15 (Shift %d)\n", R15, (insn & INSN_I ? 8 : insn & 0x10u ? 12 : 12)));
+ LOGMASKED(LOG_OPS, "%08x: Pipelined R15 (Shift %d)\n", R15, (insn & INSN_I ? 8 : insn & 0x10u ? 12 : 12));
#endif
if (MODE32)
rn = R15 + 8;
@@ -1119,7 +1124,7 @@ void arm7_cpu_device::HandleALU(uint32_t insn)
{
if (insn & INSN_S) {
#if ARM7_DEBUG_CORE
- LOG(("%08x: TST class on R15 s bit set\n", R15));
+ LOGMASKED(LOG_OPS, "%08x: TST class on R15 s bit set\n", R15);
#endif
if (MODE32)
R15 = rd;
@@ -1138,7 +1143,7 @@ void arm7_cpu_device::HandleALU(uint32_t insn)
else
{
#if ARM7_DEBUG_CORE
- LOG(("%08x: TST class on R15 no s bit set\n", R15));
+ LOGMASKED(LOG_OPS, "%08x: TST class on R15 no s bit set\n", R15);
#endif
}
// extra cycles (PC written)
@@ -1169,7 +1174,7 @@ void arm7_cpu_device::HandleMul(uint32_t insn)
if ((insn & INSN_MUL_RM) == 0xf ||
((insn & INSN_MUL_RS) >> INSN_MUL_RS_SHIFT) == 0xf ||
((insn & INSN_MUL_RN) >> INSN_MUL_RN_SHIFT) == 0xf)
- LOG(("%08x: R15 used in mult\n", R15));
+ LOGMASKED(LOG_OPS, "%08x: R15 used in mult\n", R15);
#endif
/* Add on Rn if this is a MLA */
@@ -1201,26 +1206,22 @@ void arm7_cpu_device::HandleMul(uint32_t insn)
// todo: add proper cycle counts
void arm7_cpu_device::HandleSMulLong(uint32_t insn)
{
- int32_t rm, rs;
- uint32_t rhi, rlo;
- int64_t res;
-
// MULL takes 1S + (m+1)I and MLAL 1S + (m+2)I cycles to execute, where m is the
// number of 8 bit multiplier array cycles required to complete the multiply, which is
// controlled by the value of the multiplier operand specified by Rs.
- rm = (int32_t)GetRegister(insn & 0xf);
- rs = (int32_t)GetRegister(((insn >> 8) & 0xf));
- rhi = (insn >> 16) & 0xf;
- rlo = (insn >> 12) & 0xf;
+ int32_t rm = (int32_t)GetRegister(insn & 0xf);
+ int32_t rs = (int32_t)GetRegister(((insn >> 8) & 0xf));
+ uint32_t rhi = (insn >> 16) & 0xf;
+ uint32_t rlo = (insn >> 12) & 0xf;
#if ARM7_DEBUG_CORE
if ((insn & 0xf) == 15 || ((insn >> 8) & 0xf) == 15 || ((insn >> 16) & 0xf) == 15 || ((insn >> 12) & 0xf) == 15)
- LOG(("%08x: Illegal use of PC as a register in SMULL opcode\n", R15));
+ LOGMASKED(LOG_OPS, "%08x: Illegal use of PC as a register in SMULL opcode\n", R15);
#endif
/* Perform the multiplication */
- res = (int64_t)rm * rs;
+ int64_t res = mul_32x32(rm, rs);
/* Add on Rn if this is a MLA */
if (insn & INSN_MUL_A)
@@ -1253,26 +1254,22 @@ void arm7_cpu_device::HandleSMulLong(uint32_t insn)
// todo: add proper cycle counts
void arm7_cpu_device::HandleUMulLong(uint32_t insn)
{
- uint32_t rm, rs;
- uint32_t rhi, rlo;
- uint64_t res;
-
// MULL takes 1S + (m+1)I and MLAL 1S + (m+2)I cycles to execute, where m is the
// number of 8 bit multiplier array cycles required to complete the multiply, which is
// controlled by the value of the multiplier operand specified by Rs.
- rm = (int32_t)GetRegister(insn & 0xf);
- rs = (int32_t)GetRegister(((insn >> 8) & 0xf));
- rhi = (insn >> 16) & 0xf;
- rlo = (insn >> 12) & 0xf;
+ uint32_t rm = GetRegister(insn & 0xf);
+ uint32_t rs = GetRegister(((insn >> 8) & 0xf));
+ uint32_t rhi = (insn >> 16) & 0xf;
+ uint32_t rlo = (insn >> 12) & 0xf;
#if ARM7_DEBUG_CORE
if (((insn & 0xf) == 15) || (((insn >> 8) & 0xf) == 15) || (((insn >> 16) & 0xf) == 15) || (((insn >> 12) & 0xf) == 15))
- LOG(("%08x: Illegal use of PC as a register in SMULL opcode\n", R15));
+ LOGMASKED(LOG_OPS, "%08x: Illegal use of PC as a register in SMULL opcode\n", R15);
#endif
/* Perform the multiplication */
- res = (uint64_t)rm * rs;
+ uint64_t res = mulu_32x32(rm, rs);
/* Add on Rn if this is a MLA */
if (insn & INSN_MUL_A)
@@ -1309,7 +1306,7 @@ void arm7_cpu_device::HandleMemBlock(uint32_t insn)
#if ARM7_DEBUG_CORE
if (rbp & 3)
- LOG(("%08x: Unaligned Mem Transfer @ %08x\n", R15, rbp));
+ LOGMASKED(LOG_OPS, "%08x: Unaligned Mem Transfer @ %08x\n", R15, rbp);
#endif
// Normal LDM instructions take nS + 1N + 1I and LDM PC takes (n+1)S + 2N + 1I
@@ -1335,7 +1332,7 @@ void arm7_cpu_device::HandleMemBlock(uint32_t insn)
// set to user mode - then do the transfer, and set back
//int curmode = GET_MODE;
//SwitchMode(eARM7_MODE_USER);
- LOG(("%08x: User Bank Transfer not fully tested - please check if working properly!\n", R15));
+ LOGMASKED(LOG_OPS, "%08x: User Bank Transfer not fully tested - please check if working properly!\n", R15);
result = loadInc(insn & 0xffff, rbp, insn & INSN_BDT_S, eARM7_MODE_USER);
// todo - not sure if Writeback occurs on User registers also..
//SwitchMode(curmode);
@@ -1346,8 +1343,8 @@ void arm7_cpu_device::HandleMemBlock(uint32_t insn)
if ((insn & INSN_BDT_W) && !m_pendingAbtD)
{
#if ARM7_DEBUG_CORE
- if (rb == 15)
- LOG(("%08x: Illegal LDRM writeback to r15\n", R15));
+ if (rb == 15)
+ LOGMASKED(LOG_OPS, "%08x: Illegal LDRM writeback to r15\n", R15);
#endif
// "A LDM will always overwrite the updated base if the base is in the list." (also for a user bank transfer?)
// GBA "V-Rally 3" expects R0 not to be overwritten with the updated base value [BP 8077B0C]
@@ -1372,7 +1369,7 @@ void arm7_cpu_device::HandleMemBlock(uint32_t insn)
else
{
uint32_t temp;
-// LOG(("LDM + S | R15 %08X CPSR %08X\n", R15, GET_CPSR));
+// LOGMASKED(LOG_OPS, "LDM + S | R15 %08X CPSR %08X\n", R15, GET_CPSR);
temp = (GET_CPSR & 0x0FFFFF20) | (R15 & 0xF0000000) /* N Z C V */ | ((R15 & 0x0C000000) >> (26 - 6)) /* I F */ | (R15 & 0x00000003) /* M1 M0 */;
set_cpsr( temp);
SwitchMode(temp & 3);
@@ -1402,7 +1399,7 @@ void arm7_cpu_device::HandleMemBlock(uint32_t insn)
// set to user mode - then do the transfer, and set back
//int curmode = GET_MODE;
//SwitchMode(eARM7_MODE_USER);
- LOG(("%08x: User Bank Transfer not fully tested - please check if working properly!\n", R15));
+ LOGMASKED(LOG_OPS, "%08x: User Bank Transfer not fully tested - please check if working properly!\n", R15);
result = loadDec(insn & 0xffff, rbp, insn & INSN_BDT_S, eARM7_MODE_USER);
// todo - not sure if Writeback occurs on User registers also..
//SwitchMode(curmode);
@@ -1413,7 +1410,7 @@ void arm7_cpu_device::HandleMemBlock(uint32_t insn)
if ((insn & INSN_BDT_W) && !m_pendingAbtD)
{
if (rb == 0xf)
- LOG(("%08x: Illegal LDRM writeback to r15\n", R15));
+ LOGMASKED(LOG_OPS, "%08x: Illegal LDRM writeback to r15\n", R15);
// "A LDM will always overwrite the updated base if the base is in the list." (also for a user bank transfer?)
if (((insn >> rb) & 1) == 0)
{
@@ -1435,7 +1432,7 @@ void arm7_cpu_device::HandleMemBlock(uint32_t insn)
else
{
uint32_t temp;
-// LOG(("LDM + S | R15 %08X CPSR %08X\n", R15, GET_CPSR));
+// LOGMASKED(LOG_OPS, "LDM + S | R15 %08X CPSR %08X\n", R15, GET_CPSR);
temp = (GET_CPSR & 0x0FFFFF20) /* N Z C V I F M4 M3 M2 M1 M0 */ | (R15 & 0xF0000000) /* N Z C V */ | ((R15 & 0x0C000000) >> (26 - 6)) /* I F */ | (R15 & 0x00000003) /* M1 M0 */;
set_cpsr(temp);
SwitchMode(temp & 3);
@@ -1460,7 +1457,7 @@ void arm7_cpu_device::HandleMemBlock(uint32_t insn)
if (insn & (1 << eR15))
{
#if ARM7_DEBUG_CORE
- LOG(("%08x: Writing R15 in strm\n", R15));
+ LOGMASKED(LOG_OPS, "%08x: Writing R15 in strm\n", R15);
#endif
/* special case handling if writing to PC */
R15 += 12;
@@ -1481,7 +1478,7 @@ void arm7_cpu_device::HandleMemBlock(uint32_t insn)
// set to user mode - then do the transfer, and set back
//int curmode = GET_MODE;
//SwitchMode(eARM7_MODE_USER);
- LOG(("%08x: User Bank Transfer not fully tested - please check if working properly!\n", R15));
+ LOGMASKED(LOG_OPS, "%08x: User Bank Transfer not fully tested - please check if working properly!\n", R15);
result = storeInc(insn & 0xffff, rbp, eARM7_MODE_USER);
// todo - not sure if Writeback occurs on User registers also..
//SwitchMode(curmode);
@@ -1508,7 +1505,7 @@ void arm7_cpu_device::HandleMemBlock(uint32_t insn)
// set to user mode - then do the transfer, and set back
//int curmode = GET_MODE;
//SwitchMode(eARM7_MODE_USER);
- LOG(("%08x: User Bank Transfer not fully tested - please check if working properly!\n", R15));
+ LOGMASKED(LOG_OPS, "%08x: User Bank Transfer not fully tested - please check if working properly!\n", R15);
result = storeDec(insn & 0xffff, rbp, eARM7_MODE_USER);
// todo - not sure if Writeback occurs on User registers also..
//SwitchMode(curmode);
@@ -1549,7 +1546,7 @@ const arm7_cpu_device::arm7ops_ophandler arm7_cpu_device::ops_handler[0x20] =
void arm7_cpu_device::arm9ops_undef(uint32_t insn)
{
// unsupported instruction
- LOG(("ARM7: Instruction %08X unsupported\n", insn));
+ LOGMASKED(LOG_OPS, "ARM7: Instruction %08X unsupported\n", insn);
}
void arm7_cpu_device::arm9ops_1(uint32_t insn)
@@ -1661,8 +1658,8 @@ void arm7_cpu_device::arm7ops_0123(uint32_t insn)
R15 = GetRegister(insn & 0x0f);
// If new PC address has A0 set, switch to Thumb mode
if (R15 & 1) {
- set_cpsr(GET_CPSR|T_MASK);
R15--;
+ set_cpsr(GET_CPSR|T_MASK);
}
}
else if ((insn & 0x0ff000f0) == 0x01200030) // BLX Rn - v5
@@ -1673,8 +1670,8 @@ void arm7_cpu_device::arm7ops_0123(uint32_t insn)
R15 = GetRegister(insn & 0x0f);
// If new PC address has A0 set, switch to Thumb mode
if (R15 & 1) {
- set_cpsr(GET_CPSR|T_MASK);
R15--;
+ set_cpsr(GET_CPSR|T_MASK);
}
}
else if ((insn & 0x0ff000f0) == 0x01600010) // CLZ - v5
@@ -1682,7 +1679,7 @@ void arm7_cpu_device::arm7ops_0123(uint32_t insn)
uint32_t rm = insn&0xf;
uint32_t rd = (insn>>12)&0xf;
- SetRegister(rd, count_leading_zeros(GetRegister(rm)));
+ SetRegister(rd, count_leading_zeros_32(GetRegister(rm)));
R15 += 4;
}
@@ -1690,9 +1687,8 @@ void arm7_cpu_device::arm7ops_0123(uint32_t insn)
{
int32_t src1 = GetRegister(insn&0xf);
int32_t src2 = GetRegister((insn>>16)&0xf);
- int64_t res;
- res = saturate_qbit_overflow((int64_t)src1 + (int64_t)src2);
+ int64_t res = saturate_qbit_overflow((int64_t)src1 + (int64_t)src2);
SetRegister((insn>>12)&0xf, (int32_t)res);
R15 += 4;
@@ -1701,10 +1697,9 @@ void arm7_cpu_device::arm7ops_0123(uint32_t insn)
{
int32_t src1 = GetRegister(insn&0xf);
int32_t src2 = GetRegister((insn>>16)&0xf);
- int64_t res;
// check if doubling operation will overflow
- res = (int64_t)src2 * 2;
+ int64_t res = (int64_t)src2 * 2;
saturate_qbit_overflow(res);
src2 *= 2;
@@ -1717,9 +1712,8 @@ void arm7_cpu_device::arm7ops_0123(uint32_t insn)
{
int32_t src1 = GetRegister(insn&0xf);
int32_t src2 = GetRegister((insn>>16)&0xf);
- int64_t res;
- res = saturate_qbit_overflow((int64_t)src1 - (int64_t)src2);
+ int64_t res = saturate_qbit_overflow((int64_t)src1 - (int64_t)src2);
SetRegister((insn>>12)&0xf, (int32_t)res);
R15 += 4;
@@ -1728,10 +1722,9 @@ void arm7_cpu_device::arm7ops_0123(uint32_t insn)
{
int32_t src1 = GetRegister(insn&0xf);
int32_t src2 = GetRegister((insn>>16)&0xf);
- int64_t res;
// check if doubling operation will overflow
- res = (int64_t)src2 * 2;
+ int64_t res = (int64_t)src2 * 2;
saturate_qbit_overflow(res);
src2 *= 2;
@@ -1748,26 +1741,14 @@ void arm7_cpu_device::arm7ops_0123(uint32_t insn)
// select top and bottom halves of src1/src2 and sign extend if necessary
if (insn & 0x20)
- {
src1 >>= 16;
- }
-
- src1 &= 0xffff;
- if (src1 & 0x8000)
- {
- src1 |= 0xffff0000;
- }
+ else
+ src1 = util::sext(src1, 16);
if (insn & 0x40)
- {
src2 >>= 16;
- }
-
- src2 &= 0xffff;
- if (src2 & 0x8000)
- {
- src2 |= 0xffff0000;
- }
+ else
+ src2 = util::sext(src2, 16);
// do the signed multiply
res1 = src1 * src2;
@@ -1781,13 +1762,12 @@ void arm7_cpu_device::arm7ops_0123(uint32_t insn)
{
int32_t src1 = GetRegister(insn&0xf);
int32_t src2 = GetRegister((insn>>8)&0xf);
- int64_t dst;
- dst = (int64_t)GetRegister((insn>>12)&0xf);
+ int64_t dst = (int64_t)GetRegister((insn>>12)&0xf);
dst |= (int64_t)GetRegister((insn>>16)&0xf)<<32;
// do the multiply and accumulate
- dst += (int64_t)src1 * (int64_t)src2;
+ dst += mul_32x32(src1, src2);
// write back the result
SetRegister((insn>>12)&0xf, (uint32_t)dst);
@@ -1798,32 +1778,19 @@ void arm7_cpu_device::arm7ops_0123(uint32_t insn)
{
int32_t src1 = GetRegister(insn&0xf);
int32_t src2 = GetRegister((insn>>8)&0xf);
- int32_t res;
// select top and bottom halves of src1/src2 and sign extend if necessary
if (insn & 0x20)
- {
src1 >>= 16;
- }
-
- src1 &= 0xffff;
- if (src1 & 0x8000)
- {
- src1 |= 0xffff0000;
- }
+ else
+ src1 = util::sext(src1, 16);
if (insn & 0x40)
- {
src2 >>= 16;
- }
-
- src2 &= 0xffff;
- if (src2 & 0x8000)
- {
- src2 |= 0xffff0000;
- }
+ else
+ src2 = util::sext(src2, 16);
- res = src1 * src2;
+ int32_t res = src1 * src2;
SetRegister((insn>>16)&0xf, res);
R15 += 4;
}
@@ -1831,21 +1798,13 @@ void arm7_cpu_device::arm7ops_0123(uint32_t insn)
{
int32_t src1 = GetRegister(insn&0xf);
int32_t src2 = GetRegister((insn>>8)&0xf);
- int64_t res;
if (insn & 0x40)
- {
src2 >>= 16;
- }
-
- src2 &= 0xffff;
- if (src2 & 0x8000)
- {
- src2 |= 0xffff0000;
- }
+ else
+ src2 = util::sext(src2, 16);
- res = (int64_t)src1 * (int64_t)src2;
- res >>= 16;
+ int32_t res = mul_32x32_shift(src1, src2, 16);
SetRegister((insn>>16)&0xf, (uint32_t)res);
R15 += 4;
}
@@ -1854,27 +1813,19 @@ void arm7_cpu_device::arm7ops_0123(uint32_t insn)
int32_t src1 = GetRegister(insn&0xf);
int32_t src2 = GetRegister((insn>>8)&0xf);
int32_t src3 = GetRegister((insn>>12)&0xf);
- int64_t res;
if (insn & 0x40)
- {
src2 >>= 16;
- }
-
- src2 &= 0xffff;
- if (src2 & 0x8000)
- {
- src2 |= 0xffff0000;
- }
+ else
+ src2 = util::sext(src2, 16);
- res = (int64_t)src1 * (int64_t)src2;
- res >>= 16;
+ int32_t res = mul_32x32_shift(src1, src2, 16);
// check for overflow and set the Q bit
saturate_qbit_overflow((int64_t)src3 + res);
// do the real accumulate
- src3 += (int32_t)res;
+ src3 += res;
// write the result back
SetRegister((insn>>16)&0xf, (uint32_t)res);