ARM: Make the addressing mode 3 loads/stores use the externally defined instructions.
authorGabe Black <gblack@eecs.umich.edu>
Wed, 2 Jun 2010 17:58:01 +0000 (12:58 -0500)
committerGabe Black <gblack@eecs.umich.edu>
Wed, 2 Jun 2010 17:58:01 +0000 (12:58 -0500)
src/arch/arm/isa/decoder/arm.isa
src/arch/arm/isa/formats/mem.isa

index f5e48f39d53ed9c4ca55b89c94e19aeb80642dd6..1154bd0ba4bd46716e12bbe43b24084afc79d953 100644 (file)
@@ -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 {
index 2935890c2187728f660e6546a6fe07163fdcb879..6482208841563ad3ec0afd55ddd916a2f1482fe9 100644 (file)
@@ -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() {{