summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2010-06-02 12:58:01 -0500
committerGabe Black <gblack@eecs.umich.edu>2010-06-02 12:58:01 -0500
commitfde3c8f41d08500e13d94227b52a642111043414 (patch)
tree7ee9529c31fc8fbf379f7546fb60d52a2f7f8ea5
parent3b93015304382f669a74ba21d65588a1d2235468 (diff)
downloadgem5-fde3c8f41d08500e13d94227b52a642111043414.tar.xz
ARM: Make 32 bit thumb use the new, external load instructions.
-rw-r--r--src/arch/arm/isa/bitfields.isa2
-rw-r--r--src/arch/arm/isa/decoder/thumb.isa53
-rw-r--r--src/arch/arm/isa/formats/mem.isa65
-rw-r--r--src/arch/arm/types.hh1
4 files changed, 69 insertions, 52 deletions
diff --git a/src/arch/arm/isa/bitfields.isa b/src/arch/arm/isa/bitfields.isa
index 5d191b6df..29f3e746e 100644
--- a/src/arch/arm/isa/bitfields.isa
+++ b/src/arch/arm/isa/bitfields.isa
@@ -78,6 +78,7 @@ def bitfield COND_CODE condCode;
def bitfield S_FIELD sField;
def bitfield RN rn;
def bitfield RD rd;
+def bitfield RT rt;
def bitfield SHIFT_SIZE shiftSize;
def bitfield SHIFT shift;
def bitfield RM rm;
@@ -96,6 +97,7 @@ def bitfield PUBWL pubwl;
def bitfield IMM imm;
def bitfield IMMED_11_0 immed11_0;
+def bitfield IMMED_7_0 immed7_0;
def bitfield IMMED_HI_11_8 immedHi11_8;
def bitfield IMMED_LO_3_0 immedLo3_0;
diff --git a/src/arch/arm/isa/decoder/thumb.isa b/src/arch/arm/isa/decoder/thumb.isa
index 7aba61b57..ba29d9fec 100644
--- a/src/arch/arm/isa/decoder/thumb.isa
+++ b/src/arch/arm/isa/decoder/thumb.isa
@@ -419,58 +419,7 @@
0x1: decode HTOPCODE_6_5 {
0x0: WarnUnimpl::Load_byte_memory_hints();
0x1: WarnUnimpl::Load_halfword_memory_hints();
- 0x2: decode HTOPCODE_8 {
- 0x0: decode HTRN {
- 0xf: ArmLoadMemory::ldr1(
- {{ Rd.uw = Mem.uw }},
- {{ EA = roundUp(PC, 4) +
- (UP ? IMMED_11_0 : -IMMED_11_0); }});
- default: decode HTOPCODE_7 {
- 0x0: decode LTOPCODE_11_8 {
- 0x0: decode LTOPCODE_7_6 {
- 0x0: ArmLoadMemory::ldr2(
- {{ Rd = Mem; }},
- {{ EA = Rn +
- (Rm <<
- bits(machInst, 5, 4)); }}
- );
- }
- 0x9: ArmLoadMemory::ldr3(
- {{ Rd = Mem;
- Rn = Rn - IMMED_11_0; }},
- {{ EA = Rn; }}
- );
- 0xb: ArmLoadMemory::ldr4(
- {{ Rd = Mem;
- Rn = Rn + IMMED_11_0; }},
- {{ EA = Rn; }}
- );
- 0xc: ArmLoadMemory::ldr5(
- {{ Rd = Mem; }},
- {{ EA = Rn - IMMED_11_0; }}
- );
- 0xd: ArmLoadMemory::ldr6(
- {{ Rd = Mem;
- Rn = Rn - IMMED_11_0; }},
- {{ EA = Rn - IMMED_11_0; }}
- );
- 0xf: ArmLoadMemory::ldr7(
- {{ Rd = Mem;
- Rn = Rn + IMMED_11_0; }},
- {{ EA = Rn + IMMED_11_0; }}
- );
- 0xe: ArmLoadMemory::ldrt(
- {{ Rd = Mem; }},
- {{ EA = Rn + IMMED_11_0; }}
- ); // This should force user level access
- }
- 0x1: ArmLoadMemory::ldr8(
- {{ Rd = Mem; }},
- {{ EA = Rn + IMMED_11_0; }}
- );
- }
- }
- }
+ 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 c25006d57..f72d344aa 100644
--- a/src/arch/arm/isa/formats/mem.isa
+++ b/src/arch/arm/isa/formats/mem.isa
@@ -203,6 +203,71 @@ def format AddrMode3(l0Type, l0Code, l1Type, l1Code) {{
}'''
}};
+def format Thumb32LoadWord() {{
+ decode = '''
+ {
+ uint32_t op1 = bits(machInst, 24, 23);
+ if (bits(op1, 1) == 0) {
+ uint32_t op2 = bits(machInst, 11, 6);
+ if (HTRN == 0xF) {
+ if (UP) {
+ return new %(literal_u)s(machInst, RT, INTREG_PC,
+ true, IMMED_11_0);
+ } else {
+ return new %(literal)s(machInst, RT, INTREG_PC,
+ false, IMMED_11_0);
+ }
+ } else if (op1 == 0x1) {
+ return new %(imm_pu)s(machInst, RT, RN, true, IMMED_11_0);
+ } else if (op2 == 0) {
+ return new %(register)s(machInst, RT, RN, UP,
+ bits(machInst, 5, 4), LSL, RM);
+ } else if ((op2 & 0x3c) == 0x38) {
+ return new %(ldrt)s(machInst, RT, RN, true, IMMED_7_0);
+ } else if ((op2 & 0x3c) == 0x30 || //P
+ (op2 & 0x24) == 0x24) { //W
+ uint32_t puw = bits(machInst, 10, 8);
+ uint32_t imm = IMMED_7_0;
+ switch (puw) {
+ case 0:
+ case 2:
+ // If we're here, either P or W must have been set.
+ panic("Neither P or W set, but that "
+ "shouldn't be possible.\\n");
+ case 1:
+ return new %(imm_w)s(machInst, RT, RN, false, imm);
+ case 3:
+ return new %(imm_uw)s(machInst, RT, RN, true, imm);
+ case 4:
+ return new %(imm_p)s(machInst, RT, RN, false, imm);
+ case 5:
+ return new %(imm_pw)s(machInst, RT, RN, false, imm);
+ case 6:
+ return new %(imm_pu)s(machInst, RT, RN, true, imm);
+ case 7:
+ return new %(imm_puw)s(machInst, RT, RN, true, imm);
+ }
+ }
+ } else {
+ return new Unknown(machInst);
+ }
+ }
+ '''
+ classNames = {
+ "literal_u" : loadImmClassName(False, True, False),
+ "literal" : loadImmClassName(False, False, False),
+ "register" : loadRegClassName(False, True, False),
+ "ldrt" : loadImmClassName(False, True, False, user=True),
+ "imm_w" : loadImmClassName(True, False, True),
+ "imm_uw" : loadImmClassName(True, True, True),
+ "imm_p" : loadImmClassName(False, False, False),
+ "imm_pw" : loadImmClassName(False, False, True),
+ "imm_pu" : loadImmClassName(False, True, False),
+ "imm_puw" : loadImmClassName(False, True, True)
+ }
+ decode_block = decode % classNames
+}};
+
def format ArmLoadMemory(memacc_code, ea_code = {{ EA = Rn + disp; }},
mem_flags = [], inst_flags = []) {{
ea_code = ArmGenericCodeSubs(ea_code)
diff --git a/src/arch/arm/types.hh b/src/arch/arm/types.hh
index 9bdf69305..62547d53c 100644
--- a/src/arch/arm/types.hh
+++ b/src/arch/arm/types.hh
@@ -86,6 +86,7 @@ namespace ArmISA
Bitfield<20> sField;
Bitfield<19, 16> rn;
Bitfield<15, 12> rd;
+ Bitfield<15, 12> rt;
Bitfield<11, 7> shiftSize;
Bitfield<6, 5> shift;
Bitfield<3, 0> rm;