summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2010-06-02 12:58:15 -0500
committerGabe Black <gblack@eecs.umich.edu>2010-06-02 12:58:15 -0500
commitc919ab5b4fa1d9f8721552dd2831c71c953c914f (patch)
treeda967d1b20e5439ab44c7b71d0bb944f3e8e3beb
parent92bdf57be45bd366cdf1a26630d761f58eaacbdd (diff)
downloadgem5-c919ab5b4fa1d9f8721552dd2831c71c953c914f.tar.xz
ARM: Fix double precision load/store multiple decrement.
When decrementing, the higher addressed half of a double word is at a 4 byte smaller displacement.
-rw-r--r--src/arch/arm/insts/macromem.cc13
1 files changed, 7 insertions, 6 deletions
diff --git a/src/arch/arm/insts/macromem.cc b/src/arch/arm/insts/macromem.cc
index 01ec3e1d8..e47f4c21c 100644
--- a/src/arch/arm/insts/macromem.cc
+++ b/src/arch/arm/insts/macromem.cc
@@ -161,7 +161,7 @@ MacroVFPMemOp::MacroVFPMemOp(const char *mnem, ExtMachInst machInst,
numMicroops = count * (single ? 1 : 2) + (writeback ? 1 : 0);
microOps = new StaticInstPtr[numMicroops];
- uint32_t addr = 0;
+ int64_t addr = 0;
if (!up)
addr = 4 * offset;
@@ -172,21 +172,22 @@ MacroVFPMemOp::MacroVFPMemOp(const char *mnem, ExtMachInst machInst,
microOps[i++] = new MicroLdrFpUop(machInst, vd++, rn,
tempUp, addr);
if (!single)
- microOps[i++] = new MicroLdrFpUop(machInst, vd++, rn,
- tempUp, addr + 4);
+ microOps[i++] = new MicroLdrFpUop(machInst, vd++, rn, tempUp,
+ addr + (up ? 4 : -4));
} else {
microOps[i++] = new MicroStrFpUop(machInst, vd++, rn,
tempUp, addr);
if (!single)
- microOps[i++] = new MicroStrFpUop(machInst, vd++, rn,
- tempUp, addr + 4);
+ microOps[i++] = new MicroStrFpUop(machInst, vd++, rn, tempUp,
+ addr + (up ? 4 : -4));
}
if (!tempUp) {
addr -= (single ? 4 : 8);
// The microops don't handle negative displacement, so turn if we
// hit zero, flip polarity and start adding.
- if (addr == 0) {
+ if (addr <= 0) {
tempUp = true;
+ addr = -addr;
}
} else {
addr += (single ? 4 : 8);