cpu: implements vector registers
authorNilay Vaish <nilay@cs.wisc.edu>
Sun, 26 Jul 2015 15:21:20 +0000 (10:21 -0500)
committerNilay Vaish <nilay@cs.wisc.edu>
Sun, 26 Jul 2015 15:21:20 +0000 (10:21 -0500)
This adds a vector register type.  The type is defined as a std::array of a
fixed number of uint64_ts.  The isa_parser.py has been modified to parse vector
register operands and generate the required code.  Different cpus have vector
register files now.

55 files changed:
src/arch/SConscript
src/arch/alpha/isa.hh
src/arch/alpha/registers.hh
src/arch/alpha/utility.cc
src/arch/arm/insts/static_inst.cc
src/arch/arm/isa.hh
src/arch/arm/registers.hh
src/arch/arm/utility.cc
src/arch/isa_parser.py
src/arch/mips/isa.hh
src/arch/mips/registers.hh
src/arch/mips/utility.cc
src/arch/null/registers.hh
src/arch/power/insts/static_inst.cc
src/arch/power/isa.hh
src/arch/power/registers.hh
src/arch/power/utility.cc
src/arch/sparc/isa.hh
src/arch/sparc/registers.hh
src/arch/sparc/utility.cc
src/arch/x86/insts/static_inst.cc
src/arch/x86/isa.hh
src/arch/x86/registers.hh
src/arch/x86/utility.cc
src/cpu/StaticInstFlags.py
src/cpu/base_dyn_inst.hh
src/cpu/checker/cpu.hh
src/cpu/checker/cpu_impl.hh
src/cpu/checker/thread_context.hh
src/cpu/exec_context.hh
src/cpu/minor/dyn_inst.cc
src/cpu/minor/exec_context.hh
src/cpu/minor/scoreboard.cc
src/cpu/minor/scoreboard.hh
src/cpu/o3/O3CPU.py
src/cpu/o3/cpu.cc
src/cpu/o3/cpu.hh
src/cpu/o3/dyn_inst.hh
src/cpu/o3/free_list.hh
src/cpu/o3/inst_queue_impl.hh
src/cpu/o3/regfile.cc
src/cpu/o3/regfile.hh
src/cpu/o3/rename_impl.hh
src/cpu/o3/rename_map.cc
src/cpu/o3/rename_map.hh
src/cpu/o3/thread_context.hh
src/cpu/o3/thread_context_impl.hh
src/cpu/reg_class.cc
src/cpu/reg_class.hh
src/cpu/simple/base.hh
src/cpu/simple_thread.hh
src/cpu/static_inst.hh
src/cpu/thread_context.cc
src/cpu/thread_context.hh
src/sim/insttracer.hh

index e0d6845f5790edb2e64c51dfe70d2f0c81bd70ba..89ecdfa73500e51011da3e7e391255d9c43ee7e4 100644 (file)
@@ -196,5 +196,7 @@ env.Append(BUILDERS = {'ScanISA' :
 DebugFlag('IntRegs')
 DebugFlag('FloatRegs')
 DebugFlag('CCRegs')
+DebugFlag('VectorRegs')
 DebugFlag('MiscRegs')
-CompoundFlag('Registers', [ 'IntRegs', 'FloatRegs', 'CCRegs', 'MiscRegs' ])
+CompoundFlag('Registers', [ 'IntRegs', 'FloatRegs', 'CCRegs', 'VectorRegs',
+                            'MiscRegs' ])
index 6a88ee40bb0e793c57936a667ddd47e58fefd17b..b5964e622d69cd67c818ecb2a56d9814a5412c5e 100644 (file)
@@ -114,6 +114,13 @@ namespace AlphaISA
             return reg;
         }
 
+        // dummy
+        int
+        flattenVectorIndex(int reg) const
+        {
+            return reg;
+        }
+
         int
         flattenMiscIndex(int reg) const
         {
index 3fd774cf7ff195baf670030bdeab57d6776cd715..665ea30c77e3dc7375c0976c8715af09a4e00997 100644 (file)
@@ -56,6 +56,12 @@ typedef uint64_t MiscReg;
 // dummy typedef since we don't have CC regs
 typedef uint8_t CCReg;
 
+// vector register file entry type
+typedef uint64_t VectorRegElement;
+const int NumVectorRegElements = 0;
+const int VectorRegBytes = NumVectorRegElements * sizeof(VectorRegElement);
+typedef std::array<VectorRegElement, NumVectorRegElements> VectorReg;
+
 union AnyReg
 {
     IntReg  intreg;
@@ -95,6 +101,7 @@ const int NumFloatArchRegs = 32;
 const int NumIntRegs = NumIntArchRegs + NumPALShadowRegs;
 const int NumFloatRegs = NumFloatArchRegs;
 const int NumCCRegs = 0;
+const int NumVectorRegs = 0;
 const int NumMiscRegs = NUM_MISCREGS;
 
 const int TotalNumRegs =
@@ -106,7 +113,8 @@ enum DependenceTags {
     // 32..63 are the FP regs 0..31, i.e. use (reg + FP_Reg_Base)
     FP_Reg_Base = NumIntRegs,
     CC_Reg_Base = FP_Reg_Base + NumFloatRegs,
-    Misc_Reg_Base = CC_Reg_Base + NumCCRegs, // NumCCRegs == 0
+    Vector_Reg_Base = CC_Reg_Base + NumCCRegs, // NumCCRegs == 0
+    Misc_Reg_Base = Vector_Reg_Base + NumCCRegs, // NumVectorRegs == 0
     Max_Reg_Index = Misc_Reg_Base + NumMiscRegs + NumInternalProcRegs
 };
 
index 2dfe00f967fdcaecb1ff639d7648ec449178ed65..b0a503828cb37f7683bc7e5c101b53ff688ebee3 100644 (file)
@@ -73,6 +73,7 @@ copyRegs(ThreadContext *src, ThreadContext *dest)
 
     // Would need to add condition-code regs if implemented
     assert(NumCCRegs == 0);
+    assert(NumVectorRegs == 0);
 
     // Copy misc. registers
     copyMiscRegs(src, dest);
index 9f878ac4d74386264abf6314024fd35a3b0df267..41749657998f202d0bd36cd6e3fb963698fb199d 100644 (file)
@@ -337,6 +337,8 @@ ArmStaticInst::printReg(std::ostream &os, int reg) const
       case CCRegClass:
         ccprintf(os, "cc_%s", ArmISA::ccRegName[rel_reg]);
         break;
+      case VectorRegClass:
+        panic("ARM ISA does not have any vector registers yet!");
     }
 }
 
index a07017c17dadbf8a1a6cd4e16250fb54ee7f290a..1e7edd637303c492eae719c9f34ead90fd844435 100644 (file)
@@ -287,6 +287,13 @@ namespace ArmISA
             return reg;
         }
 
