ARM: Move the integer 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/operands.isa

index 7b566bb5793b22d9b1a41af46b4900bf944f7f77..c215cdeab9ba6f6397e2665da00b5d92ed81fe55 100644 (file)
@@ -46,6 +46,23 @@ number_of_ones(int32_t val)
     return ones;
 }
 
+/**
+ * Microops of the form IntRegA = IntRegB op Imm
+ */
+class MicroIntOp : public PredOp
+{
+  protected:
+    RegIndex ura, urb;
+    uint8_t imm;
+
+    MicroIntOp(const char *mnem, ExtMachInst machInst, OpClass __opClass,
+               RegIndex _ura, RegIndex _urb, uint8_t _imm)
+            : PredOp(mnem, machInst, __opClass),
+              ura(_ura), urb(_urb), imm(_imm)
+    {
+    }
+};
+
 /**
  * Arm Macro Memory operations like LDM/STM
  */
index 0cea98a40e2cdf630e64ccf7457186b442276358..fbeb2da224fe73cea6b7a64b7cc8c3b61174c39b 100644 (file)
@@ -41,20 +41,12 @@ 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
-            0x0: PredImmOp::addi_uop({{ Raddr = Rn + rotated_imm; }},
-                                        'IsMicroop');
-            0x1: PredImmOp::subi_uop({{ Raddr = Rn - rotated_imm; }},
-                                        'IsMicroop');
             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]);
