summaryrefslogtreecommitdiff
path: root/src/arch/arm/isa/insts
diff options
context:
space:
mode:
authorMatt Horsnell <Matt.Horsnell@arm.com>2011-01-18 16:30:05 -0600
committerMatt Horsnell <Matt.Horsnell@arm.com>2011-01-18 16:30:05 -0600
commit77853b9f529947c3a9db78ef3458289f387289ce (patch)
treea65c169c3ab2e65a63e2f1b6d71d52a766692164 /src/arch/arm/isa/insts
parentb13a79ee717b876e4bc837ba95985abd4d18162f (diff)
downloadgem5-77853b9f529947c3a9db78ef3458289f387289ce.tar.xz
O3: Fix itstate prediction and recovery.
Any change of control flow now resets the itstate to 0 mask and 0 condition, except where the control flow alteration write into the cpsr register. These case, for example return from an iterrupt, require the predecoder to recover the itstate. As there is a window of opportunity between the return from an interrupt changing the control flow at the head of the pipe and the commit of the update to the CPSR, the predecoder needs to be able to grab the ITstate early. This is now handled by setting the forcedItState inside a PCstate for the control flow altering instruction. That instruction will have the correct mask/cond, but will not have a valid itstate until advancePC is called (note this happens to advance the execution). When the new PCstate is copy constructed it gets the itstate cond/mask, and upon advancing the PC the itstate becomes valid. Subsequent advancing invalidates the state and zeroes the cond/mask. This is handled in isolation for the ARM ISA and should have no impact on other ISAs. Refer arch/arm/types.hh and arch/arm/predecoder.cc for the details.
Diffstat (limited to 'src/arch/arm/isa/insts')
-rw-r--r--src/arch/arm/isa/insts/data.isa2
-rw-r--r--src/arch/arm/isa/insts/ldr.isa6
-rw-r--r--src/arch/arm/isa/insts/macromem.isa2
-rw-r--r--src/arch/arm/isa/insts/misc.isa4
4 files changed, 12 insertions, 2 deletions
diff --git a/src/arch/arm/isa/insts/data.isa b/src/arch/arm/isa/insts/data.isa
index 26b6bfc92..ac5b12a95 100644
--- a/src/arch/arm/isa/insts/data.isa
+++ b/src/arch/arm/isa/insts/data.isa
@@ -241,6 +241,8 @@ let {{
CondCodes = CondCodesMask & newCpsr;
NextThumb = ((CPSR)newCpsr).t;
NextJazelle = ((CPSR)newCpsr).j;
+ ForcedItState = ((((CPSR)newCpsr).it2 << 2) & 0xFC)
+ | (((CPSR)newCpsr).it1 & 0x3);
'''
buildImmDataInst(mnem + 's', code, flagType,
suffix = "ImmPclr", buildCc = False,
diff --git a/src/arch/arm/isa/insts/ldr.isa b/src/arch/arm/isa/insts/ldr.isa
index 21601f7d3..c60a91a50 100644
--- a/src/arch/arm/isa/insts/ldr.isa
+++ b/src/arch/arm/isa/insts/ldr.isa
@@ -107,13 +107,15 @@ let {{
SCTLR sctlr = Sctlr;
// Use the version of NPC that gets set before NextThumb
pNPC = cSwap<uint32_t>(Mem.ud, cpsr.e);
+ uint32_t tempSpsr = cSwap<uint32_t>(Mem.ud >> 32, cpsr.e);
uint32_t newCpsr =
- cpsrWriteByInstr(cpsr | CondCodes,
- cSwap<uint32_t>(Mem.ud >> 32, cpsr.e),
+ cpsrWriteByInstr(cpsr | CondCodes, tempSpsr,
0xF, true, sctlr.nmfi);
Cpsr = ~CondCodesMask & newCpsr;
NextThumb = ((CPSR)newCpsr).t;
NextJazelle = ((CPSR)newCpsr).j;
+ ForcedItState = ((((CPSR)tempSpsr).it2 << 2) & 0xFC)
+ | (((CPSR)tempSpsr).it1 & 0x3);
CondCodes = CondCodesMask & newCpsr;
'''
self.codeBlobs["memacc_code"] = accCode
diff --git a/src/arch/arm/isa/insts/macromem.isa b/src/arch/arm/isa/insts/macromem.isa
index 6bf789efd..33d57a60b 100644
--- a/src/arch/arm/isa/insts/macromem.isa
+++ b/src/arch/arm/isa/insts/macromem.isa
@@ -94,6 +94,8 @@ let {{
Cpsr = ~CondCodesMask & newCpsr;
CondCodes = CondCodesMask & newCpsr;
IWNPC = cSwap(Mem.uw, cpsr.e) | ((Spsr & 0x20) ? 1 : 0);
+ ForcedItState = ((((CPSR)Spsr).it2 << 2) & 0xFC)
+ | (((CPSR)Spsr).it1 & 0x3);
'''
microLdrRetUopIop = InstObjParams('ldr_ret_uop', 'MicroLdrRetUop',
'MicroMemOp',
diff --git a/src/arch/arm/isa/insts/misc.isa b/src/arch/arm/isa/insts/misc.isa
index 68320d3c5..dc7a71c0f 100644
--- a/src/arch/arm/isa/insts/misc.isa
+++ b/src/arch/arm/isa/insts/misc.isa
@@ -85,6 +85,8 @@ let {{
Cpsr = ~CondCodesMask & newCpsr;
NextThumb = ((CPSR)newCpsr).t;
NextJazelle = ((CPSR)newCpsr).j;
+ ForcedItState = ((((CPSR)Op1).it2 << 2) & 0xFC)
+ | (((CPSR)Op1).it1 & 0x3);
CondCodes = CondCodesMask & newCpsr;
'''
msrCpsrRegIop = InstObjParams("msr", "MsrCpsrReg", "MsrRegOp",
@@ -111,6 +113,8 @@ let {{
Cpsr = ~CondCodesMask & newCpsr;
NextThumb = ((CPSR)newCpsr).t;
NextJazelle = ((CPSR)newCpsr).j;
+ ForcedItState = ((((CPSR)imm).it2 << 2) & 0xFC)
+ | (((CPSR)imm).it1 & 0x3);
CondCodes = CondCodesMask & newCpsr;
'''
msrCpsrImmIop = InstObjParams("msr", "MsrCpsrImm", "MsrImmOp",