From 4d8f4db8d135a23ceb5d54d3096e0598dd31e2fe Mon Sep 17 00:00:00 2001 From: Gene WU Date: Wed, 25 Aug 2010 19:10:42 -0500 Subject: [PATCH] ARM: Use fewer micro-ops for register update loads if possible. Allow some loads that update the base register to use just two micro-ops. three micro-ops are only used if the destination register matches the offset register or the PC is the destination regsiter. If the PC is updated it needs to be the last micro-op otherwise O3 will mispredict. --- src/arch/arm/insts/macromem.cc | 19 +- src/arch/arm/insts/macromem.hh | 41 +++- src/arch/arm/insts/mem.hh | 54 ++++- src/arch/arm/isa/insts/ldr.isa | 46 ++-- src/arch/arm/isa/insts/macromem.isa | 38 ++- src/arch/arm/isa/insts/mem.isa | 40 +++- src/arch/arm/isa/insts/str.isa | 37 ++- src/arch/arm/isa/templates/macromem.isa | 51 +++- src/arch/arm/isa/templates/mem.isa | 296 ++++++++++++++++++++++-- src/arch/arm/isa/templates/pred.isa | 3 +- 10 files changed, 555 insertions(+), 70 deletions(-) diff --git a/src/arch/arm/insts/macromem.cc b/src/arch/arm/insts/macromem.cc index 5602231f9b..f64fbeff94 100644 --- a/src/arch/arm/insts/macromem.cc +++ b/src/arch/arm/insts/macromem.cc @@ -185,7 +185,7 @@ VldMultOp::VldMultOp(const char *mnem, ExtMachInst machInst, OpClass __opClass, if (wb) { if (rm != 15 && rm != 13) { microOps[uopIdx++] = - new MicroAddUop(machInst, rn, rn, rm); + new MicroAddUop(machInst, rn, rn, rm, 0, ArmISA::LSL); } else { microOps[uopIdx++] = new MicroAddiUop(machInst, rn, rn, regs * 8); @@ -320,7 +320,7 @@ VldSingleOp::VldSingleOp(const char *mnem, ExtMachInst machInst, if (wb) { if (rm != 15 && rm != 13) { microOps[uopIdx++] = - new MicroAddUop(machInst, rn, rn, rm); + new MicroAddUop(machInst, rn, rn, rm, 0, ArmISA::LSL); } else { microOps[uopIdx++] = new MicroAddiUop(machInst, rn, rn, loadSize); @@ -566,7 +566,7 @@ VstMultOp::VstMultOp(const char *mnem, ExtMachInst machInst, OpClass __opClass, if (wb) { if (rm != 15 && rm != 13) { microOps[uopIdx++] = - new MicroAddUop(machInst, rn, rn, rm); + new MicroAddUop(machInst, rn, rn, rm, 0, ArmISA::LSL); } else { microOps[uopIdx++] = new MicroAddiUop(machInst, rn, rn, regs * 8); @@ -762,7 +762,7 @@ VstSingleOp::VstSingleOp(const char *mnem, ExtMachInst machInst, if (wb) { if (rm != 15 && rm != 13) { microOps[uopIdx++] = - new MicroAddUop(machInst, rn, rn, rm); + new MicroAddUop(machInst, rn, rn, rm, 0, ArmISA::LSL); } else { microOps[uopIdx++] = new MicroAddiUop(machInst, rn, rn, storeSize); @@ -877,6 +877,17 @@ MicroIntImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const return ss.str(); } +std::string +MicroIntMov::generateDisassembly(Addr pc, const SymbolTable *symtab) const +{ + std::stringstream ss; + printMnemonic(ss); + printReg(ss, ura); + ss << ", "; + printReg(ss, urb); + return ss.str(); +} + std::string MicroIntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const { diff --git a/src/arch/arm/insts/macromem.hh b/src/arch/arm/insts/macromem.hh index 923e9c0a14..c1c8383dab 100644 --- a/src/arch/arm/insts/macromem.hh +++ b/src/arch/arm/insts/macromem.hh @@ -128,6 +128,23 @@ class MicroNeonMixLaneOp : public MicroNeonMixOp { } }; +/** + * Microops of the form IntRegA = IntRegB + */ +class MicroIntMov : public MicroOp +{ + protected: + RegIndex ura, urb; + + MicroIntMov(const char *mnem, ExtMachInst machInst, OpClass __opClass, + RegIndex _ura, RegIndex _urb) + : MicroOp(mnem, machInst, __opClass), + ura(_ura), urb(_urb) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; /** * Microops of the form IntRegA = IntRegB op Imm @@ -136,10 +153,10 @@ class MicroIntImmOp : public MicroOp { protected: RegIndex ura, urb; - uint8_t imm; + uint32_t imm; MicroIntImmOp(const char *mnem, ExtMachInst machInst, OpClass __opClass, - RegIndex _ura, RegIndex _urb, uint8_t _imm) + RegIndex _ura, RegIndex _urb, uint32_t _imm) : MicroOp(mnem, machInst, __opClass), ura(_ura), urb(_urb), imm(_imm) { @@ -166,6 +183,26 @@ class MicroIntOp : public MicroOp std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; +/** + * Microops of the form IntRegA = IntRegB op shifted IntRegC + */ +class MicroIntRegOp : public MicroOp +{ + protected: + RegIndex ura, urb, urc; + int32_t shiftAmt; + ArmShiftType shiftType; + + MicroIntRegOp(const char *mnem, ExtMachInst machInst, OpClass __opClass, + RegIndex _ura, RegIndex _urb, RegIndex _urc, + int32_t _shiftAmt, ArmShiftType _shiftType) + : MicroOp(mnem, machInst, __opClass), + ura(_ura), urb(_urb), urc(_urc), + shiftAmt(_shiftAmt), shiftType(_shiftType) + { + } +}; + /** * Memory microops which use IntReg + Imm addressing */ diff --git a/src/arch/arm/insts/mem.hh b/src/arch/arm/insts/mem.hh index 609afa9aa3..1baba51128 100644 --- a/src/arch/arm/insts/mem.hh +++ b/src/arch/arm/insts/mem.hh @@ -77,13 +77,29 @@ class RfeOp : public PredOp IntRegIndex base; AddrMode mode; bool wb; + static const unsigned numMicroops = 2; + + StaticInstPtr *uops; RfeOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _base, AddrMode _mode, bool _wb) : PredOp(mnem, _machInst, __opClass), - base(_base), mode(_mode), wb(_wb) + base(_base), mode(_mode), wb(_wb), uops(NULL) {} + virtual + ~RfeOp() + { + delete uops; + } + + StaticInstPtr + fetchMicroop(MicroPC microPC) + { + assert(uops != NULL && microPC < numMicroops); + return uops[microPC]; + } + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; @@ -101,13 +117,29 @@ class SrsOp : public PredOp uint32_t regMode; AddrMode mode; bool wb; + static const unsigned numMicroops = 2; + + StaticInstPtr *uops; SrsOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, uint32_t _regMode, AddrMode _mode, bool _wb) : PredOp(mnem, _machInst, __opClass), - regMode(_regMode), mode(_mode), wb(_wb) + regMode(_regMode), mode(_mode), wb(_wb), uops(NULL) {} + virtual + ~SrsOp() + { + delete uops; + } + + StaticInstPtr + fetchMicroop(MicroPC microPC) + { + assert(uops != NULL && microPC < numMicroops); + return uops[microPC]; + } + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; @@ -125,13 +157,29 @@ class Memory : public PredOp IntRegIndex dest; IntRegIndex base; bool add; + static const unsigned numMicroops = 3; + + StaticInstPtr *uops; Memory(const char *mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _base, bool _add) : PredOp(mnem, _machInst, __opClass), - dest(_dest), base(_base), add(_add) + dest(_dest), base(_base), add(_add), uops(NULL) {} + virtual + ~Memory() + { + delete [] uops; + } + + StaticInstPtr + fetchMicroop(MicroPC microPC) + { + assert(uops != NULL && microPC < numMicroops); + return uops[microPC]; + } + virtual void printOffset(std::ostream &os) const {} diff --git a/src/arch/arm/isa/insts/ldr.isa b/src/arch/arm/isa/insts/ldr.isa index a936ffaaf0..38a458b236 100644 --- a/src/arch/arm/isa/insts/ldr.isa +++ b/src/arch/arm/isa/insts/ldr.isa @@ -67,7 +67,7 @@ let {{ self.memFlags = ["ArmISA::TLB::MustBeOne"] self.codeBlobs = {"postacc_code" : ""} - def emitHelper(self, base = 'Memory'): + def emitHelper(self, base = 'Memory', wbDecl = None): global header_output, decoder_output, exec_output @@ -76,7 +76,7 @@ let {{ (newHeader, newDecoder, newExec) = self.fillTemplates(self.name, self.Name, codeBlobs, - self.memFlags, [], base) + self.memFlags, [], base, wbDecl) header_output += newHeader decoder_output += newDecoder @@ -113,22 +113,36 @@ let {{ Cpsr = ~CondCodesMask & newCpsr; CondCodes = CondCodesMask & newCpsr; ''' - if self.writeback: - accCode += "Base = Base + %s;\n" % wbDiff self.codeBlobs["memacc_code"] = accCode - self.emitHelper('RfeOp') + wbDecl = None + if self.writeback: + wbDecl = "MicroAddiUop(machInst, base, base, %d);" % wbDiff + self.emitHelper('RfeOp', wbDecl) class LoadImmInst(LoadInst): def __init__(self, *args, **kargs): super(LoadImmInst, self).__init__(*args, **kargs) self.offset = self.op + " imm" + if self.add: + self.wbDecl = "MicroAddiUop(machInst, base, base, imm);" + else: + self.wbDecl = "MicroSubiUop(machInst, base, base, imm);" + class LoadRegInst(LoadInst): def __init__(self, *args, **kargs): super(LoadRegInst, self).__init__(*args, **kargs) self.offset = self.op + " shift_rm_imm(Index, shiftAmt," + \ " shiftType, CondCodes<29:>)" + if self.add: + self.wbDecl = ''' + MicroAddUop(machInst, base, base, wbIndexReg, shiftAmt, shiftType); + ''' + else: + self.wbDecl = ''' + MicroSubUop(machInst, base, base, wbIndexReg, shiftAmt, shiftType); + ''' class LoadSingle(LoadInst): def __init__(self, *args, **kargs): @@ -175,20 +189,20 @@ let {{ accCode = "IWDest = cSwap(Mem%s, ((CPSR)Cpsr).e);" accCode = accCode % buildMemSuffix(self.sign, self.size) - if self.writeback: - accCode += "Base = Base %s;\n" % self.offset - self.codeBlobs["memacc_code"] = accCode # Push it out to the output files base = buildMemBase(self.basePrefix, self.post, self.writeback) - self.emitHelper(base) + wbDecl = None + if self.writeback: + wbDecl = self.wbDecl + self.emitHelper(base, wbDecl) def loadImmClassName(post, add, writeback, size=4, sign=False, user=False): return memClassName("LOAD_IMM", post, add, writeback, size, sign, user) class LoadImm(LoadImmInst, LoadSingle): - decConstBase = 'LoadStoreImm' + decConstBase = 'LoadImm' basePrefix = 'MemoryImm' nameFunc = staticmethod(loadImmClassName) @@ -196,7 +210,7 @@ let {{ return memClassName("LOAD_REG", post, add, writeback, size, sign, user) class LoadReg(LoadRegInst, LoadSingle): - decConstBase = 'LoadStoreReg' + decConstBase = 'LoadReg' basePrefix = 'MemoryReg' nameFunc = staticmethod(loadRegClassName) @@ -244,14 +258,14 @@ let {{ FpDest2.uw = (uint32_t)(swappedMem >> 32); ''' - if self.writeback: - accCode += "Base = Base %s;\n" % self.offset - self.codeBlobs["memacc_code"] = accCode # Push it out to the output files base = buildMemBase(self.basePrefix, self.post, self.writeback) - self.emitHelper(base) + wbDecl = None + if self.writeback: + wbDecl = self.wbDecl + self.emitHelper(base, wbDecl) def loadDoubleImmClassName(post, add, writeback): return memClassName("LOAD_IMMD", post, add, writeback, 4, False, False) @@ -265,7 +279,7 @@ let {{ return memClassName("LOAD_REGD", post, add, writeback, 4, False, False) class LoadDoubleReg(LoadRegInst, LoadDouble): - decConstBase = 'LoadStoreDReg' + decConstBase = 'LoadDReg' basePrefix = 'MemoryDReg' nameFunc = staticmethod(loadDoubleRegClassName) diff --git a/src/arch/arm/isa/insts/macromem.isa b/src/arch/arm/isa/insts/macromem.isa index bcb1e26b86..f595f40434 100644 --- a/src/arch/arm/isa/insts/macromem.isa +++ b/src/arch/arm/isa/insts/macromem.isa @@ -575,8 +575,12 @@ let {{ ['IsMicroop']) microAddUopIop = InstObjParams('add_uop', 'MicroAddUop', - 'MicroIntOp', - {'code': 'Ra = Rb + Rc;', + 'MicroIntRegOp', + {'code': + '''Ra = Rb + shift_rm_imm(Rc, shiftAmt, + shiftType, + CondCodes<29:>); + ''', 'predicate_test': predicateTest}, ['IsMicroop']) @@ -586,15 +590,39 @@ let {{ 'predicate_test': predicateTest}, ['IsMicroop']) + microSubUopIop = InstObjParams('sub_uop', 'MicroSubUop', + 'MicroIntRegOp', + {'code': + '''Ra = Rb - shift_rm_imm(Rc, shiftAmt, + shiftType, + CondCodes<29:>); + ''', + 'predicate_test': predicateTest}, + ['IsMicroop']) + + microUopRegMovIop = InstObjParams('uopReg_uop', 'MicroUopRegMov', + 'MicroIntMov', + {'code': 'IWRa = Rb;', + 'predicate_test': predicateTest}, + ['IsMicroop']) + header_output = MicroIntImmDeclare.subst(microAddiUopIop) + \ MicroIntImmDeclare.subst(microSubiUopIop) + \ - MicroIntDeclare.subst(microAddUopIop) + MicroIntRegDeclare.subst(microAddUopIop) + \ + MicroIntRegDeclare.subst(microSubUopIop) + \ + MicroIntMovDeclare.subst(microUopRegMovIop) + decoder_output = MicroIntImmConstructor.subst(microAddiUopIop) + \ MicroIntImmConstructor.subst(microSubiUopIop) + \ - MicroIntConstructor.subst(microAddUopIop) + MicroIntRegConstructor.subst(microAddUopIop) + \ + MicroIntRegConstructor.subst(microSubUopIop) + \ + MicroIntMovConstructor.subst(microUopRegMovIop) + exec_output = PredOpExecute.subst(microAddiUopIop) + \ PredOpExecute.subst(microSubiUopIop) + \ - PredOpExecute.subst(microAddUopIop) + PredOpExecute.subst(microAddUopIop) + \ + PredOpExecute.subst(microSubUopIop) + \ + PredOpExecute.subst(microUopRegMovIop) }}; let {{ diff --git a/src/arch/arm/isa/insts/mem.isa b/src/arch/arm/isa/insts/mem.isa index aa47d5b7f1..507f8cd4bf 100644 --- a/src/arch/arm/isa/insts/mem.isa +++ b/src/arch/arm/isa/insts/mem.isa @@ -48,7 +48,7 @@ let {{ self.constructTemplate = eval(self.decConstBase + 'Constructor') def fillTemplates(self, name, Name, codeBlobs, memFlags, instFlags, - base = 'Memory'): + base = 'Memory', wbDecl = None): # Make sure flags are in lists (convert to lists if not). memFlags = makeList(memFlags) instFlags = makeList(instFlags) @@ -62,14 +62,38 @@ let {{ codeBlobs["ea_code"] = eaCode - iop = InstObjParams(name, Name, base, codeBlobs, instFlags) + macroName = Name + instFlagsCopy = list(instFlags) + codeBlobsCopy = dict(codeBlobs) + if wbDecl is not None: + instFlagsCopy.append('IsMicroop') + Name = Name + 'Acc' + codeBlobsCopy['acc_name'] = Name + codeBlobsCopy['wb_decl'] = wbDecl + codeBlobsCopy['use_uops'] = 0 - # (header_output, decoder_output, decode_block, exec_output) - return (self.declareTemplate.subst(iop), - self.constructTemplate.subst(iop), - self.fullExecTemplate.subst(iop) - + self.initiateAccTemplate.subst(iop) - + self.completeAccTemplate.subst(iop)) + iop = InstObjParams(name, Name, base, + codeBlobsCopy, instFlagsCopy) + + header_output = self.declareTemplate.subst(iop) + decoder_output = self.constructTemplate.subst(iop) + exec_output = self.fullExecTemplate.subst(iop) + \ + self.initiateAccTemplate.subst(iop) + \ + self.completeAccTemplate.subst(iop) + + if wbDecl is not None: + iop = InstObjParams(name, macroName, base, + { "wb_decl" : wbDecl, + "acc_name" : Name, + "use_uops" : 1 }, + ['IsMacroop']) + header_output += self.declareTemplate.subst(iop) + decoder_output += self.constructTemplate.subst(iop) + exec_output += PanicExecute.subst(iop) + \ + PanicInitiateAcc.subst(iop) + \ + PanicCompleteAcc.subst(iop) + + return (header_output, decoder_output, exec_output) def pickPredicate(blobs): for val in blobs.values(): diff --git a/src/arch/arm/isa/insts/str.isa b/src/arch/arm/isa/insts/str.isa index 66a486ecf3..ff98c58d21 100644 --- a/src/arch/arm/isa/insts/str.isa +++ b/src/arch/arm/isa/insts/str.isa @@ -67,7 +67,7 @@ let {{ self.memFlags = ["ArmISA::TLB::MustBeOne"] self.codeBlobs = { "postacc_code" : "" } - def emitHelper(self, base = 'Memory'): + def emitHelper(self, base = 'Memory', wbDecl = None): global header_output, decoder_output, exec_output @@ -76,7 +76,7 @@ let {{ (newHeader, newDecoder, newExec) = self.fillTemplates(self.name, self.Name, codeBlobs, - self.memFlags, [], base) + self.memFlags, [], base, wbDecl) header_output += newHeader decoder_output += newDecoder @@ -137,11 +137,24 @@ let {{ super(StoreImmInst, self).__init__(*args, **kargs) self.offset = self.op + " imm" + if self.add: + self.wbDecl = "MicroAddiUop(machInst, base, base, imm);" + else: + self.wbDecl = "MicroSubiUop(machInst, base, base, imm);" + class StoreRegInst(StoreInst): def __init__(self, *args, **kargs): super(StoreRegInst, self).__init__(*args, **kargs) self.offset = self.op + " shift_rm_imm(Index, shiftAmt," + \ " shiftType, CondCodes<29:>)" + if self.add: + self.wbDecl = ''' + MicroAddUop(machInst, base, base, index, shiftAmt, shiftType); + ''' + else: + self.wbDecl = ''' + MicroSubUop(machInst, base, base, index, shiftAmt, shiftType); + ''' class StoreSingle(StoreInst): def __init__(self, *args, **kargs): @@ -186,14 +199,14 @@ let {{ accCode = accCode % \ { "suffix" : buildMemSuffix(self.sign, self.size) } - if self.writeback: - accCode += "Base = Base %s;\n" % self.offset - self.codeBlobs["memacc_code"] = accCode # Push it out to the output files base = buildMemBase(self.basePrefix, self.post, self.writeback) - self.emitHelper(base) + wbDecl = None + if self.writeback: + wbDecl = self.wbDecl + self.emitHelper(base, wbDecl) def storeImmClassName(post, add, writeback, size=4, sign=False, user=False): return memClassName("STORE_IMM", post, add, writeback, size, sign, user) @@ -217,7 +230,7 @@ let {{ return memClassName("STORE_REG", post, add, writeback, size, sign, user) class StoreReg(StoreRegInst, StoreSingle): - decConstBase = 'LoadStoreReg' + decConstBase = 'StoreReg' basePrefix = 'MemoryReg' nameFunc = staticmethod(storeRegClassName) @@ -265,14 +278,14 @@ let {{ ((uint64_t)cSwap(Dest2.uw, cpsr.e) << 32); ''' - if self.writeback: - accCode += "Base = Base %s;\n" % self.offset - self.codeBlobs["memacc_code"] = accCode # Push it out to the output files base = buildMemBase(self.basePrefix, self.post, self.writeback) - self.emitHelper(base) + wbDecl = None + if self.writeback: + wbDecl = self.wbDecl + self.emitHelper(base, wbDecl) def storeDoubleImmClassName(post, add, writeback): return memClassName("STORE_IMMD", post, add, writeback, 4, False, False) @@ -296,7 +309,7 @@ let {{ return memClassName("STORE_REGD", post, add, writeback, 4, False, False) class StoreDoubleReg(StoreRegInst, StoreDouble): - decConstBase = 'LoadStoreDReg' + decConstBase = 'StoreDReg' basePrefix = 'MemoryDReg' nameFunc = staticmethod(storeDoubleRegClassName) diff --git a/src/arch/arm/isa/templates/macromem.isa b/src/arch/arm/isa/templates/macromem.isa index 5397a2637a..c7ebfcd069 100644 --- a/src/arch/arm/isa/templates/macromem.isa +++ b/src/arch/arm/isa/templates/macromem.isa @@ -214,6 +214,31 @@ def template MicroNeonMixLaneDeclare {{ }; }}; +//////////////////////////////////////////////////////////////////// +// +// Integer = Integer +// + +def template MicroIntMovDeclare {{ + class %(class_name)s : public %(base_class)s + { + public: + %(class_name)s(ExtMachInst machInst, + RegIndex _ura, RegIndex _urb); + %(BasicExecDeclare)s + }; +}}; +def template MicroIntMovConstructor {{ + %(class_name)s::%(class_name)s(ExtMachInst machInst, + RegIndex _ura, + RegIndex _urb) + : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, + _ura, _urb) + { + %(constructor)s; + } +}}; + //////////////////////////////////////////////////////////////////// // // Integer = Integer op Immediate microops @@ -225,7 +250,7 @@ def template MicroIntImmDeclare {{ public: %(class_name)s(ExtMachInst machInst, RegIndex _ura, RegIndex _urb, - uint8_t _imm); + int32_t _imm); %(BasicExecDeclare)s }; }}; @@ -234,7 +259,7 @@ def template MicroIntImmConstructor {{ %(class_name)s::%(class_name)s(ExtMachInst machInst, RegIndex _ura, RegIndex _urb, - uint8_t _imm) + int32_t _imm) : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, _ura, _urb, _imm) { @@ -242,6 +267,28 @@ def template MicroIntImmConstructor {{ } }}; +def template MicroIntRegDeclare {{ + class %(class_name)s : public %(base_class)s + { + public: + %(class_name)s(ExtMachInst machInst, + RegIndex _ura, RegIndex _urb, RegIndex _urc, + int32_t _shiftAmt, ArmShiftType _shiftType); + %(BasicExecDeclare)s + }; +}}; + +def template MicroIntRegConstructor {{ + %(class_name)s::%(class_name)s(ExtMachInst machInst, + RegIndex _ura, RegIndex _urb, RegIndex _urc, + int32_t _shiftAmt, ArmShiftType _shiftType) + : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, + _ura, _urb, _urc, _shiftAmt, _shiftType) + { + %(constructor)s; + } +}}; + //////////////////////////////////////////////////////////////////// // // Macro Memory-format instructions diff --git a/src/arch/arm/isa/templates/mem.isa b/src/arch/arm/isa/templates/mem.isa index 686a8b0aac..1d0e1316c6 100644 --- a/src/arch/arm/isa/templates/mem.isa +++ b/src/arch/arm/isa/templates/mem.isa @@ -41,6 +41,35 @@ // Authors: Stephen Hines +def template PanicExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + panic("Execute function executed when it shouldn't be!\n"); + return NoFault; + } +}}; + +def template PanicInitiateAcc {{ + Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + panic("InitiateAcc function executed when it shouldn't be!\n"); + return NoFault; + } +}}; + +def template PanicCompleteAcc {{ + Fault %(class_name)s::completeAcc(PacketPtr pkt, + %(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + panic("CompleteAcc function executed when it shouldn't be!\n"); + return NoFault; + } +}}; + + def template SwapExecute {{ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const @@ -73,7 +102,8 @@ def template SwapExecute {{ xc->setPredicate(false); } - if (fault == NoFault && machInst.itstateMask != 0) { + if (fault == NoFault && machInst.itstateMask != 0 && + (!isMicroop() || isLastMicroop())) { xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate); } @@ -109,7 +139,8 @@ def template SwapInitiateAcc {{ xc->setPredicate(false); } - if (fault == NoFault && machInst.itstateMask != 0) { + if (fault == NoFault && machInst.itstateMask != 0 && + (!isMicroop() || isLastMicroop())) { xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate); } @@ -172,7 +203,8 @@ def template LoadExecute {{ xc->setPredicate(false); } - if (fault == NoFault && machInst.itstateMask != 0) { + if (fault == NoFault && machInst.itstateMask != 0 && + (!isMicroop() || isLastMicroop())) { xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate); } @@ -208,7 +240,8 @@ def template NeonLoadExecute {{ } } - if (fault == NoFault && machInst.itstateMask != 0) { + if (fault == NoFault && machInst.itstateMask != 0 && + (!isMicroop() || isLastMicroop())) { xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate); } @@ -245,7 +278,8 @@ def template StoreExecute {{ xc->setPredicate(false); } - if (fault == NoFault && machInst.itstateMask != 0) { + if (fault == NoFault && machInst.itstateMask != 0 && + (!isMicroop() || isLastMicroop())) { xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate); } @@ -285,7 +319,8 @@ def template NeonStoreExecute {{ } } - if (fault == NoFault && machInst.itstateMask != 0) { + if (fault == NoFault && machInst.itstateMask != 0 && + (!isMicroop() || isLastMicroop())) { xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate); } @@ -328,7 +363,8 @@ def template StoreExExecute {{ xc->setPredicate(false); } - if (fault == NoFault && machInst.itstateMask != 0) { + if (fault == NoFault && machInst.itstateMask != 0 && + (!isMicroop() || isLastMicroop())) { xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate); } @@ -365,8 +401,8 @@ def template StoreExInitiateAcc {{ } else { xc->setPredicate(false); } - - if (fault == NoFault && machInst.itstateMask != 0) { + if (fault == NoFault && machInst.itstateMask != 0 && + (!isMicroop() || isLastMicroop())) { xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate); } @@ -404,7 +440,8 @@ def template StoreInitiateAcc {{ xc->setPredicate(false); } - if (fault == NoFault && machInst.itstateMask != 0) { + if (fault == NoFault && machInst.itstateMask != 0 && + (!isMicroop() || isLastMicroop())) { xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate); } @@ -443,7 +480,8 @@ def template NeonStoreInitiateAcc {{ } } - if (fault == NoFault && machInst.itstateMask != 0) { + if (fault == NoFault && machInst.itstateMask != 0 && + (!isMicroop() || isLastMicroop())) { xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate); } @@ -469,7 +507,8 @@ def template LoadInitiateAcc {{ } } else { xc->setPredicate(false); - if (fault == NoFault && machInst.itstateMask != 0) { + if (fault == NoFault && machInst.itstateMask != 0 && + (!isMicroop() || isLastMicroop())) { xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate); } } @@ -495,7 +534,8 @@ def template NeonLoadInitiateAcc {{ if (fault == NoFault) { fault = xc->readBytes(EA, NULL, %(size)d, memAccessFlags); } - } else if (fault == NoFault && machInst.itstateMask != 0) { + } else if (fault == NoFault && machInst.itstateMask != 0 && + (!isMicroop() || isLastMicroop())) { xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate); } @@ -791,7 +831,7 @@ def template StoreExImmDeclare {{ }; }}; -def template LoadStoreDRegDeclare {{ +def template StoreDRegDeclare {{ /** * Static instruction class for "%(mnemonic)s". */ @@ -814,7 +854,7 @@ def template LoadStoreDRegDeclare {{ }; }}; -def template LoadStoreRegDeclare {{ +def template StoreRegDeclare {{ /** * Static instruction class for "%(mnemonic)s". */ @@ -836,6 +876,71 @@ def template LoadStoreRegDeclare {{ }; }}; +def template LoadDRegDeclare {{ + /** + * Static instruction class for "%(mnemonic)s". + */ + class %(class_name)s : public %(base_class)s + { + public: + + /// Constructor. + %(class_name)s(ExtMachInst machInst, + uint32_t _dest, uint32_t _dest2, + uint32_t _base, bool _add, + int32_t _shiftAmt, uint32_t _shiftType, + uint32_t _index); + + %(BasicExecDeclare)s + + %(InitiateAccDeclare)s + + %(CompleteAccDeclare)s + }; +}}; + +def template LoadRegDeclare {{ + /** + * Static instruction class for "%(mnemonic)s". + */ + class %(class_name)s : public %(base_class)s + { + public: + + /// Constructor. + %(class_name)s(ExtMachInst machInst, + uint32_t _dest, uint32_t _base, bool _add, + int32_t _shiftAmt, uint32_t _shiftType, + uint32_t _index); + + %(BasicExecDeclare)s + + %(InitiateAccDeclare)s + + %(CompleteAccDeclare)s + }; +}}; + +def template LoadImmDeclare {{ + /** + * Static instruction class for "%(mnemonic)s". + */ + class %(class_name)s : public %(base_class)s + { + public: + + /// Constructor. + %(class_name)s(ExtMachInst machInst, + uint32_t _dest, uint32_t _base, bool _add, int32_t _imm); + + %(BasicExecDeclare)s + + %(InitiateAccDeclare)s + + %(CompleteAccDeclare)s + }; +}}; + def template InitiateAccDeclare {{ Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; }}; @@ -851,6 +956,13 @@ def template RfeConstructor {{ (IntRegIndex)_base, (AddrMode)_mode, _wb) { %(constructor)s; +#if %(use_uops)d + assert(numMicroops >= 2); + uops = new StaticInstPtr[numMicroops]; + uops[0] = new %(acc_name)s(machInst, _base, _mode, _wb); + uops[1] = new %(wb_decl)s; + uops[1]->setLastMicroop(); +#endif } }}; @@ -861,6 +973,13 @@ def template SrsConstructor {{ (OperatingMode)_regMode, (AddrMode)_mode, _wb) { %(constructor)s; +#if %(use_uops)d + assert(numMicroops >= 2); + uops = new StaticInstPtr[numMicroops]; + uops[0] = new %(acc_name)s(machInst, _regMode, _mode, _wb); + uops[1] = new %(wb_decl)s; + uops[1]->setLastMicroop(); +#endif } }}; @@ -883,6 +1002,13 @@ def template LoadStoreDImmConstructor {{ (IntRegIndex)_base, _add, _imm) { %(constructor)s; +#if %(use_uops)d + assert(numMicroops >= 2); + uops = new StaticInstPtr[numMicroops]; + uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add, _imm); + uops[1] = new %(wb_decl)s; + uops[1]->setLastMicroop(); +#endif } }}; @@ -896,6 +1022,14 @@ def template StoreExDImmConstructor {{ (IntRegIndex)_base, _add, _imm) { %(constructor)s; +#if %(use_uops)d + assert(numMicroops >= 2); + uops = new StaticInstPtr[numMicroops]; + uops[0] = new %(acc_name)s(machInst, _result, _dest, _dest2, + _base, _add, _imm); + uops[1] = new %(wb_decl)s; + uops[1]->setLastMicroop(); +#endif } }}; @@ -906,6 +1040,13 @@ def template LoadStoreImmConstructor {{ (IntRegIndex)_dest, (IntRegIndex)_base, _add, _imm) { %(constructor)s; +#if %(use_uops)d + assert(numMicroops >= 2); + uops = new StaticInstPtr[numMicroops]; + uops[0] = new %(acc_name)s(machInst, _dest, _base, _add, _imm); + uops[1] = new %(wb_decl)s; + uops[1]->setLastMicroop(); +#endif } }}; @@ -918,10 +1059,18 @@ def template StoreExImmConstructor {{ (IntRegIndex)_base, _add, _imm) { %(constructor)s; +#if %(use_uops)d + assert(numMicroops >= 2); + uops = new StaticInstPtr[numMicroops]; + uops[0] = new %(acc_name)s(machInst, _result, _dest, + _base, _add, _imm); + uops[1] = new %(wb_decl)s; + uops[1]->setLastMicroop(); +#endif } }}; -def template LoadStoreDRegConstructor {{ +def template StoreDRegConstructor {{ inline %(class_name)s::%(class_name)s(ExtMachInst machInst, uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add, int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index) @@ -932,10 +1081,18 @@ def template LoadStoreDRegConstructor {{ (IntRegIndex)_index) { %(constructor)s; +#if %(use_uops)d + assert(numMicroops >= 2); + uops = new StaticInstPtr[numMicroops]; + uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add, + _shiftAmt, _shiftType, _index); + uops[1] = new %(wb_decl)s; + uops[1]->setLastMicroop(); +#endif } }}; -def template LoadStoreRegConstructor {{ +def template StoreRegConstructor {{ inline %(class_name)s::%(class_name)s(ExtMachInst machInst, uint32_t _dest, uint32_t _base, bool _add, int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index) @@ -945,5 +1102,110 @@ def template LoadStoreRegConstructor {{ (IntRegIndex)_index) { %(constructor)s; +#if %(use_uops)d + assert(numMicroops >= 2); + uops = new StaticInstPtr[numMicroops]; + uops[0] = new %(acc_name)s(machInst, _dest, _base, _add, + _shiftAmt, _shiftType, _index); + uops[1] = new %(wb_decl)s; + uops[1]->setLastMicroop(); +#endif } }}; + +def template LoadDRegConstructor {{ + inline %(class_name)s::%(class_name)s(ExtMachInst machInst, + uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add, + int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index) + : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, + (IntRegIndex)_dest, (IntRegIndex)_dest2, + (IntRegIndex)_base, _add, + _shiftAmt, (ArmShiftType)_shiftType, + (IntRegIndex)_index) + { + %(constructor)s; +#if %(use_uops)d + assert(numMicroops >= 2); + uops = new StaticInstPtr[numMicroops]; + if ((_dest == _index) || (_dest2 == _index)) { + IntRegIndex wbIndexReg = INTREG_UREG0; + uops[0] = new MicroUopRegMov(machInst, INTREG_UREG0, _index); + uops[1] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add, + _shiftAmt, _shiftType, _index); + uops[2] = new %(wb_decl)s; + uops[2]->setLastMicroop(); + } else { + IntRegIndex wbIndexReg = index; + uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add, + _shiftAmt, _shiftType, _index); + uops[1] = new %(wb_decl)s; + uops[1]->setLastMicroop(); + } +#endif + } +}}; + +def template LoadRegConstructor {{ + inline %(class_name)s::%(class_name)s(ExtMachInst machInst, + uint32_t _dest, uint32_t _base, bool _add, + int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index) + : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, + (IntRegIndex)_dest, (IntRegIndex)_base, _add, + _shiftAmt, (ArmShiftType)_shiftType, + (IntRegIndex)_index) + { + %(constructor)s; +#if %(use_uops)d + assert(numMicroops >= 2); + uops = new StaticInstPtr[numMicroops]; + if (_dest == INTREG_PC) { + IntRegIndex wbIndexReg = index; + uops[0] = new %(acc_name)s(machInst, INTREG_UREG0, _base, _add, + _shiftAmt, _shiftType, _index); + uops[1] = new %(wb_decl)s; + uops[2] = new MicroUopRegMov(machInst, INTREG_PC, INTREG_UREG0); + uops[2]->setLastMicroop(); + } else if(_dest == _index) { + IntRegIndex wbIndexReg = INTREG_UREG0; + uops[0] = new MicroUopRegMov(machInst, INTREG_UREG0, _index); + uops[1] = new %(acc_name)s(machInst, _dest, _base, _add, + _shiftAmt, _shiftType, _index); + uops[2] = new %(wb_decl)s; + uops[2]->setLastMicroop(); + } else { + IntRegIndex wbIndexReg = index; + uops[0] = new %(acc_name)s(machInst, _dest, _base, _add, + _shiftAmt, _shiftType, _index); + uops[1] = new %(wb_decl)s; + uops[1]->setLastMicroop(); + + } +#endif + } +}}; + +def template LoadImmConstructor {{ + inline %(class_name)s::%(class_name)s(ExtMachInst machInst, + uint32_t _dest, uint32_t _base, bool _add, int32_t _imm) + : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, + (IntRegIndex)_dest, (IntRegIndex)_base, _add, _imm) + { + %(constructor)s; +#if %(use_uops)d + assert(numMicroops >= 2); + uops = new StaticInstPtr[numMicroops]; + if (_dest == INTREG_PC) { + uops[0] = new %(acc_name)s(machInst, INTREG_UREG0, _base, _add, + _imm); + uops[1] = new %(wb_decl)s; + uops[2] = new MicroUopRegMov(machInst, INTREG_PC, INTREG_UREG0); + uops[2]->setLastMicroop(); + } else { + uops[0] = new %(acc_name)s(machInst, _dest, _base, _add, _imm); + uops[1] = new %(wb_decl)s; + uops[1]->setLastMicroop(); + } +#endif + } +}}; + diff --git a/src/arch/arm/isa/templates/pred.isa b/src/arch/arm/isa/templates/pred.isa index 1029cfaeec..b5bdbc40e5 100644 --- a/src/arch/arm/isa/templates/pred.isa +++ b/src/arch/arm/isa/templates/pred.isa @@ -146,7 +146,8 @@ def template PredOpExecute {{ xc->setPredicate(false); } - if (fault == NoFault && machInst.itstateMask != 0) { + if (fault == NoFault && machInst.itstateMask != 0&& + (!isMicroop() || isLastMicroop())) { xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate); }