From 0f9a3671b6d12f887501bc80ca50bb23c383686d Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Tue, 18 Jan 2011 16:30:02 -0600 Subject: [PATCH] ARM: Add support for moving predicated false dest operands from sources. --- src/arch/arm/isa/insts/misc.isa | 3 +- src/arch/arm/isa/templates/basic.isa | 5 ++ src/arch/arm/isa/templates/branch.isa | 30 ++++++++++++ src/arch/arm/isa/templates/macromem.isa | 60 +++++++++++++++++++++++ src/arch/arm/isa/templates/mem.isa | 60 +++++++++++++++++++++++ src/arch/arm/isa/templates/misc.isa | 65 +++++++++++++++++++++++++ src/arch/arm/isa/templates/mult.isa | 10 ++++ src/arch/arm/isa/templates/neon.isa | 25 ++++++++++ src/arch/arm/isa/templates/pred.isa | 15 ++++++ src/arch/arm/isa/templates/vfp.isa | 20 ++++++++ src/arch/arm/registers.hh | 6 ++- src/cpu/o3/dyn_inst.hh | 12 +++++ src/cpu/o3/iew_impl.hh | 2 + src/cpu/o3/lsq_unit_impl.hh | 5 ++ 14 files changed, 315 insertions(+), 3 deletions(-) diff --git a/src/arch/arm/isa/insts/misc.isa b/src/arch/arm/isa/insts/misc.isa index a1cf895f8..68320d3c5 100644 --- a/src/arch/arm/isa/insts/misc.isa +++ b/src/arch/arm/isa/insts/misc.isa @@ -467,8 +467,7 @@ let {{ exec_output += PredOpExecute.subst(usada8Iop) bkptCode = 'return new PrefetchAbort(PC, ArmFault::DebugEvent);\n' - bkptIop = InstObjParams("bkpt", "BkptInst", "ArmStaticInst", - bkptCode) + bkptIop = InstObjParams("bkpt", "BkptInst", "PredOp", bkptCode) header_output += BasicDeclare.subst(bkptIop) decoder_output += BasicConstructor.subst(bkptIop) exec_output += BasicExecute.subst(bkptIop) diff --git a/src/arch/arm/isa/templates/basic.isa b/src/arch/arm/isa/templates/basic.isa index 843f90840..0728b66e3 100644 --- a/src/arch/arm/isa/templates/basic.isa +++ b/src/arch/arm/isa/templates/basic.isa @@ -52,6 +52,11 @@ def template BasicConstructor {{ inline %(class_name)s::%(class_name)s(ExtMachInst machInst) : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } } }}; diff --git a/src/arch/arm/isa/templates/branch.isa b/src/arch/arm/isa/templates/branch.isa index a666c28fa..d1f581f51 100644 --- a/src/arch/arm/isa/templates/branch.isa +++ b/src/arch/arm/isa/templates/branch.isa @@ -53,6 +53,11 @@ def template BranchImmConstructor {{ : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, _imm) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } } }}; @@ -75,6 +80,11 @@ def template BranchImmCondConstructor {{ _imm, _condCode) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } } }}; @@ -94,6 +104,11 @@ def template BranchRegConstructor {{ : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, _op1) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } } }}; @@ -116,6 +131,11 @@ def template BranchRegCondConstructor {{ _op1, _condCode) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } } }}; @@ -152,6 +172,11 @@ def template BranchRegRegConstructor {{ : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, _op1, _op2) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } } }}; @@ -173,5 +198,10 @@ def template BranchImmRegConstructor {{ : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, _imm, _op1) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } } }}; diff --git a/src/arch/arm/isa/templates/macromem.isa b/src/arch/arm/isa/templates/macromem.isa index c7ebfcd06..7620fb871 100644 --- a/src/arch/arm/isa/templates/macromem.isa +++ b/src/arch/arm/isa/templates/macromem.isa @@ -69,6 +69,11 @@ def template MicroMemConstructor {{ _ura, _urb, _up, _imm) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } } }}; @@ -89,6 +94,11 @@ def template MicroNeonMemDeclare {{ { memAccessFlags |= extraMemFlags; %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } } %(BasicExecDeclare)s @@ -121,6 +131,11 @@ def template MicroIntConstructor {{ _ura, _urb, _urc) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } } }}; @@ -158,6 +173,11 @@ def template MicroNeonMixDeclare {{ _dest, _op1, _step) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } } %(BasicExecDeclare)s @@ -208,6 +228,11 @@ def template MicroNeonMixLaneDeclare {{ _dest, _op1, _step, _lane) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } } %(BasicExecDeclare)s @@ -236,6 +261,11 @@ def template MicroIntMovConstructor {{ _ura, _urb) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } } }}; @@ -264,6 +294,11 @@ def template MicroIntImmConstructor {{ _ura, _urb, _imm) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } } }}; @@ -286,6 +321,11 @@ def template MicroIntRegConstructor {{ _ura, _urb, _urc, _shiftAmt, _shiftType) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } } }}; @@ -317,6 +357,11 @@ def template MacroMemConstructor {{ index, up, user, writeback, load, reglist) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } } }}; @@ -341,6 +386,11 @@ def template VMemMultConstructor {{ rn, vd, regs, inc, size, align, rm) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } } }}; @@ -364,6 +414,11 @@ def template VMemSingleConstructor {{ rn, vd, regs, inc, size, align, rm, lane) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } } }}; @@ -390,6 +445,11 @@ def template MacroVFPMemConstructor {{ vd, single, up, writeback, load, offset) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } } }}; diff --git a/src/arch/arm/isa/templates/mem.isa b/src/arch/arm/isa/templates/mem.isa index ab4f1b01b..66384331b 100644 --- a/src/arch/arm/isa/templates/mem.isa +++ b/src/arch/arm/isa/templates/mem.isa @@ -913,6 +913,11 @@ def template RfeConstructor {{ (IntRegIndex)_base, (AddrMode)_mode, _wb) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } #if %(use_uops)d assert(numMicroops >= 2); uops = new StaticInstPtr[numMicroops]; @@ -931,6 +936,11 @@ def template SrsConstructor {{ (OperatingMode)_regMode, (AddrMode)_mode, _wb) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } #if %(use_uops)d assert(numMicroops >= 2); uops = new StaticInstPtr[numMicroops]; @@ -949,6 +959,11 @@ def template SwapConstructor {{ (IntRegIndex)_dest, (IntRegIndex)_op1, (IntRegIndex)_base) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } } }}; @@ -961,6 +976,11 @@ def template LoadStoreDImmConstructor {{ (IntRegIndex)_base, _add, _imm) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } #if %(use_uops)d assert(numMicroops >= 2); uops = new StaticInstPtr[numMicroops]; @@ -982,6 +1002,11 @@ def template StoreExDImmConstructor {{ (IntRegIndex)_base, _add, _imm) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } #if %(use_uops)d assert(numMicroops >= 2); uops = new StaticInstPtr[numMicroops]; @@ -1001,6 +1026,11 @@ def template LoadStoreImmConstructor {{ (IntRegIndex)_dest, (IntRegIndex)_base, _add, _imm) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } #if %(use_uops)d assert(numMicroops >= 2); uops = new StaticInstPtr[numMicroops]; @@ -1021,6 +1051,11 @@ def template StoreExImmConstructor {{ (IntRegIndex)_base, _add, _imm) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } #if %(use_uops)d assert(numMicroops >= 2); uops = new StaticInstPtr[numMicroops]; @@ -1044,6 +1079,11 @@ def template StoreDRegConstructor {{ (IntRegIndex)_index) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } #if %(use_uops)d assert(numMicroops >= 2); uops = new StaticInstPtr[numMicroops]; @@ -1066,6 +1106,11 @@ def template StoreRegConstructor {{ (IntRegIndex)_index) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } #if %(use_uops)d assert(numMicroops >= 2); uops = new StaticInstPtr[numMicroops]; @@ -1089,6 +1134,11 @@ def template LoadDRegConstructor {{ (IntRegIndex)_index) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } #if %(use_uops)d assert(numMicroops >= 2); uops = new StaticInstPtr[numMicroops]; @@ -1123,6 +1173,11 @@ def template LoadRegConstructor {{ (IntRegIndex)_index) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } #if %(use_uops)d assert(numMicroops >= 2); uops = new StaticInstPtr[numMicroops]; @@ -1164,6 +1219,11 @@ def template LoadImmConstructor {{ (IntRegIndex)_dest, (IntRegIndex)_base, _add, _imm) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } #if %(use_uops)d assert(numMicroops >= 2); uops = new StaticInstPtr[numMicroops]; diff --git a/src/arch/arm/isa/templates/misc.isa b/src/arch/arm/isa/templates/misc.isa index 915dea9b0..0347869f8 100644 --- a/src/arch/arm/isa/templates/misc.isa +++ b/src/arch/arm/isa/templates/misc.isa @@ -54,6 +54,11 @@ def template MrsConstructor {{ : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, _dest) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } } }}; @@ -75,6 +80,11 @@ def template MsrRegConstructor {{ : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, _op1, mask) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } } }}; @@ -96,6 +106,11 @@ def template MsrImmConstructor {{ : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, imm, mask) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } } }}; @@ -115,6 +130,11 @@ def template ImmOpConstructor {{ : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, _imm) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } } }}; @@ -135,6 +155,11 @@ def template RegImmOpConstructor {{ : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, _dest, _imm) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } } }}; @@ -156,6 +181,11 @@ def template RegRegOpConstructor {{ : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, _dest, _op1) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } } }}; @@ -182,6 +212,11 @@ def template RegRegRegImmOpConstructor {{ _dest, _op1, _op2, _imm) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } } }}; @@ -208,6 +243,11 @@ def template RegRegRegRegOpConstructor {{ _dest, _op1, _op2, _op3) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } } }}; @@ -232,6 +272,11 @@ def template RegRegRegOpConstructor {{ _dest, _op1, _op2) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } } }}; @@ -257,6 +302,11 @@ def template RegRegImmOpConstructor {{ _dest, _op1, _imm) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } } }}; @@ -283,6 +333,11 @@ def template RegRegImmImmOpConstructor {{ _dest, _op1, _imm1, _imm2) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } } }}; @@ -307,6 +362,11 @@ def template RegImmRegOpConstructor {{ _dest, _imm, _op1) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } } }}; @@ -334,6 +394,11 @@ def template RegImmRegShiftOpConstructor {{ _dest, _imm, _op1, _shiftAmt, _shiftType) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } } }}; diff --git a/src/arch/arm/isa/templates/mult.isa b/src/arch/arm/isa/templates/mult.isa index d5001fb5f..dd4847fd4 100644 --- a/src/arch/arm/isa/templates/mult.isa +++ b/src/arch/arm/isa/templates/mult.isa @@ -57,6 +57,11 @@ def template Mult3Constructor {{ _reg0, _reg1, _reg2) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } } }}; @@ -82,5 +87,10 @@ def template Mult4Constructor {{ _reg0, _reg1, _reg2, _reg3) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } } }}; diff --git a/src/arch/arm/isa/templates/neon.isa b/src/arch/arm/isa/templates/neon.isa index 0e592c6e4..02c2bb30d 100644 --- a/src/arch/arm/isa/templates/neon.isa +++ b/src/arch/arm/isa/templates/neon.isa @@ -59,6 +59,11 @@ class %(class_name)s : public %(base_class)s _dest, _op1, _op2) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } } %(BasicExecDeclare)s @@ -80,6 +85,11 @@ class %(class_name)s : public %(base_class)s _dest, _op1, _op2, _imm) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } } %(BasicExecDeclare)s @@ -100,6 +110,11 @@ class %(class_name)s : public %(base_class)s _dest, _op1, _imm) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } } %(BasicExecDeclare)s @@ -118,6 +133,11 @@ class %(class_name)s : public %(base_class)s : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, _dest, _imm) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } } %(BasicExecDeclare)s @@ -138,6 +158,11 @@ class %(class_name)s : public %(base_class)s _dest, _op1) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } } %(BasicExecDeclare)s diff --git a/src/arch/arm/isa/templates/pred.isa b/src/arch/arm/isa/templates/pred.isa index b5bdbc40e..c9e7b1803 100644 --- a/src/arch/arm/isa/templates/pred.isa +++ b/src/arch/arm/isa/templates/pred.isa @@ -71,6 +71,11 @@ def template DataImmConstructor {{ _dest, _op1, _imm, _rotC) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } } }}; @@ -97,6 +102,11 @@ def template DataRegConstructor {{ _dest, _op1, _op2, _shiftAmt, _shiftType) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } } }}; @@ -123,6 +133,11 @@ def template DataRegRegConstructor {{ _dest, _op1, _op2, _shift, _shiftType) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } } }}; diff --git a/src/arch/arm/isa/templates/vfp.isa b/src/arch/arm/isa/templates/vfp.isa index 8ccfedd0d..8888dc0ae 100644 --- a/src/arch/arm/isa/templates/vfp.isa +++ b/src/arch/arm/isa/templates/vfp.isa @@ -84,6 +84,11 @@ def template FpRegRegOpConstructor {{ _dest, _op1, mode) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } } }}; @@ -105,6 +110,11 @@ def template FpRegImmOpConstructor {{ _dest, _imm, mode) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } } }}; @@ -130,6 +140,11 @@ def template FpRegRegImmOpConstructor {{ _dest, _op1, _imm, mode) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } } }}; @@ -155,5 +170,10 @@ def template FpRegRegRegOpConstructor {{ _dest, _op1, _op2, mode) { %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } } }}; diff --git a/src/arch/arm/registers.hh b/src/arch/arm/registers.hh index 61e467e24..30289ff27 100644 --- a/src/arch/arm/registers.hh +++ b/src/arch/arm/registers.hh @@ -49,7 +49,11 @@ namespace ArmISA { -using ArmISAInst::MaxInstSrcRegs; + +// For a predicated instruction, we need all the +// destination registers to also be sources +const int MaxInstSrcRegs = ArmISAInst::MaxInstDestRegs + + ArmISAInst::MaxInstSrcRegs; using ArmISAInst::MaxInstDestRegs; typedef uint16_t RegIndex; diff --git a/src/cpu/o3/dyn_inst.hh b/src/cpu/o3/dyn_inst.hh index b62068111..487c284e6 100644 --- a/src/cpu/o3/dyn_inst.hh +++ b/src/cpu/o3/dyn_inst.hh @@ -181,6 +181,18 @@ class BaseO3DynInst : public BaseDynInst this->thread->inSyscall = in_syscall; } + void forwardOldRegs() + { + + for (int idx = 0; idx < this->numDestRegs(); idx++) { + PhysRegIndex prev_phys_reg = this->prevDestRegIdx(idx); + TheISA::RegIndex original_dest_reg = this->staticInst->destRegIdx(idx); + if (original_dest_reg < TheISA::FP_Base_DepTag) + this->setIntRegOperand(this->staticInst.get(), idx, this->cpu->readIntReg(prev_phys_reg)); + else if (original_dest_reg < TheISA::Ctrl_Base_DepTag) + this->setFloatRegOperandBits(this->staticInst.get(), idx, this->cpu->readFloatRegBits(prev_phys_reg)); + } + } #if FULL_SYSTEM /** Calls hardware return from error interrupt. */ Fault hwrei(); diff --git a/src/cpu/o3/iew_impl.hh b/src/cpu/o3/iew_impl.hh index 2acb941e0..e1af20852 100644 --- a/src/cpu/o3/iew_impl.hh +++ b/src/cpu/o3/iew_impl.hh @@ -1261,6 +1261,8 @@ DefaultIEW::executeInsts() // will be replaced and we will lose it. if (inst->getFault() == NoFault) { inst->execute(); + if (inst->readPredicate() == false) + inst->forwardOldRegs(); } inst->setExecuted(); diff --git a/src/cpu/o3/lsq_unit_impl.hh b/src/cpu/o3/lsq_unit_impl.hh index 64d674666..7be5e4e5b 100644 --- a/src/cpu/o3/lsq_unit_impl.hh +++ b/src/cpu/o3/lsq_unit_impl.hh @@ -458,6 +458,8 @@ LSQUnit::executeLoad(DynInstPtr &inst) // realizes there is activity. // Mark it as executed unless it is an uncached load that // needs to hit the head of commit. + if (inst->readPredicate() == false) + inst->forwardOldRegs(); DPRINTF(LSQUnit, "Load [sn:%lli] not executed from %s\n", inst->seqNum, (load_fault != NoFault ? "fault" : "predication")); @@ -530,6 +532,9 @@ LSQUnit::executeStore(DynInstPtr &store_inst) Fault store_fault = store_inst->initiateAcc(); + if (store_inst->readPredicate() == false) + store_inst->forwardOldRegs(); + if (storeQueue[store_idx].size == 0) { DPRINTF(LSQUnit,"Fault on Store PC %s, [sn:%lli], Size = 0\n", store_inst->pcState(), store_inst->seqNum);