+        int
+        flattenVectorIndex(int reg) const
+        {
+            assert(reg >= 0);
+            return reg;
+        }
+
         int
         flattenMiscIndex(int reg) const
         {
index 23fc2045042cb088e7fdd542233025c85cb01430..e57802e537810088bf55439ed0704dd638a670a2 100644 (file)
@@ -72,6 +72,12 @@ typedef uint64_t MiscReg;
 // condition code register; must be at least 32 bits for FpCondCodes
 typedef uint64_t CCReg;
 
+// vector register file entry type
+typedef uint64_t VectorRegElement;
+const int NumVectorRegElements = 0;
+const int VectorRegBytes = NumVectorRegElements * sizeof(VectorRegElement);
+typedef std::array<VectorRegElement, NumVectorRegElements> VectorReg;
+
 // Constants Related to the number of registers
 const int NumIntArchRegs = NUM_ARCH_INTREGS;
 // The number of single precision floating point registers
@@ -82,6 +88,7 @@ const int NumFloatSpecialRegs = 32;
 const int NumIntRegs = NUM_INTREGS;
 const int NumFloatRegs = NumFloatV8ArchRegs + NumFloatSpecialRegs;
 const int NumCCRegs = NUM_CCREGS;
+const int NumVectorRegs = 0;
 const int NumMiscRegs = NUM_MISCREGS;
 
 #define ISA_HAS_CC_REGS
@@ -112,7 +119,8 @@ const int SyscallSuccessReg = ReturnValueReg;
 // These help enumerate all the registers for dependence tracking.
 const int FP_Reg_Base = NumIntRegs * (MODE_MAXMODE + 1);
 const int CC_Reg_Base = FP_Reg_Base + NumFloatRegs;
-const int Misc_Reg_Base = CC_Reg_Base + NumCCRegs;
+const int Vector_Reg_Base = CC_Reg_Base + NumCCRegs;
+const int Misc_Reg_Base = Vector_Reg_Base + NumVectorRegs;
 const int Max_Reg_Index = Misc_Reg_Base + NumMiscRegs;
 
 typedef union {
index 34fcfd48259a52db0efb62f7107441b77844e994..e1f9dfe046cd526f822678150a8e17b524d4ff74 100644 (file)
@@ -156,6 +156,9 @@ copyRegs(ThreadContext *src, ThreadContext *dest)
     for (int i = 0; i < NumCCRegs; i++)
         dest->setCCReg(i, src->readCCReg(i));
 
+    // Copy vector registers when vector registers put to use.
+    assert(NumVectorRegs == 0);
+
     for (int i = 0; i < NumMiscRegs; i++)
         dest->setMiscRegNoEffect(i, src->readMiscRegNoEffect(i));
 
index f756161ea6abbb518f097ee61ec535efdbe54a06..5050d24d49fc226be47ad92504cde908ca1e0413 100755 (executable)
@@ -515,6 +515,9 @@ class Operand(object):
     def isCCReg(self):
         return 0
 
+    def isVectorReg(self):
+        return 0
+
     def isControlReg(self):
         return 0
 
@@ -751,6 +754,106 @@ class CCRegOperand(Operand):
 
         return wb
 
+class VectorRegOperand(Operand):
+    def isReg(self):
+        return 1
+
+    def isVectorReg(self):
+        return 1
+
+    def __init__(self, parser, full_name, ext, is_src, is_dest):
+        ## Vector registers are always treated as source registers since
+        ## not the whole of them might be written, in which case we need
+        ## to retain the earlier value.
+        super(VectorRegOperand, self).__init__(parser, full_name, ext,
+                                               True, is_dest)
+        self.size = 0
+
+    def finalize(self, predRead, predWrite):
+        self.flags = self.getFlags()
+        self.constructor = self.makeConstructor(predRead, predWrite)
+        self.op_decl = self.makeDecl()
+
+        if self.is_src:
+            self.op_rd = self.makeRead(predRead)
+            self.op_src_decl = self.makeDecl()
+        else:
+            self.op_rd = ''
+            self.op_src_decl = ''
+
+        if self.is_dest:
+            self.op_wb = self.makeWrite(predWrite)
+            self.op_dest_decl = self.makeDecl()
+        else:
+            self.op_wb = ''
+            self.op_dest_decl = ''
+
+    def makeConstructor(self, predRead, predWrite):
+        c_src = ''
+        c_dest = ''
+
+        if self.is_src:
+            c_src = '\n\t_srcRegIdx[_numSrcRegs++] = %s + Vector_Reg_Base;' % \
+                    (self.reg_spec)
+            if self.hasReadPred():
+                c_src = '\n\tif (%s) {%s\n\t}' % \
+                        (self.read_predicate, c_src)
+
+        if self.is_dest:
+            c_dest = '\n\t_destRegIdx[_numDestRegs++] = %s + Vector_Reg_Base;' % \
+                    (self.reg_spec)
+            c_dest += '\n\t_numVectorDestRegs++;'
+            if self.hasWritePred():
+                c_dest = '\n\tif (%s) {%s\n\t}' % \
+                         (self.write_predicate, c_dest)
+
+        return c_src + c_dest
+
+    def makeRead(self, predRead):
+        if self.read_code != None:
+            return self.buildReadCode('readVectorRegOperand')
+
+        vector_reg_val = ''
+        if predRead:
+            vector_reg_val = 'xc->readVectorRegOperand(this, _sourceIndex++)'
+            if self.hasReadPred():
+                vector_reg_val = '(%s) ? %s : 0' % \
+                              (self.read_predicate, vector_reg_val)
+        else:
+            vector_reg_val = 'xc->readVectorRegOperand(this, %d)' % \
+                             self.src_reg_idx
+
+        return '%s = %s;\n' % (self.base_name, vector_reg_val)
+
+    def makeWrite(self, predWrite):
+        if self.write_code != None:
+            return self.buildWriteCode('setVectorRegOperand')
+
+        if predWrite:
+            wp = 'true'
+            if self.hasWritePred():
+                wp = self.write_predicate
+
+            wcond = 'if (%s)' % (wp)
+            windex = '_destIndex++'
+        else:
+            wcond = ''
+            windex = '%d' % self.dest_reg_idx
+
+        wb = '''
+        %s
+        {
+            TheISA::VectorReg final_val = %s;
+            xc->setVectorRegOperand(this, %s, final_val);\n
+            if (traceData) { traceData->setData(final_val); }
+        }''' % (wcond, self.base_name, windex)
+
+        return wb
+
+    def makeDecl(self):
+        ctype = 'TheISA::VectorReg'
+        return '%s %s;\n' % (ctype, self.base_name)
+
 class ControlRegOperand(Operand):
     def isReg(self):
         return 1
@@ -818,7 +921,10 @@ class MemOperand(Operand):
         # Note that initializations in the declarations are solely
         # to avoid 'uninitialized variable' errors from the compiler.
         # Declare memory data variable.
-        return '%s %s = 0;\n' % (self.ctype, self.base_name)
+        if 'IsVector' in self.flags:
+            return 'TheISA::VectorReg %s;\n' % self.base_name
+        else:
+            return '%s %s = 0;\n' % (self.ctype, self.base_name)
 
     def makeRead(self, predRead):
         if self.read_code != None:
@@ -909,6 +1015,7 @@ class OperandList(object):
         self.numFPDestRegs = 0
         self.numIntDestRegs = 0
         self.numCCDestRegs = 0
+        self.numVectorDestRegs = 0
         self.numMiscDestRegs = 0
         self.memOperand = None
 
@@ -931,6 +1038,8 @@ class OperandList(object):
                         self.numIntDestRegs += 1
                     elif op_desc.isCCReg():
                         self.numCCDestRegs += 1
+                    elif op_desc.isVectorReg():
+                        self.numVectorDestRegs += 1
                     elif op_desc.isControlReg():
                         self.numMiscDestRegs += 1
             elif op_desc.isMem():
@@ -1127,6 +1236,7 @@ class InstObjParams(object):
         header += '\n\t_numFPDestRegs = 0;'
         header += '\n\t_numIntDestRegs = 0;'
         header += '\n\t_numCCDestRegs = 0;'
+        header += '\n\t_numVectorDestRegs = 0;'
 
         self.constructor = header + \
                            self.operands.concatAttrStrings('constructor')
@@ -2292,7 +2402,8 @@ StaticInstPtr
 
         operandsREString = r'''
         (?<!\w)      # neg. lookbehind assertion: prevent partial matches
-        ((%s)(?:_(%s))?)   # match: operand with optional '_' then suffix
+        ((%s)(?:_(%s))?(?:\[\w+\])?)   # match: operand with optional '_'
+        # then suffix, and then an optional array index.
         (?!\w)       # neg. lookahead assertion: prevent partial matches
         ''' % (string.join(operands, '|'), string.join(extensions, '|'))
 
index feb55e473996dfeac988c62617ab7b884a805f78..f61db6d57c6d884f916390c77071663b8cea514a 100644 (file)
@@ -184,6 +184,13 @@ namespace MipsISA
             return reg;
         }
 
+        // dummy
+        int
+        flattenVectorIndex(int reg) const
+        {
+            return reg;
+        }
+
         int
         flattenMiscIndex(int reg) const
         {
index 0ac84cc7fec056bb3094a9b7cc645e200e9541ac..e7d5e346c28f805464a7b703570c4437287d4588 100644 (file)
@@ -55,6 +55,7 @@ const int MaxShadowRegSets = 16; // Maximum number of shadow register sets
 const int NumIntRegs = NumIntArchRegs + NumIntSpecialRegs;        //HI & LO Regs
 const int NumFloatRegs = NumFloatArchRegs + NumFloatSpecialRegs;//
 const int NumCCRegs = 0;
+const int NumVectorRegs = 0;
 
 const uint32_t MIPS32_QNAN = 0x7fbfffff;
 const uint64_t MIPS64_QNAN = ULL(0x7ff7ffffffffffff);
@@ -278,7 +279,8 @@ const int NumMiscRegs = MISCREG_NUMREGS;
 // These help enumerate all the registers for dependence tracking.
 const int FP_Reg_Base = NumIntRegs;
 const int CC_Reg_Base = FP_Reg_Base + NumFloatRegs;
-const int Misc_Reg_Base = CC_Reg_Base + NumCCRegs; // NumCCRegs == 0
+const int Vector_Reg_Base = CC_Reg_Base + NumCCRegs; // NumCCRegs == 0
+const int Misc_Reg_Base = Vector_Reg_Base + NumVectorRegs;
 const int Max_Reg_Index = Misc_Reg_Base + NumMiscRegs;
 
 const int TotalNumRegs = NumIntRegs + NumFloatRegs + NumMiscRegs;
@@ -297,6 +299,12 @@ typedef uint64_t MiscReg;
 // dummy typedef since we don't have CC regs
 typedef uint8_t CCReg;
 
+// vector register file entry type
+typedef uint64_t VectorRegElement;
+const int NumVectorRegElements = 0;
+const int VectorRegBytes = NumVectorRegElements * sizeof(VectorRegElement);
+typedef std::array<VectorRegElement, NumVectorRegElements> VectorReg;
+
 typedef union {
     IntReg   intreg;
     FloatReg fpreg;
index 80047fbfdca3b439f2ca14822d867dcca126d664..92ca8c6f0b68dc8c21b093e18aee8b19335b0192 100644 (file)
@@ -252,6 +252,9 @@ copyRegs(ThreadContext *src, ThreadContext *dest)
     // Would need to add condition-code regs if implemented
     assert(NumCCRegs == 0);
 
+    // Copy vector registers when vector registers put to use.
+    assert(NumVectorRegs == 0);
+
     // Copy misc. registers
     for (int i = 0; i < NumMiscRegs; i++)
         dest->setMiscRegNoEffect(i, src->readMiscRegNoEffect(i));
index 1e52fc5a6eced0f829d84d321e3eaf1651086162..3f15245543a55a0811990f1925ad8af1bac4b40d 100644 (file)
@@ -49,6 +49,8 @@ typedef uint32_t FloatRegBits;
 typedef float FloatReg;
 typedef uint8_t CCReg;
 typedef uint64_t MiscReg;
+typedef uint64_t VectorRegElement;
+typedef std::array<VectorRegElement, 0> VectorReg;
 
 }
 
index 087e1f740c13754804a916dfc5bc220d66d7cf2b..5bd16b40ddae17edfab796d0cdb1de52be44a1c1 100644 (file)
@@ -57,6 +57,8 @@ PowerStaticInst::printReg(std::ostream &os, int reg) const
         }
       case CCRegClass:
         panic("printReg: POWER does not implement CCRegClass\n");
+      case VectorRegClass:
+        panic("printReg: POWER does not implement VectorRegClass\n");
     }
 }
 
index aaf5bd92a3be06ff65fd59b5727a76e932108357..08ee82d5dcf1b48b259e4a7c0e6f4e68cebc3dc7 100644 (file)
@@ -105,6 +105,13 @@ class ISA : public SimObject
         return reg;
     }
 
+    // dummy
+    int
+    flattenVectorIndex(int reg) const
+    {
+        return reg;
+    }
+
     int
     flattenMiscIndex(int reg) const
     {
index abee516fcda0018eccce4ee225e46512b3089da3..1d0b4a21ffa3417405013cfe78a582f20c5e6441 100644 (file)
@@ -55,6 +55,12 @@ typedef uint64_t MiscReg;
 // dummy typedef since we don't have CC regs
 typedef uint8_t CCReg;
 
+// typedefs for Vector registers
+const int NumVectorRegElements = 0;
+typedef uint64_t VectorRegElement;
+const int VectorRegBytes = NumVectorRegElements * sizeof(VectorRegElement);
+typedef std::array<VectorRegElement, NumVectorRegElements> VectorReg;
+
 // Constants Related to the number of registers
 const int NumIntArchRegs = 32;
 
@@ -68,6 +74,7 @@ const int NumInternalProcRegs = 0;
 const int NumIntRegs = NumIntArchRegs + NumIntSpecialRegs;
 const int NumFloatRegs = NumFloatArchRegs + NumFloatSpecialRegs;
 const int NumCCRegs = 0;
+const int NumVectorRegs = 0;
 const int NumMiscRegs = NUM_MISCREGS;
 
 // Semantically meaningful register indices
@@ -90,7 +97,8 @@ const int SyscallSuccessReg = 3;
 // These help enumerate all the registers for dependence tracking.
 const int FP_Reg_Base = NumIntRegs;
 const int CC_Reg_Base = FP_Reg_Base + NumFloatRegs;
-const int Misc_Reg_Base = CC_Reg_Base + NumCCRegs; // NumCCRegs == 0
+const int Vector_Reg_Base = CC_Reg_Base + NumCCRegs; // NumCCRegs == 0
+const int Misc_Reg_Base = Vector_Reg_Base + NumVectorRegs; // NumVectorRegs == 0
 const int Max_Reg_Index = Misc_Reg_Base + NumMiscRegs;
 
 typedef union {
index 7be195b8defec7671767d1b324b37f09375563ad..fa2a1d89bfc8708708ce03a6ddd396c2e2d79064 100644 (file)
@@ -51,6 +51,9 @@ copyRegs(ThreadContext *src, ThreadContext *dest)
     // Would need to add condition-code regs if implemented
     assert(NumCCRegs == 0);
 
+    // Copy vector registers when vector registers put to use.
+    assert(NumVectorRegs == 0);
+
     // Copy misc. registers
     copyMiscRegs(src, dest);
 
index 1d2a457d20d00130f62029f6bc2e0349f56b1db9..51e797c9025640912a9367d46ba486cf60d67e90 100644 (file)
@@ -211,6 +211,13 @@ class ISA : public SimObject
         return reg;
     }
 
+    // dummy
+    int
+    flattenVectorIndex(int reg) const
+    {
+        return reg;
+    }
+
     int
     flattenMiscIndex(int reg) const
     {
index b25f34584339b17fe53aeab6617d5fd9901c8683..a59139ba2750c6cb3093efebb1834129cbefbc0e 100644 (file)
@@ -51,6 +51,11 @@ typedef uint32_t FloatRegBits;
 
 // dummy typedef since we don't have CC regs
 typedef uint8_t CCReg;
+// vector register file entry type
+typedef uint64_t VectorRegElement;
+const int NumVectorRegElements = 0;
+const int VectorRegBytes = NumVectorRegElements * sizeof(VectorRegElement);
+typedef std::array<VectorRegElement, NumVectorRegElements> VectorReg;
 
 typedef union
 {
@@ -75,6 +80,7 @@ const int SyscallPseudoReturnReg = 9;
 const int NumIntArchRegs = 32;
 const int NumIntRegs = (MaxGL + 1) * 8 + NWindows * 16 + NumMicroIntRegs;
 const int NumCCRegs = 0;
+const int NumVectorRegs = 0;
 
 const int TotalNumRegs = NumIntRegs + NumFloatRegs + NumMiscRegs;
 
@@ -82,7 +88,8 @@ const int TotalNumRegs = NumIntRegs + NumFloatRegs + NumMiscRegs;
 enum DependenceTags {
     FP_Reg_Base = NumIntRegs,
     CC_Reg_Base = FP_Reg_Base + NumFloatRegs,
-    Misc_Reg_Base = CC_Reg_Base + NumCCRegs, // NumCCRegs == 0
+    Vector_Reg_Base = CC_Reg_Base + NumCCRegs, // NumCCRegs == 0
+    Misc_Reg_Base = Vector_Reg_Base + NumVectorRegs, // NumVectorRegs == 0
     Max_Reg_Index = Misc_Reg_Base + NumMiscRegs,
 };
 
index 34d4f79b350c936d3ebfce242143f13837bbb3c4..6d7a1ba954226371e13db58b232a2a251ac5f0c9 100644 (file)
@@ -237,6 +237,9 @@ copyRegs(ThreadContext *src, ThreadContext *dest)
     // Would need to add condition-code regs if implemented
     assert(NumCCRegs == 0);
 
+    // Copy vector registers when vector registers put to use.
+    assert(NumVectorRegs == 0);
+
     // Copy misc. registers
     copyMiscRegs(src, dest);
 
index 39091289fc199e2d66df2eca7d7e7b208f89450e..49ea6ef4eb0bd7931ecc2b113e3cb1506a20601b 100644 (file)
@@ -225,12 +225,19 @@ namespace X86ISA
             ccprintf(os, "%%cc%d", rel_reg);
             break;
 
+          case VectorRegClass:
+            ccprintf(os, "%%cc%d", rel_reg);
+            break;
+
           case MiscRegClass:
             switch (rel_reg) {
               default:
                 ccprintf(os, "%%ctrl%d", rel_reg);
             }
             break;
+
+          default:
+            panic("Invalid register class!\n");
         }
     }
 
index 88f4980aeee5e09c0edec6806d3bda97e0c3ef49..779241c55045d4c5dd15f8e15fa0fb6f6e1219b5 100644 (file)
@@ -91,6 +91,12 @@ namespace X86ISA
             return reg;
         }
 
