From 4d8f4db8d135a23ceb5d54d3096e0598dd31e2fe Mon Sep 17 00:00:00 2001 From: Gene WU Date: Wed, 25 Aug 2010 19:10:42 -0500 Subject: 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 +++++++++++++++++++++++++++++++++++++++--- 3 files changed, 105 insertions(+), 9 deletions(-) (limited to 'src/arch/arm/insts') diff --git a/src/arch/arm/insts/macromem.cc b/src/arch/arm/insts/macromem.cc index 5602231f9..f64fbeff9 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 923e9c0a1..c1c8383da 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 609afa9aa..1baba5112 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 {} -- cgit v1.2.3