Split COND_EXPR into Unary/Binary/AstIdent subclasses

This commit is contained in:
Artur K
2012-07-16 19:31:29 +02:00
parent ca129c5177
commit c1eb8df114
27 changed files with 1165 additions and 1077 deletions

View File

@@ -31,19 +31,19 @@ enum condOp
GREATER_EQUAL, /* >= */
/* For general expressions */
AND, /* & */
OR, /* | */
XOR, /* ^ */
NOT, /* ~ */ /* 1's complement */
ADD, /* + */
SUB, /* - */
MUL, /* * */
DIV, /* / */
SHR, /* >> */
SHL, /* << */
MOD, /* % */
DBL_AND, /* && */
DBL_OR, /* || */
DUMMY /* */
OR, /* | */
XOR, /* ^ */
NOT, /* ~ */ /* 1's complement */
ADD, /* + */
SUB, /* - */
MUL, /* * */
DIV, /* / */
SHR, /* >> */
SHL, /* << */
MOD, /* % */
DBL_AND, /* && */
DBL_OR, /* || */
DUMMY /* */
};
/* LOW_LEVEL operand location: source or destination */
enum opLoc
@@ -216,6 +216,7 @@ enum condNodeType
{
UNKNOWN_OP=0,
BOOLEAN_OP, /* condOps */
NEGATION, /* not (2's complement) */
ADDRESSOF, /* addressOf (&) */
DEREFERENCE, /* contents of (*) */

View File

@@ -20,9 +20,9 @@ static const int operandSize=20;
*/
/* High-level BOOLEAN conditions for iJB..iJNS icodes */
static const condOp condOpJCond[12] = {LESS, LESS_EQUAL, GREATER_EQUAL, GREATER,
EQUAL, NOT_EQUAL, LESS, GREATER_EQUAL,
LESS_EQUAL, GREATER, GREATER_EQUAL, LESS};
EQUAL, NOT_EQUAL, LESS, GREATER_EQUAL,
LESS_EQUAL, GREATER, GREATER_EQUAL, LESS};
struct AstIdent;
struct Function;
struct STKFRAME;
struct LOCAL_ID;
@@ -36,142 +36,185 @@ typedef boost::iterator_range<iICODE> rICODE;
/* Expression data type */
struct COND_EXPR
{
protected:
struct /* for BOOLEAN_OP */
{
condOp op;
COND_EXPR *lhs;
COND_EXPR *rhs;
} boolExpr;
public:
condNodeType m_type; /* Conditional Expression Node Type */
union _exprNode { /* Different cond expr nodes */
COND_EXPR *unaryExp; /* for NEGATION,ADDRESSOF,DEREFERENCE*/
IDENTTYPE ident; /* for IDENTIFIER */
} expr;
COND_EXPR *lhs()
{
assert(m_type==BOOLEAN_OP);
return boolExpr.lhs;
}
const COND_EXPR *lhs() const
{
assert(m_type==BOOLEAN_OP);
return boolExpr.lhs;
}
COND_EXPR *rhs()
{
assert(m_type==BOOLEAN_OP);
return boolExpr.rhs;
}
const COND_EXPR *rhs() const
{
assert(m_type==BOOLEAN_OP);
return boolExpr.rhs;
}
condOp op() const { return boolExpr.op;}
public:
static COND_EXPR * idRegIdx(int idx, regType reg_type);
static COND_EXPR * idKte(uint32_t kte, uint8_t size);
static COND_EXPR * idLoc(int off, LOCAL_ID *localId);
static COND_EXPR * idReg(eReg regi, uint32_t icodeFlg, LOCAL_ID *locsym);
static COND_EXPR * idLongIdx(int idx);
static COND_EXPR * idOther(eReg seg, eReg regi, int16_t off);
static COND_EXPR * idParam(int off, const STKFRAME *argSymtab);
static COND_EXPR * unary(condNodeType t, COND_EXPR *sub_expr);
static COND_EXPR * idLong(LOCAL_ID *localId, opLoc sd, iICODE pIcode, hlFirst f, iICODE ix, operDu du, LLInst &atOffset);
static COND_EXPR * idFunc(Function *pproc, STKFRAME *args);
static COND_EXPR * idID(const ID *retVal, LOCAL_ID *locsym, iICODE ix_);
static COND_EXPR * id(const LLInst &ll_insn, opLoc sd, Function *pProc, iICODE ix_, ICODE &duIcode, operDu du);
static COND_EXPR * boolOp(COND_EXPR *_lhs, COND_EXPR *_rhs, condOp _op);
static bool insertSubTreeLongReg(COND_EXPR *exp, COND_EXPR **tree, int longIdx);
static bool insertSubTreeLongReg(COND_EXPR *exp, COND_EXPR *&tree, int longIdx);
static bool insertSubTreeReg(COND_EXPR *&tree, COND_EXPR *_expr, eReg regi, const LOCAL_ID *locsym);
static bool insertSubTreeReg(AstIdent *&tree, COND_EXPR *_expr, eReg regi, const LOCAL_ID *locsym);
public:
virtual COND_EXPR *clone() const;
void release();
void changeBoolOp(condOp newOp);
COND_EXPR(const COND_EXPR &other)
{
m_type=other.m_type;
expr=other.expr;
boolExpr=other.boolExpr;
}
COND_EXPR(condNodeType t=UNKNOWN_OP) : m_type(t)
{
memset(&expr,0,sizeof(_exprNode));
memset(&boolExpr,0,sizeof(boolExpr));
}
virtual ~COND_EXPR() {}
virtual ~COND_EXPR();
public:
virtual COND_EXPR *inverse() const; // return new COND_EXPR that is invarse of this
virtual bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locId);
virtual COND_EXPR *insertSubTreeReg(COND_EXPR *_expr, eReg regi, const LOCAL_ID *locsym);
virtual COND_EXPR *insertSubTreeLongReg(COND_EXPR *_expr, int longIdx);
virtual std::string walkCondExpr (Function * pProc, int* numLoc) const=0;
virtual COND_EXPR *inverse() const=0; // return new COND_EXPR that is invarse of this
virtual bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locId)=0;
virtual COND_EXPR *insertSubTreeReg(COND_EXPR *_expr, eReg regi, const LOCAL_ID *locsym)=0;
virtual COND_EXPR *insertSubTreeLongReg(COND_EXPR *_expr, int longIdx)=0;
virtual hlType expType(Function *pproc) const;
virtual int hlTypeSize(Function *pproc) const=0;
virtual void performLongRemoval(eReg regi, LOCAL_ID *locId) {}
};
struct UnaryOperator : public COND_EXPR
{
UnaryOperator(condNodeType t=UNKNOWN_OP) : COND_EXPR(t),unaryExp(nullptr) {}
COND_EXPR *unaryExp;
virtual COND_EXPR *inverse() const
{
if (m_type == NEGATION) //TODO: memleak here
{
return unaryExp->clone();
}
return this->clone();
}
virtual COND_EXPR *clone() const
{
UnaryOperator *newExp = new UnaryOperator(*this);
newExp->unaryExp = unaryExp->clone();
return newExp;
}
virtual bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locs);
static UnaryOperator *Create(condNodeType t, COND_EXPR *sub_expr)
{
UnaryOperator *newExp = new UnaryOperator();
newExp->m_type = t;
newExp->unaryExp = sub_expr;
return (newExp);
}
~UnaryOperator()
{
delete unaryExp;
unaryExp=nullptr;
}
public:
int hlTypeSize(Function *pproc) const;
virtual std::string walkCondExpr(Function *pProc, int *numLoc) const;
virtual COND_EXPR *insertSubTreeReg(COND_EXPR *_expr, eReg regi, const LOCAL_ID *locsym);
virtual hlType expType(Function *pproc) const;
virtual COND_EXPR *insertSubTreeLongReg(COND_EXPR *_expr, int longIdx);
};
struct BinaryOperator : public COND_EXPR
{
condOp m_op;
COND_EXPR *m_lhs;
COND_EXPR *m_rhs;
BinaryOperator(condOp o)
BinaryOperator(condOp o) : COND_EXPR(BOOLEAN_OP)
{
m_op = o;
m_lhs=m_rhs=nullptr;
}
static BinaryOperator *Create(condOp o,COND_EXPR *l,COND_EXPR *r);
BinaryOperator(condOp o,COND_EXPR *l,COND_EXPR *r) : COND_EXPR(BOOLEAN_OP)
{
m_op = o;
m_lhs=l;
m_rhs=r;
}
~BinaryOperator()
{
assert(m_lhs!=m_rhs || m_lhs==nullptr);
delete m_lhs;
delete m_rhs;
}
static BinaryOperator *Create(condOp o,COND_EXPR *l,COND_EXPR *r)
{
BinaryOperator *res = new BinaryOperator(o);
res->m_lhs = l;
res->m_rhs = r;
return res;
}
static BinaryOperator *LogicAnd(COND_EXPR *l,COND_EXPR *r)
{
return new BinaryOperator(DBL_AND,l,r);
}
static BinaryOperator *And(COND_EXPR *l,COND_EXPR *r)
{
return new BinaryOperator(AND,l,r);
}
static BinaryOperator *Or(COND_EXPR *l,COND_EXPR *r)
{
return new BinaryOperator(OR,l,r);
}
static BinaryOperator *LogicOr(COND_EXPR *l,COND_EXPR *r)
{
return new BinaryOperator(DBL_OR,l,r);
}
static BinaryOperator *CreateAdd(COND_EXPR *l,COND_EXPR *r);
void changeBoolOp(condOp newOp);
virtual COND_EXPR *inverse() const;
virtual COND_EXPR *clone() const;
virtual bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locs);
virtual COND_EXPR *insertSubTreeReg(COND_EXPR *_expr, eReg regi, const LOCAL_ID *locsym);
virtual COND_EXPR *insertSubTreeLongReg(COND_EXPR *_expr, int longIdx);
const COND_EXPR *lhs() const
{
return const_cast<const COND_EXPR *>(const_cast<BinaryOperator *>(this)->lhs());
}
const COND_EXPR *rhs() const
{
return const_cast<const COND_EXPR *>(const_cast<BinaryOperator *>(this)->rhs());
}
COND_EXPR *lhs()
{
assert(m_type==BOOLEAN_OP);
return m_lhs;
}
const COND_EXPR *lhs() const
{
assert(m_type==BOOLEAN_OP);
return m_lhs;
}
COND_EXPR *rhs()
{
assert(m_type==BOOLEAN_OP);
return m_rhs;
}
const COND_EXPR *rhs() const
{
assert(m_type==BOOLEAN_OP);
return m_rhs;
}
condOp op() const { return m_op;}
/* Changes the boolean conditional operator at the root of this expression */
void op(condOp o) { m_op=o;}
std::string walkCondExpr (Function * pProc, int* numLoc) const;
public:
hlType expType(Function *pproc) const;
int hlTypeSize(Function *pproc) const;
};
struct UnaryOperator : public COND_EXPR
struct AstIdent : public UnaryOperator
{
condOp op;
COND_EXPR *unaryExp;
virtual COND_EXPR *inverse() const;
virtual COND_EXPR *clone() const;
virtual bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locs);
static UnaryOperator *Create(condNodeType t, COND_EXPR *sub_expr)
AstIdent() : UnaryOperator(IDENTIFIER)
{
UnaryOperator *newExp = new UnaryOperator();
newExp->m_type=t;
newExp->unaryExp = sub_expr;
return (newExp);
memset(&ident,0,sizeof(ident));
}
};
virtual COND_EXPR *clone() const
{
return new AstIdent(*this);
}
IDENTTYPE ident; /* for IDENTIFIER */
static AstIdent * RegIdx(int idx, regType reg_type);
static AstIdent * Kte(uint32_t kte, uint8_t size);
static AstIdent * Loc(int off, LOCAL_ID *localId);
static AstIdent * Reg(eReg regi, uint32_t icodeFlg, LOCAL_ID *locsym);
static AstIdent * LongIdx(int idx);
static AstIdent * Other(eReg seg, eReg regi, int16_t off);
static AstIdent * idParam(int off, const STKFRAME *argSymtab);
static AstIdent * idLong(LOCAL_ID *localId, opLoc sd, iICODE pIcode, hlFirst f, iICODE ix, operDu du, LLInst &atOffset);
static AstIdent * idFunc(Function *pproc, STKFRAME *args);
static AstIdent * idID(const ID *retVal, LOCAL_ID *locsym, iICODE ix_);
static COND_EXPR * id(const LLInst &ll_insn, opLoc sd, Function *pProc, iICODE ix_, ICODE &duIcode, operDu du);
struct GlobalVariable : public COND_EXPR
virtual int hlTypeSize(Function *pproc) const;
virtual hlType expType(Function *pproc) const;
virtual void performLongRemoval(eReg regi, LOCAL_ID *locId);
virtual std::string walkCondExpr(Function *pProc, int *numLoc) const;
virtual COND_EXPR *insertSubTreeReg(COND_EXPR *_expr, eReg regi, const LOCAL_ID *locsym);
virtual COND_EXPR *insertSubTreeLongReg(COND_EXPR *_expr, int longIdx);
virtual bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locId);
protected:
eReg otherLongRegi (eReg regi, int idx, LOCAL_ID *locTbl);
};
struct GlobalVariable : public AstIdent
{
static COND_EXPR *Create(int16_t segValue, int16_t off);
static AstIdent *Create(int16_t segValue, int16_t off);
};
struct Constant : public COND_EXPR
{};