+        int
+        flattenVectorIndex(int reg) const
+        {
+            return reg;
+        }
+
         int
         flattenMiscIndex(int reg) const
         {
index ebd88136e6ae793b372d7e42185e09f4458a5056..ad40fe17ff6160469e9d8b10a6ccdf9b8faa6287 100644 (file)
@@ -57,6 +57,7 @@ const int NumMiscRegs = NUM_MISCREGS;
 const int NumIntArchRegs = NUM_INTREGS;
 const int NumIntRegs = NumIntArchRegs + NumMicroIntRegs + NumImplicitIntRegs;
 const int NumCCRegs = NUM_CCREGS;
+const int NumVectorRegs = 0;
 
 #define ISA_HAS_CC_REGS
 
@@ -72,7 +73,8 @@ enum DependenceTags {
     // we just start at (1 << 7) == 128.
     FP_Reg_Base = 128,
     CC_Reg_Base = FP_Reg_Base + NumFloatRegs,
-    Misc_Reg_Base = CC_Reg_Base + NumCCRegs,
+    Vector_Reg_Base = CC_Reg_Base + NumCCRegs,
+    Misc_Reg_Base = Vector_Reg_Base + NumVectorRegs,
     Max_Reg_Index = Misc_Reg_Base + NumMiscRegs
 };
 
@@ -91,6 +93,13 @@ const int SyscallPseudoReturnReg = INTREG_RDX;
 
 typedef uint64_t IntReg;
 typedef uint64_t CCReg;
+
+// vector register file entry type
+typedef uint64_t VectorRegElement;
+const int NumVectorRegElements = 0;
+const int VectorRegBytes = NumVectorRegElements * sizeof(VectorRegElement);
+typedef std::array<VectorRegElement, NumVectorRegElements> VectorReg;
+
 //XXX Should this be a 128 bit structure for XMM memory ops?
 typedef uint64_t LargestRead;
 typedef uint64_t MiscReg;
index f7d0f816e1e4ed92f8f5d3c4ac29a91cb547fef1..e1be61180935ae7b749283b2994be62db6db48ca 100644 (file)
@@ -245,6 +245,10 @@ copyRegs(ThreadContext *src, ThreadContext *dest)
     //copy condition-code regs
     for (int i = 0; i < NumCCRegs; ++i)
          dest->setCCRegFlat(i, src->readCCRegFlat(i));
+
+    // copy vector regs when added to the architecture
+    assert(NumVectorRegs == 0);
+
     copyMiscRegs(src, dest);
     dest->pcState(src->pcState());
 }
index ef29726fc41907579d90adb95c62d196daaf2d8d..3b00e5df874d9efa460038b1c700ee1283c60c5a 100644 (file)
@@ -55,8 +55,8 @@ class StaticInstFlags(Enum):
     vals = [
         'IsNop',            # Is a no-op (no effect at all).
 
-        'IsInteger',        # References integer regs.
-        'IsFloating',       # References FP regs.
+        'IsInteger',        # References scalar integer regs.
+        'IsFloating',       # References scalar FP regs.
         'IsCC',             # References CC regs.
 
         'IsMemRef',         # References memory (load, store, or prefetch)
@@ -108,5 +108,6 @@ class StaticInstFlags(Enum):
         'IsMicroBranch',    # This microop branches within the microcode for
                             # a macroop
         'IsDspOp',
-        'IsSquashAfter'     # Squash all uncommitted state after executed
+        'IsSquashAfter',     # Squash all uncommitted state after executed
+        'IsVector',         # References vector register.
         ]
index 5b54679c9b98b3afb6912511a6c0a3ade7053a89..515df6821d838c02d8401d4e5ce3482873aca141 100644 (file)
@@ -99,10 +99,19 @@ class BaseDynInst : public ExecContext, public RefCounted
     union Result {
         uint64_t integer;
         double dbl;
+
+        // I am assuming that vector register type is different from the two
+        // types used above.  Else it seems useless to have a separate typedef
+        // for vector registers.
+        VectorReg vector;
+
         void set(uint64_t i) { integer = i; }
         void set(double d) { dbl = d; }
+        void set(const VectorReg &v) { vector = v; }
+
         void get(uint64_t& i) { i = integer; }
         void get(double& d) { d = dbl; }
+        void get(VectorReg& v) { v = vector; }
     };
 
   protected:
@@ -521,6 +530,9 @@ class BaseDynInst : public ExecContext, public RefCounted
     bool isDataPrefetch() const { return staticInst->isDataPrefetch(); }
     bool isInteger()      const { return staticInst->isInteger(); }
     bool isFloating()     const { return staticInst->isFloating(); }
+    bool isVector()       const { return staticInst->isVector(); }
+    bool isCC()           const { return staticInst->isCC(); }
+
     bool isControl()      const { return staticInst->isControl(); }
     bool isCall()         const { return staticInst->isCall(); }
     bool isReturn()       const { return staticInst->isReturn(); }
@@ -550,6 +562,11 @@ class BaseDynInst : public ExecContext, public RefCounted
     bool isFirstMicroop() const { return staticInst->isFirstMicroop(); }
     bool isMicroBranch() const { return staticInst->isMicroBranch(); }
 
+    void printFlags(std::ostream &outs, const std::string &separator) const
+    { staticInst->printFlags(outs, separator); }
+
+    std::string getName() const { return staticInst->getName(); }
+
     /** Temporarily sets this instruction as a serialize before instruction. */
     void setSerializeBefore() { status.set(SerializeBefore); }
 
@@ -596,6 +613,8 @@ class BaseDynInst : public ExecContext, public RefCounted
     int8_t numFPDestRegs()  const { return staticInst->numFPDestRegs(); }
     int8_t numIntDestRegs() const { return staticInst->numIntDestRegs(); }
     int8_t numCCDestRegs() const { return staticInst->numCCDestRegs(); }
+    int8_t numVectorDestRegs() const
+    { return staticInst->numVectorDestRegs(); }
 
     /** Returns the logical register index of the i'th destination register. */
     RegIndex destRegIdx(int i) const { return staticInst->destRegIdx(i); }
@@ -655,6 +674,13 @@ class BaseDynInst : public ExecContext, public RefCounted
         setResult<uint64_t>(val);
     }
 
+    /** Records a vector register being set to a value. */
+    void setVectorRegOperand(const StaticInst *si, int idx,
+                             const VectorReg &val)
+    {
+        setResult<const VectorReg &>(val);
+    }
+
     /** Records that one of the source registers is ready. */
     void markSrcRegReady();
 
index a363b6d0f6694c21716b166ce4988fcd9d3adb6d..6d75f7c12343c9d9de8a3e0a52b21f44eba57439 100644 (file)
@@ -94,6 +94,7 @@ class CheckerCPU : public BaseCPU, public ExecContext
     typedef TheISA::FloatReg FloatReg;
     typedef TheISA::FloatRegBits FloatRegBits;
     typedef TheISA::MiscReg MiscReg;
+    typedef TheISA::VectorReg VectorReg;
 
     /** id attached to all issued requests */
     MasterID masterId;
@@ -145,10 +146,19 @@ class CheckerCPU : public BaseCPU, public ExecContext
     union Result {
         uint64_t integer;
         double dbl;
+
+        // I am assuming that vector register type is different from the two
+        // types used above.  Else it seems useless to have a separate typedef
+        // for vector registers.
+        VectorReg vector;
+
         void set(uint64_t i) { integer = i; }
         void set(double d) { dbl = d; }
+        void set(const VectorReg &v) { vector = v; }
+
         void get(uint64_t& i) { i = integer; }
         void get(double& d) { d = dbl; }
+        void get(VectorReg& v) { v = vector; }
     };
 
     // ISAs like ARM can have multiple destination registers to check,
@@ -231,6 +241,11 @@ class CheckerCPU : public BaseCPU, public ExecContext
         return thread->readCCReg(reg_idx);
     }
 
+    const VectorReg &readVectorRegOperand(const StaticInst *si, int idx)
+    {
+        return thread->readVectorReg(si->srcRegIdx(idx));
+    }
+
     template <class T>
     void setResult(T t)
     {
@@ -267,6 +282,13 @@ class CheckerCPU : public BaseCPU, public ExecContext
         setResult<uint64_t>(val);
     }
 
