diff -r 866258a4a31e -r ecb65c144bbf src/arch/SConscript --- a/src/arch/SConscript Wed May 27 17:24:51 2015 -0500 +++ b/src/arch/SConscript Wed May 27 17:25:23 2015 -0500 @@ -196,5 +196,7 @@ DebugFlag('IntRegs') DebugFlag('FloatRegs') DebugFlag('CCRegs') +DebugFlag('VectorRegs') DebugFlag('MiscRegs') -CompoundFlag('Registers', [ 'IntRegs', 'FloatRegs', 'CCRegs', 'MiscRegs' ]) +CompoundFlag('Registers', [ 'IntRegs', 'FloatRegs', 'CCRegs', 'VectorRegs', + 'MiscRegs' ]) diff -r 866258a4a31e -r ecb65c144bbf src/arch/alpha/registers.hh --- a/src/arch/alpha/registers.hh Wed May 27 17:24:51 2015 -0500 +++ b/src/arch/alpha/registers.hh Wed May 27 17:25:23 2015 -0500 @@ -56,6 +56,9 @@ // dummy typedef since we don't have CC regs typedef uint8_t CCReg; +// vector register file entry type +typedef std::array VectorReg; + union AnyReg { IntReg intreg; @@ -95,6 +98,7 @@ 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 +110,8 @@ // 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 }; diff -r 866258a4a31e -r ecb65c144bbf src/arch/arm/registers.hh --- a/src/arch/arm/registers.hh Wed May 27 17:24:51 2015 -0500 +++ b/src/arch/arm/registers.hh Wed May 27 17:25:23 2015 -0500 @@ -72,6 +72,9 @@ // condition code register; must be at least 32 bits for FpCondCodes typedef uint64_t CCReg; +// vector register file entry type +typedef std::array VectorReg; + // Constants Related to the number of registers const int NumIntArchRegs = NUM_ARCH_INTREGS; // The number of single precision floating point registers @@ -82,6 +85,7 @@ 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 +116,8 @@ // 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 { diff -r 866258a4a31e -r ecb65c144bbf src/arch/isa_parser.py --- a/src/arch/isa_parser.py Wed May 27 17:24:51 2015 -0500 +++ b/src/arch/isa_parser.py Wed May 27 17:25:23 2015 -0500 @@ -751,6 +751,102 @@ return wb +class VectorRegOperand(Operand): + def __init__(self, parser, full_name, ext, is_src, is_dest): + super(VectorRegOperand, self).__init__(parser, full_name, ext, + is_src, 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 isReg(self): + return 1 + + def isVectorOperand(self): + return 1 + + 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) + 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 @@ -808,6 +904,10 @@ return wb class MemOperand(Operand): + def __init__(self, parser, full_name, ext, is_src, is_dest): + super(MemOperand, self).__init__(parser, full_name, ext, + is_src, is_dest) + def isMem(self): return 1 @@ -818,7 +918,10 @@ # 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: diff -r 866258a4a31e -r ecb65c144bbf src/arch/mips/registers.hh --- a/src/arch/mips/registers.hh Wed May 27 17:24:51 2015 -0500 +++ b/src/arch/mips/registers.hh Wed May 27 17:25:23 2015 -0500 @@ -55,6 +55,7 @@ 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 @@ // 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,9 @@ // dummy typedef since we don't have CC regs typedef uint8_t CCReg; +// vector register file entry type +typedef std::array VectorReg; + typedef union { IntReg intreg; FloatReg fpreg; diff -r 866258a4a31e -r ecb65c144bbf src/arch/null/registers.hh --- a/src/arch/null/registers.hh Wed May 27 17:24:51 2015 -0500 +++ b/src/arch/null/registers.hh Wed May 27 17:25:23 2015 -0500 @@ -49,6 +49,7 @@ typedef float FloatReg; typedef uint8_t CCReg; typedef uint64_t MiscReg; +typedef std::array VectorReg; } diff -r 866258a4a31e -r ecb65c144bbf src/arch/power/registers.hh --- a/src/arch/power/registers.hh Wed May 27 17:24:51 2015 -0500 +++ b/src/arch/power/registers.hh Wed May 27 17:25:23 2015 -0500 @@ -54,6 +54,7 @@ // dummy typedef since we don't have CC regs typedef uint8_t CCReg; +typedef std::array VectorReg; // Constants Related to the number of registers const int NumIntArchRegs = 32; @@ -68,6 +69,7 @@ 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 +92,8 @@ // 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 { diff -r 866258a4a31e -r ecb65c144bbf src/arch/sparc/registers.hh --- a/src/arch/sparc/registers.hh Wed May 27 17:24:51 2015 -0500 +++ b/src/arch/sparc/registers.hh Wed May 27 17:25:23 2015 -0500 @@ -51,6 +51,7 @@ // dummy typedef since we don't have CC regs typedef uint8_t CCReg; +typedef std::array VectorReg; typedef union { @@ -75,6 +76,7 @@ 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 +84,8 @@ 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, }; diff -r 866258a4a31e -r ecb65c144bbf src/arch/x86/insts/static_inst.cc --- a/src/arch/x86/insts/static_inst.cc Wed May 27 17:24:51 2015 -0500 +++ b/src/arch/x86/insts/static_inst.cc Wed May 27 17:25:23 2015 -0500 @@ -231,6 +231,9 @@ ccprintf(os, "%%ctrl%d", rel_reg); } break; + + default: + panic("Invalid register class!\n"); } } diff -r 866258a4a31e -r ecb65c144bbf src/arch/x86/isa.hh --- a/src/arch/x86/isa.hh Wed May 27 17:24:51 2015 -0500 +++ b/src/arch/x86/isa.hh Wed May 27 17:25:23 2015 -0500 @@ -92,6 +92,12 @@ } int + flattenVectorIndex(int reg) const + { + return reg; + } + + int flattenMiscIndex(int reg) const { return reg; diff -r 866258a4a31e -r ecb65c144bbf src/arch/x86/registers.hh --- a/src/arch/x86/registers.hh Wed May 27 17:24:51 2015 -0500 +++ b/src/arch/x86/registers.hh Wed May 27 17:25:23 2015 -0500 @@ -57,6 +57,7 @@ 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 @@ // 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,10 @@ typedef uint64_t IntReg; typedef uint64_t CCReg; + +// vector register file entry type +typedef std::array VectorReg; + //XXX Should this be a 128 bit structure for XMM memory ops? typedef uint64_t LargestRead; typedef uint64_t MiscReg; diff -r 866258a4a31e -r ecb65c144bbf src/cpu/StaticInstFlags.py --- a/src/cpu/StaticInstFlags.py Wed May 27 17:24:51 2015 -0500 +++ b/src/cpu/StaticInstFlags.py Wed May 27 17:25:23 2015 -0500 @@ -55,9 +55,10 @@ 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. + 'IsVector', # References vector register. 'IsMemRef', # References memory (load, store, or prefetch) 'IsLoad', # Reads from memory (load or prefetch). diff -r 866258a4a31e -r ecb65c144bbf src/cpu/base_dyn_inst.hh --- a/src/cpu/base_dyn_inst.hh Wed May 27 17:24:51 2015 -0500 +++ b/src/cpu/base_dyn_inst.hh Wed May 27 17:25:23 2015 -0500 @@ -99,10 +99,19 @@ 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: @@ -596,6 +605,8 @@ 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 +666,13 @@ setResult(val); } + /** Records a vector register being set to a value. */ + void setVectorRegOperand(const StaticInst *si, int idx, + const VectorReg &val) + { + setResult(val); + } + /** Records that one of the source registers is ready. */ void markSrcRegReady(); diff -r 866258a4a31e -r ecb65c144bbf src/cpu/checker/cpu.hh --- a/src/cpu/checker/cpu.hh Wed May 27 17:24:51 2015 -0500 +++ b/src/cpu/checker/cpu.hh Wed May 27 17:25:23 2015 -0500 @@ -94,6 +94,7 @@ 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 @@ 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 @@ return thread->readCCReg(reg_idx); } + VectorReg readVectorRegOperand(const StaticInst *si, int idx) + { + return thread->readVectorReg(si->srcRegIdx(idx)); + } + template void setResult(T t) { @@ -267,6 +282,13 @@ setResult(val); } + void setVectorRegOperand(const StaticInst *si, int idx, + const VectorReg &val) + { + thread->setVectorReg(si->destRegIdx(idx), val); + setResult(val); + } + bool readPredicate() { return thread->readPredicate(); } void setPredicate(bool val) { @@ -441,7 +463,7 @@ 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: diff -r 866258a4a31e -r ecb65c144bbf src/cpu/checker/cpu_impl.hh --- a/src/cpu/checker/cpu_impl.hh Wed May 27 17:24:51 2015 -0500 +++ b/src/cpu/checker/cpu_impl.hh Wed May 27 17:25:23 2015 -0500 @@ -491,7 +491,9 @@ // 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 @@ // 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 @@ template void -Checker::copyResult(DynInstPtr &inst, uint64_t mismatch_val, +Checker::copyResult(DynInstPtr &inst, Result mismatch_val, int start_idx) { // We've already popped one dest off the queue, @@ -599,39 +603,65 @@ 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(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(res); + thread->setIntReg(idx, res); + } + break; + + case FloatRegClass: { + uint64_t res = 0; + inst->template popResult(res); + thread->setFloatRegBits(idx - TheISA::FP_Reg_Base, res); + } + break; + + case CCRegClass: { + uint64_t res = 0; + inst->template popResult(res); + thread->setCCReg(idx - TheISA::CC_Reg_Base, res); + } + break; + + case VectorRegClass: { + VectorReg res; + inst->template popResult(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(res); + thread->setMiscReg(idx - TheISA::Misc_Reg_Base, res); + } + break; // else Register is out of range... } } diff -r 866258a4a31e -r ecb65c144bbf src/cpu/checker/thread_context.hh --- a/src/cpu/checker/thread_context.hh Wed May 27 17:24:51 2015 -0500 +++ b/src/cpu/checker/thread_context.hh Wed May 27 17:25:23 2015 -0500 @@ -220,6 +220,9 @@ CCReg readCCReg(int reg_idx) { return actualTC->readCCReg(reg_idx); } + VectorReg readVectorReg(int reg_idx) + { return actualTC->readVectorReg(reg_idx); } + void setIntReg(int reg_idx, uint64_t val) { actualTC->setIntReg(reg_idx, val); @@ -244,6 +247,12 @@ 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(); } @@ -300,6 +309,7 @@ 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() @@ -335,6 +345,12 @@ void setCCRegFlat(int idx, CCReg val) { actualTC->setCCRegFlat(idx, val); } + + 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__ diff -r 866258a4a31e -r ecb65c144bbf src/cpu/exec_context.hh --- a/src/cpu/exec_context.hh Wed May 27 17:24:51 2015 -0500 +++ b/src/cpu/exec_context.hh Wed May 27 17:25:23 2015 -0500 @@ -76,6 +76,7 @@ typedef TheISA::MiscReg MiscReg; typedef TheISA::CCReg CCReg; + typedef TheISA::VectorReg VectorReg; public: /** @@ -128,6 +129,21 @@ /** * @{ + * @name Vector Register Interfaces + * + */ + + /** Reads a vector register. */ + virtual 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 */ virtual MiscReg readMiscRegOperand(const StaticInst *si, int idx) = 0; diff -r 866258a4a31e -r ecb65c144bbf src/cpu/o3/O3CPU.py --- a/src/cpu/o3/O3CPU.py Wed May 27 17:24:51 2015 -0500 +++ b/src/cpu/o3/O3CPU.py Wed May 27 17:25:23 2015 -0500 @@ -114,6 +114,7 @@ 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,14 @@ _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 + if buildEnv['TARGET_ISA'] in ('x86'): + _defaultNumPhysVectorRegs = 64 + 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") diff -r 866258a4a31e -r ecb65c144bbf src/cpu/o3/cpu.hh --- a/src/cpu/o3/cpu.hh Wed May 27 17:24:51 2015 -0500 +++ b/src/cpu/o3/cpu.hh Wed May 27 17:25:23 2015 -0500 @@ -428,6 +428,8 @@ TheISA::CCReg readCCReg(int reg_idx); + TheISA::VectorReg readVectorReg(int reg_idx); + void setIntReg(int reg_idx, uint64_t val); void setFloatReg(int reg_idx, TheISA::FloatReg val); @@ -436,6 +438,8 @@ 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); @@ -444,6 +448,8 @@ TheISA::CCReg readArchCCReg(int reg_idx, ThreadID tid); + 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 @@ -457,6 +463,9 @@ 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); @@ -738,6 +747,9 @@ //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; diff -r 866258a4a31e -r ecb65c144bbf src/cpu/o3/cpu.cc --- a/src/cpu/o3/cpu.cc Wed May 27 17:24:51 2015 -0500 +++ b/src/cpu/o3/cpu.cc Wed May 27 17:25:23 2015 -0500 @@ -170,7 +170,8 @@ regFile(params->numPhysIntRegs, params->numPhysFloatRegs, - params->numPhysCCRegs), + params->numPhysCCRegs, + params->numPhysVectorRegs), freeList(name() + ".freelist", ®File), @@ -270,6 +271,7 @@ 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); @@ -522,6 +524,16 @@ .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") @@ -1269,6 +1281,14 @@ } template +VectorReg +FullO3CPU::readVectorReg(int reg_idx) +{ + vectorRegfileReads++; + return regFile.readVectorReg(reg_idx); +} + +template void FullO3CPU::setIntReg(int reg_idx, uint64_t val) { @@ -1301,6 +1321,14 @@ } template +void +FullO3CPU::setVectorReg(int reg_idx, const VectorReg &val) +{ + vectorRegfileWrites++; + regFile.setVectorReg(reg_idx, val); +} + +template uint64_t FullO3CPU::readArchIntReg(int reg_idx, ThreadID tid) { @@ -1341,6 +1369,16 @@ } template +VectorReg +FullO3CPU::readArchVectorReg(int reg_idx, ThreadID tid) +{ + vectorRegfileReads++; + PhysRegIndex phys_reg = commitRenameMap[tid].lookupVector(reg_idx); + + return regFile.readVectorReg(phys_reg); +} + +template void FullO3CPU::setArchIntReg(int reg_idx, uint64_t val, ThreadID tid) { @@ -1381,6 +1419,16 @@ } template +void +FullO3CPU::setArchVectorReg(int reg_idx, const VectorReg &val, + ThreadID tid) +{ + vectorRegfileWrites++; + PhysRegIndex phys_reg = commitRenameMap[tid].lookupVector(reg_idx); + regFile.setVectorReg(phys_reg, val); +} + +template TheISA::PCState FullO3CPU::pcState(ThreadID tid) { diff -r 866258a4a31e -r ecb65c144bbf src/cpu/o3/dyn_inst.hh --- a/src/cpu/o3/dyn_inst.hh Wed May 27 17:24:51 2015 -0500 +++ b/src/cpu/o3/dyn_inst.hh Wed May 27 17:25:23 2015 -0500 @@ -74,6 +74,7 @@ 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 @@ 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 @@ 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 @@ return this->cpu->readCCReg(this->_srcRegIdx[idx]); } + 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 @@ BaseDynInst::setCCRegOperand(si, idx, val); } + void setVectorRegOperand(const StaticInst *si, int idx, + const VectorReg& val) + { + this->cpu->setVectorReg(this->_destRegIdx[idx], val); + BaseDynInst::setVectorRegOperand(si, idx, val); + } + #if THE_ISA == MIPS_ISA MiscReg readRegOtherThread(int misc_reg, ThreadID tid) { diff -r 866258a4a31e -r ecb65c144bbf src/cpu/o3/free_list.hh --- a/src/cpu/o3/free_list.hh Wed May 27 17:24:51 2015 -0500 +++ b/src/cpu/o3/free_list.hh Wed May 27 17:25:23 2015 -0500 @@ -109,6 +109,9 @@ /** 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. @@ -160,6 +163,9 @@ /** Adds a cc register back to the free list. */ void addCCReg(PhysRegIndex freed_reg) { ccList.addReg(freed_reg); } + /** Adds a cc 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 +175,9 @@ /** 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 +186,9 @@ /** 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 +201,11 @@ intList.addReg(freed_reg); } else if (regFile->isFloatPhysReg(freed_reg)) { floatList.addReg(freed_reg); + } else if (regFile->isCCPhysReg(freed_reg)) { + ccList.addReg(freed_reg); } else { - assert(regFile->isCCPhysReg(freed_reg)); - ccList.addReg(freed_reg); + assert(regFile->isVectorPhysReg(freed_reg)); + vectorList.addReg(freed_reg); } // These assert conditions ensure that the number of free diff -r 866258a4a31e -r ecb65c144bbf src/cpu/o3/regfile.hh --- a/src/cpu/o3/regfile.hh Wed May 27 17:24:51 2015 -0500 +++ b/src/cpu/o3/regfile.hh Wed May 27 17:25:23 2015 -0500 @@ -56,6 +56,7 @@ typedef TheISA::FloatReg FloatReg; typedef TheISA::FloatRegBits FloatRegBits; typedef TheISA::CCReg CCReg; + typedef TheISA::VectorReg VectorReg; typedef union { FloatReg d; @@ -71,6 +72,9 @@ /** Condition-code register file. */ std::vector ccRegFile; + /** Vector register file. */ + std::vector vectorRegFile; + /** * The first floating-point physical register index. The physical * register file has a single continuous index space, with the @@ -93,6 +97,12 @@ */ 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 @@ */ PhysRegFile(unsigned _numPhysicalIntRegs, unsigned _numPhysicalFloatRegs, - unsigned _numPhysicalCCRegs); + unsigned _numPhysicalCCRegs, + unsigned _numPhysicalVectorRegs); /** * Destructor to free resources @@ -122,7 +133,11 @@ /** @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 @@ */ 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,15 @@ return ccRegFile[reg_offset]; } + /** Reads a vector register. */ + VectorReg readVectorReg(PhysRegIndex reg_idx) const + { + assert(isVectorPhysReg(reg_idx)); + + DPRINTF(IEW, "RegFile: Access to vector register %i\n", int(reg_idx)); + return vectorRegFile[reg_idx]; + } + /** Sets an integer register to the given value. */ void setIntReg(PhysRegIndex reg_idx, uint64_t val) { @@ -262,6 +295,14 @@ ccRegFile[reg_offset] = val; } + + /** Sets a vector register to the given value. */ + void setVectorReg(PhysRegIndex reg_idx, const VectorReg &val) + { + assert(isVectorPhysReg(reg_idx)); + DPRINTF(IEW, "RegFile: Setting vector register %i\n", int(reg_idx)); + vectorRegFile[reg_idx] = val; + } }; diff -r 866258a4a31e -r ecb65c144bbf src/cpu/o3/regfile.cc --- a/src/cpu/o3/regfile.cc Wed May 27 17:24:51 2015 -0500 +++ b/src/cpu/o3/regfile.cc Wed May 27 17:25:23 2015 -0500 @@ -37,15 +37,20 @@ 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 @@ 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 @@ 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++); + } } diff -r 866258a4a31e -r ecb65c144bbf src/cpu/o3/rename_map.hh --- a/src/cpu/o3/rename_map.hh Wed May 27 17:24:51 2015 -0500 +++ b/src/cpu/o3/rename_map.hh Wed May 27 17:25:23 2015 -0500 @@ -178,6 +178,9 @@ /** The condition-code register rename map */ SimpleRenameMap ccMap; + /** The vector register rename map */ + SimpleRenameMap vectorMap; + public: typedef TheISA::RegIndex RegIndex; @@ -297,6 +300,17 @@ } /** + * 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. */ diff -r 866258a4a31e -r ecb65c144bbf src/cpu/o3/thread_context.hh --- a/src/cpu/o3/thread_context.hh Wed May 27 17:24:51 2015 -0500 +++ b/src/cpu/o3/thread_context.hh Wed May 27 17:25:23 2015 -0500 @@ -189,6 +189,10 @@ return readCCRegFlat(flattenCCIndex(reg_idx)); } + virtual VectorReg readVectorReg(int reg_idx) { + return readVectorRegFlat(flattenCCIndex(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 @@ 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 @@ 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 @@ virtual CCReg readCCRegFlat(int idx); virtual void setCCRegFlat(int idx, CCReg val); + + virtual VectorReg readVectorRegFlat(int idx); + virtual void setVectorRegFlat(int idx, const VectorReg &val); }; #endif diff -r 866258a4a31e -r ecb65c144bbf src/cpu/o3/thread_context_impl.hh --- a/src/cpu/o3/thread_context_impl.hh Wed May 27 17:24:51 2015 -0500 +++ b/src/cpu/o3/thread_context_impl.hh Wed May 27 17:25:23 2015 -0500 @@ -216,6 +216,13 @@ } template +TheISA::VectorReg +O3ThreadContext::readVectorRegFlat(int reg_idx) +{ + return cpu->readArchVectorReg(reg_idx, thread->threadId()); +} + +template void O3ThreadContext::setIntRegFlat(int reg_idx, uint64_t val) { @@ -253,6 +260,15 @@ template void +O3ThreadContext::setVectorRegFlat(int reg_idx, + const TheISA::VectorReg &val) +{ + cpu->setArchVectorReg(reg_idx, val, thread->threadId()); + conditionalSquash(); +} + +template +void O3ThreadContext::pcState(const TheISA::PCState &val) { cpu->pcState(val, thread->threadId()); @@ -292,6 +308,13 @@ template int +O3ThreadContext::flattenVectorIndex(int reg) +{ + return cpu->isa[thread->threadId()]->flattenCCIndex(reg); +} + +template +int O3ThreadContext::flattenMiscIndex(int reg) { return cpu->isa[thread->threadId()]->flattenMiscIndex(reg); diff -r 866258a4a31e -r ecb65c144bbf src/cpu/reg_class.hh --- a/src/cpu/reg_class.hh Wed May 27 17:24:51 2015 -0500 +++ b/src/cpu/reg_class.hh Wed May 27 17:25:23 2015 -0500 @@ -42,6 +42,7 @@ IntRegClass, ///< Integer register FloatRegClass, ///< Floating-point register CCRegClass, ///< Condition-code register + VectorRegClass, ///< Vector register MiscRegClass ///< Control (misc) register }; @@ -76,12 +77,15 @@ } 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; diff -r 866258a4a31e -r ecb65c144bbf src/cpu/simple/base.hh --- a/src/cpu/simple/base.hh Wed May 27 17:24:51 2015 -0500 +++ b/src/cpu/simple/base.hh Wed May 27 17:25:23 2015 -0500 @@ -87,6 +87,7 @@ typedef TheISA::FloatReg FloatReg; typedef TheISA::FloatRegBits FloatRegBits; typedef TheISA::CCReg CCReg; + typedef TheISA::VectorReg VectorReg; BPredUnit *branchPred; @@ -239,6 +240,10 @@ 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 @@ return thread->readCCReg(reg_idx); } + 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 @@ 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) { diff -r 866258a4a31e -r ecb65c144bbf src/cpu/simple_thread.hh --- a/src/cpu/simple_thread.hh Wed May 27 17:24:51 2015 -0500 +++ b/src/cpu/simple_thread.hh Wed May 27 17:25:23 2015 -0500 @@ -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 @@ 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 @@ 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,22 @@ #endif } + VectorReg readVectorReg(int reg_idx) + { +#ifdef ISA_HAS_VECTOR_REGS + int flatIndex = isa->flattenVectorIndex(reg_idx); + assert(0 <= flatIndex); + assert(flatIndex < TheISA::NumVectorRegs); + VectorReg regVal(readVectorRegFlat(flatIndex)); + DPRINTF(CCRegs, "Reading vector reg %d (%d).\n", + reg_idx, flatIndex); + return regVal; +#else + panic("Tried to read a vector register."); + return VectorReg(); +#endif + } + void setIntReg(int reg_idx, uint64_t val) { int flatIndex = isa->flattenIntIndex(reg_idx); @@ -325,6 +350,19 @@ #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() { @@ -414,6 +452,12 @@ } int + flattenVectorIndex(int reg) + { + return isa->flattenVectorIndex(reg); + } + + int flattenMiscIndex(int reg) { return isa->flattenMiscIndex(reg); @@ -450,6 +494,18 @@ void setCCRegFlat(int idx, CCReg val) { panic("setCCRegFlat w/no CC regs!\n"); } #endif + +#ifdef ISA_HAS_VECTOR_REGS + VectorReg readVectorRegFlat(int idx) { return vectorRegs[idx]; } + void setVectorRegFlat(int idx, const VectorReg &val) + { vectorRegs[idx] = val; } +#else + 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 }; diff -r 866258a4a31e -r ecb65c144bbf src/cpu/static_inst.hh --- a/src/cpu/static_inst.hh Wed May 27 17:24:51 2015 -0500 +++ b/src/cpu/static_inst.hh Wed May 27 17:25:23 2015 -0500 @@ -98,6 +98,7 @@ int8_t _numFPDestRegs; int8_t _numIntDestRegs; int8_t _numCCDestRegs; + int8_t _numVectorDestRegs; //@} public: @@ -116,9 +117,10 @@ 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 condition code destination regs. + int8_t numVectorDestRegs() const { return _numVectorDestRegs; } //@} /// @name Flag accessors. @@ -140,6 +142,7 @@ 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]; } diff -r 866258a4a31e -r ecb65c144bbf src/cpu/thread_context.hh --- a/src/cpu/thread_context.hh Wed May 27 17:24:51 2015 -0500 +++ b/src/cpu/thread_context.hh Wed May 27 17:25:23 2015 -0500 @@ -98,6 +98,7 @@ 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 @@ virtual CCReg readCCReg(int reg_idx) = 0; + virtual 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 @@ 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 @@ 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 @@ virtual CCReg readCCRegFlat(int idx) = 0; virtual void setCCRegFlat(int idx, CCReg val) = 0; + + virtual VectorReg readVectorRegFlat(int idx) = 0; + virtual void setVectorRegFlat(int idx, const VectorReg &val) = 0; /** @} */ }; @@ -402,6 +411,9 @@ CCReg readCCReg(int reg_idx) { return actualTC->readCCReg(reg_idx); } + 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 @@ 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 @@ 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 @@ void setCCRegFlat(int idx, CCReg val) { actualTC->setCCRegFlat(idx, val); } + + VectorReg readVectorRegFlat(int idx) + { return actualTC->readVectorRegFlat(idx); } + + void setVectorRegFlat(int idx, const VectorReg &val) + { actualTC->setVectorRegFlat(idx, val); } }; /** @{ */ diff -r 866258a4a31e -r ecb65c144bbf src/sim/insttracer.hh --- a/src/sim/insttracer.hh Wed May 27 17:24:51 2015 -0500 +++ b/src/sim/insttracer.hh Wed May 27 17:25:23 2015 -0500 @@ -58,6 +58,8 @@ class InstRecord { protected: + typedef TheISA::VectorReg VectorReg; + Tick when; // The following fields are initialized by the constructor and @@ -97,6 +99,7 @@ union { uint64_t as_int; double as_double; + VectorReg as_vector; } data; /** @defgroup fetch_seq @@ -120,7 +123,8 @@ DataInt16 = 2, DataInt32 = 4, DataInt64 = 8, - DataDouble = 3 + DataDouble = 3, + DataVector = 16 } data_status; /** @ingroup memory @@ -173,6 +177,8 @@ 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 @@ uint64_t getIntData() const { return data.as_int; } double getFloatData() const { return data.as_double; } + VectorReg getVectorData() const { return data.as_vector; } int getDataStatus() const { return data_status; } InstSeqNum getFetchSeq() const { return fetch_seq; }