diff options
Diffstat (limited to 'src/devices/cpu/arm/arm.cpp')
-rw-r--r-- | src/devices/cpu/arm/arm.cpp | 79 |
1 files changed, 26 insertions, 53 deletions
diff --git a/src/devices/cpu/arm/arm.cpp b/src/devices/cpu/arm/arm.cpp index 13a6cf7c64b..03b610e86dc 100644 --- a/src/devices/cpu/arm/arm.cpp +++ b/src/devices/cpu/arm/arm.cpp @@ -1,7 +1,7 @@ // license:BSD-3-Clause // copyright-holders:Bryan McPhail, Phil Stroffolino /* - ARM 2/3/6 Emulation (26 bit address bus) + ARM 2/3 Emulation (26 bit address bus, no separate PSRs) Todo: - Timing - Currently very approximated, nothing relies on proper timing so far. @@ -18,7 +18,6 @@ #include "emu.h" #include "arm.h" -#include "debugger.h" #include "armdasm.h" #define ARM_DEBUG_CORE 0 @@ -213,16 +212,10 @@ enum COND_NV /* never */ }; -#define LSL(v,s) ((v) << (s)) -#define LSR(v,s) ((v) >> (s)) -#define ROL(v,s) (LSL((v),(s)) | (LSR((v),32u - (s)))) -#define ROR(v,s) (LSR((v),(s)) | (LSL((v),32u - (s)))) - /***************************************************************************/ -DEFINE_DEVICE_TYPE(ARM, arm_cpu_device, "arm_le", "ARM (little)") -DEFINE_DEVICE_TYPE(ARM_BE, arm_be_cpu_device, "arm_be", "ARM (big)") +DEFINE_DEVICE_TYPE(ARM, arm_cpu_device, "arm_cpu", "ARM") device_memory_interface::space_config_vector arm_cpu_device::memory_space_config() const @@ -233,27 +226,20 @@ device_memory_interface::space_config_vector arm_cpu_device::memory_space_config } arm_cpu_device::arm_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : arm_cpu_device(mconfig, ARM, tag, owner, clock, ENDIANNESS_LITTLE) + : arm_cpu_device(mconfig, ARM, tag, owner, clock) { } -arm_cpu_device::arm_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, endianness_t endianness) +arm_cpu_device::arm_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : cpu_device(mconfig, type, tag, owner, clock) - , m_program_config("program", endianness, 32, 26, 0) - , m_endian(endianness) + , m_program_config("program", ENDIANNESS_LITTLE, 32, 26, 0) , m_copro_type(copro_type::UNKNOWN_CP15) { std::fill(std::begin(m_sArmRegister), std::end(m_sArmRegister), 0); } -arm_be_cpu_device::arm_be_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : arm_cpu_device(mconfig, ARM_BE, tag, owner, clock, ENDIANNESS_BIG) -{ -} - - void arm_cpu_device::cpu_write32( int addr, uint32_t data ) { @@ -278,11 +264,11 @@ uint32_t arm_cpu_device::cpu_read32( int addr ) logerror("%08x: Unaligned byte read %08x\n",R15,addr); if ((addr&3)==1) - return ((result&0x000000ff)<<24)|((result&0xffffff00)>> 8); + return rotr_32(result, 8); if ((addr&3)==2) - return ((result&0x0000ffff)<<16)|((result&0xffff0000)>>16); + return rotr_32(result, 16); if ((addr&3)==3) - return ((result&0x00ffffff)<< 8)|((result&0xff000000)>>24); + return rotr_32(result, 24); } return result; @@ -343,7 +329,7 @@ void arm_cpu_device::execute_run() /* load instruction */ uint32_t pc = R15; - uint32_t insn = m_pr32( pc & ADDRESS_MASK ); + uint32_t insn = m_cache.read_dword( pc & ADDRESS_MASK ); switch (insn >> INSN_COND_SHIFT) { @@ -448,10 +434,10 @@ void arm_cpu_device::arm_check_irq_state() { uint32_t pc = R15+4; /* save old pc (already incremented in pipeline) */; - /* Exception priorities (from ARM6, not specifically ARM2/3): + /* Exception priorities for ARM2/3: Reset - Data abort + Data abort or address exception FIRQ IRQ Prefetch abort @@ -460,19 +446,19 @@ void arm_cpu_device::arm_check_irq_state() if (m_pendingFiq && (pc&F_MASK)==0) { + standard_irq_callback(ARM_FIRQ_LINE, R15 & ADDRESS_MASK); R15 = eARM_MODE_FIQ; /* Set FIQ mode so PC is saved to correct R14 bank */ SetRegister( 14, pc ); /* save PC */ R15 = (pc&PSR_MASK)|(pc&IRQ_MASK)|0x1c|eARM_MODE_FIQ|I_MASK|F_MASK; /* Mask both IRQ & FIRQ, set PC=0x1c */ - standard_irq_callback(ARM_FIRQ_LINE); return; } if (m_pendingIrq && (pc&I_MASK)==0) { + standard_irq_callback(ARM_IRQ_LINE, R15 & ADDRESS_MASK); R15 = eARM_MODE_IRQ; /* Set IRQ mode so PC is saved to correct R14 bank */ SetRegister( 14, pc ); /* save PC */ R15 = (pc&PSR_MASK)|(pc&IRQ_MASK)|0x18|eARM_MODE_IRQ|I_MASK|(pc&F_MASK); /* Mask only IRQ, set PC=0x18 */ - standard_irq_callback(ARM_IRQ_LINE); return; } } @@ -497,13 +483,7 @@ void arm_cpu_device::device_start() { m_program = &space(AS_PROGRAM); - if(m_program->endianness() == ENDIANNESS_LITTLE) { - m_program->cache(m_cachele); - m_pr32 = [this](offs_t address) -> u32 { return m_cachele.read_dword(address); }; - } else { - m_program->cache(m_cachebe); - m_pr32 = [this](offs_t address) -> u32 { return m_cachebe.read_dword(address); }; - } + m_program->cache(m_cache); save_item(NAME(m_sArmRegister)); save_item(NAME(m_coproRegister)); @@ -539,8 +519,8 @@ void arm_cpu_device::device_start() state_add( ARM32_SR13, "SR13", m_sArmRegister[eR13_SVC] ).formatstr("%08X"); state_add( ARM32_SR14, "SR14", m_sArmRegister[eR14_SVC] ).formatstr("%08X"); - state_add(STATE_GENPC, "GENPC", m_sArmRegister[15]).mask(ADDRESS_MASK).formatstr("%8s").noshow(); - state_add(STATE_GENPCBASE, "CURPC", m_sArmRegister[15]).mask(ADDRESS_MASK).formatstr("%8s").noshow(); + state_add(STATE_GENPC, "GENPC", m_sArmRegister[15]).mask(ADDRESS_MASK).noshow(); + state_add(STATE_GENPCBASE, "CURPC", m_sArmRegister[15]).mask(ADDRESS_MASK).noshow(); state_add(STATE_GENFLAGS, "GENFLAGS", m_sArmRegister[15]).formatstr("%11s").noshow(); set_icountptr(m_icount); @@ -580,14 +560,7 @@ void arm_cpu_device::HandleBranch( uint32_t insn ) } /* Sign-extend the 24-bit offset in our calculations */ - if (off & 0x2000000u) - { - R15 = ((R15 - (((~(off | 0xfc000000u)) + 1) - 8)) & ADDRESS_MASK) | (R15 & ~ADDRESS_MASK); - } - else - { - R15 = ((R15 + (off + 8)) & ADDRESS_MASK) | (R15 & ~ADDRESS_MASK); - } + R15 = ((R15 + (util::sext(off, 26) + 8)) & ADDRESS_MASK) | (R15 & ~ADDRESS_MASK); m_icount -= 2 * S_CYCLE + N_CYCLE; } @@ -765,7 +738,7 @@ void arm_cpu_device::HandleMemSingle( uint32_t insn ) ((R15 &~ (N_MASK | Z_MASK | V_MASK | C_MASK)) \ | (((!SIGN_BITS_DIFFER(rn, op2)) && SIGN_BITS_DIFFER(rn, rd)) \ << V_BIT) \ - | (((~(rn)) < (op2)) << C_BIT) \ + | (((IsNeg(rn) & IsNeg(op2)) | (IsNeg(rn) & IsPos(rd)) | (IsNeg(op2) & IsPos(rd))) ? C_MASK : 0) \ | HandleALUNZFlags(rd)) \ + 4; \ else R15 += 4; @@ -811,7 +784,7 @@ void arm_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 @@ -824,7 +797,7 @@ void arm_cpu_device::HandleALU( uint32_t insn ) { op2 = decodeShift(insn, (insn & INSN_S) ? &sc : nullptr); - if (!(insn & INSN_S)) + if (!(insn & INSN_S)) sc=0; } @@ -1327,7 +1300,7 @@ uint32_t arm_cpu_device::decodeShift(uint32_t insn, uint32_t *pCarry) { *pCarry = k ? (rm & (1 << (32 - k))) : (R15 & C_MASK); } - return k ? LSL(rm, k) : rm; + return rm << k; case 1: /* LSR */ if (k == 0 || k == 32) @@ -1343,7 +1316,7 @@ uint32_t arm_cpu_device::decodeShift(uint32_t insn, uint32_t *pCarry) else { if (pCarry) *pCarry = (rm & (1 << (k - 1))); - return LSR(rm, k); + return rm >> k; } case 2: /* ASR */ @@ -1355,9 +1328,9 @@ uint32_t arm_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 */ @@ -1365,12 +1338,12 @@ uint32_t arm_cpu_device::decodeShift(uint32_t insn, uint32_t *pCarry) { while (k > 32) k -= 32; if (pCarry) *pCarry = rm & (1 << (k - 1)); - return ROR(rm, k); + return rotr_32(rm, k); } else { if (pCarry) *pCarry = (rm & 1); - return LSR(rm, 1) | ((R15 & C_MASK) << 2); + return (rm >> 1) | ((R15 & C_MASK) << 2); } } |