+    void setVectorRegOperand(const StaticInst *si, int idx,
+                             const VectorReg &val)
+    {
+        thread->setVectorReg(si->destRegIdx(idx), val);
+        setResult<VectorReg>(val);
+    }
+
     bool readPredicate() { return thread->readPredicate(); }
     void setPredicate(bool val)
     {
@@ -441,7 +463,7 @@ class Checker : public CheckerCPU
     void validateExecution(DynInstPtr &inst);
     void validateState();
 
-    void copyResult(DynInstPtr &inst, uint64_t mismatch_val, int start_idx);
+    void copyResult(DynInstPtr &inst, Result mismatch_val, int start_idx);
     void handlePendingInt();
 
   private:
index 289861521508bfe89f3b5026c1b763db6ffd3808..d6a467358da1874ccb5b2789c317fb9f9ffb2685 100644 (file)
@@ -491,7 +491,9 @@ Checker<Impl>::validateExecution(DynInstPtr &inst)
         // Unverifiable instructions assume they were executed
         // properly by the CPU. Grab the result from the
         // instruction and write it to the register.
-        copyResult(inst, 0, idx);
+        Result r;
+        r.integer = 0;
+        copyResult(inst, r, idx);
     } else if (inst->numDestRegs() > 0 && !result.empty()) {
         DPRINTF(Checker, "Dest regs %d, number of checker dest regs %d\n",
                          inst->numDestRegs(), result.size());
@@ -525,7 +527,9 @@ Checker<Impl>::validateExecution(DynInstPtr &inst)
         // The load/store queue in Detailed CPU can also cause problems
         // if load/store forwarding is allowed.
         if (inst->isLoad() && warnOnlyOnLoadError) {
-            copyResult(inst, inst_val, idx);
+            Result r;
+            r.integer = inst_val;
+            copyResult(inst, r, idx);
         } else {
             handleError(inst);
         }
@@ -590,7 +594,7 @@ Checker<Impl>::validateState()
 
 template <class Impl>
 void
-Checker<Impl>::copyResult(DynInstPtr &inst, uint64_t mismatch_val,
+Checker<Impl>::copyResult(DynInstPtr &inst, Result mismatch_val,
                           int start_idx)
 {
     // We've already popped one dest off the queue,
@@ -599,39 +603,65 @@ Checker<Impl>::copyResult(DynInstPtr &inst, uint64_t mismatch_val,
         RegIndex idx = inst->destRegIdx(start_idx);
         switch (regIdxToClass(idx)) {
           case IntRegClass:
-            thread->setIntReg(idx, mismatch_val);
+            thread->setIntReg(idx, mismatch_val.integer);
             break;
           case FloatRegClass:
-            thread->setFloatRegBits(idx - TheISA::FP_Reg_Base, mismatch_val);
+            thread->setFloatRegBits(idx - TheISA::FP_Reg_Base,
+                    mismatch_val.integer);
             break;
           case CCRegClass:
-            thread->setCCReg(idx - TheISA::CC_Reg_Base, mismatch_val);
+            thread->setCCReg(idx - TheISA::CC_Reg_Base, mismatch_val.integer);
+            break;
+          case VectorRegClass:
+            thread->setVectorReg(idx - TheISA::Vector_Reg_Base,
+                    mismatch_val.vector);
             break;
           case MiscRegClass:
             thread->setMiscReg(idx - TheISA::Misc_Reg_Base,
-                               mismatch_val);
+                               mismatch_val.integer);
             break;
         }
     }
+
     start_idx++;
-    uint64_t res = 0;
     for (int i = start_idx; i < inst->numDestRegs(); i++) {
         RegIndex idx = inst->destRegIdx(i);
-        inst->template popResult<uint64_t>(res);
         switch (regIdxToClass(idx)) {
-          case IntRegClass:
-            thread->setIntReg(idx, res);
-            break;
-          case FloatRegClass:
-            thread->setFloatRegBits(idx - TheISA::FP_Reg_Base, res);
-            break;
-          case CCRegClass:
-            thread->setCCReg(idx - TheISA::CC_Reg_Base, res);
-            break;
-          case MiscRegClass:
-            // Try to get the proper misc register index for ARM here...
-            thread->setMiscReg(idx - TheISA::Misc_Reg_Base, res);
-            break;
+          case IntRegClass: {
+              uint64_t res = 0;
+              inst->template popResult<uint64_t>(res);
+              thread->setIntReg(idx, res);
+          }
+          break;
+
+          case FloatRegClass: {
+              uint64_t res = 0;
+              inst->template popResult<uint64_t>(res);
+              thread->setFloatRegBits(idx - TheISA::FP_Reg_Base, res);
+          }
+          break;
+
+          case CCRegClass: {
+              uint64_t res = 0;
+              inst->template popResult<uint64_t>(res);
+              thread->setCCReg(idx - TheISA::CC_Reg_Base, res);
+          }
+          break;
+
+          case VectorRegClass: {
+              VectorReg res;
+              inst->template popResult<VectorReg>(res);
+              thread->setVectorReg(idx - TheISA::Vector_Reg_Base, res);
+          }
+          break;
+
+          case MiscRegClass: {
+              // Try to get the proper misc register index for ARM here...
+              uint64_t res = 0;
+              inst->template popResult<uint64_t>(res);
+              thread->setMiscReg(idx - TheISA::Misc_Reg_Base, res);
+          }
+          break;
             // else Register is out of range...
         }
     }
index 71c231ba0e5ebe053f058e52c2c13b5937aab3a7..436c9784712384ae1257a47c3e5ae8d125bc8dfe 100644 (file)
@@ -216,6 +216,9 @@ class CheckerThreadContext : public ThreadContext
     CCReg readCCReg(int reg_idx)
     { return actualTC->readCCReg(reg_idx); }
 
+    const VectorReg &readVectorReg(int reg_idx)
+    { return actualTC->readVectorReg(reg_idx); }
+
     void setIntReg(int reg_idx, uint64_t val)
     {
         actualTC->setIntReg(reg_idx, val);
@@ -240,6 +243,12 @@ class CheckerThreadContext : public ThreadContext
         checkerTC->setCCReg(reg_idx, val);
     }
 
+    void setVectorReg(int reg_idx, const VectorReg &val)
+    {
+        actualTC->setVectorReg(reg_idx, val);
+        checkerTC->setVectorReg(reg_idx, val);
+    }
+
     /** Reads this thread's PC state. */
     TheISA::PCState pcState()
     { return actualTC->pcState(); }
@@ -296,6 +305,7 @@ class CheckerThreadContext : public ThreadContext
     int flattenIntIndex(int reg) { return actualTC->flattenIntIndex(reg); }
     int flattenFloatIndex(int reg) { return actualTC->flattenFloatIndex(reg); }
     int flattenCCIndex(int reg) { return actualTC->flattenCCIndex(reg); }
+    int flattenVectorIndex(int reg) { return actualTC->flattenVectorIndex(reg); }
     int flattenMiscIndex(int reg) { return actualTC->flattenMiscIndex(reg); }
 
     unsigned readStCondFailures()
@@ -331,6 +341,12 @@ class CheckerThreadContext : public ThreadContext
 
     void setCCRegFlat(int idx, CCReg val)
     { actualTC->setCCRegFlat(idx, val); }
+
+    const VectorReg &readVectorRegFlat(int idx)
+    { return actualTC->readVectorRegFlat(idx); }
+
+    void setVectorRegFlat(int idx, const VectorReg &val)
+    { actualTC->setVectorRegFlat(idx, val); }
 };
 
 #endif // __CPU_CHECKER_EXEC_CONTEXT_HH__
index c65841db2152a0bc36ca1fccf3426d3bcb8379f5..5c6b3fad7c8831e8b9c1559b5a9d15b999858ace 100644 (file)
@@ -76,6 +76,7 @@ class ExecContext {
     typedef TheISA::MiscReg MiscReg;
 
     typedef TheISA::CCReg CCReg;
+    typedef TheISA::VectorReg VectorReg;
 
   public:
     /**
@@ -126,6 +127,22 @@ class ExecContext {
     virtual void setCCRegOperand(const StaticInst *si, int idx, CCReg val) = 0;
     /** @} */
 
+    /**
+     * @{
+     * @name Vector Register Interfaces
+     *
+     */
+
+    /** Reads a vector register. */
+    virtual const VectorReg &readVectorRegOperand (const StaticInst *si,
+                                                   int idx) = 0;
+
+    /** Sets a vector register to a value. */
+    virtual void setVectorRegOperand(const StaticInst *si,
+                                     int idx, const VectorReg &val) = 0;
+
+    /** @} */
+
     /**
      * @{
      * @name Misc Register Interfaces
index ab08e6b4aa69fc60ba93314d0e02af9f4e434084..03cf785ef65edaa92d57b6e290a61395c32ecfec 100644 (file)
@@ -157,6 +157,8 @@ printRegName(std::ostream &os, TheISA::RegIndex reg)
         break;
       case CCRegClass:
         os << 'c' << static_cast<unsigned int>(reg - TheISA::CC_Reg_Base);
+      case VectorRegClass:
+        os << 'v' << static_cast<unsigned int>(reg - TheISA::Vector_Reg_Base);
     }
 }
 
index 80d5d98720b624b26d90945b33dfb42c0cbd5793..6ea74047c74adda258f2c9c4c9c6509bf6d6704a 100644 (file)
@@ -140,6 +140,20 @@ class ExecContext : public ::ExecContext
         return thread.readFloatRegBits(reg_idx);
     }
 
+    TheISA::CCReg
+    readCCRegOperand(const StaticInst *si, int idx)
+    {
+        int reg_idx = si->srcRegIdx(idx) - TheISA::CC_Reg_Base;
+        return thread.readCCReg(reg_idx);
+    }
+
+    const TheISA::VectorReg &
+    readVectorRegOperand(const StaticInst *si, int idx)
+    {
+        int reg_idx = si->srcRegIdx(idx) - TheISA::Vector_Reg_Base;
+        return thread.readVectorReg(reg_idx);
+    }
+
     void
     setIntRegOperand(const StaticInst *si, int idx, IntReg val)
     {
@@ -162,6 +176,21 @@ class ExecContext : public ::ExecContext
         thread.setFloatRegBits(reg_idx, val);
     }
 
+    void
+    setCCRegOperand(const StaticInst *si, int idx, TheISA::CCReg val)
+    {
+        int reg_idx = si->destRegIdx(idx) - TheISA::CC_Reg_Base;
+        thread.setCCReg(reg_idx, val);
+    }
+
+    void
+    setVectorRegOperand(const StaticInst *si, int idx,
+                        const TheISA::VectorReg &val)
+    {
+        int reg_idx = si->destRegIdx(idx) - TheISA::Vector_Reg_Base;
+        thread.setVectorReg(reg_idx, val);
+    }
+
     bool
     readPredicate()
     {
@@ -265,20 +294,6 @@ class ExecContext : public ::ExecContext
         thread.getDTBPtr()->demapPage(vaddr, asn);
     }
 
-    TheISA::CCReg
-    readCCRegOperand(const StaticInst *si, int idx)
-    {
-        int reg_idx = si->srcRegIdx(idx) - TheISA::CC_Reg_Base;
-        return thread.readCCReg(reg_idx);
-    }
-
-    void
-    setCCRegOperand(const StaticInst *si, int idx, TheISA::CCReg val)
-    {
-        int reg_idx = si->destRegIdx(idx) - TheISA::CC_Reg_Base;
-        thread.setCCReg(reg_idx, val);
-    }
-
     void
     demapInstPage(Addr vaddr, uint64_t asn)
     {
index f6b1f7944a6d0638c171418770f4183c5a465c83..3eb09271a189455346d01119b0a769119ed618b8 100644 (file)
@@ -71,6 +71,11 @@ Scoreboard::findIndex(RegIndex reg, Index &scoreboard_index)
             scoreboard_index = TheISA::NumIntRegs + reg - TheISA::FP_Reg_Base;
             ret = true;
             break;
+          case VectorRegClass:
+            scoreboard_index = TheISA::NumIntRegs + TheISA::NumCCRegs +
+                    TheISA::NumFloatRegs + reg - TheISA::Vector_Reg_Base;
+            ret = true;
+            break;
           case MiscRegClass:
               /* Don't bother with Misc registers */
             ret = false;
@@ -99,6 +104,9 @@ flattenRegIndex(TheISA::RegIndex reg, ThreadContext *thread_context)
       case CCRegClass:
         ret = thread_context->flattenCCIndex(reg);
         break;
+      case VectorRegClass:
+        ret = thread_context->flattenVectorIndex(reg);
+        break;
       case MiscRegClass:
         /* Don't bother to flatten misc regs as we don't need them here */
         /* return thread_context->flattenMiscIndex(reg); */
index 711bcafb2021189dd5dc3d4a2de342a81a6946dc..3a3a9d3c35fa7c82a51341ee4e07191860977d16 100644 (file)
@@ -60,11 +60,13 @@ class Scoreboard : public Named
 {
   public:
     /** The number of registers in the Scoreboard.  These
-     *  are just the integer, CC and float registers packed
+     *  are just the integer, CC, float and vector registers packed
      *  together with integer regs in the range [0,NumIntRegs-1],
-     *  CC regs in the range [NumIntRegs, NumIntRegs+NumCCRegs-1]
-     *  and float regs in the range
-     *  [NumIntRegs+NumCCRegs, NumFloatRegs+NumIntRegs+NumCCRegs-1] */
+     *  CC regs in the range [NumIntRegs, NumIntRegs + NumCCRegs - 1],
+     *  float regs in the range
+     *  [NumIntRegs + NumCCRegs, NumFloatRegs + NumIntRegs + NumCCRegs - 1]
+     *  and vector regs in the range [NumFloatRegs + NumIntRegs + NumCCRegs,
+     *  NumFloatRegs + NumIntRegs + NumCCRegs + NumVectorRegs - 1]*/
     const unsigned numRegs;
 
     /** Type to use for thread context registers */
@@ -97,7 +99,7 @@ class Scoreboard : public Named
     Scoreboard(const std::string &name) :
         Named(name),
         numRegs(TheISA::NumIntRegs + TheISA::NumCCRegs +
-            TheISA::NumFloatRegs),
+            TheISA::NumFloatRegs + TheISA::NumVectorRegs),
         numResults(numRegs, 0),
         numUnpredictableResults(numRegs, 0),
         fuIndices(numRegs, 0),
index 92f96a3b634afe0c4f3b1e9d3530cb2a27eb5124..d2220de8258e5b693c559079bed0892e9244d777 100644 (file)
@@ -114,6 +114,7 @@ class DerivO3CPU(BaseCPU):
     numPhysIntRegs = Param.Unsigned(256, "Number of physical integer registers")
     numPhysFloatRegs = Param.Unsigned(256, "Number of physical floating point "
                                       "registers")
+
     # most ISAs don't use condition-code regs, so default is 0
     _defaultNumPhysCCRegs = 0
     if buildEnv['TARGET_ISA'] in ('arm','x86'):
@@ -126,6 +127,12 @@ class DerivO3CPU(BaseCPU):
         _defaultNumPhysCCRegs = Self.numPhysIntRegs * 5
     numPhysCCRegs = Param.Unsigned(_defaultNumPhysCCRegs,
                                    "Number of physical cc registers")
+
+    # most ISAs don't use vector regs, so default is 0
+    _defaultNumPhysVectorRegs = 0
+    numPhysVectorRegs = Param.Unsigned(_defaultNumPhysVectorRegs,
+                                   "Number of physical vector registers")
+
     numIQEntries = Param.Unsigned(64, "Number of instruction queue entries")
     numROBEntries = Param.Unsigned(192, "Number of reorder buffer entries")
 
index 026907a9410386b667c0165e02110d7c9f56052c..d8f39bbe4d52379dacf62b3f7bb95d0ac3d53da2 100644 (file)
@@ -170,7 +170,8 @@ FullO3CPU<Impl>::FullO3CPU(DerivO3CPUParams *params)
 
       regFile(params->numPhysIntRegs,
               params->numPhysFloatRegs,
-              params->numPhysCCRegs),
+              params->numPhysCCRegs,
+              params->numPhysVectorRegs),
 
       freeList(name() + ".freelist", &regFile),
 
@@ -269,6 +270,7 @@ FullO3CPU<Impl>::FullO3CPU(DerivO3CPUParams *params)
     assert(params->numPhysIntRegs   >= numThreads * TheISA::NumIntRegs);
     assert(params->numPhysFloatRegs >= numThreads * TheISA::NumFloatRegs);
     assert(params->numPhysCCRegs >= numThreads * TheISA::NumCCRegs);
+    assert(params->numPhysVectorRegs >= numThreads * TheISA::NumVectorRegs);
 
     rename.setScoreboard(&scoreboard);
     iew.setScoreboard(&scoreboard);
@@ -313,6 +315,12 @@ FullO3CPU<Impl>::FullO3CPU(DerivO3CPUParams *params)
             renameMap[tid].setCCEntry(ridx, phys_reg);
             commitRenameMap[tid].setCCEntry(ridx, phys_reg);
         }
