summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/arch/arm/isa/decoder/arm.isa11
-rw-r--r--src/arch/arm/isa/formats/mem.isa158
2 files changed, 107 insertions, 62 deletions
diff --git a/src/arch/arm/isa/decoder/arm.isa b/src/arch/arm/isa/decoder/arm.isa
index f5e48f39d..1154bd0ba 100644
--- a/src/arch/arm/isa/decoder/arm.isa
+++ b/src/arch/arm/isa/decoder/arm.isa
@@ -90,16 +90,7 @@ format DataOp {
0x19: WarnUnimpl::ldrex();
}
}
- format AddrMode3 {
- 0xb: strh_ldrh(store, {{ Mem.uh = Rd; }},
- load, {{ Rd = Mem.uh; }});
- 0xd: ldrd_ldrsb(load, {{ Rde = bits(Mem.ud, 31, 0);
- Rdo = bits(Mem.ud, 63, 32); }},
- load, {{ Rd = Mem.sb; }});
- 0xf: strd_ldrsh(store, {{ Mem.ud = (Rde.ud & mask(32)) |
- (Rdo.ud << 32); }},
- load, {{ Rd = Mem.sh; }});
- }
+ 0xb, 0xd, 0xf: AddrMode3::addrMode3();
}
0: decode IS_MISC {
0: decode OPCODE {
diff --git a/src/arch/arm/isa/formats/mem.isa b/src/arch/arm/isa/formats/mem.isa
index 2935890c2..648220884 100644
--- a/src/arch/arm/isa/formats/mem.isa
+++ b/src/arch/arm/isa/formats/mem.isa
@@ -38,7 +38,8 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
-// Authors: Stephen Hines
+// Authors: Gabe Black
+// Stephen Hines
////////////////////////////////////////////////////////////////////
//
@@ -83,30 +84,15 @@ def template LoadStoreConstructor {{
}
}};
-let {{
- def buildPUBWLCase(p, u, b, w, l):
- return (p << 4) + (u << 3) + (b << 2) + (w << 1) + (l << 0)
-
- def buildMode3Inst(p, u, i, w, type, code, mnem):
- op = ("-", "+")[u]
- offset = ("%s Rm", "%s hilo")[i] % op
- ea_code = "EA = Rn %s;" % ("", offset)[p]
- if p == 0 or w == 1:
- code += "Rn = Rn %s;" % offset
- newSuffix = "_P%dU%dI%dW%d" % (p, u, i, w)
- suffix = ("Reg", "Hilo")[i]
- return LoadStoreBase(mnem, mnem.capitalize() + newSuffix,
- ea_code, code, mem_flags = [], inst_flags = [],
- base_class = 'Memory' + suffix,
- exec_template_base = type.capitalize())
-}};
-
def format AddrMode2(imm) {{
if eval(imm):
imm = True
else:
imm = False
+ def buildPUBWLCase(p, u, b, w, l):
+ return (p << 4) + (u << 3) + (b << 2) + (w << 1) + (l << 0)
+
header_output = decoder_output = exec_output = ""
decode_block = "switch(PUBWL) {\n"
@@ -117,7 +103,7 @@ def format AddrMode2(imm) {{
for b in (0, 1):
for w in (0, 1):
post = (p == 0)
- user = (p == 0 and w == 0)
+ user = (p == 0 and w == 1)
writeback = (p == 0 or w == 1)
add = (u == 1)
if b == 0:
@@ -163,44 +149,112 @@ def format AddrMode2(imm) {{
}'''
}};
-def format AddrMode3(l0Type, l0Code, l1Type, l1Code) {{
- l0Code = ArmGenericCodeSubs(l0Code);
- l1Code = ArmGenericCodeSubs(l1Code);
+def format AddrMode3() {{
+ decode = '''
+ {
+ const uint32_t op1 = bits(machInst, 24, 20);
+ const uint32_t op2 = bits(machInst, 6, 5);
+ const uint32_t puiw = bits(machInst, 24, 21);
+ const uint32_t imm = IMMED_HI_11_8 << 4 | IMMED_LO_3_0;
+ switch (op2) {
+ case 0x1:
+ if (op1 & 0x1) {
+ %(ldrh)s
+ } else {
+ %(strh)s
+ }
+ case 0x2:
+ if (op1 & 0x1) {
+ %(ldrsb)s
+ } else {
+ %(ldrd)s
+ }
+ case 0x3:
+ if (op1 & 0x1) {
+ %(ldrsh)s
+ } else {
+ %(strd)s
+ }
+ default:
+ return new Unknown(machInst);
+ }
+ }
+ '''
- header_output = decoder_output = exec_output = ""
- decode_block = "switch(PUBWL) {\n"
- (l0Mnem, l1Mnem) = name.split("_");
+ def decodePuiwCase(load, d, p, u, i, w, size=4, sign=False):
+ post = (p == 0)
+ user = (p == 0 and w == 1)
+ writeback = (p == 0 or w == 1)
+ add = (u == 1)
+ caseVal = (p << 3) + (u << 2) + (i << 1) + (w << 0)
+ decode = '''
+ case %#x:
+ return new '''% caseVal
+ if add:
+ addStr = "true"
+ else:
+ addStr = "false"
+ if i:
+ if load:
+ if d:
+ className = loadDoubleImmClassName(post, add, writeback)
+ else:
+ className = loadImmClassName(post, add, writeback, \
+ size=size, sign=sign, \
+ user=user)
+ else:
+ if d:
+ className = storeDoubleImmClassName(post, add, writeback)
+ else:
+ className = storeImmClassName(post, add, writeback, \
+ size=size, sign=sign, \
+ user=user)
+ decode += ("%s(machInst, RT, RN, %s, imm);\n" % \
+ (className, addStr))
+ else:
+ if load:
+ if d:
+ className = loadDoubleRegClassName(post, add, writeback)
+ else:
+ className = loadRegClassName(post, add, writeback, \
+ size=size, sign=sign, \
+ user=user)
+ else:
+ if d:
+ className = storeDoubleRegClassName(post, add, writeback)
+ else:
+ className = storeRegClassName(post, add, writeback, \
+ size=size, sign=sign, \
+ user=user)
+ decode += ("%s(machInst, RT, RN, %s, 0, LSL, RM);\n" % \
+ (className, addStr))
+ return decode
- # Loop over all the values of p, u, i, w and l and build instructions and
- # a decode block for them.
- for (l, type, code, mnem) in ((0, l0Type, l0Code, l0Mnem),
- (1, l1Type, l1Code, l1Mnem)):
+ def decodePuiw(load, d, size=4, sign=False):
+ global decodePuiwCase
+ decode = "switch (puiw) {\n"
for p in (0, 1):
- wset = (0, 1)
- if (p == 0):
- wset = (0,)
for u in (0, 1):
for i in (0, 1):
- for w in wset:
- (new_header_output,
- new_decoder_output,
- new_decode_block,
- new_exec_output) = buildMode3Inst(p, u, i, w,
- type, code, mnem)
- header_output += new_header_output
- decoder_output += new_decoder_output
- exec_output += new_exec_output
- decode_block += '''
- case %#x:
- {%s}
- break;
- ''' % (buildPUBWLCase(p,u,i,w,l), new_decode_block)
+ for w in (0, 1):
+ decode += decodePuiwCase(load, d, p, u, i, w,
+ size, sign)
+ decode += '''
+ default:
+ return new Unknown(machInst);
+ }
+ '''
+ return decode
- decode_block += '''
- default:
- return new Unknown(machInst);
- break;
- }'''
+ subs = {
+ "ldrh" : decodePuiw(True, False, size=2),
+ "strh" : decodePuiw(False, False, size=2),
+ "ldrsb" : decodePuiw(True, False, size=1, sign=True),
+ "ldrd" : decodePuiw(True, True),
+ "ldrsh" : decodePuiw(True, False, size=2, sign=True),
+ "strd" : decodePuiw(False, True)
+ }
+ decode_block = decode % subs
}};
def format Thumb32LoadWord() {{