Replaced a few places which used ICODE * in favour of ICODE &, also split HLTYPE attriubtes into 3 classes with virtual methods
This commit is contained in:
parent
e0503c71a3
commit
493225ad64
@ -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);
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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);
|
||||
|
||||
137
src/dataflow.cpp
137
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);
|
||||
}
|
||||
}
|
||||
|
||||
182
src/hlicode.cpp
182
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
251
src/parser.cpp
251
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;
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -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 */
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user