+
+        for (RegIndex ridx = 0; ridx < TheISA::NumVectorRegs; ++ridx) {
+            PhysRegIndex phys_reg = freeList.getVectorReg();
+            renameMap[tid].setVectorEntry(ridx, phys_reg);
+            commitRenameMap[tid].setVectorEntry(ridx, phys_reg);
+        }
     }
 
     rename.setRenameMap(renameMap);
@@ -521,6 +529,16 @@ FullO3CPU<Impl>::regStats()
         .desc("number of cc regfile writes")
         .prereq(ccRegfileWrites);
 
+    vectorRegfileReads
+        .name(name() + ".vector_regfile_reads")
+        .desc("number of vector regfile reads")
+        .prereq(vectorRegfileReads);
+
+    vectorRegfileWrites
+        .name(name() + ".vector_regfile_writes")
+        .desc("number of vector regfile writes")
+        .prereq(vectorRegfileWrites);
+
     miscRegfileReads
         .name(name() + ".misc_regfile_reads")
         .desc("number of misc regfile reads")
@@ -807,6 +825,18 @@ FullO3CPU<Impl>::insertThread(ThreadID tid)
         scoreboard.setReg(phys_reg);
     }
 
+    //Bind vector Regs to Rename Map
+    max_reg = TheISA::NumIntRegs + TheISA::NumFloatRegs + TheISA::NumCCRegs +
+              TheISA::NumVectorRegs;
+    for (int vreg = TheISA::NumIntRegs + TheISA::NumFloatRegs +
+                    TheISA::NumCCRegs;
+         vreg < max_reg; vreg++) {
+        PhysRegIndex phys_reg = freeList.getVectorReg();
+
+        renameMap[tid].setEntry(vreg, phys_reg);
+        scoreboard.setReg(phys_reg);
+    }
+
     //Copy Thread Data Into RegFile
     //this->copyFromTC(tid);
 
@@ -860,6 +890,14 @@ FullO3CPU<Impl>::removeThread(ThreadID tid)
         freeList.addReg(phys_reg);
     }
 
+    // Unbind condition-code Regs from Rename Map
+    max_reg = TheISA::Vector_Reg_Base + TheISA::NumVectorRegs;
+    for (int vreg = TheISA::Vector_Reg_Base; vreg < max_reg; vreg++) {
+        PhysRegIndex phys_reg = renameMap[tid].lookup(vreg);
+        scoreboard.unsetReg(phys_reg);
+        freeList.addReg(phys_reg);
+    }
+
     // Squash Throughout Pipeline
     DynInstPtr inst = commit.rob->readHeadInst(tid);
     InstSeqNum squash_seq_num = inst->seqNum;
@@ -1258,6 +1296,14 @@ FullO3CPU<Impl>::readCCReg(int reg_idx)
     return regFile.readCCReg(reg_idx);
 }
 
+template <class Impl>
+const VectorReg &
+FullO3CPU<Impl>::readVectorReg(int reg_idx)
+{
+    vectorRegfileReads++;
+    return regFile.readVectorReg(reg_idx);
+}
+
 template <class Impl>
 void
 FullO3CPU<Impl>::setIntReg(int reg_idx, uint64_t val)
@@ -1290,6 +1336,14 @@ FullO3CPU<Impl>::setCCReg(int reg_idx, CCReg val)
     regFile.setCCReg(reg_idx, val);
 }
 
+template <class Impl>
+void
+FullO3CPU<Impl>::setVectorReg(int reg_idx, const VectorReg &val)
+{
+    vectorRegfileWrites++;
+    regFile.setVectorReg(reg_idx, val);
+}
+
 template <class Impl>
 uint64_t
 FullO3CPU<Impl>::readArchIntReg(int reg_idx, ThreadID tid)
@@ -1330,6 +1384,16 @@ FullO3CPU<Impl>::readArchCCReg(int reg_idx, ThreadID tid)
     return regFile.readCCReg(phys_reg);
 }
 
+template <class Impl>
+const VectorReg&
+FullO3CPU<Impl>::readArchVectorReg(int reg_idx, ThreadID tid)
+{
+    vectorRegfileReads++;
+    PhysRegIndex phys_reg = commitRenameMap[tid].lookupVector(reg_idx);
+
+    return regFile.readVectorReg(phys_reg);
+}
+
 template <class Impl>
 void
 FullO3CPU<Impl>::setArchIntReg(int reg_idx, uint64_t val, ThreadID tid)
@@ -1370,6 +1434,16 @@ FullO3CPU<Impl>::setArchCCReg(int reg_idx, CCReg val, ThreadID tid)
     regFile.setCCReg(phys_reg, val);
 }
 
+template <class Impl>
+void
+FullO3CPU<Impl>::setArchVectorReg(int reg_idx, const VectorReg &val,
+                                  ThreadID tid)
+{
+    vectorRegfileWrites++;
+    PhysRegIndex phys_reg = commitRenameMap[tid].lookupVector(reg_idx);
+    regFile.setVectorReg(phys_reg, val);
+}
+
 template <class Impl>
 TheISA::PCState
 FullO3CPU<Impl>::pcState(ThreadID tid)
index aa02ee2ea17a40d1bc8900dc01c3698d87e7c92c..f16450d19a703e59e7631c8da8dd72b925c04e39 100644 (file)
@@ -427,6 +427,8 @@ class FullO3CPU : public BaseO3CPU
 
     TheISA::CCReg readCCReg(int reg_idx);
 
+    const TheISA::VectorReg &readVectorReg(int reg_idx);
+
     void setIntReg(int reg_idx, uint64_t val);
 
     void setFloatReg(int reg_idx, TheISA::FloatReg val);
@@ -435,6 +437,8 @@ class FullO3CPU : public BaseO3CPU
 
     void setCCReg(int reg_idx, TheISA::CCReg val);
 
+    void setVectorReg(int reg_idx, const TheISA::VectorReg &val);
+
     uint64_t readArchIntReg(int reg_idx, ThreadID tid);
 
     float readArchFloatReg(int reg_idx, ThreadID tid);
@@ -443,6 +447,8 @@ class FullO3CPU : public BaseO3CPU
 
     TheISA::CCReg readArchCCReg(int reg_idx, ThreadID tid);
 
+    const TheISA::VectorReg &readArchVectorReg(int reg_idx, ThreadID tid);
+
     /** Architectural register accessors.  Looks up in the commit
      * rename table to obtain the true physical index of the
      * architected register first, then accesses that physical
@@ -456,6 +462,9 @@ class FullO3CPU : public BaseO3CPU
 
     void setArchCCReg(int reg_idx, TheISA::CCReg val, ThreadID tid);
 
+    void setArchVectorReg(int reg_idx, const TheISA::VectorReg &val,
+                          ThreadID tid);
+
     /** Sets the commit PC state of a specific thread. */
     void pcState(const TheISA::PCState &newPCState, ThreadID tid);
 
@@ -734,6 +743,9 @@ class FullO3CPU : public BaseO3CPU
     //number of CC register file accesses
     Stats::Scalar ccRegfileReads;
     Stats::Scalar ccRegfileWrites;
+    //number of integer register file accesses
+    Stats::Scalar vectorRegfileReads;
+    Stats::Scalar vectorRegfileWrites;
     //number of misc
     Stats::Scalar miscRegfileReads;
     Stats::Scalar miscRegfileWrites;
index 6740c601dc7d5079ce6ec727c7edc5c3fec06fc1..d19e4d46146cdf1ba5a88be4e7874ec5167b4db6 100644 (file)
@@ -74,6 +74,7 @@ class BaseO3DynInst : public BaseDynInst<Impl>
     typedef TheISA::FloatReg FloatReg;
     typedef TheISA::FloatRegBits FloatRegBits;
     typedef TheISA::CCReg   CCReg;
+    typedef TheISA::VectorReg VectorReg;
 
     /** Misc register index type. */
     typedef TheISA::MiscReg  MiscReg;
@@ -206,7 +207,6 @@ class BaseO3DynInst : public BaseDynInst<Impl>
 
     void forwardOldRegs()
     {
-
         for (int idx = 0; idx < this->numDestRegs(); idx++) {
             PhysRegIndex prev_phys_reg = this->prevDestRegIdx(idx);
             TheISA::RegIndex original_dest_reg =
@@ -224,6 +224,11 @@ class BaseO3DynInst : public BaseDynInst<Impl>
                 this->setCCRegOperand(this->staticInst.get(), idx,
                                       this->cpu->readCCReg(prev_phys_reg));
                 break;
+              case VectorRegClass:
+                this->setVectorRegOperand(this->staticInst.get(), idx,
+                        this->cpu->readVectorReg(prev_phys_reg));
+                break;
+
               case MiscRegClass:
                 // no need to forward misc reg values
                 break;
@@ -272,6 +277,11 @@ class BaseO3DynInst : public BaseDynInst<Impl>
         return this->cpu->readCCReg(this->_srcRegIdx[idx]);
     }
 
+    const VectorReg &readVectorRegOperand(const StaticInst *si, int idx)
+    {
+        return this->cpu->readVectorReg(this->_srcRegIdx[idx]);
+    }
+
     /** @todo: Make results into arrays so they can handle multiple dest
      *  registers.
      */
@@ -300,6 +310,13 @@ class BaseO3DynInst : public BaseDynInst<Impl>
         BaseDynInst<Impl>::setCCRegOperand(si, idx, val);
     }
 
+    void setVectorRegOperand(const StaticInst *si, int idx,
+                             const VectorReg &val)
+    {
+        this->cpu->setVectorReg(this->_destRegIdx[idx], val);
+        BaseDynInst<Impl>::setVectorRegOperand(si, idx, val);
+    }
+
 #if THE_ISA == MIPS_ISA
     MiscReg readRegOtherThread(int misc_reg, ThreadID tid)
     {
index aa805e26e0d93fa8744a06ece1657f0b32b12987..d345d7ac81d543384f6154cd1a34a5f82f65bbcf 100644 (file)
@@ -109,6 +109,9 @@ class UnifiedFreeList
     /** The list of free condition-code registers. */
     SimpleFreeList ccList;
 
+    /** The list of free vector registers. */
+    SimpleFreeList vectorList;
+
     /**
      * The register file object is used only to distinguish integer
      * from floating-point physical register indices.
@@ -148,6 +151,9 @@ class UnifiedFreeList
     /** Gets a free cc register. */
     PhysRegIndex getCCReg() { return ccList.getReg(); }
 
+    /** Gets a free vector register. */
+    PhysRegIndex getVectorReg() { return vectorList.getReg(); }
+
     /** Adds a register back to the free list. */
     void addReg(PhysRegIndex freed_reg);
 
@@ -160,6 +166,9 @@ class UnifiedFreeList
     /** Adds a cc register back to the free list. */
     void addCCReg(PhysRegIndex freed_reg) { ccList.addReg(freed_reg); }
 
+    /** Adds a vector register back to the free list. */
+    void addVectorReg(PhysRegIndex freed_reg) { vectorList.addReg(freed_reg); }
+
     /** Checks if there are any free integer registers. */
     bool hasFreeIntRegs() const { return intList.hasFreeRegs(); }
 
@@ -169,6 +178,9 @@ class UnifiedFreeList
     /** Checks if there are any free cc registers. */
     bool hasFreeCCRegs() const { return ccList.hasFreeRegs(); }
 
+    /** Checks if there are any free vector registers. */
+    bool hasFreeVectorRegs() const { return vectorList.hasFreeRegs(); }
+
     /** Returns the number of free integer registers. */
     unsigned numFreeIntRegs() const { return intList.numFreeRegs(); }
 
@@ -177,6 +189,9 @@ class UnifiedFreeList
 
     /** Returns the number of free cc registers. */
     unsigned numFreeCCRegs() const { return ccList.numFreeRegs(); }
+
+    /** Returns the number of free vector registers. */
+    unsigned numFreeVectorRegs() const { return vectorList.numFreeRegs(); }
 };
 
 inline void
