CIcodeRec is no longer an Array, it's now a list, will help with iterator stability
This commit is contained in:
parent
f131b7e619
commit
3cb26d99d2
3
base_regression.sh
Executable file
3
base_regression.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
./test_use_base.sh
|
||||
./regression_tester.rb ./bld/dcc_original -s -c 2>stderr >stdout; diff tests/prev/ tests/outputs/
|
||||
3
full_regression.sh
Executable file
3
full_regression.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
./test_use_all.sh
|
||||
./regression_tester.rb ./bld/dcc_original -s -c 2>stderr >stdout; diff tests/prev/ tests/outputs/
|
||||
@ -108,7 +108,7 @@ static BB * Create(Int start, Int ip, byte nodeType, Int numOutEdges, Function *
|
||||
///
|
||||
const Function *getParent() const { return Parent; }
|
||||
Function *getParent() { return Parent; }
|
||||
void writeBB(ICODE *hli, Int lev, Function *pProc, Int *numLoc);
|
||||
void writeBB(Int lev, Function *pProc, Int *numLoc);
|
||||
BB *rmJMP(Int marker, BB *pBB);
|
||||
private:
|
||||
Function *Parent;
|
||||
|
||||
@ -1,39 +0,0 @@
|
||||
#pragma once
|
||||
#include "idiom.h"
|
||||
#include "icode.h"
|
||||
#include <deque>
|
||||
struct EpilogIdiom : public Idiom
|
||||
{
|
||||
protected:
|
||||
std::deque<iICODE> m_icodes; // deque to push_front optional icodes from popStkVars
|
||||
void popStkVars (iICODE pIcode);
|
||||
public:
|
||||
virtual ~EpilogIdiom() {}
|
||||
EpilogIdiom(Function *f) : Idiom(f)
|
||||
{
|
||||
}
|
||||
|
||||
};
|
||||
struct Idiom2 : public EpilogIdiom
|
||||
{
|
||||
virtual ~Idiom2() {}
|
||||
Idiom2(Function *f) : EpilogIdiom(f)
|
||||
{
|
||||
}
|
||||
uint8_t minimum_match_length() {return 3;}
|
||||
bool match(iICODE pIcode);
|
||||
int action();
|
||||
};
|
||||
struct Idiom4 : public EpilogIdiom
|
||||
{
|
||||
protected:
|
||||
int m_param_count;
|
||||
public:
|
||||
virtual ~Idiom4() {}
|
||||
Idiom4(Function *f) : EpilogIdiom(f)
|
||||
{
|
||||
}
|
||||
uint8_t minimum_match_length() {return 1;}
|
||||
bool match(iICODE pIcode);
|
||||
int action();
|
||||
};
|
||||
@ -4,6 +4,7 @@
|
||||
****************************************************************************/
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <bitset>
|
||||
#include <llvm/MC/MCInst.h>
|
||||
#include <llvm/MC/MCAsmInfo.h>
|
||||
@ -276,8 +277,8 @@ struct HLTYPE
|
||||
struct { /* for HLI_CALL */
|
||||
Function *proc;
|
||||
STKFRAME *args; /* actual arguments */
|
||||
} call;
|
||||
} oper; /* operand */
|
||||
} call;
|
||||
} oper; /* operand */
|
||||
} ;
|
||||
/* LOW_LEVEL icode operand record */
|
||||
struct LLOperand //: public llvm::MCOperand
|
||||
@ -344,9 +345,9 @@ struct ICODE
|
||||
{
|
||||
struct DU1
|
||||
{
|
||||
Int numRegsDef; /* # registers defined by this inst */
|
||||
Int numRegsDef; /* # registers defined by this inst */
|
||||
byte regi[MAX_REGS_DEF]; /* registers defined by this inst */
|
||||
Int idx[MAX_REGS_DEF][MAX_USES]; /* inst that uses this def */
|
||||
Int idx[MAX_REGS_DEF][MAX_USES]; /* inst that uses this def */
|
||||
};
|
||||
icodeType type; /* Icode type */
|
||||
bool invalid; /* Has no HIGH_LEVEL equivalent */
|
||||
@ -387,7 +388,7 @@ public:
|
||||
};
|
||||
|
||||
// This is the icode array object.
|
||||
class CIcodeRec : public std::vector<ICODE>
|
||||
class CIcodeRec : public std::list<ICODE>
|
||||
{
|
||||
public:
|
||||
CIcodeRec(); // Constructor
|
||||
|
||||
@ -1,15 +0,0 @@
|
||||
#pragma once
|
||||
#include "icode.h"
|
||||
#include "Procedure.h"
|
||||
struct Idiom
|
||||
{
|
||||
protected:
|
||||
Function *m_func;
|
||||
iICODE m_end;
|
||||
public:
|
||||
Idiom(Function *f) : m_func(f),m_end(f->Icode.end())
|
||||
{
|
||||
}
|
||||
virtual uint8_t minimum_match_length()=0;
|
||||
virtual bool match(iICODE at)=0;
|
||||
};
|
||||
@ -1,16 +0,0 @@
|
||||
#pragma once
|
||||
#include "idiom.h"
|
||||
struct Idiom1 : public Idiom
|
||||
{
|
||||
protected:
|
||||
std::vector<iICODE> m_icodes;
|
||||
int m_min_off;
|
||||
Int checkStkVars (iICODE pIcode);
|
||||
public:
|
||||
Idiom1(Function *f) : Idiom(f)
|
||||
{
|
||||
}
|
||||
uint8_t minimum_match_length() {return 1;}
|
||||
bool match(iICODE picode);
|
||||
int action();
|
||||
};
|
||||
@ -99,14 +99,13 @@ struct ID
|
||||
dword l; /* low word */
|
||||
} longKte;
|
||||
} id;
|
||||
ID()
|
||||
ID() : type(TYPE_UNKNOWN),illegal(false),loc(STK_FRAME),hasMacro(false)
|
||||
{
|
||||
memset(this,0,sizeof(ID));
|
||||
memset(&id,0,sizeof(id));
|
||||
}
|
||||
ID(hlType t, frameType f)
|
||||
ID(hlType t, frameType f) : type(t),illegal(false),hasMacro(false)
|
||||
{
|
||||
memset(this,0,sizeof(ID));
|
||||
type=t;
|
||||
memset(&id,0,sizeof(id));
|
||||
loc=f;
|
||||
}
|
||||
bool isSigned() const { return (type==TYPE_BYTE_SIGN)||(type==TYPE_WORD_SIGN)||(type==TYPE_LONG_SIGN);}
|
||||
@ -133,7 +132,7 @@ public:
|
||||
Int newByteWordStk(hlType t, Int off, byte regOff);
|
||||
Int newIntIdx(int16 seg, int16 off, byte regi, Int ix, hlType t);
|
||||
Int newLongReg(hlType t, byte regH, byte regL, iICODE ix_);
|
||||
Int newLong(opLoc sd, ICODE *pIcode, hlFirst f, iICODE ix, operDu du, Int off);
|
||||
Int newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix, operDu du, Int off);
|
||||
void newIdent(hlType t, frameType f);
|
||||
void flagByteWordId(Int off);
|
||||
void propLongId(byte regL, byte regH, const char *name);
|
||||
|
||||
@ -153,7 +153,7 @@ void BB::writeCode (Int indLevel, Function * pProc , Int *numLoc,Int latchNode,
|
||||
if (numHlIcodes > 1)
|
||||
{
|
||||
/* Write the code for this basic block */
|
||||
writeBB(&pProc->Icode.front(), indLevel, pProc, numLoc);
|
||||
writeBB(indLevel, pProc, numLoc);
|
||||
repCond = true;
|
||||
}
|
||||
|
||||
@ -183,7 +183,7 @@ void BB::writeCode (Int indLevel, Function * pProc , Int *numLoc,Int latchNode,
|
||||
|
||||
/* Write the code for this basic block */
|
||||
if (repCond == FALSE)
|
||||
writeBB (&pProc->Icode.front(), indLevel, pProc, numLoc);
|
||||
writeBB (indLevel, pProc, numLoc);
|
||||
|
||||
/* Check for end of path */
|
||||
_nodeType = nodeType;
|
||||
@ -218,7 +218,7 @@ void BB::writeCode (Int indLevel, Function * pProc , Int *numLoc,Int latchNode,
|
||||
/* Check if there is need to repeat other statements involved
|
||||
* in while condition, then, emit the loop trailer */
|
||||
if (repCond)
|
||||
writeBB (&pProc->Icode.front(), indLevel+1, pProc, numLoc);
|
||||
writeBB (indLevel+1, pProc, numLoc);
|
||||
cCode.appendCode( "%s} /* end of while */\n",indent(indLevel));
|
||||
}
|
||||
else if (_loopType == ENDLESS_TYPE)
|
||||
@ -325,28 +325,34 @@ void BB::writeCode (Int indLevel, Function * pProc , Int *numLoc,Int latchNode,
|
||||
* Args: pBB: pointer to the current basic block.
|
||||
* Icode: pointer to the array of icodes for current procedure.
|
||||
* lev: indentation level - used for formatting. */
|
||||
void BB::writeBB(ICODE * hli, Int lev, Function * pProc, Int *numLoc)
|
||||
void BB::writeBB(Int lev, Function * pProc, Int *numLoc)
|
||||
{
|
||||
Int i, last;
|
||||
char *line; /* Pointer to the HIGH-LEVEL line */
|
||||
|
||||
/* Save the index into the code table in case there is a later goto
|
||||
* into this instruction (first instruction of the BB) */
|
||||
hli[start].codeIdx = nextBundleIdx (&cCode.code);
|
||||
front().codeIdx = nextBundleIdx (&cCode.code);
|
||||
//hli[start].codeIdx = nextBundleIdx (&cCode.code);
|
||||
//for (i = start, last = i + length; i < last; i++)
|
||||
|
||||
/* Generate code for each hlicode that is not a HLI_JCOND */
|
||||
for (i = start, last = i + length; i < last; i++)
|
||||
if ((hli[i].type == HIGH_LEVEL) && (hli[i].invalid == FALSE))
|
||||
int idx=start;
|
||||
for(iICODE hli=begin2(); hli!=end2(); ++hli)
|
||||
{
|
||||
if ((hli->type == HIGH_LEVEL) && (hli->invalid == FALSE))
|
||||
{
|
||||
line = write1HlIcode (hli[i].ic.hl, pProc, numLoc);
|
||||
line = write1HlIcode (hli->ic.hl, pProc, numLoc);
|
||||
if (line[0] != '\0')
|
||||
{
|
||||
cCode.appendCode( "%s%s", indent(lev), line);
|
||||
stats.numHLIcode++;
|
||||
}
|
||||
if (option.verbose)
|
||||
hli[i].writeDU(i);
|
||||
hli->writeDU(idx);
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
int BB::begin()
|
||||
{
|
||||
@ -355,12 +361,16 @@ int BB::begin()
|
||||
|
||||
iICODE BB::begin2()
|
||||
{
|
||||
return Parent->Icode.begin()+start;
|
||||
iICODE result(Parent->Icode.begin());
|
||||
advance(result,start);
|
||||
return result;
|
||||
}
|
||||
|
||||
iICODE BB::end2()
|
||||
{
|
||||
return Parent->Icode.begin()+start+length;
|
||||
iICODE result(Parent->Icode.begin());
|
||||
advance(result,start+length);
|
||||
return result;
|
||||
}
|
||||
int BB::rbegin()
|
||||
{
|
||||
@ -372,7 +382,7 @@ int BB::end()
|
||||
}
|
||||
ICODE &BB::back()
|
||||
{
|
||||
return Parent->Icode[rbegin()];
|
||||
return *rbegin2();
|
||||
}
|
||||
|
||||
size_t BB::size()
|
||||
@ -382,17 +392,16 @@ size_t BB::size()
|
||||
|
||||
ICODE &BB::front()
|
||||
{
|
||||
return Parent->Icode[start];
|
||||
return *begin2();
|
||||
}
|
||||
|
||||
riICODE BB::rbegin2()
|
||||
{
|
||||
riICODE res(Parent->Icode.begin()+start+length);
|
||||
assert(res->loc_ip==back().loc_ip);
|
||||
riICODE res(end2());
|
||||
assert(res->loc_ip==rbegin());
|
||||
return res;
|
||||
}
|
||||
riICODE BB::rend2()
|
||||
{
|
||||
riICODE res(Parent->Icode.begin()+start);
|
||||
return res;
|
||||
return riICODE(begin2());
|
||||
}
|
||||
|
||||
@ -261,23 +261,24 @@ COND_EXPR *COND_EXPR::idLong(LOCAL_ID *localId, opLoc sd, iICODE pIcode, hlFirst
|
||||
{
|
||||
Int idx;
|
||||
COND_EXPR *newExp = new COND_EXPR(IDENTIFIER);
|
||||
|
||||
/* Check for long constant and save it as a constant expression */
|
||||
if ((sd == SRC) && ((pIcode->ic.ll.flg & I) == I)) /* constant */
|
||||
{
|
||||
iICODE atOffset=pIcode;
|
||||
advance(atOffset,off);
|
||||
newExp->expr.ident.idType = CONSTANT;
|
||||
if (f == HIGH_FIRST)
|
||||
newExp->expr.ident.idNode.kte.kte = (pIcode->ic.ll.src.op() << 16) +
|
||||
(pIcode+off)->ic.ll.src.op();
|
||||
atOffset->ic.ll.src.op();
|
||||
else /* LOW_FIRST */
|
||||
newExp->expr.ident.idNode.kte.kte =
|
||||
((pIcode+off)->ic.ll.src.op() << 16)+ pIcode->ic.ll.src.op();
|
||||
(atOffset->ic.ll.src.op() << 16)+ pIcode->ic.ll.src.op();
|
||||
newExp->expr.ident.idNode.kte.size = 4;
|
||||
}
|
||||
/* Save it as a long expression (reg, stack or glob) */
|
||||
else
|
||||
{
|
||||
idx = localId->newLong(sd, &(*pIcode), f, ix, du, off);
|
||||
idx = localId->newLong(sd, pIcode, f, ix, du, off);
|
||||
newExp->expr.ident.idType = LONG_VAR;
|
||||
newExp->expr.ident.idNode.longIdx = idx;
|
||||
}
|
||||
|
||||
@ -132,19 +132,22 @@ void Function::elimCondCodes ()
|
||||
(use = useAt->ic.ll.flagDU.u))
|
||||
{
|
||||
/* Find definition within the same basic block */
|
||||
for (defAt = useAt+1; defAt != pBB->rend2(); defAt++)
|
||||
defAt=useAt;
|
||||
++defAt;
|
||||
for (; defAt != pBB->rend2(); defAt++)
|
||||
{
|
||||
def = defAt->ic.ll.flagDU.d;
|
||||
if ((use & def) == use)
|
||||
{
|
||||
if ((use & def) != use)
|
||||
continue;
|
||||
notSup = FALSE;
|
||||
if ((useAt->GetLlOpcode() >= iJB) && (useAt->GetLlOpcode() <= iJNS))
|
||||
{
|
||||
iICODE befDefAt = (++riICODE(defAt)).base();
|
||||
switch (defAt->GetLlOpcode())
|
||||
{
|
||||
case iCMP:
|
||||
rhs = srcIdent (*defAt, this, (defAt+1).base(),*useAt, eUSE);
|
||||
lhs = dstIdent (*defAt, this, (defAt+1).base(),*useAt, eUSE);
|
||||
rhs = srcIdent (*defAt, this, befDefAt,*useAt, eUSE);
|
||||
lhs = dstIdent (*defAt, this, befDefAt,*useAt, eUSE);
|
||||
break;
|
||||
|
||||
case iOR:
|
||||
@ -157,8 +160,8 @@ void Function::elimCondCodes ()
|
||||
break;
|
||||
|
||||
case iTEST:
|
||||
rhs = srcIdent (*defAt,this, (defAt+1).base(),*useAt, eUSE);
|
||||
lhs = dstIdent (*defAt,this, (defAt+1).base(),*useAt, eUSE);
|
||||
rhs = srcIdent (*defAt,this, befDefAt,*useAt, eUSE);
|
||||
lhs = dstIdent (*defAt,this, befDefAt,*useAt, eUSE);
|
||||
lhs = COND_EXPR::boolOp (lhs, rhs, AND);
|
||||
if (defAt->isLlFlag(B))
|
||||
rhs = COND_EXPR::idKte (0, 1);
|
||||
@ -195,7 +198,6 @@ void Function::elimCondCodes ()
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for extended basic block */
|
||||
if ((pBB->size() == 1) &&(useAt->GetLlOpcode() >= iJB) && (useAt->GetLlOpcode() <= iJNS))
|
||||
@ -423,10 +425,10 @@ void Function::genDU1 ()
|
||||
continue;
|
||||
if ((regi == rSI) && (flg & SI_REGVAR))
|
||||
continue;
|
||||
if ((picode + 1) != lastInst) /* several instructions */
|
||||
if (distance(picode,lastInst)>1) /* several instructions */
|
||||
{
|
||||
useIdx = 0;
|
||||
for (auto ricode = picode + 1; ricode != lastInst; ricode++)
|
||||
for (auto ricode = ++iICODE(picode); ricode != lastInst; ricode++)
|
||||
{
|
||||
ticode=ricode;
|
||||
/* Only check uses of HIGH_LEVEL icodes */
|
||||
@ -608,7 +610,6 @@ static boolT xClear (COND_EXPR *rhs, iICODE f, Int t, iICODE lastBBinst, Functio
|
||||
iICODE i;
|
||||
boolT res;
|
||||
byte regi;
|
||||
ICODE * picode;
|
||||
|
||||
if (rhs == NULL)
|
||||
return false;
|
||||
@ -618,9 +619,8 @@ static boolT xClear (COND_EXPR *rhs, iICODE f, Int t, iICODE lastBBinst, Functio
|
||||
case IDENTIFIER:
|
||||
if (rhs->expr.ident.idType == REGISTER)
|
||||
{
|
||||
picode = &pproc->Icode.front();
|
||||
regi= pproc->localId.id_arr[rhs->expr.ident.idNode.regiIdx].id.regi;
|
||||
for (i = (f + 1); (i != lastBBinst) && (i->loc_ip < t); i++)
|
||||
for (i = ++iICODE(f); (i != lastBBinst) && (i->loc_ip < t); i++)
|
||||
if ((i->type == HIGH_LEVEL) && ( not i->invalid ))
|
||||
{
|
||||
if ((i->du.def & duReg[regi]).any())
|
||||
@ -741,7 +741,8 @@ void Function::findExps()
|
||||
case HLI_ASSIGN:
|
||||
/* Replace rhs of current icode into target
|
||||
* icode expression */
|
||||
ticode = Icode.begin()+picode->du1.idx[0][0];
|
||||
ticode = Icode.begin();
|
||||
advance(ticode,picode->du1.idx[0][0]);
|
||||
if ((picode->du.lastDefRegi & duReg[regi]).any() &&
|
||||
((ticode->ic.hl.opcode != HLI_CALL) &&
|
||||
(ticode->ic.hl.opcode != HLI_RET)))
|
||||
@ -781,7 +782,8 @@ void Function::findExps()
|
||||
break;
|
||||
|
||||
case HLI_POP:
|
||||
ticode = Icode.begin()+(picode->du1.idx[0][0]);
|
||||
ticode = Icode.begin();
|
||||
advance(ticode,picode->du1.idx[0][0]);
|
||||
if ((picode->du.lastDefRegi & duReg[regi]).any() &&
|
||||
((ticode->ic.hl.opcode != HLI_CALL) &&
|
||||
(ticode->ic.hl.opcode != HLI_RET)))
|
||||
@ -816,7 +818,8 @@ void Function::findExps()
|
||||
break;
|
||||
|
||||
case HLI_CALL:
|
||||
ticode = Icode.begin()+(picode->du1.idx[0][0]);
|
||||
ticode = Icode.begin();
|
||||
advance(ticode,picode->du1.idx[0][0]);
|
||||
switch (ticode->ic.hl.opcode) {
|
||||
case HLI_ASSIGN:
|
||||
exp = COND_EXPR::idFunc (
|
||||
@ -885,7 +888,8 @@ void Function::findExps()
|
||||
* icode expression */
|
||||
if (picode->du1.idx[0][0] == picode->du1.idx[1][0])
|
||||
{
|
||||
ticode = Icode.begin()+(picode->du1.idx[0][0]);
|
||||
ticode = Icode.begin();
|
||||
advance(ticode,picode->du1.idx[0][0]);
|
||||
if ((picode->du.lastDefRegi & duReg[regi]).any() &&
|
||||
((ticode->ic.hl.opcode != HLI_CALL) &&
|
||||
(ticode->ic.hl.opcode != HLI_RET)))
|
||||
@ -922,7 +926,8 @@ void Function::findExps()
|
||||
case HLI_POP:
|
||||
if (picode->du1.idx[0][0] == picode->du1.idx[1][0])
|
||||
{
|
||||
ticode = Icode.begin()+(picode->du1.idx[0][0]);
|
||||
ticode = Icode.begin();
|
||||
advance(ticode,picode->du1.idx[0][0]);
|
||||
if ((picode->du.lastDefRegi & duReg[regi]).any() &&
|
||||
((ticode->ic.hl.opcode != HLI_CALL) &&
|
||||
(ticode->ic.hl.opcode != HLI_RET)))
|
||||
@ -951,7 +956,8 @@ void Function::findExps()
|
||||
break;
|
||||
|
||||
case HLI_CALL: /* check for function return */
|
||||
ticode = Icode.begin()+(picode->du1.idx[0][0]);
|
||||
ticode = Icode.begin();
|
||||
advance(ticode,picode->du1.idx[0][0]);
|
||||
switch (ticode->ic.hl.opcode)
|
||||
{
|
||||
case HLI_ASSIGN:
|
||||
|
||||
316
src/disassem.cpp
316
src/disassem.cpp
@ -3,18 +3,18 @@
|
||||
* (C) Cristina Cifuentes, Mike van Emmerik, Jeff Ledermann
|
||||
****************************************************************************/
|
||||
#include <stdint.h>
|
||||
#include "dcc.h"
|
||||
#include "symtab.h"
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h> /* For free() */
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#ifdef _CONSOLE
|
||||
#include <windows.h> /* For console mode routines */
|
||||
#endif
|
||||
|
||||
#include "dcc.h"
|
||||
#include "symtab.h"
|
||||
#include "disassem.h"
|
||||
|
||||
// Note: for the time being, there is no interactive disassembler
|
||||
// for unix
|
||||
#ifndef __UNIX__
|
||||
@ -127,23 +127,24 @@ static const char *szWreg[12] = { "ax", "cx", "dx", "bx", "sp", "bp", "si", "di"
|
||||
static const char *szPtr[2] = { "word ptr ", "byte ptr " };
|
||||
|
||||
|
||||
static void dis1Line (Int i, Int pass);
|
||||
static void dis1Line (ICODE &icode, Int pass);
|
||||
void dis1LineOp(Int i, boolT fWin, char attr, word *len, Function * pProc);
|
||||
static void formatRM(ostringstream &p, flags32 flg, LLOperand *pm);
|
||||
static ostringstream &strDst(ostringstream &os, flags32 flg, LLOperand *pm);
|
||||
static ostringstream &strSrc(ostringstream &os, ICODE *pc, bool skip_comma=false);
|
||||
static void formatRM(ostringstream &p, flags32 flg, const LLOperand &pm);
|
||||
static ostringstream &strDst(ostringstream &os, flags32 flg, LLOperand &pm);
|
||||
static ostringstream &strSrc(ostringstream &os,const LLInst &pc,bool skip_comma=false);
|
||||
|
||||
static char *strHex(dword d);
|
||||
static Int checkScanned(dword pcCur);
|
||||
static void setProc(Function * proc);
|
||||
static void dispData(word dataSeg);
|
||||
void flops(ICODE *pIcode,std::ostringstream &out);
|
||||
void flops(LLInst &pIcode, std::ostringstream &out);
|
||||
boolT callArg(word off, char *temp); /* Check for procedure name */
|
||||
|
||||
static FILE *fp;
|
||||
static CIcodeRec pc;
|
||||
static std::ostringstream buf;
|
||||
static Int cb, j, numIcode, allocIcode, eop;
|
||||
static vector<int> pl;
|
||||
static map<int,int> pl;
|
||||
static dword nextInst;
|
||||
static boolT fImpure;
|
||||
static Int lab, prevPass;
|
||||
@ -209,24 +210,25 @@ void disassem(Int pass, Function * ppProc)
|
||||
if (pass == 1)
|
||||
{
|
||||
/* Bind jump offsets to labels */
|
||||
for (i = 0; i < numIcode; i++)
|
||||
//for (i = 0; i < numIcode; i++)
|
||||
for( ICODE &icode : pc)
|
||||
{
|
||||
if ((pc[i].ic.ll.flg & I) && !(pc[i].ic.ll.flg & JMP_ICODE) &&
|
||||
JmpInst(pc[i].ic.ll.opcode))
|
||||
if ((icode.ic.ll.flg & I) && !(icode.ic.ll.flg & JMP_ICODE) &&
|
||||
JmpInst(icode.ic.ll.opcode))
|
||||
{
|
||||
/* Replace the immediate operand with an icode index */
|
||||
dword labTgt;
|
||||
if (pc.labelSrch(pc[i].ic.ll.src.op(),labTgt))
|
||||
iICODE labTgt=pc.labelSrch(icode.ic.ll.src.op());
|
||||
if (labTgt!=pc.end())
|
||||
{
|
||||
pc[i].ic.ll.src.SetImmediateOp(labTgt);
|
||||
icode.ic.ll.src.SetImmediateOp(labTgt->loc_ip);
|
||||
/* This icode is the target of a jump */
|
||||
pc[labTgt].ic.ll.flg |= TARGET;
|
||||
pc[i].ic.ll.flg |= JMP_ICODE; /* So its not done twice */
|
||||
labTgt->ic.ll.flg |= TARGET;
|
||||
icode.ic.ll.flg |= JMP_ICODE; /* So its not done twice */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This jump cannot be linked to a label */
|
||||
pc[i].ic.ll.flg |= NO_LABEL;
|
||||
icode.ic.ll.flg |= NO_LABEL;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -234,17 +236,16 @@ void disassem(Int pass, Function * ppProc)
|
||||
|
||||
/* Create label array to keep track of location => label name */
|
||||
pl.clear();
|
||||
pl.resize(numIcode,0);
|
||||
|
||||
/* Write procedure header */
|
||||
if (pass != 3)
|
||||
fprintf(fp, "\t\t%s PROC %s\n", pProc->name.c_str(), (pProc->flg & PROC_FAR)? "FAR": "NEAR");
|
||||
|
||||
/* Loop over array printing each record */
|
||||
for (i = nextInst = 0; i < numIcode; i++)
|
||||
{
|
||||
dis1Line(i, pass);
|
||||
}
|
||||
nextInst = 0;
|
||||
std::for_each(pc.begin(),
|
||||
pc.end(),
|
||||
[pass](ICODE &iter)->void {dis1Line(iter, pass);});
|
||||
|
||||
/* Write procedure epilogue */
|
||||
if (pass != 3)
|
||||
@ -262,28 +263,29 @@ void disassem(Int pass, Function * ppProc)
|
||||
* i is index into Icode for this proc *
|
||||
* It is assumed that icode i is already scanned *
|
||||
****************************************************************************/
|
||||
static void dis1Line(Int i, Int pass)
|
||||
static void dis1Line(ICODE &icode_iter, Int pass)
|
||||
{
|
||||
ostringstream oper_stream;
|
||||
ostringstream hex_bytes;
|
||||
ostringstream result_stream;
|
||||
ICODE * pIcode = &pc[i];
|
||||
|
||||
oper_stream << uppercase;
|
||||
hex_bytes << uppercase;
|
||||
LLInst &_IcLL(icode_iter.ic.ll);
|
||||
/* Disassembly stage 1 --
|
||||
* Do not try to display NO_CODE entries or synthetic instructions,
|
||||
* other than JMPs, that have been introduced for def/use analysis. */
|
||||
if ((option.asm1) &&
|
||||
((pIcode->ic.ll.flg & NO_CODE) ||
|
||||
((pIcode->ic.ll.flg & SYNTHETIC) && (pIcode->ic.ll.opcode != iJMP))))
|
||||
((_IcLL.flg & NO_CODE) ||
|
||||
((_IcLL.flg & SYNTHETIC) && (_IcLL.opcode != iJMP))))
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if (pIcode->ic.ll.flg & NO_CODE)
|
||||
else if (_IcLL.flg & NO_CODE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (pIcode->ic.ll.flg & (TARGET | CASE))
|
||||
if (_IcLL.flg & (TARGET | CASE))
|
||||
{
|
||||
if (pass == 3)
|
||||
cCode.appendCode("\n"); /* Print to c code buffer */
|
||||
@ -292,19 +294,19 @@ static void dis1Line(Int i, Int pass)
|
||||
}
|
||||
|
||||
/* Find next instruction label and print hex bytes */
|
||||
if (pIcode->ic.ll.flg & SYNTHETIC)
|
||||
nextInst = pIcode->ic.ll.label;
|
||||
if (_IcLL.flg & SYNTHETIC)
|
||||
nextInst = _IcLL.label;
|
||||
else
|
||||
{
|
||||
cb = (dword) pIcode->ic.ll.numBytes;
|
||||
nextInst = pIcode->ic.ll.label + cb;
|
||||
cb = (dword) _IcLL.numBytes;
|
||||
nextInst = _IcLL.label + cb;
|
||||
|
||||
/* Output hexa code in program image */
|
||||
if (pass != 3)
|
||||
{
|
||||
for (j = 0; j < cb; j++)
|
||||
{
|
||||
hex_bytes << hex << setw(2) << setfill('0') << uint16_t(prog.Image[pIcode->ic.ll.label + j]);
|
||||
hex_bytes << hex << setw(2) << setfill('0') << uint16_t(prog.Image[_IcLL.label + j]);
|
||||
}
|
||||
hex_bytes << ' ';
|
||||
}
|
||||
@ -315,78 +317,78 @@ static void dis1Line(Int i, Int pass)
|
||||
oper_stream << setw(5)<<left; // align for the labels
|
||||
{
|
||||
ostringstream lab_contents;
|
||||
if (readVal(lab_contents, pIcode->ic.ll.label, 0))
|
||||
if (readVal(lab_contents, _IcLL.label, 0))
|
||||
{
|
||||
lab_contents << ':'; /* Also removes the null */
|
||||
}
|
||||
else if (pIcode->ic.ll.flg & TARGET) /* Symbols override Lnn labels */
|
||||
else if (_IcLL.flg & TARGET) /* Symbols override Lnn labels */
|
||||
{
|
||||
/* Print label */
|
||||
if (! pl[i])
|
||||
if (pl.count(icode_iter.loc_ip)==0)
|
||||
{
|
||||
pl[i] = ++lab;
|
||||
pl[icode_iter.loc_ip] = ++lab;
|
||||
}
|
||||
lab_contents<< "L"<<pl[i]<<':';
|
||||
lab_contents<< "L"<<pl[icode_iter.loc_ip]<<':';
|
||||
}
|
||||
oper_stream<< lab_contents.str();
|
||||
}
|
||||
if (pIcode->ic.ll.opcode == iSIGNEX && (pIcode->ic.ll.flg & B))
|
||||
if (_IcLL.opcode == iSIGNEX && (_IcLL.flg & B))
|
||||
{
|
||||
pIcode->ic.ll.opcode = iCBW;
|
||||
_IcLL.opcode = iCBW;
|
||||
}
|
||||
oper_stream << setw(15) << left <<szOps[pIcode->ic.ll.opcode];
|
||||
oper_stream << setw(15) << left <<szOps[_IcLL.opcode];
|
||||
|
||||
switch (pIcode->ic.ll.opcode)
|
||||
switch (_IcLL.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,pIcode->ic.ll.flg, &pIcode->ic.ll.dst);
|
||||
strSrc(oper_stream,pIcode);
|
||||
strDst(oper_stream,_IcLL.flg, _IcLL.dst);
|
||||
strSrc(oper_stream,_IcLL);
|
||||
break;
|
||||
|
||||
case iESC:
|
||||
flops(pIcode,oper_stream);
|
||||
flops(_IcLL,oper_stream);
|
||||
break;
|
||||
|
||||
case iSAR: case iSHL: case iSHR: case iRCL: case iRCR: case iROL:
|
||||
case iROR:
|
||||
strDst(oper_stream,pIcode->ic.ll.flg | I, &pIcode->ic.ll.dst);
|
||||
if(pIcode->ic.ll.flg & I)
|
||||
strSrc(oper_stream,pIcode);
|
||||
strDst(oper_stream,_IcLL.flg | I, _IcLL.dst);
|
||||
if(_IcLL.flg & I)
|
||||
strSrc(oper_stream,_IcLL);
|
||||
else
|
||||
oper_stream<<", cl";
|
||||
break;
|
||||
|
||||
case iINC: case iDEC: case iNEG: case iNOT: case iPOP:
|
||||
strDst(oper_stream,pIcode->ic.ll.flg | I, &pIcode->ic.ll.dst);
|
||||
strDst(oper_stream,_IcLL.flg | I, _IcLL.dst);
|
||||
break;
|
||||
|
||||
case iPUSH:
|
||||
if (pIcode->ic.ll.flg & I)
|
||||
if (_IcLL.flg & I)
|
||||
{
|
||||
oper_stream<<strHex(pIcode->ic.ll.src.op());
|
||||
oper_stream<<strHex(_IcLL.src.op());
|
||||
// strcpy(p + WID_PTR, strHex(pIcode->ic.ll.immed.op));
|
||||
}
|
||||
else
|
||||
{
|
||||
strDst(oper_stream,pIcode->ic.ll.flg | I, &pIcode->ic.ll.dst);
|
||||
strDst(oper_stream,_IcLL.flg | I, _IcLL.dst);
|
||||
}
|
||||
break;
|
||||
|
||||
case iDIV: case iIDIV: case iMUL: case iIMUL: case iMOD:
|
||||
if (pIcode->ic.ll.flg & I)
|
||||
if (_IcLL.flg & I)
|
||||
{
|
||||
strDst(oper_stream,pIcode->ic.ll.flg, &pIcode->ic.ll.dst) <<", ";
|
||||
formatRM(oper_stream, pIcode->ic.ll.flg, &pIcode->ic.ll.src);
|
||||
strSrc(oper_stream,pIcode);
|
||||
strDst(oper_stream,_IcLL.flg, _IcLL.dst) <<", ";
|
||||
formatRM(oper_stream, _IcLL.flg, _IcLL.src);
|
||||
strSrc(oper_stream,_IcLL);
|
||||
}
|
||||
else
|
||||
strDst(oper_stream,pIcode->ic.ll.flg | I, &pIcode->ic.ll.src);
|
||||
strDst(oper_stream,_IcLL.flg | I, _IcLL.src);
|
||||
break;
|
||||
|
||||
case iLDS: case iLES: case iBOUND:
|
||||
strDst(oper_stream,pIcode->ic.ll.flg, &pIcode->ic.ll.dst)<<", dword ptr";
|
||||
strSrc(oper_stream,pIcode,true);
|
||||
strDst(oper_stream,_IcLL.flg, _IcLL.dst)<<", dword ptr";
|
||||
strSrc(oper_stream,_IcLL,true);
|
||||
break;
|
||||
|
||||
case iJB: case iJBE: case iJAE: case iJA:
|
||||
@ -397,69 +399,72 @@ static void dis1Line(Int i, Int pass)
|
||||
case iJMP: case iJMPF:
|
||||
|
||||
/* Check if there is a symbol here */
|
||||
{
|
||||
ICODE *lab=pc.GetIcode(_IcLL.src.op());
|
||||
selectTable(Label);
|
||||
if ((pIcode->ic.ll.src.op() < (dword)numIcode) && /* Ensure in range */
|
||||
readVal(oper_stream, pc[pIcode->ic.ll.src.op()].ic.ll.label, 0))
|
||||
if ((_IcLL.src.op() < (dword)numIcode) && /* Ensure in range */
|
||||
readVal(oper_stream, lab->ic.ll.label, 0))
|
||||
{
|
||||
break; /* Symbolic label. Done */
|
||||
}
|
||||
}
|
||||
|
||||
if (pIcode->ic.ll.flg & NO_LABEL)
|
||||
if (_IcLL.flg & NO_LABEL)
|
||||
{
|
||||
//strcpy(p + WID_PTR, strHex(pIcode->ic.ll.immed.op));
|
||||
oper_stream<<strHex(pIcode->ic.ll.src.op());
|
||||
oper_stream<<strHex(_IcLL.src.op());
|
||||
}
|
||||
else if (pIcode->ic.ll.flg & I)
|
||||
else if (_IcLL.flg & I)
|
||||
{
|
||||
j = pIcode->ic.ll.src.op();
|
||||
if (! pl[j]) /* Forward jump */
|
||||
j = _IcLL.src.op();
|
||||
if (pl.count(j)==0) /* Forward jump */
|
||||
{
|
||||
pl[j] = ++lab;
|
||||
}
|
||||
if (pIcode->ic.ll.opcode == iJMPF)
|
||||
if (_IcLL.opcode == iJMPF)
|
||||
{
|
||||
oper_stream<<" far ptr ";
|
||||
}
|
||||
oper_stream<<"L"<<pl[j];
|
||||
}
|
||||
else if (pIcode->ic.ll.opcode == iJMPF)
|
||||
else if (_IcLL.opcode == iJMPF)
|
||||
{
|
||||
oper_stream<<"dword ptr";
|
||||
strSrc(oper_stream,pIcode,true);
|
||||
strSrc(oper_stream,_IcLL,true);
|
||||
}
|
||||
else
|
||||
{
|
||||
strDst(oper_stream,I, &pIcode->ic.ll.src);
|
||||
strDst(oper_stream,I, _IcLL.src);
|
||||
}
|
||||
break;
|
||||
|
||||
case iCALL: case iCALLF:
|
||||
if (pIcode->ic.ll.flg & I)
|
||||
if (_IcLL.flg & I)
|
||||
{
|
||||
if((pIcode->ic.ll.opcode == iCALL))
|
||||
if((_IcLL.opcode == iCALL))
|
||||
oper_stream<< "near";
|
||||
else
|
||||
oper_stream<< " far";
|
||||
oper_stream<<" ptr "<<(pIcode->ic.ll.src.proc.proc)->name;
|
||||
oper_stream<<" ptr "<<(_IcLL.src.proc.proc)->name;
|
||||
}
|
||||
else if (pIcode->ic.ll.opcode == iCALLF)
|
||||
else if (_IcLL.opcode == iCALLF)
|
||||
{
|
||||
oper_stream<<"dword ptr ";
|
||||
strSrc(oper_stream,pIcode,true);
|
||||
strSrc(oper_stream,_IcLL,true);
|
||||
}
|
||||
else
|
||||
strDst(oper_stream,I, &pIcode->ic.ll.src);
|
||||
strDst(oper_stream,I, _IcLL.src);
|
||||
break;
|
||||
|
||||
case iENTER:
|
||||
oper_stream<<strHex(pIcode->ic.ll.dst.off)<<", ";
|
||||
oper_stream<<strHex(pIcode->ic.ll.src.op());
|
||||
oper_stream<<strHex(_IcLL.dst.off)<<", ";
|
||||
oper_stream<<strHex(_IcLL.src.op());
|
||||
break;
|
||||
|
||||
case iRET: case iRETF: case iINT:
|
||||
if (pIcode->ic.ll.flg & I)
|
||||
if (_IcLL.flg & I)
|
||||
{
|
||||
oper_stream<<strHex(pIcode->ic.ll.src.op());
|
||||
oper_stream<<strHex(_IcLL.src.op());
|
||||
}
|
||||
break;
|
||||
|
||||
@ -470,46 +475,46 @@ static void dis1Line(Int i, Int pass)
|
||||
case iMOVS: case iREP_MOVS:
|
||||
case iINS: case iREP_INS:
|
||||
case iOUTS: case iREP_OUTS:
|
||||
if (pIcode->ic.ll.src.segOver)
|
||||
if (_IcLL.src.segOver)
|
||||
{
|
||||
bool is_dx_src=(pIcode->ic.ll.opcode == iOUTS || pIcode->ic.ll.opcode == iREP_OUTS);
|
||||
bool is_dx_src=(_IcLL.opcode == iOUTS || _IcLL.opcode == iREP_OUTS);
|
||||
if(is_dx_src)
|
||||
oper_stream<<"dx, "<<szPtr[pIcode->ic.ll.flg & B];
|
||||
oper_stream<<"dx, "<<szPtr[_IcLL.flg & B];
|
||||
else
|
||||
oper_stream<<szPtr[pIcode->ic.ll.flg & B];
|
||||
if (pIcode->ic.ll.opcode == iLODS ||
|
||||
pIcode->ic.ll.opcode == iREP_LODS ||
|
||||
pIcode->ic.ll.opcode == iOUTS ||
|
||||
pIcode->ic.ll.opcode == iREP_OUTS)
|
||||
oper_stream<<szPtr[_IcLL.flg & B];
|
||||
if (_IcLL.opcode == iLODS ||
|
||||
_IcLL.opcode == iREP_LODS ||
|
||||
_IcLL.opcode == iOUTS ||
|
||||
_IcLL.opcode == iREP_OUTS)
|
||||
{
|
||||
oper_stream<<szWreg[pIcode->ic.ll.src.segOver-rAX];
|
||||
oper_stream<<szWreg[_IcLL.src.segOver-rAX];
|
||||
}
|
||||
else
|
||||
{
|
||||
oper_stream<<"es:[di], "<<szWreg[pIcode->ic.ll.src.segOver - rAX];
|
||||
oper_stream<<"es:[di], "<<szWreg[_IcLL.src.segOver - rAX];
|
||||
}
|
||||
oper_stream<<":[si]";
|
||||
}
|
||||
else
|
||||
oper_stream<<(pIcode->ic.ll.flg & B)? "B": "W";
|
||||
oper_stream<<(_IcLL.flg & B)? "B": "W";
|
||||
break;
|
||||
|
||||
case iXLAT:
|
||||
if (pIcode->ic.ll.src.segOver)
|
||||
if (_IcLL.src.segOver)
|
||||
{
|
||||
oper_stream<<" "<<szPtr[1];
|
||||
oper_stream<<szWreg[pIcode->ic.ll.src.segOver-rAX]<<":[bx]";
|
||||
oper_stream<<szWreg[_IcLL.src.segOver-rAX]<<":[bx]";
|
||||
}
|
||||
break;
|
||||
|
||||
case iIN:
|
||||
oper_stream<<(pIcode->ic.ll.flg & B)?"al, ": "ax, ";
|
||||
oper_stream<<(pIcode->ic.ll.flg & I)? strHex(pIcode->ic.ll.src.op()): "dx";
|
||||
oper_stream<<(_IcLL.flg & B)?"al, ": "ax, ";
|
||||
oper_stream<<(_IcLL.flg & I)? strHex(_IcLL.src.op()): "dx";
|
||||
break;
|
||||
|
||||
case iOUT:
|
||||
oper_stream<<(pIcode->ic.ll.flg & I)? strHex(pIcode->ic.ll.src.op()): "dx";
|
||||
oper_stream<<(pIcode->ic.ll.flg & B)?", al": ", ax";
|
||||
oper_stream<<(_IcLL.flg & I)? strHex(_IcLL.src.op()): "dx";
|
||||
oper_stream<<(_IcLL.flg & B)?", al": ", ax";
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -517,13 +522,13 @@ static void dis1Line(Int i, Int pass)
|
||||
}
|
||||
|
||||
/* Comments */
|
||||
if (pIcode->ic.ll.flg & SYNTHETIC)
|
||||
if (_IcLL.flg & SYNTHETIC)
|
||||
{
|
||||
fImpure = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (j = pIcode->ic.ll.label, fImpure = 0; j > 0 && j < (Int)nextInst; j++)
|
||||
for (j = _IcLL.label, fImpure = 0; j > 0 && j < (Int)nextInst; j++)
|
||||
{
|
||||
fImpure |= BITMAP(j, BM_DATA);
|
||||
}
|
||||
@ -533,17 +538,17 @@ static void dis1Line(Int i, Int pass)
|
||||
/* Check for user supplied comment */
|
||||
selectTable(Comment);
|
||||
ostringstream cbuf;
|
||||
if (readVal(cbuf, pIcode->ic.ll.label, 0))
|
||||
if (readVal(cbuf, _IcLL.label, 0))
|
||||
{
|
||||
result_stream <<"; "<<cbuf.str();
|
||||
}
|
||||
else if (fImpure || (pIcode->ic.ll.flg & (SWITCH | CASE | SEG_IMMED | IMPURE | SYNTHETIC | TERMINATES)))
|
||||
else if (fImpure || (_IcLL.flg & (SWITCH | CASE | SEG_IMMED | IMPURE | SYNTHETIC | TERMINATES)))
|
||||
{
|
||||
if (pIcode->ic.ll.flg & CASE)
|
||||
if (_IcLL.flg & CASE)
|
||||
{
|
||||
result_stream << ";Case l"<< pIcode->ic.ll.caseTbl.numEntries;
|
||||
result_stream << ";Case l"<< _IcLL.caseTbl.numEntries;
|
||||
}
|
||||
if (pIcode->ic.ll.flg & SWITCH)
|
||||
if (_IcLL.flg & SWITCH)
|
||||
{
|
||||
result_stream << ";Switch ";
|
||||
}
|
||||
@ -551,29 +556,29 @@ static void dis1Line(Int i, Int pass)
|
||||
{
|
||||
result_stream << ";Accessed as data ";
|
||||
}
|
||||
if (pIcode->ic.ll.flg & IMPURE)
|
||||
if (_IcLL.flg & IMPURE)
|
||||
{
|
||||
result_stream << ";Impure operand ";
|
||||
}
|
||||
if (pIcode->ic.ll.flg & SEG_IMMED)
|
||||
if (_IcLL.flg & SEG_IMMED)
|
||||
{
|
||||
result_stream << ";Segment constant";
|
||||
}
|
||||
if (pIcode->ic.ll.flg & TERMINATES)
|
||||
if (_IcLL.flg & TERMINATES)
|
||||
{
|
||||
result_stream << ";Exit to DOS";
|
||||
}
|
||||
}
|
||||
|
||||
/* Comment on iINT icodes */
|
||||
if (pIcode->ic.ll.opcode == iINT)
|
||||
pIcode->writeIntComment (result_stream);
|
||||
if (_IcLL.opcode == iINT)
|
||||
icode_iter.writeIntComment(result_stream);
|
||||
|
||||
/* Display output line */
|
||||
if(pass==3)
|
||||
{
|
||||
/* output to .b code buffer */
|
||||
if (pIcode->isLlFlag(SYNTHETIC))
|
||||
if (_IcLL.anyFlagSet(SYNTHETIC))
|
||||
result_stream<<";Synthetic inst";
|
||||
if (pass == 3) /* output to .b code buffer */
|
||||
cCode.appendCode("%s\n", result_stream.str().c_str());
|
||||
@ -581,15 +586,15 @@ static void dis1Line(Int i, Int pass)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (! (pIcode->ic.ll.flg & SYNTHETIC))
|
||||
if (not _IcLL.anyFlagSet(SYNTHETIC) )
|
||||
{
|
||||
/* output to .a1 or .a2 file */
|
||||
fprintf (fp, "%03ld %06lX %s\n", i, pIcode->ic.ll.label, result_stream.str().c_str());
|
||||
fprintf (fp, "%03ld %06lX %s\n", icode_iter.loc_ip, _IcLL.label, result_stream.str().c_str());
|
||||
}
|
||||
else /* SYNTHETIC instruction */
|
||||
{
|
||||
result_stream<<";Synthetic inst";
|
||||
fprintf (fp, "%03ld %s\n", i, result_stream.str().c_str());
|
||||
fprintf (fp, "%03ld %s\n", icode_iter.loc_ip, result_stream.str().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -599,58 +604,58 @@ static void dis1Line(Int i, Int pass)
|
||||
/****************************************************************************
|
||||
* formatRM
|
||||
***************************************************************************/
|
||||
static void formatRM(std::ostringstream &p, flags32 flg, LLOperand *pm)
|
||||
static void formatRM(std::ostringstream &p, flags32 flg, const LLOperand &pm)
|
||||
{
|
||||
char seg[4];
|
||||
|
||||
if (pm->segOver)
|
||||
if (pm.segOver)
|
||||
{
|
||||
strcat(strcpy(seg, szWreg[pm->segOver - rAX]), ":");
|
||||
strcat(strcpy(seg, szWreg[pm.segOver - rAX]), ":");
|
||||
}
|
||||
else *seg = '\0';
|
||||
|
||||
if (pm->regi == 0)
|
||||
if (pm.regi == 0)
|
||||
{
|
||||
p<<seg<<"["<<strHex((dword)pm->off)<<"]";
|
||||
p<<seg<<"["<<strHex((dword)pm.off)<<"]";
|
||||
}
|
||||
|
||||
else if (pm->regi == (INDEXBASE - 1))
|
||||
else if (pm.regi == (INDEXBASE - 1))
|
||||
{
|
||||
p<<"tmp";
|
||||
}
|
||||
|
||||
else if (pm->regi < INDEXBASE)
|
||||
else if (pm.regi < INDEXBASE)
|
||||
{
|
||||
if(flg & B)
|
||||
p << szBreg[pm->regi - rAL];
|
||||
p << szBreg[pm.regi - rAL];
|
||||
else
|
||||
p << szWreg[pm->regi - rAX];
|
||||
p << szWreg[pm.regi - rAX];
|
||||
}
|
||||
|
||||
else if (pm->off)
|
||||
else if (pm.off)
|
||||
{
|
||||
if (pm->off < 0)
|
||||
if (pm.off < 0)
|
||||
{
|
||||
p <<seg<<"["<<szIndex[pm->regi - INDEXBASE]<<"-"<<strHex((dword)(- pm->off))<<"]";
|
||||
p <<seg<<"["<<szIndex[pm.regi - INDEXBASE]<<"-"<<strHex((dword)(- pm.off))<<"]";
|
||||
}
|
||||
else
|
||||
{
|
||||
p <<seg<<"["<<szIndex[pm->regi - INDEXBASE]<<"+"<<strHex((dword)(pm->off))<<"]";
|
||||
p <<seg<<"["<<szIndex[pm.regi - INDEXBASE]<<"+"<<strHex((dword)(pm.off))<<"]";
|
||||
}
|
||||
}
|
||||
else
|
||||
p <<seg<<"["<<szIndex[pm->regi - INDEXBASE]<<"]";
|
||||
p <<seg<<"["<<szIndex[pm.regi - INDEXBASE]<<"]";
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* strDst
|
||||
****************************************************************************/
|
||||
static ostringstream & strDst(ostringstream &os,flags32 flg, LLOperand *pm)
|
||||
static ostringstream & strDst(ostringstream &os,flags32 flg, LLOperand &pm)
|
||||
{
|
||||
/* Immediates to memory require size descriptor */
|
||||
//os << setw(WID_PTR);
|
||||
if ((flg & I) && (pm->regi == 0 || pm->regi >= INDEXBASE))
|
||||
if ((flg & I) && (pm.regi == 0 || pm.regi >= INDEXBASE))
|
||||
os << szPtr[flg & B];
|
||||
formatRM(os, flg, pm);
|
||||
return os;
|
||||
@ -660,22 +665,23 @@ static ostringstream & strDst(ostringstream &os,flags32 flg, LLOperand *pm)
|
||||
/****************************************************************************
|
||||
* strSrc *
|
||||
****************************************************************************/
|
||||
static ostringstream &strSrc(ostringstream &os,ICODE *pc,bool skip_comma)
|
||||
static ostringstream &strSrc(ostringstream &os,const LLInst &l_ins,bool skip_comma)
|
||||
{
|
||||
static char buf[30] = {", "};
|
||||
if(false==skip_comma)
|
||||
os<<", ";
|
||||
if (pc->ic.ll.flg & I)
|
||||
os<<strHex(pc->ic.ll.src.op());
|
||||
else if (pc->ic.ll.flg & IM_SRC) /* level 2 */
|
||||
if (l_ins.flg & I)
|
||||
os<<strHex(l_ins.src.op());
|
||||
else if (l_ins.flg & IM_SRC) /* level 2 */
|
||||
os<<"dx:ax";
|
||||
else
|
||||
formatRM(os, pc->ic.ll.flg, &pc->ic.ll.src);
|
||||
formatRM(os, l_ins.flg, l_ins.src);
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* strHex *
|
||||
****************************************************************************/
|
||||
@ -698,15 +704,15 @@ void interactDis(Function * initProc, Int initIC)
|
||||
}
|
||||
|
||||
/* Handle the floating point opcodes (icode iESC) */
|
||||
void flops(ICODE *pIcode,std::ostringstream &out)
|
||||
void flops(LLInst &pIcode,std::ostringstream &out)
|
||||
{
|
||||
char bf[30];
|
||||
byte op = (byte)pIcode->ic.ll.src.op();
|
||||
byte op = (byte)pIcode.src.op();
|
||||
|
||||
/* Note that op is set to the escape number, e.g.
|
||||
esc 0x38 is FILD */
|
||||
|
||||
if ((pIcode->ic.ll.dst.regi == 0) || (pIcode->ic.ll.dst.regi >= INDEXBASE))
|
||||
if ((pIcode.dst.regi == 0) || (pIcode.dst.regi >= INDEXBASE))
|
||||
{
|
||||
/* The mod/rm mod bits are not set to 11 (i.e. register). This is the normal floating point opcode */
|
||||
out<<szFlops1[op]<<' ';
|
||||
@ -742,7 +748,7 @@ void flops(ICODE *pIcode,std::ostringstream &out)
|
||||
}
|
||||
}
|
||||
|
||||
formatRM(out, pIcode->ic.ll.flg, &pIcode->ic.ll.dst);
|
||||
formatRM(out, pIcode.flg, pIcode.dst);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -751,44 +757,44 @@ void flops(ICODE *pIcode,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=pIcode.dst.regi - rAX;
|
||||
switch (op)
|
||||
{
|
||||
case 0x0C:
|
||||
out << szFlops0C[pIcode->ic.ll.dst.regi - rAX];
|
||||
out << szFlops0C[destRegIdx];
|
||||
break;
|
||||
case 0x0D:
|
||||
out << szFlops0D[pIcode->ic.ll.dst.regi - rAX];
|
||||
out << szFlops0D[destRegIdx];
|
||||
break;
|
||||
case 0x0E:
|
||||
out << szFlops0E[pIcode->ic.ll.dst.regi - rAX];
|
||||
out << szFlops0E[destRegIdx];
|
||||
break;
|
||||
case 0x0F:
|
||||
out << szFlops0F[pIcode->ic.ll.dst.regi - rAX];
|
||||
out << szFlops0F[destRegIdx];
|
||||
break;
|
||||
case 0x15:
|
||||
out << szFlops15[pIcode->ic.ll.dst.regi - rAX];
|
||||
out << szFlops15[destRegIdx];
|
||||
break;
|
||||
case 0x1C:
|
||||
out << szFlops1C[pIcode->ic.ll.dst.regi - rAX];
|
||||
out << szFlops1C[destRegIdx];
|
||||
break;
|
||||
case 0x33:
|
||||
out << szFlops33[pIcode->ic.ll.dst.regi - rAX];
|
||||
out << szFlops33[destRegIdx];
|
||||
break;
|
||||
case 0x3C:
|
||||
out << szFlops3C[pIcode->ic.ll.dst.regi - rAX];
|
||||
out << szFlops3C[destRegIdx];
|
||||
break;
|
||||
default:
|
||||
out << szFlops2[op];
|
||||
if ((op >= 0x20) && (op <= 0x27))
|
||||
{
|
||||
/* This is the ST(i), ST form. */
|
||||
out << "ST("<<pIcode->ic.ll.dst.regi - rAX<<"),ST";
|
||||
out << "ST("<<destRegIdx - rAX<<"),ST";
|
||||
}
|
||||
else
|
||||
{
|
||||
/* ST, ST(i) */
|
||||
out << "ST,ST("<<pIcode->ic.ll.dst.regi - rAX;
|
||||
out << "ST,ST("<<destRegIdx;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
@ -1,139 +0,0 @@
|
||||
#include "dcc.h"
|
||||
#include "epilogue_idioms.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* popStkVars - checks for
|
||||
* [POP DI]
|
||||
* [POP SI]
|
||||
* or [POP SI]
|
||||
* [POP DI]
|
||||
****************************************************************************/
|
||||
void EpilogIdiom::popStkVars(iICODE pIcode)
|
||||
{
|
||||
// TODO : only process SI-DI DI-SI pairings, no SI-SI, DI-DI like it's now
|
||||
/* Match [POP DI] */
|
||||
if (pIcode->ic.ll.match(iPOP))
|
||||
{
|
||||
if ((m_func->flg & DI_REGVAR) && pIcode->ic.ll.match(rDI))
|
||||
m_icodes.push_front(pIcode);
|
||||
else if ((m_func->flg & SI_REGVAR) && pIcode->ic.ll.match(rSI))
|
||||
m_icodes.push_front(pIcode);
|
||||
}
|
||||
++pIcode;
|
||||
if(pIcode==m_end)
|
||||
return;
|
||||
/* Match [POP SI] */
|
||||
if (pIcode->ic.ll.match(iPOP))
|
||||
{
|
||||
if ((m_func->flg & SI_REGVAR) && pIcode->ic.ll.match(rSI))
|
||||
m_icodes.push_front(pIcode);
|
||||
else if ((m_func->flg & DI_REGVAR) && pIcode->ic.ll.match(rDI))
|
||||
m_icodes.push_front(pIcode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* idiom2 - HLL procedure epilogue; Returns number of instructions matched.
|
||||
* [POP DI]
|
||||
* [POP SI]
|
||||
* MOV SP, BP
|
||||
* POP BP
|
||||
* RET(F)
|
||||
*****************************************************************************/
|
||||
bool Idiom2::match(iICODE pIcode)
|
||||
{
|
||||
iICODE nicode;
|
||||
if(pIcode==m_func->Icode.begin()) // pIcode->loc_ip == 0
|
||||
return false;
|
||||
if ( ((pIcode->ic.ll.flg & I) == I) || not pIcode->ic.ll.match(rSP,rBP))
|
||||
return false;
|
||||
if(distance(pIcode,m_end)<3)
|
||||
return false;
|
||||
/* Matched MOV SP, BP */
|
||||
m_icodes.clear();
|
||||
m_icodes.push_back(pIcode);
|
||||
/* Get next icode, skip over holes in the icode array */
|
||||
nicode = pIcode + 1;
|
||||
while (nicode->ic.ll.flg & NO_CODE && (nicode != m_end))
|
||||
{
|
||||
nicode++;
|
||||
}
|
||||
if(nicode == m_end)
|
||||
return false;
|
||||
|
||||
if (nicode->ic.ll.match(iPOP,rBP) && ! (nicode->ic.ll.flg & (I | TARGET | CASE)) )
|
||||
{
|
||||
m_icodes.push_back(nicode++); // Matched POP BP
|
||||
|
||||
/* Match RET(F) */
|
||||
if ( nicode != m_end &&
|
||||
!(nicode->ic.ll.flg & (I | TARGET | CASE)) &&
|
||||
(nicode->ic.ll.match(iRET) || nicode->ic.ll.match(iRETF))
|
||||
)
|
||||
{
|
||||
m_icodes.push_back(nicode); // Matched RET
|
||||
popStkVars (pIcode-2); // will add optional pop di/si to m_icodes
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
int Idiom2::action()
|
||||
{
|
||||
for(size_t idx=0; idx<m_icodes.size()-1; ++idx) // don't invalidate last entry
|
||||
m_icodes[idx]->invalidate();
|
||||
return 3;
|
||||
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* idiom4 - Pascal calling convention.
|
||||
* RET(F) immed
|
||||
* ==> pProc->cbParam = immed
|
||||
* sets CALL_PASCAL flag
|
||||
* - Second version: check for optional pop of stack vars
|
||||
* [POP DI]
|
||||
* [POP SI]
|
||||
* POP BP
|
||||
* RET(F) [immed]
|
||||
* - Third version: pop stack vars
|
||||
* [POP DI]
|
||||
* [POP SI]
|
||||
* RET(F) [immed]
|
||||
****************************************************************************/
|
||||
bool Idiom4::match(iICODE pIcode)
|
||||
{
|
||||
m_param_count = 0;
|
||||
/* Check for [POP DI]
|
||||
* [POP SI] */
|
||||
if(distance(m_func->Icode.begin(),pIcode)>=3)
|
||||
popStkVars (pIcode-3);
|
||||
if(pIcode != m_func->Icode.begin())
|
||||
{
|
||||
iICODE prev1=pIcode-1;
|
||||
/* Check for POP BP */
|
||||
if (prev1->ic.ll.match(iPOP,rBP) && not prev1->ic.ll.anyFlagSet(I) )
|
||||
m_icodes.push_back(prev1);
|
||||
else if(prev1!=m_func->Icode.begin())
|
||||
popStkVars (pIcode-2);
|
||||
}
|
||||
|
||||
/* Check for RET(F) immed */
|
||||
if (pIcode->ic.ll.flg & I)
|
||||
{
|
||||
m_param_count = (int16)pIcode->ic.ll.src.op();
|
||||
}
|
||||
}
|
||||
int Idiom4::action()
|
||||
{
|
||||
for(size_t idx=0; idx<m_icodes.size()-1; ++idx) // don't invalidate last entry
|
||||
m_icodes[idx]->invalidate();
|
||||
if(m_param_count)
|
||||
{
|
||||
m_func->cbParam = (int16)m_param_count;
|
||||
m_func->flg |= CALL_PASCAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -116,19 +116,24 @@ CondJumps:
|
||||
|
||||
default:
|
||||
/* Check for exit to DOS */
|
||||
iICODE next1=++iICODE(pIcode);
|
||||
if (pIcode->ic.ll.flg & TERMINATES)
|
||||
{
|
||||
pBB = BB::Create(start, ip, TERMINATE_NODE, 0, this);
|
||||
start = ip + 1;
|
||||
}
|
||||
/* Check for a fall through */
|
||||
else if (Icode[ip + 1].ic.ll.flg & (TARGET | CASE))
|
||||
else if (next1 != Icode.end())
|
||||
{
|
||||
pBB = BB::Create(start, ip, FALL_NODE, 1, this);
|
||||
start = ip + 1;
|
||||
pBB->edges[0].ip = (dword)start;
|
||||
assert(next1->loc_ip==ip+1);
|
||||
if (next1->ic.ll.flg & (TARGET | CASE))
|
||||
{
|
||||
pBB = BB::Create(start, ip, FALL_NODE, 1, this);
|
||||
start = ip + 1;
|
||||
pBB->edges[0].ip = (dword)start;
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -217,7 +222,9 @@ void Function::compressCFG()
|
||||
if (not pBB->edges.empty()) /* Might have been clobbered */
|
||||
{
|
||||
pBB->edges[i].BBptr = pNxt;
|
||||
Icode[ip].SetImmediateOp((dword)pNxt->begin());
|
||||
assert(pBB->back().loc_ip==ip);
|
||||
pBB->back().SetImmediateOp((dword)pNxt->begin());
|
||||
//Icode[ip].SetImmediateOp((dword)pNxt->begin());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,7 +15,6 @@
|
||||
|
||||
CIcodeRec::CIcodeRec()
|
||||
{
|
||||
reserve(1024);
|
||||
}
|
||||
|
||||
/* Copies the icode that is pointed to by pIcode to the icode array.
|
||||
@ -30,8 +29,11 @@ ICODE * CIcodeRec::addIcode(ICODE *pIcode)
|
||||
|
||||
void CIcodeRec::SetInBB(int start, int end, BB *pnewBB)
|
||||
{
|
||||
for (int i = start; i <= end; i++)
|
||||
at(i).inBB = pnewBB;
|
||||
for(ICODE &icode : *this)
|
||||
if((icode.loc_ip>=start) and (icode.loc_ip<=end))
|
||||
icode.inBB = pnewBB;
|
||||
// for (int i = start; i <= end; i++)
|
||||
// at(i).inBB = pnewBB;
|
||||
}
|
||||
|
||||
/* labelSrchRepl - Searches the icodes for instruction with label = target, and
|
||||
@ -39,33 +41,23 @@ void CIcodeRec::SetInBB(int start, int end, BB *pnewBB)
|
||||
bool CIcodeRec::labelSrch(dword target, dword &pIndex)
|
||||
{
|
||||
Int i;
|
||||
|
||||
for (i = 0; i < size(); i++)
|
||||
{
|
||||
if (at(i).ic.ll.label == target)
|
||||
{
|
||||
pIndex = i;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
iICODE location=labelSrch(target);
|
||||
if(end()==location)
|
||||
return false;
|
||||
pIndex=location->loc_ip;
|
||||
return true;
|
||||
}
|
||||
CIcodeRec::iterator CIcodeRec::labelSrch(dword target)
|
||||
{
|
||||
Int i;
|
||||
|
||||
for (i = 0; i < size(); i++)
|
||||
{
|
||||
if (at(i).ic.ll.label == target)
|
||||
{
|
||||
return begin()+i;
|
||||
}
|
||||
}
|
||||
return end();
|
||||
return find_if(begin(),end(),[target](ICODE &l) -> bool {return l.ic.ll.label==target;});
|
||||
}
|
||||
ICODE * CIcodeRec::GetIcode(int ip)
|
||||
{
|
||||
return &at(ip);
|
||||
assert(ip>=0 && ip<size());
|
||||
iICODE res=begin();
|
||||
advance(res,ip);
|
||||
return &(*res);
|
||||
}
|
||||
|
||||
extern char *indent(int level);
|
||||
|
||||
132
src/idiom1.cpp
132
src/idiom1.cpp
@ -1,132 +0,0 @@
|
||||
#include "idiom1.h"
|
||||
#include "dcc.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* idiom1 - HLL procedure prologue; Returns number of instructions matched.
|
||||
* PUSH BP ==> ENTER immed, 0
|
||||
* MOV BP, SP and sets PROC_HLL flag
|
||||
* [SUB SP, immed]
|
||||
* [PUSH SI]
|
||||
* [PUSH DI]
|
||||
* - Second version: Push stack variables and then save BP
|
||||
* PUSH BP
|
||||
* PUSH SI
|
||||
* [PUSH DI]
|
||||
* MOV BP, SP
|
||||
* - Third version: Stack variables
|
||||
* [PUSH SI]
|
||||
* [PUSH DI]
|
||||
****************************************************************************/
|
||||
/*****************************************************************************
|
||||
/* checkStkVars - Checks for PUSH SI
|
||||
* [PUSH DI]
|
||||
* or PUSH DI
|
||||
* [PUSH SI]
|
||||
* In which case, the stack variable flags are set
|
||||
****************************************************************************/
|
||||
Int Idiom1::checkStkVars (iICODE pIcode)
|
||||
{
|
||||
/* Look for PUSH SI */
|
||||
int si_matched=0;
|
||||
int di_matched=0;
|
||||
if(pIcode==m_end)
|
||||
return 0;
|
||||
if (pIcode->ic.ll.match(iPUSH,rSI))
|
||||
{
|
||||
si_matched = 1;
|
||||
++pIcode;
|
||||
if ((pIcode != m_end) && pIcode->ic.ll.match(iPUSH,rDI)) // Look for PUSH DI
|
||||
di_matched = 1;
|
||||
}
|
||||
else if (pIcode->ic.ll.match(iPUSH,rDI))
|
||||
{
|
||||
di_matched = 1;
|
||||
++pIcode;
|
||||
if ((pIcode != m_end) && pIcode->ic.ll.match(iPUSH,rSI)) // Look for PUSH SI
|
||||
si_matched = 1;
|
||||
}
|
||||
m_func->flg |= (si_matched ? SI_REGVAR : 0) | (di_matched ? DI_REGVAR : 0);
|
||||
return si_matched+di_matched;
|
||||
}
|
||||
bool Idiom1::match(iICODE picode)
|
||||
{
|
||||
uint8_t type = 0; /* type of variable: 1 = reg-var, 2 = local */
|
||||
byte regi; /* register of the MOV */
|
||||
if(picode==m_end)
|
||||
return false;
|
||||
Int n;
|
||||
m_icodes.clear();
|
||||
m_min_off = 0;
|
||||
/* PUSH BP as first instruction of procedure */
|
||||
if ( !(picode->ic.ll.flg & I) && picode->ic.ll.src.regi == rBP)
|
||||
{
|
||||
m_icodes.push_back( picode++ ); // insert iPUSH
|
||||
if(picode==m_end)
|
||||
return false;
|
||||
/* MOV BP, SP as next instruction */
|
||||
if ( !picode->ic.ll.anyFlagSet(I | TARGET | CASE) && picode->ic.ll.match(iMOV ,rBP,rSP) )
|
||||
{
|
||||
m_icodes.push_back( picode++ ); // insert iMOV
|
||||
if(picode==m_end)
|
||||
return false;
|
||||
m_min_off = 2;
|
||||
|
||||
/* Look for SUB SP, immed */
|
||||
if (
|
||||
picode->ic.ll.anyFlagSet(I | TARGET | CASE) && picode->ic.ll.match(iSUB,rSP)
|
||||
)
|
||||
{
|
||||
m_icodes.push_back( picode++ ); // insert iSUB
|
||||
int n = checkStkVars (picode); // find iPUSH si [iPUSH di]
|
||||
for(int i=0; i<n; ++i)
|
||||
m_icodes.push_back(picode++); // insert
|
||||
}
|
||||
}
|
||||
|
||||
/* PUSH SI
|
||||
* [PUSH DI]
|
||||
* MOV BP, SP */
|
||||
else
|
||||
{
|
||||
int n = checkStkVars (picode);
|
||||
if (n > 0)
|
||||
{
|
||||
for(int i=0; i<n; ++i)
|
||||
m_icodes.push_back(picode++);
|
||||
if(picode == m_end)
|
||||
return false;
|
||||
/* Look for MOV BP, SP */
|
||||
if ( picode != m_end &&
|
||||
!picode->ic.ll.anyFlagSet(I | TARGET | CASE) &&
|
||||
picode->ic.ll.match(iMOV,rBP,rSP))
|
||||
{
|
||||
m_icodes.push_back(picode);
|
||||
m_min_off = 2 + (n * 2);
|
||||
}
|
||||
else
|
||||
return false; // Cristina: check this please!
|
||||
}
|
||||
else
|
||||
return false; // Cristina: check this please!
|
||||
}
|
||||
}
|
||||
else // push di [push si] / push si [push di]
|
||||
{
|
||||
n = checkStkVars (picode);
|
||||
for(int i=0; i<n; ++i)
|
||||
m_icodes.push_back(picode++);
|
||||
|
||||
}
|
||||
return !m_icodes.empty();
|
||||
}
|
||||
int Idiom1::action()
|
||||
{
|
||||
for(iICODE ic : m_icodes)
|
||||
{
|
||||
ic->invalidate();
|
||||
}
|
||||
m_func->flg |= PROC_IS_HLL;
|
||||
if(0!=m_min_off)
|
||||
m_func->args.m_minOff = m_min_off;
|
||||
return m_icodes.size();
|
||||
}
|
||||
@ -15,7 +15,7 @@
|
||||
#include "shift_idioms.h"
|
||||
#include "arith_idioms.h"
|
||||
#include "dcc.h"
|
||||
|
||||
#include <boost/iterator/filter_iterator.hpp>
|
||||
/*****************************************************************************
|
||||
* JmpInst - Returns TRUE if opcode is a conditional or unconditional jump
|
||||
****************************************************************************/
|
||||
@ -70,8 +70,12 @@ void Function::findIdioms()
|
||||
Idiom18 i18(this);
|
||||
Idiom19 i19(this);
|
||||
Idiom20 i20(this);
|
||||
|
||||
while (pIcode < pEnd)
|
||||
struct is_valid
|
||||
{
|
||||
bool operator()(ICODE &z) { return not z.invalid;}
|
||||
};
|
||||
typedef boost::filter_iterator<is_valid,iICODE> ifICODE;
|
||||
while (pIcode != pEnd)
|
||||
{
|
||||
switch (pIcode->ic.ll.opcode)
|
||||
{
|
||||
@ -224,13 +228,22 @@ void Function::bindIcodeOff()
|
||||
pIcode = Icode.begin();
|
||||
|
||||
/* Flag all jump targets for BB construction and disassembly stage 2 */
|
||||
for (i = 0; i < Icode.size(); i++)
|
||||
if ((pIcode[i].ic.ll.flg & I) && JmpInst(pIcode[i].ic.ll.opcode))
|
||||
for(ICODE &c : Icode)
|
||||
{
|
||||
iICODE loc=Icode.labelSrch(pIcode[i].ic.ll.src.op());
|
||||
if ((c.ic.ll.flg & I) && JmpInst(c.ic.ll.opcode))
|
||||
{
|
||||
iICODE loc=Icode.labelSrch(c.ic.ll.src.op());
|
||||
if (loc!=Icode.end())
|
||||
loc->ic.ll.flg |= TARGET;
|
||||
}
|
||||
}
|
||||
// for (i = 0; i < Icode.size(); i++)
|
||||
// if ((pIcode[i].ic.ll.flg & I) && JmpInst(pIcode[i].ic.ll.opcode))
|
||||
// {
|
||||
// iICODE loc=Icode.labelSrch(pIcode[i].ic.ll.src.op());
|
||||
// if (loc!=Icode.end())
|
||||
// loc->ic.ll.flg |= TARGET;
|
||||
// }
|
||||
|
||||
/* Finally bind jump targets to Icode offsets. Jumps for which no label
|
||||
* is found (no code at dest. of jump) are simply left unlinked and
|
||||
|
||||
@ -170,21 +170,6 @@ int Idiom18::action() // action length
|
||||
m_icodes[1]->invalidate();
|
||||
m_icodes[2]->invalidate();
|
||||
return 3;
|
||||
/*
|
||||
lhs = COND_EXPR::id (*(pIcode-1), SRC, this, pIcode, *pIcode, eUSE);
|
||||
if (pIcode->ic.ll.opcode == iDEC)
|
||||
lhs = COND_EXPR::unary (POST_DEC, lhs);
|
||||
else
|
||||
lhs = COND_EXPR::unary (POST_INC, lhs);
|
||||
rhs = COND_EXPR::id (*(pIcode+1), SRC, this, pIcode, *(pIcode+2), eUSE);
|
||||
exp = COND_EXPR::boolOp (lhs, rhs, condOpJCond[(pIcode+2)->ic.ll.opcode - iJB]);
|
||||
(pIcode+2)->setJCond(exp);
|
||||
|
||||
(pIcode-1)->invalidate();
|
||||
pIcode->invalidate();
|
||||
(pIcode+1)->invalidate();
|
||||
pIcode += 3;
|
||||
*/
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
@ -320,8 +305,7 @@ int Idiom20::action()
|
||||
rhs = COND_EXPR::id (*m_icodes[2], SRC, m_func, m_icodes[0], *m_icodes[3], eUSE);
|
||||
expr = COND_EXPR::boolOp (lhs, rhs, condOpJCond[m_icodes[3]->ic.ll.opcode - iJB]);
|
||||
m_icodes[3]->setJCond(expr);
|
||||
m_icodes[0]->invalidate();
|
||||
m_icodes[1]->invalidate();
|
||||
m_icodes[2]->invalidate();
|
||||
for(int i=0; i<3; ++i)
|
||||
m_icodes[i]->invalidate();
|
||||
return 4;
|
||||
}
|
||||
|
||||
@ -54,7 +54,7 @@ bool Idiom2::match(iICODE pIcode)
|
||||
m_icodes.clear();
|
||||
m_icodes.push_back(pIcode);
|
||||
/* Get next icode, skip over holes in the icode array */
|
||||
nicode = pIcode + 1;
|
||||
nicode = ++iICODE(pIcode);
|
||||
while (nicode->ic.ll.flg & NO_CODE && (nicode != m_end))
|
||||
{
|
||||
nicode++;
|
||||
@ -73,7 +73,8 @@ bool Idiom2::match(iICODE pIcode)
|
||||
)
|
||||
{
|
||||
m_icodes.push_back(nicode); // Matched RET
|
||||
popStkVars (pIcode-2); // will add optional pop di/si to m_icodes
|
||||
advance(pIcode,-2); // move back before our start
|
||||
popStkVars (pIcode); // and add optional pop di/si to m_icodes
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -108,15 +109,23 @@ bool Idiom4::match(iICODE pIcode)
|
||||
/* Check for [POP DI]
|
||||
* [POP SI] */
|
||||
if(distance(m_func->Icode.begin(),pIcode)>=3)
|
||||
popStkVars (pIcode-3);
|
||||
{
|
||||
iICODE search_at(pIcode);
|
||||
advance(search_at,-3);
|
||||
popStkVars(search_at);
|
||||
}
|
||||
if(pIcode != m_func->Icode.begin())
|
||||
{
|
||||
iICODE prev1=pIcode-1;
|
||||
iICODE prev1 = --iICODE(pIcode);
|
||||
/* Check for POP BP */
|
||||
if (prev1->ic.ll.match(iPOP,rBP) && not prev1->ic.ll.anyFlagSet(I) )
|
||||
m_icodes.push_back(prev1);
|
||||
else if(prev1!=m_func->Icode.begin())
|
||||
popStkVars (pIcode-2);
|
||||
{
|
||||
iICODE search_at(pIcode);
|
||||
advance(search_at,-2);
|
||||
popStkVars (search_at);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for RET(F) immed */
|
||||
|
||||
@ -134,40 +134,3 @@ int Idiom10::action()
|
||||
return 2;
|
||||
|
||||
}
|
||||
/*****************************************************************************
|
||||
* idiom10 - Jump if not equal to 0
|
||||
* OR reg, reg
|
||||
* JNE labX
|
||||
* Eg: OR ax, ax
|
||||
* JNE labX
|
||||
* => HLI_JCOND (ax != 0) labX
|
||||
* Note: we also check that these instructions are not followed by
|
||||
* CMP reg, kte
|
||||
* JE lab
|
||||
* because this is most likely a long conditional equality test.
|
||||
* Found in Borland Turbo C.
|
||||
****************************************************************************/
|
||||
static boolT idiom10old (iICODE pIcode, iICODE pEnd)
|
||||
{
|
||||
if (pIcode < pEnd)
|
||||
{
|
||||
/* Check OR reg, reg */
|
||||
if (((pIcode->ic.ll.flg & I) != I) &&
|
||||
(pIcode->ic.ll.src. regi > 0) &&
|
||||
(pIcode->ic.ll.src.regi < INDEXBASE) &&
|
||||
(pIcode->ic.ll.src.regi == pIcode->ic.ll.dst.regi))
|
||||
if ((pIcode+3) < pEnd)
|
||||
{
|
||||
if (((pIcode+1)->ic.ll.opcode == iJNE) &&
|
||||
((pIcode+2)->ic.ll.opcode != iCMP) &&
|
||||
((pIcode+3)->ic.ll.opcode != iJE))
|
||||
return true;
|
||||
}
|
||||
else /* at the end of the procedure */
|
||||
if (((pIcode+1) < pEnd) && ((pIcode+1)->ic.ll.opcode == iJNE))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -249,20 +249,22 @@ Int LOCAL_ID::newLongStk(hlType t, Int offH, Int offL)
|
||||
/* Returns the index to an appropriate long identifier.
|
||||
* Note: long constants should be checked first and stored as a long integer
|
||||
* number in an expression record. */
|
||||
Int LOCAL_ID::newLong(opLoc sd, ICODE *pIcode, hlFirst f, iICODE ix,operDu du, Int off)
|
||||
Int LOCAL_ID::newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix,operDu du, Int off)
|
||||
{
|
||||
Int idx;
|
||||
LLOperand *pmH, *pmL;
|
||||
iICODE atOffset(pIcode);
|
||||
advance(atOffset,off);
|
||||
|
||||
if (f == LOW_FIRST)
|
||||
{
|
||||
pmL = (sd == SRC) ? &pIcode->ic.ll.src : &pIcode->ic.ll.dst;
|
||||
pmH = (sd == SRC) ? &(pIcode+off)->ic.ll.src : &(pIcode+off)->ic.ll.dst;
|
||||
pmH = (sd == SRC) ? &atOffset->ic.ll.src : &atOffset->ic.ll.dst;
|
||||
}
|
||||
else /* HIGH_FIRST */
|
||||
{
|
||||
pmH = (sd == SRC) ? &pIcode->ic.ll.src : &pIcode->ic.ll.dst;
|
||||
pmL = (sd == SRC) ? &(pIcode+off)->ic.ll.src : &(pIcode+off)->ic.ll.dst;
|
||||
pmL = (sd == SRC) ? &atOffset->ic.ll.src : &atOffset->ic.ll.dst;
|
||||
}
|
||||
|
||||
if (pmL->regi == 0) /* global variable */
|
||||
@ -310,11 +312,13 @@ boolT checkLongEq (LONG_STKID_TYPE longId, iICODE pIcode, Int i,
|
||||
Function * pProc, Assignment &asgn, Int off)
|
||||
{
|
||||
LLOperand *pmHdst, *pmLdst, *pmHsrc, *pmLsrc; /* pointers to LOW_LEVEL icodes */
|
||||
iICODE atOffset(pIcode);
|
||||
advance(atOffset,off);
|
||||
|
||||
pmHdst = &pIcode->ic.ll.dst;
|
||||
pmLdst = &(pIcode+off)->ic.ll.dst;
|
||||
pmLdst = &atOffset->ic.ll.dst;
|
||||
pmHsrc = &pIcode->ic.ll.src;
|
||||
pmLsrc = &(pIcode+off)->ic.ll.src;
|
||||
pmLsrc = &atOffset->ic.ll.src;
|
||||
|
||||
if ((longId.offH == pmHdst->off) && (longId.offL == pmLdst->off))
|
||||
{
|
||||
@ -349,18 +353,19 @@ boolT checkLongRegEq (LONGID_TYPE longId, iICODE pIcode, Int i,
|
||||
Function * pProc, COND_EXPR *&rhs, COND_EXPR *&lhs, Int off)
|
||||
{
|
||||
LLOperand *pmHdst, *pmLdst, *pmHsrc, *pmLsrc; /* pointers to LOW_LEVEL icodes */
|
||||
iICODE atOffset(pIcode);
|
||||
advance(atOffset,off);
|
||||
|
||||
pmHdst = &pIcode->ic.ll.dst;
|
||||
pmLdst = &(pIcode+off)->ic.ll.dst;
|
||||
pmLdst = &atOffset->ic.ll.dst;
|
||||
pmHsrc = &pIcode->ic.ll.src;
|
||||
pmLsrc = &(pIcode+off)->ic.ll.src;
|
||||
pmLsrc = &atOffset->ic.ll.src;
|
||||
|
||||
if ((longId.h == pmHdst->regi) && (longId.l == pmLdst->regi))
|
||||
{
|
||||
lhs = COND_EXPR::idLongIdx (i);
|
||||
if ((pIcode->ic.ll.flg & NO_SRC) != NO_SRC)
|
||||
{
|
||||
//rhs = COND_EXPR::idLong (&pProc->localId, SRC, pIcode, HIGH_FIRST, idx, eUSE, off);
|
||||
rhs = COND_EXPR::idLong (&pProc->localId, SRC, pIcode, HIGH_FIRST, pIcode, eUSE, off);
|
||||
}
|
||||
return true;
|
||||
@ -368,7 +373,6 @@ boolT checkLongRegEq (LONGID_TYPE longId, iICODE pIcode, Int i,
|
||||
else if ((longId.h == pmHsrc->regi) && (longId.l == pmLsrc->regi))
|
||||
{
|
||||
lhs = COND_EXPR::idLong (&pProc->localId, DST, pIcode, HIGH_FIRST, pIcode, eDEF, off);
|
||||
//lhs = COND_EXPR::idLong (&pProc->localId, DST, pIcode, HIGH_FIRST, idx, eDEF, off);
|
||||
rhs = COND_EXPR::idLongIdx (i);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -150,12 +150,13 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
|
||||
flg |= (_Icode.ic.ll.flg & (NOT_HLL | FLOAT_OP));
|
||||
|
||||
/* Check if this instruction has already been parsed */
|
||||
if (Icode.labelSrch(_Icode.ic.ll.label, lab))
|
||||
iICODE labLoc = Icode.labelSrch(_Icode.ic.ll.label);
|
||||
if (Icode.end()!=labLoc)
|
||||
{ /* Synthetic jump */
|
||||
_Icode.type = LOW_LEVEL;
|
||||
_Icode.ic.ll.opcode = iJMP;
|
||||
_Icode.ic.ll.flg = I | SYNTHETIC | NO_OPS;
|
||||
_Icode.ic.ll.src.SetImmediateOp(Icode[lab].GetLlLabel());
|
||||
_Icode.ic.ll.src.SetImmediateOp(labLoc->GetLlLabel());
|
||||
_Icode.ic.ll.label = SynthLab++;
|
||||
}
|
||||
|
||||
@ -484,13 +485,15 @@ boolT Function::process_JMP (ICODE * pIcode, STATE *pstate, CALL_GRAPH * pcallGr
|
||||
{
|
||||
memcpy(&StCopy, pstate, sizeof(STATE));
|
||||
StCopy.IP = cs + LH(&prog.Image[i]);
|
||||
iICODE last_current_insn = (++Icode.rbegin()).base();
|
||||
ip = Icode.size();
|
||||
|
||||
FollowCtrl (pcallGraph, &StCopy);
|
||||
++last_current_insn;
|
||||
last_current_insn->ic.ll.caseTbl.numEntries = k++;
|
||||
last_current_insn->ic.ll.flg |= CASE;
|
||||
*psw++ = last_current_insn->GetLlLabel();
|
||||
|
||||
Icode.GetIcode(ip)->ic.ll.caseTbl.numEntries = k++;
|
||||
Icode.GetIcode(ip)->ic.ll.flg |= CASE;
|
||||
*psw++ = Icode[ip].GetLlLabel();
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
@ -516,7 +519,7 @@ boolT Function::process_JMP (ICODE * pIcode, STATE *pstate, CALL_GRAPH * pcallGr
|
||||
|
||||
boolT Function::process_CALL (ICODE * pIcode, CALL_GRAPH * pcallGraph, STATE *pstate)
|
||||
{
|
||||
Int ip = Icode.size() - 1;
|
||||
ICODE &last_insn(Icode.back());
|
||||
STATE localState; /* Local copy of the machine state */
|
||||
dword off;
|
||||
boolT indirect;
|
||||
@ -581,7 +584,7 @@ boolT Function::process_CALL (ICODE * pIcode, CALL_GRAPH * pcallGraph, STATE *ps
|
||||
/* A library function. No need to do any more to it */
|
||||
pcallGraph->insertCallGraph (this, iter);
|
||||
iter = (++pProcList.rbegin()).base();
|
||||
Icode.GetIcode(ip)->ic.ll.src.proc.proc = &x;
|
||||
last_insn.ic.ll.src.proc.proc = &x;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -621,7 +624,7 @@ boolT Function::process_CALL (ICODE * pIcode, CALL_GRAPH * pcallGraph, STATE *ps
|
||||
else
|
||||
pcallGraph->insertCallGraph (this, iter);
|
||||
|
||||
Icode[ip].ic.ll.src.proc.proc = &(*iter); // ^ target proc
|
||||
last_insn.ic.ll.src.proc.proc = &(*iter); // ^ target proc
|
||||
|
||||
/* return ((p->flg & TERMINATES) != 0); */
|
||||
return FALSE;
|
||||
@ -856,20 +859,7 @@ void STATE::setState(word reg, int16 value)
|
||||
|
||||
/* labelSrchRepl - Searches Icode for instruction with label = target, and
|
||||
replaces *pIndex with an icode index */
|
||||
bool labelSrch(CIcodeRec &pIcode, Int numIp, dword target, Int *pIndex)
|
||||
{
|
||||
Int i;
|
||||
|
||||
for (i = 0; i < numIp; i++)
|
||||
{
|
||||
if (pIcode[i].ic.ll.label == target)
|
||||
{
|
||||
*pIndex = i;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static void setBits(int16 type, dword start, dword len)
|
||||
|
||||
161
src/proplong.cpp
161
src/proplong.cpp
@ -22,40 +22,6 @@ static boolT isJCond (llIcode opcode)
|
||||
|
||||
|
||||
/* Returns whether the conditions for a 2-3 long variable are satisfied */
|
||||
static boolT isLong23 (Int i, BB * pbb, Int *off, Int *arc)
|
||||
{
|
||||
BB * t, * e, * obb2;
|
||||
|
||||
if (pbb->nodeType != TWO_BRANCH)
|
||||
return false;
|
||||
t = pbb->edges[THEN].BBptr;
|
||||
e = pbb->edges[ELSE].BBptr;
|
||||
|
||||
/* Check along the THEN path */
|
||||
if ((t->size() == 1) && (t->nodeType == TWO_BRANCH) && (t->inEdges.size() == 1))
|
||||
{
|
||||
obb2 = t->edges[THEN].BBptr;
|
||||
if ((obb2->size() == 2) && (obb2->nodeType == TWO_BRANCH) && (obb2->front().ic.ll.opcode == iCMP))
|
||||
{
|
||||
*off = obb2->front().loc_ip - i;
|
||||
*arc = THEN;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check along the ELSE path */
|
||||
else if ((e->size() == 1) && (e->nodeType == TWO_BRANCH) && (e->inEdges.size() == 1))
|
||||
{
|
||||
obb2 = e->edges[THEN].BBptr;
|
||||
if ((obb2->size() == 2) && (obb2->nodeType == TWO_BRANCH) && (obb2->front().ic.ll.opcode == iCMP))
|
||||
{
|
||||
*off = obb2->front().loc_ip - i;
|
||||
*arc = ELSE;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
static boolT isLong23 (iICODE iter, BB * pbb, Int *off, Int *arc)
|
||||
{
|
||||
BB * t, * e, * obb2;
|
||||
@ -95,14 +61,13 @@ static boolT isLong23 (iICODE iter, BB * pbb, Int *off, Int *arc)
|
||||
/* Returns whether the conditions for a 2-2 long variable are satisfied */
|
||||
static boolT isLong22 (iICODE pIcode, iICODE pEnd, Int *off)
|
||||
{
|
||||
iICODE next1 = pIcode+1;
|
||||
iICODE next2 = pIcode+2;
|
||||
iICODE next3 = pIcode+3;
|
||||
if(next3>=pEnd)
|
||||
if(distance(pIcode,pEnd)<4)
|
||||
return false;
|
||||
if ( (next2->ic.ll.opcode == iCMP) &&
|
||||
(isJCond (next1->ic.ll.opcode)) &&
|
||||
(isJCond (next3->ic.ll.opcode)))
|
||||
// preincrement because pIcode is not checked here
|
||||
iICODE icodes[] = { ++pIcode,++pIcode,++pIcode };
|
||||
if ( icodes[1]->ic.ll.match(iCMP) &&
|
||||
(isJCond (icodes[0]->ic.ll.opcode)) &&
|
||||
(isJCond (icodes[2]->ic.ll.opcode)))
|
||||
{
|
||||
*off = 2;
|
||||
return true;
|
||||
@ -173,12 +138,14 @@ static int longJCond23 (COND_EXPR *rhs, COND_EXPR *lhs, iICODE pIcode, Int arc,
|
||||
/* Update icode index */
|
||||
skipped_insn = 2;
|
||||
}
|
||||
|
||||
iICODE atOffset(pIcode),atOffset1(pIcode),next1(++iICODE(pIcode));
|
||||
advance(atOffset,off);
|
||||
advance(atOffset1,off+1);
|
||||
/* Create new HLI_JCOND and condition */
|
||||
lhs = COND_EXPR::boolOp (lhs, rhs, condOpJCond[(pIcode+off+1)->ic.ll.opcode-iJB]);
|
||||
(pIcode+1)->setJCond(lhs);
|
||||
(pIcode+1)->copyDU(*pIcode, eUSE, eUSE);
|
||||
(pIcode+1)->du.use |= (pIcode+off)->du.use;
|
||||
lhs = COND_EXPR::boolOp (lhs, rhs, condOpJCond[atOffset1->ic.ll.opcode-iJB]);
|
||||
next1->setJCond(lhs);
|
||||
next1->copyDU(*pIcode, eUSE, eUSE);
|
||||
next1->du.use |= atOffset->du.use;
|
||||
|
||||
/* Update statistics */
|
||||
obb1->flg |= INVALID_BB;
|
||||
@ -187,8 +154,10 @@ static int longJCond23 (COND_EXPR *rhs, COND_EXPR *lhs, iICODE pIcode, Int arc,
|
||||
|
||||
pIcode->invalidate();
|
||||
obb1->front().invalidate();
|
||||
obb2->front().invalidate();
|
||||
(obb2->begin2()+1)->invalidate();
|
||||
// invalidate 2 first instructions of BB 2
|
||||
iICODE ibb2 = obb2->begin2();
|
||||
(ibb2++)->invalidate();
|
||||
(ibb2++)->invalidate();
|
||||
return skipped_insn;
|
||||
}
|
||||
|
||||
@ -198,22 +167,24 @@ static int longJCond23 (COND_EXPR *rhs, COND_EXPR *lhs, iICODE pIcode, Int arc,
|
||||
* the new edges for the remaining nodes.
|
||||
* @return number of ICODE's to skip
|
||||
*/
|
||||
static int longJCond22 (COND_EXPR *rhs, COND_EXPR *lhs, iICODE pIcode)
|
||||
static int longJCond22 (COND_EXPR *rhs, COND_EXPR *lhs, iICODE pIcode,iICODE pEnd)
|
||||
{
|
||||
Int j;
|
||||
BB * pbb, * obb1, * tbb;
|
||||
iICODE next1=pIcode+1;
|
||||
iICODE next2=pIcode+2;
|
||||
iICODE next3=pIcode+3;
|
||||
if(distance(pIcode,pEnd)<4)
|
||||
return false;
|
||||
// preincrement because pIcode is not checked here
|
||||
iICODE icodes[] = { pIcode++,pIcode++,pIcode++,pIcode++ };
|
||||
|
||||
/* Form conditional expression */
|
||||
lhs = COND_EXPR::boolOp (lhs, rhs, condOpJCond[(pIcode+3)->ic.ll.opcode - iJB]);
|
||||
next1->setJCond(lhs);
|
||||
next1->copyDU (*pIcode, eUSE, eUSE);
|
||||
next1->du.use |= next2->du.use;
|
||||
lhs = COND_EXPR::boolOp (lhs, rhs, condOpJCond[icodes[3]->ic.ll.opcode - iJB]);
|
||||
icodes[1]->setJCond(lhs);
|
||||
icodes[1]->copyDU (*icodes[0], eUSE, eUSE);
|
||||
icodes[1]->du.use |= icodes[2]->du.use;
|
||||
|
||||
/* Adjust outEdges[0] to the new target basic block */
|
||||
pbb = pIcode->inBB;
|
||||
if (pbb->back().loc_ip == next1->loc_ip)
|
||||
pbb = icodes[0]->inBB;
|
||||
if (pbb->back().loc_ip == icodes[1]->loc_ip)
|
||||
{
|
||||
/* Find intermediate and target basic blocks */
|
||||
obb1 = pbb->edges[THEN].BBptr;
|
||||
@ -227,7 +198,7 @@ static int longJCond22 (COND_EXPR *rhs, COND_EXPR *lhs, iICODE pIcode)
|
||||
assert(iter!=tbb->inEdges.end());
|
||||
tbb->inEdges.erase(iter);
|
||||
|
||||
if ((pIcode+3)->ic.ll.opcode != iJE)
|
||||
if (icodes[3]->ic.ll.opcode != iJE)
|
||||
tbb->inEdges.push_back(pbb); /* iJNE => replace arc */
|
||||
|
||||
/* Modify ELSE out edge of header basic block */
|
||||
@ -237,7 +208,7 @@ static int longJCond22 (COND_EXPR *rhs, COND_EXPR *lhs, iICODE pIcode)
|
||||
iter=std::find(tbb->inEdges.begin(),tbb->inEdges.end(),obb1);
|
||||
assert(iter!=tbb->inEdges.end());
|
||||
tbb->inEdges.erase(iter);
|
||||
if ((pIcode+3)->ic.ll.opcode == iJE) /* replace */
|
||||
if (icodes[3]->ic.ll.opcode == iJE) /* replace */
|
||||
tbb->inEdges.push_back(pbb);
|
||||
|
||||
/* Update statistics */
|
||||
@ -245,9 +216,9 @@ static int longJCond22 (COND_EXPR *rhs, COND_EXPR *lhs, iICODE pIcode)
|
||||
stats.numBBaft--;
|
||||
}
|
||||
|
||||
pIcode->invalidate();
|
||||
next2->invalidate();
|
||||
next3->invalidate();
|
||||
icodes[0]->invalidate();
|
||||
icodes[2]->invalidate();
|
||||
icodes[3]->invalidate();
|
||||
return 4;
|
||||
}
|
||||
|
||||
@ -258,20 +229,24 @@ static int longJCond22 (COND_EXPR *rhs, COND_EXPR *lhs, iICODE pIcode)
|
||||
* pProc : ptr to current procedure's record. */
|
||||
void Function::propLongStk (Int i, const ID &pLocId)
|
||||
{
|
||||
Int idx, off, arc;
|
||||
Int off, arc;
|
||||
Assignment asgn;
|
||||
//COND_EXPR *lhs, *rhs; /* Pointers to left and right hand expression */
|
||||
iICODE pIcode, pEnd;
|
||||
iICODE next1, pEnd;
|
||||
|
||||
/* Check all icodes for offHi:offLo */
|
||||
pEnd = Icode.end();
|
||||
for (idx = 0; idx < (this->Icode.size() - 1); idx++)
|
||||
int stat_size=Icode.size();
|
||||
// for (idx = 0; idx < (Icode.size() - 1); idx++)
|
||||
for(auto pIcode = Icode.begin(); ;++pIcode)
|
||||
{
|
||||
pIcode = Icode.begin()+idx;
|
||||
assert(Icode.size()==stat_size);
|
||||
next1 = ++iICODE(pIcode);
|
||||
if(next1==pEnd)
|
||||
break;
|
||||
if ((pIcode->type == HIGH_LEVEL) || (pIcode->invalid == TRUE))
|
||||
continue;
|
||||
|
||||
if (pIcode->ic.ll.opcode == (pIcode+1)->ic.ll.opcode)
|
||||
if (pIcode->ic.ll.opcode == next1->ic.ll.opcode)
|
||||
{
|
||||
switch (pIcode->ic.ll.opcode)
|
||||
{
|
||||
@ -279,8 +254,7 @@ void Function::propLongStk (Int i, const ID &pLocId)
|
||||
if (checkLongEq (pLocId.id.longStkId, pIcode, i, this, asgn, 1) == TRUE)
|
||||
{
|
||||
pIcode->setAsgn(asgn.lhs, asgn.rhs);
|
||||
(pIcode+1)->invalidate();
|
||||
idx++;
|
||||
next1->invalidate();
|
||||
}
|
||||
break;
|
||||
|
||||
@ -294,8 +268,7 @@ void Function::propLongStk (Int i, const ID &pLocId)
|
||||
case iXOR: asgn.rhs = COND_EXPR::boolOp (asgn.lhs, asgn.rhs, XOR); break;
|
||||
}
|
||||
pIcode->setAsgn(asgn.lhs, asgn.rhs);
|
||||
(pIcode+1)->invalidate();
|
||||
idx++;
|
||||
next1->invalidate();
|
||||
}
|
||||
break;
|
||||
|
||||
@ -303,19 +276,18 @@ void Function::propLongStk (Int i, const ID &pLocId)
|
||||
if (checkLongEq (pLocId.id.longStkId, pIcode, i, this, asgn, 1) == TRUE)
|
||||
{
|
||||
pIcode->setUnary( HLI_PUSH, asgn.lhs);
|
||||
(pIcode+1)->invalidate();
|
||||
idx++;
|
||||
next1->invalidate();
|
||||
}
|
||||
break;
|
||||
} /*eos*/
|
||||
}
|
||||
|
||||
/* Check long conditional (i.e. 2 CMPs and 3 branches */
|
||||
else if ((pIcode->ic.ll.opcode == iCMP) && (isLong23 (idx, pIcode->inBB, &off, &arc)))
|
||||
else if ((pIcode->ic.ll.opcode == iCMP) && (isLong23 (pIcode, pIcode->inBB, &off, &arc)))
|
||||
{
|
||||
if ( checkLongEq (pLocId.id.longStkId, pIcode, i, this, asgn, off) )
|
||||
{
|
||||
idx += longJCond23 (asgn.rhs, asgn.lhs, pIcode, arc, off); //
|
||||
advance(pIcode,longJCond23 (asgn.rhs, asgn.lhs, pIcode, arc, off));
|
||||
}
|
||||
}
|
||||
|
||||
@ -325,7 +297,7 @@ void Function::propLongStk (Int i, const ID &pLocId)
|
||||
{
|
||||
if ( checkLongEq (pLocId.id.longStkId, pIcode, i, this,asgn, off) )
|
||||
{
|
||||
idx += longJCond22 (asgn.rhs, asgn.lhs, pIcode); // maybe this should have -1 to offset loop autoincrement?
|
||||
advance(pIcode,longJCond22 (asgn.rhs, asgn.lhs, pIcode,pEnd));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -339,9 +311,9 @@ int Function::findBackwarLongDefs(int loc_ident_idx, const ID &pLocId, iICODE be
|
||||
bool forced_finish=false;
|
||||
for (; not forced_finish and rev!=Icode.rend();rev++) //idx = pLocId_idx - 1; idx > 0 ; idx--
|
||||
{
|
||||
ICODE &icode(*rev);
|
||||
ICODE &next1(*(rev-1)); // prev reverse is actually next instruction
|
||||
pIcode = (rev+1).base();//Icode.begin()+(idx-1);
|
||||
pIcode = (++riICODE(rev)).base();//forward iterator from rev
|
||||
ICODE &icode(*pIcode);
|
||||
ICODE &next1(*(++iICODE(pIcode))); // next instruction
|
||||
|
||||
|
||||
if ((icode.type == HIGH_LEVEL) || (icode.invalid == TRUE))
|
||||
@ -414,9 +386,11 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be
|
||||
bool forced_finish=false;
|
||||
auto pEnd=Icode.end();
|
||||
Assignment asgn;
|
||||
for (auto pIcode=beg; not forced_finish and ((pIcode+1)!=Icode.end()); ++pIcode)
|
||||
for (auto pIcode=beg; not forced_finish; ++pIcode)
|
||||
{
|
||||
iICODE next1(pIcode+1);
|
||||
iICODE next1(++iICODE(pIcode));
|
||||
if(next1==pEnd)
|
||||
break;
|
||||
LLOperand * pmH,* pmL; /* Pointers to dst LOW_LEVEL icodes */
|
||||
int off,arc;
|
||||
|
||||
@ -474,7 +448,7 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be
|
||||
break;
|
||||
}
|
||||
pIcode->setAsgn(asgn.lhs, asgn.rhs);
|
||||
(pIcode+1)->invalidate();
|
||||
next1->invalidate();
|
||||
// ftw loop restart ????
|
||||
//idx = 0;
|
||||
// maybe this should end the loop instead
|
||||
@ -488,19 +462,18 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be
|
||||
{
|
||||
if (checkLongRegEq (pLocId.id.longId, pIcode, loc_ident_idx, this, asgn.rhs, asgn.lhs, off) == TRUE)
|
||||
{
|
||||
pIcode += longJCond23 (asgn.rhs, asgn.lhs, pIcode, arc, off);
|
||||
// reduce the advance by 1 here (loop increases) ?
|
||||
advance(pIcode,longJCond23 (asgn.rhs, asgn.lhs, pIcode, arc, off));
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for long conditional equality or inequality. This requires
|
||||
* 2 CMPs and 2 branches */
|
||||
else if ((pIcode->ic.ll.opcode == iCMP) &&
|
||||
(isLong22 (pIcode, pEnd, &off)))
|
||||
else if (pIcode->ic.ll.match(iCMP) && (isLong22 (pIcode, pEnd, &off)))
|
||||
{
|
||||
if (checkLongRegEq (pLocId.id.longId, pIcode, loc_ident_idx, this,
|
||||
asgn.rhs, asgn.lhs, off) == TRUE)
|
||||
if (checkLongRegEq (pLocId.id.longId, pIcode, loc_ident_idx, this, asgn.rhs, asgn.lhs, off) == TRUE)
|
||||
{
|
||||
pIcode += longJCond22 (asgn.rhs, asgn.lhs, pIcode);
|
||||
advance(pIcode,longJCond22 (asgn.rhs, asgn.lhs, pIcode,pEnd) - 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -508,14 +481,11 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be
|
||||
* JX lab
|
||||
* => HLI_JCOND (regH:regL X 0) lab
|
||||
* This is better code than HLI_JCOND (HI(regH:regL) | LO(regH:regL)) */
|
||||
else if ((pIcode->ic.ll.opcode == iOR) && (next1 < pEnd) &&
|
||||
(isJCond (next1->ic.ll.opcode)))
|
||||
else if (pIcode->ic.ll.match(iOR) && (next1 != pEnd) && (isJCond (next1->ic.ll.opcode)))
|
||||
{
|
||||
if ((pIcode->ic.ll.dst.regi == pLocId.id.longId.h) &&
|
||||
(pIcode->ic.ll.src.regi == pLocId.id.longId.l))
|
||||
if ((pIcode->ic.ll.dst.regi == pLocId.id.longId.h) && (pIcode->ic.ll.src.regi == pLocId.id.longId.l))
|
||||
{
|
||||
asgn.lhs = COND_EXPR::idLongIdx (loc_ident_idx);
|
||||
|
||||
asgn.rhs = COND_EXPR::idKte (0, 4); /* long 0 */
|
||||
asgn.lhs = COND_EXPR::boolOp (asgn.lhs, asgn.rhs, condOpJCond[next1->ic.ll.opcode - iJB]);
|
||||
next1->setJCond(asgn.lhs);
|
||||
@ -523,7 +493,6 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be
|
||||
pIcode->invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
} /* end for */
|
||||
}
|
||||
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
long LMOD@ (long arg0, int arg2, int arg3)
|
||||
/* Takes 8 bytes of parameters.
|
||||
* Runtime support routine of the compiler.
|
||||
* High-level language prologue code.
|
||||
* Untranslatable routine. Assembler provided.
|
||||
* Return value in registers dx:ax.
|
||||
* Pascal calling convention.
|
||||
|
||||
@ -12,7 +12,7 @@ int proc_1 (int arg0)
|
||||
* C calling convention.
|
||||
*/
|
||||
{
|
||||
int loc1;
|
||||
int loc1; /* si */
|
||||
int loc2; /* ax */
|
||||
|
||||
loc1 = arg0;
|
||||
|
||||
37
valgrind_tester
Executable file
37
valgrind_tester
Executable file
@ -0,0 +1,37 @@
|
||||
#!/usr/bin/env ruby
|
||||
require 'fileutils'
|
||||
print("Regression tester 0.0.1\n")
|
||||
def path_local(from)
|
||||
|
||||
return from #from.gsub('/','//')
|
||||
from.gsub('/','\\\\')
|
||||
end
|
||||
TESTS_DIR="./tests"
|
||||
def perform_test(exepath,filepath,outname)
|
||||
output_path=path_local(TESTS_DIR+"/outputs/"+outname)
|
||||
error_path=path_local(TESTS_DIR+"/errors/"+outname)
|
||||
exepath=path_local(exepath)
|
||||
output_path=path_local(output_path)
|
||||
filepath=path_local(filepath)
|
||||
printf("calling:" + "#{exepath} -a1 -o#{output_path}.a1 #{filepath}\n")
|
||||
valgrind_mode="valgrind --track-origins=yes "
|
||||
#valgrind --tool=callgrind --dump-instr=yes --collect-jumps=yes
|
||||
result = `#{valgrind_mode} #{exepath} -a2V -o#{output_path}.a2 #{filepath} 2>#{error_path}.val`
|
||||
puts result
|
||||
p $?
|
||||
end
|
||||
`rm -rf #{TESTS_DIR}/outputs/*.*`
|
||||
#exit(1)
|
||||
if(ARGV.size()==0)
|
||||
puts("valgrind_tester DCC_EXECUTABLE")
|
||||
exit(0)
|
||||
end
|
||||
Dir.open(TESTS_DIR+"/inputs").each() {|f|
|
||||
next if f=="." or f==".."
|
||||
perform_test(".//"+ARGV[0],TESTS_DIR+"/inputs/"+f,f)
|
||||
}
|
||||
Dir.open(TESTS_DIR+"/inputs").each() {|f|
|
||||
next if f=="." or f==".."
|
||||
FileUtils.mv(TESTS_DIR+"/inputs/"+f,TESTS_DIR+"/outputs/"+f) if f.end_with?(".b")
|
||||
}
|
||||
"diff -rqbwB"
|
||||
Loading…
x
Reference in New Issue
Block a user