ARM: Explicitly keep track of the second destination for double loads/stores.
[gem5.git] / src / arch / arm / insts / pred_inst.hh
index 817ed44f54bb35bcb5d5da375d59d886daaf59f7..8f92a2f26159419002c595d9b45c25bb49deedfb 100644 (file)
@@ -54,6 +54,30 @@ rotate_imm(uint32_t immValue, int rotateValue)
             (immValue << (32 - (rotateValue & 31))));
 }
 
+static inline uint32_t
+modified_imm(uint8_t ctrlImm, uint8_t dataImm)
+{
+    uint32_t bigData = dataImm;
+    uint32_t bigCtrl = ctrlImm;
+    if (bigCtrl < 4) {
+        switch (bigCtrl) {
+          case 0:
+            return bigData;
+          case 1:
+            return bigData | (bigData << 16);
+          case 2:
+            return (bigData << 8) | (bigData << 24);
+          case 3:
+            return (bigData << 0) | (bigData << 8) |
+                   (bigData << 16) | (bigData << 24);
+        }
+    }
+    bigCtrl = (bigCtrl << 1) | ((bigData >> 7) & 0x1);
+    bigData |= (1 << 7);
+    return bigData << (32 - bigCtrl);
+}
+
+
 /**
  * Base class for predicated integer operations.
  */
@@ -74,65 +98,27 @@ class PredOp : public ArmStaticInst
 /**
  * Base class for predicated immediate operations.
  */
-class PredImmOpBase : public PredOp
+class PredImmOp : public PredOp
 {
     protected:
 
     uint32_t imm;
     uint32_t rotated_imm;
     uint32_t rotated_carry;
-
-    /// Constructor
-    PredImmOpBase(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
-                  PredOp(mnem, _machInst, __opClass),
-                  imm(machInst.imm), rotated_imm(0), rotated_carry(0)
-    {
-    }
-
-    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
-};
-
-/**
- * Base class for regular predicated immediate operations.
- */
-class PredImmOp : public PredImmOpBase
-{
-    protected:
-
     uint32_t rotate;
 
     /// Constructor
     PredImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
-              PredImmOpBase(mnem, _machInst, __opClass),
+              PredOp(mnem, _machInst, __opClass),
+              imm(machInst.imm), rotated_imm(0), rotated_carry(0),
               rotate(machInst.rotate << 1)
     {
         rotated_imm = rotate_imm(imm, rotate);
         if (rotate != 0)
             rotated_carry = bits(rotated_imm, 31);
     }
-};
-
-/**
- * Base class for modified predicated immediate operations.
- */
-class PredModImmOp : public PredImmOpBase
-{
-    protected:
 
-    uint8_t ctrlImm;
-    uint8_t dataImm;
-
-
-    /// Constructor
-    PredModImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
-                 PredImmOpBase(mnem, _machInst, __opClass),
-                 ctrlImm(bits(machInst.instBits, 26) << 3 |
-                         bits(machInst.instBits, 14, 12)),
-                 dataImm(bits(machInst.instBits, 7, 0))
-    {
-        rotated_imm = modified_imm(ctrlImm, dataImm);
-        rotated_carry = bits(rotated_imm, 31);
-    }
+    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
 };
 
 /**
@@ -155,6 +141,59 @@ class PredIntOp : public PredOp
     std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
 };
 
+class DataImmOp : public PredOp
+{
+  protected:
+    IntRegIndex dest, op1;
+    uint32_t imm;
+    // Whether the carry flag should be modified if that's an option for
+    // this instruction.
+    bool rotC;
+
+    DataImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
+              IntRegIndex _dest, IntRegIndex _op1, uint32_t _imm, bool _rotC) :
+        PredOp(mnem, _machInst, __opClass),
+        dest(_dest), op1(_op1), imm(_imm), rotC(_rotC)
+    {}
+
+    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+};
+
+class DataRegOp : public PredOp
+{
+  protected:
+    IntRegIndex dest, op1, op2;
+    int32_t shiftAmt;
+    ArmShiftType shiftType;
+
+    DataRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
+              IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2,
+              int32_t _shiftAmt, ArmShiftType _shiftType) :
+        PredOp(mnem, _machInst, __opClass),
+        dest(_dest), op1(_op1), op2(_op2),
+        shiftAmt(_shiftAmt), shiftType(_shiftType)
+    {}
+
+    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+};
+
+class DataRegRegOp : public PredOp
+{
+  protected:
+    IntRegIndex dest, op1, op2, shift;
+    ArmShiftType shiftType;
+
+    DataRegRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
+                 IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2,
+                 IntRegIndex _shift, ArmShiftType _shiftType) :
+        PredOp(mnem, _machInst, __opClass),
+        dest(_dest), op1(_op1), op2(_op2), shift(_shift),
+        shiftType(_shiftType)
+    {}
+
+    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+};
+
 /**
  * Base class for predicated macro-operations.
  */