@@ -189,9 +204,11 @@ UnifiedFreeList::addReg(PhysRegIndex freed_reg)
         intList.addReg(freed_reg);
     } else if (regFile->isFloatPhysReg(freed_reg)) {
         floatList.addReg(freed_reg);
-    } else {
-        assert(regFile->isCCPhysReg(freed_reg));
+    } else if (regFile->isCCPhysReg(freed_reg)) {
         ccList.addReg(freed_reg);
+    } else {
+        assert(regFile->isVectorPhysReg(freed_reg));
+        vectorList.addReg(freed_reg);
     }
 
     // These assert conditions ensure that the number of free
index 7d359b9922046040f1c1be5a2ba5974cd723a73f..e16843160620ecee7358199de82ed4d3bfb5a238 100644 (file)
@@ -99,7 +99,7 @@ InstructionQueue<Impl>::InstructionQueue(O3CPU *cpu_ptr, IEW *iew_ptr,
 
     // Set the number of total physical registers
     numPhysRegs = params->numPhysIntRegs + params->numPhysFloatRegs +
-        params->numPhysCCRegs;
+        params->numPhysCCRegs + params->numPhysVectorRegs;
 
     //Create an entry for each physical register within the
     //dependency graph.
index 96ce44bddb1e3ea4265315bf56724cfc13b7d8e1..a7476c5ec6d16c8522630e7c0b1463b90c60286a 100644 (file)
 
 PhysRegFile::PhysRegFile(unsigned _numPhysicalIntRegs,
                          unsigned _numPhysicalFloatRegs,
-                         unsigned _numPhysicalCCRegs)
+                         unsigned _numPhysicalCCRegs,
+                         unsigned _numPhysicalVectorRegs)
     : intRegFile(_numPhysicalIntRegs),
       floatRegFile(_numPhysicalFloatRegs),
       ccRegFile(_numPhysicalCCRegs),
+      vectorRegFile(_numPhysicalVectorRegs),
       baseFloatRegIndex(_numPhysicalIntRegs),
       baseCCRegIndex(_numPhysicalIntRegs + _numPhysicalFloatRegs),
+      baseVectorRegIndex(_numPhysicalIntRegs + _numPhysicalFloatRegs
+              + _numPhysicalCCRegs),
       totalNumRegs(_numPhysicalIntRegs
                    + _numPhysicalFloatRegs
-                   + _numPhysicalCCRegs)
+                   + _numPhysicalCCRegs
+                   + _numPhysicalVectorRegs)
 {
     if (TheISA::NumCCRegs == 0 && _numPhysicalCCRegs != 0) {
         // Just make this a warning and go ahead and allocate them
@@ -53,6 +58,13 @@ PhysRegFile::PhysRegFile(unsigned _numPhysicalIntRegs,
         warn("Non-zero number of physical CC regs specified, even though\n"
              "    ISA does not use them.\n");
     }
+
+    if (TheISA::NumVectorRegs == 0 && _numPhysicalVectorRegs != 0) {
+        // Just make this a warning and go ahead and allocate them
+        // anyway, to keep from having to add checks everywhere
+        warn("Non-zero number of physical vector regs specified, even though\n"
+             "    ISA does not use them.\n");
+    }
 }
 
 
@@ -73,9 +85,15 @@ PhysRegFile::initFreeList(UnifiedFreeList *freeList)
         freeList->addFloatReg(reg_idx++);
     }
 
-    // The rest of the registers are the condition-code physical
+    // The next batch of registers are the condition-code physical
     // registers; put them onto the condition-code free list.
-    while (reg_idx < totalNumRegs) {
+    while (reg_idx < baseVectorRegIndex) {
         freeList->addCCReg(reg_idx++);
     }
+
+    // The rest of the registers are the vector physical
+    // registers; put them onto the vector free list.
+    while (reg_idx < totalNumRegs) {
+        freeList->addVectorReg(reg_idx++);
+    }
 }
index 8b87725caa2f33b58d916b6dd0aad40d8ff2665a..71ca5015f9484121461d5feb71ed360e13a1fe95 100644 (file)
@@ -56,6 +56,7 @@ class PhysRegFile
     typedef TheISA::FloatReg FloatReg;
     typedef TheISA::FloatRegBits FloatRegBits;
     typedef TheISA::CCReg CCReg;
+    typedef TheISA::VectorReg VectorReg;
 
     typedef union {
         FloatReg d;
@@ -71,6 +72,9 @@ class PhysRegFile
     /** Condition-code register file. */
     std::vector<CCReg> ccRegFile;
 
+    /** Vector register file. */
+    std::vector<VectorReg> vectorRegFile;
+
     /**
      * The first floating-point physical register index.  The physical
      * register file has a single continuous index space, with the
@@ -93,6 +97,12 @@ class PhysRegFile
      */
     unsigned baseCCRegIndex;
 
+    /**
+     * The first vector physical register index.  The vector registers follow
+     * the condition-code registers.
+     */
+    unsigned baseVectorRegIndex;
+
     /** Total number of physical registers. */
     unsigned totalNumRegs;
 
@@ -103,7 +113,8 @@ class PhysRegFile
      */
     PhysRegFile(unsigned _numPhysicalIntRegs,
                 unsigned _numPhysicalFloatRegs,
-                unsigned _numPhysicalCCRegs);
+                unsigned _numPhysicalCCRegs,
+                unsigned _numPhysicalVectorRegs);
 
     /**
      * Destructor to free resources
@@ -122,7 +133,11 @@ class PhysRegFile
 
     /** @return the number of condition-code physical registers. */
     unsigned numCCPhysRegs() const
-    { return totalNumRegs - baseCCRegIndex; }
+    { return baseVectorRegIndex - baseCCRegIndex; }
+
+    /** @return the number of vector physical registers. */
+    unsigned numVectorPhysRegs() const
+    { return totalNumRegs - baseVectorRegIndex; }
 
     /** @return the total number of physical registers. */
     unsigned totalNumPhysRegs() const { return totalNumRegs; }
@@ -151,7 +166,16 @@ class PhysRegFile
      */
     bool isCCPhysReg(PhysRegIndex reg_idx)
     {
-        return (baseCCRegIndex <= reg_idx && reg_idx < totalNumRegs);
+        return (baseCCRegIndex <= reg_idx && reg_idx < baseVectorRegIndex);
+    }
+
+    /**
+     * @return true if the specified physical register index
+     * corresponds to a vector physical register.
+     */
+    bool isVectorPhysReg(PhysRegIndex reg_idx) const
+    {
+        return baseVectorRegIndex <= reg_idx && reg_idx < totalNumRegs;
     }
 
     /** Reads an integer register. */
@@ -207,6 +231,18 @@ class PhysRegFile
         return ccRegFile[reg_offset];
     }
 
+    /** Reads a vector register. */
+    const VectorReg &readVectorReg(PhysRegIndex reg_idx) const
+    {
+        assert(isVectorPhysReg(reg_idx));
+
+        // Remove the base vector reg dependency.
+        PhysRegIndex reg_offset = reg_idx - baseVectorRegIndex;
+
+        DPRINTF(IEW, "RegFile: Access to vector register %i\n", int(reg_idx));
+        return vectorRegFile[reg_offset];
+    }
+
     /** Sets an integer register to the given value. */
     void setIntReg(PhysRegIndex reg_idx, uint64_t val)
     {
@@ -262,6 +298,16 @@ class PhysRegFile
 
         ccRegFile[reg_offset] = val;
     }
+
+    /** Sets a vector register to the given value. */
+    void setVectorReg(PhysRegIndex reg_idx, const VectorReg &val)
+    {
+        assert(isVectorPhysReg(reg_idx));
+        // Remove the base vector reg dependency.
+        PhysRegIndex reg_offset = reg_idx - baseVectorRegIndex;
+        DPRINTF(IEW, "RegFile: Setting vector register %i\n", int(reg_idx));
+        vectorRegFile[reg_offset] = val;
+    }
 };
 
 
