diff --git a/src/arch/arm/insts/macromem.cc b/src/arch/arm/insts/macromem.cc index 5c4c2522d..e5c374089 100644 --- a/src/arch/arm/insts/macromem.cc +++ b/src/arch/arm/insts/macromem.cc @@ -101,7 +101,7 @@ MacroMemOp::MacroMemOp(const char *mnem, ExtMachInst machInst, unsigned regIdx = reg; if (force_user) { - regIdx = intRegForceUser(regIdx); + regIdx = intRegInMode(MODE_USER, regIdx); } if (load) { diff --git a/src/arch/arm/intregs.hh b/src/arch/arm/intregs.hh index d13cca6df..99ea9b7a6 100644 --- a/src/arch/arm/intregs.hh +++ b/src/arch/arm/intregs.hh @@ -1,4 +1,16 @@ /* + * Copyright (c) 2010 ARM Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 2009 The Regents of The University of Michigan * All rights reserved. * @@ -33,6 +45,8 @@ #ifndef __ARCH_ARM_INTREGS_HH__ #define __ARCH_ARM_INTREGS_HH__ +#include "arch/arm/types.hh" + namespace ArmISA { @@ -322,12 +336,13 @@ INTREG_FIQ(unsigned index) return IntRegFiqMap[index]; } -static inline IntRegIndex -intRegForceUser(unsigned index) -{ - assert(index < NUM_ARCH_INTREGS); +static const unsigned intRegsPerMode = NUM_INTREGS; - return index == 15 ? (IntRegIndex)15 : (IntRegIndex)(index + NUM_INTREGS); +static inline int +intRegInMode(OperatingMode mode, int reg) +{ + assert(reg < NUM_ARCH_INTREGS); + return mode * intRegsPerMode + reg; } } diff --git a/src/arch/arm/isa.hh b/src/arch/arm/isa.hh index a9c404351..a7bb1cc3e 100644 --- a/src/arch/arm/isa.hh +++ b/src/arch/arm/isa.hh @@ -270,9 +270,27 @@ namespace ArmISA } else if (reg < NUM_INTREGS) { return reg; } else { - reg -= NUM_INTREGS; - assert(reg < NUM_ARCH_INTREGS); - return reg; + int mode = reg / intRegsPerMode; + reg = reg % intRegsPerMode; + switch (mode) { + case MODE_USER: + case MODE_SYSTEM: + return INTREG_USR(reg); + case MODE_FIQ: + return INTREG_FIQ(reg); + case MODE_IRQ: + return INTREG_IRQ(reg); + case MODE_SVC: + return INTREG_SVC(reg); + case MODE_MON: + return INTREG_MON(reg); + case MODE_ABORT: + return INTREG_ABT(reg); + case MODE_UNDEFINED: + return INTREG_UND(reg); + default: + panic("Flattening into an unknown mode.\n"); + } } } diff --git a/src/arch/arm/isa/operands.isa b/src/arch/arm/isa/operands.isa index 3fda93668..d99211b89 100644 --- a/src/arch/arm/isa/operands.isa +++ b/src/arch/arm/isa/operands.isa @@ -99,6 +99,9 @@ def operands {{ maybePCRead, maybeIWPCWrite), 'AIWDest': ('IntReg', 'uw', 'dest', 'IsInteger', 2, maybePCRead, maybeAIWPCWrite), + 'SpMode': ('IntReg', 'uw', + 'intRegInMode((OperatingMode)regMode, INTREG_SP)', + 'IsInteger', 2), 'MiscDest': ('ControlReg', 'uw', 'dest', (None, None, 'IsControl'), 2), 'Base': ('IntReg', 'uw', 'base', 'IsInteger', 0, maybeAlignedPCRead, maybePCWrite), diff --git a/src/arch/arm/registers.hh b/src/arch/arm/registers.hh index ada8b5079..ac95f4091 100644 --- a/src/arch/arm/registers.hh +++ b/src/arch/arm/registers.hh @@ -40,7 +40,7 @@ namespace ArmISA { using ArmISAInst::MaxInstSrcRegs; using ArmISAInst::MaxInstDestRegs; -typedef uint8_t RegIndex; +typedef uint16_t RegIndex; typedef uint64_t IntReg;