This commit is contained in:
nemerle
2014-03-07 19:42:27 +01:00
parent 1c5e1c2fce
commit 50950028e0
39 changed files with 922 additions and 795 deletions

View File

@@ -37,7 +37,7 @@ private:
inEdges(0),
edges(0),beenOnH(0),inEdgeCount(0),reachingInt(0),
inInterval(0),correspInt(0),
dfsFirstNum(0),dfsLastNum(0),immedDom(0),ifFollow(0),loopType(0),latchNode(0),
dfsFirstNum(0),dfsLastNum(0),immedDom(0),ifFollow(0),loopType(NO_TYPE),latchNode(0),
numBackEdges(0),loopHead(0),loopFollow(0),caseHead(0),caseTail(0),index(0)
{
@@ -90,7 +90,7 @@ public:
int dfsLastNum; /* DFS #: last visit of node */
int immedDom; /* Immediate dominator (dfsLast index) */
int ifFollow; /* node that ends the if */
int loopType; /* Type of loop (if any) */
eNodeHeaderType loopType; /* Type of loop (if any) */
int latchNode; /* latching node of the loop */
size_t numBackEdges; /* # of back edges */
int loopHead; /* most nested loop head to which this node belongs (dfsLast) */
@@ -101,7 +101,7 @@ public:
int index; /* Index, used in several ways */
static BB * Create(void *ctx=0,const std::string &s="",Function *parent=0,BB *insertBefore=0);
static BB * CreateIntervalBB(Function *parent);
static BB * Create(const rCODE &r, uint8_t _nodeType, Function *parent);
static BB * Create(const rCODE &r, eBBKind _nodeType, Function *parent);
void writeCode(int indLevel, Function *pProc, int *numLoc, int latchNode, int ifFollow);
void mergeFallThrough(CIcodeRec &Icode);
void dfsNumbering(std::vector<BB *> &dfsLast, int *first, int *last);

View File

@@ -17,5 +17,6 @@ struct PROG /* Loaded program image parameters */
int cbImage; /* Length of image in bytes */
const uint8_t *image() const {return Imagez;}
uint8_t * Imagez; /* Allocated by loader to hold entire program image */
int addressingMode;
};

31
include/CallConvention.h Normal file
View File

@@ -0,0 +1,31 @@
#pragma once
#include "ast.h"
struct CConv {
enum Type {
UNKNOWN=0,
C,
PASCAL
};
virtual void processHLI(Function *func, Expr *_exp, iICODE picode)=0;
virtual void writeComments(std::ostream &)=0;
static CConv * create(Type v);
protected:
};
struct C_CallingConvention : public CConv {
virtual void processHLI(Function *func, Expr *_exp, iICODE picode);
virtual void writeComments(std::ostream &);
private:
int processCArg(Function *callee, Function *pProc, ICODE *picode, size_t numArgs);
};
struct Pascal_CallingConvention : public CConv {
virtual void processHLI(Function *func, Expr *_exp, iICODE picode);
virtual void writeComments(std::ostream &);
};
struct Unknown_CallingConvention : public CConv {
void processHLI(Function *func, Expr *_exp, iICODE picode) {}
virtual void writeComments(std::ostream &);
};

View File

