summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2010-06-02 12:58:10 -0500
committerGabe Black <gblack@eecs.umich.edu>2010-06-02 12:58:10 -0500
commit3caa75d53aa9c04b238aeae281983d8b73754e98 (patch)
tree6b1b240a3127872b86262db4342d32d4be0dfc85
parent36eeee013339141994ef3091c4b3726d08395f04 (diff)
downloadgem5-3caa75d53aa9c04b238aeae281983d8b73754e98.tar.xz
ARM: Squash the low order bits of the PC when performing a regular branch.
-rw-r--r--src/arch/arm/insts/static_inst.hh8
-rw-r--r--src/arch/arm/isa/operands.isa7
2 files changed, 11 insertions, 4 deletions
diff --git a/src/arch/arm/insts/static_inst.hh b/src/arch/arm/insts/static_inst.hh
index 23c04306d..c0d313680 100644
--- a/src/arch/arm/insts/static_inst.hh
+++ b/src/arch/arm/insts/static_inst.hh
@@ -221,7 +221,13 @@ class ArmStaticInst : public StaticInst
static void
setNextPC(XC *xc, Addr val)
{
- xc->setNextPC((xc->readNextPC() & PcModeMask) |
+ Addr npc = xc->readNextPC();
+ if (npc & (ULL(1) << PcTBitShift)) {
+ val &= ~mask(1);
+ } else {
+ val &= ~mask(2);
+ }
+ xc->setNextPC((npc & PcModeMask) |
(val & ~PcModeMask));
}
diff --git a/src/arch/arm/isa/operands.isa b/src/arch/arm/isa/operands.isa
index 1a98a9087..a8b0b197a 100644
--- a/src/arch/arm/isa/operands.isa
+++ b/src/arch/arm/isa/operands.isa
@@ -70,10 +70,11 @@ let {{
'''
maybeAIWPCWrite = '''
if (%(reg_idx)s == PCReg) {
- if (xc->readPC() & (ULL(1) << PcTBitShift)) {
- setIWNextPC(xc, %(final_val)s);
- } else {
+ bool thumb = THUMB;
+ if (thumb) {
setNextPC(xc, %(final_val)s);
+ } else {
+ setIWNextPC(xc, %(final_val)s);
}
} else {
xc->%(func)s(this, %(op_idx)s, %(final_val)s);