Fixed synthetic instructions for DIV and XCHG to handle Byte wide operations, and also in case of XCHG memory, also fixed assembly generation for IN/OUT operations and all string instructions MOVS etc.

This commit is contained in:
Artur K
2012-03-04 00:30:53 +01:00
parent 32d1b71e79
commit d7ddc86d76
11 changed files with 405 additions and 361 deletions

View File

@@ -133,7 +133,10 @@ COND_EXPR *COND_EXPR::idGlob (int16_t segValue, int16_t off)
if (symtab[i].label == adr)
break;
if (i == symtab.size())
{
printf ("Error, glob var not found in symtab\n");
return 0;
}
newExp->expr.ident.idNode.globIdx = i;
return (newExp);
}
@@ -824,48 +827,48 @@ void COND_EXPR::changeBoolOp (condOp newOp)
expr.boolExpr.op = newOp;
}
/* Inserts the expression exp into the tree at the location specified by the
* register regi */
bool insertSubTreeReg (COND_EXPR *expr, COND_EXPR **tree, uint8_t regi,LOCAL_ID *locsym)
bool insertSubTreeReg (COND_EXPR *&tree, COND_EXPR *expr, uint8_t regi,LOCAL_ID *locsym)
{
HlTypeSupport *set_val;
uint8_t treeReg;
if (*tree == NULL)
return FALSE;
if (tree == NULL)
return false;
switch ((*tree)->type) {
switch (tree->type) {
case IDENTIFIER:
if ((*tree)->expr.ident.idType == REGISTER)
if (tree->expr.ident.idType == REGISTER)
{
treeReg = locsym->id_arr[(*tree)->expr.ident.idNode.regiIdx].id.regi;
treeReg = locsym->id_arr[tree->expr.ident.idNode.regiIdx].id.regi;
if (treeReg == regi) /* uint16_t reg */
{
*tree = expr;
return TRUE;
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;
return TRUE;
tree = expr;
return true;
}
}
}
return FALSE;
case BOOLEAN_OP:
if (insertSubTreeReg (expr, &(*tree)->expr.boolExpr.lhs, regi, locsym))
return TRUE;
if (insertSubTreeReg (expr, &(*tree)->expr.boolExpr.rhs, regi, locsym))
return TRUE;
return FALSE;
if (insertSubTreeReg (tree->expr.boolExpr.lhs, expr, regi, locsym))
return true;
if (insertSubTreeReg (tree->expr.boolExpr.rhs, expr, regi, locsym))
return true;
return false;
case NEGATION:
case ADDRESSOF:
case DEREFERENCE:
if (insertSubTreeReg(expr, &(*tree)->expr.unaryExp,regi, locsym))
if (insertSubTreeReg(tree->expr.unaryExp, expr, regi, locsym))
return TRUE;
return FALSE;
}

View File

@@ -556,7 +556,7 @@ static void forwardSubs (COND_EXPR *lhs, COND_EXPR *rhs, iICODE picode,
return;
/* Insert on rhs of ticode, if possible */
res = insertSubTreeReg (rhs, &ticode->hl()->asgn.rhs,
res = insertSubTreeReg (ticode->hl()->asgn.rhs,rhs,
locsym->id_arr[lhs->expr.ident.idNode.regiIdx].id.regi,
locsym);
if (res)
@@ -567,7 +567,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->hl()->asgn.lhs,
res = insertSubTreeReg (ticode->hl()->asgn.lhs,rhs,
locsym->id_arr[lhs->expr.ident.idNode.regiIdx].id.regi,
locsym);
if (res)
@@ -698,9 +698,101 @@ static void processCArg (Function * pp, Function * pProc, ICODE * picode, int nu
/** Eliminates extraneous intermediate icode instructions when finding
* expressions. Generates new hlIcodes in the form of expression trees.
* For HLI_CALL hlIcodes, places the arguments in the argument list. */
void Function::processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode,bool isLong)
{
boolT res;
switch (ticode->hl()->opcode) {
case HLI_ASSIGN:
if(isLong)
{
forwardSubsLong (picode->hl()->asgn.lhs->expr.ident.idNode.longIdx,
picode->hl()->asgn.rhs, picode,ticode,
&numHlIcodes);
}
else
forwardSubs (picode->hl()->asgn.lhs, picode->hl()->asgn.rhs,
picode, ticode, &localId, numHlIcodes);
break;
case HLI_JCOND: case HLI_PUSH: case HLI_RET:
if(isLong)
{
res = insertSubTreeLongReg (
picode->hl()->asgn.rhs,
&ticode->hl()->exp.v,
picode->hl()->asgn.lhs->expr.ident.idNode.longIdx);
}
else
{
res = insertSubTreeReg (
ticode->hl()->exp.v,
picode->hl()->asgn.rhs,
localId.id_arr[picode->hl()->asgn.lhs->expr.ident.idNode.regiIdx].id.regi,
&localId);
}
if (res)
{
picode->invalidate();
numHlIcodes--;
}
break;
case HLI_CALL: /* register arguments */
newRegArg ( picode, ticode);
picode->invalidate();
numHlIcodes--;
break;
}
}
void Function::processHliCall1(COND_EXPR *exp, iICODE picode)
{
Function * pp;
int cb, numArgs;
boolT res;
int k;
pp = picode->hl()->call.proc;
if (pp->flg & CALL_PASCAL)
{
cb = pp->cbParam; /* fixed # arguments */
for (k = 0, numArgs = 0; k < cb; numArgs++)
{
exp = g_exp_stk.pop();
if (pp->flg & PROC_ISLIB) /* library function */
{
if (pp->args.numArgs > 0)
adjustActArgType(exp, pp->args.sym[numArgs].type, this);
res = picode->newStkArg (exp, picode->ll()->getOpcode(), this);
}
else /* user function */
{
if (pp->args.numArgs >0)
pp->args.adjustForArgType (numArgs,expType (exp, this));
res = picode->newStkArg (exp,picode->ll()->getOpcode(), this);
}
if (res == FALSE)
k += hlTypeSize (exp, this);
}
}
else /* CALL_C */
{
cb = picode->hl()->call.args->cb;
numArgs = 0;
if (cb)
for (k = 0; k < cb; numArgs++)
processCArg (pp, this, &(*picode), numArgs, &k);
else if ((cb == 0) && picode->ll()->testFlags(REST_STK))
while (! g_exp_stk.empty())
{
processCArg (pp, this, &(*picode), numArgs, &k);
numArgs++;
}
}
}
void Function::findExps()
{
int i, k, numHlIcodes;
int i, numHlIcodes;
iICODE lastInst,
picode, // Current icode */
ticode; // Target icode */
@@ -755,33 +847,7 @@ void Function::findExps()
if (xClear (picode->hl()->asgn.rhs, picode,
picode->du1.idx[0].uses[0], lastInst, this))
{
switch (ticode->hl()->opcode) {
case HLI_ASSIGN:
forwardSubs (picode->hl()->asgn.lhs,
picode->hl()->asgn.rhs,
picode, ticode, &localId,
numHlIcodes);
break;
case HLI_JCOND: case HLI_PUSH: case HLI_RET:
res = insertSubTreeReg (
picode->hl()->asgn.rhs,
&ticode->hl()->exp.v,
localId.id_arr[picode->hl()->asgn.lhs->expr.ident.idNode.regiIdx].id.regi,
&localId);
if (res)
{
picode->invalidate();
numHlIcodes--;
}
break;
case HLI_CALL: /* register arguments */
newRegArg (picode, ticode);
picode->invalidate();
numHlIcodes--;
break;
} /* eos */
processTargetIcode(picode, numHlIcodes, ticode,false);
}
break;
@@ -801,8 +867,8 @@ void Function::findExps()
break;
case HLI_JCOND: case HLI_PUSH: case HLI_RET:
res = insertSubTreeReg (exp,
&ticode->hl()->exp.v,
res = insertSubTreeReg (ticode->hl()->exp.v,
exp,
localId.id_arr[picode->hl()->expr()->expr.ident.idNode.regiIdx].id.regi,
&localId);
if (res)
@@ -827,13 +893,13 @@ void Function::findExps()
exp = COND_EXPR::idFunc (
picode->hl()->call.proc,
picode->hl()->call.args);
res = insertSubTreeReg (exp,
&ticode->hl()->asgn.rhs,
res = insertSubTreeReg (ticode->hl()->asgn.rhs,
exp,
picode->hl()->call.proc->retVal.id.regi,
&localId);
if (! res)
insertSubTreeReg (exp,
&ticode->hl()->asgn.lhs,
insertSubTreeReg (ticode->hl()->asgn.lhs,
exp,
picode->hl()->call.proc->retVal.id.regi,
&localId);
/*** TODO: HERE missing: 2 regs ****/
@@ -850,8 +916,8 @@ 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 (exp,
&ticode->hl()->exp.v,
res = insertSubTreeReg (ticode->hl()->exp.v,
exp,
retVal->id.regi, &localId);
if (res) /* was substituted */
{
@@ -887,32 +953,7 @@ void Function::findExps()
((ticode->hl()->opcode != HLI_CALL) &&
(ticode->hl()->opcode != HLI_RET)))
continue;
switch (ticode->hl()->opcode) {
case HLI_ASSIGN:
forwardSubsLong (picode->hl()->asgn.lhs->expr.ident.idNode.longIdx,
picode->hl()->asgn.rhs, picode,ticode,
&numHlIcodes);
break;
case HLI_JCOND: case HLI_PUSH: case HLI_RET:
res = insertSubTreeLongReg (
picode->hl()->asgn.rhs,
&ticode->hl()->exp.v,
picode->hl()->asgn.lhs->expr.ident.idNode.longIdx);
if (res)
{
picode->invalidate();
numHlIcodes--;
}
break;
case HLI_CALL: /* register arguments */
newRegArg ( picode, ticode);
picode->invalidate();
numHlIcodes--;
break;
} /* eos */
processTargetIcode(picode, numHlIcodes, ticode,true);
}
break;
@@ -1000,51 +1041,12 @@ void Function::findExps()
}
/* For HLI_CALL instructions that use arguments from the stack,
* pop them from the expression stack and place them on the
* procedure's argument list */
if ((picode->hl()->opcode == HLI_CALL) &&
! (picode->hl()->call.proc->flg & REG_ARGS))
{ Function * pp;
int cb, numArgs;
boolT res;
* pop them from the expression stack and place them on the
* procedure's argument list */
pp = picode->hl()->call.proc;
if (pp->flg & CALL_PASCAL)
{
cb = pp->cbParam; /* fixed # arguments */
for (k = 0, numArgs = 0; k < cb; numArgs++)
{
exp = g_exp_stk.pop();
if (pp->flg & PROC_ISLIB) /* library function */
{
if (pp->args.numArgs > 0)
adjustActArgType(exp, pp->args.sym[numArgs].type, this);
res = picode->newStkArg (exp, picode->ll()->getOpcode(), this);
}
else /* user function */
{
if (pp->args.numArgs >0)
pp->args.adjustForArgType (numArgs,expType (exp, this));
res = picode->newStkArg (exp,picode->ll()->getOpcode(), this);
}
if (res == FALSE)
k += hlTypeSize (exp, this);
}
}
else /* CALL_C */
{
cb = picode->hl()->call.args->cb;
numArgs = 0;
if (cb)
for (k = 0; k < cb; numArgs++)
processCArg (pp, this, &(*picode), numArgs, &k);
else if ((cb == 0) && picode->ll()->testFlags(REST_STK))
while (! g_exp_stk.empty())
{
processCArg (pp, this, &(*picode), numArgs, &k);
numArgs++;
}
}
if ((picode->hl()->opcode == HLI_CALL) && ! (picode->hl()->call.proc->flg & REG_ARGS))
{
processHliCall1(exp, picode);
}
/* If we could not substitute the result of a function,

View File

@@ -271,6 +271,8 @@ void LLInst::dis1Line(int loc_ip, int pass)
ostringstream oper_stream;
ostringstream hex_bytes;
ostringstream result_stream;
ostringstream opcode_with_mods;
ostringstream operands_s;
oper_stream << uppercase;
hex_bytes << uppercase;
@@ -338,59 +340,59 @@ void LLInst::dis1Line(int loc_ip, int pass)
{
opcode = iCBW;
}
oper_stream << setw(15) << left <<szOps[opcode];
opcode_with_mods<<szOps[opcode];
switch (opcode)
{
case iADD: case iADC: case iSUB: case iSBB: case iAND: case iOR:
case iXOR: case iTEST: case iCMP: case iMOV: case iLEA: case iXCHG:
strDst(oper_stream,getFlag(), dst);
strSrc(oper_stream);
strDst(operands_s,getFlag(), dst);
strSrc(operands_s);
break;
case iESC:
flops(oper_stream);
flops(operands_s);
break;
case iSAR: case iSHL: case iSHR: case iRCL: case iRCR: case iROL:
case iROR:
strDst(oper_stream,getFlag() | I, dst);
strDst(operands_s,getFlag() | I, dst);
if(testFlags(I))
strSrc(oper_stream);
strSrc(operands_s);
else
oper_stream<<", cl";
operands_s<<", cl";
break;
case iINC: case iDEC: case iNEG: case iNOT: case iPOP:
strDst(oper_stream,getFlag() | I, dst);
strDst(operands_s,getFlag() | I, dst);
break;
case iPUSH:
if (testFlags(I))
{
oper_stream<<strHex(src.op());
operands_s<<strHex(src.op());
// strcpy(p + WID_PTR, strHex(pIcode->ll()->immed.op));
}
else
{
strDst(oper_stream,getFlag() | I, dst);
strDst(operands_s,getFlag() | I, dst);
}
break;
case iDIV: case iIDIV: case iMUL: case iIMUL: case iMOD:
if (testFlags(I))
{
strDst(oper_stream,getFlag(), dst) <<", ";
formatRM(oper_stream, getFlag(), src);
strSrc(oper_stream);
strDst(operands_s,getFlag(), dst) <<", ";
formatRM(operands_s, getFlag(), src);
strSrc(operands_s);
}
else
strDst(oper_stream,getFlag() | I, src);
strDst(operands_s,getFlag() | I, src);
break;
case iLDS: case iLES: case iBOUND:
strDst(oper_stream,getFlag(), dst)<<", dword ptr";
strSrc(oper_stream,true);
strDst(operands_s,getFlag(), dst)<<", dword ptr";
strSrc(operands_s,true);
break;
case iJB: case iJBE: case iJAE: case iJA:
@@ -405,7 +407,7 @@ void LLInst::dis1Line(int loc_ip, int pass)
ICODE *lab=pc.GetIcode(src.op());
selectTable(Label);
if ((src.op() < (uint32_t)numIcode) && /* Ensure in range */
readVal(oper_stream, lab->ll()->label, 0))
readVal(operands_s, lab->ll()->label, 0))
{
break; /* Symbolic label. Done */
}
@@ -414,7 +416,7 @@ void LLInst::dis1Line(int loc_ip, int pass)
if (testFlags(NO_LABEL))
{
//strcpy(p + WID_PTR, strHex(pIcode->ll()->immed.op));
oper_stream<<strHex(src.op());
operands_s<<strHex(src.op());
}
else if (testFlags(I) )
{
@@ -425,18 +427,18 @@ void LLInst::dis1Line(int loc_ip, int pass)
}
if (opcode == iJMPF)
{
oper_stream<<" far ptr ";
operands_s<<" far ptr ";
}
oper_stream<<"L"<<pl[j];
operands_s<<"L"<<pl[j];
}
else if (opcode == iJMPF)
{
oper_stream<<"dword ptr";
strSrc(oper_stream,true);
operands_s<<"dword ptr";
strSrc(operands_s,true);
}
else
{
strDst(oper_stream,I, src);
strDst(operands_s,I, src);
}
break;
@@ -444,29 +446,29 @@ void LLInst::dis1Line(int loc_ip, int pass)
if (testFlags(I))
{
if((opcode == iCALL))
oper_stream<< "near";
operands_s<< "near";
else
oper_stream<< " far";
oper_stream<<" ptr "<<(src.proc.proc)->name;
operands_s<< " far";
operands_s<<" ptr "<<(src.proc.proc)->name;
}
else if (opcode == iCALLF)
{
oper_stream<<"dword ptr ";
strSrc(oper_stream,true);
operands_s<<"dword ptr ";
strSrc(operands_s,true);
}
else
strDst(oper_stream,I, src);
strDst(operands_s,I, src);
break;
case iENTER:
oper_stream<<strHex(dst.off)<<", ";
oper_stream<<strHex(src.op());
operands_s<<strHex(dst.off)<<", ";
operands_s<<strHex(src.op());
break;
case iRET: case iRETF: case iINT:
if (testFlags(I))
{
oper_stream<<strHex(src.op());
operands_s<<strHex(src.op());
}
break;
@@ -481,48 +483,54 @@ void LLInst::dis1Line(int loc_ip, int pass)
{
bool is_dx_src=(opcode == iOUTS || opcode == iREP_OUTS);
if(is_dx_src)
oper_stream<<"dx, "<<szPtr[getFlag() & B];
operands_s<<"dx, "<<szPtr[getFlag() & B];
else
oper_stream<<szPtr[getFlag() & B];
operands_s<<szPtr[getFlag() & B];
if (opcode == iLODS ||
opcode == iREP_LODS ||
opcode == iOUTS ||
opcode == iREP_OUTS)
{
oper_stream<<szWreg[src.segOver-rAX];
operands_s<<szWreg[src.segOver-rAX];
}
else
{
oper_stream<<"es:[di], "<<szWreg[src.segOver - rAX];
operands_s<<"es:[di], "<<szWreg[src.segOver - rAX];
}
oper_stream<<":[si]";
operands_s<<":[si]";
}
else
oper_stream<<(getFlag() & B)? "B": "W";
break;
{
(getFlag() & B)? opcode_with_mods<< "B": opcode_with_mods<< "W";
}
break;
case iXLAT:
if (src.segOver)
{
oper_stream<<" "<<szPtr[1];
oper_stream<<szWreg[src.segOver-rAX]<<":[bx]";
operands_s<<" "<<szPtr[1];
operands_s<<szWreg[src.segOver-rAX]<<":[bx]";
}
break;
case iIN:
oper_stream<<(getFlag() & B)?"al, ": "ax, ";
oper_stream<<(testFlags(I))? strHex(src.op()): "dx";
(getFlag() & B)? operands_s<<"al, " : operands_s<< "ax, ";
(testFlags(I))? operands_s << strHex(src.op()) : operands_s<< "dx";
break;
case iOUT:
oper_stream<<(testFlags(I))? strHex(src.op()): "dx";
oper_stream<<(getFlag() & B)?", al": ", ax";
break;
{
std::string d1=((testFlags(I))? strHex(src.op()): "dx");
std::string d2=((getFlag() & B) ? ", al": ", ax");
operands_s<<d1 << d2;
}
break;
default:
break;
}
oper_stream << setw(15) << left <<opcode_with_mods.str();
oper_stream << operands_s.str();
/* Comments */
if (testFlags(SYNTHETIC))
{

View File

@@ -14,14 +14,14 @@ using namespace std;
/* Masks off bits set by duReg[] */
uint32_t maskDuReg[] = { 0x00,
0xFEEFFE, 0xFDDFFD, 0xFBB00B, 0xF77007, /* uint16_t regs */
0xFFFFEF, 0xFFFFDF, 0xFFFFBF, 0xFFFF7F,
0xFFFEFF, 0xFFFDFF, 0xFFFBFF, 0xFFF7FF, /* seg regs */
0xFFEFFF, 0xFFDFFF, 0xFFBFFF, 0xFF7FFF, /* uint8_t regs */
0xFEFFFF, 0xFDFFFF, 0xFBFFFF, 0xF7FFFF,
0xEFFFFF, /* tmp reg */
0xFFFFB7, 0xFFFF77, 0xFFFF9F, 0xFFFF5F, /* index regs */
0xFFFFBF, 0xFFFF7F, 0xFFFFDF, 0xFFFFF7 };
0xFEEFFE, 0xFDDFFD, 0xFBB00B, 0xF77007, /* uint16_t regs */
0xFFFFEF, 0xFFFFDF, 0xFFFFBF, 0xFFFF7F,
0xFFFEFF, 0xFFFDFF, 0xFFFBFF, 0xFFF7FF, /* seg regs */
0xFFEFFF, 0xFFDFFF, 0xFFBFFF, 0xFF7FFF, /* uint8_t regs */
0xFEFFFF, 0xFDFFFF, 0xFBFFFF, 0xF7FFFF,
0xEFFFFF, /* tmp reg */
0xFFFFB7, 0xFFFF77, 0xFFFF9F, 0xFFFF5F, /* index regs */
0xFFFFBF, 0xFFFF7F, 0xFFFFDF, 0xFFFFF7 };
static char buf[lineSize]; /* Line buffer for hl icode output */
@@ -91,14 +91,14 @@ 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--)
// {
// if ((du1.idx[numDefs-1][0] != 0)||(du.lastDefRegi.any()))
// break;
// }
// }
if (numDefs == thisDefIdx)
{
@@ -129,16 +129,19 @@ bool ICODE::removeDefRegi (uint8_t regi, int thisDefIdx, LOCAL_ID *locId)
* 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 */
{
int i, /* idx into icode array */
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) )
@@ -149,141 +152,146 @@ void Function::highLevelGen()
if ((flg & IM_OPS) != IM_OPS) /* not processing IM_OPS yet */
if ((flg & NO_OPS) != NO_OPS) /* if there are opers */
{
if ((flg & NO_SRC) != NO_SRC) /* if there is src op */
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);
}
switch (ll->getOpcode())
{
case iADD:
rhs = COND_EXPR::boolOp (lhs, rhs, ADD);
pIcode->setAsgn(lhs, rhs);
break;
case iADD:
rhs = COND_EXPR::boolOp (lhs, rhs, ADD);
pIcode->setAsgn(lhs, rhs);
break;
case iAND:
rhs = COND_EXPR::boolOp (lhs, rhs, AND);
pIcode->setAsgn(lhs, rhs);
break;
case iAND:
rhs = COND_EXPR::boolOp (lhs, rhs, AND);
pIcode->setAsgn(lhs, rhs);
break;
case iCALL:
case iCALLF:
pIcode->checkHlCall();
pIcode->newCallHl();
break;
case iCALL:
case iCALLF:
pIcode->checkHlCall();
pIcode->newCallHl();
break;
case iDEC:
rhs = COND_EXPR::idKte (1, 2);
rhs = COND_EXPR::boolOp (lhs, rhs, SUB);
pIcode->setAsgn(lhs, rhs);
break;
case iDEC:
rhs = COND_EXPR::idKte (1, 2);
rhs = COND_EXPR::boolOp (lhs, rhs, SUB);
pIcode->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);
}
pIcode->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);
}
pIcode->setAsgn(lhs, rhs);
break;
case iIMUL:
rhs = COND_EXPR::boolOp (lhs, rhs, MUL);
lhs = COND_EXPR::id (*pIcode, LHS_OP, this, i, *pIcode, NONE);
pIcode->setAsgn(lhs, rhs);
break;
case iIMUL:
rhs = COND_EXPR::boolOp (lhs, rhs, MUL);
lhs = COND_EXPR::id (*pIcode, LHS_OP, this, i, *pIcode, NONE);
pIcode->setAsgn(lhs, rhs);
break;
case iINC:
rhs = COND_EXPR::idKte (1, 2);
rhs = COND_EXPR::boolOp (lhs, rhs, ADD);
pIcode->setAsgn(lhs, rhs);
break;
case iINC:
rhs = COND_EXPR::idKte (1, 2);
rhs = COND_EXPR::boolOp (lhs, rhs, ADD);
pIcode->setAsgn(lhs, rhs);
break;
case iLEA:
rhs = COND_EXPR::unary (ADDRESSOF, rhs);
pIcode->setAsgn(lhs, rhs);
break;
case iLEA:
rhs = COND_EXPR::unary (ADDRESSOF, rhs);
pIcode->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);
}
pIcode->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);
}
pIcode->setAsgn(lhs, rhs);
break;
case iMOV: pIcode->setAsgn(lhs, rhs);
break;
case iMOV: pIcode->setAsgn(lhs, rhs);
break;
case iMUL:
rhs = COND_EXPR::boolOp (lhs, rhs, MUL);
lhs = COND_EXPR::id (*pIcode, LHS_OP, this, i, *pIcode, NONE);
pIcode->setAsgn(lhs, rhs);
break;
case iMUL:
rhs = COND_EXPR::boolOp (lhs, rhs, MUL);
lhs = COND_EXPR::id (*pIcode, LHS_OP, this, i, *pIcode, NONE);
pIcode->setAsgn(lhs, rhs);
break;
case iNEG: rhs = COND_EXPR::unary (NEGATION, lhs);
pIcode->setAsgn(lhs, rhs);
break;
case iNEG: rhs = COND_EXPR::unary (NEGATION, lhs);
pIcode->setAsgn(lhs, rhs);
break;
case iNOT:
rhs = COND_EXPR::boolOp (NULL, rhs, NOT);
pIcode->setAsgn(lhs, rhs);
break;
case iNOT:
rhs = COND_EXPR::boolOp (NULL, rhs, NOT);
pIcode->setAsgn(lhs, rhs);
break;
case iOR:
rhs = COND_EXPR::boolOp (lhs, rhs, OR);
pIcode->setAsgn(lhs, rhs);
break;
case iOR:
rhs = COND_EXPR::boolOp (lhs, rhs, OR);
pIcode->setAsgn(lhs, rhs);
break;
case iPOP: pIcode->setUnary(HLI_POP, lhs);
break;
case iPOP: pIcode->setUnary(HLI_POP, lhs);
break;
case iPUSH: pIcode->setUnary(HLI_PUSH, lhs);
break;
case iPUSH: pIcode->setUnary(HLI_PUSH, lhs);
break;
case iRET:
case iRETF: pIcode->setUnary(HLI_RET, NULL);
break;
case iRET:
case iRETF: pIcode->setUnary(HLI_RET, NULL);
break;
case iSHL:
rhs = COND_EXPR::boolOp (lhs, rhs, SHL);
pIcode->setAsgn(lhs, rhs);
break;
case iSHL:
rhs = COND_EXPR::boolOp (lhs, rhs, SHL);
pIcode->setAsgn(lhs, rhs);
break;
case iSAR: /* signed */
case iSHR:
rhs = COND_EXPR::boolOp (lhs, rhs, SHR); /* unsigned*/
pIcode->setAsgn(lhs, rhs);
break;
case iSAR: /* signed */
case iSHR:
rhs = COND_EXPR::boolOp (lhs, rhs, SHR); /* unsigned*/
pIcode->setAsgn(lhs, rhs);
break;
case iSIGNEX: pIcode->setAsgn(lhs, rhs);
break;
case iSIGNEX: pIcode->setAsgn(lhs, rhs);
break;
case iSUB: rhs = COND_EXPR::boolOp (lhs, rhs, SUB);
pIcode->setAsgn(lhs, rhs);
break;
case iSUB: rhs = COND_EXPR::boolOp (lhs, rhs, SUB);
pIcode->setAsgn(lhs, rhs);
break;
case iXCHG:
break;
case iXCHG:
break;
case iXOR:
rhs = COND_EXPR::boolOp (lhs, rhs, XOR);
pIcode->setAsgn(lhs, rhs);
break;
case iXOR:
rhs = COND_EXPR::boolOp (lhs, rhs, XOR);
pIcode->setAsgn(lhs, rhs);
break;
}
}
@@ -306,22 +314,22 @@ COND_EXPR *COND_EXPR::inverse ()
{
switch (expr.boolExpr.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];
return res;
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];
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, this->clone());
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, this->clone());
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 ();
return res;
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 ();
return res;
} /* eos */
}
@@ -355,6 +363,7 @@ std::string writeCall (Function * tproc, STKFRAME * args, Function * pproc, int
/* Displays the output of a HLI_JCOND icode. */
char *writeJcond (HLTYPE h, Function * pProc, int *numLoc)
{
assert(h.expr());
memset (buf, ' ', sizeof(buf));
buf[0] = '\0';
strcat (buf, "if ");
@@ -414,25 +423,25 @@ string HLTYPE::write1HlIcode (Function * pProc, int *numLoc)
HlTypeSupport *p = get();
switch (opcode)
{
case HLI_ASSIGN:
return p->writeOut(pProc,numLoc);
case HLI_CALL:
return p->writeOut(pProc,numLoc);
case HLI_RET:
e = p->writeOut(pProc,numLoc);
if (! e.empty())
ostr << "return (" << e << ");\n";
break;
case HLI_POP:
ostr << "HLI_POP ";
ostr << p->writeOut(pProc,numLoc);
ostr << "\n";
break;
case HLI_PUSH:
ostr << "HLI_PUSH ";
ostr << p->writeOut(pProc,numLoc);
ostr << "\n";
break;
case HLI_ASSIGN:
return p->writeOut(pProc,numLoc);
case HLI_CALL:
return p->writeOut(pProc,numLoc);
case HLI_RET:
e = p->writeOut(pProc,numLoc);
if (! e.empty())
ostr << "return (" << e << ");\n";
break;
case HLI_POP:
ostr << "HLI_POP ";
ostr << p->writeOut(pProc,numLoc);
ostr << "\n";
break;
case HLI_PUSH:
ostr << "HLI_PUSH ";
ostr << p->writeOut(pProc,numLoc);
ostr << "\n";
break;
}
return ostr.str();
}

View File

@@ -15,6 +15,7 @@
#include "shift_idioms.h"
#include "arith_idioms.h"
#include "dcc.h"
#include <llvm/Support/PatternMatch.h>
#include <boost/iterator/filter_iterator.hpp>
/*****************************************************************************
* JmpInst - Returns TRUE if opcode is a conditional or unconditional jump

View File

@@ -86,6 +86,8 @@ int Idiom6::action()
****************************************************************************/
bool Idiom18::match(iICODE picode)
{
if(picode==m_func->Icode.begin())
return false;
if(std::distance(picode,m_end)<3)
return false;
--picode; //

View File

@@ -187,7 +187,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
eIcode.ll()->set(iMOD,0);
eIcode.ll()->src = _Icode.ll()->src;
eIcode.du = _Icode.du;
eIcode.ll()->setFlags( ( ll->getFlag() | SYNTHETIC) );
eIcode.ll()->setFlags( ( ll->getFlag() | SYNTHETIC | IM_TMP_DST) );
eIcode.ll()->label = SynthLab++;
pIcode = Icode.addIcode(&eIcode);
}
@@ -196,19 +196,21 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
/* MOV rTMP, regDst */
eIcode = ICODE();
eIcode.type = LOW_LEVEL;
eIcode.ll()->set(iMOV,0);
eIcode.ll()->set(iMOV,SYNTHETIC);
eIcode.ll()->dst.regi = rTMP;
eIcode.ll()->src.regi = _Icode.ll()->dst.regi;
eIcode.ll()->src = _Icode.ll()->dst;
eIcode.setRegDU( rTMP, eDEF);
eIcode.setRegDU( eIcode.ll()->src.regi, eUSE);
eIcode.ll()->setFlags( SYNTHETIC );
/* eIcode.ll()->label = SynthLab++; */
if(eIcode.ll()->src.regi)
{
eIcode.setRegDU( eIcode.ll()->src.regi, eUSE);
if((eIcode.ll()->src.regi>=rAL) && (eIcode.ll()->src.regi<=rBH))
eIcode.ll()->setFlags( B );
}
eIcode.ll()->label = _Icode.ll()->label;
Icode.addIcode(&eIcode);
/* MOV regDst, regSrc */
_Icode.ll()->set(iMOV,SYNTHETIC);
/* Icode.ll()->label = SynthLab++; */
_Icode.ll()->set(iMOV,SYNTHETIC|_Icode.ll()->getFlag());
Icode.addIcode(&_Icode);
ll->setOpcode(iXCHG); /* for next case */
@@ -216,9 +218,14 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
eIcode = ICODE();
eIcode.type = LOW_LEVEL;
eIcode.ll()->set(iMOV,SYNTHETIC);
eIcode.ll()->dst.regi = ll->src.regi;
eIcode.ll()->dst = ll->src;
if(eIcode.ll()->dst.regi)
{
if((eIcode.ll()->dst.regi>=rAL) && (eIcode.ll()->dst.regi<=rBH))
eIcode.ll()->setFlags( B );
eIcode.setRegDU( eIcode.ll()->dst.regi, eDEF);
}
eIcode.ll()->src.regi = rTMP;
eIcode.setRegDU( eIcode.ll()->dst.regi, eDEF);
eIcode.setRegDU( rTMP, eUSE);
eIcode.ll()->label = SynthLab++;
pIcode = Icode.addIcode(&eIcode);
@@ -693,9 +700,9 @@ static hlType cbType[] = {TYPE_UNKNOWN, TYPE_BYTE_UNSIGN, TYPE_WORD_SIGN,
* the maximum size is always saved). */
static SYM * updateGlobSym (uint32_t operand, int size, uint16_t duFlag)
{
int i;
int i;
/* Check for symbol in symbol table */
/* Check for symbol in symbol table */
for (i = 0; i < symtab.size(); i++)
if (symtab[i].label == operand)
{
@@ -704,7 +711,7 @@ static SYM * updateGlobSym (uint32_t operand, int size, uint16_t duFlag)
break;
}
/* New symbol, not in symbol table */
/* New symbol, not in symbol table */
if (i == symtab.size())
{
SYM v;
@@ -712,17 +719,17 @@ static SYM * updateGlobSym (uint32_t operand, int size, uint16_t duFlag)
v.label = operand;
v.size = size;
v.type = cbType[size];
if (duFlag == eDuVal::USE) /* must already have init value */
{
if (duFlag == eDuVal::USE) /* must already have init value */
{
v.duVal.use =1; // USEVAL;
v.duVal.val =1;
}
else
{
v.duVal.setFlags(duFlag);
}
symtab.push_back(v);
}
else
{
v.duVal.setFlags(duFlag);
}
symtab.push_back(v);
}
return (&symtab[i]);
}