From c1eb8df11418f4f5ab6844452a74aee04e1fb318 Mon Sep 17 00:00:00 2001 From: Artur K Date: Mon, 16 Jul 2012 19:31:29 +0200 Subject: [PATCH] Split COND_EXPR into Unary/Binary/AstIdent subclasses --- CMakeLists.txt | 3 +- include/Enums.h | 27 +- include/ast.h | 223 +++++--- include/dcc.h | 6 - include/icode.h | 62 ++- include/locident.h | 3 +- include/symtab.h | 6 +- include/types.h | 25 +- src/BasicBlock.cpp | 14 +- src/ast.cpp | 1024 +++++++++++++++++------------------ src/backend.cpp | 19 +- src/comwrite.cpp | 6 +- src/control.cpp | 24 +- src/dataflow.cpp | 203 +++---- src/disassem.cpp | 22 +- src/hlicode.cpp | 170 +++--- src/hltype.cpp | 1 - src/icode.cpp | 11 + src/idioms/arith_idioms.cpp | 45 +- src/idioms/mov_idioms.cpp | 15 +- src/idioms/neg_idioms.cpp | 14 +- src/idioms/shift_idioms.cpp | 38 +- src/idioms/xor_idioms.cpp | 17 +- src/locident.cpp | 20 +- src/parser.cpp | 71 +-- src/procs.cpp | 50 +- src/proplong.cpp | 123 +++-- 27 files changed, 1165 insertions(+), 1077 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7bb19c1..e0e028f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ PROJECT(dcc_original) CMAKE_MINIMUM_REQUIRED(VERSION 2.8) OPTION(dcc_build_tests "Enable unit tests." OFF) - +#SET(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}) ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS -D__UNIX__ -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS) IF(CMAKE_BUILD_TOOL MATCHES "(msdev|devenv|nmake)") ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS -D__UNIX__ -D_CRT_NONSTDC_NO_DEPRECATE) @@ -14,6 +14,7 @@ ELSE() ENDIF() SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMakeScripts;${CMAKE_MODULE_PATH}) +SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}) include(cotire) FIND_PACKAGE(LLVM) FIND_PACKAGE(Boost) diff --git a/include/Enums.h b/include/Enums.h index 2be129b..e2d3507 100644 --- a/include/Enums.h +++ b/include/Enums.h @@ -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 (*) */ diff --git a/include/ast.h b/include/ast.h index 40ef840..a96260f 100644 --- a/include/ast.h +++ b/include/ast.h @@ -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 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_cast(this)->lhs()); + } + const COND_EXPR *rhs() const + { + return const_cast(const_cast(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 {}; diff --git a/include/dcc.h b/include/dcc.h index 262f8c2..7f21d55 100644 --- a/include/dcc.h +++ b/include/dcc.h @@ -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 *); diff --git a/include/icode.h b/include/icode.h index b0e870d..ee7f88e 100644 --- a/include/icode.h +++ b/include/icode.h @@ -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_cast(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) { diff --git a/include/locident.h b/include/locident.h index 11ca625..550dbd5 100644 --- a/include/locident.h +++ b/include/locident.h @@ -19,6 +19,7 @@ // this array has to stay in-order of addition i.e. not std::set > // TODO: why ? struct COND_EXPR; +struct AstIdent; struct ICODE; struct LLInst; typedef std::list::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_); }; diff --git a/include/symtab.h b/include/symtab.h index f310351..e3b3650 100644 --- a/include/symtab.h +++ b/include/symtab.h @@ -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; diff --git a/include/types.h b/include/types.h index edad398..d81dd8d 100644 --- a/include/types.h +++ b/include/types.h @@ -1,7 +1,9 @@ -/**************************************************************************** +/* + *************************************************************************** * dcc project general header * (C) Cristina Cifuentes, Mike van Emmerik - ****************************************************************************/ + *************************************************************************** +*/ #pragma once #include #include @@ -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", diff --git a/src/BasicBlock.cpp b/src/BasicBlock.cpp index c5ebf38..659a2ad 100644 --- a/src/BasicBlock.cpp +++ b/src/BasicBlock.cpp @@ -158,10 +158,10 @@ ICODE* BB::writeLoopHeader(int &indLevel, Function* pProc, int *numLoc, BB *&lat * the THEN path of the header node */ if (edges[ELSE].BBptr->dfsLastNum == loopFollow) { - picode->hl()->replaceExpr(picode->hl()->expr()->inverse()); + picode->hlU()->replaceExpr(picode->hl()->expr()->inverse()); } { - string e=walkCondExpr (picode->hl()->expr(), pProc, numLoc); + string e=picode->hl()->expr()->walkCondExpr (pProc, numLoc); ostr << "\n"<invalidate(); @@ -262,12 +262,16 @@ void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode, cCode.appendCode( "%s} /* end of loop */\n",indentStr(indLevel)); else if (loopType == REPEAT_TYPE) { + string e = "//*failed*//"; if (picode->hl()->opcode != HLI_JCOND) - reportError (REPEAT_FAIL); { - string e=walkCondExpr (picode->hl()->expr(), pProc, numLoc); - cCode.appendCode( "%s} while (%s);\n", indentStr(indLevel),e.c_str()); + reportError (REPEAT_FAIL); } + else + { + e=picode->hl()->expr()->walkCondExpr (pProc, numLoc); + } + cCode.appendCode( "%s} while (%s);\n", indentStr(indLevel),e.c_str()); } /* Recurse on the loop follow */ diff --git a/src/ast.cpp b/src/ast.cpp index f9effd7..6231177 100644 --- a/src/ast.cpp +++ b/src/ast.cpp @@ -20,7 +20,6 @@ static const char * const condOpSym[] = { " <= ", " < ", " == ", " != ", " > ", " + ", " - ", " * ", " / ", " >> ", " << ", " % ", " && ", " || " }; - /* Local expression stack */ //typedef struct _EXP_STK { // COND_EXPR *exp; @@ -42,19 +41,19 @@ void ICODE::setRegDU (eReg regi, operDu du_in) // printf("%s %d %x\n",__FUNCTION__,regi,int(du_in)); switch (du_in) { - case eDEF: - du.def.addReg(regi); - du1.numRegsDef++; - break; - case eUSE: - du.use.addReg(regi); - break; - case USE_DEF: - du.addDefinedAndUsed(regi); - du1.numRegsDef++; - break; - case NONE: /* do nothing */ - break; + case eDEF: + du.def.addReg(regi); + du1.numRegsDef++; + break; + case eUSE: + du.use.addReg(regi); + break; + case USE_DEF: + du.addDefinedAndUsed(regi); + du1.numRegsDef++; + break; + case NONE: /* do nothing */ + break; } } @@ -64,61 +63,47 @@ void ICODE::copyDU(const ICODE &duIcode, operDu _du, operDu duDu) { switch (_du) { - case eDEF: - if (duDu == eDEF) - du.def=duIcode.du.def; - else - du.def=duIcode.du.use; - break; - case eUSE: - if (duDu == eDEF) - du.use=duIcode.du.def; - else - du.use =duIcode.du.use; - break; - case USE_DEF: - du = duIcode.du; - break; - case NONE: - assert(false); - break; + case eDEF: + if (duDu == eDEF) + du.def=duIcode.du.def; + else + du.def=duIcode.du.use; + break; + case eUSE: + if (duDu == eDEF) + du.use=duIcode.du.def; + else + du.use =duIcode.du.use; + break; + case USE_DEF: + du = duIcode.du; + break; + case NONE: + assert(false); + break; } } /* Creates a conditional boolean expression and returns it */ -COND_EXPR *COND_EXPR::boolOp(COND_EXPR *_lhs, COND_EXPR *_rhs, condOp _op) -{ - COND_EXPR *newExp; - - newExp = new COND_EXPR(BOOLEAN_OP); - newExp->boolExpr.op = _op; - newExp->boolExpr.lhs = _lhs; - newExp->boolExpr.rhs = _rhs; - return (newExp); -} +//COND_EXPR *COND_EXPR::boolOp(COND_EXPR *_lhs, COND_EXPR *_rhs, condOp _op) +//{ +// return BinaryOperator::Create(_op,_lhs,_rhs); +//} /* Returns a unary conditional expression node. This procedure should * only be used with the following conditional node types: NEGATION, * ADDRESSOF, DEREFERENCE, POST_INC, POST_DEC, PRE_INC, PRE_DEC */ -COND_EXPR *COND_EXPR::unary(condNodeType t, COND_EXPR *sub_expr) -{ - COND_EXPR *newExp; - - newExp = new COND_EXPR(t); - newExp->expr.unaryExp = sub_expr; - return (newExp); -} /* Returns an identifier conditional expression node of type GLOB_VAR */ -COND_EXPR *GlobalVariable::Create(int16_t segValue, int16_t off) +AstIdent *GlobalVariable::Create(int16_t segValue, int16_t off) { - COND_EXPR *newExp; + AstIdent *newExp; uint32_t adr; - newExp = new COND_EXPR(IDENTIFIER); - newExp->expr.ident.idType = GLOB_VAR; + newExp = new AstIdent(); + newExp->ident.idType = GLOB_VAR; adr = opAdr(segValue, off); auto i=Project::get()->getSymIdxByAdd(adr); if ( not Project::get()->validSymIdx(i) ) @@ -127,159 +112,163 @@ COND_EXPR *GlobalVariable::Create(int16_t segValue, int16_t off) delete newExp; return 0; } - newExp->expr.ident.idNode.globIdx = i; + newExp->ident.idNode.globIdx = i; return (newExp); } /* Returns an identifier conditional expression node of type REGISTER */ -COND_EXPR *COND_EXPR::idReg(eReg regi, uint32_t icodeFlg, LOCAL_ID *locsym) +AstIdent *AstIdent::Reg(eReg regi, uint32_t icodeFlg, LOCAL_ID *locsym) { - COND_EXPR *newExp; + AstIdent *newExp; - newExp = new COND_EXPR(IDENTIFIER); - newExp->expr.ident.idType = REGISTER; + newExp = new AstIdent(); + newExp->ident.idType = REGISTER; + hlType type_sel; + regType reg_type; if ((icodeFlg & B) || (icodeFlg & SRC_B)) { - newExp->expr.ident.idNode.regiIdx = locsym->newByteWordReg(TYPE_BYTE_SIGN, regi); - newExp->expr.ident.regiType = BYTE_REG; + type_sel = TYPE_BYTE_SIGN; + reg_type = BYTE_REG; } else /* uint16_t */ { - newExp->expr.ident.idNode.regiIdx = locsym->newByteWordReg( TYPE_WORD_SIGN, regi); - newExp->expr.ident.regiType = WORD_REG; + type_sel = TYPE_WORD_SIGN; + reg_type = WORD_REG; } + newExp->ident.idNode.regiIdx = locsym->newByteWordReg(type_sel, regi); + newExp->ident.regiType = reg_type; return (newExp); } /* Returns an identifier conditional expression node of type REGISTER */ -COND_EXPR *COND_EXPR::idRegIdx(int idx, regType reg_type) +AstIdent *AstIdent::RegIdx(int idx, regType reg_type) { - COND_EXPR *newExp; + AstIdent *newExp; - newExp = new COND_EXPR(IDENTIFIER); - newExp->expr.ident.idType = REGISTER; - newExp->expr.ident.regiType = reg_type; - newExp->expr.ident.idNode.regiIdx = idx; + newExp = new AstIdent(); + newExp->ident.idType = REGISTER; + newExp->ident.regiType = reg_type; + newExp->ident.idNode.regiIdx = idx; return (newExp); } /* Returns an identifier conditional expression node of type LOCAL_VAR */ -COND_EXPR *COND_EXPR::idLoc(int off, LOCAL_ID *localId) +AstIdent *AstIdent::Loc(int off, LOCAL_ID *localId) { - COND_EXPR *newExp; size_t i; + AstIdent *newExp; - newExp = new COND_EXPR(IDENTIFIER); - newExp->expr.ident.idType = LOCAL_VAR; + newExp = new AstIdent(); + newExp->ident.idType = LOCAL_VAR; for (i = 0; i < localId->csym(); i++) - if ((localId->id_arr[i].id.bwId.off == off) && - (localId->id_arr[i].id.bwId.regOff == 0)) + { + const ID &lID(localId->id_arr[i]); + if ((lID.id.bwId.off == off) && (lID.id.bwId.regOff == 0)) break; + } if (i == localId->csym()) printf ("Error, cannot find local var\n"); - newExp->expr.ident.idNode.localIdx = i; + newExp->ident.idNode.localIdx = i; localId->id_arr[i].setLocalName(i); return (newExp); } /* Returns an identifier conditional expression node of type PARAM */ -COND_EXPR *COND_EXPR::idParam(int off, const STKFRAME * argSymtab) +AstIdent *AstIdent::idParam(int off, const STKFRAME * argSymtab) { - COND_EXPR *newExp; + AstIdent *newExp; - newExp = new COND_EXPR(IDENTIFIER); - newExp->expr.ident.idType = PARAM; + newExp = new AstIdent(); + newExp->ident.idType = PARAM; auto iter=argSymtab->findByLabel(off); if (iter == argSymtab->end()) printf ("Error, cannot find argument var\n"); - newExp->expr.ident.idNode.localIdx = distance(argSymtab->begin(),iter); + newExp->ident.idNode.localIdx = distance(argSymtab->begin(),iter); return (newExp); } /* Returns an identifier conditional expression node of type GLOB_VAR_IDX. * This global variable is indexed by regi. */ -COND_EXPR *idCondExpIdxGlob (int16_t segValue, int16_t off, uint8_t regi, const LOCAL_ID *locSym) +AstIdent *idCondExpIdxGlob (int16_t segValue, int16_t off, uint8_t regi, const LOCAL_ID *locSym) { - COND_EXPR *newExp; size_t i; - - newExp = new COND_EXPR(IDENTIFIER); - newExp->expr.ident.idType = GLOB_VAR_IDX; + AstIdent *newExp = new AstIdent(); + newExp->ident.idType = GLOB_VAR_IDX; for (i = 0; i < locSym->csym(); i++) - if ((locSym->id_arr[i].id.bwGlb.seg == segValue) && - (locSym->id_arr[i].id.bwGlb.off == off) && - (locSym->id_arr[i].id.bwGlb.regi == regi)) + { + const BWGLB_TYPE &lID(locSym->id_arr[i].id.bwGlb); + if ((lID.seg == segValue) && (lID.off == off) && (lID.regi == regi)) break; + } if (i == locSym->csym()) printf ("Error, indexed-glob var not found in local id table\n"); - newExp->expr.ident.idNode.idxGlbIdx = i; + newExp->ident.idNode.idxGlbIdx = i; return (newExp); } /* Returns an identifier conditional expression node of type CONSTANT */ -COND_EXPR *COND_EXPR::idKte(uint32_t kte, uint8_t size) +AstIdent *AstIdent::Kte(uint32_t kte, uint8_t size) { - COND_EXPR *newExp = new COND_EXPR(IDENTIFIER); - newExp->expr.ident.idType = CONSTANT; - newExp->expr.ident.idNode.kte.kte = kte; - newExp->expr.ident.idNode.kte.size = size; + AstIdent *newExp = new AstIdent(); + newExp->ident.idType = CONSTANT; + newExp->ident.idNode.kte.kte = kte; + newExp->ident.idNode.kte.size = size; return (newExp); } /* Returns an identifier conditional expression node of type LONG_VAR, * that points to the given index idx. */ -COND_EXPR *COND_EXPR::idLongIdx (int idx) +AstIdent *AstIdent::LongIdx (int idx) { - COND_EXPR *newExp = new COND_EXPR(IDENTIFIER); - newExp->expr.ident.idType = LONG_VAR; - newExp->expr.ident.idNode.longIdx = idx; + AstIdent *newExp = new AstIdent(); + newExp->ident.idType = LONG_VAR; + newExp->ident.idNode.longIdx = idx; return (newExp); } /* Returns an identifier conditional expression node of type LONG_VAR */ -COND_EXPR *COND_EXPR::idLong(LOCAL_ID *localId, opLoc sd, iICODE pIcode, hlFirst f, iICODE ix, operDu du, LLInst &atOffset) +AstIdent *AstIdent::idLong(LOCAL_ID *localId, opLoc sd, iICODE pIcode, hlFirst f, iICODE ix, operDu du, LLInst &atOffset) { int idx; - COND_EXPR *newExp = new COND_EXPR(IDENTIFIER); + AstIdent *newExp = new AstIdent(); /* Check for long constant and save it as a constant expression */ if ((sd == SRC) && pIcode->ll()->testFlags(I)) /* constant */ { - newExp->expr.ident.idType = CONSTANT; + newExp->ident.idType = CONSTANT; + int value; if (f == HIGH_FIRST) - newExp->expr.ident.idNode.kte.kte = (pIcode->ll()->src().getImm2() << 16) + - atOffset.src().getImm2(); - else /* LOW_FIRST */ - newExp->expr.ident.idNode.kte.kte = - (atOffset.src().getImm2() << 16)+ pIcode->ll()->src().getImm2(); - newExp->expr.ident.idNode.kte.size = 4; + value = (pIcode->ll()->src().getImm2() << 16) + atOffset.src().getImm2(); + else/* LOW_FIRST */ + value = (atOffset.src().getImm2() << 16)+ pIcode->ll()->src().getImm2(); + newExp->ident.idNode.kte.kte = value; + newExp->ident.idNode.kte.size = 4; } /* Save it as a long expression (reg, stack or glob) */ else { idx = localId->newLong(sd, pIcode, f, ix, du, atOffset); - newExp->expr.ident.idType = LONG_VAR; - newExp->expr.ident.idNode.longIdx = idx; + newExp->ident.idType = LONG_VAR; + newExp->ident.idNode.longIdx = idx; } return (newExp); } /* Returns an identifier conditional expression node of type FUNCTION */ -COND_EXPR *COND_EXPR::idFunc(Function * pproc, STKFRAME * args) +AstIdent *AstIdent::idFunc(Function * pproc, STKFRAME * args) { - COND_EXPR *newExp; + AstIdent *newExp = new AstIdent(); - newExp = new COND_EXPR(IDENTIFIER); - newExp->expr.ident.idType = FUNCTION; - newExp->expr.ident.idNode.call.proc = pproc; - newExp->expr.ident.idNode.call.args = args; + newExp->ident.idType = FUNCTION; + newExp->ident.idNode.call.proc = pproc; + newExp->ident.idNode.call.args = args; return (newExp); } @@ -287,38 +276,35 @@ COND_EXPR *COND_EXPR::idFunc(Function * pproc, STKFRAME * args) /* Returns an identifier conditional expression node of type OTHER. * Temporary solution, should really be encoded as an indexed type (eg. * arrays). */ -COND_EXPR *COND_EXPR::idOther(eReg seg, eReg regi, int16_t off) +AstIdent *AstIdent::Other(eReg seg, eReg regi, int16_t off) { - COND_EXPR *newExp; - - newExp = new COND_EXPR(IDENTIFIER); - newExp->expr.ident.idType = OTHER; - newExp->expr.ident.idNode.other.seg = seg; - newExp->expr.ident.idNode.other.regi = regi; - newExp->expr.ident.idNode.other.off = off; + AstIdent *newExp = new AstIdent(); + newExp->ident.idType = OTHER; + newExp->ident.idNode.other.seg = seg; + newExp->ident.idNode.other.regi = regi; + newExp->ident.idNode.other.off = off; return (newExp); } /* Returns an identifier conditional expression node of type TYPE_LONG or * TYPE_WORD_SIGN */ -COND_EXPR *COND_EXPR::idID (const ID *retVal, LOCAL_ID *locsym, iICODE ix_) +AstIdent *AstIdent::idID (const ID *retVal, LOCAL_ID *locsym, iICODE ix_) { - COND_EXPR *newExp; + AstIdent *newExp = new AstIdent(); int idx; - newExp = new COND_EXPR(IDENTIFIER); if (retVal->type == TYPE_LONG_SIGN) { idx = locsym->newLongReg (TYPE_LONG_SIGN, retVal->id.longId.h,retVal->id.longId.l, ix_); - newExp->expr.ident.idType = LONG_VAR; - newExp->expr.ident.idNode.longIdx = idx; + newExp->ident.idType = LONG_VAR; + newExp->ident.idNode.longIdx = idx; } else if (retVal->type == TYPE_WORD_SIGN) { - newExp->expr.ident.idType = REGISTER; - newExp->expr.ident.idNode.regiIdx = locsym->newByteWordReg(TYPE_WORD_SIGN, retVal->id.regi); - newExp->expr.ident.regiType = WORD_REG; + newExp->ident.idType = REGISTER; + newExp->ident.idNode.regiIdx = locsym->newByteWordReg(TYPE_WORD_SIGN, retVal->id.regi); + newExp->ident.regiType = WORD_REG; } return (newExp); } @@ -329,7 +315,7 @@ COND_EXPR *COND_EXPR::idID (const ID *retVal, LOCAL_ID *locsym, iICODE ix_) * Arguments: * duIcode: icode instruction that needs the du set. * du: operand is defined or used in current instruction. */ -COND_EXPR *COND_EXPR::id(const LLInst &ll_insn, opLoc sd, Function * pProc, iICODE ix_,ICODE &duIcode, operDu du) +COND_EXPR *AstIdent::id(const LLInst &ll_insn, opLoc sd, Function * pProc, iICODE ix_,ICODE &duIcode, operDu du) { COND_EXPR *newExp; @@ -342,26 +328,26 @@ COND_EXPR *COND_EXPR::id(const LLInst &ll_insn, opLoc sd, Function * pProc, iICO (sd == LHS_OP)) /* for MUL lhs */ { /* implicit dx:ax */ idx = pProc->localId.newLongReg (TYPE_LONG_SIGN, rDX, rAX, ix_); - newExp = COND_EXPR::idLongIdx (idx); + newExp = AstIdent::LongIdx (idx); duIcode.setRegDU (rDX, du); duIcode.setRegDU (rAX, du); } else if ((sd == DST) && ll_insn.testFlags(IM_TMP_DST)) { /* implicit tmp */ - newExp = COND_EXPR::idReg (rTMP, 0, &pProc->localId); + newExp = AstIdent::Reg (rTMP, 0, &pProc->localId); duIcode.setRegDU(rTMP, (operDu)eUSE); } else if ((sd == SRC) && ll_insn.testFlags(I)) /* constant */ - newExp = COND_EXPR::idKte (ll_insn.src().getImm2(), 2); + newExp = AstIdent::Kte (ll_insn.src().getImm2(), 2); else if (pm.regi == rUNDEF) /* global variable */ newExp = GlobalVariable::Create(pm.segValue, pm.off); else if ( pm.isReg() ) /* register */ { - newExp = COND_EXPR::idReg (pm.regi, (sd == SRC) ? ll_insn.getFlag() : - ll_insn.getFlag() & NO_SRC_B, - &pProc->localId); + newExp = AstIdent::Reg (pm.regi, (sd == SRC) ? ll_insn.getFlag() : + ll_insn.getFlag() & NO_SRC_B, + &pProc->localId); duIcode.setRegDU( pm.regi, du); } @@ -370,20 +356,20 @@ COND_EXPR *COND_EXPR::id(const LLInst &ll_insn, opLoc sd, Function * pProc, iICO if ((pm.seg == rSS) && (pm.regi == INDEX_BP)) /* idx on bp */ { if (pm.off >= 0) /* argument */ - newExp = COND_EXPR::idParam (pm.off, &pProc->args); + newExp = AstIdent::idParam (pm.off, &pProc->args); else /* local variable */ - newExp = COND_EXPR::idLoc (pm.off, &pProc->localId); + newExp = AstIdent::Loc (pm.off, &pProc->localId); } else if ((pm.seg == rDS) && (pm.regi == INDEX_BX)) /* bx */ { if (pm.off > 0) /* global variable */ newExp = idCondExpIdxGlob (pm.segValue, pm.off, rBX,&pProc->localId); else - newExp = COND_EXPR::idOther (pm.seg, pm.regi, pm.off); + newExp = AstIdent::Other (pm.seg, pm.regi, pm.off); duIcode.setRegDU( rBX, eUSE); } else /* idx <> bp, bx */ - newExp = COND_EXPR::idOther (pm.seg, pm.regi, pm.off); + newExp = AstIdent::Other (pm.seg, pm.regi, pm.off); /**** check long ops, indexed global var *****/ } @@ -392,31 +378,30 @@ COND_EXPR *COND_EXPR::id(const LLInst &ll_insn, opLoc sd, Function * pProc, iICO if ((pm.seg == rDS) && (pm.regi > INDEX_BP_DI)) /* dereference */ { switch (pm.regi) { - case INDEX_SI: - newExp = COND_EXPR::idReg(rSI, 0, &pProc->localId); - duIcode.setRegDU( rSI, du); - break; - case INDEX_DI: - newExp = COND_EXPR::idReg(rDI, 0, &pProc->localId); - duIcode.setRegDU( rDI, du); - break; - case INDEX_BP: - newExp = COND_EXPR::idReg(rBP, 0, &pProc->localId); - break; - case INDEX_BX: - newExp = COND_EXPR::idReg(rBX, 0, &pProc->localId); - duIcode.setRegDU( rBX, du); - break; - default: - newExp = 0; - assert(false); + case INDEX_SI: + newExp = AstIdent::Reg(rSI, 0, &pProc->localId); + duIcode.setRegDU( rSI, du); + break; + case INDEX_DI: + newExp = AstIdent::Reg(rDI, 0, &pProc->localId); + duIcode.setRegDU( rDI, du); + break; + case INDEX_BP: + newExp = AstIdent::Reg(rBP, 0, &pProc->localId); + break; + case INDEX_BX: + newExp = AstIdent::Reg(rBX, 0, &pProc->localId); + duIcode.setRegDU( rBX, du); + break; + default: + newExp = 0; + assert(false); } - newExp = COND_EXPR::unary (DEREFERENCE, newExp); + newExp = UnaryOperator::Create(DEREFERENCE, newExp); } else - newExp = COND_EXPR::idOther (pm.seg, pm.regi, 0); + newExp = AstIdent::Other (pm.seg, pm.regi, 0); } - return (newExp); } @@ -448,125 +433,144 @@ condId LLInst::idType(opLoc sd) const /* Size of hl types */ int hlSize[] = {2, 1, 1, 2, 2, 4, 4, 4, 2, 2, 1, 4, 4}; - -/* Returns the type of the expression */ -int hlTypeSize (const COND_EXPR *expr, Function * pproc) +int COND_EXPR::hlTypeSize(Function * pproc) const { - int first, second; - - if (expr == NULL) + if (this == NULL) return (2); /* for TYPE_UNKNOWN */ - switch (expr->m_type) { - case BOOLEAN_OP: - first = hlTypeSize (expr->lhs(), pproc); - second = hlTypeSize (expr->rhs(), pproc); - if (first > second) - return (first); - else - return (second); + switch (m_type) { + case BOOLEAN_OP: + assert(false); + return 0; + // return expr->hlTypeSize(pproc); + case NEGATION: case ADDRESSOF: + case POST_INC: case POST_DEC: + case PRE_INC: case PRE_DEC: + case DEREFERENCE: + assert(false); + return 0; + //return expr->hlTypeSize(pproc); + case IDENTIFIER: + assert(false); + return 0; + default: + fprintf(stderr,"hlTypeSize queried for Unkown type %d \n",m_type); + break; + } + return 2; // CC: is this correct? +} - case NEGATION: case ADDRESSOF: - case POST_INC: case POST_DEC: - case PRE_INC: case PRE_DEC: - case DEREFERENCE: return (hlTypeSize (expr->expr.unaryExp, pproc)); - - case IDENTIFIER: - switch (expr->expr.ident.idType) - { +/* Returns the type of the expression */ +int BinaryOperator::hlTypeSize(Function * pproc) const +{ + return std::max(lhs()->hlTypeSize (pproc),rhs()->hlTypeSize (pproc)); +} +int UnaryOperator::hlTypeSize(Function *pproc) const +{ + return (unaryExp->hlTypeSize (pproc)); +} +int AstIdent::hlTypeSize(Function *pproc) const +{ + switch (ident.idType) + { case GLOB_VAR: - return (Project::get()->symbolSize(expr->expr.ident.idNode.globIdx)); + return (Project::get()->symbolSize(ident.idNode.globIdx)); case REGISTER: - if (expr->expr.ident.regiType == BYTE_REG) + if (ident.regiType == BYTE_REG) return (1); else return (2); case LOCAL_VAR: - return (hlSize[pproc->localId.id_arr[expr->expr.ident.idNode.localIdx].type]); + return (hlSize[pproc->localId.id_arr[ident.idNode.localIdx].type]); case PARAM: - return (hlSize[pproc->args[expr->expr.ident.idNode.paramIdx].type]); + return (hlSize[pproc->args[ident.idNode.paramIdx].type]); case GLOB_VAR_IDX: - return (hlSize[pproc->localId.id_arr[expr->expr.ident.idNode.idxGlbIdx].type]); + return (hlSize[pproc->localId.id_arr[ident.idNode.idxGlbIdx].type]); case CONSTANT: - return (expr->expr.ident.idNode.kte.size); + return (ident.idNode.kte.size); case STRING: return (2); case LONG_VAR: return (4); case FUNCTION: - return (hlSize[expr->expr.ident.idNode.call.proc->retVal.type]); + return (hlSize[ident.idNode.call.proc->retVal.type]); case OTHER: return (2); - } /* eos */ - break; - default: - fprintf(stderr,"hlTypeSize queried for Unkown type %d \n",expr->m_type); - break; - } - return 2; // CC: is this correct? + } /* eos */ +} +hlType BinaryOperator::expType(Function *pproc) const +{ + hlType first = lhs()->expType ( pproc ); + hlType second = rhs()->expType ( pproc ); + if (first != second) + { + if (lhs()->hlTypeSize(pproc) > rhs()->hlTypeSize (pproc)) + return (first); + else + return (second); + } + else + return (first); +} +hlType UnaryOperator::expType(Function *pproc) const +{ + return unaryExp->expType (pproc); +} +hlType AstIdent::expType(Function *pproc) const +{ + switch (ident.idType) + { + case GLOB_VAR: + return Project::get()->symbolType(ident.idNode.globIdx); + case REGISTER: + if (ident.regiType == BYTE_REG) + return (TYPE_BYTE_SIGN); + else + return (TYPE_WORD_SIGN); + case LOCAL_VAR: + return (pproc->localId.id_arr[ident.idNode.localIdx].type); + case PARAM: + return (pproc->args[ident.idNode.paramIdx].type); + case GLOB_VAR_IDX: + return (pproc->localId.id_arr[ident.idNode.idxGlbIdx].type); + case CONSTANT: + return (TYPE_CONST); + case STRING: + return (TYPE_STR); + case LONG_VAR: + return (pproc->localId.id_arr[ident.idNode.longIdx].type); + case FUNCTION: + return (ident.idNode.call.proc->retVal.type); + default: + return (TYPE_UNKNOWN); + } /* eos */ + return (TYPE_UNKNOWN); } - - /* Returns the type of the expression */ hlType COND_EXPR::expType(Function * pproc) const { - hlType first, second; if (this == nullptr) return (TYPE_UNKNOWN); switch (m_type) { - case BOOLEAN_OP: - first = lhs()->expType ( pproc ); - second = rhs()->expType ( pproc ); - if (first != second) - { - if (hlTypeSize (lhs(), pproc) > hlTypeSize (rhs(), pproc)) - return (first); - else - return (second); - } - else - return (first); - - case POST_INC: case POST_DEC: - case PRE_INC: case PRE_DEC: - case NEGATION: - return (expr.unaryExp->expType (pproc)); - - case ADDRESSOF: return (TYPE_PTR); /***????****/ - case DEREFERENCE: return (TYPE_PTR); - case IDENTIFIER: - switch (expr.ident.idType) - { - case GLOB_VAR: - return Project::get()->symbolType(expr.ident.idNode.globIdx); - case REGISTER: - if (expr.ident.regiType == BYTE_REG) - return (TYPE_BYTE_SIGN); - else - return (TYPE_WORD_SIGN); - case LOCAL_VAR: - return (pproc->localId.id_arr[expr.ident.idNode.localIdx].type); - case PARAM: - return (pproc->args[expr.ident.idNode.paramIdx].type); - case GLOB_VAR_IDX: - return (pproc->localId.id_arr[expr.ident.idNode.idxGlbIdx].type); - case CONSTANT: - return (TYPE_CONST); - case STRING: - return (TYPE_STR); - case LONG_VAR: - return (pproc->localId.id_arr[expr.ident.idNode.longIdx].type); - case FUNCTION: - return (expr.ident.idNode.call.proc->retVal.type); - case OTHER: + case BOOLEAN_OP: + assert(false); + return TYPE_UNKNOWN; + case POST_INC: case POST_DEC: + case PRE_INC: case PRE_DEC: + case NEGATION: + assert(false); + return TYPE_UNKNOWN; + case ADDRESSOF: return (TYPE_PTR); /***????****/ + case DEREFERENCE: return (TYPE_PTR); + case IDENTIFIER: + assert(false); + return TYPE_UNKNOWN; + case UNKNOWN_OP: + assert(false); return (TYPE_UNKNOWN); - } /* eos */ - case UNKNOWN_OP: - assert(false); - return (TYPE_UNKNOWN); } return TYPE_UNKNOWN; // CC: Correct? } @@ -577,26 +581,14 @@ hlType COND_EXPR::expType(Function * pproc) const * node. */ void HlTypeSupport::performLongRemoval (eReg regi, LOCAL_ID *locId, COND_EXPR *tree) { - IDENTTYPE* ident; /* ptr to an identifier */ - eReg otherRegi; /* high or low part of long register */ - switch (tree->m_type) { case BOOLEAN_OP: - break; case POST_INC: case POST_DEC: case PRE_INC: case PRE_DEC: case NEGATION: case ADDRESSOF: case DEREFERENCE: - break; case IDENTIFIER: - ident = &tree->expr.ident; - if (ident->idType == LONG_VAR) - { - otherRegi = otherLongRegi (regi, ident->idNode.longIdx, locId); - ident->idType = REGISTER; - ident->regiType = WORD_REG; - ident->idNode.regiIdx = locId->newByteWordReg(TYPE_WORD_SIGN,otherRegi); - } + tree->performLongRemoval(regi,locId); break; default: fprintf(stderr,"performLongRemoval attemped on %d\n",tree->m_type); @@ -604,7 +596,6 @@ void HlTypeSupport::performLongRemoval (eReg regi, LOCAL_ID *locId, COND_EXPR *t } } - /* Returns the string located in image, formatted in C format. */ static std::string getString (int offset) { @@ -619,207 +610,203 @@ static std::string getString (int offset) o << "\"\0"; return (o.str()); } - - -/* Walks the conditional expression tree and returns the result on a string */ -string walkCondExpr (const COND_EXPR* expr, Function * pProc, int* numLoc) +string BinaryOperator::walkCondExpr(Function * pProc, int* numLoc) const +{ + std::ostringstream outStr; + outStr << "("; + outStr << lhs()->walkCondExpr(pProc, numLoc); + outStr << condOpSym[m_op]; + outStr << rhs()->walkCondExpr(pProc, numLoc); + outStr << ")"; + return outStr.str(); +} +string AstIdent::walkCondExpr(Function *pProc, int *numLoc) const { int16_t off; /* temporal - for OTHER */ ID* id; /* Pointer to local identifier table */ - //char* o; /* Operand string pointer */ - bool needBracket; /* Determine whether parenthesis is needed */ BWGLB_TYPE* bwGlb; /* Ptr to BWGLB_TYPE (global indexed var) */ STKSYM * psym; /* Pointer to argument in the stack */ std::ostringstream outStr,codeOut; - if (expr == NULL) - return ""; - - needBracket = true; - switch (expr->m_type) + std::ostringstream o; + switch (ident.idType) { - case BOOLEAN_OP: - outStr << "("; - outStr << walkCondExpr(expr->lhs(), pProc, numLoc); - outStr << condOpSym[expr->op()]; - outStr << walkCondExpr(expr->rhs(), pProc, numLoc); - outStr << ")"; + case GLOB_VAR: + o << Project::get()->symtab[ident.idNode.globIdx].name; + break; + case REGISTER: + id = &pProc->localId.id_arr[ident.idNode.regiIdx]; + if (id->name[0] == '\0') /* no name */ + { + id->setLocalName(++(*numLoc)); + codeOut <type)<< " "<name<<"; "; + codeOut <<"/* "<id.regi)<<" */\n"; + } + if (id->hasMacro) + o << id->macro << "("<name<<")"; + else + o << id->name; break; + case LOCAL_VAR: + o << pProc->localId.id_arr[ident.idNode.localIdx].name; + break; + + case PARAM: + psym = &pProc->args[ident.idNode.paramIdx]; + if (psym->hasMacro) + o << psym->macro<<"("<name<< ")"; + else + o << psym->name; + break; + + case GLOB_VAR_IDX: + bwGlb = &pProc->localId.id_arr[ident.idNode.idxGlbIdx].id.bwGlb; + o << (bwGlb->seg << 4) + bwGlb->off << "["<regi)<<"]"; + break; + + case CONSTANT: + if (ident.idNode.kte.kte < 1000) + o << ident.idNode.kte.kte; + else + o << "0x"<localId.id_arr[ident.idNode.longIdx]; + if (id->name[0] != '\0') /* STK_FRAME & REG w/name*/ + o << id->name; + else if (id->loc == REG_FRAME) + { + id->setLocalName(++(*numLoc)); + codeOut <type)<< " "<name<<"; "; + codeOut <<"/* "<id.longId.h) << ":" << + Machine_X86::regName(id->id.longId.l) << " */\n"; + o << id->name; + pProc->localId.propLongId (id->id.longId.l,id->id.longId.h, id->name.c_str()); + } + else /* GLB_FRAME */ + { + if (id->id.longGlb.regi == 0) /* not indexed */ + o << "[" << (id->id.longGlb.seg<<4) + id->id.longGlb.offH <<"]"; + else if (id->id.longGlb.regi == rBX) + o << "[" << (id->id.longGlb.seg<<4) + id->id.longGlb.offH <<"][bx]"; + } + break; + + case FUNCTION: + o << writeCall (ident.idNode.call.proc,*ident.idNode.call.args, pProc, numLoc); + break; + + case OTHER: + off = ident.idNode.other.off; + o << Machine_X86::regName(ident.idNode.other.seg)<< "["; + o << Machine_X86::regName(ident.idNode.other.regi); + if (off < 0) + o << "-"<< hexStr (-off); + else if (off>0) + o << "+"<< hexStr (off); + o << "]"; + } /* eos */ + outStr << o.str(); + cCode.appendDecl(codeOut.str()); + return outStr.str(); + +} +string UnaryOperator::walkCondExpr(Function *pProc, int *numLoc) const +{ + std::ostringstream outStr; + bool needBracket=true; + switch(m_type) + { case NEGATION: - if (expr->expr.unaryExp->m_type == IDENTIFIER) + if (unaryExp->m_type == IDENTIFIER) { needBracket = false; outStr << "!"; } else outStr << "! ("; - outStr << walkCondExpr (expr->expr.unaryExp, pProc, numLoc); + outStr << unaryExp->walkCondExpr (pProc, numLoc); if (needBracket == true) outStr << ")"; break; case ADDRESSOF: - if (expr->expr.unaryExp->m_type == IDENTIFIER) + if (unaryExp->m_type == IDENTIFIER) { needBracket = false; outStr << "&"; } else outStr << "&("; - outStr << walkCondExpr (expr->expr.unaryExp, pProc, numLoc); + outStr << unaryExp->walkCondExpr (pProc, numLoc); if (needBracket == true) outStr << ")"; break; case DEREFERENCE: outStr << "*"; - if (expr->expr.unaryExp->m_type == IDENTIFIER) + if (unaryExp->m_type == IDENTIFIER) needBracket = false; else outStr << "("; - outStr << walkCondExpr (expr->expr.unaryExp, pProc, numLoc); + outStr << unaryExp->walkCondExpr (pProc, numLoc); if (needBracket == true) outStr << ")"; break; case POST_INC: - outStr << walkCondExpr (expr->expr.unaryExp, pProc, numLoc) << "++"; + outStr << unaryExp->walkCondExpr (pProc, numLoc) << "++"; break; case POST_DEC: - outStr << walkCondExpr (expr->expr.unaryExp, pProc, numLoc) << "--"; + outStr << unaryExp->walkCondExpr (pProc, numLoc) << "--"; break; case PRE_INC: - outStr << "++"<< walkCondExpr (expr->expr.unaryExp, pProc, numLoc); + outStr << "++"<< unaryExp->walkCondExpr (pProc, numLoc); break; case PRE_DEC: - outStr << "--"<< walkCondExpr (expr->expr.unaryExp, pProc, numLoc); - break; - - case IDENTIFIER: - { - std::ostringstream o; - switch (expr->expr.ident.idType) - { - case GLOB_VAR: - o << Project::get()->symtab[expr->expr.ident.idNode.globIdx].name; - break; - case REGISTER: - id = &pProc->localId.id_arr[expr->expr.ident.idNode.regiIdx]; - if (id->name[0] == '\0') /* no name */ - { - id->setLocalName(++(*numLoc)); - codeOut <type)<< " "<name<<"; "; - codeOut <<"/* "<id.regi)<<" */\n"; - } - if (id->hasMacro) - o << id->macro << "("<name<<")"; - else - o << id->name; - break; - - case LOCAL_VAR: - o << pProc->localId.id_arr[expr->expr.ident.idNode.localIdx].name; - break; - - case PARAM: - psym = &pProc->args[expr->expr.ident.idNode.paramIdx]; - if (psym->hasMacro) - o << psym->macro<<"("<name<< ")"; - else - o << psym->name; - break; - - case GLOB_VAR_IDX: - bwGlb = &pProc->localId.id_arr[expr->expr.ident.idNode.idxGlbIdx].id.bwGlb; - o << (bwGlb->seg << 4) + bwGlb->off << "["<regi)<<"]"; - break; - - case CONSTANT: - if (expr->expr.ident.idNode.kte.kte < 1000) - o << expr->expr.ident.idNode.kte.kte; - else - o << "0x"<expr.ident.idNode.kte.kte; - break; - - case STRING: - o << getString (expr->expr.ident.idNode.strIdx); - break; - - case LONG_VAR: - id = &pProc->localId.id_arr[expr->expr.ident.idNode.longIdx]; - if (id->name[0] != '\0') /* STK_FRAME & REG w/name*/ - o << id->name; - else if (id->loc == REG_FRAME) - { - id->setLocalName(++(*numLoc)); - codeOut <type)<< " "<name<<"; "; - codeOut <<"/* "<id.longId.h) << ":" << - Machine_X86::regName(id->id.longId.l) << " */\n"; - o << id->name; - pProc->localId.propLongId (id->id.longId.l,id->id.longId.h, id->name.c_str()); - } - else /* GLB_FRAME */ - { - if (id->id.longGlb.regi == 0) /* not indexed */ - o << "[" << (id->id.longGlb.seg<<4) + id->id.longGlb.offH <<"]"; - else if (id->id.longGlb.regi == rBX) - o << "[" << (id->id.longGlb.seg<<4) + id->id.longGlb.offH <<"][bx]"; - } - break; - - case FUNCTION: - o << writeCall (expr->expr.ident.idNode.call.proc,*expr->expr.ident.idNode.call.args, pProc, numLoc); - break; - - case OTHER: - off = expr->expr.ident.idNode.other.off; - o << Machine_X86::regName(expr->expr.ident.idNode.other.seg)<< "["; - o << Machine_X86::regName(expr->expr.ident.idNode.other.regi); - if (off < 0) - o << "-"<< hexStr (-off); - else if (off>0) - o << "+"<< hexStr (off); - o << "]"; - } /* eos */ - outStr << o.str(); - break; - } - default: - fprintf(stderr,"walkCondExpr attemped on %d\n",expr->m_type); + outStr << "--"<< unaryExp->walkCondExpr (pProc, numLoc); break; } - cCode.appendDecl(codeOut.str()); return outStr.str(); } +/* Walks the conditional expression tree and returns the result on a string */ + + /* Makes a copy of the given expression. Allocates newExp storage for each * node. Returns the copy. */ COND_EXPR *COND_EXPR::clone() const { - COND_EXPR* newExp=0; /* Expression node copy */ + COND_EXPR* newExp=nullptr; /* Expression node copy */ switch (m_type) { case BOOLEAN_OP: - newExp = new COND_EXPR(*this); - newExp->boolExpr.lhs = lhs()->clone(); - newExp->boolExpr.rhs = rhs()->clone(); + assert(false); break; case NEGATION: case ADDRESSOF: case DEREFERENCE: - newExp = new COND_EXPR(*this); - newExp->expr.unaryExp = expr.unaryExp->clone(); + case PRE_DEC: case POST_DEC: + case PRE_INC: case POST_INC: + assert(false); break; case IDENTIFIER: - return new COND_EXPR(*this); + assert(false); + break; + default: fprintf(stderr,"Clone attempt on unhandled type %d\n",m_type); } @@ -828,11 +815,22 @@ COND_EXPR *COND_EXPR::clone() const /* Changes the boolean conditional operator at the root of this expression */ -void COND_EXPR::changeBoolOp (condOp newOp) +void BinaryOperator::changeBoolOp (condOp newOp) { - boolExpr.op = newOp; + m_op = newOp; +} +bool COND_EXPR::insertSubTreeReg (AstIdent *&tree, COND_EXPR *_expr, eReg regi,const LOCAL_ID *locsym) +{ + COND_EXPR *nd = tree; + bool res=insertSubTreeReg (nd, _expr, regi,locsym); + if(res) + { + tree= dynamic_cast(nd); + return true; + assert(tree); + } + return false; } - /* Inserts the expression exp into the tree at the location specified by the * register regi */ bool COND_EXPR::insertSubTreeReg (COND_EXPR *&tree, COND_EXPR *_expr, eReg regi,const LOCAL_ID *locsym) @@ -848,69 +846,43 @@ bool COND_EXPR::insertSubTreeReg (COND_EXPR *&tree, COND_EXPR *_expr, eReg regi, } return false; } -COND_EXPR *COND_EXPR::insertSubTreeReg (COND_EXPR *_expr, eReg regi,const LOCAL_ID *locsym) + +COND_EXPR *UnaryOperator::insertSubTreeReg(COND_EXPR *_expr, eReg regi, const LOCAL_ID *locsym) { eReg treeReg; COND_EXPR *temp; switch (m_type) { - case IDENTIFIER: - if (expr.ident.idType == REGISTER) - { - treeReg = locsym->id_arr[expr.ident.idNode.regiIdx].id.regi; - if (treeReg == regi) /* uint16_t reg */ + case NEGATION: + case ADDRESSOF: + case DEREFERENCE: + temp = unaryExp->insertSubTreeReg( _expr, regi, locsym); + if (nullptr!=temp) { - return _expr; + unaryExp = temp; + return this; } - else if(Machine_X86::isSubRegisterOf(treeReg,regi)) /* uint16_t/uint8_t reg */ - { - return _expr; - } - } - return nullptr; - - case BOOLEAN_OP: - temp = lhs()->insertSubTreeReg( _expr, regi, locsym); - if (nullptr!=temp) - { - boolExpr.lhs = temp; - return this; - } - temp = rhs()->insertSubTreeReg( _expr, regi, locsym); - if (nullptr!=temp) - { - boolExpr.rhs = temp; - return this; - } - return nullptr; - - case NEGATION: - case ADDRESSOF: - case DEREFERENCE: - temp = expr.unaryExp->insertSubTreeReg( _expr, regi, locsym); - if (nullptr!=temp) - { - expr.unaryExp = temp; - return this; - } - return nullptr; - default: - fprintf(stderr,"insertSubTreeReg attempt on unhandled type %d\n",m_type); - + return nullptr; + default: + fprintf(stderr,"insertSubTreeReg attempt on unhandled type %d\n",m_type); } - return nullptr; } COND_EXPR *BinaryOperator::insertSubTreeReg(COND_EXPR *_expr, eReg regi, const LOCAL_ID *locsym) { COND_EXPR *r; - r=m_lhs->insertSubTreeReg(_expr,regi,locsym); - if(r) + if(this->op()!=NOT) { - m_lhs = r; - return this; + assert(m_lhs); + r=m_lhs->insertSubTreeReg(_expr,regi,locsym); + if(r) + { + m_lhs = r; + return this; + } } + assert(m_rhs); r=m_rhs->insertSubTreeReg(_expr,regi,locsym); if(r) { @@ -919,71 +891,58 @@ COND_EXPR *BinaryOperator::insertSubTreeReg(COND_EXPR *_expr, eReg regi, const L } return nullptr; } - +COND_EXPR *AstIdent::insertSubTreeReg(COND_EXPR *_expr, eReg regi, const LOCAL_ID *locsym) +{ + eReg treeReg; + if (ident.idType == REGISTER) + { + treeReg = locsym->id_arr[ident.idNode.regiIdx].id.regi; + if (treeReg == regi) /* uint16_t reg */ + { + return _expr; + } + else if(Machine_X86::isSubRegisterOf(treeReg,regi)) /* uint16_t/uint8_t reg */ + { + return _expr; + } + } + return nullptr; +} /* Inserts the expression exp into the tree at the location specified by the * long register index longIdx*/ -bool COND_EXPR::insertSubTreeLongReg(COND_EXPR *_expr, COND_EXPR **tree, int longIdx) +bool COND_EXPR::insertSubTreeLongReg(COND_EXPR *_expr, COND_EXPR *&tree, int longIdx) { if (tree == NULL) return false; - COND_EXPR *temp=(*tree)->insertSubTreeLongReg(_expr,longIdx); + COND_EXPR *temp=tree->insertSubTreeLongReg(_expr,longIdx); if(nullptr!=temp) { - *tree=temp; + tree=temp; return true; } return false; } -COND_EXPR *COND_EXPR::insertSubTreeLongReg(COND_EXPR *_expr, int longIdx) +COND_EXPR *UnaryOperator::insertSubTreeLongReg(COND_EXPR *_expr, int longIdx) { - COND_EXPR *temp; - switch (m_type) + COND_EXPR *temp = unaryExp->insertSubTreeLongReg(_expr,longIdx); + if (nullptr!=temp) { - case IDENTIFIER: - if (expr.ident.idNode.longIdx == longIdx) - { - return _expr; - } - return nullptr; - - case BOOLEAN_OP: - temp = lhs()->insertSubTreeLongReg( _expr,longIdx); - if (nullptr!=temp) - { - boolExpr.lhs = temp; - return this; - } - temp = rhs()->insertSubTreeLongReg( _expr,longIdx); - if (nullptr!=temp) - { - boolExpr.rhs = temp; - return this; - } - return nullptr; - - case NEGATION: - case ADDRESSOF: - case DEREFERENCE: - temp = expr.unaryExp->insertSubTreeLongReg(_expr,longIdx); - if (nullptr!=temp) - { - expr.unaryExp = temp; - return this; - } - return nullptr; - default: - fprintf(stderr,"insertSubTreeLongReg attempt on unhandled type %d\n",m_type); + unaryExp = temp; + return this; } return nullptr; } COND_EXPR *BinaryOperator::insertSubTreeLongReg(COND_EXPR *_expr, int longIdx) { COND_EXPR *r; - r=m_lhs->insertSubTreeLongReg(_expr,longIdx); - if(r) + if(m_op!=NOT) { - m_lhs = r; - return this; + r=m_lhs->insertSubTreeLongReg(_expr,longIdx); + if(r) + { + m_lhs = r; + return this; + } } r=m_rhs->insertSubTreeLongReg(_expr,longIdx); if(r) @@ -993,26 +952,29 @@ COND_EXPR *BinaryOperator::insertSubTreeLongReg(COND_EXPR *_expr, int longIdx) } return nullptr; } - +COND_EXPR *AstIdent::insertSubTreeLongReg(COND_EXPR *_expr, int longIdx) +{ + if (ident.idNode.longIdx == longIdx) + { + return _expr; + } + return nullptr; +} /* Recursively deallocates the abstract syntax tree rooted at *exp */ -void COND_EXPR::release() +COND_EXPR::~COND_EXPR() { switch (m_type) { - case BOOLEAN_OP: - lhs()->release(); - rhs()->release(); - break; - case NEGATION: - case ADDRESSOF: - case DEREFERENCE: - expr.unaryExp->release(); - break; - default: - fprintf(stderr,"release attempt on unhandled type %d\n",m_type); + case BOOLEAN_OP: + case NEGATION: + case ADDRESSOF: + case DEREFERENCE: + case IDENTIFIER: + break; + default: + fprintf(stderr,"release attempt on unhandled type %d\n",m_type); } - delete (this); } /* Makes a copy of the given expression. Allocates newExp storage for each * node. Returns the copy. */ @@ -1034,24 +996,52 @@ COND_EXPR *BinaryOperator::inverse() const BinaryOperator *res=reinterpret_cast(this->clone()); switch (m_op) { - case LESS_EQUAL: case LESS: case EQUAL: - case NOT_EQUAL: case GREATER: case GREATER_EQUAL: - res->m_op = invCondOp[m_op]; - return res; + case LESS_EQUAL: case LESS: case EQUAL: + case NOT_EQUAL: case GREATER: case GREATER_EQUAL: + res->m_op = invCondOp[m_op]; + return res; - case AND: case OR: case XOR: case NOT: case ADD: - case SUB: case MUL: case DIV: case SHR: case SHL: case MOD: - return COND_EXPR::unary (NEGATION, res); + case AND: case OR: case XOR: case NOT: case ADD: + case SUB: case MUL: case DIV: case SHR: case SHL: case MOD: + return UnaryOperator::Create(NEGATION, res); - case DBL_AND: case DBL_OR: - res->m_op = invCondOp[m_op]; - res->m_lhs=m_lhs->inverse (); - res->m_rhs=m_rhs->inverse (); - return res; - default: - fprintf(stderr,"BinaryOperator::inverse attempt on unhandled op %d\n",m_op); + case DBL_AND: case DBL_OR: + res->m_op = invCondOp[m_op]; + res->m_lhs=m_lhs->inverse (); + res->m_rhs=m_rhs->inverse (); + return res; + default: + fprintf(stderr,"BinaryOperator::inverse attempt on unhandled op %d\n",m_op); } /* eos */ assert(false); return res; } +void AstIdent::performLongRemoval(eReg regi, LOCAL_ID *locId) +{ + eReg otherRegi; /* high or low part of long register */ + + IDENTTYPE* ident_2 = &ident; + if (ident_2->idType == LONG_VAR) + { + otherRegi = otherLongRegi (regi, ident_2->idNode.longIdx, locId); + ident_2->idType = REGISTER; + ident_2->regiType = WORD_REG; + ident_2->idNode.regiIdx = locId->newByteWordReg(TYPE_WORD_SIGN,otherRegi); + } +} +eReg AstIdent::otherLongRegi (eReg regi, int idx, LOCAL_ID *locTbl) +{ + ID *id; + + id = &locTbl->id_arr[idx]; + if ((id->loc == REG_FRAME) && ((id->type == TYPE_LONG_SIGN) || + (id->type == TYPE_LONG_UNSIGN))) + { + if (id->id.longId.h == regi) + return (id->id.longId.l); + else if (id->id.longId.l == regi) + return (id->id.longId.h); + } + return rUNDEF; // Cristina: please check this! +} diff --git a/src/backend.cpp b/src/backend.cpp index f468798..bbeecd1 100644 --- a/src/backend.cpp +++ b/src/backend.cpp @@ -6,6 +6,9 @@ ****************************************************************************/ #include #include +#include +#include +#include #include "dcc.h" #include "disassem.h" @@ -15,6 +18,8 @@ #include #include #include "project.h" +using namespace boost; +using namespace boost::adaptors; bundle cCode; /* Procedure declaration and code */ using namespace std; @@ -215,12 +220,16 @@ void Function::codeGen (std::ostream &fs) ostr<< "\nvoid "<args[i]; ostr << " * "<name<<" = "; - if (psym->regs->expr.ident.idType == REGISTER) + if (psym->regs->ident.idType == REGISTER) { - id = &this->localId.id_arr[psym->regs->expr.ident.idNode.regiIdx]; + id = &this->localId.id_arr[psym->regs->ident.idNode.regiIdx]; ostr << Machine_X86::regName(id->id.regi); } else /* long register */ { - id = &this->localId.id_arr[psym->regs->expr.ident.idNode.longIdx]; + id = &this->localId.id_arr[psym->regs->ident.idNode.longIdx]; ostr << Machine_X86::regName(id->id.longId.h) << ":"; ostr << Machine_X86::regName(id->id.longId.l); } diff --git a/src/control.cpp b/src/control.cpp index b0281c2..fa5d6dc 100644 --- a/src/control.cpp +++ b/src/control.cpp @@ -505,14 +505,14 @@ void Function::replaceInEdge(BB* where, BB* which,BB* with) } bool Function::Case_notX_or_Y(BB* pbb, BB* thenBB, BB* elseBB) { - HLTYPE &hl1(*pbb->back().hl()); - HLTYPE &hl2(*thenBB->back().hl()); + HLTYPE &hl1(*pbb->back().hlU()); + HLTYPE &hl2(*thenBB->back().hlU()); BB* obb = elseBB->edges[THEN].BBptr; /* Construct compound DBL_OR expression */ hl1.replaceExpr(hl1.expr()->inverse()); - hl1.expr(COND_EXPR::boolOp (hl1.expr(), hl2.expr(), DBL_OR)); + hl1.expr(BinaryOperator::Create(DBL_OR,hl1.expr(), hl2.expr())); /* Replace in-edge to obb from e to pbb */ replaceInEdge(obb,elseBB,pbb); @@ -526,12 +526,12 @@ bool Function::Case_notX_or_Y(BB* pbb, BB* thenBB, BB* elseBB) } bool Function::Case_X_and_Y(BB* pbb, BB* thenBB, BB* elseBB) { - HLTYPE &hl1(*pbb->back().hl()); - HLTYPE &hl2(*thenBB->back().hl()); + HLTYPE &hl1(*pbb->back().hlU()); + HLTYPE &hl2(*thenBB->back().hlU()); BB* obb = elseBB->edges[ELSE].BBptr; /* Construct compound DBL_AND expression */ - hl1.expr(COND_EXPR::boolOp (hl1.expr(),hl2.expr(), DBL_AND)); + hl1.expr(BinaryOperator::Create(DBL_AND,hl1.expr(),hl2.expr())); /* Replace in-edge to obb from e to pbb */ replaceInEdge(obb,elseBB,pbb); @@ -545,15 +545,15 @@ bool Function::Case_X_and_Y(BB* pbb, BB* thenBB, BB* elseBB) bool Function::Case_notX_and_Y(BB* pbb, BB* thenBB, BB* elseBB) { - HLTYPE &hl1(*pbb->back().hl()); - HLTYPE &hl2(*thenBB->back().hl()); + HLTYPE &hl1(*pbb->back().hlU()); + HLTYPE &hl2(*thenBB->back().hlU()); BB* obb = thenBB->edges[ELSE].BBptr; /* Construct compound DBL_AND expression */ hl1.replaceExpr(hl1.expr()->inverse()); - hl1.expr(COND_EXPR::boolOp (hl1.expr(), hl2.expr(), DBL_AND)); + hl1.expr(BinaryOperator::LogicAnd(hl1.expr(), hl2.expr())); /* Replace in-edge to obb from t to pbb */ replaceInEdge(obb,thenBB,pbb); @@ -568,13 +568,13 @@ bool Function::Case_notX_and_Y(BB* pbb, BB* thenBB, BB* elseBB) bool Function::Case_X_or_Y(BB* pbb, BB* thenBB, BB* elseBB) { - HLTYPE &hl1(*pbb->back().hl()); - HLTYPE &hl2(*thenBB->back().hl()); + HLTYPE &hl1(*pbb->back().hlU()); + HLTYPE &hl2(*thenBB->back().hlU()); BB * obb = thenBB->edges[THEN].BBptr; /* Construct compound DBL_OR expression */ - hl1.expr(COND_EXPR::boolOp (hl1.expr(), hl2.expr(), DBL_OR)); + hl1.expr(BinaryOperator::LogicOr(hl1.expr(), hl2.expr())); /* Replace in-edge to obb from t to pbb */ diff --git a/src/dataflow.cpp b/src/dataflow.cpp index 40af9ea..79e1eee 100644 --- a/src/dataflow.cpp +++ b/src/dataflow.cpp @@ -30,7 +30,7 @@ struct ExpStack boolT empty(); void processExpPush(int &numHlIcodes, iICODE picode) { - push(picode->hl()->expr()); + push(picode->hlU()->expr()); picode->invalidate(); numHlIcodes--; } @@ -96,11 +96,11 @@ static COND_EXPR *srcIdent (const LLInst &ll_insn, Function * pProc, iICODE i, I if (ll_insn.testFlags(I)) /* immediate operand */ { if (ll_insn.testFlags(B)) - return COND_EXPR::idKte (ll_insn.src().getImm2(), 1); - return COND_EXPR::idKte (ll_insn.src().getImm2(), 2); + return AstIdent::Kte (ll_insn.src().getImm2(), 1); + return AstIdent::Kte (ll_insn.src().getImm2(), 2); } // otherwise - return COND_EXPR::id (ll_insn, SRC, pProc, i, duIcode, du); + return AstIdent::id (ll_insn, SRC, pProc, i, duIcode, du); } @@ -108,7 +108,7 @@ static COND_EXPR *srcIdent (const LLInst &ll_insn, Function * pProc, iICODE i, I static COND_EXPR *dstIdent (const LLInst & ll_insn, Function * pProc, iICODE i, ICODE & duIcode, operDu du) { COND_EXPR *n; - n = COND_EXPR::id (ll_insn, DST, pProc, i, duIcode, du); + n = AstIdent::id (ll_insn, DST, pProc, i, duIcode, du); /** Is it needed? (pIcode->ll()->flg) & NO_SRC_B **/ return (n); } @@ -122,7 +122,7 @@ void Function::elimCondCodes () boolT notSup; /* Use/def combination not supported */ COND_EXPR *rhs; /* Source operand */ COND_EXPR *lhs; /* Destination operand */ - COND_EXPR *_expr; /* Boolean expression */ + BinaryOperator *_expr; /* Boolean expression */ //BB * pBB; /* Pointer to BBs in dfs last ordering */ riICODE useAt; /* Instruction that used flag */ riICODE defAt; /* Instruction that defined flag */ @@ -133,6 +133,7 @@ void Function::elimCondCodes () //auto reversed_instructions = pBB->range() | reversed; for (useAt = pBB->rbegin(); useAt != pBB->rend(); useAt++) { + ICODE &useIcode(*useAt); llIcode useAtOp = llIcode(useAt->ll()->getOpcode()); use = useAt->ll()->flagDU.u; if ((useAt->type != LOW_LEVEL) || ( ! useAt->valid() ) || ( 0 == use )) @@ -142,6 +143,7 @@ void Function::elimCondCodes () ++defAt; for (; defAt != pBB->rend(); defAt++) { + ICODE &defIcode(*defAt); def = defAt->ll()->flagDU.d; if ((use & def) != use) continue; @@ -160,21 +162,29 @@ void Function::elimCondCodes () lhs = defAt->hl()->asgn.lhs->clone(); useAt->copyDU(*defAt, eUSE, eDEF); if (defAt->ll()->testFlags(B)) - rhs = COND_EXPR::idKte (0, 1); + rhs = AstIdent::Kte (0, 1); else - rhs = COND_EXPR::idKte (0, 2); + rhs = AstIdent::Kte (0, 2); break; case iTEST: rhs = srcIdent (*defAt->ll(),this, befDefAt,*useAt, eUSE); lhs = dstIdent (*defAt->ll(),this, befDefAt,*useAt, eUSE); - lhs = COND_EXPR::boolOp (lhs, rhs, AND); + lhs = BinaryOperator::And(lhs, rhs); if (defAt->ll()->testFlags(B)) - rhs = COND_EXPR::idKte (0, 1); + rhs = AstIdent::Kte (0, 1); else - rhs = COND_EXPR::idKte (0, 2); + rhs = AstIdent::Kte (0, 2); + break; + case iINC: + case iDEC: //WARNING: verbatim copy from iOR needs fixing ? + lhs = defAt->hl()->asgn.lhs->clone(); + useAt->copyDU(*defAt, eUSE, eDEF); + if (defAt->ll()->testFlags(B)) + rhs = AstIdent::Kte (0, 1); + else + rhs = AstIdent::Kte (0, 2); break; - default: notSup = true; std::cout << hex<loc_ip; @@ -185,17 +195,17 @@ void Function::elimCondCodes () { assert(lhs); assert(rhs); - _expr = COND_EXPR::boolOp (lhs, rhs,condOpJCond[useAtOp-iJB]); + _expr = BinaryOperator::Create(condOpJCond[useAtOp-iJB],lhs,rhs); useAt->setJCond(_expr); } } else if (useAtOp == iJCXZ) { - lhs = COND_EXPR::idReg (rCX, 0, &localId); + lhs = AstIdent::Reg (rCX, 0, &localId); useAt->setRegDU (rCX, eUSE); - rhs = COND_EXPR::idKte (0, 2); - _expr = COND_EXPR::boolOp (lhs, rhs, EQUAL); + rhs = AstIdent::Kte (0, 2); + _expr = BinaryOperator::Create(EQUAL,lhs,rhs); useAt->setJCond(_expr); } // else if (useAt->getOpcode() == iRCL) @@ -217,7 +227,8 @@ void Function::elimCondCodes () ICODE & _prev(pBB->back()); /* For extended basic blocks - previous icode inst */ if (_prev.hl()->opcode == HLI_JCOND) { - _expr = _prev.hl()->expr()->clone(); + _expr = dynamic_cast(_prev.hl()->expr()->clone()); + assert(_expr); _expr->changeBoolOp (condOpJCond[useAtOp-iJB]); useAt->copyDU(_prev, eUSE, eUSE); useAt->setJCond(_expr); @@ -308,7 +319,7 @@ void Function::liveRegAnalysis (LivenessSet &in_liveOut) auto picode = pbb->rbegin(); /* icode of function return */ if (picode->hl()->opcode == HLI_RET) { - picode->hl()->expr(COND_EXPR::idID (&retVal, &localId, (++pbb->rbegin()).base())); + picode->hlU()->expr(AstIdent::idID (&retVal, &localId, (++pbb->rbegin()).base())); picode->du.use = in_liveOut; } } @@ -547,12 +558,20 @@ void Function::genDU1 () void LOCAL_ID::forwardSubs (COND_EXPR *lhs, COND_EXPR *rhs, iICODE picode, iICODE ticode, int &numHlIcodes) const { bool res; - + UnaryOperator *lhs_unary; + while(lhs_unary = dynamic_cast(lhs)) + { + if(dynamic_cast(lhs_unary)) + break; + lhs = lhs_unary->unaryExp; + } + AstIdent * lhs_id=dynamic_cast(lhs_unary); + assert(lhs_id); if (rhs == NULL) /* In case expression popped is NULL */ return; /* Insert on rhs of ticode, if possible */ - res = COND_EXPR::insertSubTreeReg (ticode->hl()->asgn.rhs,rhs, id_arr[lhs->expr.ident.idNode.regiIdx].id.regi, this); + res = COND_EXPR::insertSubTreeReg (ticode->hlU()->asgn.rhs,rhs, id_arr[lhs_id->ident.idNode.regiIdx].id.regi, this); if (res) { picode->invalidate(); @@ -561,7 +580,7 @@ void LOCAL_ID::forwardSubs (COND_EXPR *lhs, COND_EXPR *rhs, iICODE picode, iICOD else { /* Try to insert it on lhs of ticode*/ - res = COND_EXPR::insertSubTreeReg (ticode->hl()->asgn.lhs,rhs, id_arr[lhs->expr.ident.idNode.regiIdx].id.regi, this); + res = COND_EXPR::insertSubTreeReg (ticode->hlU()->asgn.lhs,rhs, id_arr[lhs_id->ident.idNode.regiIdx].id.regi, this); if (res) { picode->invalidate(); @@ -580,7 +599,7 @@ static void forwardSubsLong (int longIdx, COND_EXPR *_exp, iICODE picode, iICODE return; /* Insert on rhs of ticode, if possible */ - res = COND_EXPR::insertSubTreeLongReg (_exp, &ticode->hl()->asgn.rhs, longIdx); + res = COND_EXPR::insertSubTreeLongReg (_exp, ticode->hlU()->asgn.rhs, longIdx); if (res) { picode->invalidate(); @@ -589,7 +608,7 @@ static void forwardSubsLong (int longIdx, COND_EXPR *_exp, iICODE picode, iICODE else { /* Try to insert it on lhs of ticode*/ - res = COND_EXPR::insertSubTreeLongReg (_exp, &ticode->hl()->asgn.lhs, longIdx); + res = COND_EXPR::insertSubTreeLongReg (_exp, ticode->hlU()->asgn.lhs, longIdx); if (res) { picode->invalidate(); @@ -601,56 +620,6 @@ static void forwardSubsLong (int longIdx, COND_EXPR *_exp, iICODE picode, iICODE /* Returns whether the elements of the expression rhs are all x-clear from * instruction f up to instruction t. */ -bool COND_EXPR::xClear (rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID & locId) -{ - iICODE i; - boolT res; - uint8_t regi; - - switch (m_type) - { - case IDENTIFIER: - if (expr.ident.idType == REGISTER) - { - regi= locId.id_arr[expr.ident.idNode.regiIdx].id.regi; - range_to_check.advance_begin(1); - auto all_valid_and_high_level_after_start = range_to_check | filtered(ICODE::select_valid_high_level); - for (ICODE &i : all_valid_and_high_level_after_start) - if ((i.du.def & duReg[regi]).any()) - return false; - if (all_valid_and_high_level_after_start.end().base() != lastBBinst) - return true; - return false; - } - else - return true; - /* else if (rhs->expr.ident.idType == LONG_VAR) - { - missing all other identifiers **** - } */ - - case BOOLEAN_OP: - if(0==rhs()) - return false; - res = rhs()->xClear ( range_to_check, lastBBinst, locId); - if (res == false) - return false; - if(0==lhs()) - return false; - return lhs()->xClear ( range_to_check, lastBBinst, locId); - - case NEGATION: - case ADDRESSOF: - case DEREFERENCE: - if(0==expr.unaryExp) - return false; - return expr.unaryExp->xClear ( range_to_check, lastBBinst, locId); - default: - fprintf(stderr,"COND_EXPR::xClear unhandled type %d\n",m_type); - - } /* eos */ - return false; -} bool UnaryOperator::xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locs) { if(0==unaryExp) @@ -668,6 +637,26 @@ bool BinaryOperator::xClear(rICODE range_to_check, iICODE lastBBinst, const LOCA return false; return m_lhs->xClear (range_to_check, lastBBinst, locs); } +bool AstIdent::xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locId) +{ + iICODE i; + uint8_t regi; + if (ident.idType == REGISTER) + { + regi= locId.id_arr[ident.idNode.regiIdx].id.regi; + range_to_check.advance_begin(1); + auto all_valid_and_high_level_after_start = range_to_check | filtered(ICODE::select_valid_high_level); + for (ICODE &i : all_valid_and_high_level_after_start) + if ((i.du.def & duReg[regi]).any()) + return false; + if (all_valid_and_high_level_after_start.end().base() != lastBBinst) + return true; + return false; + } + else + return true; + +} /* Checks the type of the formal argument as against to the actual argument, * whenever possible, and then places the actual argument on the procedure's * argument list. */ @@ -709,7 +698,11 @@ static int processCArg (Function * pp, Function * pProc, ICODE * picode, size_t /* Do not update the size of k if the expression was a segment register * in a near call */ if (res == false) - return hlTypeSize (_exp, pProc); + { + if(_exp==nullptr) + return 2; + return _exp->hlTypeSize (pProc); + } return 0; // be default we do not know the size of the argument } @@ -719,35 +712,40 @@ static int processCArg (Function * pp, Function * pProc, ICODE * picode, size_t void LOCAL_ID::processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode,bool isLong) const { boolT res; - HLTYPE &p_hl(*picode->hl()); - HLTYPE &t_hl(*ticode->hl()); + HLTYPE &p_hl(*picode->hlU()); + HLTYPE &t_hl(*ticode->hlU()); + AstIdent *lhs_ident = dynamic_cast(p_hl.asgn.lhs); + switch (t_hl.opcode) { case HLI_ASSIGN: if(isLong) { - forwardSubsLong (p_hl.asgn.lhs->expr.ident.idNode.longIdx, + assert(lhs_ident); + forwardSubsLong (lhs_ident->ident.idNode.longIdx, p_hl.asgn.rhs, picode,ticode, &numHlIcodes); } else - this->forwardSubs (p_hl.asgn.lhs, p_hl.asgn.rhs, picode, ticode, numHlIcodes); + this->forwardSubs (lhs_ident, p_hl.asgn.rhs, picode, ticode, numHlIcodes); break; case HLI_JCOND: case HLI_PUSH: case HLI_RET: if(isLong) { + assert(lhs_ident); res = COND_EXPR::insertSubTreeLongReg ( p_hl.asgn.rhs, - &t_hl.exp.v, - p_hl.asgn.lhs->expr.ident.idNode.longIdx); + t_hl.exp.v, + lhs_ident->ident.idNode.longIdx); } else { + assert(lhs_ident); res = COND_EXPR::insertSubTreeReg ( t_hl.exp.v, p_hl.asgn.rhs, - id_arr[p_hl.asgn.lhs->expr.ident.idNode.regiIdx].id.regi, + id_arr[lhs_ident->ident.idNode.regiIdx].id.regi, this); } if (res) @@ -802,7 +800,7 @@ void Function::processHliCall(COND_EXPR *_exp, iICODE picode) res = picode->newStkArg (_exp,(llIcode)picode->ll()->getOpcode(), this); } if (res == false) - k += hlTypeSize (_exp, this); + k += _exp->hlTypeSize (this); numArgs++; } } @@ -846,7 +844,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc) auto valid_and_highlevel = instructions | filtered(ICODE::TypeAndValidFilter()); for (auto picode = valid_and_highlevel.begin(); picode != valid_and_highlevel.end(); picode++) { - HLTYPE &_icHl(*picode->hl()); + HLTYPE &_icHl(*picode->hlU()); numHlIcodes++; if (picode->du1.numRegsDef == 1) /* uint8_t/uint16_t regs */ { @@ -880,8 +878,12 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc) break; case HLI_POP: + // TODO: sometimes picode->du1.idx[0].uses.front() points to next basic block ? + // pop X + // lab1: + // call F() <- somehow this is marked as user of POP ? ticode = picode->du1.idx[0].uses.front(); - ti_hl = ticode->hl(); + ti_hl = ticode->hlU(); if ((picode->du.lastDefRegi & duReg[regi]).any() && ((ti_hl->opcode != HLI_CALL) && (ti_hl->opcode != HLI_RET))) @@ -894,15 +896,19 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc) break; case HLI_JCOND: case HLI_PUSH: case HLI_RET: + { + AstIdent *v = dynamic_cast(_icHl.expr()); + assert(v); res = COND_EXPR::insertSubTreeReg (ti_hl->exp.v, _exp, - locals.id_arr[_icHl.expr()->expr.ident.idNode.regiIdx].id.regi, + locals.id_arr[v->ident.idNode.regiIdx].id.regi, &locals); if (res) { picode->invalidate(); numHlIcodes--; } + } break; /****case HLI_CALL: // register arguments @@ -918,7 +924,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc) case HLI_CALL: ticode = picode->du1.idx[0].uses.front(); - ti_hl = ticode->hl(); + ti_hl = ticode->hlU(); _retVal = &_icHl.call.proc->retVal; switch (ti_hl->opcode) { @@ -949,8 +955,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc) } else /* cannot substitute function */ { - //picode->loc_ip - lhs = COND_EXPR::idID(_retVal,&locals,picode.base()); + auto lhs = AstIdent::idID(_retVal,&locals,picode.base()); picode->setAsgn(lhs, _exp); } break; @@ -999,13 +1004,13 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc) _exp = g_exp_stk.pop(); /* pop last exp pushed */ switch (ticode->hl()->opcode) { case HLI_ASSIGN: - forwardSubsLong (_icHl.expr()->expr.ident.idNode.longIdx, + forwardSubsLong (dynamic_cast(_icHl.expr())->ident.idNode.longIdx, _exp, picode.base(), ticode, &numHlIcodes); break; case HLI_JCOND: case HLI_PUSH: res = COND_EXPR::insertSubTreeLongReg (_exp, - &ticode->hl()->exp.v, - _icHl.asgn.lhs->expr.ident.idNode.longIdx); + ticode->hlU()->exp.v, + dynamic_cast(_icHl.asgn.lhs)->ident.idNode.longIdx); if (res) { picode->invalidate(); @@ -1026,17 +1031,17 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc) { case HLI_ASSIGN: _exp = _icHl.call.toId(); - ticode->hl()->asgn.lhs = - COND_EXPR::idLong(&locals, DST, + ticode->hlU()->asgn.lhs = + AstIdent::idLong(&locals, DST, ticode,HIGH_FIRST, picode.base(), eDEF, *(++iICODE(ticode))->ll()); - ticode->hl()->asgn.rhs = _exp; + ticode->hlU()->asgn.rhs = _exp; picode->invalidate(); numHlIcodes--; break; case HLI_PUSH: case HLI_RET: - ticode->hl()->expr( _icHl.call.toId() ); + ticode->hlU()->expr( _icHl.call.toId() ); picode->invalidate(); numHlIcodes--; break; @@ -1045,7 +1050,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc) _exp = _icHl.call.toId(); _retVal = &picode->hl()->call.proc->retVal; res = COND_EXPR::insertSubTreeLongReg (_exp, - &ticode->hl()->exp.v, + ticode->hlU()->exp.v, locals.newLongReg ( _retVal->type, _retVal->id.longId.h, _retVal->id.longId.l, picode.base())); if (res) /* was substituted */ @@ -1055,7 +1060,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc) } else /* cannot substitute function */ { - lhs = locals.createId(_retVal,picode.base()); + auto lhs = locals.createId(_retVal,picode.base()); picode->setAsgn(lhs, _exp); } break; @@ -1093,8 +1098,8 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc) * assign it to the corresponding registers */ if ( not _icHl.call.proc->isLibrary() and (not picode->du1.used(0)) and (picode->du1.numRegsDef > 0)) { - _exp = COND_EXPR::idFunc (_icHl.call.proc, _icHl.call.args); - lhs = COND_EXPR::idID (&_icHl.call.proc->retVal, &locals, picode.base()); + _exp = AstIdent::idFunc (_icHl.call.proc, _icHl.call.args); + auto lhs = AstIdent::idID (&_icHl.call.proc->retVal, &locals, picode.base()); picode->setAsgn(lhs, _exp); } } diff --git a/src/disassem.cpp b/src/disassem.cpp index 8e89d44..c1a1e2f 100644 --- a/src/disassem.cpp +++ b/src/disassem.cpp @@ -218,7 +218,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass) * other than JMPs, that have been introduced for def/use analysis. */ if ((option.asm1) && ( inst.testFlags(NO_CODE) || - (inst.testFlags(SYNTHETIC) && (inst.getOpcode() != iJMP)))) + (inst.testFlags(SYNTHETIC) && (inst.getOpcode() != iJMP)))) { return; } @@ -339,15 +339,15 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass) case iJMP: case iJMPF: /* Check if there is a symbol here */ - { - ICODE *lab=pc.GetIcode(inst.src().getImm2()); + { + ICODE *lab=pc.GetIcode(inst.src().getImm2()); selectTable(Label); - if ((inst.src().getImm2() < (uint32_t)numIcode) && /* Ensure in range */ - readVal(operands_s, lab->ll()->label, 0)) + if ((inst.src().getImm2() < (uint32_t)numIcode) && /* Ensure in range */ + readVal(operands_s, lab->ll()->label, 0)) { break; /* Symbolic label. Done */ - } } + } if (inst.testFlags(NO_LABEL)) { @@ -423,9 +423,9 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass) else operands_s<opcode = HLI_CALL; - hl()->call.proc = ll()->src().proc.proc; - hl()->call.args = new STKFRAME; + hlU()->setCall(ll()->src().proc.proc); if (ll()->src().proc.cb != 0) - hl()->call.args->cb = ll()->src().proc.cb; + hlU()->call.args->cb = ll()->src().proc.cb; else if(hl()->call.proc) - hl()->call.args->cb =hl()->call.proc->cbParam; + hlU()->call.args->cb = hl()->call.proc->cbParam; else { printf("Function with no cb set, and no valid oper.call.proc , probaby indirect call\n"); @@ -72,7 +71,7 @@ void ICODE::newCallHl() void ICODE::setUnary(hlIcode op, COND_EXPR *_exp) { type = HIGH_LEVEL; - hl()->set(op,_exp); + hlU()->set(op,_exp); } @@ -80,7 +79,7 @@ void ICODE::setUnary(hlIcode op, COND_EXPR *_exp) void ICODE::setJCond(COND_EXPR *cexp) { type = HIGH_LEVEL; - hl()->set(HLI_JCOND,cexp); + hlU()->set(HLI_JCOND,cexp); } @@ -116,7 +115,7 @@ bool ICODE::removeDefRegi (eReg regi, int thisDefIdx, LOCAL_ID *locId) invalidate(); return true; } - HlTypeSupport *p=hl()->get(); + HlTypeSupport *p=hlU()->get(); if(p and p->removeRegFromLong(regi,locId)) { du1.numRegsDef--; @@ -168,7 +167,7 @@ HLTYPE LLInst::toHighLevel(COND_EXPR *lhs,COND_EXPR *rhs,Function *func) break; case iDEC: - rhs = COND_EXPR::idKte (1, 2); + rhs = AstIdent::idKte (1, 2); rhs = COND_EXPR::boolOp (lhs, rhs, SUB); res.setAsgn(lhs, rhs); break; @@ -178,12 +177,12 @@ HLTYPE LLInst::toHighLevel(COND_EXPR *lhs,COND_EXPR *rhs,Function *func) rhs = COND_EXPR::boolOp (lhs, rhs, DIV); if ( ll->testFlags(B) ) { - lhs = COND_EXPR::idReg (rAL, 0, &localId); + lhs = AstIdent::idReg (rAL, 0, &localId); pIcode->setRegDU( rAL, eDEF); } else { - lhs = COND_EXPR::idReg (rAX, 0, &localId); + lhs = AstIdent::idReg (rAX, 0, &localId); pIcode->setRegDU( rAX, eDEF); } res.setAsgn(lhs, rhs); @@ -191,12 +190,12 @@ HLTYPE LLInst::toHighLevel(COND_EXPR *lhs,COND_EXPR *rhs,Function *func) case iIMUL: rhs = COND_EXPR::boolOp (lhs, rhs, MUL); - lhs = COND_EXPR::id (*pIcode, LHS_OP, func, i, *pIcode, NONE); + lhs = AstIdent::id (*pIcode, LHS_OP, func, i, *pIcode, NONE); res.setAsgn(lhs, rhs); break; case iINC: - rhs = COND_EXPR::idKte (1, 2); + rhs = AstIdent::idKte (1, 2); rhs = COND_EXPR::boolOp (lhs, rhs, ADD); res.setAsgn(lhs, rhs); break; @@ -210,12 +209,12 @@ HLTYPE LLInst::toHighLevel(COND_EXPR *lhs,COND_EXPR *rhs,Function *func) rhs = COND_EXPR::boolOp (lhs, rhs, MOD); if ( ll->testFlags(B) ) { - lhs = COND_EXPR::idReg (rAH, 0, &localId); + lhs = AstIdent::idReg (rAH, 0, &localId); pIcode->setRegDU( rAH, eDEF); } else { - lhs = COND_EXPR::idReg (rDX, 0, &localId); + lhs = AstIdent::idReg (rDX, 0, &localId); pIcode->setRegDU( rDX, eDEF); } res.setAsgn(lhs, rhs); @@ -226,7 +225,7 @@ HLTYPE LLInst::toHighLevel(COND_EXPR *lhs,COND_EXPR *rhs,Function *func) case iMUL: rhs = COND_EXPR::boolOp (lhs, rhs, MUL); - lhs = COND_EXPR::id (*pIcode, LHS_OP, this, i, *pIcode, NONE); + lhs = AstIdent::id (*pIcode, LHS_OP, this, i, *pIcode, NONE); res.setAsgn(lhs, rhs); break; @@ -294,7 +293,8 @@ void Function::highLevelGen() { size_t numIcode; /* number of icode instructions */ iICODE pIcode; /* ptr to current icode node */ - COND_EXPR *lhs, *rhs; /* left- and right-hand side of expression */ + COND_EXPR *lhs; + COND_EXPR *rhs; /* left- and right-hand side of expression */ uint32_t _flg; /* icode flags */ numIcode = Icode.size(); for (iICODE i = Icode.begin(); i!=Icode.end() ; ++i) @@ -311,18 +311,18 @@ void Function::highLevelGen() if ((_flg & NO_OPS) != NO_OPS) /* if there are opers */ { if ( not ll->testFlags(NO_SRC) ) /* if there is src op */ - rhs = COND_EXPR::id (*pIcode->ll(), SRC, this, i, *pIcode, NONE); - lhs = COND_EXPR::id (*pIcode->ll(), DST, this, i, *pIcode, NONE); + rhs = AstIdent::id (*pIcode->ll(), SRC, this, i, *pIcode, NONE); + lhs = AstIdent::id (*pIcode->ll(), DST, this, i, *pIcode, NONE); } switch (ll->getOpcode()) { case iADD: - rhs = COND_EXPR::boolOp (lhs, rhs, ADD); + rhs = new BinaryOperator(ADD,lhs, rhs); pIcode->setAsgn(lhs, rhs); break; case iAND: - rhs = COND_EXPR::boolOp (lhs, rhs, AND); + rhs = BinaryOperator::And(lhs, rhs); pIcode->setAsgn(lhs, rhs); break; @@ -333,54 +333,54 @@ void Function::highLevelGen() break; case iDEC: - rhs = COND_EXPR::idKte (1, 2); - rhs = COND_EXPR::boolOp (lhs, rhs, SUB); + rhs = AstIdent::Kte (1, 2); + rhs = new BinaryOperator(SUB,lhs, rhs); pIcode->setAsgn(lhs, rhs); break; case iDIV: case iIDIV:/* should be signed div */ - rhs = COND_EXPR::boolOp (lhs, rhs, DIV); + rhs = new BinaryOperator(DIV,lhs, rhs); if ( ll->testFlags(B) ) { - lhs = COND_EXPR::idReg (rAL, 0, &localId); + lhs = AstIdent::Reg (rAL, 0, &localId); pIcode->setRegDU( rAL, eDEF); } else { - lhs = COND_EXPR::idReg (rAX, 0, &localId); + lhs = AstIdent::Reg (rAX, 0, &localId); pIcode->setRegDU( rAX, eDEF); } pIcode->setAsgn(lhs, rhs); break; case iIMUL: - rhs = COND_EXPR::boolOp (lhs, rhs, MUL); - lhs = COND_EXPR::id (*ll, LHS_OP, this, i, *pIcode, NONE); + rhs = new BinaryOperator(MUL,lhs, rhs); + lhs = AstIdent::id (*ll, LHS_OP, this, i, *pIcode, NONE); pIcode->setAsgn(lhs, rhs); break; case iINC: - rhs = COND_EXPR::idKte (1, 2); - rhs = COND_EXPR::boolOp (lhs, rhs, ADD); + rhs = AstIdent::Kte (1, 2); + rhs = new BinaryOperator(ADD,lhs, rhs); pIcode->setAsgn(lhs, rhs); break; case iLEA: - rhs = COND_EXPR::unary (ADDRESSOF, rhs); + rhs =UnaryOperator::Create(ADDRESSOF, rhs); pIcode->setAsgn(lhs, rhs); break; case iMOD: - rhs = COND_EXPR::boolOp (lhs, rhs, MOD); + rhs = new BinaryOperator(MOD,lhs, rhs); if ( ll->testFlags(B) ) { - lhs = COND_EXPR::idReg (rAH, 0, &localId); + lhs = AstIdent::Reg (rAH, 0, &localId); pIcode->setRegDU( rAH, eDEF); } else { - lhs = COND_EXPR::idReg (rDX, 0, &localId); + lhs = AstIdent::Reg (rDX, 0, &localId); pIcode->setRegDU( rDX, eDEF); } pIcode->setAsgn(lhs, rhs); @@ -390,23 +390,23 @@ void Function::highLevelGen() break; case iMUL: - rhs = COND_EXPR::boolOp (lhs, rhs, MUL); - lhs = COND_EXPR::id (*ll, LHS_OP, this, i, *pIcode, NONE); + rhs = new BinaryOperator(MUL,lhs, rhs); + lhs = AstIdent::id (*ll, LHS_OP, this, i, *pIcode, NONE); pIcode->setAsgn(lhs, rhs); break; case iNEG: - rhs = COND_EXPR::unary (NEGATION, lhs); + rhs = UnaryOperator::Create(NEGATION, lhs); pIcode->setAsgn(lhs, rhs); break; case iNOT: - rhs = COND_EXPR::boolOp (NULL, rhs, NOT); + rhs = new BinaryOperator(NOT,NULL, rhs); // TODO: change this to unary NOT ? pIcode->setAsgn(lhs, rhs); break; case iOR: - rhs = COND_EXPR::boolOp (lhs, rhs, OR); + rhs = new BinaryOperator(OR,lhs, rhs); pIcode->setAsgn(lhs, rhs); break; @@ -421,13 +421,13 @@ void Function::highLevelGen() break; case iSHL: - rhs = COND_EXPR::boolOp (lhs, rhs, SHL); + rhs = new BinaryOperator(SHL,lhs, rhs); pIcode->setAsgn(lhs, rhs); break; case iSAR: /* signed */ case iSHR: - rhs = COND_EXPR::boolOp (lhs, rhs, SHR); /* unsigned*/ + rhs = new BinaryOperator(SHR,lhs, rhs); /* unsigned*/ pIcode->setAsgn(lhs, rhs); break; @@ -435,7 +435,7 @@ void Function::highLevelGen() break; case iSUB: - rhs = COND_EXPR::boolOp (lhs, rhs, SUB); + rhs = new BinaryOperator(SUB,lhs, rhs); pIcode->setAsgn(lhs, rhs); break; @@ -443,7 +443,7 @@ void Function::highLevelGen() break; case iXOR: - rhs = COND_EXPR::boolOp (lhs, rhs, XOR); + rhs = new BinaryOperator(XOR,lhs, rhs); pIcode->setAsgn(lhs, rhs); break; } @@ -452,49 +452,13 @@ void Function::highLevelGen() } -/* Modifies the given conditional operator to its inverse. This is used - * in if..then[..else] statements, to reflect the condition that takes the - * then part. */ -COND_EXPR *COND_EXPR::inverse () const -{ - static condOp invCondOp[] = {GREATER, GREATER_EQUAL, NOT_EQUAL, EQUAL, - LESS_EQUAL, LESS, DUMMY,DUMMY,DUMMY,DUMMY, - DUMMY, DUMMY, DUMMY, DUMMY, DUMMY, DUMMY, - DUMMY, DBL_OR, DBL_AND}; - COND_EXPR *res=0; - if (m_type == BOOLEAN_OP) - { - switch ( op() ) - { - case LESS_EQUAL: case LESS: case EQUAL: - case NOT_EQUAL: case GREATER: case GREATER_EQUAL: - res = this->clone(); - res->boolExpr.op = invCondOp[op()]; - return res; +/** + \fn COND_EXPR::inverse + Modifies the given conditional operator to its inverse. This is used + in if..then[..else] statements, to reflect the condition that takes the + then part. +*/ - case AND: case OR: case XOR: case NOT: case ADD: - case SUB: case MUL: case DIV: case SHR: case SHL: case MOD: - return COND_EXPR::unary (NEGATION, this->clone()); - - case DBL_AND: case DBL_OR: - // Binary::Create(invertop,lhs->inverse(),rhs->inverse()); - res = this->clone(); - res->boolExpr.op = invCondOp[op()]; - res->boolExpr.lhs=lhs()->inverse (); - res->boolExpr.rhs=rhs()->inverse (); - return res; - default: - fprintf(stderr,"COND_EXPR::inverse unhandled op %d",op()); - } /* eos */ - - } - else if (m_type == NEGATION) //TODO: memleak here - { - return expr.unaryExp->clone(); - } - return this->clone(); - /* other types are left unmodified */ -} /* Returns the string that represents the procedure call of tproc (ie. with * actual parameters) */ @@ -505,7 +469,10 @@ std::string writeCall (Function * tproc, STKFRAME & args, Function * pproc, int ostr<name<<" ("; for(const STKSYM &sym : args) { - ostr << walkCondExpr (sym.actual, pproc, numLoc); + if(sym.actual) + ostr << sym.actual->walkCondExpr (pproc, numLoc); + else + ostr << ""; if((&sym)!=&(args.back())) ostr << ", "; } @@ -523,7 +490,7 @@ char *writeJcond (const HLTYPE &h, Function * pProc, int *numLoc) strcat (buf, "if "); COND_EXPR *inverted=h.expr()->inverse(); //inverseCondOp (&h.exp); - std::string e = walkCondExpr (inverted, pProc, numLoc); + std::string e = inverted->walkCondExpr (pProc, numLoc); delete inverted; strcat (buf, e.c_str()); strcat (buf, " {\n"); @@ -539,42 +506,53 @@ char *writeJcondInv (HLTYPE h, Function * pProc, int *numLoc) memset (buf, ' ', sizeof(buf)); buf[0] = '\0'; strcat (buf, "if "); - std::string e = walkCondExpr (h.expr(), pProc, numLoc); + std::string e = h.expr()->walkCondExpr (pProc, numLoc); strcat (buf, e.c_str()); strcat (buf, " {\n"); return (buf); } -string AssignType::writeOut(Function *pProc, int *numLoc) +string AssignType::writeOut(Function *pProc, int *numLoc) const { ostringstream ostr; - ostr << walkCondExpr (lhs, pProc, numLoc); + ostr << lhs->walkCondExpr (pProc, numLoc); ostr << " = "; - ostr << walkCondExpr (rhs, pProc, numLoc); + ostr << rhs->walkCondExpr (pProc, numLoc); ostr << ";\n"; return ostr.str(); } -string CallType::writeOut(Function *pProc, int *numLoc) +string CallType::writeOut(Function *pProc, int *numLoc) const { ostringstream ostr; ostr << writeCall (proc, *args, pProc,numLoc); ostr << ";\n"; return ostr.str(); } -string ExpType::writeOut(Function *pProc, int *numLoc) +string ExpType::writeOut(Function *pProc, int *numLoc) const { - return walkCondExpr (v, pProc, numLoc); + if(v==nullptr) + return ""; + return v->walkCondExpr (pProc, numLoc); } +void HLTYPE::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; +} /* 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 * done in a separate routine to be able to support the removal of * empty THEN clauses on an if..then..else. */ -string HLTYPE::write1HlIcode (Function * pProc, int *numLoc) +string HLTYPE::write1HlIcode (Function * pProc, int *numLoc) const { string e; ostringstream ostr; - HlTypeSupport *p = get(); + const HlTypeSupport *p = get(); switch (opcode) { case HLI_ASSIGN: diff --git a/src/hltype.cpp b/src/hltype.cpp index ad83e6d..cfe1d18 100644 --- a/src/hltype.cpp +++ b/src/hltype.cpp @@ -9,7 +9,6 @@ void HLTYPE::replaceExpr(COND_EXPR *e) } - HlTypeSupport *HLTYPE::get() { switch(opcode) diff --git a/src/icode.cpp b/src/icode.cpp index 97978ce..0dde24f 100644 --- a/src/icode.cpp +++ b/src/icode.cpp @@ -95,3 +95,14 @@ void LLOperand::addProcInformation(int param_count, uint32_t call_conv) proc.cb = param_count; proc.proc->flg |= call_conv; } +void HLTYPE::setCall(Function *proc) +{ + opcode = HLI_CALL; + call.proc = proc; + call.args = new STKFRAME; +} +bool AssignType::removeRegFromLong(eReg regi, LOCAL_ID *locId) +{ + lhs->performLongRemoval(regi,locId); + return true; +} diff --git a/src/idioms/arith_idioms.cpp b/src/idioms/arith_idioms.cpp index 053e574..cb3a203 100644 --- a/src/idioms/arith_idioms.cpp +++ b/src/idioms/arith_idioms.cpp @@ -25,10 +25,11 @@ bool Idiom5::match(iICODE pIcode) int Idiom5::action() { - COND_EXPR *rhs,*lhs,*expr; - lhs = COND_EXPR::idLong (&m_func->localId, DST, m_icodes[0], LOW_FIRST, m_icodes[0], USE_DEF, *m_icodes[1]->ll()); - rhs = COND_EXPR::idLong (&m_func->localId, SRC, m_icodes[0], LOW_FIRST, m_icodes[0], eUSE, *m_icodes[1]->ll()); - expr = COND_EXPR::boolOp (lhs, rhs, ADD); + AstIdent *rhs,*lhs; + COND_EXPR *expr; + lhs = AstIdent::idLong (&m_func->localId, DST, m_icodes[0], LOW_FIRST, m_icodes[0], USE_DEF, *m_icodes[1]->ll()); + rhs = AstIdent::idLong (&m_func->localId, SRC, m_icodes[0], LOW_FIRST, m_icodes[0], eUSE, *m_icodes[1]->ll()); + expr = new BinaryOperator(ADD,lhs, rhs); m_icodes[0]->setAsgn(lhs, expr); m_icodes[1]->invalidate(); return 2; @@ -58,10 +59,12 @@ bool Idiom6::match(iICODE pIcode) int Idiom6::action() { - COND_EXPR *rhs,*lhs,*expr; - lhs = COND_EXPR::idLong (&m_func->localId, DST, m_icodes[0], LOW_FIRST, m_icodes[0], USE_DEF, *m_icodes[1]->ll()); - rhs = COND_EXPR::idLong (&m_func->localId, SRC, m_icodes[0], LOW_FIRST, m_icodes[0], eUSE, *m_icodes[1]->ll()); - expr = COND_EXPR::boolOp (lhs, rhs, SUB); + + AstIdent *rhs,*lhs; + COND_EXPR *expr; + lhs = AstIdent::idLong (&m_func->localId, DST, m_icodes[0], LOW_FIRST, m_icodes[0], USE_DEF, *m_icodes[1]->ll()); + rhs = AstIdent::idLong (&m_func->localId, SRC, m_icodes[0], LOW_FIRST, m_icodes[0], eUSE, *m_icodes[1]->ll()); + expr = new BinaryOperator(SUB,lhs, rhs); m_icodes[0]->setAsgn(lhs, expr); m_icodes[1]->invalidate(); return 2; @@ -163,12 +166,12 @@ bool Idiom18::match(iICODE picode) int Idiom18::action() // action length { - COND_EXPR *rhs, *lhs; /* Pointers to left and right hand side exps */ + COND_EXPR *rhs,*lhs;/* Pointers to left and right hand side exps */ COND_EXPR *expr; - lhs = COND_EXPR::id (*m_icodes[0]->ll(), SRC, m_func, m_icodes[1], *m_icodes[1], eUSE); - lhs = COND_EXPR::unary ( m_is_dec ? POST_DEC : POST_INC, lhs); - rhs = COND_EXPR::id (*m_icodes[2]->ll(), SRC, m_func, m_icodes[1], *m_icodes[3], eUSE); - expr = COND_EXPR::boolOp (lhs, rhs, condOpJCond[m_icodes[3]->ll()->getOpcode() - iJB]); + lhs = AstIdent::id (*m_icodes[0]->ll(), SRC, m_func, m_icodes[1], *m_icodes[1], eUSE); + lhs = UnaryOperator::Create(m_is_dec ? POST_DEC : POST_INC, lhs); + rhs = AstIdent::id (*m_icodes[2]->ll(), SRC, m_func, m_icodes[1], *m_icodes[3], eUSE); + expr = new BinaryOperator(condOpJCond[m_icodes[3]->ll()->getOpcode() - iJB],lhs, rhs); m_icodes[3]->setJCond(expr); m_icodes[0]->invalidate(); @@ -220,10 +223,10 @@ int Idiom19::action() { COND_EXPR *lhs,*rhs,*expr; ICODE &ic1(*m_icodes[1]); - lhs = COND_EXPR::id (*m_icodes[0]->ll(), DST, m_func, m_icodes[0], *m_icodes[1], eUSE); - lhs = COND_EXPR::unary (m_is_dec ? PRE_DEC : PRE_INC, lhs); - rhs = COND_EXPR::idKte (0, 2); - expr = COND_EXPR::boolOp (lhs, rhs, condOpJCond[m_icodes[1]->ll()->getOpcode() - iJB]); + lhs = AstIdent::id (*m_icodes[0]->ll(), DST, m_func, m_icodes[0], *m_icodes[1], eUSE); + lhs = UnaryOperator::Create(m_is_dec ? PRE_DEC : PRE_INC, lhs); + rhs = AstIdent::Kte (0, 2); + expr = new BinaryOperator(condOpJCond[m_icodes[1]->ll()->getOpcode() - iJB],lhs, rhs); m_icodes[1]->setJCond(expr); m_icodes[0]->invalidate(); return 2; @@ -310,10 +313,10 @@ bool Idiom20::match(iICODE picode) int Idiom20::action() { COND_EXPR *lhs,*rhs,*expr; - lhs = COND_EXPR::id (*m_icodes[1]->ll(), SRC, m_func, m_icodes[0], *m_icodes[0], eUSE); - lhs = COND_EXPR::unary (m_is_dec, lhs); - rhs = COND_EXPR::id (*m_icodes[2]->ll(), SRC, m_func, m_icodes[0], *m_icodes[3], eUSE); - expr = COND_EXPR::boolOp (lhs, rhs, condOpJCond[m_icodes[3]->ll()->getOpcode() - iJB]); + lhs = AstIdent::id (*m_icodes[1]->ll(), SRC, m_func, m_icodes[0], *m_icodes[0], eUSE); + lhs = UnaryOperator::Create(m_is_dec, lhs); + rhs = AstIdent::id (*m_icodes[2]->ll(), SRC, m_func, m_icodes[0], *m_icodes[3], eUSE); + expr = new BinaryOperator(condOpJCond[m_icodes[3]->ll()->getOpcode() - iJB],lhs, rhs); m_icodes[3]->setJCond(expr); for(int i=0; i<3; ++i) m_icodes[i]->invalidate(); diff --git a/src/idioms/mov_idioms.cpp b/src/idioms/mov_idioms.cpp index 5dae4f7..592c5e6 100644 --- a/src/idioms/mov_idioms.cpp +++ b/src/idioms/mov_idioms.cpp @@ -49,11 +49,13 @@ bool Idiom14::match(iICODE pIcode) int Idiom14::action() { int idx; - COND_EXPR *lhs,*rhs; + AstIdent *lhs; + COND_EXPR *rhs; + idx = m_func->localId.newLongReg (TYPE_LONG_SIGN, m_regH, m_regL, m_icodes[0]); - lhs = COND_EXPR::idLongIdx (idx); + lhs = AstIdent::LongIdx (idx); m_icodes[0]->setRegDU( m_regH, eDEF); - rhs = COND_EXPR::id (*m_icodes[0]->ll(), SRC, m_func, m_icodes[0], *m_icodes[0], NONE); + rhs = AstIdent::id (*m_icodes[0]->ll(), SRC, m_func, m_icodes[0], *m_icodes[0], NONE); m_icodes[0]->setAsgn(lhs, rhs); m_icodes[1]->invalidate(); return 2; @@ -98,11 +100,12 @@ bool Idiom13::match(iICODE pIcode) int Idiom13::action() { - COND_EXPR *lhs,*rhs; - lhs = COND_EXPR::idReg (m_loaded_reg, 0, &m_func->localId); + AstIdent *lhs; + COND_EXPR *rhs; + lhs = AstIdent::Reg (m_loaded_reg, 0, &m_func->localId); m_icodes[0]->setRegDU( m_loaded_reg, eDEF); m_icodes[0]->du1.numRegsDef--; /* prev uint8_t reg def */ - rhs = COND_EXPR::id (*m_icodes[0]->ll(), SRC, m_func, m_icodes[0], *m_icodes[0], NONE); + rhs = AstIdent::id (*m_icodes[0]->ll(), SRC, m_func, m_icodes[0], *m_icodes[0], NONE); m_icodes[0]->setAsgn(lhs, rhs); m_icodes[1]->invalidate(); return 2; diff --git a/src/idioms/neg_idioms.cpp b/src/idioms/neg_idioms.cpp index fca8680..00c8166 100644 --- a/src/idioms/neg_idioms.cpp +++ b/src/idioms/neg_idioms.cpp @@ -52,9 +52,10 @@ bool Idiom11::match (iICODE picode) } int Idiom11::action() { - COND_EXPR *lhs,*rhs; - lhs = COND_EXPR::idLong (&m_func->localId, DST, m_icodes[0], HIGH_FIRST,m_icodes[0], USE_DEF, *m_icodes[1]->ll()); - rhs = COND_EXPR::unary (NEGATION, lhs); + AstIdent *lhs; + COND_EXPR *rhs; + lhs = AstIdent::idLong (&m_func->localId, DST, m_icodes[0], HIGH_FIRST,m_icodes[0], USE_DEF, *m_icodes[1]->ll()); + rhs = UnaryOperator::Create(NEGATION, lhs); m_icodes[0]->setAsgn(lhs, rhs); m_icodes[1]->invalidate(); m_icodes[2]->invalidate(); @@ -94,9 +95,10 @@ bool Idiom16::match (iICODE picode) } int Idiom16::action() { - COND_EXPR *lhs,*rhs; - lhs = COND_EXPR::idReg (m_icodes[0]->ll()->dst.regi, m_icodes[0]->ll()->getFlag(),&m_func->localId); - rhs = COND_EXPR::unary (NEGATION, lhs->clone()); + AstIdent *lhs; + COND_EXPR *rhs; + lhs = AstIdent::Reg (m_icodes[0]->ll()->dst.regi, m_icodes[0]->ll()->getFlag(),&m_func->localId); + rhs = UnaryOperator::Create(NEGATION, lhs->clone()); m_icodes[0]->setAsgn(lhs, rhs); m_icodes[1]->invalidate(); m_icodes[2]->invalidate(); diff --git a/src/idioms/shift_idioms.cpp b/src/idioms/shift_idioms.cpp index 49c0694..9393334 100644 --- a/src/idioms/shift_idioms.cpp +++ b/src/idioms/shift_idioms.cpp @@ -28,16 +28,17 @@ bool Idiom8::match(iICODE pIcode) int Idiom8::action() { int idx; - COND_EXPR *rhs,*lhs,*expr; + AstIdent *lhs; + COND_EXPR *rhs,*expr; eReg regH,regL; regH=m_icodes[0]->ll()->dst.regi; regL=m_icodes[1]->ll()->dst.regi; idx = m_func->localId.newLongReg (TYPE_LONG_SIGN, regH, regL, m_icodes[0]); - lhs = COND_EXPR::idLongIdx (idx); + lhs = AstIdent::LongIdx (idx); m_icodes[0]->setRegDU( regL, USE_DEF); - rhs = COND_EXPR::idKte(1,2); - expr = COND_EXPR::boolOp(lhs, rhs, SHR); + rhs = AstIdent::Kte(1,2); + expr = new BinaryOperator(SHR,lhs, rhs); m_icodes[0]->setAsgn(lhs, expr); m_icodes[1]->invalidate(); return 2; @@ -78,12 +79,14 @@ bool Idiom15::match(iICODE pIcode) int Idiom15::action() { - COND_EXPR *lhs,*rhs,*_exp; - lhs = COND_EXPR::idReg (m_icodes[0]->ll()->dst.regi, + AstIdent *lhs; + + COND_EXPR *rhs,*_exp; + lhs = AstIdent::Reg (m_icodes[0]->ll()->dst.regi, m_icodes[0]->ll()->getFlag() & NO_SRC_B, &m_func->localId); - rhs = COND_EXPR::idKte (m_icodes.size(), 2); - _exp = COND_EXPR::boolOp (lhs, rhs, SHL); + rhs = AstIdent::Kte (m_icodes.size(), 2); + _exp = new BinaryOperator(SHL,lhs, rhs); m_icodes[0]->setAsgn(lhs, _exp); for (size_t i=1; ill()->dst.regi; regH=m_icodes[1]->ll()->dst.regi; idx = m_func->localId.newLongReg (TYPE_LONG_UNSIGN, regH, regL,m_icodes[0]); - lhs = COND_EXPR::idLongIdx (idx); + lhs = AstIdent::LongIdx (idx); m_icodes[0]->setRegDU( regH, USE_DEF); - rhs = COND_EXPR::idKte (1, 2); - expr = COND_EXPR::boolOp (lhs, rhs, SHL); + rhs = AstIdent::Kte (1, 2); + expr = new BinaryOperator(SHL,lhs, rhs); m_icodes[0]->setAsgn(lhs, expr); m_icodes[1]->invalidate(); return 2; @@ -155,15 +160,16 @@ bool Idiom9::match(iICODE pIcode) int Idiom9::action() { int idx; - COND_EXPR *rhs,*lhs,*expr; + AstIdent *lhs; + COND_EXPR *rhs,*expr; eReg regH,regL; regL=m_icodes[1]->ll()->dst.regi; regH=m_icodes[0]->ll()->dst.regi; idx = m_func->localId.newLongReg (TYPE_LONG_UNSIGN,regH,regL,m_icodes[0]); - lhs = COND_EXPR::idLongIdx (idx); + lhs = AstIdent::LongIdx (idx); m_icodes[0]->setRegDU(regL, USE_DEF); - rhs = COND_EXPR::idKte (1, 2); - expr = COND_EXPR::boolOp (lhs, rhs, SHR); + rhs = AstIdent::Kte (1, 2); + expr = new BinaryOperator(SHR,lhs, rhs); m_icodes[0]->setAsgn(lhs, expr); m_icodes[1]->invalidate(); return 2; diff --git a/src/idioms/xor_idioms.cpp b/src/idioms/xor_idioms.cpp index 279f4b8..ca24a58 100644 --- a/src/idioms/xor_idioms.cpp +++ b/src/idioms/xor_idioms.cpp @@ -39,9 +39,11 @@ bool Idiom21::match (iICODE picode) } int Idiom21::action() { - COND_EXPR *lhs,*rhs; - lhs = COND_EXPR::idLong (&m_func->localId, DST, m_icodes[0],HIGH_FIRST, m_icodes[0], eDEF, *m_icodes[1]->ll()); - rhs = COND_EXPR::idKte (m_icodes[1]->ll()->src().getImm2() , 4); + COND_EXPR *rhs; + AstIdent *lhs; + + lhs = AstIdent::idLong (&m_func->localId, DST, m_icodes[0],HIGH_FIRST, m_icodes[0], eDEF, *m_icodes[1]->ll()); + rhs = AstIdent::Kte (m_icodes[1]->ll()->src().getImm2() , 4); m_icodes[0]->setAsgn(lhs, rhs); m_icodes[0]->du.use = 0; /* clear register used in iXOR */ m_icodes[1]->invalidate(); @@ -82,10 +84,11 @@ bool Idiom7::match(iICODE picode) } int Idiom7::action() { - COND_EXPR *lhs,*rhs; - lhs = COND_EXPR::id (*m_icode->ll(), DST, m_func, m_icode, *m_icode, NONE); - rhs = COND_EXPR::idKte (0, 2); - m_icode->setAsgn(lhs, rhs); + COND_EXPR *lhs; + COND_EXPR *rhs; + lhs = AstIdent::id (*m_icode->ll(), DST, m_func, m_icode, *m_icode, NONE); + rhs = AstIdent::Kte (0, 2); + m_icode->setAsgn(dynamic_cast(lhs), rhs); m_icode->du.use = 0; /* clear register used in iXOR */ m_icode->ll()->setFlags(I); return 1; diff --git a/src/locident.cpp b/src/locident.cpp index 54e24d4..5cd272a 100644 --- a/src/locident.cpp +++ b/src/locident.cpp @@ -176,9 +176,9 @@ int LOCAL_ID::newLongReg(hlType t, eReg regH, eReg regL, iICODE ix_) } /* Returns an identifier conditional expression node of type TYPE_LONG or * TYPE_WORD_SIGN */ -COND_EXPR * LOCAL_ID::createId(const ID *retVal, iICODE ix_) +AstIdent * LOCAL_ID::createId(const ID *retVal, iICODE ix_) { - return COND_EXPR::idID(retVal,this,ix_); + return AstIdent::idID(retVal,this,ix_); } /* Checks if the entry exists in the locSym, if so, returns the idx to this @@ -337,18 +337,18 @@ boolT checkLongEq (LONG_STKID_TYPE longId, iICODE pIcode, int i, Function * pPro if ((longId.offH == pmHdst->off) && (longId.offL == pmLdst->off)) { - asgn.lhs = COND_EXPR::idLongIdx (i); + asgn.lhs = AstIdent::LongIdx (i); if ( not pIcode->ll()->testFlags(NO_SRC) ) { - asgn.rhs = COND_EXPR::idLong (&pProc->localId, SRC, pIcode, HIGH_FIRST, pIcode, eUSE, atOffset); + asgn.rhs = AstIdent::idLong (&pProc->localId, SRC, pIcode, HIGH_FIRST, pIcode, eUSE, atOffset); } return true; } else if ((longId.offH == pmHsrc->off) && (longId.offL == pmLsrc->off)) { - asgn.lhs = COND_EXPR::idLong (&pProc->localId, DST, pIcode, HIGH_FIRST, pIcode,eDEF, atOffset); - asgn.rhs = COND_EXPR::idLongIdx (i); + asgn.lhs = AstIdent::idLong (&pProc->localId, DST, pIcode, HIGH_FIRST, pIcode,eDEF, atOffset); + asgn.rhs = AstIdent::LongIdx (i); return true; } return false; @@ -377,17 +377,17 @@ boolT checkLongRegEq (LONGID_TYPE longId, iICODE pIcode, int i, if ((longId.h == pmHdst->regi) && (longId.l == pmLdst->regi)) { - asgn.lhs = COND_EXPR::idLongIdx (i); + asgn.lhs = AstIdent::LongIdx (i); if ( not pIcode->ll()->testFlags(NO_SRC) ) { - asgn.rhs = COND_EXPR::idLong (&pProc->localId, SRC, pIcode, HIGH_FIRST, pIcode, eUSE, atOffset); + asgn.rhs = AstIdent::idLong (&pProc->localId, SRC, pIcode, HIGH_FIRST, pIcode, eUSE, atOffset); } return true; } else if ((longId.h == pmHsrc->regi) && (longId.l == pmLsrc->regi)) { - asgn.lhs = COND_EXPR::idLong (&pProc->localId, DST, pIcode, HIGH_FIRST, pIcode, eDEF, atOffset); - asgn.rhs = COND_EXPR::idLongIdx (i); + asgn.lhs = AstIdent::idLong (&pProc->localId, DST, pIcode, HIGH_FIRST, pIcode, eDEF, atOffset); + asgn.rhs = AstIdent::LongIdx (i); return true; } return false; diff --git a/src/parser.cpp b/src/parser.cpp index 4a1be24..b3f5dd1 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -229,7 +229,8 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate) case iJE: case iJNE: case iJS: case iJNS: case iJO: case iJNO: case iJP: case iJNP: case iJCXZ: - { STATE StCopy; + { + STATE StCopy; int ip = Icode.size()-1; /* Index of this jump */ ICODE &prev(*(++Icode.rbegin())); /* Previous icode */ boolT fBranch = false; @@ -247,7 +248,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate) if (ll->getOpcode() == iJAE || ll->getOpcode() == iJA) pstate->JCond.regi = prev.ll()->dst.regi; fBranch = (bool) - (ll->getOpcode() == iJB || ll->getOpcode() == iJBE); + (ll->getOpcode() == iJB || ll->getOpcode() == iJBE); } StCopy = *pstate; //memcpy(&StCopy, pstate, sizeof(STATE)); @@ -308,10 +309,10 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate) if (funcNum == 0x09) { operand = ((uint32_t)(uint16_t)pstate->r[rDS]<<4) + - (uint32_t)(uint16_t)pstate->r[rDX]; + (uint32_t)(uint16_t)pstate->r[rDX]; size = prog.fCOM ? - strSize (&prog.Image[operand], '$') : - strSize (&prog.Image[operand], '$'); // + 0x100 + strSize (&prog.Image[operand], '$') : + strSize (&prog.Image[operand], '$'); // + 0x100 global_symbol_table.updateSymType (operand, TypeContainer(TYPE_STR, size)); } } @@ -581,9 +582,9 @@ boolT Function::process_CALL (ICODE & pIcode, CALL_GRAPH * pcallGraph, STATE *ps if(pIcode.ll()->dst.isReg()) { if( not pstate->isKnown(pIcode.ll()->dst.regi) - or - not pstate->isKnown(pIcode.ll()->dst.seg) - ) + or + not pstate->isKnown(pIcode.ll()->dst.seg) + ) { fprintf(stderr,"Indirect call with unkown register values\n"); return false; @@ -596,7 +597,7 @@ boolT Function::process_CALL (ICODE & pIcode, CALL_GRAPH * pcallGraph, STATE *ps else { off = (uint32_t)(uint16_t)pIcode.ll()->dst.off + - ((uint32_t)(uint16_t)pIcode.ll()->dst.segValue << 4); + ((uint32_t)(uint16_t)pIcode.ll()->dst.segValue << 4); } /* Address of function is given by 4 (CALLF) or 2 (CALL) bytes at @@ -799,30 +800,30 @@ static SYM * lookupAddr (LLOperand *pm, STATE *pstate, int size, uint16_t duFlag if (pm->regi != rUNDEF) return nullptr; // register or indexed - /* Global var */ + /* Global var */ if (pm->segValue) /* there is a value in the seg field */ { - operand = opAdr (pm->segValue, pm->off); + operand = opAdr (pm->segValue, pm->off); psym = Project::get()->symtab.updateGlobSym (operand, size, duFlag,created_new); - } + } else if (pstate->f[pm->seg]) /* new value */ { - pm->segValue = pstate->r[pm->seg]; - operand = opAdr(pm->segValue, pm->off); + pm->segValue = pstate->r[pm->seg]; + operand = opAdr(pm->segValue, pm->off); psym = Project::get()->symtab.updateGlobSym (operand, size, duFlag,created_new); - /* Flag new memory locations that are segment values */ + /* Flag new memory locations that are segment values */ if (created_new) - { - if (size == 4) - operand += 2; /* High uint16_t */ - for (i = 0; i < prog.cReloc; i++) - if (prog.relocTable[i] == operand) { - psym->flg = SEG_IMMED; - break; - } - } + { + if (size == 4) + operand += 2; /* High uint16_t */ + for (i = 0; i < prog.cReloc; i++) + if (prog.relocTable[i] == operand) { + psym->flg = SEG_IMMED; + break; + } } + } /* Check for out of bounds */ if (psym and (psym->label < (uint32_t)prog.cbImage)) return psym; @@ -887,15 +888,15 @@ static void setBits(int16_t type, uint32_t start, uint32_t len) /* DU bit definitions for each reg value - including index registers */ LivenessSet duReg[] = { 0x00, - //AH AL . . AX, BH - 0x11001, 0x22002, 0x44004, 0x88008, /* uint16_t regs */ - 0x10, 0x20, 0x40, 0x80, - 0x100, 0x200, 0x400, 0x800, /* seg regs */ - 0x1000, 0x2000, 0x4000, 0x8000, /* uint8_t regs */ - 0x10000, 0x20000, 0x40000, 0x80000, - 0x100000, /* tmp reg */ - 0x48, 0x88, 0x60, 0xA0, /* index regs */ - 0x40, 0x80, 0x20, 0x08 }; + //AH AL . . AX, BH + 0x11001, 0x22002, 0x44004, 0x88008, /* uint16_t regs */ + 0x10, 0x20, 0x40, 0x80, + 0x100, 0x200, 0x400, 0x800, /* seg regs */ + 0x1000, 0x2000, 0x4000, 0x8000, /* uint8_t regs */ + 0x10000, 0x20000, 0x40000, 0x80000, + 0x100000, /* tmp reg */ + 0x48, 0x88, 0x60, 0xA0, /* index regs */ + 0x40, 0x80, 0x20, 0x08 }; /* Checks which registers were used and updates the du.u flag. @@ -1184,9 +1185,9 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate) pIcode.du1.numRegsDef++; case iLODS: pIcode.du.addDefinedAndUsed(rSI); - pIcode.du.def |= duReg[(cb==2)? rAX: rAL]; + pIcode.du.def.addReg((cb==2)? rAX: rAL); pIcode.du1.numRegsDef += 2; - pIcode.du.use |= duReg[sseg]; + pIcode.du.use.addReg(sseg); break; case iREP_OUTS: diff --git a/src/procs.cpp b/src/procs.cpp index 2fb9ab4..86102ef 100644 --- a/src/procs.cpp +++ b/src/procs.cpp @@ -90,7 +90,7 @@ void CALL_GRAPH::write() * Note: register(s) are only included once in the table. */ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const { - COND_EXPR *lhs; + AstIdent *lhs; STKFRAME * call_args_stackframe, *target_stackframe; const ID *id; int tidx; @@ -106,11 +106,12 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const /* Get registers and index into target procedure's local list */ call_args_stackframe = ticode->hl()->call.args; target_stackframe = &tproc->args; - lhs = picode->hl()->asgn.lhs; - type = lhs->expr.ident.idType; + lhs = dynamic_cast(picode->hl()->asgn.lhs); + assert(lhs); + type = lhs->ident.idType; if (type == REGISTER) { - regL = id_arr[lhs->expr.ident.idNode.regiIdx].id.regi; + regL = id_arr[lhs->ident.idNode.regiIdx].id.regi; if (regL < rAL) tidx = tproc->localId.newByteWordReg(TYPE_WORD_SIGN, regL); else @@ -118,7 +119,7 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const } else if (type == LONG_VAR) { - int longIdx = lhs->expr.ident.idNode.longIdx; + int longIdx = lhs->ident.idNode.longIdx; regL = id_arr[longIdx].id.longId.l; regH = id_arr[longIdx].id.longId.h; tidx = tproc->localId.newLongReg(TYPE_LONG_SIGN, regH, regL, tproc->Icode.begin() /*0*/); @@ -132,14 +133,14 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const continue; if (type == REGISTER) { - if ( tgt_sym.regs->expr.ident.idNode.regiIdx == tidx ) + if ( tgt_sym.regs->ident.idNode.regiIdx == tidx ) { regExist = true; } } else if (type == LONG_VAR) { - if ( tgt_sym.regs->expr.ident.idNode.longIdx == tidx ) + if ( tgt_sym.regs->ident.idNode.longIdx == tidx ) { regExist = true; } @@ -160,18 +161,18 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const if (regL < rAL) { newsym.type = TYPE_WORD_SIGN; - newsym.regs = COND_EXPR::idRegIdx(tidx, WORD_REG); + newsym.regs = AstIdent::RegIdx(tidx, WORD_REG); } else { newsym.type = TYPE_BYTE_SIGN; - newsym.regs = COND_EXPR::idRegIdx(tidx, BYTE_REG); + newsym.regs = AstIdent::RegIdx(tidx, BYTE_REG); } tproc->localId.id_arr[tidx].name = newsym.name; } else if (type == LONG_VAR) { - newsym.regs = COND_EXPR::idLongIdx (tidx); + newsym.regs = AstIdent::LongIdx (tidx); newsym.type = TYPE_LONG_SIGN; tproc->localId.id_arr[tidx].name = newsym.name; tproc->localId.propLongId (regL, regH, tproc->localId.id_arr[tidx].name.c_str()); @@ -188,7 +189,7 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const /* Mask off high and low register(s) in picode */ switch (type) { case REGISTER: - id = &id_arr[lhs->expr.ident.idNode.regiIdx]; + id = &id_arr[lhs->ident.idNode.regiIdx]; picode->du.def &= maskDuReg[id->id.regi]; if (id->id.regi < rAL) newsym.type = TYPE_WORD_SIGN; @@ -196,7 +197,7 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const newsym.type = TYPE_BYTE_SIGN; break; case LONG_VAR: - id = &id_arr[lhs->expr.ident.idNode.longIdx]; + id = &id_arr[lhs->ident.idNode.longIdx]; picode->du.def &= maskDuReg[id->id.longId.h]; picode->du.def &= maskDuReg[id->id.longId.l]; newsym.type = TYPE_LONG_SIGN; @@ -216,15 +217,17 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const */ bool CallType::newStkArg(COND_EXPR *exp, llIcode opcode, Function * pproc) { + AstIdent *expr = dynamic_cast(exp); + uint8_t regi; /* Check for far procedure call, in which case, references to segment * registers are not be considered another parameter (i.e. they are * long references to another segment) */ - if (exp) + if (expr) { - if ((exp->m_type == IDENTIFIER) && (exp->expr.ident.idType == REGISTER)) + if (expr->ident.idType == REGISTER) { - regi = pproc->localId.id_arr[exp->expr.ident.idNode.regiIdx].id.regi; + regi = pproc->localId.id_arr[expr->ident.idNode.regiIdx].id.regi; if ((regi >= rES) && (regi <= rDS)) { if (opcode == iCALLF) @@ -254,24 +257,25 @@ void CallType::placeStkArg (COND_EXPR *exp, int pos) COND_EXPR *CallType::toId() { - return COND_EXPR::idFunc( proc, args); + return AstIdent::idFunc( proc, args); } /* Checks to determine whether the expression (actual argument) has the * same type as the given type (from the procedure's formal list). If not, * the actual argument gets modified */ -void adjustActArgType (COND_EXPR *exp, hlType forType, Function * pproc) +void adjustActArgType (COND_EXPR *_exp, hlType forType, Function * pproc) { + AstIdent *expr = dynamic_cast(_exp); PROG &prog(Project::get()->prog); hlType actType; int offset, offL; - if (exp == NULL) + if (expr == NULL) return; - actType = exp-> expType (pproc); - if (((actType == forType) || (exp->m_type != IDENTIFIER))) + actType = expr-> expType (pproc); + if (actType == forType) return; switch (forType) { @@ -290,13 +294,13 @@ void adjustActArgType (COND_EXPR *exp, hlType forType, Function * pproc) case TYPE_CONST: /* It's an offset into image where a string is * found. Point to the string. */ - offL = exp->expr.ident.idNode.kte.kte; + offL = expr->ident.idNode.kte.kte; if (prog.fCOM) offset = (pproc->state.r[rDS]<<4) + offL + 0x100; else offset = (pproc->state.r[rDS]<<4) + offL; - exp->expr.ident.idNode.strIdx = offset; - exp->expr.ident.idType = STRING; + expr->ident.idNode.strIdx = offset; + expr->ident.idType = STRING; break; case TYPE_PTR: diff --git a/src/proplong.cpp b/src/proplong.cpp index 34bf54b..6f6aa28 100644 --- a/src/proplong.cpp +++ b/src/proplong.cpp @@ -142,7 +142,8 @@ static int longJCond23 (Assignment &asgn, iICODE pIcode, int arc, iICODE atOffse iICODE atOffset1(atOffset),next1(++iICODE(pIcode)); advance(atOffset1,1); /* Create new HLI_JCOND and condition */ - asgn.lhs = COND_EXPR::boolOp (asgn.lhs, asgn.rhs, condOpJCond[atOffset1->ll()->getOpcode()-iJB]); + condOp oper=condOpJCond[atOffset1->ll()->getOpcode()-iJB]; + asgn.lhs = new BinaryOperator(oper,asgn.lhs, asgn.rhs); next1->setJCond(asgn.lhs); next1->copyDU(*pIcode, eUSE, eUSE); next1->du.use |= atOffset->du.use; @@ -177,7 +178,8 @@ static int longJCond22 (Assignment &asgn, iICODE pIcode,iICODE pEnd) iICODE icodes[] = { pIcode++,pIcode++,pIcode++,pIcode++ }; /* Form conditional expression */ - asgn.lhs = COND_EXPR::boolOp (asgn.lhs, asgn.rhs, condOpJCond[icodes[3]->ll()->getOpcode() - iJB]); + condOp oper=condOpJCond[icodes[3]->ll()->getOpcode() - iJB]; + asgn.lhs = new BinaryOperator(oper,asgn.lhs, asgn.rhs); icodes[1]->setJCond(asgn.lhs); icodes[1]->copyDU (*icodes[0], eUSE, eUSE); icodes[1]->du.use |= icodes[2]->du.use; @@ -253,20 +255,27 @@ void Function::propLongStk (int i, const ID &pLocId) switch (pIcode->ll()->getOpcode()) { case iMOV: - pIcode->setAsgn(asgn.lhs, asgn.rhs); + pIcode->setAsgn(dynamic_cast(asgn.lhs), asgn.rhs); next1->invalidate(); break; case iAND: case iOR: case iXOR: - switch (pIcode->ll()->getOpcode()) { - case iAND: asgn.rhs = COND_EXPR::boolOp (asgn.lhs, asgn.rhs, AND); break; - case iOR: asgn.rhs = COND_EXPR::boolOp (asgn.lhs, asgn.rhs, OR); break; - case iXOR: asgn.rhs = COND_EXPR::boolOp (asgn.lhs, asgn.rhs, XOR); break; + condOp oper = DUMMY; + switch (pIcode->ll()->getOpcode()) + { + case iAND: oper=AND; break; + case iOR: oper=OR; break; + case iXOR: oper=XOR; break; + } + if(DUMMY!=oper) + { + asgn.rhs = new BinaryOperator(oper,asgn.lhs, asgn.rhs); + } + pIcode->setAsgn(dynamic_cast(asgn.lhs), asgn.rhs); + next1->invalidate(); + break; } - pIcode->setAsgn(asgn.lhs, asgn.rhs); - next1->invalidate(); - break; case iPUSH: pIcode->setUnary( HLI_PUSH, asgn.lhs); @@ -326,8 +335,8 @@ int Function::findBackwarLongDefs(int loc_ident_idx, const ID &pLocId, iICODE be { localId.id_arr[loc_ident_idx].idx.push_back(pIcode);//idx-1//insert icode.setRegDU( pmL->regi, eDEF); - asgn.lhs = COND_EXPR::idLongIdx (loc_ident_idx); - asgn.rhs = COND_EXPR::idLong (&this->localId, SRC, pIcode, HIGH_FIRST, pIcode, eUSE, *next1->ll()); + asgn.lhs = AstIdent::LongIdx (loc_ident_idx); + asgn.rhs = AstIdent::idLong (&this->localId, SRC, pIcode, HIGH_FIRST, pIcode, eUSE, *next1->ll()); icode.setAsgn(asgn.lhs, asgn.rhs); next1->invalidate(); forced_finish=true; /* to exit the loop */ @@ -339,7 +348,7 @@ int Function::findBackwarLongDefs(int loc_ident_idx, const ID &pLocId, iICODE be pmL = &icode.ll()->dst; if ((pLocId.id.longId.h == pmH->regi) && (pLocId.id.longId.l == pmL->regi)) { - asgn.lhs = COND_EXPR::idLongIdx (loc_ident_idx); + asgn.lhs = AstIdent::LongIdx (loc_ident_idx); icode.setRegDU( pmH->regi, eDEF); icode.setUnary(HLI_POP, asgn.lhs); next1->invalidate(); @@ -355,19 +364,18 @@ int Function::findBackwarLongDefs(int loc_ident_idx, const ID &pLocId, iICODE be pmH = &next1->ll()->dst; if ((pLocId.id.longId.h == pmH->regi) && (pLocId.id.longId.l == pmL->regi)) { - asgn.lhs = COND_EXPR::idLongIdx (loc_ident_idx); - asgn.rhs = COND_EXPR::idLong (&this->localId, SRC, pIcode, LOW_FIRST, pIcode, eUSE, *next1->ll()); + asgn.lhs = AstIdent::LongIdx (loc_ident_idx); + asgn.rhs = AstIdent::idLong (&this->localId, SRC, pIcode, LOW_FIRST, pIcode, eUSE, *next1->ll()); icode.setRegDU( pmH->regi, USE_DEF); + condOp toCreate=DUMMY; switch (icode.ll()->getOpcode()) { - case iAND: asgn.rhs = COND_EXPR::boolOp (asgn.lhs, asgn.rhs, AND); - break; - case iOR: - asgn.rhs = COND_EXPR::boolOp (asgn.lhs, asgn.rhs, OR); - break; - case iXOR: asgn.rhs = COND_EXPR::boolOp (asgn.lhs, asgn.rhs, XOR); - break; + case iAND: toCreate = AND; break; + case iOR: toCreate = OR; break; + case iXOR: toCreate = XOR; break; } /* eos */ + if(toCreate != DUMMY) + asgn.rhs = new BinaryOperator(toCreate,asgn.lhs, asgn.rhs); icode.setAsgn(asgn.lhs, asgn.rhs); next1->invalidate(); forced_finish=true; /* to exit the loop */ @@ -398,31 +406,42 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be switch (pIcode->ll()->getOpcode()) { case iMOV: - if ((pLocId.id.longId.h == pIcode->ll()->src().getReg2()) && - (pLocId.id.longId.l == next1->ll()->src().getReg2())) { - pIcode->setRegDU( next1->ll()->src().getReg2(), eUSE); + const LONGID_TYPE &ref_long(pLocId.id.longId); + const LLOperand &src_op1(pIcode->ll()->src()); + const LLOperand &src_op2(next1->ll()->src()); + eReg srcReg1=src_op1.getReg2(); + eReg srcReg2=src_op2.getReg2(); + if ((ref_long.h == srcReg1) && (ref_long.l == srcReg2)) + { + pIcode->setRegDU( next1->ll()->src().getReg2(), eUSE); - asgn.rhs = COND_EXPR::idLongIdx (loc_ident_idx); - asgn.lhs = COND_EXPR::idLong (&this->localId, DST, pIcode,HIGH_FIRST, pIcode, eDEF, *next1->ll()); + asgn.rhs = AstIdent::LongIdx (loc_ident_idx); + asgn.lhs = AstIdent::idLong (&this->localId, DST, pIcode,HIGH_FIRST, pIcode, eDEF, *next1->ll()); - pIcode->setAsgn(asgn.lhs, asgn.rhs); - next1->invalidate(); - forced_finish =true; /* to exit the loop */ + pIcode->setAsgn(dynamic_cast(asgn.lhs), asgn.rhs); + next1->invalidate(); + forced_finish =true; /* to exit the loop */ + } + break; } - break; case iPUSH: - if ((pLocId.id.longId.h == pIcode->ll()->src().getReg2()) && - (pLocId.id.longId.l == next1->ll()->src().getReg2())) { - asgn.rhs = COND_EXPR::idLongIdx (loc_ident_idx); - pIcode->setRegDU( next1->ll()->src().getReg2(), eUSE); - pIcode->setUnary(HLI_PUSH, asgn.rhs); - next1->invalidate(); + const LONGID_TYPE &ref_long(pLocId.id.longId); + const LLOperand &src_op1(pIcode->ll()->src()); + const LLOperand &src_op2(next1->ll()->src()); + if ((ref_long.h == src_op1.getReg2()) && + (ref_long.l == src_op2.getReg2())) + { + asgn.rhs = AstIdent::LongIdx (loc_ident_idx); + pIcode->setRegDU( next1->ll()->src().getReg2(), eUSE); + pIcode->setUnary(HLI_PUSH, asgn.rhs); + next1->invalidate(); + } + forced_finish =true; /* to exit the loop */ + break; } - forced_finish =true; /* to exit the loop */ - break; /*** others missing ****/ @@ -432,19 +451,21 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be if ((pLocId.id.longId.h == pmH->regi) && (pLocId.id.longId.l == pmL->regi)) { - asgn.lhs = COND_EXPR::idLongIdx (loc_ident_idx); + asgn.lhs = AstIdent::LongIdx (loc_ident_idx); pIcode->setRegDU( pmH->regi, USE_DEF); - asgn.rhs = COND_EXPR::idLong (&this->localId, SRC, pIcode, + asgn.rhs = AstIdent::idLong (&this->localId, SRC, pIcode, LOW_FIRST, pIcode, eUSE, *next1->ll()); + condOp toCreate=DUMMY; switch (pIcode->ll()->getOpcode()) { - case iAND: asgn.rhs = COND_EXPR::boolOp (asgn.lhs, asgn.rhs, AND); - break; - case iOR: asgn.rhs = COND_EXPR::boolOp (asgn.lhs, asgn.rhs, OR); - break; - case iXOR: asgn.rhs = COND_EXPR::boolOp (asgn.lhs, asgn.rhs, XOR); - break; + case iAND: toCreate=AND; break; + case iOR: toCreate=OR; break; + case iXOR: toCreate= XOR; break; } - pIcode->setAsgn(asgn.lhs, asgn.rhs); + if(DUMMY!=toCreate) + { + asgn.rhs = new BinaryOperator(toCreate,asgn.lhs, asgn.rhs); + } + pIcode->setAsgn(dynamic_cast(asgn.lhs), asgn.rhs); next1->invalidate(); // ftw loop restart ???? //idx = 0; @@ -483,9 +504,9 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be { if (pLocId.id.longId.srcDstRegMatch(pIcode,pIcode)) { - asgn.lhs = COND_EXPR::idLongIdx (loc_ident_idx); - asgn.rhs = COND_EXPR::idKte (0, 4); /* long 0 */ - asgn.lhs = COND_EXPR::boolOp (asgn.lhs, asgn.rhs, condOpJCond[next1->ll()->getOpcode() - iJB]); + asgn.lhs = AstIdent::LongIdx (loc_ident_idx); + asgn.rhs = AstIdent::Kte (0, 4); /* long 0 */ + asgn.lhs = new BinaryOperator(condOpJCond[next1->ll()->getOpcode() - iJB],asgn.lhs, asgn.rhs); next1->setJCond(asgn.lhs); next1->copyDU(*pIcode, eUSE, eUSE); pIcode->invalidate();