summaryrefslogtreecommitdiff
path: root/src/arch/arm/predecoder.cc
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
commitb13a79ee717b876e4bc837ba95985abd4d18162f (patch)
treecc11aa8c68e1a22854f2201bf6073e69db88e84e /src/arch/arm/predecoder.cc
parentc98df6f8c2f3a3685fd9210ccaee2fac07e4f604 (diff)
downloadgem5-b13a79ee717b876e4bc837ba95985abd4d18162f.tar.xz
O3: Fix some variable length instruction issues with the O3 CPU and ARM ISA.
Diffstat (limited to 'src/arch/arm/predecoder.cc')
-rw-r--r--src/arch/arm/predecoder.cc15
1 files changed, 11 insertions, 4 deletions
diff --git a/src/arch/arm/predecoder.cc b/src/arch/arm/predecoder.cc
index 456b9e4c4..71d399e35 100644
--- a/src/arch/arm/predecoder.cc
+++ b/src/arch/arm/predecoder.cc
@@ -74,11 +74,15 @@ Predecoder::advanceThumbCond()
void
Predecoder::process()
{
+ // emi is typically ready, with some caveats below...
+ emiReady = true;
+
if (!emi.thumb) {
emi.instBits = data;
emi.sevenAndFour = bits(data, 7) && bits(data, 4);
emi.isMisc = (bits(data, 24, 23) == 0x2 &&
bits(data, 20) == 0);
+ consumeBytes(4);
DPRINTF(Predecoder, "Arm inst: %#x.\n", (uint64_t)emi);
} else {
uint16_t word = (data >> (offset * 8));
@@ -86,7 +90,7 @@ Predecoder::process()
// A 32 bit thumb inst is half collected.
emi.instBits = emi.instBits | word;
bigThumb = false;
- offset += 2;
+ consumeBytes(2);
DPRINTF(Predecoder, "Second half of 32 bit Thumb: %#x.\n",
emi.instBits);
if (itstate.mask) {
@@ -105,7 +109,7 @@ Predecoder::process()
emi.instBits = (data >> 16) | (data << 16);
DPRINTF(Predecoder, "All of 32 bit Thumb: %#x.\n",
emi.instBits);
- offset += 4;
+ consumeBytes(4);
if (itstate.mask) {
emi.itstate = itstate;
advanceThumbCond();
@@ -117,11 +121,13 @@ Predecoder::process()
"First half of 32 bit Thumb.\n");
emi.instBits = (uint32_t)word << 16;
bigThumb = true;
- offset += 2;
+ consumeBytes(2);
+ // emi not ready yet.
+ emiReady = false;
}
} else {
// A 16 bit thumb inst.
- offset += 2;
+ consumeBytes(2);
emi.instBits = word;
// Set the condition code field artificially.
emi.condCode = COND_UC;
@@ -159,6 +165,7 @@ Predecoder::moreBytes(const PCState &pc, Addr fetchPC, MachInst inst)
CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
itstate.top6 = cpsr.it2;
itstate.bottom2 = cpsr.it1;
+ outOfBytes = false;
process();
}