summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2009-11-15 00:23:14 -0800
committerGabe Black <gblack@eecs.umich.edu>2009-11-15 00:23:14 -0800
commit9127ee5ac8913eacfc62967bd4b275a1845d8a9b (patch)
treef41997bae46008a68e23a10ab490699d2cf9193c
parent903fb8c73df6feec125204fb4e636468f17b5eec (diff)
downloadgem5-9127ee5ac8913eacfc62967bd4b275a1845d8a9b.tar.xz
ARM: Make the exception return form of ldm restore CPSR.
-rw-r--r--src/arch/arm/isa/formats/macromem.isa13
1 files changed, 10 insertions, 3 deletions
diff --git a/src/arch/arm/isa/formats/macromem.isa b/src/arch/arm/isa/formats/macromem.isa
index ad27b5a56..068b48199 100644
--- a/src/arch/arm/isa/formats/macromem.isa
+++ b/src/arch/arm/isa/formats/macromem.isa
@@ -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);