From 774808f76c8f2c157dcf560488fe45e3e4c57af9 Mon Sep 17 00:00:00 2001 From: jdh8d <jdh8d@git.zephyr-software.com> Date: Mon, 25 Jul 2011 17:13:58 +0000 Subject: [PATCH] Fixes to generate_spri to work with and without ILR. --- libIRDB/src/generate_spri.cpp | 71 ++++++++++++++++++++++++++++++++--- 1 file changed, 65 insertions(+), 6 deletions(-) diff --git a/libIRDB/src/generate_spri.cpp b/libIRDB/src/generate_spri.cpp index a1ef0c066..639d2e1e3 100644 --- a/libIRDB/src/generate_spri.cpp +++ b/libIRDB/src/generate_spri.cpp @@ -14,18 +14,37 @@ using namespace libIRDB; using namespace std; +// +// the set of insturctions that have control +// transfers to them (including fallthrough type control transfers) from instructions that do not need a spri rule. +// +set<Instruction_t*> unmoved_insn_targets; + + // // map an instruction from the new variant back to the old variant; // static map<Instruction_t*,Instruction_t*> insnMap; +// +// does this instruction need a spri rule +// +static bool needs_spri_rule(Instruction_t* newinsn,Instruction_t* oldinsn); +// +// return the address as a string for this instruction +// +static string addressify(Instruction_t* insn); + // // create a label for the given instruction // static string labelfy(Instruction_t* insn) { + if(!needs_spri_rule(insn, insnMap[insn])) + return addressify(insn); + return string("Label_insn_") + to_string(insn->GetBaseID()); } @@ -221,18 +240,18 @@ static bool needs_spri_rule(Instruction_t* newinsn,Instruction_t* oldinsn) return true; // if there's a fallthrough, but it is different, return true - if(newFT && newFT->GetOriginalAddressID()!=oldFT->GetBaseID()) + if(newFT && newFT->GetOriginalAddressID()!=oldFT->GetAddress()->GetBaseID()) return true; // if there's a target, but it is different, return true - if(newTG && newTG->GetOriginalAddressID()!=oldTG->GetBaseID()) + if(newTG && newTG->GetOriginalAddressID()!=oldTG->GetAddress()->GetBaseID()) return true; // data bits themselves changed if(newinsn->GetDataBits() != oldinsn->GetDataBits()) return true; - + return false; } // @@ -250,10 +269,15 @@ We need to emit a rule of this form Instruction_t* old_insn=insnMap[newinsn]; - fout << "# Orig addr: "<<addressify(newinsn)<<" addr_id: "<< newinsn->GetBaseID()<<" with comment "<<newinsn->GetComment()<<endl; + fout << "# Orig addr: "<<addressify(newinsn)<<" addr_id: "<< std::dec << newinsn->GetBaseID()<<" with comment "<<newinsn->GetComment()<<endl; if(addressify(newinsn).c_str()[0]=='0') { - if(old_insn->GetIsIndirectTarget()) + if( + // if it's an indirect branch target + old_insn->GetIsIndirectTarget() || + // or the target of an unmodified instruction + unmoved_insn_targets.find(newinsn) != unmoved_insn_targets.end() + ) { fout << addressify(newinsn) <<" -> ."<<endl; } @@ -378,6 +402,37 @@ void VariantIR_t::generate_spri(ostream &fout) this->generate_spri(orig_variant_ir_p,fout); } + +// +// generate_unmoved_insn_targets_set -- create the set of insturctions that have control +// transfers to them (including fallthrough type control transfers) from instructions that do not need a spri rule. +// +static void generate_unmoved_insn_targets_set(VariantIR_t* varirp) +{ + for( + set<Instruction_t*>::const_iterator it=varirp->GetInstructions().begin(); + it!=varirp->GetInstructions().end(); + ++it + ) + { + Instruction_t *insn=*it; + + if( + // this instruction corresponds to an old instructino + insnMap[insn] && + // and we need a spri rule for it + !needs_spri_rule(insn, insnMap[insn]) + ) + { + unmoved_insn_targets.insert(insn->GetTarget()); + unmoved_insn_targets.insert(insn->GetFallthrough()); + } + + } + +} + + void VariantIR_t::generate_spri(VariantIR_t *orig_varirp, ostream &fout) { @@ -385,9 +440,13 @@ void VariantIR_t::generate_spri(VariantIR_t *orig_varirp, ostream &fout) // give 'this' a name VariantIR_t *varirp=this; - // generate the map needed for this transform. + // generate the map from new instruction to old instruction needed for this transform. generate_insn_to_insn_maps(varirp, orig_varirp); + // generate unmoved_insn_targets_set -- the set of insturctions that have control + // transfers to them (including fallthrough type control transfers) from instructions that do not need a spri rule. + generate_unmoved_insn_targets_set(varirp); + // // for each instruction, compare the new instruction with the original instruction and see if // they are the same. If so, do nothing, otherwise emit a rewrite rule for this instruction. -- GitLab