diff --git a/base_regression.sh b/base_regression.sh new file mode 100755 index 0000000..bf49b58 --- /dev/null +++ b/base_regression.sh @@ -0,0 +1,3 @@ +#!/bin/bash +./test_use_base.sh +./regression_tester.rb ./bld/dcc_original -s -c 2>stderr >stdout; diff tests/prev/ tests/outputs/ diff --git a/full_regression.sh b/full_regression.sh new file mode 100755 index 0000000..e64a873 --- /dev/null +++ b/full_regression.sh @@ -0,0 +1,3 @@ +#!/bin/bash +./test_use_all.sh +./regression_tester.rb ./bld/dcc_original -s -c 2>stderr >stdout; diff tests/prev/ tests/outputs/ diff --git a/include/BasicBlock.h b/include/BasicBlock.h index ed609cc..5d059cc 100644 --- a/include/BasicBlock.h +++ b/include/BasicBlock.h @@ -108,7 +108,7 @@ static BB * Create(Int start, Int ip, byte nodeType, Int numOutEdges, Function * /// const Function *getParent() const { return Parent; } Function *getParent() { return Parent; } - void writeBB(ICODE *hli, Int lev, Function *pProc, Int *numLoc); + void writeBB(Int lev, Function *pProc, Int *numLoc); BB *rmJMP(Int marker, BB *pBB); private: Function *Parent; diff --git a/include/epilogue_idioms.h b/include/epilogue_idioms.h deleted file mode 100644 index daf5c0d..0000000 --- a/include/epilogue_idioms.h +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once -#include "idiom.h" -#include "icode.h" -#include -struct EpilogIdiom : public Idiom -{ -protected: - std::deque m_icodes; // deque to push_front optional icodes from popStkVars - void popStkVars (iICODE pIcode); -public: - virtual ~EpilogIdiom() {} - EpilogIdiom(Function *f) : Idiom(f) - { - } - -}; -struct Idiom2 : public EpilogIdiom -{ - virtual ~Idiom2() {} - Idiom2(Function *f) : EpilogIdiom(f) - { - } - uint8_t minimum_match_length() {return 3;} - bool match(iICODE pIcode); - int action(); -}; -struct Idiom4 : public EpilogIdiom -{ -protected: - int m_param_count; -public: - virtual ~Idiom4() {} - Idiom4(Function *f) : EpilogIdiom(f) - { - } - uint8_t minimum_match_length() {return 1;} - bool match(iICODE pIcode); - int action(); -}; diff --git a/include/icode.h b/include/icode.h index 22a7d22..d101c47 100644 --- a/include/icode.h +++ b/include/icode.h @@ -4,6 +4,7 @@ ****************************************************************************/ #pragma once #include +#include #include #include #include @@ -276,8 +277,8 @@ struct HLTYPE struct { /* for HLI_CALL */ Function *proc; STKFRAME *args; /* actual arguments */ - } call; - } oper; /* operand */ + } call; + } oper; /* operand */ } ; /* LOW_LEVEL icode operand record */ struct LLOperand //: public llvm::MCOperand @@ -344,9 +345,9 @@ struct ICODE { struct DU1 { - Int numRegsDef; /* # registers defined by this inst */ + Int numRegsDef; /* # registers defined by this inst */ byte regi[MAX_REGS_DEF]; /* registers defined by this inst */ - Int idx[MAX_REGS_DEF][MAX_USES]; /* inst that uses this def */ + Int idx[MAX_REGS_DEF][MAX_USES]; /* inst that uses this def */ }; icodeType type; /* Icode type */ bool invalid; /* Has no HIGH_LEVEL equivalent */ @@ -387,7 +388,7 @@ public: }; // This is the icode array object. -class CIcodeRec : public std::vector +class CIcodeRec : public std::list { public: CIcodeRec(); // Constructor diff --git a/include/idiom.h b/include/idiom.h deleted file mode 100644 index be634ca..0000000 --- a/include/idiom.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once -#include "icode.h" -#include "Procedure.h" -struct Idiom -{ -protected: - Function *m_func; - iICODE m_end; -public: - Idiom(Function *f) : m_func(f),m_end(f->Icode.end()) - { - } - virtual uint8_t minimum_match_length()=0; - virtual bool match(iICODE at)=0; -}; diff --git a/include/idiom1.h b/include/idiom1.h deleted file mode 100644 index 9ba6777..0000000 --- a/include/idiom1.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once -#include "idiom.h" -struct Idiom1 : public Idiom -{ -protected: - std::vector m_icodes; - int m_min_off; - Int checkStkVars (iICODE pIcode); -public: - Idiom1(Function *f) : Idiom(f) - { - } - uint8_t minimum_match_length() {return 1;} - bool match(iICODE picode); - int action(); -}; diff --git a/include/locident.h b/include/locident.h index 9c44747..0eb9626 100644 --- a/include/locident.h +++ b/include/locident.h @@ -99,14 +99,13 @@ struct ID dword l; /* low word */ } longKte; } id; - ID() + ID() : type(TYPE_UNKNOWN),illegal(false),loc(STK_FRAME),hasMacro(false) { - memset(this,0,sizeof(ID)); + memset(&id,0,sizeof(id)); } - ID(hlType t, frameType f) + ID(hlType t, frameType f) : type(t),illegal(false),hasMacro(false) { - memset(this,0,sizeof(ID)); - type=t; + memset(&id,0,sizeof(id)); loc=f; } bool isSigned() const { return (type==TYPE_BYTE_SIGN)||(type==TYPE_WORD_SIGN)||(type==TYPE_LONG_SIGN);} @@ -133,7 +132,7 @@ public: Int newByteWordStk(hlType t, Int off, byte regOff); Int newIntIdx(int16 seg, int16 off, byte regi, Int ix, hlType t); Int newLongReg(hlType t, byte regH, byte regL, iICODE ix_); - Int newLong(opLoc sd, ICODE *pIcode, hlFirst f, iICODE ix, operDu du, Int off); + Int newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix, operDu du, Int off); void newIdent(hlType t, frameType f); void flagByteWordId(Int off); void propLongId(byte regL, byte regH, const char *name); diff --git a/src/BasicBlock.cpp b/src/BasicBlock.cpp index 7b96f0f..4e5825c 100644 --- a/src/BasicBlock.cpp +++ b/src/BasicBlock.cpp @@ -153,7 +153,7 @@ void BB::writeCode (Int indLevel, Function * pProc , Int *numLoc,Int latchNode, if (numHlIcodes > 1) { /* Write the code for this basic block */ - writeBB(&pProc->Icode.front(), indLevel, pProc, numLoc); + writeBB(indLevel, pProc, numLoc); repCond = true; } @@ -183,7 +183,7 @@ void BB::writeCode (Int indLevel, Function * pProc , Int *numLoc,Int latchNode, /* Write the code for this basic block */ if (repCond == FALSE) - writeBB (&pProc->Icode.front(), indLevel, pProc, numLoc); + writeBB (indLevel, pProc, numLoc); /* Check for end of path */ _nodeType = nodeType; @@ -218,7 +218,7 @@ void BB::writeCode (Int indLevel, Function * pProc , Int *numLoc,Int latchNode, /* Check if there is need to repeat other statements involved * in while condition, then, emit the loop trailer */ if (repCond) - writeBB (&pProc->Icode.front(), indLevel+1, pProc, numLoc); + writeBB (indLevel+1, pProc, numLoc); cCode.appendCode( "%s} /* end of while */\n",indent(indLevel)); } else if (_loopType == ENDLESS_TYPE) @@ -325,28 +325,34 @@ void BB::writeCode (Int indLevel, Function * pProc , Int *numLoc,Int latchNode, * Args: pBB: pointer to the current basic block. * Icode: pointer to the array of icodes for current procedure. * lev: indentation level - used for formatting. */ -void BB::writeBB(ICODE * hli, Int lev, Function * pProc, Int *numLoc) +void BB::writeBB(Int lev, Function * pProc, Int *numLoc) { Int i, last; char *line; /* Pointer to the HIGH-LEVEL line */ /* Save the index into the code table in case there is a later goto * into this instruction (first instruction of the BB) */ - hli[start].codeIdx = nextBundleIdx (&cCode.code); + front().codeIdx = nextBundleIdx (&cCode.code); + //hli[start].codeIdx = nextBundleIdx (&cCode.code); + //for (i = start, last = i + length; i < last; i++) /* Generate code for each hlicode that is not a HLI_JCOND */ - for (i = start, last = i + length; i < last; i++) - if ((hli[i].type == HIGH_LEVEL) && (hli[i].invalid == FALSE)) + int idx=start; + for(iICODE hli=begin2(); hli!=end2(); ++hli) + { + if ((hli->type == HIGH_LEVEL) && (hli->invalid == FALSE)) { - line = write1HlIcode (hli[i].ic.hl, pProc, numLoc); + line = write1HlIcode (hli->ic.hl, pProc, numLoc); if (line[0] != '\0') { cCode.appendCode( "%s%s", indent(lev), line); stats.numHLIcode++; } if (option.verbose) - hli[i].writeDU(i); + hli->writeDU(idx); } + idx++; + } } int BB::begin() { @@ -355,12 +361,16 @@ int BB::begin() iICODE BB::begin2() { - return Parent->Icode.begin()+start; + iICODE result(Parent->Icode.begin()); + advance(result,start); + return result; } iICODE BB::end2() { - return Parent->Icode.begin()+start+length; + iICODE result(Parent->Icode.begin()); + advance(result,start+length); + return result; } int BB::rbegin() { @@ -372,7 +382,7 @@ int BB::end() } ICODE &BB::back() { - return Parent->Icode[rbegin()]; + return *rbegin2(); } size_t BB::size() @@ -382,17 +392,16 @@ size_t BB::size() ICODE &BB::front() { - return Parent->Icode[start]; + return *begin2(); } riICODE BB::rbegin2() { - riICODE res(Parent->Icode.begin()+start+length); - assert(res->loc_ip==back().loc_ip); + riICODE res(end2()); + assert(res->loc_ip==rbegin()); return res; } riICODE BB::rend2() { - riICODE res(Parent->Icode.begin()+start); - return res; + return riICODE(begin2()); } diff --git a/src/ast.cpp b/src/ast.cpp index 3e5bc84..3d0767d 100644 --- a/src/ast.cpp +++ b/src/ast.cpp @@ -261,23 +261,24 @@ COND_EXPR *COND_EXPR::idLong(LOCAL_ID *localId, opLoc sd, iICODE pIcode, hlFirst { Int idx; COND_EXPR *newExp = new COND_EXPR(IDENTIFIER); - /* Check for long constant and save it as a constant expression */ if ((sd == SRC) && ((pIcode->ic.ll.flg & I) == I)) /* constant */ { + iICODE atOffset=pIcode; + advance(atOffset,off); newExp->expr.ident.idType = CONSTANT; if (f == HIGH_FIRST) newExp->expr.ident.idNode.kte.kte = (pIcode->ic.ll.src.op() << 16) + - (pIcode+off)->ic.ll.src.op(); + atOffset->ic.ll.src.op(); else /* LOW_FIRST */ newExp->expr.ident.idNode.kte.kte = - ((pIcode+off)->ic.ll.src.op() << 16)+ pIcode->ic.ll.src.op(); + (atOffset->ic.ll.src.op() << 16)+ pIcode->ic.ll.src.op(); newExp->expr.ident.idNode.kte.size = 4; } /* Save it as a long expression (reg, stack or glob) */ else { - idx = localId->newLong(sd, &(*pIcode), f, ix, du, off); + idx = localId->newLong(sd, pIcode, f, ix, du, off); newExp->expr.ident.idType = LONG_VAR; newExp->expr.ident.idNode.longIdx = idx; } diff --git a/src/dataflow.cpp b/src/dataflow.cpp index 4de4c4c..7f16185 100644 --- a/src/dataflow.cpp +++ b/src/dataflow.cpp @@ -132,19 +132,22 @@ void Function::elimCondCodes () (use = useAt->ic.ll.flagDU.u)) { /* Find definition within the same basic block */ - for (defAt = useAt+1; defAt != pBB->rend2(); defAt++) + defAt=useAt; + ++defAt; + for (; defAt != pBB->rend2(); defAt++) { def = defAt->ic.ll.flagDU.d; - if ((use & def) == use) - { + if ((use & def) != use) + continue; notSup = FALSE; if ((useAt->GetLlOpcode() >= iJB) && (useAt->GetLlOpcode() <= iJNS)) { + iICODE befDefAt = (++riICODE(defAt)).base(); switch (defAt->GetLlOpcode()) { case iCMP: - rhs = srcIdent (*defAt, this, (defAt+1).base(),*useAt, eUSE); - lhs = dstIdent (*defAt, this, (defAt+1).base(),*useAt, eUSE); + rhs = srcIdent (*defAt, this, befDefAt,*useAt, eUSE); + lhs = dstIdent (*defAt, this, befDefAt,*useAt, eUSE); break; case iOR: @@ -157,8 +160,8 @@ void Function::elimCondCodes () break; case iTEST: - rhs = srcIdent (*defAt,this, (defAt+1).base(),*useAt, eUSE); - lhs = dstIdent (*defAt,this, (defAt+1).base(),*useAt, eUSE); + rhs = srcIdent (*defAt,this, befDefAt,*useAt, eUSE); + lhs = dstIdent (*defAt,this, befDefAt,*useAt, eUSE); lhs = COND_EXPR::boolOp (lhs, rhs, AND); if (defAt->isLlFlag(B)) rhs = COND_EXPR::idKte (0, 1); @@ -195,7 +198,6 @@ void Function::elimCondCodes () } break; } - } /* Check for extended basic block */ if ((pBB->size() == 1) &&(useAt->GetLlOpcode() >= iJB) && (useAt->GetLlOpcode() <= iJNS)) @@ -423,10 +425,10 @@ void Function::genDU1 () continue; if ((regi == rSI) && (flg & SI_REGVAR)) continue; - if ((picode + 1) != lastInst) /* several instructions */ + if (distance(picode,lastInst)>1) /* several instructions */ { useIdx = 0; - for (auto ricode = picode + 1; ricode != lastInst; ricode++) + for (auto ricode = ++iICODE(picode); ricode != lastInst; ricode++) { ticode=ricode; /* Only check uses of HIGH_LEVEL icodes */ @@ -608,7 +610,6 @@ static boolT xClear (COND_EXPR *rhs, iICODE f, Int t, iICODE lastBBinst, Functio iICODE i; boolT res; byte regi; - ICODE * picode; if (rhs == NULL) return false; @@ -618,9 +619,8 @@ static boolT xClear (COND_EXPR *rhs, iICODE f, Int t, iICODE lastBBinst, Functio case IDENTIFIER: if (rhs->expr.ident.idType == REGISTER) { - picode = &pproc->Icode.front(); regi= pproc->localId.id_arr[rhs->expr.ident.idNode.regiIdx].id.regi; - for (i = (f + 1); (i != lastBBinst) && (i->loc_ip < t); i++) + for (i = ++iICODE(f); (i != lastBBinst) && (i->loc_ip < t); i++) if ((i->type == HIGH_LEVEL) && ( not i->invalid )) { if ((i->du.def & duReg[regi]).any()) @@ -741,7 +741,8 @@ void Function::findExps() case HLI_ASSIGN: /* Replace rhs of current icode into target * icode expression */ - ticode = Icode.begin()+picode->du1.idx[0][0]; + ticode = Icode.begin(); + advance(ticode,picode->du1.idx[0][0]); if ((picode->du.lastDefRegi & duReg[regi]).any() && ((ticode->ic.hl.opcode != HLI_CALL) && (ticode->ic.hl.opcode != HLI_RET))) @@ -781,7 +782,8 @@ void Function::findExps() break; case HLI_POP: - ticode = Icode.begin()+(picode->du1.idx[0][0]); + ticode = Icode.begin(); + advance(ticode,picode->du1.idx[0][0]); if ((picode->du.lastDefRegi & duReg[regi]).any() && ((ticode->ic.hl.opcode != HLI_CALL) && (ticode->ic.hl.opcode != HLI_RET))) @@ -816,7 +818,8 @@ void Function::findExps() break; case HLI_CALL: - ticode = Icode.begin()+(picode->du1.idx[0][0]); + ticode = Icode.begin(); + advance(ticode,picode->du1.idx[0][0]); switch (ticode->ic.hl.opcode) { case HLI_ASSIGN: exp = COND_EXPR::idFunc ( @@ -885,7 +888,8 @@ void Function::findExps() * icode expression */ if (picode->du1.idx[0][0] == picode->du1.idx[1][0]) { - ticode = Icode.begin()+(picode->du1.idx[0][0]); + ticode = Icode.begin(); + advance(ticode,picode->du1.idx[0][0]); if ((picode->du.lastDefRegi & duReg[regi]).any() && ((ticode->ic.hl.opcode != HLI_CALL) && (ticode->ic.hl.opcode != HLI_RET))) @@ -922,7 +926,8 @@ void Function::findExps() case HLI_POP: if (picode->du1.idx[0][0] == picode->du1.idx[1][0]) { - ticode = Icode.begin()+(picode->du1.idx[0][0]); + ticode = Icode.begin(); + advance(ticode,picode->du1.idx[0][0]); if ((picode->du.lastDefRegi & duReg[regi]).any() && ((ticode->ic.hl.opcode != HLI_CALL) && (ticode->ic.hl.opcode != HLI_RET))) @@ -951,7 +956,8 @@ void Function::findExps() break; case HLI_CALL: /* check for function return */ - ticode = Icode.begin()+(picode->du1.idx[0][0]); + ticode = Icode.begin(); + advance(ticode,picode->du1.idx[0][0]); switch (ticode->ic.hl.opcode) { case HLI_ASSIGN: diff --git a/src/disassem.cpp b/src/disassem.cpp index b76f4e6..ab0fd61 100644 --- a/src/disassem.cpp +++ b/src/disassem.cpp @@ -3,18 +3,18 @@ * (C) Cristina Cifuentes, Mike van Emmerik, Jeff Ledermann ****************************************************************************/ #include -#include "dcc.h" -#include "symtab.h" +#include +#include +#include +#include #include #include #include /* For free() */ -#include -#include -#include -#ifdef _CONSOLE -#include /* For console mode routines */ -#endif + +#include "dcc.h" +#include "symtab.h" #include "disassem.h" + // Note: for the time being, there is no interactive disassembler // for unix #ifndef __UNIX__ @@ -127,23 +127,24 @@ static const char *szWreg[12] = { "ax", "cx", "dx", "bx", "sp", "bp", "si", "di" static const char *szPtr[2] = { "word ptr ", "byte ptr " }; -static void dis1Line (Int i, Int pass); +static void dis1Line (ICODE &icode, Int pass); void dis1LineOp(Int i, boolT fWin, char attr, word *len, Function * pProc); -static void formatRM(ostringstream &p, flags32 flg, LLOperand *pm); -static ostringstream &strDst(ostringstream &os, flags32 flg, LLOperand *pm); -static ostringstream &strSrc(ostringstream &os, ICODE *pc, bool skip_comma=false); +static void formatRM(ostringstream &p, flags32 flg, const LLOperand &pm); +static ostringstream &strDst(ostringstream &os, flags32 flg, LLOperand &pm); +static ostringstream &strSrc(ostringstream &os,const LLInst &pc,bool skip_comma=false); + static char *strHex(dword d); static Int checkScanned(dword pcCur); static void setProc(Function * proc); static void dispData(word dataSeg); -void flops(ICODE *pIcode,std::ostringstream &out); +void flops(LLInst &pIcode, std::ostringstream &out); boolT callArg(word off, char *temp); /* Check for procedure name */ static FILE *fp; static CIcodeRec pc; static std::ostringstream buf; static Int cb, j, numIcode, allocIcode, eop; -static vector pl; +static map pl; static dword nextInst; static boolT fImpure; static Int lab, prevPass; @@ -209,24 +210,25 @@ void disassem(Int pass, Function * ppProc) if (pass == 1) { /* Bind jump offsets to labels */ - for (i = 0; i < numIcode; i++) + //for (i = 0; i < numIcode; i++) + for( ICODE &icode : pc) { - if ((pc[i].ic.ll.flg & I) && !(pc[i].ic.ll.flg & JMP_ICODE) && - JmpInst(pc[i].ic.ll.opcode)) + if ((icode.ic.ll.flg & I) && !(icode.ic.ll.flg & JMP_ICODE) && + JmpInst(icode.ic.ll.opcode)) { /* Replace the immediate operand with an icode index */ - dword labTgt; - if (pc.labelSrch(pc[i].ic.ll.src.op(),labTgt)) + iICODE labTgt=pc.labelSrch(icode.ic.ll.src.op()); + if (labTgt!=pc.end()) { - pc[i].ic.ll.src.SetImmediateOp(labTgt); + icode.ic.ll.src.SetImmediateOp(labTgt->loc_ip); /* This icode is the target of a jump */ - pc[labTgt].ic.ll.flg |= TARGET; - pc[i].ic.ll.flg |= JMP_ICODE; /* So its not done twice */ + labTgt->ic.ll.flg |= TARGET; + icode.ic.ll.flg |= JMP_ICODE; /* So its not done twice */ } else { /* This jump cannot be linked to a label */ - pc[i].ic.ll.flg |= NO_LABEL; + icode.ic.ll.flg |= NO_LABEL; } } } @@ -234,17 +236,16 @@ void disassem(Int pass, Function * ppProc) /* Create label array to keep track of location => label name */ pl.clear(); - pl.resize(numIcode,0); /* Write procedure header */ if (pass != 3) fprintf(fp, "\t\t%s PROC %s\n", pProc->name.c_str(), (pProc->flg & PROC_FAR)? "FAR": "NEAR"); /* Loop over array printing each record */ - for (i = nextInst = 0; i < numIcode; i++) - { - dis1Line(i, pass); - } + nextInst = 0; + std::for_each(pc.begin(), + pc.end(), + [pass](ICODE &iter)->void {dis1Line(iter, pass);}); /* Write procedure epilogue */ if (pass != 3) @@ -262,28 +263,29 @@ void disassem(Int pass, Function * ppProc) * i is index into Icode for this proc * * It is assumed that icode i is already scanned * ****************************************************************************/ -static void dis1Line(Int i, Int pass) +static void dis1Line(ICODE &icode_iter, Int pass) { ostringstream oper_stream; ostringstream hex_bytes; ostringstream result_stream; - ICODE * pIcode = &pc[i]; + oper_stream << uppercase; hex_bytes << uppercase; + LLInst &_IcLL(icode_iter.ic.ll); /* Disassembly stage 1 -- * Do not try to display NO_CODE entries or synthetic instructions, * other than JMPs, that have been introduced for def/use analysis. */ if ((option.asm1) && - ((pIcode->ic.ll.flg & NO_CODE) || - ((pIcode->ic.ll.flg & SYNTHETIC) && (pIcode->ic.ll.opcode != iJMP)))) + ((_IcLL.flg & NO_CODE) || + ((_IcLL.flg & SYNTHETIC) && (_IcLL.opcode != iJMP)))) { return; } - else if (pIcode->ic.ll.flg & NO_CODE) + else if (_IcLL.flg & NO_CODE) { return; } - if (pIcode->ic.ll.flg & (TARGET | CASE)) + if (_IcLL.flg & (TARGET | CASE)) { if (pass == 3) cCode.appendCode("\n"); /* Print to c code buffer */ @@ -292,19 +294,19 @@ static void dis1Line(Int i, Int pass) } /* Find next instruction label and print hex bytes */ - if (pIcode->ic.ll.flg & SYNTHETIC) - nextInst = pIcode->ic.ll.label; + if (_IcLL.flg & SYNTHETIC) + nextInst = _IcLL.label; else { - cb = (dword) pIcode->ic.ll.numBytes; - nextInst = pIcode->ic.ll.label + cb; + cb = (dword) _IcLL.numBytes; + nextInst = _IcLL.label + cb; /* Output hexa code in program image */ if (pass != 3) { for (j = 0; j < cb; j++) { - hex_bytes << hex << setw(2) << setfill('0') << uint16_t(prog.Image[pIcode->ic.ll.label + j]); + hex_bytes << hex << setw(2) << setfill('0') << uint16_t(prog.Image[_IcLL.label + j]); } hex_bytes << ' '; } @@ -315,78 +317,78 @@ static void dis1Line(Int i, Int pass) oper_stream << setw(5)<ic.ll.label, 0)) + if (readVal(lab_contents, _IcLL.label, 0)) { lab_contents << ':'; /* Also removes the null */ } - else if (pIcode->ic.ll.flg & TARGET) /* Symbols override Lnn labels */ + else if (_IcLL.flg & TARGET) /* Symbols override Lnn labels */ { /* Print label */ - if (! pl[i]) + if (pl.count(icode_iter.loc_ip)==0) { - pl[i] = ++lab; + pl[icode_iter.loc_ip] = ++lab; } - lab_contents<< "L"<ic.ll.opcode == iSIGNEX && (pIcode->ic.ll.flg & B)) + if (_IcLL.opcode == iSIGNEX && (_IcLL.flg & B)) { - pIcode->ic.ll.opcode = iCBW; + _IcLL.opcode = iCBW; } - oper_stream << setw(15) << left <ic.ll.opcode]; + oper_stream << setw(15) << left <ic.ll.opcode) + switch (_IcLL.opcode) { case iADD: case iADC: case iSUB: case iSBB: case iAND: case iOR: case iXOR: case iTEST: case iCMP: case iMOV: case iLEA: case iXCHG: - strDst(oper_stream,pIcode->ic.ll.flg, &pIcode->ic.ll.dst); - strSrc(oper_stream,pIcode); + strDst(oper_stream,_IcLL.flg, _IcLL.dst); + strSrc(oper_stream,_IcLL); break; case iESC: - flops(pIcode,oper_stream); + flops(_IcLL,oper_stream); break; case iSAR: case iSHL: case iSHR: case iRCL: case iRCR: case iROL: case iROR: - strDst(oper_stream,pIcode->ic.ll.flg | I, &pIcode->ic.ll.dst); - if(pIcode->ic.ll.flg & I) - strSrc(oper_stream,pIcode); + strDst(oper_stream,_IcLL.flg | I, _IcLL.dst); + if(_IcLL.flg & I) + strSrc(oper_stream,_IcLL); else oper_stream<<", cl"; break; case iINC: case iDEC: case iNEG: case iNOT: case iPOP: - strDst(oper_stream,pIcode->ic.ll.flg | I, &pIcode->ic.ll.dst); + strDst(oper_stream,_IcLL.flg | I, _IcLL.dst); break; case iPUSH: - if (pIcode->ic.ll.flg & I) + if (_IcLL.flg & I) { - oper_stream<ic.ll.src.op()); + oper_stream<ic.ll.immed.op)); } else { - strDst(oper_stream,pIcode->ic.ll.flg | I, &pIcode->ic.ll.dst); + strDst(oper_stream,_IcLL.flg | I, _IcLL.dst); } break; case iDIV: case iIDIV: case iMUL: case iIMUL: case iMOD: - if (pIcode->ic.ll.flg & I) + if (_IcLL.flg & I) { - strDst(oper_stream,pIcode->ic.ll.flg, &pIcode->ic.ll.dst) <<", "; - formatRM(oper_stream, pIcode->ic.ll.flg, &pIcode->ic.ll.src); - strSrc(oper_stream,pIcode); + strDst(oper_stream,_IcLL.flg, _IcLL.dst) <<", "; + formatRM(oper_stream, _IcLL.flg, _IcLL.src); + strSrc(oper_stream,_IcLL); } else - strDst(oper_stream,pIcode->ic.ll.flg | I, &pIcode->ic.ll.src); + strDst(oper_stream,_IcLL.flg | I, _IcLL.src); break; case iLDS: case iLES: case iBOUND: - strDst(oper_stream,pIcode->ic.ll.flg, &pIcode->ic.ll.dst)<<", dword ptr"; - strSrc(oper_stream,pIcode,true); + strDst(oper_stream,_IcLL.flg, _IcLL.dst)<<", dword ptr"; + strSrc(oper_stream,_IcLL,true); break; case iJB: case iJBE: case iJAE: case iJA: @@ -397,69 +399,72 @@ static void dis1Line(Int i, Int pass) case iJMP: case iJMPF: /* Check if there is a symbol here */ + { + ICODE *lab=pc.GetIcode(_IcLL.src.op()); selectTable(Label); - if ((pIcode->ic.ll.src.op() < (dword)numIcode) && /* Ensure in range */ - readVal(oper_stream, pc[pIcode->ic.ll.src.op()].ic.ll.label, 0)) + if ((_IcLL.src.op() < (dword)numIcode) && /* Ensure in range */ + readVal(oper_stream, lab->ic.ll.label, 0)) { break; /* Symbolic label. Done */ + } } - if (pIcode->ic.ll.flg & NO_LABEL) + if (_IcLL.flg & NO_LABEL) { //strcpy(p + WID_PTR, strHex(pIcode->ic.ll.immed.op)); - oper_stream<ic.ll.src.op()); + oper_stream<ic.ll.flg & I) + else if (_IcLL.flg & I) { - j = pIcode->ic.ll.src.op(); - if (! pl[j]) /* Forward jump */ + j = _IcLL.src.op(); + if (pl.count(j)==0) /* Forward jump */ { pl[j] = ++lab; } - if (pIcode->ic.ll.opcode == iJMPF) + if (_IcLL.opcode == iJMPF) { oper_stream<<" far ptr "; } oper_stream<<"L"<ic.ll.opcode == iJMPF) + else if (_IcLL.opcode == iJMPF) { oper_stream<<"dword ptr"; - strSrc(oper_stream,pIcode,true); + strSrc(oper_stream,_IcLL,true); } else { - strDst(oper_stream,I, &pIcode->ic.ll.src); + strDst(oper_stream,I, _IcLL.src); } break; case iCALL: case iCALLF: - if (pIcode->ic.ll.flg & I) + if (_IcLL.flg & I) { - if((pIcode->ic.ll.opcode == iCALL)) + if((_IcLL.opcode == iCALL)) oper_stream<< "near"; else oper_stream<< " far"; - oper_stream<<" ptr "<<(pIcode->ic.ll.src.proc.proc)->name; + oper_stream<<" ptr "<<(_IcLL.src.proc.proc)->name; } - else if (pIcode->ic.ll.opcode == iCALLF) + else if (_IcLL.opcode == iCALLF) { oper_stream<<"dword ptr "; - strSrc(oper_stream,pIcode,true); + strSrc(oper_stream,_IcLL,true); } else - strDst(oper_stream,I, &pIcode->ic.ll.src); + strDst(oper_stream,I, _IcLL.src); break; case iENTER: - oper_stream<ic.ll.dst.off)<<", "; - oper_stream<ic.ll.src.op()); + oper_stream<ic.ll.flg & I) + if (_IcLL.flg & I) { - oper_stream<ic.ll.src.op()); + oper_stream<ic.ll.src.segOver) + if (_IcLL.src.segOver) { - bool is_dx_src=(pIcode->ic.ll.opcode == iOUTS || pIcode->ic.ll.opcode == iREP_OUTS); + bool is_dx_src=(_IcLL.opcode == iOUTS || _IcLL.opcode == iREP_OUTS); if(is_dx_src) - oper_stream<<"dx, "<ic.ll.flg & B]; + oper_stream<<"dx, "<ic.ll.flg & B]; - if (pIcode->ic.ll.opcode == iLODS || - pIcode->ic.ll.opcode == iREP_LODS || - pIcode->ic.ll.opcode == iOUTS || - pIcode->ic.ll.opcode == iREP_OUTS) + oper_stream<ic.ll.src.segOver-rAX]; + oper_stream<ic.ll.src.segOver - rAX]; + oper_stream<<"es:[di], "<ic.ll.flg & B)? "B": "W"; + oper_stream<<(_IcLL.flg & B)? "B": "W"; break; case iXLAT: - if (pIcode->ic.ll.src.segOver) + if (_IcLL.src.segOver) { oper_stream<<" "<ic.ll.src.segOver-rAX]<<":[bx]"; + oper_stream<ic.ll.flg & B)?"al, ": "ax, "; - oper_stream<<(pIcode->ic.ll.flg & I)? strHex(pIcode->ic.ll.src.op()): "dx"; + oper_stream<<(_IcLL.flg & B)?"al, ": "ax, "; + oper_stream<<(_IcLL.flg & I)? strHex(_IcLL.src.op()): "dx"; break; case iOUT: - oper_stream<<(pIcode->ic.ll.flg & I)? strHex(pIcode->ic.ll.src.op()): "dx"; - oper_stream<<(pIcode->ic.ll.flg & B)?", al": ", ax"; + oper_stream<<(_IcLL.flg & I)? strHex(_IcLL.src.op()): "dx"; + oper_stream<<(_IcLL.flg & B)?", al": ", ax"; break; default: @@ -517,13 +522,13 @@ static void dis1Line(Int i, Int pass) } /* Comments */ - if (pIcode->ic.ll.flg & SYNTHETIC) + if (_IcLL.flg & SYNTHETIC) { fImpure = FALSE; } else { - for (j = pIcode->ic.ll.label, fImpure = 0; j > 0 && j < (Int)nextInst; j++) + for (j = _IcLL.label, fImpure = 0; j > 0 && j < (Int)nextInst; j++) { fImpure |= BITMAP(j, BM_DATA); } @@ -533,17 +538,17 @@ static void dis1Line(Int i, Int pass) /* Check for user supplied comment */ selectTable(Comment); ostringstream cbuf; - if (readVal(cbuf, pIcode->ic.ll.label, 0)) + if (readVal(cbuf, _IcLL.label, 0)) { result_stream <<"; "<ic.ll.flg & (SWITCH | CASE | SEG_IMMED | IMPURE | SYNTHETIC | TERMINATES))) + else if (fImpure || (_IcLL.flg & (SWITCH | CASE | SEG_IMMED | IMPURE | SYNTHETIC | TERMINATES))) { - if (pIcode->ic.ll.flg & CASE) + if (_IcLL.flg & CASE) { - result_stream << ";Case l"<< pIcode->ic.ll.caseTbl.numEntries; + result_stream << ";Case l"<< _IcLL.caseTbl.numEntries; } - if (pIcode->ic.ll.flg & SWITCH) + if (_IcLL.flg & SWITCH) { result_stream << ";Switch "; } @@ -551,29 +556,29 @@ static void dis1Line(Int i, Int pass) { result_stream << ";Accessed as data "; } - if (pIcode->ic.ll.flg & IMPURE) + if (_IcLL.flg & IMPURE) { result_stream << ";Impure operand "; } - if (pIcode->ic.ll.flg & SEG_IMMED) + if (_IcLL.flg & SEG_IMMED) { result_stream << ";Segment constant"; } - if (pIcode->ic.ll.flg & TERMINATES) + if (_IcLL.flg & TERMINATES) { result_stream << ";Exit to DOS"; } } /* Comment on iINT icodes */ - if (pIcode->ic.ll.opcode == iINT) - pIcode->writeIntComment (result_stream); + if (_IcLL.opcode == iINT) + icode_iter.writeIntComment(result_stream); /* Display output line */ if(pass==3) { /* output to .b code buffer */ - if (pIcode->isLlFlag(SYNTHETIC)) + if (_IcLL.anyFlagSet(SYNTHETIC)) result_stream<<";Synthetic inst"; if (pass == 3) /* output to .b code buffer */ cCode.appendCode("%s\n", result_stream.str().c_str()); @@ -581,15 +586,15 @@ static void dis1Line(Int i, Int pass) } else { - if (! (pIcode->ic.ll.flg & SYNTHETIC)) + if (not _IcLL.anyFlagSet(SYNTHETIC) ) { /* output to .a1 or .a2 file */ - fprintf (fp, "%03ld %06lX %s\n", i, pIcode->ic.ll.label, result_stream.str().c_str()); + fprintf (fp, "%03ld %06lX %s\n", icode_iter.loc_ip, _IcLL.label, result_stream.str().c_str()); } else /* SYNTHETIC instruction */ { result_stream<<";Synthetic inst"; - fprintf (fp, "%03ld %s\n", i, result_stream.str().c_str()); + fprintf (fp, "%03ld %s\n", icode_iter.loc_ip, result_stream.str().c_str()); } } } @@ -599,58 +604,58 @@ static void dis1Line(Int i, Int pass) /**************************************************************************** * formatRM ***************************************************************************/ -static void formatRM(std::ostringstream &p, flags32 flg, LLOperand *pm) +static void formatRM(std::ostringstream &p, flags32 flg, const LLOperand &pm) { char seg[4]; - if (pm->segOver) + if (pm.segOver) { - strcat(strcpy(seg, szWreg[pm->segOver - rAX]), ":"); + strcat(strcpy(seg, szWreg[pm.segOver - rAX]), ":"); } else *seg = '\0'; - if (pm->regi == 0) + if (pm.regi == 0) { - p<off)<<"]"; + p<regi == (INDEXBASE - 1)) + else if (pm.regi == (INDEXBASE - 1)) { p<<"tmp"; } - else if (pm->regi < INDEXBASE) + else if (pm.regi < INDEXBASE) { if(flg & B) - p << szBreg[pm->regi - rAL]; + p << szBreg[pm.regi - rAL]; else - p << szWreg[pm->regi - rAX]; + p << szWreg[pm.regi - rAX]; } - else if (pm->off) + else if (pm.off) { - if (pm->off < 0) + if (pm.off < 0) { - p <regi - INDEXBASE]<<"-"<off))<<"]"; + p <regi - INDEXBASE]<<"+"<off))<<"]"; + p <regi - INDEXBASE]<<"]"; + p <regi == 0 || pm->regi >= INDEXBASE)) + if ((flg & I) && (pm.regi == 0 || pm.regi >= INDEXBASE)) os << szPtr[flg & B]; formatRM(os, flg, pm); return os; @@ -660,22 +665,23 @@ static ostringstream & strDst(ostringstream &os,flags32 flg, LLOperand *pm) /**************************************************************************** * strSrc * ****************************************************************************/ -static ostringstream &strSrc(ostringstream &os,ICODE *pc,bool skip_comma) +static ostringstream &strSrc(ostringstream &os,const LLInst &l_ins,bool skip_comma) { static char buf[30] = {", "}; if(false==skip_comma) os<<", "; - if (pc->ic.ll.flg & I) - os<ic.ll.src.op()); - else if (pc->ic.ll.flg & IM_SRC) /* level 2 */ + if (l_ins.flg & I) + os<ic.ll.flg, &pc->ic.ll.src); + formatRM(os, l_ins.flg, l_ins.src); return os; } + /**************************************************************************** * strHex * ****************************************************************************/ @@ -698,15 +704,15 @@ void interactDis(Function * initProc, Int initIC) } /* Handle the floating point opcodes (icode iESC) */ -void flops(ICODE *pIcode,std::ostringstream &out) +void flops(LLInst &pIcode,std::ostringstream &out) { char bf[30]; - byte op = (byte)pIcode->ic.ll.src.op(); + byte op = (byte)pIcode.src.op(); /* Note that op is set to the escape number, e.g. esc 0x38 is FILD */ - if ((pIcode->ic.ll.dst.regi == 0) || (pIcode->ic.ll.dst.regi >= INDEXBASE)) + if ((pIcode.dst.regi == 0) || (pIcode.dst.regi >= INDEXBASE)) { /* The mod/rm mod bits are not set to 11 (i.e. register). This is the normal floating point opcode */ out<ic.ll.flg, &pIcode->ic.ll.dst); + formatRM(out, pIcode.flg, pIcode.dst); } else { @@ -751,44 +757,44 @@ void flops(ICODE *pIcode,std::ostringstream &out) normal opcodes. Because the opcodes are slightly different for this case (e.g. op=04 means FSUB if reg != 3, but FSUBR for reg == 3), a separate table is used (szFlops2). */ - + int destRegIdx=pIcode.dst.regi - rAX; switch (op) { case 0x0C: - out << szFlops0C[pIcode->ic.ll.dst.regi - rAX]; + out << szFlops0C[destRegIdx]; break; case 0x0D: - out << szFlops0D[pIcode->ic.ll.dst.regi - rAX]; + out << szFlops0D[destRegIdx]; break; case 0x0E: - out << szFlops0E[pIcode->ic.ll.dst.regi - rAX]; + out << szFlops0E[destRegIdx]; break; case 0x0F: - out << szFlops0F[pIcode->ic.ll.dst.regi - rAX]; + out << szFlops0F[destRegIdx]; break; case 0x15: - out << szFlops15[pIcode->ic.ll.dst.regi - rAX]; + out << szFlops15[destRegIdx]; break; case 0x1C: - out << szFlops1C[pIcode->ic.ll.dst.regi - rAX]; + out << szFlops1C[destRegIdx]; break; case 0x33: - out << szFlops33[pIcode->ic.ll.dst.regi - rAX]; + out << szFlops33[destRegIdx]; break; case 0x3C: - out << szFlops3C[pIcode->ic.ll.dst.regi - rAX]; + out << szFlops3C[destRegIdx]; break; default: out << szFlops2[op]; if ((op >= 0x20) && (op <= 0x27)) { /* This is the ST(i), ST form. */ - out << "ST("<ic.ll.dst.regi - rAX<<"),ST"; + out << "ST("<ic.ll.dst.regi - rAX; + out << "ST,ST("<ic.ll.match(iPOP)) - { - if ((m_func->flg & DI_REGVAR) && pIcode->ic.ll.match(rDI)) - m_icodes.push_front(pIcode); - else if ((m_func->flg & SI_REGVAR) && pIcode->ic.ll.match(rSI)) - m_icodes.push_front(pIcode); - } - ++pIcode; - if(pIcode==m_end) - return; - /* Match [POP SI] */ - if (pIcode->ic.ll.match(iPOP)) - { - if ((m_func->flg & SI_REGVAR) && pIcode->ic.ll.match(rSI)) - m_icodes.push_front(pIcode); - else if ((m_func->flg & DI_REGVAR) && pIcode->ic.ll.match(rDI)) - m_icodes.push_front(pIcode); - } -} - - -/***************************************************************************** - * idiom2 - HLL procedure epilogue; Returns number of instructions matched. - * [POP DI] - * [POP SI] - * MOV SP, BP - * POP BP - * RET(F) - *****************************************************************************/ -bool Idiom2::match(iICODE pIcode) -{ - iICODE nicode; - if(pIcode==m_func->Icode.begin()) // pIcode->loc_ip == 0 - return false; - if ( ((pIcode->ic.ll.flg & I) == I) || not pIcode->ic.ll.match(rSP,rBP)) - return false; - if(distance(pIcode,m_end)<3) - return false; - /* Matched MOV SP, BP */ - m_icodes.clear(); - m_icodes.push_back(pIcode); - /* Get next icode, skip over holes in the icode array */ - nicode = pIcode + 1; - while (nicode->ic.ll.flg & NO_CODE && (nicode != m_end)) - { - nicode++; - } - if(nicode == m_end) - return false; - - if (nicode->ic.ll.match(iPOP,rBP) && ! (nicode->ic.ll.flg & (I | TARGET | CASE)) ) - { - m_icodes.push_back(nicode++); // Matched POP BP - - /* Match RET(F) */ - if ( nicode != m_end && - !(nicode->ic.ll.flg & (I | TARGET | CASE)) && - (nicode->ic.ll.match(iRET) || nicode->ic.ll.match(iRETF)) - ) - { - m_icodes.push_back(nicode); // Matched RET - popStkVars (pIcode-2); // will add optional pop di/si to m_icodes - return true; - } - } - return false; -} -int Idiom2::action() -{ - for(size_t idx=0; idxinvalidate(); - return 3; - -} - -/***************************************************************************** - * idiom4 - Pascal calling convention. - * RET(F) immed - * ==> pProc->cbParam = immed - * sets CALL_PASCAL flag - * - Second version: check for optional pop of stack vars - * [POP DI] - * [POP SI] - * POP BP - * RET(F) [immed] - * - Third version: pop stack vars - * [POP DI] - * [POP SI] - * RET(F) [immed] - ****************************************************************************/ -bool Idiom4::match(iICODE pIcode) -{ - m_param_count = 0; - /* Check for [POP DI] - * [POP SI] */ - if(distance(m_func->Icode.begin(),pIcode)>=3) - popStkVars (pIcode-3); - if(pIcode != m_func->Icode.begin()) - { - iICODE prev1=pIcode-1; - /* Check for POP BP */ - if (prev1->ic.ll.match(iPOP,rBP) && not prev1->ic.ll.anyFlagSet(I) ) - m_icodes.push_back(prev1); - else if(prev1!=m_func->Icode.begin()) - popStkVars (pIcode-2); - } - - /* Check for RET(F) immed */ - if (pIcode->ic.ll.flg & I) - { - m_param_count = (int16)pIcode->ic.ll.src.op(); - } -} -int Idiom4::action() -{ - for(size_t idx=0; idxinvalidate(); - if(m_param_count) - { - m_func->cbParam = (int16)m_param_count; - m_func->flg |= CALL_PASCAL; - } - return 0; -} - diff --git a/src/graph.cpp b/src/graph.cpp index a51cf1b..fd97da0 100644 --- a/src/graph.cpp +++ b/src/graph.cpp @@ -116,19 +116,24 @@ CondJumps: default: /* Check for exit to DOS */ + iICODE next1=++iICODE(pIcode); if (pIcode->ic.ll.flg & TERMINATES) { pBB = BB::Create(start, ip, TERMINATE_NODE, 0, this); start = ip + 1; } /* Check for a fall through */ - else if (Icode[ip + 1].ic.ll.flg & (TARGET | CASE)) + else if (next1 != Icode.end()) { - pBB = BB::Create(start, ip, FALL_NODE, 1, this); - start = ip + 1; - pBB->edges[0].ip = (dword)start; + assert(next1->loc_ip==ip+1); + if (next1->ic.ll.flg & (TARGET | CASE)) + { + pBB = BB::Create(start, ip, FALL_NODE, 1, this); + start = ip + 1; + pBB->edges[0].ip = (dword)start; + } } - break; + break; } } } @@ -217,7 +222,9 @@ void Function::compressCFG() if (not pBB->edges.empty()) /* Might have been clobbered */ { pBB->edges[i].BBptr = pNxt; - Icode[ip].SetImmediateOp((dword)pNxt->begin()); + assert(pBB->back().loc_ip==ip); + pBB->back().SetImmediateOp((dword)pNxt->begin()); + //Icode[ip].SetImmediateOp((dword)pNxt->begin()); } } } diff --git a/src/icode.cpp b/src/icode.cpp index 78ea6e8..f7245a0 100644 --- a/src/icode.cpp +++ b/src/icode.cpp @@ -15,7 +15,6 @@ CIcodeRec::CIcodeRec() { - reserve(1024); } /* Copies the icode that is pointed to by pIcode to the icode array. @@ -30,8 +29,11 @@ ICODE * CIcodeRec::addIcode(ICODE *pIcode) void CIcodeRec::SetInBB(int start, int end, BB *pnewBB) { - for (int i = start; i <= end; i++) - at(i).inBB = pnewBB; + for(ICODE &icode : *this) + if((icode.loc_ip>=start) and (icode.loc_ip<=end)) + icode.inBB = pnewBB; +// for (int i = start; i <= end; i++) +// at(i).inBB = pnewBB; } /* labelSrchRepl - Searches the icodes for instruction with label = target, and @@ -39,33 +41,23 @@ void CIcodeRec::SetInBB(int start, int end, BB *pnewBB) bool CIcodeRec::labelSrch(dword target, dword &pIndex) { Int i; - - for (i = 0; i < size(); i++) - { - if (at(i).ic.ll.label == target) - { - pIndex = i; - return true; - } - } - return false; + iICODE location=labelSrch(target); + if(end()==location) + return false; + pIndex=location->loc_ip; + return true; } CIcodeRec::iterator CIcodeRec::labelSrch(dword target) { Int i; - - for (i = 0; i < size(); i++) - { - if (at(i).ic.ll.label == target) - { - return begin()+i; - } - } - return end(); + return find_if(begin(),end(),[target](ICODE &l) -> bool {return l.ic.ll.label==target;}); } ICODE * CIcodeRec::GetIcode(int ip) { - return &at(ip); + assert(ip>=0 && ip ENTER immed, 0 - * MOV BP, SP and sets PROC_HLL flag - * [SUB SP, immed] - * [PUSH SI] - * [PUSH DI] - * - Second version: Push stack variables and then save BP - * PUSH BP - * PUSH SI - * [PUSH DI] - * MOV BP, SP - * - Third version: Stack variables - * [PUSH SI] - * [PUSH DI] - ****************************************************************************/ -/***************************************************************************** -/* checkStkVars - Checks for PUSH SI - * [PUSH DI] - * or PUSH DI - * [PUSH SI] - * In which case, the stack variable flags are set - ****************************************************************************/ -Int Idiom1::checkStkVars (iICODE pIcode) -{ - /* Look for PUSH SI */ - int si_matched=0; - int di_matched=0; - if(pIcode==m_end) - return 0; - if (pIcode->ic.ll.match(iPUSH,rSI)) - { - si_matched = 1; - ++pIcode; - if ((pIcode != m_end) && pIcode->ic.ll.match(iPUSH,rDI)) // Look for PUSH DI - di_matched = 1; - } - else if (pIcode->ic.ll.match(iPUSH,rDI)) - { - di_matched = 1; - ++pIcode; - if ((pIcode != m_end) && pIcode->ic.ll.match(iPUSH,rSI)) // Look for PUSH SI - si_matched = 1; - } - m_func->flg |= (si_matched ? SI_REGVAR : 0) | (di_matched ? DI_REGVAR : 0); - return si_matched+di_matched; -} -bool Idiom1::match(iICODE picode) -{ - uint8_t type = 0; /* type of variable: 1 = reg-var, 2 = local */ - byte regi; /* register of the MOV */ - if(picode==m_end) - return false; - Int n; - m_icodes.clear(); - m_min_off = 0; - /* PUSH BP as first instruction of procedure */ - if ( !(picode->ic.ll.flg & I) && picode->ic.ll.src.regi == rBP) - { - m_icodes.push_back( picode++ ); // insert iPUSH - if(picode==m_end) - return false; - /* MOV BP, SP as next instruction */ - if ( !picode->ic.ll.anyFlagSet(I | TARGET | CASE) && picode->ic.ll.match(iMOV ,rBP,rSP) ) - { - m_icodes.push_back( picode++ ); // insert iMOV - if(picode==m_end) - return false; - m_min_off = 2; - - /* Look for SUB SP, immed */ - if ( - picode->ic.ll.anyFlagSet(I | TARGET | CASE) && picode->ic.ll.match(iSUB,rSP) - ) - { - m_icodes.push_back( picode++ ); // insert iSUB - int n = checkStkVars (picode); // find iPUSH si [iPUSH di] - for(int i=0; i 0) - { - for(int i=0; iic.ll.anyFlagSet(I | TARGET | CASE) && - picode->ic.ll.match(iMOV,rBP,rSP)) - { - m_icodes.push_back(picode); - m_min_off = 2 + (n * 2); - } - else - return false; // Cristina: check this please! - } - else - return false; // Cristina: check this please! - } - } - else // push di [push si] / push si [push di] - { - n = checkStkVars (picode); - for(int i=0; iinvalidate(); - } - m_func->flg |= PROC_IS_HLL; - if(0!=m_min_off) - m_func->args.m_minOff = m_min_off; - return m_icodes.size(); -} diff --git a/src/idioms.cpp b/src/idioms.cpp index 70f0b8c..e2605c0 100644 --- a/src/idioms.cpp +++ b/src/idioms.cpp @@ -15,7 +15,7 @@ #include "shift_idioms.h" #include "arith_idioms.h" #include "dcc.h" - +#include /***************************************************************************** * JmpInst - Returns TRUE if opcode is a conditional or unconditional jump ****************************************************************************/ @@ -70,8 +70,12 @@ void Function::findIdioms() Idiom18 i18(this); Idiom19 i19(this); Idiom20 i20(this); - - while (pIcode < pEnd) + struct is_valid + { + bool operator()(ICODE &z) { return not z.invalid;} + }; + typedef boost::filter_iterator ifICODE; + while (pIcode != pEnd) { switch (pIcode->ic.ll.opcode) { @@ -224,13 +228,22 @@ void Function::bindIcodeOff() pIcode = Icode.begin(); /* Flag all jump targets for BB construction and disassembly stage 2 */ - for (i = 0; i < Icode.size(); i++) - if ((pIcode[i].ic.ll.flg & I) && JmpInst(pIcode[i].ic.ll.opcode)) + for(ICODE &c : Icode) { - iICODE loc=Icode.labelSrch(pIcode[i].ic.ll.src.op()); + if ((c.ic.ll.flg & I) && JmpInst(c.ic.ll.opcode)) + { + iICODE loc=Icode.labelSrch(c.ic.ll.src.op()); if (loc!=Icode.end()) loc->ic.ll.flg |= TARGET; } + } +// for (i = 0; i < Icode.size(); i++) +// if ((pIcode[i].ic.ll.flg & I) && JmpInst(pIcode[i].ic.ll.opcode)) +// { +// iICODE loc=Icode.labelSrch(pIcode[i].ic.ll.src.op()); +// if (loc!=Icode.end()) +// loc->ic.ll.flg |= TARGET; +// } /* Finally bind jump targets to Icode offsets. Jumps for which no label * is found (no code at dest. of jump) are simply left unlinked and diff --git a/src/idioms/arith_idioms.cpp b/src/idioms/arith_idioms.cpp index 1dc61fc..f0192a6 100644 --- a/src/idioms/arith_idioms.cpp +++ b/src/idioms/arith_idioms.cpp @@ -170,21 +170,6 @@ int Idiom18::action() // action length m_icodes[1]->invalidate(); m_icodes[2]->invalidate(); return 3; - /* - lhs = COND_EXPR::id (*(pIcode-1), SRC, this, pIcode, *pIcode, eUSE); - if (pIcode->ic.ll.opcode == iDEC) - lhs = COND_EXPR::unary (POST_DEC, lhs); - else - lhs = COND_EXPR::unary (POST_INC, lhs); - rhs = COND_EXPR::id (*(pIcode+1), SRC, this, pIcode, *(pIcode+2), eUSE); - exp = COND_EXPR::boolOp (lhs, rhs, condOpJCond[(pIcode+2)->ic.ll.opcode - iJB]); - (pIcode+2)->setJCond(exp); - - (pIcode-1)->invalidate(); - pIcode->invalidate(); - (pIcode+1)->invalidate(); - pIcode += 3; - */ } /***************************************************************************** @@ -320,8 +305,7 @@ int Idiom20::action() rhs = COND_EXPR::id (*m_icodes[2], SRC, m_func, m_icodes[0], *m_icodes[3], eUSE); expr = COND_EXPR::boolOp (lhs, rhs, condOpJCond[m_icodes[3]->ic.ll.opcode - iJB]); m_icodes[3]->setJCond(expr); - m_icodes[0]->invalidate(); - m_icodes[1]->invalidate(); - m_icodes[2]->invalidate(); + for(int i=0; i<3; ++i) + m_icodes[i]->invalidate(); return 4; } diff --git a/src/idioms/epilogue_idioms.cpp b/src/idioms/epilogue_idioms.cpp index 3ee9cdc..b80075c 100644 --- a/src/idioms/epilogue_idioms.cpp +++ b/src/idioms/epilogue_idioms.cpp @@ -54,7 +54,7 @@ bool Idiom2::match(iICODE pIcode) m_icodes.clear(); m_icodes.push_back(pIcode); /* Get next icode, skip over holes in the icode array */ - nicode = pIcode + 1; + nicode = ++iICODE(pIcode); while (nicode->ic.ll.flg & NO_CODE && (nicode != m_end)) { nicode++; @@ -73,7 +73,8 @@ bool Idiom2::match(iICODE pIcode) ) { m_icodes.push_back(nicode); // Matched RET - popStkVars (pIcode-2); // will add optional pop di/si to m_icodes + advance(pIcode,-2); // move back before our start + popStkVars (pIcode); // and add optional pop di/si to m_icodes return true; } } @@ -108,15 +109,23 @@ bool Idiom4::match(iICODE pIcode) /* Check for [POP DI] * [POP SI] */ if(distance(m_func->Icode.begin(),pIcode)>=3) - popStkVars (pIcode-3); + { + iICODE search_at(pIcode); + advance(search_at,-3); + popStkVars(search_at); + } if(pIcode != m_func->Icode.begin()) { - iICODE prev1=pIcode-1; + iICODE prev1 = --iICODE(pIcode); /* Check for POP BP */ if (prev1->ic.ll.match(iPOP,rBP) && not prev1->ic.ll.anyFlagSet(I) ) m_icodes.push_back(prev1); else if(prev1!=m_func->Icode.begin()) - popStkVars (pIcode-2); + { + iICODE search_at(pIcode); + advance(search_at,-2); + popStkVars (search_at); + } } /* Check for RET(F) immed */ diff --git a/src/idioms/xor_idioms.cpp b/src/idioms/xor_idioms.cpp index 0878a1e..636c424 100644 --- a/src/idioms/xor_idioms.cpp +++ b/src/idioms/xor_idioms.cpp @@ -134,40 +134,3 @@ int Idiom10::action() return 2; } -/***************************************************************************** - * idiom10 - Jump if not equal to 0 - * OR reg, reg - * JNE labX - * Eg: OR ax, ax - * JNE labX - * => HLI_JCOND (ax != 0) labX - * Note: we also check that these instructions are not followed by - * CMP reg, kte - * JE lab - * because this is most likely a long conditional equality test. - * Found in Borland Turbo C. - ****************************************************************************/ -static boolT idiom10old (iICODE pIcode, iICODE pEnd) -{ - if (pIcode < pEnd) - { - /* Check OR reg, reg */ - if (((pIcode->ic.ll.flg & I) != I) && - (pIcode->ic.ll.src. regi > 0) && - (pIcode->ic.ll.src.regi < INDEXBASE) && - (pIcode->ic.ll.src.regi == pIcode->ic.ll.dst.regi)) - if ((pIcode+3) < pEnd) - { - if (((pIcode+1)->ic.ll.opcode == iJNE) && - ((pIcode+2)->ic.ll.opcode != iCMP) && - ((pIcode+3)->ic.ll.opcode != iJE)) - return true; - } - else /* at the end of the procedure */ - if (((pIcode+1) < pEnd) && ((pIcode+1)->ic.ll.opcode == iJNE)) - return true; - } - return false; -} - - diff --git a/src/locident.cpp b/src/locident.cpp index 615e011..084f851 100644 --- a/src/locident.cpp +++ b/src/locident.cpp @@ -249,20 +249,22 @@ Int LOCAL_ID::newLongStk(hlType t, Int offH, Int offL) /* Returns the index to an appropriate long identifier. * Note: long constants should be checked first and stored as a long integer * number in an expression record. */ -Int LOCAL_ID::newLong(opLoc sd, ICODE *pIcode, hlFirst f, iICODE ix,operDu du, Int off) +Int LOCAL_ID::newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix,operDu du, Int off) { Int idx; LLOperand *pmH, *pmL; + iICODE atOffset(pIcode); + advance(atOffset,off); if (f == LOW_FIRST) { pmL = (sd == SRC) ? &pIcode->ic.ll.src : &pIcode->ic.ll.dst; - pmH = (sd == SRC) ? &(pIcode+off)->ic.ll.src : &(pIcode+off)->ic.ll.dst; + pmH = (sd == SRC) ? &atOffset->ic.ll.src : &atOffset->ic.ll.dst; } else /* HIGH_FIRST */ { pmH = (sd == SRC) ? &pIcode->ic.ll.src : &pIcode->ic.ll.dst; - pmL = (sd == SRC) ? &(pIcode+off)->ic.ll.src : &(pIcode+off)->ic.ll.dst; + pmL = (sd == SRC) ? &atOffset->ic.ll.src : &atOffset->ic.ll.dst; } if (pmL->regi == 0) /* global variable */ @@ -310,11 +312,13 @@ boolT checkLongEq (LONG_STKID_TYPE longId, iICODE pIcode, Int i, Function * pProc, Assignment &asgn, Int off) { LLOperand *pmHdst, *pmLdst, *pmHsrc, *pmLsrc; /* pointers to LOW_LEVEL icodes */ + iICODE atOffset(pIcode); + advance(atOffset,off); pmHdst = &pIcode->ic.ll.dst; - pmLdst = &(pIcode+off)->ic.ll.dst; + pmLdst = &atOffset->ic.ll.dst; pmHsrc = &pIcode->ic.ll.src; - pmLsrc = &(pIcode+off)->ic.ll.src; + pmLsrc = &atOffset->ic.ll.src; if ((longId.offH == pmHdst->off) && (longId.offL == pmLdst->off)) { @@ -349,18 +353,19 @@ boolT checkLongRegEq (LONGID_TYPE longId, iICODE pIcode, Int i, Function * pProc, COND_EXPR *&rhs, COND_EXPR *&lhs, Int off) { LLOperand *pmHdst, *pmLdst, *pmHsrc, *pmLsrc; /* pointers to LOW_LEVEL icodes */ + iICODE atOffset(pIcode); + advance(atOffset,off); pmHdst = &pIcode->ic.ll.dst; - pmLdst = &(pIcode+off)->ic.ll.dst; + pmLdst = &atOffset->ic.ll.dst; pmHsrc = &pIcode->ic.ll.src; - pmLsrc = &(pIcode+off)->ic.ll.src; + pmLsrc = &atOffset->ic.ll.src; if ((longId.h == pmHdst->regi) && (longId.l == pmLdst->regi)) { lhs = COND_EXPR::idLongIdx (i); if ((pIcode->ic.ll.flg & NO_SRC) != NO_SRC) { - //rhs = COND_EXPR::idLong (&pProc->localId, SRC, pIcode, HIGH_FIRST, idx, eUSE, off); rhs = COND_EXPR::idLong (&pProc->localId, SRC, pIcode, HIGH_FIRST, pIcode, eUSE, off); } return true; @@ -368,7 +373,6 @@ boolT checkLongRegEq (LONGID_TYPE longId, iICODE pIcode, Int i, else if ((longId.h == pmHsrc->regi) && (longId.l == pmLsrc->regi)) { lhs = COND_EXPR::idLong (&pProc->localId, DST, pIcode, HIGH_FIRST, pIcode, eDEF, off); - //lhs = COND_EXPR::idLong (&pProc->localId, DST, pIcode, HIGH_FIRST, idx, eDEF, off); rhs = COND_EXPR::idLongIdx (i); return true; } diff --git a/src/parser.cpp b/src/parser.cpp index f7874fa..4fb8ef5 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -150,12 +150,13 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate) flg |= (_Icode.ic.ll.flg & (NOT_HLL | FLOAT_OP)); /* Check if this instruction has already been parsed */ - if (Icode.labelSrch(_Icode.ic.ll.label, lab)) + iICODE labLoc = Icode.labelSrch(_Icode.ic.ll.label); + if (Icode.end()!=labLoc) { /* Synthetic jump */ _Icode.type = LOW_LEVEL; _Icode.ic.ll.opcode = iJMP; _Icode.ic.ll.flg = I | SYNTHETIC | NO_OPS; - _Icode.ic.ll.src.SetImmediateOp(Icode[lab].GetLlLabel()); + _Icode.ic.ll.src.SetImmediateOp(labLoc->GetLlLabel()); _Icode.ic.ll.label = SynthLab++; } @@ -484,13 +485,15 @@ boolT Function::process_JMP (ICODE * pIcode, STATE *pstate, CALL_GRAPH * pcallGr { memcpy(&StCopy, pstate, sizeof(STATE)); StCopy.IP = cs + LH(&prog.Image[i]); + iICODE last_current_insn = (++Icode.rbegin()).base(); ip = Icode.size(); FollowCtrl (pcallGraph, &StCopy); + ++last_current_insn; + last_current_insn->ic.ll.caseTbl.numEntries = k++; + last_current_insn->ic.ll.flg |= CASE; + *psw++ = last_current_insn->GetLlLabel(); - Icode.GetIcode(ip)->ic.ll.caseTbl.numEntries = k++; - Icode.GetIcode(ip)->ic.ll.flg |= CASE; - *psw++ = Icode[ip].GetLlLabel(); } return TRUE; } @@ -516,7 +519,7 @@ boolT Function::process_JMP (ICODE * pIcode, STATE *pstate, CALL_GRAPH * pcallGr boolT Function::process_CALL (ICODE * pIcode, CALL_GRAPH * pcallGraph, STATE *pstate) { - Int ip = Icode.size() - 1; + ICODE &last_insn(Icode.back()); STATE localState; /* Local copy of the machine state */ dword off; boolT indirect; @@ -581,7 +584,7 @@ boolT Function::process_CALL (ICODE * pIcode, CALL_GRAPH * pcallGraph, STATE *ps /* A library function. No need to do any more to it */ pcallGraph->insertCallGraph (this, iter); iter = (++pProcList.rbegin()).base(); - Icode.GetIcode(ip)->ic.ll.src.proc.proc = &x; + last_insn.ic.ll.src.proc.proc = &x; return false; } @@ -621,7 +624,7 @@ boolT Function::process_CALL (ICODE * pIcode, CALL_GRAPH * pcallGraph, STATE *ps else pcallGraph->insertCallGraph (this, iter); - Icode[ip].ic.ll.src.proc.proc = &(*iter); // ^ target proc + last_insn.ic.ll.src.proc.proc = &(*iter); // ^ target proc /* return ((p->flg & TERMINATES) != 0); */ return FALSE; @@ -856,20 +859,7 @@ void STATE::setState(word reg, int16 value) /* labelSrchRepl - Searches Icode for instruction with label = target, and replaces *pIndex with an icode index */ -bool labelSrch(CIcodeRec &pIcode, Int numIp, dword target, Int *pIndex) -{ - Int i; - for (i = 0; i < numIp; i++) - { - if (pIcode[i].ic.ll.label == target) - { - *pIndex = i; - return true; - } - } - return false; -} static void setBits(int16 type, dword start, dword len) diff --git a/src/proplong.cpp b/src/proplong.cpp index 11cf6e8..a2a7989 100644 --- a/src/proplong.cpp +++ b/src/proplong.cpp @@ -22,40 +22,6 @@ static boolT isJCond (llIcode opcode) /* Returns whether the conditions for a 2-3 long variable are satisfied */ -static boolT isLong23 (Int i, BB * pbb, Int *off, Int *arc) -{ - BB * t, * e, * obb2; - - if (pbb->nodeType != TWO_BRANCH) - return false; - t = pbb->edges[THEN].BBptr; - e = pbb->edges[ELSE].BBptr; - - /* Check along the THEN path */ - if ((t->size() == 1) && (t->nodeType == TWO_BRANCH) && (t->inEdges.size() == 1)) - { - obb2 = t->edges[THEN].BBptr; - if ((obb2->size() == 2) && (obb2->nodeType == TWO_BRANCH) && (obb2->front().ic.ll.opcode == iCMP)) - { - *off = obb2->front().loc_ip - i; - *arc = THEN; - return true; - } - } - - /* Check along the ELSE path */ - else if ((e->size() == 1) && (e->nodeType == TWO_BRANCH) && (e->inEdges.size() == 1)) - { - obb2 = e->edges[THEN].BBptr; - if ((obb2->size() == 2) && (obb2->nodeType == TWO_BRANCH) && (obb2->front().ic.ll.opcode == iCMP)) - { - *off = obb2->front().loc_ip - i; - *arc = ELSE; - return true; - } - } - return false; -} static boolT isLong23 (iICODE iter, BB * pbb, Int *off, Int *arc) { BB * t, * e, * obb2; @@ -95,14 +61,13 @@ static boolT isLong23 (iICODE iter, BB * pbb, Int *off, Int *arc) /* Returns whether the conditions for a 2-2 long variable are satisfied */ static boolT isLong22 (iICODE pIcode, iICODE pEnd, Int *off) { - iICODE next1 = pIcode+1; - iICODE next2 = pIcode+2; - iICODE next3 = pIcode+3; - if(next3>=pEnd) + if(distance(pIcode,pEnd)<4) return false; - if ( (next2->ic.ll.opcode == iCMP) && - (isJCond (next1->ic.ll.opcode)) && - (isJCond (next3->ic.ll.opcode))) + // preincrement because pIcode is not checked here + iICODE icodes[] = { ++pIcode,++pIcode,++pIcode }; + if ( icodes[1]->ic.ll.match(iCMP) && + (isJCond (icodes[0]->ic.ll.opcode)) && + (isJCond (icodes[2]->ic.ll.opcode))) { *off = 2; return true; @@ -173,12 +138,14 @@ static int longJCond23 (COND_EXPR *rhs, COND_EXPR *lhs, iICODE pIcode, Int arc, /* Update icode index */ skipped_insn = 2; } - + iICODE atOffset(pIcode),atOffset1(pIcode),next1(++iICODE(pIcode)); + advance(atOffset,off); + advance(atOffset1,off+1); /* Create new HLI_JCOND and condition */ - lhs = COND_EXPR::boolOp (lhs, rhs, condOpJCond[(pIcode+off+1)->ic.ll.opcode-iJB]); - (pIcode+1)->setJCond(lhs); - (pIcode+1)->copyDU(*pIcode, eUSE, eUSE); - (pIcode+1)->du.use |= (pIcode+off)->du.use; + lhs = COND_EXPR::boolOp (lhs, rhs, condOpJCond[atOffset1->ic.ll.opcode-iJB]); + next1->setJCond(lhs); + next1->copyDU(*pIcode, eUSE, eUSE); + next1->du.use |= atOffset->du.use; /* Update statistics */ obb1->flg |= INVALID_BB; @@ -187,8 +154,10 @@ static int longJCond23 (COND_EXPR *rhs, COND_EXPR *lhs, iICODE pIcode, Int arc, pIcode->invalidate(); obb1->front().invalidate(); - obb2->front().invalidate(); - (obb2->begin2()+1)->invalidate(); + // invalidate 2 first instructions of BB 2 + iICODE ibb2 = obb2->begin2(); + (ibb2++)->invalidate(); + (ibb2++)->invalidate(); return skipped_insn; } @@ -198,22 +167,24 @@ static int longJCond23 (COND_EXPR *rhs, COND_EXPR *lhs, iICODE pIcode, Int arc, * the new edges for the remaining nodes. * @return number of ICODE's to skip */ -static int longJCond22 (COND_EXPR *rhs, COND_EXPR *lhs, iICODE pIcode) +static int longJCond22 (COND_EXPR *rhs, COND_EXPR *lhs, iICODE pIcode,iICODE pEnd) { Int j; BB * pbb, * obb1, * tbb; - iICODE next1=pIcode+1; - iICODE next2=pIcode+2; - iICODE next3=pIcode+3; + if(distance(pIcode,pEnd)<4) + return false; + // preincrement because pIcode is not checked here + iICODE icodes[] = { pIcode++,pIcode++,pIcode++,pIcode++ }; + /* Form conditional expression */ - lhs = COND_EXPR::boolOp (lhs, rhs, condOpJCond[(pIcode+3)->ic.ll.opcode - iJB]); - next1->setJCond(lhs); - next1->copyDU (*pIcode, eUSE, eUSE); - next1->du.use |= next2->du.use; + lhs = COND_EXPR::boolOp (lhs, rhs, condOpJCond[icodes[3]->ic.ll.opcode - iJB]); + icodes[1]->setJCond(lhs); + icodes[1]->copyDU (*icodes[0], eUSE, eUSE); + icodes[1]->du.use |= icodes[2]->du.use; /* Adjust outEdges[0] to the new target basic block */ - pbb = pIcode->inBB; - if (pbb->back().loc_ip == next1->loc_ip) + pbb = icodes[0]->inBB; + if (pbb->back().loc_ip == icodes[1]->loc_ip) { /* Find intermediate and target basic blocks */ obb1 = pbb->edges[THEN].BBptr; @@ -227,7 +198,7 @@ static int longJCond22 (COND_EXPR *rhs, COND_EXPR *lhs, iICODE pIcode) assert(iter!=tbb->inEdges.end()); tbb->inEdges.erase(iter); - if ((pIcode+3)->ic.ll.opcode != iJE) + if (icodes[3]->ic.ll.opcode != iJE) tbb->inEdges.push_back(pbb); /* iJNE => replace arc */ /* Modify ELSE out edge of header basic block */ @@ -237,7 +208,7 @@ static int longJCond22 (COND_EXPR *rhs, COND_EXPR *lhs, iICODE pIcode) iter=std::find(tbb->inEdges.begin(),tbb->inEdges.end(),obb1); assert(iter!=tbb->inEdges.end()); tbb->inEdges.erase(iter); - if ((pIcode+3)->ic.ll.opcode == iJE) /* replace */ + if (icodes[3]->ic.ll.opcode == iJE) /* replace */ tbb->inEdges.push_back(pbb); /* Update statistics */ @@ -245,9 +216,9 @@ static int longJCond22 (COND_EXPR *rhs, COND_EXPR *lhs, iICODE pIcode) stats.numBBaft--; } - pIcode->invalidate(); - next2->invalidate(); - next3->invalidate(); + icodes[0]->invalidate(); + icodes[2]->invalidate(); + icodes[3]->invalidate(); return 4; } @@ -258,20 +229,24 @@ static int longJCond22 (COND_EXPR *rhs, COND_EXPR *lhs, iICODE pIcode) * pProc : ptr to current procedure's record. */ void Function::propLongStk (Int i, const ID &pLocId) { - Int idx, off, arc; + Int off, arc; Assignment asgn; //COND_EXPR *lhs, *rhs; /* Pointers to left and right hand expression */ - iICODE pIcode, pEnd; + iICODE next1, pEnd; /* Check all icodes for offHi:offLo */ pEnd = Icode.end(); - for (idx = 0; idx < (this->Icode.size() - 1); idx++) + int stat_size=Icode.size(); +// for (idx = 0; idx < (Icode.size() - 1); idx++) + for(auto pIcode = Icode.begin(); ;++pIcode) { - pIcode = Icode.begin()+idx; + assert(Icode.size()==stat_size); + next1 = ++iICODE(pIcode); + if(next1==pEnd) + break; if ((pIcode->type == HIGH_LEVEL) || (pIcode->invalid == TRUE)) continue; - - if (pIcode->ic.ll.opcode == (pIcode+1)->ic.ll.opcode) + if (pIcode->ic.ll.opcode == next1->ic.ll.opcode) { switch (pIcode->ic.ll.opcode) { @@ -279,8 +254,7 @@ void Function::propLongStk (Int i, const ID &pLocId) if (checkLongEq (pLocId.id.longStkId, pIcode, i, this, asgn, 1) == TRUE) { pIcode->setAsgn(asgn.lhs, asgn.rhs); - (pIcode+1)->invalidate(); - idx++; + next1->invalidate(); } break; @@ -294,8 +268,7 @@ void Function::propLongStk (Int i, const ID &pLocId) case iXOR: asgn.rhs = COND_EXPR::boolOp (asgn.lhs, asgn.rhs, XOR); break; } pIcode->setAsgn(asgn.lhs, asgn.rhs); - (pIcode+1)->invalidate(); - idx++; + next1->invalidate(); } break; @@ -303,19 +276,18 @@ void Function::propLongStk (Int i, const ID &pLocId) if (checkLongEq (pLocId.id.longStkId, pIcode, i, this, asgn, 1) == TRUE) { pIcode->setUnary( HLI_PUSH, asgn.lhs); - (pIcode+1)->invalidate(); - idx++; + next1->invalidate(); } break; } /*eos*/ } /* Check long conditional (i.e. 2 CMPs and 3 branches */ - else if ((pIcode->ic.ll.opcode == iCMP) && (isLong23 (idx, pIcode->inBB, &off, &arc))) + else if ((pIcode->ic.ll.opcode == iCMP) && (isLong23 (pIcode, pIcode->inBB, &off, &arc))) { if ( checkLongEq (pLocId.id.longStkId, pIcode, i, this, asgn, off) ) { - idx += longJCond23 (asgn.rhs, asgn.lhs, pIcode, arc, off); // + advance(pIcode,longJCond23 (asgn.rhs, asgn.lhs, pIcode, arc, off)); } } @@ -325,7 +297,7 @@ void Function::propLongStk (Int i, const ID &pLocId) { if ( checkLongEq (pLocId.id.longStkId, pIcode, i, this,asgn, off) ) { - idx += longJCond22 (asgn.rhs, asgn.lhs, pIcode); // maybe this should have -1 to offset loop autoincrement? + advance(pIcode,longJCond22 (asgn.rhs, asgn.lhs, pIcode,pEnd)); } } } @@ -339,9 +311,9 @@ int Function::findBackwarLongDefs(int loc_ident_idx, const ID &pLocId, iICODE be bool forced_finish=false; for (; not forced_finish and rev!=Icode.rend();rev++) //idx = pLocId_idx - 1; idx > 0 ; idx-- { - ICODE &icode(*rev); - ICODE &next1(*(rev-1)); // prev reverse is actually next instruction - pIcode = (rev+1).base();//Icode.begin()+(idx-1); + pIcode = (++riICODE(rev)).base();//forward iterator from rev + ICODE &icode(*pIcode); + ICODE &next1(*(++iICODE(pIcode))); // next instruction if ((icode.type == HIGH_LEVEL) || (icode.invalid == TRUE)) @@ -414,9 +386,11 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be bool forced_finish=false; auto pEnd=Icode.end(); Assignment asgn; - for (auto pIcode=beg; not forced_finish and ((pIcode+1)!=Icode.end()); ++pIcode) + for (auto pIcode=beg; not forced_finish; ++pIcode) { - iICODE next1(pIcode+1); + iICODE next1(++iICODE(pIcode)); + if(next1==pEnd) + break; LLOperand * pmH,* pmL; /* Pointers to dst LOW_LEVEL icodes */ int off,arc; @@ -474,7 +448,7 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be break; } pIcode->setAsgn(asgn.lhs, asgn.rhs); - (pIcode+1)->invalidate(); + next1->invalidate(); // ftw loop restart ???? //idx = 0; // maybe this should end the loop instead @@ -488,19 +462,18 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be { if (checkLongRegEq (pLocId.id.longId, pIcode, loc_ident_idx, this, asgn.rhs, asgn.lhs, off) == TRUE) { - pIcode += longJCond23 (asgn.rhs, asgn.lhs, pIcode, arc, off); + // reduce the advance by 1 here (loop increases) ? + advance(pIcode,longJCond23 (asgn.rhs, asgn.lhs, pIcode, arc, off)); } } /* Check for long conditional equality or inequality. This requires * 2 CMPs and 2 branches */ - else if ((pIcode->ic.ll.opcode == iCMP) && - (isLong22 (pIcode, pEnd, &off))) + else if (pIcode->ic.ll.match(iCMP) && (isLong22 (pIcode, pEnd, &off))) { - if (checkLongRegEq (pLocId.id.longId, pIcode, loc_ident_idx, this, - asgn.rhs, asgn.lhs, off) == TRUE) + if (checkLongRegEq (pLocId.id.longId, pIcode, loc_ident_idx, this, asgn.rhs, asgn.lhs, off) == TRUE) { - pIcode += longJCond22 (asgn.rhs, asgn.lhs, pIcode); + advance(pIcode,longJCond22 (asgn.rhs, asgn.lhs, pIcode,pEnd) - 1); } } @@ -508,14 +481,11 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be * JX lab * => HLI_JCOND (regH:regL X 0) lab * This is better code than HLI_JCOND (HI(regH:regL) | LO(regH:regL)) */ - else if ((pIcode->ic.ll.opcode == iOR) && (next1 < pEnd) && - (isJCond (next1->ic.ll.opcode))) + else if (pIcode->ic.ll.match(iOR) && (next1 != pEnd) && (isJCond (next1->ic.ll.opcode))) { - if ((pIcode->ic.ll.dst.regi == pLocId.id.longId.h) && - (pIcode->ic.ll.src.regi == pLocId.id.longId.l)) + if ((pIcode->ic.ll.dst.regi == pLocId.id.longId.h) && (pIcode->ic.ll.src.regi == pLocId.id.longId.l)) { asgn.lhs = COND_EXPR::idLongIdx (loc_ident_idx); - asgn.rhs = COND_EXPR::idKte (0, 4); /* long 0 */ asgn.lhs = COND_EXPR::boolOp (asgn.lhs, asgn.rhs, condOpJCond[next1->ic.ll.opcode - iJB]); next1->setJCond(asgn.lhs); @@ -523,7 +493,6 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be pIcode->invalidate(); } } - } /* end for */ } diff --git a/tests/prev_base/BENCHLNG.b b/tests/prev_base/BENCHLNG.b index da66c79..bfceece 100644 --- a/tests/prev_base/BENCHLNG.b +++ b/tests/prev_base/BENCHLNG.b @@ -9,6 +9,7 @@ long LMOD@ (long arg0, int arg2, int arg3) /* Takes 8 bytes of parameters. * Runtime support routine of the compiler. + * High-level language prologue code. * Untranslatable routine. Assembler provided. * Return value in registers dx:ax. * Pascal calling convention. diff --git a/tests/prev_base/FIBOS.b b/tests/prev_base/FIBOS.b index aec76cf..41118ea 100644 --- a/tests/prev_base/FIBOS.b +++ b/tests/prev_base/FIBOS.b @@ -12,7 +12,7 @@ int proc_1 (int arg0) * C calling convention. */ { -int loc1; +int loc1; /* si */ int loc2; /* ax */ loc1 = arg0; diff --git a/valgrind_tester b/valgrind_tester new file mode 100755 index 0000000..b347735 --- /dev/null +++ b/valgrind_tester @@ -0,0 +1,37 @@ +#!/usr/bin/env ruby +require 'fileutils' +print("Regression tester 0.0.1\n") +def path_local(from) + + return from #from.gsub('/','//') + from.gsub('/','\\\\') +end +TESTS_DIR="./tests" +def perform_test(exepath,filepath,outname) + output_path=path_local(TESTS_DIR+"/outputs/"+outname) + error_path=path_local(TESTS_DIR+"/errors/"+outname) + exepath=path_local(exepath) + output_path=path_local(output_path) + filepath=path_local(filepath) + printf("calling:" + "#{exepath} -a1 -o#{output_path}.a1 #{filepath}\n") + valgrind_mode="valgrind --track-origins=yes " + #valgrind --tool=callgrind --dump-instr=yes --collect-jumps=yes + result = `#{valgrind_mode} #{exepath} -a2V -o#{output_path}.a2 #{filepath} 2>#{error_path}.val` + puts result + p $? +end +`rm -rf #{TESTS_DIR}/outputs/*.*` +#exit(1) +if(ARGV.size()==0) + puts("valgrind_tester DCC_EXECUTABLE") + exit(0) +end +Dir.open(TESTS_DIR+"/inputs").each() {|f| + next if f=="." or f==".." + perform_test(".//"+ARGV[0],TESTS_DIR+"/inputs/"+f,f) +} +Dir.open(TESTS_DIR+"/inputs").each() {|f| + next if f=="." or f==".." + FileUtils.mv(TESTS_DIR+"/inputs/"+f,TESTS_DIR+"/outputs/"+f) if f.end_with?(".b") +} +"diff -rqbwB" \ No newline at end of file