index 43b7ba9aa18057228be8ae577a34cd2c42d7cd8a..3da6fd4fab7bd6ea684ca2469e1813cc825fc16b 100644 (file)
@@ -69,7 +69,7 @@ DefaultRename<Impl>::DefaultRename(O3CPU *_cpu, DerivO3CPUParams *params)
       commitWidth(params->commitWidth),
       numThreads(params->numThreads),
       maxPhysicalRegs(params->numPhysIntRegs + params->numPhysFloatRegs
-                      + params->numPhysCCRegs)
+                      + params->numPhysCCRegs + params->numPhysVectorRegs)
 {
     if (renameWidth > Impl::MaxWidth)
         fatal("renameWidth (%d) is larger than compiled limit (%d),\n"
@@ -635,7 +635,8 @@ DefaultRename<Impl>::renameInsts(ThreadID tid)
         // to rename to.  Otherwise block.
         if (!renameMap[tid]->canRename(inst->numIntDestRegs(),
                                        inst->numFPDestRegs(),
-                                       inst->numCCDestRegs())) {
+                                       inst->numCCDestRegs(),
+                                       inst->numVectorDestRegs())) {
             DPRINTF(Rename, "Blocking due to lack of free "
                     "physical registers to rename to.\n");
             blockThisCycle = true;
@@ -1016,6 +1017,11 @@ DefaultRename<Impl>::renameSrcRegs(DynInstPtr &inst, ThreadID tid)
             renamed_reg = map->lookupCC(flat_rel_src_reg);
             break;
 
+          case VectorRegClass:
+            flat_rel_src_reg = tc->flattenVectorIndex(rel_src_reg);
+            renamed_reg = map->lookupVector(flat_rel_src_reg);
+            break;
+
           case MiscRegClass:
             // misc regs don't get flattened
             flat_rel_src_reg = rel_src_reg;
@@ -1082,6 +1088,12 @@ DefaultRename<Impl>::renameDestRegs(DynInstPtr &inst, ThreadID tid)
             flat_uni_dest_reg = flat_rel_dest_reg + TheISA::CC_Reg_Base;
             break;
 
+          case VectorRegClass:
+            flat_rel_dest_reg = tc->flattenVectorIndex(rel_dest_reg);
+            rename_result = map->renameVector(flat_rel_dest_reg);
+            flat_uni_dest_reg = flat_rel_dest_reg + TheISA::Vector_Reg_Base;
+            break;
+
           case MiscRegClass:
             // misc regs don't get flattened
             flat_rel_dest_reg = rel_dest_reg;
@@ -1156,7 +1168,7 @@ inline int
 DefaultRename<Impl>::calcFreeLQEntries(ThreadID tid)
 {
         int num_free = freeEntries[tid].lqEntries -
-                                  (loadsInProgress[tid] - fromIEW->iewInfo[tid].dispatchedToLQ);
+                  (loadsInProgress[tid] - fromIEW->iewInfo[tid].dispatchedToLQ);
         DPRINTF(Rename, "calcFreeLQEntries: free lqEntries: %d, loadsInProgress: %d, "
                 "loads dispatchedToLQ: %d\n", freeEntries[tid].lqEntries,
                 loadsInProgress[tid], fromIEW->iewInfo[tid].dispatchedToLQ);
@@ -1168,7 +1180,7 @@ inline int
 DefaultRename<Impl>::calcFreeSQEntries(ThreadID tid)
 {
         int num_free = freeEntries[tid].sqEntries -
-                                  (storesInProgress[tid] - fromIEW->iewInfo[tid].dispatchedToSQ);
+              (storesInProgress[tid] - fromIEW->iewInfo[tid].dispatchedToSQ);
         DPRINTF(Rename, "calcFreeSQEntries: free sqEntries: %d, storesInProgress: %d, "
                 "stores dispatchedToSQ: %d\n", freeEntries[tid].sqEntries,
                 storesInProgress[tid], fromIEW->iewInfo[tid].dispatchedToSQ);
index b0232df2084c1c1fc1779e24982903996fcb59d0..27ddd8c6359085b7bf2c4552236f2b7a269479ce 100644 (file)
@@ -99,6 +99,9 @@ UnifiedRenameMap::init(PhysRegFile *_regFile,
     floatMap.init(TheISA::NumFloatRegs, &(freeList->floatList), _floatZeroReg);
 
     ccMap.init(TheISA::NumCCRegs, &(freeList->ccList), (RegIndex)-1);
+
+    vectorMap.init(TheISA::NumVectorRegs, &(freeList->vectorList),
+                   (RegIndex)-1);
 }
 
 
@@ -117,6 +120,9 @@ UnifiedRenameMap::rename(RegIndex arch_reg)
       case CCRegClass:
         return renameCC(rel_arch_reg);
 
+      case VectorRegClass:
+        return renameVector(rel_arch_reg);
+
       case MiscRegClass:
         return renameMisc(rel_arch_reg);
 
@@ -142,6 +148,9 @@ UnifiedRenameMap::lookup(RegIndex arch_reg) const
       case CCRegClass:
         return lookupCC(rel_arch_reg);
 
+      case VectorRegClass:
+        return lookupVector(rel_arch_reg);
+
       case MiscRegClass:
         return lookupMisc(rel_arch_reg);
 
@@ -166,6 +175,9 @@ UnifiedRenameMap::setEntry(RegIndex arch_reg, PhysRegIndex phys_reg)
       case CCRegClass:
         return setCCEntry(rel_arch_reg, phys_reg);
 
+      case VectorRegClass:
+        return setVectorEntry(rel_arch_reg, phys_reg);
+
       case MiscRegClass:
         // Misc registers do not actually rename, so don't change
         // their mappings.  We end up here when a commit or squash
index 9d91f232e35db3aadf2dc5f90cb21548dc4c359e..37487c3d3788e62258c25950c7c1b720dd1290b4 100644 (file)
@@ -178,6 +178,9 @@ class UnifiedRenameMap
     /** The condition-code register rename map */
     SimpleRenameMap ccMap;
 
+    /** The vector register rename map */
+    SimpleRenameMap vectorMap;
+
   public:
     typedef TheISA::RegIndex RegIndex;
 
@@ -239,6 +242,17 @@ class UnifiedRenameMap
         return info;
     }
 
+    /**
+     * Perform rename() on a vector register, given a relative vector register
+     * index.
+     */
+    RenameInfo renameVector(RegIndex rel_arch_reg)
+    {
+        RenameInfo info = vectorMap.rename(rel_arch_reg);
+        assert(regFile->isVectorPhysReg(info.first));
+        return info;
+    }
+
     /**
      * Perform rename() on a misc register, given a relative
      * misc register index.
@@ -296,6 +310,17 @@ class UnifiedRenameMap
         return phys_reg;
     }
 
+    /**
+     * Perform lookup() on a vector register, given a relative
+     * vector register index.
+     */
+    PhysRegIndex lookupVector(RegIndex rel_arch_reg) const
+    {
+        PhysRegIndex phys_reg = vectorMap.lookup(rel_arch_reg);
+        assert(regFile->isVectorPhysReg(phys_reg));
+        return phys_reg;
+    }
+
     /**
      * Perform lookup() on a misc register, given a relative
      * misc register index.
@@ -348,6 +373,16 @@ class UnifiedRenameMap
         ccMap.setEntry(arch_reg, phys_reg);
     }
 
+    /**
+     * Perform setEntry() on a vector register, given a relative vector
+     * register index.
+     */
+    void setVectorEntry(RegIndex arch_reg, PhysRegIndex phys_reg)
+    {
+        assert(regFile->isVectorPhysReg(phys_reg));
+        vectorMap.setEntry(arch_reg, phys_reg);
+    }
+
     /**
      * Return the minimum number of free entries across all of the
      * register classes.  The minimum is used so we guarantee that
@@ -362,11 +397,13 @@ class UnifiedRenameMap
     /**
      * Return whether there are enough registers to serve the request.
      */
-    bool canRename(uint32_t intRegs, uint32_t floatRegs, uint32_t ccRegs) const
+    bool canRename(uint32_t intRegs, uint32_t floatRegs, uint32_t ccRegs,
+                   uint32_t vectorRegs) const
     {
         return intRegs <= intMap.numFreeEntries() &&
             floatRegs <= floatMap.numFreeEntries() &&
-            ccRegs <= ccMap.numFreeEntries();
+            ccRegs <= ccMap.numFreeEntries() &&
+            vectorRegs <= vectorMap.numFreeEntries();
     }
 
 };
index 87d87900c1e3bd49b58656acbf026577723b2ab4..6e9b054da176432b2b1889e4e0e3ccab27835705 100755 (executable)
@@ -189,6 +189,10 @@ class O3ThreadContext : public ThreadContext
         return readCCRegFlat(flattenCCIndex(reg_idx));
     }
 
+    virtual const VectorReg &readVectorReg(int reg_idx) {
+        return readVectorRegFlat(flattenVectorIndex(reg_idx));
+    }
+
     /** Sets an integer register to a value. */
     virtual void setIntReg(int reg_idx, uint64_t val) {
         setIntRegFlat(flattenIntIndex(reg_idx), val);
@@ -206,6 +210,10 @@ class O3ThreadContext : public ThreadContext
         setCCRegFlat(flattenCCIndex(reg_idx), val);
     }
 
+    virtual void setVectorReg(int reg_idx, const VectorReg &val) {
+        setVectorRegFlat(flattenVectorIndex(reg_idx), val);
+    }
+
     /** Reads this thread's PC state. */
     virtual TheISA::PCState pcState()
     { return cpu->pcState(thread->threadId()); }
@@ -246,6 +254,7 @@ class O3ThreadContext : public ThreadContext
     virtual int flattenIntIndex(int reg);
     virtual int flattenFloatIndex(int reg);
     virtual int flattenCCIndex(int reg);
+    virtual int flattenVectorIndex(int reg);
     virtual int flattenMiscIndex(int reg);
 
     /** Returns the number of consecutive store conditional failures. */
@@ -291,6 +300,9 @@ class O3ThreadContext : public ThreadContext
 
     virtual CCReg readCCRegFlat(int idx);
     virtual void setCCRegFlat(int idx, CCReg val);
+
+    virtual const VectorReg &readVectorRegFlat(int idx);
+    virtual void setVectorRegFlat(int idx, const VectorReg &val);
 };
 
 #endif
index e6a3d50831bd2cb3eec54672bbccdf848482c634..ecdd9ebb96d7a83929e2f59638b4a8ef971fb7d1 100755 (executable)
@@ -215,6 +215,13 @@ O3ThreadContext<Impl>::readCCRegFlat(int reg_idx)
     return cpu->readArchCCReg(reg_idx, thread->threadId());
 }
 
+template <class Impl>
+const TheISA::VectorReg &
+O3ThreadContext<Impl>::readVectorRegFlat(int reg_idx)
+{
+    return cpu->readArchVectorReg(reg_idx, thread->threadId());
+}
+
 template <class Impl>
 void
 O3ThreadContext<Impl>::setIntRegFlat(int reg_idx, uint64_t val)
@@ -251,6 +258,15 @@ O3ThreadContext<Impl>::setCCRegFlat(int reg_idx, TheISA::CCReg val)
     conditionalSquash();
 }
 
+template <class Impl>
+void
+O3ThreadContext<Impl>::setVectorRegFlat(int reg_idx,
+                                        const TheISA::VectorReg &val)
+{
+    cpu->setArchVectorReg(reg_idx, val, thread->threadId());
+    conditionalSquash();
+}
+
 template <class Impl>
 void
 O3ThreadContext<Impl>::pcState(const TheISA::PCState &val)
@@ -290,6 +306,13 @@ O3ThreadContext<Impl>::flattenCCIndex(int reg)
     return cpu->isa[thread->threadId()]->flattenCCIndex(reg);
 }
 
+template <class Impl>
+int
+O3ThreadContext<Impl>::flattenVectorIndex(int reg)
+{
+    return cpu->isa[thread->threadId()]->flattenVectorIndex(reg);
+}
+
 template <class Impl>
 int
 O3ThreadContext<Impl>::flattenMiscIndex(int reg)
index 1805eae133a42b693e804d5508957b0c9f624a71..0cb789fe1ea264aa8259d46f9dbd379d0791b109 100644 (file)
@@ -34,5 +34,6 @@ const char *RegClassStrings[] = {
     "IntRegClass",
     "FloatRegClass",
     "CCRegClass",
+    "VectorRegClass",
     "MiscRegClass"
 };
index 549ebab2627d2619f50f977f27194ea7ed50bf07..6c7b1b55dfc162e21e4c7aa1443f46572e6ff2cd 100644 (file)
@@ -42,6 +42,7 @@ enum RegClass {
     IntRegClass,        ///< Integer register
     FloatRegClass,      ///< Floating-point register
     CCRegClass,         ///< Condition-code register
+    VectorRegClass,     ///< Vector register
     MiscRegClass        ///< Control (misc) register
 };
 
@@ -76,12 +77,15 @@ RegClass regIdxToClass(TheISA::RegIndex reg_idx,
     } else if (reg_idx < TheISA::CC_Reg_Base) {
         cl = FloatRegClass;
         offset = TheISA::FP_Reg_Base;
-    } else if (reg_idx < TheISA::Misc_Reg_Base) {
+    } else if (reg_idx < TheISA::Vector_Reg_Base) {
         // if there are no CC regs, the ISA should set
         // CC_Reg_Base == Misc_Reg_Base so the if above
         // never succeeds
         cl = CCRegClass;
         offset = TheISA::CC_Reg_Base;
+    } else if (reg_idx < TheISA::Misc_Reg_Base) {
+        cl = VectorRegClass;
+        offset = TheISA::Vector_Reg_Base;
     } else {
         cl = MiscRegClass;
         offset = TheISA::Misc_Reg_Base;
index 2f72470109e07a4b723dbb2fe118f365431b4fbf..27e434132e7fbce5f24b4a4cbb2393ace4c92365 100644 (file)
@@ -87,6 +87,7 @@ class BaseSimpleCPU : public BaseCPU, public ExecContext
     typedef TheISA::FloatReg FloatReg;
     typedef TheISA::FloatRegBits FloatRegBits;
     typedef TheISA::CCReg CCReg;
+    typedef TheISA::VectorReg VectorReg;
 
     BPredUnit *branchPred;
 
@@ -239,6 +240,10 @@ class BaseSimpleCPU : public BaseCPU, public ExecContext
     Stats::Scalar numCCRegReads;
     Stats::Scalar numCCRegWrites;
 
+    //number of vector register file accesses
+    Stats::Scalar numVectorRegReads;
+    Stats::Scalar numVectorRegWrites;
+
     // number of simulated memory references
     Stats::Scalar numMemRefs;
     Stats::Scalar numLoadInsts;
@@ -325,6 +330,13 @@ class BaseSimpleCPU : public BaseCPU, public ExecContext
         return thread->readCCReg(reg_idx);
     }
 
+    const VectorReg &readVectorRegOperand(const StaticInst *si, int idx)
+    {
+        numVectorRegReads++;
+        int reg_idx = si->srcRegIdx(idx) - TheISA::Vector_Reg_Base;
+        return thread->readVectorReg(reg_idx);
+    }
+
     void setIntRegOperand(const StaticInst *si, int idx, IntReg val)
     {
         numIntRegWrites++;
@@ -353,6 +365,14 @@ class BaseSimpleCPU : public BaseCPU, public ExecContext
         thread->setCCReg(reg_idx, val);
     }
 
+    void setVectorRegOperand(const StaticInst *si, int idx,
+                             const VectorReg &val)
+    {
+        numVectorRegWrites++;
+        int reg_idx = si->destRegIdx(idx) - TheISA::Vector_Reg_Base;
+        thread->setVectorReg(reg_idx, val);
+    }
+
     bool readPredicate() { return thread->readPredicate(); }
     void setPredicate(bool val)
     {
index 20acff6ee27891fd3c4857b44e73efc0d804d413..070a00dc82210d8e7cc788a32910f3f3098389da 100644 (file)
@@ -58,6 +58,7 @@
 #include "debug/CCRegs.hh"
 #include "debug/FloatRegs.hh"
 #include "debug/IntRegs.hh"
+#include "debug/VectorRegs.hh"
 #include "mem/page_table.hh"
 #include "mem/request.hh"
 #include "sim/byteswap.hh"
@@ -102,6 +103,8 @@ class SimpleThread : public ThreadState
     typedef TheISA::FloatReg FloatReg;
     typedef TheISA::FloatRegBits FloatRegBits;
     typedef TheISA::CCReg CCReg;
+    typedef TheISA::VectorReg VectorReg;
+
   public:
     typedef ThreadContext::Status Status;
 
@@ -111,9 +114,15 @@ class SimpleThread : public ThreadState
         FloatRegBits i[TheISA::NumFloatRegs];
     } floatRegs;
     TheISA::IntReg intRegs[TheISA::NumIntRegs];
+
 #ifdef ISA_HAS_CC_REGS
     TheISA::CCReg ccRegs[TheISA::NumCCRegs];
 #endif
+
+#ifdef ISA_HAS_VECTOR_REGS
+    TheISA::VectorReg vectorRegs[TheISA::NumVectorRegs];
+#endif
+
     TheISA::ISA *const isa;    // one "instance" of the current ISA.
 
     TheISA::PCState _pcState;
@@ -282,6 +291,16 @@ class SimpleThread : public ThreadState
 #endif
     }
 
