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
commit7b397925af7fd9864189387179137dd4ac40dfad (patch)
treef8bf8d6d718fe4ff3b61a115bb46474e8862a676
parenta2cb503ba6d504838e0db95335b518266577d6d9 (diff)
downloadgem5-7b397925af7fd9864189387179137dd4ac40dfad.tar.xz
ARM: Decode the RFE instruction.
-rw-r--r--src/arch/arm/isa/decoder/thumb.isa5
-rw-r--r--src/arch/arm/isa/formats/mem.isa30
-rw-r--r--src/arch/arm/isa/formats/uncond.isa38
3 files changed, 67 insertions, 6 deletions
diff --git a/src/arch/arm/isa/decoder/thumb.isa b/src/arch/arm/isa/decoder/thumb.isa
index 231796281..23c33df48 100644
--- a/src/arch/arm/isa/decoder/thumb.isa
+++ b/src/arch/arm/isa/decoder/thumb.isa
@@ -70,10 +70,7 @@
0x1: decode HTOPCODE_10_9 {
0x0: decode HTOPCODE_6 {
0x0: decode HTOPCODE_8_7 {
- 0x0, 0x3: decode HTOPCODE_4 {
- 0x0: WarnUnimpl::srs();
- 0x1: WarnUnimpl::rfe();
- }
+ 0x0, 0x3: Thumb32SrsRfe::thumb32SrsRfe();
// This uses the same encoding as regular ARM.
default: ArmMacroMem::armMacroMem();
}
diff --git a/src/arch/arm/isa/formats/mem.isa b/src/arch/arm/isa/formats/mem.isa
index 41706c48d..5d389458c 100644
--- a/src/arch/arm/isa/formats/mem.isa
+++ b/src/arch/arm/isa/formats/mem.isa
@@ -255,6 +255,36 @@ def format ArmSyncMem() {{
}
}};
+def format Thumb32SrsRfe() {{
+ decode_block = '''
+ {
+ if (bits(machInst, 20) == 1) {
+ const bool add = (bits(machInst, 24, 23) == 0x3);
+ // post == add
+ const bool wb = (bits(machInst, 21) == 1);
+ const IntRegIndex rn =
+ (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
+ if (!add && !wb) {
+ return new %(rfe)s(machInst, rn, RfeOp::DecrementBefore, wb);
+ } else if (add && !wb) {
+ return new %(rfe_u)s(machInst, rn, RfeOp::IncrementAfter, wb);
+ } else if (!add && wb) {
+ return new %(rfe_w)s(machInst, rn, RfeOp::DecrementBefore, wb);
+ } else {
+ return new %(rfe_uw)s(machInst, rn, RfeOp::IncrementAfter, wb);
+ }
+ } else {
+ return new WarnUnimplemented("srs", machInst);
+ }
+ }
+ ''' % {
+ "rfe" : "RFE_" + loadImmClassName(False, False, False, 8),
+ "rfe_u" : "RFE_" + loadImmClassName(True, True, False, 8),
+ "rfe_w" : "RFE_" + loadImmClassName(False, False, True, 8),
+ "rfe_uw" : "RFE_" + loadImmClassName(True, True, True, 8)
+ }
+}};
+
def format Thumb32LdrStrDExTbh() {{
decode_block = '''
{
diff --git a/src/arch/arm/isa/formats/uncond.isa b/src/arch/arm/isa/formats/uncond.isa
index cd041f21b..d305ee996 100644
--- a/src/arch/arm/isa/formats/uncond.isa
+++ b/src/arch/arm/isa/formats/uncond.isa
@@ -165,7 +165,33 @@ def format ArmUnconditional() {{
if (val == 0x4) {
return new WarnUnimplemented("srs", machInst);
} else if (val == 0x1) {
- return new WarnUnimplemented("rfe", machInst);
+ switch (bits(machInst, 24, 21)) {
+ case 0x0:
+ return new %(rfe)s(machInst, rn,
+ RfeOp::DecrementAfter, false);
+ case 0x1:
+ return new %(rfe_w)s(machInst, rn,
+ RfeOp::DecrementAfter, true);
+ case 0x4:
+ return new %(rfe_u)s(machInst, rn,
+ RfeOp::IncrementAfter, false);
+ case 0x5:
+ return new %(rfe_uw)s(machInst, rn,
+ RfeOp::IncrementAfter, true);
+ case 0x8:
+ return new %(rfe_p)s(machInst, rn,
+ RfeOp::DecrementBefore, false);
+ case 0x9:
+ return new %(rfe_pw)s(machInst, rn,
+ RfeOp::DecrementBefore, true);
+ case 0xc:
+ return new %(rfe_pu)s(machInst, rn,
+ RfeOp::IncrementBefore, false);
+ case 0xd:
+ return new %(rfe_puw)s(machInst, rn,
+ RfeOp::IncrementBefore, true);
+ }
+ return new Unknown(machInst);
}
}
break;
@@ -232,6 +258,14 @@ def format ArmUnconditional() {{
"pld_radd" : "PLD_" + loadRegClassName(False, True, False, 1),
"pld_rsub" : "PLD_" + loadRegClassName(False, False, False, 1),
"pldw_radd" : "PLDW_" + loadRegClassName(False, True, False, 1),
- "pldw_rsub" : "PLDW_" + loadRegClassName(False, False, False, 1)
+ "pldw_rsub" : "PLDW_" + loadRegClassName(False, False, False, 1),
+ "rfe" : "RFE_" + loadImmClassName(True, False, False, 8),
+ "rfe_w" : "RFE_" + loadImmClassName(True, False, True, 8),
+ "rfe_u" : "RFE_" + loadImmClassName(True, True, False, 8),
+ "rfe_uw" : "RFE_" + loadImmClassName(True, True, True, 8),
+ "rfe_p" : "RFE_" + loadImmClassName(False, False, False, 8),
+ "rfe_pw" : "RFE_" + loadImmClassName(False, False, True, 8),
+ "rfe_pu" : "RFE_" + loadImmClassName(False, True, False, 8),
+ "rfe_puw" : "RFE_" + loadImmClassName(False, True, True, 8)
};
}};