ARM: Move the memory microops out of the decoder and into the ISA desc.
authorGabe Black <gblack@eecs.umich.edu>
Thu, 9 Jul 2009 06:02:19 +0000 (23:02 -0700)
committerGabe Black <gblack@eecs.umich.edu>
Thu, 9 Jul 2009 06:02:19 +0000 (23:02 -0700)
src/arch/arm/insts/macromem.hh
src/arch/arm/isa/decoder.isa
src/arch/arm/isa/formats/macromem.isa
src/arch/arm/isa/formats/util.isa

index c215cdeab9ba6f6397e2665da00b5d92ed81fe55..541c9e3f55431429519036a203dfe0bf528ca208 100644 (file)
@@ -63,6 +63,22 @@ class MicroIntOp : public PredOp
     }
 };
 
+/**
+ * Memory microops which use IntReg + Imm addressing
+ */
+class MicroMemOp : public MicroIntOp
+{
+  protected:
+    unsigned memAccessFlags;
+
+    MicroMemOp(const char *mnem, ExtMachInst machInst, OpClass __opClass,
+               RegIndex _ura, RegIndex _urb, uint8_t _imm)
+            : MicroIntOp(mnem, machInst, __opClass, _ura, _urb, _imm),
+              memAccessFlags(0)
+    {
+    }
+};
+
 /**
  * Arm Macro Memory operations like LDM/STM
  */
index fbeb2da224fe73cea6b7a64b7cc8c3b61174c39b..f52cbe1a19ad8582bcb623f8ea722553b8b305ae 100644 (file)
 //
 decode COND_CODE default Unknown::unknown() {
     0xf: decode COND_CODE {
-        0x0: decode OPCODE {
-            // Just a simple trick to allow us to specify our new uops here
-            0x2: ArmLoadMemory::ldr_uop({{ Rd = Mem; }},
-                                        {{ EA = Raddr + (up ? disp : -disp); }},
-                                           inst_flags = [IsMicroop]);
-            0x3: ArmStoreMemory::str_uop({{ Mem = Rd; }},
-                                         {{ EA = Raddr + (up ? disp : -disp); }},
-                                            inst_flags = [IsMicroop]);
-        }
         0x1: decode OPCODE {
+            // Just a simple trick to allow us to specify our new uops here
             0x0: PredIntOp::mvtd_uop({{ Fd.ud = ((uint64_t) Rhi << 32)|Rlo; }},
                                         'IsMicroop');
             0x1: PredIntOp::mvfd_uop({{ Rhi = (Fd.ud >> 32) & 0xffffffff;
                                         Rlo = Fd.ud & 0xffffffff; }},
                                         'IsMicroop');
-            0x2: ArmLoadMemory::ldhi_uop({{ Rhi = Mem; }},
-                                         {{ EA = Rn + (up ? disp : -disp); }},
-                                            inst_flags = [IsMicroop]);
-            0x3: ArmLoadMemory::ldlo_uop({{ Rlo = Mem; }},
-                                         {{ EA = Rn + (up ? disp : -disp); }},
-                                            inst_flags = [IsMicroop]);
-            0x4: ArmStoreMemory::sthi_uop({{ Mem = Rhi; }},
-                                          {{ EA = Rn + (up ? disp : -disp); }},
-                                             inst_flags = [IsMicroop]);
-            0x5: ArmStoreMemory::stlo_uop({{ Mem = Rlo; }},
-                                          {{ EA = Rn + (up ? disp : -disp); }},
-                                             inst_flags = [IsMicroop]);
         }
         default: Unknown::unknown(); // TODO: Ignore other NV space for now
     }
index 9b3a4f75fe231e4a4bfe57fbb7e4b1f533757920..be95040510ae1e0f1c92de704325cc6fcab6f3f5 100644 (file)
 // Authors: Stephen Hines
 //          Gabe Black
 
+////////////////////////////////////////////////////////////////////
+//
+// Common microop templates
+//
+
+def template MicroConstructor {{
+    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
+                                          RegIndex _ura,
+                                          RegIndex _urb,
+                                          uint8_t _imm)
+        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
+                         _ura, _urb, _imm)
+    {
+        %(constructor)s;
+    }
+}};
 
 ////////////////////////////////////////////////////////////////////
 //
-// Integer = Integer op Immediate microops
+// Load/store microops
 //
 