+    const VectorReg &readVectorReg(int reg_idx)
+    {
+        int flatIndex = isa->flattenVectorIndex(reg_idx);
+        assert(0 <= flatIndex);
+        assert(flatIndex < TheISA::NumVectorRegs);
+        DPRINTF(VectorRegs, "Reading vector reg %d (%d).\n",
+                reg_idx, flatIndex);
+        return readVectorRegFlat(flatIndex);
+    }
+
     void setIntReg(int reg_idx, uint64_t val)
     {
         int flatIndex = isa->flattenIntIndex(reg_idx);
@@ -325,6 +344,19 @@ class SimpleThread : public ThreadState
 #endif
     }
 
+    void setVectorReg(int reg_idx, const VectorReg &val)
+    {
+#ifdef ISA_HAS_VECTOR_REGS
+        int flatIndex = isa->flattenVectorIndex(reg_idx);
+        assert(flatIndex < TheISA::NumVectorRegs);
+        DPRINTF(VectorRegs, "Setting vector reg %d (%d).\n",
+                reg_idx, flatIndex);
+        setVectorRegFlat(flatIndex, val);
+#else
+        panic("Tried to set a vector register.");
+#endif
+    }
+
     TheISA::PCState
     pcState()
     {
@@ -413,6 +445,12 @@ class SimpleThread : public ThreadState
         return isa->flattenCCIndex(reg);
     }
 
+    int
+    flattenVectorIndex(int reg)
+    {
+        return isa->flattenVectorIndex(reg);
+    }
+
     int
     flattenMiscIndex(int reg)
     {
@@ -450,6 +488,18 @@ class SimpleThread : public ThreadState
     void setCCRegFlat(int idx, CCReg val)
     { panic("setCCRegFlat w/no CC regs!\n"); }
 #endif
+
+#ifdef ISA_HAS_VECTOR_REGS
+    const VectorReg &readVectorRegFlat(int idx) { return vectorRegs[idx]; }
+    void setVectorRegFlat(int idx, const VectorReg &val)
+    { vectorRegs[idx] = val; }
+#else
+    const VectorReg &readVectorRegFlat(int idx)
+    { panic("readVectorRegFlat w/no Vector regs!\n"); }
+
+    void setVectorRegFlat(int idx, const VectorReg &val)
+    { panic("setVectorRegFlat w/no Vector regs!\n"); }
+#endif
 };
 
 
index 684a228562ccab46d2a520c02b125fe9376e5a51..58cf752b753fb13395dfbbb6fef2f03248fb0d61 100644 (file)
@@ -98,6 +98,7 @@ class StaticInst : public RefCounted, public StaticInstFlags
     int8_t _numFPDestRegs;
     int8_t _numIntDestRegs;
     int8_t _numCCDestRegs;
+    int8_t _numVectorDestRegs;
     //@}
 
   public:
@@ -116,9 +117,10 @@ class StaticInst : public RefCounted, public StaticInstFlags
     int8_t numFPDestRegs()  const { return _numFPDestRegs; }
     /// Number of integer destination regs.
     int8_t numIntDestRegs() const { return _numIntDestRegs; }
-    //@}
-    /// Number of coprocesor destination regs.
+    /// Number of condition code destination regs.
     int8_t numCCDestRegs() const { return _numCCDestRegs; }
+    /// Number of vector destination regs.
+    int8_t numVectorDestRegs() const { return _numVectorDestRegs; }
     //@}
 
     /// @name Flag accessors.
@@ -140,6 +142,7 @@ class StaticInst : public RefCounted, public StaticInstFlags
 
     bool isInteger()      const { return flags[IsInteger]; }
     bool isFloating()     const { return flags[IsFloating]; }
+    bool isVector() const { return flags[IsVector]; }
     bool isCC()           const { return flags[IsCC]; }
 
     bool isControl()      const { return flags[IsControl]; }
@@ -252,7 +255,8 @@ class StaticInst : public RefCounted, public StaticInstFlags
     StaticInst(const char *_mnemonic, ExtMachInst _machInst, OpClass __opClass)
         : _opClass(__opClass), _numSrcRegs(0), _numDestRegs(0),
           _numFPDestRegs(0), _numIntDestRegs(0), _numCCDestRegs(0),
-          machInst(_machInst), mnemonic(_mnemonic), cachedDisassembly(0)
+          _numVectorDestRegs(0), machInst(_machInst), mnemonic(_mnemonic),
+          cachedDisassembly(0)
     { }
 
   public:
@@ -326,7 +330,7 @@ class StaticInst : public RefCounted, public StaticInstFlags
     void printFlags(std::ostream &outs, const std::string &separator) const;
 
     /// Return name of machine instruction
-    std::string getName() { return mnemonic; }
+    std::string getName() const { return mnemonic; }
 };
 
 #endif // __CPU_STATIC_INST_HH__
index fe1ae69dd43ff1de945f31fd7bab909a16b493fb..ce7604d3c0be806e1612d8edc0e6b9b59eaba03b 100644 (file)
@@ -88,6 +88,15 @@ ThreadContext::compare(ThreadContext *one, ThreadContext *two)
             panic("CC reg idx %d doesn't match, one: %#x, two: %#x",
                   i, t1, t2);
     }
+
+    // loop through the Vector registers.
+    for (int i = 0; i < TheISA::NumVectorRegs; ++i) {
+        const TheISA::VectorReg &t1 = one->readVectorReg(i);
+        const TheISA::VectorReg &t2 = two->readVectorReg(i);
+        if (t1 != t2)
+            panic("Vector reg idx %d doesn't match", i);
+    }
+
     if (!(one->pcState() == two->pcState()))
         panic("PC state doesn't match.");
     int id1 = one->cpuId();
@@ -127,6 +136,16 @@ serialize(ThreadContext &tc, CheckpointOut &cp)
     SERIALIZE_ARRAY(ccRegs, NumCCRegs);
 #endif
 
+#ifdef ISA_HAS_VECTOR_REGS
+    VectorRegElement vectorRegs[NumVectorRegs * NumVectorRegElements];
+    for (int i = 0; i < NumVectorRegs; ++i) {
+        const VectorReg &v = tc.readVectorRegFlat(i);
+        for (int j = 0; i < NumVectorRegElements; ++j)
+            vectorRegs[i * NumVectorRegElements + j] = v[j];
+    }
+    SERIALIZE_ARRAY(vectorRegs, NumVectorRegs * NumVectorRegElements);
+#endif
+
     tc.pcState().serialize(cp);
 
     // thread_num and cpu_id are deterministic from the config
@@ -156,6 +175,17 @@ unserialize(ThreadContext &tc, CheckpointIn &cp)
         tc.setCCRegFlat(i, ccRegs[i]);
 #endif
 
+#ifdef ISA_HAS_VECTOR_REGS
+    VectorRegElement vectorRegs[NumVectorRegs * NumVectorRegElements];
+    UNSERIALIZE_ARRAY(vectorRegs, NumVectorRegs * NumVectorRegElements);
+    for (int i = 0; i < NumVectorRegs; ++i) {
+        VectorReg v;
+        for (int j = 0; i < NumVectorRegElements; ++j)
+            v[j] = vectorRegs[i * NumVectorRegElements + j];
+        tc.setVectorRegFlat(i, v);
+    }
+#endif
+
     PCState pcState;
     pcState.unserialize(cp);
     tc.pcState(pcState);
index 2544b19c66d0031dd4b6661eba446dcd197d34dd..cd8b98f0cae37cff633c23e562b82a6795831354 100644 (file)
@@ -98,6 +98,7 @@ class ThreadContext
     typedef TheISA::FloatReg FloatReg;
     typedef TheISA::FloatRegBits FloatRegBits;
     typedef TheISA::CCReg CCReg;
+    typedef TheISA::VectorReg VectorReg;
     typedef TheISA::MiscReg MiscReg;
   public:
 
@@ -205,6 +206,8 @@ class ThreadContext
 
     virtual CCReg readCCReg(int reg_idx) = 0;
 
+    virtual const VectorReg &readVectorReg(int reg_idx) = 0;
+
     virtual void setIntReg(int reg_idx, uint64_t val) = 0;
 
     virtual void setFloatReg(int reg_idx, FloatReg val) = 0;
@@ -213,6 +216,8 @@ class ThreadContext
 
     virtual void setCCReg(int reg_idx, CCReg val) = 0;
 
+    virtual void setVectorReg(int reg_idx, const VectorReg &val) = 0;
+
     virtual TheISA::PCState pcState() = 0;
 
     virtual void pcState(const TheISA::PCState &val) = 0;
@@ -236,6 +241,7 @@ class ThreadContext
     virtual int flattenIntIndex(int reg) = 0;
     virtual int flattenFloatIndex(int reg) = 0;
     virtual int flattenCCIndex(int reg) = 0;
+    virtual int flattenVectorIndex(int reg) = 0;
     virtual int flattenMiscIndex(int reg) = 0;
 
     virtual uint64_t
@@ -291,6 +297,9 @@ class ThreadContext
 
     virtual CCReg readCCRegFlat(int idx) = 0;
     virtual void setCCRegFlat(int idx, CCReg val) = 0;
+
+    virtual const VectorReg &readVectorRegFlat(int idx) = 0;
+    virtual void setVectorRegFlat(int idx, const VectorReg &val) = 0;
     /** @} */
 
 };
@@ -402,6 +411,9 @@ class ProxyThreadContext : public ThreadContext
     CCReg readCCReg(int reg_idx)
     { return actualTC->readCCReg(reg_idx); }
 
+    const VectorReg &readVectorReg(int reg_idx)
+    { return actualTC->readVectorReg(reg_idx); }
+
     void setIntReg(int reg_idx, uint64_t val)
     { actualTC->setIntReg(reg_idx, val); }
 
@@ -414,6 +426,9 @@ class ProxyThreadContext : public ThreadContext
     void setCCReg(int reg_idx, CCReg val)
     { actualTC->setCCReg(reg_idx, val); }
 
+    void setVectorReg(int reg_idx, const VectorReg &val)
+    { actualTC->setVectorReg(reg_idx, val); }
+
     TheISA::PCState pcState() { return actualTC->pcState(); }
 
     void pcState(const TheISA::PCState &val) { actualTC->pcState(val); }
@@ -450,6 +465,9 @@ class ProxyThreadContext : public ThreadContext
     int flattenCCIndex(int reg)
     { return actualTC->flattenCCIndex(reg); }
 
+    int flattenVectorIndex(int reg)
+    { return actualTC->flattenVectorIndex(reg); }
+
     int flattenMiscIndex(int reg)
     { return actualTC->flattenMiscIndex(reg); }
 
@@ -487,6 +505,12 @@ class ProxyThreadContext : public ThreadContext
 
     void setCCRegFlat(int idx, CCReg val)
     { actualTC->setCCRegFlat(idx, val); }
+
+    const VectorReg &readVectorRegFlat(int idx)
+    { return actualTC->readVectorRegFlat(idx); }
+
+    void setVectorRegFlat(int idx, const VectorReg &val)
+    { actualTC->setVectorRegFlat(idx, val); }
 };
 
 /** @{ */
index 6819c2199e9fc7c898874992b4508a7a51d1e95a..3c954df26437ea9b67594ee71a264032d03f7887 100644 (file)
@@ -58,6 +58,8 @@ namespace Trace {
 class InstRecord
 {
   protected:
+    typedef TheISA::VectorReg VectorReg;
+
     Tick when;
 
     // The following fields are initialized by the constructor and
@@ -97,6 +99,7 @@ class InstRecord
     union {
         uint64_t as_int;
         double as_double;
+        VectorReg as_vector;
     } data;
 
     /** @defgroup fetch_seq
@@ -120,7 +123,8 @@ class InstRecord
         DataInt16 = 2,
         DataInt32 = 4,
         DataInt64 = 8,
-        DataDouble = 3
+        DataDouble = 3,
+        DataVector = sizeof(VectorReg),
     } data_status;
 
     /** @ingroup memory
@@ -173,6 +177,8 @@ class InstRecord
     void setData(int8_t d)  { setData((uint8_t)d); }
 
     void setData(double d) { data.as_double = d; data_status = DataDouble; }
+    void setData(const VectorReg& v)
+    { data.as_vector = v; data_status = DataVector; }
 
     void setFetchSeq(InstSeqNum seq)
     { fetch_seq = seq; fetch_seq_valid = true; }
@@ -198,6 +204,7 @@ class InstRecord
 
     uint64_t getIntData() const { return data.as_int; }
     double getFloatData() const { return data.as_double; }
+    const VectorReg &getVectorData() const { return data.as_vector; }
     int getDataStatus() const { return data_status; }
 
     InstSeqNum getFetchSeq() const { return fetch_seq; }