diff --git a/src/arch/arm/insts/macromem.hh b/src/arch/arm/insts/macromem.hh index 541c9e3f5..714b8bb7e 100644 --- a/src/arch/arm/insts/macromem.hh +++ b/src/arch/arm/insts/macromem.hh @@ -84,33 +84,20 @@ class MicroMemOp : public MicroIntOp */ class ArmMacroMemoryOp : public PredMacroOp { - protected: + protected: /// Memory request flags. See mem_req_base.hh. unsigned memAccessFlags; uint32_t reglist; uint32_t ones; - uint32_t puswl, - prepost, - up, - psruser, - writeback, - loadop; ArmMacroMemoryOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) - : PredMacroOp(mnem, _machInst, __opClass), - memAccessFlags(0), - reglist(machInst.regList), ones(0), - puswl(machInst.puswl), - prepost(machInst.puswl.prepost), - up(machInst.puswl.up), - psruser(machInst.puswl.psruser), - writeback(machInst.puswl.writeback), - loadop(machInst.puswl.loadOp) + : PredMacroOp(mnem, _machInst, __opClass), memAccessFlags(0), + reglist(machInst.regList), ones(0) { ones = number_of_ones(reglist); - numMicroops = ones + writeback + 1; + numMicroops = ones + machInst.puswl.writeback + 1; // Remember that writeback adds a uop microOps = new StaticInstPtr[numMicroops]; } @@ -121,7 +108,7 @@ class ArmMacroMemoryOp : public PredMacroOp */ class ArmMacroFPAOp : public PredMacroOp { - protected: + protected: uint32_t puswl, prepost, up, @@ -150,7 +137,7 @@ class ArmMacroFPAOp : public PredMacroOp */ class ArmMacroFMOp : public PredMacroOp { - protected: + protected: uint32_t punwl, prepost, up, diff --git a/src/arch/arm/intregs.hh b/src/arch/arm/intregs.hh index b5f955c4b..0c2fc5fbb 100644 --- a/src/arch/arm/intregs.hh +++ b/src/arch/arm/intregs.hh @@ -324,6 +324,13 @@ INTREG_FIQ(unsigned index) return IntRegFiqMap[index]; } +static inline IntRegIndex +intRegForceUser(unsigned index) +{ + assert(index < NUM_ARCH_INTREGS); + return (IntRegIndex)(index + NUM_INTREGS); +} + } #endif diff --git a/src/arch/arm/isa.hh b/src/arch/arm/isa.hh index f8359679b..a4a328614 100644 --- a/src/arch/arm/isa.hh +++ b/src/arch/arm/isa.hh @@ -125,8 +125,11 @@ namespace ArmISA assert(reg >= 0); if (reg < NUM_ARCH_INTREGS) { return intRegMap[reg]; + } else if (reg < NUM_INTREGS) { + return reg; } else { - assert(reg < NUM_INTREGS); + reg -= NUM_INTREGS; + assert(reg < NUM_ARCH_INTREGS); return reg; } } diff --git a/src/arch/arm/isa/formats/macromem.isa b/src/arch/arm/isa/formats/macromem.isa index 8c8ba8a1a..9a3185af3 100644 --- a/src/arch/arm/isa/formats/macromem.isa +++ b/src/arch/arm/isa/formats/macromem.isa @@ -180,11 +180,12 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst) %(constructor)s; uint32_t regs = reglist; uint32_t addr = 0; + bool up = machInst.puswl.up; if (!up) addr = (ones << 2) - 4; - if (prepost) + if (machInst.puswl.prepost) addr += 4; // Add 0 to Rn and stick it in ureg0. @@ -198,10 +199,18 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst) reg++; replaceBits(regs, reg, 0); - if (loadop) - microOps[i] = new MicroLdrUop(machInst, reg, INTREG_UREG0, addr); - else - microOps[i] = new MicroStrUop(machInst, reg, INTREG_UREG0, addr); + unsigned regIdx = reg; + if (machInst.puswl.psruser) { + regIdx = intRegForceUser(regIdx); + } + + if (machInst.puswl.loadOp) { + microOps[i] = + new MicroLdrUop(machInst, regIdx, INTREG_UREG0, addr); + } else { + microOps[i] = + new MicroStrUop(machInst, regIdx, INTREG_UREG0, addr); + } if (up) addr += 4; @@ -210,7 +219,7 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst) } StaticInstPtr &lastUop = microOps[numMicroops - 1]; - if (writeback) { + if (machInst.puswl.writeback) { if (up) { lastUop = new MicroAddiUop(machInst, RN, RN, ones * 4); } else {