COND_EXPR splitting preparations

This commit is contained in:
Artur K 2012-03-06 08:35:45 +01:00
parent d7ddc86d76
commit ddd501de1f
10 changed files with 443 additions and 151 deletions

View File

@ -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 */

View File

@ -27,6 +27,7 @@ struct Function;
struct STKFRAME;
struct LOCAL_ID;
struct ICODE;
struct LLInst;
struct ID;
typedef std::list<ICODE>::iterator iICODE;
#include "IdentType.h"
@ -34,19 +35,42 @@ typedef std::list<ICODE>::iterator iICODE;
/* Expression data type */
struct COND_EXPR
{
condNodeType type; /* Conditional Expression Node Type */
union _exprNode { /* Different cond expr nodes */
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 */
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
{};

View File

@ -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 */

View File

@ -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);

View File

@ -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<BinaryOperator *>(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<BinaryOperator *>(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();
}

View File

@ -6,10 +6,14 @@
****************************************************************************/
#include "dcc.h"
#include <boost/range.hpp>
#include <boost/range/adaptors.hpp>
#include <boost/range/algorithm.hpp>
#include <string.h>
#include <iostream>
#include <iomanip>
#include <stdio.h>
using namespace boost;
struct ExpStack
{
typedef std::list<COND_EXPR *> 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. */
@ -717,14 +730,14 @@ void Function::processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode
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));

View File

@ -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;
@ -295,8 +439,6 @@ void Function::highLevelGen()
}
}
}
}
@ -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 */

View File

@ -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)

View File

@ -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;

View File

@ -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 */