ARM: Make the exception return form of ldm restore CPSR.
authorGabe Black <gblack@eecs.umich.edu>
Sun, 15 Nov 2009 08:23:14 +0000 (00:23 -0800)
committerGabe Black <gblack@eecs.umich.edu>
Sun, 15 Nov 2009 08:23:14 +0000 (00:23 -0800)
src/arch/arm/isa/formats/macromem.isa

index ad27b5a5636acc3218fb8abc42f7e153941b7ef0..068b48199dbf48f738c211721bab416ac162f381 100644 (file)
@@ -210,6 +210,7 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
     microOps[0] = new MicroAddiUop(machInst, INTREG_UREG0, RN, 0);
 
     unsigned reg = 0;
+    bool forceUser = machInst.puswl.psruser;
     for (int i = 1; i < ones + 1; i++) {
         // Find the next register.
         while (!bits(regs, reg))
@@ -217,13 +218,19 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
         replaceBits(regs, reg, 0);
 
         unsigned regIdx = reg;
-        if (machInst.puswl.psruser) {
+        if (forceUser) {
             regIdx = intRegForceUser(regIdx);
         }
 
         if (machInst.puswl.loadOp) {
-            microOps[i] =
-                new MicroLdrUop(machInst, regIdx, INTREG_UREG0, addr);
+            if (reg == INTREG_PC && forceUser) {
+                // This must be the exception return form of ldm.
+                microOps[i] =
+                    new MicroLdrRetUop(machInst, regIdx, INTREG_UREG0, addr);
+            } else {
+                microOps[i] =
+                    new MicroLdrUop(machInst, regIdx, INTREG_UREG0, addr);
+            }
         } else {
             microOps[i] =
                 new MicroStrUop(machInst, regIdx, INTREG_UREG0, addr);