Various code cleanups.
This commit is contained in:
parent
29efcd5be1
commit
a5f1d17e83
@ -1,16 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "ast.h"
|
#include "ast.h"
|
||||||
|
|
||||||
#ifdef PASCAL
|
|
||||||
#undef PASCAL
|
|
||||||
#endif
|
|
||||||
class QTextStream;
|
class QTextStream;
|
||||||
|
|
||||||
struct CConv {
|
struct CConv {
|
||||||
enum Type {
|
enum Type {
|
||||||
UNKNOWN=0,
|
eUnknown=0,
|
||||||
C,
|
eCdecl,
|
||||||
PASCAL
|
ePascal
|
||||||
};
|
};
|
||||||
virtual void processHLI(Function *func, Expr *_exp, iICODE picode)=0;
|
virtual void processHLI(Function *func, Expr *_exp, iICODE picode)=0;
|
||||||
virtual void writeComments(QTextStream &)=0;
|
virtual void writeComments(QTextStream &)=0;
|
||||||
|
|||||||
@ -100,7 +100,7 @@ protected:
|
|||||||
hasCase(false),liveAnal(0)
|
hasCase(false),liveAnal(0)
|
||||||
{
|
{
|
||||||
type = new FunctionType;
|
type = new FunctionType;
|
||||||
callingConv(CConv::UNKNOWN);
|
callingConv(CConv::eUnknown);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@ -28,25 +28,25 @@ extern bundle cCode; /* Output C procedure's declaration and code */
|
|||||||
|
|
||||||
extern QString asm1_name, asm2_name; /* Assembler output filenames */
|
extern QString asm1_name, asm2_name; /* Assembler output filenames */
|
||||||
|
|
||||||
typedef struct { /* Command line option flags */
|
/** Command line option flags */
|
||||||
unsigned verbose : 1;
|
struct OPTION
|
||||||
unsigned VeryVerbose : 1;
|
{
|
||||||
unsigned asm1 : 1; /* Early disassembly listing */
|
bool verbose;
|
||||||
unsigned asm2 : 1; /* Disassembly listing after restruct */
|
bool VeryVerbose;
|
||||||
unsigned Map : 1;
|
bool asm1; /* Early disassembly listing */
|
||||||
unsigned Stats : 1;
|
bool asm2; /* Disassembly listing after restruct */
|
||||||
unsigned Interact : 1; /* Interactive mode */
|
bool Map;
|
||||||
unsigned Calls : 1; /* Follow register indirect calls */
|
bool Stats;
|
||||||
|
bool Interact; /* Interactive mode */
|
||||||
|
bool Calls; /* Follow register indirect calls */
|
||||||
QString filename; /* The input filename */
|
QString filename; /* The input filename */
|
||||||
uint32_t CustomEntryPoint;
|
uint32_t CustomEntryPoint;
|
||||||
} OPTION;
|
};
|
||||||
|
|
||||||
extern OPTION option; /* Command line options */
|
extern OPTION option; /* Command line options */
|
||||||
|
|
||||||
#include "BinaryImage.h"
|
#include "BinaryImage.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Memory map states */
|
/* Memory map states */
|
||||||
enum eAreaType
|
enum eAreaType
|
||||||
{
|
{
|
||||||
|
|||||||
@ -165,8 +165,8 @@ struct AssignType : public HlTypeSupport
|
|||||||
/* for HLI_ASSIGN */
|
/* for HLI_ASSIGN */
|
||||||
protected:
|
protected:
|
||||||
public:
|
public:
|
||||||
Expr *m_lhs;
|
Expr * m_lhs;
|
||||||
Expr *rhs;
|
Expr * m_rhs;
|
||||||
AssignType() {}
|
AssignType() {}
|
||||||
Expr *lhs() const {return m_lhs;}
|
Expr *lhs() const {return m_lhs;}
|
||||||
void lhs(Expr *l);
|
void lhs(Expr *l);
|
||||||
@ -176,8 +176,8 @@ public:
|
|||||||
struct ExpType : public HlTypeSupport
|
struct ExpType : public HlTypeSupport
|
||||||
{
|
{
|
||||||
/* for HLI_JCOND, HLI_RET, HLI_PUSH, HLI_POP*/
|
/* for HLI_JCOND, HLI_RET, HLI_PUSH, HLI_POP*/
|
||||||
Expr *v;
|
Expr * v;
|
||||||
ExpType() : v(0) {}
|
ExpType() : v(nullptr) {}
|
||||||
bool removeRegFromLong(eReg regi, LOCAL_ID *locId)
|
bool removeRegFromLong(eReg regi, LOCAL_ID *locId)
|
||||||
{
|
{
|
||||||
v=performLongRemoval(regi,locId,v);
|
v=performLongRemoval(regi,locId,v);
|
||||||
|
|||||||
@ -170,9 +170,9 @@ public:
|
|||||||
void flagByteWordId(int off);
|
void flagByteWordId(int off);
|
||||||
void propLongId(uint8_t regL, uint8_t regH, const QString & name);
|
void propLongId(uint8_t regL, uint8_t regH, const QString & name);
|
||||||
size_t csym() const {return id_arr.size();}
|
size_t csym() const {return id_arr.size();}
|
||||||
void newRegArg(iICODE picode, iICODE ticode) const;
|
void newRegArg(ICODE & picode, ICODE & ticode) const;
|
||||||
void processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode, bool isLong) const;
|
void processTargetIcode(ICODE & picode, int &numHlIcodes, ICODE & ticode, bool isLong) const;
|
||||||
void forwardSubs(Expr *lhs, Expr *rhs, iICODE picode, iICODE ticode, int &numHlIcodes) const;
|
void forwardSubs(Expr *lhs, Expr *rhs, ICODE & picode, ICODE & ticode, int &numHlIcodes) const;
|
||||||
AstIdent *createId(const ID *retVal, iICODE ix_);
|
AstIdent *createId(const ID *retVal, iICODE ix_);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -15,9 +15,9 @@ CConv *CConv::create(Type v)
|
|||||||
if(nullptr==u_call)
|
if(nullptr==u_call)
|
||||||
u_call = new Unknown_CallingConvention;
|
u_call = new Unknown_CallingConvention;
|
||||||
switch(v) {
|
switch(v) {
|
||||||
case UNKNOWN: return u_call;
|
case eUnknown: return u_call;
|
||||||
case C: return c_call;
|
case eCdecl: return c_call;
|
||||||
case PASCAL: return p_call;
|
case ePascal: return p_call;
|
||||||
}
|
}
|
||||||
assert(false);
|
assert(false);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|||||||
@ -259,14 +259,13 @@ AstIdent *AstIdent::Other(eReg seg, eReg regi, int16_t off)
|
|||||||
* TYPE_WORD_SIGN */
|
* TYPE_WORD_SIGN */
|
||||||
AstIdent *AstIdent::idID (const ID *retVal, LOCAL_ID *locsym, iICODE ix_)
|
AstIdent *AstIdent::idID (const ID *retVal, LOCAL_ID *locsym, iICODE ix_)
|
||||||
{
|
{
|
||||||
int idx;
|
|
||||||
AstIdent *newExp=nullptr;
|
AstIdent *newExp=nullptr;
|
||||||
switch(retVal->type)
|
switch(retVal->type)
|
||||||
{
|
{
|
||||||
case TYPE_LONG_SIGN:
|
case TYPE_LONG_SIGN:
|
||||||
{
|
{
|
||||||
newExp = new AstIdent();
|
newExp = new AstIdent();
|
||||||
idx = locsym->newLongReg (TYPE_LONG_SIGN, retVal->longId(), ix_);
|
int idx = locsym->newLongReg (TYPE_LONG_SIGN, retVal->longId(), ix_);
|
||||||
newExp->ident.idType = LONG_VAR;
|
newExp->ident.idType = LONG_VAR;
|
||||||
newExp->ident.idNode.longIdx = idx;
|
newExp->ident.idNode.longIdx = idx;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -477,7 +477,7 @@ bool LibCheck(Function & pProc)
|
|||||||
if ((numFunc == 0) or (i=searchPList(ht[h].htSym)) != NIL)
|
if ((numFunc == 0) or (i=searchPList(ht[h].htSym)) != NIL)
|
||||||
{
|
{
|
||||||
pProc.flg |= PROC_ISLIB; /* It's a lib function */
|
pProc.flg |= PROC_ISLIB; /* It's a lib function */
|
||||||
pProc.callingConv(CConv::C);
|
pProc.callingConv(CConv::eCdecl);
|
||||||
if (i != NIL)
|
if (i != NIL)
|
||||||
{
|
{
|
||||||
/* Allocate space for the arg struct, and copy the hlType to
|
/* Allocate space for the arg struct, and copy the hlType to
|
||||||
@ -534,7 +534,7 @@ bool LibCheck(Function & pProc)
|
|||||||
pProc.args.numArgs = 0; /* With no args */
|
pProc.args.numArgs = 0; /* With no args */
|
||||||
}
|
}
|
||||||
|
|
||||||
return (bool)((pProc.flg & PROC_ISLIB) != 0);
|
return pProc.isLibrary();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -548,8 +548,7 @@ void grab(int n, FILE *_file)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t
|
uint16_t readFileShort(FILE *f)
|
||||||
readFileShort(FILE *f)
|
|
||||||
{
|
{
|
||||||
uint8_t b1, b2;
|
uint8_t b1, b2;
|
||||||
|
|
||||||
|
|||||||
243
src/control.cpp
243
src/control.cpp
@ -7,25 +7,29 @@
|
|||||||
#include "msvc_fixes.h"
|
#include "msvc_fixes.h"
|
||||||
|
|
||||||
#include <boost/range/algorithm.hpp>
|
#include <boost/range/algorithm.hpp>
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstring>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <cassert>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
typedef std::list<int> nodeList; /* dfsLast index to the node */
|
typedef std::list<int> nodeList; /* dfsLast index to the node */
|
||||||
|
|
||||||
#define ancestor(a,b) ((a->dfsLastNum < b->dfsLastNum) and (a->dfsFirstNum < b->dfsFirstNum))
|
|
||||||
/* there is a path on the DFST from a to b if the a was first visited in a
|
/* there is a path on the DFST from a to b if the a was first visited in a
|
||||||
* dfs, and a was later visited than b when doing the last visit of each
|
* dfs, and a was later visited than b when doing the last visit of each
|
||||||
* node. */
|
* node. */
|
||||||
|
bool inline ancestor(BB *a,BB *b)
|
||||||
|
{
|
||||||
|
return (a->dfsLastNum < b->dfsLastNum) and (a->dfsFirstNum < b->dfsFirstNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Checks if the edge (p,s) is a back edge. If node s was visited first
|
/** Checks if the edge (p,s) is a back edge. If node s was visited first
|
||||||
* during the dfs traversal (ie. s has a smaller dfsFirst number) or s == p,
|
* during the dfs traversal (ie. s has a smaller dfsFirst number) or s == p,
|
||||||
* then it is a backedge.
|
* then it is a backedge.
|
||||||
* Also incrementes the number of backedges entries to the header node. */
|
* Also incrementes the number of backedges entries to the header node. */
|
||||||
static bool isBackEdge (BB * p,BB * s)
|
bool isBackEdge (BB * p,BB * s)
|
||||||
{
|
{
|
||||||
if (p->dfsFirstNum >= s->dfsFirstNum)
|
if (p->dfsFirstNum >= s->dfsFirstNum)
|
||||||
{
|
{
|
||||||
@ -36,9 +40,9 @@ static bool isBackEdge (BB * p,BB * s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Finds the common dominator of the current immediate dominator
|
/** Finds the common dominator of the current immediate dominator
|
||||||
* currImmDom and its predecessor's immediate dominator predImmDom */
|
* currImmDom and its predecessor's immediate dominator predImmDom */
|
||||||
static int commonDom (int currImmDom, int predImmDom, Function * pProc)
|
int commonDom (int currImmDom, int predImmDom, Function * pProc)
|
||||||
{
|
{
|
||||||
if (currImmDom == NO_DOM)
|
if (currImmDom == NO_DOM)
|
||||||
return (predImmDom);
|
return (predImmDom);
|
||||||
@ -55,67 +59,44 @@ static int commonDom (int currImmDom, int predImmDom, Function * pProc)
|
|||||||
}
|
}
|
||||||
return (currImmDom);
|
return (currImmDom);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Finds the immediate dominator of each node in the graph pProc->cfg.
|
|
||||||
* Adapted version of the dominators algorithm by Hecht and Ullman; finds
|
|
||||||
* immediate dominators only.
|
|
||||||
* Note: graph should be reducible */
|
|
||||||
void Function::findImmedDom ()
|
|
||||||
{
|
|
||||||
BB * currNode;
|
|
||||||
for (size_t currIdx = 0; currIdx < numBBs; currIdx++)
|
|
||||||
{
|
|
||||||
currNode = m_dfsLast[currIdx];
|
|
||||||
if (currNode->flg & INVALID_BB) /* Do not process invalid BBs */
|
|
||||||
continue;
|
|
||||||
for (BB * inedge : currNode->inEdges)
|
|
||||||
{
|
|
||||||
size_t predIdx = inedge->dfsLastNum;
|
|
||||||
if (predIdx < currIdx)
|
|
||||||
currNode->immedDom = commonDom (currNode->immedDom, predIdx, this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Inserts the node n to the list l. */
|
|
||||||
static void insertList (nodeList &l, int n)
|
|
||||||
{
|
|
||||||
l.push_back(n);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Returns whether or not the node n (dfsLast numbering of a basic block)
|
/* Returns whether or not the node n (dfsLast numbering of a basic block)
|
||||||
* is on the list l. */
|
* is on the list l. */
|
||||||
static bool inList (const nodeList &l, int n)
|
bool inList (const nodeList &l, int n)
|
||||||
{
|
{
|
||||||
return std::find(l.begin(),l.end(),n)!=l.end();
|
return std::find(l.begin(),l.end(),n)!=l.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Frees space allocated by the list l. */
|
|
||||||
static void freeList (nodeList &l)
|
|
||||||
{
|
|
||||||
l.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Returns whether the node n belongs to the queue list q. */
|
/* Returns whether the node n belongs to the queue list q. */
|
||||||
static bool inInt(BB * n, queue &q)
|
bool inInt(BB * n, queue &q)
|
||||||
{
|
{
|
||||||
return std::find(q.begin(),q.end(),n)!=q.end();
|
return std::find(q.begin(),q.end(),n)!=q.end();
|
||||||
}
|
}
|
||||||
|
/** Recursive procedure to find nodes that belong to the interval (ie. nodes
|
||||||
|
* from G1). */
|
||||||
|
void findNodesInInt (queue &intNodes, int level, interval *Ii)
|
||||||
|
{
|
||||||
|
if (level == 1)
|
||||||
|
{
|
||||||
|
for(BB *en : Ii->nodes)
|
||||||
|
{
|
||||||
|
appendQueue(intNodes,en);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(BB *en : Ii->nodes)
|
||||||
|
{
|
||||||
|
findNodesInInt(intNodes,level-1,en->correspInt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
/* Finds the follow of the endless loop headed at node head (if any).
|
/* Finds the follow of the endless loop headed at node head (if any).
|
||||||
* The follow node is the closest node to the loop. */
|
* The follow node is the closest node to the loop. */
|
||||||
static void findEndlessFollow (Function * pProc, nodeList &loopNodes, BB * head)
|
void findEndlessFollow (Function * pProc, nodeList &loopNodes, BB * head)
|
||||||
{
|
{
|
||||||
head->loopFollow = MAX;
|
head->loopFollow = MAX;
|
||||||
for( int loop_node : loopNodes)
|
for( int loop_node : loopNodes)
|
||||||
{
|
{
|
||||||
for (TYPEADR_TYPE &typeaddr: pProc->m_dfsLast[loop_node]->edges)
|
for (const TYPEADR_TYPE &typeaddr: pProc->m_dfsLast[loop_node]->edges)
|
||||||
{
|
{
|
||||||
int succ = typeaddr.BBptr->dfsLastNum;
|
int succ = typeaddr.BBptr->dfsLastNum;
|
||||||
if ((not inList(loopNodes, succ)) and (succ < head->loopFollow))
|
if ((not inList(loopNodes, succ)) and (succ < head->loopFollow))
|
||||||
@ -128,7 +109,7 @@ static void findEndlessFollow (Function * pProc, nodeList &loopNodes, BB * head)
|
|||||||
//static void findNodesInLoop(BB * latchNode,BB * head,PPROC pProc,queue *intNodes)
|
//static void findNodesInLoop(BB * latchNode,BB * head,PPROC pProc,queue *intNodes)
|
||||||
/* Flags nodes that belong to the loop determined by (latchNode, head) and
|
/* Flags nodes that belong to the loop determined by (latchNode, head) and
|
||||||
* determines the type of loop. */
|
* determines the type of loop. */
|
||||||
static void findNodesInLoop(BB * latchNode,BB * head,Function * pProc,queue &intNodes)
|
void findNodesInLoop(BB * latchNode,BB * head,Function * pProc,queue &intNodes)
|
||||||
{
|
{
|
||||||
int i, headDfsNum, intNodeType;
|
int i, headDfsNum, intNodeType;
|
||||||
nodeList loopNodes;
|
nodeList loopNodes;
|
||||||
@ -139,7 +120,7 @@ static void findNodesInLoop(BB * latchNode,BB * head,Function * pProc,queue &int
|
|||||||
/* Flag nodes in loop headed by head (except header node) */
|
/* Flag nodes in loop headed by head (except header node) */
|
||||||
headDfsNum = head->dfsLastNum;
|
headDfsNum = head->dfsLastNum;
|
||||||
head->loopHead = headDfsNum;
|
head->loopHead = headDfsNum;
|
||||||
insertList (loopNodes, headDfsNum);
|
loopNodes.push_back(headDfsNum);
|
||||||
for (i = headDfsNum + 1; i < latchNode->dfsLastNum; i++)
|
for (i = headDfsNum + 1; i < latchNode->dfsLastNum; i++)
|
||||||
{
|
{
|
||||||
if (pProc->m_dfsLast[i]->flg & INVALID_BB) /* skip invalid BBs */
|
if (pProc->m_dfsLast[i]->flg & INVALID_BB) /* skip invalid BBs */
|
||||||
@ -148,14 +129,14 @@ static void findNodesInLoop(BB * latchNode,BB * head,Function * pProc,queue &int
|
|||||||
immedDom = pProc->m_dfsLast[i]->immedDom;
|
immedDom = pProc->m_dfsLast[i]->immedDom;
|
||||||
if (inList (loopNodes, immedDom) and inInt(pProc->m_dfsLast[i], intNodes))
|
if (inList (loopNodes, immedDom) and inInt(pProc->m_dfsLast[i], intNodes))
|
||||||
{
|
{
|
||||||
insertList (loopNodes, i);
|
loopNodes.push_back(i);
|
||||||
if (pProc->m_dfsLast[i]->loopHead == NO_NODE)/*not in other loop*/
|
if (pProc->m_dfsLast[i]->loopHead == NO_NODE)/*not in other loop*/
|
||||||
pProc->m_dfsLast[i]->loopHead = headDfsNum;
|
pProc->m_dfsLast[i]->loopHead = headDfsNum;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
latchNode->loopHead = headDfsNum;
|
latchNode->loopHead = headDfsNum;
|
||||||
if (latchNode != head)
|
if (latchNode != head)
|
||||||
insertList (loopNodes, latchNode->dfsLastNum);
|
loopNodes.push_back(latchNode->dfsLastNum);
|
||||||
|
|
||||||
/* Determine type of loop and follow node */
|
/* Determine type of loop and follow node */
|
||||||
intNodeType = head->nodeType;
|
intNodeType = head->nodeType;
|
||||||
@ -216,7 +197,7 @@ static void findNodesInLoop(BB * latchNode,BB * head,Function * pProc,queue &int
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Check if couldn't find it, then it is a strangely formed
|
/* Check if couldn't find it, then it is a strangely formed
|
||||||
* loop, so it is safer to consider it an endless loop */
|
* loop, so it is safer to consider it an endless loop */
|
||||||
if (pbb->dfsLastNum <= head->dfsLastNum)
|
if (pbb->dfsLastNum <= head->dfsLastNum)
|
||||||
{
|
{
|
||||||
head->loopType = eNodeHeaderType::ENDLESS_TYPE;
|
head->loopType = eNodeHeaderType::ENDLESS_TYPE;
|
||||||
@ -235,32 +216,79 @@ static void findNodesInLoop(BB * latchNode,BB * head,Function * pProc,queue &int
|
|||||||
findEndlessFollow (pProc, loopNodes, head);
|
findEndlessFollow (pProc, loopNodes, head);
|
||||||
}
|
}
|
||||||
|
|
||||||
freeList(loopNodes);
|
loopNodes.clear();
|
||||||
}
|
}
|
||||||
|
/** \returns whether the BB indexed by s is a successor of the BB indexed by \arg h
|
||||||
//static void findNodesInInt (queue **intNodes, int level, interval *Ii)
|
* \note that h is a case node.
|
||||||
/* Recursive procedure to find nodes that belong to the interval (ie. nodes
|
*/
|
||||||
* from G1). */
|
bool successor (int s, int h, Function * pProc)
|
||||||
static void findNodesInInt (queue &intNodes, int level, interval *Ii)
|
|
||||||
{
|
{
|
||||||
if (level == 1)
|
BB * header = pProc->m_dfsLast[h];
|
||||||
|
auto iter = std::find_if(header->edges.begin(),
|
||||||
|
header->edges.end(),
|
||||||
|
[s](const TYPEADR_TYPE &te)->bool{ return te.BBptr->dfsLastNum == s;});
|
||||||
|
return iter!=header->edges.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Recursive procedure to tag nodes that belong to the case described by
|
||||||
|
* the list l, head and tail (dfsLast index to first and exit node of the
|
||||||
|
* case). */
|
||||||
|
void tagNodesInCase (BB * pBB, nodeList &l, int head, int tail)
|
||||||
|
{
|
||||||
|
int current; /* index to current node */
|
||||||
|
|
||||||
|
pBB->traversed = DFS_CASE;
|
||||||
|
current = pBB->dfsLastNum;
|
||||||
|
if ((current != tail) and (pBB->nodeType != MULTI_BRANCH) and (inList (l, pBB->immedDom)))
|
||||||
{
|
{
|
||||||
for(BB *en : Ii->nodes)
|
l.push_back(current);
|
||||||
|
pBB->caseHead = head;
|
||||||
|
for(TYPEADR_TYPE &edge : pBB->edges)
|
||||||
{
|
{
|
||||||
appendQueue(intNodes,en);
|
if (edge.BBptr->traversed != DFS_CASE)
|
||||||
|
tagNodesInCase (edge.BBptr, l, head, tail);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
|
||||||
|
/** Flags all nodes in the list l as having follow node f, and deletes all
|
||||||
|
* nodes from the list. */
|
||||||
|
void flagNodes (nodeList &l, int f, Function * pProc)
|
||||||
|
{
|
||||||
|
for(int idx : l)
|
||||||
{
|
{
|
||||||
for(BB *en : Ii->nodes)
|
pProc->m_dfsLast[idx]->ifFollow = f;
|
||||||
|
}
|
||||||
|
l.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // end of anonymouse namespace
|
||||||
|
|
||||||
|
/** Finds the immediate dominator of each node in the graph pProc->cfg.
|
||||||
|
* Adapted version of the dominators algorithm by Hecht and Ullman; finds
|
||||||
|
* immediate dominators only.
|
||||||
|
* Note: graph should be reducible */
|
||||||
|
void Function::findImmedDom ()
|
||||||
|
{
|
||||||
|
BB * currNode;
|
||||||
|
for (size_t currIdx = 0; currIdx < numBBs; currIdx++)
|
||||||
|
{
|
||||||
|
currNode = m_dfsLast[currIdx];
|
||||||
|
if (currNode->flg & INVALID_BB) /* Do not process invalid BBs */
|
||||||
|
continue;
|
||||||
|
for (BB * inedge : currNode->inEdges)
|
||||||
{
|
{
|
||||||
findNodesInInt(intNodes,level-1,en->correspInt);
|
size_t predIdx = inedge->dfsLastNum;
|
||||||
|
if (predIdx < currIdx)
|
||||||
|
currNode->immedDom = commonDom (currNode->immedDom, predIdx, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Algorithm for structuring loops */
|
/** Algorithm for structuring loops */
|
||||||
void Function::structLoops(derSeq *derivedG)
|
void Function::structLoops(derSeq *derivedG)
|
||||||
{
|
{
|
||||||
interval *Ii;
|
interval *Ii;
|
||||||
@ -276,8 +304,7 @@ void Function::structLoops(derSeq *derivedG)
|
|||||||
for(auto & elem : *derivedG)
|
for(auto & elem : *derivedG)
|
||||||
{
|
{
|
||||||
level++;
|
level++;
|
||||||
Ii = elem.Ii;
|
for (Ii = elem.Ii; Ii!=nullptr; Ii = Ii->next) /* for all intervals Ii of Gi */
|
||||||
while (Ii) /* for all intervals Ii of Gi */
|
|
||||||
{
|
{
|
||||||
latchNode = nullptr;
|
latchNode = nullptr;
|
||||||
intNodes.clear();
|
intNodes.clear();
|
||||||
@ -319,45 +346,6 @@ void Function::structLoops(derSeq *derivedG)
|
|||||||
latchNode->flg |= IS_LATCH_NODE;
|
latchNode->flg |= IS_LATCH_NODE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Next interval */
|
|
||||||
Ii = Ii->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Next derived sequence */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Returns whether the BB indexed by s is a successor of the BB indexed by
|
|
||||||
* h. Note that h is a case node. */
|
|
||||||
static bool successor (int s, int h, Function * pProc)
|
|
||||||
{
|
|
||||||
BB * header = pProc->m_dfsLast[h];
|
|
||||||
auto iter = std::find_if(header->edges.begin(),
|
|
||||||
header->edges.end(),
|
|
||||||
[s](const TYPEADR_TYPE &te)->bool{ return te.BBptr->dfsLastNum == s;});
|
|
||||||
return iter!=header->edges.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Recursive procedure to tag nodes that belong to the case described by
|
|
||||||
* the list l, head and tail (dfsLast index to first and exit node of the
|
|
||||||
* case). */
|
|
||||||
static void tagNodesInCase (BB * pBB, nodeList &l, int head, int tail)
|
|
||||||
{
|
|
||||||
int current; /* index to current node */
|
|
||||||
|
|
||||||
pBB->traversed = DFS_CASE;
|
|
||||||
current = pBB->dfsLastNum;
|
|
||||||
if ((current != tail) and (pBB->nodeType != MULTI_BRANCH) and (inList (l, pBB->immedDom)))
|
|
||||||
{
|
|
||||||
insertList (l, current);
|
|
||||||
pBB->caseHead = head;
|
|
||||||
for(TYPEADR_TYPE &edge : pBB->edges)
|
|
||||||
{
|
|
||||||
if (edge.BBptr->traversed != DFS_CASE)
|
|
||||||
tagNodesInCase (edge.BBptr, l, head, tail);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -385,9 +373,7 @@ void Function::structCases()
|
|||||||
if ((not successor(j, i, this)) and (m_dfsLast[j]->immedDom == i))
|
if ((not successor(j, i, this)) and (m_dfsLast[j]->immedDom == i))
|
||||||
{
|
{
|
||||||
if (exitNode == NO_NODE)
|
if (exitNode == NO_NODE)
|
||||||
{
|
|
||||||
exitNode = j;
|
exitNode = j;
|
||||||
}
|
|
||||||
else if (m_dfsLast[exitNode]->inEdges.size() < m_dfsLast[j]->inEdges.size())
|
else if (m_dfsLast[exitNode]->inEdges.size() < m_dfsLast[j]->inEdges.size())
|
||||||
exitNode = j;
|
exitNode = j;
|
||||||
}
|
}
|
||||||
@ -396,7 +382,7 @@ void Function::structCases()
|
|||||||
|
|
||||||
/* Tag nodes that belong to the case by recording the
|
/* Tag nodes that belong to the case by recording the
|
||||||
* header field with caseHeader. */
|
* header field with caseHeader. */
|
||||||
insertList (caseNodes, i);
|
caseNodes.push_back(i);
|
||||||
m_dfsLast[i]->caseHead = i;
|
m_dfsLast[i]->caseHead = i;
|
||||||
for(TYPEADR_TYPE &pb : caseHeader->edges)
|
for(TYPEADR_TYPE &pb : caseHeader->edges)
|
||||||
{
|
{
|
||||||
@ -409,20 +395,6 @@ void Function::structCases()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Flags all nodes in the list l as having follow node f, and deletes all
|
|
||||||
* nodes from the list. */
|
|
||||||
static void flagNodes (nodeList &l, int f, Function * pProc)
|
|
||||||
{
|
|
||||||
nodeList::iterator p;
|
|
||||||
for(int idx : l)
|
|
||||||
{
|
|
||||||
pProc->m_dfsLast[idx]->ifFollow = f;
|
|
||||||
}
|
|
||||||
l.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Structures if statements */
|
/* Structures if statements */
|
||||||
void Function::structIfs ()
|
void Function::structIfs ()
|
||||||
{
|
{
|
||||||
@ -434,7 +406,7 @@ void Function::structIfs ()
|
|||||||
unresolved /* List of unresolved if nodes */
|
unresolved /* List of unresolved if nodes */
|
||||||
;
|
;
|
||||||
BB * currNode, /* Pointer to current node */
|
BB * currNode, /* Pointer to current node */
|
||||||
* pbb;
|
* pbb;
|
||||||
|
|
||||||
/* Linear scan of nodes in reverse dfsLast order */
|
/* Linear scan of nodes in reverse dfsLast order */
|
||||||
for (curr = numBBs - 1; curr >= 0; curr--)
|
for (curr = numBBs - 1; curr >= 0; curr--)
|
||||||
@ -453,7 +425,7 @@ void Function::structIfs ()
|
|||||||
{
|
{
|
||||||
if (m_dfsLast[desc]->immedDom == curr)
|
if (m_dfsLast[desc]->immedDom == curr)
|
||||||
{
|
{
|
||||||
insertList (domDesc, desc);
|
domDesc.push_back(desc);
|
||||||
pbb = m_dfsLast[desc];
|
pbb = m_dfsLast[desc];
|
||||||
if ((pbb->inEdges.size() - pbb->numBackEdges) >= followInEdges)
|
if ((pbb->inEdges.size() - pbb->numBackEdges) >= followInEdges)
|
||||||
{
|
{
|
||||||
@ -472,9 +444,9 @@ void Function::structIfs ()
|
|||||||
flagNodes (unresolved, follow, this);
|
flagNodes (unresolved, follow, this);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
insertList (unresolved, curr);
|
unresolved.push_back(curr);
|
||||||
}
|
}
|
||||||
freeList (domDesc);
|
domDesc.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool Function::removeInEdge_Flag_and_ProcessLatch(BB *pbb,BB *a,BB *b)
|
bool Function::removeInEdge_Flag_and_ProcessLatch(BB *pbb,BB *a,BB *b)
|
||||||
@ -651,8 +623,7 @@ void Function::compoundCond()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Structuring algorithm to find the structures of the graph pProc->cfg */
|
||||||
/* Structuring algorithm to find the structures of the graph pProc->cfg */
|
|
||||||
void Function::structure(derSeq *derivedG)
|
void Function::structure(derSeq *derivedG)
|
||||||
{
|
{
|
||||||
/* Find immediate dominators of the graph */
|
/* Find immediate dominators of the graph */
|
||||||
|
|||||||
229
src/dataflow.cpp
229
src/dataflow.cpp
@ -22,6 +22,9 @@
|
|||||||
|
|
||||||
using namespace boost;
|
using namespace boost;
|
||||||
using namespace boost::adaptors;
|
using namespace boost::adaptors;
|
||||||
|
using namespace std;
|
||||||
|
namespace
|
||||||
|
{
|
||||||
struct ExpStack
|
struct ExpStack
|
||||||
{
|
{
|
||||||
Function *func;
|
Function *func;
|
||||||
@ -49,6 +52,57 @@ struct ExpStack
|
|||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
ExpStack g_exp_stk;
|
||||||
|
/** Returns a string with the source operand of Icode */
|
||||||
|
Expr *srcIdent (const LLInst &ll_insn, Function * pProc, iICODE i, ICODE & duIcode, operDu du)
|
||||||
|
{
|
||||||
|
const LLOperand * src_op = ll_insn.get(SRC);
|
||||||
|
if (src_op->isImmediate()) /* immediate operand ll_insn.testFlags(I)*/
|
||||||
|
{
|
||||||
|
//if (ll_insn.testFlags(B))
|
||||||
|
return new Constant(src_op->getImm2(), src_op->byteWidth());
|
||||||
|
}
|
||||||
|
// otherwise
|
||||||
|
return AstIdent::id (ll_insn, SRC, pProc, i, duIcode, du);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Returns the destination operand */
|
||||||
|
Expr *dstIdent (const LLInst & ll_insn, Function * pProc, iICODE i, ICODE & duIcode, operDu du)
|
||||||
|
{
|
||||||
|
Expr *n;
|
||||||
|
n = AstIdent::id (ll_insn, DST, pProc, i, duIcode, du);
|
||||||
|
/** Is it needed? (pIcode->ll()->flg) & NO_SRC_B **/
|
||||||
|
return (n);
|
||||||
|
}
|
||||||
|
/* Substitutes the rhs (or lhs if rhs not possible) of ticode for the expression exp given */
|
||||||
|
void forwardSubsLong (int longIdx, Expr *_exp, ICODE &picode, ICODE &ticode, int *numHlIcodes)
|
||||||
|
{
|
||||||
|
bool res;
|
||||||
|
|
||||||
|
if (_exp == nullptr) /* In case expression popped is NULL */
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Insert on rhs of ticode, if possible */
|
||||||
|
res = Expr::insertSubTreeLongReg (_exp, ticode.hlU()->asgn.m_rhs, longIdx);
|
||||||
|
if (res)
|
||||||
|
{
|
||||||
|
picode.invalidate();
|
||||||
|
(*numHlIcodes)--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Try to insert it on lhs of ticode*/
|
||||||
|
res = Expr::insertSubTreeLongReg (_exp, ticode.hlU()->asgn.m_lhs, longIdx);
|
||||||
|
if (res)
|
||||||
|
{
|
||||||
|
picode.invalidate();
|
||||||
|
(*numHlIcodes)--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end of anonymous namespace
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Expression stack functions
|
* Expression stack functions
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
@ -92,8 +146,6 @@ bool ExpStack::empty()
|
|||||||
return expStk.empty();
|
return expStk.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
ExpStack g_exp_stk;
|
|
||||||
|
|
||||||
/* Returns the index of the local variable or parameter at offset off, if it
|
/* Returns the index of the local variable or parameter at offset off, if it
|
||||||
* is in the stack frame provided. */
|
* is in the stack frame provided. */
|
||||||
@ -104,28 +156,6 @@ size_t STKFRAME::getLocVar(int off)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Returns a string with the source operand of Icode */
|
|
||||||
static Expr *srcIdent (const LLInst &ll_insn, Function * pProc, iICODE i, ICODE & duIcode, operDu du)
|
|
||||||
{
|
|
||||||
const LLOperand * src_op = ll_insn.get(SRC);
|
|
||||||
if (src_op->isImmediate()) /* immediate operand ll_insn.testFlags(I)*/
|
|
||||||
{
|
|
||||||
//if (ll_insn.testFlags(B))
|
|
||||||
return new Constant(src_op->getImm2(), src_op->byteWidth());
|
|
||||||
}
|
|
||||||
// otherwise
|
|
||||||
return AstIdent::id (ll_insn, SRC, pProc, i, duIcode, du);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Returns the destination operand */
|
|
||||||
static Expr *dstIdent (const LLInst & ll_insn, Function * pProc, iICODE i, ICODE & duIcode, operDu du)
|
|
||||||
{
|
|
||||||
Expr *n;
|
|
||||||
n = AstIdent::id (ll_insn, DST, pProc, i, duIcode, du);
|
|
||||||
/** Is it needed? (pIcode->ll()->flg) & NO_SRC_B **/
|
|
||||||
return (n);
|
|
||||||
}
|
|
||||||
/* Eliminates all condition codes and generates new hlIcode instructions */
|
/* Eliminates all condition codes and generates new hlIcode instructions */
|
||||||
void Function::elimCondCodes ()
|
void Function::elimCondCodes ()
|
||||||
{
|
{
|
||||||
@ -563,7 +593,7 @@ void Function::genDU1 ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Substitutes the rhs (or lhs if rhs not possible) of ticode for the rhs of picode. */
|
/* Substitutes the rhs (or lhs if rhs not possible) of ticode for the rhs of picode. */
|
||||||
void LOCAL_ID::forwardSubs (Expr *lhs, Expr *rhs, iICODE picode, iICODE ticode, int &numHlIcodes) const
|
void LOCAL_ID::forwardSubs (Expr *lhs, Expr *rhs, ICODE &picode, ICODE &ticode, int &numHlIcodes) const
|
||||||
{
|
{
|
||||||
bool res;
|
bool res;
|
||||||
UnaryOperator *lhs_unary;
|
UnaryOperator *lhs_unary;
|
||||||
@ -579,16 +609,16 @@ void LOCAL_ID::forwardSubs (Expr *lhs, Expr *rhs, iICODE picode, iICODE ticode,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
/* Insert on rhs of ticode, if possible */
|
/* Insert on rhs of ticode, if possible */
|
||||||
res = Expr::insertSubTreeReg (ticode->hlU()->asgn.rhs,rhs, id_arr[lhs_reg->regiIdx].id.regi, this);
|
res = Expr::insertSubTreeReg (ticode.hlU()->asgn.m_rhs,rhs, id_arr[lhs_reg->regiIdx].id.regi, this);
|
||||||
if (res)
|
if (res)
|
||||||
{
|
{
|
||||||
picode->invalidate();
|
picode.invalidate();
|
||||||
numHlIcodes--;
|
numHlIcodes--;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Try to insert it on lhs of ticode*/
|
/* Try to insert it on lhs of ticode*/
|
||||||
RegisterNode *op = dynamic_cast<RegisterNode *>(ticode->hlU()->asgn.m_lhs);
|
RegisterNode *op = dynamic_cast<RegisterNode *>(ticode.hlU()->asgn.m_lhs);
|
||||||
if(op)
|
if(op)
|
||||||
{
|
{
|
||||||
eReg inserted = id_arr[lhs_reg->regiIdx].id.regi;
|
eReg inserted = id_arr[lhs_reg->regiIdx].id.regi;
|
||||||
@ -599,44 +629,17 @@ void LOCAL_ID::forwardSubs (Expr *lhs, Expr *rhs, iICODE picode, iICODE ticode,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
res = Expr::insertSubTreeReg (ticode->hlU()->asgn.m_lhs,rhs, id_arr[lhs_reg->regiIdx].id.regi, this);
|
res = Expr::insertSubTreeReg (ticode.hlU()->asgn.m_lhs,rhs, id_arr[lhs_reg->regiIdx].id.regi, this);
|
||||||
if (res)
|
if (res)
|
||||||
{
|
{
|
||||||
picode->invalidate();
|
picode.invalidate();
|
||||||
numHlIcodes--;
|
numHlIcodes--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Substitutes the rhs (or lhs if rhs not possible) of ticode for the expression exp given */
|
/** Returns whether the elements of the expression rhs are all x-clear from
|
||||||
static void forwardSubsLong (int longIdx, Expr *_exp, iICODE picode, iICODE ticode, int *numHlIcodes)
|
|
||||||
{
|
|
||||||
bool res;
|
|
||||||
|
|
||||||
if (_exp == nullptr) /* In case expression popped is NULL */
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Insert on rhs of ticode, if possible */
|
|
||||||
res = Expr::insertSubTreeLongReg (_exp, ticode->hlU()->asgn.rhs, longIdx);
|
|
||||||
if (res)
|
|
||||||
{
|
|
||||||
picode->invalidate();
|
|
||||||
(*numHlIcodes)--;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Try to insert it on lhs of ticode*/
|
|
||||||
res = Expr::insertSubTreeLongReg (_exp, ticode->hlU()->asgn.m_lhs, longIdx);
|
|
||||||
if (res)
|
|
||||||
{
|
|
||||||
picode->invalidate();
|
|
||||||
(*numHlIcodes)--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Returns whether the elements of the expression rhs are all x-clear from
|
|
||||||
* instruction f up to instruction t. */
|
* instruction f up to instruction t. */
|
||||||
bool UnaryOperator::xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locs)
|
bool UnaryOperator::xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locs)
|
||||||
{
|
{
|
||||||
@ -679,7 +682,7 @@ int C_CallingConvention::processCArg (Function * callee, Function * pProc, ICODE
|
|||||||
return; */
|
return; */
|
||||||
assert(pProc==g_exp_stk.func);
|
assert(pProc==g_exp_stk.func);
|
||||||
_exp = g_exp_stk.pop();
|
_exp = g_exp_stk.pop();
|
||||||
if (callee->flg & PROC_ISLIB) /* library function */
|
if (callee->isLibrary() ) /* library function */
|
||||||
{
|
{
|
||||||
if (callee->args.numArgs > 0)
|
if (callee->args.numArgs > 0)
|
||||||
{
|
{
|
||||||
@ -747,11 +750,11 @@ int C_CallingConvention::processCArg (Function * callee, Function * pProc, ICODE
|
|||||||
/** Eliminates extraneous intermediate icode instructions when finding
|
/** Eliminates extraneous intermediate icode instructions when finding
|
||||||
* expressions. Generates new hlIcodes in the form of expression trees.
|
* expressions. Generates new hlIcodes in the form of expression trees.
|
||||||
* For HLI_CALL hlIcodes, places the arguments in the argument list. */
|
* For HLI_CALL hlIcodes, places the arguments in the argument list. */
|
||||||
void LOCAL_ID::processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode,bool isLong) const
|
void LOCAL_ID::processTargetIcode(ICODE &picode, int &numHlIcodes, ICODE &ticode,bool isLong) const
|
||||||
{
|
{
|
||||||
bool res;
|
bool res;
|
||||||
HLTYPE &p_hl(*picode->hlU());
|
HLTYPE &p_hl(*picode.hlU());
|
||||||
HLTYPE &t_hl(*ticode->hlU());
|
HLTYPE &t_hl(*ticode.hlU());
|
||||||
|
|
||||||
AstIdent *lhs_ident = dynamic_cast<AstIdent *>(p_hl.asgn.lhs());
|
AstIdent *lhs_ident = dynamic_cast<AstIdent *>(p_hl.asgn.lhs());
|
||||||
switch (t_hl.opcode)
|
switch (t_hl.opcode)
|
||||||
@ -761,11 +764,11 @@ void LOCAL_ID::processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode
|
|||||||
if(isLong)
|
if(isLong)
|
||||||
{
|
{
|
||||||
forwardSubsLong (lhs_ident->ident.idNode.longIdx,
|
forwardSubsLong (lhs_ident->ident.idNode.longIdx,
|
||||||
p_hl.asgn.rhs, picode,ticode,
|
p_hl.asgn.m_rhs, picode,ticode,
|
||||||
&numHlIcodes);
|
&numHlIcodes);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
this->forwardSubs (lhs_ident, p_hl.asgn.rhs, picode, ticode, numHlIcodes);
|
this->forwardSubs (lhs_ident, p_hl.asgn.m_rhs, picode, ticode, numHlIcodes);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HLI_JCOND: case HLI_PUSH: case HLI_RET:
|
case HLI_JCOND: case HLI_PUSH: case HLI_RET:
|
||||||
@ -773,7 +776,7 @@ void LOCAL_ID::processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode
|
|||||||
{
|
{
|
||||||
assert(lhs_ident);
|
assert(lhs_ident);
|
||||||
res = Expr::insertSubTreeLongReg (
|
res = Expr::insertSubTreeLongReg (
|
||||||
p_hl.asgn.rhs,
|
p_hl.asgn.m_rhs,
|
||||||
t_hl.exp.v,
|
t_hl.exp.v,
|
||||||
lhs_ident->ident.idNode.longIdx);
|
lhs_ident->ident.idNode.longIdx);
|
||||||
}
|
}
|
||||||
@ -783,20 +786,20 @@ void LOCAL_ID::processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode
|
|||||||
assert(lhs_reg);
|
assert(lhs_reg);
|
||||||
res = Expr::insertSubTreeReg (
|
res = Expr::insertSubTreeReg (
|
||||||
t_hl.exp.v,
|
t_hl.exp.v,
|
||||||
p_hl.asgn.rhs,
|
p_hl.asgn.m_rhs,
|
||||||
id_arr[lhs_reg->regiIdx].id.regi,
|
id_arr[lhs_reg->regiIdx].id.regi,
|
||||||
this);
|
this);
|
||||||
}
|
}
|
||||||
if (res)
|
if (res)
|
||||||
{
|
{
|
||||||
picode->invalidate();
|
picode.invalidate();
|
||||||
numHlIcodes--;
|
numHlIcodes--;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HLI_CALL: /* register arguments */
|
case HLI_CALL: /* register arguments */
|
||||||
newRegArg ( picode, ticode);
|
newRegArg ( picode, ticode);
|
||||||
picode->invalidate();
|
picode.invalidate();
|
||||||
numHlIcodes--;
|
numHlIcodes--;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -843,7 +846,7 @@ void Pascal_CallingConvention::processHLI(Function *func,Expr *_exp, iICODE pico
|
|||||||
while(k<cb)
|
while(k<cb)
|
||||||
{
|
{
|
||||||
_exp = g_exp_stk.pop();
|
_exp = g_exp_stk.pop();
|
||||||
if (pp->flg & PROC_ISLIB) /* library function */
|
if (pp->isLibrary() ) /* library function */
|
||||||
{
|
{
|
||||||
if (pp->args.numArgs > 0)
|
if (pp->args.numArgs > 0)
|
||||||
_exp = func->adjustActArgType(_exp, pp->args[numArgs].type);
|
_exp = func->adjustActArgType(_exp, pp->args[numArgs].type);
|
||||||
@ -857,7 +860,8 @@ void Pascal_CallingConvention::processHLI(Function *func,Expr *_exp, iICODE pico
|
|||||||
{
|
{
|
||||||
fprintf(stderr,"Would try to adjustForArgType with null _exp\n");
|
fprintf(stderr,"Would try to adjustForArgType with null _exp\n");
|
||||||
}
|
}
|
||||||
pp->args.adjustForArgType (numArgs,_exp->expType (func));
|
else
|
||||||
|
pp->args.adjustForArgType (numArgs,_exp->expType (func));
|
||||||
}
|
}
|
||||||
res = picode->newStkArg (_exp,(llIcode)picode->ll()->getOpcode(), func);
|
res = picode->newStkArg (_exp,(llIcode)picode->ll()->getOpcode(), func);
|
||||||
}
|
}
|
||||||
@ -880,7 +884,6 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
|
|||||||
|
|
||||||
ID *_retVal; // function return value
|
ID *_retVal; // function return value
|
||||||
Expr *_exp; // expression pointer - for HLI_POP and HLI_CALL */
|
Expr *_exp; // expression pointer - for HLI_POP and HLI_CALL */
|
||||||
//Expr *lhs; // exp ptr for return value of a HLI_CALL */
|
|
||||||
iICODE ticode; // Target icode */
|
iICODE ticode; // Target icode */
|
||||||
HLTYPE *ti_hl=nullptr;
|
HLTYPE *ti_hl=nullptr;
|
||||||
uint8_t regi;
|
uint8_t regi;
|
||||||
@ -891,18 +894,18 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
|
|||||||
for (auto picode = valid_and_highlevel.begin(); picode != valid_and_highlevel.end(); picode++)
|
for (auto picode = valid_and_highlevel.begin(); picode != valid_and_highlevel.end(); picode++)
|
||||||
{
|
{
|
||||||
ICODE &_ic(*picode);
|
ICODE &_ic(*picode);
|
||||||
HLTYPE &_icHl(*picode->hlU());
|
HLTYPE &_icHl(*_ic.hlU());
|
||||||
numHlIcodes++;
|
numHlIcodes++;
|
||||||
if (picode->du1.getNumRegsDef() == 1) /* uint8_t/uint16_t regs */
|
if (_ic.du1.getNumRegsDef() == 1) /* uint8_t/uint16_t regs */
|
||||||
{
|
{
|
||||||
/* Check for only one use of this register. If this is
|
/* Check for only one use of this register. If this is
|
||||||
* the last definition of the register in this BB, check
|
* the last definition of the register in this BB, check
|
||||||
* that it is not liveOut from this basic block */
|
* that it is not liveOut from this basic block */
|
||||||
if (picode->du1.numUses(0)==1)
|
if (_ic.du1.numUses(0)==1)
|
||||||
{
|
{
|
||||||
/* Check that this register is not liveOut, if it
|
/* Check that this register is not liveOut, if it
|
||||||
* is the last definition of the register */
|
* is the last definition of the register */
|
||||||
regi = picode->du1.regi[0];
|
regi = _ic.du1.regi[0];
|
||||||
|
|
||||||
/* Check if we can forward substitute this register */
|
/* Check if we can forward substitute this register */
|
||||||
switch (_icHl.opcode)
|
switch (_icHl.opcode)
|
||||||
@ -911,16 +914,16 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
|
|||||||
/* Replace rhs of current icode into target
|
/* Replace rhs of current icode into target
|
||||||
* icode expression */
|
* icode expression */
|
||||||
|
|
||||||
ticode = picode->du1.idx[0].uses.front();
|
ticode = _ic.du1.idx[0].uses.front();
|
||||||
if ((picode->du.lastDefRegi.testRegAndSubregs(regi)) and
|
if ((_ic.du.lastDefRegi.testRegAndSubregs(regi)) and
|
||||||
((ticode->hl()->opcode != HLI_CALL) and
|
((ticode->hl()->opcode != HLI_CALL) and
|
||||||
(ticode->hl()->opcode != HLI_RET)))
|
(ticode->hl()->opcode != HLI_RET)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (_icHl.asgn.rhs->xClear (make_iterator_range(picode.base(),picode->du1.idx[0].uses[0]),
|
if (_icHl.asgn.m_rhs->xClear (make_iterator_range(picode.base(),_ic.du1.idx[0].uses[0]),
|
||||||
end(), locals))
|
end(), locals))
|
||||||
{
|
{
|
||||||
locals.processTargetIcode(picode.base(), numHlIcodes, ticode,false);
|
locals.processTargetIcode(_ic, numHlIcodes, *ticode,false);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -929,9 +932,9 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
|
|||||||
// pop X
|
// pop X
|
||||||
// lab1:
|
// lab1:
|
||||||
// call F() <- somehow this is marked as user of POP ?
|
// call F() <- somehow this is marked as user of POP ?
|
||||||
ticode = picode->du1.idx[0].uses.front();
|
ticode = _ic.du1.idx[0].uses.front();
|
||||||
ti_hl = ticode->hlU();
|
ti_hl = ticode->hlU();
|
||||||
if ((picode->du.lastDefRegi.testRegAndSubregs(regi)) and
|
if ((_ic.du.lastDefRegi.testRegAndSubregs(regi)) and
|
||||||
((ti_hl->opcode != HLI_CALL) and
|
((ti_hl->opcode != HLI_CALL) and
|
||||||
(ti_hl->opcode != HLI_RET)))
|
(ti_hl->opcode != HLI_RET)))
|
||||||
continue;
|
continue;
|
||||||
@ -939,7 +942,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
|
|||||||
_exp = g_exp_stk.pop(); /* pop last exp pushed */
|
_exp = g_exp_stk.pop(); /* pop last exp pushed */
|
||||||
switch (ticode->hl()->opcode) {
|
switch (ticode->hl()->opcode) {
|
||||||
case HLI_ASSIGN:
|
case HLI_ASSIGN:
|
||||||
locals.forwardSubs(_icHl.expr(), _exp, picode.base(), ticode, numHlIcodes);
|
locals.forwardSubs(_icHl.expr(), _exp, _ic, *ticode, numHlIcodes);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HLI_JCOND: case HLI_PUSH: case HLI_RET:
|
case HLI_JCOND: case HLI_PUSH: case HLI_RET:
|
||||||
@ -952,7 +955,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
|
|||||||
&locals);
|
&locals);
|
||||||
if (res)
|
if (res)
|
||||||
{
|
{
|
||||||
picode->invalidate();
|
_ic.invalidate();
|
||||||
numHlIcodes--;
|
numHlIcodes--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -970,25 +973,25 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case HLI_CALL:
|
case HLI_CALL:
|
||||||
ticode = picode->du1.idx[0].uses.front();
|
ticode = _ic.du1.idx[0].uses.front();
|
||||||
ti_hl = ticode->hlU();
|
ti_hl = ticode->hlU();
|
||||||
_retVal = &_icHl.call.proc->retVal;
|
_retVal = &_icHl.call.proc->retVal;
|
||||||
switch (ti_hl->opcode)
|
switch (ti_hl->opcode)
|
||||||
{
|
{
|
||||||
case HLI_ASSIGN:
|
case HLI_ASSIGN:
|
||||||
assert(ti_hl->asgn.rhs);
|
assert(ti_hl->asgn.m_rhs);
|
||||||
_exp = _icHl.call.toAst();
|
_exp = _icHl.call.toAst();
|
||||||
res = Expr::insertSubTreeReg (ti_hl->asgn.rhs,_exp, _retVal->id.regi, &locals);
|
res = Expr::insertSubTreeReg (ti_hl->asgn.m_rhs,_exp, _retVal->id.regi, &locals);
|
||||||
if (not res)
|
if (not res)
|
||||||
Expr::insertSubTreeReg (ti_hl->asgn.m_lhs, _exp,_retVal->id.regi, &locals);
|
Expr::insertSubTreeReg (ti_hl->asgn.m_lhs, _exp,_retVal->id.regi, &locals);
|
||||||
//TODO: HERE missing: 2 regs
|
//TODO: HERE missing: 2 regs
|
||||||
picode->invalidate();
|
_ic.invalidate();
|
||||||
numHlIcodes--;
|
numHlIcodes--;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HLI_PUSH: case HLI_RET:
|
case HLI_PUSH: case HLI_RET:
|
||||||
ti_hl->expr( _icHl.call.toAst() );
|
ti_hl->expr( _icHl.call.toAst() );
|
||||||
picode->invalidate();
|
_ic.invalidate();
|
||||||
numHlIcodes--;
|
numHlIcodes--;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -997,13 +1000,13 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
|
|||||||
res = Expr::insertSubTreeReg (ti_hl->exp.v, _exp, _retVal->id.regi, &locals);
|
res = Expr::insertSubTreeReg (ti_hl->exp.v, _exp, _retVal->id.regi, &locals);
|
||||||
if (res) /* was substituted */
|
if (res) /* was substituted */
|
||||||
{
|
{
|
||||||
picode->invalidate();
|
_ic.invalidate();
|
||||||
numHlIcodes--;
|
numHlIcodes--;
|
||||||
}
|
}
|
||||||
else /* cannot substitute function */
|
else /* cannot substitute function */
|
||||||
{
|
{
|
||||||
auto lhs = AstIdent::idID(_retVal,&locals,picode.base());
|
auto lhs = AstIdent::idID(_retVal,&locals,picode.base());
|
||||||
picode->setAsgn(lhs, _exp);
|
_ic.setAsgn(lhs, _exp);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -1016,34 +1019,34 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (picode->du1.getNumRegsDef() == 2) /* long regs */
|
else if (_ic.du1.getNumRegsDef() == 2) /* long regs */
|
||||||
{
|
{
|
||||||
/* Check for only one use of these registers */
|
/* Check for only one use of these registers */
|
||||||
if ((picode->du1.numUses(0) == 1) and (picode->du1.numUses(1) == 1))
|
if ((_ic.du1.numUses(0) == 1) and (_ic.du1.numUses(1) == 1))
|
||||||
{
|
{
|
||||||
regi = picode->du1.regi[0]; //TODO: verify that regi actually should be assigned this
|
regi = _ic.du1.regi[0]; //TODO: verify that regi actually should be assigned this
|
||||||
|
|
||||||
switch (_icHl.opcode)
|
switch (_icHl.opcode)
|
||||||
{
|
{
|
||||||
case HLI_ASSIGN:
|
case HLI_ASSIGN:
|
||||||
/* Replace rhs of current icode into target
|
/* Replace rhs of current icode into target
|
||||||
* icode expression */
|
* icode expression */
|
||||||
if (picode->du1.idx[0].uses[0] == picode->du1.idx[1].uses[0])
|
if (_ic.du1.idx[0].uses[0] == _ic.du1.idx[1].uses[0])
|
||||||
{
|
{
|
||||||
ticode = picode->du1.idx[0].uses.front();
|
ticode = _ic.du1.idx[0].uses.front();
|
||||||
if ((picode->du.lastDefRegi.testRegAndSubregs(regi)) and
|
if ((_ic.du.lastDefRegi.testRegAndSubregs(regi)) and
|
||||||
((ticode->hl()->opcode != HLI_CALL) and
|
((ticode->hl()->opcode != HLI_CALL) and
|
||||||
(ticode->hl()->opcode != HLI_RET)))
|
(ticode->hl()->opcode != HLI_RET)))
|
||||||
continue;
|
continue;
|
||||||
locals.processTargetIcode(picode.base(), numHlIcodes, ticode,true);
|
locals.processTargetIcode(_ic, numHlIcodes, *ticode,true);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HLI_POP:
|
case HLI_POP:
|
||||||
if (picode->du1.idx[0].uses[0] == picode->du1.idx[1].uses[0])
|
if (_ic.du1.idx[0].uses[0] == _ic.du1.idx[1].uses[0])
|
||||||
{
|
{
|
||||||
ticode = picode->du1.idx[0].uses.front();
|
ticode = _ic.du1.idx[0].uses.front();
|
||||||
if ((picode->du.lastDefRegi.testRegAndSubregs(regi)) and
|
if ((_ic.du.lastDefRegi.testRegAndSubregs(regi)) and
|
||||||
((ticode->hl()->opcode != HLI_CALL) and
|
((ticode->hl()->opcode != HLI_CALL) and
|
||||||
(ticode->hl()->opcode != HLI_RET)))
|
(ticode->hl()->opcode != HLI_RET)))
|
||||||
continue;
|
continue;
|
||||||
@ -1052,7 +1055,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
|
|||||||
switch (ticode->hl()->opcode) {
|
switch (ticode->hl()->opcode) {
|
||||||
case HLI_ASSIGN:
|
case HLI_ASSIGN:
|
||||||
forwardSubsLong (dynamic_cast<AstIdent *>(_icHl.expr())->ident.idNode.longIdx,
|
forwardSubsLong (dynamic_cast<AstIdent *>(_icHl.expr())->ident.idNode.longIdx,
|
||||||
_exp, picode.base(), ticode, &numHlIcodes);
|
_exp, _ic, *ticode, &numHlIcodes);
|
||||||
break;
|
break;
|
||||||
case HLI_JCOND: case HLI_PUSH:
|
case HLI_JCOND: case HLI_PUSH:
|
||||||
res = Expr::insertSubTreeLongReg (_exp,
|
res = Expr::insertSubTreeLongReg (_exp,
|
||||||
@ -1060,7 +1063,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
|
|||||||
dynamic_cast<AstIdent *>(_icHl.asgn.lhs())->ident.idNode.longIdx);
|
dynamic_cast<AstIdent *>(_icHl.asgn.lhs())->ident.idNode.longIdx);
|
||||||
if (res)
|
if (res)
|
||||||
{
|
{
|
||||||
picode->invalidate();
|
_ic.invalidate();
|
||||||
numHlIcodes--;
|
numHlIcodes--;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1073,7 +1076,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case HLI_CALL: /* check for function return */
|
case HLI_CALL: /* check for function return */
|
||||||
ticode = picode->du1.idx[0].uses.front();
|
ticode = _ic.du1.idx[0].uses.front();
|
||||||
switch (ticode->hl()->opcode)
|
switch (ticode->hl()->opcode)
|
||||||
{
|
{
|
||||||
case HLI_ASSIGN:
|
case HLI_ASSIGN:
|
||||||
@ -1082,33 +1085,33 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
|
|||||||
AstIdent::Long(&locals, DST,
|
AstIdent::Long(&locals, DST,
|
||||||
ticode,HIGH_FIRST, picode.base(),
|
ticode,HIGH_FIRST, picode.base(),
|
||||||
eDEF, *(++iICODE(ticode))->ll()));
|
eDEF, *(++iICODE(ticode))->ll()));
|
||||||
ticode->hlU()->asgn.rhs = _exp;
|
ticode->hlU()->asgn.m_rhs = _exp;
|
||||||
picode->invalidate();
|
_ic.invalidate();
|
||||||
numHlIcodes--;
|
numHlIcodes--;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HLI_PUSH:
|
case HLI_PUSH:
|
||||||
case HLI_RET:
|
case HLI_RET:
|
||||||
ticode->hlU()->expr( _icHl.call.toAst() );
|
ticode->hlU()->expr( _icHl.call.toAst() );
|
||||||
picode->invalidate();
|
_ic.invalidate();
|
||||||
numHlIcodes--;
|
numHlIcodes--;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HLI_JCOND:
|
case HLI_JCOND:
|
||||||
_exp = _icHl.call.toAst();
|
_exp = _icHl.call.toAst();
|
||||||
_retVal = &picode->hl()->call.proc->retVal;
|
_retVal = &_ic.hl()->call.proc->retVal;
|
||||||
res = Expr::insertSubTreeLongReg (_exp,
|
res = Expr::insertSubTreeLongReg (_exp,
|
||||||
ticode->hlU()->exp.v,
|
ticode->hlU()->exp.v,
|
||||||
locals.newLongReg ( _retVal->type, _retVal->longId(), picode.base()));
|
locals.newLongReg ( _retVal->type, _retVal->longId(), picode.base()));
|
||||||
if (res) /* was substituted */
|
if (res) /* was substituted */
|
||||||
{
|
{
|
||||||
picode->invalidate();
|
_ic.invalidate();
|
||||||
numHlIcodes--;
|
numHlIcodes--;
|
||||||
}
|
}
|
||||||
else /* cannot substitute function */
|
else /* cannot substitute function */
|
||||||
{
|
{
|
||||||
auto lhs = locals.createId(_retVal,picode.base());
|
auto lhs = locals.createId(_retVal,picode.base());
|
||||||
picode->setAsgn(lhs, _exp);
|
_ic.setAsgn(lhs, _exp);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -1129,8 +1132,8 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
|
|||||||
{
|
{
|
||||||
g_exp_stk.processExpPush(numHlIcodes, *picode);
|
g_exp_stk.processExpPush(numHlIcodes, *picode);
|
||||||
}
|
}
|
||||||
else if(picode->du1.getNumRegsDef()!=0)
|
else if(_ic.du1.getNumRegsDef()!=0)
|
||||||
printf("Num def %d\n",picode->du1.getNumRegsDef());
|
printf("Num def %d\n",_ic.du1.getNumRegsDef());
|
||||||
|
|
||||||
/* For HLI_CALL instructions that use arguments from the stack,
|
/* For HLI_CALL instructions that use arguments from the stack,
|
||||||
* pop them from the expression stack and place them on the
|
* pop them from the expression stack and place them on the
|
||||||
@ -1144,11 +1147,11 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
|
|||||||
|
|
||||||
/* If we could not substitute the result of a function,
|
/* If we could not substitute the result of a function,
|
||||||
* assign it to the corresponding registers */
|
* assign it to the corresponding registers */
|
||||||
if ( not _icHl.call.proc->isLibrary() and (not picode->du1.used(0)) and (picode->du1.getNumRegsDef() > 0))
|
if ( not _icHl.call.proc->isLibrary() and (not _ic.du1.used(0)) and (_ic.du1.getNumRegsDef() > 0))
|
||||||
{
|
{
|
||||||
_exp = new FuncNode(_icHl.call.proc, _icHl.call.args);
|
_exp = new FuncNode(_icHl.call.proc, _icHl.call.args);
|
||||||
auto lhs = AstIdent::idID (&_icHl.call.proc->retVal, &locals, picode.base());
|
auto lhs = AstIdent::idID (&_icHl.call.proc->retVal, &locals, picode.base());
|
||||||
picode->setAsgn(lhs, _exp);
|
_ic.setAsgn(lhs, _exp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,12 +25,11 @@ extern SYMTAB symtab; /* Global symbol table */
|
|||||||
extern STATS stats; /* cfg statistics */
|
extern STATS stats; /* cfg statistics */
|
||||||
extern OPTION option; /* Command line options */
|
extern OPTION option; /* Command line options */
|
||||||
|
|
||||||
static char *initargs(int argc, char *argv[]);
|
static void displayTotalStats();
|
||||||
static void displayTotalStats(void);
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* main
|
* main
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
void setupOptions(QCoreApplication &app) {
|
void setupOptions(const QCoreApplication &app) {
|
||||||
//[-a1a2cmsi]
|
//[-a1a2cmsi]
|
||||||
QCommandLineParser parser;
|
QCommandLineParser parser;
|
||||||
parser.setApplicationDescription("dcc");
|
parser.setApplicationDescription("dcc");
|
||||||
@ -80,7 +79,7 @@ void setupOptions(QCoreApplication &app) {
|
|||||||
option.Interact = false;
|
option.Interact = false;
|
||||||
option.Calls = parser.isSet(boolOpts[2]);
|
option.Calls = parser.isSet(boolOpts[2]);
|
||||||
option.filename = args.first();
|
option.filename = args.first();
|
||||||
option.CustomEntryPoint = parser.value(entryPointOption).toUInt(0,16);
|
option.CustomEntryPoint = parser.value(entryPointOption).toUInt(nullptr,16);
|
||||||
if(parser.isSet(targetFileOption))
|
if(parser.isSet(targetFileOption))
|
||||||
asm1_name = asm2_name = parser.value(targetFileOption);
|
asm1_name = asm2_name = parser.value(targetFileOption);
|
||||||
else if(option.asm1 or option.asm2) {
|
else if(option.asm1 or option.asm2) {
|
||||||
|
|||||||
@ -11,36 +11,37 @@
|
|||||||
|
|
||||||
#include "dcc.h"
|
#include "dcc.h"
|
||||||
|
|
||||||
static std::map<eErrorId,std::string> errorMessage =
|
static const std::map<eErrorId,std::string> errorMessage =
|
||||||
{
|
{
|
||||||
{INVALID_ARG ,"Invalid option -%c\n"},
|
{INVALID_ARG ,"Invalid option -%c\n"},
|
||||||
{INVALID_OPCODE ,"Invalid instruction %02X at location %06lX\n"},
|
{INVALID_OPCODE ,"Invalid instruction %02X at location %06lX\n"},
|
||||||
{INVALID_386OP ,"Don't understand 80386 instruction %02X at location %06lX\n"},
|
{INVALID_386OP ,"Don't understand 80386 instruction %02X at location %06lX\n"},
|
||||||
{FUNNY_SEGOVR ,"Segment override with no memory operand at location %06lX\n"},
|
{FUNNY_SEGOVR ,"Segment override with no memory operand at location %06lX\n"},
|
||||||
{FUNNY_REP ,"REP prefix without a string instruction at location %06lX\n"},
|
{FUNNY_REP ,"REP prefix without a string instruction at location %06lX\n"},
|
||||||
{CANNOT_OPEN ,"Cannot open %s\n"},
|
{CANNOT_OPEN ,"Cannot open %s\n"},
|
||||||
{CANNOT_READ ,"Error while reading %s\n"},
|
{CANNOT_READ ,"Error while reading %s\n"},
|
||||||
{MALLOC_FAILED ,"malloc of %ld bytes failed\n"},
|
{MALLOC_FAILED ,"malloc of %ld bytes failed\n"},
|
||||||
{NEWEXE_FORMAT ,"Don't understand new EXE format\n"},
|
{NEWEXE_FORMAT ,"Don't understand new EXE format\n"},
|
||||||
{NO_BB ,"Failed to find a BB for jump to %ld in proc %s\n"},
|
{NO_BB ,"Failed to find a BB for jump to %ld in proc %s\n"},
|
||||||
{INVALID_SYNTHETIC_BB,"Basic Block is a synthetic jump\n"},
|
{INVALID_SYNTHETIC_BB,"Basic Block is a synthetic jump\n"},
|
||||||
{INVALID_INT_BB ,"Failed to find a BB for interval\n"},
|
{INVALID_INT_BB ,"Failed to find a BB for interval\n"},
|
||||||
{IP_OUT_OF_RANGE ,"Instruction at location %06lX goes beyond loaded image\n"},
|
{IP_OUT_OF_RANGE ,"Instruction at location %06lX goes beyond loaded image\n"},
|
||||||
{DEF_NOT_FOUND ,"Definition not found for condition code usage at opcode %d\n"},
|
{DEF_NOT_FOUND ,"Definition not found for condition code usage at opcode %d\n"},
|
||||||
{JX_NOT_DEF ,"JX use, definition not supported at opcode #%d\n"},
|
{JX_NOT_DEF ,"JX use, definition not supported at opcode #%d\n"},
|
||||||
{NOT_DEF_USE ,"%x: Def - use not supported. Def op = %d, use op = %d.\n"},
|
{NOT_DEF_USE ,"%x: Def - use not supported. Def op = %d, use op = %d.\n"},
|
||||||
{REPEAT_FAIL ,"Failed to construct repeat..until() condition.\n"},
|
{REPEAT_FAIL ,"Failed to construct repeat..until() condition.\n"},
|
||||||
{WHILE_FAIL ,"Failed to construct while() condition.\n"},
|
{WHILE_FAIL ,"Failed to construct while() condition.\n"},
|
||||||
};
|
};
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
fatalError: displays error message and exits the program.
|
fatalError: displays error message and exits the program.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
void fatalError(eErrorId errId, ...)
|
void fatalError(eErrorId errId, ...)
|
||||||
{ va_list args;
|
{
|
||||||
//#ifdef __UNIX__ /* ultrix */
|
va_list args;
|
||||||
|
//#ifdef __UNIX__ /* ultrix */
|
||||||
#if 0
|
#if 0
|
||||||
int errId;
|
int errId;
|
||||||
|
|
||||||
va_start(args);
|
va_start(args);
|
||||||
errId = va_arg(args, int);
|
errId = va_arg(args, int);
|
||||||
@ -49,10 +50,12 @@ void fatalError(eErrorId errId, ...)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (errId == USAGE)
|
if (errId == USAGE)
|
||||||
fprintf(stderr,"Usage: dcc [-a1a2cmpsvVi][-o asmfile] DOS_executable\n");
|
fprintf(stderr,"Usage: dcc [-a1a2cmpsvVi][-o asmfile] DOS_executable\n");
|
||||||
else {
|
else {
|
||||||
|
auto msg_iter = errorMessage.find(errId);
|
||||||
|
assert(msg_iter!=errorMessage.end());
|
||||||
fprintf(stderr, "dcc: ");
|
fprintf(stderr, "dcc: ");
|
||||||
vfprintf(stderr, errorMessage[errId].c_str(), args);
|
vfprintf(stderr, msg_iter->second.c_str(), args);
|
||||||
}
|
}
|
||||||
va_end(args);
|
va_end(args);
|
||||||
exit((int)errId);
|
exit((int)errId);
|
||||||
@ -63,10 +66,11 @@ void fatalError(eErrorId errId, ...)
|
|||||||
reportError: reports the warning/error and continues with the program.
|
reportError: reports the warning/error and continues with the program.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
void reportError(eErrorId errId, ...)
|
void reportError(eErrorId errId, ...)
|
||||||
{ va_list args;
|
{
|
||||||
//#ifdef __UNIX__ /* ultrix */
|
va_list args;
|
||||||
|
//#ifdef __UNIX__ /* ultrix */
|
||||||
#if 0
|
#if 0
|
||||||
int errId;
|
int errId;
|
||||||
|
|
||||||
va_start(args);
|
va_start(args);
|
||||||
errId = va_arg(args, int);
|
errId = va_arg(args, int);
|
||||||
@ -74,6 +78,8 @@ void reportError(eErrorId errId, ...)
|
|||||||
va_start(args, errId);
|
va_start(args, errId);
|
||||||
#endif
|
#endif
|
||||||
fprintf(stderr, "dcc: ");
|
fprintf(stderr, "dcc: ");
|
||||||
vfprintf(stderr, errorMessage[errId].c_str(), args);
|
auto msg_iter = errorMessage.find(errId);
|
||||||
|
assert(msg_iter!=errorMessage.end());
|
||||||
|
vfprintf(stderr, msg_iter->second.c_str(), args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -532,7 +532,7 @@ QString AssignType::writeOut(Function *pProc, int *numLoc) const
|
|||||||
{
|
{
|
||||||
return QString("%1 = %2;\n")
|
return QString("%1 = %2;\n")
|
||||||
.arg(m_lhs->walkCondExpr (pProc, numLoc))
|
.arg(m_lhs->walkCondExpr (pProc, numLoc))
|
||||||
.arg(rhs->walkCondExpr (pProc, numLoc));
|
.arg(m_rhs->walkCondExpr (pProc, numLoc));
|
||||||
}
|
}
|
||||||
QString CallType::writeOut(Function *pProc, int *numLoc) const
|
QString CallType::writeOut(Function *pProc, int *numLoc) const
|
||||||
{
|
{
|
||||||
@ -553,7 +553,7 @@ void HLTYPE::set(Expr *l, Expr *r)
|
|||||||
//assert((asgn.lhs==0) and (asgn.rhs==0)); //prevent memory leaks
|
//assert((asgn.lhs==0) and (asgn.rhs==0)); //prevent memory leaks
|
||||||
assert(dynamic_cast<UnaryOperator *>(l));
|
assert(dynamic_cast<UnaryOperator *>(l));
|
||||||
asgn.m_lhs=l;
|
asgn.m_lhs=l;
|
||||||
asgn.rhs=r;
|
asgn.m_rhs=r;
|
||||||
}
|
}
|
||||||
/* Returns a string with the contents of the current high-level icode.
|
/* Returns a string with the contents of the current high-level icode.
|
||||||
* Note: this routine does not output the contens of HLI_JCOND icodes. This is
|
* Note: this routine does not output the contens of HLI_JCOND icodes. This is
|
||||||
|
|||||||
@ -213,12 +213,12 @@ void Function::findIdioms()
|
|||||||
/* Check if number of parameter bytes match their calling convention */
|
/* Check if number of parameter bytes match their calling convention */
|
||||||
if ((flg & PROC_HLL) and (not args.empty()))
|
if ((flg & PROC_HLL) and (not args.empty()))
|
||||||
{
|
{
|
||||||
args.m_minOff += (flg & PROC_FAR ? 4 : 2);
|
args.m_minOff += ((flg & PROC_FAR)!=0 ? 4 : 2);
|
||||||
delta = args.maxOff - args.m_minOff;
|
delta = args.maxOff - args.m_minOff;
|
||||||
if (cbParam != delta)
|
if (cbParam != delta)
|
||||||
{
|
{
|
||||||
cbParam = delta;
|
cbParam = delta;
|
||||||
callingConv(CConv::UNKNOWN);
|
callingConv(CConv::eUnknown);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -147,13 +147,13 @@ bool Idiom18::match(iICODE picode)
|
|||||||
break;
|
break;
|
||||||
case 1: /* register variable */
|
case 1: /* register variable */
|
||||||
/* Check previous instruction for a MOV */
|
/* Check previous instruction for a MOV */
|
||||||
if ( (m_icodes[0]->ll()->src().regi == m_icodes[1]->ll()->m_dst.regi))
|
if ( m_icodes[0]->ll()->src().regi == m_icodes[1]->ll()->m_dst.regi)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2: /* local */
|
case 2: /* local */
|
||||||
if ((m_icodes[0]->ll()->src().off == m_icodes[1]->ll()->m_dst.off))
|
if (m_icodes[0]->ll()->src().off == m_icodes[1]->ll()->m_dst.off)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -41,7 +41,7 @@ int Idiom3::action()
|
|||||||
{
|
{
|
||||||
if (m_icodes[0]->ll()->testFlags(I) )
|
if (m_icodes[0]->ll()->testFlags(I) )
|
||||||
{
|
{
|
||||||
m_icodes[0]->ll()->src().addProcInformation(m_param_count,CConv::C);
|
m_icodes[0]->ll()->src().addProcInformation(m_param_count,CConv::eCdecl);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -99,7 +99,7 @@ int Idiom17::action()
|
|||||||
{
|
{
|
||||||
if (m_icodes[0]->ll()->testFlags(I))
|
if (m_icodes[0]->ll()->testFlags(I))
|
||||||
{
|
{
|
||||||
m_icodes[0]->ll()->src().addProcInformation(m_param_count,CConv::C);
|
m_icodes[0]->ll()->src().addProcInformation(m_param_count,CConv::eCdecl);
|
||||||
for(size_t idx=1; idx<m_icodes.size(); ++idx)
|
for(size_t idx=1; idx<m_icodes.size(); ++idx)
|
||||||
{
|
{
|
||||||
m_icodes[idx]->invalidate();
|
m_icodes[idx]->invalidate();
|
||||||
|
|||||||
@ -148,7 +148,7 @@ int Idiom4::action()
|
|||||||
if(m_param_count)
|
if(m_param_count)
|
||||||
{
|
{
|
||||||
m_func->cbParam = (int16_t)m_param_count;
|
m_func->cbParam = (int16_t)m_param_count;
|
||||||
m_func->callingConv(CConv::PASCAL);
|
m_func->callingConv(CConv::ePascal);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
118
src/locident.cpp
118
src/locident.cpp
@ -10,6 +10,9 @@
|
|||||||
#include "msvc_fixes.h"
|
#include "msvc_fixes.h"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
static const int LOCAL_ID_DELTA = 25;
|
||||||
|
static const int IDX_ARRAY_DELTA = 5;
|
||||||
|
|
||||||
|
|
||||||
bool LONGID_TYPE::srcDstRegMatch(iICODE a, iICODE b) const
|
bool LONGID_TYPE::srcDstRegMatch(iICODE a, iICODE b) const
|
||||||
{
|
{
|
||||||
@ -55,9 +58,6 @@ ID::ID(hlType t, const LONGGLB_TYPE &s) : type(t),illegal(false)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define LOCAL_ID_DELTA 25
|
|
||||||
#define IDX_ARRAY_DELTA 5
|
|
||||||
|
|
||||||
/* Creates a new identifier node of type t and returns it.
|
/* Creates a new identifier node of type t and returns it.
|
||||||
* Arguments: locSym : local long symbol table
|
* Arguments: locSym : local long symbol table
|
||||||
* t : type of LONG identifier
|
* t : type of LONG identifier
|
||||||
@ -74,17 +74,15 @@ void LOCAL_ID::newIdent(hlType t, frameType f)
|
|||||||
* TYPE_WORD_(UN)SIGN type. Returns the index to this new entry. */
|
* TYPE_WORD_(UN)SIGN type. Returns the index to this new entry. */
|
||||||
int LOCAL_ID::newByteWordReg(hlType t, eReg regi)
|
int LOCAL_ID::newByteWordReg(hlType t, eReg regi)
|
||||||
{
|
{
|
||||||
int idx;
|
|
||||||
|
|
||||||
/* Check for entry in the table */
|
/* Check for entry in the table */
|
||||||
auto found=std::find_if(id_arr.begin(),id_arr.end(),[t,regi](ID &el)->bool {
|
auto found=std::find_if(id_arr.begin(),id_arr.end(),[t,regi](ID &el)->bool {
|
||||||
return ((el.type == t) and (el.id.regi == regi));
|
return ((el.type == t) and (el.id.regi == regi));
|
||||||
});
|
});
|
||||||
if(found!=id_arr.end())
|
if(found!=id_arr.end())
|
||||||
return found-id_arr.begin();
|
return found-id_arr.begin();
|
||||||
/* Not in table, create new identifier */
|
/* Not in table, create new identifier */
|
||||||
newIdent (t, REG_FRAME);
|
newIdent (t, REG_FRAME);
|
||||||
idx = id_arr.size() - 1;
|
int idx = id_arr.size() - 1;
|
||||||
id_arr[idx].id.regi = regi;
|
id_arr[idx].id.regi = regi;
|
||||||
return (idx);
|
return (idx);
|
||||||
}
|
}
|
||||||
@ -99,11 +97,8 @@ int LOCAL_ID::newByteWordReg(hlType t, eReg regi)
|
|||||||
void LOCAL_ID::flagByteWordId (int off)
|
void LOCAL_ID::flagByteWordId (int off)
|
||||||
{
|
{
|
||||||
auto found=std::find_if(id_arr.begin(),id_arr.end(),[off](ID &en)->bool {
|
auto found=std::find_if(id_arr.begin(),id_arr.end(),[off](ID &en)->bool {
|
||||||
//if (((en.type == TYPE_WORD_SIGN) or (en.type == TYPE_BYTE_SIGN)) and
|
//if (((en.type == TYPE_WORD_SIGN) or (en.type == TYPE_BYTE_SIGN)) and
|
||||||
if ((en.typeBitsize()<=16) and
|
return ((en.typeBitsize()<=16) and (en.id.bwId.off == off) and (en.id.bwId.regOff == 0));
|
||||||
(en.id.bwId.off == off) and (en.id.bwId.regOff == 0))
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
});
|
});
|
||||||
if(found==id_arr.end())
|
if(found==id_arr.end())
|
||||||
{
|
{
|
||||||
@ -117,23 +112,21 @@ void LOCAL_ID::flagByteWordId (int off)
|
|||||||
* TYPE_WORD_(UN)SIGN type. Returns the index to this new entry. */
|
* TYPE_WORD_(UN)SIGN type. Returns the index to this new entry. */
|
||||||
int LOCAL_ID::newByteWordStk(hlType t, int off, uint8_t regOff)
|
int LOCAL_ID::newByteWordStk(hlType t, int off, uint8_t regOff)
|
||||||
{
|
{
|
||||||
int idx;
|
|
||||||
|
|
||||||
/* Check for entry in the table */
|
/* Check for entry in the table */
|
||||||
auto found=std::find_if(id_arr.begin(),id_arr.end(),[off,regOff](ID &el)->bool {
|
auto found=std::find_if(id_arr.begin(),id_arr.end(),[off,regOff](ID &el)->bool {
|
||||||
if ((el.id.bwId.off == off) and (el.id.bwId.regOff == regOff))
|
if ((el.id.bwId.off == off) and (el.id.bwId.regOff == regOff))
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
if(found!=id_arr.end())
|
if(found!=id_arr.end())
|
||||||
return found-id_arr.begin(); //return Index to found element
|
return found-id_arr.begin(); //return Index to found element
|
||||||
|
|
||||||
/* Not in table, create new identifier */
|
/* Not in table, create new identifier */
|
||||||
newIdent (t, STK_FRAME);
|
newIdent (t, STK_FRAME);
|
||||||
idx = id_arr.size() - 1;
|
ID &last_id(id_arr.back());
|
||||||
id_arr[idx].id.bwId.regOff = regOff;
|
last_id.id.bwId.regOff = regOff;
|
||||||
id_arr[idx].id.bwId.off = off;
|
last_id.id.bwId.off = off;
|
||||||
return (idx);
|
return id_arr.size()-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -152,9 +145,9 @@ int LOCAL_ID::newIntIdx(int16_t seg, int16_t off, eReg regi, hlType t)
|
|||||||
for (size_t idx = 0; idx < id_arr.size(); idx++)
|
for (size_t idx = 0; idx < id_arr.size(); idx++)
|
||||||
{
|
{
|
||||||
if (/*(locSym->id[idx].type == t) and Not checking type */
|
if (/*(locSym->id[idx].type == t) and Not checking type */
|
||||||
(id_arr[idx].id.bwGlb.seg == seg) and
|
(id_arr[idx].id.bwGlb.seg == seg) and
|
||||||
(id_arr[idx].id.bwGlb.off == off) and
|
(id_arr[idx].id.bwGlb.off == off) and
|
||||||
(id_arr[idx].id.bwGlb.regi == regi))
|
(id_arr[idx].id.bwGlb.regi == regi))
|
||||||
return (idx);
|
return (idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,23 +182,22 @@ int LOCAL_ID::newLongReg(hlType t, const LONGID_TYPE &longT, iICODE ix_)
|
|||||||
{
|
{
|
||||||
/* Check for occurrence in the list */
|
/* Check for occurrence in the list */
|
||||||
if (entry.idx.inList(ix_))
|
if (entry.idx.inList(ix_))
|
||||||
return (idx);
|
return idx;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Insert icode index in list */
|
/* Insert icode index in list */
|
||||||
entry.idx.push_back(ix_);
|
entry.idx.push_back(ix_);
|
||||||
return (idx);
|
return idx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Not in the table, create new identifier */
|
/* Not in the table, create new identifier */
|
||||||
id_arr.push_back(ID(t, LONGID_TYPE(regH,regL)));
|
id_arr.emplace_back(t, LONGID_TYPE(regH,regL));
|
||||||
id_arr.back().idx.push_back(ix_);
|
id_arr.back().idx.push_back(ix_);
|
||||||
return (id_arr.size() - 1);
|
return (id_arr.size() - 1);
|
||||||
}
|
}
|
||||||
/* Returns an identifier conditional expression node of type TYPE_LONG or
|
/** \returns an identifier conditional expression node of type TYPE_LONG or TYPE_WORD_SIGN */
|
||||||
* TYPE_WORD_SIGN */
|
|
||||||
AstIdent * LOCAL_ID::createId(const ID *retVal, iICODE ix_)
|
AstIdent * LOCAL_ID::createId(const ID *retVal, iICODE ix_)
|
||||||
{
|
{
|
||||||
return AstIdent::idID(retVal,this,ix_);
|
return AstIdent::idID(retVal,this,ix_);
|
||||||
@ -222,14 +214,14 @@ int LOCAL_ID::newLongGlb(int16_t seg, int16_t offH, int16_t offL,hlType t)
|
|||||||
for (idx = 0; idx < id_arr.size(); idx++)
|
for (idx = 0; idx < id_arr.size(); idx++)
|
||||||
{
|
{
|
||||||
if (/*(locSym->id[idx].type == t) and Not checking type */
|
if (/*(locSym->id[idx].type == t) and Not checking type */
|
||||||
(id_arr[idx].id.longGlb.seg == seg) and
|
(id_arr[idx].id.longGlb.seg == seg) and
|
||||||
(id_arr[idx].id.longGlb.offH == offH) and
|
(id_arr[idx].id.longGlb.offH == offH) and
|
||||||
(id_arr[idx].id.longGlb.offL == offL))
|
(id_arr[idx].id.longGlb.offL == offL))
|
||||||
return (idx);
|
return (idx);
|
||||||
}
|
}
|
||||||
printf("%d",t);
|
printf("%d",t);
|
||||||
/* Not in the table, create new identifier */
|
/* Not in the table, create new identifier */
|
||||||
id_arr.push_back(ID(t, LONGGLB_TYPE(seg,offH,offL)));
|
id_arr.emplace_back(t, LONGGLB_TYPE(seg,offH,offL));
|
||||||
return (id_arr.size() - 1);
|
return (id_arr.size() - 1);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -246,15 +238,15 @@ int LOCAL_ID::newLongIdx( int16_t seg, int16_t offH, int16_t offL,uint8_t regi,
|
|||||||
for (idx = 0; idx < id_arr.size(); idx++)
|
for (idx = 0; idx < id_arr.size(); idx++)
|
||||||
{
|
{
|
||||||
if (/*(locSym->id[idx].type == t) and Not checking type */
|
if (/*(locSym->id[idx].type == t) and Not checking type */
|
||||||
(id_arr[idx].id.longGlb.seg == seg) and
|
(id_arr[idx].id.longGlb.seg == seg) and
|
||||||
(id_arr[idx].id.longGlb.offH == offH) and
|
(id_arr[idx].id.longGlb.offH == offH) and
|
||||||
(id_arr[idx].id.longGlb.offL == offL) and
|
(id_arr[idx].id.longGlb.offL == offL) and
|
||||||
(id_arr[idx].id.longGlb.regi == regi))
|
(id_arr[idx].id.longGlb.regi == regi))
|
||||||
return (idx);
|
return (idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Not in the table, create new identifier */
|
/* Not in the table, create new identifier */
|
||||||
id_arr.push_back(ID(t,LONGGLB_TYPE(seg,offH,offL,regi)));
|
id_arr.emplace_back(t,LONGGLB_TYPE(seg,offH,offL,regi));
|
||||||
idx = id_arr.size() - 1;
|
idx = id_arr.size() - 1;
|
||||||
return (idx);
|
return (idx);
|
||||||
}
|
}
|
||||||
@ -272,8 +264,8 @@ int LOCAL_ID::newLongStk(hlType t, int offH, int offL)
|
|||||||
if(id_arr[idx].loc!=STK_FRAME)
|
if(id_arr[idx].loc!=STK_FRAME)
|
||||||
continue;
|
continue;
|
||||||
if ((id_arr[idx].type == t) and
|
if ((id_arr[idx].type == t) and
|
||||||
(id_arr[idx].longStkId().offH == offH) and
|
(id_arr[idx].longStkId().offH == offH) and
|
||||||
(id_arr[idx].longStkId().offL == offL))
|
(id_arr[idx].longStkId().offL == offL))
|
||||||
return (idx);
|
return (idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -282,7 +274,7 @@ int LOCAL_ID::newLongStk(hlType t, int offH, int offL)
|
|||||||
flagByteWordId (offL);
|
flagByteWordId (offL);
|
||||||
|
|
||||||
/* Create new identifier */
|
/* Create new identifier */
|
||||||
id_arr.push_back(ID(t,LONG_STKID_TYPE(offH,offL)));
|
id_arr.emplace_back(t,LONG_STKID_TYPE(offH,offL));
|
||||||
return (id_arr.size() - 1);
|
return (id_arr.size() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -294,7 +286,7 @@ int LOCAL_ID::newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix,operDu du, L
|
|||||||
{
|
{
|
||||||
size_t idx = ~0; //WARNING: clients of this method might propagate this bogus value!
|
size_t idx = ~0; //WARNING: clients of this method might propagate this bogus value!
|
||||||
const LLOperand *pmH, *pmL;
|
const LLOperand *pmH, *pmL;
|
||||||
LLInst &p_ll(*pIcode->ll());
|
LLInst &p_ll(*pIcode->ll());
|
||||||
if (f == LOW_FIRST)
|
if (f == LOW_FIRST)
|
||||||
{
|
{
|
||||||
pmL = p_ll.get(sd);
|
pmL = p_ll.get(sd);
|
||||||
@ -356,22 +348,22 @@ bool checkLongEq (LONG_STKID_TYPE longId, iICODE pIcode, int i, Function * pProc
|
|||||||
pmLdst = &atOffset.m_dst;
|
pmLdst = &atOffset.m_dst;
|
||||||
pmHsrc = &pIcode->ll()->src();
|
pmHsrc = &pIcode->ll()->src();
|
||||||
pmLsrc = &atOffset.src();
|
pmLsrc = &atOffset.src();
|
||||||
// if ((longId.offH == pmHsrc->off) and (longId.offL == pmLsrc->off))
|
// if ((longId.offH == pmHsrc->off) and (longId.offL == pmLsrc->off))
|
||||||
// {
|
// {
|
||||||
// asgn.lhs = AstIdent::LongIdx (i);
|
// asgn.lhs = AstIdent::LongIdx (i);
|
||||||
|
|
||||||
// if ( not pIcode->ll()->testFlags(NO_SRC) )
|
// if ( not pIcode->ll()->testFlags(NO_SRC) )
|
||||||
// {
|
// {
|
||||||
// asgn.rhs = AstIdent::Long (&pProc->localId, SRC, pIcode, HIGH_FIRST, pIcode, eUSE, atOffset);
|
// asgn.rhs = AstIdent::Long (&pProc->localId, SRC, pIcode, HIGH_FIRST, pIcode, eUSE, atOffset);
|
||||||
// }
|
// }
|
||||||
// return true;
|
// return true;
|
||||||
// }
|
// }
|
||||||
// else if ((longId.offH == pmHdst->off) and (longId.offL == pmLdst->off))
|
// else if ((longId.offH == pmHdst->off) and (longId.offL == pmLdst->off))
|
||||||
// {
|
// {
|
||||||
// asgn.lhs = AstIdent::Long (&pProc->localId, DST, pIcode, HIGH_FIRST, pIcode,eDEF, atOffset);
|
// asgn.lhs = AstIdent::Long (&pProc->localId, DST, pIcode, HIGH_FIRST, pIcode,eDEF, atOffset);
|
||||||
// asgn.rhs = AstIdent::LongIdx (i);
|
// asgn.rhs = AstIdent::LongIdx (i);
|
||||||
// return true;
|
// return true;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
if ((longId.offH == pmHdst->off) and (longId.offL == pmLdst->off))
|
if ((longId.offH == pmHdst->off) and (longId.offL == pmLdst->off))
|
||||||
{
|
{
|
||||||
@ -403,7 +395,7 @@ bool checkLongEq (LONG_STKID_TYPE longId, iICODE pIcode, int i, Function * pProc
|
|||||||
* pProc : ptr to current procedure record
|
* pProc : ptr to current procedure record
|
||||||
* rhs, lhs : return expressions if successful. */
|
* rhs, lhs : return expressions if successful. */
|
||||||
bool checkLongRegEq (LONGID_TYPE longId, iICODE pIcode, int i,
|
bool checkLongRegEq (LONGID_TYPE longId, iICODE pIcode, int i,
|
||||||
Function * pProc, Assignment &asgn, LLInst &atOffset)
|
Function * pProc, Assignment &asgn, LLInst &atOffset)
|
||||||
{
|
{
|
||||||
/* pointers to LOW_LEVEL icodes */
|
/* pointers to LOW_LEVEL icodes */
|
||||||
const LLOperand *pmHdst, *pmLdst, *pmHsrc, *pmLsrc;
|
const LLOperand *pmHdst, *pmLdst, *pmHsrc, *pmLsrc;
|
||||||
@ -442,7 +434,7 @@ eReg otherLongRegi (eReg regi, int idx, LOCAL_ID *locTbl)
|
|||||||
|
|
||||||
id = &locTbl->id_arr[idx];
|
id = &locTbl->id_arr[idx];
|
||||||
if ((id->loc == REG_FRAME) and ((id->type == TYPE_LONG_SIGN) or
|
if ((id->loc == REG_FRAME) and ((id->type == TYPE_LONG_SIGN) or
|
||||||
(id->type == TYPE_LONG_UNSIGN)))
|
(id->type == TYPE_LONG_UNSIGN)))
|
||||||
{
|
{
|
||||||
if (id->longId().h() == regi)
|
if (id->longId().h() == regi)
|
||||||
return (id->longId().l());
|
return (id->longId().l());
|
||||||
@ -472,9 +464,9 @@ void LOCAL_ID::propLongId (uint8_t regL, uint8_t regH, const QString &name)
|
|||||||
if (rid.id.regi == regL)
|
if (rid.id.regi == regL)
|
||||||
{
|
{
|
||||||
strcpy (rid.macro, "LO");
|
strcpy (rid.macro, "LO");
|
||||||
}
|
}
|
||||||
else // if (rid.id.regi == regH)
|
else // if (rid.id.regi == regH)
|
||||||
{
|
{
|
||||||
strcpy (rid.macro, "HI");
|
strcpy (rid.macro, "HI");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,15 +7,15 @@
|
|||||||
#include "CallGraph.h"
|
#include "CallGraph.h"
|
||||||
#include "msvc_fixes.h"
|
#include "msvc_fixes.h"
|
||||||
|
|
||||||
#include <inttypes.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h> /* For exit() */
|
|
||||||
#include <sstream>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <algorithm>
|
|
||||||
#include <deque>
|
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
#include <QtCore/QDebug>
|
#include <QtCore/QDebug>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <cstring>
|
||||||
|
#include <cstdlib> /* For exit() */
|
||||||
|
#include <cstdio>
|
||||||
|
#include <sstream>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <deque>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@ -129,7 +129,6 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
|
|||||||
// Danger! Dcc will likely fall over in this code.
|
// Danger! Dcc will likely fall over in this code.
|
||||||
// So we act as though we have done with this proc
|
// So we act as though we have done with this proc
|
||||||
// pProc->flg &= ~TERMINATES; // Not sure about this
|
// pProc->flg &= ~TERMINATES; // Not sure about this
|
||||||
done = true;
|
|
||||||
// And mark it as a library function, so structure() won't choke on it
|
// And mark it as a library function, so structure() won't choke on it
|
||||||
flg |= PROC_ISLIB;
|
flg |= PROC_ISLIB;
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -88,7 +88,7 @@ void CALL_GRAPH::write()
|
|||||||
/* Updates the argument table by including the register(s) (ie. lhs of
|
/* Updates the argument table by including the register(s) (ie. lhs of
|
||||||
* picode) and the actual expression (ie. rhs of picode).
|
* picode) and the actual expression (ie. rhs of picode).
|
||||||
* Note: register(s) are only included once in the table. */
|
* Note: register(s) are only included once in the table. */
|
||||||
void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
|
void LOCAL_ID::newRegArg(ICODE &picode, ICODE &ticode) const
|
||||||
{
|
{
|
||||||
AstIdent *lhs;
|
AstIdent *lhs;
|
||||||
STKFRAME * call_args_stackframe, *target_stackframe;
|
STKFRAME * call_args_stackframe, *target_stackframe;
|
||||||
@ -101,13 +101,13 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
|
|||||||
eReg regH; /* Registers involved in arguments */
|
eReg regH; /* Registers involved in arguments */
|
||||||
|
|
||||||
/* Flag ticode as having register arguments */
|
/* Flag ticode as having register arguments */
|
||||||
tproc = ticode->hl()->call.proc;
|
tproc = ticode.hl()->call.proc;
|
||||||
tproc->flg |= REG_ARGS;
|
tproc->flg |= REG_ARGS;
|
||||||
|
|
||||||
/* Get registers and index into target procedure's local list */
|
/* Get registers and index into target procedure's local list */
|
||||||
call_args_stackframe = ticode->hl()->call.args;
|
call_args_stackframe = ticode.hl()->call.args;
|
||||||
target_stackframe = &tproc->args;
|
target_stackframe = &tproc->args;
|
||||||
lhs = dynamic_cast<AstIdent *>(picode->hl()->asgn.lhs());
|
lhs = dynamic_cast<AstIdent *>(picode.hl()->asgn.lhs());
|
||||||
RegisterNode *lhs_reg = dynamic_cast<RegisterNode *>(lhs);
|
RegisterNode *lhs_reg = dynamic_cast<RegisterNode *>(lhs);
|
||||||
assert(lhs);
|
assert(lhs);
|
||||||
type = lhs->ident.type();
|
type = lhs->ident.type();
|
||||||
@ -188,13 +188,13 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
|
|||||||
/* Do ps (actual arguments) */
|
/* Do ps (actual arguments) */
|
||||||
STKSYM newsym;
|
STKSYM newsym;
|
||||||
newsym.setArgName(call_args_stackframe->size());
|
newsym.setArgName(call_args_stackframe->size());
|
||||||
newsym.actual = picode->hl()->asgn.rhs;
|
newsym.actual = picode.hl()->asgn.m_rhs;
|
||||||
newsym.regs = lhs;
|
newsym.regs = lhs;
|
||||||
/* Mask off high and low register(s) in picode */
|
/* Mask off high and low register(s) in picode */
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case REGISTER:
|
case REGISTER:
|
||||||
id = &id_arr[lhs_reg->regiIdx];
|
id = &id_arr[lhs_reg->regiIdx];
|
||||||
picode->du.def.clrReg(id->id.regi);
|
picode.du.def.clrReg(id->id.regi);
|
||||||
if (id->id.regi < rAL)
|
if (id->id.regi < rAL)
|
||||||
newsym.type = TYPE_WORD_SIGN;
|
newsym.type = TYPE_WORD_SIGN;
|
||||||
else
|
else
|
||||||
@ -202,8 +202,8 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
|
|||||||
break;
|
break;
|
||||||
case LONG_VAR:
|
case LONG_VAR:
|
||||||
id = &id_arr[lhs->ident.idNode.longIdx];
|
id = &id_arr[lhs->ident.idNode.longIdx];
|
||||||
picode->du.def.clrReg(id->longId().h());
|
picode.du.def.clrReg(id->longId().h());
|
||||||
picode->du.def.clrReg(id->longId().l());
|
picode.du.def.clrReg(id->longId().l());
|
||||||
newsym.type = TYPE_LONG_SIGN;
|
newsym.type = TYPE_LONG_SIGN;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
#include "msvc_fixes.h"
|
#include "msvc_fixes.h"
|
||||||
|
|
||||||
#include <QtCore/QCoreApplication>
|
#include <QtCore/QCoreApplication>
|
||||||
|
#include <QtCore/QDebug>
|
||||||
#include <QtCore/QStringList>
|
#include <QtCore/QStringList>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -58,6 +59,9 @@ int main(int argc, char *argv[])
|
|||||||
collector = new TPL_PatternCollector;
|
collector = new TPL_PatternCollector;
|
||||||
} else if(arg2.endsWith(".lib")) {
|
} else if(arg2.endsWith(".lib")) {
|
||||||
collector = new LIB_PatternCollector;
|
collector = new LIB_PatternCollector;
|
||||||
|
} else {
|
||||||
|
qCritical() << "Unsupported file type.";
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
if ((srcfile = fopen(argv[1], "rb")) == NULL)
|
if ((srcfile = fopen(argv[1], "rb")) == NULL)
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user