diff -r b6bf8a2e708e -r 08459057bda6 src/arch/arm/isa/insts/misc.isa --- a/src/arch/arm/isa/insts/misc.isa Mon Nov 08 17:34:53 2010 -0600 +++ b/src/arch/arm/isa/insts/misc.isa Mon Nov 08 17:55:52 2010 -0600 @@ -474,7 +474,7 @@ ArmISA::PCState pc = PCS; return new PrefetchAbort(pc.pc(), ArmFault::DebugEvent); ''' - bkptIop = InstObjParams("bkpt", "BkptInst", "ArmStaticInst", + bkptIop = InstObjParams("bkpt", "BkptInst", "PredOp", bkptCode) header_output += BasicDeclare.subst(bkptIop) decoder_output += BasicConstructor.subst(bkptIop) diff -r b6bf8a2e708e -r 08459057bda6 src/arch/isa_parser.py --- a/src/arch/isa_parser.py Mon Nov 08 17:34:53 2010 -0600 +++ b/src/arch/isa_parser.py Mon Nov 08 17:55:52 2010 -0600 @@ -1,3 +1,15 @@ +# Copyright (c) 2010 ARM Limited +# All rights reserved +# +# The license below extends only to copyright in the software and shall +# not be construed as granting a license to any other intellectual +# property including but not limited to intellectual property relating +# to a hardware implementation of the functionality of the software +# licensed hereunder. You may use the software subject to the license +# terms below provided that you ensure that this notice is replicated +# unmodified and in its entirety in all distributions of the software, +# modified or unmodified, in source code or in binary form. +# # Copyright (c) 2003-2005 The Regents of The University of Michigan # All rights reserved. # @@ -780,8 +792,8 @@ if self.memOperand: error("Code block has more than one memory operand.") self.memOperand = op_desc - if parser.maxInstSrcRegs < self.numSrcRegs: - parser.maxInstSrcRegs = self.numSrcRegs + if parser.maxInstSrcRegs < (self.numSrcRegs + self.numDestRegs): + parser.maxInstSrcRegs = (self.numSrcRegs + self.numDestRegs) if parser.maxInstDestRegs < self.numDestRegs: parser.maxInstDestRegs = self.numDestRegs # now make a final pass to finalize op_desc fields that may depend @@ -925,6 +937,22 @@ '\n\t_numFPDestRegs = %d;' % self.operands.numFPDestRegs self.constructor += \ '\n\t_numIntDestRegs = %d;' % self.operands.numIntDestRegs + + # This part will only work with Arm PredOps + # It is here because the constructor code is not customizable + # This code makes destination registers source registers only if + # the condition code of the StaticInst is not unconditonal or + # always_execute. To support register-renaming with predication. + self.constructor += '\n#ifdef TARGET_ARM\n' + self.constructor += \ + '\n\tif (!(condCode == COND_AL || condCode == COND_UC)) {' + rangelist = range(self.operands.numDestRegs) + for number in rangelist: + self.constructor +=''' + _srcRegIdx[_numSrcRegs++] = _destRegIdx[%d];''' % number + self.constructor += '\n\t}' + self.constructor += '\n#endif // end of TARGET_ARM\n' + self.flags = self.operands.concatAttrLists('flags') # Make a basic guess on the operand class (function unit type). diff -r b6bf8a2e708e -r 08459057bda6 src/cpu/o3/dyn_inst.hh --- a/src/cpu/o3/dyn_inst.hh Mon Nov 08 17:34:53 2010 -0600 +++ b/src/cpu/o3/dyn_inst.hh Mon Nov 08 17:55:52 2010 -0600 @@ -1,4 +1,16 @@ /* + * Copyright (c) 2010 ARM Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 2004-2006 The Regents of The University of Michigan * All rights reserved. * @@ -168,6 +180,18 @@ val, this->threadNumber); } + 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 -r b6bf8a2e708e -r 08459057bda6 src/cpu/o3/iew_impl.hh --- a/src/cpu/o3/iew_impl.hh Mon Nov 08 17:34:53 2010 -0600 +++ b/src/cpu/o3/iew_impl.hh Mon Nov 08 17:55:52 2010 -0600 @@ -1265,6 +1265,10 @@ // Such case can happen when it faulted during ITLB translation. if (inst->fault == NoFault) { inst->execute(); + if (inst->readPredicate() == false) + inst->forwardOldRegs(); + + } inst->setExecuted(); diff -r b6bf8a2e708e -r 08459057bda6 src/cpu/o3/lsq_unit_impl.hh --- a/src/cpu/o3/lsq_unit_impl.hh Mon Nov 08 17:34:53 2010 -0600 +++ b/src/cpu/o3/lsq_unit_impl.hh Mon Nov 08 17:55:52 2010 -0600 @@ -474,6 +474,7 @@ // realizes there is activity. // Mark it as executed unless it is an uncached load that // needs to hit the head of commit. + inst->forwardOldRegs(); DPRINTF(LSQUnit, "Load [sn:%lli] not executed from %s\n", inst->seqNum, (load_fault != NoFault ? "fault" : "predication")); @@ -513,6 +514,8 @@ store_inst->faultInInitiateAcc = false; Fault store_fault = store_inst->initiateAcc(); + if (store_inst->readPredicate() == false) + store_inst->forwardOldRegs(); ///////////////////////////////////////////////////////////////////