diff --git a/include/Procedure.h b/include/Procedure.h index 78fed5c..ab89379 100644 --- a/include/Procedure.h +++ b/include/Procedure.h @@ -106,9 +106,9 @@ public: void markImpure(); void findImmedDom(); void FollowCtrl(CALL_GRAPH *pcallGraph, STATE *pstate); - void process_operands(ICODE *pIcode, STATE *pstate); - boolT process_JMP(ICODE *pIcode, STATE *pstate, CALL_GRAPH *pcallGraph); - boolT process_CALL(ICODE *pIcode, CALL_GRAPH *pcallGraph, STATE *pstate); + void process_operands(ICODE &pIcode, STATE *pstate); + boolT process_JMP(ICODE &pIcode, STATE *pstate, CALL_GRAPH *pcallGraph); + boolT process_CALL(ICODE &pIcode, CALL_GRAPH *pcallGraph, STATE *pstate); void displayCFG(); void freeCFG(); void codeGen(std::ostream &fs); diff --git a/include/ast.h b/include/ast.h index 9b273f8..6217ba2 100644 --- a/include/ast.h +++ b/include/ast.h @@ -23,10 +23,6 @@ static const condOp condOpJCond[12] = {LESS, LESS_EQUAL, GREATER_EQUAL, GREATER, EQUAL, NOT_EQUAL, LESS, GREATER_EQUAL, LESS_EQUAL, GREATER, GREATER_EQUAL, LESS}; -static const condOp invCondOpJCond[12] = {GREATER_EQUAL, GREATER, LESS, LESS_EQUAL, - NOT_EQUAL, EQUAL, GREATER_EQUAL, LESS, - GREATER, LESS_EQUAL, LESS, GREATER_EQUAL}; - struct Function; struct STKFRAME; struct LOCAL_ID; @@ -79,6 +75,7 @@ public: memset(&expr,0,sizeof(_exprNode)); } public: + COND_EXPR *inverse(); // return new COND_EXPR that is invarse of this }; /* Sequence of conditional expression data type */ diff --git a/include/dcc.h b/include/dcc.h index b0a15e0..c659ed5 100644 --- a/include/dcc.h +++ b/include/dcc.h @@ -166,7 +166,7 @@ void freeCFG(BB * cfg); /* graph.c */ BB * newBB(BB *, Int, Int, byte, Int, Function *); /* graph.c */ void BackEnd(char *filename, CALL_GRAPH *); /* backend.c */ char *cChar(byte c); /* backend.c */ -eErrorId scan(dword ip, ICODE * p); /* scanner.c */ +eErrorId scan(dword ip, ICODE &p); /* scanner.c */ void parse (CALL_GRAPH * *); /* parser.c */ Int strSize (byte *, char); /* parser.c */ @@ -181,7 +181,6 @@ bool LibCheck(Function &p); /* chklib.c */ /* Exported functions from procs.c */ boolT insertCallGraph (CALL_GRAPH *, ilFunction, ilFunction); -boolT newStkArg (ICODE *, COND_EXPR *, llIcode, Function *); void allocStkArgs (ICODE *, Int); void placeStkArg (ICODE *, COND_EXPR *, Int); void adjustActArgType (COND_EXPR *, hlType, Function *); @@ -197,11 +196,9 @@ bool insertSubTreeLongReg (COND_EXPR *, COND_EXPR **, Int); /* Exported functions from hlicode.c */ std::string writeCall (Function *, STKFRAME *, Function *, Int *); -char *write1HlIcode (HLTYPE, Function *, Int *); char *writeJcond (HLTYPE, Function *, Int *); char *writeJcondInv (HLTYPE, Function *, Int *); Int power2 (Int); -void inverseCondOp (COND_EXPR **); /* Exported funcions from locident.c */ boolT checkLongEq (LONG_STKID_TYPE, iICODE, Int, Function *, Assignment &asgn, Int); diff --git a/include/icode.h b/include/icode.h index d4918c1..79feab2 100644 --- a/include/icode.h +++ b/include/icode.h @@ -253,20 +253,92 @@ struct DU struct COND_EXPR; +struct HlTypeSupport +{ + //hlIcode opcode; /* hlIcode opcode */ + virtual bool removeRegFromLong(byte regi, LOCAL_ID *locId)=0; + virtual std::string writeOut(Function *pProc, Int *numLoc)=0; +protected: + void performLongRemoval (byte regi, LOCAL_ID *locId, COND_EXPR *tree); +}; + +struct CallType : public HlTypeSupport +{ + //for HLI_CALL + Function * proc; + STKFRAME * args; // actual arguments + void allocStkArgs (Int num); + bool newStkArg(COND_EXPR *exp, llIcode opcode, Function *pproc); + void placeStkArg(COND_EXPR *exp, Int pos); +public: + bool removeRegFromLong(byte regi, LOCAL_ID *locId) + { + printf("CallType : removeRegFromLong not supproted"); + return false; + } + std::string writeOut(Function *pProc, Int *numLoc); +}; +struct AssignType : public HlTypeSupport +{ + /* for HLI_ASSIGN */ + COND_EXPR *lhs; + COND_EXPR *rhs; + bool removeRegFromLong(byte regi, LOCAL_ID *locId) + { + performLongRemoval(regi,locId,lhs); + return true; + } + std::string writeOut(Function *pProc, Int *numLoc); +}; +struct ExpType : public HlTypeSupport +{ + /* for HLI_JCOND, HLI_RET, HLI_PUSH, HLI_POP*/ + COND_EXPR *v; + bool removeRegFromLong(byte regi, LOCAL_ID *locId) + { + performLongRemoval(regi,locId,v); + return true; + } + std::string writeOut(Function *pProc, Int *numLoc); +}; + struct HLTYPE { hlIcode opcode; /* hlIcode opcode */ - union { /* different operands */ - struct { /* for HLI_ASSIGN */ - COND_EXPR *lhs; - COND_EXPR *rhs; - } asgn; - COND_EXPR *exp; /* for HLI_JCOND, HLI_RET, HLI_PUSH, HLI_POP*/ - struct { /* for HLI_CALL */ - Function *proc; - STKFRAME *args; /* actual arguments */ - } call; - } oper; /* operand */ + ExpType exp; /* for HLI_JCOND, HLI_RET, HLI_PUSH, HLI_POP*/ + AssignType asgn; + CallType call; + HlTypeSupport *get() + { + switch(opcode) + { + case HLI_ASSIGN: return &asgn; + case HLI_RET: + case HLI_POP: + case HLI_PUSH: return &exp; + case HLI_CALL: return &call; + default: + return 0; + } + } + + void expr(COND_EXPR *e) { exp.v=e;} + COND_EXPR * expr() { return exp.v;} + void set(hlIcode i,COND_EXPR *e) + { + assert(exp.v==0); + opcode=i; + exp.v=e; + } + void set(COND_EXPR *l,COND_EXPR *r) + { + opcode = HLI_ASSIGN; + assert((asgn.lhs==0) and (asgn.rhs==0)); //prevent memory leaks + asgn.lhs=l; + asgn.rhs=r; + } +public: + std::string write1HlIcode(Function *pProc, Int *numLoc); } ; /* LOW_LEVEL icode operand record */ struct LLOperand //: public llvm::MCOperand @@ -430,6 +502,10 @@ struct ICODE public: bool removeDefRegi(byte regi, Int thisDefIdx, LOCAL_ID *locId); void checkHlCall(); + bool newStkArg(COND_EXPR *exp, llIcode opcode, Function *pproc) + { + return ic.hl.call.newStkArg(exp,opcode,pproc); + } }; // This is the icode array object. diff --git a/src/BasicBlock.cpp b/src/BasicBlock.cpp index 4e5825c..12995c5 100644 --- a/src/BasicBlock.cpp +++ b/src/BasicBlock.cpp @@ -160,9 +160,14 @@ void BB::writeCode (Int indLevel, Function * pProc , Int *numLoc,Int latchNode, /* Condition needs to be inverted if the loop body is along * the THEN path of the header node */ if (edges[ELSE].BBptr->dfsLastNum == loopFollow) - inverseCondOp (&picode->ic.hl.oper.exp); { - string e=walkCondExpr (picode->ic.hl.oper.exp, pProc, numLoc); + COND_EXPR *old_expr=picode->ic.hl.expr(); + string e=walkCondExpr (old_expr, pProc, numLoc); + picode->ic.hl.expr(picode->ic.hl.expr()->inverse()); + delete old_expr; + } + { + string e=walkCondExpr (picode->ic.hl.expr(), pProc, numLoc); cCode.appendCode( "\n%swhile (%s) {\n", indent(indLevel),e.c_str()); } picode->invalidate(); @@ -228,7 +233,7 @@ void BB::writeCode (Int indLevel, Function * pProc , Int *numLoc,Int latchNode, if (picode->ic.hl.opcode != HLI_JCOND) reportError (REPEAT_FAIL); { - string e=walkCondExpr (picode->ic.hl.oper.exp, pProc, numLoc); + string e=walkCondExpr (picode->ic.hl.expr(), pProc, numLoc); cCode.appendCode( "%s} while (%s);\n", indent(indLevel),e.c_str()); } } @@ -327,9 +332,6 @@ void BB::writeCode (Int indLevel, Function * pProc , Int *numLoc,Int latchNode, * lev: indentation level - used for formatting. */ 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) */ front().codeIdx = nextBundleIdx (&cCode.code); @@ -342,10 +344,10 @@ void BB::writeBB(Int lev, Function * pProc, Int *numLoc) { if ((hli->type == HIGH_LEVEL) && (hli->invalid == FALSE)) { - line = write1HlIcode (hli->ic.hl, pProc, numLoc); - if (line[0] != '\0') + std::string line = hli->ic.hl.write1HlIcode(pProc, numLoc); + if (!line.empty()) { - cCode.appendCode( "%s%s", indent(lev), line); + cCode.appendCode( "%s%s", indent(lev), line.c_str()); stats.numHLIcode++; } if (option.verbose) diff --git a/src/ast.cpp b/src/ast.cpp index e81362d..54f6f49 100644 --- a/src/ast.cpp +++ b/src/ast.cpp @@ -578,7 +578,7 @@ hlType expType (const COND_EXPR *expr, Function * pproc) /* Removes the register from the tree. If the register was part of a long * register (eg. dx:ax), the node gets transformed into an integer register * node. */ -void removeRegFromLong (byte regi, LOCAL_ID *locId, COND_EXPR *tree) +void HlTypeSupport::performLongRemoval (byte regi, LOCAL_ID *locId, COND_EXPR *tree) { IDENTTYPE* ident; /* ptr to an identifier */ byte otherRegi; /* high or low part of long register */ @@ -621,7 +621,6 @@ static std::string getString (Int offset) /* Walks the conditional expression tree and returns the result on a string */ -// TODO: use string stream here string walkCondExpr (const COND_EXPR* expr, Function * pProc, Int* numLoc) { int16 off; /* temporal - for OTHER */ diff --git a/src/control.cpp b/src/control.cpp index 59e47c8..27b64d7 100644 --- a/src/control.cpp +++ b/src/control.cpp @@ -526,9 +526,7 @@ void Function::compoundCond() /* Construct compound DBL_OR expression */ picode = &pbb->back(); ticode = &t->back(); - exp = COND_EXPR::boolOp (picode->ic.hl.oper.exp, - ticode->ic.hl.oper.exp, DBL_OR); - picode->ic.hl.oper.exp = exp; + picode->ic.hl.expr(COND_EXPR::boolOp (picode->ic.hl.expr(), ticode->ic.hl.expr(), DBL_OR)); /* Replace in-edge to obb from t to pbb */ { @@ -564,10 +562,11 @@ void Function::compoundCond() picode = &pbb->back(); ticode = &t->back(); - inverseCondOp (&picode->ic.hl.oper.exp); - exp = COND_EXPR::boolOp (picode->ic.hl.oper.exp, - ticode->ic.hl.oper.exp, DBL_AND); - picode->ic.hl.oper.exp = exp; + COND_EXPR *oldexpr=picode->ic.hl.expr(); + picode->ic.hl.expr(picode->ic.hl.expr()->inverse()); + delete oldexpr; + + picode->ic.hl.expr(COND_EXPR::boolOp (picode->ic.hl.expr(), ticode->ic.hl.expr(), DBL_AND)); /* Replace in-edge to obb from t to pbb */ auto iter=std::find(obb->inEdges.begin(),obb->inEdges.end(),t); @@ -601,10 +600,7 @@ void Function::compoundCond() /* Construct compound DBL_AND expression */ picode = &pbb->back(); ticode = &t->back(); - - exp = COND_EXPR::boolOp (picode->ic.hl.oper.exp, - ticode->ic.hl.oper.exp, DBL_AND); - picode->ic.hl.oper.exp = exp; + picode->ic.hl.expr(COND_EXPR::boolOp (picode->ic.hl.expr(),ticode->ic.hl.expr(), DBL_AND)); /* Replace in-edge to obb from e to pbb */ auto iter = std::find(obb->inEdges.begin(),obb->inEdges.end(),e); @@ -636,10 +632,11 @@ void Function::compoundCond() /* Construct compound DBL_OR expression */ picode = &pbb->back(); ticode = &t->back(); - inverseCondOp (&picode->ic.hl.oper.exp); - exp = COND_EXPR::boolOp (picode->ic.hl.oper.exp, - ticode->ic.hl.oper.exp, DBL_OR); - picode->ic.hl.oper.exp = exp; + COND_EXPR *oldexp=picode->ic.hl.expr(); + picode->ic.hl.expr(picode->ic.hl.expr()->inverse()); + delete oldexp; + picode->ic.hl.expr(COND_EXPR::boolOp (picode->ic.hl.expr(), ticode->ic.hl.expr(), DBL_OR)); + //picode->ic.hl.expr() = exp; /* Replace in-edge to obb from e to pbb */ auto iter = std::find(obb->inEdges.begin(),obb->inEdges.end(),e); diff --git a/src/dataflow.cpp b/src/dataflow.cpp index 39839f4..cbe3bea 100644 --- a/src/dataflow.cpp +++ b/src/dataflow.cpp @@ -151,7 +151,7 @@ void Function::elimCondCodes () break; case iOR: - lhs = defAt->ic.hl.oper.asgn.lhs->clone(); + lhs = defAt->ic.hl.asgn.lhs->clone(); useAt->copyDU(*defAt, eUSE, eDEF); if (defAt->isLlFlag(B)) rhs = COND_EXPR::idKte (0, 1); @@ -205,7 +205,7 @@ void Function::elimCondCodes () ICODE & prev(pBB->back()); /* For extended basic blocks - previous icode inst */ if (prev.ic.hl.opcode == HLI_JCOND) { - exp = prev.ic.hl.oper.exp->clone(); + exp = prev.ic.hl.expr()->clone(); exp->changeBoolOp (condOpJCond[useAt->GetLlOpcode()-iJB]); useAt->copyDU(prev, eUSE, eUSE); useAt->setJCond(exp); @@ -302,8 +302,7 @@ void Function::liveRegAnalysis (std::bitset<32> &in_liveOut) if (picode->ic.hl.opcode == HLI_RET) { //pbb->back().loc_ip - picode->ic.hl.oper.exp = COND_EXPR::idID (&retVal, &localId, - (++pbb->rbegin2()).base()); + picode->ic.hl.expr(COND_EXPR::idID (&retVal, &localId, (++pbb->rbegin2()).base())); picode->du.use = in_liveOut; } } @@ -317,7 +316,7 @@ void Function::liveRegAnalysis (std::bitset<32> &in_liveOut) if (pbb->nodeType == CALL_NODE) { ICODE &ticode(pbb->back()); - pcallee = ticode.ic.hl.oper.call.proc; + pcallee = ticode.ic.hl.call.proc; /* user/runtime routine */ if (! (pcallee->flg & PROC_ISLIB)) @@ -449,7 +448,7 @@ void BB::genDU1() * next basic block (unoptimized code) or somewhere else * on optimized code. */ if ((picode->ic.hl.opcode == HLI_CALL) && - (picode->ic.hl.oper.call.proc->flg & PROC_IS_FUNC)) + (picode->ic.hl.call.proc->flg & PROC_IS_FUNC)) { tbb = this->edges[0].BBptr; for (ticode = tbb->begin2(); ticode != tbb->end2(); ticode++) @@ -480,7 +479,7 @@ void BB::genDU1() if (picode->valid() and not picode->du1.used(defRegIdx) and (not (picode->du.lastDefRegi & duReg[regi]).any()) && (not ((picode->ic.hl.opcode == HLI_CALL) && - (picode->ic.hl.oper.call.proc->flg & PROC_ISLIB)))) + (picode->ic.hl.call.proc->flg & PROC_ISLIB)))) { if (! (this->liveOut & duReg[regi]).any()) /* not liveOut */ { @@ -542,7 +541,7 @@ static void forwardSubs (COND_EXPR *lhs, COND_EXPR *rhs, iICODE picode, return; /* Insert on rhs of ticode, if possible */ - res = insertSubTreeReg (rhs, &ticode->ic.hl.oper.asgn.rhs, + res = insertSubTreeReg (rhs, &ticode->ic.hl.asgn.rhs, locsym->id_arr[lhs->expr.ident.idNode.regiIdx].id.regi, locsym); if (res) @@ -553,7 +552,7 @@ static void forwardSubs (COND_EXPR *lhs, COND_EXPR *rhs, iICODE picode, else { /* Try to insert it on lhs of ticode*/ - res = insertSubTreeReg (rhs, &ticode->ic.hl.oper.asgn.lhs, + res = insertSubTreeReg (rhs, &ticode->ic.hl.asgn.lhs, locsym->id_arr[lhs->expr.ident.idNode.regiIdx].id.regi, locsym); if (res) @@ -567,8 +566,8 @@ static void forwardSubs (COND_EXPR *lhs, COND_EXPR *rhs, iICODE picode, /* Substitutes the rhs (or lhs if rhs not possible) of ticode for the * expression exp given */ -static void forwardSubsLong (Int longIdx, COND_EXPR *exp, ICODE * picode, - ICODE * ticode, Int *numHlIcodes) +static void forwardSubsLong (Int longIdx, COND_EXPR *exp, iICODE picode, + iICODE ticode, Int *numHlIcodes) { bool res; @@ -576,7 +575,7 @@ static void forwardSubsLong (Int longIdx, COND_EXPR *exp, ICODE * picode, return; /* Insert on rhs of ticode, if possible */ - res = insertSubTreeLongReg (exp, &ticode->ic.hl.oper.asgn.rhs, longIdx); + res = insertSubTreeLongReg (exp, &ticode->ic.hl.asgn.rhs, longIdx); if (res) { picode->invalidate(); @@ -585,7 +584,7 @@ static void forwardSubsLong (Int longIdx, COND_EXPR *exp, ICODE * picode, else { /* Try to insert it on lhs of ticode*/ - res = insertSubTreeLongReg (exp, &ticode->ic.hl.oper.asgn.lhs, longIdx); + res = insertSubTreeLongReg (exp, &ticode->ic.hl.asgn.lhs, longIdx); if (res) { picode->invalidate(); @@ -666,13 +665,13 @@ static void processCArg (Function * pp, Function * pProc, ICODE * picode, Int nu } else adjustActArgType (exp, pp->args.sym[numArgs].type, pProc); - res = newStkArg (picode, exp, picode->ic.ll.opcode, pProc); + res = picode->newStkArg (exp, picode->ic.ll.opcode, pProc); } else /* user function */ { if (pp->args.numArgs > 0) pp->args.adjustForArgType (numArgs, expType (exp, pProc)); - res = newStkArg (picode, exp, picode->ic.ll.opcode, pProc); + res = picode->newStkArg (exp, picode->ic.ll.opcode, pProc); } /* Do not update the size of k if the expression was a segment register @@ -738,22 +737,22 @@ void Function::findExps() (ticode->ic.hl.opcode != HLI_RET))) continue; - if (xClear (picode->ic.hl.oper.asgn.rhs, picode, + if (xClear (picode->ic.hl.asgn.rhs, picode, picode->du1.idx[0].uses[0], lastInst, this)) { switch (ticode->ic.hl.opcode) { case HLI_ASSIGN: - forwardSubs (picode->ic.hl.oper.asgn.lhs, - picode->ic.hl.oper.asgn.rhs, + forwardSubs (picode->ic.hl.asgn.lhs, + picode->ic.hl.asgn.rhs, picode, ticode, &localId, numHlIcodes); break; case HLI_JCOND: case HLI_PUSH: case HLI_RET: res = insertSubTreeReg ( - picode->ic.hl.oper.asgn.rhs, - &ticode->ic.hl.oper.exp, - localId.id_arr[picode->ic.hl.oper.asgn.lhs->expr.ident.idNode.regiIdx].id.regi, + picode->ic.hl.asgn.rhs, + &ticode->ic.hl.exp.v, + localId.id_arr[picode->ic.hl.asgn.lhs->expr.ident.idNode.regiIdx].id.regi, &localId); if (res) { @@ -781,15 +780,15 @@ void Function::findExps() exp = g_exp_stk.pop(); /* pop last exp pushed */ switch (ticode->ic.hl.opcode) { case HLI_ASSIGN: - forwardSubs (picode->ic.hl.oper.exp, exp, + forwardSubs (picode->ic.hl.expr(), exp, picode, ticode, &localId, numHlIcodes); break; case HLI_JCOND: case HLI_PUSH: case HLI_RET: res = insertSubTreeReg (exp, - &ticode->ic.hl.oper.exp, - localId.id_arr[picode->ic.hl.oper.exp->expr.ident.idNode.regiIdx].id.regi, + &ticode->ic.hl.exp.v, + localId.id_arr[picode->ic.hl.expr()->expr.ident.idNode.regiIdx].id.regi, &localId); if (res) { @@ -811,16 +810,16 @@ void Function::findExps() switch (ticode->ic.hl.opcode) { case HLI_ASSIGN: exp = COND_EXPR::idFunc ( - picode->ic.hl.oper.call.proc, - picode->ic.hl.oper.call.args); + picode->ic.hl.call.proc, + picode->ic.hl.call.args); res = insertSubTreeReg (exp, - &ticode->ic.hl.oper.asgn.rhs, - picode->ic.hl.oper.call.proc->retVal.id.regi, + &ticode->ic.hl.asgn.rhs, + picode->ic.hl.call.proc->retVal.id.regi, &localId); if (! res) insertSubTreeReg (exp, - &ticode->ic.hl.oper.asgn.lhs, - picode->ic.hl.oper.call.proc->retVal.id.regi, + &ticode->ic.hl.asgn.lhs, + picode->ic.hl.call.proc->retVal.id.regi, &localId); /*** TODO: HERE missing: 2 regs ****/ picode->invalidate(); @@ -828,21 +827,16 @@ void Function::findExps() break; case HLI_PUSH: case HLI_RET: - exp = COND_EXPR::idFunc ( - picode->ic.hl.oper.call.proc, - picode->ic.hl.oper.call.args); - ticode->ic.hl.oper.exp = exp; + ticode->ic.hl.expr( COND_EXPR::idFunc ( picode->ic.hl.call.proc, picode->ic.hl.call.args) ); picode->invalidate(); numHlIcodes--; break; case HLI_JCOND: - exp = COND_EXPR::idFunc ( - picode->ic.hl.oper.call.proc, - picode->ic.hl.oper.call.args); - retVal = &picode->ic.hl.oper.call.proc->retVal, + exp = COND_EXPR::idFunc ( picode->ic.hl.call.proc, picode->ic.hl.call.args); + retVal = &picode->ic.hl.call.proc->retVal, res = insertSubTreeReg (exp, - &ticode->ic.hl.oper.exp, + &ticode->ic.hl.exp.v, retVal->id.regi, &localId); if (res) /* was substituted */ { @@ -881,16 +875,16 @@ void Function::findExps() switch (ticode->ic.hl.opcode) { case HLI_ASSIGN: - forwardSubsLong (picode->ic.hl.oper.asgn.lhs->expr.ident.idNode.longIdx, - picode->ic.hl.oper.asgn.rhs, &(*picode), - &(*ticode), &numHlIcodes); + forwardSubsLong (picode->ic.hl.asgn.lhs->expr.ident.idNode.longIdx, + picode->ic.hl.asgn.rhs, picode,ticode, + &numHlIcodes); break; case HLI_JCOND: case HLI_PUSH: case HLI_RET: res = insertSubTreeLongReg ( - picode->ic.hl.oper.asgn.rhs, - &ticode->ic.hl.oper.exp, - picode->ic.hl.oper.asgn.lhs->expr.ident.idNode.longIdx); + picode->ic.hl.asgn.rhs, + &ticode->ic.hl.exp.v, + picode->ic.hl.asgn.lhs->expr.ident.idNode.longIdx); if (res) { picode->invalidate(); @@ -919,13 +913,13 @@ void Function::findExps() exp = g_exp_stk.pop(); /* pop last exp pushed */ switch (ticode->ic.hl.opcode) { case HLI_ASSIGN: - forwardSubsLong (picode->ic.hl.oper.exp->expr.ident.idNode.longIdx, - exp, &(*picode), &(*ticode), &numHlIcodes); + forwardSubsLong (picode->ic.hl.expr()->expr.ident.idNode.longIdx, + exp, picode, ticode, &numHlIcodes); break; case HLI_JCOND: case HLI_PUSH: res = insertSubTreeLongReg (exp, - &ticode->ic.hl.oper.exp, - picode->ic.hl.oper.asgn.lhs->expr.ident.idNode.longIdx); + &ticode->ic.hl.exp.v, + picode->ic.hl.asgn.lhs->expr.ident.idNode.longIdx); if (res) { picode->invalidate(); @@ -944,35 +938,28 @@ void Function::findExps() { case HLI_ASSIGN: exp = COND_EXPR::idFunc ( - picode->ic.hl.oper.call.proc, - picode->ic.hl.oper.call.args); - ticode->ic.hl.oper.asgn.lhs = + picode->ic.hl.call.proc, + picode->ic.hl.call.args); + ticode->ic.hl.asgn.lhs = COND_EXPR::idLong(&localId, DST, ticode,HIGH_FIRST, picode, eDEF, 1); - ticode->ic.hl.oper.asgn.rhs = exp; + ticode->ic.hl.asgn.rhs = exp; picode->invalidate(); numHlIcodes--; break; case HLI_PUSH: case HLI_RET: - exp = COND_EXPR::idFunc ( - picode->ic.hl.oper.call.proc, - picode->ic.hl.oper.call.args); - ticode->ic.hl.oper.exp = exp; + ticode->ic.hl.expr( COND_EXPR::idFunc ( picode->ic.hl.call.proc, picode->ic.hl.call.args) ); picode->invalidate(); numHlIcodes--; break; case HLI_JCOND: - exp = COND_EXPR::idFunc ( - picode->ic.hl.oper.call.proc, - picode->ic.hl.oper.call.args); - retVal = &picode->ic.hl.oper.call.proc->retVal; + exp = COND_EXPR::idFunc ( picode->ic.hl.call.proc, picode->ic.hl.call.args); + retVal = &picode->ic.hl.call.proc->retVal; res = insertSubTreeLongReg (exp, - &ticode->ic.hl.oper.exp, - localId.newLongReg - ( - retVal->type, retVal->id.longId.h, - retVal->id.longId.l, picode/*picode->loc_ip*/)); + &ticode->ic.hl.exp.v, + localId.newLongReg ( retVal->type, retVal->id.longId.h, + retVal->id.longId.l, picode)); if (res) /* was substituted */ { picode->invalidate(); @@ -994,7 +981,7 @@ void Function::findExps() * expression stack */ else if (picode->ic.hl.opcode == HLI_PUSH) { - g_exp_stk.push(picode->ic.hl.oper.exp); + g_exp_stk.push(picode->ic.hl.expr()); picode->invalidate(); numHlIcodes--; } @@ -1003,12 +990,12 @@ void Function::findExps() * pop them from the expression stack and place them on the * procedure's argument list */ if ((picode->ic.hl.opcode == HLI_CALL) && - ! (picode->ic.hl.oper.call.proc->flg & REG_ARGS)) + ! (picode->ic.hl.call.proc->flg & REG_ARGS)) { Function * pp; Int cb, numArgs; boolT res; - pp = picode->ic.hl.oper.call.proc; + pp = picode->ic.hl.call.proc; if (pp->flg & CALL_PASCAL) { cb = pp->cbParam; /* fixed # arguments */ @@ -1019,13 +1006,13 @@ void Function::findExps() { if (pp->args.numArgs > 0) adjustActArgType(exp, pp->args.sym[numArgs].type, this); - res = newStkArg (&(*picode), exp, picode->ic.ll.opcode, this); + res = picode->newStkArg (exp, picode->ic.ll.opcode, this); } else /* user function */ { if (pp->args.numArgs >0) pp->args.adjustForArgType (numArgs,expType (exp, this)); - res = newStkArg (&(*picode), exp,picode->ic.ll.opcode, this); + res = picode->newStkArg (exp,picode->ic.ll.opcode, this); } if (res == FALSE) k += hlTypeSize (exp, this); @@ -1033,7 +1020,7 @@ void Function::findExps() } else /* CALL_C */ { - cb = picode->ic.hl.oper.call.args->cb; + cb = picode->ic.hl.call.args->cb; numArgs = 0; if (cb) for (k = 0; k < cb; numArgs++) @@ -1050,12 +1037,12 @@ void Function::findExps() /* If we could not substitute the result of a function, * assign it to the corresponding registers */ if ((picode->ic.hl.opcode == HLI_CALL) && - ((picode->ic.hl.oper.call.proc->flg & PROC_ISLIB) != + ((picode->ic.hl.call.proc->flg & PROC_ISLIB) != PROC_ISLIB) && (not picode->du1.used(0)) && (picode->du1.numRegsDef > 0)) { - exp = COND_EXPR::idFunc (picode->ic.hl.oper.call.proc, picode->ic.hl.oper.call.args); - lhs = COND_EXPR::idID (&picode->ic.hl.oper.call.proc->retVal, &localId, picode); + exp = COND_EXPR::idFunc (picode->ic.hl.call.proc, picode->ic.hl.call.args); + lhs = COND_EXPR::idID (&picode->ic.hl.call.proc->retVal, &localId, picode); picode->setAsgn(lhs, exp); } } diff --git a/src/hlicode.cpp b/src/hlicode.cpp index 081e42e..b6efb42 100644 --- a/src/hlicode.cpp +++ b/src/hlicode.cpp @@ -31,11 +31,8 @@ static char buf[lineSize]; /* Line buffer for hl icode output */ void ICODE::setAsgn(COND_EXPR *lhs, COND_EXPR *rhs) { type = HIGH_LEVEL; - ic.hl.opcode = HLI_ASSIGN; - assert(ic.hl.oper.asgn.lhs==0); //prevent memory leaks - assert(ic.hl.oper.asgn.rhs==0); //prevent memory leaks - ic.hl.oper.asgn.lhs = lhs; - ic.hl.oper.asgn.rhs = rhs; + ic.hl.set(lhs,rhs); + } void ICODE::checkHlCall() { @@ -46,17 +43,17 @@ void ICODE::newCallHl() { type = HIGH_LEVEL; ic.hl.opcode = HLI_CALL; - ic.hl.oper.call.proc = ic.ll.src.proc.proc; - ic.hl.oper.call.args = new STKFRAME; + ic.hl.call.proc = ic.ll.src.proc.proc; + ic.hl.call.args = new STKFRAME; if (ic.ll.src.proc.cb != 0) - ic.hl.oper.call.args->cb = ic.ll.src.proc.cb; - else if(ic.hl.oper.call.proc) - ic.hl.oper.call.args->cb =ic.hl.oper.call.proc->cbParam; + ic.hl.call.args->cb = ic.ll.src.proc.cb; + else if(ic.hl.call.proc) + ic.hl.call.args->cb =ic.hl.call.proc->cbParam; else { printf("Function with no cb set, and no valid oper.call.proc , probaby indirect call\n"); - ic.hl.oper.call.args->cb = 0; + ic.hl.call.args->cb = 0; } } @@ -65,20 +62,16 @@ void ICODE::newCallHl() * array */ void ICODE::setUnary(hlIcode op, COND_EXPR *exp) { - assert(ic.hl.oper.exp==0); type = HIGH_LEVEL; - ic.hl.opcode = op; - ic.hl.oper.exp = exp; + ic.hl.set(op,exp); } /* Places the new HLI_JCOND high-level operand in the high-level icode array */ void ICODE::setJCond(COND_EXPR *cexp) { - assert(ic.hl.oper.exp==0); type = HIGH_LEVEL; - ic.hl.opcode = HLI_JCOND; - ic.hl.oper.exp = cexp; + ic.hl.set(HLI_JCOND,cexp); } @@ -123,19 +116,11 @@ bool ICODE::removeDefRegi (byte regi, Int thisDefIdx, LOCAL_ID *locId) invalidate(); return true; } - switch (ic.hl.opcode) + HlTypeSupport *p=ic.hl.get(); + if(p and p->removeRegFromLong(regi,locId)) { - case HLI_ASSIGN: - removeRegFromLong (regi, locId,ic.hl.oper.asgn.lhs); - du1.numRegsDef--; - du.def &= maskDuReg[regi]; - break; - case HLI_POP: - case HLI_PUSH: - removeRegFromLong (regi, locId, ic.hl.oper.exp); - du1.numRegsDef--; - du.def &= maskDuReg[regi]; - break; + du1.numRegsDef--; + du.def &= maskDuReg[regi]; } return false; } @@ -307,44 +292,44 @@ void Function::highLevelGen() /* Modifies the given conditional operator to its inverse. This is used * in if..then[..else] statements, to reflect the condition that takes the * then part. */ -void inverseCondOp (COND_EXPR **exp) +COND_EXPR *COND_EXPR::inverse () { static condOp invCondOp[] = {GREATER, GREATER_EQUAL, NOT_EQUAL, EQUAL, LESS_EQUAL, LESS, DUMMY,DUMMY,DUMMY,DUMMY, DUMMY, DUMMY, DUMMY, DUMMY, DUMMY, DUMMY, DUMMY, DBL_OR, DBL_AND}; - if (*exp == NULL) - return; - - if ((*exp)->type == BOOLEAN_OP) + COND_EXPR *res=0; + if (type == BOOLEAN_OP) { - switch ((*exp)->expr.boolExpr.op) + switch (expr.boolExpr.op) { case LESS_EQUAL: case LESS: case EQUAL: case NOT_EQUAL: case GREATER: case GREATER_EQUAL: - (*exp)->expr.boolExpr.op = invCondOp[(*exp)->expr.boolExpr.op]; - break; + res = this->clone(); + res->expr.boolExpr.op = invCondOp[expr.boolExpr.op]; + return res; case AND: case OR: case XOR: case NOT: case ADD: case SUB: case MUL: case DIV: case SHR: case SHL: case MOD: - *exp = COND_EXPR::unary (NEGATION, *exp); - break; + return COND_EXPR::unary (NEGATION, this->clone()); case DBL_AND: case DBL_OR: - (*exp)->expr.boolExpr.op = invCondOp[(*exp)->expr.boolExpr.op]; - inverseCondOp (&(*exp)->expr.boolExpr.lhs); - inverseCondOp (&(*exp)->expr.boolExpr.rhs); - break; + res = this->clone(); + res->expr.boolExpr.op = invCondOp[expr.boolExpr.op]; + res->expr.boolExpr.lhs=expr.boolExpr.lhs->inverse (); + res->expr.boolExpr.rhs=expr.boolExpr.rhs->inverse (); + return res; } /* eos */ } - else if ((*exp)->type == NEGATION) //TODO: memleak here - *exp = (*exp)->expr.unaryExp; - + else if (type == NEGATION) //TODO: memleak here + { + return expr.unaryExp->clone(); + } + return this->clone(); /* other types are left unmodified */ } - /* Returns the string that represents the procedure call of tproc (ie. with * actual parameters) */ std::string writeCall (Function * tproc, STKFRAME * args, Function * pproc, Int *numLoc) @@ -370,8 +355,10 @@ char *writeJcond (HLTYPE h, Function * pProc, Int *numLoc) memset (buf, ' ', sizeof(buf)); buf[0] = '\0'; strcat (buf, "if "); - inverseCondOp (&h.oper.exp); - std::string e = walkCondExpr (h.oper.exp, pProc, numLoc); + COND_EXPR *inverted=h.expr()->inverse(); + //inverseCondOp (&h.exp); + std::string e = walkCondExpr (inverted, pProc, numLoc); + delete inverted; strcat (buf, e.c_str()); strcat (buf, " {\n"); return (buf); @@ -386,60 +373,65 @@ char *writeJcondInv (HLTYPE h, Function * pProc, Int *numLoc) memset (buf, ' ', sizeof(buf)); buf[0] = '\0'; strcat (buf, "if "); - std::string e = walkCondExpr (h.oper.exp, pProc, numLoc); + std::string e = walkCondExpr (h.expr(), pProc, numLoc); strcat (buf, e.c_str()); strcat (buf, " {\n"); return (buf); } +string AssignType::writeOut(Function *pProc, Int *numLoc) +{ + ostringstream ostr; + ostr << walkCondExpr (lhs, pProc, numLoc); + ostr << " = "; + ostr << walkCondExpr (rhs, pProc, numLoc); + ostr << ";\n"; + return ostr.str(); +} +string CallType::writeOut(Function *pProc, Int *numLoc) +{ + ostringstream ostr; + ostr << writeCall (proc, args, pProc,numLoc); + ostr << ";\n"; + return ostr.str(); +} +string ExpType::writeOut(Function *pProc, Int *numLoc) +{ + return walkCondExpr (v, pProc, numLoc); +} /* Returns a string with the contents of the current high-level icode. * Note: this routine does not output the contens of HLI_JCOND icodes. This is * done in a separate routine to be able to support the removal of * empty THEN clauses on an if..then..else. */ -char *write1HlIcode (HLTYPE h, Function * pProc, Int *numLoc) +string HLTYPE::write1HlIcode (Function * pProc, Int *numLoc) { - std::string e; - - memset (buf, ' ', sizeof(buf)); - buf[0] = '\0'; - switch (h.opcode) { + string e; + ostringstream ostr; + HlTypeSupport *p = get(); + switch (opcode) + { case HLI_ASSIGN: - e = walkCondExpr (h.oper.asgn.lhs, pProc, numLoc); - strcat (buf, e.c_str()); - strcat (buf, " = "); - e = walkCondExpr (h.oper.asgn.rhs, pProc, numLoc); - strcat (buf, e.c_str()); - strcat (buf, ";\n"); - break; + return p->writeOut(pProc,numLoc); case HLI_CALL: - e = writeCall (h.oper.call.proc, h.oper.call.args, pProc, - numLoc); - strcat (buf, e.c_str()); - strcat (buf, ";\n"); - break; + return p->writeOut(pProc,numLoc); case HLI_RET: - e = walkCondExpr (h.oper.exp, pProc, numLoc); + e = p->writeOut(pProc,numLoc); if (! e.empty()) - { - strcat (buf, "return ("); - strcat (buf, e.c_str()); - strcat (buf, ");\n"); - } + ostr << "return (" << e << ");\n"; break; case HLI_POP: - strcat (buf, "HLI_POP "); - e = walkCondExpr (h.oper.exp, pProc, numLoc); - strcat (buf, e.c_str()); - strcat (buf, "\n"); + ostr << "HLI_POP "; + ostr << p->writeOut(pProc,numLoc); + ostr << "\n"; break; - case HLI_PUSH: strcat (buf, "HLI_PUSH "); - e = walkCondExpr (h.oper.exp, pProc, numLoc); - strcat (buf, e.c_str()); - strcat (buf, "\n"); + case HLI_PUSH: + ostr << "HLI_PUSH "; + ostr << p->writeOut(pProc,numLoc); + ostr << "\n"; break; } - return (buf); + return ostr.str(); } @@ -502,32 +494,10 @@ void ICODE::writeDU(Int idx) /* For HLI_CALL, print # parameter bytes */ if (ic.hl.opcode == HLI_CALL) - printf ("# param bytes = %d\n", ic.hl.oper.call.args->cb); + printf ("# param bytes = %d\n", ic.hl.call.args->cb); printf ("\n"); } -/* Frees the storage allocated to h->hlIcode */ -void freeHlIcode (ICODE * icode, Int numIcodes) -{ - Int i; - HLTYPE h; - for (i = 0; i < numIcodes; i++) - { - h = icode[i].ic.hl; - switch (h.opcode) - { - case HLI_ASSIGN: - h.oper.asgn.lhs->release(); - h.oper.asgn.rhs->release(); - break; - case HLI_POP: - case HLI_PUSH: - case HLI_JCOND: - h.oper.exp->release(); - break; - } - } -} diff --git a/src/parser.cpp b/src/parser.cpp index 416a457..d5173be 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -12,15 +12,10 @@ #include "dcc.h" using namespace std; static void FollowCtrl (Function * pProc, CALL_GRAPH * pcallGraph, STATE * pstate); -static boolT process_JMP (ICODE * pIcode, STATE * pstate, - CALL_GRAPH * pcallGraph); -static boolT process_CALL(ICODE * pIcode, CALL_GRAPH * pcallGraph, - STATE * pstate); -static void process_operands(ICODE * pIcode, Function * pProc, STATE * pstate, - Int ix); +static boolT process_JMP (ICODE * pIcode, STATE * pstate, CALL_GRAPH * pcallGraph); static void setBits(int16 type, dword start, dword len); static SYM * updateGlobSym(dword operand, Int size, word duFlag); -static void process_MOV(ICODE * pIcode, STATE * pstate); +static void process_MOV(ICODE & pIcode, STATE * pstate); static SYM * lookupAddr (LLOperand *pm, STATE * pstate, Int size, word duFlag); void interactDis(Function * initProc, Int ic); static dword SynthLab; @@ -122,7 +117,6 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate) dword offset; eErrorId err; boolT done = FALSE; - dword lab; if (name.find("chkstk") != string::npos) { @@ -139,12 +133,12 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate) printf("Parsing proc %s at %lX\n", name.c_str(), pstate->IP); } - while (! done && ! (err = scan(pstate->IP, &_Icode))) + while (! done && ! (err = scan(pstate->IP, _Icode))) { pstate->IP += (dword)_Icode.ic.ll.numBytes; setBits(BM_CODE, _Icode.ic.ll.label, (dword)_Icode.ic.ll.numBytes); - process_operands(&_Icode,pstate); + process_operands(_Icode,pstate); /* Keep track of interesting instruction flags in procedure */ flg |= (_Icode.ic.ll.flg & (NOT_HLL | FLOAT_OP)); @@ -281,13 +275,13 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate) /*** Jumps ***/ case iJMP: case iJMPF: /* Returns TRUE if we've run into a loop */ - done = process_JMP (pIcode, pstate, pcallGraph); + done = process_JMP (*pIcode, pstate, pcallGraph); break; /*** Calls ***/ case iCALL: case iCALLF: - done = process_CALL (pIcode, pcallGraph, pstate); + done = process_CALL (*pIcode, pcallGraph, pstate); break; /*** Returns ***/ @@ -339,7 +333,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate) break; case iMOV: - process_MOV(pIcode, pstate); + process_MOV(*pIcode, pstate); break; /* case iXCHG: @@ -390,7 +384,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate) /* process_JMP - Handles JMPs, returns TRUE if we should end recursion */ -boolT Function::process_JMP (ICODE * pIcode, STATE *pstate, CALL_GRAPH * pcallGraph) +boolT Function::process_JMP (ICODE & pIcode, STATE *pstate, CALL_GRAPH * pcallGraph) { static byte i2r[4] = {rSI, rDI, rBP, rBX}; ICODE _Icode; @@ -398,11 +392,11 @@ boolT Function::process_JMP (ICODE * pIcode, STATE *pstate, CALL_GRAPH * pcallGr dword i, k, seg, target; dword tmp; - if (pIcode->ic.ll.flg & I) + if (pIcode.ic.ll.flg & I) { - if (pIcode->ic.ll.opcode == iJMPF) - pstate->setState( rCS, LH(prog.Image + pIcode->ic.ll.label + 3)); - i = pstate->IP = pIcode->ic.ll.src.op(); + if (pIcode.ic.ll.opcode == iJMPF) + pstate->setState( rCS, LH(prog.Image + pIcode.ic.ll.label + 3)); + i = pstate->IP = pIcode.ic.ll.src.op(); if ((long)i < 0) { exit(1); @@ -414,17 +408,17 @@ boolT Function::process_JMP (ICODE * pIcode, STATE *pstate, CALL_GRAPH * pcallGr /* We've got an indirect JMP - look for switch() stmt. idiom of the form * JMP word ptr word_offset[rBX | rSI | rDI] */ - seg = (pIcode->ic.ll.src.seg)? pIcode->ic.ll.src.seg: rDS; + seg = (pIcode.ic.ll.src.seg)? pIcode.ic.ll.src.seg: rDS; /* Ensure we have a word offset & valid seg */ - if (pIcode->ic.ll.opcode == iJMP && (pIcode->ic.ll.flg & WORD_OFF) && + if (pIcode.ic.ll.opcode == iJMP && (pIcode.ic.ll.flg & WORD_OFF) && pstate->f[seg] && - (pIcode->ic.ll.src.regi == INDEXBASE + 4 || - pIcode->ic.ll.src.regi == INDEXBASE + 5 || /* Idx reg. BX, SI, DI */ - pIcode->ic.ll.src.regi == INDEXBASE + 7)) + (pIcode.ic.ll.src.regi == INDEXBASE + 4 || + pIcode.ic.ll.src.regi == INDEXBASE + 5 || /* Idx reg. BX, SI, DI */ + pIcode.ic.ll.src.regi == INDEXBASE + 7)) { - offTable = ((dword)(word)pstate->r[seg] << 4) + pIcode->ic.ll.src.off; + offTable = ((dword)(word)pstate->r[seg] << 4) + pIcode.ic.ll.src.off; /* Firstly look for a leading range check of the form:- * CMP {BX | SI | DI}, immed @@ -432,7 +426,7 @@ boolT Function::process_JMP (ICODE * pIcode, STATE *pstate, CALL_GRAPH * pcallGr * This is stored in the current state as if we had just * followed a JBE branch (i.e. [reg] lies between 0 - immed). */ - if (pstate->JCond.regi == i2r[pIcode->ic.ll.src.regi-(INDEXBASE+4)]) + if (pstate->JCond.regi == i2r[pIcode.ic.ll.src.regi-(INDEXBASE+4)]) endTable = offTable + pstate->JCond.immed; else endTable = (dword)prog.cbImage; @@ -461,7 +455,7 @@ boolT Function::process_JMP (ICODE * pIcode, STATE *pstate, CALL_GRAPH * pcallGr target = cs + LH(&prog.Image[i]); /* Be wary of 00 00 as code - it's probably data */ if (! (prog.Image[target] || prog.Image[target+1]) || - scan(target, &_Icode)) + scan(target, _Icode)) endTable = i; } @@ -475,10 +469,10 @@ boolT Function::process_JMP (ICODE * pIcode, STATE *pstate, CALL_GRAPH * pcallGr setBits(BM_DATA, offTable, endTable - offTable); - pIcode->ic.ll.flg |= SWITCH; - pIcode->ic.ll.caseTbl.numEntries = (endTable - offTable) / 2; - psw = (dword*)allocMem(pIcode->ic.ll.caseTbl.numEntries*sizeof(dword)); - pIcode->ic.ll.caseTbl.entries = psw; + pIcode.ic.ll.flg |= SWITCH; + pIcode.ic.ll.caseTbl.numEntries = (endTable - offTable) / 2; + psw = (dword*)allocMem(pIcode.ic.ll.caseTbl.numEntries*sizeof(dword)); + pIcode.ic.ll.caseTbl.entries = psw; for (i = offTable, k = 0; i < endTable; i += 2) { @@ -516,7 +510,7 @@ boolT Function::process_JMP (ICODE * pIcode, STATE *pstate, CALL_GRAPH * pcallGr * programmer expected it to come back - otherwise surely a JMP would * have been used. */ -boolT Function::process_CALL (ICODE * pIcode, CALL_GRAPH * pcallGraph, STATE *pstate) +boolT Function::process_CALL (ICODE & pIcode, CALL_GRAPH * pcallGraph, STATE *pstate) { ICODE &last_insn(Icode.back()); STATE localState; /* Local copy of the machine state */ @@ -525,12 +519,12 @@ boolT Function::process_CALL (ICODE * pIcode, CALL_GRAPH * pcallGraph, STATE *ps /* For Indirect Calls, find the function address */ indirect = FALSE; - //pIcode->ic.ll.immed.proc.proc=fakeproc; - if ( not pIcode->isLlFlag(I) ) + //pIcode.ic.ll.immed.proc.proc=fakeproc; + if ( not pIcode.isLlFlag(I) ) { /* Not immediate, i.e. indirect call */ - if (pIcode->ic.ll.dst.regi && (!option.Calls)) + if (pIcode.ic.ll.dst.regi && (!option.Calls)) { /* We have not set the brave option to attempt to follow the execution path through register indirect calls. @@ -546,28 +540,28 @@ boolT Function::process_CALL (ICODE * pIcode, CALL_GRAPH * pcallGraph, STATE *ps usually wrong! Consider also CALL [BP+0E] in which the segment for the pointer is in SS! - Mike */ - off = (dword)(word)pIcode->ic.ll.dst.off + - ((dword)(word)pIcode->ic.ll.dst.segValue << 4); + off = (dword)(word)pIcode.ic.ll.dst.off + + ((dword)(word)pIcode.ic.ll.dst.segValue << 4); /* Address of function is given by 4 (CALLF) or 2 (CALL) bytes at * previous offset into the program image */ dword tgtAddr=0; - if (pIcode->ic.ll.opcode == iCALLF) + if (pIcode.ic.ll.opcode == iCALLF) tgtAddr= LH(&prog.Image[off]) + (dword)(LH(&prog.Image[off+2])) << 4; else tgtAddr= LH(&prog.Image[off]) + (dword)(word)state.r[rCS] << 4; - pIcode->ic.ll.src.SetImmediateOp( tgtAddr ); - pIcode->ic.ll.flg |= I; + pIcode.ic.ll.src.SetImmediateOp( tgtAddr ); + pIcode.ic.ll.flg |= I; indirect = TRUE; } - /* Process CALL. Function address is located in pIcode->ic.ll.immed.op */ - if (pIcode->ic.ll.flg & I) + /* Process CALL. Function address is located in pIcode.ic.ll.immed.op */ + if (pIcode.ic.ll.flg & I) { /* Search procedure list for one with appropriate entry point */ ilFunction iter= std::find_if(pProcList.begin(),pProcList.end(), [pIcode](const Function &f) -> - bool { return f.procEntry==pIcode->ic.ll.src.op(); }); + bool { return f.procEntry==pIcode.ic.ll.src.op(); }); /* Create a new procedure node and save copy of the state */ if (iter==pProcList.end()) @@ -575,7 +569,7 @@ boolT Function::process_CALL (ICODE * pIcode, CALL_GRAPH * pcallGraph, STATE *ps pProcList.push_back(Function::Create()); Function &x(pProcList.back()); iter = (++pProcList.rbegin()).base(); - x.procEntry = pIcode->ic.ll.src.op(); + x.procEntry = pIcode.ic.ll.src.op(); LibCheck(x); if (x.flg & PROC_ISLIB) @@ -601,9 +595,9 @@ boolT Function::process_CALL (ICODE * pIcode, CALL_GRAPH * pcallGraph, STATE *ps /* Save machine state in localState, load up IP and CS.*/ localState = *pstate; - pstate->IP = pIcode->ic.ll.src.op(); - if (pIcode->ic.ll.opcode == iCALLF) - pstate->setState( rCS, LH(prog.Image + pIcode->ic.ll.label + 3)); + pstate->IP = pIcode.ic.ll.src.op(); + if (pIcode.ic.ll.opcode == iCALLF) + pstate->setState( rCS, LH(prog.Image + pIcode.ic.ll.label + 3)); x.state = *pstate; /* Insert new procedure in call graph */ @@ -626,26 +620,25 @@ boolT Function::process_CALL (ICODE * pIcode, CALL_GRAPH * pcallGraph, STATE *ps last_insn.ic.ll.src.proc.proc = &(*iter); // ^ target proc /* return ((p->flg & TERMINATES) != 0); */ - return FALSE; } - return FALSE; // Cristina, please check!! + return false; // Cristina, please check!! } /* process_MOV - Handles state changes due to simple assignments */ -static void process_MOV(ICODE * pIcode, STATE * pstate) +static void process_MOV(ICODE & pIcode, STATE * pstate) { SYM * psym, *psym2; /* Pointer to symbol in global symbol table */ - byte dstReg = pIcode->ic.ll.dst.regi; - byte srcReg = pIcode->ic.ll.src.regi; + byte dstReg = pIcode.ic.ll.dst.regi; + byte srcReg = pIcode.ic.ll.src.regi; if (dstReg > 0 && dstReg < INDEXBASE) { - if (pIcode->ic.ll.flg & I) - pstate->setState( dstReg, (int16)pIcode->ic.ll.src.op()); + if (pIcode.ic.ll.flg & I) + pstate->setState( dstReg, (int16)pIcode.ic.ll.src.op()); else if (srcReg == 0) /* direct memory offset */ { - psym = lookupAddr(&pIcode->ic.ll.src, pstate, 2, eDuVal::USE); + psym = lookupAddr(&pIcode.ic.ll.src, pstate, 2, eDuVal::USE); if (psym && ((psym->flg & SEG_IMMED) || psym->duVal.val)) pstate->setState( dstReg, LH(&prog.Image[psym->label])); } @@ -659,15 +652,15 @@ static void process_MOV(ICODE * pIcode, STATE * pstate) } } else if (dstReg == 0) { /* direct memory offset */ - psym = lookupAddr (&pIcode->ic.ll.dst, pstate, 2, eDEF); + psym = lookupAddr (&pIcode.ic.ll.dst, pstate, 2, eDEF); if (psym && ! (psym->duVal.val)) /* no initial value yet */ - if (pIcode->ic.ll.flg & I) { /* immediate */ - prog.Image[psym->label] = (byte)pIcode->ic.ll.src.op(); - prog.Image[psym->label+1] = (byte)(pIcode->ic.ll.src.op()>>8); + if (pIcode.ic.ll.flg & I) { /* immediate */ + prog.Image[psym->label] = (byte)pIcode.ic.ll.src.op(); + prog.Image[psym->label+1] = (byte)(pIcode.ic.ll.src.op()>>8); psym->duVal.val = 1; } else if (srcReg == 0) { /* direct mem offset */ - psym2 = lookupAddr (&pIcode->ic.ll.src, pstate, 2, eDuVal::USE); + psym2 = lookupAddr (&pIcode.ic.ll.src, pstate, 2, eDuVal::USE); if (psym2 && ((psym->flg & SEG_IMMED) || (psym->duVal.val))) { prog.Image[psym->label] = (byte)prog.Image[psym2->label]; @@ -900,9 +893,9 @@ std::bitset<32> duReg[] = { 0x00, * pstate: ptr to current procedure state * size : size of the operand * ix : current index into icode array */ -static void use (opLoc d, ICODE * pIcode, Function * pProc, STATE * pstate, Int size, Int ix) +static void use (opLoc d, ICODE & pIcode, Function * pProc, STATE * pstate, Int size, Int ix) { - LLOperand * pm = (d == SRC)? &pIcode->ic.ll.src: &pIcode->ic.ll.dst; + LLOperand * pm = (d == SRC)? &pIcode.ic.ll.src: &pIcode.ic.ll.dst; SYM * psym; if (pm->regi == 0 || pm->regi >= INDEXBASE) @@ -926,30 +919,30 @@ static void use (opLoc d, ICODE * pIcode, Function * pProc, STATE * pstate, Int if (pm->off > 0) /* global indexed variable */ pProc->localId.newIntIdx(pm->segValue, pm->off, rBX,ix, TYPE_WORD_SIGN); } - pIcode->du.use |= duReg[pm->regi]; + pIcode.du.use |= duReg[pm->regi]; } else if (psym = lookupAddr(pm, pstate, size, eDuVal::USE)) { setBits (BM_DATA, psym->label, (dword)size); - pIcode->ic.ll.flg |= SYM_USE; - pIcode->ic.ll.caseTbl.numEntries = psym - &symtab[0]; + pIcode.ic.ll.flg |= SYM_USE; + pIcode.ic.ll.caseTbl.numEntries = psym - &symtab[0]; } } /* Use of register */ - else if ((d == DST) || ((d == SRC) && (pIcode->ic.ll.flg & I) != I)) - pIcode->du.use |= duReg[pm->regi]; + else if ((d == DST) || ((d == SRC) && (pIcode.ic.ll.flg & I) != I)) + pIcode.du.use |= duReg[pm->regi]; } /* Checks which registers were defined (ie. got a new value) and updates the * du.d flag. * Places local variables in the local symbol table. */ -static void def (opLoc d, ICODE * pIcode, Function * pProc, STATE * pstate, Int size, +static void def (opLoc d, ICODE & pIcode, Function * pProc, STATE * pstate, Int size, Int ix) { - LLOperand *pm = (d == SRC)? &pIcode->ic.ll.src: &pIcode->ic.ll.dst; + LLOperand *pm = (d == SRC)? &pIcode.ic.ll.src: &pIcode.ic.ll.dst; SYM * psym; if (pm->regi == 0 || pm->regi >= INDEXBASE) @@ -975,22 +968,22 @@ static void def (opLoc d, ICODE * pIcode, Function * pProc, STATE * pstate, Int if (pm->off > 0) /* global var */ pProc->localId.newIntIdx(pm->segValue, pm->off, rBX,ix, TYPE_WORD_SIGN); } - pIcode->du.use |= duReg[pm->regi]; + pIcode.du.use |= duReg[pm->regi]; } else if (psym = lookupAddr(pm, pstate, size, eDEF)) { setBits(BM_DATA, psym->label, (dword)size); - pIcode->ic.ll.flg |= SYM_DEF; - pIcode->ic.ll.caseTbl.numEntries = psym - &symtab[0]; + pIcode.ic.ll.flg |= SYM_DEF; + pIcode.ic.ll.caseTbl.numEntries = psym - &symtab[0]; } } /* Definition of register */ - else if ((d == DST) || ((d == SRC) && (pIcode->ic.ll.flg & I) != I)) + else if ((d == DST) || ((d == SRC) && (pIcode.ic.ll.flg & I) != I)) { - pIcode->du.def |= duReg[pm->regi]; - pIcode->du1.numRegsDef++; + pIcode.du.def |= duReg[pm->regi]; + pIcode.du1.numRegsDef++; } } @@ -998,32 +991,32 @@ static void def (opLoc d, ICODE * pIcode, Function * pProc, STATE * pstate, Int /* use_def - operand is both use and def'd. * Note: the destination will always be a register, stack variable, or global * variable. */ -static void use_def(opLoc d, ICODE * pIcode, Function * pProc, STATE * pstate, Int cb, +static void use_def(opLoc d, ICODE & pIcode, Function * pProc, STATE * pstate, Int cb, Int ix) { - LLOperand * pm = (d == SRC)? &pIcode->ic.ll.src: &pIcode->ic.ll.dst; + LLOperand * pm = (d == SRC)? &pIcode.ic.ll.src: &pIcode.ic.ll.dst; use (d, pIcode, pProc, pstate, cb, ix); if (pm->regi < INDEXBASE) /* register */ { - pIcode->du.def |= duReg[pm->regi]; - pIcode->du1.numRegsDef++; + pIcode.du.def |= duReg[pm->regi]; + pIcode.du1.numRegsDef++; } } /* Set DU vector, local variables and arguments, and DATA bits in the * bitmap */ -void Function::process_operands(ICODE * pIcode, STATE * pstate) +void Function::process_operands(ICODE & pIcode, STATE * pstate) { Int ix=Icode.size(); Int i; - Int sseg = (pIcode->ic.ll.src.seg)? pIcode->ic.ll.src.seg: rDS; - Int cb = (pIcode->ic.ll.flg & B) ? 1: 2; - flags32 Imm = (pIcode->ic.ll.flg & I); + Int sseg = (pIcode.ic.ll.src.seg)? pIcode.ic.ll.src.seg: rDS; + Int cb = (pIcode.ic.ll.flg & B) ? 1: 2; + flags32 Imm = (pIcode.ic.ll.flg & I); - switch (pIcode->ic.ll.opcode) { + switch (pIcode.ic.ll.opcode) { case iAND: case iOR: case iXOR: case iSAR: case iSHL: case iSHR: case iRCL: case iRCR: case iROL: case iROR: @@ -1054,7 +1047,7 @@ void Function::process_operands(ICODE * pIcode, STATE * pstate) case iDIV: case iIDIV: use(SRC, pIcode, this, pstate, cb, ix); if (cb == 1) - pIcode->du.use |= duReg[rTMP]; + pIcode.du.use |= duReg[rTMP]; break; case iMUL: case iIMUL: @@ -1064,13 +1057,13 @@ void Function::process_operands(ICODE * pIcode, STATE * pstate) use (DST, pIcode, this, pstate, cb, ix); if (cb == 1) { - pIcode->du.def |= duReg[rAX]; - pIcode->du1.numRegsDef++; + pIcode.du.def |= duReg[rAX]; + pIcode.du1.numRegsDef++; } else { - pIcode->du.def |= (duReg[rAX] | duReg[rDX]); - pIcode->du1.numRegsDef += 2; + pIcode.du.def |= (duReg[rAX] | duReg[rDX]); + pIcode.du1.numRegsDef += 2; } } else @@ -1078,18 +1071,18 @@ void Function::process_operands(ICODE * pIcode, STATE * pstate) break; case iSIGNEX: - cb = (pIcode->ic.ll.flg & SRC_B) ? 1 : 2; + cb = (pIcode.ic.ll.flg & SRC_B) ? 1 : 2; if (cb == 1) /* byte */ { - pIcode->du.def |= duReg[rAX]; - pIcode->du1.numRegsDef++; - pIcode->du.use |= duReg[rAL]; + pIcode.du.def |= duReg[rAX]; + pIcode.du1.numRegsDef++; + pIcode.du.use |= duReg[rAL]; } else /* word */ { - pIcode->du.def |= (duReg[rDX] | duReg[rAX]); - pIcode->du1.numRegsDef += 2; - pIcode->du.use |= duReg[rAX]; + pIcode.du.def |= (duReg[rDX] | duReg[rAX]); + pIcode.du1.numRegsDef += 2; + pIcode.du.use |= duReg[rAX]; } break; @@ -1097,7 +1090,7 @@ void Function::process_operands(ICODE * pIcode, STATE * pstate) cb = 4; case iCALL: case iPUSH: case iPOP: if (! Imm) { - if (pIcode->ic.ll.opcode == iPOP) + if (pIcode.ic.ll.opcode == iPOP) def(DST, pIcode, this, pstate, cb, ix); else use(DST, pIcode, this, pstate, cb, ix); @@ -1109,8 +1102,8 @@ void Function::process_operands(ICODE * pIcode, STATE * pstate) break; case iLDS: case iLES: - pIcode->du.def |= duReg[(pIcode->ic.ll.opcode == iLDS) ? rDS : rES]; - pIcode->du1.numRegsDef++; + pIcode.du.def |= duReg[(pIcode.ic.ll.opcode == iLDS) ? rDS : rES]; + pIcode.du1.numRegsDef++; cb = 4; case iMOV: use(SRC, pIcode, this, pstate, cb, ix); @@ -1135,70 +1128,70 @@ void Function::process_operands(ICODE * pIcode, STATE * pstate) break; case iLOOP: case iLOOPE: case iLOOPNE: - pIcode->du.def |= duReg[rCX]; - pIcode->du1.numRegsDef++; + pIcode.du.def |= duReg[rCX]; + pIcode.du1.numRegsDef++; case iJCXZ: - pIcode->du.use |= duReg[rCX]; + pIcode.du.use |= duReg[rCX]; break; case iREPNE_CMPS: case iREPE_CMPS: case iREP_MOVS: - pIcode->du.def |= duReg[rCX]; - pIcode->du1.numRegsDef++; - pIcode->du.use |= duReg[rCX]; + pIcode.du.def |= duReg[rCX]; + pIcode.du1.numRegsDef++; + pIcode.du.use |= duReg[rCX]; case iCMPS: case iMOVS: - pIcode->du.def |= duReg[rSI] | duReg[rDI]; - pIcode->du1.numRegsDef += 2; - pIcode->du.use |= duReg[rSI] | duReg[rDI] | duReg[rES] | duReg[sseg]; + pIcode.du.def |= duReg[rSI] | duReg[rDI]; + pIcode.du1.numRegsDef += 2; + pIcode.du.use |= duReg[rSI] | duReg[rDI] | duReg[rES] | duReg[sseg]; break; case iREPNE_SCAS: case iREPE_SCAS: case iREP_STOS: case iREP_INS: - pIcode->du.def |= duReg[rCX]; - pIcode->du1.numRegsDef++; - pIcode->du.use |= duReg[rCX]; + pIcode.du.def |= duReg[rCX]; + pIcode.du1.numRegsDef++; + pIcode.du.use |= duReg[rCX]; case iSCAS: case iSTOS: case iINS: - pIcode->du.def |= duReg[rDI]; - pIcode->du1.numRegsDef++; - if (pIcode->ic.ll.opcode == iREP_INS || pIcode->ic.ll.opcode== iINS) + pIcode.du.def |= duReg[rDI]; + pIcode.du1.numRegsDef++; + if (pIcode.ic.ll.opcode == iREP_INS || pIcode.ic.ll.opcode== iINS) { - pIcode->du.use |= duReg[rDI] | duReg[rES] | duReg[rDX]; + pIcode.du.use |= duReg[rDI] | duReg[rES] | duReg[rDX]; } else { - pIcode->du.use |= duReg[rDI] | duReg[rES] | duReg[(cb == 2)? rAX: rAL]; + pIcode.du.use |= duReg[rDI] | duReg[rES] | duReg[(cb == 2)? rAX: rAL]; } break; case iREP_LODS: - pIcode->du.def |= duReg[rCX]; - pIcode->du1.numRegsDef++; - pIcode->du.use |= duReg[rCX]; + pIcode.du.def |= duReg[rCX]; + pIcode.du1.numRegsDef++; + pIcode.du.use |= duReg[rCX]; case iLODS: - pIcode->du.def |= duReg[rSI] | duReg[(cb==2)? rAX: rAL]; - pIcode->du1.numRegsDef += 2; - pIcode->du.use |= duReg[rSI] | duReg[sseg]; + pIcode.du.def |= duReg[rSI] | duReg[(cb==2)? rAX: rAL]; + pIcode.du1.numRegsDef += 2; + pIcode.du.use |= duReg[rSI] | duReg[sseg]; break; case iREP_OUTS: - pIcode->du.def |= duReg[rCX]; - pIcode->du1.numRegsDef++; - pIcode->du.use |= duReg[rCX]; + pIcode.du.def |= duReg[rCX]; + pIcode.du1.numRegsDef++; + pIcode.du.use |= duReg[rCX]; case iOUTS: - pIcode->du.def |= duReg[rSI]; - pIcode->du1.numRegsDef++; - pIcode->du.use |= duReg[rSI] | duReg[rDX] | duReg[sseg]; + pIcode.du.def |= duReg[rSI]; + pIcode.du1.numRegsDef++; + pIcode.du.use |= duReg[rSI] | duReg[rDX] | duReg[sseg]; break; case iIN: case iOUT: def(DST, pIcode, this, pstate, cb, ix); if (! Imm) { - pIcode->du.use |= duReg[rDX]; + pIcode.du.use |= duReg[rDX]; } break; } for (i = rSP; i <= rBH; i++) /* Kill all defined registers */ - if (pIcode->ic.ll.flagDU.d & (1 << i)) + if (pIcode.ic.ll.flagDU.d & (1 << i)) pstate->f[i] = FALSE; } diff --git a/src/procs.cpp b/src/procs.cpp index 2be3b5c..047708c 100644 --- a/src/procs.cpp +++ b/src/procs.cpp @@ -106,13 +106,13 @@ void Function::newRegArg(iICODE picode, iICODE ticode) uint8_t regL, regH; /* Registers involved in arguments */ /* Flag ticode as having register arguments */ - tproc = ticode->ic.hl.oper.call.proc; + tproc = ticode->ic.hl.call.proc; tproc->flg |= REG_ARGS; /* Get registers and index into target procedure's local list */ - ps = ticode->ic.hl.oper.call.args; + ps = ticode->ic.hl.call.args; ts = &tproc->args; - lhs = picode->ic.hl.oper.asgn.lhs; + lhs = picode->ic.hl.asgn.lhs; type = lhs->expr.ident.idType; if (type == REGISTER) { @@ -187,7 +187,7 @@ void Function::newRegArg(iICODE picode, iICODE ticode) /* Do ps (actual arguments) */ STKSYM newsym; sprintf (newsym.name, "arg%ld", ps->sym.size()); - newsym.actual = picode->ic.hl.oper.asgn.rhs; + newsym.actual = picode->ic.hl.asgn.rhs; newsym.regs = lhs; /* Mask off high and low register(s) in picode */ switch (type) { @@ -211,27 +211,14 @@ void Function::newRegArg(iICODE picode, iICODE ticode) } -/* Allocates num arguments in the actual argument list of the current - * icode picode. */ -/** NOTE: this function is not used ****/ -void allocStkArgs (ICODE *picode, Int num) -{ - STKFRAME * ps; - ps = picode->ic.hl.oper.call.args; - ps->numArgs = num; - ps->sym.resize(num); -} - - -/* Inserts the new expression (ie. the actual parameter) on the argument +/** Inserts the new expression (ie. the actual parameter) on the argument * list. - * Returns: TRUE if it was a near call that made use of a segment register. - * FALSE elsewhere */ -boolT newStkArg (ICODE *picode, COND_EXPR *exp, llIcode opcode, Function * pproc) + * @return TRUE if it was a near call that made use of a segment register. + * FALSE elsewhere +*/ +bool CallType::newStkArg(COND_EXPR *exp, llIcode opcode, Function * pproc) { - STKFRAME * ps; byte regi; - /* Check for far procedure call, in which case, references to segment * registers are not be considered another parameter (i.e. they are * long references to another segment) */ @@ -249,23 +236,20 @@ boolT newStkArg (ICODE *picode, COND_EXPR *exp, llIcode opcode, Function * pproc } /* Place register argument on the argument list */ - ps = picode->ic.hl.oper.call.args; STKSYM newsym; newsym.actual = exp; - ps->sym.push_back(newsym); - ps->numArgs++; + args->sym.push_back(newsym); + args->numArgs++; return false; } /* Places the actual argument exp in the position given by pos in the * argument list of picode. */ -void placeStkArg (ICODE *picode, COND_EXPR *exp, Int pos) -{ STKFRAME * ps; - - ps = picode->ic.hl.oper.call.args; - ps->sym[pos].actual = exp; - sprintf (ps->sym[pos].name, "arg%ld", pos); +void CallType::placeStkArg (COND_EXPR *exp, Int pos) +{ + args->sym[pos].actual = exp; + sprintf (args->sym[pos].name, "arg%ld", pos); } diff --git a/src/scanner.cpp b/src/scanner.cpp index 1dcd72b..cb30cef 100644 --- a/src/scanner.cpp +++ b/src/scanner.cpp @@ -318,13 +318,12 @@ static ICODE * pIcode; /* Ptr to Icode record filled in by scan() */ Scans one machine instruction at offset ip in prog.Image and returns error. At the same time, fill in low-level icode details for the scanned inst. ****************************************************************************/ -eErrorId scan(dword ip, ICODE *p) +eErrorId scan(dword ip, ICODE &p) { Int op; - - memset(p, 0, sizeof(ICODE)); - p->type = LOW_LEVEL; - p->ic.ll.label = ip; /* ip is absolute offset into image*/ + p = ICODE(); + p.type = LOW_LEVEL; + p.ic.ll.label = ip; /* ip is absolute offset into image*/ if (ip >= (dword)prog.cbImage) { return (IP_OUT_OF_RANGE); @@ -332,25 +331,25 @@ eErrorId scan(dword ip, ICODE *p) SegPrefix = RepPrefix = 0; pInst = prog.Image + ip; - pIcode = p; + pIcode = &p; do { op = *pInst++; /* First state - trivial */ - p->ic.ll.opcode = stateTable[op].opcode; /* Convert to Icode.opcode */ - p->ic.ll.flg = stateTable[op].flg & ICODEMASK; - p->ic.ll.flagDU.d = stateTable[op].df; - p->ic.ll.flagDU.u = stateTable[op].uf; + p.ic.ll.opcode = stateTable[op].opcode; /* Convert to Icode.opcode */ + p.ic.ll.flg = stateTable[op].flg & ICODEMASK; + p.ic.ll.flagDU.d = stateTable[op].df; + p.ic.ll.flagDU.u = stateTable[op].uf; (*stateTable[op].state1)(op); /* Second state */ (*stateTable[op].state2)(op); /* Third state */ } while (stateTable[op].state1 == prefix); /* Loop if prefix */ - if (p->ic.ll.opcode) + if (p.ic.ll.opcode) { /* Save bytes of image used */ - p->ic.ll.numBytes = (byte)((pInst - prog.Image) - ip); + p.ic.ll.numBytes = (byte)((pInst - prog.Image) - ip); return ((SegPrefix)? FUNNY_SEGOVR: /* Seg. Override invalid */ (RepPrefix ? FUNNY_REP: NO_ERR));/* REP prefix invalid */ }