CIcodeRec is no longer an Array, it's now a list, will help with iterator stability

This commit is contained in:
Artur K 2012-02-28 03:06:34 +01:00
parent f131b7e619
commit 3cb26d99d2
26 changed files with 426 additions and 770 deletions

3
base_regression.sh Executable file
View 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
View 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/

View File

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

View File

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

View File

@ -4,6 +4,7 @@
****************************************************************************/
#pragma once
#include <vector>
#include <list>
#include <bitset>
#include <llvm/MC/MCInst.h>
#include <llvm/MC/MCAsmInfo.h>
@ -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

View File

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

View File

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

View File

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

View File

@ -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,27 +325,33 @@ 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)
{
line = write1HlIcode (hli[i].ic.hl, pProc, numLoc);
if ((hli->type == HIGH_LEVEL) && (hli->invalid == FALSE))
{
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());
}

View File

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

View File

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

View File

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

View File

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

View File

@ -116,18 +116,23 @@ 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())
{
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;
}
}
@ -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());
}
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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
View 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"