View File

@@ -128,12 +128,6 @@ bool LibCheck(Function &p); /* chklib.c */
boolT insertCallGraph (CALL_GRAPH *, ilFunction, ilFunction);
void adjustActArgType (COND_EXPR *, hlType, Function *);
/* Exported functions from ast.c */
std::string walkCondExpr (const COND_EXPR *exp, Function * pProc, int *);
int hlTypeSize (const COND_EXPR *, Function *);
//hlType expType (const COND_EXPR *, Function *);
/* Exported functions from hlicode.c */
std::string writeCall (Function *, STKFRAME &, Function *, int *);
char *writeJcond (const HLTYPE &, Function *, int *);

View File

@@ -84,11 +84,12 @@ struct DU
struct COND_EXPR;
struct AstIdent;
struct HlTypeSupport
{
//hlIcode opcode; /* hlIcode opcode */
virtual bool removeRegFromLong(eReg regi, LOCAL_ID *locId)=0;
virtual std::string writeOut(Function *pProc, int *numLoc)=0;
virtual std::string writeOut(Function *pProc, int *numLoc) const=0;
protected:
void performLongRemoval (eReg regi, LOCAL_ID *locId, COND_EXPR *tree);
};
@@ -108,7 +109,7 @@ public:
printf("CallType : removeRegFromLong not supproted");
return false;
}
std::string writeOut(Function *pProc, int *numLoc);
std::string writeOut(Function *pProc, int *numLoc) const;
};
struct AssignType : public HlTypeSupport
{
@@ -116,12 +117,8 @@ struct AssignType : public HlTypeSupport
COND_EXPR *lhs;
COND_EXPR *rhs;
AssignType() : lhs(0),rhs(0) {}
bool removeRegFromLong(eReg regi, LOCAL_ID *locId)
{
performLongRemoval(regi,locId,lhs);
return true;
}
std::string writeOut(Function *pProc, int *numLoc);
bool removeRegFromLong(eReg regi, LOCAL_ID *locId);
std::string writeOut(Function *pProc, int *numLoc) const;
};
struct ExpType : public HlTypeSupport
{
@@ -133,7 +130,7 @@ struct ExpType : public HlTypeSupport
performLongRemoval(regi,locId,v);
return true;
}
std::string writeOut(Function *pProc, int *numLoc);
std::string writeOut(Function *pProc, int *numLoc) const;
};
struct HLTYPE
@@ -145,6 +142,10 @@ public:
AssignType asgn;
CallType call;
HlTypeSupport *get();
const HlTypeSupport *get() const
{
return const_cast<const HlTypeSupport *>(const_cast<HLTYPE*>(this)->get());
}
void expr(COND_EXPR *e)
{
@@ -162,27 +163,22 @@ public:
opcode=i;
exp.v=e;
}
void set(COND_EXPR *l,COND_EXPR *r)
{
assert(l);
assert(r);
opcode = HLI_ASSIGN;
assert((asgn.lhs==0) and (asgn.rhs==0)); //prevent memory leaks
asgn.lhs=l;
asgn.rhs=r;
}
void set(COND_EXPR *l,COND_EXPR *r);
void setCall(Function *proc);
HLTYPE(hlIcode op=HLI_INVALID) : opcode(op)
{}
// HLTYPE() // help valgrind find uninitialized HLTYPES
// {}
HLTYPE & operator=(const HLTYPE &l)
{
exp=l.exp;
opcode=l.opcode;
asgn=l.asgn;
call=l.call;
exp = l.exp;
opcode = l.opcode;
asgn = l.asgn;
call = l.call;
return *this;
}
public:
std::string write1HlIcode(Function *pProc, int *numLoc);
std::string write1HlIcode(Function *pProc, int *numLoc) const;
void setAsgn(COND_EXPR *lhs, COND_EXPR *rhs);
} ;
/* LOW_LEVEL icode operand record */
@@ -210,7 +206,7 @@ struct LLOperand
{
opz=dw;
}
eReg getReg2() {return regi;}
eReg getReg2() const {return regi;}
bool isReg() const;
static LLOperand CreateImm2(int64_t Val)
{
@@ -312,7 +308,7 @@ public:
void flops(std::ostringstream &out);
bool isJmpInst();
HLTYPE toHighLevel(COND_EXPR *lhs, COND_EXPR *rhs, Function *func);
//HLTYPE toHighLevel(COND_EXPR *lhs, COND_EXPR *rhs, Function *func);
HLTYPE createCall();
LLInst(ICODE *container) : flg(0),codeIdx(0),numBytes(0),m_link(container)
{
@@ -450,8 +446,16 @@ public:
LLInst * ll() { return &m_ll;}
const LLInst * ll() const { return &m_ll;}
HLTYPE * hl() { return &m_hl;}
const HLTYPE * hl() const { return &m_hl;}
HLTYPE * hlU() {
// assert(type==HIGH_LEVEL);
// assert(m_hl.opcode!=HLI_INVALID);
return &m_hl;
}
const HLTYPE * hl() const {
// assert(type==HIGH_LEVEL);
// assert(m_hl.opcode!=HLI_INVALID);
return &m_hl;
}
void hl(const HLTYPE &v) { m_hl=v;}
void setRegDU(eReg regi, operDu du_in);
@@ -464,7 +468,7 @@ public:
void setAsgn(COND_EXPR *lhs, COND_EXPR *rhs)
{
type=HIGH_LEVEL;
hl()->setAsgn(lhs,rhs);
hlU()->setAsgn(lhs,rhs);
}
void setUnary(hlIcode op, COND_EXPR *_exp);
void setJCond(COND_EXPR *cexp);
@@ -478,7 +482,7 @@ public:
void checkHlCall();
bool newStkArg(COND_EXPR *exp, llIcode opcode, Function *pproc)
{
return hl()->call.newStkArg(exp,opcode,pproc);
return hlU()->call.newStkArg(exp,opcode,pproc);
}
ICODE() : m_ll(this),Parent(0),invalid(false),type(NOT_SCANNED),loc_ip(0)
{

View File

@@ -19,6 +19,7 @@
// this array has to stay in-order of addition i.e. not std::set<iICODE,std::less<iICODE> >
// TODO: why ?
struct COND_EXPR;
struct AstIdent;
struct ICODE;
struct LLInst;
typedef std::list<ICODE>::iterator iICODE;
@@ -132,7 +133,7 @@ public:
void newRegArg(iICODE picode, iICODE ticode) const;
void processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode, bool isLong) const;
void forwardSubs(COND_EXPR *lhs, COND_EXPR *rhs, iICODE picode, iICODE ticode, int &numHlIcodes) const;
COND_EXPR *createId(const ID *retVal, iICODE ix_);
AstIdent *createId(const ID *retVal, iICODE ix_);
};

View File

@@ -8,6 +8,7 @@
#include "Enums.h"
#include "types.h"
struct COND_EXPR;
struct AstIdent;
struct TypeContainer;
/* * * * * * * * * * * * * * * * * */
/* Symbol table structs and protos */
@@ -36,7 +37,7 @@ struct STKSYM : public SymbolCommon
{
typedef int16_t tLabel;
COND_EXPR *actual; /* Expression tree of actual parameter */
COND_EXPR *regs; /* For register arguments only */
AstIdent *regs; /* For register arguments only */
tLabel label; /* Immediate off from BP (+:args, -:params) */
uint8_t regOff; /* Offset is a register (e.g. SI, DI) */
bool hasMacro; /* This type needs a macro */
@@ -44,7 +45,8 @@ struct STKSYM : public SymbolCommon
bool invalid; /* Boolean: invalid entry in formal arg list*/
STKSYM()
{
actual=regs=0;
actual=0;
regs=0;
label=0;
regOff=0;
invalid=hasMacro = false;

View File

@@ -1,7 +1,9 @@
/****************************************************************************
/*
***************************************************************************
* dcc project general header
* (C) Cristina Cifuentes, Mike van Emmerik
****************************************************************************/
***************************************************************************
*/
#pragma once
#include <cassert>
#include <stdint.h>
@@ -22,10 +24,10 @@ typedef unsigned char boolT; /* 8 bits */
#define PATLEN 23 /* Length of proc patterns */
#define WILD 0xF4 /* The wild byte */
/****** MACROS *******/
/* MACROS */
/* 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 */
// 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))
@@ -53,19 +55,20 @@ struct eDuVal
USE=2,
VAL=4
};
uint8_t def :1; /* Variable was first defined than used */
uint8_t use :1; /* Variable was first used than defined */
uint8_t def :1; //!< Variable was first defined than used
uint8_t use :1; //!< Variable was first used than defined
uint8_t val :1; /* Variable has an initial value. 2 cases:
* 1. When variable is used first (ie. global)
* 2. When a value is moved into the variable
* for the first time. */
1. When variable is used first (ie. global)
2. When a value is moved into the variable
for the first time.
*/
void setFlags(uint16_t x)
{
def = x&DEF;
use = x&USE;
val = x&VAL;
}
bool isUSE_VAL() {return use&&val;} /* Use and Val */
bool isUSE_VAL() {return use&&val;} //Use and Val
};
static constexpr const char * hlTypes[13] = {
"", "char", "unsigned char", "int", "unsigned int",