-def template MicroIntDeclare {{
+def template MicroMemDeclare {{
     class %(class_name)s : public %(base_class)s
     {
       public:
@@ -43,19 +59,52 @@ def template MicroIntDeclare {{
                        RegIndex _ura, RegIndex _urb,
                        uint8_t _imm);
         %(BasicExecDeclare)s
+        %(InitiateAccDeclare)s
+        %(CompleteAccDeclare)s
     };
 }};
 
-def template MicroIntConstructor {{
-    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
-                                          RegIndex _ura,
-                                          RegIndex _urb,
-                                          uint8_t _imm)
-        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
-                         _ura, _urb, _imm)
+let {{
+    microLdrUopIop = InstObjParams('ldr_uop', 'MicroLdrUop',
+                                   'MicroMemOp',
+                                   {'memacc_code': 'Ra = Mem;',
+                                    'ea_code': 'EA = Rb + (UP ? imm : -imm);',
+                                    'predicate_test': predicateTest},
+                                   ['IsMicroop'])
+
+    microStrUopIop = InstObjParams('str_uop', 'MicroStrUop',
+                                   'MicroMemOp',
+                                   {'memacc_code': 'Mem = Ra;',
+                                    'ea_code': 'EA = Rb + (UP ? imm : -imm);',
+                                    'predicate_test': predicateTest},
+                                   ['IsMicroop'])
+
+    header_output = MicroMemDeclare.subst(microLdrUopIop) + \
+                    MicroMemDeclare.subst(microStrUopIop)
+    decoder_output = MicroConstructor.subst(microLdrUopIop) + \
+                     MicroConstructor.subst(microStrUopIop)
+    exec_output = LoadExecute.subst(microLdrUopIop) + \
+                  StoreExecute.subst(microStrUopIop) + \
+                  LoadInitiateAcc.subst(microLdrUopIop) + \
+                  StoreInitiateAcc.subst(microStrUopIop) + \
+                  LoadCompleteAcc.subst(microLdrUopIop) + \
+                  StoreCompleteAcc.subst(microStrUopIop)
+}};
+
+////////////////////////////////////////////////////////////////////
+//
+// Integer = Integer op Immediate microops
+//
+
+def template MicroIntDeclare {{
+    class %(class_name)s : public %(base_class)s
     {
-        %(constructor)s;
-    }
+      public:
+        %(class_name)s(ExtMachInst machInst,
+                       RegIndex _ura, RegIndex _urb,
+                       uint8_t _imm);
+        %(BasicExecDeclare)s
+    };
 }};
 
 let {{
@@ -73,8 +122,8 @@ let {{
 
     header_output = MicroIntDeclare.subst(microAddiUopIop) + \
                     MicroIntDeclare.subst(microSubiUopIop)
-    decoder_output = MicroIntConstructor.subst(microAddiUopIop) + \
-                     MicroIntConstructor.subst(microSubiUopIop)
+    decoder_output = MicroConstructor.subst(microAddiUopIop) + \
+                     MicroConstructor.subst(microSubiUopIop)
     exec_output = PredOpExecute.subst(microAddiUopIop) + \
                   PredOpExecute.subst(microSubiUopIop)
 }};
@@ -148,7 +197,10 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
             j++;
         regs_to_handle &= ~(1<<j);
 
-        microOps[i] = gen_ldrstr_uop(machInst, loadop, j, start_addr);
+        if (loadop)
+            microOps[i] = new MicroLdrUop(machInst, j, 17, start_addr);
+        else
+            microOps[i] = new MicroStrUop(machInst, j, 17, start_addr);
 
         if (up)
             start_addr += 4;
index e9cb533d623d65a6b4a8fda120ce86441dc034f9..ea4ffa660b46f036e5e74809d5f16ca81ee35321 100644 (file)
@@ -101,67 +101,27 @@ output decoder {{
         return str;
     }
 
-    // Generate the bit pattern for an Ldr_uop or Str_uop;
-    StaticInstPtr
-    gen_ldrstr_uop(uint32_t baseinst, int loadop, uint32_t rd, int32_t disp)
-    {
-        StaticInstPtr newInst;
-        uint32_t newMachInst = baseinst & 0xffff0000;
-        newMachInst |= (rd << 12);
-        newMachInst |= disp;
-        if (loadop)
-            newInst = new Ldr_uop(newMachInst);
-        else
-            newInst = new Str_uop(newMachInst);
-        return newInst;
-    }
-
     // Emits uops for a double fp move
-    int
-    emit_ldfstf_uops(StaticInstPtr* microOps, int index, uint32_t baseinst, int loadop, int up, int32_t disp)
+    void
+    emit_ldfstf_uops(StaticInstPtr* microOps, int index, ExtMachInst machInst,
+                     bool loadop, bool up, int32_t disp)
     {
-        StaticInstPtr newInst;
-        uint32_t newMachInst;
+        MachInst newMachInst = machInst & 0xf000f000;
 
         if (loadop)
         {
-            newMachInst = baseinst & 0xfffff000;
-            newMachInst |= (disp & 0x0fff);
-            newInst = new Ldlo_uop(newMachInst);
-            microOps[index++] = newInst;
-
-            newMachInst = baseinst & 0xfffff000;
-            if (up)
-                newMachInst |= ((disp + 4) & 0x0fff);
-            else
-                newMachInst |= ((disp - 4) & 0x0fff);
-            newInst = new Ldhi_uop(newMachInst);
-            microOps[index++] = newInst;
-
-            newMachInst = baseinst & 0xf000f000;
-            newInst = new Mvtd_uop(newMachInst);
-            microOps[index++] = newInst;
+            microOps[index++] = new MicroLdrUop(machInst, 19, RN, disp);
+            microOps[index++] =
+                new MicroLdrUop(machInst, 18, RN, disp + (up ? 4 : -4));
+            microOps[index++] = new Mvtd_uop(newMachInst);
         }
         else
         {
-            newMachInst = baseinst & 0xf000f000;
-            newInst = new Mvfd_uop(newMachInst);
-            microOps[index++] = newInst;
-
-            newMachInst = baseinst & 0xfffff000;
-            newMachInst |= (disp & 0x0fff);
-            newInst = new Stlo_uop(newMachInst);
-            microOps[index++] = newInst;
-
-            newMachInst = baseinst & 0xfffff000;
-            if (up)
-                newMachInst |= ((disp + 4) & 0x0fff);
-            else
-                newMachInst |= ((disp - 4) & 0x0fff);
-            newInst = new Sthi_uop(newMachInst);
-            microOps[index++] = newInst;
+            microOps[index++] = new Mvfd_uop(newMachInst);
+            microOps[index++] = new MicroStrUop(machInst, 19, RN, disp);
+            microOps[index++] =
+                new MicroStrUop(machInst, 18, RN, disp + (up ? 4 : -4));
         }
-        return 3;
     }
 
 }};