@@ -1,12 +1,14 @@
#pragma once
#include <llvm/ADT/ilist.h>
#include <llvm/ADT/ilist_node.h>
//#include <llvm/ADT/ilist_node.h>
#include <bitset>
#include <map>
#include "BasicBlock.h"
#include "locident.h"
#include "state.h"
#include "icode.h"
#include "StackFrame.h"
#include "CallConvention.h"
/* PROCEDURE NODE */
struct CALL_GRAPH;
struct Expr;
@@ -15,9 +17,7 @@ struct Function;
struct CALL_GRAPH;
struct PROG;
typedef llvm::iplist<Function> FunctionListType;
typedef FunctionListType lFunction;
typedef lFunction::iterator ilFunction;
struct Function;
namespace llvm
{
@@ -49,9 +49,9 @@ enum PROC_FLAGS
PROC_IJMP =0x00000200,/* Proc incomplete due to indirect jmp */
PROC_ICALL =0x00000400, /* Proc incomplete due to indirect call */
PROC_HLL =0x00001000, /* Proc is likely to be from a HLL */
CALL_PASCAL =0x00002000, /* Proc uses Pascal calling convention */
CALL_C =0x00004000, /* Proc uses C calling convention */
CALL_UNKNOWN=0x00008000, /* Proc uses unknown calling convention */
// CALL_PASCAL =0x00002000, /* Proc uses Pascal calling convention */
// CALL_C =0x00004000, /* Proc uses C calling convention */
// CALL_UNKNOWN=0x00008000, /* Proc uses unknown calling convention */
PROC_NEAR =0x00010000, /* Proc exits with near return */
PROC_FAR =0x00020000, /* Proc exits with far return */
GRAPH_IRRED =0x00100000, /* Proc generates an irreducible graph */
@@ -59,18 +59,18 @@ enum PROC_FLAGS
DI_REGVAR =0x00400000, /* DI is used as a stack variable */
PROC_IS_FUNC=0x00800000, /* Proc is a function */
REG_ARGS =0x01000000, /* Proc has registers as arguments */
PROC_VARARG =0x02000000, /* Proc has variable arguments */
// PROC_VARARG =0x02000000, /* Proc has variable arguments */
PROC_OUTPUT =0x04000000, /* C for this proc has been output */
PROC_RUNTIME=0x08000000, /* Proc is part of the runtime support */
PROC_ISLIB =0x10000000, /* Proc is a library function */
PROC_ASM =0x20000000, /* Proc is an intrinsic assembler routine */
PROC_IS_HLL =0x40000000 /* Proc has HLL prolog code */
#define CALL_MASK 0xFFFF9FFF /* Masks off CALL_C and CALL_PASCAL */
//#define CALL_MASK 0xFFFF9FFF /* Masks off CALL_C and CALL_PASCAL */
};
struct FunctionType
{
bool m_vararg;
bool m_vararg=false;
bool isVarArg() const {return m_vararg;}
};
struct Assignment
@@ -113,16 +113,24 @@ struct Function : public llvm::ilist_node<Function>
// BasicBlock iterators...
typedef BasicBlockListType::iterator iterator;
typedef BasicBlockListType::const_iterator const_iterator;
private:
protected:
BasicBlockListType BasicBlocks; ///< The basic blocks
Function(FunctionType */*ty*/) : procEntry(0),depth(0),flg(0),cbParam(0),m_dfsLast(0),numBBs(0),
hasCase(false),liveAnal(0)
{
type = new FunctionType;
callingConv(CConv::UNKNOWN);
}
public:
FunctionType * type;
CConv * m_call_conv;
uint32_t procEntry; /* label number */
std::string name; /* Meaningful name for this proc */
STATE state; /* Entry state */
int depth; /* Depth at which we found it - for printing */
uint32_t flg; /* Combination of Icode & Proc flags */
int16_t cbParam; /* Probable no. of bytes of parameters */
uint32_t flg; /* Combination of Icode & Proc flags */
int16_t cbParam; /* Probable no. of bytes of parameters */
STKFRAME args; /* Array of arguments */
LOCAL_ID localId; /* Local identifiers */
ID retVal; /* Return value - identifier */
@@ -130,10 +138,8 @@ public:
/* Icodes and control flow graph */
CIcodeRec Icode; /* Object with ICODE records */
FunctionCfg m_actual_cfg;
std::list<BB*> m_cfg; /* Ptr. to BB list/CFG */
std::vector<BB*> m_dfsLast;
std::list<BB*> heldBBs;
//BB * *dfsLast; /* Array of pointers to BBs in dfsLast
std::map<int,BB*> m_ip_to_bb;
// * (reverse postorder) order */
size_t numBBs; /* Number of BBs in the graph cfg */
bool hasCase; /* Procedure has a case node */
@@ -143,18 +149,23 @@ public:
LivenessSet liveOut; /* Registers that may be used in successors */
bool liveAnal; /* Procedure has been analysed already */
Function(void */*ty*/=0) : procEntry(0),depth(0),flg(0),cbParam(0),m_cfg(0),m_dfsLast(0),numBBs(0),
hasCase(false),liveAnal(0)//,next(0),prev(0)
{
virtual ~Function() {
delete type;
}
public:
static Function *Create(void *ty=0,int /*Linkage*/=0,const std::string &nm="",void */*module*/=0)
static Function *Create(FunctionType *ty=0,int /*Linkage*/=0,const std::string &nm="",void */*module*/=0)
{
Function *r=new Function(ty);
r->name = nm;
return r;
}
bool anyFlagsSet(uint32_t t) { return (flg&t)!=0;}
FunctionType *getFunctionType() const {
return type;
}
CConv *callingConv() const { return m_call_conv;}
void callingConv(CConv::Type v);
// bool anyFlagsSet(uint32_t t) { return (flg&t)!=0;}
bool hasRegArgs() const { return (flg & REG_ARGS)!=0;}
bool isLibrary() const { return (flg & PROC_ISLIB)!=0;}
void compoundCond();
@@ -172,7 +183,7 @@ public:
void FollowCtrl(CALL_GRAPH *pcallGraph, STATE *pstate);
void process_operands(ICODE &pIcode, STATE *pstate);
bool process_JMP(ICODE &pIcode, STATE *pstate, CALL_GRAPH *pcallGraph);
boolT process_CALL(ICODE &pIcode, CALL_GRAPH *pcallGraph, STATE *pstate);
bool process_CALL(ICODE &pIcode, CALL_GRAPH *pcallGraph, STATE *pstate);
void freeCFG();
void codeGen(std::ostream &fs);
void mergeFallThrough(BB *pBB);
@@ -191,6 +202,8 @@ public:
Expr * adjustActArgType(Expr *_exp, hlType forType);
std::string writeCall(Function *tproc, STKFRAME &args, int *numLoc);
void processDosInt(STATE *pstate, PROG &prog, bool done);
ICODE *translate_DIV(LLInst *ll, ICODE &_Icode);
ICODE *translate_XCHG(LLInst *ll, ICODE &_Icode);
protected:
void extractJumpTableRange(ICODE& pIcode, STATE *pstate, JumpTable &table);
bool followAllTableEntries(JumpTable &table, uint32_t cs, ICODE &pIcode, CALL_GRAPH *pcallGraph, STATE *pstate);
@@ -218,6 +231,28 @@ protected:
void findIdioms();
void propLong();
void genLiveKtes();
uint8_t findDerivedSeq (derSeq &derivedGi);
bool findDerivedSeq(derSeq &derivedGi);
bool nextOrderGraph(derSeq &derivedGi);
};
namespace llvm {
template<> struct ilist_traits<typename ::Function>
: public ilist_default_traits<typename ::Function> {
// createSentinel is used to get hold of the node that marks the end of the
// list... (same trick used here as in ilist_traits<Instruction>)
typename ::Function *createSentinel() const {
return static_cast<typename ::Function*>(&Sentinel);
}
static void destroySentinel(typename ::Function*) {}
typename ::Function *provideInitialHead() const { return createSentinel(); }
typename ::Function *ensureHead(::Function*) const { return createSentinel(); }
static void noteHead(typename ::Function*, typename ::Function*) {}
private:
mutable ilist_node<typename ::Function> Sentinel;
};
}
typedef llvm::iplist<Function> FunctionListType;
typedef FunctionListType lFunction;
typedef lFunction::iterator ilFunction;

