diff --git a/src/arch/arm/insts/macromem.cc b/src/arch/arm/insts/macromem.cc index e1b754204..d05ac7728 100644 --- a/src/arch/arm/insts/macromem.cc +++ b/src/arch/arm/insts/macromem.cc @@ -113,6 +113,14 @@ MacroMemOp::MacroMemOp(const char *mnem, ExtMachInst machInst, } else { *++uop = new MicroLdrUop(machInst, regIdx, INTREG_UREG0, up, addr); + if (reg == INTREG_PC) { + (*uop)->setFlag(StaticInst::IsControl); + if (!(condCode == COND_AL || condCode == COND_UC)) + (*uop)->setFlag(StaticInst::IsCondControl); + else + (*uop)->setFlag(StaticInst::IsUncondControl); + (*uop)->setFlag(StaticInst::IsIndirectControl); + } } } } else { diff --git a/src/arch/arm/isa/insts/data.isa b/src/arch/arm/isa/insts/data.isa index 97ae7d0c0..be56554b0 100644 --- a/src/arch/arm/isa/insts/data.isa +++ b/src/arch/arm/isa/insts/data.isa @@ -116,7 +116,8 @@ let {{ regRegOp2 = "shift_rm_rs(Op2, Shift<7:0>, shiftType, 0)" def buildImmDataInst(mnem, code, flagType = "logic", suffix = "Imm", \ - buildCc = True, buildNonCc = True, instFlags = []): + buildCc = True, buildNonCc = True, isBranch = "0", \ + instFlags = []): cCode = carryCode[flagType] vCode = overflowCode[flagType] negBit = 31 @@ -133,10 +134,12 @@ let {{ immCode = secondOpRe.sub(immOp2, code) immIop = InstObjParams(mnem, mnem.capitalize() + suffix, "DataImmOp", {"code" : immCode, + "is_branch" : isBranch, "predicate_test": pickPredicate(immCode)}, instFlags) immIopCc = InstObjParams(mnem + "s", mnem.capitalize() + suffix + "Cc", "DataImmOp", {"code" : immCode + immCcCode, + "is_branch" : isBranch, "predicate_test": pickPredicate(immCode + immCcCode)}, instFlags) def subst(iop): @@ -244,7 +247,7 @@ let {{ if regRegAiw: regRegCode = "AIW" + regRegCode - buildImmDataInst(mnem, instCode, flagType) + buildImmDataInst(mnem, instCode, flagType, isBranch = isBranch) buildRegDataInst(mnem, instCode, flagType, isRasPop = isRasPop, isBranch = isBranch) buildRegRegDataInst(mnem, regRegCode, flagType) @@ -276,13 +279,15 @@ let {{ buildDataInst("and", "Dest = resTemp = Op1 & secondOp;") buildDataInst("eor", "Dest = resTemp = Op1 ^ secondOp;") - buildDataInst("sub", "Dest = resTemp = Op1 - secondOp;", "sub") + buildDataInst("sub", "Dest = resTemp = Op1 - secondOp;", "sub", + isBranch = "dest == INTREG_PC") buildDataInst("rsb", "Dest = resTemp = secondOp - Op1;", "rsb") - buildDataInst("add", "Dest = resTemp = Op1 + secondOp;", "add") + buildDataInst("add", "Dest = resTemp = Op1 + secondOp;", "add", + isBranch = "dest == INTREG_PC") buildImmDataInst("adr", ''' Dest = resTemp = (PC & ~0x3) + (op1 ? secondOp : -secondOp); - ''') + ''', isBranch = "dest == INTREG_PC") buildDataInst("adc", "Dest = resTemp = Op1 + secondOp + %s;" % oldC, "add") buildDataInst("sbc", "Dest = resTemp = Op1 - secondOp - !%s;" % oldC, "sub") buildDataInst("rsc", "Dest = resTemp = secondOp - Op1 - !%s;" % oldC, "rsb") diff --git a/src/arch/arm/isa/templates/mem.isa b/src/arch/arm/isa/templates/mem.isa index a4a740f89..2ccda65e1 100644 --- a/src/arch/arm/isa/templates/mem.isa +++ b/src/arch/arm/isa/templates/mem.isa @@ -1155,6 +1155,15 @@ def template LoadRegConstructor {{ uops[1]->setLastMicroop(); } +#else + if (_dest == INTREG_PC) { + flags[IsControl] = true; + flags[IsIndirectControl] = true; + if (conditional) + flags[IsCondControl] = true; + else + flags[IsUncondControl] = true; + } #endif } }}; @@ -1198,6 +1207,15 @@ def template LoadImmConstructor {{ uops[1] = new %(wb_decl)s; uops[1]->setLastMicroop(); } +#else + if (_dest == INTREG_PC) { + flags[IsControl] = true; + flags[IsIndirectControl] = true; + if (conditional) + flags[IsCondControl] = true; + else + flags[IsUncondControl] = true; + } #endif } }}; diff --git a/src/arch/arm/isa/templates/pred.isa b/src/arch/arm/isa/templates/pred.isa index 88e8fecd1..918029cc2 100644 --- a/src/arch/arm/isa/templates/pred.isa +++ b/src/arch/arm/isa/templates/pred.isa @@ -76,6 +76,15 @@ def template DataImmConstructor {{ _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; } } + + if (%(is_branch)s){ + flags[IsControl] = true; + flags[IsIndirectControl] = true; + if (condCode == COND_AL || condCode == COND_UC) + flags[IsUncondControl] = true; + else + flags[IsCondControl] = true; + } } }};