diff --git a/include/Enums.h b/include/Enums.h index 72f4a4c..e323f13 100644 --- a/include/Enums.h +++ b/include/Enums.h @@ -52,7 +52,7 @@ enum condId enum condOp { /* For conditional expressions */ - LESS_EQUAL = 0, /* <= */ + LESS_EQUAL, /* <= */ LESS, /* < */ EQUAL, /* == */ NOT_EQUAL, /* != */ @@ -267,6 +267,7 @@ enum hlFirst /* HIGH_LEVEL icodes opcodes */ enum hlIcode { + HLI_INVALID, HLI_ASSIGN, /* := */ HLI_CALL, /* Call procedure */ HLI_JCOND, /* Conditional jump */ diff --git a/include/ast.h b/include/ast.h index 9f66e1d..8e9edf3 100644 --- a/include/ast.h +++ b/include/ast.h @@ -27,6 +27,7 @@ struct Function; struct STKFRAME; struct LOCAL_ID; struct ICODE; +struct LLInst; struct ID; typedef std::list::iterator iICODE; #include "IdentType.h" @@ -34,19 +35,42 @@ typedef std::list::iterator iICODE; /* Expression data type */ struct COND_EXPR { +protected: + struct /* for BOOLEAN_OP */ + { + condOp op; + COND_EXPR *lhs; + COND_EXPR *rhs; + } boolExpr; + +public: condNodeType type; /* Conditional Expression Node Type */ union _exprNode { /* Different cond expr nodes */ - struct /* for BOOLEAN_OP */ - { - condOp op; - COND_EXPR *lhs; - COND_EXPR *rhs; - } boolExpr; COND_EXPR *unaryExp; /* for NEGATION,ADDRESSOF,DEREFERENCE*/ IDENTTYPE ident; /* for IDENTIFIER */ } expr; + COND_EXPR *lhs() + { + assert(type==BOOLEAN_OP); + return boolExpr.lhs; + } + const COND_EXPR *lhs() const + { + assert(type==BOOLEAN_OP); + return boolExpr.lhs; + } + COND_EXPR *rhs() + { + assert(type==BOOLEAN_OP); + return boolExpr.rhs; + } + const COND_EXPR *rhs() const + { + assert(type==BOOLEAN_OP); + return boolExpr.rhs; + } + condOp op() const { return boolExpr.op;} public: - static COND_EXPR *idGlob(int16_t segValue, int16_t off); static COND_EXPR *idRegIdx(int idx, regType reg_type); static COND_EXPR *idKte(uint32_t kte, uint8_t size); static COND_EXPR *idLoc(int off, LOCAL_ID *localId); @@ -58,23 +82,86 @@ public: static COND_EXPR *idLong(LOCAL_ID *localId, opLoc sd, iICODE pIcode, hlFirst f, iICODE ix, operDu du, iICODE atOffset); static COND_EXPR *idFunc(Function *pproc, STKFRAME *args); static COND_EXPR *idID(const ID *retVal, LOCAL_ID *locsym, iICODE ix_); - static COND_EXPR *id(const ICODE &pIcode, opLoc sd, Function *pProc, iICODE ix_, ICODE &duIcode, operDu du); + static COND_EXPR * id(const LLInst &ll_insn, opLoc sd, Function *pProc, iICODE ix_, ICODE &duIcode, operDu du); static COND_EXPR *boolOp(COND_EXPR *lhs, COND_EXPR *rhs, condOp op); + static bool insertSubTreeLongReg(COND_EXPR *exp, COND_EXPR **tree, int longIdx); + static bool insertSubTreeReg(COND_EXPR *&tree, COND_EXPR *_expr, uint8_t regi, LOCAL_ID *locsym); public: - COND_EXPR *clone(); + virtual COND_EXPR *clone(); void release(); void changeBoolOp(condOp newOp); COND_EXPR(COND_EXPR &other) { type=other.type; expr=other.expr; + boolExpr=other.boolExpr; } COND_EXPR(condNodeType t=UNKNOWN_OP) : type(t) { memset(&expr,0,sizeof(_exprNode)); + memset(&boolExpr,0,sizeof(boolExpr)); + } + virtual ~COND_EXPR() {} public: - COND_EXPR *inverse(); // return new COND_EXPR that is invarse of this + virtual COND_EXPR *inverse(); // return new COND_EXPR that is invarse of this + virtual bool xClear(iICODE f, iICODE t, iICODE lastBBinst, Function *pproc); +}; +struct BinaryOperator : public COND_EXPR +{ + condOp m_op; + COND_EXPR *m_lhs; + COND_EXPR *m_rhs; + BinaryOperator() + { + m_op = DUMMY; + m_lhs=m_rhs=nullptr; + } + static BinaryOperator *CreateAdd(COND_EXPR *l,COND_EXPR *r); + virtual COND_EXPR *inverse(); + virtual COND_EXPR *clone(); + virtual bool xClear(iICODE f, iICODE t, iICODE lastBBinst, Function *pproc); + COND_EXPR *lhs() + { + assert(type==BOOLEAN_OP); + return m_lhs; + } + const COND_EXPR *lhs() const + { + assert(type==BOOLEAN_OP); + return m_lhs; + } + COND_EXPR *rhs() + { + assert(type==BOOLEAN_OP); + return m_rhs; + } + const COND_EXPR *rhs() const + { + assert(type==BOOLEAN_OP); + return m_rhs; + } + condOp op() const { return m_op;} +}; +struct UnaryOperator : public COND_EXPR +{ + condOp op; + COND_EXPR *unaryExp; + virtual COND_EXPR *inverse(); + virtual COND_EXPR *clone(); + virtual bool xClear(iICODE f, iICODE t, iICODE lastBBinst, Function *pproc); + static UnaryOperator *Create(condNodeType t, COND_EXPR *sub_expr) + { + UnaryOperator *newExp = new UnaryOperator(); + newExp->type=t; + newExp->unaryExp = sub_expr; + return (newExp); + } }; - +struct GlobalVariable : public COND_EXPR +{ + static COND_EXPR *Create(int16_t segValue, int16_t off); +}; +struct Constant : public COND_EXPR +{}; diff --git a/include/dcc.h b/include/dcc.h index 86a93e4..ec6a354 100644 --- a/include/dcc.h +++ b/include/dcc.h @@ -163,8 +163,6 @@ void adjustActArgType (COND_EXPR *, hlType, Function *); std::string walkCondExpr (const COND_EXPR *exp, Function * pProc, int *); int hlTypeSize (const COND_EXPR *, Function *); hlType expType (const COND_EXPR *, Function *); -bool insertSubTreeReg(COND_EXPR *&, COND_EXPR *, uint8_t, LOCAL_ID *); -bool insertSubTreeLongReg (COND_EXPR *, COND_EXPR **, int); /* Exported functions from hlicode.c */ diff --git a/include/icode.h b/include/icode.h index 60c1e1e..bca7de8 100644 --- a/include/icode.h +++ b/include/icode.h @@ -137,6 +137,15 @@ public: asgn.lhs=l; asgn.rhs=r; } + HLTYPE(hlIcode op=HLI_INVALID) : opcode(op) + {} + HLTYPE & operator=(const HLTYPE &l) + { + exp=l.exp; + opcode=l.opcode; + asgn=l.asgn; + call=l.call; + } public: std::string write1HlIcode(Function *pProc, int *numLoc); void setAsgn(COND_EXPR *lhs, COND_EXPR *rhs); @@ -245,6 +254,8 @@ public: void flops(std::ostringstream &out); bool isJmpInst(); + HLTYPE toHighLevel(COND_EXPR *lhs, COND_EXPR *rhs, Function *func); + HLTYPE createCall(); }; /* Icode definition: LOW_LEVEL and HIGH_LEVEL */ @@ -319,6 +330,7 @@ public: const LLInst * ll() const { return &m_ll;} HLTYPE * hl() { return &m_hl;} const HLTYPE * hl() const { return &m_hl;} + void hl(const HLTYPE &v) { m_hl=v;} int loc_ip; // used by CICodeRec to number ICODEs void setRegDU(uint8_t regi, operDu du_in); diff --git a/src/ast.cpp b/src/ast.cpp index 28f9c62..1eef40d 100644 --- a/src/ast.cpp +++ b/src/ast.cpp @@ -95,13 +95,12 @@ void ICODE::copyDU(const ICODE &duIcode, operDu _du, operDu duDu) /* Creates a conditional boolean expression and returns it */ COND_EXPR *COND_EXPR::boolOp(COND_EXPR *lhs, COND_EXPR *rhs, condOp op) { - //printf("%s:%d\n",__FUNCTION__,int(op)); COND_EXPR *newExp; newExp = new COND_EXPR(BOOLEAN_OP); - newExp->expr.boolExpr.op = op; - newExp->expr.boolExpr.lhs = lhs; - newExp->expr.boolExpr.rhs = rhs; + newExp->boolExpr.op = op; + newExp->boolExpr.lhs = lhs; + newExp->boolExpr.rhs = rhs; return (newExp); } @@ -120,7 +119,7 @@ COND_EXPR *COND_EXPR::unary(condNodeType t, COND_EXPR *sub_expr) /* Returns an identifier conditional expression node of type GLOB_VAR */ -COND_EXPR *COND_EXPR::idGlob (int16_t segValue, int16_t off) +COND_EXPR *GlobalVariable::Create(int16_t segValue, int16_t off) { COND_EXPR *newExp; uint32_t adr; @@ -341,16 +340,16 @@ COND_EXPR *COND_EXPR::idID (const ID *retVal, LOCAL_ID *locsym, iICODE ix_) * Arguments: * duIcode: icode instruction that needs the du set. * du: operand is defined or used in current instruction. */ -COND_EXPR *COND_EXPR::id(const ICODE &pIcode, opLoc sd, Function * pProc, iICODE ix_,ICODE &duIcode, operDu du) +COND_EXPR *COND_EXPR::id(const LLInst &ll_insn, opLoc sd, Function * pProc, iICODE ix_,ICODE &duIcode, operDu du) { COND_EXPR *newExp; int idx; /* idx into pIcode->localId table */ - const LLOperand &pm((sd == SRC) ? pIcode.ll()->src : pIcode.ll()->dst); + const LLOperand &pm((sd == SRC) ? ll_insn.src : ll_insn.dst); - if ( ((sd == DST) && pIcode.ll()->testFlags(IM_DST)) or - ((sd == SRC) && pIcode.ll()->testFlags(IM_SRC)) or + if ( ((sd == DST) && ll_insn.testFlags(IM_DST)) or + ((sd == SRC) && ll_insn.testFlags(IM_SRC)) or (sd == LHS_OP)) /* for MUL lhs */ { /* implicit dx:ax */ idx = pProc->localId.newLongReg (TYPE_LONG_SIGN, rDX, rAX, ix_); @@ -359,20 +358,20 @@ COND_EXPR *COND_EXPR::id(const ICODE &pIcode, opLoc sd, Function * pProc, iICODE duIcode.setRegDU (rAX, du); } - else if ((sd == DST) && pIcode.ll()->testFlags(IM_TMP_DST)) + else if ((sd == DST) && ll_insn.testFlags(IM_TMP_DST)) { /* implicit tmp */ newExp = COND_EXPR::idReg (rTMP, 0, &pProc->localId); duIcode.setRegDU(rTMP, (operDu)eUSE); } - else if ((sd == SRC) && pIcode.ll()->testFlags(I)) /* constant */ - newExp = COND_EXPR::idKte (pIcode.ll()->src.op(), 2); + else if ((sd == SRC) && ll_insn.testFlags(I)) /* constant */ + newExp = COND_EXPR::idKte (ll_insn.src.op(), 2); else if (pm.regi == 0) /* global variable */ - newExp = COND_EXPR::idGlob(pm.segValue, pm.off); + newExp = GlobalVariable::Create(pm.segValue, pm.off); else if (pm.regi < INDEXBASE) /* register */ { - newExp = COND_EXPR::idReg (pm.regi, (sd == SRC) ? pIcode.ll()->getFlag() : - pIcode.ll()->getFlag() & NO_SRC_B, + newExp = COND_EXPR::idReg (pm.regi, (sd == SRC) ? ll_insn.getFlag() : + ll_insn.getFlag() & NO_SRC_B, &pProc->localId); duIcode.setRegDU( pm.regi, du); } @@ -466,8 +465,8 @@ int hlTypeSize (const COND_EXPR *expr, Function * pproc) switch (expr->type) { case BOOLEAN_OP: - first = hlTypeSize (expr->expr.boolExpr.lhs, pproc); - second = hlTypeSize (expr->expr.boolExpr.rhs, pproc); + first = hlTypeSize (expr->lhs(), pproc); + second = hlTypeSize (expr->rhs(), pproc); if (first > second) return (first); else @@ -522,12 +521,11 @@ hlType expType (const COND_EXPR *expr, Function * pproc) switch (expr->type) { case BOOLEAN_OP: - first = expType (expr->expr.boolExpr.lhs, pproc); - second = expType (expr->expr.boolExpr.rhs, pproc); + first = expType (expr->lhs(), pproc); + second = expType (expr->rhs(), pproc); if (first != second) { - if (hlTypeSize (expr->expr.boolExpr.lhs, pproc) > - hlTypeSize (expr->expr.boolExpr.rhs, pproc)) + if (hlTypeSize (expr->lhs(), pproc) > hlTypeSize (expr->rhs(), pproc)) return (first); else return (second); @@ -641,9 +639,9 @@ string walkCondExpr (const COND_EXPR* expr, Function * pProc, int* numLoc) { case BOOLEAN_OP: outStr << "("; - outStr << walkCondExpr(expr->expr.boolExpr.lhs, pProc, numLoc); - outStr << condOpSym[expr->expr.boolExpr.op]; - outStr << walkCondExpr(expr->expr.boolExpr.rhs, pProc, numLoc); + outStr << walkCondExpr(expr->lhs(), pProc, numLoc); + outStr << condOpSym[expr->op()]; + outStr << walkCondExpr(expr->rhs(), pProc, numLoc); outStr << ")"; break; @@ -803,8 +801,8 @@ COND_EXPR *COND_EXPR::clone() { case BOOLEAN_OP: newExp = new COND_EXPR(*this); - newExp->expr.boolExpr.lhs = expr.boolExpr.lhs->clone(); - newExp->expr.boolExpr.rhs = expr.boolExpr.rhs->clone(); + newExp->boolExpr.lhs = lhs()->clone(); + newExp->boolExpr.rhs = rhs()->clone(); break; case NEGATION: @@ -824,12 +822,12 @@ COND_EXPR *COND_EXPR::clone() /* Changes the boolean conditional operator at the root of this expression */ void COND_EXPR::changeBoolOp (condOp newOp) { - expr.boolExpr.op = newOp; + boolExpr.op = newOp; } /* Inserts the expression exp into the tree at the location specified by the * register regi */ -bool insertSubTreeReg (COND_EXPR *&tree, COND_EXPR *expr, uint8_t regi,LOCAL_ID *locsym) +bool COND_EXPR::insertSubTreeReg (COND_EXPR *&tree, COND_EXPR *_expr, uint8_t regi,LOCAL_ID *locsym) { HlTypeSupport *set_val; uint8_t treeReg; @@ -844,14 +842,14 @@ bool insertSubTreeReg (COND_EXPR *&tree, COND_EXPR *expr, uint8_t regi,LOCAL_ID treeReg = locsym->id_arr[tree->expr.ident.idNode.regiIdx].id.regi; if (treeReg == regi) /* uint16_t reg */ { - tree = expr; + tree = _expr; return true; } else if ((regi >= rAX) && (regi <= rBX)) /* uint16_t/uint8_t reg */ { if ((treeReg == (regi + rAL-1)) || (treeReg == (regi + rAH-1))) { - tree = expr; + tree = _expr; return true; } } @@ -859,16 +857,16 @@ bool insertSubTreeReg (COND_EXPR *&tree, COND_EXPR *expr, uint8_t regi,LOCAL_ID return FALSE; case BOOLEAN_OP: - if (insertSubTreeReg (tree->expr.boolExpr.lhs, expr, regi, locsym)) + if (insertSubTreeReg (tree->boolExpr.lhs, _expr, regi, locsym)) return true; - if (insertSubTreeReg (tree->expr.boolExpr.rhs, expr, regi, locsym)) + if (insertSubTreeReg (tree->boolExpr.rhs, _expr, regi, locsym)) return true; return false; case NEGATION: case ADDRESSOF: case DEREFERENCE: - if (insertSubTreeReg(tree->expr.unaryExp, expr, regi, locsym)) + if (insertSubTreeReg(tree->expr.unaryExp, _expr, regi, locsym)) return TRUE; return FALSE; } @@ -878,29 +876,29 @@ bool insertSubTreeReg (COND_EXPR *&tree, COND_EXPR *expr, uint8_t regi,LOCAL_ID /* Inserts the expression exp into the tree at the location specified by the * long register index longIdx*/ -bool insertSubTreeLongReg(COND_EXPR *exp, COND_EXPR **tree, int longIdx) +bool COND_EXPR::insertSubTreeLongReg(COND_EXPR *_expr, COND_EXPR **tree, int longIdx) { switch ((*tree)->type) { case IDENTIFIER: if ((*tree)->expr.ident.idNode.longIdx == longIdx) { - *tree = exp; + *tree = _expr; return true; } return false; case BOOLEAN_OP: - if (insertSubTreeLongReg (exp, &(*tree)->expr.boolExpr.lhs, longIdx)) + if (insertSubTreeLongReg (_expr, &(*tree)->boolExpr.lhs, longIdx)) return true; - if (insertSubTreeLongReg (exp, &(*tree)->expr.boolExpr.rhs, longIdx)) + if (insertSubTreeLongReg (_expr, &(*tree)->boolExpr.rhs, longIdx)) return true; return false; case NEGATION: case ADDRESSOF: case DEREFERENCE: - if (insertSubTreeLongReg (exp, &(*tree)->expr.unaryExp, longIdx)) + if (insertSubTreeLongReg (_expr, &(*tree)->expr.unaryExp, longIdx)) return true; return false; } @@ -914,8 +912,8 @@ void COND_EXPR::release() switch (type) { case BOOLEAN_OP: - expr.boolExpr.lhs->release(); - expr.boolExpr.rhs->release(); + lhs()->release(); + rhs()->release(); break; case NEGATION: case ADDRESSOF: @@ -925,3 +923,44 @@ void COND_EXPR::release() } delete (this); } + + +COND_EXPR *BinaryOperator::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}; + BinaryOperator *res=0; + switch (m_op) + { + case LESS_EQUAL: case LESS: case EQUAL: + case NOT_EQUAL: case GREATER: case GREATER_EQUAL: + res = static_cast(clone()); + res->m_op = invCondOp[m_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: + return COND_EXPR::unary (NEGATION, clone()); + + case DBL_AND: case DBL_OR: + res = static_cast(clone()); + res->m_op = invCondOp[m_op]; + res->m_lhs=m_lhs->inverse (); + res->m_rhs=m_rhs->inverse (); + return res; + } /* eos */ + assert(false); +} +/* Makes a copy of the given expression. Allocates newExp storage for each + * node. Returns the copy. */ +COND_EXPR *BinaryOperator::clone() +{ + BinaryOperator* newExp=0; /* Expression node copy */ + newExp = new BinaryOperator(); + newExp->m_op = m_op; + newExp->m_lhs = m_lhs->clone(); + newExp->m_rhs = m_rhs->clone(); + +} diff --git a/src/dataflow.cpp b/src/dataflow.cpp index 3c5b4d8..7f8df02 100644 --- a/src/dataflow.cpp +++ b/src/dataflow.cpp @@ -6,10 +6,14 @@ ****************************************************************************/ #include "dcc.h" +#include +#include +#include #include #include #include #include +using namespace boost; struct ExpStack { typedef std::list EXP_STK; @@ -81,24 +85,24 @@ int STKFRAME::getLocVar(int off) /* Returns a string with the source operand of Icode */ -static COND_EXPR *srcIdent (const ICODE &Icode, Function * pProc, iICODE i, ICODE & duIcode, operDu du) +static COND_EXPR *srcIdent (const LLInst &ll_insn, Function * pProc, iICODE i, ICODE & duIcode, operDu du) { - if (Icode.ll()->testFlags(I)) /* immediate operand */ + if (ll_insn.testFlags(I)) /* immediate operand */ { - if (Icode.ll()->testFlags(B)) - return COND_EXPR::idKte (Icode.ll()->src.op(), 1); - return COND_EXPR::idKte (Icode.ll()->src.op(), 2); + if (ll_insn.testFlags(B)) + return COND_EXPR::idKte (ll_insn.src.op(), 1); + return COND_EXPR::idKte (ll_insn.src.op(), 2); } // otherwise - return COND_EXPR::id (Icode, SRC, pProc, i, duIcode, du); + return COND_EXPR::id (ll_insn, SRC, pProc, i, duIcode, du); } /* Returns the destination operand */ -static COND_EXPR *dstIdent (const ICODE & Icode, Function * pProc, iICODE i, ICODE & duIcode, operDu du) +static COND_EXPR *dstIdent (const LLInst & ll_insn, Function * pProc, iICODE i, ICODE & duIcode, operDu du) { COND_EXPR *n; - n = COND_EXPR::id (Icode, DST, pProc, i, duIcode, du); + n = COND_EXPR::id (ll_insn, DST, pProc, i, duIcode, du); /** Is it needed? (pIcode->ll()->flg) & NO_SRC_B **/ return (n); } @@ -121,7 +125,9 @@ void Function::elimCondCodes () pBB = m_dfsLast[i]; if (pBB->flg & INVALID_BB) continue; /* Do not process invalid BBs */ - + // auto v(pBB | boost::adaptors::reversed); + // for (const ICODE &useAt : v) + // {} for (useAt = pBB->rbegin2(); useAt != pBB->rend2(); useAt++) { llIcode useAtOp = useAt->ll()->getOpcode(); @@ -142,8 +148,8 @@ void Function::elimCondCodes () switch (defAt->ll()->getOpcode()) { case iCMP: - rhs = srcIdent (*defAt, this, befDefAt,*useAt, eUSE); - lhs = dstIdent (*defAt, this, befDefAt,*useAt, eUSE); + rhs = srcIdent (*defAt->ll(), this, befDefAt,*useAt, eUSE); + lhs = dstIdent (*defAt->ll(), this, befDefAt,*useAt, eUSE); break; case iOR: @@ -156,8 +162,8 @@ void Function::elimCondCodes () break; case iTEST: - rhs = srcIdent (*defAt,this, befDefAt,*useAt, eUSE); - lhs = dstIdent (*defAt,this, befDefAt,*useAt, eUSE); + rhs = srcIdent (*defAt->ll(),this, befDefAt,*useAt, eUSE); + lhs = dstIdent (*defAt->ll(),this, befDefAt,*useAt, eUSE); lhs = COND_EXPR::boolOp (lhs, rhs, AND); if (defAt->ll()->testFlags(B)) rhs = COND_EXPR::idKte (0, 1); @@ -186,22 +192,9 @@ void Function::elimCondCodes () exp = COND_EXPR::boolOp (lhs, rhs, EQUAL); useAt->setJCond(exp); } -// else if (useAt->getOpcode() == iRCL) -// { -// ICODE &a(*defAt); -// ICODE &b(*useAt); -// if(a.getOpcode() == iRCL) -// { -// if ((b.ll()->flg & NO_SRC) != NO_SRC) /* if there is src op */ -// rhs = COND_EXPR::id (*useAt, SRC, this, Icode.end(), *useAt, NONE); -// lhs = COND_EXPR::id (*useAt, DST, this, Icode.end(), *useAt, USE_DEF); - -// rhs = COND_EXPR::boolOp (lhs, rhs, SHL); -// useAt->setAsgn(lhs->clone(), rhs); -// printf("RCL\n"); -// } - -// } + // else if (useAt->getOpcode() == iRCL) + // { + // } else { ICODE &a(*defAt); @@ -292,6 +285,8 @@ void Function::liveRegAnalysis (std::bitset<32> &in_liveOut) /* Process nodes in reverse postorder order */ change = false; //for (i = numBBs; i > 0; i--) + //boost::RandomAccessContainerConcept; + for(auto iBB=m_dfsLast.rbegin(); iBB!=m_dfsLast.rend(); ++iBB) { pbb = *iBB;//m_dfsLast[i-1]; @@ -556,7 +551,7 @@ static void forwardSubs (COND_EXPR *lhs, COND_EXPR *rhs, iICODE picode, return; /* Insert on rhs of ticode, if possible */ - res = insertSubTreeReg (ticode->hl()->asgn.rhs,rhs, + res = COND_EXPR::insertSubTreeReg (ticode->hl()->asgn.rhs,rhs, locsym->id_arr[lhs->expr.ident.idNode.regiIdx].id.regi, locsym); if (res) @@ -567,7 +562,7 @@ static void forwardSubs (COND_EXPR *lhs, COND_EXPR *rhs, iICODE picode, else { /* Try to insert it on lhs of ticode*/ - res = insertSubTreeReg (ticode->hl()->asgn.lhs,rhs, + res = COND_EXPR::insertSubTreeReg (ticode->hl()->asgn.lhs,rhs, locsym->id_arr[lhs->expr.ident.idNode.regiIdx].id.regi, locsym); if (res) @@ -590,7 +585,7 @@ static void forwardSubsLong (int longIdx, COND_EXPR *exp, iICODE picode, return; /* Insert on rhs of ticode, if possible */ - res = insertSubTreeLongReg (exp, &ticode->hl()->asgn.rhs, longIdx); + res = COND_EXPR::insertSubTreeLongReg (exp, &ticode->hl()->asgn.rhs, longIdx); if (res) { picode->invalidate(); @@ -599,7 +594,7 @@ static void forwardSubsLong (int longIdx, COND_EXPR *exp, iICODE picode, else { /* Try to insert it on lhs of ticode*/ - res = insertSubTreeLongReg (exp, &ticode->hl()->asgn.lhs, longIdx); + res = COND_EXPR::insertSubTreeLongReg (exp, &ticode->hl()->asgn.lhs, longIdx); if (res) { picode->invalidate(); @@ -611,21 +606,18 @@ static void forwardSubsLong (int longIdx, COND_EXPR *exp, iICODE picode, /* Returns whether the elements of the expression rhs are all x-clear from * instruction f up to instruction t. */ -static boolT xClear (COND_EXPR *rhs, iICODE f, iICODE t, iICODE lastBBinst, Function * pproc) +bool COND_EXPR::xClear (iICODE f, iICODE t, iICODE lastBBinst, Function * pproc) { iICODE i; boolT res; uint8_t regi; - if (rhs == NULL) - return false; - - switch (rhs->type) + switch (type) { case IDENTIFIER: - if (rhs->expr.ident.idType == REGISTER) + if (expr.ident.idType == REGISTER) { - regi= pproc->localId.id_arr[rhs->expr.ident.idNode.regiIdx].id.regi; + regi= pproc->localId.id_arr[expr.ident.idNode.regiIdx].id.regi; for (i = ++iICODE(f); (i != lastBBinst) && (i!=t); i++) if ((i->type == HIGH_LEVEL) && ( not i->invalid )) { @@ -644,20 +636,41 @@ static boolT xClear (COND_EXPR *rhs, iICODE f, iICODE t, iICODE lastBBinst, Func } */ case BOOLEAN_OP: - res = xClear (rhs->expr.boolExpr.rhs, f, t, lastBBinst, pproc); + if(0==rhs()) + return false; + res = rhs()->xClear ( f, t, lastBBinst, pproc); if (res == FALSE) return false; - return (xClear (rhs->expr.boolExpr.lhs, f, t, lastBBinst, pproc)); + if(0==lhs()) + return false; + return lhs()->xClear ( f, t, lastBBinst, pproc); case NEGATION: case ADDRESSOF: case DEREFERENCE: - return (xClear (rhs->expr.unaryExp, f, t, lastBBinst, pproc)); + if(0==expr.unaryExp) + return false; + return expr.unaryExp->xClear ( f, t, lastBBinst, pproc); } /* eos */ return false; } +bool UnaryOperator::xClear(iICODE f, iICODE t, iICODE lastBBinst, Function *pproc) +{ + if(0==unaryExp) + return false; + return unaryExp->xClear ( f, t, lastBBinst, pproc); +} - +bool BinaryOperator::xClear(iICODE f, iICODE t, iICODE lastBBinst, Function *pproc) +{ + if(0==m_rhs) + return false; + if ( not m_rhs->xClear (f, t, lastBBinst, pproc) ) + return false; + if(0==m_lhs) + return false; + return m_lhs->xClear (f, t, lastBBinst, pproc); +} /* Checks the type of the formal argument as against to the actual argument, * whenever possible, and then places the actual argument on the procedure's * argument list. */ @@ -711,20 +724,20 @@ void Function::processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode } else forwardSubs (picode->hl()->asgn.lhs, picode->hl()->asgn.rhs, - picode, ticode, &localId, numHlIcodes); + picode, ticode, &localId, numHlIcodes); break; case HLI_JCOND: case HLI_PUSH: case HLI_RET: if(isLong) { - res = insertSubTreeLongReg ( + res = COND_EXPR::insertSubTreeLongReg ( picode->hl()->asgn.rhs, &ticode->hl()->exp.v, picode->hl()->asgn.lhs->expr.ident.idNode.longIdx); } else { - res = insertSubTreeReg ( + res = COND_EXPR::insertSubTreeReg ( ticode->hl()->exp.v, picode->hl()->asgn.rhs, localId.id_arr[picode->hl()->asgn.lhs->expr.ident.idNode.regiIdx].id.regi, @@ -844,7 +857,7 @@ void Function::findExps() (ticode->hl()->opcode != HLI_RET))) continue; - if (xClear (picode->hl()->asgn.rhs, picode, + if (picode->hl()->asgn.rhs->xClear (picode, picode->du1.idx[0].uses[0], lastInst, this)) { processTargetIcode(picode, numHlIcodes, ticode,false); @@ -867,7 +880,7 @@ void Function::findExps() break; case HLI_JCOND: case HLI_PUSH: case HLI_RET: - res = insertSubTreeReg (ticode->hl()->exp.v, + res = COND_EXPR::insertSubTreeReg (ticode->hl()->exp.v, exp, localId.id_arr[picode->hl()->expr()->expr.ident.idNode.regiIdx].id.regi, &localId); @@ -893,12 +906,12 @@ void Function::findExps() exp = COND_EXPR::idFunc ( picode->hl()->call.proc, picode->hl()->call.args); - res = insertSubTreeReg (ticode->hl()->asgn.rhs, + res = COND_EXPR::insertSubTreeReg (ticode->hl()->asgn.rhs, exp, picode->hl()->call.proc->retVal.id.regi, &localId); if (! res) - insertSubTreeReg (ticode->hl()->asgn.lhs, + COND_EXPR::insertSubTreeReg (ticode->hl()->asgn.lhs, exp, picode->hl()->call.proc->retVal.id.regi, &localId); @@ -916,7 +929,7 @@ void Function::findExps() case HLI_JCOND: exp = COND_EXPR::idFunc ( picode->hl()->call.proc, picode->hl()->call.args); retVal = &picode->hl()->call.proc->retVal, - res = insertSubTreeReg (ticode->hl()->exp.v, + res = COND_EXPR::insertSubTreeReg (ticode->hl()->exp.v, exp, retVal->id.regi, &localId); if (res) /* was substituted */ @@ -973,7 +986,7 @@ void Function::findExps() exp, picode, ticode, &numHlIcodes); break; case HLI_JCOND: case HLI_PUSH: - res = insertSubTreeLongReg (exp, + res = COND_EXPR::insertSubTreeLongReg (exp, &ticode->hl()->exp.v, picode->hl()->asgn.lhs->expr.ident.idNode.longIdx); if (res) @@ -1010,7 +1023,7 @@ void Function::findExps() case HLI_JCOND: exp = COND_EXPR::idFunc ( picode->hl()->call.proc, picode->hl()->call.args); retVal = &picode->hl()->call.proc->retVal; - res = insertSubTreeLongReg (exp, + res = COND_EXPR::insertSubTreeLongReg (exp, &ticode->hl()->exp.v, localId.newLongReg ( retVal->type, retVal->id.longId.h, retVal->id.longId.l, picode)); diff --git a/src/hlicode.cpp b/src/hlicode.cpp index e6fdfce..9b5dee1 100644 --- a/src/hlicode.cpp +++ b/src/hlicode.cpp @@ -91,15 +91,6 @@ bool ICODE::removeDefRegi (uint8_t regi, int thisDefIdx, LOCAL_ID *locId) int numDefs; numDefs = du1.numRegsDef; - // if (numDefs == thisDefIdx) - // { - // for ( ; numDefs > 0; numDefs--) - // { - // if ((du1.idx[numDefs-1][0] != 0)||(du.lastDefRegi.any())) - // break; - // } - // } - if (numDefs == thisDefIdx) { for ( ; numDefs > 0; numDefs--) @@ -123,43 +114,195 @@ bool ICODE::removeDefRegi (uint8_t regi, int thisDefIdx, LOCAL_ID *locId) } return false; } +HLTYPE LLInst::createCall() +{ + HLTYPE res(HLI_CALL); + res.call.proc = src.proc.proc; + res.call.args = new STKFRAME; + if (src.proc.cb != 0) + res.call.args->cb = src.proc.cb; + else if(res.call.proc) + res.call.args->cb =res.call.proc->cbParam; + else + { + printf("Function with no cb set, and no valid oper.call.proc , probaby indirect call\n"); + res.call.args->cb = 0; + } + return res; +} +#if 0 +HLTYPE LLInst::toHighLevel(COND_EXPR *lhs,COND_EXPR *rhs,Function *func) +{ + HLTYPE res(HLI_INVALID); + if ( testFlags(NOT_HLL) ) + return res; + flg = getFlag(); + switch (getOpcode()) + { + case iADD: + rhs = COND_EXPR::boolOp (lhs, rhs, ADD); + res.setAsgn(lhs, rhs); + break; + + case iAND: + rhs = COND_EXPR::boolOp (lhs, rhs, AND); + res.setAsgn(lhs, rhs); + break; + + case iCALL: + case iCALLF: + //TODO: this is noop pIcode->checkHlCall(); + res=createCall(); + break; + + case iDEC: + rhs = COND_EXPR::idKte (1, 2); + rhs = COND_EXPR::boolOp (lhs, rhs, SUB); + res.setAsgn(lhs, rhs); + break; + + case iDIV: + case iIDIV:/* should be signed div */ + rhs = COND_EXPR::boolOp (lhs, rhs, DIV); + if ( ll->testFlags(B) ) + { + lhs = COND_EXPR::idReg (rAL, 0, &localId); + pIcode->setRegDU( rAL, eDEF); + } + else + { + lhs = COND_EXPR::idReg (rAX, 0, &localId); + pIcode->setRegDU( rAX, eDEF); + } + res.setAsgn(lhs, rhs); + break; + + case iIMUL: + rhs = COND_EXPR::boolOp (lhs, rhs, MUL); + lhs = COND_EXPR::id (*pIcode, LHS_OP, func, i, *pIcode, NONE); + res.setAsgn(lhs, rhs); + break; + + case iINC: + rhs = COND_EXPR::idKte (1, 2); + rhs = COND_EXPR::boolOp (lhs, rhs, ADD); + res.setAsgn(lhs, rhs); + break; + + case iLEA: + rhs = COND_EXPR::unary (ADDRESSOF, rhs); + res.setAsgn(lhs, rhs); + break; + + case iMOD: + rhs = COND_EXPR::boolOp (lhs, rhs, MOD); + if ( ll->testFlags(B) ) + { + lhs = COND_EXPR::idReg (rAH, 0, &localId); + pIcode->setRegDU( rAH, eDEF); + } + else + { + lhs = COND_EXPR::idReg (rDX, 0, &localId); + pIcode->setRegDU( rDX, eDEF); + } + res.setAsgn(lhs, rhs); + break; + + case iMOV: res.setAsgn(lhs, rhs); + break; + + case iMUL: + rhs = COND_EXPR::boolOp (lhs, rhs, MUL); + lhs = COND_EXPR::id (*pIcode, LHS_OP, this, i, *pIcode, NONE); + res.setAsgn(lhs, rhs); + break; + + case iNEG: + rhs = COND_EXPR::unary (NEGATION, lhs); + res.setAsgn(lhs, rhs); + break; + + case iNOT: + rhs = COND_EXPR::boolOp (NULL, rhs, NOT); + res.setAsgn(lhs, rhs); + break; + + case iOR: + rhs = COND_EXPR::boolOp (lhs, rhs, OR); + res.setAsgn(lhs, rhs); + break; + + case iPOP: res.set(HLI_POP, lhs); + break; + + case iPUSH: res.set(HLI_PUSH, lhs); + break; + + case iRET: + case iRETF: + res.set(HLI_RET, NULL); + break; + + case iSHL: + rhs = COND_EXPR::boolOp (lhs, rhs, SHL); + res.setAsgn(lhs, rhs); + break; + + case iSAR: /* signed */ + case iSHR: + rhs = COND_EXPR::boolOp (lhs, rhs, SHR); /* unsigned*/ + res.setAsgn(lhs, rhs); + break; + + case iSIGNEX: + res.setAsgn(lhs, rhs); + break; + + case iSUB: + rhs = COND_EXPR::boolOp (lhs, rhs, SUB); + res.setAsgn(lhs, rhs); + break; + + case iXCHG: + break; + + case iXOR: + rhs = COND_EXPR::boolOp (lhs, rhs, XOR); + res.setAsgn(lhs, rhs); + break; + } + return res; +} +#endif /* Translates LOW_LEVEL icodes to HIGH_LEVEL icodes - 1st stage. * Note: this process should be done before data flow analysis, which * refines the HIGH_LEVEL icodes. */ void Function::highLevelGen() { - int i, /* idx into icode array */ - numIcode; /* number of icode instructions */ + int numIcode; /* number of icode instructions */ iICODE pIcode; /* ptr to current icode node */ COND_EXPR *lhs, *rhs; /* left- and right-hand side of expression */ uint32_t flg; /* icode flags */ - iICODE prev_ic=Icode.end(); numIcode = Icode.size(); for (iICODE i = Icode.begin(); i!=Icode.end() ; ++i) { assert(numIcode==Icode.size()); - if(i!=Icode.begin()) - prev_ic = --iICODE(i); pIcode = i; //Icode.GetIcode(i) LLInst *ll = pIcode->ll(); if ( ll->testFlags(NOT_HLL) ) pIcode->invalidate(); - if ((pIcode->type == LOW_LEVEL) && pIcode->valid() ) - { + if ((pIcode->type != LOW_LEVEL) or not pIcode->valid() ) + continue; flg = ll->getFlag(); if ((flg & IM_OPS) != IM_OPS) /* not processing IM_OPS yet */ if ((flg & NO_OPS) != NO_OPS) /* if there are opers */ { if ( not ll->testFlags(NO_SRC) ) /* if there is src op */ - rhs = COND_EXPR::id (*pIcode, SRC, this, i, *pIcode, NONE); - lhs = COND_EXPR::id (*pIcode, DST, this, i, *pIcode, NONE); - } - if(prev_ic!=Icode.end()) - { - ICODE &iz(*prev_ic); - assert(iz.type!=NOT_SCANNED); + rhs = COND_EXPR::id (*pIcode->ll(), SRC, this, i, *pIcode, NONE); + lhs = COND_EXPR::id (*pIcode->ll(), DST, this, i, *pIcode, NONE); } switch (ll->getOpcode()) @@ -176,8 +319,8 @@ void Function::highLevelGen() case iCALL: case iCALLF: - pIcode->checkHlCall(); - pIcode->newCallHl(); + pIcode->type = HIGH_LEVEL; + pIcode->hl( ll->createCall() ); break; case iDEC: @@ -204,7 +347,7 @@ void Function::highLevelGen() case iIMUL: rhs = COND_EXPR::boolOp (lhs, rhs, MUL); - lhs = COND_EXPR::id (*pIcode, LHS_OP, this, i, *pIcode, NONE); + lhs = COND_EXPR::id (*ll, LHS_OP, this, i, *pIcode, NONE); pIcode->setAsgn(lhs, rhs); break; @@ -239,7 +382,7 @@ void Function::highLevelGen() case iMUL: rhs = COND_EXPR::boolOp (lhs, rhs, MUL); - lhs = COND_EXPR::id (*pIcode, LHS_OP, this, i, *pIcode, NONE); + lhs = COND_EXPR::id (*ll, LHS_OP, this, i, *pIcode, NONE); pIcode->setAsgn(lhs, rhs); break; @@ -281,7 +424,8 @@ void Function::highLevelGen() case iSIGNEX: pIcode->setAsgn(lhs, rhs); break; - case iSUB: rhs = COND_EXPR::boolOp (lhs, rhs, SUB); + case iSUB: + rhs = COND_EXPR::boolOp (lhs, rhs, SUB); pIcode->setAsgn(lhs, rhs); break; @@ -293,8 +437,6 @@ void Function::highLevelGen() pIcode->setAsgn(lhs, rhs); break; } - } - } } @@ -312,12 +454,12 @@ COND_EXPR *COND_EXPR::inverse () COND_EXPR *res=0; if (type == BOOLEAN_OP) { - switch (expr.boolExpr.op) + switch ( op() ) { case LESS_EQUAL: case LESS: case EQUAL: case NOT_EQUAL: case GREATER: case GREATER_EQUAL: res = this->clone(); - res->expr.boolExpr.op = invCondOp[expr.boolExpr.op]; + res->boolExpr.op = invCondOp[op()]; return res; case AND: case OR: case XOR: case NOT: case ADD: @@ -326,9 +468,9 @@ COND_EXPR *COND_EXPR::inverse () case DBL_AND: case DBL_OR: 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 (); + res->boolExpr.op = invCondOp[op()]; + res->boolExpr.lhs=lhs()->inverse (); + res->boolExpr.rhs=rhs()->inverse (); return res; } /* eos */ diff --git a/src/idioms/arith_idioms.cpp b/src/idioms/arith_idioms.cpp index 4e7b927..bf07eb2 100644 --- a/src/idioms/arith_idioms.cpp +++ b/src/idioms/arith_idioms.cpp @@ -162,9 +162,9 @@ int Idiom18::action() // action length { COND_EXPR *rhs, *lhs; /* Pointers to left and right hand side exps */ COND_EXPR *expr; - lhs = COND_EXPR::id (*m_icodes[0], SRC, m_func, m_icodes[1], *m_icodes[1], eUSE); + lhs = COND_EXPR::id (*m_icodes[0]->ll(), SRC, m_func, m_icodes[1], *m_icodes[1], eUSE); lhs = COND_EXPR::unary ( m_is_dec ? POST_DEC : POST_INC, lhs); - rhs = COND_EXPR::id (*m_icodes[2], SRC, m_func, m_icodes[1], *m_icodes[3], eUSE); + rhs = COND_EXPR::id (*m_icodes[2]->ll(), SRC, m_func, m_icodes[1], *m_icodes[3], eUSE); expr = COND_EXPR::boolOp (lhs, rhs, condOpJCond[m_icodes[3]->ll()->getOpcode() - iJB]); m_icodes[3]->setJCond(expr); @@ -213,7 +213,7 @@ bool Idiom19::match(iICODE picode) int Idiom19::action() { COND_EXPR *lhs,*rhs,*expr; - lhs = COND_EXPR::id (*m_icodes[1], DST, m_func, m_icodes[0], *m_icodes[1], eUSE); + lhs = COND_EXPR::id (*m_icodes[1]->ll(), DST, m_func, m_icodes[0], *m_icodes[1], eUSE); lhs = COND_EXPR::unary (m_is_dec ? PRE_DEC : PRE_INC, lhs); rhs = COND_EXPR::idKte (0, 2); expr = COND_EXPR::boolOp (lhs, rhs, condOpJCond[m_icodes[1]->ll()->getOpcode() - iJB]); @@ -302,9 +302,9 @@ bool Idiom20::match(iICODE picode) int Idiom20::action() { COND_EXPR *lhs,*rhs,*expr; - lhs = COND_EXPR::id (*m_icodes[1], SRC, m_func, m_icodes[0], *m_icodes[0], eUSE); + lhs = COND_EXPR::id (*m_icodes[1]->ll(), SRC, m_func, m_icodes[0], *m_icodes[0], eUSE); lhs = COND_EXPR::unary (m_is_dec ? PRE_DEC : PRE_INC, lhs); - rhs = COND_EXPR::id (*m_icodes[2], SRC, m_func, m_icodes[0], *m_icodes[3], eUSE); + rhs = COND_EXPR::id (*m_icodes[2]->ll(), SRC, m_func, m_icodes[0], *m_icodes[3], eUSE); expr = COND_EXPR::boolOp (lhs, rhs, condOpJCond[m_icodes[3]->ll()->getOpcode() - iJB]); m_icodes[3]->setJCond(expr); for(int i=0; i<3; ++i) diff --git a/src/idioms/mov_idioms.cpp b/src/idioms/mov_idioms.cpp index e76a50b..9db2a75 100644 --- a/src/idioms/mov_idioms.cpp +++ b/src/idioms/mov_idioms.cpp @@ -53,7 +53,7 @@ int Idiom14::action() idx = m_func->localId.newLongReg (TYPE_LONG_SIGN, m_regH, m_regL, m_icodes[0]); lhs = COND_EXPR::idLongIdx (idx); m_icodes[0]->setRegDU( m_regH, eDEF); - rhs = COND_EXPR::id (*m_icodes[0], SRC, m_func, m_icodes[0], *m_icodes[0], NONE); + rhs = COND_EXPR::id (*m_icodes[0]->ll(), SRC, m_func, m_icodes[0], *m_icodes[0], NONE); m_icodes[0]->setAsgn(lhs, rhs); m_icodes[1]->invalidate(); return 2; @@ -102,7 +102,7 @@ int Idiom13::action() lhs = COND_EXPR::idReg (m_loaded_reg, 0, &m_func->localId); m_icodes[0]->setRegDU( m_loaded_reg, eDEF); m_icodes[0]->du1.numRegsDef--; /* prev uint8_t reg def */ - rhs = COND_EXPR::id (*m_icodes[0], SRC, m_func, m_icodes[0], *m_icodes[0], NONE); + rhs = COND_EXPR::id (*m_icodes[0]->ll(), SRC, m_func, m_icodes[0], *m_icodes[0], NONE); m_icodes[0]->setAsgn(lhs, rhs); m_icodes[1]->invalidate(); return 2; diff --git a/src/idioms/xor_idioms.cpp b/src/idioms/xor_idioms.cpp index ffae260..28c95c2 100644 --- a/src/idioms/xor_idioms.cpp +++ b/src/idioms/xor_idioms.cpp @@ -83,7 +83,7 @@ bool Idiom7::match(iICODE picode) int Idiom7::action() { COND_EXPR *lhs,*rhs; - lhs = COND_EXPR::id (*m_icode, DST, m_func, m_icode, *m_icode, NONE); + lhs = COND_EXPR::id (*m_icode->ll(), DST, m_func, m_icode, *m_icode, NONE); rhs = COND_EXPR::idKte (0, 2); m_icode->setAsgn(lhs, rhs); m_icode->du.use = 0; /* clear register used in iXOR */