View File

@@ -51,7 +51,8 @@ public:
{
}
virtual ~Expr();
/** Recursively deallocates the abstract syntax tree rooted at *exp */
virtual ~Expr() {}
public:
virtual std::string walkCondExpr (Function * pProc, int* numLoc) const=0;
virtual Expr *inverse() const=0; // return new COND_EXPR that is invarse of this
@@ -122,6 +123,7 @@ struct BinaryOperator : public Expr
assert(m_lhs!=m_rhs || m_lhs==nullptr);
delete m_lhs;
delete m_rhs;
m_lhs=m_rhs=nullptr;
}
static BinaryOperator *Create(condOp o,Expr *l,Expr *r)
{
@@ -132,21 +134,28 @@ struct BinaryOperator : public Expr
}
static BinaryOperator *LogicAnd(Expr *l,Expr *r)
{
return new BinaryOperator(DBL_AND,l,r);
return Create(DBL_AND,l,r);
}
static BinaryOperator *createSHL(Expr *l,Expr *r)
{
return Create(SHL,l,r);
}
static BinaryOperator *And(Expr *l,Expr *r)
{
return new BinaryOperator(AND,l,r);
return Create(AND,l,r);
}
static BinaryOperator *Or(Expr *l,Expr *r)
{
return new BinaryOperator(OR,l,r);
return Create(OR,l,r);
}
static BinaryOperator *LogicOr(Expr *l,Expr *r)
{
return new BinaryOperator(DBL_OR,l,r);
return Create(DBL_OR,l,r);
}
static BinaryOperator *CreateAdd(Expr *l,Expr *r) {
return Create(ADD,l,r);
}
static BinaryOperator *CreateAdd(Expr *l,Expr *r);
void changeBoolOp(condOp newOp);
virtual Expr *inverse() const;
virtual Expr *clone() const;
@@ -281,20 +290,22 @@ struct FuncNode : public AstIdent
};
struct RegisterNode : public AstIdent
{
const LOCAL_ID *m_syms;
regType regiType; /* for REGISTER only */
int regiIdx; /* index into localId, REGISTER */
virtual Expr *insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *locsym);
RegisterNode(int idx, regType reg_type)
RegisterNode(int idx, regType reg_type,const LOCAL_ID *syms)
{
m_syms= syms;
ident.type(REGISTER);
regiType = reg_type;
regiIdx = idx;
}
RegisterNode(const LLOperand &, LOCAL_ID *locsym);
RegisterNode(eReg regi, uint32_t icodeFlg, LOCAL_ID *locsym);
//RegisterNode(eReg regi, uint32_t icodeFlg, LOCAL_ID *locsym);
virtual Expr *clone() const
{
return new RegisterNode(*this);

View File

@@ -101,8 +101,6 @@ void SetupLibCheck(void); /* chklib.c */
void CleanupLibCheck(void); /* chklib.c */
bool LibCheck(Function &p); /* chklib.c */
/* Exported functions from procs.c */
boolT insertCallGraph (CALL_GRAPH *, ilFunction, ilFunction);
/* Exported functions from hlicode.c */
const char *writeJcond(const HLTYPE &, Function *, int *);

View File

@@ -68,32 +68,24 @@ typedef std::list<BB *> queue;
struct interval
{
uint8_t numInt; /* # of the interval */
uint8_t numOutEdges; /* Number of out edges */
uint8_t numInt=0; /* # of the interval */
uint8_t numOutEdges=0; /* Number of out edges */
queue nodes; /* Nodes of the interval*/
queue::iterator currNode; /* Current node */
interval *next; /* Next interval */
BB *firstOfInt();
interval()
{
numInt=numOutEdges=0;
currNode=nodes.end();
next=0;
}
void appendNodeInt(queue &pqH, BB *node);
interval * next=0; /* Next interval */
BB * firstOfInt();
interval() : currNode(nodes.end()){
}
void appendNodeInt(queue &pqH, BB *node);
};
/* Derived Sequence structure */
struct derSeq_Entry
{
BB * Gi; /* Graph pointer */
BB * Gi=nullptr; /* Graph pointer */
std::list<interval *> m_intervals;
interval * Ii; /* Interval list of Gi */
derSeq_Entry() : Gi(0),Ii(0)
{
}
interval * Ii=nullptr; /* Interval list of Gi */
~derSeq_Entry();
public:
void findIntervals(Function *c);

View File

@@ -18,6 +18,7 @@
#include "libdis.h"
#include "Enums.h"
#include "state.h" // State depends on INDEXBASE, but later need STATE
#include "CallConvention.h"
//enum condId;
@@ -307,7 +308,7 @@ struct LLOperand
{
return not (*this == LLOperand());
}
void addProcInformation(int param_count,uint32_t call_conv);
void addProcInformation(int param_count, CConv::Type call_conv);
bool isImmediate() const { return immed;}
void setImmediate(bool x) { immed=x;}
bool compound() const {return is_compound;} // dx:ax pair

View File

@@ -101,7 +101,7 @@ public:
char macro[10]; /* Macro for this identifier */
std::string name; /* Identifier's name */
union ID_UNION { /* Different types of identifiers */
friend class ID;
friend struct ID;
protected:
LONG_STKID_TYPE longStkId; /* For TYPE_LONG_(UN)SIGN on the stack */
public:
@@ -118,27 +118,27 @@ public:
} longKte;
ID_UNION() { /*new (&longStkId) LONG_STKID_TYPE();*/}
} id;
LONGID_TYPE &longId() {assert(isLong() && loc==REG_FRAME); return m_longId;}
const LONGID_TYPE &longId() const {assert(isLong() && loc==REG_FRAME); return m_longId;}
LONG_STKID_TYPE &longStkId() {assert(isLong() && loc==STK_FRAME); return id.longStkId;}
const LONG_STKID_TYPE &longStkId() const {assert(isLong() && loc==STK_FRAME); return id.longStkId;}
ID();
ID(hlType t, frameType f);
ID(hlType t, const LONGID_TYPE &s);
ID(hlType t, const LONG_STKID_TYPE &s);
ID(hlType t, const LONGGLB_TYPE &s);
bool isSigned() const { return (type==TYPE_BYTE_SIGN)||(type==TYPE_WORD_SIGN)||(type==TYPE_LONG_SIGN);}
uint16_t typeBitsize() const
{
return TypeContainer::typeSize(type)*8;
}
bool isLong() const { return (type==TYPE_LONG_UNSIGN)||(type==TYPE_LONG_SIGN); }
void setLocalName(int i)
{
char buf[32];
sprintf (buf, "loc%d", i);
name=buf;
}
LONGID_TYPE & longId() {assert(isLong() && loc==REG_FRAME); return m_longId;}
const LONGID_TYPE & longId() const {assert(isLong() && loc==REG_FRAME); return m_longId;}
LONG_STKID_TYPE & longStkId() {assert(isLong() && loc==STK_FRAME); return id.longStkId;}
const LONG_STKID_TYPE & longStkId() const {assert(isLong() && loc==STK_FRAME); return id.longStkId;}
ID();
ID(hlType t, frameType f);
ID(hlType t, const LONGID_TYPE &s);
ID(hlType t, const LONG_STKID_TYPE &s);
ID(hlType t, const LONGGLB_TYPE &s);
bool isSigned() const { return (type==TYPE_BYTE_SIGN)||(type==TYPE_WORD_SIGN)||(type==TYPE_LONG_SIGN);}
uint16_t typeBitsize() const
{
return TypeContainer::typeSize(type)*8;
}
bool isLong() const { return (type==TYPE_LONG_UNSIGN)||(type==TYPE_LONG_SIGN); }
void setLocalName(int i)
{
char buf[32];
sprintf (buf, "loc%d", i);
name=buf;
}
};
struct LOCAL_ID

