ARM: Support forcing load/store multiple to use user registers.
authorGabe Black <gblack@eecs.umich.edu>
Sun, 8 Nov 2009 23:49:03 +0000 (15:49 -0800)
committerGabe Black <gblack@eecs.umich.edu>
Sun, 8 Nov 2009 23:49:03 +0000 (15:49 -0800)
src/arch/arm/insts/macromem.hh
src/arch/arm/intregs.hh
src/arch/arm/isa.hh
src/arch/arm/isa/formats/macromem.isa

index 541c9e3f55431429519036a203dfe0bf528ca208..714b8bb7ed0bd4cb41a006b16f6f33f15bf48612 100644 (file)
@@ -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,
index b5f955c4b6ecc7971580edebc058781c455d2dfe..0c2fc5fbbb5dd6b2681043d38b813e7ee725f384 100644 (file)
@@ -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
index f8359679b2ddd0e94496074147d44421f40bf4eb..a4a328614e66d59501e6055276bb38c9783b5b16 100644 (file)
@@ -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;
             }
         }
index 8c8ba8a1a2df67b719d1b390c91b7b6ee58d55b2..9a3185af332ab31f9d7a8d2ef0fe2531622ff56f 100644 (file)
@@ -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 {