Changes
This commit is contained in:
34
src/ast.cpp
34
src/ast.cpp
@@ -52,18 +52,23 @@ static const char *hexStr (uint16_t i)
|
||||
void ICODE::setRegDU (eReg regi, operDu du_in)
|
||||
{
|
||||
// printf("%s %d %x\n",__FUNCTION__,regi,int(du_in));
|
||||
if(regi==rSP)
|
||||
{
|
||||
printf("Discarding SP def&use info for now\n");
|
||||
return;
|
||||
}
|
||||
switch (du_in)
|
||||
{
|
||||
case eDEF:
|
||||
du.def.addReg(regi);
|
||||
du1.numRegsDef++;
|
||||
du1.addDef(regi);
|
||||
break;
|
||||
case eUSE:
|
||||
du.use.addReg(regi);
|
||||
break;
|
||||
case USE_DEF:
|
||||
du.addDefinedAndUsed(regi);
|
||||
du1.numRegsDef++;
|
||||
du1.addDef(regi);
|
||||
break;
|
||||
case NONE: /* do nothing */
|
||||
break;
|
||||
@@ -233,9 +238,8 @@ AstIdent *AstIdent::Long(LOCAL_ID *localId, opLoc sd, iICODE pIcode, hlFirst f,
|
||||
else
|
||||
{
|
||||
newExp = new AstIdent();
|
||||
idx = localId->newLong(sd, pIcode, f, ix, du, atOffset);
|
||||
newExp->ident.idType = LONG_VAR;
|
||||
newExp->ident.idNode.longIdx = idx;
|
||||
newExp->ident.idNode.longIdx = localId->newLong(sd, pIcode, f, ix, du, atOffset);
|
||||
}
|
||||
return (newExp);
|
||||
}
|
||||
@@ -265,7 +269,7 @@ AstIdent *AstIdent::idID (const ID *retVal, LOCAL_ID *locsym, iICODE ix_)
|
||||
case TYPE_LONG_SIGN:
|
||||
{
|
||||
newExp = new AstIdent();
|
||||
idx = locsym->newLongReg (TYPE_LONG_SIGN, retVal->id.longId.h,retVal->id.longId.l, ix_);
|
||||
idx = locsym->newLongReg (TYPE_LONG_SIGN, retVal->longId(), ix_);
|
||||
newExp->ident.idType = LONG_VAR;
|
||||
newExp->ident.idNode.longIdx = idx;
|
||||
break;
|
||||
@@ -294,13 +298,13 @@ Expr *AstIdent::id(const LLInst &ll_insn, opLoc sd, Function * pProc, iICODE ix_
|
||||
|
||||
int idx; /* idx into pIcode->localId table */
|
||||
|
||||
const LLOperand &pm((sd == SRC) ? ll_insn.src() : ll_insn.dst);
|
||||
const LLOperand &pm((sd == SRC) ? ll_insn.src() : ll_insn.m_dst);
|
||||
|
||||
if ( ((sd == DST) && ll_insn.testFlags(IM_DST)) or
|
||||
((sd == SRC) && ll_insn.testFlags(IM_SRC)) or
|
||||
(sd == LHS_OP)) /* for MUL lhs */
|
||||
{ /* implicit dx:ax */
|
||||
idx = pProc->localId.newLongReg (TYPE_LONG_SIGN, rDX, rAX, ix_);
|
||||
idx = pProc->localId.newLongReg (TYPE_LONG_SIGN, LONGID_TYPE(rDX, rAX), ix_);
|
||||
newExp = AstIdent::LongIdx (idx);
|
||||
duIcode.setRegDU (rDX, du);
|
||||
duIcode.setRegDU (rAX, du);
|
||||
@@ -372,7 +376,7 @@ Expr *AstIdent::id(const LLInst &ll_insn, opLoc sd, Function * pProc, iICODE ix_
|
||||
/* Returns the identifier type */
|
||||
condId LLInst::idType(opLoc sd) const
|
||||
{
|
||||
const LLOperand &pm((sd == SRC) ? src() : dst);
|
||||
const LLOperand &pm((sd == SRC) ? src() : m_dst);
|
||||
|
||||
if ((sd == SRC) && testFlags(I))
|
||||
return (CONSTANT);
|
||||
@@ -582,10 +586,10 @@ string AstIdent::walkCondExpr(Function *pProc, int *numLoc) const
|
||||
{
|
||||
id->setLocalName(++(*numLoc));
|
||||
codeOut <<TypeContainer::typeName(id->type)<< " "<<id->name<<"; ";
|
||||
codeOut <<"/* "<<Machine_X86::regName(id->id.longId.h) << ":" <<
|
||||
Machine_X86::regName(id->id.longId.l) << " */\n";
|
||||
codeOut <<"/* "<<Machine_X86::regName(id->longId().h()) << ":" <<
|
||||
Machine_X86::regName(id->longId().l()) << " */\n";
|
||||
o << id->name;
|
||||
pProc->localId.propLongId (id->id.longId.l,id->id.longId.h, id->name.c_str());
|
||||
pProc->localId.propLongId (id->longId().l(),id->longId().h(), id->name.c_str());
|
||||
}
|
||||
else /* GLB_FRAME */
|
||||
{
|
||||
@@ -884,10 +888,10 @@ eReg AstIdent::otherLongRegi (eReg regi, int idx, LOCAL_ID *locTbl)
|
||||
if ((id->loc == REG_FRAME) && ((id->type == TYPE_LONG_SIGN) ||
|
||||
(id->type == TYPE_LONG_UNSIGN)))
|
||||
{
|
||||
if (id->id.longId.h == regi)
|
||||
return (id->id.longId.l);
|
||||
else if (id->id.longId.l == regi)
|
||||
return (id->id.longId.h);
|
||||
if (id->longId().h() == regi)
|
||||
return (id->longId().l());
|
||||
else if (id->longId().l() == regi)
|
||||
return (id->longId().h());
|
||||
}
|
||||
return rUNDEF; // Cristina: please check this!
|
||||
}
|
||||
|
||||
@@ -154,7 +154,7 @@ void LLInst::writeIntComment (std::ostringstream &s)
|
||||
s<<"\t/* ";
|
||||
if (src_immed == 0x21)
|
||||
{
|
||||
s <<int21h[dst.off];
|
||||
s <<int21h[m_dst.off];
|
||||
}
|
||||
else if (src_immed > 0x1F && src_immed < 0x2F)
|
||||
{
|
||||
@@ -162,7 +162,7 @@ void LLInst::writeIntComment (std::ostringstream &s)
|
||||
}
|
||||
else if (src_immed == 0x2F)
|
||||
{
|
||||
switch (dst.off)
|
||||
switch (m_dst.off)
|
||||
{
|
||||
case 0x01 :
|
||||
s << "Print spooler";
|
||||
@@ -215,8 +215,8 @@ void Function::writeProcComments(std::ostream &ostr)
|
||||
else /* long register */
|
||||
{
|
||||
id = &this->localId.id_arr[psym->regs->ident.idNode.longIdx];
|
||||
ostr << Machine_X86::regName(id->id.longId.h) << ":";
|
||||
ostr << Machine_X86::regName(id->id.longId.l);
|
||||
ostr << Machine_X86::regName(id->longId().h()) << ":";
|
||||
ostr << Machine_X86::regName(id->longId().l());
|
||||
}
|
||||
ostr << ".\n";
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ void ExpStack::push(Expr *expr)
|
||||
Expr *ExpStack::pop()
|
||||
{
|
||||
if(expStk.empty())
|
||||
return 0;
|
||||
return expStk.back();
|
||||
Expr *topExp = expStk.back();
|
||||
expStk.pop_back();
|
||||
return topExp;
|
||||
@@ -266,7 +266,7 @@ void Function::genLiveKtes ()
|
||||
{
|
||||
if ((insn.type == HIGH_LEVEL) && ( insn.valid() ))
|
||||
{
|
||||
liveUse |= (insn.du.use & ~def);
|
||||
liveUse |= (insn.du.use - def);
|
||||
def |= insn.du.def;
|
||||
}
|
||||
}
|
||||
@@ -358,14 +358,15 @@ void Function::liveRegAnalysis (LivenessSet &in_liveOut)
|
||||
{
|
||||
switch (pcallee->retVal.type) {
|
||||
case TYPE_LONG_SIGN: case TYPE_LONG_UNSIGN:
|
||||
ticode.du1.numRegsDef = 2;
|
||||
ticode.du1.setDef(rAX).addDef(rDX);
|
||||
//TODO: use Calling convention to properly set regs here
|
||||
break;
|
||||
case TYPE_WORD_SIGN: case TYPE_WORD_UNSIGN:
|
||||
case TYPE_BYTE_SIGN: case TYPE_BYTE_UNSIGN:
|
||||
ticode.du1.numRegsDef = 1;
|
||||
ticode.du1.setDef(rAX);
|
||||
break;
|
||||
default:
|
||||
ticode.du1.numRegsDef = 0;
|
||||
ticode.du1 = ICODE::DU1(); // was .numRegsDef = 0
|
||||
//fprintf(stderr,"Function::liveRegAnalysis : Unknown return type %d, assume 0\n",pcallee->retVal.type);
|
||||
} /*eos*/
|
||||
|
||||
@@ -377,7 +378,7 @@ void Function::liveRegAnalysis (LivenessSet &in_liveOut)
|
||||
}
|
||||
|
||||
/* liveIn(b) = liveUse(b) U (liveOut(b) - def(b) */
|
||||
pbb->liveIn = LivenessSet(pbb->liveUse | (pbb->liveOut & ~pbb->def));
|
||||
pbb->liveIn = LivenessSet(pbb->liveUse + (pbb->liveOut - pbb->def));
|
||||
|
||||
/* Check if live sets have been modified */
|
||||
if ((prevLiveIn != pbb->liveIn) || (prevLiveOut != pbb->liveOut))
|
||||
@@ -422,10 +423,10 @@ bool BB::FindUseBeforeDef(eReg regi, int defRegIdx, iICODE start_at)
|
||||
if (checked_icode->type != HIGH_LEVEL) // Only check uses of HIGH_LEVEL icodes
|
||||
continue;
|
||||
/* if used, get icode index */
|
||||
if ((checked_icode->du.use & duReg[regi]).any())
|
||||
if ( checked_icode->du.use.testRegAndSubregs(regi) )
|
||||
start_at->du1.recordUse(defRegIdx,checked_icode.base());
|
||||
/* if defined, stop finding uses for this reg */
|
||||
if ((checked_icode->du.def & duReg[regi]).any())
|
||||
if (checked_icode->du.def.testRegAndSubregs(regi))
|
||||
{
|
||||
ticode=checked_icode.base();
|
||||
break;
|
||||
@@ -435,13 +436,13 @@ bool BB::FindUseBeforeDef(eReg regi, int defRegIdx, iICODE start_at)
|
||||
ticode=(++riICODE(rbegin())).base();
|
||||
|
||||
/* Check if last definition of this register */
|
||||
if ((not (ticode->du.def & duReg[regi]).any()) and (liveOut & duReg[regi]).any())
|
||||
if (not ticode->du.def.testRegAndSubregs(regi) and liveOut.testRegAndSubregs(regi) )
|
||||
start_at->du.lastDefRegi.addReg(regi);
|
||||
}
|
||||
else /* only 1 instruction in this basic block */
|
||||
{
|
||||
/* Check if last definition of this register */
|
||||
if ((liveOut & duReg[regi]).any())
|
||||
if ( liveOut.testRegAndSubregs(regi) )
|
||||
start_at->du.lastDefRegi.addReg(regi);
|
||||
}
|
||||
return false;
|
||||
@@ -460,17 +461,17 @@ void BB::ProcessUseDefForFunc(eReg regi, int defRegIdx, ICODE &picode)
|
||||
for (auto iter=target_instructions.begin(); iter!=target_instructions.end(); ++iter)
|
||||
{
|
||||
/* if used, get icode index */
|
||||
if ((iter->du.use & duReg[regi]).any())
|
||||
if ( iter->du.use.testRegAndSubregs(regi) )
|
||||
picode.du1.recordUse(defRegIdx,iter.base());
|
||||
/* if defined, stop finding uses for this reg */
|
||||
if ((iter->du.def & duReg[regi]).any())
|
||||
if (iter->du.def.testRegAndSubregs(regi))
|
||||
break;
|
||||
}
|
||||
|
||||
/* if not used in this basic block, check if the
|
||||
* register is live out, if so, make it the last
|
||||
* definition of this register */
|
||||
if ( picode.du1.used(defRegIdx) && (tbb->liveOut & duReg[regi]).any())
|
||||
if ( picode.du1.used(defRegIdx) && tbb->liveOut.testRegAndSubregs(regi))
|
||||
picode.du.lastDefRegi.addReg(regi);
|
||||
}
|
||||
}
|
||||
@@ -484,11 +485,11 @@ void BB::ProcessUseDefForFunc(eReg regi, int defRegIdx, ICODE &picode)
|
||||
void BB::RemoveUnusedDefs(eReg regi, int defRegIdx, iICODE picode)
|
||||
{
|
||||
if (picode->valid() and not picode->du1.used(defRegIdx) and
|
||||
(not (picode->du.lastDefRegi & duReg[regi]).any()) &&
|
||||
(not picode->du.lastDefRegi.testRegAndSubregs(regi)) &&
|
||||
(not ((picode->hl()->opcode == HLI_CALL) &&
|
||||
(picode->hl()->call.proc->flg & PROC_ISLIB))))
|
||||
{
|
||||
if (! (this->liveOut & duReg[regi]).any()) /* not liveOut */
|
||||
if (! (this->liveOut.testRegAndSubregs(regi))) /* not liveOut */
|
||||
{
|
||||
bool res = picode->removeDefRegi (regi, defRegIdx+1,&Parent->localId);
|
||||
if (res == true)
|
||||
@@ -537,7 +538,7 @@ void BB::genDU1()
|
||||
defRegIdx++;
|
||||
|
||||
/* Check if all defined registers have been processed */
|
||||
if ((defRegIdx >= picode->du1.numRegsDef) || (defRegIdx == MAX_REGS_DEF))
|
||||
if ((defRegIdx >= picode->du1.getNumRegsDef()) || (defRegIdx == MAX_REGS_DEF))
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -736,18 +737,18 @@ void LOCAL_ID::processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode
|
||||
{
|
||||
assert(lhs_ident);
|
||||
res = Expr::insertSubTreeLongReg (
|
||||
p_hl.asgn.rhs,
|
||||
t_hl.exp.v,
|
||||
lhs_ident->ident.idNode.longIdx);
|
||||
p_hl.asgn.rhs,
|
||||
t_hl.exp.v,
|
||||
lhs_ident->ident.idNode.longIdx);
|
||||
}
|
||||
else
|
||||
{
|
||||
RegisterNode *lhs_reg = dynamic_cast<RegisterNode *>(p_hl.asgn.lhs());
|
||||
assert(lhs_reg);
|
||||
res = Expr::insertSubTreeReg (
|
||||
t_hl.exp.v,
|
||||
p_hl.asgn.rhs,
|
||||
id_arr[lhs_reg->regiIdx].id.regi,
|
||||
t_hl.exp.v,
|
||||
p_hl.asgn.rhs,
|
||||
id_arr[lhs_reg->regiIdx].id.regi,
|
||||
this);
|
||||
}
|
||||
if (res)
|
||||
@@ -848,7 +849,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
|
||||
{
|
||||
HLTYPE &_icHl(*picode->hlU());
|
||||
numHlIcodes++;
|
||||
if (picode->du1.numRegsDef == 1) /* uint8_t/uint16_t regs */
|
||||
if (picode->du1.getNumRegsDef() == 1) /* uint8_t/uint16_t regs */
|
||||
{
|
||||
/* Check for only one use of this register. If this is
|
||||
* the last definition of the register in this BB, check
|
||||
@@ -867,7 +868,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
|
||||
* icode expression */
|
||||
|
||||
ticode = picode->du1.idx[0].uses.front();
|
||||
if ((picode->du.lastDefRegi & duReg[regi]).any() &&
|
||||
if ((picode->du.lastDefRegi.testRegAndSubregs(regi)) &&
|
||||
((ticode->hl()->opcode != HLI_CALL) &&
|
||||
(ticode->hl()->opcode != HLI_RET)))
|
||||
continue;
|
||||
@@ -886,7 +887,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
|
||||
// call F() <- somehow this is marked as user of POP ?
|
||||
ticode = picode->du1.idx[0].uses.front();
|
||||
ti_hl = ticode->hlU();
|
||||
if ((picode->du.lastDefRegi & duReg[regi]).any() &&
|
||||
if ((picode->du.lastDefRegi.testRegAndSubregs(regi)) &&
|
||||
((ti_hl->opcode != HLI_CALL) &&
|
||||
(ti_hl->opcode != HLI_RET)))
|
||||
continue;
|
||||
@@ -902,8 +903,8 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
|
||||
RegisterNode *v = dynamic_cast<RegisterNode *>(_icHl.expr());
|
||||
assert(v);
|
||||
res = Expr::insertSubTreeReg (ti_hl->exp.v,
|
||||
_exp,
|
||||
locals.id_arr[v->regiIdx].id.regi,
|
||||
_exp,
|
||||
locals.id_arr[v->regiIdx].id.regi,
|
||||
&locals);
|
||||
if (res)
|
||||
{
|
||||
@@ -971,7 +972,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
|
||||
}
|
||||
}
|
||||
|
||||
else if (picode->du1.numRegsDef == 2) /* long regs */
|
||||
else if (picode->du1.getNumRegsDef() == 2) /* long regs */
|
||||
{
|
||||
/* Check for only one use of these registers */
|
||||
if ((picode->du1.numUses(0) == 1) and (picode->du1.numUses(1) == 1))
|
||||
@@ -986,7 +987,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
|
||||
if (picode->du1.idx[0].uses[0] == picode->du1.idx[1].uses[0])
|
||||
{
|
||||
ticode = picode->du1.idx[0].uses.front();
|
||||
if ((picode->du.lastDefRegi & duReg[regi]).any() &&
|
||||
if ((picode->du.lastDefRegi.testRegAndSubregs(regi)) &&
|
||||
((ticode->hl()->opcode != HLI_CALL) &&
|
||||
(ticode->hl()->opcode != HLI_RET)))
|
||||
continue;
|
||||
@@ -998,7 +999,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
|
||||
if (picode->du1.idx[0].uses[0] == picode->du1.idx[1].uses[0])
|
||||
{
|
||||
ticode = picode->du1.idx[0].uses.front();
|
||||
if ((picode->du.lastDefRegi & duReg[regi]).any() &&
|
||||
if ((picode->du.lastDefRegi.testRegAndSubregs(regi)) &&
|
||||
((ticode->hl()->opcode != HLI_CALL) &&
|
||||
(ticode->hl()->opcode != HLI_RET)))
|
||||
continue;
|
||||
@@ -1011,7 +1012,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
|
||||
break;
|
||||
case HLI_JCOND: case HLI_PUSH:
|
||||
res = Expr::insertSubTreeLongReg (_exp,
|
||||
ticode->hlU()->exp.v,
|
||||
ticode->hlU()->exp.v,
|
||||
dynamic_cast<AstIdent *>(_icHl.asgn.lhs())->ident.idNode.longIdx);
|
||||
if (res)
|
||||
{
|
||||
@@ -1034,9 +1035,9 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
|
||||
case HLI_ASSIGN:
|
||||
_exp = _icHl.call.toAst();
|
||||
ticode->hlU()->asgn.lhs(
|
||||
AstIdent::Long(&locals, DST,
|
||||
ticode,HIGH_FIRST, picode.base(),
|
||||
eDEF, *(++iICODE(ticode))->ll()));
|
||||
AstIdent::Long(&locals, DST,
|
||||
ticode,HIGH_FIRST, picode.base(),
|
||||
eDEF, *(++iICODE(ticode))->ll()));
|
||||
ticode->hlU()->asgn.rhs = _exp;
|
||||
picode->invalidate();
|
||||
numHlIcodes--;
|
||||
@@ -1052,9 +1053,8 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
|
||||
_exp = _icHl.call.toAst();
|
||||
_retVal = &picode->hl()->call.proc->retVal;
|
||||
res = Expr::insertSubTreeLongReg (_exp,
|
||||
ticode->hlU()->exp.v,
|
||||
locals.newLongReg ( _retVal->type, _retVal->id.longId.h,
|
||||
_retVal->id.longId.l, picode.base()));
|
||||
ticode->hlU()->exp.v,
|
||||
locals.newLongReg ( _retVal->type, _retVal->longId(), picode.base()));
|
||||
if (res) /* was substituted */
|
||||
{
|
||||
picode->invalidate();
|
||||
@@ -1083,8 +1083,8 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
|
||||
{
|
||||
g_exp_stk.processExpPush(numHlIcodes, picode.base());
|
||||
}
|
||||
else if(picode->du1.numRegsDef!=0)
|
||||
printf("Num def %d\n",picode->du1.numRegsDef);
|
||||
else if(picode->du1.getNumRegsDef()!=0)
|
||||
printf("Num def %d\n",picode->du1.getNumRegsDef());
|
||||
|
||||
/* For HLI_CALL instructions that use arguments from the stack,
|
||||
* pop them from the expression stack and place them on the
|
||||
@@ -1098,7 +1098,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
|
||||
|
||||
/* If we could not substitute the result of a function,
|
||||
* assign it to the corresponding registers */
|
||||
if ( not _icHl.call.proc->isLibrary() and (not picode->du1.used(0)) and (picode->du1.numRegsDef > 0))
|
||||
if ( not _icHl.call.proc->isLibrary() and (not picode->du1.used(0)) and (picode->du1.getNumRegsDef() > 0))
|
||||
{
|
||||
_exp = new FuncNode(_icHl.call.proc, _icHl.call.args);
|
||||
auto lhs = AstIdent::idID (&_icHl.call.proc->retVal, &locals, picode.base());
|
||||
@@ -1131,13 +1131,13 @@ void Function::preprocessReturnDU(LivenessSet &_liveOut)
|
||||
eReg bad_regs[] = {rES,rCS,rDS,rSS};
|
||||
constexpr char * names[] ={"ES","CS","DS","SS"};
|
||||
for(int i=0; i<4; ++i)
|
||||
if(_liveOut.testReg(bad_regs[i]))
|
||||
{
|
||||
fprintf(stderr,"LivenessSet probably screwed up, %s register as an liveOut in preprocessReturnDU\n",names[i]);
|
||||
_liveOut.clrReg(bad_regs[i]);
|
||||
if(not _liveOut.any())
|
||||
return;
|
||||
}
|
||||
if(_liveOut.testReg(bad_regs[i]))
|
||||
{
|
||||
fprintf(stderr,"LivenessSet probably screwed up, %s register as an liveOut in preprocessReturnDU\n",names[i]);
|
||||
_liveOut.clrReg(bad_regs[i]);
|
||||
if(not _liveOut.any())
|
||||
return;
|
||||
}
|
||||
flg |= PROC_IS_FUNC;
|
||||
isAx = _liveOut.testReg(rAX);
|
||||
isBx = _liveOut.testReg(rBX);
|
||||
@@ -1176,9 +1176,8 @@ void Function::preprocessReturnDU(LivenessSet &_liveOut)
|
||||
{
|
||||
retVal.type = TYPE_LONG_SIGN;
|
||||
retVal.loc = REG_FRAME;
|
||||
retVal.id.longId.h = rDX;
|
||||
retVal.id.longId.l = rAX;
|
||||
/*idx = */localId.newLongReg(TYPE_LONG_SIGN, rDX, rAX, Icode.begin()/*0*/);
|
||||
retVal.longId() = LONGID_TYPE(rDX,rAX);
|
||||
/*idx = */localId.newLongReg(TYPE_LONG_SIGN, LONGID_TYPE(rDX,rAX), Icode.begin());
|
||||
localId.propLongId (rAX, rDX, "\0");
|
||||
}
|
||||
else if (isAx || isBx || isCx || isDx) /* uint16_t */
|
||||
|
||||
@@ -70,7 +70,7 @@ static const char *szFlops3C[] =
|
||||
|
||||
static const char *szPtr[2] = { "word ptr ", "byte ptr " };
|
||||
|
||||
static void formatRM(ostringstream &p, uint32_t flg, const LLOperand &pm);
|
||||
static void formatRM(ostringstream &p, const LLOperand &pm);
|
||||
static ostringstream &strDst(ostringstream &os, uint32_t flg, const LLOperand &pm);
|
||||
|
||||
static char *strHex(uint32_t d);
|
||||
@@ -283,7 +283,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
|
||||
{
|
||||
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(operands_s,inst.getFlag(), inst.dst);
|
||||
strDst(operands_s,inst.getFlag(), inst.m_dst);
|
||||
inst.strSrc(operands_s);
|
||||
break;
|
||||
|
||||
@@ -293,7 +293,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
|
||||
|
||||
case iSAR: case iSHL: case iSHR: case iRCL: case iRCR: case iROL:
|
||||
case iROR:
|
||||
strDst(operands_s,inst.getFlag() | I, inst.dst);
|
||||
strDst(operands_s,inst.getFlag() | I, inst.m_dst);
|
||||
if(inst.testFlags(I))
|
||||
inst.strSrc(operands_s);
|
||||
else
|
||||
@@ -301,7 +301,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
|
||||
break;
|
||||
|
||||
case iINC: case iDEC: case iNEG: case iNOT: case iPOP:
|
||||
strDst(operands_s,inst.getFlag() | I, inst.dst);
|
||||
strDst(operands_s,inst.getFlag() | I, inst.m_dst);
|
||||
break;
|
||||
|
||||
case iPUSH:
|
||||
@@ -311,15 +311,15 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
|
||||
}
|
||||
else
|
||||
{
|
||||
strDst(operands_s,inst.getFlag() | I, inst.dst);
|
||||
strDst(operands_s,inst.getFlag() | I, inst.m_dst);
|
||||
}
|
||||
break;
|
||||
|
||||
case iDIV: case iIDIV: case iMUL: case iIMUL: case iMOD:
|
||||
if (inst.testFlags(I))
|
||||
{
|
||||
strDst(operands_s,inst.getFlag(), inst.dst) <<", ";
|
||||
formatRM(operands_s, inst.getFlag(), inst.src());
|
||||
strDst(operands_s,inst.getFlag(), inst.m_dst) <<", ";
|
||||
formatRM(operands_s, inst.src());
|
||||
inst.strSrc(operands_s);
|
||||
}
|
||||
else
|
||||
@@ -327,7 +327,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
|
||||
break;
|
||||
|
||||
case iLDS: case iLES: case iBOUND:
|
||||
strDst(operands_s,inst.getFlag(), inst.dst)<<", dword ptr";
|
||||
strDst(operands_s,inst.getFlag(), inst.m_dst)<<", dword ptr";
|
||||
inst.strSrc(operands_s,true);
|
||||
break;
|
||||
|
||||
@@ -397,8 +397,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
|
||||
break;
|
||||
|
||||
case iENTER:
|
||||
operands_s<<strHex(inst.dst.off)<<", ";
|
||||
operands_s<<strHex(inst.src().getImm2());
|
||||
operands_s<<strHex(inst.m_dst.off) << ", " << strHex(inst.src().getImm2());
|
||||
break;
|
||||
|
||||
case iRET: case iRETF: case iINT:
|
||||
@@ -552,7 +551,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
|
||||
/****************************************************************************
|
||||
* formatRM
|
||||
***************************************************************************/
|
||||
static void formatRM(std::ostringstream &p, uint32_t /*flg*/, const LLOperand &pm)
|
||||
static void formatRM(std::ostringstream &p, const LLOperand &pm)
|
||||
{
|
||||
//char seg[4];
|
||||
|
||||
@@ -595,7 +594,7 @@ static ostringstream & strDst(ostringstream &os,uint32_t flg, const LLOperand &p
|
||||
//os << setw(WID_PTR);
|
||||
if ((flg & I) and not pm.isReg())
|
||||
os << szPtr[flg & B];
|
||||
formatRM(os, flg, pm);
|
||||
formatRM(os, pm);
|
||||
return os;
|
||||
}
|
||||
|
||||
@@ -612,7 +611,7 @@ ostringstream &LLInst::strSrc(ostringstream &os,bool skip_comma)
|
||||
else if (testFlags(IM_SRC)) /* level 2 */
|
||||
os<<"dx:ax";
|
||||
else
|
||||
formatRM(os, getFlag(), src());
|
||||
formatRM(os, src());
|
||||
|
||||
return os;
|
||||
}
|
||||
@@ -649,7 +648,7 @@ void LLInst::flops(std::ostringstream &out)
|
||||
/* Note that op is set to the escape number, e.g.
|
||||
esc 0x38 is FILD */
|
||||
|
||||
if ( not dst.isReg() )
|
||||
if ( not m_dst.isReg() )
|
||||
{
|
||||
/* The mod/rm mod bits are not set to 11 (i.e. register). This is the normal floating point opcode */
|
||||
out<<Machine_X86::floatOpName(op)<<' ';
|
||||
@@ -685,7 +684,7 @@ void LLInst::flops(std::ostringstream &out)
|
||||
}
|
||||
}
|
||||
|
||||
formatRM(out, getFlag(), dst);
|
||||
formatRM(out, m_dst);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -694,7 +693,7 @@ void LLInst::flops(std::ostringstream &out)
|
||||
normal opcodes. Because the opcodes are slightly different for
|
||||
this case (e.g. op=04 means FSUB if reg != 3, but FSUBR for
|
||||
reg == 3), a separate table is used (szFlops2). */
|
||||
int destRegIdx=dst.regi - rAX;
|
||||
int destRegIdx=m_dst.regi - rAX;
|
||||
switch (op)
|
||||
{
|
||||
case 0x0C:
|
||||
|
||||
@@ -11,27 +11,6 @@
|
||||
#include "dcc.h"
|
||||
using namespace std;
|
||||
|
||||
/* Masks off bits set by duReg[] */
|
||||
LivenessSet maskDuReg[] = { 0x00,
|
||||
/* uint16_t regs */
|
||||
0xFEEFFE, //rAX
|
||||
0xFDDFFD, //rCX
|
||||
0xFBB00B, //rDX
|
||||
0xF77007, //rBX
|
||||
0xFFFFEF, //rSP
|
||||
0xFFFFDF, //rBP
|
||||
0xFFFFBF, //rSI
|
||||
0xFFFF7F, //rDI
|
||||
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 */
|
||||
|
||||
|
||||
@@ -98,13 +77,13 @@ bool ICODE::removeDefRegi (eReg regi, int thisDefIdx, LOCAL_ID *locId)
|
||||
{
|
||||
int numDefs;
|
||||
|
||||
numDefs = du1.numRegsDef;
|
||||
numDefs = du1.getNumRegsDef();
|
||||
if (numDefs == thisDefIdx)
|
||||
{
|
||||
for ( ; numDefs > 0; numDefs--)
|
||||
{
|
||||
|
||||
if (du1.used(numDefs-1)||(du.lastDefRegi[regi]))
|
||||
if (du1.used(numDefs-1)||(du.lastDefRegi.testReg(regi)))
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -117,8 +96,9 @@ bool ICODE::removeDefRegi (eReg regi, int thisDefIdx, LOCAL_ID *locId)
|
||||
HlTypeSupport *p=hlU()->get();
|
||||
if(p and p->removeRegFromLong(regi,locId))
|
||||
{
|
||||
du1.numRegsDef--;
|
||||
du.def &= maskDuReg[regi];
|
||||
du1.removeDef(regi); //du1.numRegsDef--;
|
||||
//du.def &= maskDuReg[regi];
|
||||
du.def.clrReg(regi);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -285,6 +265,41 @@ HLTYPE LLInst::toHighLevel(COND_EXPR *lhs,COND_EXPR *rhs,Function *func)
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
static bool needsLhs(unsigned opc)
|
||||
{
|
||||
switch (opc)
|
||||
{
|
||||
case iCALL:
|
||||
case iCALLF:
|
||||
case iRET:
|
||||
case iRETF:
|
||||
default: return false;
|
||||
case iADD:
|
||||
case iAND:
|
||||
case iDEC:
|
||||
case iDIV:
|
||||
case iIDIV:/* should be signed div */
|
||||
case iIMUL:
|
||||
case iINC:
|
||||
case iLEA:
|
||||
case iMOD:
|
||||
case iMOV:
|
||||
case iMUL:
|
||||
case iNEG:
|
||||
case iNOT:
|
||||
case iOR:
|
||||
case iPOP:
|
||||
case iPUSH:
|
||||
case iSHL:
|
||||
case iSAR: /* signed */
|
||||
case iSHR:
|
||||
case iSIGNEX:
|
||||
case iSUB:
|
||||
case iXCHG:
|
||||
case iXOR:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
/* Translates LOW_LEVEL icodes to HIGH_LEVEL icodes - 1st stage.
|
||||
* Note: this process should be done before data flow analysis, which
|
||||
* refines the HIGH_LEVEL icodes. */
|
||||
@@ -292,12 +307,12 @@ void Function::highLevelGen()
|
||||
{
|
||||
size_t numIcode; /* number of icode instructions */
|
||||
iICODE pIcode; /* ptr to current icode node */
|
||||
Expr *lhs;
|
||||
Expr *rhs; /* left- and right-hand side of expression */
|
||||
uint32_t _flg; /* icode flags */
|
||||
numIcode = Icode.size();
|
||||
for (iICODE i = Icode.begin(); i!=Icode.end() ; ++i)
|
||||
{
|
||||
Expr *lhs=nullptr;
|
||||
assert(numIcode==Icode.size());
|
||||
pIcode = i; //Icode.GetIcode(i)
|
||||
LLInst *ll = pIcode->ll();
|
||||
@@ -306,13 +321,16 @@ void Function::highLevelGen()
|
||||
if ((pIcode->type != LOW_LEVEL) or not pIcode->valid() )
|
||||
continue;
|
||||
_flg = ll->getFlag();
|
||||
if ((_flg & IM_OPS) != IM_OPS) /* not processing IM_OPS yet */
|
||||
if ((_flg & NO_OPS) != NO_OPS) /* if there are opers */
|
||||
if (not ll->testFlags(IM_OPS)) /* not processing IM_OPS yet */
|
||||
if ( not ll->testFlags(NO_OPS) ) /* if there are opers */
|
||||
{
|
||||
if ( not ll->testFlags(NO_SRC) ) /* if there is src op */
|
||||
rhs = AstIdent::id (*pIcode->ll(), SRC, this, i, *pIcode, NONE);
|
||||
if(ll->m_dst.isSet() || (ll->getOpcode()==iMOD))
|
||||
lhs = AstIdent::id (*pIcode->ll(), DST, this, i, *pIcode, NONE);
|
||||
}
|
||||
if(needsLhs(ll->getOpcode()))
|
||||
assert(lhs!=nullptr);
|
||||
switch (ll->getOpcode())
|
||||
{
|
||||
case iADD:
|
||||
@@ -406,10 +424,12 @@ void Function::highLevelGen()
|
||||
pIcode->setAsgn(lhs, rhs);
|
||||
break;
|
||||
|
||||
case iPOP: pIcode->setUnary(HLI_POP, lhs);
|
||||
case iPOP:
|
||||
pIcode->setUnary(HLI_POP, lhs);
|
||||
break;
|
||||
|
||||
case iPUSH: pIcode->setUnary(HLI_PUSH, lhs);
|
||||
case iPUSH:
|
||||
pIcode->setUnary(HLI_PUSH, lhs);
|
||||
break;
|
||||
|
||||
case iRET:
|
||||
@@ -613,7 +633,7 @@ void ICODE::writeDU()
|
||||
}
|
||||
|
||||
/* Print du1 chain */
|
||||
printf ("# regs defined = %d\n", du1.numRegsDef);
|
||||
printf ("# regs defined = %d\n", du1.getNumRegsDef());
|
||||
for (int i = 0; i < MAX_REGS_DEF; i++)
|
||||
{
|
||||
if (not du1.used(i))
|
||||
|
||||
@@ -122,7 +122,7 @@ void Function::findIdioms()
|
||||
{
|
||||
if ((pIcode->ll()->src().proc.proc->retVal.type==TYPE_LONG_SIGN)
|
||||
|| (pIcode->ll()->src().proc.proc->retVal.type == TYPE_LONG_UNSIGN))
|
||||
localId.newLongReg(TYPE_LONG_SIGN, rDX, rAX, pIcode/*ip*/);
|
||||
localId.newLongReg(TYPE_LONG_SIGN, LONGID_TYPE(rDX,rAX), pIcode/*ip*/);
|
||||
}
|
||||
|
||||
/* Check for idioms */
|
||||
|
||||
@@ -102,20 +102,20 @@ bool Idiom18::match(iICODE picode)
|
||||
m_is_dec = m_icodes[1]->ll()->match(iDEC);
|
||||
|
||||
uint8_t regi; /* register of the MOV */
|
||||
if(not (m_icodes[0]->ll()->match(iMOV) and m_icodes[0]->ll()->dst.isReg() ))
|
||||
if(not m_icodes[0]->ll()->matchWithRegDst(iMOV) )
|
||||
return false;
|
||||
regi = m_icodes[0]->ll()->dst.regi;
|
||||
if( not ( m_icodes[2]->ll()->match(iCMP) && (m_icodes[2]->ll()->dst.regi == regi) &&
|
||||
regi = m_icodes[0]->ll()->m_dst.regi;
|
||||
if( not ( m_icodes[2]->ll()->match(iCMP,regi) &&
|
||||
m_icodes[3]->ll()->conditionalJump() ) )
|
||||
return false;
|
||||
// Simple matching finished, select apropriate matcher based on dst type
|
||||
/* Get variable */
|
||||
if (m_icodes[1]->ll()->dst.regi == 0) /* global variable */
|
||||
if (m_icodes[1]->ll()->m_dst.regi == 0) /* global variable */
|
||||
{
|
||||
/* not supported yet */
|
||||
m_idiom_type = 0;
|
||||
}
|
||||
else if ( m_icodes[1]->ll()->dst.isReg() ) /* register */
|
||||
else if ( m_icodes[1]->ll()->m_dst.isReg() ) /* register */
|
||||
{
|
||||
m_idiom_type = 1;
|
||||
// if ((m_icodes[1]->ll()->dst.regi == rSI) && (m_func->flg & SI_REGVAR))
|
||||
@@ -123,7 +123,7 @@ bool Idiom18::match(iICODE picode)
|
||||
// else if ((m_icodes[1]->ll()->dst.regi == rDI) && (m_func->flg & DI_REGVAR))
|
||||
// m_idiom_type = 1;
|
||||
}
|
||||
else if (m_icodes[1]->ll()->dst.off) /* local variable */
|
||||
else if (m_icodes[1]->ll()->m_dst.off) /* local variable */
|
||||
m_idiom_type = 2;
|
||||
else /* indexed */
|
||||
{
|
||||
@@ -141,20 +141,20 @@ bool Idiom18::match(iICODE picode)
|
||||
break;
|
||||
case 1: /* register variable */
|
||||
/* Check previous instruction for a MOV */
|
||||
if ( (m_icodes[0]->ll()->src().regi == m_icodes[1]->ll()->dst.regi))
|
||||
if ( (m_icodes[0]->ll()->src().regi == m_icodes[1]->ll()->m_dst.regi))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case 2: /* local */
|
||||
if ((m_icodes[0]->ll()->src().off == m_icodes[1]->ll()->dst.off))
|
||||
if ((m_icodes[0]->ll()->src().off == m_icodes[1]->ll()->m_dst.off))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case 3: // indexed
|
||||
printf("Untested idiom18 type: indexed\n");
|
||||
if ((m_icodes[0]->ll()->src() == m_icodes[1]->ll()->dst))
|
||||
if ((m_icodes[0]->ll()->src() == m_icodes[1]->ll()->m_dst))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -200,15 +200,15 @@ bool Idiom19::match(iICODE picode)
|
||||
m_is_dec = m_icodes[0]->ll()->match(iDEC);
|
||||
if ( not m_icodes[1]->ll()->conditionalJump() )
|
||||
return false;
|
||||
if (m_icodes[0]->ll()->dst.regi == 0) /* global variable */
|
||||
if (m_icodes[0]->ll()->m_dst.regi == 0) /* global variable */
|
||||
/* not supported yet */ ;
|
||||
else if ( m_icodes[0]->ll()->dst.isReg() ) /* register */
|
||||
else if ( m_icodes[0]->ll()->m_dst.isReg() ) /* register */
|
||||
{
|
||||
// if (((picode->ll()->dst.regi == rSI) && (pproc->flg & SI_REGVAR)) ||
|
||||
// ((picode->ll()->dst.regi == rDI) && (pproc->flg & DI_REGVAR)))
|
||||
return true;
|
||||
}
|
||||
else if (m_icodes[0]->ll()->dst.off) /* stack variable */
|
||||
else if (m_icodes[0]->ll()->m_dst.off) /* stack variable */
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -257,12 +257,12 @@ bool Idiom20::match(iICODE picode)
|
||||
for(int i=0; i<4; ++i)
|
||||
m_icodes[i] =picode++;
|
||||
/* Check second instruction for a MOV */
|
||||
if(not (m_icodes[1]->ll()->match(iMOV) && m_icodes[1]->ll()->dst.isReg()))
|
||||
if( not m_icodes[1]->ll()->matchWithRegDst(iMOV) )
|
||||
return false;
|
||||
|
||||
m_is_dec = m_icodes[0]->ll()->match(iDEC) ? PRE_DEC : PRE_INC;
|
||||
|
||||
LLOperand &ll_dest(m_icodes[0]->ll()->dst);
|
||||
const LLOperand &ll_dest(m_icodes[0]->ll()->m_dst);
|
||||
/* Get variable */
|
||||
if (ll_dest.regi == 0) /* global variable */
|
||||
{
|
||||
@@ -284,7 +284,7 @@ bool Idiom20::match(iICODE picode)
|
||||
type = 3;
|
||||
/* not supported yet */ ;
|
||||
}
|
||||
regi = m_icodes[1]->ll()->dst.regi;
|
||||
regi = m_icodes[1]->ll()->m_dst.regi;
|
||||
const LLOperand &mov_src(m_icodes[1]->ll()->src());
|
||||
if (m_icodes[2]->ll()->match(iCMP,(eReg)regi) && m_icodes[3]->ll()->conditionalJump())
|
||||
{
|
||||
|
||||
@@ -77,13 +77,13 @@ bool Idiom17::match(iICODE picode)
|
||||
if (m_icodes[1]->ll()->match(iPOP))
|
||||
{
|
||||
int i=0;
|
||||
regi = m_icodes[1]->ll()->dst.regi;
|
||||
regi = m_icodes[1]->ll()->m_dst.regi;
|
||||
if ((regi >= rAX) && (regi <= rBX))
|
||||
i++;
|
||||
|
||||
while (picode != m_end && picode->ll()->match(iPOP))
|
||||
{
|
||||
if (picode->ll()->dst.regi != regi)
|
||||
if (picode->ll()->m_dst.regi != regi)
|
||||
break;
|
||||
i++;
|
||||
m_icodes.push_back(picode++);
|
||||
|
||||
@@ -28,13 +28,13 @@ bool Idiom14::match(iICODE pIcode)
|
||||
m_icodes[0]=pIcode++;
|
||||
m_icodes[1]=pIcode++;
|
||||
/* Check for regL */
|
||||
m_regL = m_icodes[0]->ll()->dst.regi;
|
||||
m_regL = m_icodes[0]->ll()->m_dst.regi;
|
||||
if (not m_icodes[0]->ll()->testFlags(I) && ((m_regL == rAX) || (m_regL ==rBX)))
|
||||
{
|
||||
/* Check for XOR regH, regH */
|
||||
if (m_icodes[1]->ll()->match(iXOR) && not m_icodes[1]->ll()->testFlags(I))
|
||||
{
|
||||
m_regH = m_icodes[1]->ll()->dst.regi;
|
||||
m_regH = m_icodes[1]->ll()->m_dst.regi;
|
||||
if (m_regH == m_icodes[1]->ll()->src().getReg2())
|
||||
{
|
||||
if ((m_regL == rAX) && (m_regH == rDX))
|
||||
@@ -52,7 +52,7 @@ int Idiom14::action()
|
||||
AstIdent *lhs;
|
||||
Expr *rhs;
|
||||
|
||||
idx = m_func->localId.newLongReg (TYPE_LONG_SIGN, m_regH, m_regL, m_icodes[0]);
|
||||
idx = m_func->localId.newLongReg (TYPE_LONG_SIGN, LONGID_TYPE(m_regH,m_regL), m_icodes[0]);
|
||||
lhs = AstIdent::LongIdx (idx);
|
||||
m_icodes[0]->setRegDU( m_regH, eDEF);
|
||||
rhs = AstIdent::id (*m_icodes[0]->ll(), SRC, m_func, m_icodes[0], *m_icodes[0], NONE);
|
||||
@@ -82,13 +82,13 @@ bool Idiom13::match(iICODE pIcode)
|
||||
eReg regi;
|
||||
|
||||
/* Check for regL */
|
||||
regi = m_icodes[0]->ll()->dst.regi;
|
||||
regi = m_icodes[0]->ll()->m_dst.regi;
|
||||
if (not m_icodes[0]->ll()->testFlags(I) && (regi >= rAL) && (regi <= rBH))
|
||||
{
|
||||
/* Check for MOV regH, 0 */
|
||||
if (m_icodes[1]->ll()->match(iMOV,I) && (m_icodes[1]->ll()->src().getImm2() == 0))
|
||||
{
|
||||
if (m_icodes[1]->ll()->dst.regi == (regi + 4)) //WARNING: based on distance between AH-AL,BH-BL etc.
|
||||
if (m_icodes[1]->ll()->m_dst.regi == (regi + 4)) //WARNING: based on distance between AH-AL,BH-BL etc.
|
||||
{
|
||||
m_loaded_reg=(eReg)(regi - rAL + rAX);
|
||||
return true;
|
||||
@@ -102,9 +102,11 @@ int Idiom13::action()
|
||||
{
|
||||
AstIdent *lhs;
|
||||
Expr *rhs;
|
||||
eReg regi = m_icodes[0]->ll()->m_dst.regi;
|
||||
m_icodes[0]->du1.removeDef(regi);
|
||||
//m_icodes[0]->du1.numRegsDef--; /* prev uint8_t reg def */
|
||||
lhs = new RegisterNode(m_loaded_reg, 0, &m_func->localId);
|
||||
m_icodes[0]->setRegDU( m_loaded_reg, eDEF);
|
||||
m_icodes[0]->du1.numRegsDef--; /* prev uint8_t reg def */
|
||||
rhs = AstIdent::id (*m_icodes[0]->ll(), SRC, m_func, m_icodes[0], *m_icodes[0], NONE);
|
||||
m_icodes[0]->setAsgn(lhs, rhs);
|
||||
m_icodes[1]->invalidate();
|
||||
|
||||
@@ -32,17 +32,17 @@ bool Idiom11::match (iICODE picode)
|
||||
switch (type)
|
||||
{
|
||||
case GLOB_VAR:
|
||||
if ((m_icodes[2]->ll()->dst.segValue == m_icodes[0]->ll()->dst.segValue) &&
|
||||
(m_icodes[2]->ll()->dst.off == m_icodes[0]->ll()->dst.off))
|
||||
if ((m_icodes[2]->ll()->m_dst.segValue == m_icodes[0]->ll()->m_dst.segValue) &&
|
||||
(m_icodes[2]->ll()->m_dst.off == m_icodes[0]->ll()->m_dst.off))
|
||||
return true;
|
||||
break;
|
||||
case REGISTER:
|
||||
if (m_icodes[2]->ll()->dst.regi == m_icodes[0]->ll()->dst.regi)
|
||||
if (m_icodes[2]->ll()->m_dst.regi == m_icodes[0]->ll()->m_dst.regi)
|
||||
return true;
|
||||
break;
|
||||
case PARAM:
|
||||
case LOCAL_VAR:
|
||||
if (m_icodes[2]->ll()->dst.off == m_icodes[0]->ll()->dst.off)
|
||||
if (m_icodes[2]->ll()->m_dst.off == m_icodes[0]->ll()->m_dst.off)
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
@@ -82,11 +82,11 @@ bool Idiom16::match (iICODE picode)
|
||||
for(int i=0; i<3; ++i)
|
||||
m_icodes[i]=picode++;
|
||||
|
||||
uint8_t regi = m_icodes[0]->ll()->dst.regi;
|
||||
uint8_t regi = m_icodes[0]->ll()->m_dst.regi;
|
||||
if ((regi >= rAX) && (regi < INDEX_BX_SI))
|
||||
{
|
||||
if (m_icodes[1]->ll()->match(iSBB) && m_icodes[2]->ll()->match(iINC))
|
||||
if ((m_icodes[1]->ll()->dst.regi == (m_icodes[1]->ll()->src().getReg2())) &&
|
||||
if ((m_icodes[1]->ll()->m_dst.regi == (m_icodes[1]->ll()->src().getReg2())) &&
|
||||
m_icodes[1]->ll()->match((eReg)regi) &&
|
||||
m_icodes[2]->ll()->match((eReg)regi))
|
||||
return true;
|
||||
@@ -97,7 +97,7 @@ int Idiom16::action()
|
||||
{
|
||||
AstIdent *lhs;
|
||||
Expr *rhs;
|
||||
lhs = new RegisterNode(m_icodes[0]->ll()->dst.regi, m_icodes[0]->ll()->getFlag(),&m_func->localId);
|
||||
lhs = new RegisterNode(m_icodes[0]->ll()->m_dst.regi, m_icodes[0]->ll()->getFlag(),&m_func->localId);
|
||||
rhs = UnaryOperator::Create(NEGATION, lhs->clone());
|
||||
m_icodes[0]->setAsgn(lhs, rhs);
|
||||
m_icodes[1]->invalidate();
|
||||
|
||||
@@ -31,9 +31,9 @@ int Idiom8::action()
|
||||
AstIdent *lhs;
|
||||
Expr *expr;
|
||||
eReg regH,regL;
|
||||
regH=m_icodes[0]->ll()->dst.regi;
|
||||
regL=m_icodes[1]->ll()->dst.regi;
|
||||
idx = m_func->localId.newLongReg (TYPE_LONG_SIGN, regH, regL, m_icodes[0]);
|
||||
regH=m_icodes[0]->ll()->m_dst.regi;
|
||||
regL=m_icodes[1]->ll()->m_dst.regi;
|
||||
idx = m_func->localId.newLongReg (TYPE_LONG_SIGN, LONGID_TYPE(regH,regL), m_icodes[0]);
|
||||
lhs = AstIdent::LongIdx (idx);
|
||||
m_icodes[0]->setRegDU( regL, USE_DEF);
|
||||
|
||||
@@ -65,7 +65,7 @@ bool Idiom15::match(iICODE pIcode)
|
||||
if (not pIcode->ll()->testFlags(I) or (pIcode->ll()->src().getImm2() != 1))
|
||||
return false;
|
||||
m_icodes.clear();
|
||||
regi = pIcode->ll()->dst.regi;
|
||||
regi = pIcode->ll()->m_dst.regi;
|
||||
m_icodes.push_back(pIcode++);
|
||||
while( (pIcode!=m_end) and
|
||||
pIcode->ll()->match(iSHL,(eReg)regi,I) and
|
||||
@@ -81,7 +81,7 @@ int Idiom15::action()
|
||||
AstIdent *lhs;
|
||||
|
||||
Expr *rhs,*_exp;
|
||||
lhs = new RegisterNode(m_icodes[0]->ll()->dst.regi,
|
||||
lhs = new RegisterNode(m_icodes[0]->ll()->m_dst.regi,
|
||||
m_icodes[0]->ll()->getFlag() & NO_SRC_B,
|
||||
&m_func->localId);
|
||||
rhs = new Constant(m_icodes.size(), 2);
|
||||
@@ -122,10 +122,10 @@ int Idiom12::action()
|
||||
AstIdent *lhs;
|
||||
|
||||
eReg regH,regL;
|
||||
regL=m_icodes[0]->ll()->dst.regi;
|
||||
regH=m_icodes[1]->ll()->dst.regi;
|
||||
regL=m_icodes[0]->ll()->m_dst.regi;
|
||||
regH=m_icodes[1]->ll()->m_dst.regi;
|
||||
|
||||
idx = m_func->localId.newLongReg (TYPE_LONG_UNSIGN, regH, regL,m_icodes[0]);
|
||||
idx = m_func->localId.newLongReg (TYPE_LONG_UNSIGN, LONGID_TYPE(regH,regL),m_icodes[0]);
|
||||
lhs = AstIdent::LongIdx (idx);
|
||||
m_icodes[0]->setRegDU( regH, USE_DEF);
|
||||
expr = new BinaryOperator(SHL,lhs, new Constant(1, 2));
|
||||
@@ -161,9 +161,9 @@ int Idiom9::action()
|
||||
AstIdent *lhs;
|
||||
Expr *rhs,*expr;
|
||||
eReg regH,regL;
|
||||
regL=m_icodes[1]->ll()->dst.regi;
|
||||
regH=m_icodes[0]->ll()->dst.regi;
|
||||
idx = m_func->localId.newLongReg (TYPE_LONG_UNSIGN,regH,regL,m_icodes[0]);
|
||||
regL=m_icodes[1]->ll()->m_dst.regi;
|
||||
regH=m_icodes[0]->ll()->m_dst.regi;
|
||||
idx = m_func->localId.newLongReg (TYPE_LONG_UNSIGN,LONGID_TYPE(regH,regL),m_icodes[0]);
|
||||
lhs = AstIdent::LongIdx (idx);
|
||||
m_icodes[0]->setRegDU(regL, USE_DEF);
|
||||
expr = new BinaryOperator(SHR,lhs, new Constant(1, 2));
|
||||
|
||||
@@ -26,7 +26,7 @@ bool Idiom21::match (iICODE picode)
|
||||
if (not m_icodes[1]->ll()->testFlags(I))
|
||||
return false;
|
||||
|
||||
dst = &m_icodes[0]->ll()->dst;
|
||||
dst = &m_icodes[0]->ll()->m_dst;
|
||||
src = &m_icodes[0]->ll()->src();
|
||||
if ((dst->regi == src->getReg2()) && (dst->getReg2() > 0) && (dst->getReg2() < INDEX_BX_SI))
|
||||
{
|
||||
@@ -45,7 +45,7 @@ int Idiom21::action()
|
||||
lhs = AstIdent::Long (&m_func->localId, DST, m_icodes[0],HIGH_FIRST, m_icodes[0], eDEF, *m_icodes[1]->ll());
|
||||
rhs = new Constant(m_icodes[1]->ll()->src().getImm2(), 4);
|
||||
m_icodes[0]->setAsgn(lhs, rhs);
|
||||
m_icodes[0]->du.use = 0; /* clear register used in iXOR */
|
||||
m_icodes[0]->du.use.reset(); /* clear register used in iXOR */
|
||||
m_icodes[1]->invalidate();
|
||||
return 2;
|
||||
}
|
||||
@@ -63,7 +63,7 @@ bool Idiom7::match(iICODE picode)
|
||||
return false;
|
||||
const LLOperand *dst, *src;
|
||||
m_icode=picode;
|
||||
dst = &picode->ll()->dst;
|
||||
dst = &picode->ll()->m_dst;
|
||||
src = &picode->ll()->src();
|
||||
if (dst->regi == 0) /* global variable */
|
||||
{
|
||||
@@ -87,7 +87,7 @@ int Idiom7::action()
|
||||
Expr *lhs;
|
||||
lhs = AstIdent::id (*m_icode->ll(), DST, m_func, m_icode, *m_icode, NONE);
|
||||
m_icode->setAsgn(dynamic_cast<AstIdent *>(lhs), new Constant(0, 2));
|
||||
m_icode->du.use = 0; /* clear register used in iXOR */
|
||||
m_icode->du.use.reset(); /* clear register used in iXOR */
|
||||
m_icode->ll()->setFlags(I);
|
||||
return 1;
|
||||
}
|
||||
@@ -116,7 +116,7 @@ bool Idiom10::match(iICODE pIcode)
|
||||
/* Check OR reg, reg */
|
||||
if (not m_icodes[0]->ll()->testFlags(I) &&
|
||||
m_icodes[0]->ll()->src().isReg() &&
|
||||
(m_icodes[0]->ll()->src().getReg2() == m_icodes[0]->ll()->dst.getReg2()))
|
||||
(m_icodes[0]->ll()->src().getReg2() == m_icodes[0]->ll()->m_dst.getReg2()))
|
||||
if (m_icodes[1]->ll()->match(iJNE)) //.conditionalJump()
|
||||
{
|
||||
return true;
|
||||
@@ -128,8 +128,9 @@ int Idiom10::action()
|
||||
{
|
||||
m_icodes[0]->ll()->set(iCMP,I);
|
||||
m_icodes[0]->ll()->replaceSrc(LLOperand::CreateImm2(0));
|
||||
m_icodes[0]->du.def = 0;
|
||||
m_icodes[0]->du1.numRegsDef = 0;
|
||||
m_icodes[0]->du.def.reset(); //TODO: this defines FLAGS
|
||||
m_icodes[0]->du1.clearAllDefs();
|
||||
//m_icodes[0]->du1.numRegsDef = 0;
|
||||
return 2;
|
||||
|
||||
}
|
||||
|
||||
113
src/locident.cpp
113
src/locident.cpp
@@ -10,10 +10,9 @@
|
||||
#include "dcc.h"
|
||||
bool LONGID_TYPE::srcDstRegMatch(iICODE a, iICODE b) const
|
||||
{
|
||||
return (a->ll()->src().getReg2()==l) and (b->ll()->dst.getReg2()==h);
|
||||
return (a->ll()->src().getReg2()==m_l) and (b->ll()->m_dst.getReg2()==m_h);
|
||||
}
|
||||
|
||||
|
||||
ID::ID() : type(TYPE_UNKNOWN),illegal(false),loc(STK_FRAME),hasMacro(false)
|
||||
{
|
||||
macro[0]=0;
|
||||
@@ -24,6 +23,32 @@ ID::ID(hlType t, frameType f) : type(t),illegal(false),hasMacro(false)
|
||||
macro[0]=0;
|
||||
memset(&id,0,sizeof(id));
|
||||
loc=f;
|
||||
assert(not ((t==TYPE_LONG_SIGN)||(t==TYPE_LONG_UNSIGN)));
|
||||
}
|
||||
ID::ID(hlType t,const LONGID_TYPE &s) : type(t),illegal(false),hasMacro(false)
|
||||
{
|
||||
macro[0]=0;
|
||||
memset(&id,0,sizeof(id));
|
||||
loc=REG_FRAME;
|
||||
m_longId = s;
|
||||
assert((t==TYPE_LONG_SIGN)||(t==TYPE_LONG_UNSIGN));
|
||||
}
|
||||
ID::ID(hlType t,const LONG_STKID_TYPE &s) : type(t),illegal(false),hasMacro(false)
|
||||
{
|
||||
macro[0]=0;
|
||||
memset(&id,0,sizeof(id));
|
||||
loc=STK_FRAME;
|
||||
id.longStkId = s;
|
||||
assert((t==TYPE_LONG_SIGN)||(t==TYPE_LONG_UNSIGN));
|
||||
}
|
||||
|
||||
ID::ID(hlType t, const LONGGLB_TYPE &s)
|
||||
{
|
||||
macro[0]=0;
|
||||
memset(&id,0,sizeof(id));
|
||||
loc=GLB_FRAME;
|
||||
id.longGlb = s;
|
||||
assert((t==TYPE_LONG_SIGN)||(t==TYPE_LONG_UNSIGN));
|
||||
}
|
||||
|
||||
|
||||
@@ -142,17 +167,22 @@ int LOCAL_ID::newIntIdx(int16_t seg, int16_t off, eReg regi, hlType t)
|
||||
/* Checks if the entry exists in the locSym, if so, returns the idx to this
|
||||
* entry; otherwise creates a new register identifier node of type
|
||||
* TYPE_LONG_(UN)SIGN and returns the index to this new entry. */
|
||||
int LOCAL_ID::newLongReg(hlType t, eReg regH, eReg regL, iICODE ix_)
|
||||
int LOCAL_ID::newLongReg(hlType t, const LONGID_TYPE &longT, iICODE ix_)
|
||||
{
|
||||
eReg regH,regL;
|
||||
regL = longT.l();
|
||||
regH = longT.h();
|
||||
size_t idx;
|
||||
//iICODE ix_;
|
||||
/* Check for entry in the table */
|
||||
for (idx = 0; idx < id_arr.size(); idx++)
|
||||
{
|
||||
ID &entry(id_arr[idx]);
|
||||
if(!entry.isLong() || (entry.loc != REG_FRAME))
|
||||
continue;
|
||||
if (/*(locSym->id[idx].type == t) && Not checking type */
|
||||
(entry.id.longId.h == regH) &&
|
||||
(entry.id.longId.l == regL))
|
||||
(entry.longId().h() == regH) &&
|
||||
(entry.longId().l() == regL))
|
||||
{
|
||||
/* Check for occurrence in the list */
|
||||
if (entry.idx.inList(ix_))
|
||||
@@ -167,12 +197,9 @@ int LOCAL_ID::newLongReg(hlType t, eReg regH, eReg regL, iICODE ix_)
|
||||
}
|
||||
|
||||
/* Not in the table, create new identifier */
|
||||
newIdent (t, REG_FRAME);
|
||||
id_arr[id_arr.size()-1].idx.push_back(ix_);
|
||||
idx = id_arr.size() - 1;
|
||||
id_arr[idx].id.longId.h = regH;
|
||||
id_arr[idx].id.longId.l = regL;
|
||||
return (idx);
|
||||
id_arr.push_back(ID(t, LONGID_TYPE(regH,regL)));
|
||||
id_arr.back().idx.push_back(ix_);
|
||||
return (id_arr.size() - 1);
|
||||
}
|
||||
/* Returns an identifier conditional expression node of type TYPE_LONG or
|
||||
* TYPE_WORD_SIGN */
|
||||
@@ -199,12 +226,9 @@ int LOCAL_ID::newLongGlb(int16_t seg, int16_t offH, int16_t offL,hlType t)
|
||||
}
|
||||
|
||||
/* Not in the table, create new identifier */
|
||||
newIdent (t, GLB_FRAME);
|
||||
idx = id_arr.size() - 1;
|
||||
id_arr[idx].id.longGlb.seg = seg;
|
||||
id_arr[idx].id.longGlb.offH = offH;
|
||||
id_arr[idx].id.longGlb.offL = offL;
|
||||
return (idx);
|
||||
id_arr.push_back(ID(t, LONGGLB_TYPE(seg,offH,offL)));
|
||||
return (id_arr.size() - 1);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -246,9 +270,11 @@ int LOCAL_ID::newLongStk(hlType t, int offH, int offL)
|
||||
/* Check for entry in the table */
|
||||
for (idx = 0; idx < id_arr.size(); idx++)
|
||||
{
|
||||
if(id_arr[idx].loc!=STK_FRAME)
|
||||
continue;
|
||||
if ((id_arr[idx].type == t) &&
|
||||
(id_arr[idx].id.longStkId.offH == offH) &&
|
||||
(id_arr[idx].id.longStkId.offL == offL))
|
||||
(id_arr[idx].longStkId().offH == offH) &&
|
||||
(id_arr[idx].longStkId().offL == offL))
|
||||
return (idx);
|
||||
}
|
||||
|
||||
@@ -257,11 +283,8 @@ int LOCAL_ID::newLongStk(hlType t, int offH, int offL)
|
||||
flagByteWordId (offL);
|
||||
|
||||
/* Create new identifier */
|
||||
newIdent (t, STK_FRAME);
|
||||
idx = id_arr.size() - 1;
|
||||
id_arr[idx].id.longStkId.offH = offH;
|
||||
id_arr[idx].id.longStkId.offL = offL;
|
||||
return (idx);
|
||||
id_arr.push_back(ID(t,LONG_STKID_TYPE(offH,offL)));
|
||||
return (id_arr.size() - 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -289,7 +312,7 @@ int LOCAL_ID::newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix,operDu du, L
|
||||
|
||||
else if (pmL->regi < INDEX_BX_SI) /* register */
|
||||
{
|
||||
idx = newLongReg(TYPE_LONG_SIGN, pmH->regi, pmL->regi, ix);
|
||||
idx = newLongReg(TYPE_LONG_SIGN, LONGID_TYPE(pmH->regi, pmL->regi), ix);
|
||||
if (f == HIGH_FIRST)
|
||||
pIcode->setRegDU( pmL->regi, du); /* low part */
|
||||
else
|
||||
@@ -325,15 +348,31 @@ int LOCAL_ID::newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix,operDu du, L
|
||||
* idx : idx into icode array
|
||||
* pProc : ptr to current procedure record
|
||||
* rhs, lhs : return expressions if successful. */
|
||||
boolT checkLongEq (LONG_STKID_TYPE longId, iICODE pIcode, int i, Function * pProc, Assignment &asgn, LLInst &atOffset)
|
||||
bool checkLongEq (LONG_STKID_TYPE longId, iICODE pIcode, int i, Function * pProc, Assignment &asgn, LLInst &atOffset)
|
||||
{
|
||||
/* pointers to LOW_LEVEL icodes */
|
||||
const LLOperand *pmHdst, *pmLdst, *pmHsrc, *pmLsrc;
|
||||
|
||||
pmHdst = &pIcode->ll()->dst;
|
||||
pmLdst = &atOffset.dst;
|
||||
pmHdst = &pIcode->ll()->m_dst;
|
||||
pmLdst = &atOffset.m_dst;
|
||||
pmHsrc = &pIcode->ll()->src();
|
||||
pmLsrc = &atOffset.src();
|
||||
// if ((longId.offH == pmHsrc->off) && (longId.offL == pmLsrc->off))
|
||||
// {
|
||||
// asgn.lhs = AstIdent::LongIdx (i);
|
||||
|
||||
// if ( not pIcode->ll()->testFlags(NO_SRC) )
|
||||
// {
|
||||
// asgn.rhs = AstIdent::Long (&pProc->localId, SRC, pIcode, HIGH_FIRST, pIcode, eUSE, atOffset);
|
||||
// }
|
||||
// return true;
|
||||
// }
|
||||
// else if ((longId.offH == pmHdst->off) && (longId.offL == pmLdst->off))
|
||||
// {
|
||||
// asgn.lhs = AstIdent::Long (&pProc->localId, DST, pIcode, HIGH_FIRST, pIcode,eDEF, atOffset);
|
||||
// asgn.rhs = AstIdent::LongIdx (i);
|
||||
// return true;
|
||||
// }
|
||||
|
||||
if ((longId.offH == pmHdst->off) && (longId.offL == pmLdst->off))
|
||||
{
|
||||
@@ -364,18 +403,18 @@ boolT checkLongEq (LONG_STKID_TYPE longId, iICODE pIcode, int i, Function * pPro
|
||||
* idx : idx into icode array
|
||||
* pProc : ptr to current procedure record
|
||||
* rhs, lhs : return expressions if successful. */
|
||||
boolT checkLongRegEq (LONGID_TYPE longId, iICODE pIcode, int i,
|
||||
bool checkLongRegEq (LONGID_TYPE longId, iICODE pIcode, int i,
|
||||
Function * pProc, Assignment &asgn, LLInst &atOffset)
|
||||
{
|
||||
/* pointers to LOW_LEVEL icodes */
|
||||
const LLOperand *pmHdst, *pmLdst, *pmHsrc, *pmLsrc;
|
||||
|
||||
pmHdst = &pIcode->ll()->dst;
|
||||
pmLdst = &atOffset.dst;
|
||||
pmHdst = &pIcode->ll()->m_dst;
|
||||
pmLdst = &atOffset.m_dst;
|
||||
pmHsrc = &pIcode->ll()->src();
|
||||
pmLsrc = &atOffset.src();
|
||||
|
||||
if ((longId.h == pmHdst->regi) && (longId.l == pmLdst->regi))
|
||||
if ((longId.h() == pmHdst->regi) && (longId.l() == pmLdst->regi))
|
||||
{
|
||||
asgn.lhs = AstIdent::LongIdx (i);
|
||||
if ( not pIcode->ll()->testFlags(NO_SRC) )
|
||||
@@ -384,7 +423,7 @@ boolT checkLongRegEq (LONGID_TYPE longId, iICODE pIcode, int i,
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if ((longId.h == pmHsrc->regi) && (longId.l == pmLsrc->regi))
|
||||
else if ((longId.h() == pmHsrc->regi) && (longId.l() == pmLsrc->regi))
|
||||
{
|
||||
asgn.lhs = AstIdent::Long (&pProc->localId, DST, pIcode, HIGH_FIRST, pIcode, eDEF, atOffset);
|
||||
asgn.rhs = AstIdent::LongIdx (i);
|
||||
@@ -406,10 +445,10 @@ eReg otherLongRegi (eReg regi, int idx, LOCAL_ID *locTbl)
|
||||
if ((id->loc == REG_FRAME) && ((id->type == TYPE_LONG_SIGN) ||
|
||||
(id->type == TYPE_LONG_UNSIGN)))
|
||||
{
|
||||
if (id->id.longId.h == regi)
|
||||
return (id->id.longId.l);
|
||||
else if (id->id.longId.l == regi)
|
||||
return (id->id.longId.h);
|
||||
if (id->longId().h() == regi)
|
||||
return (id->longId().l());
|
||||
else if (id->longId().l() == regi)
|
||||
return (id->longId().h());
|
||||
}
|
||||
return rUNDEF; // Cristina: please check this!
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <cassert>
|
||||
#include "machine_x86.h"
|
||||
#include "icode.h"
|
||||
// Index registers **** temp solution
|
||||
static const std::string regNames[] = {
|
||||
"undef",
|
||||
@@ -8,7 +9,7 @@ static const std::string regNames[] = {
|
||||
"es", "cs", "ss", "ds",
|
||||
"al", "cl", "dl", "bl",
|
||||
"ah", "ch", "dh", "bh",
|
||||
"tmp",
|
||||
"tmp","tmp2",
|
||||
"bx+si", "bx+di", "bp+si", "bp+di",
|
||||
"si", "di", "bp", "bx"
|
||||
};
|
||||
@@ -132,3 +133,12 @@ eReg Machine_X86::compositeParent(eReg reg)
|
||||
}
|
||||
return rUNDEF;
|
||||
}
|
||||
void Machine_X86::writeRegVector (std::ostream &ostr,const LivenessSet ®i)
|
||||
{
|
||||
int j;
|
||||
for (j = rAX; j < INDEX_BX_SI; j++)
|
||||
{
|
||||
if (regi.testReg(j))
|
||||
ostr << regName(eReg(j))<<" ";
|
||||
}
|
||||
}
|
||||
|
||||
126
src/parser.cpp
126
src/parser.cpp
@@ -146,8 +146,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
|
||||
eIcode = ICODE();
|
||||
|
||||
eIcode.type = LOW_LEVEL;
|
||||
eIcode.ll()->set(iMOV,0);
|
||||
eIcode.ll()->replaceDst(rTMP);
|
||||
eIcode.ll()->set(iMOV,0,rTMP);
|
||||
if (ll->testFlags(B) )
|
||||
{
|
||||
eIcode.ll()->setFlags( B );
|
||||
@@ -171,10 +170,9 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
|
||||
/* iMOD */
|
||||
eIcode = ICODE();
|
||||
eIcode.type = LOW_LEVEL;
|
||||
eIcode.ll()->set(iMOD,0);
|
||||
eIcode.ll()->set(iMOD,ll->getFlag() | SYNTHETIC | IM_TMP_DST);
|
||||
eIcode.ll()->replaceSrc(_Icode.ll()->src());
|
||||
eIcode.du = _Icode.du;
|
||||
eIcode.ll()->setFlags( ( ll->getFlag() | SYNTHETIC | IM_TMP_DST) );
|
||||
eIcode.ll()->label = SynthLab++;
|
||||
pIcode = Icode.addIcode(&eIcode);
|
||||
}
|
||||
@@ -183,9 +181,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
|
||||
/* MOV rTMP, regDst */
|
||||
eIcode = ICODE();
|
||||
eIcode.type = LOW_LEVEL;
|
||||
eIcode.ll()->set(iMOV,SYNTHETIC);
|
||||
eIcode.ll()->replaceDst(LLOperand::CreateReg2(rTMP));
|
||||
eIcode.ll()->replaceSrc(_Icode.ll()->dst);
|
||||
eIcode.ll()->set(iMOV,SYNTHETIC,rTMP,_Icode.ll()->m_dst);
|
||||
eIcode.setRegDU( rTMP, eDEF);
|
||||
if(eIcode.ll()->src().getReg2())
|
||||
{
|
||||
@@ -207,11 +203,11 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
|
||||
eIcode.type = LOW_LEVEL;
|
||||
eIcode.ll()->set(iMOV,SYNTHETIC);
|
||||
eIcode.ll()->replaceDst(ll->src());
|
||||
if(eIcode.ll()->dst.regi)
|
||||
if(eIcode.ll()->m_dst.regi)
|
||||
{
|
||||
if((eIcode.ll()->dst.regi>=rAL) && (eIcode.ll()->dst.regi<=rBH))
|
||||
if((eIcode.ll()->m_dst.regi>=rAL) && (eIcode.ll()->m_dst.regi<=rBH))
|
||||
eIcode.ll()->setFlags( B );
|
||||
eIcode.setRegDU( eIcode.ll()->dst.regi, eDEF);
|
||||
eIcode.setRegDU( eIcode.ll()->m_dst.regi, eDEF);
|
||||
}
|
||||
eIcode.ll()->replaceSrc(rTMP);
|
||||
eIcode.setRegDU( rTMP, eUSE);
|
||||
@@ -246,7 +242,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
|
||||
if (ll->match(iJA) || ll->match(iJBE) )
|
||||
pstate->JCond.immed++;
|
||||
if (ll->getOpcode() == iJAE || ll->getOpcode() == iJA)
|
||||
pstate->JCond.regi = prev.ll()->dst.regi;
|
||||
pstate->JCond.regi = prev.ll()->m_dst.regi;
|
||||
fBranch = (bool)
|
||||
(ll->getOpcode() == iJB || ll->getOpcode() == iJBE);
|
||||
}
|
||||
@@ -258,7 +254,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
|
||||
|
||||
if (fBranch) /* Do branching code */
|
||||
{
|
||||
pstate->JCond.regi = prev.ll()->dst.regi;
|
||||
pstate->JCond.regi = prev.ll()->m_dst.regi;
|
||||
}
|
||||
/* Next icode. Note: not the same as GetLastIcode() because of the call
|
||||
to FollowCtrl() */
|
||||
@@ -297,7 +293,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
|
||||
int size;
|
||||
|
||||
/* Save function number */
|
||||
Icode.back().ll()->dst.off = (int16_t)funcNum;
|
||||
Icode.back().ll()->m_dst.off = (int16_t)funcNum;
|
||||
//Icode.GetIcode(Icode.GetNumIcodes() - 1)->
|
||||
|
||||
/* Program termination: int21h, fn 00h, 31h, 4Ch */
|
||||
@@ -318,7 +314,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
|
||||
}
|
||||
else if ((ll->src().getImm2() == 0x2F) && (pstate->f[rAH]))
|
||||
{
|
||||
Icode.back().ll()->dst.off = pstate->r[rAH];
|
||||
Icode.back().ll()->m_dst.off = pstate->r[rAH];
|
||||
}
|
||||
else /* Program termination: int20h, int27h */
|
||||
done = (boolT)(ll->src().getImm2() == 0x20 ||
|
||||
@@ -337,7 +333,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
|
||||
break; **** HERE ***/
|
||||
|
||||
case iSHL:
|
||||
if (pstate->JCond.regi == ll->dst.regi)
|
||||
if (pstate->JCond.regi == ll->m_dst.regi)
|
||||
{
|
||||
if ((ll->testFlags(I)) && ll->src().getImm2() == 1)
|
||||
pstate->JCond.immed *= 2;
|
||||
@@ -348,7 +344,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
|
||||
|
||||
case iLEA:
|
||||
if (ll->src().getReg2()== rUNDEF) /* direct mem offset */
|
||||
pstate->setState( ll->dst.getReg2(), ll->src().off);
|
||||
pstate->setState( ll->m_dst.getReg2(), ll->src().off);
|
||||
break;
|
||||
|
||||
case iLDS: case iLES:
|
||||
@@ -358,7 +354,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
|
||||
offset = LH(&prog.image()[psym->label]);
|
||||
pstate->setState( (ll->getOpcode() == iLDS)? rDS: rES,
|
||||
LH(&prog.image()[psym->label + 2]));
|
||||
pstate->setState( ll->dst.regi, (int16_t)offset);
|
||||
pstate->setState( ll->m_dst.regi, (int16_t)offset);
|
||||
psym->type = TYPE_PTR;
|
||||
}
|
||||
break;
|
||||
@@ -564,7 +560,7 @@ boolT Function::process_CALL (ICODE & pIcode, CALL_GRAPH * pcallGraph, STATE *ps
|
||||
{
|
||||
/* Not immediate, i.e. indirect call */
|
||||
|
||||
if (pIcode.ll()->dst.regi && (!option.Calls))
|
||||
if (pIcode.ll()->m_dst.regi && (!option.Calls))
|
||||
{
|
||||
/* We have not set the brave option to attempt to follow
|
||||
the execution path through register indirect calls.
|
||||
@@ -579,25 +575,25 @@ boolT Function::process_CALL (ICODE & pIcode, CALL_GRAPH * pcallGraph, STATE *ps
|
||||
es:0 where es:0 is the start of the image. This is
|
||||
usually wrong! Consider also CALL [BP+0E] in which the
|
||||
segment for the pointer is in SS! - Mike */
|
||||
if(pIcode.ll()->dst.isReg())
|
||||
if(pIcode.ll()->m_dst.isReg())
|
||||
{
|
||||
if( not pstate->isKnown(pIcode.ll()->dst.regi)
|
||||
if( not pstate->isKnown(pIcode.ll()->m_dst.regi)
|
||||
or
|
||||
not pstate->isKnown(pIcode.ll()->dst.seg)
|
||||
not pstate->isKnown(pIcode.ll()->m_dst.seg)
|
||||
)
|
||||
{
|
||||
fprintf(stderr,"Indirect call with unkown register values\n");
|
||||
fprintf(stderr,"Indirect call with unknown register values\n");
|
||||
return false;
|
||||
}
|
||||
off = pstate->r[pIcode.ll()->dst.seg];
|
||||
off = pstate->r[pIcode.ll()->m_dst.seg];
|
||||
off <<=4;
|
||||
off += pstate->r[pIcode.ll()->dst.regi];
|
||||
off += pstate->r[pIcode.ll()->m_dst.regi];
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
off = (uint32_t)(uint16_t)pIcode.ll()->dst.off +
|
||||
((uint32_t)(uint16_t)pIcode.ll()->dst.segValue << 4);
|
||||
off = (uint32_t)(uint16_t)pIcode.ll()->m_dst.off +
|
||||
((uint32_t)(uint16_t)pIcode.ll()->m_dst.segValue << 4);
|
||||
}
|
||||
|
||||
/* Address of function is given by 4 (CALLF) or 2 (CALL) bytes at
|
||||
@@ -684,7 +680,7 @@ static void process_MOV(LLInst & ll, STATE * pstate)
|
||||
{
|
||||
PROG &prog(Project::get()->prog);
|
||||
SYM * psym, *psym2; /* Pointer to symbol in global symbol table */
|
||||
uint8_t dstReg = ll.dst.regi;
|
||||
uint8_t dstReg = ll.m_dst.regi;
|
||||
uint8_t srcReg = ll.src().regi;
|
||||
if (dstReg > 0 && dstReg < INDEX_BX_SI)
|
||||
{
|
||||
@@ -709,7 +705,7 @@ static void process_MOV(LLInst & ll, STATE * pstate)
|
||||
int size=2;
|
||||
if((ll.src().regi>=rAL)&&(ll.src().regi<=rBH))
|
||||
size=1;
|
||||
psym = lookupAddr (&ll.dst, pstate, size, eDEF);
|
||||
psym = lookupAddr (&ll.m_dst, pstate, size, eDEF);
|
||||
if (psym && ! (psym->duVal.val)) /* no initial value yet */
|
||||
{
|
||||
if (ll.testFlags(I)) /* immediate */
|
||||
@@ -898,19 +894,6 @@ static void setBits(int16_t type, uint32_t start, uint32_t len)
|
||||
}
|
||||
}
|
||||
|
||||
/* DU bit definitions for each reg value - including index registers */
|
||||
LivenessSet duReg[] = { 0x00,
|
||||
//AH AL . . AX, BH
|
||||
0x11001, 0x22002, 0x44004, 0x88008, /* uint16_t regs */
|
||||
0x10, 0x20, 0x40, 0x80,
|
||||
0x100, 0x200, 0x400, 0x800, /* seg regs */
|
||||
0x1000, 0x2000, 0x4000, 0x8000, /* uint8_t regs */
|
||||
0x10000, 0x20000, 0x40000, 0x80000,
|
||||
0x100000, /* tmp reg */
|
||||
0x48, 0x88, 0x60, 0xA0, /* index regs */
|
||||
0x40, 0x80, 0x20, 0x08 };
|
||||
|
||||
|
||||
/* Checks which registers were used and updates the du.u flag.
|
||||
* Places local variables on the local symbol table.
|
||||
* Arguments: d : SRC or DST icode operand
|
||||
@@ -945,7 +928,7 @@ 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,TYPE_WORD_SIGN);
|
||||
}
|
||||
pIcode.du.use |= duReg[pm->regi];
|
||||
pIcode.du.use.addReg(pm->regi);
|
||||
}
|
||||
|
||||
else
|
||||
@@ -963,7 +946,7 @@ static void use (opLoc d, ICODE & pIcode, Function * pProc, STATE * pstate, int
|
||||
|
||||
/* Use of register */
|
||||
else if ((d == DST) || ((d == SRC) && (not pIcode.ll()->testFlags(I))))
|
||||
pIcode.du.use |= duReg[pm->regi];
|
||||
pIcode.du.use.addReg(pm->regi);
|
||||
}
|
||||
|
||||
|
||||
@@ -1007,14 +990,15 @@ 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,TYPE_WORD_SIGN);
|
||||
}
|
||||
pIcode.du.use |= duReg[pm->regi];
|
||||
pIcode.du.use.addReg(pm->regi);
|
||||
}
|
||||
}
|
||||
/* Definition of register */
|
||||
else if ((d == DST) || ((d == SRC) && (not pIcode.ll()->testFlags(I))))
|
||||
{
|
||||
pIcode.du.def |= duReg[pm->regi];
|
||||
pIcode.du1.numRegsDef++;
|
||||
assert(not pIcode.ll()->match(iPUSH));
|
||||
pIcode.du1.addDef(pm->regi);
|
||||
pIcode.du.def.addReg(pm->regi);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1030,8 +1014,9 @@ static void use_def(opLoc d, ICODE & pIcode, Function * pProc, STATE * pstate, i
|
||||
|
||||
if (pm->regi < INDEX_BX_SI) /* register */
|
||||
{
|
||||
pIcode.du.def |= duReg[pm->regi];
|
||||
pIcode.du1.numRegsDef++;
|
||||
assert(not pIcode.ll()->match(iPUSH));
|
||||
pIcode.du1.addDef(pm->regi);
|
||||
pIcode.du.def.addReg(pm->regi);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1090,12 +1075,12 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate)
|
||||
if (cb == 1)
|
||||
{
|
||||
pIcode.du.def.addReg(rAX);
|
||||
pIcode.du1.numRegsDef++;
|
||||
pIcode.du1.addDef(rAX);
|
||||
}
|
||||
else
|
||||
{
|
||||
pIcode.du.def.addReg(rAX).addReg(rDX);
|
||||
pIcode.du1.numRegsDef += 2;
|
||||
pIcode.du1.addDef(rAX).addDef(rDX);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1107,13 +1092,13 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate)
|
||||
if (cb == 1) /* uint8_t */
|
||||
{
|
||||
pIcode.du.def.addReg(rAX);
|
||||
pIcode.du1.numRegsDef++;
|
||||
pIcode.du1.addDef(rAX);
|
||||
pIcode.du.use.addReg(rAL);
|
||||
}
|
||||
else /* uint16_t */
|
||||
{
|
||||
pIcode.du.def.addReg(rDX).addReg(rAX);
|
||||
pIcode.du1.numRegsDef += 2;
|
||||
pIcode.du1.addDef(rAX).addDef(rDX);
|
||||
pIcode.du.use.addReg(rAX);
|
||||
}
|
||||
break;
|
||||
@@ -1134,9 +1119,13 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate)
|
||||
break;
|
||||
|
||||
case iLDS: case iLES:
|
||||
pIcode.du.def.addReg(((pIcode.ll()->getOpcode() == iLDS) ? rDS : rES));
|
||||
pIcode.du1.numRegsDef++;
|
||||
{
|
||||
eReg r=((pIcode.ll()->getOpcode() == iLDS) ? rDS : rES);
|
||||
pIcode.du.def.addReg(r);
|
||||
pIcode.du1.addDef(r);
|
||||
cb = 4;
|
||||
// fallthrough
|
||||
}
|
||||
case iMOV:
|
||||
use(SRC, pIcode, this, pstate, cb);
|
||||
def(DST, pIcode, this, pstate, cb);
|
||||
@@ -1161,27 +1150,27 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate)
|
||||
|
||||
case iLOOP: case iLOOPE: case iLOOPNE:
|
||||
pIcode.du.def.addReg(rCX);
|
||||
pIcode.du1.numRegsDef++;
|
||||
pIcode.du1.addDef(rCX);
|
||||
case iJCXZ:
|
||||
pIcode.du.use.addReg(rCX);
|
||||
break;
|
||||
|
||||
case iREPNE_CMPS: case iREPE_CMPS: case iREP_MOVS:
|
||||
pIcode.du.addDefinedAndUsed(rCX);
|
||||
pIcode.du1.numRegsDef++;
|
||||
pIcode.du1.addDef(rCX);
|
||||
case iCMPS: case iMOVS:
|
||||
pIcode.du.addDefinedAndUsed(rSI);
|
||||
pIcode.du.addDefinedAndUsed(rDI);
|
||||
pIcode.du1.numRegsDef += 2;
|
||||
pIcode.du1.addDef(rSI).addDef(rDI);
|
||||
pIcode.du.use.addReg(rES).addReg(sseg);
|
||||
break;
|
||||
|
||||
case iREPNE_SCAS: case iREPE_SCAS: case iREP_STOS: case iREP_INS:
|
||||
pIcode.du.addDefinedAndUsed(rCX);
|
||||
pIcode.du1.numRegsDef++;
|
||||
pIcode.du1.addDef(rCX);
|
||||
case iSCAS: case iSTOS: case iINS:
|
||||
pIcode.du.def.addReg(rDI);
|
||||
pIcode.du1.numRegsDef++;
|
||||
pIcode.du1.addDef(rDI);
|
||||
if (pIcode.ll()->getOpcode() == iREP_INS || pIcode.ll()->getOpcode()== iINS)
|
||||
{
|
||||
pIcode.du.use.addReg(rDI).addReg(rES).addReg(rDX);
|
||||
@@ -1194,28 +1183,31 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate)
|
||||
|
||||
case iREP_LODS:
|
||||
pIcode.du.addDefinedAndUsed(rCX);
|
||||
pIcode.du1.numRegsDef++;
|
||||
pIcode.du1.addDef(rCX);
|
||||
case iLODS:
|
||||
{
|
||||
eReg r = (cb==2)? rAX: rAL;
|
||||
pIcode.du.addDefinedAndUsed(rSI);
|
||||
pIcode.du.def.addReg((cb==2)? rAX: rAL);
|
||||
pIcode.du1.numRegsDef += 2;
|
||||
pIcode.du1.addDef(rSI);
|
||||
pIcode.du.def.addReg(r);
|
||||
pIcode.du1.addDef(r);
|
||||
pIcode.du.use.addReg(sseg);
|
||||
}
|
||||
break;
|
||||
|
||||
case iREP_OUTS:
|
||||
pIcode.du.addDefinedAndUsed(rCX);
|
||||
pIcode.du1.numRegsDef++;
|
||||
pIcode.du1.addDef(rCX);
|
||||
case iOUTS:
|
||||
pIcode.du.addDefinedAndUsed(rSI);
|
||||
pIcode.du1.numRegsDef++;
|
||||
pIcode.du.use |= duReg[rDX] | duReg[sseg];
|
||||
pIcode.du1.addDef(rSI);
|
||||
pIcode.du.use.addReg(rDX).addReg(sseg);
|
||||
break;
|
||||
|
||||
case iIN: case iOUT:
|
||||
def(DST, pIcode, this, pstate, cb);
|
||||
if (! Imm)
|
||||
{
|
||||
pIcode.du.use |= duReg[rDX];
|
||||
pIcode.du.use.addReg(rDX);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -97,7 +97,8 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
|
||||
bool regExist=false;
|
||||
condId type;
|
||||
Function * tproc;
|
||||
eReg regL, regH; /* Registers involved in arguments */
|
||||
eReg regL = rUNDEF;
|
||||
eReg regH; /* Registers involved in arguments */
|
||||
|
||||
/* Flag ticode as having register arguments */
|
||||
tproc = ticode->hl()->call.proc;
|
||||
@@ -113,6 +114,7 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
|
||||
if (lhs_reg)
|
||||
{
|
||||
regL = id_arr[lhs_reg->regiIdx].id.regi;
|
||||
assert(regL!=rUNDEF);
|
||||
if (regL < rAL)
|
||||
tidx = tproc->localId.newByteWordReg(TYPE_WORD_SIGN, regL);
|
||||
else
|
||||
@@ -133,9 +135,10 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
|
||||
else if (type == LONG_VAR)
|
||||
{
|
||||
int longIdx = lhs->ident.idNode.longIdx;
|
||||
regL = id_arr[longIdx].id.longId.l;
|
||||
regH = id_arr[longIdx].id.longId.h;
|
||||
tidx = tproc->localId.newLongReg(TYPE_LONG_SIGN, regH, regL, tproc->Icode.begin() /*0*/);
|
||||
LONGID_TYPE regHL = id_arr[longIdx].longId();
|
||||
regH=regHL.h();
|
||||
regL=regHL.l();
|
||||
tidx = tproc->localId.newLongReg(TYPE_LONG_SIGN, regHL, tproc->Icode.begin() /*0*/);
|
||||
/* Check if register argument already on the formal argument list */
|
||||
for(STKSYM &tgt_sym : *target_stackframe)
|
||||
{
|
||||
@@ -175,6 +178,7 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
|
||||
{
|
||||
newsym.regs = AstIdent::LongIdx (tidx);
|
||||
newsym.type = TYPE_LONG_SIGN;
|
||||
assert(regL!=rUNDEF);
|
||||
tproc->localId.id_arr[tidx].name = newsym.name;
|
||||
tproc->localId.propLongId (regL, regH, tproc->localId.id_arr[tidx].name.c_str());
|
||||
}
|
||||
@@ -191,7 +195,7 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
|
||||
switch (type) {
|
||||
case REGISTER:
|
||||
id = &id_arr[lhs_reg->regiIdx];
|
||||
picode->du.def &= maskDuReg[id->id.regi];
|
||||
picode->du.def.clrReg(id->id.regi);
|
||||
if (id->id.regi < rAL)
|
||||
newsym.type = TYPE_WORD_SIGN;
|
||||
else
|
||||
@@ -199,8 +203,8 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
|
||||
break;
|
||||
case LONG_VAR:
|
||||
id = &id_arr[lhs->ident.idNode.longIdx];
|
||||
picode->du.def &= maskDuReg[id->id.longId.h];
|
||||
picode->du.def &= maskDuReg[id->id.longId.l];
|
||||
picode->du.def.clrReg(id->longId().h());
|
||||
picode->du.def.clrReg(id->longId().l());
|
||||
newsym.type = TYPE_LONG_SIGN;
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -250,7 +250,7 @@ void Function::propLongStk (int i, const ID &pLocId)
|
||||
continue;
|
||||
if (pIcode->ll()->getOpcode() == next1->ll()->getOpcode())
|
||||
{
|
||||
if (checkLongEq (pLocId.id.longStkId, pIcode, i, this, asgn, *next1->ll()) == true)
|
||||
if (checkLongEq (pLocId.longStkId(), pIcode, i, this, asgn, *next1->ll()) == true)
|
||||
{
|
||||
switch (pIcode->ll()->getOpcode())
|
||||
{
|
||||
@@ -290,7 +290,7 @@ void Function::propLongStk (int i, const ID &pLocId)
|
||||
/* Check long conditional (i.e. 2 CMPs and 3 branches */
|
||||
else if ((pIcode->ll()->getOpcode() == iCMP) && (isLong23 (pIcode->getParent(), l23, &arc)))
|
||||
{
|
||||
if ( checkLongEq (pLocId.id.longStkId, pIcode, i, this, asgn, *l23->ll()) )
|
||||
if ( checkLongEq (pLocId.longStkId(), pIcode, i, this, asgn, *l23->ll()) )
|
||||
{
|
||||
advance(pIcode,longJCond23 (asgn, pIcode, arc, l23));
|
||||
}
|
||||
@@ -300,7 +300,7 @@ void Function::propLongStk (int i, const ID &pLocId)
|
||||
* 2 CMPs and 2 branches */
|
||||
else if ((pIcode->ll()->getOpcode() == iCMP) && isLong22 (pIcode, pEnd, l23))
|
||||
{
|
||||
if ( checkLongEq (pLocId.id.longStkId, pIcode, i, this,asgn, *l23->ll()) )
|
||||
if ( checkLongEq (pLocId.longStkId(), pIcode, i, this,asgn, *l23->ll()) )
|
||||
{
|
||||
advance(pIcode,longJCond22 (asgn, pIcode,pEnd));
|
||||
}
|
||||
@@ -329,9 +329,9 @@ int Function::findBackwarLongDefs(int loc_ident_idx, const ID &pLocId, iICODE be
|
||||
switch (icode.ll()->getOpcode())
|
||||
{
|
||||
case iMOV:
|
||||
pmH = &icode.ll()->dst;
|
||||
pmL = &next1->ll()->dst;
|
||||
if ((pLocId.id.longId.h == pmH->regi) && (pLocId.id.longId.l == pmL->regi))
|
||||
pmH = &icode.ll()->m_dst;
|
||||
pmL = &next1->ll()->m_dst;
|
||||
if ((pLocId.longId().h() == pmH->regi) && (pLocId.longId().l() == pmL->regi))
|
||||
{
|
||||
localId.id_arr[loc_ident_idx].idx.push_back(pIcode);//idx-1//insert
|
||||
icode.setRegDU( pmL->regi, eDEF);
|
||||
@@ -344,9 +344,9 @@ int Function::findBackwarLongDefs(int loc_ident_idx, const ID &pLocId, iICODE be
|
||||
break;
|
||||
|
||||
case iPOP:
|
||||
pmH = &next1->ll()->dst;
|
||||
pmL = &icode.ll()->dst;
|
||||
if ((pLocId.id.longId.h == pmH->regi) && (pLocId.id.longId.l == pmL->regi))
|
||||
pmH = &next1->ll()->m_dst;
|
||||
pmL = &icode.ll()->m_dst;
|
||||
if ((pLocId.longId().h() == pmH->regi) && (pLocId.longId().l() == pmL->regi))
|
||||
{
|
||||
asgn.lhs = AstIdent::LongIdx (loc_ident_idx);
|
||||
icode.setRegDU( pmH->regi, eDEF);
|
||||
@@ -360,9 +360,9 @@ int Function::findBackwarLongDefs(int loc_ident_idx, const ID &pLocId, iICODE be
|
||||
// /**** others missing ***/
|
||||
|
||||
case iAND: case iOR: case iXOR:
|
||||
pmL = &icode.ll()->dst;
|
||||
pmH = &next1->ll()->dst;
|
||||
if ((pLocId.id.longId.h == pmH->regi) && (pLocId.id.longId.l == pmL->regi))
|
||||
pmL = &icode.ll()->m_dst;
|
||||
pmH = &next1->ll()->m_dst;
|
||||
if ((pLocId.longId().h() == pmH->regi) && (pLocId.longId().l() == pmL->regi))
|
||||
{
|
||||
asgn.lhs = AstIdent::LongIdx (loc_ident_idx);
|
||||
asgn.rhs = AstIdent::Long (&this->localId, SRC, pIcode, LOW_FIRST, pIcode, eUSE, *next1->ll());
|
||||
@@ -407,12 +407,12 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be
|
||||
{
|
||||
case iMOV:
|
||||
{
|
||||
const LONGID_TYPE &ref_long(pLocId.id.longId);
|
||||
const LONGID_TYPE &ref_long(pLocId.longId());
|
||||
const LLOperand &src_op1(pIcode->ll()->src());
|
||||
const LLOperand &src_op2(next1->ll()->src());
|
||||
eReg srcReg1=src_op1.getReg2();
|
||||
eReg nextReg2=src_op2.getReg2();
|
||||
if ((ref_long.h == srcReg1) && (ref_long.l == nextReg2))
|
||||
if ((ref_long.h() == srcReg1) && (ref_long.l() == nextReg2))
|
||||
{
|
||||
pIcode->setRegDU( nextReg2, eUSE);
|
||||
|
||||
@@ -428,11 +428,10 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be
|
||||
|
||||
case iPUSH:
|
||||
{
|
||||
const LONGID_TYPE &ref_long(pLocId.id.longId);
|
||||
const LONGID_TYPE &ref_long(pLocId.longId());
|
||||
const LLOperand &src_op1(pIcode->ll()->src());
|
||||
const LLOperand &src_op2(next1->ll()->src());
|
||||
if ((ref_long.h == src_op1.getReg2()) &&
|
||||
(ref_long.l == src_op2.getReg2()))
|
||||
if ((ref_long.h() == src_op1.getReg2()) && (ref_long.l() == src_op2.getReg2()))
|
||||
{
|
||||
asgn.rhs = AstIdent::LongIdx (loc_ident_idx);
|
||||
pIcode->setRegDU( next1->ll()->src().getReg2(), eUSE);
|
||||
@@ -446,10 +445,9 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be
|
||||
/*** others missing ****/
|
||||
|
||||
case iAND: case iOR: case iXOR:
|
||||
pmL = &pIcode->ll()->dst;
|
||||
pmH = &next1->ll()->dst;
|
||||
if ((pLocId.id.longId.h == pmH->regi) &&
|
||||
(pLocId.id.longId.l == pmL->regi))
|
||||
pmL = &pIcode->ll()->m_dst;
|
||||
pmH = &next1->ll()->m_dst;
|
||||
if ((pLocId.longId().h() == pmH->regi) && (pLocId.longId().l() == pmL->regi))
|
||||
{
|
||||
asgn.lhs = AstIdent::LongIdx (loc_ident_idx);
|
||||
pIcode->setRegDU( pmH->regi, USE_DEF);
|
||||
@@ -478,7 +476,7 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be
|
||||
/* Check long conditional (i.e. 2 CMPs and 3 branches */
|
||||
else if ((pIcode->ll()->getOpcode() == iCMP) && (isLong23 (pIcode->getParent(), long_loc, &arc)))
|
||||
{
|
||||
if (checkLongRegEq (pLocId.id.longId, pIcode, loc_ident_idx, this, asgn, *long_loc->ll()))
|
||||
if (checkLongRegEq (pLocId.longId(), pIcode, loc_ident_idx, this, asgn, *long_loc->ll()))
|
||||
{
|
||||
// reduce the advance by 1 here (loop increases) ?
|
||||
advance(pIcode,longJCond23 (asgn, pIcode, arc, long_loc));
|
||||
@@ -489,7 +487,7 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be
|
||||
* 2 CMPs and 2 branches */
|
||||
else if (pIcode->ll()->match(iCMP) && (isLong22 (pIcode, pEnd, long_loc)))
|
||||
{
|
||||
if (checkLongRegEq (pLocId.id.longId, pIcode, loc_ident_idx, this, asgn, *long_loc->ll()) )
|
||||
if (checkLongRegEq (pLocId.longId(), pIcode, loc_ident_idx, this, asgn, *long_loc->ll()) )
|
||||
{
|
||||
// TODO: verify that removing -1 does not change anything !
|
||||
advance(pIcode,longJCond22 (asgn, pIcode,pEnd));
|
||||
@@ -502,7 +500,7 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be
|
||||
* This is better code than HLI_JCOND (HI(regH:regL) | LO(regH:regL)) */
|
||||
else if (pIcode->ll()->match(iOR) && (next1 != pEnd) && (isJCond ((llIcode)next1->ll()->getOpcode())))
|
||||
{
|
||||
if (pLocId.id.longId.srcDstRegMatch(pIcode,pIcode))
|
||||
if (pLocId.longId().srcDstRegMatch(pIcode,pIcode))
|
||||
{
|
||||
asgn.lhs = AstIdent::LongIdx (loc_ident_idx);
|
||||
asgn.rhs = new Constant(0, 4); /* long 0 */
|
||||
|
||||
119
src/scanner.cpp
119
src/scanner.cpp
@@ -6,6 +6,8 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include <cstring>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include "dcc.h"
|
||||
#include "scanner.h"
|
||||
#include "project.h"
|
||||
@@ -411,33 +413,116 @@ int disassembleOneLibDisasm(uint32_t ip,x86_insn_t &l)
|
||||
}
|
||||
eReg convertRegister(const x86_reg_t ®)
|
||||
{
|
||||
if( (reg_pc==reg.type) || (0==reg.id))
|
||||
return rUNDEF;
|
||||
|
||||
eReg regmap[]={ rUNDEF,
|
||||
rUNDEF,rUNDEF,rUNDEF,rUNDEF, //eax ecx ebx edx
|
||||
rSP,rUNDEF,rUNDEF,rUNDEF, //esp ebp esi edi
|
||||
rSP,rUNDEF,rUNDEF,rDI, //esp ebp esi edi
|
||||
rAX,rCX,rDX,rBX,
|
||||
rSP,rBP,rSI,rDI,
|
||||
rAL,rCL,rDL,rBL,
|
||||
rAH,rCH,rDH,rBH
|
||||
};
|
||||
std::map<std::string,eReg> nameToEnum = {{"es",rES},{"ds",rDS},{"cs",rCS},{"ss",rSS}};
|
||||
if(nameToEnum.find(reg.name)!=nameToEnum.end())
|
||||
return nameToEnum[reg.name];
|
||||
assert(reg.id<sizeof(regmap)/sizeof(eReg));
|
||||
assert(regmap[reg.id]!=rUNDEF);
|
||||
return regmap[reg.id];
|
||||
}
|
||||
LLOperand convertExpression(const x86_ea_t &from)
|
||||
{
|
||||
// BASE + Scale*Index + Disp
|
||||
LLOperand res;
|
||||
res.seg = rDS;
|
||||
/*
|
||||
INDEX_BX_SI = 22, // "bx+si"
|
||||
INDEX_BX_DI, // "bx+di"
|
||||
INDEX_BP_SI, // "bp+si"
|
||||
INDEX_BP_DI, // "bp+di"
|
||||
INDEX_SI, // "si"
|
||||
INDEX_DI, // "di"
|
||||
INDEX_BP, // "bp"
|
||||
INDEX_BX, // "bx"
|
||||
*/
|
||||
if(from.base.id)
|
||||
{
|
||||
eReg base_reg = convertRegister(from.base);
|
||||
eReg index_reg = convertRegister(from.index);
|
||||
// if(base_reg==rBX)
|
||||
switch(base_reg)
|
||||
{
|
||||
case rDI:
|
||||
res.regi = INDEX_DI; break;
|
||||
case rBP:
|
||||
res.seg=rSS;
|
||||
switch(index_reg)
|
||||
{
|
||||
case rDI:
|
||||
res.regi = INDEX_BP_DI; break;
|
||||
case rSI:
|
||||
res.regi = INDEX_BP_SI; break;
|
||||
case rUNDEF:
|
||||
res.regi = INDEX_BP; break;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
break;
|
||||
case rBX:
|
||||
switch(index_reg)
|
||||
{
|
||||
case rDI:
|
||||
res.regi = INDEX_BX_DI; break;
|
||||
case rSI:
|
||||
res.regi = INDEX_BX_SI; break;
|
||||
case rUNDEF:
|
||||
res.regi = INDEX_BX; break;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
assert(index_reg==rUNDEF);
|
||||
}
|
||||
assert(from.scale==0);
|
||||
if(from.index.id)
|
||||
{
|
||||
assert(false);
|
||||
}
|
||||
res.off = from.disp;
|
||||
return res;
|
||||
}
|
||||
LLOperand convertOperand(const x86_op_t &from)
|
||||
{
|
||||
LLOperand res;
|
||||
switch(from.type)
|
||||
{
|
||||
case op_unused:
|
||||
break;
|
||||
case op_register:
|
||||
return LLOperand::CreateReg2(convertRegister(from.data.reg));
|
||||
res.regi = convertRegister(from.data.reg); break;
|
||||
case op_immediate:
|
||||
return LLOperand::CreateImm2(from.data.sdword);
|
||||
res.opz = from.data.sdword;
|
||||
case op_expression:
|
||||
res = convertExpression(from.data.expression); break;
|
||||
case op_offset:
|
||||
{
|
||||
LLOperand res;
|
||||
res.seg = rDS;
|
||||
res.off = from.data.offset;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
fprintf(stderr,"convertOperand does not know how to convert %d\n",from.type);
|
||||
}
|
||||
return LLOperand::CreateImm2(0);
|
||||
if(res.isSet() && (res.seg == rUNDEF))
|
||||
{
|
||||
res.seg = rDS;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
/*****************************************************************************
|
||||
Scans one machine instruction at offset ip in prog.Image and returns error.
|
||||
@@ -481,15 +566,8 @@ eErrorId scan(uint32_t ip, ICODE &p)
|
||||
if(p.insn.x86_get_branch_target())
|
||||
decodeBranchTgt(p.insn);
|
||||
}
|
||||
x86_op_t *dst_op = p.insn.get_dest();
|
||||
static int only_first=1;
|
||||
if(dst_op && only_first)
|
||||
{
|
||||
only_first = 0;
|
||||
LLOperand conv = convertOperand(*dst_op);
|
||||
p.ll()->dst=conv;
|
||||
//assert(conv==p.ll()->dst);
|
||||
}
|
||||
// LLOperand conv = convertOperand(*p.insn.get_dest());
|
||||
// assert(conv==p.ll()->dst);
|
||||
if (p.ll()->getOpcode())
|
||||
{
|
||||
/* Save bytes of image used */
|
||||
@@ -552,7 +630,7 @@ static void setAddress(int i, bool fdst, uint16_t seg, int16_t reg, uint16_t off
|
||||
|
||||
/* If not to register (i.e. to r/m), and talking about r/m, then this is dest */
|
||||
pm = (!(stateTable[i].flg & TO_REG) == fdst) ?
|
||||
&pIcode->ll()->dst : &pIcode->ll()->src();
|
||||
&pIcode->ll()->m_dst : &pIcode->ll()->src();
|
||||
|
||||
/* Set segment. A later procedure (lookupAddr in proclist.c) will
|
||||
* provide the value of this segment in the field segValue. */
|
||||
@@ -619,7 +697,7 @@ static void rm(int i)
|
||||
}
|
||||
//pIcode->insn.get_dest()->
|
||||
if ((stateTable[i].flg & NSP) && (pIcode->ll()->src().getReg2()==rSP ||
|
||||
pIcode->ll()->dst.getReg2()==rSP))
|
||||
pIcode->ll()->m_dst.getReg2()==rSP))
|
||||
pIcode->ll()->setFlags(NOT_HLL);
|
||||
}
|
||||
|
||||
@@ -656,10 +734,9 @@ static void segrm(int i)
|
||||
static void regop(int i)
|
||||
{
|
||||
setAddress(i, false, 0, ((int16_t)i & 7) + rAX, 0);
|
||||
pIcode->ll()->replaceDst(LLOperand::CreateReg2(pIcode->ll()->src().getReg2()));
|
||||
// pIcode->ll()->dst.regi = pIcode->ll()->src.regi;
|
||||
}
|
||||
pIcode->ll()->replaceDst(pIcode->ll()->src());
|
||||
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
segop - seg encoded in middle of opcode
|
||||
@@ -767,7 +844,7 @@ static void trans(int i)
|
||||
if ((uint8_t)REG(*pInst) < 2 || !(stateTable[i].flg & B)) { /* INC & DEC */
|
||||
ll->setOpcode(transTable[REG(*pInst)]); /* valid on bytes */
|
||||
rm(i);
|
||||
ll->replaceSrc( pIcode->ll()->dst );
|
||||
ll->replaceSrc( pIcode->ll()->m_dst );
|
||||
if (ll->match(iJMP) || ll->match(iCALL) || ll->match(iCALLF))
|
||||
ll->setFlags(NO_OPS);
|
||||
else if (ll->match(iINC) || ll->match(iPUSH) || ll->match(iDEC))
|
||||
@@ -799,7 +876,7 @@ static void arith(int i)
|
||||
}
|
||||
else if (!(opcode == iNOT || opcode == iNEG))
|
||||
{
|
||||
pIcode->ll()->replaceSrc( pIcode->ll()->dst );
|
||||
pIcode->ll()->replaceSrc( pIcode->ll()->m_dst );
|
||||
setAddress(i, true, 0, rAX, 0); /* dst = AX */
|
||||
}
|
||||
else if (opcode == iNEG || opcode == iNOT)
|
||||
@@ -838,7 +915,7 @@ static void data2(int )
|
||||
* set to NO_OPS. */
|
||||
if (pIcode->ll()->getOpcode() == iENTER)
|
||||
{
|
||||
pIcode->ll()->dst.off = getWord();
|
||||
pIcode->ll()->m_dst.off = getWord();
|
||||
pIcode->ll()->setFlags(NO_OPS);
|
||||
}
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user