View File

@@ -46,7 +46,7 @@ public:
const std::string &binary_path() const {return m_fname;}
ilFunction funcIter(Function *to_find);
ilFunction findByEntry(uint32_t entry);
ilFunction createFunction();
ilFunction createFunction(FunctionType *f,const std::string &name);
bool valid(ilFunction iter);
int getSymIdxByAdd(uint32_t adr);

View File

@@ -112,6 +112,6 @@ constexpr int NUM_TABLE_TYPES = int(Comment)+1; /* Number of entries: must be la
void createSymTables(void);
void destroySymTables(void);
boolT readVal (std::ostringstream &symName, uint32_t symOff, Function *symProc);
bool readVal (std::ostringstream &symName, uint32_t symOff, Function *symProc);
void selectTable(tableType); /* Select a particular table */

View File

@@ -12,10 +12,6 @@
#define MAX 0x7FFFFFFF
/* Type definitions used in the program */
typedef unsigned char byte; /* 8 bits */
typedef unsigned short word;/* 16 bits */
typedef short int16; /* 16 bits */
typedef unsigned char boolT; /* 8 bits */
#define SYNTHESIZED_MIN 0x100000 /* Synthesized labs use bits 21..32 */
@@ -29,12 +25,12 @@ typedef unsigned char boolT; /* 8 bits */
// Macro reads a LH word from the image regardless of host convention
// Returns a 16 bit quantity, e.g. C000 is read into an Int as C000
//#define LH(p) ((int16)((byte *)(p))[0] + ((int16)((byte *)(p))[1] << 8))
#define LH(p) ((word)((byte *)(p))[0] + ((word)((byte *)(p))[1] << 8))
#define LH(p) ((uint16_t)((uint8_t *)(p))[0] + ((uint16_t)((uint8_t *)(p))[1] << 8))
/* Macro reads a LH word from the image regardless of host convention */
/* Returns a signed quantity, e.g. C000 is read into an Int as FFFFC000 */
#define LH_SIGNED(p) (((byte *)(p))[0] + (((char *)(p))[1] << 8))
#define LH_SIGNED(p) (((uint8_t *)(p))[0] + (((char *)(p))[1] << 8))
/* Macro tests bit b for type t in prog.map */
#define BITMAP(b, t) (prog.map[(b) >> 2] & ((t) << (((b) & 3) << 1)))