diff options
Diffstat (limited to 'src/arch/arm/isa/formats')
-rw-r--r-- | src/arch/arm/isa/formats/mem.isa | 158 |
1 files changed, 106 insertions, 52 deletions
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() {{ |