-            0x4: PredImmOp::addi_rd_uop({{ Rd = Rn + rotated_imm; }},
-                                           'IsMicroop');
-            0x5: PredImmOp::subi_rd_uop({{ Rd = Rn - rotated_imm; }},
-                                           'IsMicroop');
         }
         0x1: decode OPCODE {
             0x0: PredIntOp::mvtd_uop({{ Fd.ud = ((uint64_t) Rhi << 32)|Rlo; }},
index e50e3138615bba5fec968781c6855fa44b17c9b5..9b3a4f75fe231e4a4bfe57fbb7e4b1f533757920 100644 (file)
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 //
 // Authors: Stephen Hines
+//          Gabe Black
+
+
+////////////////////////////////////////////////////////////////////
+//
+// Integer = Integer op Immediate microops
+//
+
+def template MicroIntDeclare {{
+    class %(class_name)s : public %(base_class)s
+    {
+      public:
+        %(class_name)s(ExtMachInst machInst,
+                       RegIndex _ura, RegIndex _urb,
+                       uint8_t _imm);
+        %(BasicExecDeclare)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)
+    {
+        %(constructor)s;
+    }
+}};
+
+let {{
+    microAddiUopIop = InstObjParams('addi_uop', 'MicroAddiUop',
+                                    'MicroIntOp',
+                                    {'code': 'Ra = Rb + imm;',
+                                     'predicate_test': predicateTest},
+                                    ['IsMicroop'])
+
+    microSubiUopIop = InstObjParams('subi_uop', 'MicroSubiUop',
+                                    'MicroIntOp',
+                                    {'code': 'Ra = Rb - imm;',
+                                     'predicate_test': predicateTest},
+                                    ['IsMicroop'])
+
+    header_output = MicroIntDeclare.subst(microAddiUopIop) + \
+                    MicroIntDeclare.subst(microSubiUopIop)
+    decoder_output = MicroIntConstructor.subst(microAddiUopIop) + \
+                     MicroIntConstructor.subst(microSubiUopIop)
+    exec_output = PredOpExecute.subst(microAddiUopIop) + \
+                  PredOpExecute.subst(microSubiUopIop)
+}};
 
 ////////////////////////////////////////////////////////////////////
 //
@@ -86,13 +137,12 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
             break;
     }
 
-    uint32_t newMachInst = 0;
-    newMachInst = machInst & 0xffff0000;
-    microOps[0] = new Addi_uop(newMachInst);
+    // Add 0 to Rn and stick it in Raddr (register 17).
+    // This is equivalent to a move.
+    microOps[0] = new MicroAddiUop(machInst, 17, RN, 0);
 
     unsigned j = 0;
-    for (int i = 1; i < ones+1; i++)
-    {
+    for (int i = 1; i < ones+1; i++) {
         // Get next available bit for transfer
         while (! ( regs_to_handle & (1<<j)))
             j++;
@@ -106,24 +156,13 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
             start_addr -= 4;
     }
 
-    if (writeback)
-    {
-        uint32_t newMachInst = machInst & 0xf0000000;
-        uint32_t rn = (machInst >> 16) & 0x0f;
-        // 3322 2222 2222 1111 1111 11
-        // 1098 7654 3210 9876 5432 1098 7654 3210
-        // COND 0010 0100 [RN] [RD] 0000 [  IMM  ]
-        // sub rn, rn, imm
-        newMachInst |= 0x02400000;
-        newMachInst |= ((rn << 16) | (rn << 12));
-        newMachInst |= (ones << 2);
-        if (up)
-        {
-            microOps[numMicroops-1] = new Addi_rd_uop(newMachInst);
-        }
-        else
-        {
-            microOps[numMicroops-1] = new Subi_rd_uop(newMachInst);
+    if (writeback) {
+        if (up) {
+            microOps[numMicroops-1] =
+                new MicroAddiUop(machInst, RN, RN, ones * 4);
+        } else {
+            microOps[numMicroops-1] =
+                new MicroSubiUop(machInst, RN, RN, ones * 4);
         }
     }
     microOps[numMicroops-1]->setLastMicroop();
@@ -166,23 +205,12 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
 
     if (writeback)
     {
-        uint32_t newMachInst = machInst & 0xf0000000;
-        uint32_t rn = (machInst >> 16) & 0x0f;
-        // 3322 2222 2222 1111 1111 11
-        // 1098 7654 3210 9876 5432 1098 7654 3210
-        // COND 0010 0100 [RN] [RD] 0000 [  IMM  ]
-        // sub rn, rn, imm
-        newMachInst |= 0x02400000;
-        newMachInst |= ((rn << 16) | (rn << 12));
-        if (up)
-        {
-            newMachInst |= disp8;
-            microOps[numMicroops-1] = new Addi_rd_uop(newMachInst);
-        }
-        else
-        {
-            newMachInst |= disp8;
-            microOps[numMicroops-1] = new Subi_rd_uop(newMachInst);
+        if (up) {
+            microOps[numMicroops-1] =
+                new MicroAddiUop(machInst, RN, RN, disp8);
+        } else {
+            microOps[numMicroops-1] =
+                new MicroSubiUop(machInst, RN, RN, disp8);
         }
     }
     microOps[numMicroops-1]->setLastMicroop();
@@ -205,29 +233,15 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
         start_addr = 0;
 
     for (int i = 0; i < count; i++)
-    {
         emit_ldfstf_uops(microOps, 3*i, machInst, loadop, up, start_addr);
-    }
 
-    if (writeback)
-    {
-        uint32_t newMachInst = machInst & 0xf0000000;
-        uint32_t rn = (machInst >> 16) & 0x0f;
-        // 3322 2222 2222 1111 1111 11
-        // 1098 7654 3210 9876 5432 1098 7654 3210
-        // COND 0010 0100 [RN] [RD] 0000 [  IMM  ]
-        // sub rn, rn, imm
-        newMachInst |= 0x02400000;
-        newMachInst |= ((rn << 16) | (rn << 12));
-        if (up)
-        {
-            newMachInst |= disp8;
-            microOps[numMicroops-1] = new Addi_rd_uop(newMachInst);
-        }
-        else
-        {
-            newMachInst |= disp8;
-            microOps[numMicroops-1] = new Subi_rd_uop(newMachInst);
+    if (writeback) {
+        if (up) {
+            microOps[numMicroops-1] =
+                new MicroAddiUop(machInst, RN, RN, disp8);
+        } else {
+            microOps[numMicroops-1] =
+                new MicroSubiUop(machInst, RN, RN, disp8);
         }
     }
     microOps[numMicroops-1]->setLastMicroop();
index 18295cf61e331c881d38329561dd23b2750ad2be..c9df79e1eb25ee5cfc255b1d2d4b5e13d5f9a608 100644 (file)
@@ -56,6 +56,10 @@ def operands {{
     'Rlo': ('IntReg', 'uw', '19', 'IsInteger', 8),
     'LR': ('IntReg', 'uw', '14', 'IsInteger', 9),
 
+    #Register fields for microops
+    'Ra' : ('IntReg', 'uw', 'ura', 'IsInteger', 11),
+    'Rb' : ('IntReg', 'uw', 'urb', 'IsInteger', 12),
+
     #General Purpose Floating Point Reg Operands
     'Fd': ('FloatReg', 'df', 'FD', 'IsFloating', 20),
     'Fn': ('FloatReg', 'df', 'FN', 'IsFloating', 21),