summaryrefslogtreecommitdiff
path: root/src/arch/arm/isa
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2010-06-02 12:58:09 -0500
committerGabe Black <gblack@eecs.umich.edu>2010-06-02 12:58:09 -0500
commit7a9dcdf99f4d33fc24f9b7a41155f4cc7cd835bd (patch)
tree23ff7894375e308a77c0c48a97f053118f8b81c1 /src/arch/arm/isa
parenta483d44d9fb75a3b9fb5b497b59961532674badb (diff)
downloadgem5-7a9dcdf99f4d33fc24f9b7a41155f4cc7cd835bd.tar.xz
ARM: Decode the load halfword, memory hints instructions for 32 bit Thumb.
Diffstat (limited to 'src/arch/arm/isa')
-rw-r--r--src/arch/arm/isa/decoder/thumb.isa2
-rw-r--r--src/arch/arm/isa/formats/mem.isa174
2 files changed, 175 insertions, 1 deletions
diff --git a/src/arch/arm/isa/decoder/thumb.isa b/src/arch/arm/isa/decoder/thumb.isa
index e8e2d5919..ab431303c 100644
--- a/src/arch/arm/isa/decoder/thumb.isa
+++ b/src/arch/arm/isa/decoder/thumb.isa
@@ -140,7 +140,7 @@
}
0x1: decode HTOPCODE_6_5 {
0x0: WarnUnimpl::Load_byte_memory_hints();
- 0x1: WarnUnimpl::Load_halfword_memory_hints();
+ 0x1: LoadHalfwordMemoryHints::loadHalfwordMemoryHints();
0x2: Thumb32LoadWord::thumb32LoadWord();
0x3: WarnUnimpl::undefined();
}
diff --git a/src/arch/arm/isa/formats/mem.isa b/src/arch/arm/isa/formats/mem.isa
index 6b36e39fb..6b511362f 100644
--- a/src/arch/arm/isa/formats/mem.isa
+++ b/src/arch/arm/isa/formats/mem.isa
@@ -468,6 +468,180 @@ def format Thumb32StoreSingle() {{
decode_block = decode % classNames
}};
+def format LoadHalfwordMemoryHints() {{
+ decode = '''
+ {
+ const uint32_t op1 = bits(machInst, 24, 23);
+ const uint32_t op2 = bits(machInst, 11, 6);
+ const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
+ const IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
+ const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
+ const uint32_t imm12 = bits(machInst, 11, 0);
+ const uint32_t imm8 = bits(machInst, 7, 0);
+ bool pldw = bits(machInst, 21);
+ const uint32_t imm2 = bits(machInst, 5, 4);
+ if (rn == 0xf) {
+ if (rt == 0xf) {
+ if (bits(op1, 1) == 1) {
+ // Unallocated memory hint
+ return new NopInst(machInst);
+ } else {
+ return new Unknown(machInst);
+ }
+ } else {
+ if (bits(op1, 1) == 1) {
+ if (bits(machInst, 23)) {
+ return new %(ldrsh_lit_u)s(machInst, rt, INTREG_PC,
+ true, imm12);
+ } else {
+ return new %(ldrsh_lit)s(machInst, rt, INTREG_PC,
+ false, imm12);
+ }
+ } else {
+ if (bits(machInst, 23)) {
+ return new %(ldrh_lit_u)s(machInst, rt, INTREG_PC,
+ true, imm12);
+ } else {
+ return new %(ldrh_lit)s(machInst, rt, INTREG_PC,
+ false, imm12);
+ }
+ }
+ }
+ } else if (rt == 0xf) {
+ switch (op1) {
+ case 0x0:
+ if (op2 == 0x0) {
+ if (pldw) {
+ return new %(pldw_radd)s(machInst, INTREG_ZERO,
+ rn, true, imm2, LSL, rm);
+ } else {
+ return new %(pld_radd)s(machInst, INTREG_ZERO,
+ rn, true, imm2, LSL, rm);
+ }
+ } else if (bits(op2, 5, 2) == 0xc) {
+ if (pldw) {
+ return new %(pldw_isub)s(machInst, INTREG_ZERO,
+ rn, false, imm8);
+ } else {
+ return new %(pld_isub)s(machInst, INTREG_ZERO,
+ rn, false, imm8);
+ }
+ }
+ break;
+ case 0x1:
+ if (pldw) {
+ return new %(pldw_iadd)s(machInst, INTREG_ZERO,
+ rn, true, imm12);
+ } else {
+ return new %(pld_iadd)s(machInst, INTREG_ZERO,
+ rn, true, imm12);
+ }
+ case 0x2:
+ if (op2 == 0x0 || bits(op2, 5, 2) == 0xc) {
+ // Unallocated memory hint
+ return new NopInst(machInst);
+ }
+ break;
+ case 0x3:
+ return new NopInst(machInst);
+ }
+ return new Unknown(machInst);
+ } else {
+ switch (op1) {
+ case 0x0:
+ if (op2 == 0) {
+ return new %(ldrh_radd)s(machInst, rt, rn, true,
+ imm2, LSL, rm);
+ } else if (bits(op2, 5, 2) == 0xe) {
+ return new %(ldrht)s(machInst, rt, rn, true, imm8);
+ } else if ((op2 & 0x24) == 0x24 || bits(op2, 5, 2) == 0xc) {
+ const uint32_t puw = bits(machInst, 10, 8);
+ switch (puw) {
+ case 0x1:
+ return new %(ldrh_iw)s(machInst, rt,
+ rn, false, imm8);
+ case 0x3:
+ return new %(ldrh_iuw)s(machInst, rt,
+ rn, true, imm8);
+ case 0x4:
+ return new %(ldrh_ip)s(machInst, rt,
+ rn, false, imm8);
+ case 0x5:
+ return new %(ldrh_ipw)s(machInst, rt,
+ rn, false, imm8);
+ case 0x7:
+ return new %(ldrh_ipuw)s(machInst, rt,
+ rn, true, imm8);
+ }
+ }
+ break;
+ case 0x1:
+ return new %(ldrh_iadd)s(machInst, rt, rn, true, imm12);
+ case 0x2:
+ if (op2 == 0) {
+ return new %(ldrsh_radd)s(machInst, rt, rn, true,
+ imm2, LSL, rm);
+ } else if (bits(op2, 5, 2) == 0xe) {
+ return new %(ldrsht)s(machInst, rt, rn, true, imm8);
+ } else if ((op2 & 0x24) == 0x24 || bits(op2, 5, 2) == 0xc) {
+ const uint32_t puw = bits(machInst, 10, 8);
+ switch (puw) {
+ case 0x1:
+ return new %(ldrsh_iw)s(machInst, rt,
+ rn, false, imm8);
+ case 0x3:
+ return new %(ldrsh_iuw)s(machInst, rt,
+ rn, true, imm8);
+ case 0x4:
+ return new %(ldrsh_ip)s(machInst, rt,
+ rn, false, imm8);
+ case 0x5:
+ return new %(ldrsh_ipw)s(machInst, rt,
+ rn, false, imm8);
+ case 0x7:
+ return new %(ldrsh_ipuw)s(machInst, rt,
+ rn, true, imm8);
+ }
+ }
+ break;
+ case 0x3:
+ return new %(ldrsh_iadd)s(machInst, rt, rn, true, imm12);
+ }
+ return new Unknown(machInst);
+ }
+ }
+ '''
+ substDict = {
+ "ldrsh_lit_u" : loadImmClassName(False, True, False, 2, True),
+ "ldrsh_lit" : loadImmClassName(False, False, False, 2, True),
+ "ldrh_lit_u" : loadImmClassName(False, True, False, 2),
+ "ldrh_lit" : loadImmClassName(False, False, False, 2),
+ "ldrsh_radd" : loadRegClassName(False, True, False, 2, True),
+ "ldrh_radd" : loadRegClassName(False, True, False, 2),
+ "ldrsh_iw" : loadImmClassName(True, False, True, 2, True),
+ "ldrsh_iuw" : loadImmClassName(True, True, True, 2, True),
+ "ldrsh_ip" : loadImmClassName(False, False, False, 2, True),
+ "ldrsh_ipw" : loadImmClassName(False, False, True, 2, True),
+ "ldrsh_ipuw" : loadImmClassName(False, True, True, 2, True),
+ "ldrsh_iadd" : loadImmClassName(False, True, False, 2, True),
+ "ldrh_iw" : loadImmClassName(True, False, True, 2),
+ "ldrh_iuw" : loadImmClassName(True, True, True, 2),
+ "ldrh_ip" : loadImmClassName(False, False, False, 2),
+ "ldrh_ipw" : loadImmClassName(False, False, True, 2),
+ "ldrh_ipuw" : loadImmClassName(False, True, True, 2),
+ "ldrh_iadd" : loadImmClassName(False, True, False, 2),
+ "ldrht" : loadImmClassName(False, True, False, 2, user=True),
+ "ldrsht" : loadImmClassName(False, True, False, 2, True, user=True),
+ "pldw_radd" : "PLDW_" + loadRegClassName(False, True, False, 1),
+ "pld_radd" : "PLD_" + loadRegClassName(False, True, False, 1),
+ "pldw_isub" : "PLDW_" + loadImmClassName(False, False, False, 1),
+ "pld_isub" : "PLD_" + loadImmClassName(False, False, False, 1),
+ "pldw_iadd" : "PLDW_" + loadImmClassName(False, True, False, 1),
+ "pld_iadd" : "PLD_" + loadImmClassName(False, True, False, 1)
+ }
+ decode_block = decode % substDict
+}};
+
def format Thumb16MemReg() {{
decode = '''
{