Browse Source

Orignal dcc code

Only 2 differences with original release:
  add return type to main
  int disassem.cpp popPosStack() add cast to intptr_t
nemerle 9 years ago
parent
commit
2a59d07ef2
74 changed files with 11139 additions and 12201 deletions
  1. 17 46
      CMakeLists.txt
  2. 0 132
      include/BasicBlock.h
  3. 0 20
      include/BinaryImage.h
  4. 0 283
      include/Enums.h
  5. 0 33
      include/IdentType.h
  6. 0 199
      include/Procedure.h
  7. 0 24
      include/StackFrame.h
  8. 119 159
      include/ast.h
  9. 16 27
      include/bundle.h
  10. 267 92
      include/dcc.h
  11. 4 29
      include/disassem.h
  12. 21 18
      include/dosdcc.h
  13. 23 26
      include/error.h
  14. 101 70
      include/graph.h
  15. 20 4
      include/hlicode.h
  16. 345 467
      include/icode.h
  17. 0 75
      include/idioms/arith_idioms.h
  18. 0 42
      include/idioms/call_idioms.h
  19. 0 39
      include/idioms/epilogue_idioms.h
  20. 0 22
      include/idioms/idiom.h
  21. 0 17
      include/idioms/idiom1.h
  22. 0 36
      include/idioms/mov_idioms.h
  23. 0 33
      include/idioms/neg_idioms.h
  24. 0 66
      include/idioms/shift_idioms.h
  25. 0 46
      include/idioms/xor_idioms.h
  26. 82 110
      include/locident.h
  27. 0 82
      include/machine_x86.h
  28. 20 27
      include/perfhlib.h
  29. 0 77
      include/project.h
  30. 33 7
      include/scanner.h
  31. 9 25
      include/state.h
  32. 24 94
      include/symtab.h
  33. 24 72
      include/types.h
  34. BIN
      prototypes/dcclibs.dat
  35. BIN
      sigs/dccb2s.sig
  36. 0 443
      src/BasicBlock.cpp
  37. 0 7
      src/CMakeLists.txt
  38. 0 32
      src/Procedure.cpp
  39. 757 771
      src/ast.cpp
  40. 581 270
      src/backend.cpp
  41. 71 53
      src/bundle.cpp
  42. 316 318
      src/chklib.cpp
  43. 235 251
      src/comwrite.cpp
  44. 586 525
      src/control.cpp
  45. 903 1025
      src/dataflow.cpp
  46. 65 67
      src/dcc.cpp
  47. 511 329
      src/disassem.cpp
  48. 40 33
      src/error.cpp
  49. 71 67
      src/fixwild.cpp
  50. 446 297
      src/frontend.cpp
  51. 348 358
      src/graph.cpp
  52. 366 514
      src/hlicode.cpp
  53. 99 58
      src/icode.cpp
  54. 1250 177
      src/idioms.cpp
  55. 0 314
      src/idioms/arith_idioms.cpp
  56. 0 111
      src/idioms/call_idioms.cpp
  57. 0 153
      src/idioms/epilogue_idioms.cpp
  58. 0 137
      src/idioms/idiom1.cpp
  59. 0 110
      src/idioms/mov_idioms.cpp
  60. 0 102
      src/idioms/neg_idioms.cpp
  61. 0 170
      src/idioms/shift_idioms.cpp
  62. 0 134
      src/idioms/xor_idioms.cpp
  63. 235 232
      src/locident.cpp
  64. 0 111
      src/machine_x86.cpp
  65. 442 490
      src/parser.cpp
  66. 371 26
      src/perfhlib.cpp
  67. 335 308
      src/procs.cpp
  68. 0 73
      src/project.cpp
  69. 489 482
      src/proplong.cpp
  70. 284 254
      src/reducible.cpp
  71. 587 698
      src/scanner.cpp
  72. 506 118
      src/symtab.cpp
  73. 0 14
      src/tests/comwrite.cpp
  74. 120 70
      src/udm.cpp

+ 17 - 46
CMakeLists.txt

@@ -1,7 +1,7 @@
 PROJECT(dcc_original)
 CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
 
-OPTION(dcc_build_tests "Enable unit tests." OFF)
+#OPTION(dcc_build_tests "Enable unit tests." OFF)
 
 ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS -D__UNIX__ -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS)
 IF(CMAKE_BUILD_TOOL MATCHES "(msdev|devenv|nmake)")
@@ -14,25 +14,24 @@ ENDIF()
 
 SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMakeScripts;${CMAKE_MODULE_PATH})
 
-FIND_PACKAGE(LLVM)
-FIND_PACKAGE(Boost)
-IF(dcc_build_tests)
-    FIND_PACKAGE(GMock)
-ENDIF()
+#FIND_PACKAGE(LLVM)
+#FIND_PACKAGE(Boost)
+#IF(dcc_build_tests)
+#    FIND_PACKAGE(GMock)
+#ENDIF()
 
-ADD_SUBDIRECTORY(3rd_party)
+#ADD_SUBDIRECTORY(3rd_party)
 
-llvm_map_components_to_libraries(REQ_LLVM_LIBRARIES jit native mc support)
+#llvm_map_components_to_libraries(REQ_LLVM_LIBRARIES jit native mc support)
 INCLUDE_DIRECTORIES(
-    3rd_party/libdisasm
+#    3rd_party/libdisasm
     include
-    include/idioms
-    ${Boost_INCLUDE_DIRS}
-    ${LLVM_INCLUDE_DIRS}
+#    include/idioms
+#    ${Boost_INCLUDE_DIRS}
+#    ${LLVM_INCLUDE_DIRS}
 )
 
 set(dcc_SOURCES
-    src/dcc.cpp
     src/ast.cpp
     src/backend.cpp
     src/bundle.cpp
@@ -40,75 +39,47 @@ set(dcc_SOURCES
     src/comwrite.cpp
     src/control.cpp
     src/dataflow.cpp
+    src/dcc.cpp
     src/disassem.cpp
     src/error.cpp
     src/fixwild.cpp
     src/frontend.cpp
     src/graph.cpp
     src/hlicode.cpp
-    src/machine_x86.cpp
     src/icode.cpp
     src/idioms.cpp
-    src/idioms/idiom1.cpp
-    src/idioms/arith_idioms.cpp
-    src/idioms/call_idioms.cpp
-    src/idioms/epilogue_idioms.cpp
-    src/idioms/mov_idioms.cpp
-    src/idioms/neg_idioms.cpp
-    src/idioms/shift_idioms.cpp
-    src/idioms/xor_idioms.cpp
     src/locident.cpp
     src/parser.cpp
     src/perfhlib.cpp
     src/procs.cpp
-    src/project.cpp
-    src/Procedure.cpp
     src/proplong.cpp
     src/reducible.cpp
     src/scanner.cpp
     src/symtab.cpp
     src/udm.cpp
-    src/BasicBlock.cpp
 )
 set(dcc_HEADERS
     include/ast.h
     include/bundle.h
-    include/BinaryImage.h
     include/dcc.h
     include/disassem.h
     include/dosdcc.h
     include/error.h
     include/graph.h
     include/hlicode.h
-    include/machine_x86.h
     include/icode.h
-    include/idioms/idiom.h
-    include/idioms/idiom1.h
-    include/idioms/arith_idioms.h
-    include/idioms/call_idioms.h
-    include/idioms/epilogue_idioms.h
-    include/idioms/mov_idioms.h
-    include/idioms/neg_idioms.h
-    include/idioms/shift_idioms.h
-    include/idioms/xor_idioms.h
     include/locident.h
     include/perfhlib.h
-    include/project.h
     include/scanner.h
     include/state.h
     include/symtab.h
     include/types.h
-    include/Procedure.h
-    include/StackFrame.h
-    include/BasicBlock.h
 )
 SOURCE_GROUP(Source FILES ${dcc_SOURCES})
 SOURCE_GROUP(Headers FILES ${dcc_HEADERS})
 
 ADD_EXECUTABLE(dcc_original ${dcc_SOURCES} ${dcc_HEADERS})
-TARGET_LINK_LIBRARIES(dcc_original disasm_s ${REQ_LLVM_LIBRARIES})
-if(dcc_build_tests)
-ADD_SUBDIRECTORY(src)
-endif()
-
-
+#TARGET_LINK_LIBRARIES(dcc_original disasm_s ${REQ_LLVM_LIBRARIES})
+#if(dcc_build_tests)
+#ADD_SUBDIRECTORY(src)
+#endif()

+ 0 - 132
include/BasicBlock.h

@@ -1,132 +0,0 @@
-#pragma once
-#include <list>
-#include <vector>
-#include <bitset>
-#include <string>
-#include <llvm/ADT/ilist.h>
-#include <llvm/ADT/ilist_node.h>
-#include <boost/range.hpp>
-#include "icode.h"
-#include "types.h"
-#include "graph.h"
-//#include "icode.h"
-/* Basic block (BB) node definition */
-struct Function;
-class CIcodeRec;
-struct BB;
-struct LOCAL_ID;
-struct interval;
-
-struct TYPEADR_TYPE
-{
-    uint32_t         ip;             /* Out edge icode address       */
-    BB *          BBptr;          /* Out edge pointer to next BB  */
-    interval     *intPtr;         /* Out edge ptr to next interval*/
-};
-
-struct BB : public llvm::ilist_node<BB>
-{
-private:
-    BB(const BB&);
-    BB() : nodeType(0),traversed(DFS_NONE),
-        numHlIcodes(0),flg(0),
-        inEdges(0),
-        edges(0),beenOnH(0),inEdgeCount(0),reachingInt(0),
-        inInterval(0),correspInt(0),liveUse(0),def(0),liveIn(0),liveOut(0),
-        dfsFirstNum(0),dfsLastNum(0),immedDom(0),ifFollow(0),loopType(0),latchNode(0),
-        numBackEdges(0),loopHead(0),loopFollow(0),caseHead(0),caseTail(0),index(0)
-    {
-
-    }
-    //friend class SymbolTableListTraits<BB, Function>;
-    typedef boost::iterator_range<iICODE> rCODE;
-    rCODE instructions;
-
-public:
-    struct ValidFunctor
-    {
-        bool operator()(BB *p) {return p->valid();}
-    };
-    iICODE begin();
-    iICODE end() const;
-    riICODE rbegin();
-    riICODE rend();
-    ICODE &front();
-    ICODE &back();
-    size_t size();
-    uint8_t            nodeType;       /* Type of node                 */
-    eDFS             traversed;      /* last traversal id is held here traversed yet?      */
-    int             numHlIcodes;	/* No. of high-level icodes		*/
-    uint32_t         flg;			/* BB flags						*/
-
-    /* In edges and out edges */
-    std::vector<BB *> inEdges; // does not own held pointers
-
-    //int             numOutEdges;    /* Number of out edges          */
-    std::vector<TYPEADR_TYPE> edges;/* Array of ptrs. to out edges  */
-
-    /* For interval construction */
-    int             beenOnH;        /* #times been on header list H */
-    int             inEdgeCount;    /* #inEdges (to find intervals) */
-    BB *            reachingInt;    /* Reaching interval header     */
-    interval       *inInterval;     /* Node's interval              */
-
-    /* For derived sequence construction */
-    interval       *correspInt;     /* Corresponding interval in
-                                     * derived graph Gi-1       	*/
-
-    /* For live register analysis
-         * LiveIn(b) = LiveUse(b) U (LiveOut(b) - Def(b))	*/
-    std::bitset<32> liveUse;		/* LiveUse(b)					*/
-    std::bitset<32> def;			/* Def(b)						*/
-    std::bitset<32> liveIn;			/* LiveIn(b)					*/
-    std::bitset<32> liveOut;		/* LiveOut(b)					*/
-
-    /* For structuring analysis */
-    int             dfsFirstNum;    /* DFS #: first visit of node   */
-    int             dfsLastNum;     /* DFS #: last visit of node    */
-    int             immedDom;       /* Immediate dominator (dfsLast
-                                     * index)                       */
-    int             ifFollow;       /* node that ends the if        */
-    int             loopType;       /* Type of loop (if any)        */
-    int             latchNode;      /* latching node of the loop    */
-    int             numBackEdges;	/* # of back edges				*/
-    int             loopHead;       /* most nested loop head to which
-                                     * thcis node belongs (dfsLast)  */
-    int             loopFollow;     /* node that follows the loop   */
-    int             caseHead;       /* most nested case to which this
-                                        node belongs (dfsLast)      */
-    int             caseTail;       /* tail node for the case       */
-
-    int             index;          /* Index, used in several ways  */
-    static BB * Create(void *ctx=0,const std::string &s="",Function *parent=0,BB *insertBefore=0);
-    static BB * Create(int start, int ip, uint8_t nodeType, int numOutEdges, Function * parent);
-    static BB * Create(iICODE start, iICODE fin, uint8_t _nodeType, int numOutEdges, Function *parent);
-    void    writeCode(int indLevel, Function *pProc, int *numLoc, int latchNode, int ifFollow);
-    void    mergeFallThrough(CIcodeRec &Icode);
-    void    dfsNumbering(std::vector<BB *> &dfsLast, int *first, int *last);
-    void    displayDfs();
-    void    display();
-    /// getParent - Return the enclosing method, or null if none
-    ///
-    const Function *getParent() const { return Parent; }
-    Function *getParent()       { return Parent; }
-    void    writeBB(std::ostream &ostr, int lev, Function *pProc, int *numLoc);
-    BB *    rmJMP(int marker, BB *pBB);
-    void    genDU1();
-    int     findBBExps(LOCAL_ID &locals, Function *f);
-    bool    valid() {return 0==(flg & INVALID_BB); }
-    bool    wasTraversedAtLevel(int l) const {return traversed==l;}
-    ICODE * writeLoopHeader(int &indLevel, Function* pProc, int *numLoc, BB *&latch, boolT &repCond);
-    void addOutEdge(uint32_t ip)  // TODO: fix this
-    {
-        edges[0].ip = ip;
-    }
-    void RemoveUnusedDefs(eReg regi, int defRegIdx, iICODE picode);
-private:
-    bool    FindUseBeforeDef(eReg regi, int defRegIdx, iICODE start_at);
-    void    ProcessUseDefForFunc(eReg regi, int defRegIdx, iICODE picode);
-    bool    isEndOfPath(int latch_node_idx) const;
-    Function *Parent;
-
-};

+ 0 - 20
include/BinaryImage.h

@@ -1,20 +0,0 @@
-#pragma once
-#include <stdint.h>
-struct PROG /* Loaded program image parameters  */
-{
-    int16_t     initCS;
-    int16_t     initIP;     /* These are initial load values    */
-    int16_t     initSS;     /* Probably not of great interest   */
-    uint16_t    initSP;
-    bool        fCOM;       /* Flag set if COM program (else EXE)*/
-    int         cReloc;     /* No. of relocation table entries  */
-    uint32_t *  relocTable; /* Ptr. to relocation table         */
-    uint8_t *   map;        /* Memory bitmap ptr                */
-    int         cProcs;     /* Number of procedures so far      */
-    int         offMain;    /* The offset  of the main() proc   */
-    uint16_t    segMain;    /* The segment of the main() proc   */
-    bool        bSigs;		/* True if signatures loaded		*/
-    int         cbImage;    /* Length of image in bytes         */
-    uint8_t *   Image;      /* Allocated by loader to hold entire program image */
-};
-

+ 0 - 283
include/Enums.h

@@ -1,283 +0,0 @@
-#pragma once
-
-/* Register types */
-enum regType
-{
-    BYTE_REG,
-    WORD_REG
-};
-enum condId
-{
-    GLOB_VAR,       /* global variable  */
-    REGISTER,       /* register         */
-    LOCAL_VAR,      /* negative disp    */
-    PARAM,          /* positive disp    */
-    GLOB_VAR_IDX,   /* indexed global variable *//*** should merge w/glob-var*/
-    CONSTANT,       /* constant         */
-    STRING,         /* string			*/
-    LONG_VAR,       /* long variable	*/
-    FUNCTION,       /* function			*/
-    OTHER           /* other **** tmp solution */
-};
-
-enum condOp
-{
-    /* For conditional expressions */
-    LESS_EQUAL, /* <=   */
-    LESS,           /* <    */
-    EQUAL,          /* ==   */
-    NOT_EQUAL,      /* !=   */
-    GREATER,        /* >    */
-    GREATER_EQUAL,  /* >=   */
-    /* For general expressions */
-    AND,            /* &    */
-    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
-{
-    SRC,						/* Source operand 		*/
-    DST,						/* Destination operand	*/
-    LHS_OP						/* Left-hand side operand (for HIGH_LEVEL) */
-};
-/* LOW_LEVEL icode flags */
-#define NO_SRC_B    0xF7FFFF    /* Masks off SRC_B */
-enum eLLFlags
-{
-
-    B           =0x0000001,    /* uint8_t operands (value implicitly used) */
-    I           =0x0000002,    /* Immed. source */
-    NOT_HLL     =0x0000004,    /* Not HLL inst. */
-    FLOAT_OP    =0x0000008,    /* ESC or WAIT   */
-    SEG_IMMED   =0x0000010,    /* Number is relocated segment value */
-    IMPURE      =0x0000020,    /* Instruction modifies code */
-    WORD_OFF    =0x0000040,    /* Inst has uint16_t offset ie.could be address */
-    TERMINATES  =0x0000080,    /* Instruction terminates program */
-    CASE        =0x0000100,    /* Label as case part of switch */
-    SWITCH      =0x0000200,    /* Treat indirect JMP as switch stmt */
-    TARGET      =0x0000400,    /* Jump target */
-    SYNTHETIC   =0x0000800,    /* Synthetic jump instruction */
-    NO_LABEL    =0x0001000,    /* Immed. jump cannot be linked to a label */
-    NO_CODE     =0x0002000,    /* Hole in Icode array */
-    SYM_USE     =0x0004000,    /* Instruction uses a symbol */
-    SYM_DEF     =0x0008000,    /* Instruction defines a symbol */
-    NO_SRC      =0x0010000,    /* Opcode takes no source */
-    NO_OPS      =0x0020000,    /* Opcode takes no operands */
-    IM_OPS      =0x0040000,    /* Opcode takes implicit operands */
-    SRC_B       =0x0080000,    /* Source operand is uint8_t (dest is uint16_t) */
-    HLL_LABEL   =0x0100000, /* Icode has a high level language label */
-    IM_DST      =0x0200000, /* Implicit DST for opcode (SIGNEX) */
-    IM_SRC      =0x0400000, /* Implicit SRC for opcode (dx:ax)	*/
-    IM_TMP_DST  =0x0800000, /* Implicit rTMP DST for opcode (DIV/IDIV) */
-    JMP_ICODE   =0x1000000, /* Jmp dest immed.op converted to icode index */
-    JX_LOOP     =0x2000000, /* Cond jump is part of loop conditional exp */
-    REST_STK    =0x4000000  /* Stack needs to be restored after CALL */
-#define ICODEMASK 0x0FF00FF    /* Masks off parser flags */
-};
-/* Types of icodes */
-enum icodeType
-{
-    NOT_SCANNED = 0,    // not even scanned yet
-    LOW_LEVEL,          // low-level icode
-    HIGH_LEVEL          // high-level icode
-};
-
-
-/* LOW_LEVEL icode opcodes */
-enum llIcode
-{
-    //iINVALID,
-    iCBW,		/* 0 */
-    iAAA,
-    iAAD,
-    iAAM,
-    iAAS,
-    iADC,
-    iADD,
-    iAND,
-    iBOUND,
-    iCALL,
-    iCALLF,		/* 10 */
-    iCLC,
-    iCLD,
-    iCLI,
-    iCMC,
-    iCMP,
-    iCMPS,
-    iREPNE_CMPS,
-    iREPE_CMPS,
-    iDAA,
-    iDAS,		/* 20 */
-    iDEC,
-    iDIV,
-    iENTER,
-    iESC,
-    iHLT,
-    iIDIV,
-    iIMUL,
-    iIN,
-    iINC,
-    iINS,		/* 30 */
-    iREP_INS,
-    iINT,
-    iIRET,
-    iJB,
-    iJBE,
-    iJAE,
-    iJA,
-    iJE,
-    iJNE,
-    iJL,		/* 40 */
-    iJGE,
-    iJLE,
-    iJG,
-    iJS,
-    iJNS,
-    iJO,
-    iJNO,
-    iJP,
-    iJNP,
-    iJCXZ,		/* 50 */
-    iJMP,
-    iJMPF,
-    iLAHF,
-    iLDS,
-    iLEA,
-    iLEAVE,
-    iLES,
-    iLOCK,
-    iLODS,
-    iREP_LODS,	/* 60 */
-    iLOOP,
-    iLOOPE,
-    iLOOPNE,
-    iMOV,		/* 64 */
-    iMOVS,
-    iREP_MOVS,
-    iMUL,		/* 67 */
-    iNEG,
-    iNOT,
-    iOR,   		/* 70 */
-    iOUT,
-    iOUTS,
-    iREP_OUTS,
-    iPOP,
-    iPOPA,
-    iPOPF,
-    iPUSH,
-    iPUSHA,
-    iPUSHF,
-    iRCL,		/* 80 */
-    iRCR,
-    iROL,
-    iROR,
-    iRET,		/* 84 */
-    iRETF,
-    iSAHF,
-    iSAR,
-    iSHL,
-    iSHR,
-    iSBB,		/* 90 */
-    iSCAS,
-    iREPNE_SCAS,
-    iREPE_SCAS,
-    iSIGNEX,
-    iSTC,
-    iSTD,
-    iSTI,
-    iSTOS,
-    iREP_STOS,
-    iSUB,		/* 100 */
-    iTEST,
-    iWAIT,
-    iXCHG,
-    iXLAT,
-    iXOR,
-    iINTO,
-    iNOP,
-    iREPNE,
-    iREPE,
-    iMOD		/* 110 */
-};
-/* Conditional Expression enumeration nodes and operators               */
-enum condNodeType
-{
-    UNKNOWN_OP=0,
-    BOOLEAN_OP,         /* condOps  			*/
-    NEGATION,           /* not (2's complement)	*/
-    ADDRESSOF,          /* addressOf (&)		*/
-    DEREFERENCE,        /* contents of (*) 		*/
-    IDENTIFIER,         /* {register | local | param | constant | global} */
-    /* The following are only available to C programs */
-    POST_INC,           /* ++ (post increment)	*/
-    POST_DEC,           /* -- (post decrement)	*/
-    PRE_INC,            /* ++ (pre increment)	*/
-    PRE_DEC             /* -- (pre decrement)	*/
-} ;
-
-/* Enumeration to determine whether pIcode points to the high or low part
- * of a long number */
-enum hlFirst
-{
-        HIGH_FIRST,			/* High value is first		*/
-        LOW_FIRST			/* Low value is first		*/
-};
-/* HIGH_LEVEL icodes opcodes */
-enum hlIcode
-{
-    HLI_INVALID,
-    HLI_ASSIGN,         /* :=               		*/
-    HLI_CALL,			/* Call procedure			*/
-    HLI_JCOND,          /* Conditional jump 		*/
-    HLI_RET,			/* Return from procedure	*/
-    /* pseudo high-level icodes */
-    HLI_POP,			/* Pop expression			*/
-    HLI_PUSH			/* Push expression			*/
-} ;
-/* Type definitions used in the decompiled program  */
-enum hlType
-{
-    TYPE_UNKNOWN = 0,   /* unknown so far      		*/
-    TYPE_BYTE_SIGN,		/* signed byte (8 bits) 	*/
-    TYPE_BYTE_UNSIGN,	/* unsigned byte 			*/
-    TYPE_WORD_SIGN,     /* signed word (16 bits) 	*/
-    TYPE_WORD_UNSIGN,	/* unsigned word (16 bits)	*/
-    TYPE_LONG_SIGN,		/* signed long (32 bits)	*/
-    TYPE_LONG_UNSIGN,	/* unsigned long (32 bits)	*/
-    TYPE_RECORD,        /* record structure			*/
-    TYPE_PTR,        	/* pointer (32 bit ptr) 	*/
-    TYPE_STR,        	/* string               	*/
-    TYPE_CONST,         /* constant (any type)		*/
-    TYPE_FLOAT,         /* floating point			*/
-    TYPE_DOUBLE		/* double precision float	*/
-};
-
-/* Operand is defined, used or both flag */
-enum operDu
-{
-    eDEF=0x10,			/* Operand is defined						*/
-    eUSE=0x100,			/* Operand is used							*/
-    USE_DEF,		/* Operand is used and defined				*/
-    NONE			/* No operation is required on this operand	*/
-};
-
-/* LOW_LEVEL icode, DU flag bits */
-enum eDuFlags
-{
-    Cf=1,
-    Sf=2,
-    Zf=4,
-    Df=8
-};

+ 0 - 33
include/IdentType.h

@@ -1,33 +0,0 @@
-#pragma once
-#include "ast.h"
-#include "types.h"
-#include "machine_x86.h"
-
-struct IDENTTYPE
-{
-    condId           idType;
-    regType          regiType;  /* for REGISTER only                */
-    union _idNode {
-        int          regiIdx;   /* index into localId, REGISTER		*/
-        int          globIdx;   /* index into symtab for GLOB_VAR   */
-        int          localIdx;  /* idx into localId,  LOCAL_VAR		*/
-        int          paramIdx;  /* idx into args symtab, PARAMS     */
-        int			 idxGlbIdx;	/* idx into localId, GLOB_VAR_IDX   */
-        struct _kte
-        {			/* for CONSTANT only					*/
-            uint32_t   kte;   	/*   value of the constant			*/
-            uint8_t    size;       /*   #bytes size constant	 		*/
-        } kte;
-        uint32_t        strIdx;	/* idx into image, for STRING	 	*/
-        int             longIdx;	/* idx into LOCAL_ID table, LONG_VAR*/
-        struct _call {			/* for FUNCTION only				*/
-            Function     *proc;
-            STKFRAME *args;
-        }			 call;
-        struct {                /* for OTHER; tmp struct            */
-            eReg     seg;       /*   segment                        */
-            eReg     regi;      /*   index mode                     */
-            int16_t    off;       /*   offset                         */
-        }            other;
-    }                idNode;
-};

+ 0 - 199
include/Procedure.h

@@ -1,199 +0,0 @@
-#pragma once
-#include <llvm/ADT/ilist.h>
-#include <llvm/ADT/ilist_node.h>
-#include <bitset>
-#include "BasicBlock.h"
-#include "locident.h"
-#include "state.h"
-#include "icode.h"
-#include "StackFrame.h"
-/* PROCEDURE NODE */
-struct CALL_GRAPH;
-struct COND_EXPR;
-struct Disassembler;
-struct Function;
-struct CALL_GRAPH;
-
-typedef llvm::iplist<Function> FunctionListType;
-typedef FunctionListType lFunction;
-typedef lFunction::iterator ilFunction;
-
-namespace llvm
-{
-// Traits for intrusive list of basic blocks...
-template<>
-struct ilist_traits<BB> : public ilist_default_traits<BB>
-{
-
-    // createSentinel is used to get hold of the node that marks the end of the
-    // list... (same trick used here as in ilist_traits<Instruction>)
-    BB *createSentinel() const {
-        return static_cast<BB*>(&Sentinel);
-    }
-    static void destroySentinel(BB*) {}
-
-    BB *provideInitialHead() const { return createSentinel(); }
-    BB *ensureHead(BB*) const { return createSentinel(); }
-    static void noteHead(BB*, BB*) {}
-
-    //static ValueSymbolTable *getSymTab(Function *ItemParent);
-private:
-    mutable ilist_half_node<BB> Sentinel;
-};
-}
-/* Procedure FLAGS */
-enum PROC_FLAGS
-{
-    PROC_BADINST=0x00000100,/* Proc contains invalid or 386 instruction */
-    PROC_IJMP   =0x00000200,/* Proc incomplete due to indirect jmp	 	*/
-    PROC_ICALL  =0x00000400, /* Proc incomplete due to indirect call		*/
-    PROC_HLL    =0x00001000, /* Proc is likely to be from a HLL			*/
-    CALL_PASCAL =0x00002000, /* Proc uses Pascal calling convention		*/
-    CALL_C      =0x00004000, /* Proc uses C calling convention			*/
-    CALL_UNKNOWN=0x00008000, /* Proc uses unknown calling convention		*/
-    PROC_NEAR   =0x00010000, /* Proc exits with near return				*/
-    PROC_FAR    =0x00020000, /* Proc exits with far return				*/
-    GRAPH_IRRED =0x00100000, /* Proc generates an irreducible graph		*/
-    SI_REGVAR   =0x00200000, /* SI is used as a stack variable 			*/
-    DI_REGVAR   =0x00400000, /* DI is used as a stack variable 			*/
-    PROC_IS_FUNC=0x00800000,	/* Proc is a function 						*/
-    REG_ARGS    =0x01000000, /* Proc has registers as arguments			*/
-    PROC_VARARG =0x02000000,	/* Proc has variable arguments				*/
-    PROC_OUTPUT =0x04000000, /* C for this proc has been output 			*/
-    PROC_RUNTIME=0x08000000, /* Proc is part of the runtime support		*/
-    PROC_ISLIB  =0x10000000, /* Proc is a library function				*/
-    PROC_ASM    =0x20000000, /* Proc is an intrinsic assembler routine   */
-    PROC_IS_HLL =0x40000000 /* Proc has HLL prolog code					*/
-#define CALL_MASK    0xFFFF9FFF /* Masks off CALL_C and CALL_PASCAL		 	*/
-};
-
-struct FunctionType
-{
-    bool m_vararg;
-    bool isVarArg() const {return m_vararg;}
-};
-struct Assignment
-{
-    COND_EXPR *lhs;
-    COND_EXPR *rhs;
-};
-struct JumpTable
-{
-    uint32_t start;
-    uint32_t finish;
-    bool valid() {return start<finish;}
-    size_t size() { return (finish-start)/2;}
-    size_t entrySize() { return 2;}
-    void pruneEntries(uint16_t cs);
-};
-
-struct Function : public llvm::ilist_node<Function>
-{
-    typedef llvm::iplist<BB> BasicBlockListType;
-    // BasicBlock iterators...
-    typedef BasicBlockListType::iterator iterator;
-    typedef BasicBlockListType::const_iterator const_iterator;
-private:
-    BasicBlockListType  BasicBlocks;        ///< The basic blocks
-
-public:
-    uint32_t        procEntry; /* label number                         	 */
-    std::string  name;      /* Meaningful name for this proc     	 */
-    STATE        state;     /* Entry state                          	 */
-    int          depth;     /* Depth at which we found it - for printing */
-    uint32_t      flg;       /* Combination of Icode & Proc flags    	 */
-    int16_t        cbParam;   /* Probable no. of bytes of parameters  	 */
-    STKFRAME     args;      /* Array of arguments                   	 */
-    LOCAL_ID	 localId;   /* Local identifiers                         */
-    ID           retVal;    /* Return value - identifier    		 */
-
-        /* Icodes and control flow graph */
-    CIcodeRec	 Icode;     /* Object with ICODE records                 */
-    std::list<BB*> m_cfg;      /* Ptr. to BB list/CFG                  	 */
-    std::vector<BB*> m_dfsLast;
-    std::list<BB*> heldBBs;
-    //BB *         *dfsLast;  /* Array of pointers to BBs in dfsLast
-//                           * (reverse postorder) order            	 */
-    size_t        numBBs;    /* Number of BBs in the graph cfg       	 */
-    bool         hasCase;   /* Procedure has a case node            	 */
-
-    /* For interprocedural live analysis */
-    std::bitset<32>     liveIn;	/* Registers used before defined                 */
-    std::bitset<32>     liveOut;	/* Registers that may be used in successors	 */
-    bool                liveAnal;	/* Procedure has been analysed already		 */
-
-    Function(void *ty=0) : procEntry(0),depth(0),flg(0),cbParam(0),m_cfg(0),m_dfsLast(0),numBBs(0),
-        hasCase(false),liveIn(0),liveOut(0),liveAnal(0)//,next(0),prev(0)
-    {
-    }
-public:
-    static Function *Create(void *ty=0,int Linkage=0,const std::string &nm="",void *module=0)
-    {
-        Function *r=new Function(ty);
-        r->name = nm;
-        return r;
-    }
-    bool anyFlagsSet(uint32_t t) { return (flg&t)!=0;}
-    bool hasRegArgs() const { return (flg & REG_ARGS)!=0;}
-    bool isLibrary() const { return (flg & PROC_ISLIB)!=0;}
-    void compoundCond();
-    void writeProcComments();
-    void lowLevelAnalysis();
-    void bindIcodeOff();
-    void dataFlow(std::bitset<32> &liveOut);
-    void compressCFG();
-    void highLevelGen();
-    void structure(derSeq *derivedG);
-    derSeq *checkReducibility();
-    void createCFG();
-    void markImpure();
-    void findImmedDom();
-    void FollowCtrl(CALL_GRAPH *pcallGraph, STATE *pstate);
-    void process_operands(ICODE &pIcode, STATE *pstate);
-    bool process_JMP(ICODE &pIcode, STATE *pstate, CALL_GRAPH *pcallGraph);
-    boolT process_CALL(ICODE &pIcode, CALL_GRAPH *pcallGraph, STATE *pstate);
-    void freeCFG();
-    void codeGen(std::ostream &fs);
-    void mergeFallThrough(BB *pBB);
-    void structIfs();
-    void structLoops(derSeq *derivedG);
-    void buildCFG(Disassembler &ds);
-    void controlFlowAnalysis();
-    void newRegArg(iICODE picode, iICODE ticode);
-    void writeProcComments(std::ostream &ostr);
-
-    void displayCFG();
-    void displayStats();
-    void processHliCall(COND_EXPR *exp, iICODE picode);
-
-    void preprocessReturnDU(std::bitset<32> &_liveOut);
-protected:
-    void extractJumpTableRange(ICODE& pIcode, STATE *pstate, JumpTable &table);
-    bool followAllTableEntries(JumpTable &table, uint32_t cs, ICODE &pIcode, CALL_GRAPH *pcallGraph, STATE *pstate);
-    bool removeInEdge_Flag_and_ProcessLatch(BB *pbb, BB *a, BB *b);
-    bool Case_X_and_Y(BB* pbb, BB* thenBB, BB* elseBB);
-    bool Case_X_or_Y(BB* pbb, BB* thenBB, BB* elseBB);
-    bool Case_notX_or_Y(BB* pbb, BB* thenBB, BB* elseBB);
-    bool Case_notX_and_Y(BB* pbb, BB* thenBB, BB* elseBB);
-    void replaceInEdge(BB* where, BB* which, BB* with);
-    void processExpPush(int &numHlIcodes, iICODE picode);
-
-    // TODO: replace those with friend visitor ?
-    void propLongReg(int loc_ident_idx, const ID &pLocId);
-    void propLongStk(int i, const ID &pLocId);
-    void propLongGlb(int i, const ID &pLocId);
-    void processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode, bool isLong);
-
-    int     findBackwarLongDefs(int loc_ident_idx, const ID &pLocId, iICODE iter);
-    int     findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE beg);
-    void    structCases();
-    void    findExps();
-    void    genDU1();
-    void    elimCondCodes();
-    void    liveRegAnalysis(std::bitset<32> &in_liveOut);
-    void    findIdioms();
-    void    propLong();
-    void    genLiveKtes();
-    uint8_t findDerivedSeq (derSeq &derivedGi);
-    bool    nextOrderGraph(derSeq &derivedGi);
-};

+ 0 - 24
include/StackFrame.h

@@ -1,24 +0,0 @@
-#pragma once
-#include <vector>
-#include <cstring>
-#include "types.h"
-#include "Enums.h"
-#include "symtab.h"
-
-struct STKFRAME : public SymbolTableCommon<STKSYM>
-{
-    //std::vector<STKSYM> sym;
-    //STKSYM *    sym;        /* Symbols                      */
-    int16_t       m_minOff;     /* Initial offset in stack frame*/
-    int16_t       maxOff;     /* Maximum offset in stack frame*/
-    int         cb;         /* Number of bytes in arguments */
-    int         numArgs;    /* No. of arguments in the table*/
-    void        adjustForArgType(int numArg_, hlType actType_);
-    STKFRAME() : m_minOff(0),maxOff(0),cb(0),numArgs(0)
-    {
-
-    }
-    size_t getLocVar(int off);
-public:
-    void updateFrameOff(int16_t off, int size, uint16_t duFlag);
-};

+ 119 - 159
include/ast.h

@@ -4,12 +4,9 @@
  * Date:    September 1993
  * (C) Cristina Cifuentes
  */
-#pragma once
-#include <cstring>
-#include <list>
-#include "Enums.h"
-#include <boost/range.hpp>
-static const int operandSize=20;
+
+#define operandSize		20
+
 /* The following definitions and types define the Conditional Expression
  * attributed syntax tree, as defined by the following EBNF:
     CondExp     ::= CondTerm AND CondTerm | CondTerm
@@ -18,160 +15,123 @@ static const int operandSize=20;
     Identifier  ::= globalVar | register | localVar | parameter | constant
     op          ::= <= | < | = | != | > | >=
  */
+
+/* Conditional Expression enumeration nodes and operators               */
+typedef enum {
+    BOOLEAN_OP,            /* condOps  			*/
+    NEGATION,           /* not (2's complement)	*/ 
+	ADDRESSOF,			/* addressOf (&)		*/
+	DEREFERENCE,		/* contents of (*) 		*/
+    IDENTIFIER,         /* {register | local | param | constant | global} */
+	/* The following are only available to C programs */
+	POST_INC,			/* ++ (post increment)	*/
+	POST_DEC,			/* -- (post decrement)	*/
+	PRE_INC,			/* ++ (pre increment)	*/
+	PRE_DEC,			/* -- (pre decrement)	*/
+} condNodeType;
+
+typedef enum {
+    GLOB_VAR,       /* global variable  */
+    REGISTER,       /* register         */
+    LOCAL_VAR,      /* negative disp    */
+    PARAM,          /* positive disp    */
+	GLOB_VAR_IDX,	/* indexed global variable *//*** should merge w/glob-var*/
+    CONSTANT,		/* constant         */
+	STRING,			/* string			*/
+	LONG_VAR,		/* long variable	*/
+	FUNCTION,		/* function			*/
+    OTHER           /* other **** tmp solution */
+} condId;
+
+typedef enum {
+        /* For conditional expressions */
+    LESS_EQUAL = 0, /* <=   */
+    LESS,           /* <    */ 
+    EQUAL,          /* ==   */
+    NOT_EQUAL,      /* !=   */
+    GREATER,        /* >    */
+    GREATER_EQUAL,  /* >=   */
+        /* For general expressions */
+    AND,            /* &    */
+	OR,				/* |	*/
+	XOR,			/* ^	*/
+	NOT,			/* ~	*/  /* 1's complement */
+	ADD,			/* +	*/
+	SUB,			/* -	*/
+	MUL,			/* *	*/
+	DIV,			/* /	*/
+	SHR,			/* >>	*/
+	SHL,			/* <<	*/
+	MOD,			/* %	*/
+	DBL_AND,		/* &&	*/
+	DBL_OR,			/* ||	*/
+	DUMMY,			/*      */
+} condOp;
+
 /* 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};
-
-struct Function;
-struct STKFRAME;
-struct LOCAL_ID;
-struct ICODE;
-struct LLInst;
-struct ID;
-typedef std::list<ICODE>::iterator iICODE;
-typedef boost::iterator_range<iICODE> rICODE;
-#include "IdentType.h"
+static condOp condOpJCond[12] = {LESS, LESS_EQUAL, GREATER_EQUAL, GREATER, 
+								EQUAL, NOT_EQUAL, LESS, GREATER_EQUAL, 
+								LESS_EQUAL, GREATER, GREATER_EQUAL, LESS};
 
-/* Expression data type */
-struct COND_EXPR
+static condOp invCondOpJCond[12] = {GREATER_EQUAL, GREATER, LESS, LESS_EQUAL,
+									NOT_EQUAL, EQUAL, GREATER_EQUAL, LESS, 
+									GREATER, LESS_EQUAL, LESS, GREATER_EQUAL};
+
+
+/* Register types */
+typedef enum {
+    BYTE_REG, WORD_REG
+} regType;
+
+
+typedef struct
 {
-protected:
-    struct /* for BOOLEAN_OP					*/
-    {
-        condOp           op;
-        COND_EXPR *lhs;
-        COND_EXPR *rhs;
-    } boolExpr;
-
-public:
-    condNodeType            m_type;       /* Conditional Expression Node Type */
+    condId           idType;
+    regType          regiType;  /* for REGISTER only                */
+    union _idNode {
+        Int          regiIdx;   /* index into localId, REGISTER		*/
+        Int          globIdx;   /* index into symtab for GLOB_VAR   */
+        Int          localIdx;  /* idx into localId,  LOCAL_VAR		*/
+        Int          paramIdx;  /* idx into args symtab, PARAMS     */
+		Int			 idxGlbIdx;	/* idx into localId, GLOB_VAR_IDX   */
+		struct _kte	{			/* for CONSTANT only					*/
+        	dword    kte;   	/*   value of the constant			*/
+			byte	 size;		/*   #bytes size constant	 		*/
+		}			 kte;
+		dword		 strIdx;	/* idx into image, for STRING	 	*/
+		Int			 longIdx;	/* idx into LOCAL_ID table, LONG_VAR*/
+		struct _call {			/* for FUNCTION only				*/
+			struct _proc     *proc;
+			struct _STKFRAME *args;
+		}			 call;
+        struct {                /* for OTHER; tmp struct            */
+            byte     seg;       /*   segment                        */
+            byte     regi;      /*   index mode                     */
+            int16    off;       /*   offset                         */
+        }            other;
+    }                idNode;
+} IDENTTYPE;
+
+
+/* Expression data type */
+typedef struct _condExpr {
+    condNodeType            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         insertSubTreeReg(COND_EXPR *&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() {}
-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 hlType expType(Function *pproc) const;
-};
-struct BinaryOperator : public COND_EXPR
-{
-    condOp      m_op;
-    COND_EXPR *m_lhs;
-    COND_EXPR *m_rhs;
-    BinaryOperator(condOp o)
-    {
-        m_op = o;
-        m_lhs=m_rhs=nullptr;
-    }
-    static BinaryOperator *Create(condOp o,COND_EXPR *l,COND_EXPR *r);
-    static BinaryOperator *CreateAdd(COND_EXPR *l,COND_EXPR *r);
-    virtual COND_EXPR *inverse();
-    virtual COND_EXPR *clone();
-    virtual bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locs);
-    virtual COND_EXPR *insertSubTreeReg(COND_EXPR *_expr, eReg regi, LOCAL_ID *locsym);
-    virtual COND_EXPR *insertSubTreeLongReg(COND_EXPR *_expr, int longIdx);
-
-    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;}
-};
-struct UnaryOperator : public COND_EXPR
-{
-    condOp      op;
-    COND_EXPR *unaryExp;
-    virtual COND_EXPR *inverse();
-    virtual COND_EXPR *clone();
-    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);
-    }
-};
-
-struct GlobalVariable : public COND_EXPR
-{
-    static COND_EXPR *Create(int16_t segValue, int16_t off);
-};
-struct Constant : public COND_EXPR
-{};
+        struct {                        /* for BOOLEAN_OP					*/
+            condOp           op;
+            struct _condExpr *lhs;
+            struct _condExpr *rhs;
+        }                    boolExpr;
+        struct _condExpr    *unaryExp;  /* for NEGATION,ADDRESSOF,DEREFERENCE*/
+        IDENTTYPE			 ident;     /* for IDENTIFIER                   */
+    }                        expr;  
+} COND_EXPR;
+
+/* Sequence of conditional expression data type */
+/*** NOTE: not used at present ****/
+typedef struct _condExpSeq {
+    COND_EXPR           *expr;
+    struct _condExpSeq  *next;
+} SEQ_COND_EXPR;
+
+

+ 16 - 27
include/bundle.h

@@ -4,39 +4,28 @@
  * Purpose: Module to handle the bundle type (array of pointers to strings).
  * (C) Cristina Cifuentes
  ****************************************************************************/
-#pragma once
+
 #include <stdio.h>
-#include <vector>
-#include <string>
-struct strTable : std::vector<std::string>
-{
-    /* Returns the next available index into the table */
-    size_t nextIdx() {return size();}
-public:
-    void addLabelBundle(int idx, int label);
-};
-
-struct bundle
-{
-public:
-    void appendCode(const char *format, ...);
-    void appendCode(const std::string &s);
-    void appendDecl(const char *format, ...);
-    void appendDecl(const std::string &);
-    void init()
-    {
-        decl.clear();
-        code.clear();
-    }
+
+typedef struct {
+    Int     numLines;   /* Number of lines in the table   */
+    Int     allocLines; /* Number of lines allocated in the table */
+    char    **str;      /* Table of strings */
+} strTable;
+
+
+typedef struct {
     strTable    decl;   /* Declarations */
     strTable    code;   /* C code       */
-    int current_indent;
-};
+} bundle;
 
 
 #define lineSize	360		/* 3 lines in the mean time */
 
-//void    newBundle (bundle *procCode);
-void    writeBundle (std::ostream &ios, bundle procCode);
+void    newBundle (bundle *procCode);
+void    appendStrTab (strTable *strTab, char *format, ...);
+Int		nextBundleIdx (strTable *strTab);
+void	addLabelBundle (strTable *strTab, Int idx, Int label);
+void    writeBundle (FILE *fp, bundle procCode);
 void    freeBundle (bundle *procCode);
 

+ 267 - 92
include/dcc.h

@@ -2,15 +2,8 @@
  *          dcc project general header
  * (C) Cristina Cifuentes, Mike van Emmerik
  ****************************************************************************/
-#pragma once
-//TODO: Remove boolT
 
-#include <llvm/ADT/ilist.h>
-#include <utility>
-#include <algorithm>
-#include <bitset>
 
-#include "Enums.h"
 #include "types.h"
 #include "ast.h"
 #include "icode.h"
@@ -18,31 +11,134 @@
 #include "error.h"
 #include "graph.h"
 #include "bundle.h"
-#include "Procedure.h"
-#include "BasicBlock.h"
-struct Project;
+
+
+/* SYMBOL TABLE */
+typedef struct {        
+    char        name[10];   /* New name for this variable   */
+    dword       label;      /* physical address (20 bit)    */
+    Int         size;       /* maximum size                 */
+	flags32     flg;        /* SEG_IMMED, IMPURE, WORD_OFF  */
+    hlType      type;       /* probable type                */
+    word        duVal;      /* DEF, USE, VAL                */
+} SYM;
+typedef SYM *PSYM;
+
+typedef struct {
+    Int         csym;       /* No. of symbols in table  */
+    Int         alloc;      /* Allocation               */
+    PSYM        sym;        /* Symbols                  */
+} SYMTAB;
+typedef SYMTAB *PSYMTAB;
+
+
+/* STACK FRAME */
+typedef struct {        
+	COND_EXPR	*actual;	/* Expression tree of actual parameter 		*/
+	COND_EXPR 	*regs;		/* For register arguments only				*/
+    int16       off;        /* Immediate off from BP (+:args, -:params) */
+    byte        regOff;     /* Offset is a register (e.g. SI, DI)       */
+    Int         size;       /* Size             						*/
+    hlType      type;       /* Probable type    						*/
+    word        duVal;      /* DEF, USE, VAL    						*/
+	boolT		hasMacro;	/* This type needs a macro					*/
+	char		macro[10];	/* Macro name								*/
+    char        name[10];   /* Name for this symbol/argument            */
+	boolT		invalid;	/* Boolean: invalid entry in formal arg list*/
+} STKSYM;
+typedef STKSYM *PSTKSYM;
+
+typedef struct _STKFRAME {
+    Int         csym;       /* No. of symbols in table      */
+    Int         alloc;      /* Allocation                   */
+    PSTKSYM     sym;        /* Symbols                      */
+	int16		minOff;		/* Initial offset in stack frame*/
+    int16       maxOff;     /* Maximum offset in stack frame*/
+	Int			cb;			/* Number of bytes in arguments	*/
+	Int			numArgs;	/* No. of arguments in the table*/
+} STKFRAME;
+typedef STKFRAME *PSTKFRAME;
+
+/* PROCEDURE NODE */
+typedef struct _proc {
+    dword        procEntry; /* label number                         	 */
+    char         name[SYMLEN]; /* Meaningful name for this proc     	 */
+    STATE        state;     /* Entry state                          	 */
+    Int          depth;     /* Depth at which we found it - for printing */
+	flags32      flg;       /* Combination of Icode & Proc flags    	 */
+    int16        cbParam;   /* Probable no. of bytes of parameters  	 */
+    STKFRAME     args;      /* Array of arguments                   	 */
+	LOCAL_ID	 localId;	/* Local identifiers						 */
+	ID			 retVal;	/* Return value - identifier				 */
+
+	/* Icodes and control flow graph */
+	CIcodeRec	 Icode;		/* Object with ICODE records				 */
+    PBB          cfg;       /* Ptr. to BB list/CFG                  	 */
+    PBB         *dfsLast;   /* Array of pointers to BBs in dfsLast
+                             * (reverse postorder) order            	 */
+    Int          numBBs;    /* Number of BBs in the graph cfg       	 */
+    boolT        hasCase;   /* Procedure has a case node            	 */
+
+	/* For interprocedural live analysis */
+	dword		 liveIn;	/* Registers used before defined			 */
+	dword		 liveOut;	/* Registers that may be used in successors	 */
+	boolT		 liveAnal;	/* Procedure has been analysed already		 */
+
+	/* Double-linked list */
+    struct      _proc *next;
+	struct		_proc *prev;
+} PROCEDURE;
+typedef PROCEDURE *PPROC;
+
+
 /* CALL GRAPH NODE */
-struct CALL_GRAPH
-{
-        ilFunction proc;               /* Pointer to procedure in pProcList	*/
-        std::vector<CALL_GRAPH *> outEdges; /* array of out edges                   */
-public:
-        void write();
-        CALL_GRAPH() : outEdges(0)
-        {
-        }
-public:
-        void writeNodeCallGraph(int indIdx);
-        bool insertCallGraph(ilFunction caller, ilFunction callee);
-        bool insertCallGraph(Function *caller, ilFunction callee);
-        void insertArc(ilFunction newProc);
-};
-//#define NUM_PROCS_DELTA		5		/* delta # procs a proc invokes		 	*/
-//extern std::list<Function> pProcList;
-//extern FunctionListType pProcList;
-//extern CALL_GRAPH * callGraph;	/* Pointer to the head of the call graph     */
+typedef struct _callGraph {
+	PPROC			  proc;			/* Pointer to procedure in pProcList	*/
+	Int				  numOutEdges;	/* # of out edges (ie. # procs invoked)	*/
+	Int				  numAlloc;		/* # of out edges allocated				*/
+	struct _callGraph **outEdges;	/* array of out edges					*/
+} CALL_GRAPH;
+typedef CALL_GRAPH *PCALL_GRAPH;
+#define NUM_PROCS_DELTA		5		/* delta # procs a proc invokes		 	*/
+
+extern PPROC pProcList;         /* Pointer to the head of the procedure list */
+extern PPROC pLastProc;			/* Pointer to last node of the proc list     */
+extern PCALL_GRAPH callGraph;	/* Pointer to the head of the call graph     */
 extern bundle cCode;			/* Output C procedure's declaration and code */
 
+/* Procedure FLAGS */
+#define PROC_BADINST   0x000100 /* Proc contains invalid or 386 instruction */
+#define PROC_IJMP      0x000200 /* Proc incomplete due to indirect jmp	 	*/
+#define PROC_ICALL     0x000400 /* Proc incomplete due to indirect call		*/
+#define PROC_HLL       0x001000 /* Proc is likely to be from a HLL			*/
+#define CALL_PASCAL    0x002000 /* Proc uses Pascal calling convention		*/
+#define CALL_C         0x004000 /* Proc uses C calling convention			*/
+#define CALL_UNKNOWN   0x008000 /* Proc uses unknown calling convention		*/
+#define PROC_NEAR      0x010000 /* Proc exits with near return				*/
+#define PROC_FAR       0x020000 /* Proc exits with far return				*/
+#define GRAPH_IRRED    0x100000 /* Proc generates an irreducible graph		*/
+#define SI_REGVAR	   0x200000 /* SI is used as a stack variable 			*/
+#define DI_REGVAR	   0x400000 /* DI is used as a stack variable 			*/
+#define PROC_IS_FUNC   0x800000	/* Proc is a function 						*/
+#define REG_ARGS	  0x1000000 /* Proc has registers as arguments			*/
+#define	PROC_VARARG	  0x2000000	/* Proc has variable arguments				*/
+#define PROC_OUTPUT   0x4000000 /* C for this proc has been output 			*/
+#define PROC_RUNTIME  0x8000000 /* Proc is part of the runtime support		*/
+#define PROC_ISLIB	 0x10000000 /* Proc is a library function				*/
+#define PROC_ASM	 0x20000000 /* Proc is an intrinsic assembler routine   */
+#define PROC_IS_HLL  0x40000000 /* Proc has HLL prolog code					*/
+#define CALL_MASK    0xFFFF9FFF /* Masks off CALL_C and CALL_PASCAL		 	*/
+
+/* duVal FLAGS */
+#define DEF 0x0010      /* Variable was first defined than used 		*/
+#define USE 0x0100      /* Variable was first used than defined 		*/
+#define VAL 0x1000      /* 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.       				*/
+#define USEVAL  0x1100  /* Use and Val              					*/
+
+
 /**** Global variables ****/
 
 extern char *asm1_name, *asm2_name; /* Assembler output filenames 		*/
@@ -55,95 +151,174 @@ typedef struct {            /* Command line option flags */
     unsigned Map            : 1;
     unsigned Stats          : 1;
     unsigned Interact       : 1;    /* Interactive mode */
-    unsigned Calls          : 1;    /* Follow register indirect calls */
-    char	filename[80];			/* The input filename */
+	unsigned Calls			: 1;	/* Follow register indirect calls */
+	char	filename[80];			/* The input filename */
 } OPTION;
 
 extern OPTION option;       /* Command line options             */
+extern SYMTAB symtab;       /* Global symbol table              */
 
-#include "BinaryImage.h"
-extern std::bitset<32> duReg[30];   /* def/use bits for registers		*/
+typedef struct {            /* Loaded program image parameters  */
+    int16       initCS;
+    int16       initIP;     /* These are initial load values    */
+    int16       initSS;     /* Probably not of great interest   */
+    int16       initSP;
+    boolT       fCOM;       /* Flag set if COM program (else EXE)*/
+    Int         cReloc;     /* No. of relocation table entries  */
+    dword      *relocTable; /* Ptr. to relocation table         */
+    byte       *map;        /* Memory bitmap ptr                */
+    Int         cProcs;     /* Number of procedures so far      */
+    Int         offMain;    /* The offset  of the main() proc   */
+    word        segMain;    /* The segment of the main() proc   */
+	boolT		bSigs;		/* True if signatures loaded		*/
+    Int         cbImage;    /* Length of image in bytes         */
+    byte       *Image;      /* Allocated by loader to hold entire 
+                             * program image                    */
+} PROG;
 
-//extern uint32_t duReg[30];		/* def/use bits for registers		*/
-extern std::bitset<32> maskDuReg[30];	/* masks off du bits for regs		*/
+extern PROG prog;   		/* Loaded program image parameters  */
+extern char condExp[200];	/* Conditional expression buffer 	*/
+extern char callBuf[100];	/* Function call buffer				*/
+extern dword duReg[30];		/* def/use bits for registers		*/
+extern dword maskDuReg[30];	/* masks off du bits for regs		*/
 
 /* Registers used by icode instructions */
+static char *allRegs[21] = {"ax", "cx", "dx", "bx", "sp", "bp", 
+                			"si", "di", "es", "cs", "ss", "ds", 
+							"al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
+							"tmp"};
 
 /* Memory map states */
-enum eAreaType
-{
-    BM_UNKNOWN = 0,   /* Unscanned memory     */
-    BM_DATA =    1,   /* Data                 */
-    BM_CODE =    2,   /* Code                 */
-    BM_IMPURE =  3   /* Used as Data and Code*/
-};
+#define BM_UNKNOWN  0   /* Unscanned memory     */
+#define BM_DATA     1   /* Data                 */
+#define BM_CODE     2   /* Code                 */
+#define BM_IMPURE   3   /* Used as Data and Code*/
 
 /* Intermediate instructions statistics */
-struct STATS
-{
-        int		numBBbef;       /* number of basic blocks initially 	       */
-        int		numBBaft;       /* number of basic blocks at the end 	       */
-        int		nOrder;         /* n-th order								   */
-        int		numLLIcode;     /* number of low-level Icode instructions      */
-        int		numHLIcode; 	/* number of high-level Icode instructions     */
-        int		totalLL;        /* total number of low-level Icode insts       */
-        int		totalHL;        /* total number of high-level Icod insts       */
-};
+typedef struct {
+	Int		numBBbef;		/* number of basic blocks initially 	       */
+	Int		numBBaft;		/* number of basic blocks at the end 	       */
+	Int		nOrder;			/* n-th order								   */
+	Int		numLLIcode;		/* number of low-level Icode instructions      */
+	Int		numHLIcode; 	/* number of high-level Icode instructions     */
+	Int		totalLL;		/* total number of low-level Icode insts       */
+	Int		totalHL;		/* total number of high-level Icod insts       */
+} STATS;
 
 extern STATS stats; /* Icode statistics */
 
 
 /**** Global function prototypes ****/
-class DccFrontend
-{
-    void    LoadImage(Project &proj);
-    void    parse(Project &proj);
-    std::string m_fname;
-public:
-    DccFrontend(const std::string &fname) : m_fname(fname)
-    {
-    }
-    bool FrontEnd();            /* frontend.c   */
-};
 
+void    FrontEnd(char *filename, PCALL_GRAPH *);            /* frontend.c   */
+void   *allocMem(Int cb);                                   /* frontend.c   */
+void   *reallocVar(void *p, Int newsize);                   /* frontend.c   */
 void    udm(void);                                          /* udm.c        */
-void    freeCFG(BB * cfg);                                  /* graph.c      */
-BB *    newBB(BB *, int, int, uint8_t, int, Function *);    /* graph.c      */
-void    BackEnd(char *filename, CALL_GRAPH *);              /* backend.c    */
-char   *cChar(uint8_t c);                                   /* backend.c    */
-eErrorId scan(uint32_t ip, ICODE &p);                       /* scanner.c    */
-void    parse (CALL_GRAPH * *);                             /* parser.c     */
-
-int     strSize (uint8_t *, char);                          /* parser.c     */
-//void    disassem(int pass, Function * pProc);             /* disassem.c   */
-void    interactDis(Function * initProc, int initIC);       /* disassem.c   */
-bool    JmpInst(llIcode opcode);                            /* idioms.c     */
-queue::iterator  appendQueue(queue &Q, BB *node);           /* reducible.c  */
-
+PBB     createCFG(PPROC pProc);                             /* graph.c      */
+void    compressCFG(PPROC pProc);                           /* graph.c      */
+void    freeCFG(PBB cfg);                                   /* graph.c      */
+PBB     newBB(PBB, Int, Int, byte, Int, PPROC);				/* graph.c		*/
+void    BackEnd(char *filename, PCALL_GRAPH);               /* backend.c    */
+char   *cChar(byte c);                                      /* backend.c    */
+Int     scan(dword ip, PICODE p);                           /* scanner.c    */
+void    parse (PCALL_GRAPH *);                              /* parser.c     */
+boolT   labelSrch(PICODE pIc, Int n, dword tg, Int *pIdx);  /* parser.c     */
+void    setState(PSTATE state, word reg, int16 value);      /* parser.c     */
+Int		strSize (byte *, char);								/* parser.c		*/
+void    disassem(Int pass, PPROC pProc);                    /* disassem.c   */
+void    interactDis(PPROC initProc, Int initIC);            /* disassem.c   */
+void	bindIcodeOff (PPROC);								/* idioms.c		*/
+void    lowLevelAnalysis (PPROC pProc);                     /* idioms.c     */
+void    propLong (PPROC pproc);								/* proplong.c   */
+boolT   JmpInst(llIcode opcode);                            /* idioms.c     */
+void    checkReducibility(PPROC pProc, derSeq **derG);      /* reducible.c  */
+queue   *appendQueue(queue **Q, BB *node);                  /* reducible.c  */
+void    freeDerivedSeq(derSeq *derivedG);                   /* reducible.c  */
+void    displayDerivedSeq(derSeq *derG);                    /* reducible.c  */
+void    structure(PPROC pProc, derSeq *derG);               /* control.c    */
+void	compoundCond (PPROC);								/* control.c    */
+void    dataFlow(PPROC pProc, dword liveOut);               /* dataflow.c   */
+void    writeIntComment (PICODE icode, char *s);      		/* comwrite.c   */
+void    writeProcComments (PPROC pProc, strTable *sTab);    /* comwrite.c   */
+void    checkStartup(PSTATE pState);                        /* chklib.c     */
 void    SetupLibCheck(void);                                /* chklib.c     */
 void    CleanupLibCheck(void);                              /* chklib.c     */
-bool    LibCheck(Function &p);                              /* chklib.c     */
+boolT   LibCheck(PPROC p);                                  /* chklib.c     */
 
 /* Exported functions from procs.c */
-boolT	insertCallGraph (CALL_GRAPH *, ilFunction, ilFunction);
-void	adjustActArgType (COND_EXPR *, hlType, Function *);
+boolT	insertCallGraph (PCALL_GRAPH, PPROC, PPROC);
+void	writeCallGraph (PCALL_GRAPH);
+void 	newRegArg (PPROC, PICODE, PICODE);
+boolT 	newStkArg (PICODE, COND_EXPR *, llIcode, PPROC);
+void	allocStkArgs (PICODE, Int);
+void	placeStkArg (PICODE, COND_EXPR *, Int);
+void	adjustActArgType (COND_EXPR *, hlType, PPROC);		
+void	adjustForArgType (PSTKFRAME, Int, hlType);
 
 /* 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 *);
-
+COND_EXPR *boolCondExp (COND_EXPR *lhs, COND_EXPR *rhs, condOp op);
+COND_EXPR *unaryCondExp (condNodeType, COND_EXPR *exp);
+COND_EXPR *idCondExpGlob (int16 segValue, int16 off);
+COND_EXPR *idCondExpReg (byte regi, flags32 flg, LOCAL_ID *);
+COND_EXPR *idCondExpRegIdx (Int idx, regType);
+COND_EXPR *idCondExpLoc (Int off, LOCAL_ID *);
+COND_EXPR *idCondExpParam (Int off, PSTKFRAME argSymtab);
+COND_EXPR *idCondExpKte (dword kte, byte);
+COND_EXPR *idCondExpLong (LOCAL_ID *, opLoc, PICODE, hlFirst, Int idx, operDu,
+						  Int);
+COND_EXPR *idCondExpLongIdx (Int);
+COND_EXPR *idCondExpFunc (PPROC, PSTKFRAME);
+COND_EXPR *idCondExpOther (byte seg, byte regi, int16 off);
+COND_EXPR *idCondExpID (ID *, LOCAL_ID *, Int);
+COND_EXPR *idCondExp (PICODE, opLoc, PPROC, Int i, PICODE duIcode, operDu);
+COND_EXPR *copyCondExp (COND_EXPR *);
+void	  removeRegFromLong (byte, LOCAL_ID *, COND_EXPR *);
+char      *walkCondExpr (COND_EXPR *exp, PPROC pProc, Int *);
+condId 	  idType (PICODE pIcode, opLoc sd);
+Int		  hlTypeSize (COND_EXPR *, PPROC);
+hlType	  expType (COND_EXPR *, PPROC);
+void	  setRegDU (PICODE, byte regi, operDu);
+void	  copyDU (PICODE, PICODE, operDu, operDu);
+void	  changeBoolCondExpOp (COND_EXPR *, condOp);
+boolT	  insertSubTreeReg (COND_EXPR *, COND_EXPR **, byte, LOCAL_ID *);
+boolT	  insertSubTreeLongReg (COND_EXPR *, COND_EXPR **, Int);
+void      freeCondExpr (COND_EXPR *exp);
+COND_EXPR *concatExps (SEQ_COND_EXPR *, COND_EXPR *, condNodeType);
+void	  initExpStk();
+void	  pushExpStk (COND_EXPR *);
+COND_EXPR *popExpStk();
+Int		  numElemExpStk();
+boolT	  emptyExpStk();
 
 /* Exported functions from hlicode.c */
-std::string writeCall (Function *, STKFRAME &, Function *, int *);
-char 	*writeJcond (const HLTYPE &, Function *, int *);
-char 	*writeJcondInv (HLTYPE, Function *, int *);
-
+void    newAsgnHlIcode (PICODE, COND_EXPR *, COND_EXPR *);
+void	newCallHlIcode (PICODE);
+void    newUnaryHlIcode (PICODE, hlIcode, COND_EXPR *);
+void    newJCondHlIcode (PICODE, COND_EXPR *);
+void	invalidateIcode (PICODE);
+boolT	removeDefRegi (byte, PICODE, Int, LOCAL_ID *);
+void	highLevelGen (PPROC);
+char	*writeCall (PPROC, PSTKFRAME, PPROC, Int *);
+char 	*write1HlIcode (HLTYPE, PPROC, Int *);
+char 	*writeJcond (HLTYPE, PPROC, Int *);
+char 	*writeJcondInv (HLTYPE, PPROC, Int *);
+Int		power2 (Int);
+void	writeDU (PICODE, Int);
+void	inverseCondOp (COND_EXPR **);
 
-/* Exported funcions from locident.c */
-boolT checkLongEq (LONG_STKID_TYPE, iICODE, int, Function *, Assignment &asgn, LLInst &atOffset);
-boolT checkLongRegEq (LONGID_TYPE, iICODE, int, Function *, Assignment &asgn, LLInst &);
-eReg otherLongRegi(eReg, int, LOCAL_ID *);
+/* Exported funcions from locident.c */ 
+Int newByteWordRegId (LOCAL_ID *, hlType t, byte regi);
+Int newByteWordStkId (LOCAL_ID *, hlType t, Int off, byte regOff);
+Int	newIntIdxId (LOCAL_ID *, int16 seg, int16 off, byte regi, Int, hlType);
+Int newLongRegId (LOCAL_ID *, hlType t, byte regH, byte regL, Int idx);
+Int newLongStkId (LOCAL_ID *, hlType t, Int offH, Int offL);
+Int newLongId (LOCAL_ID *, opLoc sd, PICODE, hlFirst, Int idx, operDu, Int);
+boolT checkLongEq (LONG_STKID_TYPE, PICODE, Int, Int, PPROC, COND_EXPR **,
+				   COND_EXPR **, Int);
+boolT checkLongRegEq (LONGID_TYPE, PICODE, Int, Int, PPROC, COND_EXPR **,
+					  COND_EXPR **, Int);
+byte otherLongRegi (byte, Int, LOCAL_ID *);
+void insertIdx (IDX_ARRAY *, Int);
+void propLongId (LOCAL_ID *, byte, byte, char *);
 
 
-extern const char *indentStr(int level);

+ 4 - 29
include/disassem.h

@@ -2,32 +2,7 @@
  *  dcc project disassembler header
  * (C) Mike van Emmerik
  ****************************************************************************/
-#pragma once
-#include <sstream>
-#include <fstream>
-#include <vector>
-#include "bundle.h"
-struct LLInst;
-struct Disassembler
-{
-protected:
-    int pass;
-    int g_lab;
-    //bundle &cCode;
-    std::ofstream m_fp;
-    std::vector<std::string> m_decls;
-    std::vector<std::string> m_code;
 
-public:
-    Disassembler(int _p) : pass(_p)
-    {
-        g_lab=0;
-    }
-public:
-    void disassem(Function *ppProc);
-    void disassem(Function *ppProc, int i);
-    void dis1Line(LLInst &inst, int loc_ip, int pass);
-};
 /* Definitions for extended keys (first key is zero) */
 
 #define EXT			0x100		/* "Extended" flag */
@@ -44,10 +19,10 @@ public:
 #ifdef _CONSOLE
 #define KEY_DOWN	0x50		/* Same as keypad scancodes */
 #define KEY_LEFT	0x4B
-#define KEY_UP		0x48
-#define KEY_RIGHT	0x4D
-#define KEY_NPAGE	0x51
-#define KEY_PPAGE	0x49
+#define KEY_UP		0x48		
+#define KEY_RIGHT	0x4D	
+#define KEY_NPAGE	0x51	
+#define KEY_PPAGE	0x49	
 #endif
 
 #ifdef __UNIX__

+ 21 - 18
include/dosdcc.h

@@ -5,34 +5,34 @@
  **************************************************************************/
 
 /* Type definitions for intel 80x86 architecture */
-typedef unsigned int    uint16_t;       /* 16 bits */
-typedef unsigned char   uint8_t;       /* 8 bits  */
+typedef unsigned int    Word;       /* 16 bits */
+typedef unsigned char   Byte;       /* 8 bits  */
 typedef union {
     unsigned long   dW;
-    uint16_t            wL, wH;         /* 2 words */
+    Word            wL, wH;         /* 2 words */
 } Dword;                            /* 32 bits */
 
-/* Structure to access high and low bits of a uint8_t or uint16_t variable */
+/* Structure to access high and low bits of a Byte or Word variable */
 typedef struct {
-    /* low  uint8_t */
-    uint16_t    lowBitWord  : 1;
-    uint16_t    filler1     : 6;
-    uint16_t    highBitByte : 1;
-    /* high uint8_t */ 
-    uint16_t    lowBitByte  : 1;
-    uint16_t    filler2     : 6;
-    uint16_t    highBitWord : 1;
+    /* low  byte */
+    Word    lowBitWord  : 1;
+    Word    filler1     : 6;
+    Word    highBitByte : 1;
+    /* high byte */ 
+    Word    lowBitByte  : 1;
+    Word    filler2     : 6;
+    Word    highBitWord : 1;
 } wordBits;
 
-/* Low and high bits of a uint8_t or uint16_t variable */
+/* Low and high bits of a Byte or Word variable */
 #define lowBit(a)       ((wordBits)(a).lowBitWord)
 #define highBitByte(a)  ((wordBits)(a).highBitByte)
 #define lowBitByte(a)   ((wordBits)(a).lowBitByte)
-#define highBit(a)      (sizeof(a) == sizeof(uint16_t) ? \
+#define highBit(a)      (sizeof(a) == sizeof(Word) ? \
                         ((wordBits)(a).highBitWord):\
                         ((wordBits)(a).highBitByte))
 
-/* uint16_t register variables */
+/* Word register variables */
 #define ax      regs.x.ax
 #define bx      regs.x.bx
 #define cx      regs.x.cx
@@ -52,7 +52,7 @@ typedef struct {
 #define carry       regs.x.cflags
 #define overF       regs.x.flags    /***** check *****/
 
-/* uint8_t register variables */
+/* Byte register variables */
 #define ah      regs.h.ah
 #define al      regs.h.al
 #define bh      regs.h.bh
@@ -64,8 +64,8 @@ typedef struct {
 
 
 /* High and low words of a Dword */
-#define highWord(w)     (*((uint16_t*)&(w) + 1))
-#define lowWord(w)      ((uint16_t)(w))
+#define highWord(w)     (*((Word*)&(w) + 1))
+#define lowWord(w)      ((Word)(w))
 
 #define MAXByte     0xFF
 #define MAXWord     0xFFFF
@@ -74,4 +74,7 @@ typedef struct {
 #define MAXSignWord 0x7FFF
 #define MINSignWord 0x8001
 
+/* Booleans */
+#define TRUE    1
+#define FALSE   0
 

+ 23 - 26
include/error.h

@@ -2,35 +2,32 @@
  * Error codes
  * (C) Cristina Cifuentes
  ****************************************************************************/
-#pragma once
+
 
 /* These definitions refer to errorMessage in error.c */
-enum eErrorId
-{
-    NO_ERR              =0,
-    USAGE,
-    INVALID_ARG,
-    INVALID_OPCODE,
-    INVALID_386OP,
-    FUNNY_SEGOVR,
-    FUNNY_REP,
-    CANNOT_OPEN,
-    CANNOT_READ,
-    MALLOC_FAILED,
-    NEWEXE_FORMAT,
 
-    NO_BB,
-    INVALID_SYNTHETIC_BB,
-    INVALID_INT_BB,
-    IP_OUT_OF_RANGE,
-    DEF_NOT_FOUND,
-    JX_NOT_DEF,
-    NOT_DEF_USE,
-    REPEAT_FAIL,
-    WHILE_FAIL
-};
+#define USAGE                   0
+#define INVALID_ARG             1
+#define INVALID_OPCODE          2
+#define INVALID_386OP           3
+#define FUNNY_SEGOVR            4
+#define FUNNY_REP               5
+#define CANNOT_OPEN             6
+#define CANNOT_READ             7
+#define MALLOC_FAILED           8
+#define NEWEXE_FORMAT           9
+
+#define NO_BB              		10
+#define INVALID_SYNTHETIC_BB    11
+#define INVALID_INT_BB          12
+#define IP_OUT_OF_RANGE         13
+#define DEF_NOT_FOUND           14
+#define JX_NOT_DEF				15
+#define NOT_DEF_USE				16
+#define REPEAT_FAIL				17
+#define WHILE_FAIL				18
 
 
-void fatalError(eErrorId errId, ...);
-void reportError(eErrorId errId, ...);
+void fatalError(Int errId, ...);
+void reportError(Int errId, ...);
 

+ 101 - 70
include/graph.h

@@ -2,49 +2,37 @@
  *      CFG, BB and interval related definitions
  * (C) Cristina Cifuentes
  ****************************************************************************/
-#pragma once
-#include <list>
-#include <vector>
-struct Function;
+
+
 /* Types of basic block nodes */
 /* Real basic blocks: type defined according to their out-edges */
-enum eBBKind
-{
-    ONE_BRANCH = 0,   /* unconditional branch */
-    TWO_BRANCH = 1,   /* conditional branch   */
-    MULTI_BRANCH=2,   /* case branch          */
-    FALL_NODE=3,   /* fall through         */
-    RETURN_NODE=4,   /* procedure/program return */
-    CALL_NODE=5,   /* procedure call       */
-    LOOP_NODE=6,   /* loop instruction     */
-    REP_NODE=7,   /* repeat instruction   */
-    INTERVAL_NODE=8,   /* contains interval list */
+#define ONE_BRANCH      0   /* unconditional branch */
+#define TWO_BRANCH      1   /* conditional branch   */
+#define MULTI_BRANCH    2   /* case branch          */
+#define FALL_NODE       3   /* fall through         */
+#define RETURN_NODE     4   /* procedure/program return */
+#define CALL_NODE       5   /* procedure call       */
+#define LOOP_NODE       6   /* loop instruction     */
+#define REP_NODE        7   /* repeat instruction   */
+#define INTERVAL_NODE   8   /* contains interval list */
 
-    TERMINATE_NODE=11,   /* Exit to DOS          */
-    NOWHERE_NODE=12   /* No outedges going anywhere */
-};
+#define TERMINATE_NODE 11   /* Exit to DOS          */
+#define NOWHERE_NODE   12   /* No outedges going anywhere */
 
 
 /* Depth-first traversal constants */
-enum eDFS
-{
-    DFS_NONE,
-    DFS_DISP=1,   /* Display graph pass   */
-    DFS_MERGE=2,   /* Merge nodes pass     */
-    DFS_NUM=3,   /* DFS numbering pass   */
-    DFS_CASE=4,   /* Case pass            */
-    DFS_ALPHA=5,   /* Alpha code generation*/
-    DFS_JMP=9   /* rmJMP pass - must be largest flag */
-};
+#define DFS_DISP        1   /* Display graph pass   */
+#define DFS_MERGE       2   /* Merge nodes pass     */
+#define DFS_NUM         3   /* DFS numbering pass   */
+#define DFS_CASE        4   /* Case pass            */
+#define DFS_ALPHA       5   /* Alpha code generation*/
+#define DFS_JMP         9   /* rmJMP pass - must be largest flag */
 
 /* Control flow analysis constants */
-enum eNodeHeaderType
-{
-    NO_TYPE=0,   /* node is not a loop header*/
-    WHILE_TYPE=1,   /* node is a while header   */
-    REPEAT_TYPE=2,   /* node is a repeat header  */
-    ENDLESS_TYPE=3   /* endless loop header      */
-};
+#define NO_TYPE         0   /* node is not a loop header*/
+#define WHILE_TYPE      1   /* node is a while header   */
+#define REPEAT_TYPE     2   /* node is a repeat header  */
+#define ENDLESS_TYPE    3   /* endless loop header      */
 
 /* Uninitialized values for certain fields */
 #define NO_NODE         MAX /* node has no associated node  */
@@ -55,47 +43,90 @@ enum eNodeHeaderType
 #define ELSE            1   /* else edge            */
 
 /* Basic Block (BB) flags */
-#define INVALID_BB      0x0001		/* BB is not valid any more 		 */
+#define INVALID_BB		0x0001		/* BB is not valid any more 		 */
 #define IS_LATCH_NODE	0x0002		/* BB is the latching node of a loop */
 
-struct BB;
+
 /* Interval structure */
-typedef std::list<BB *> queue;
+typedef struct _queueNode {
+    struct _BB         *node;   /* Ptr to basic block   */
+    struct _queueNode  *next;
+} queue;
+
+typedef struct _intNode {
+    byte            numInt;         /* # of the interval    */
+    byte            numOutEdges;    /* Number of out edges  */
+    queue           *nodes;         /* Nodes of the interval*/
+    queue           *currNode;      /* Current node     */
+    struct _intNode *next;          /* Next interval    */
+} interval;
 
-struct interval
+typedef union
 {
-    uint8_t            numInt;         /* # of the interval    */
-    uint8_t            numOutEdges;    /* Number of out edges  */
-    queue           nodes;         /* Nodes of the interval*/
-    queue::iterator currNode;      /* Current node     */
-    interval *next;          /* Next interval    */
-    BB *firstOfInt();
-    interval()
-    {
-        numInt=numOutEdges=0;
-        currNode=nodes.end();
-        next=0;
-    }
-};
+      dword         ip;             /* Out edge icode address       */
+      struct _BB   *BBptr;          /* Out edge pointer to next BB  */
+      interval     *intPtr;         /* Out edge ptr to next interval*/
+} TYPEADR_TYPE;
+
+/* Basic block (BB) node definition */
+typedef struct _BB {
+    byte            nodeType;       /* Type of node                 */
+    Int             traversed;      /* Boolean: traversed yet?      */
+    Int             start;          /* First instruction offset     */
+    Int             length;         /* No. of instructions this BB  */
+	Int				numHlIcodes;	/* No. of high-level icodes		*/
+	flags32			flg;			/* BB flags						*/
+
+    /* In edges and out edges */
+    Int             numInEdges;     /* Number of in edges           */
+    struct _BB    **inEdges;        /* Array of ptrs. to in edges   */
+
+    Int     		numOutEdges;    /* Number of out edges          */
+    TYPEADR_TYPE	*edges;          /* Array of ptrs. to out edges  */
+
+    /* For interval construction */
+    Int             beenOnH;        /* #times been on header list H */
+    Int             inEdgeCount;    /* #inEdges (to find intervals) */
+    struct _BB     *reachingInt;    /* Reaching interval header     */
+    interval       *inInterval;     /* Node's interval              */
+
+    /* For derived sequence construction */
+    interval       *correspInt;     /* Corresponding interval in
+                                     * derived graph Gi-1       	*/
+
+	/* For live register analysis 
+	 * LiveIn(b) = LiveUse(b) U (LiveOut(b) - Def(b))	*/
+	dword			liveUse;		/* LiveUse(b)					*/
+	dword			def;			/* Def(b)						*/
+	dword			liveIn;			/* LiveIn(b)					*/
+	dword			liveOut;		/* LiveOut(b)					*/
+
+    /* For structuring analysis */
+    Int             dfsFirstNum;    /* DFS #: first visit of node   */
+    Int             dfsLastNum;     /* DFS #: last visit of node    */
+    Int             immedDom;       /* Immediate dominator (dfsLast
+                                     * index)                       */
+    Int             ifFollow;       /* node that ends the if        */
+    Int             loopType;       /* Type of loop (if any)        */
+    Int             latchNode;      /* latching node of the loop    */
+	Int				numBackEdges;	/* # of back edges				*/
+    Int             loopHead;       /* most nested loop head to which
+                                     * this node belongs (dfsLast)  */
+    Int             loopFollow;     /* node that follows the loop   */
+    Int             caseHead;       /* most nested case to which this
+                                        node belongs (dfsLast)      */
+    Int             caseTail;       /* tail node for the case       */
+
+    Int             index;          /* Index, used in several ways  */
+    struct _BB     *next;           /* Next (list link)             */
+} BB;
+typedef BB *PBB;
 
 
 /* Derived Sequence structure */
-struct derSeq_Entry
-{
-    BB *                Gi;        /* Graph pointer        */
-    interval *          Ii;        /* Interval list of Gi  */
-    derSeq_Entry() : Gi(0),Ii(0)
-    {
-
-    }
-    ~derSeq_Entry();
-public:
-    void findIntervals(Function *c);
-};
-class derSeq : public std::list<derSeq_Entry>
-{
-public:
-    void display();
-};
-void    freeDerivedSeq(derSeq &derivedG);                   /* reducible.c  */
+typedef struct _derivedNode {
+    BB                  *Gi;        /* Graph pointer        */
+    interval            *Ii;        /* Interval list of Gi  */
+    struct _derivedNode *next;      /* Next derived graph   */
+} derSeq;
 

+ 20 - 4
include/hlicode.h

@@ -1,4 +1,4 @@
-/*
+/* 
  * File:    hlIcode.h
  * Purpose: module definitions for high-level icodes
  * Date:    September 1993
@@ -6,8 +6,16 @@
 
 
 /* High level icodes opcodes - def in file icode.h */
-struct HLICODE
-{
+/*typedef enum {
+    HLI_ASSIGN,
+    INC,
+    DEC,
+    HLI_JCOND,
+
+} hlIcode; */
+
+
+typedef struct {
     hlIcode             opcode;     /* hlIcode opcode           */
     union {                         /* different operands       */
         struct {
@@ -17,4 +25,12 @@ struct HLICODE
         COND_EXPR       *exp;       /* for HLI_JCOND, INC, DEC      */
     }                   oper;       /* operand                  */
     boolT               valid;      /* has a valid hlIcode      */
-};
+} HLICODE;
+
+
+typedef struct {
+    Int         numIcodes;      /* No. of hlIcode reocrds written   */
+    Int         numAlloc;       /* No. of hlIcode records allocated */
+    HLICODE     *hlIcode;       /* Array of high-level icodes       */
+} HLICODEREC;
+

+ 345 - 467
include/icode.h

@@ -2,489 +2,367 @@
  *          I-code related definitions
  * (C) Cristina Cifuentes
  ****************************************************************************/
-#pragma once
-#include <memory>
-#include <vector>
-#include <list>
-#include <bitset>
-#include <llvm/ADT/ilist.h>
-#include <llvm/ADT/ilist_node.h>
-#include <llvm/CodeGen/MachineInstr.h>
-#include <llvm/MC/MCInst.h>
-#include <llvm/MC/MCAsmInfo.h>
-#include <llvm/Value.h>
-#include <llvm/Instruction.h>
-#include <boost/range.hpp>
-#include "libdis.h"
-#include "Enums.h"
+
+
+/* LOW_LEVEL icode flags */
+#define B           0x000001    /* Byte operands (value implicitly used) */
+#define I           0x000002    /* Immed. source */
+#define NOT_HLL     0x000004    /* Not HLL inst. */
+#define FLOAT_OP    0x000008    /* ESC or WAIT   */
+
+#define SEG_IMMED   0x000010    /* Number is relocated segment value */
+#define IMPURE      0x000020    /* Instruction modifies code */
+#define WORD_OFF    0x000040    /* Inst has word offset ie.could be address */
+#define TERMINATES  0x000080    /* Instruction terminates program */
+
+#define CASE        0x000100    /* Label as case part of switch */
+#define SWITCH      0x000200    /* Treat indirect JMP as switch stmt */
+#define TARGET      0x000400    /* Jump target */
+#define SYNTHETIC   0x000800    /* Synthetic jump instruction */
+#define NO_LABEL    0x001000    /* Immed. jump cannot be linked to a label */
+#define NO_CODE     0x002000    /* Hole in Icode array */
+#define SYM_USE     0x004000    /* Instruction uses a symbol */
+#define SYM_DEF     0x008000    /* Instruction defines a symbol */
+
+#define NO_SRC      0x010000    /* Opcode takes no source */
+#define NO_OPS      0x020000    /* Opcode takes no operands */
+#define IM_OPS      0x040000    /* Opcode takes implicit operands */
+#define SRC_B       0x080000    /* Source operand is byte (dest is word) */
+#define NO_SRC_B    0xF7FFFF    /* Masks off SRC_B */
+#define HLL_LABEL   0x100000    /* Icode has a high level language label */
+#define IM_DST		0x200000	/* Implicit DST for opcode (SIGNEX) */
+#define IM_SRC		0x400000	/* Implicit SRC for opcode (dx:ax)	*/
+#define IM_TMP_DST	0x800000	/* Implicit rTMP DST for opcode (DIV/IDIV) */
+
+#define JMP_ICODE  0x1000000    /* Jmp dest immed.op converted to icode index */
+#define JX_LOOP	   0x2000000	/* Cond jump is part of loop conditional exp */
+#define REST_STK   0x4000000	/* Stack needs to be restored after CALL */
+
+/*  Parser flags  */
+#define TO_REG      0x000100    /* rm is source  */
+#define S           0x000200    /* sign extend   */
+#define OP386       0x000400    /* 386 op-code   */
+#define NSP         0x000800    /* NOT_HLL if SP is src or dst */
+#define ICODEMASK   0xFF00FF    /* Masks off parser flags */
+
+/* LOW_LEVEL icode, DU flag bits */
+#define Cf           1  
+#define Sf           2
+#define Zf           4
+#define Df           8
+
+/* Machine registers */
+#define rAX          1  /* These are numbered relative to real 8086 */
+#define rCX          2
+#define rDX          3
+#define rBX          4
+#define rSP          5
+#define rBP          6
+#define rSI          7
+#define rDI          8
+
+#define rES          9
+#define rCS         10
+#define rSS         11
+#define rDS         12
+
+#define rAL         13
+#define rCL         14
+#define rDL         15
+#define rBL         16
+#define rAH         17
+#define rCH         18
+#define rDH         19
+#define rBH         20
+
+#define rTMP		21			/* temp register for DIV/IDIV/MOD	*/
+#define INDEXBASE   22          /* Indexed modes go from INDEXBASE to
+                                 * INDEXBASE+7  */
+
+/* Byte and Word registers */
+static char *byteReg[9]  = {"al", "cl", "dl", "bl", 
+							"ah", "ch", "dh", "bh", "tmp" };
+static char *wordReg[21] = {"ax", "cx", "dx", "bx", "sp", "bp", 
+                			"si", "di", "es", "cs", "ss", "ds",
+							"", "", "", "", "", "", "", "", "tmp"};
+
 #include "state.h"			// State depends on INDEXBASE, but later need STATE
 
-//enum condId;
-
-struct LOCAL_ID;
-struct BB;
-struct Function;
-struct STKFRAME;
-struct CIcodeRec;
-struct ICODE;
-struct bundle;
-typedef std::list<ICODE>::iterator iICODE;
-typedef std::list<ICODE>::reverse_iterator riICODE;
-typedef boost::iterator_range<iICODE> rCODE;
-extern std::bitset<32> duReg[30];
-/* uint8_t and uint16_t registers */
+/* Types of icodes */
+typedef enum {
+    NOT_SCANNED = 0,    /* not even scanned yet */
+    LOW_LEVEL,          /* low-level icode  */
+    HIGH_LEVEL          /* high-level icode */
+} icodeType;
+
+
+/* LOW_LEVEL icode opcodes */
+typedef enum {
+	iCBW,		/* 0 */
+    iAAA,
+    iAAD,       
+    iAAM,
+    iAAS,
+    iADC,
+    iADD,
+    iAND,
+    iBOUND,
+    iCALL,
+    iCALLF,		/* 10 */
+    iCLC,
+    iCLD,
+    iCLI,
+    iCMC,
+    iCMP,
+    iCMPS,
+    iREPNE_CMPS,
+    iREPE_CMPS,
+    iDAA,
+    iDAS,		/* 20 */
+    iDEC,
+    iDIV,
+    iENTER,
+    iESC,
+    iHLT,
+    iIDIV,
+    iIMUL,
+    iIN,
+    iINC,
+    iINS,		/* 30 */
+    iREP_INS,
+    iINT,
+    iIRET,
+    iJB,
+    iJBE,
+    iJAE,
+    iJA,
+    iJE,                
+    iJNE,
+    iJL,		/* 40 */
+    iJGE,
+    iJLE,
+    iJG,
+    iJS,                
+    iJNS,
+    iJO,
+    iJNO,
+    iJP,    
+    iJNP,
+    iJCXZ,		/* 50 */
+    iJMP,
+    iJMPF,
+    iLAHF,
+    iLDS,
+    iLEA,
+    iLEAVE,
+    iLES,
+    iLOCK,
+    iLODS,
+    iREP_LODS,	/* 60 */
+    iLOOP,
+    iLOOPE,
+    iLOOPNE,            
+    iMOV,		/* 64 */
+    iMOVS,
+    iREP_MOVS,
+    iMUL,		/* 67 */
+    iNEG,
+    iNOT,
+    iOR,   		/* 70 */ 
+    iOUT,
+    iOUTS,
+    iREP_OUTS,
+    iPOP,
+    iPOPA,
+    iPOPF,
+    iPUSH,
+    iPUSHA,
+    iPUSHF,
+    iRCL,		/* 80 */
+    iRCR,
+    iROL,
+    iROR,
+    iRET,		/* 84 */
+    iRETF,          
+    iSAHF,
+    iSAR,
+    iSHL,
+    iSHR,
+    iSBB,		/* 90 */
+    iSCAS,
+    iREPNE_SCAS,
+    iREPE_SCAS,
+    iSIGNEX,
+    iSTC,
+    iSTD,
+    iSTI,
+    iSTOS,
+    iREP_STOS,
+    iSUB,		/* 100 */
+    iTEST,
+    iWAIT,          
+    iXCHG,          
+    iXLAT,          
+    iXOR,
+    iINTO,          
+    iNOP,
+    iREPNE,         
+    iREPE,
+	iMOD,		/* 110 */
+} llIcode;
+
+
+/* HIGH_LEVEL icodes opcodes */
+typedef enum {
+    HLI_ASSIGN,         /* :=               		*/
+	HLI_CALL,			/* Call procedure			*/
+    HLI_JCOND,          /* Conditional jump 		*/
+	HLI_RET,			/* Return from procedure	*/
+	/* pseudo high-level icodes */
+	HLI_POP,			/* Pop expression			*/
+	HLI_PUSH,			/* Push expression			*/
+} hlIcode;
+
+
+/* Operand is defined, used or both flag */
+typedef enum {
+	DEF,			/* Operand is defined						*/
+	USE,			/* Operand is used							*/
+	USE_DEF,		/* Operand is used and defined				*/
+	NONE,			/* No operation is required on this operand	*/
+} operDu;
+
+// I can't believe these are necessary!
+#define E_DEF (operDu)DEF
+#define E_USE (operDu)USE
+#define E_NONE (operDu)NONE
+#define E_USE_DEF (operDu)USE_DEF
 
 /* Def/use of flags - low 4 bits represent flags */
-struct DU
-{
-    uint8_t   d;
-    uint8_t   u;
-};
+typedef struct {
+    byte   d;
+    byte   u;
+} DU;
+typedef DU *PDU;
 
-/* Definition-use chain for level 1 (within a basic block) */
-#define MAX_REGS_DEF	4		/* 2 regs def'd for long-reg vars */
+/* Def/Use of registers and stack variables */
+typedef struct {
+	dword	def;		/* For Registers: position in dword is reg index*/
+	dword	lastDefRegi;/* Bit set if last def of this register in BB   */
+	dword	use;		/* For Registers: position in dword is reg index*/
+}DU_ICODE;
 
 
-struct COND_EXPR;
-struct HlTypeSupport
-{
-    //hlIcode              opcode;    /* hlIcode opcode           */
-    virtual bool        removeRegFromLong(eReg regi, LOCAL_ID *locId)=0;
-    virtual std::string writeOut(Function *pProc, int *numLoc)=0;
-protected:
-    void performLongRemoval (eReg regi, LOCAL_ID *locId, COND_EXPR *tree);
-};
+/* Definition-use chain for level 1 (within a basic block) */
+#define MAX_REGS_DEF	2		/* 2 regs def'd for long-reg vars */
+#define MAX_USES		5
+
+typedef struct {
+	Int		numRegsDef;			/* # registers defined by this inst		*/
+	byte	regi[MAX_REGS_DEF];	/* registers defined by this inst		*/
+	Int		idx[MAX_REGS_DEF][MAX_USES];	/* inst that uses this def  */
+} DU1;
 
-struct CallType : public HlTypeSupport
-{
-    //for HLI_CALL
-    Function *      proc;
-    STKFRAME *      args;   // actual arguments
-    void allocStkArgs (int num);
-    bool newStkArg(COND_EXPR *exp, llIcode opcode, Function *pproc);
-    void placeStkArg(COND_EXPR *exp, int pos);
-    virtual COND_EXPR * toId();
-public:
-    bool removeRegFromLong(eReg regi, LOCAL_ID *locId)
-    {
-        printf("CallType : removeRegFromLong not supproted");
-        return false;
-    }
-    std::string writeOut(Function *pProc, int *numLoc);
-};
-struct AssignType : public HlTypeSupport
-{
-    /* for HLI_ASSIGN */
-    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);
-};
-struct ExpType : public HlTypeSupport
-{
-    /* for HLI_JCOND, HLI_RET, HLI_PUSH, HLI_POP*/
-    COND_EXPR    *v;
-    ExpType() : v(0) {}
-    bool removeRegFromLong(eReg regi, LOCAL_ID *locId)
-    {
-        performLongRemoval(regi,locId,v);
-        return true;
-    }
-    std::string writeOut(Function *pProc, int *numLoc);
-};
 
-struct HLTYPE
-{
-protected:
-public:
-    ExpType         exp;      /* for HLI_JCOND, HLI_RET, HLI_PUSH, HLI_POP*/
-    hlIcode         opcode;    /* hlIcode opcode           */
-    AssignType      asgn;
-    CallType        call;
-    HlTypeSupport *get()
-    {
-        switch(opcode)
-        {
-        case HLI_ASSIGN: return &asgn;
-        case HLI_RET:
-        case HLI_POP:
-        case HLI_JCOND:
-        case HLI_PUSH:   return &exp;
-        case HLI_CALL:   return &call;
-        default:
-            return 0;
-        }
-    }
-
-    void expr(COND_EXPR *e)
-    {
-        assert(e);
-        exp.v=e;
-    }
-    void replaceExpr(COND_EXPR *e)
-    {
-        assert(e);
-        delete exp.v;
-        exp.v=e;
-    }
-    COND_EXPR * expr() { return exp.v;}
-    const COND_EXPR * const expr() const  { return exp.v;}
-    void set(hlIcode i,COND_EXPR *e)
-    {
-        if(i!=HLI_RET)
-            assert(e);
-        assert(exp.v==0);
-        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;
-    }
-    HLTYPE(hlIcode op=HLI_INVALID) : opcode(op)
-    {}
-    HLTYPE & operator=(const HLTYPE &l)
-    {
-        exp=l.exp;
-        opcode=l.opcode;
-        asgn=l.asgn;
-        call=l.call;
-        return *this;
-    }
-public:
-    std::string write1HlIcode(Function *pProc, int *numLoc);
-    void setAsgn(COND_EXPR *lhs, COND_EXPR *rhs);
-} ;
 /* LOW_LEVEL icode operand record */
-struct LLOperand
+typedef struct {
+    byte     seg;               /* CS, DS, ES, SS                       */
+    int16    segValue;          /* Value of segment seg during analysis */
+    byte     segOver;           /* CS, DS, ES, SS if segment override   */
+    byte     regi;              /* 0 < regs < INDEXBASE <= index modes  */
+    int16    off;               /* memory address offset                */
+} ICODEMEM;
+typedef ICODEMEM *PMEM;
+
+/* LOW_LEVEL operand location: source or destination */
+typedef enum {
+	SRC,						/* Source operand 		*/
+	DST,						/* Destination operand	*/
+	LHS_OP,						/* Left-hand side operand (for HIGH_LEVEL) */
+} opLoc;
+
+typedef struct
 {
-    llvm::MCOperand llvm_op;
-    eReg     seg;               /* CS, DS, ES, SS                       */
-    eReg     segOver;           /* CS, DS, ES, SS if segment override   */
-    int16_t    segValue;          /* Value of segment seg during analysis */
-    eReg       regi;              /* 0 < regs < INDEXBASE <= index modes  */
-    int16_t    off;               /* memory address offset                */
-    uint32_t   opz;             /*   idx of immed src op        */
-    //union {/* Source operand if (flg & I)  */
-    struct {				/* Call & # actual arg bytes	*/
-        Function *proc;     /*   pointer to target proc (for CALL(F))*/
-        int     cb;		/*   # actual arg bytes			*/
-    } proc;
-    LLOperand() : seg(rUNDEF),segValue(0),segOver(rUNDEF),regi(rUNDEF),off(0),opz(0)
-    {
-        proc.proc=0;
-        proc.cb=0;
-    }
-    int64_t getImm2() const {return opz;}
-    void SetImmediateOp(uint32_t dw)
-    {
-        opz=dw;
-    }
-    eReg getReg2() {return regi;}
-    bool isReg() const;
-    static LLOperand CreateImm2(int64_t Val)
-    {
-        LLOperand Op;
-        //Op.Kind = kImmediate;
-        //Op.ImmVal = Val;
-        Op.opz = Val;
-        return Op;
-    }
-    static LLOperand CreateReg2(unsigned Val)
-    {
-        LLOperand Op;
-//        Op.Kind = kRegister;
-//        Op.RegVal = Reg;
-        Op.regi = (eReg)Val;
-        return Op;
-    }
-    void addProcInformation(int param_count,uint32_t call_conv);
-};
-struct LLInst : public llvm::MCInst //: public llvm::ilist_node<LLInst>
+    hlIcode              opcode;    /* hlIcode opcode           */
+    union {                         /* different operands       */
+        struct {                    /* for HLI_ASSIGN			*/
+            COND_EXPR    *lhs;
+            COND_EXPR    *rhs;
+        }                asgn;       
+        COND_EXPR        *exp;      /* for HLI_JCOND, HLI_RET, HLI_PUSH, HLI_POP*/
+		struct {					/* for HLI_CALL				*/
+			struct _proc     *proc;
+			struct _STKFRAME *args;	/* actual arguments			*/
+		}				 call;
+    }                    oper;      /* operand                  */
+} HLTYPE;
+
+typedef struct
 {
-protected:
-    uint32_t     flg;            /* icode flags                  */
-    LLOperand    m_src;            /* source operand               */
-public:
-    int          codeIdx;    	/* Index into cCode.code            */
-    uint8_t      numBytes;       /* Number of bytes this instr   */
-    uint32_t     label;          /* offset in image (20-bit adr) */
-    LLOperand    dst;            /* destination operand          */
-    DU           flagDU;         /* def/use of flags				*/
-        int caseEntry;
-    std::vector<uint32_t> caseTbl2;
-    int         hllLabNum;      /* label # for hll codegen      */
-    bool conditionalJump()
-    {
-        return (getOpcode() >= iJB) && (getOpcode() < iJCXZ);
-    }
-    bool testFlags(uint32_t x) const { return (flg & x)!=0;}
-    void  setFlags(uint32_t flag) {flg |= flag;}
-    void  clrFlags(uint32_t flag)
-    {
-        if(getOpcode()==iMOD)
-        {
-            assert(false);
-        }
-        flg &= ~flag;
-    }
-    uint32_t getFlag() const {return flg;}
-    //llIcode getOpcode() const { return opcode; }
-
-    uint32_t  GetLlLabel() const { return label;}
-
-    void SetImmediateOp(uint32_t dw) {m_src.SetImmediateOp(dw);}
-
-
-    bool match(llIcode op)
-    {
-        return (getOpcode()==op);
-    }
-    bool match(llIcode op,eReg dest)
-    {
-        return (getOpcode()==op)&&dst.regi==dest;
-    }
-    bool match(llIcode op,eReg dest,uint32_t flgs)
-    {
-        return (getOpcode()==op) and (dst.regi==dest) and testFlags(flgs);
-    }
-    bool match(llIcode op,eReg dest,eReg src_reg)
-    {
-        return (getOpcode()==op)&&(dst.regi==dest)&&(m_src.regi==src_reg);
-    }
-    bool match(eReg dest,eReg src_reg)
-    {
-        return (dst.regi==dest)&&(m_src.regi==src_reg);
-    }
-    bool match(eReg dest)
-    {
-        return (dst.regi==dest);
-    }
-    bool match(llIcode op,uint32_t flgs)
-    {
-        return (getOpcode()==op) and testFlags(flgs);
-    }
-    void set(llIcode op,uint32_t flags)
-    {
-        setOpcode(op);
-        flg =flags;
-    }
-    void emitGotoLabel(int indLevel);
-    void findJumpTargets(CIcodeRec &_pc);
-    void writeIntComment(std::ostringstream &s);
-    void dis1Line(int loc_ip, int pass);
-    std::ostringstream &strSrc(std::ostringstream &os,bool skip_comma=false);
-
-    void flops(std::ostringstream &out);
-    bool isJmpInst();
-    HLTYPE toHighLevel(COND_EXPR *lhs, COND_EXPR *rhs, Function *func);
-    HLTYPE createCall();
-    LLInst(ICODE *container) : flg(0),codeIdx(0),numBytes(0),m_link(container)
-    {
-        setOpcode(0);
-    }
-    const LLOperand &src() const {return m_src;}
-    LLOperand &src() {return m_src;}
-    void replaceSrc(const LLOperand &with)
-    {
-        m_src = with;
-    }
-    void replaceSrc(eReg r)
-    {
-        m_src = LLOperand::CreateReg2(r);
-    }
-    void replaceSrc(int64_t r)
-    {
-        m_src = LLOperand::CreateImm2(r);
-    }
-    void replaceDst(const LLOperand &with)
-    {
-        dst = with;
-    }
-    void replaceDst(eReg r)
-    {
-        dst = LLOperand::CreateReg2(r);
-    }
-    ICODE *m_link;
-    condId idType(opLoc sd) const;
-    const LLOperand *   get(opLoc sd) const { return (sd == SRC) ? &src() : &dst; }
-    LLOperand *         get(opLoc sd) { return (sd == SRC) ? &src() : &dst; }
-};
+    llIcode     opcode;         /* llIcode instruction          */
+    byte        numBytes;       /* Number of bytes this instr   */
+	flags32     flg;            /* icode flags                  */
+    dword       label;          /* offset in image (20-bit adr) */
+    ICODEMEM    dst;            /* destination operand          */
+    ICODEMEM    src;            /* source operand               */
+    union {                     /* Source operand if (flg & I)  */
+        dword   op;             /*   idx of immed src op        */
+		struct {				/* Call & # actual arg bytes	*/
+          struct _proc *proc;   /*   ^ target proc (for CALL(F))*/
+		  Int		   cb;		/*   # actual arg bytes			*/
+		}		proc;
+    }           immed;
+    DU          flagDU;         /* def/use of flags				*/
+    struct {                    /* Case table if op==JMP && !I  */
+        Int     numEntries;     /*   # entries in case table    */
+        dword  *entries;        /*   array of offsets           */
+    }           caseTbl;
+    Int         hllLabNum;      /* label # for hll codegen      */
+} LLTYPE;
+
 
 /* Icode definition: LOW_LEVEL and HIGH_LEVEL */
-struct ICODE
-{
-    // use llvm names at least
-    typedef BB MachineBasicBlock;
-protected:
-    LLInst m_ll;
-    HLTYPE m_hl;
-    MachineBasicBlock * Parent;      	/* BB to which this icode belongs   */
-    bool                invalid;        /* Has no HIGH_LEVEL equivalent     */
-public:
-    x86_insn_t insn;
-    template<int FLAG>
-    struct FlagFilter
-    {
-        bool operator()(ICODE *ic) {return ic->ll()->testFlags(FLAG);}
-        bool operator()(ICODE &ic) {return ic.ll()->testFlags(FLAG);}
-    };
-    template<int TYPE>
-    struct TypeFilter
-    {
-        bool operator()(ICODE *ic) {return ic->type==HIGH_LEVEL;}
-        bool operator()(ICODE &ic) {return ic.type==HIGH_LEVEL;}
-    };
-    template<int TYPE>
-    struct TypeAndValidFilter
-    {
-        bool operator()(ICODE *ic) {return (ic->type==HIGH_LEVEL)&&(ic->valid());}
-        bool operator()(ICODE &ic) {return (ic.type==HIGH_LEVEL)&&ic.valid();}
-    };
-    static TypeFilter<HIGH_LEVEL> select_high_level;
-    static TypeAndValidFilter<HIGH_LEVEL> select_valid_high_level;
-    /* Def/Use of registers and stack variables */
-    struct DU_ICODE
-    {
-        DU_ICODE()
-        {
-            def.reset();
-            use.reset();
-            lastDefRegi.reset();
-        }
-        std::bitset<32> def;        // For Registers: position in bitset is reg index
-        std::bitset<32> use;	// For Registers: position in uint32_t is reg index
-        std::bitset<32> lastDefRegi;// Bit set if last def of this register in BB
-        void addDefinedAndUsed(eReg r)
-        {
-            def |= duReg[r];
-            use |= duReg[r];
-
-        }
-    };
-    struct DU1
-    {
-        struct Use
-        {
-            int Reg; // used register
-            std::vector<std::list<ICODE>::iterator> uses; // use locations [MAX_USES]
-            void removeUser(std::list<ICODE>::iterator us)
-            {
-                // ic is no no longer an user
-                auto iter=std::find(uses.begin(),uses.end(),us);
-                if(iter==uses.end())
-                    return;
-                uses.erase(iter);
-                assert("Same user more then once!" && uses.end()==std::find(uses.begin(),uses.end(),us));
-            }
-
-        };
-        int     numRegsDef;             /* # registers defined by this inst */
-        uint8_t	regi[MAX_REGS_DEF+1];	/* registers defined by this inst   */
-        Use     idx[MAX_REGS_DEF+1];
-        //int     idx[MAX_REGS_DEF][MAX_USES];	/* inst that uses this def  */
-        bool    used(int regIdx)
-        {
-            return not idx[regIdx].uses.empty();
-        }
-        int     numUses(int regIdx)
-        {
-            return idx[regIdx].uses.size();
-        }
-        void recordUse(int regIdx,std::list<ICODE>::iterator location)
-        {
-            idx[regIdx].uses.push_back(location);
-        }
-        void remove(int regIdx,int use_idx)
-        {
-            idx[regIdx].uses.erase(idx[regIdx].uses.begin()+use_idx);
-        }
-        void remove(int regIdx,std::list<ICODE>::iterator ic)
-        {
-            Use &u(idx[regIdx]);
-            u.removeUser(ic);
-        }
-        DU1() : numRegsDef(0)
-        {
-        }
-    };
-    icodeType           type;           /* Icode type                       */
-    DU_ICODE		du;             /* Def/use regs/vars                */
-    DU1			du1;        	/* du chain 1                       */
-    int                 loc_ip; // used by CICodeRec to number ICODEs
-
-    LLInst *            ll() { return &m_ll;}
-    const LLInst *      ll() const { return &m_ll;}
-
-    HLTYPE *            hl() { return &m_hl;}
-    const HLTYPE *      hl() const { return &m_hl;}
-    void                hl(const HLTYPE &v) { m_hl=v;}
-
-    void setRegDU(eReg regi, operDu du_in);
-    void invalidate();
-    void newCallHl();
-    void writeDU();
-    condId idType(opLoc sd);
-    // HLL setting functions
-    // set this icode to be an assign
-    void setAsgn(COND_EXPR *lhs, COND_EXPR *rhs)
-    {
-        type=HIGH_LEVEL;
-        hl()->setAsgn(lhs,rhs);
-    }
-    void setUnary(hlIcode op, COND_EXPR *_exp);
-    void setJCond(COND_EXPR *cexp);
-
-    void emitGotoLabel(int indLevel);
-    void copyDU(const ICODE &duIcode, operDu _du, operDu duDu);
-    bool valid() {return not invalid;}
-    void setParent(MachineBasicBlock *P) { Parent = P; }
-public:
-    bool removeDefRegi(eReg regi, int thisDefIdx, LOCAL_ID *locId);
-    void checkHlCall();
-    bool newStkArg(COND_EXPR *exp, llIcode opcode, Function *pproc)
-    {
-        return hl()->call.newStkArg(exp,opcode,pproc);
-    }
-    ICODE() : m_ll(this),type(NOT_SCANNED),Parent(0),loc_ip(0),invalid(false)
-    {
-    }
-public:
-  const MachineBasicBlock* getParent() const { return Parent; }
-  MachineBasicBlock* getParent() { return Parent; }
-  //unsigned getNumOperands() const { return (unsigned)Operands.size(); }
+typedef struct {
+    icodeType           type;           /* Icode type                   */
+    boolT               invalid;        /* Has no HIGH_LEVEL equivalent */
+	struct _BB			*inBB;			/* BB to which this icode belongs */
+	DU_ICODE			du;				/* Def/use regs/vars			*/
+	DU1					du1;			/* du chain 1					*/
+	Int					codeIdx;		/* Index into cCode.code		*/
+    struct {                            /* Different types of icodes    */
+		LLTYPE ll;
+        HLTYPE hl;						/* For HIGH_LEVEL icodes    */
+    }                   		 ic;    /* intermediate code        */
+} ICODE;
+typedef ICODE* PICODE;
 
-};
-/** Map n low level instructions to m high level instructions
-*/
-struct MappingLLtoML
-{
-    typedef llvm::iplist<llvm::Instruction> InstListType;
-    typedef boost::iterator_range<iICODE> rSourceRange;
-    typedef boost::iterator_range<InstListType::iterator> rTargetRange;
-    rSourceRange m_low_level;
-    rTargetRange m_middle_level;
-};
 // This is the icode array object.
-class CIcodeRec : public std::list<ICODE>
+// The bulk of this could well be done with a class library
+class CIcodeRec
 {
 public:
-    CIcodeRec();	// Constructor
-
-    ICODE *	addIcode(ICODE *pIcode);
-    void	SetInBB(rCODE &rang, BB* pnewBB);
-    bool	labelSrch(uint32_t target, uint32_t &pIndex);
-    iterator    labelSrch(uint32_t target);
-    ICODE *	GetIcode(int ip);
-    bool        alreadyDecoded(uint32_t target);
+			CIcodeRec();	// Constructor
+			~CIcodeRec();	// Destructor
+
+	PICODE	addIcode(PICODE pIcode);
+	PICODE	GetFirstIcode();
+//	PICODE	GetNextIcode(PICODE pCurIcode);
+	boolT	IsValid(PICODE pCurIcode);
+	int		GetNumIcodes();
+	void	SetInBB(int start, int end, struct _BB* pnewBB);
+	void	SetImmediateOp(int ip, dword dw);
+	void	SetLlFlag(int ip, dword flag);
+	void	ClearLlFlag(int ip, dword flag);
+	dword	GetLlFlag(int ip);
+	void	SetLlInvalid(int ip, boolT fInv);
+	dword	GetLlLabel(int ip);
+	llIcode	GetLlOpcode(int ip);
+	boolT	labelSrch(dword target, Int *pIndex);
+	PICODE	GetIcode(int ip);
+
+protected:
+	Int		numIcode;		/* # icodes in use 		*/
+	Int		alloc;			/* # icodes allocated 	*/
+	PICODE	icode;			/* Array of icodes		*/
+
 };

+ 0 - 75
include/idioms/arith_idioms.h

@@ -1,75 +0,0 @@
-#pragma once
-#include <vector>
-#include "idiom.h"
-#include "icode.h"
-#include <deque>
-
-struct Idiom5 : public Idiom
-{
-protected:
-    iICODE m_icodes[2];
-public:
-    virtual ~Idiom5() {}
-    Idiom5(Function *f) : Idiom(f)
-    {
-    }
-    uint8_t minimum_match_length() {return 2;}
-    bool match(iICODE pIcode);
-    int action();
-};
-
-struct Idiom6 : public Idiom
-{
-protected:
-    iICODE m_icodes[2];
-public:
-    virtual ~Idiom6() {}
-    Idiom6(Function *f) : Idiom(f)
-    {
-    }
-    uint8_t minimum_match_length() {return 2;}
-    bool match(iICODE pIcode);
-    int action();
-};
-
-struct Idiom18 : public Idiom
-{
-protected:
-    iICODE m_icodes[4];
-    bool m_is_dec;
-public:
-    Idiom18(Function *f) : Idiom(f)
-    {
-    }
-    uint8_t minimum_match_length() {return 4;}
-    bool match(iICODE picode);
-    int action();
-};
-
-struct Idiom19 : public Idiom
-{
-protected:
-    iICODE m_icodes[2];
-    bool m_is_dec;
-public:
-    Idiom19(Function *f) : Idiom(f)
-    {
-    }
-    uint8_t minimum_match_length() {return 2;}
-    bool match(iICODE picode);
-    int action();
-};
-
-struct Idiom20 : public Idiom
-{
-protected:
-    iICODE m_icodes[4];
-    bool m_is_dec;
-public:
-    Idiom20(Function *f) : Idiom(f)
-    {
-    }
-    uint8_t minimum_match_length() {return 4;}
-    bool match(iICODE picode);
-    int action();
-};

+ 0 - 42
include/idioms/call_idioms.h

@@ -1,42 +0,0 @@
-#pragma once
-#include <vector>
-#include "idiom.h"
-#include "icode.h"
-#include <deque>
-struct CallIdiom : public Idiom
-{
-protected:
-    int m_param_count;
-public:
-    virtual ~CallIdiom() {}
-    CallIdiom(Function *f) : Idiom(f)
-    {
-    }
-
-};
-struct Idiom3 : public CallIdiom
-{
-protected:
-    iICODE m_icodes[2];
-public:
-    virtual ~Idiom3() {}
-    Idiom3(Function *f) : CallIdiom(f)
-    {
-    }
-    uint8_t minimum_match_length() {return 2;}
-    bool match(iICODE pIcode);
-    int action();
-};
-struct Idiom17 : public CallIdiom
-{
-protected:
-    std::vector<iICODE> m_icodes;
-public:
-    virtual ~Idiom17() {}
-    Idiom17(Function *f) : CallIdiom(f)
-    {
-    }
-    uint8_t minimum_match_length() {return 2;}
-    bool match(iICODE pIcode);
-    int action();
-};

+ 0 - 39
include/idioms/epilogue_idioms.h

@@ -1,39 +0,0 @@
-#pragma once
-#include "idiom.h"
-#include "icode.h"
-#include <deque>
-struct EpilogIdiom : public Idiom
-{
-protected:
-    std::deque<iICODE> m_icodes; // deque to push_front optional icodes from popStkVars
-    void popStkVars (iICODE pIcode);
-public:
-    virtual ~EpilogIdiom() {}
-    EpilogIdiom(Function *f) : Idiom(f)
-    {
-    }
-
-};
-struct Idiom2 : public EpilogIdiom
-{
-    virtual ~Idiom2() {}
-    Idiom2(Function *f) : EpilogIdiom(f)
-    {
-    }
-    uint8_t minimum_match_length() {return 3;}
-    bool match(iICODE pIcode);
-    int action();
-};
-struct Idiom4 : public EpilogIdiom
-{
-protected:
-    int m_param_count;
-public:
-    virtual ~Idiom4() {}
-    Idiom4(Function *f) : EpilogIdiom(f)
-    {
-    }
-    uint8_t minimum_match_length() {return 1;}
-    bool match(iICODE pIcode);
-    int action();
-};

+ 0 - 22
include/idioms/idiom.h

@@ -1,22 +0,0 @@
-#pragma once
-#include "icode.h"
-#include "Procedure.h"
-struct Idiom
-{
-protected:
-    Function *m_func;
-    iICODE m_end;
-public:
-    Idiom(Function *f) : m_func(f),m_end(f->Icode.end())
-    {
-    }
-    virtual uint8_t minimum_match_length()=0;
-    virtual bool match(iICODE at)=0;
-    virtual int action()=0;
-    int operator ()(iICODE at)
-    {
-        if(match(at))
-            return action();
-        return 1;
-    }
-};

+ 0 - 17
include/idioms/idiom1.h

@@ -1,17 +0,0 @@
-#pragma once
-#include "idiom.h"
-struct Idiom1 : public Idiom
-{
-protected:
-    std::vector<iICODE> m_icodes;
-    int m_min_off;
-    int checkStkVars (iICODE pIcode);
-public:
-    Idiom1(Function *f) : Idiom(f)
-    {
-    }
-    uint8_t minimum_match_length() {return 1;}
-    bool match(iICODE picode);
-    int action();
-    size_t match_length() {return m_icodes.size();}
-};

+ 0 - 36
include/idioms/mov_idioms.h

@@ -1,36 +0,0 @@
-#pragma once
-#include <vector>
-#include "idiom.h"
-#include "icode.h"
-#include <deque>
-
-struct Idiom14 : public Idiom
-{
-protected:
-    iICODE m_icodes[2];
-    eReg m_regL;
-    eReg m_regH;
-public:
-    virtual ~Idiom14() {}
-    Idiom14(Function *f) : Idiom(f),m_regL(rUNDEF),m_regH(rUNDEF)
-    {
-    }
-    uint8_t minimum_match_length() {return 2;}
-    bool match(iICODE pIcode);
-    int action();
-};
-
-struct Idiom13 : public Idiom
-{
-protected:
-    iICODE m_icodes[2];
-    eReg m_loaded_reg;
-public:
-    virtual ~Idiom13() {}
-    Idiom13(Function *f) : Idiom(f)
-    {
-    }
-    uint8_t minimum_match_length() {return 2;}
-    bool match(iICODE pIcode);
-    int action();
-};

+ 0 - 33
include/idioms/neg_idioms.h

@@ -1,33 +0,0 @@
-#pragma once
-#include <vector>
-#include "idiom.h"
-#include "icode.h"
-#include <deque>
-
-struct Idiom11 : public Idiom
-{
-protected:
-    iICODE m_icodes[3];
-public:
-    virtual ~Idiom11() {}
-    Idiom11(Function *f) : Idiom(f)
-    {
-    }
-    uint8_t minimum_match_length() {return 3;}
-    bool match(iICODE pIcode);
-    int action();
-};
-
-struct Idiom16 : public Idiom
-{
-protected:
-    iICODE m_icodes[3];
-public:
-    virtual ~Idiom16() {}
-    Idiom16(Function *f) : Idiom(f)
-    {
-    }
-    uint8_t minimum_match_length() {return 3;}
-    bool match(iICODE pIcode);
-    int action();
-};

+ 0 - 66
include/idioms/shift_idioms.h

@@ -1,66 +0,0 @@
-#pragma once
-#include <vector>
-#include "idiom.h"
-#include "icode.h"
-#include <deque>
-
-struct Idiom8 : public Idiom
-{
-protected:
-    iICODE m_icodes[2];
-    uint8_t m_loaded_reg;
-public:
-    virtual ~Idiom8() {}
-    Idiom8(Function *f) : Idiom(f)
-    {
-    }
-    uint8_t minimum_match_length() {return 2;}
-    bool match(iICODE pIcode);
-    int action();
-};
-
-struct Idiom15 : public Idiom
-{
-protected:
-    std::vector<iICODE> m_icodes;
-public:
-    virtual ~Idiom15() {}
-    Idiom15(Function *f) : Idiom(f)
-    {
-    }
-    uint8_t minimum_match_length() {return 2;}
-    bool match(iICODE pIcode);
-    int action();
-};
-
-struct Idiom12 : public Idiom
-{
-protected:
-    iICODE m_icodes[2];
-    uint8_t m_loaded_reg;
-public:
-    virtual ~Idiom12() {}
-    Idiom12(Function *f) : Idiom(f)
-    {
-    }
-    uint8_t minimum_match_length() {return 2;}
-    bool match(iICODE pIcode);
-    int action();
-};
-
-
-struct Idiom9 : public Idiom
-{
-protected:
-    iICODE m_icodes[2];
-    uint8_t m_loaded_reg;
-public:
-    virtual ~Idiom9() {}
-    Idiom9(Function *f) : Idiom(f)
-    {
-    }
-    uint8_t minimum_match_length() {return 2;}
-    bool match(iICODE pIcode);
-    int action();
-};
-

+ 0 - 46
include/idioms/xor_idioms.h

@@ -1,46 +0,0 @@
-#pragma once
-#include <vector>
-#include "idiom.h"
-#include "icode.h"
-#include <deque>
-
-struct Idiom21 : public Idiom
-{
-protected:
-    iICODE m_icodes[2];
-public:
-    virtual ~Idiom21() {}
-    Idiom21(Function *f) : Idiom(f)
-    {
-    }
-    uint8_t minimum_match_length() {return 2;}
-    bool match(iICODE pIcode);
-    int action();
-};
-
-struct Idiom7 : public Idiom
-{
-protected:
-    iICODE m_icode;
-public:
-    virtual ~Idiom7() {}
-    Idiom7(Function *f) : Idiom(f)
-    {
-    }
-    uint8_t minimum_match_length() {return 1;}
-    bool match(iICODE pIcode);
-    int action();
-};
-struct Idiom10 : public Idiom
-{
-protected:
-    iICODE m_icodes[2];
-public:
-    virtual ~Idiom10() {}
-    Idiom10(Function *f) : Idiom(f)
-    {
-    }
-    uint8_t minimum_match_length() {return 1;}
-    bool match(iICODE pIcode);
-    int action();
-};

+ 82 - 110
include/locident.h

@@ -5,134 +5,106 @@
  * (C) Cristina Cifuentes
  */
 
-#pragma once
-#include <stdint.h>
-#include <vector>
-#include <list>
-#include <set>
-#include <algorithm>
-#include "types.h"
-#include "Enums.h"
-#include "machine_x86.h"
 
 /* Type definition */
-// this array has to stay in-order of addition i.e. not std::set<iICODE,std::less<iICODE> >
-// TODO: why ?
-struct COND_EXPR;
-struct ICODE;
-struct LLInst;
-typedef std::list<ICODE>::iterator iICODE;
-struct IDX_ARRAY : public std::vector<iICODE>
-{
-    bool inList(iICODE idx)
-    {
-        return std::find(begin(),end(),idx)!=end();
-    }
-};
+typedef struct {
+	Int		csym;		/* # symbols used 			*/
+	Int		alloc;		/* # symbols allocated 		*/
+	Int		*idx;		/* Array of integer indexes */
+} IDX_ARRAY;
+
+/* Type definitions used in the decompiled program  */
+typedef enum {
+    TYPE_UNKNOWN = 0,   /* unknown so far      		*/
+    TYPE_BYTE_SIGN,		/* signed byte (8 bits) 	*/
+	TYPE_BYTE_UNSIGN,	/* unsigned byte 			*/
+    TYPE_WORD_SIGN,     /* signed word (16 bits) 	*/
+	TYPE_WORD_UNSIGN,	/* unsigned word (16 bits)	*/
+	TYPE_LONG_SIGN,		/* signed long (32 bits)	*/
+	TYPE_LONG_UNSIGN,	/* unsigned long (32 bits)	*/
+	TYPE_RECORD,		/* record structure			*/
+    TYPE_PTR,        	/* pointer (32 bit ptr) 	*/
+    TYPE_STR,        	/* string               	*/
+ 	TYPE_CONST,			/* constant (any type)		*/
+	TYPE_FLOAT,			/* floating point			*/
+	TYPE_DOUBLE,		/* double precision float	*/
+} hlType;
+
+static char *hlTypes[13] = {"", "char", "unsigned char", "int", "unsigned int", 
+			 		 "long", "unsigned long", "record", "int *", "char *",
+			 		 "", "float", "double"};
 
 typedef enum
 {
-    STK_FRAME,			/* For stack vars			*/
-    REG_FRAME,			/* For register variables 	*/
-    GLB_FRAME			/* For globals				*/
+	STK_FRAME,			/* For stack vars			*/
+	REG_FRAME,			/* For register variables 	*/
+	GLB_FRAME,			/* For globals				*/
 } frameType;
 
+
+/* Enumeration to determine whether pIcode points to the high or low part
+ * of a long number */
+typedef enum {
+	HIGH_FIRST,			/* High value is first		*/
+	LOW_FIRST,			/* Low value is first		*/
+} hlFirst;
+
+
 typedef struct
 {
-    int16_t	seg;			/*   segment value							 */
-    int16_t	off;			/*   offset									 */
-    eReg 	regi;			/*   optional indexed register				 */
+	int16	seg;			/*   segment value							 */
+	int16	off;			/*   offset									 */
+	byte 	regi;			/*   optional indexed register				 */
 } BWGLB_TYPE;
 
 
 typedef struct
 { /* For TYPE_LONG_(UN)SIGN on the stack	     */
-    int		offH;	/*   high offset from BP					 */
-    int		offL;	/*   low offset from BP						 */
+	Int		offH;	/*   high offset from BP					 */
+	Int		offL;	/*   low offset from BP						 */
 }	LONG_STKID_TYPE;
-struct LONGID_TYPE
+typedef struct
 {		/* For TYPE_LONG_(UN)SIGN registers			 */
-    eReg	h;		/*   high register							 */
-    eReg	l;		/*   low register							 */
-    bool srcDstRegMatch(iICODE a,iICODE b) const;
-};
+	byte	h;		/*   high register							 */
+	byte	l;		/*   low register							 */
+} LONGID_TYPE;
 
 
 /* ID, LOCAL_ID */
-struct ID
-{
-    hlType              type;       /* Probable type                            */
-    bool                illegal;    /* Boolean: not a valid field any more      */
-    //std::vector<iICODE> idx;
-    IDX_ARRAY           idx;        /* Index into icode array (REG_FRAME only)  */
-    frameType           loc;        /* Frame location                           */
-    bool                hasMacro;   /* Identifier requires a macro              */
-    char                macro[10];  /* Macro for this identifier                */
-    std::string         name;       /* Identifier's name                        */
-    union {                         /* Different types of identifiers           */
-        eReg		regi;       /* For TYPE_BYTE(uint16_t)_(UN)SIGN registers   */
-        struct {                    /* For TYPE_BYTE(uint16_t)_(UN)SIGN on the stack */
-            uint8_t	regOff;     /*    register offset (if any)              */
-            int		off;        /*    offset from BP            		*/
-        }               bwId;
-        BWGLB_TYPE	bwGlb;	/* For TYPE_BYTE(uint16_t)_(UN)SIGN globals		 */
-        LONGID_TYPE     longId; /* For TYPE_LONG_(UN)SIGN registers			 */
-        LONG_STKID_TYPE	longStkId;  /* For TYPE_LONG_(UN)SIGN on the stack */
-        struct {			/* For TYPE_LONG_(UN)SIGN globals			 */
-            int16_t	seg;	/*   segment value                                              */
-            int16_t	offH;	/*   offset high                                                */
-            int16_t	offL;	/*   offset low                                                 */
-            uint8_t	regi;	/*   optional indexed register                                  */
-        }			longGlb;
-        struct {			/* For TYPE_LONG_(UN)SIGN constants                     */
-            uint32_t	h;		/*	 high uint16_t								 */
-            uint32_t 	l;		/*	 low uint16_t								 */
-        } longKte;
-    } id;
-    ID();
-    ID(hlType t, frameType f);
-    bool isSigned() const { return (type==TYPE_BYTE_SIGN)||(type==TYPE_WORD_SIGN)||(type==TYPE_LONG_SIGN);}
-    uint16_t typeBitsize() const
-    {
-        return TypeContainer::typeSize(type)*8;
-    }
-    void setLocalName(int i)
-    {
-        char buf[32];
-        sprintf (buf, "loc%ld", i);
-        name=buf;
-    }
-};
-
-struct LOCAL_ID
-{
-    std::vector<ID> id_arr;
-protected:
-    int newLongIdx(int16_t seg, int16_t offH, int16_t offL, uint8_t regi, hlType t);
-    int newLongGlb(int16_t seg, int16_t offH, int16_t offL, hlType t);
-    int newLongStk(hlType t, int offH, int offL);
-public:
-    LOCAL_ID()
-    {
-        id_arr.reserve(256);
-    }
-    // interface to allow range based iteration
-    std::vector<ID>::iterator begin() {return id_arr.begin();}
-    std::vector<ID>::iterator end() {return id_arr.end();}
-    int newByteWordReg(hlType t, eReg regi);
-    int newByteWordStk(hlType t, int off, uint8_t regOff);
-    int newIntIdx(int16_t seg, int16_t off, eReg regi, int ix, hlType t);
-    int newLongReg(hlType t, eReg regH, eReg regL, iICODE ix_);
-    int newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix, operDu du, int off);
-    int newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix, operDu du, LLInst &atOffset);
-    void newIdent(hlType t, frameType f);
-    void flagByteWordId(int off);
-    void propLongId(uint8_t regL, uint8_t regH, const char *name);
-    size_t csym() const {return id_arr.size();}
-    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_);
-};
+typedef struct {
+	hlType			type;	/* Probable type							 */
+	boolT			illegal;/* Boolean: not a valid field any more		 */
+	IDX_ARRAY		idx;	/* Index into icode array (REG_FRAME only)	 */
+	frameType		loc;	/* Frame location							 */
+	boolT			hasMacro;/* Identifier requires a macro				 */
+	char			macro[10];/* Macro for this identifier				 */
+	char			name[20];/* Identifier's name						 */
+	union {					/* Different types of identifiers 			 */
+		byte		regi;	/* For TYPE_BYTE(WORD)_(UN)SIGN registers    */ 
+		struct {			/* For TYPE_BYTE(WORD)_(UN)SIGN on the stack */
+			byte	regOff; /*    register offset (if any)				 */
+			Int		off;	/*    offset from BP						 */
+		}			bwId;
+		BWGLB_TYPE	bwGlb;	/* For TYPE_BYTE(WORD)_(UN)SIGN globals		 */
+		LONGID_TYPE longId; /* For TYPE_LONG_(UN)SIGN registers			 */
+		LONG_STKID_TYPE	longStkId;/* For TYPE_LONG_(UN)SIGN on the stack */
+		struct {			/* For TYPE_LONG_(UN)SIGN globals			 */
+			int16	seg;	/*   segment value							 */
+			int16	offH;	/*   offset high							 */
+			int16	offL;	/*   offset low								 */
+			byte	regi;	/*   optional indexed register				 */
+		}			longGlb;
+		struct {			/* For TYPE_LONG_(UN)SIGN constants			 */
+			dword	h;		/*	 high word								 */
+			dword 	l;		/*	 low word								 */
+		}			longKte;
+	}				id;
+} ID;
+
+typedef struct {
+	Int			csym;		/* No. of symbols in the table	*/
+	Int			alloc;		/* No. of symbols allocated		*/
+	ID			*id;		/* Identifier					*/
+} LOCAL_ID;
 
 

+ 0 - 82
include/machine_x86.h

@@ -1,82 +0,0 @@
-#pragma once
-#include <stdint.h>
-#include <string>
-#include <sstream>
-#include <bitset>
-
-/* Machine registers */
-enum eReg
-{
-    rUNDEF =     0,
-    rAX =        1,  /* These are numbered relative to real 8086 */
-    rCX =        2,
-    rDX =        3,
-    rBX =        4,
-    rSP =        5,
-    rBP =        6,
-    rSI =        7,
-    rDI =        8,
-
-    rES =        9,
-    rCS =       10,
-    rSS =       11,
-    rDS =       12,
-
-    rAL =       13,
-    rCL =       14,
-    rDL =       15,
-    rBL =       16,
-    rAH =       17,
-    rCH =       18,
-    rDH =       19,
-    rBH =       20,
-
-    rTMP=       21, /* temp register for DIV/IDIV/MOD	*/
-    /* Indexed modes go from INDEXBASE to INDEXBASE+7  */
-    INDEX_BX_SI = 22, // "bx+si"
-    INDEX_BX_DI, // "bx+di"
-    INDEX_BP_SI, // "bp+si"
-    INDEX_BP_DI, // "bp+di"
-    INDEX_SI, // "si"
-    INDEX_DI, // "di"
-    INDEX_BP, // "bp"
-    INDEX_BX, // "bx"
-    LAST_REG
-};
-class SourceMachine
-{
-public:
-    virtual bool physicalReg(eReg r)=0;
-
-};
-//class Machine_X86_Disassembler
-//{
-//    void formatRM(std::ostringstream &p, uint32_t flg, const LLOperand &pm);
-//};
-class Machine_X86 : public SourceMachine
-{
-public:
-    Machine_X86();
-    virtual ~Machine_X86() {}
-    static const std::string &regName(eReg r);
-    static const std::string &opcodeName(unsigned r);
-    static const std::string &floatOpName(unsigned r);
-    bool physicalReg(eReg r);
-    /* Writes the registers that are set in the bitvector */
-    //TODO: move this into Machine_X86 ?
-    static void writeRegVector (std::ostream &ostr,const std::bitset<32> &regi)
-    {
-        int j;
-        for (j = rAX; j < INDEX_BX_SI; j++)
-        {
-            if (regi.test(j-1))
-                ostr << regName(eReg(j))<<" ";
-        }
-    }
-    static eReg subRegH(eReg reg); //TODO: move these into machine_x86
-    static eReg subRegL(eReg reg);
-
-    static bool isMemOff(eReg r);
-    static bool isSubRegisterOf(eReg reg, eReg parent);
-
-};

+ 20 - 27
include/perfhlib.h

@@ -1,41 +1,34 @@
-#pragma once
 /* Perfect hashing function library. Contains functions to generate perfect
     hashing functions
  * (C) Mike van Emmerik
  */
 
-//#define bool unsigned char
-#define uint8_t unsigned char
-#define uint16_t unsigned short
+
+#define TRUE 1
+#define FALSE 0
+#define bool unsigned char
+#define byte unsigned char
+#define word unsigned short
 
 /* Prototypes */
+void hashParams(int NumEntry, int EntryLen, int SetSize, char SetMin,
+                    int NumVert);   /* Set the parameters for the hash table */
 void hashCleanup(void);         /* Frees memory allocated by hashParams() */
 void map(void);                 /* Part 1 of creating the tables */
+void assign(void);              /* Part 2 of creating the tables */
+int  hash(byte *s);             /* Hash the string to an int 0 .. NUMENTRY-1 */
+
+word *readT1(void);             /* Returns a pointer to the T1 table */
+word *readT2(void);             /* Returns a pointer to the T2 table */
+word *readG(void);              /* Returns a pointer to the g  table */
+
 
 /* The application must provide these functions: */
-void getKey(int i, uint8_t **pKeys);/* Set *keys to point to the i+1th key */
+void getKey(int i, byte **pKeys);/* Set *keys to point to the i+1th key */
 void dispKey(int i);            /* Display the key */
-class PatternHasher
-{
-    uint16_t    *T1base, *T2base;   /* Pointers to start of T1, T2 */
-    int     NumEntry;   /* Number of entries in the hash table (# keys) */
-    int     EntryLen;   /* Size (bytes) of each entry (size of keys) */
-    int     SetSize;    /* Size of the char set */
-    char    SetMin;     /* First char in the set */
-    int     NumVert;    /* c times NumEntry */
-    int     *graphNode; /* The array of edges */
-    int     *graphNext; /* Linked list of edges */
-    int     *graphFirst;/* First edge at a vertex */
-public:
-    uint16_t *readT1(void);             /* Returns a pointer to the T1 table */
-    uint16_t *readT2(void);             /* Returns a pointer to the T2 table */
-    uint16_t *readG(void);              /* Returns a pointer to the g  table */
-    void init(int _NumEntry, int _EntryLen, int _SetSize, char _SetMin,int _NumVert); /* Set the parameters for the hash table */
-    void cleanup();
-    int hash(unsigned char *string); //!< Hash the string to an int 0 .. NUMENTRY-1
-};
-extern PatternHasher g_pattern_hasher;
-/* Macro reads a LH uint16_t from the image regardless of host convention */
+
+
+/* Macro reads a LH word from the image regardless of host convention */
 #ifndef LH
-#define LH(p)  ((int)((uint8_t *)(p))[0] + ((int)((uint8_t *)(p))[1] << 8))
+#define LH(p)  ((int)((byte *)(p))[0] + ((int)((byte *)(p))[1] << 8))
 #endif

+ 0 - 77
include/project.h

@@ -1,77 +0,0 @@
-#pragma once
-#include <string>
-#include <stdint.h>
-#include <cassert>
-#include <list>
-#include <llvm/ADT/ilist.h>
-#include "symtab.h"
-#include "BinaryImage.h"
-struct Function;
-struct SourceMachine;
-struct CALL_GRAPH;
-
-typedef llvm::iplist<Function> FunctionListType;
-typedef FunctionListType lFunction;
-typedef lFunction::iterator ilFunction;
-
-
-struct Project
-{
-    SYMTAB symtab;       /* Global symbol table              */
-
-    std::string m_fname;
-    FunctionListType pProcList;
-    CALL_GRAPH * callGraph;	/* Pointer to the head of the call graph     */
-    PROG prog;   		/* Loaded program image parameters  */
-    Project() {}
-    // no copies
-    Project(const Project&) = delete;
-    const Project &operator=(const Project & l) =delete;
-    // only moves
-    Project(Project && l)
-    {
-        m_fname  =l.m_fname;
-        size_t before=l.pProcList.size();
-        pProcList.splice(pProcList.end(),l.pProcList);
-        callGraph=l.callGraph;
-        l.m_fname.clear();
-        l.pProcList.clear();
-        l.callGraph=0;
-        assert(before==pProcList.size());
-    }
-    Project &operator=(Project && l)
-    {
-        if(this == &l)
-            return *this;
-        m_fname  =l.m_fname;
-        size_t before=l.pProcList.size();
-        pProcList.splice(pProcList.end(),l.pProcList);
-        callGraph=l.callGraph;
-        l.m_fname.clear();
-        l.pProcList.clear();
-        l.callGraph=0;
-        assert(before==pProcList.size());
-        return *this;
-    }
-
-public:
-    ilFunction funcIter(Function *to_find);
-    ilFunction findByEntry(uint32_t entry);
-    ilFunction createFunction();
-    bool valid(ilFunction iter);
-
-    int     getSymIdxByAdd(uint32_t adr);
-    bool    validSymIdx(size_t idx);
-    size_t  symbolSize(size_t idx);
-    hlType  symbolType(size_t idx);
-    const std::string &symbolName(size_t idx);
-    const SYM &getSymByIdx(size_t idx) const;
-
-    static Project *get();
-    PROG * binary() {return &prog;}
-    SourceMachine *machine();
-
-protected:
-    void writeGlobSymTable();
-};
-//extern Project g_proj;

+ 33 - 7
include/scanner.h

@@ -1,12 +1,38 @@
-#pragma once
 /* Scanner functions
  * (C) Cristina Cifuentes, Jeff Ledermann
  */
-#include <stdint.h>
-#include "error.h"
-/* Extracts reg bits from middle of mod-reg-rm uint8_t */
-#define REG(x)  ((uint8_t)(x & 0x38) >> 3)
 
-struct ICODE;
+#define LH(p)  ((int)((byte *)(p))[0] + ((int)((byte *)(p))[1] << 8))
 
-extern eErrorId scan(uint32_t ip, ICODE &p);
+static void rm(Int i);
+static void modrm(Int i);
+static void segrm(Int i);
+static void data1(Int i);
+static void data2(Int i);
+static void regop(Int i);
+static void segop(Int i);
+static void strop(Int i);
+static void escop(Int i);
+static void axImp(Int i);
+static void alImp(Int i);
+static void axSrcIm(Int i);
+static void memImp(Int i);
+static void memReg0(Int i);
+static void memOnly(Int i);
+static void dispM(Int i);
+static void dispS(Int i);
+static void dispN(Int i);
+static void dispF(Int i);
+static void prefix(Int i);
+static void immed(Int i);
+static void shift(Int i);
+static void arith(Int i);
+static void trans(Int i);
+static void const1(Int i);
+static void const3(Int i);
+static void none1(Int i);
+static void none2(Int i);
+static void checkInt(Int i);
+
+/* Extracts reg bits from middle of mod-reg-rm byte */
+#define REG(x)  ((byte)(x & 0x38) >> 3)

+ 9 - 25
include/state.h

@@ -2,34 +2,18 @@
  *          dcc project header
  * (C) Cristina Cifuentes, Mike van Emmerik
  ****************************************************************************/
-#pragma once
-#include <stdint.h>
-#include <cstring>
-#include "machine_x86.h"
 
 /* STATE TABLE */
-struct STATE
+typedef struct
 {
-    uint32_t      IP;             /* Offset into Image                    */
-    int16_t       r[INDEX_BX_SI];   /* Value of segs and AX                 */
-    bool          f[INDEX_BX_SI];   /* True if r[.] has a value             */
+    dword       IP;             /* Offset into Image                    */
+    int16       r[INDEXBASE];   /* Value of segs and AX                 */
+    byte        f[INDEXBASE];   /* True if r[.] has a value             */
     struct
-    {                           /* For case stmt indexed reg            */
-        uint8_t    regi;           /*   Last conditional jump              */
-        int16_t   immed;          /*   Contents of the previous register  */
+	{							/* For case stmt indexed reg            */
+        byte    regi;           /*   Last conditional jump              */
+        int16   immed;          /*   Contents of the previous register  */
     }           JCond;
-    void setState(uint16_t reg, int16_t value);
-    void checkStartup();
-    bool isKnown(eReg v) {return f[v];}
-    void kill(eReg v) { f[v]=false;}
-    STATE() : IP(0)
-    {
-        JCond.regi=0;
-        JCond.immed=0;
-
-        memset(r,0,sizeof(int16_t)*INDEX_BX_SI); //TODO: move this to machine_x86
-        memset(f,0,sizeof(uint8_t)*INDEX_BX_SI);
-    }
-};
-
+} STATE;
+typedef STATE *PSTATE;
 

+ 24 - 94
include/symtab.h

@@ -2,112 +2,42 @@
  * Symbol table prototypes
  * (C) Mike van Emmerik
 */
-#pragma once
-#include <string>
-#include <stdint.h>
-#include "Enums.h"
-#include "types.h"
-struct COND_EXPR;
-struct TypeContainer;
+
 /* * * * * * * * * * * * * * * * * */
 /* Symbol table structs and protos */
 /* * * * * * * * * * * * * * * * * */
-struct SymbolCommon
-{
-    std::string name;   /* New name for this variable/symbol/argument */
-    int         size;   /* Size/maximum size                */
-    hlType      type;       /* probable type                */
-    eDuVal      duVal;      /* DEF, USE, VAL    						*/
-    SymbolCommon() : size(0),type(TYPE_UNKNOWN)
-    {}
-};
-struct SYM : public SymbolCommon
-{
-    SYM() : label(0),flg(0)
-    {
-
-    }
-    int32_t    label;      /* physical address (20 bit)    */
-    uint32_t     flg;       /* SEG_IMMED, IMPURE, WORD_OFF  */
-};
-/* STACK FRAME */
-struct STKSYM : public SymbolCommon
-{
-    COND_EXPR	*actual;	/* Expression tree of actual parameter 		*/
-    COND_EXPR 	*regs;		/* For register arguments only				*/
-    int16_t      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					*/
-    std::string macro;  	/* Macro name								*/
-    bool        invalid;	/* Boolean: invalid entry in formal arg list*/
-    STKSYM()
-    {
-        actual=regs=0;
-        label=0;
-        regOff=0;
-        invalid=hasMacro = false;
-    }
-    void setArgName(int i)
-    {
-        char buf[32];
-        sprintf (buf, "arg%d", i);
-        name = buf;
-    }
-};
-template<class T>
-class SymbolTableCommon : public std::vector<T>
-{
-public:
-    typedef typename std::vector<T>::iterator iterator;
-    typedef typename std::vector<T>::const_iterator const_iterator;
-    iterator findByLabel(int lab)
-    {
-        auto iter = std::find_if(this->begin(),this->end(),
-                                 [lab](T &s)->bool {return s.label==lab;});
-        return iter;
-    }
-    const_iterator findByLabel(int lab) const
-    {
-        auto iter = std::find_if(this->begin(),this->end(),
-                                 [lab](const T &s)->bool {return s.label==lab;});
-        return iter;
-    }
-
-};
-/* SYMBOL TABLE */
-class SYMTAB : public SymbolTableCommon<SYM>
-{
 
-public:
-    void updateSymType(uint32_t symbol, const TypeContainer &tc);
-    SYM *updateGlobSym(uint32_t operand, int size, uint16_t duFlag, bool &inserted_new);
-};
-struct Function;
-struct SYMTABLE
+typedef struct
 {
-    std::string pSymName;              /* Ptr to symbolic name or comment */
-    uint32_t   symOff;                 /* Symbol image offset */
-    Function *symProc;             /* Procedure pointer */
-    SYMTABLE() : symOff(0),symProc(0) {}
-    SYMTABLE(uint32_t _sym,Function *_proc) : symOff(_sym),symProc(_proc)
-    {}
-    bool operator == (const SYMTABLE &other) const
-    {
-        // does not yse pSymName, to ease finding by symOff/symProc combo
-        // in map<SYMTABLE,X>
-        return (symOff==other.symOff) && symProc==(other.symProc);
-    }
-};
+    char    *pSymName;              /* Ptr to symbolic name or comment */
+    dword   symOff;                 /* Symbol image offset */
+    PPROC   symProc;                /* Procedure pointer */
+    word    preHash;                /* Hash value before the modulo */
+    word    postHash;               /* Hash value after the modulo */
+    word    nextOvf;                /* Next entry this hash bucket, or -1 */
+    word    prevOvf;                /* Back link in Ovf chain */
+} SYMTABLE;
 
-enum tableType                     /* The table types */
+enum _tableType                     /* The table types */
 {
     Label=0,                        /* The label table */
     Comment,                        /* The comment table */
     NUM_TABLE_TYPES                 /* Number of entries: must be last */
-};
+};              
+
+typedef enum _tableType tableType;  /* For convenience */
 
 void    createSymTables(void);
 void    destroySymTables(void);
-boolT   readVal (std::ostringstream &symName, uint32_t   symOff, Function *symProc);
+void    enterSym(char *symName, dword   symOff, PPROC   symProc, boolT bSymToo);
+boolT   readSym (char *symName, dword *pSymOff, PPROC *pSymProc);
+boolT   readVal (char *symName, dword   symOff, PPROC   symProc);
+void    deleteSym(char *symName);
+void    deleteVal(dword symOff, PPROC symProc, boolT bSymToo);
+boolT   findVal(dword symOff, PPROC symProc, word *pIndex);
+word    symHash(char *name, word *pre);
+word    valHash(dword off, PPROC proc, word *pre);
 void    selectTable(tableType);     /* Select a particular table */
 
+char   *addStrTbl(char *pStr);      /* Add string to string table */
+

+ 24 - 72
include/types.h

@@ -2,19 +2,34 @@
  *          dcc project general header
  * (C) Cristina Cifuentes, Mike van Emmerik
  ****************************************************************************/
-#pragma once
-#include <cassert>
-#include <stdint.h>
-#include "Enums.h"
+
 /**** Common definitions and macros ****/
+#ifdef __MSDOS__            /* Intel: 16 bit integer        */
+typedef long    Int;        /* Int: 0x80000000..0x7FFFFFFF  */
+typedef unsigned long flags32;  /* 32 bits  */
+typedef unsigned long dword;    /* 32 bits  */
+#define MAX 0x7FFFFFFF
+#else                       /* Unix: 32 bit integer         */
+typedef int Int;            /* Int: 0x80000000..0x7FFFFFFF  */
+typedef unsigned int flags32;  /* 32 bits  */
+typedef unsigned int dword;    /* 32 bits  */
 #define MAX 0x7FFFFFFF
+#endif
 
 /* Type definitions used in the program */
-typedef unsigned char byte; /* 8 bits   */
+typedef unsigned char byte; /* 8 bits   */ 
 typedef unsigned short word;/* 16 bits  */
 typedef short int16;        /* 16 bits  */
 typedef unsigned char boolT; /* 8 bits   */
 
+#if defined(__MSDOS__) | defined(WIN32)
+#define unlink _unlink		// Compiler is picky about non Ansi names
+#endif
+
+
+#define TRUE    1
+#define FALSE   0
+
 #define SYNTHESIZED_MIN 0x100000    /* Synthesized labs use bits 21..32 */
 
 /* These are for C library signature detection */
@@ -24,15 +39,17 @@ typedef unsigned char boolT; /* 8 bits   */
 
 /****** MACROS *******/
 
+/* Macro to allocate a node of size sizeof(structType). */
+#define allocStruc(structType)  (structType *)allocMem(sizeof(structType))
+
 /* 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))
 
-
 /* Macro reads a LH word from the image regardless of host convention */
 /* Returns a signed quantity, e.g. C000 is read into an Int as FFFFC000 */
-#define LH_SIGNED(p) (((byte *)(p))[0] + (((char *)(p))[1] << 8))
+#define LHS(p) (((byte *)(p))[0] + (((char *)(p))[1] << 8))
 
 /* Macro tests bit b for type t in prog.map */
 #define BITMAP(b, t)  (prog.map[(b) >> 2] & ((t) << (((b) & 3) << 1)))
@@ -40,68 +57,3 @@ typedef unsigned char boolT; /* 8 bits   */
 /* Macro to convert a segment, offset definition into a 20 bit address */
 #define opAdr(seg,off)  ((seg << 4) + off)
 
-/* duVal FLAGS */
-struct eDuVal
-{
-    eDuVal()
-    {
-        def=use=val=0;
-    }
-    enum flgs
-    {
-        DEF=1,
-        USE=2,
-        VAL=4
-    };
-    int def :1; /* Variable was first defined than used          */
-    int use :1;      /* Variable was first used than defined          */
-    int 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.                        */
-    void setFlags(uint16_t x)
-    {
-        def = x&DEF;
-        use = x&USE;
-        val = x&VAL;
-    }
-    bool isUSE_VAL() {return use&&val;}            /* Use and Val                                   */
-};
-static constexpr const char * hlTypes[13] = {
-    "", "char", "unsigned char", "int", "unsigned int",
-    "long", "unsigned long", "record", "int *", "char *",
-    "", "float", "double"
-};
-
-struct TypeContainer
-{
-    hlType m_type;
-    size_t m_size;
-    TypeContainer(hlType t,size_t sz) : m_type(t),m_size(sz)
-    {
-    }
-    static size_t typeSize(hlType t)
-    {
-        switch(t)
-        {
-            case TYPE_WORD_SIGN: case TYPE_WORD_UNSIGN:
-            return 2;
-            case TYPE_BYTE_SIGN: case TYPE_BYTE_UNSIGN:
-            return 1;
-        }
-        return 0;
-    }
-    static hlType defaultTypeForSize(size_t x)
-    {
-        /* Type of the symbol according to the number of bytes it uses */
-        static hlType cbType[] = {TYPE_UNKNOWN, TYPE_BYTE_UNSIGN, TYPE_WORD_SIGN,
-                                  TYPE_UNKNOWN, TYPE_LONG_SIGN};
-
-        assert(x < sizeof(cbType)/sizeof(hlType));
-        return cbType[x];
-    }
-    static constexpr const char *typeName(hlType t)
-    {
-        return hlTypes[t];
-    }
-};

BIN
prototypes/dcclibs.dat


BIN
sigs/dccb2s.sig


+ 0 - 443
src/BasicBlock.cpp

@@ -1,443 +0,0 @@
-#include <cassert>
-#include <string>
-#include <boost/range/rbegin.hpp>
-#include <boost/range/rend.hpp>
-#include <boost/range/adaptors.hpp>
-#include "BasicBlock.h"
-#include "Procedure.h"
-#include "dcc.h"
-using namespace std;
-using namespace boost;
-
-BB *BB::Create(void *ctx, const string &s, Function *parent, BB *insertBefore)
-{
-    BB *pnewBB = new BB;
-    pnewBB->Parent = parent;
-    return pnewBB;
-}
-/**
- *  @arg start - basic block starts here, might be parent->Icode.end()
- *  @arg fin - last of basic block's instructions
-*/
-BB *BB::Create(iICODE start, iICODE fin, uint8_t _nodeType, int numOutEdges, Function *parent)
-{
-    BB* pnewBB;
-    pnewBB = new BB;
-    pnewBB->nodeType = _nodeType;	/* Initialise */
-    pnewBB->immedDom = NO_DOM;
-    pnewBB->loopHead = pnewBB->caseHead = pnewBB->caseTail =
-    pnewBB->latchNode= pnewBB->loopFollow = NO_NODE;
-    pnewBB->instructions = make_iterator_range(start,fin);
-    if(start==parent->Icode.end())
-    {
-        pnewBB->instructions = make_iterator_range(parent->Icode.end(),parent->Icode.end());
-    }
-    else
-    {
-        pnewBB->instructions.advance_end(1); // 1 after fin, to create range where fin is inclusive
-    }
-    if (numOutEdges)
-        pnewBB->edges.resize(numOutEdges);
-
-    /* Mark the basic block to which the icodes belong to, but only for
-         * real code basic blocks (ie. not interval bbs) */
-    if(parent)
-    {
-        if (start != parent->Icode.end())
-            parent->Icode.SetInBB(pnewBB->instructions, pnewBB);
-        parent->heldBBs.push_back(pnewBB);
-        parent->m_cfg.push_back(pnewBB);
-        pnewBB->Parent = parent;
-    }
-    if ( start != parent->Icode.end() )		/* Only for code BB's */
-        stats.numBBbef++;
-    return pnewBB;
-}
-BB *BB::Create(int start, int ip, uint8_t _nodeType, int numOutEdges, Function *parent)
-{
-    iICODE st(parent->Icode.begin());
-    iICODE fin(parent->Icode.begin());
-    if(start==-1)
-    {
-        st  = parent->Icode.end();
-        fin = parent->Icode.end();
-    }
-    else
-    {
-        advance(st,start);
-        advance(fin,ip);
-    }
-    return Create(st,fin,_nodeType,numOutEdges,parent);
-}
-
-static const char *const s_nodeType[] = {"branch", "if", "case", "fall", "return", "call",
-                                 "loop", "repeat", "interval", "cycleHead",
-                                 "caseHead", "terminate",
-                                 "nowhere" };
-
-static const char *const s_loopType[] = {"noLoop", "while", "repeat", "loop", "for"};
-
-
-void BB::display()
-{
-    printf("\nnode type = %s, ", s_nodeType[nodeType]);
-    printf("start = %ld, length = %ld, #out edges = %ld\n", begin()->loc_ip, size(), edges.size());
-
-    for (size_t i = 0; i < edges.size(); i++)
-    {
-        if(edges[i].BBptr==0)
-            printf(" outEdge[%2d] = Unlinked out edge to %d\n",i, edges[i].ip);
-        else
-            printf(" outEdge[%2d] = %d\n",i, edges[i].BBptr->begin()->loc_ip);
-    }
-}
-/*****************************************************************************
- * displayDfs - Displays the CFG using a depth first traversal
- ****************************************************************************/
-void BB::displayDfs()
-{
-    int i;
-    assert(this);
-    traversed = DFS_DISP;
-
-    printf("node type = %s, ", s_nodeType[nodeType]);
-    printf("start = %ld, length = %ld, #in-edges = %ld, #out-edges = %ld\n",
-           begin()->loc_ip, size(), inEdges.size(), edges.size());
-    printf("dfsFirst = %ld, dfsLast = %ld, immed dom = %ld\n",
-           dfsFirstNum, dfsLastNum,
-           immedDom == MAX ? -1 : immedDom);
-    printf("loopType = %s, loopHead = %ld, latchNode = %ld, follow = %ld\n",
-           s_loopType[loopType],
-           loopHead == MAX ? -1 : loopHead,
-           latchNode == MAX ? -1 : latchNode,
-           loopFollow == MAX ? -1 : loopFollow);
-    printf ("ifFollow = %ld, caseHead = %ld, caseTail = %ld\n",
-            ifFollow == MAX ? -1 : ifFollow,
-            caseHead == MAX ? -1 : caseHead,
-            caseTail == MAX ? -1 : caseTail);
-
-    if (nodeType == INTERVAL_NODE)
-        printf("corresponding interval = %ld\n", correspInt->numInt);
-    else
-    {
-        int edge_idx=0;
-        for(BB *node : inEdges)
-        {
-            printf ("  inEdge[%ld] = %ld\n", edge_idx, node->begin()->loc_ip);
-            edge_idx++;
-        }
-    }
-    /* Display out edges information */
-    i=0;
-    for(TYPEADR_TYPE &edg : edges)
-    {
-        if (nodeType == INTERVAL_NODE)
-            printf(" outEdge[%ld] = %ld\n", i, edg.BBptr->correspInt->numInt);
-        else
-            printf(" outEdge[%d] = %ld\n", i, edg.BBptr->begin()->loc_ip);
-        ++i;
-    }
-    printf("----\n");
-
-    /* Recursive call on successors of current node */
-    for(TYPEADR_TYPE &pb : edges)
-    {
-        if (pb.BBptr->traversed != DFS_DISP)
-            pb.BBptr->displayDfs();
-    }
-}
-/* Recursive procedure that writes the code for the given procedure, pointed
- * to by pBB.
- * Parameters:	pBB:	pointer to the cfg.
- *				Icode:	pointer to the Icode array for the cfg graph of the
- *						current procedure.
- *				indLevel: indentation level - used for formatting.
- *				numLoc: last # assigned to local variables 				*/
-ICODE* BB::writeLoopHeader(int &indLevel, Function* pProc, int *numLoc, BB *&latch, boolT &repCond)
-{
-    latch = pProc->m_dfsLast[this->latchNode];
-    std::ostringstream ostr;
-    ICODE* picode;
-    switch (loopType)
-    {
-        case WHILE_TYPE:
-            picode = &this->back();
-
-            /* Check for error in while condition */
-            if (picode->hl()->opcode != HLI_JCOND)
-                reportError (WHILE_FAIL);
-
-            /* Check if condition is more than 1 HL instruction */
-            if (numHlIcodes > 1)
-            {
-                /* Write the code for this basic block */
-                writeBB(ostr,indLevel, pProc, numLoc);
-                repCond = true;
-            }
-
-            /* Condition needs to be inverted if the loop body is along
-             * the THEN path of the header node */
-            if (edges[ELSE].BBptr->dfsLastNum == loopFollow)
-            {
-                picode->hl()->replaceExpr(picode->hl()->expr()->inverse());
-            }
-            {
-                string e=walkCondExpr (picode->hl()->expr(), pProc, numLoc);
-                ostr << "\n"<<indentStr(indLevel)<<"while ("<<e<<") {\n";
-            }
-            picode->invalidate();
-            break;
-
-        case REPEAT_TYPE:
-            ostr << "\n"<<indentStr(indLevel)<<"do {\n";
-            picode = &latch->back();
-            picode->invalidate();
-            break;
-
-        case ENDLESS_TYPE:
-            ostr << "\n"<<indentStr(indLevel)<<"for (;;) {\n";
-    }
-    cCode.appendCode(ostr.str());
-    stats.numHLIcode += 1;
-    indLevel++;
-    return picode;
-}
-bool BB::isEndOfPath(int latch_node_idx) const
-{
-    return nodeType == RETURN_NODE || nodeType == TERMINATE_NODE ||
-           nodeType == NOWHERE_NODE || (dfsLastNum == latch_node_idx);
-}
-void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode, int _ifFollow)
-{
-    int follow;						/* ifFollow                 	*/
-    BB * succ, *latch;					/* Successor and latching node 	*/
-    ICODE * picode;					/* Pointer to HLI_JCOND instruction	*/
-    char *l;                                            /* Pointer to HLI_JCOND expression	*/
-    boolT emptyThen,					/* THEN clause is empty			*/
-            repCond;					/* Repeat condition for while() */
-
-    /* Check if this basic block should be analysed */
-    if ((_ifFollow != UN_INIT) && (this == pProc->m_dfsLast[_ifFollow]))
-        return;
-
-    if (wasTraversedAtLevel(DFS_ALPHA))
-        return;
-    traversed = DFS_ALPHA;
-
-    /* Check for start of loop */
-    repCond = false;
-    latch = NULL;
-    if (loopType)
-    {
-       picode=writeLoopHeader(indLevel, pProc, numLoc, latch, repCond);
-    }
-
-    /* Write the code for this basic block */
-    if (repCond == false)
-    {
-        std::ostringstream ostr;
-        writeBB(ostr,indLevel, pProc, numLoc);
-        cCode.appendCode(ostr.str());
-    }
-
-    /* Check for end of path */
-    if (isEndOfPath(_latchNode))
-        return;
-
-    /* Check type of loop/node and process code */
-    if (    loopType)	/* there is a loop */
-    {
-        assert(latch);
-        if (this != latch)		/* loop is over several bbs */
-        {
-            if (loopType == WHILE_TYPE)
-            {
-                succ = edges[THEN].BBptr;
-                if (succ->dfsLastNum == loopFollow)
-                    succ = edges[ELSE].BBptr;
-            }
-            else
-                succ = edges[0].BBptr;
-            if (succ->traversed != DFS_ALPHA)
-                succ->writeCode (indLevel, pProc, numLoc, latch->dfsLastNum,_ifFollow);
-            else	/* has been traversed so we need a goto */
-                succ->front().ll()->emitGotoLabel (indLevel);
-        }
-
-        /* Loop epilogue: generate the loop trailer */
-        indLevel--;
-        if (loopType == WHILE_TYPE)
-        {
-            std::ostringstream ostr;
-            /* Check if there is need to repeat other statements involved
-                         * in while condition, then, emit the loop trailer */
-            if (repCond)
-            {
-                writeBB(ostr,indLevel+1, pProc, numLoc);
-            }
-            ostr <<indentStr(indLevel)<< "}	/* end of while */\n";
-            cCode.appendCode(ostr.str());
-        }
-        else if (loopType == ENDLESS_TYPE)
-            cCode.appendCode( "%s}	/* end of loop */\n",indentStr(indLevel));
-        else if (loopType == REPEAT_TYPE)
-        {
-            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());
-            }
-        }
-
-        /* Recurse on the loop follow */
-        if (loopFollow != MAX)
-        {
-            succ = pProc->m_dfsLast[loopFollow];
-            if (succ->traversed != DFS_ALPHA)
-                succ->writeCode (indLevel, pProc, numLoc, _latchNode, _ifFollow);
-            else		/* has been traversed so we need a goto */
-                succ->front().ll()->emitGotoLabel (indLevel);
-        }
-    }
-
-    else		/* no loop, process nodeType of the graph */
-    {
-        if (nodeType == TWO_BRANCH)		/* if-then[-else] */
-        {
-            stats.numHLIcode++;
-            indLevel++;
-            emptyThen = false;
-
-            if (ifFollow != MAX)		/* there is a follow */
-            {
-                /* process the THEN part */
-                follow = ifFollow;
-                succ = edges[THEN].BBptr;
-                if (succ->traversed != DFS_ALPHA)	/* not visited */
-                {
-                    if (succ->dfsLastNum != follow)	/* THEN part */
-                    {
-                        l = writeJcond ( *back().hl(), pProc, numLoc);
-                        cCode.appendCode( "\n%s%s", indentStr(indLevel-1), l);
-                        succ->writeCode (indLevel, pProc, numLoc, _latchNode,follow);
-                    }
-                    else		/* empty THEN part => negate ELSE part */
-                    {
-                        l = writeJcondInv ( *back().hl(), pProc, numLoc);
-                        cCode.appendCode( "\n%s%s", indentStr(indLevel-1), l);
-                        edges[ELSE].BBptr->writeCode (indLevel, pProc, numLoc, _latchNode, follow);
-                        emptyThen = true;
-                    }
-                }
-                else	/* already visited => emit label */
-                    succ->front().ll()->emitGotoLabel(indLevel);
-
-                /* process the ELSE part */
-                succ = edges[ELSE].BBptr;
-                if (succ->traversed != DFS_ALPHA)		/* not visited */
-                {
-                    if (succ->dfsLastNum != follow)		/* ELSE part */
-                    {
-                        cCode.appendCode( "%s}\n%selse {\n",
-                                          indentStr(indLevel-1), indentStr(indLevel - 1));
-                        succ->writeCode (indLevel, pProc, numLoc, _latchNode, follow);
-                    }
-                    /* else (empty ELSE part) */
-                }
-                else if (! emptyThen) 	/* already visited => emit label */
-                {
-                    cCode.appendCode( "%s}\n%selse {\n",
-                                      indentStr(indLevel-1), indentStr(indLevel - 1));
-                    succ->front().ll()->emitGotoLabel (indLevel);
-                }
-                cCode.appendCode( "%s}\n", indentStr(--indLevel));
-
-                /* Continue with the follow */
-                succ = pProc->m_dfsLast[follow];
-                if (succ->traversed != DFS_ALPHA)
-                    succ->writeCode (indLevel, pProc, numLoc, _latchNode,_ifFollow);
-            }
-            else		/* no follow => if..then..else */
-            {
-                l = writeJcond ( *back().hl(), pProc, numLoc);
-                cCode.appendCode( "%s%s", indentStr(indLevel-1), l);
-                edges[THEN].BBptr->writeCode (indLevel, pProc, numLoc, _latchNode, _ifFollow);
-                cCode.appendCode( "%s}\n%selse {\n", indentStr(indLevel-1), indentStr(indLevel - 1));
-                edges[ELSE].BBptr->writeCode (indLevel, pProc, numLoc, _latchNode, _ifFollow);
-                cCode.appendCode( "%s}\n", indentStr(--indLevel));
-            }
-        }
-
-        else 	/* fall, call, 1w */
-        {
-            succ = edges[0].BBptr;		/* fall-through edge */
-            assert(succ->size()>0);
-            if (succ->traversed != DFS_ALPHA)
-            {
-                succ->writeCode (indLevel, pProc,numLoc, _latchNode,_ifFollow);
-            }
-        }
-    }
-}
-/* Writes the code for the current basic block.
- * Args: pBB: pointer to the current basic block.
- *		 Icode: pointer to the array of icodes for current procedure.
- *		 lev: indentation level - used for formatting.	*/
-void BB::writeBB(std::ostream &ostr,int lev, Function * pProc, int *numLoc)
-{
-    /* Save the index into the code table in case there is a later goto
-     * into this instruction (first instruction of the BB) */
-    front().ll()->codeIdx = cCode.code.nextIdx();
-
-    /* Generate code for each hlicode that is not a HLI_JCOND */
-
-    for(ICODE &pHli : instructions)
-    {
-        if ((pHli.type == HIGH_LEVEL) && ( pHli.valid() )) //TODO: use filtering range here.
-        {
-            std::string line = pHli.hl()->write1HlIcode(pProc, numLoc);
-            if (!line.empty())
-            {
-                ostr<<indentStr(lev)<<line;
-                stats.numHLIcode++;
-            }
-            if (option.verbose)
-                pHli.writeDU();
-        }
-    }
-}
-
-iICODE BB::begin()
-{
-    return instructions.begin();//range_start;
-}
-
-iICODE BB::end() const
-{
-    return instructions.end();//range_end
-}
-ICODE &BB::back()
-{
-    return instructions.back();//*rbegin();
-}
-
-size_t BB::size()
-{
-
-    return distance(instructions.begin(),instructions.end());
-}
-
-ICODE &BB::front()
-{
-    return instructions.front();//*begin();
-}
-
-riICODE BB::rbegin()
-{
-    return riICODE( instructions.end() );
-}
-riICODE BB::rend()
-{
-    return riICODE( instructions.begin() );
-}

+ 0 - 7
src/CMakeLists.txt

@@ -1,7 +0,0 @@
-SET(dcc_test_SOURCES tests/comwrite.cpp)
-include_directories(${GMOCK_INCLUDE_DIRS} ${GMOCK_ROOT}/gtest/include)
-enable_testing()
-add_executable(tester ${dcc_test_SOURCES})
-target_link_libraries(tester
-    ${GMOCK_BOTH_LIBRARIES} ${REQ_LLVM_LIBRARIES})
-add_test(dcc-tests tester)

+ 0 - 32
src/Procedure.cpp

@@ -1,32 +0,0 @@
-#include "Procedure.h"
-#include "project.h"
-#include "scanner.h"
-//FunctionType *Function::getFunctionType() const
-//{
-//    return &m_type;
-//}
-
-/* Does some heuristic pruning.  Looks for ptrs. into the table
- * and for addresses that don't appear to point to valid code.
-*/
-void JumpTable::pruneEntries(uint16_t cs)
-{
-    PROG *prg(Project::get()->binary());
-    for (uint32_t i = start; i < finish; i += 2)
-    {
-        uint32_t target = cs + LH(&prg->Image[i]);
-        if (target < finish && target >= start)
-            finish = target;
-        else if (target >= (uint32_t)prg->cbImage)
-            finish = i;
-    }
-    ICODE _Icode; // used as scan input
-    for (uint32_t i = start; i < finish; i += 2)
-    {
-        uint32_t target = cs + LH(&prg->Image[i]);
-        /* Be wary of 00 00 as code - it's probably data */
-        if (! (prg->Image[target] || prg->Image[target+1]) || scan(target, _Icode))
-            finish = i;
-    }
-
-}

+ 757 - 771
src/ast.cpp

@@ -4,268 +4,278 @@
  * Date: September 1993
  * (C) Cristina Cifuentes
  */
-#include <stdint.h>
-#include <string>
-#include <sstream>
-#include <iostream>
-#include <cassert>
-#include "types.h"
+
+#if __BORLAND__
+#include <alloc.h>
+#else
+#include <malloc.h>		/* For free() */
+#endif
+#include <string.h>
 #include "dcc.h"
-#include "machine_x86.h"
-#include "project.h"
-extern Project g_proj;
-using namespace std;
-// Conditional operator symbols in C.  Index by condOp enumeration type
-static const char * const condOpSym[] = { " <= ", " < ", " == ", " != ", " > ", " >= ",
-                                          " & ", " | ", " ^ ", " ~ ",
-                                          " + ", " - ", " * ", " / ",
-                                          " >> ", " << ", " % ", " && ", " || " };
 
+/* Index registers **** temp solution */
+static char *idxReg[8] = {"bx+si", "bx+di", "bp+si", "bp+di", 
+                          "si", "di", "bp", "bx" };
+/* Conditional operator symbols in C.  Index by condOp enumeration type */
+static char *condOpSym[] = { " <= ", " < ", " == ", " != ", " > ", " >= ",
+                             " & ", " | ", " ^ ", " ~ ",
+                             " + ", " - ", " * ", " / ", 
+                             " >> ", " << ", " % ", " && ", " || " };
+
+#define EXP_SIZE 200		/* Size of the expression buffer */
 
 /* Local expression stack */
-//typedef struct _EXP_STK {
-//    COND_EXPR       *exp;
-//    struct _EXP_STK *next;
-//} EXP_STK; - for local expression stack
+typedef struct _EXP_STK {
+    COND_EXPR       *exp;
+    struct _EXP_STK *next;
+} EXP_STK;
+
+static EXP_STK *expStk = NULL;      /* local expression stack */
+
 
+static char *hexStr (Int i)
 /* Returns the integer i in C hexadecimal format */
-static const char *hexStr (uint16_t i)
-{
-    static char buf[10];
-    sprintf (buf, "%s%x", (i > 9) ? "0x" : "", i);
+{ static char buf[10];
+
+    i &= 0xFFFF;
+    sprintf (buf, "%s%lX", (i > 9) ? "0x" : "", i);
     return (buf);
 }
 
 
+void setRegDU (PICODE pIcode, byte regi, operDu du)
 /* Sets the du record for registers according to the du flag    */
-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 |= duReg[regi];
-        du1.numRegsDef++;
-        break;
-    case eUSE:
-        du.use |= duReg[regi];
-        break;
-    case USE_DEF:
-        du.def |= duReg[regi];
-        du.use |= duReg[regi];
-        du1.numRegsDef++;
-        break;
-    case NONE:    /* do nothing */
-        break;
+    switch (du) {
+      case DEF:     pIcode->du.def |= duReg[regi];
+                    pIcode->du1.numRegsDef++;
+                    break;
+      case USE:     pIcode->du.use |= duReg[regi];
+                    break;
+      case USE_DEF: pIcode->du.def |= duReg[regi];
+                    pIcode->du1.numRegsDef++;
+                    pIcode->du.use |= duReg[regi];
+                    break;
+      case NONE:    /* do nothing */
+                    break;
     }
 }
 
 
+void copyDU (PICODE pIcode, PICODE duIcode, operDu du, operDu duDu)
 /* Copies the def, use, or def and use fields of duIcode into pIcode */
-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;
+    switch (du) {
+      case DEF:     
+            if (duDu == DEF)
+                memcpy (&pIcode->du.def, &duIcode->du.def, sizeof(dword));
+            else
+                memcpy (&pIcode->du.def, &duIcode->du.use, sizeof(dword));
+            break;
+      case USE: 
+            if (duDu == DEF)
+                memcpy (&pIcode->du.use, &duIcode->du.def, sizeof(dword));
+            else
+                memcpy (&pIcode->du.use, &duIcode->du.use, sizeof(dword));
+            break;
+      case USE_DEF: 
+            memcpy (&pIcode->du, &duIcode->du, sizeof(DU_ICODE));
+            break;
     }
 }
 
 
+static COND_EXPR *newCondExp (condNodeType t)
+/* Creates a newExp conditional expression node of type t and returns it */
+{ COND_EXPR *newExp;
+    
+    newExp = allocStruc(COND_EXPR); 
+    memset(newExp, 0, sizeof(COND_EXPR));
+    newExp->type = t;
+    return (newExp);
+}
+
+
+COND_EXPR *boolCondExp (COND_EXPR *lhs, COND_EXPR *rhs, condOp op)
 /* Creates a conditional boolean expression and returns it */
-COND_EXPR *COND_EXPR::boolOp(COND_EXPR *_lhs, COND_EXPR *_rhs, condOp _op)
-{
-    COND_EXPR *newExp;
+{ COND_EXPR *newExp;
 
-    newExp = new COND_EXPR(BOOLEAN_OP);
-    newExp->boolExpr.op = _op;
-    newExp->boolExpr.lhs = _lhs;
-    newExp->boolExpr.rhs = _rhs;
+    newExp = newCondExp (BOOLEAN_OP);
+    newExp->expr.boolExpr.op = op;
+    newExp->expr.boolExpr.lhs = lhs;
+    newExp->expr.boolExpr.rhs = rhs;
     return (newExp);
 }
 
-/* Returns a unary conditional expression node.  This procedure should
+
+COND_EXPR *unaryCondExp (condNodeType t, COND_EXPR *exp)
+/* 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;
+{ COND_EXPR *newExp;
 
-    newExp = new COND_EXPR(t);
-    newExp->expr.unaryExp = sub_expr;
-    return (newExp);
+	newExp = newCondExp (t);
+	newExp->expr.unaryExp = exp;
+	return (newExp);
 }
 
 
+COND_EXPR *idCondExpGlob (int16 segValue, int16 off)
 /* Returns an identifier conditional expression node of type GLOB_VAR */
-COND_EXPR *GlobalVariable::Create(int16_t segValue, int16_t off)
-{
-    COND_EXPR *newExp;
-    uint32_t adr;
+{ COND_EXPR *newExp;
+  dword adr;
+  Int i;
 
-    newExp = new COND_EXPR(IDENTIFIER);
+    newExp = newCondExp (IDENTIFIER);
     newExp->expr.ident.idType = GLOB_VAR;
     adr = opAdr(segValue, off);
-    auto i=g_proj.getSymIdxByAdd(adr);
-    if ( not g_proj.validSymIdx(i) )
-    {
-        printf ("Error, glob var not found in symtab\n");
-        delete newExp;
-        return 0;
-    }
+    for (i = 0; i < symtab.csym; i++)
+        if (symtab.sym[i].label == adr)
+            break;
+if (i == symtab.csym)
+printf ("Error, glob var not found in symtab\n");
     newExp->expr.ident.idNode.globIdx = i;
     return (newExp);
 }
 
 
+COND_EXPR *idCondExpReg (byte regi, flags32 icodeFlg, LOCAL_ID *locsym)
 /* Returns an identifier conditional expression node of type REGISTER */
-COND_EXPR *COND_EXPR::idReg(eReg regi, uint32_t icodeFlg, LOCAL_ID *locsym)
-{
-    COND_EXPR *newExp;
+{ COND_EXPR *newExp;
 
-    newExp = new COND_EXPR(IDENTIFIER);
+    newExp = newCondExp (IDENTIFIER);
     newExp->expr.ident.idType = REGISTER;
     if ((icodeFlg & B) || (icodeFlg & SRC_B))
     {
-        newExp->expr.ident.idNode.regiIdx = locsym->newByteWordReg(TYPE_BYTE_SIGN, regi);
+        newExp->expr.ident.idNode.regiIdx = newByteWordRegId (locsym, 
+                                                        TYPE_BYTE_SIGN, regi);
         newExp->expr.ident.regiType = BYTE_REG;
     }
-    else    /* uint16_t */
+    else    /* word */
     {
-        newExp->expr.ident.idNode.regiIdx = locsym->newByteWordReg( TYPE_WORD_SIGN, regi);
+        newExp->expr.ident.idNode.regiIdx = newByteWordRegId (locsym, 
+                                                        TYPE_WORD_SIGN, regi);
         newExp->expr.ident.regiType = WORD_REG;
     }
     return (newExp);
 }
 
 
+COND_EXPR *idCondExpRegIdx (Int idx, regType type)
 /* Returns an identifier conditional expression node of type REGISTER */
-COND_EXPR *COND_EXPR::idRegIdx(int idx, regType reg_type)
-{
-    COND_EXPR *newExp;
+{ COND_EXPR *newExp;
 
-    newExp = new COND_EXPR(IDENTIFIER);
-    newExp->expr.ident.idType = REGISTER;
-    newExp->expr.ident.regiType = reg_type;
-    newExp->expr.ident.idNode.regiIdx = idx;
-    return (newExp);
+	newExp = newCondExp (IDENTIFIER);
+	newExp->expr.ident.idType = REGISTER;
+	newExp->expr.ident.regiType = type;
+	newExp->expr.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)
-{
-    COND_EXPR *newExp;
-    size_t i;
 
-    newExp = new COND_EXPR(IDENTIFIER);
+COND_EXPR *idCondExpLoc (Int off, LOCAL_ID *localId)
+/* Returns an identifier conditional expression node of type LOCAL_VAR */ 
+{ COND_EXPR *newExp;
+  Int i;
+
+    newExp = newCondExp (IDENTIFIER);
     newExp->expr.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))
+    for (i = 0; i < localId->csym; i++)
+        if ((localId->id[i].id.bwId.off == off) &&
+            (localId->id[i].id.bwId.regOff == 0))
             break;
-    if (i == localId->csym())
-        printf ("Error, cannot find local var\n");
+if (i == localId->csym) printf ("Error, cannot find local var\n");
     newExp->expr.ident.idNode.localIdx = i;
-    localId->id_arr[i].setLocalName(i);
+    sprintf (localId->id[i].name, "loc%ld", i);
     return (newExp);
 }
 
 
-/* Returns an identifier conditional expression node of type PARAM */
-COND_EXPR *COND_EXPR::idParam(int off, const STKFRAME * argSymtab)
-{
-    COND_EXPR *newExp;
+COND_EXPR *idCondExpParam (Int off, PSTKFRAME argSymtab)
+/* Returns an identifier conditional expression node of type PARAM */ 
+{ COND_EXPR *newExp;
+  Int i;
 
-    newExp = new COND_EXPR(IDENTIFIER);
+    newExp = newCondExp (IDENTIFIER);
     newExp->expr.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);
+    for (i = 0; i < argSymtab->csym; i++)
+        if (argSymtab->sym[i].off == off)
+            break;
+if (i == argSymtab->csym) printf ("Error, cannot find argument var\n");
+    newExp->expr.ident.idNode.localIdx = i;
     return (newExp);
 }
 
 
+COND_EXPR *idCondExpIdxGlob (int16 segValue, int16 off, byte regi, 
+                              LOCAL_ID *locSym)
 /* 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)
-{
-    COND_EXPR *newExp;
-    size_t i;
+{ COND_EXPR *newExp;
+  Int i;
 
-    newExp = new COND_EXPR(IDENTIFIER);
+    newExp = newCondExp (IDENTIFIER);
     newExp->expr.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))
+    for (i = 0; i < locSym->csym; i++)
+        if ((locSym->id[i].id.bwGlb.seg == segValue) &&
+            (locSym->id[i].id.bwGlb.off == off) &&
+            (locSym->id[i].id.bwGlb.regi == regi))
             break;
-    if (i == locSym->csym())
-        printf ("Error, indexed-glob var not found in local id table\n");
+if (i == locSym->csym) 
+printf ("Error, indexed-glob var not found in local id table\n");
     newExp->expr.ident.idNode.idxGlbIdx = i;
     return (newExp);
 }
 
 
+COND_EXPR *idCondExpKte (dword kte, byte size)
 /* Returns an identifier conditional expression node of type CONSTANT */
-COND_EXPR *COND_EXPR::idKte(uint32_t kte, uint8_t size)
-{
-    COND_EXPR *newExp = new COND_EXPR(IDENTIFIER);
+{ COND_EXPR *newExp;
+
+    newExp = newCondExp (IDENTIFIER);
     newExp->expr.ident.idType = CONSTANT;
     newExp->expr.ident.idNode.kte.kte = kte;
-    newExp->expr.ident.idNode.kte.size = size;
+	newExp->expr.ident.idNode.kte.size = size;
     return (newExp);
 }
 
 
+COND_EXPR *idCondExpLongIdx (Int idx)
 /* Returns an identifier conditional expression node of type LONG_VAR,
  * that points to the given index idx.  */
-COND_EXPR *COND_EXPR::idLongIdx (int idx)
-{
-    COND_EXPR *newExp = new COND_EXPR(IDENTIFIER);
+{ COND_EXPR *newExp;
+    
+    newExp = newCondExp (IDENTIFIER);
     newExp->expr.ident.idType = LONG_VAR;
     newExp->expr.ident.idNode.longIdx = idx;
     return (newExp);
 }
 
 
+COND_EXPR *idCondExpLong (LOCAL_ID *localId, opLoc sd, PICODE pIcode, 
+                          hlFirst f, Int ix, operDu du, Int off)
 /* 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)
-{
-    int idx;
-    COND_EXPR *newExp = new COND_EXPR(IDENTIFIER);
+{ COND_EXPR *newExp;
+  Int idx;
+
+    newExp = newCondExp (IDENTIFIER);
+
     /* Check for long constant and save it as a constant expression */
-    if ((sd == SRC) && pIcode->ll()->testFlags(I))  /* constant */
+    if ((sd == SRC) && ((pIcode->ic.ll.flg & I) == I))  /* constant */
     {
         newExp->expr.ident.idType = CONSTANT;
         if (f == HIGH_FIRST)
-            newExp->expr.ident.idNode.kte.kte = (pIcode->ll()->src().getImm2() << 16) +
-                    atOffset.src().getImm2();
+            newExp->expr.ident.idNode.kte.kte = (pIcode->ic.ll.immed.op << 16) +
+                                         (pIcode+off)->ic.ll.immed.op;
         else        /* LOW_FIRST */
-            newExp->expr.ident.idNode.kte.kte =
-                    (atOffset.src().getImm2() << 16)+ pIcode->ll()->src().getImm2();
-        newExp->expr.ident.idNode.kte.size = 4;
+            newExp->expr.ident.idNode.kte.kte = 
+				((pIcode+off)->ic.ll.immed.op << 16)+ pIcode->ic.ll.immed.op;
+		newExp->expr.ident.idNode.kte.size = 4;
     }
     /* Save it as a long expression (reg, stack or glob) */
     else
     {
-        idx = localId->newLong(sd, pIcode, f, ix, du, atOffset);
+        idx = newLongId (localId, sd, pIcode, f, ix, du, off);
         newExp->expr.ident.idType = LONG_VAR;
         newExp->expr.ident.idNode.longIdx = idx;
     }
@@ -273,27 +283,25 @@ COND_EXPR *COND_EXPR::idLong(LOCAL_ID *localId, opLoc sd, iICODE pIcode, hlFirst
 }
 
 
+COND_EXPR *idCondExpFunc (PPROC pproc, PSTKFRAME args)
 /* Returns an identifier conditional expression node of type FUNCTION */
-COND_EXPR *COND_EXPR::idFunc(Function * pproc, STKFRAME * args)
-{
-    COND_EXPR *newExp;
+{ COND_EXPR *newExp;
 
-    newExp = new COND_EXPR(IDENTIFIER);
+    newExp = newCondExp (IDENTIFIER);
     newExp->expr.ident.idType = FUNCTION;
     newExp->expr.ident.idNode.call.proc = pproc;
-    newExp->expr.ident.idNode.call.args = args;
+	newExp->expr.ident.idNode.call.args = args;
     return (newExp);
 }
 
 
-/* Returns an identifier conditional expression node of type OTHER.
+COND_EXPR *idCondExpOther (byte seg, byte regi, int16 off)
+/* 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)
-{
-    COND_EXPR *newExp;
+{ COND_EXPR *newExp;
 
-    newExp = new COND_EXPR(IDENTIFIER);
+    newExp = newCondExp (IDENTIFIER);
     newExp->expr.ident.idType = OTHER;
     newExp->expr.ident.idNode.other.seg = seg;
     newExp->expr.ident.idNode.other.regi = regi;
@@ -302,142 +310,138 @@ COND_EXPR *COND_EXPR::idOther(eReg seg, eReg regi, int16_t off)
 }
 
 
+COND_EXPR *idCondExpID (ID *retVal, LOCAL_ID *locsym, Int ix)
 /* 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_)
-{
-    COND_EXPR *newExp;
-    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;
-    }
-    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);
+{ COND_EXPR *newExp;
+  Int idx;
+
+	newExp = newCondExp (IDENTIFIER);
+	if (retVal->type == TYPE_LONG_SIGN)
+	{
+		idx = newLongRegId (locsym, TYPE_LONG_SIGN, retVal->id.longId.h,
+							retVal->id.longId.l, ix);
+		newExp->expr.ident.idType = LONG_VAR;
+		newExp->expr.ident.idNode.longIdx = idx;
+	}
+	else if (retVal->type == TYPE_WORD_SIGN)
+	{
+		newExp->expr.ident.idType = REGISTER;
+        newExp->expr.ident.idNode.regiIdx = newByteWordRegId (locsym, 
+                                         TYPE_WORD_SIGN, retVal->id.regi);
         newExp->expr.ident.regiType = WORD_REG;
-    }
-    return (newExp);
+	}
+	return (newExp);
 }
 
 
+COND_EXPR *idCondExp (PICODE pIcode, opLoc sd, PPROC pProc, Int i, 
+                      PICODE duIcode, operDu du)
 /* Returns an identifier conditional expression node, according to the given
  * type.
- * Arguments:
+ * Arguments: i : index into the icode array, used for newLongRegId only. 
  *            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 *newExp;
-
-    int idx;          /* idx into pIcode->localId table */
+{ COND_EXPR *newExp;
+  PMEM pm;
+  Int idx;          /* idx into pIcode->localId table */
 
-    const LLOperand &pm((sd == SRC) ? ll_insn.src() : ll_insn.dst);
+    pm = (sd == SRC) ? &pIcode->ic.ll.src : &pIcode->ic.ll.dst;
 
-    if (    ((sd == DST) && ll_insn.testFlags(IM_DST)) or
-            ((sd == SRC) && ll_insn.testFlags(IM_SRC)) or
-            (sd == LHS_OP))             /* for MUL lhs */
+    if (((sd == DST) && (pIcode->ic.ll.flg & IM_DST) == IM_DST) ||
+        ((sd == SRC) && (pIcode->ic.ll.flg & IM_SRC)) ||
+        (sd == LHS_OP))             /* for MUL lhs */
     {                                                   /* implicit dx:ax */
-        idx = pProc->localId.newLongReg (TYPE_LONG_SIGN, rDX, rAX, ix_);
-        newExp = COND_EXPR::idLongIdx (idx);
-        duIcode.setRegDU (rDX, du);
-        duIcode.setRegDU (rAX, du);
+        idx = newLongRegId (&pProc->localId, TYPE_LONG_SIGN, rDX, rAX, i);
+        newExp = idCondExpLongIdx (idx);
+        setRegDU (duIcode, rDX, du); 
+        setRegDU (duIcode, rAX, du);
     }
 
-    else if ((sd == DST) && ll_insn.testFlags(IM_TMP_DST))
+    else if ((sd == DST) && (pIcode->ic.ll.flg & IM_TMP_DST) == IM_TMP_DST)
     {                                                   /* implicit tmp */
-        newExp = COND_EXPR::idReg (rTMP, 0, &pProc->localId);
-        duIcode.setRegDU(rTMP, (operDu)eUSE);
+        newExp = idCondExpReg (rTMP, 0, &pProc->localId);
+        setRegDU (duIcode, rTMP, (operDu)USE);
     }
 
-    else if ((sd == SRC) && ll_insn.testFlags(I)) /* constant */
-        newExp = COND_EXPR::idKte (ll_insn.src().getImm2(), 2);
-    else if (pm.regi == rUNDEF) /* global variable */
-        newExp = GlobalVariable::Create(pm.segValue, pm.off);
-    else if ( pm.isReg() )      /* register */
+    else if ((sd == SRC) && ((pIcode->ic.ll.flg & I) == I)) /* constant */
+        newExp = idCondExpKte (pIcode->ic.ll.immed.op, 2);
+
+    else if (pm->regi == 0)                             /* global variable */
+        newExp = idCondExpGlob (pm->segValue, pm->off);
+
+    else if (pm->regi < INDEXBASE)                      /* register */
     {
-        newExp = COND_EXPR::idReg (pm.regi, (sd == SRC) ? ll_insn.getFlag() :
-                                                          ll_insn.getFlag() & NO_SRC_B,
-                                   &pProc->localId);
-        duIcode.setRegDU( pm.regi, du);
+        newExp = idCondExpReg (pm->regi, (sd == SRC) ? pIcode->ic.ll.flg :
+                            pIcode->ic.ll.flg & NO_SRC_B, &pProc->localId);
+        setRegDU (duIcode, pm->regi, du);
     }
 
-    else if (pm.off)                                   /* offset */
+    else if (pm->off)                                   /* offset */
     {
-        if ((pm.seg == rSS) && (pm.regi == INDEX_BP)) /* idx on bp */
+        if ((pm->seg == rSS) && (pm->regi == INDEXBASE + 6)) /* idx on bp */
         {
-            if (pm.off >= 0)                           /* argument */
-                newExp = COND_EXPR::idParam (pm.off, &pProc->args);
+            if (pm->off >= 0)                           /* argument */
+                newExp = idCondExpParam (pm->off, &pProc->args);
             else                                        /* local variable */
-                newExp = COND_EXPR::idLoc (pm.off, &pProc->localId);
+                newExp = idCondExpLoc (pm->off, &pProc->localId); 
         }
-        else if ((pm.seg == rDS) && (pm.regi == INDEX_BX)) /* bx */
+        else if ((pm->seg == rDS) && (pm->regi == INDEXBASE + 7)) /* bx */
         {
-            if (pm.off > 0)        /* global variable */
-                newExp = idCondExpIdxGlob (pm.segValue, pm.off, rBX,&pProc->localId);
+            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);
-            duIcode.setRegDU( rBX, eUSE);
+                newExp = idCondExpOther (pm->seg, pm->regi, pm->off);
+            setRegDU (duIcode, rBX, (operDu)USE);
         }
         else                                            /* idx <> bp, bx */
-            newExp = COND_EXPR::idOther (pm.seg, pm.regi, pm.off);
-        /**** check long ops, indexed global var *****/
+            newExp = idCondExpOther (pm->seg, pm->regi, pm->off);
+            /**** check long ops, indexed global var *****/
     }
 
-    else  /* (pm->regi >= INDEXBASE && pm->off = 0) => indexed && no off */
+    else  /* (pm->regi >= INDEXBASE && pm->off = 0) => indexed && no off */ 
     {
-        if ((pm.seg == rDS) && (pm.regi > INDEX_BP_DI)) /* dereference */
+        if ((pm->seg == rDS) && (pm->regi > INDEXBASE + 3)) /* 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);
+            switch (pm->regi) {
+              case INDEXBASE + 4:   newExp = idCondExpReg(rSI, 0, &pProc->localId);
+                                    setRegDU (duIcode, rSI, du);
+                                    break;
+              case INDEXBASE + 5:   newExp = idCondExpReg(rDI, 0, &pProc->localId);
+                                    setRegDU (duIcode, rDI, du);
+                                    break;
+              case INDEXBASE + 6:   newExp = idCondExpReg(rBP, 0, &pProc->localId);
+                                    break;
+              case INDEXBASE + 7:   newExp = idCondExpReg(rBX, 0, &pProc->localId);
+                                    setRegDU (duIcode, rBX, du);
+                                    break;
             }
-            newExp = COND_EXPR::unary (DEREFERENCE, newExp);
+            newExp = unaryCondExp (DEREFERENCE, newExp);
         }
         else
-            newExp = COND_EXPR::idOther (pm.seg, pm.regi, 0);
+            newExp = idCondExpOther (pm->seg, pm->regi, 0);
     }
 
     return (newExp);
 }
 
 
+condId idType (PICODE pIcode, opLoc sd)
 /* Returns the identifier type */
-condId LLInst::idType(opLoc sd) const
-{
-    const LLOperand &pm((sd == SRC) ? src() : dst);
+{ PMEM pm;
 
-    if ((sd == SRC) && testFlags(I))
+    pm = (sd == SRC) ? &pIcode->ic.ll.src : &pIcode->ic.ll.dst;
+
+    if ((sd == SRC) && ((pIcode->ic.ll.flg & I) == I))
         return (CONSTANT);
-    else if (pm.regi == 0)
+    else if (pm->regi == 0)
         return (GLOB_VAR);
-    else if ( pm.isReg() )
+    else if (pm->regi < INDEXBASE)
         return (REGISTER);
-    else if ((pm.seg == rSS) && (pm.regi == INDEX_BP))
+    else if ((pm->seg == rSS) && (pm->regi == INDEXBASE))
     {
-        //TODO: which pm.seg/pm.regi pairs should produce PARAM/LOCAL_VAR ?
-        if (pm.off >= 0)
+        if (pm->off >= 0)
             return (PARAM);
         else
             return (LOCAL_VAR);
@@ -448,590 +452,572 @@ 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};
+Int hlSize[] = {2, 1, 1, 2, 2, 4, 4, 4, 2, 2, 1, 4, 4};
 
 
+Int hlTypeSize (COND_EXPR *exp, PPROC pproc)
 /* Returns the type of the expression */
-int hlTypeSize (const COND_EXPR *expr, Function * pproc)
-{
-    int first, second;
-
-    if (expr == 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);
-
-    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)
-        {
-        case GLOB_VAR:
-            return (g_proj.symbolSize(expr->expr.ident.idNode.globIdx));
-        case REGISTER:
-            if (expr->expr.ident.regiType == BYTE_REG)
-                return (1);
-            else
-                return (2);
-        case LOCAL_VAR:
-            return (hlSize[pproc->localId.id_arr[expr->expr.ident.idNode.localIdx].type]);
-        case PARAM:
-            return (hlSize[pproc->args[expr->expr.ident.idNode.paramIdx].type]);
-        case GLOB_VAR_IDX:
-            return (hlSize[pproc->localId.id_arr[expr->expr.ident.idNode.idxGlbIdx].type]);
-        case CONSTANT:
-            return (expr->expr.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]);
-        case OTHER:
-            return (2);
-        } /* eos */
-        break;
-    }
-    return 2;			// CC: is this correct?
-}
-
-
+{ Int first, second;
+
+	if (exp == NULL)
+		return (2);		/* for TYPE_UNKNOWN */
+
+	switch (exp->type) {
+	  case BOOLEAN_OP: 	first = hlTypeSize (exp->expr.boolExpr.lhs, pproc);
+						second = hlTypeSize (exp->expr.boolExpr.rhs, pproc);
+						if (first > second)
+							return (first);
+						else
+							return (second);
+					
+	  case NEGATION:	case ADDRESSOF:	
+	  case POST_INC:	case POST_DEC:
+	  case PRE_INC:		case PRE_DEC:
+	  case DEREFERENCE:	return (hlTypeSize (exp->expr.unaryExp, pproc));
+						
+	  case IDENTIFIER:
+			switch (exp->expr.ident.idType) {
+			  case GLOB_VAR:
+					return (symtab.sym[exp->expr.ident.idNode.globIdx].size);
+			  case REGISTER:
+					if (exp->expr.ident.regiType == BYTE_REG)
+						return (1);
+					else
+						return (2);
+			  case LOCAL_VAR:
+					return (hlSize[pproc->localId.id[exp->expr.ident.idNode.localIdx].type]);
+			  case PARAM:
+					return (hlSize[pproc->args.sym[exp->expr.ident.idNode.paramIdx].type]);
+			  case GLOB_VAR_IDX:
+					return (hlSize[pproc->localId.id[exp->expr.ident.idNode.idxGlbIdx].type]);
+			  case CONSTANT:
+					return (exp->expr.ident.idNode.kte.size);
+			  case STRING:
+					return (2);
+			  case LONG_VAR:
+					return (4);
+			  case FUNCTION:
+					return (hlSize[exp->expr.ident.idNode.call.proc->retVal.type]);
+			  case OTHER:
+					return (2);
+			} /* eos */
+			break;
+	}
+	return 2;			// CC: is this correct?
+}
+
+
+hlType expType (COND_EXPR *exp, PPROC pproc)
 /* 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 g_proj.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:
-            return (TYPE_UNKNOWN);
-        } /* eos */
-    case UNKNOWN_OP:
-        assert(false);
-        return (TYPE_UNKNOWN);
-    }
-    return TYPE_UNKNOWN;		// CC: Correct?
-}
-
-
+{ hlType first, second;
+
+	if (exp == NULL)
+		return (TYPE_UNKNOWN);
+
+	switch (exp->type) {
+	  case BOOLEAN_OP: 	first = expType (exp->expr.boolExpr.lhs, pproc);
+						second = expType (exp->expr.boolExpr.rhs, pproc);
+						if (first != second)
+						{
+							if (hlTypeSize (exp->expr.boolExpr.lhs, pproc) > 
+								hlTypeSize (exp->expr.boolExpr.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 (expType (exp->expr.unaryExp, pproc));
+
+	  case ADDRESSOF:	return (TYPE_PTR);		/***????****/
+	  case DEREFERENCE:	return (TYPE_PTR);
+	  case IDENTIFIER:
+			switch (exp->expr.ident.idType) {
+			  case GLOB_VAR:
+					return (symtab.sym[exp->expr.ident.idNode.globIdx].type);
+			  case REGISTER:
+					if (exp->expr.ident.regiType == BYTE_REG)
+						return (TYPE_BYTE_SIGN);
+					else
+						return (TYPE_WORD_SIGN);
+			  case LOCAL_VAR:
+					return (pproc->localId.id[exp->expr.ident.idNode.localIdx].type);
+			  case PARAM:
+					return (pproc->args.sym[exp->expr.ident.idNode.paramIdx].type);
+			  case GLOB_VAR_IDX:
+					return (pproc->localId.id[exp->expr.ident.idNode.idxGlbIdx].type);
+			  case CONSTANT:
+					return (TYPE_CONST);
+			  case STRING:
+					return (TYPE_STR);
+			  case LONG_VAR:
+					return (pproc->localId.id[exp->expr.ident.idNode.longIdx].type);
+			  case FUNCTION:
+					return (exp->expr.ident.idNode.call.proc->retVal.type);
+			  case OTHER:
+					return (TYPE_UNKNOWN);
+			} /* eos */
+	}
+	return TYPE_UNKNOWN;		// CC: Correct?
+}
+
+
+void removeRegFromLong (byte regi, LOCAL_ID *locId, COND_EXPR *tree)
 /* Removes the register from the tree.  If the register was part of a long
  * register (eg. dx:ax), the node gets transformed into an integer register
  * 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);
-        }
-        break;
+	IDENTTYPE* ident;     	/* ptr to an identifier */
+	byte otherRegi;         /* high or low part of long register */
+
+    switch (tree->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 = newByteWordRegId (locId, TYPE_WORD_SIGN,
+                                                      otherRegi); 
+            }
+            break;
     }
 }
 
 
+static char *getString (Int offset)
 /* Returns the string located in image, formatted in C format. */
-static std::string getString (int offset)
-{
-    PROG &prog(Project::get()->prog);
-    ostringstream o;
-    int strLen, i;
-
-    strLen = strSize (&prog.Image[offset], '\0');
-    o << '"';
-    for (i = 0; i < strLen; i++)
-        o<<cChar(prog.Image[offset+i]);
-    o << "\"\0";
-    return (o.str());
+{ char *o;
+  Int strLen, i;
+
+	strLen = strSize (&prog.Image[offset], '\0');
+	o = (char *) allocMem((strLen*2+1) * sizeof(char));
+	o[0] = '"';
+	o[1] = '\0';
+	for (i = 0; i < strLen; i++)
+		strcat (o, cChar(prog.Image[offset+i]));
+	strcat (o, "\"\0");
+	return (o);
 }
 
 
+char *walkCondExpr (COND_EXPR* exp, PPROC pProc, Int* numLoc)
 /* Walks the conditional expression tree and returns the result on a string */
-string walkCondExpr (const COND_EXPR* expr, Function * pProc, int* numLoc)
-{
-    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)
+{ int16 off;                /* temporal - for OTHER */
+  ID* id;                   /* Pointer to local identifier table */
+  char* o;                  /* Operand string pointer */
+  boolT needBracket;        /* Determine whether parenthesis is needed */
+  BWGLB_TYPE* bwGlb;     	/* Ptr to BWGLB_TYPE (global indexed var) */
+  PSTKSYM psym;				/* Pointer to argument in the stack */
+  char* condExp, *e;		/* Return and intermediate expressions */
+
+	condExp = (char*) allocMem (EXP_SIZE * sizeof(char));
+	condExp[0] = '\0';
+
+    if (exp == NULL)
+        return (condExp);
+
+    needBracket = TRUE;
+    switch (exp->type)
     {
-    case BOOLEAN_OP:
-        outStr << "(";
-        outStr << walkCondExpr(expr->lhs(), pProc, numLoc);
-        outStr << condOpSym[expr->op()];
-        outStr << walkCondExpr(expr->rhs(), pProc, numLoc);
-        outStr << ")";
-        break;
-
-    case NEGATION:
-        if (expr->expr.unaryExp->m_type == IDENTIFIER)
-        {
-            needBracket = false;
-            outStr << "!";
-        }
-        else
-            outStr << "! (";
-        outStr << walkCondExpr (expr->expr.unaryExp, pProc, numLoc);
-        if (needBracket == true)
-            outStr << ")";
-        break;
-
-    case ADDRESSOF:
-        if (expr->expr.unaryExp->m_type == IDENTIFIER)
-        {
-            needBracket = false;
-            outStr << "&";
-        }
-        else
-            outStr << "&(";
-        outStr << walkCondExpr (expr->expr.unaryExp, pProc, numLoc);
-        if (needBracket == true)
-            outStr << ")";
-        break;
-
-    case DEREFERENCE:
-        outStr << "*";
-        if (expr->expr.unaryExp->m_type == IDENTIFIER)
-            needBracket = false;
-        else
-            outStr << "(";
-        outStr << walkCondExpr (expr->expr.unaryExp, pProc, numLoc);
-        if (needBracket == true)
-            outStr << ")";
-        break;
-
-    case POST_INC:
-        outStr <<  walkCondExpr (expr->expr.unaryExp, pProc, numLoc) << "++";
-        break;
-
-    case POST_DEC:
-        outStr <<  walkCondExpr (expr->expr.unaryExp, pProc, numLoc) << "--";
-        break;
-
-    case PRE_INC:
-        outStr << "++"<< walkCondExpr (expr->expr.unaryExp, 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 << g_proj.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 <<TypeContainer::typeName(id->type)<< " "<<id->name<<"; ";
-                codeOut <<"/* "<<Machine_X86::regName(id->id.regi)<<" */\n";
-            }
-            if (id->hasMacro)
-                o << id->macro << "("<<id->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<<"("<<psym->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 <<  "["<<Machine_X86::regName(bwGlb->regi)<<"]";
-            break;
-
-        case CONSTANT:
-            if (expr->expr.ident.idNode.kte.kte < 1000)
-                o << expr->expr.ident.idNode.kte.kte;
-            else
-                o << "0x"<<std::hex << expr->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 <<TypeContainer::typeName(id->type)<< " "<<id->name<<"; ";
-                codeOut <<"/* "<<Machine_X86::regName(id->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;
+      case BOOLEAN_OP:	strcat (condExp, "(");
+                        e = walkCondExpr(exp->expr.boolExpr.lhs, pProc, numLoc);
+						strcat (condExp, e);
+                        strcat (condExp, condOpSym[exp->expr.boolExpr.op]);
+                        e = walkCondExpr(exp->expr.boolExpr.rhs, pProc, numLoc);
+						strcat (condExp, e);
+                        strcat (condExp, ")");
+                        break;
+
+      case NEGATION:    if (exp->expr.unaryExp->type == IDENTIFIER)
+                        {
+                            needBracket = FALSE;
+                            strcat (condExp, "!");
+                        }
+                        else
+                            strcat (condExp, "! (");
+                        e = walkCondExpr (exp->expr.unaryExp, pProc, numLoc);
+						strcat (condExp, e);
+                        if (needBracket == TRUE)
+                            strcat (condExp, ")");
+                        break;
+
+      case ADDRESSOF:   if (exp->expr.unaryExp->type == IDENTIFIER)
+                        {
+                            needBracket = FALSE;
+                            strcat (condExp, "&");
+                        }
+                        else
+                            strcat (condExp, "&(");
+                        e = walkCondExpr (exp->expr.unaryExp, pProc, numLoc);
+						strcat (condExp, e);
+                        if (needBracket == TRUE)
+                            strcat (condExp, ")");
+                        break;
+
+      case DEREFERENCE: if (exp->expr.unaryExp->type == IDENTIFIER)
+                        {
+                            needBracket = FALSE;
+                            strcat (condExp, "*");
+                        }
+                        else
+                            strcat (condExp, "*(");
+                        e = walkCondExpr (exp->expr.unaryExp, pProc, numLoc);
+						strcat (condExp, e);
+                        if (needBracket == TRUE)
+                            strcat (condExp, ")");
+                        break;
+
+	  case POST_INC:	e = walkCondExpr (exp->expr.unaryExp, pProc, numLoc);
+						strcat (condExp, e);
+						strcat (condExp, "++");
+						break;
+
+	  case POST_DEC:	e = walkCondExpr (exp->expr.unaryExp, pProc, numLoc);
+						strcat (condExp, e);
+						strcat (condExp, "--");
+						break;
+
+      case PRE_INC:     strcat (condExp, "++");
+                        e = walkCondExpr (exp->expr.unaryExp, pProc, numLoc);
+						strcat (condExp, e);
+                        break;
+
+      case PRE_DEC:     strcat (condExp, "--");
+                        e = walkCondExpr (exp->expr.unaryExp, pProc, numLoc);
+						strcat (condExp, e);
+                        break;
+
+      case IDENTIFIER:
+      					o = (char*) allocMem (operandSize);
+                        switch (exp->expr.ident.idType) {
+                          case GLOB_VAR:    sprintf (o, "%s",
+                            symtab.sym[exp->expr.ident.idNode.globIdx].name);
+                                            break;
+                          case REGISTER:    
+							id = &pProc->localId.id[exp->expr.ident.idNode.regiIdx];
+							if (id->name[0] == '\0')	/* no name */
+							{
+								sprintf (id->name, "loc%ld", ++(*numLoc));
+								if (id->id.regi < rAL)
+									appendStrTab (&cCode.decl, 
+											  "%s %s; /* %s */\n",
+											  hlTypes[id->type], id->name,
+                                        	  wordReg[id->id.regi - rAX]);
+								else
+									appendStrTab (&cCode.decl, 
+											  "%s %s; /* %s */\n",
+											  hlTypes[id->type], id->name,
+                                        	  byteReg[id->id.regi - rAL]);
+							}
+                            if (id->hasMacro)
+								sprintf (o, "%s(%s)", id->macro, id->name);
+							else
+								sprintf (o, "%s", id->name);
+                            break;
+
+                          case LOCAL_VAR:   
+                            sprintf (o, "%s",
+                                     pProc->localId.id[exp->expr.ident.idNode.localIdx].name);
+                            break;
+
+                          case PARAM:
+                            psym = &pProc->args.sym[exp->expr.ident.idNode.paramIdx];
+							if (psym->hasMacro)
+								sprintf (o, "%s(%s)", psym->macro, psym->name);
+							else
+								sprintf (o, "%s", psym->name);
+                            break;
+
+                          case GLOB_VAR_IDX:
+                            bwGlb = &pProc->localId.id[exp->expr.ident.idNode.idxGlbIdx].id.bwGlb;
+                          
+                            sprintf (o, "%d[%s]", (bwGlb->seg << 4) +
+                                     bwGlb->off, wordReg[bwGlb->regi - rAX]);
+                            break;
+
+                          case CONSTANT:       
+                            if (exp->expr.ident.idNode.kte.kte < 1000)
+                               sprintf (o,"%d",exp->expr.ident.idNode.kte.kte);
+                            else
+                               sprintf(o,"0x%X",exp->expr.ident.idNode.kte.kte);
+                            break;
+
+						  case STRING:
+							o = getString (exp->expr.ident.idNode.strIdx);
+							break;
+
+                          case LONG_VAR:    
+                            id = &pProc->localId.id[exp->expr.ident.idNode.longIdx];
+							if (id->name[0] != '\0') /* STK_FRAME & REG w/name*/
+                                sprintf (o, "%s", id->name);
+                            else if (id->loc == REG_FRAME)
+							{
+								sprintf (id->name, "loc%ld", ++(*numLoc));
+								appendStrTab (&cCode.decl, 
+											  "%s %s; /* %s:%s */\n",
+											  hlTypes[id->type], id->name,
+                                        	  wordReg[id->id.longId.h - rAX],
+											  wordReg[id->id.longId.l - rAX]);
+								sprintf (o, "%s", id->name);
+								propLongId (&pProc->localId, id->id.longId.l,
+											id->id.longId.h, id->name); 
+							}
+                            else    /* GLB_FRAME */
+                            {
+                                if (id->id.longGlb.regi == 0)  /* not indexed */
+                                    sprintf (o, "[%ld]", (id->id.longGlb.seg<<4)
+                                             + id->id.longGlb.offH);
+                                else if (id->id.longGlb.regi == rBX)
+                                    sprintf (o, "[%ld][bx]", 
+                                             (id->id.longGlb.seg<<4) + 
+                                             id->id.longGlb.offH);
+                            }
+                            break;
+
+                          case FUNCTION:
+                            o = writeCall (exp->expr.ident.idNode.call.proc,
+										   exp->expr.ident.idNode.call.args, 
+										   pProc, numLoc);
+                            break;
+
+                          case OTHER:       
+                            off = exp->expr.ident.idNode.other.off; 
+                            if (off == 0)   
+                                sprintf (o, "%s[%s]", 
+                                wordReg[exp->expr.ident.idNode.other.seg - rAX],
+                                idxReg[exp->expr.ident.idNode.other.regi - INDEXBASE]);
+                            else if (off < 0)
+                                sprintf (o, "%s[%s-%s]",
+                                wordReg[exp->expr.ident.idNode.other.seg - rAX],
+                                idxReg[exp->expr.ident.idNode.other.regi - INDEXBASE],
+                                hexStr (-off));
+                            else
+                                sprintf (o, "%s[%s+%s]",
+                                wordReg[exp->expr.ident.idNode.other.seg - rAX],
+                                idxReg[exp->expr.ident.idNode.other.regi - INDEXBASE],
+                                hexStr (off));
+                        } /* eos */
+                        strcat (condExp, o);
+                        break;
     }
-    cCode.appendDecl(codeOut.str());
-    return outStr.str();
+
+	return (condExp);
 }
 
 
+COND_EXPR *copyCondExp (COND_EXPR *exp)
 /* 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;        /* Expression node copy */
 
-    switch (m_type)
-    {
-    case BOOLEAN_OP:
-        newExp = new COND_EXPR(*this);
-        newExp->boolExpr.lhs = lhs()->clone();
-        newExp->boolExpr.rhs = rhs()->clone();
-        break;
-
-    case NEGATION:
-    case ADDRESSOF:
-    case DEREFERENCE:
-        newExp = new COND_EXPR(*this);
-        newExp->expr.unaryExp = expr.unaryExp->clone();
-        break;
-
-    case IDENTIFIER:
-        return new COND_EXPR(*this);
+    switch (exp->type) {
+      case BOOLEAN_OP:     
+			newExp = allocStruc(COND_EXPR);
+			memcpy(newExp, exp, sizeof(COND_EXPR));
+            newExp->expr.boolExpr.lhs = copyCondExp (exp->expr.boolExpr.lhs);
+            newExp->expr.boolExpr.rhs = copyCondExp (exp->expr.boolExpr.rhs);
+            break;
+
+      case NEGATION:    
+      case ADDRESSOF:
+      case DEREFERENCE:
+			newExp = allocStruc(COND_EXPR);
+			memcpy(newExp, exp, sizeof(COND_EXPR));
+            newExp->expr.unaryExp = copyCondExp (exp->expr.unaryExp);
+            break;
+
+      case IDENTIFIER:  
+			newExp = allocStruc(COND_EXPR);
+			memcpy(newExp, exp, sizeof(COND_EXPR));
     }
     return (newExp);
 }
 
 
+void changeBoolCondExpOp (COND_EXPR *exp, condOp newOp)
 /* Changes the boolean conditional operator at the root of this expression */
-void COND_EXPR::changeBoolOp (condOp newOp)
 {
-    boolExpr.op = newOp;
+    exp->expr.boolExpr.op = newOp;
 }
 
+
+boolT insertSubTreeReg (COND_EXPR *exp, COND_EXPR **tree, byte regi,
+                        LOCAL_ID *locsym)
 /* 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)
-{
-
-    if (tree == NULL)
-        return false;
-    COND_EXPR *temp=tree->insertSubTreeReg(_expr,regi,locsym);
-    if(nullptr!=temp)
-    {
-        tree=temp;
-        return true;
-    }
-    return false;
-}
-COND_EXPR *COND_EXPR::insertSubTreeReg (COND_EXPR *_expr, eReg regi,const LOCAL_ID *locsym)
-{
+{ byte treeReg;
 
-    eReg treeReg;
-    COND_EXPR *temp;
+    if (*tree == NULL)
+        return FALSE;
 
-    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 */
+    switch ((*tree)->type) {
+      case IDENTIFIER:  
+        if ((*tree)->expr.ident.idType == REGISTER)
+		{
+            treeReg = locsym->id[(*tree)->expr.ident.idNode.regiIdx].id.regi;
+            if (treeReg == regi)                        /* word reg */
             {
-                return _expr;
+                *tree = exp;
+                return TRUE;
             }
-            else if(Machine_X86::isSubRegisterOf(treeReg,regi))    /* uint16_t/uint8_t reg */
+            else if ((regi >= rAX) && (regi <= rBX))    /* word/byte reg */
             {
-                return _expr;
+                if ((treeReg == (regi + rAL-1)) || (treeReg == (regi + rAH-1)))
+                {
+                    *tree = exp;
+                    return TRUE;
+                }
             }
-        }
-        return false;
-
-    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;
-    }
-
-    return nullptr;
-}
-COND_EXPR *BinaryOperator::insertSubTreeReg(COND_EXPR *_expr, eReg regi, LOCAL_ID *locsym)
-{
-    COND_EXPR *r;
-    r=m_lhs->insertSubTreeReg(_expr,regi,locsym);
-    if(r)
-    {
-        m_lhs = r;
-        return this;
-    }
-    r=m_rhs->insertSubTreeReg(_expr,regi,locsym);
-    if(r)
-    {
-        m_rhs = r;
-        return this;
+		}
+        return FALSE;
+
+      case BOOLEAN_OP:     
+            if (insertSubTreeReg (exp, &(*tree)->expr.boolExpr.lhs, regi,
+                                  locsym))
+                return TRUE;
+            if (insertSubTreeReg (exp, &(*tree)->expr.boolExpr.rhs, regi,
+                                  locsym))
+                return TRUE;
+            return FALSE;
+
+      case NEGATION:
+      case ADDRESSOF:
+      case DEREFERENCE: 
+            if (insertSubTreeReg(exp, &(*tree)->expr.unaryExp,regi, locsym))
+                return TRUE;
+            return FALSE;
     }
-    return nullptr;
+	return FALSE;
 }
 
+
+boolT insertSubTreeLongReg (COND_EXPR *exp, COND_EXPR **tree, Int longIdx)
 /* 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)
 {
-    if (tree == NULL)
-        return false;
-    COND_EXPR *temp=(*tree)->insertSubTreeLongReg(_expr,longIdx);
-    if(nullptr!=temp)
-    {
-        *tree=temp;
-        return true;
+    switch ((*tree)->type) {
+      case IDENTIFIER:  if ((*tree)->expr.ident.idNode.longIdx == longIdx)
+                        {
+                            *tree = exp;
+                            return TRUE;
+                        }
+                        return FALSE;
+                        
+      case BOOLEAN_OP:	if (insertSubTreeLongReg (exp, 
+                                    &(*tree)->expr.boolExpr.lhs, longIdx))
+                            return TRUE;
+                        if (insertSubTreeLongReg (exp, 
+                                    &(*tree)->expr.boolExpr.rhs, longIdx))
+                            return TRUE;
+                        return FALSE;
+                        
+      case NEGATION:
+      case ADDRESSOF:
+      case DEREFERENCE: if (insertSubTreeLongReg (exp, 
+                                        &(*tree)->expr.unaryExp, longIdx))
+                            return TRUE;
+                        return FALSE;
     }
-    return false;
+	return FALSE;
 }
-COND_EXPR *COND_EXPR::insertSubTreeLongReg(COND_EXPR *_expr, int longIdx)
-{
-    COND_EXPR *temp;
-    switch (m_type)
-    {
-    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;
-    }
-    return nullptr;
-}
-COND_EXPR *BinaryOperator::insertSubTreeLongReg(COND_EXPR *_expr, int longIdx)
+void freeCondExpr (COND_EXPR *exp)
+/* Recursively deallocates the abstract syntax tree rooted at *exp */
 {
-    COND_EXPR *r;
-    r=m_lhs->insertSubTreeLongReg(_expr,longIdx);
-    if(r)
-    {
-        m_lhs = r;
-        return this;
+    switch (exp->type) {
+      case BOOLEAN_OP:     freeCondExpr (exp->expr.boolExpr.lhs);
+                        freeCondExpr (exp->expr.boolExpr.rhs);
+                        break;
+      case NEGATION:
+      case ADDRESSOF:
+      case DEREFERENCE: freeCondExpr (exp->expr.unaryExp);
+                        break;
     }
-    r=m_rhs->insertSubTreeLongReg(_expr,longIdx);
-    if(r)
+    free (exp);
+}
+
+
+/***************************************************************************
+ * Expression stack functions
+ **************************************************************************/
+
+void initExpStk()
+/* Reinitalizes the expression stack (expStk) to NULL, by freeing all the
+ * space allocated (if any).        */
+{ EXP_STK *top;
+
+    while (expStk != NULL)
     {
-        m_rhs = r;
-        return this;
+        top = expStk;
+        expStk = expStk->next;
+        free (top);
     }
-    return nullptr;
 }
 
 
-/* Recursively deallocates the abstract syntax tree rooted at *exp */
-void COND_EXPR::release()
-{
-    switch (m_type)
+void pushExpStk (COND_EXPR *exp)
+/* Pushes the given expression onto the local stack (expStk). */
+{ EXP_STK *newExp;
+
+    newExp = allocStruc(EXP_STK);
+    newExp->exp = exp;
+    newExp->next = expStk;
+    expStk = newExp;
+}
+
+
+COND_EXPR *popExpStk()
+/* Returns the element on the top of the local expression stack (expStk),
+ * and deallocates the space allocated by this node.
+ * If there are no elements on the stack, returns NULL. */
+{ EXP_STK *top;
+  COND_EXPR *topExp;
+
+    if (expStk != NULL)
     {
-    case BOOLEAN_OP:
-        lhs()->release();
-        rhs()->release();
-        break;
-    case NEGATION:
-    case ADDRESSOF:
-    case DEREFERENCE:
-        expr.unaryExp->release();
-        break;
+        topExp = expStk->exp;
+        top = expStk;
+        expStk = expStk->next;
+        free (top);
+        return (topExp);
     }
-    delete (this);
+    else
+        return (NULL);
 }
-/* Makes a copy of the given expression.  Allocates newExp storage for each
- * node.  Returns the copy. */
 
-COND_EXPR *BinaryOperator::clone()
-{
-    BinaryOperator* newExp=new BinaryOperator(m_op);        /* Expression node copy */
-    newExp->m_lhs = m_lhs->clone();
-    newExp->m_rhs = m_rhs->clone();
-    return newExp;
+Int numElemExpStk()
+/* Returns the number of elements available in the expression stack */
+{ EXP_STK *top;
+  Int num;
+
+	num = 0; 
+	top = expStk;
+	while (top)
+	{
+		top = top->next;
+		num++;
+	}
+	return (num);
 }
 
-COND_EXPR *BinaryOperator::inverse()
+boolT emptyExpStk()
+/* Returns whether the expression stack is empty or not */
 {
-    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};
-    BinaryOperator *res=reinterpret_cast<BinaryOperator *>(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 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 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;
-    } /* eos */
-    assert(false);
-    return res;
-
+	if (expStk == NULL)
+		return TRUE;
+	return FALSE;
 }

+ 581 - 270
src/backend.cpp

@@ -4,40 +4,47 @@
  * Purpose:	Back-end module.  Generates C code for each procedure.
  * (C) Cristina Cifuentes
  ****************************************************************************/
-#include <cassert>
-#include <string>
 
 #include "dcc.h"
-#include "disassem.h"
-#include <fstream>
-#include <iostream>
-#include <sstream>
 #include <string.h>
 #include <stdio.h>
-#include "project.h"
+
 bundle cCode;			/* Procedure declaration and code */
-using namespace std;
 
+/* Indentation buffer */
+#define indSize	81		/* size of the indentation buffer.  Each indentation
+						 * is of 4 spaces => max. 20 indentation levels */
+static char indentBuf[indSize] = 
+	"                                                                                ";
+
+
+static char *indent (Int indLevel)
+/* Indentation according to the depth of the statement */
+{ 
+	return (&indentBuf[indSize-(indLevel*4)-1]); 
+}
+
+
+static Int getNextLabel()
 /* Returns a unique index to the next label */
-int getNextLabel()
-{
-    static int labelIdx = 1;	/* index of the next label		*/
-    return (labelIdx++);
+{ static Int labelIdx = 1;	/* index of the next label		*/
+
+	return (labelIdx++);
 }
 
 
+static void displayStats (PPROC pProc)
 /* displays statistics on the subroutine */
-void Function::displayStats ()
 {
-    printf("\nStatistics - Subroutine %s\n", name.c_str());
-    printf ("Number of Icode instructions:\n");
-    printf ("  Low-level : %4d\n", stats.numLLIcode);
-    if (! (flg & PROC_ASM))
-    {
-        printf ("  High-level: %4d\n", stats.numHLIcode);
-        printf ("  Percentage reduction: %2.2f%%\n", 100.0 - (stats.numHLIcode *
-                                                              100.0) / stats.numLLIcode);
-    }
+   printf("\nStatistics - Subroutine %s\n", pProc->name);
+   printf ("Number of Icode instructions:\n");
+   printf ("  Low-level : %4d\n", stats.numLLIcode);
+   if (! (pProc->flg & PROC_ASM))
+   {
+	  printf ("  High-level: %4d\n", stats.numHLIcode);
+      printf ("  Percentage reduction: %2.2f%%\n", 100.0 - (stats.numHLIcode *
+           100.0) / stats.numLLIcode);
+   }
 }
 
 
@@ -48,315 +55,619 @@ static void fixupLabels (PPROC pProc)
  * a unique label number for it.  This label is placed in the associated
  * icode for the node (pProc->Icode).  The procedure is done in sequential
  * order of dsfLast numbering.	*/
-{ int i;				/* index into the dfsLast array */
-    PBB *dfsLast;			/* pointer to the dfsLast array */
-
-    dfsLast = pProc->dfsLast;
-    for (i = 0; i < pProc->numBBs; i++)
-        if (dfsLast[i]->flg/* & BB_HAS_LABEL*/) {
-            pProc->Icode.icode[dfsLast[i]->start].ll()->flg |= HLL_LABEL;
-            pProc->Icode.icode[dfsLast[i]->start].ll()->hllLabNum = getNextLabel();
-        }
+{ Int i;				/* index into the dfsLast array */
+  PBB *dfsLast;			/* pointer to the dfsLast array */
+
+	dfsLast = pProc->dfsLast;
+	for (i = 0; i < pProc->numBBs; i++)
+		if (dfsLast[i]->flg/* & BB_HAS_LABEL*/) {
+			pProc->Icode.icode[dfsLast[i]->start].ic.ll.flg |= HLL_LABEL;
+			pProc->Icode.icode[dfsLast[i]->start].ic.ll.hllLabNum = getNextLabel();
+		}
 }
 #endif
 
 
+char *cChar (byte c)
 /* Returns the corresponding C string for the given character c.  Character
  * constants such as carriage return and line feed, require 2 C characters. */
-char *cChar (uint8_t c)
-{
-    static char res[3];
-
-    switch (c) {
-        case 0x8:		/* backspace */
-            sprintf (res, "\\b");
-            break;
-        case 0x9:		/* horizontal tab */
-            sprintf (res, "\\t");
-            break;
-        case 0x0A:	/* new line */
-            sprintf (res, "\\n");
-            break;
-        case 0x0C:	/* form feed */
-            sprintf (res, "\\f");
-            break;
-        case 0x0D:	/* carriage return */
-            sprintf (res, "\\r");
-            break;
-        default: 		/* any other character*/
-            sprintf (res, "%c", c);
-    }
-    return (res);
+{ static char res[3];
+
+	switch (c) {
+	  case 0x8:		/* backspace */
+					sprintf (res, "\\b");
+					break;
+	  case 0x9:		/* horizontal tab */
+					sprintf (res, "\\t");
+					break;
+	  case 0x0A:	/* new line */
+					sprintf (res, "\\n");
+					break;
+	  case 0x0C:	/* form feed */
+					sprintf (res, "\\f");
+					break;
+	  case 0x0D:	/* carriage return */
+					sprintf (res, "\\r");
+					break;
+	  default: 		/* any other character*/
+					sprintf (res, "%c", c);
+	}
+	return (res);
 }
 
 
-/* Prints the variable's name and initial contents on the file.
+static void printGlobVar (PSYM psym)
+/* Prints the variable's name and initial contents on the file.  
  * Note: to get to the value of the variable:
  *		com file: prog.Image[operand]
  *		exe file: prog.Image[operand+0x100] 	*/
-static void printGlobVar (std::ostream &ostr,SYM * psym)
-{
-    int j;
-    PROG &prog(Project::get()->prog);
-    uint32_t relocOp = prog.fCOM ? psym->label : psym->label + 0x100;
-
-    switch (psym->size)
-    {
-        case 1:
-            ostr << "uint8_t\t"<<psym->name<<" = "<<prog.Image[relocOp]<<";\n";
-            break;
-        case 2:
-            ostr << "uint16_t\t"<<psym->name<<" = "<<LH(prog.Image+relocOp)<<";\n";
-            break;
-        case 4: if (psym->type == TYPE_PTR)  /* pointer */
-                ostr << "uint16_t *\t"<<psym->name<<" = "<<LH(prog.Image+relocOp)<<";\n";
-            else 			/* char */
-                ostr << "char\t"<<psym->name<<"[4] = \""<<
-                        prog.Image[relocOp]<<prog.Image[relocOp+1]<<
-                        prog.Image[relocOp+2]<<prog.Image[relocOp+3]<<";\n";
-            break;
-        default:
-        {
-            ostringstream strContents;
-            for (j=0; j < psym->size; j++)
-                strContents << cChar(prog.Image[relocOp + j]);
-            ostr << "char\t*"<<psym->name<<" = \""<<strContents.str()<<"\";\n";
-        }
-    }
+{ Int j;
+  dword relocOp = prog.fCOM ? psym->label : psym->label + 0x100;
+  char *strContents;		/* initial contents of variable */
+
+	switch (psym->size) {
+		 case 1: appendStrTab (&cCode.decl, "byte\t%s = %ld;\n",
+				 psym->name, prog.Image[relocOp]);
+				 break;
+		 case 2: appendStrTab (&cCode.decl, "word\t%s = %ld;\n",
+				 psym->name, LH(prog.Image+relocOp));
+				 break;
+		 case 4: if (psym->type == TYPE_PTR)  /* pointer */
+					appendStrTab (&cCode.decl, "word\t*%s = %ld;\n",
+								  psym->name, LH(prog.Image+relocOp));
+				 else 			/* char */
+					appendStrTab (&cCode.decl,
+								"char\t%s[4] = \"%c%c%c%c\";\n",
+								psym->name, prog.Image[relocOp],
+								prog.Image[relocOp+1], prog.Image[relocOp+2],
+								prog.Image[relocOp+3]);
+				 break;
+		 default:strContents = (char *)allocMem((psym->size*2+1) *sizeof(char));
+				 strContents[0] = '\0';
+				 for (j=0; j < psym->size; j++)
+					strcat (strContents, cChar(prog.Image[relocOp + j]));
+				 appendStrTab (&cCode.decl, "char\t*%s = \"%s\";\n",
+								psym->name, strContents);
+	   }
 }
 
 
 // Note: Not called at present.
+static void writeGlobSymTable()
 /* Writes the contents of the symbol table, along with any variable
  * initialization. */
-void Project::writeGlobSymTable()
-{
-    std::ostringstream ostr;
-
-    if (symtab.empty())
-        return;
-    ostr<<"/* Global variables */\n";
-        for (SYM &sym : symtab)
-        {
-            if (sym.duVal.isUSE_VAL())	/* first used */
-            printGlobVar (ostr,&sym);
-            else {					/* first defined */
-                switch (sym.size) {
-                case 1:  ostr<<"uint8_t\t"; break;
-                case 2:  ostr<<"int\t"; break;
-                    case 4:  if (sym.type == TYPE_PTR)
-                        ostr<<"int\t*";
-                        else
-                        ostr<<"char\t*";
-                        break;
-                default: ostr<<"char\t*";
-                }
-            ostr<<sym.name<<";\t/* size = "<<sym.size<<" */\n";
-            }
-        }
-    ostr<< "\n";
-    cCode.appendDecl( ostr.str() );
+{ Int idx;
+  char type[10];
+  PSYM pSym;
+
+	if (symtab.csym) 
+	{
+		appendStrTab (&cCode.decl, "/* Global variables */\n");
+		for (idx = 0; idx < symtab.csym; idx++) 
+		{
+	       pSym = &symtab.sym[idx];
+	       if (symtab.sym[idx].duVal & USEVAL)	/* first used */
+	          printGlobVar (&(symtab.sym[idx]));
+	       else {					/* first defined */
+	          switch (pSym->size) {
+	          case 1:  strcpy (type, "byte\t"); break;
+	          case 2:  strcpy (type, "int\t"); break;
+	          case 4:  if (pSym->type == TYPE_PTR)
+						strcpy (type, "int\t*");
+					   else
+						strcpy (type, "char\t*");
+					   break;
+			  default: strcpy (type, "char\t*");
+			  }
+			  appendStrTab (&cCode.decl, "%s%s;\t/* size = %ld */\n",
+			 				type, pSym->name, pSym->size);
+		   }
+	   }
+	   appendStrTab (&cCode.decl, "\n");
+	}
 }
 
 
+static void writeHeader (FILE *fp, char *fileName)
 /* Writes the header information and global variables to the output C file
  * fp. */
-static void writeHeader (std::ostream &_ios, char *fileName)
+{ 
+	/* Write header information */
+	newBundle (&cCode);
+	appendStrTab (&cCode.decl, "/*\n");
+	appendStrTab (&cCode.decl, " * Input file\t: %s\n", fileName);
+	appendStrTab (&cCode.decl, " * File type\t: %s\n", (prog.fCOM)?"COM":"EXE");
+	appendStrTab (&cCode.decl, " */\n\n#include \"dcc.h\"\n\n"); 
+
+	/* Write global symbol table */
+	/** writeGlobSymTable(); *** need to change them into locident fmt ***/
+	writeBundle (fp, cCode);
+	freeBundle (&cCode); 
+}
+
+
+static void writeBitVector (dword regi)
+/* Writes the registers that are set in the bitvector */
+{ Int j;
+
+    for (j = 0; j < INDEXBASE; j++)
+    {
+        if ((regi & power2(j)) != 0)
+            printf ("%s ", allRegs[j]);
+    }
+}
+
+
+static void emitGotoLabel (PICODE pt, Int indLevel)
+/* Checks the given icode to determine whether it has a label associated
+ * to it.  If so, a goto is emitted to this label; otherwise, a new label
+ * is created and a goto is also emitted.	
+ * Note: this procedure is to be used when the label is to be backpatched
+ *       onto code in cCode.code */
 {
-    PROG &prog(Project::get()->prog);
-    /* Write header information */
-    cCode.init();
-    cCode.appendDecl( "/*\n");
-    cCode.appendDecl( " * Input file\t: %s\n", fileName);
-    cCode.appendDecl( " * File type\t: %s\n", (prog.fCOM)?"COM":"EXE");
-    cCode.appendDecl( " */\n\n#include \"dcc.h\"\n\n");
-
-    /* Write global symbol table */
-    /** writeGlobSymTable(); *** need to change them into locident fmt ***/
-    writeBundle (_ios, cCode);
-    freeBundle (&cCode);
+	if (! (pt->ic.ll.flg & HLL_LABEL)) /* node hasn't got a lab */
+	{
+		/* Generate new label */
+		pt->ic.ll.hllLabNum = getNextLabel();
+		pt->ic.ll.flg |= HLL_LABEL;
+
+		/* Node has been traversed already, so backpatch this label into
+		 * the code */
+		addLabelBundle (&cCode.code, pt->codeIdx, pt->ic.ll.hllLabNum);
+	}
+	appendStrTab (&cCode.code, "%sgoto L%ld;\n", indent(indLevel), 
+				  pt->ic.ll.hllLabNum);
+	stats.numHLIcode++;
 }
 
+
 // Note: Not currently called!
+static void emitFwdGotoLabel (PICODE pt, Int indLevel)
 /* Checks the given icode to determine whether it has a label associated
  * to it.  If so, a goto is emitted to this label; otherwise, a new label
- * is created and a goto is also emitted.
+ * is created and a goto is also emitted.	
  * Note: this procedure is to be used when the label is to be forward on
  *		 the code; that is, the target code has not been traversed yet. */
-static void emitFwdGotoLabel (ICODE * pt, int indLevel)
 {
-    if ( not pt->ll()->testFlags(HLL_LABEL)) /* node hasn't got a lab */
-    {
-        /* Generate new label */
-        pt->ll()->hllLabNum = getNextLabel();
-        pt->ll()->setFlags(HLL_LABEL);
-    }
-    cCode.appendCode( "%sgoto l%ld;\n", indentStr(indLevel), pt->ll()->hllLabNum);
+	if (! (pt->ic.ll.flg & HLL_LABEL)) /* node hasn't got a lab */
+	{
+		/* Generate new label */
+		pt->ic.ll.hllLabNum = getNextLabel();
+		pt->ic.ll.flg |= HLL_LABEL;
+	}
+	appendStrTab (&cCode.code, "%sgoto l%ld;\n", indent(indLevel),
+				  pt->ic.ll.hllLabNum);
 }
 
 
+static void writeBB (PBB pBB, PICODE hli, Int lev, PPROC pProc, Int *numLoc)
+/* Writes the code for the current basic block.
+ * Args: pBB: pointer to the current basic block.
+ *		 Icode: pointer to the array of icodes for current procedure.
+ *		 lev: indentation level - used for formatting.	*/
+{ Int	i, last;
+  char *line;           /* Pointer to the HIGH-LEVEL line   */
+
+	/* Save the index into the code table in case there is a later goto
+	 * into this instruction (first instruction of the BB) */
+	hli[pBB->start].codeIdx = nextBundleIdx (&cCode.code);
+
+	/* Generate code for each hlicode that is not a HLI_JCOND */
+	for (i = pBB->start, last = i + pBB->length; i < last; i++)
+		if ((hli[i].type == HIGH_LEVEL) && (hli[i].invalid == FALSE))
+		{
+			line = write1HlIcode (hli[i].ic.hl, pProc, numLoc);
+			if (line[0] != '\0')
+			{
+				appendStrTab (&cCode.code, "%s%s", indent(lev), line);
+				stats.numHLIcode++;
+			}
+			if (option.verbose)
+				writeDU (&hli[i], i);
+		}
+//if (hli[i].invalid)
+//printf("Invalid icode: %d!\n", hli[i].invalid);
+}
+
+
+static void writeCode (PBB pBB, Int indLevel, PPROC pProc , Int *numLoc,
+					   Int latchNode, Int ifFollow)
+/* Recursive procedure that writes the code for the given procedure, pointed
+ * to by pBB.
+ * Parameters:	pBB:	pointer to the cfg.
+ *				Icode:	pointer to the Icode array for the cfg graph of the
+ *						current procedure.
+ *				indLevel: indentation level - used for formatting.
+ *				numLoc: last # assigned to local variables 				*/
+{
+  Int follow,						/* ifFollow						*/
+      loopType, 					/* Type of loop, if any 		*/ 
+  	  nodeType;						/* Type of node 				*/
+  PBB succ, latch;					/* Successor and latching node 	*/
+  PICODE picode;					/* Pointer to HLI_JCOND instruction	*/
+  char *l;							/* Pointer to HLI_JCOND expression	*/
+  boolT emptyThen,					/* THEN clause is empty			*/
+		repCond;					/* Repeat condition for while() */
+
+	/* Check if this basic block should be analysed */
+	if (!pBB) return;
+	if ((ifFollow != UN_INIT) && (pBB == pProc->dfsLast[ifFollow])) 
+		return;
+
+	if (pBB->traversed == DFS_ALPHA)
+		return;
+	pBB->traversed = DFS_ALPHA;
+
+	/* Check for start of loop */
+	repCond = FALSE;
+	latch = NULL;
+	loopType = pBB->loopType;
+	if (loopType) 
+	{
+		latch = pProc->dfsLast[pBB->latchNode];
+	    switch (loopType) {
+	      case WHILE_TYPE:
+			picode = pProc->Icode.GetIcode(pBB->start + pBB->length - 1);
+
+			/* Check for error in while condition */
+			if (picode->ic.hl.opcode != HLI_JCOND)
+				reportError (WHILE_FAIL);
+
+			/* Check if condition is more than 1 HL instruction */
+			if (pBB->numHlIcodes > 1)
+			{
+				/* Write the code for this basic block */
+				writeBB(pBB, pProc->Icode.GetFirstIcode(), indLevel, pProc, numLoc);
+				repCond = TRUE;
+			}
+
+			/* Condition needs to be inverted if the loop body is along
+			 * the THEN path of the header node */
+			if (pBB->edges[ELSE].BBptr->dfsLastNum == pBB->loopFollow)
+				inverseCondOp (&picode->ic.hl.oper.exp);
+			appendStrTab (&cCode.code, "\n%swhile (%s) {\n", indent(indLevel), 
+						walkCondExpr (picode->ic.hl.oper.exp, pProc, numLoc));
+			invalidateIcode (picode);
+			break;
+
+		  case REPEAT_TYPE:
+			appendStrTab (&cCode.code, "\n%sdo {\n", indent(indLevel));
+			picode = pProc->Icode.GetIcode(latch->start+latch->length-1);
+			invalidateIcode (picode);
+			break;
+
+		  case ENDLESS_TYPE:
+			appendStrTab (&cCode.code, "\n%sfor (;;) {\n", indent(indLevel));
+	    }
+		stats.numHLIcode += 1;
+	    indLevel++;
+	}
+
+	/* Write the code for this basic block */
+	if (repCond == FALSE)
+		writeBB (pBB, pProc->Icode.GetFirstIcode(), indLevel, pProc, numLoc);
+
+	/* Check for end of path */
+	nodeType = pBB->nodeType;
+	if (nodeType == RETURN_NODE || nodeType == TERMINATE_NODE ||
+	    nodeType == NOWHERE_NODE || (pBB->dfsLastNum == latchNode))
+		return;
+
+	/* Check type of loop/node and process code */
+	if (loopType)	/* there is a loop */
+	{
+		if (pBB != latch)		/* loop is over several bbs */
+		{
+			if (loopType == WHILE_TYPE)
+			{
+				succ = pBB->edges[THEN].BBptr;
+				if (succ->dfsLastNum == pBB->loopFollow)
+					succ = pBB->edges[ELSE].BBptr;
+			}
+			else
+				succ = pBB->edges[0].BBptr;
+			if (succ->traversed != DFS_ALPHA)
+				writeCode (succ, indLevel, pProc, numLoc, latch->dfsLastNum, 
+						   ifFollow);
+			else	/* has been traversed so we need a goto */
+				emitGotoLabel (pProc->Icode.GetIcode(succ->start), indLevel);
+		}
+
+		/* Loop epilogue: generate the loop trailer */
+		indLevel--;
+		if (loopType == WHILE_TYPE)
+		{
+			/* Check if there is need to repeat other statements involved
+			 * in while condition, then, emit the loop trailer */
+			if (repCond)
+				writeBB (pBB, pProc->Icode.GetFirstIcode(), indLevel+1, pProc, numLoc); 
+			appendStrTab (&cCode.code, "%s}	/* end of while */\n",
+					indent(indLevel));
+		}
+		else if (loopType == ENDLESS_TYPE)
+			appendStrTab (&cCode.code, "%s}	/* end of loop */\n",
+				indent(indLevel));
+		else if (loopType == REPEAT_TYPE) 
+		{
+			if (picode->ic.hl.opcode != HLI_JCOND)
+				reportError (REPEAT_FAIL);
+		   	appendStrTab (&cCode.code, "%s} while (%s);\n", indent(indLevel),
+				walkCondExpr (picode->ic.hl.oper.exp, pProc, numLoc));
+		}
+
+		/* Recurse on the loop follow */
+		if (pBB->loopFollow != MAX) 
+		{
+			succ = pProc->dfsLast[pBB->loopFollow];
+			if (succ->traversed != DFS_ALPHA)
+				writeCode (succ, indLevel, pProc, numLoc, latchNode, ifFollow);
+			else		/* has been traversed so we need a goto */
+				emitGotoLabel (pProc->Icode.GetIcode(succ->start), indLevel);
+		}
+	}
+
+	else		/* no loop, process nodeType of the graph */
+	{
+		if (nodeType == TWO_BRANCH)		/* if-then[-else] */
+		{
+		  stats.numHLIcode++;
+		  indLevel++;
+		  emptyThen = FALSE;
+
+		  if (pBB->ifFollow != MAX)		/* there is a follow */
+		  {
+			/* process the THEN part */
+			follow = pBB->ifFollow;
+			succ = pBB->edges[THEN].BBptr;
+			if (succ->traversed != DFS_ALPHA)	/* not visited */
+			{
+				if (succ->dfsLastNum != follow)	/* THEN part */
+				{
+					l = writeJcond (
+						pProc->Icode.GetIcode(pBB->start + pBB->length -1)->ic.hl, 
+						pProc, numLoc);
+					appendStrTab (&cCode.code, "\n%s%s", indent(indLevel-1), l);
+					writeCode (succ, indLevel, pProc, numLoc, latchNode, 
+							   follow); 
+				}
+				else		/* empty THEN part => negate ELSE part */
+				{
+					l = writeJcondInv (
+						pProc->Icode.GetIcode(pBB->start + pBB->length -1)->ic.hl, 
+						pProc, numLoc);
+					appendStrTab (&cCode.code, "\n%s%s", indent(indLevel-1), l);
+					writeCode (pBB->edges[ELSE].BBptr, indLevel, pProc, numLoc,
+							   latchNode, follow); 
+					emptyThen = TRUE;
+				}
+			}
+			else	/* already visited => emit label */
+				emitGotoLabel (pProc->Icode.GetIcode(succ->start), indLevel);
+
+			/* process the ELSE part */
+			succ = pBB->edges[ELSE].BBptr;
+			if (succ->traversed != DFS_ALPHA)		/* not visited */
+			{
+				if (succ->dfsLastNum != follow)		/* ELSE part */
+				{
+					appendStrTab (&cCode.code, "%s}\n%selse {\n",
+								  indent(indLevel-1), indent(indLevel - 1));
+					writeCode (succ, indLevel, pProc, numLoc, latchNode, 
+							   follow); 
+				}
+				/* else (empty ELSE part) */
+			}
+			else if (! emptyThen) 	/* already visited => emit label */
+			{
+				appendStrTab (&cCode.code, "%s}\n%selse {\n",
+							  indent(indLevel-1), indent(indLevel - 1));
+				emitGotoLabel (pProc->Icode.GetIcode(succ->start), indLevel);
+			}
+			appendStrTab (&cCode.code, "%s}\n", indent(--indLevel));
+
+			/* Continue with the follow */
+			succ = pProc->dfsLast[follow];
+			if (succ->traversed != DFS_ALPHA)
+				writeCode (succ, indLevel, pProc, numLoc, latchNode, 
+						   ifFollow);
+		  }
+		  else		/* no follow => if..then..else */
+		  {
+			l = writeJcond (
+					pProc->Icode.GetIcode(pBB->start + pBB->length -1)->ic.hl, 
+					pProc, numLoc);
+			appendStrTab (&cCode.code, "%s%s", indent(indLevel-1), l);
+			writeCode (pBB->edges[THEN].BBptr, indLevel, pProc, numLoc, 
+					   latchNode, ifFollow); 
+			appendStrTab (&cCode.code, "%s}\n%selse {\n", indent(indLevel-1), 
+						  indent(indLevel - 1));
+			writeCode (pBB->edges[ELSE].BBptr, indLevel, pProc, numLoc, 
+					   latchNode, ifFollow); 
+			appendStrTab (&cCode.code, "%s}\n", indent(--indLevel));
+		  }
+		}
+
+		else 	/* fall, call, 1w */
+		{
+			succ = pBB->edges[0].BBptr;		/* fall-through edge */
+			if (succ->traversed != DFS_ALPHA)
+			   writeCode (succ, indLevel, pProc,numLoc, latchNode,ifFollow);
+		}
+	}
+}
+
+
+static void codeGen (PPROC pProc, FILE *fp)
 /* Writes the procedure's declaration (including arguments), local variables,
  * and invokes the procedure that writes the code of the given record *hli */
-void Function::codeGen (std::ostream &fs)
-{
-    int numLoc;
-    ostringstream ostr;
-    //STKFRAME * args;       /* Procedure arguments              */
-    //char buf[200],        /* Procedure's definition           */
-    //        arg[30];         /* One argument                     */
-    BB *pBB;              /* Pointer to basic block           */
+{ Int i, numLoc;
+  PSTKFRAME args;       /* Procedure arguments              */
+  char buf[200],        /* Procedure's definition           */
+       arg[30];         /* One argument                     */
+  ID *locid;            /* Pointer to one local identifier  */
+  BB *pBB;              /* Pointer to basic block           */
 
     /* Write procedure/function header */
-    cCode.init();
-    if (flg & PROC_IS_FUNC)      /* Function */
-        ostr<< "\n"<<TypeContainer::typeName(retVal.type)<<" "<<name<<" (";
+	newBundle (&cCode);
+    if (pProc->flg & PROC_IS_FUNC)      /* Function */
+		appendStrTab (&cCode.decl, "\n%s %s (", hlTypes[pProc->retVal.type], 
+					  pProc->name);
     else                                /* Procedure */
-        ostr<< "\nvoid "<<name<<" (";
+        appendStrTab (&cCode.decl, "\nvoid %s (", pProc->name);
 
     /* Write arguments */
-    for (size_t i = 0; i < args.size(); i++)
+    args = &pProc->args;
+	memset (buf, 0, sizeof(buf));
+    for (i = 0; i < args->csym; i++)
     {
-        if ( args[i].invalid )
-            continue;
-        ostr<<hlTypes[args[i].type]<<" "<<args[i].name;
-        if (i < (args.size() - 1))
-            ostr<<", ";
+		if (args->sym[i].invalid == FALSE)
+		{
+			sprintf (arg,"%s %s",hlTypes[args->sym[i].type], args->sym[i].name);
+        	strcat (buf, arg);
+        	if (i < (args->numArgs - 1))
+            	strcat (buf, ", ");
+		}
     }
-    ostr<<")\n";
+    strcat (buf, ")\n");
+    appendStrTab (&cCode.decl, "%s", buf);
 
-    /* Write comments */
-    writeProcComments( ostr );
+	/* Write comments */
+	writeProcComments (pProc, &cCode.decl);
 
     /* Write local variables */
-    if (! (flg & PROC_ASM))
-    {
-        numLoc = 0;
-        for (ID &refId : localId )
-        {
-            /* Output only non-invalidated entries */
-            if ( refId.illegal )
-                continue;
-            if (refId.loc == REG_FRAME)
-            {
-                /* Register variables are assigned to a local variable */
-                if (((flg & SI_REGVAR) && (refId.id.regi == rSI)) ||
-                        ((flg & DI_REGVAR) && (refId.id.regi == rDI)))
-                {
-                    refId.setLocalName(++numLoc);
-                    ostr << "int "<<refId.name<<";\n";
-                }
-                /* Other registers are named when they are first used in
-                     * the output C code, and appended to the proc decl. */
-            }
-            else if (refId.loc == STK_FRAME)
-            {
-                /* Name local variables and output appropriate type */
-                    refId.setLocalName(++numLoc);
-                ostr << TypeContainer::typeName(refId.type)<<" "<<refId.name<<";\n";
-            }
-        }
-    }
-    fs<<ostr.str();
+	if (! (pProc->flg & PROC_ASM))
+	{
+    	locid = &pProc->localId.id[0];
+    	numLoc = 0;
+    	for (i = 0; i < pProc->localId.csym; i++, locid++)
+    	{
+        	/* Output only non-invalidated entries */   
+        	if (locid->illegal == FALSE)
+        	{
+            	if (locid->loc == REG_FRAME)
+            	{
+                	/* Register variables are assigned to a local variable */
+                	if (((pProc->flg & SI_REGVAR) && (locid->id.regi == rSI)) ||
+                    	((pProc->flg & DI_REGVAR) && (locid->id.regi == rDI)))
+                	{
+                		sprintf (locid->name, "loc%ld", ++numLoc);
+                    	appendStrTab (&cCode.decl, "int %s;\n", locid->name);
+                	}
+					/* Other registers are named when they are first used in
+				  	 * the output C code, and appended to the proc decl. */
+            	}
+
+            	else if (locid->loc == STK_FRAME)
+            	{
+                	/* Name local variables and output appropriate type */
+                	sprintf (locid->name, "loc%ld", ++numLoc);
+					appendStrTab (&cCode.decl, "%s %s;\n", 
+								  hlTypes[locid->type], locid->name);
+            	}
+        	}
+    	}
+	}
     /* Write procedure's code */
-    if (flg & PROC_ASM)		/* generate assembler */
-    {
-        Disassembler ds(3);
-        ds.disassem(this);
-    }
-    else							/* generate C */
-    {
-        m_cfg.front()->writeCode (1, this, &numLoc, MAX, UN_INIT);
-    }
+	if (pProc->flg & PROC_ASM)		/* generate assembler */
+		disassem (3, pProc);
+	else							/* generate C */
+		writeCode (pProc->cfg, 1, pProc, &numLoc, MAX, UN_INIT);
 
-    cCode.appendCode( "}\n\n");
-    writeBundle (fs, cCode);
-    freeBundle (&cCode);
+	appendStrTab (&cCode.code, "}\n\n");
+	writeBundle (fp, cCode);
+	freeBundle (&cCode);
 
     /* Write Live register analysis information */
-    if (option.verbose)
-        for (size_t i = 0; i < numBBs; i++)
-        {
-            pBB = m_dfsLast[i];
-            if (pBB->flg & INVALID_BB)	continue;	/* skip invalid BBs */
-            cout << "BB "<<i<<"\n";
-            cout << "  Start = "<<pBB->begin()->loc_ip;
-            cout << ", end = "<<pBB->begin()->loc_ip+pBB->size()<<"\n";
-            cout << "  LiveUse = ";
-            Machine_X86::writeRegVector(cout,pBB->liveUse);
-            cout << "\n  Def = ";
-            Machine_X86::writeRegVector(cout,pBB->def);
-            cout << "\n  LiveOut = ";
-            Machine_X86::writeRegVector(cout,pBB->liveOut);
-            cout << "\n  LiveIn = ";
-            Machine_X86::writeRegVector(cout,pBB->liveIn);
-            cout <<"\n\n";
-        }
+	if (option.verbose) 
+    	for (i = 0; i < pProc->numBBs; i++)
+    	{
+        	pBB = pProc->dfsLast[i];
+			if (pBB->flg & INVALID_BB)	continue;	/* skip invalid BBs */
+        	printf ("BB %d\n", i);
+			printf ("  Start = %d, end = %d\n", pBB->start, pBB->start + 
+					pBB->length - 1);
+        	printf ("  LiveUse = ");
+        	writeBitVector (pBB->liveUse);
+        	printf ("\n  Def = ");
+        	writeBitVector (pBB->def);
+        	printf ("\n  LiveOut = ");
+        	writeBitVector (pBB->liveOut);
+        	printf ("\n  LiveIn = ");
+        	writeBitVector (pBB->liveIn);
+        	printf ("\n\n");
+    	}
 }
 
 
+static void backBackEnd (char *filename, PCALL_GRAPH pcallGraph, FILE *fp)
 /* Recursive procedure. Displays the procedure's code in depth-first order
  * of the call graph.	*/
-static void backBackEnd (char *filename, CALL_GRAPH * pcallGraph, std::ostream &_ios)
-{
-
-    //	IFace.Yield();			/* This is a good place to yield to other apps */
-
-    /* Check if this procedure has been processed already */
-    if ((pcallGraph->proc->flg & PROC_OUTPUT) ||
-        (pcallGraph->proc->flg & PROC_ISLIB))
-        return;
-    pcallGraph->proc->flg |= PROC_OUTPUT;
-
-    /* Dfs if this procedure has any successors */
-    for (size_t i = 0; i < pcallGraph->outEdges.size(); i++)
-    {
-        backBackEnd (filename, pcallGraph->outEdges[i], _ios);
-    }
-
-    /* Generate code for this procedure */
-    stats.numLLIcode = pcallGraph->proc->Icode.size();
-    stats.numHLIcode = 0;
-    pcallGraph->proc->codeGen (_ios);
-
-    /* Generate statistics */
-    if (option.Stats)
-        pcallGraph->proc->displayStats ();
-    if (! (pcallGraph->proc->flg & PROC_ASM))
-    {
-        stats.totalLL += stats.numLLIcode;
-        stats.totalHL += stats.numHLIcode;
-    }
+{ Int i;
+
+//	IFace.Yield();			/* This is a good place to yield to other apps */
+
+	/* Check if this procedure has been processed already */
+	if ((pcallGraph->proc->flg & PROC_OUTPUT) || 
+		(pcallGraph->proc->flg & PROC_ISLIB))
+		return;
+	pcallGraph->proc->flg |= PROC_OUTPUT;
+
+	/* Dfs if this procedure has any successors */
+	if (pcallGraph->numOutEdges > 0)
+	{
+		for (i = 0; i < pcallGraph->numOutEdges; i++)
+		{
+			backBackEnd (filename, pcallGraph->outEdges[i], fp);
+		}
+	}
+
+	/* Generate code for this procedure */
+	stats.numLLIcode = pcallGraph->proc->Icode.GetNumIcodes();
+	stats.numHLIcode = 0;
+	codeGen (pcallGraph->proc, fp);
+
+	/* Generate statistics */
+	if (option.Stats)
+		displayStats (pcallGraph->proc);
+	if (! (pcallGraph->proc->flg & PROC_ASM))
+	{
+		stats.totalLL += stats.numLLIcode;
+		stats.totalHL += stats.numHLIcode;
+	}
 }
 
 
+void BackEnd (char *fileName, PCALL_GRAPH pcallGraph)
 /* Invokes the necessary routines to produce code one procedure at a time. */
-void BackEnd (char *fileName, CALL_GRAPH * pcallGraph)
 {
-    std::ofstream fs; /* Output C file 	*/
-
-    /* Get output file name */
-    std::string outNam(fileName);
-    outNam = outNam.substr(0,outNam.rfind("."))+".b"; /* b for beta */
-
-    /* Open output file */
-    fs.open(outNam);
-    if(!fs.is_open())
-        fatalError (CANNOT_OPEN, outNam.c_str());
-    printf ("dcc: Writing C beta file %s\n", outNam.c_str());
-
-    /* Header information */
-    writeHeader (fs, fileName);
-
-    /* Initialize total Icode instructions statistics */
-    stats.totalLL = 0;
-    stats.totalHL = 0;
-
-    /* Process each procedure at a time */
-    backBackEnd (fileName, pcallGraph, fs);
-
-    /* Close output file */
-    fs.close();
-    printf ("dcc: Finished writing C beta file\n");
+ 	char*	outName, *ext;
+	FILE*	fp;				/* Output C file 	*/
+
+	/* Get output file name */
+	outName = strcpy ((char*)allocMem(strlen(fileName)+1), fileName);
+	if ((ext = strrchr (outName, '.')) != NULL)
+	   *ext = '\0';
+	strcat (outName, ".b");		/* b for beta */
+
+	/* Open output file */
+	fp = fopen (outName, "wt");
+	if (!fp)
+	   fatalError (CANNOT_OPEN, outName);
+	printf ("dcc: Writing C beta file %s\n", outName);
+
+	/* Header information */
+	writeHeader (fp, fileName);
+
+	/* Initialize total Icode instructions statistics */
+	stats.totalLL = 0;
+	stats.totalHL = 0;
+
+	/* Process each procedure at a time */
+	backBackEnd (fileName, pcallGraph, fp);
+
+	/* Close output file */
+	fclose (fp);
+	printf ("dcc: Finished writing C beta file\n");
 }
 
 

+ 71 - 53
src/bundle.cpp

@@ -6,89 +6,107 @@
 
 #include "dcc.h"
 #include <stdarg.h>
-#include <iostream>
 #include <memory.h>
 #include <stdlib.h>
 #include <string.h>
 
 #define deltaProcLines  20
 
-using namespace std;
-/* Allocates memory for a new bundle and initializes it to zero.    */
-
 
-/* Adds the given label to the start of the line strTab[idx].  The first
- * tab is removed and replaced by this label */
-void strTable::addLabelBundle (int idx, int label)
+void newBundle (bundle *procCode)
+/* Allocates memory for a new bundle and initializes it to zero.    */
 {
-    char s[16];
-    sprintf (s, "l%d: ", label);
-    if(at(idx).size()<4)
-        at(idx)=s;
-    else
-        at(idx) = string(s)+at(idx).substr(4);
+    memset (&(procCode->decl), 0, sizeof(strTable));
+    memset (&(procCode->code), 0, sizeof(strTable));
 }
 
 
-/* Writes the contents of the string table on the file fp.  */
-static void writeStrTab (std::ostream &ios, strTable &strTab)
+static void incTableSize (strTable *strTab)
+/* Increments the size of the table strTab by deltaProcLines and copies all 
+ * the strings to the new table.        */
 {
-    for (size_t i = 0; i < strTab.size(); i++)
-        ios << strTab[i];
+    strTab->allocLines += deltaProcLines;
+	strTab->str = (char**)reallocVar (strTab->str, strTab->allocLines*sizeof(char *));
+	memset (&strTab->str[strTab->allocLines - deltaProcLines], 0,
+    		deltaProcLines * sizeof(char *));
 }
 
 
-/* Writes the contents of the bundle (procedure code and declaration) to
- * a file.          */
-void writeBundle (std::ostream &ios, bundle procCode)
-{
-    writeStrTab (ios, procCode.decl);
-    writeStrTab (ios, procCode.code);
+void appendStrTab (strTable *strTab, char *format, ...) 
+/* Appends the new line (in printf style) to the string table strTab.   */
+{  va_list args;
+
+    va_start (args, format);
+    if (strTab->numLines == strTab->allocLines)
+    {
+        incTableSize (strTab);
+    }
+    strTab->str[strTab->numLines] = (char *)malloc(lineSize * sizeof(char));
+    if (strTab->str == NULL)
+    {
+        fatalError(MALLOC_FAILED, lineSize * sizeof(char));
+    }
+    vsprintf (strTab->str[strTab->numLines], format, args); 
+    strTab->numLines++;
+    va_end (args);
 }
 
 
-/* Frees the storage allocated by the string table. */
-static void freeStrTab (strTable &strTab)
+Int nextBundleIdx (strTable *strTab)
+/* Returns the next available index into the table */
 {
-    strTab.clear();
+	return (strTab->numLines);
 }
 
 
-/* Deallocates the space taken by the bundle procCode */
-void freeBundle (bundle *procCode)
-{
-    freeStrTab (procCode->decl);
-    freeStrTab (procCode->code);
-}
+void addLabelBundle (strTable *strTab, Int idx, Int label)
+/* Adds the given label to the start of the line strTab[idx].  The first
+ * tab is removed and replaced by this label */
+{ char s[lineSize];
 
-void bundle::appendCode(const char *format,...)
-{
-    va_list args;
-    char buf[lineSize]={0};
-    va_start (args, format);
-    vsprintf (buf, format, args);
-    code.push_back(buf);
-    va_end (args);
+	sprintf (s, "l%ld: %s", label, &strTab->str[idx][4]);
+	strcpy (strTab->str[idx], s);
 }
-void bundle::appendCode(const std::string &s)
-{
-    code.push_back(s);
+
+
+static void writeStrTab (FILE *fp, strTable strTab)
+/* Writes the contents of the string table on the file fp.  */
+{ Int i;
+
+    for (i = 0; i < strTab.numLines; i++)
+        fprintf (fp, "%s", strTab.str[i]); 
 }
 
-void bundle::appendDecl(const char *format,...)
+
+void writeBundle (FILE *fp, bundle procCode)
+/* Writes the contents of the bundle (procedure code and declaration) to
+ * a file.          */
 {
-    va_list args;
-    char buf[lineSize]={0};
-    va_start (args, format);
-    vsprintf (buf, format, args);
-    decl.push_back(buf);
-    va_end (args);
+    writeStrTab (fp, procCode.decl);
+    if (procCode.decl.str[procCode.decl.numLines - 1][0] != ' ')
+       fprintf (fp, "\n");
+    writeStrTab (fp, procCode.code);
 }
 
-void bundle::appendDecl(const std::string &v)
-{
-    decl.push_back(v);
+
+static void freeStrTab (strTable *strTab)
+/* Frees the storage allocated by the string table. */
+{ Int i;
+
+    if (strTab->allocLines > 0)  {
+       for (i = 0; i < strTab->numLines; i++)
+         free (strTab->str[i]); 
+       free (strTab->str);
+       memset (strTab, 0, sizeof(strTable));
+    }
 }
 
 
+void freeBundle (bundle *procCode)
+/* Deallocates the space taken by the bundle procCode */
+{ 
+    freeStrTab (&(procCode->decl));
+    freeStrTab (&(procCode->code));
+}
+
 

File diff suppressed because it is too large
+ 316 - 318
src/chklib.cpp


+ 235 - 251
src/comwrite.cpp

@@ -7,274 +7,258 @@
  ****************************************************************************/
 
 #include "dcc.h"
-#include "machine_x86.h"
 #include <string.h>
-#include <sstream>
-using namespace std;
 #define intSize		40
 
-static const char *int21h[] =
-{
-    "Terminate process",
-    "Character input with echo",
-    "Character output",
-    "Auxiliary input",
-    "Auxiliary output",
-    "Printer output",
-    "Direct console i/o",
-    "Unfiltered char i w/o echo",
-    "Character input without echo",
-    "Display string",
-    "Buffered keyboard input",
-    "Check input status",
-    "Flush input buffer and then input",
-    "Disk reset",
-    "Select disk",
-    "Open file",
-    "Close file",
-    "Find first file",
-    "Find next file",
-    "Delete file",
-    "Sequential read",
-    "Sequential write",
-    "Create file",
-    "Rename file",
-    "Reserved",
-    "Get current disk",
-    "Set DTA address",
-    "Get default drive data",
-    "Get drive data",
-    "Reserved",
-    "Reserved",
-    "Reserved",
-    "Reserved",
-    "Random read",
-    "Random write",
-    "Get file size",
-    "Set relative record number",
-    "Set interrupt vector",
-    "Create new PSP",
-    "Random block read",
-    "Random block write",
-    "Parse filename",
-    "Get date",
-    "Set date",
-    "Get time",
-    "Set time",
-    "Set verify flag",
-    "Get DTA address",
-    "Get MSDOS version number",
-    "Terminate and stay resident",
-    "Reserved",
-    "Get or set break flag",
-    "Reserved",
-    "Get interrupt vector",
-    "Get drive allocation info",
-    "Reserved",
-    "Get or set country info",
-    "Create directory",
-    "Delete directory",
-    "Set current directory",
-    "Create file",
-    "Open file",
-    "Close file",
-    "Read file or device",
-    "Write file or device",
-    "Delete file",
-    "Set file pointer",
-    "Get or set file attributes",
-    "IOCTL (i/o control)",
-    "Duplicate handle",
-    "Redirect handle",
-    "Get current directory",
-    "Alloate memory block",
-    "Release memory block",
-    "Resize memory block",
-    "Execute program (exec)",
-    "Terminate process with return code",
-    "Get return code",
-    "Find first file",
-    "Find next file",
-    "Reserved",
-    "Reserved",
-    "Reserved",
-    "Reserved",
-    "Get verify flag",
-    "Reserved",
-    "Rename file",
-    "Get or set file date & time",
-    "Get or set allocation strategy",
-    "Get extended error information",
-    "Create temporary file",
-    "Create new file",
-    "Lock or unlock file region",
-    "Reserved",
-    "Get machine name",
-    "Device redirection",
-    "Reserved",
-    "Reserved",
-    "Get PSP address",
-    "Get DBCS lead uint8_t table",
-    "Reserved",
-    "Get extended country information",
-    "Get or set code page",
-    "Set handle count",
-    "Commit file",
-    "Reserved",
-    "Reserved",
-    "Reserved",
-    "Extended open file"
+static char *int21h[] =
+       {"Terminate process",
+	"Character input with echo",
+	"Character output",
+	"Auxiliary input",
+	"Auxiliary output",
+	"Printer output",
+	"Direct console i/o",
+	"Unfiltered char i w/o echo",
+	"Character input without echo",
+	"Display string",
+	"Buffered keyboard input",
+	"Check input status",
+	"Flush input buffer and then input",
+	"Disk reset",
+	"Select disk",
+	"Open file",
+	"Close file",
+	"Find first file",
+	"Find next file",
+	"Delete file",
+	"Sequential read",
+	"Sequential write",
+	"Create file",
+	"Rename file",
+	"Reserved",
+	"Get current disk",
+	"Set DTA address",
+	"Get default drive data",
+	"Get drive data",
+	"Reserved",
+	"Reserved",
+	"Reserved",
+	"Reserved",
+	"Random read",
+	"Random write",
+	"Get file size",
+	"Set relative record number",
+	"Set interrupt vector",
+	"Create new PSP",
+	"Random block read",
+	"Random block write",
+	"Parse filename",
+	"Get date",
+	"Set date",
+	"Get time",
+	"Set time",
+	"Set verify flag",
+	"Get DTA address",
+	"Get MSDOS version number",
+	"Terminate and stay resident",
+	"Reserved",
+	"Get or set break flag",
+	"Reserved",
+	"Get interrupt vector",
+	"Get drive allocation info",
+	"Reserved",
+	"Get or set country info",
+	"Create directory",
+	"Delete directory",
+	"Set current directory",
+	"Create file",
+	"Open file",
+	"Close file",
+	"Read file or device",
+	"Write file or device",
+	"Delete file",
+	"Set file pointer",
+	"Get or set file attributes",
+	"IOCTL (i/o control)",
+	"Duplicate handle",
+	"Redirect handle",
+	"Get current directory",
+	"Alloate memory block",
+	"Release memory block",
+	"Resize memory block",
+	"Execute program (exec)",
+	"Terminate process with return code",
+	"Get return code",
+	"Find first file",
+	"Find next file",
+	"Reserved",
+	"Reserved",
+	"Reserved",
+	"Reserved",
+	"Get verify flag",
+	"Reserved",
+	"Rename file",
+	"Get or set file date & time",
+	"Get or set allocation strategy",
+	"Get extended error information",
+	"Create temporary file",
+	"Create new file",
+	"Lock or unlock file region",
+	"Reserved",
+	"Get machine name",
+	"Device redirection",
+	"Reserved",
+	"Reserved",
+	"Get PSP address",
+	"Get DBCS lead byte table",
+	"Reserved",
+	"Get extended country information",
+	"Get or set code page",
+	"Set handle count",
+	"Commit file",
+	"Reserved",
+	"Reserved",
+	"Reserved",
+	"Extended open file"
 };
 
 
-static const char *intOthers[] = {
-    "Exit",					/* 0x20 */
-    "",					/* other table */
-    "Terminate handler address",		/* 0x22 */
-    "Ctrl-C handler address",		/* 0x23 */
-    "Critical-error handler address",	/* 0x24 */
-    "Absolute disk read",			/* 0x25 */
-    "Absolute disk write",			/* 0x26 */
-    "Terminate and stay resident",		/* 0x27 */
-    "Reserved",				/* 0x28 */
-    "Reserved",				/* 0x29 */
-    "Reserved",				/* 0x2A */
-    "Reserved",				/* 0x2B */
-    "Reserved",				/* 0x2C */
-    "Reserved",				/* 0x2D */
-    "Reserved"				/* 0x2E */
+static char *intOthers[] = {
+	"Exit",					/* 0x20 */
+	"",					/* other table */
+	"Terminate handler address",		/* 0x22 */
+	"Ctrl-C handler address",		/* 0x23 */
+	"Critical-error handler address",	/* 0x24 */
+	"Absolute disk read",			/* 0x25 */
+	"Absolute disk write",			/* 0x26 */
+	"Terminate and stay resident",		/* 0x27 */
+	"Reserved",				/* 0x28 */
+	"Reserved",				/* 0x29 */
+	"Reserved",				/* 0x2A */
+	"Reserved",				/* 0x2B */
+	"Reserved",				/* 0x2C */
+	"Reserved",				/* 0x2D */
+	"Reserved"				/* 0x2E */
 };
 
 
-/* Writes the description of the current interrupt. Appends it to the
+void writeIntComment (PICODE icode, char *s)
+/* Writes the description of the current interrupt. Appends it to the 
  * string s.	*/
-void LLInst::writeIntComment (std::ostringstream &s)
-{
-    uint32_t src_immed=src().getImm2();
-    s<<"\t/* ";
-    if (src_immed == 0x21)
-    {
-        s <<int21h[dst.off];
-    }
-    else if (src_immed > 0x1F && src_immed < 0x2F)
-    {
-        s <<intOthers[src_immed - 0x20];
-    }
-    else if (src_immed == 0x2F)
-    {
-        switch (dst.off)
-        {
-            case 0x01 :
-                s << "Print spooler";
-                break;
-            case 0x02:
-                s << "Assign";
-                break;
-            case 0x10:
-                s << "Share";
-                break;
-            case 0xB7:
-                s << "Append";
-        }
-    }
-    else
-        s<<"Unknown int";
-    s<<" */\n";
-}
-
+{ char *t;
 
-//, &cCode.decl
-void Function::writeProcComments()
-{
-    std::ostringstream ostr;
-    writeProcComments(ostr);
-    cCode.appendDecl(ostr.str());
+	t = (char *)allocMem(intSize * sizeof(char));
+	if (icode->ic.ll.immed.op == 0x21)
+	{  sprintf (t, "\t/* %s */\n", int21h[icode->ic.ll.dst.off]);
+	   strcat (s, t);
+	}
+	else if (icode->ic.ll.immed.op > 0x1F && icode->ic.ll.immed.op < 0x2F)
+	{
+	   sprintf (t, "\t/* %s */\n", intOthers[icode->ic.ll.immed.op - 0x20]);
+	   strcat (s, t);
+    }
+	else if (icode->ic.ll.immed.op == 0x2F)
+	   switch (icode->ic.ll.dst.off) {
+		case 0x01 : strcat (s, "\t/* Print spooler */\n");
+			break;
+		case 0x02:  strcat (s, "\t/* Assign */\n");
+			break;
+		case 0x10:  strcat (s, "\t/* Share */\n");
+			break;
+		case 0xB7:  strcat (s, "\t/* Append */\n");
+	   }
+	else
+	   strcat (s, "\n");
 }
 
-void Function::writeProcComments(std::ostream &ostr)
-{
-    int i;
-    ID *id;			/* Pointer to register argument identifier */
-    STKSYM * psym;		/* Pointer to register argument symbol */
 
-    /* About the parameters */
-    if (this->cbParam)
-        ostr << "/* Takes "<<this->cbParam<<" bytes of parameters.\n";
-    else if (this->flg & REG_ARGS)
-    {
-        ostr << "/* Uses register arguments:\n";
-        for (i = 0; i < this->args.numArgs; i++)
-        {
-            psym = &this->args[i];
-            ostr << " *     "<<psym->name<<" = ";
-            if (psym->regs->expr.ident.idType == REGISTER)
-            {
-                id = &this->localId.id_arr[psym->regs->expr.ident.idNode.regiIdx];
-                ostr << Machine_X86::regName(id->id.regi);
-            }
-            else		/* long register */
-            {
-                id = &this->localId.id_arr[psym->regs->expr.ident.idNode.longIdx];
-                ostr << Machine_X86::regName(id->id.longId.h) << ":";
-                ostr << Machine_X86::regName(id->id.longId.l);
-            }
-            ostr << ".\n";
+void writeProcComments (PPROC p, strTable *strTab)
+{ int i;
+  ID *id;			/* Pointer to register argument identifier */
+  PSTKSYM psym;		/* Pointer to register argument symbol */
 
-        }
-    }
-    else
-        ostr << "/* Takes no parameters.\n";
+	/* About the parameters */
+	if (p->cbParam)	
+		appendStrTab (strTab, "/* Takes %d bytes of parameters.\n",
+			p->cbParam);
+	else if (p->flg & REG_ARGS)
+	{
+		appendStrTab (strTab, "/* Uses register arguments:\n");
+		for (i = 0; i < p->args.numArgs; i++)
+		{
+			psym = &p->args.sym[i];
+			if (psym->regs->expr.ident.idType == REGISTER)
+			{
+				id = &p->localId.id[psym->regs->expr.ident.idNode.regiIdx];
+				if (psym->regs->expr.ident.regiType == WORD_REG)
+					appendStrTab (strTab, " *     %s = %s.\n", psym->name, 
+								  wordReg[id->id.regi - rAX]);	
+				else		/* BYTE_REG */
+					appendStrTab (strTab, " *     %s = %s.\n", psym->name, 
+								  byteReg[id->id.regi - rAL]);	
+			}
+			else		/* long register */
+			{
+				id = &p->localId.id[psym->regs->expr.ident.idNode.longIdx];
+				appendStrTab (strTab, " *     %s = %s:%s.\n", psym->name, 
+							  wordReg[id->id.longId.h - rAX],
+							  wordReg[id->id.longId.l - rAX]);
+			}
+			
+		}
+	}
+	else
+		appendStrTab (strTab, "/* Takes no parameters.\n");
 
-    /* Type of procedure */
-    if (this->flg & PROC_RUNTIME)
-        ostr << " * Runtime support routine of the compiler.\n";
-    if (this->flg & PROC_IS_HLL)
-        ostr << " * High-level language prologue code.\n";
-    if (this->flg & PROC_ASM)
-    {
-        ostr << " * Untranslatable routine.  Assembler provided.\n";
-        if (this->flg & PROC_IS_FUNC)
-            switch (this->retVal.type) { // TODO: Functions return value in various regs
-                case TYPE_BYTE_SIGN: case TYPE_BYTE_UNSIGN:
-                    ostr << " * Return value in register al.\n";
-                    break;
-                case TYPE_WORD_SIGN: case TYPE_WORD_UNSIGN:
-                    ostr << " * Return value in register ax.\n";
-                    break;
-                case TYPE_LONG_SIGN: case TYPE_LONG_UNSIGN:
-                    ostr << " * Return value in registers dx:ax.\n";
-                    break;
-            } /* eos */
-    }
+	/* Type of procedure */
+	if (p->flg & PROC_RUNTIME)
+		appendStrTab (strTab," * Runtime support routine of the compiler.\n");
+	if (p->flg & PROC_IS_HLL) 
+		appendStrTab (strTab," * High-level language prologue code.\n");
+	if (p->flg & PROC_ASM)
+	{
+		appendStrTab (strTab,
+					  " * Untranslatable routine.  Assembler provided.\n");
+		if (p->flg & PROC_IS_FUNC)
+			switch (p->retVal.type) {
+			  case TYPE_BYTE_SIGN: case TYPE_BYTE_UNSIGN:
+				appendStrTab (strTab, " * Return value in register al.\n");
+				break;
+			  case TYPE_WORD_SIGN: case TYPE_WORD_UNSIGN:
+				appendStrTab (strTab, " * Return value in register ax.\n");
+				break;
+			  case TYPE_LONG_SIGN: case TYPE_LONG_UNSIGN:
+				appendStrTab (strTab, " * Return value in registers dx:ax.\n");
+				break;
+			} /* eos */
+	}
 
-    /* Calling convention */
-    if (this->flg & CALL_PASCAL)
-        ostr << " * Pascal calling convention.\n";
-    else if (this->flg & CALL_C)
-        ostr << " * C calling convention.\n";
-    else if (this->flg & CALL_UNKNOWN)
-        ostr << " * Unknown calling convention.\n";
+	/* Calling convention */
+	if (p->flg & CALL_PASCAL)
+		appendStrTab (strTab, " * Pascal calling convention.\n");
+	else if (p->flg & CALL_C)
+		appendStrTab (strTab, " * C calling convention.\n");
+	else if (p->flg & CALL_UNKNOWN)
+		appendStrTab (strTab, " * Unknown calling convention.\n");
 
-    /* Other flags */
-    if (this->flg & (PROC_BADINST | PROC_IJMP))
-    {
-        ostr << " * Incomplete due to an ";
-        if(this->flg & PROC_BADINST)
-            ostr << "untranslated opcode.\n";
-        else
-            ostr << "indirect JMP.\n";
-    }
-    if (this->flg & PROC_ICALL)
-        ostr << " * Indirect call procedure.\n";
-    if (this->flg & IMPURE)
-        ostr << " * Contains impure code.\n";
-    if (this->flg & NOT_HLL)
-        ostr << " * Contains instructions not normally used by compilers.\n";
-    if (this->flg & FLOAT_OP)
-        ostr << " * Contains coprocessor instructions.\n";
+	/* Other flags */
+	if (p->flg & (PROC_BADINST | PROC_IJMP)) 
+		appendStrTab (strTab, " * Incomplete due to an %s.\n",
+					(p->flg & PROC_BADINST)? "untranslated opcode":
+											 "indirect JMP");
+	if (p->flg & PROC_ICALL)
+		appendStrTab (strTab, " * Indirect call procedure.\n");
+	if (p->flg & IMPURE)
+		appendStrTab (strTab, " * Contains impure code.\n");
+	if (p->flg & NOT_HLL)
+		appendStrTab (strTab,
+			" * Contains instructions not normally used by compilers.\n");
+	if (p->flg & FLOAT_OP)
+			appendStrTab (strTab," * Contains coprocessor instructions.\n");
 
-    /* Graph reducibility */
-    if (this->flg & GRAPH_IRRED)
-        ostr << " * Irreducible control flow graph.\n";
-    ostr << " */\n{\n";
+	/* Graph reducibility */
+	if (p->flg & GRAPH_IRRED)
+		appendStrTab (strTab," * Irreducible control flow graph.\n");
+	appendStrTab (strTab, " */\n{\n");
 }
+

+ 586 - 525
src/control.cpp

@@ -2,666 +2,727 @@
  * Description   : Performs control flow analysis on the CFG
  * (C) Cristina Cifuentes
  ********************************************************************/
-#include <boost/range/algorithm.hpp>
-#include <algorithm>
-#include <list>
-#include <cassert>
+
+#include "dcc.h"
 #include <stdio.h>
 #include <string.h>
+#if __BORLAND__
+#include <alloc.h>
+#else
 #include <malloc.h>
+#endif
 
-#include "dcc.h"
+typedef struct list {
+    Int         nodeIdx;    /* dfsLast index to the node */
+    struct list *next;
+} nodeList;
 
-//typedef struct list {
-//    int         nodeIdx;
-//    struct list *next;
-//} nodeList;
-typedef std::list<int> nodeList; /* dfsLast index to the node */
 
 #define ancestor(a,b)	((a->dfsLastNum < b->dfsLastNum) && (a->dfsFirstNum < b->dfsFirstNum))
-/* there is a path on the DFST from a to b if the a was first visited in a
- * dfs, and a was later visited than b when doing the last visit of each
+/* there is a path on the DFST from a to b if the a was first visited in a 
+ * dfs, and a was later visited than b when doing the last visit of each 
  * node. */
 
 
-/* Checks if the edge (p,s) is a back edge.  If node s was visited first
+static boolT isBackEdge (PBB p,PBB s)
+/* Checks if the edge (p,s) is a back edge.  If node s was visited first 
  * during the dfs traversal (ie. s has a smaller dfsFirst number) or s == p,
- * then it is a backedge.
+ * then it is a backedge. 
  * Also incrementes the number of backedges entries to the header node. */
-static bool isBackEdge (BB * p,BB * s)
 {
-    if (p->dfsFirstNum >= s->dfsFirstNum)
-    {
-        s->numBackEdges++;
-        return true;
-    }
-    return false;
+	if (p->dfsFirstNum >= s->dfsFirstNum)
+	{
+		s->numBackEdges++;
+		return (TRUE);
+	}
+	return (FALSE);
 }
 
 
+static Int commonDom (Int currImmDom, Int predImmDom, PPROC pProc)
 /* Finds the common dominator of the current immediate dominator
- * currImmDom and its predecessor's immediate dominator predImmDom  */
-static int commonDom (int currImmDom, int predImmDom, Function * pProc)
+ * currImmDom and its predecessor's immediate dominator predImmDom  */ 
 {
     if (currImmDom == NO_DOM)
-        return (predImmDom);
+       return (predImmDom);
     if (predImmDom == NO_DOM)   /* predecessor is the root */
-        return (currImmDom);
+       return (currImmDom);
 
     while ((currImmDom != NO_DOM) && (predImmDom != NO_DOM) &&
            (currImmDom != predImmDom))
     {
-        if (currImmDom < predImmDom)
-            predImmDom = pProc->m_dfsLast[predImmDom]->immedDom;
-        else
-            currImmDom = pProc->m_dfsLast[currImmDom]->immedDom;
+       if (currImmDom < predImmDom)
+          predImmDom = pProc->dfsLast[predImmDom]->immedDom;
+       else
+          currImmDom = pProc->dfsLast[currImmDom]->immedDom;
     }
     return (currImmDom);
 }
 
 
-/* Finds the immediate dominator of each node in the graph pProc->cfg.
+static void findImmedDom (PPROC pProc)
+/* Finds the immediate dominator of each node in the graph pProc->cfg. 
  * Adapted version of the dominators algorithm by Hecht and Ullman; finds
- * immediate dominators only.
+ * immediate dominators only.  
  * Note: graph should be reducible */
-void Function::findImmedDom ()
-{
-    BB * currNode;
-    for (size_t currIdx = 0; currIdx < numBBs; currIdx++)
+{ PBB currNode;
+  Int currIdx, j, predIdx;
+
+    for (currIdx = 0; currIdx < pProc->numBBs; currIdx++) 
     {
-        currNode = m_dfsLast[currIdx];
-        if (currNode->flg & INVALID_BB)		/* Do not process invalid BBs */
-            continue;
-        for (BB * inedge : currNode->inEdges)
-        {
-            size_t predIdx = inedge->dfsLastNum;
-            if (predIdx < currIdx)
-                currNode->immedDom = commonDom (currNode->immedDom, predIdx, this);
-        }
+		currNode = pProc->dfsLast[currIdx]; 
+		if (currNode->flg & INVALID_BB)		/* Do not process invalid BBs */
+			continue;
+
+		for (j = 0; j < currNode->numInEdges; j++)
+		{
+			predIdx = currNode->inEdges[j]->dfsLastNum;
+			if (predIdx < currIdx)
+				currNode->immedDom = commonDom (currNode->immedDom, 
+												predIdx, pProc);
+		}
     }
 }
 
 
+static void insertList (nodeList **l, Int n)
 /* Inserts the node n to the list l. */
-static void insertList (nodeList &l, int n)
 {
-    l.push_back(n);
+	nodeList *newNode;
+
+	newNode = allocStruc(nodeList);
+	memset(newNode, 0, sizeof(nodeList));
+    newNode->nodeIdx = n;
+    newNode->next = *l;
+    *l = newNode;
 }
 
 
-/* Returns whether or not the node n (dfsLast numbering of a basic block)
+static boolT inList (nodeList *l, Int n)
+/* Returns whether or not the node n (dfsLast numbering of a basic block) 
  * is on the list l. */
-static bool inList (const nodeList &l, int n)
 {
-    return std::find(l.begin(),l.end(),n)!=l.end();
+    while (l)
+      if (l->nodeIdx == n)
+         return (TRUE);
+      else
+         l = l->next;
+    return (FALSE);
 }
 
 
+static void freeList (nodeList **l)
 /* Frees space allocated by the list l.  */
-static void freeList (nodeList &l)
-{
-    l.clear();
+{ nodeList *next;
+
+    if (*l)
+    {
+       next = (*l)->next;
+       free (*l);
+       *l = next;
+    }
+    *l = NULL;
 }
 
 
-/* Returns whether the node n belongs to the queue list q. */
-static boolT inInt(BB * n, queue &q)
-{
-    return std::find(q.begin(),q.end(),n)!=q.end();
+static boolT inInt(PBB n, queue *q) 
+/* Returns whether the node n belongs to the queue list q. */ 
+{ 
+    while (q)
+      if (q->node == n)
+         return (TRUE);
+      else
+         q = q->next;
+    return (FALSE);
 }
 
 
+static void findEndlessFollow (PPROC pProc, nodeList *loopNodes, PBB head)
 /* Finds the follow of the endless loop headed at node head (if any).
  * The follow node is the closest node to the loop. */
-static void findEndlessFollow (Function * pProc, nodeList &loopNodes, BB * head)
-{
-    head->loopFollow = MAX;
-    for( int loop_node :  loopNodes)
-    {
-        for (TYPEADR_TYPE &typeaddr: pProc->m_dfsLast[loop_node]->edges)
-        {
-            int succ = typeaddr.BBptr->dfsLastNum;
-            if ((! inList(loopNodes, succ)) && (succ < head->loopFollow))
-                head->loopFollow = succ;
-        }
-    }
+{ nodeList *p;
+  Int j, succ;
+
+	head->loopFollow = MAX;
+	p = loopNodes;
+	while (p != NULL)
+	{
+		for (j = 0; j < pProc->dfsLast[p->nodeIdx]->numOutEdges; j++)
+		{
+			succ = pProc->dfsLast[p->nodeIdx]->edges[j].BBptr->dfsLastNum; 
+			if ((! inList(loopNodes, succ)) && (succ < head->loopFollow))
+				head->loopFollow = succ;
+		}
+		p = p->next;
+	}
 }
 
 
-//static void findNodesInLoop(BB * latchNode,BB * head,PPROC pProc,queue *intNodes)
-/* Flags nodes that belong to the loop determined by (latchNode, head) and
+static void findNodesInLoop(PBB latchNode,PBB head,PPROC pProc,queue *intNodes) 
+/* Flags nodes that belong to the loop determined by (latchNode, head) and 
  * determines the type of loop.                     */
-static void findNodesInLoop(BB * latchNode,BB * head,Function * pProc,queue &intNodes)
-{
-    int i, headDfsNum, intNodeType;
-    nodeList loopNodes;
-    int immedDom,     		/* dfsLast index to immediate dominator */
-        thenDfs, elseDfs;       /* dsfLast index for THEN and ELSE nodes */
-    BB * pbb;
+{ Int i, headDfsNum, intNodeType, j;
+  nodeList *loopNodes = NULL, p;
+  Int immedDom,     		/* dfsLast index to immediate dominator */
+	  thenDfs, elseDfs;		/* dsfLast index for THEN and ELSE nodes */
+  PBB pbb;
 
     /* Flag nodes in loop headed by head (except header node) */
     headDfsNum = head->dfsLastNum;
     head->loopHead = headDfsNum;
-    insertList (loopNodes, headDfsNum);
+    insertList (&loopNodes, headDfsNum);
     for (i = headDfsNum + 1; i < latchNode->dfsLastNum; i++)
     {
-        if (pProc->m_dfsLast[i]->flg & INVALID_BB)	/* skip invalid BBs */
-            continue;
+		if (pProc->dfsLast[i]->flg & INVALID_BB)	/* skip invalid BBs */
+			continue;
 
-        immedDom = pProc->m_dfsLast[i]->immedDom;
-        if (inList (loopNodes, immedDom) && inInt(pProc->m_dfsLast[i], intNodes))
+        immedDom = pProc->dfsLast[i]->immedDom;
+        if (inList (loopNodes, immedDom) && inInt(pProc->dfsLast[i], intNodes))
         {
-            insertList (loopNodes, i);
-            if (pProc->m_dfsLast[i]->loopHead == NO_NODE)/*not in other loop*/
-                pProc->m_dfsLast[i]->loopHead = headDfsNum;
+           	insertList (&loopNodes, i);
+           	if (pProc->dfsLast[i]->loopHead == NO_NODE)/*not in other loop*/
+          	  	pProc->dfsLast[i]->loopHead = headDfsNum;
         }
     }
     latchNode->loopHead = headDfsNum;
     if (latchNode != head)
-        insertList (loopNodes, latchNode->dfsLastNum);
+        insertList (&loopNodes, latchNode->dfsLastNum);
 
     /* Determine type of loop and follow node */
     intNodeType = head->nodeType;
     if (latchNode->nodeType == TWO_BRANCH)
-        if ((intNodeType == TWO_BRANCH) || (latchNode == head))
-            if ((latchNode == head) ||
-                (inList (loopNodes, head->edges[THEN].BBptr->dfsLastNum) &&
-                 inList (loopNodes, head->edges[ELSE].BBptr->dfsLastNum)))
-            {
-                head->loopType = REPEAT_TYPE;
-                if (latchNode->edges[0].BBptr == head)
-                    head->loopFollow = latchNode->edges[ELSE].BBptr->dfsLastNum;
-                else
-                    head->loopFollow = latchNode->edges[THEN].BBptr->dfsLastNum;
-                latchNode->back().ll()->setFlags(JX_LOOP);
-            }
+       if ((intNodeType == TWO_BRANCH) || (latchNode == head))
+          if ((latchNode == head) ||
+              (inList (loopNodes, head->edges[THEN].BBptr->dfsLastNum) &&
+           	   inList (loopNodes, head->edges[ELSE].BBptr->dfsLastNum)))
+          {
+			head->loopType = REPEAT_TYPE;
+            if (latchNode->edges[0].BBptr == head)
+               head->loopFollow = latchNode->edges[ELSE].BBptr->dfsLastNum;
             else
-            {
-                head->loopType = WHILE_TYPE;
-                if (inList (loopNodes, head->edges[THEN].BBptr->dfsLastNum))
-                    head->loopFollow = head->edges[ELSE].BBptr->dfsLastNum;
-                else
-                    head->loopFollow = head->edges[THEN].BBptr->dfsLastNum;
-                head->back().ll()->setFlags(JX_LOOP);
-            }
-        else /* head = anything besides 2-way, latch = 2-way */
-        {
-            head->loopType = REPEAT_TYPE;
-            if (latchNode->edges[THEN].BBptr == head)
-                head->loopFollow = latchNode->edges[ELSE].BBptr->dfsLastNum;
+               head->loopFollow = latchNode->edges[THEN].BBptr->dfsLastNum;
+			pProc->Icode.SetLlFlag(latchNode->start + latchNode->length - 1,
+				JX_LOOP);
+          }
+          else
+          {
+         	head->loopType = WHILE_TYPE;
+            if (inList (loopNodes, head->edges[THEN].BBptr->dfsLastNum))
+            	head->loopFollow = head->edges[ELSE].BBptr->dfsLastNum; 
             else
-                head->loopFollow = latchNode->edges[THEN].BBptr->dfsLastNum;
-            latchNode->back().ll()->setFlags(JX_LOOP);
-        }
-    else	/* latch = 1-way */
-        if (latchNode->nodeType == LOOP_NODE)
-        {
-            head->loopType = REPEAT_TYPE;
-            head->loopFollow = latchNode->edges[0].BBptr->dfsLastNum;
-        }
-        else if (intNodeType == TWO_BRANCH)
-        {
-            head->loopType = WHILE_TYPE;
-            pbb = latchNode;
-            thenDfs = head->edges[THEN].BBptr->dfsLastNum;
-            elseDfs = head->edges[ELSE].BBptr->dfsLastNum;
-            while (1)
-            {
-                if (pbb->dfsLastNum == thenDfs)
-                {
-                    head->loopFollow = elseDfs;
-                    break;
-                }
-                else if (pbb->dfsLastNum == elseDfs)
-                {
-                    head->loopFollow = thenDfs;
-                    break;
-                }
-
-                /* Check if couldn't find it, then it is a strangely formed
-                                 * loop, so it is safer to consider it an endless loop */
-                if (pbb->dfsLastNum <= head->dfsLastNum)
-                {
-                    head->loopType = ENDLESS_TYPE;
-                    findEndlessFollow (pProc, loopNodes, head);
-                    break;
-                }
-                pbb = pProc->m_dfsLast[pbb->immedDom];
-            }
-            if (pbb->dfsLastNum > head->dfsLastNum)
-                pProc->m_dfsLast[head->loopFollow]->loopHead = NO_NODE;	/*****/
-            head->back().ll()->setFlags(JX_LOOP);
-        }
-        else
-        {
-            head->loopType = ENDLESS_TYPE;
-            findEndlessFollow (pProc, loopNodes, head);
-        }
-
-    freeList(loopNodes);
+            	head->loopFollow = head->edges[THEN].BBptr->dfsLastNum; 
+			pProc->Icode.SetLlFlag(head->start + head->length - 1, JX_LOOP);
+          }
+	   else /* head = anything besides 2-way, latch = 2-way */ 
+       {
+			head->loopType = REPEAT_TYPE;
+			if (latchNode->edges[THEN].BBptr == head)
+				head->loopFollow = latchNode->edges[ELSE].BBptr->dfsLastNum;
+			else
+				head->loopFollow = latchNode->edges[THEN].BBptr->dfsLastNum;
+			pProc->Icode.SetLlFlag(latchNode->start + latchNode->length - 1,
+				JX_LOOP);
+       }
+	else	/* latch = 1-way */
+		if (latchNode->nodeType == LOOP_NODE)
+		{
+			head->loopType = REPEAT_TYPE; 
+			head->loopFollow = latchNode->edges[0].BBptr->dfsLastNum;
+		}
+		else if (intNodeType == TWO_BRANCH)
+		{
+			head->loopType = WHILE_TYPE;
+			pbb = latchNode; 
+			thenDfs = head->edges[THEN].BBptr->dfsLastNum;
+			elseDfs = head->edges[ELSE].BBptr->dfsLastNum;
+			while (1)
+			{
+				if (pbb->dfsLastNum == thenDfs)
+				{
+					head->loopFollow = elseDfs;
+					break;
+				}
+				else if (pbb->dfsLastNum == elseDfs)
+				{
+					head->loopFollow = thenDfs;
+					break;
+				}
+
+				/* Check if couldn't find it, then it is a strangely formed
+				 * loop, so it is safer to consider it an endless loop */
+				if (pbb->dfsLastNum <= head->dfsLastNum)
+				{
+					head->loopType = ENDLESS_TYPE;
+					findEndlessFollow (pProc, loopNodes, head);
+					break;
+				}
+				pbb = pProc->dfsLast[pbb->immedDom];	
+			}
+			if (pbb->dfsLastNum > head->dfsLastNum)
+				pProc->dfsLast[head->loopFollow]->loopHead = NO_NODE;	/*****/
+			pProc->Icode.SetLlFlag(head->start + head->length - 1, JX_LOOP);
+		}
+		else
+		{
+			head->loopType = ENDLESS_TYPE;
+			findEndlessFollow (pProc, loopNodes, head);
+		}
+
+    freeList(&loopNodes);
 }
 
-//static void findNodesInInt (queue **intNodes, int level, interval *Ii)
-/* Recursive procedure to find nodes that belong to the interval (ie. nodes
+
+static void findNodesInInt (queue **intNodes, Int level, interval *Ii)
+/* Recursive procedure to find nodes that belong to the interval (ie. nodes 
  * from G1).                                */
-static void findNodesInInt (queue &intNodes, int level, interval *Ii)
-{
+{ queue *l;
+
     if (level == 1)
-    {
-        for(BB *en : Ii->nodes)
-        {
-            appendQueue(intNodes,en);
-        }
-    }
+       for (l = Ii->nodes; l; l = l->next)
+          appendQueue (intNodes, l->node);
     else
-    {
-        for(BB *en : Ii->nodes)
-        {
-            findNodesInInt(intNodes,level-1,en->correspInt);
-        }
-    }
+       for (l = Ii->nodes; l; l= l->next)
+          findNodesInInt (intNodes, level - 1, l->node->correspInt);
 }
 
 
+static void structLoops(PPROC pProc, derSeq *derivedG)
 /* Algorithm for structuring loops */
-void Function::structLoops(derSeq *derivedG)
-{
-    interval *Ii;
-    BB * intHead,      	/* interval header node         	*/
-            * pred,     /* predecessor node         		*/
-            * latchNode;/* latching node (in case of loops) */
-    size_t  level = 0;  /* derived sequence level       	*/
-    interval *initInt;  /* initial interval         		*/
-    queue intNodes;  	/* list of interval nodes       	*/
+{ interval *Ii;
+  PBB intHead,      	/* interval header node         	*/
+      pred,     		/* predecessor node         		*/ 
+      latchNode;    	/* latching node (in case of loops) */
+  Int i,        		/* counter              			*/ 
+      level = 0;    	/* derived sequence level       	*/
+  interval *initInt;    /* initial interval         		*/
+  queue *intNodes;  	/* list of interval nodes       	*/
 
     /* Structure loops */
-    /* for all derived sequences Gi */
-    for(derSeq::iterator iter=derivedG->begin(); iter!=derivedG->end(); ++iter)
+    while (derivedG)    /* for all derived sequences Gi */
     {
-        level++;
-        Ii = iter->Ii;
-        while (Ii)       /* for all intervals Ii of Gi */
-        {
-            latchNode = NULL;
-            intNodes.clear();
-
-            /* Find interval head (original BB node in G1) and create
+       level++;
+       Ii = derivedG->Ii;
+       while (Ii)       /* for all intervals Ii of Gi */
+       {
+          latchNode = NULL;
+          intNodes  = NULL;
+
+          /* Find interval head (original BB node in G1) and create
            * list of nodes of interval Ii.              */
-            initInt = Ii;
-            for (size_t i = 1; i < level; i++)
-                initInt = (*initInt->nodes.begin())->correspInt;
-            intHead = *initInt->nodes.begin();
-
-            /* Find nodes that belong to the interval (nodes from G1) */
-            findNodesInInt (intNodes, level, Ii);
-
-            /* Find greatest enclosing back edge (if any) */
-            for (size_t i = 0; i < intHead->inEdges.size(); i++)
-            {
-                pred = intHead->inEdges[i];
-                if (inInt(pred, intNodes) && isBackEdge(pred, intHead))
-                    if (! latchNode)
-                        latchNode = pred;
-                    else
-                    {
-                        if (pred->dfsLastNum > latchNode->dfsLastNum)
-                            latchNode = pred;
-                    }
-            }
-
-            /* Find nodes in the loop and the type of loop */
-            if (latchNode)
-            {
-                /* Check latching node is at the same nesting level of case
-                 * statements (if any) and that the node doesn't belong to
-                 * another loop.                   */
-                if ((latchNode->caseHead == intHead->caseHead) &&
-                        (latchNode->loopHead == NO_NODE))
-                {
-                    intHead->latchNode = latchNode->dfsLastNum;
-                    findNodesInLoop(latchNode, intHead, this, intNodes);
-                    latchNode->flg |= IS_LATCH_NODE;
-                }
-            }
-
-            /* Next interval */
-            Ii = Ii->next;
-        }
-
-        /* Next derived sequence */
+          initInt = Ii;
+          for (i = 1; i < level; i++)
+          	initInt = initInt->nodes->node->correspInt;
+          intHead = initInt->nodes->node;
+
+          /* Find nodes that belong to the interval (nodes from G1) */
+          findNodesInInt (&intNodes, level, Ii);
+
+          /* Find greatest enclosing back edge (if any) */
+          for (i = 0; i < intHead->numInEdges; i++)
+          {
+          	pred = intHead->inEdges[i]; 
+          	if (inInt(pred, intNodes) && isBackEdge(pred, intHead))
+             	if (! latchNode)
+            		latchNode = pred;
+             	else
+             	{
+                	if (pred->dfsLastNum > latchNode->dfsLastNum)
+               			latchNode = pred;
+             	}
+          }
+
+          /* Find nodes in the loop and the type of loop */
+          if (latchNode)
+          { 
+         	/* Check latching node is at the same nesting level of case
+          	 * statements (if any) and that the node doesn't belong to
+          	 * another loop.                   */
+         	if ((latchNode->caseHead == intHead->caseHead) &&
+             	(latchNode->loopHead == NO_NODE)) 
+         	{
+            	intHead->latchNode = latchNode->dfsLastNum;
+            	findNodesInLoop(latchNode, intHead, pProc, intNodes);
+				latchNode->flg |= IS_LATCH_NODE;
+         	}
+          }
+
+          /* Next interval */
+          Ii = Ii->next;
+       }
+
+       /* Next derived sequence */
+       derivedG = derivedG->next;
     }
 }
 
 
+static boolT successor (Int s, Int h, PPROC pProc)
 /* Returns whether the BB indexed by s is a successor of the BB indexed by
  * h.  Note that h is a case node.                  */
-static bool successor (int s, int h, Function * pProc)
-{
-    BB * header;
-
-    header = pProc->m_dfsLast[h];
-    auto iter = std::find_if(header->edges.begin(),
-                             header->edges.end(),
-                             [s](const TYPEADR_TYPE &te)->bool{ return te.BBptr->dfsLastNum == s;});
-    return iter!=header->edges.end();
+{ Int i;
+  PBB header;
+
+    header = pProc->dfsLast[h];
+    for (i = 0; i < header->numOutEdges; i++)
+      if (header->edges[i].BBptr->dfsLastNum == s)
+         return (TRUE);
+    return (FALSE);
 }
 
 
+static void tagNodesInCase (PBB pBB, nodeList **l, Int head, Int tail)
 /* Recursive procedure to tag nodes that belong to the case described by
- * the list l, head and tail (dfsLast index to first and exit node of the
+ * the list l, head and tail (dfsLast index to first and exit node of the 
  * case).                               */
-static void tagNodesInCase (BB * pBB, nodeList &l, int head, int tail)
-{
-    int current,      /* index to current node */
-            i;
+{ Int current,      /* index to current node */
+      i;
 
     pBB->traversed = DFS_CASE;
     current = pBB->dfsLastNum;
-    if ((current != tail) && (pBB->nodeType != MULTI_BRANCH) && (inList (l, pBB->immedDom)))
+    if ((current != tail) && (pBB->nodeType != MULTI_BRANCH) && 
+        (inList (*l, pBB->immedDom)))
     {
-        insertList (l, current);
-        pBB->caseHead = head;
-        for(TYPEADR_TYPE &edge : pBB->edges)
-        {
-            if (edge.BBptr->traversed != DFS_CASE)
-                tagNodesInCase (edge.BBptr, l, head, tail);
-        }
+       insertList (l, current);
+       pBB->caseHead = head;
+       for (i = 0; i < pBB->numOutEdges; i++)
+          if (pBB->edges[i].BBptr->traversed != DFS_CASE)
+             tagNodesInCase (pBB->edges[i].BBptr, l, head, tail);
     }
 }
 
 
+static void structCases(PPROC pProc)
 /* Structures case statements.  This procedure is invoked only when pProc
  * has a case node.                         */
-void Function::structCases()
-{
-    int i, j;
-    BB * caseHeader;       		/* case header node         */
-    int exitNode = NO_NODE;   	/* case exit node           */
-    nodeList caseNodes;   /* temporary: list of nodes in case */
+{ Int i, j;
+  PBB caseHeader;       		/* case header node         */
+  Int exitNode = NO_NODE;   	/* case exit node           */
+  nodeList *caseNodes = NULL;   /* temporary: list of nodes in case */
 
     /* Linear scan of the nodes in reverse dfsLast order, searching for
      * case nodes                           */
-    for (i = numBBs - 1; i >= 0; i--)
-        if (m_dfsLast[i]->nodeType == MULTI_BRANCH)
-        {
-            caseHeader = m_dfsLast[i];
-
-            /* Find descendant node which has as immediate predecessor
-                         * the current header node, and is not a successor.    */
-            for (j = i + 2; j < numBBs; j++)
-            {
-                if ((!successor(j, i, this)) &&
-                    (m_dfsLast[j]->immedDom == i))
-                    if (exitNode == NO_NODE)
-                        exitNode = j;
-                    else if (m_dfsLast[exitNode]->inEdges.size() < m_dfsLast[j]->inEdges.size())
-                        exitNode = j;
-            }
-            m_dfsLast[i]->caseTail = exitNode;
-
-            /* Tag nodes that belong to the case by recording the
-                         * header field with caseHeader.           */
-            insertList (caseNodes, i);
-            m_dfsLast[i]->caseHead = i;
-            for(TYPEADR_TYPE &pb : caseHeader->edges)
-            {
-                tagNodesInCase(pb.BBptr, caseNodes, i, exitNode);
-            }
-            //for (j = 0; j < caseHeader->edges[j]; j++)
-            //    tagNodesInCase (caseHeader->edges[j].BBptr, caseNodes, i, exitNode);
-            if (exitNode != NO_NODE)
-                m_dfsLast[exitNode]->caseHead = i;
-        }
+	for (i = pProc->numBBs - 1; i >= 0; i--)
+		if (pProc->dfsLast[i]->nodeType == MULTI_BRANCH)
+		{
+			caseHeader = pProc->dfsLast[i];
+
+			/* Find descendant node which has as immediate predecessor 
+			 * the current header node, and is not a successor.    */
+			for (j = i + 2; j < pProc->numBBs; j++)
+			{
+				if ((!successor(j, i, pProc)) && 
+										(pProc->dfsLast[j]->immedDom == i))
+					if (exitNode == NO_NODE)
+              			exitNode = j;
+					else if (pProc->dfsLast[exitNode]->numInEdges <
+                			 pProc->dfsLast[j]->numInEdges) 
+              			exitNode = j;
+         	}
+			pProc->dfsLast[i]->caseTail = exitNode;
+         
+			/* Tag nodes that belong to the case by recording the
+			 * header field with caseHeader.           */
+			insertList (&caseNodes, i); 
+			pProc->dfsLast[i]->caseHead = i;
+			for (j = 0; j < caseHeader->numOutEdges; j++)
+        		tagNodesInCase (caseHeader->edges[j].BBptr, &caseNodes, i,
+								exitNode);
+			if (exitNode != NO_NODE)
+            	pProc->dfsLast[exitNode]->caseHead = i;
+		}
 }
 
 
+static void flagNodes (nodeList **l, Int f, PPROC pProc)
 /* Flags all nodes in the list l as having follow node f, and deletes all
  * nodes from the list.                         */
-static void flagNodes (nodeList &l, int f, Function * pProc)
-{
-    nodeList::iterator p;
-    for(int idx : l)
+{  nodeList *p;
+
+    p = *l;
+    while (p)
     {
-        pProc->m_dfsLast[idx]->ifFollow = f;
+       pProc->dfsLast[p->nodeIdx]->ifFollow = f;
+       p = p->next;
+       free (*l);
+       *l = p;
     }
-    l.clear();
+    *l = NULL;
 }
 
 
+static void structIfs (PPROC pProc)
 /* Structures if statements */
-void Function::structIfs ()
-{
-    int curr,    				/* Index for linear scan of nodes   	*/
-            desc,    				/* Index for descendant         		*/
-            followInEdges,			/* Largest # in-edges so far 			*/
-            follow;  				/* Possible follow node 				*/
-    nodeList domDesc,    /* List of nodes dominated by curr  	*/
-            unresolved 	/* List of unresolved if nodes  		*/
-            ;
-    BB * currNode,    			/* Pointer to current node  			*/
-            * pbb;
-
-    /* Linear scan of nodes in reverse dfsLast order */
-    for (curr = numBBs - 1; curr >= 0; curr--)
+{  Int curr,    				/* Index for linear scan of nodes   	*/
+       desc,    				/* Index for descendant         		*/
+	   followInEdges,			/* Largest # in-edges so far 			*/
+       follow;  				/* Possible follow node 				*/
+   nodeList *domDesc = NULL,    /* List of nodes dominated by curr  	*/
+        *unresolved = NULL, 	/* List of unresolved if nodes  		*/
+        *l;         			/* Temporary list       				*/
+   PBB currNode,    			/* Pointer to current node  			*/
+		pbb;
+
+	/* Linear scan of nodes in reverse dfsLast order */
+    for (curr = pProc->numBBs - 1; curr >= 0; curr--)
     {
-        currNode = m_dfsLast[curr];
-        if (currNode->flg & INVALID_BB)		/* Do not process invalid BBs */
-            continue;
-
-        if ((currNode->nodeType == TWO_BRANCH) && (!currNode->back().ll()->testFlags(JX_LOOP)))
-        {
-            followInEdges = 0;
-            follow = 0;
-
-            /* Find all nodes that have this node as immediate dominator */
-            for (desc = curr+1; desc < numBBs; desc++)
-            {
-                if (m_dfsLast[desc]->immedDom == curr)
-                {
-                    insertList (domDesc, desc);
-                    pbb = m_dfsLast[desc];
-                    if ((pbb->inEdges.size() - pbb->numBackEdges) >= followInEdges)
-                    {
-                        follow = desc;
-                        followInEdges = pbb->inEdges.size() - pbb->numBackEdges;
-                    }
-                }
-            }
-
-            /* Determine follow according to number of descendants
-                         * immediately dominated by this node  */
-            if ((follow != 0) && (followInEdges > 1))
-            {
-                currNode->ifFollow = follow;
-                if (!unresolved.empty())
-                    flagNodes (unresolved, follow, this);
-            }
-            else
-                insertList (unresolved, curr);
-        }
-        freeList (domDesc);
-    }
-}
-bool Function::removeInEdge_Flag_and_ProcessLatch(BB *pbb,BB *a,BB *b)
-{
-    /* Remove in-edge e to t */
-    auto iter = std::find(b->inEdges.begin(),b->inEdges.end(),a);
-    assert(iter!=b->inEdges.end());
-    b->inEdges.erase(iter); /* looses 1 arc */
-    a->flg |= INVALID_BB;
-
-    if (pbb->flg & IS_LATCH_NODE)
-        this->m_dfsLast[a->dfsLastNum] = pbb;
-    else
-        return true; /* to repeat this analysis */
-    return false;
-
+		currNode = pProc->dfsLast[curr];
+		if (currNode->flg & INVALID_BB)		/* Do not process invalid BBs */
+			continue;
+
+		if ((currNode->nodeType == TWO_BRANCH) &&
+			(! (pProc->Icode.GetLlFlag(currNode->start + currNode->length - 1)
+				& JX_LOOP)))
+		{
+			followInEdges = 0;
+			follow = 0;
+
+			/* Find all nodes that have this node as immediate dominator */
+			for (desc = curr+1; desc < pProc->numBBs; desc++)
+			{
+				if (pProc->dfsLast[desc]->immedDom == curr)  {
+					insertList (&domDesc, desc);
+					pbb = pProc->dfsLast[desc];
+					if ((pbb->numInEdges - pbb->numBackEdges) >= followInEdges)
+					{
+						follow = desc;
+						followInEdges = pbb->numInEdges - pbb->numBackEdges;
+					}
+				}
+			}
+
+			/* Determine follow according to number of descendants
+			 * immediately dominated by this node  */
+			if ((follow != 0) && (followInEdges > 1))
+			{
+				currNode->ifFollow = follow;
+				if (unresolved)
+					flagNodes (&unresolved, follow, pProc);
+			}
+			else
+				insertList (&unresolved, curr);
+		}
+		freeList (&domDesc);
+	}
 }
 
 
-void Function::replaceInEdge(BB* where, BB* which,BB* with)
-{
-    auto iter=std::find(where->inEdges.begin(),where->inEdges.end(),which);
-    assert(iter!=where->inEdges.end());
-    *iter=with;
-}
-bool Function::Case_notX_or_Y(BB* pbb, BB* thenBB, BB* elseBB)
-{
-    HLTYPE &hl1(*pbb->back().hl());
-    HLTYPE &hl2(*thenBB->back().hl());
-
-    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));
-
-    /* Replace in-edge to obb from e to pbb */
-    replaceInEdge(obb,elseBB,pbb);
-
-    /* New THEN and ELSE out-edges of pbb */
-    pbb->edges[THEN].BBptr = obb;
-    pbb->edges[ELSE].BBptr = thenBB;
-
-    /* Remove in-edge e to t */
-    return removeInEdge_Flag_and_ProcessLatch(pbb,elseBB,thenBB);
-}
-bool Function::Case_X_and_Y(BB* pbb, BB* thenBB, BB* elseBB)
-{
-    HLTYPE &hl1(*pbb->back().hl());
-    HLTYPE &hl2(*thenBB->back().hl());
-    BB* obb = elseBB->edges[ELSE].BBptr;
-
-    /* Construct compound DBL_AND expression */
-    hl1.expr(COND_EXPR::boolOp (hl1.expr(),hl2.expr(), DBL_AND));
-
-    /* Replace in-edge to obb from e to pbb */
-    replaceInEdge(obb,elseBB,pbb);
-    /* New ELSE out-edge of pbb */
-    pbb->edges[ELSE].BBptr = obb;
-
-    /* Remove in-edge e to t */
-    return removeInEdge_Flag_and_ProcessLatch(pbb,elseBB,thenBB);
-}
-
-
-bool Function::Case_notX_and_Y(BB* pbb, BB* thenBB, BB* elseBB)
-{
-    HLTYPE &hl1(*pbb->back().hl());
-    HLTYPE &hl2(*thenBB->back().hl());
-
-    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));
-
-    /* Replace in-edge to obb from t to pbb */
-    replaceInEdge(obb,thenBB,pbb);
-
-    /* New THEN and ELSE out-edges of pbb */
-    pbb->edges[THEN].BBptr = elseBB;
-    pbb->edges[ELSE].BBptr = obb;
-
-    /* Remove in-edge t to e */
-    return removeInEdge_Flag_and_ProcessLatch(pbb,thenBB,elseBB);
-}
-
-bool Function::Case_X_or_Y(BB* pbb, BB* thenBB, BB* elseBB)
-{
-    HLTYPE &hl1(*pbb->back().hl());
-    HLTYPE &hl2(*thenBB->back().hl());
-
-    BB * obb = thenBB->edges[THEN].BBptr;
-
-    /* Construct compound DBL_OR expression */
-    hl1.expr(COND_EXPR::boolOp (hl1.expr(), hl2.expr(), DBL_OR));
-
-    /* Replace in-edge to obb from t to pbb */
-
-    auto iter=find(obb->inEdges.begin(),obb->inEdges.end(),thenBB);
-    if(iter!=obb->inEdges.end())
-        *iter = pbb;
-
-    /* New THEN out-edge of pbb */
-    pbb->edges[THEN].BBptr = obb;
-
-    /* Remove in-edge t to e */
-    return removeInEdge_Flag_and_ProcessLatch(pbb,thenBB,elseBB);
-}
-/** \brief Checks for compound conditions of basic blocks that have only 1 high
+void compoundCond (PPROC pproc)
+/* Checks for compound conditions of basic blocks that have only 1 high 
  * level instruction.  Whenever these blocks are found, they are merged
  * into one block with the appropriate condition */
-void Function::compoundCond()
-{
-    BB * pbb, * thenBB, * elseBB;
-    bool change = true;
-    while (change)
-    {
-        change = false;
-
-        /* Traverse nodes in postorder, this way, the header node of a
-         * compound condition is analysed first */
-        for (int i = 0; i < this->numBBs; i++)
-        {
-            pbb = this->m_dfsLast[i];
-            if (pbb->flg & INVALID_BB)
-                continue;
-
-            if (pbb->nodeType != TWO_BRANCH)
-                continue;
-
-            thenBB = pbb->edges[THEN].BBptr;
-            elseBB = pbb->edges[ELSE].BBptr;
-
-            change = true; //assume change
-
-            /* Check (X || Y) case */
-            if ((thenBB->nodeType == TWO_BRANCH) && (thenBB->numHlIcodes == 1) &&
-                (thenBB->inEdges.size() == 1) && (thenBB->edges[ELSE].BBptr == elseBB))
-            {
-                if(Case_X_or_Y(pbb, thenBB, elseBB))
-                    --i;
-            }
-
-            /* Check (!X && Y) case */
-            else if ((thenBB->nodeType == TWO_BRANCH) && (thenBB->numHlIcodes == 1) &&
-                     (thenBB->inEdges.size() == 1) && (thenBB->edges[THEN].BBptr == elseBB))
-            {
-                if(Case_notX_and_Y(pbb, thenBB, elseBB))
-                    --i;
-            }
-
-            /* Check (X && Y) case */
-            else if ((elseBB->nodeType == TWO_BRANCH) && (elseBB->numHlIcodes == 1) &&
-                     (elseBB->inEdges.size()==1) && (elseBB->edges[THEN].BBptr == thenBB))
-            {
-                if(Case_X_and_Y(pbb, thenBB, elseBB ))
-                    --i;
-            }
-
-            /* Check (!X || Y) case */
-            else if ((elseBB->nodeType == TWO_BRANCH) && (elseBB->numHlIcodes == 1) &&
-                     (elseBB->inEdges.size() == 1) && (elseBB->edges[ELSE].BBptr == thenBB))
-            {
-                if(Case_notX_or_Y(pbb, thenBB, elseBB ))
-                    --i;
-            }
-            else
-                change = false; // otherwise we changed nothing
-        }
-    }
+{ Int i, j, k, numOutEdges;
+  PBB pbb, t, e, obb, pred;
+  PICODE picode, ticode;
+  COND_EXPR *exp;
+ TYPEADR_TYPE *edges;
+  boolT change;
+
+  change = TRUE;
+  while (change)
+  {
+	change = FALSE;
+
+	/* Traverse nodes in postorder, this way, the header node of a
+	 * compound condition is analysed first */
+	for (i = 0; i < pproc->numBBs; i++)
+	{
+		pbb = pproc->dfsLast[i];
+		if (pbb->flg & INVALID_BB)
+			continue;
+
+		if (pbb->nodeType == TWO_BRANCH)
+		{
+			t = pbb->edges[THEN].BBptr;
+			e = pbb->edges[ELSE].BBptr;
+
+			/* Check (X || Y) case */
+			if ((t->nodeType == TWO_BRANCH) && (t->numHlIcodes == 1) && 
+				(t->numInEdges == 1) && (t->edges[ELSE].BBptr == e)) 
+			{
+				obb = t->edges[THEN].BBptr;
+
+				/* Construct compound DBL_OR expression */
+				picode = pproc->Icode.GetIcode(pbb->start + pbb->length -1);
+				ticode = pproc->Icode.GetIcode(t->start + t->length -1);
+				exp = boolCondExp (picode->ic.hl.oper.exp,
+								   ticode->ic.hl.oper.exp, DBL_OR);
+				picode->ic.hl.oper.exp = exp;
+
+				/* Replace in-edge to obb from t to pbb */
+				for (j = 0; j < obb->numInEdges; j++)
+					if (obb->inEdges[j] == t)
+					{
+						obb->inEdges[j] = pbb;
+						break;
+					}
+
+				/* New THEN out-edge of pbb */
+				pbb->edges[THEN].BBptr = obb;
+
+				/* Remove in-edge t to e */
+				for (j = 0; j < (e->numInEdges-1); j++)
+					if (e->inEdges[j] == t)
+					{
+						memmove (&e->inEdges[j], &e->inEdges[j+1], 
+								 (size_t)((e->numInEdges - j - 1) * sizeof(PBB)));
+						break;
+					}
+				e->numInEdges--;	/* looses 1 arc */
+				t->flg |= INVALID_BB;
+
+				if (pbb->flg & IS_LATCH_NODE)
+					pproc->dfsLast[t->dfsLastNum] = pbb;
+				else 
+					i--;		/* to repeat this analysis */
+
+				change = TRUE;
+			}
+
+			/* Check (!X && Y) case */
+			else if ((t->nodeType == TWO_BRANCH) && (t->numHlIcodes == 1) && 
+				(t->numInEdges == 1) && (t->edges[THEN].BBptr == e)) 
+			{
+				obb = t->edges[ELSE].BBptr;
+
+				/* Construct compound DBL_AND expression */
+				picode = pproc->Icode.GetIcode(pbb->start + pbb->length -1);
+				ticode = pproc->Icode.GetIcode(t->start + t->length -1);
+				inverseCondOp (&picode->ic.hl.oper.exp);
+				exp = boolCondExp (picode->ic.hl.oper.exp,
+								   ticode->ic.hl.oper.exp, DBL_AND);
+				picode->ic.hl.oper.exp = exp;
+
+				/* Replace in-edge to obb from t to pbb */
+				for (j = 0; j < obb->numInEdges; j++)
+					if (obb->inEdges[j] == t)
+					{
+						obb->inEdges[j] = pbb;
+						break;
+					}
+
+				/* New THEN and ELSE out-edges of pbb */
+				pbb->edges[THEN].BBptr = e;
+				pbb->edges[ELSE].BBptr = obb;
+				
+				/* Remove in-edge t to e */
+				for (j = 0; j < (e->numInEdges-1); j++)
+					if (e->inEdges[j] == t)
+					{
+						memmove (&e->inEdges[j], &e->inEdges[j+1], 
+								 (size_t)((e->numInEdges - j - 1) * sizeof(PBB)));
+						break;
+					}
+				e->numInEdges--;	/* looses 1 arc */
+				t->flg |= INVALID_BB;
+
+				if (pbb->flg & IS_LATCH_NODE)
+					pproc->dfsLast[t->dfsLastNum] = pbb;
+				else 
+					i--;		/* to repeat this analysis */
+
+				change = TRUE;
+			}
+
+			/* Check (X && Y) case */
+			else if ((e->nodeType == TWO_BRANCH) && (e->numHlIcodes == 1) && 
+					 (e->numInEdges == 1) && (e->edges[THEN].BBptr == t)) 
+			{
+				obb = e->edges[ELSE].BBptr;
+
+				/* Construct compound DBL_AND expression */
+				picode = pproc->Icode.GetIcode(pbb->start + pbb->length -1);
+				ticode = pproc->Icode.GetIcode(t->start + t->length -1);
+				exp = boolCondExp (picode->ic.hl.oper.exp,
+								   ticode->ic.hl.oper.exp, DBL_AND);
+				picode->ic.hl.oper.exp = exp;
+				
+				/* Replace in-edge to obb from e to pbb */
+				for (j = 0; j < obb->numInEdges; j++)
+					if (obb->inEdges[j] == e)
+					{
+						obb->inEdges[j] = pbb;
+						break;
+					}
+
+				/* New ELSE out-edge of pbb */
+				pbb->edges[ELSE].BBptr = obb;
+
+				/* Remove in-edge e to t */
+				for (j = 0; j < (t->numInEdges-1); j++)
+					if (t->inEdges[j] == e)
+					{
+						memmove (&t->inEdges[j], &t->inEdges[j+1], 
+								 (size_t)((t->numInEdges - j - 1) * sizeof(PBB)));
+						break;
+					}
+				t->numInEdges--;	/* looses 1 arc */
+				e->flg |= INVALID_BB;
+
+				if (pbb->flg & IS_LATCH_NODE)
+					pproc->dfsLast[e->dfsLastNum] = pbb;
+				else 
+					i--;		/* to repeat this analysis */
+
+				change = TRUE;
+			}
+
+			/* Check (!X || Y) case */
+			else if ((e->nodeType == TWO_BRANCH) && (e->numHlIcodes == 1) && 
+					 (e->numInEdges == 1) && (e->edges[ELSE].BBptr == t)) 
+			{
+				obb = e->edges[THEN].BBptr;
+
+				/* Construct compound DBL_OR expression */
+				picode = pproc->Icode.GetIcode(pbb->start + pbb->length -1);
+				ticode = pproc->Icode.GetIcode(t->start + t->length -1);
+				inverseCondOp (&picode->ic.hl.oper.exp);
+				exp = boolCondExp (picode->ic.hl.oper.exp,
+								   ticode->ic.hl.oper.exp, DBL_OR);
+				picode->ic.hl.oper.exp = exp;
+				
+				/* Replace in-edge to obb from e to pbb */
+				for (j = 0; j < obb->numInEdges; j++)
+					if (obb->inEdges[j] == e)
+					{
+						obb->inEdges[j] = pbb;
+						break;
+					}
+
+				/* New THEN and ELSE out-edges of pbb */
+				pbb->edges[THEN].BBptr = obb;
+				pbb->edges[ELSE].BBptr = t;
+
+				/* Remove in-edge e to t */
+				for (j = 0; j < (t->numInEdges-1); j++)
+					if (t->inEdges[j] == e)
+					{
+						memmove (&t->inEdges[j], &t->inEdges[j+1], 
+								 (size_t)((t->numInEdges - j - 1) * sizeof(PBB)));
+						break;
+					}
+				t->numInEdges--;	/* looses 1 arc */
+				e->flg |= INVALID_BB;
+
+				if (pbb->flg & IS_LATCH_NODE)
+					pproc->dfsLast[e->dfsLastNum] = pbb;
+				else 
+					i--;		/* to repeat this analysis */
+
+				change = TRUE;
+			}
+		}
+	}
+  }
 }
 
 
+void structure(PPROC pProc, derSeq *derivedG)
 /* Structuring algorithm to find the structures of the graph pProc->cfg */
-void Function::structure(derSeq *derivedG)
 {
     /* Find immediate dominators of the graph */
-    findImmedDom();
-    if (hasCase)
-        structCases();
-    structLoops(derivedG);
-    structIfs();
+    findImmedDom(pProc);
+    if (pProc->hasCase)
+       structCases(pProc); 
+    structLoops(pProc, derivedG); 
+    structIfs(pProc); 
 }

+ 903 - 1025
src/dataflow.cpp

@@ -6,262 +6,203 @@
  ****************************************************************************/
 
 #include "dcc.h"
-#include <boost/range.hpp>
-#include <boost/range/adaptors.hpp>
-#include <boost/range/algorithm.hpp>
-#include <boost/assign.hpp>
 #include <string.h>
-#include <iostream>
-#include <iomanip>
 #include <stdio.h>
-using namespace boost;
-using namespace boost::adaptors;
-struct ExpStack
-{
-    typedef std::list<COND_EXPR *> EXP_STK;
-    EXP_STK expStk;      /* local expression stack */
-
-    void        init();
-    void        push(COND_EXPR *);
-    COND_EXPR * pop();
-    int         numElem();
-    boolT	empty();
-    void processExpPush(int &numHlIcodes, iICODE picode)
-    {
-        push(picode->hl()->expr());
-        picode->invalidate();
-        numHlIcodes--;
-    }
 
-};
-/***************************************************************************
- * Expression stack functions
- **************************************************************************/
-
-/* Reinitalizes the expression stack (expStk) to NULL, by freeing all the
- * space allocated (if any).        */
-void ExpStack::init()
-{
-    expStk.clear();
-}
 
+static Int getLocVar (PSTKFRAME pStkFrame, Int off)
+/* Returns the index of the local variable or parameter at offset off, if it 
+ * is in the stack frame provided.  */
+{   Int     i;
 
-/* Pushes the given expression onto the local stack (expStk). */
-void ExpStack::push(COND_EXPR *expr)
-{
-    expStk.push_back(expr);
+    for (i = 0; i < pStkFrame->csym; i++)
+       if (pStkFrame->sym[i].off == off) 
+          break;
+    return (i);
 }
 
 
-/* Returns the element on the top of the local expression stack (expStk),
- * and deallocates the space allocated by this node.
- * If there are no elements on the stack, returns NULL. */
-COND_EXPR *ExpStack::pop()
-{
-    if(expStk.empty())
-        return 0;
-    COND_EXPR *topExp = expStk.back();
-    expStk.pop_back();
-    return topExp;
-}
-
-/* Returns the number of elements available in the expression stack */
-int ExpStack::numElem()
-{
-    return expStk.size();
+static COND_EXPR *srcIdent (PICODE Icode, PPROC pProc, Int i, PICODE duIcode, 
+                            operDu du)
+/* Returns a string with the source operand of Icode */
+{ COND_EXPR *n;
+
+    if (Icode->ic.ll.flg & I)   /* immediate operand */
+	{
+		if (Icode->ic.ll.flg & B)
+        	n = idCondExpKte (Icode->ic.ll.immed.op, 1);
+		else
+        	n = idCondExpKte (Icode->ic.ll.immed.op, 2);
+	}
+    else
+       n = idCondExp (Icode, SRC, pProc, i, duIcode, du);
+    return (n);
 }
 
-/* Returns whether the expression stack is empty or not */
-boolT ExpStack::empty()
-{
-    return expStk.empty();
-}
 
-using namespace std;
-ExpStack g_exp_stk;
+static COND_EXPR *dstIdent (PICODE pIcode, PPROC pProc, Int i, PICODE duIcode,
+                            operDu du) 
+/* Returns the destination operand */
+{ COND_EXPR *n; 
 
-/* Returns the index of the local variable or parameter at offset off, if it
- * is in the stack frame provided.  */
-size_t STKFRAME::getLocVar(int off)
-{
-    auto iter=findByLabel(off);
-    return distance(begin(),iter);
+    n = idCondExp (pIcode, DST, pProc, i, duIcode, du);
+            /** Is it needed? (pIcode->ic.ll.flg) & NO_SRC_B **/
+    return (n);
 }
 
 
-/* Returns a string with the source operand of Icode */
-static COND_EXPR *srcIdent (const LLInst &ll_insn, Function * pProc, iICODE i, ICODE & duIcode, operDu du)
-{
-    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);
-    }
-    // otherwise
-    return COND_EXPR::id (ll_insn, SRC, pProc, i, duIcode, du);
-}
-
 
-/* Returns the destination operand */
-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);
-    /** Is it needed? (pIcode->ll()->flg) & NO_SRC_B **/
-    return (n);
-}
+static void elimCondCodes (PPROC pProc)
 /* Eliminates all condition codes and generates new hlIcode instructions */
-void Function::elimCondCodes ()
-{
-    int i;
-
-    uint8_t use;           /* Used flags bit vector                  */
-    uint8_t def;           /* Defined flags bit vector               */
-    boolT notSup;       /* Use/def combination not supported      */
-    COND_EXPR *rhs;     /* Source operand                         */
-    COND_EXPR *lhs;     /* Destination operand                    */
-    COND_EXPR *_expr;   /* Boolean expression                     */
-    BB * pBB;           /* Pointer to BBs in dfs last ordering    */
-    riICODE useAt;      /* Instruction that used flag    */
-    riICODE defAt;      /* Instruction that defined flag */
-        //lhs=rhs=_expr=0;
-    for (i = 0; i < numBBs; i++)
-    {
-        pBB = m_dfsLast[i];
-        if (pBB->flg & INVALID_BB)
-            continue; /* Do not process invalid BBs */
-        //        auto v(pBB | boost::adaptors::reversed);
-        //        for (const ICODE &useAt : v)
-        //        {}
-        for (useAt = pBB->rbegin(); useAt != pBB->rend(); useAt++)
+{ Int i, 
+      useAt,            /* Index to instruction that used flag    */
+      defAt;            /* Index to instruction that defined flag */
+  byte use;             /* Used flags bit vector                  */
+  byte def;             /* Defined flags bit vector               */
+  boolT notSup;         /* Use/def combination not supported      */
+  COND_EXPR *rhs;       /* Source operand                         */
+  COND_EXPR *lhs;       /* Destination operand                    */
+  COND_EXPR *exp;       /* Boolean expression                     */
+  PBB pBB;              /* Pointer to BBs in dfs last ordering    */
+  ICODE *prev;          /* For extended basic blocks - previous icode inst */
+
+  for (i = 0; i < pProc->numBBs; i++) 
+  {
+    pBB = pProc->dfsLast[i];
+	if (pBB->flg & INVALID_BB)	continue; /* Do not process invalid BBs */
+
+    for (useAt = pBB->start + pBB->length; useAt != pBB->start; useAt--)
+        if ((pProc->Icode.GetIcode(useAt-1)->type == LOW_LEVEL) &&
+            (pProc->Icode.GetIcode(useAt-1)->invalid == FALSE) &&
+            (use = pProc->Icode.GetIcode(useAt-1)->ic.ll.flagDU.u))
         {
-            llIcode useAtOp = llIcode(useAt->ll()->getOpcode());
-            use = useAt->ll()->flagDU.u;
-            if ((useAt->type != LOW_LEVEL) || ( ! useAt->valid() ) || ( 0 == use ))
-                continue;
             /* Find definition within the same basic block */
-            defAt=useAt;
-            ++defAt;
-            for (; defAt != pBB->rend(); defAt++)
+            for (defAt = useAt-1; defAt != pBB->start; defAt--)
             {
-                def = defAt->ll()->flagDU.d;
-                if ((use & def) != use)
-                    continue;
-                notSup = false;
-                if ((useAtOp >= iJB) && (useAtOp <= iJNS))
+                def = pProc->Icode.GetIcode(defAt-1)->ic.ll.flagDU.d;
+                if ((use & def) == use)
                 {
-                    iICODE befDefAt = (++riICODE(defAt)).base();
-                    switch (defAt->ll()->getOpcode())
+                    notSup = FALSE;
+                    if ((pProc->Icode.GetLlOpcode(useAt-1) >= iJB) &&
+                        (pProc->Icode.GetLlOpcode(useAt-1) <= iJNS))
                     {
-                        case iCMP:
-                            rhs = srcIdent (*defAt->ll(), this, befDefAt,*useAt, eUSE);
-                            lhs = dstIdent (*defAt->ll(), this, befDefAt,*useAt, eUSE);
+                        switch (pProc->Icode.GetLlOpcode(defAt-1))
+						{
+                          case iCMP:
+                            rhs = srcIdent (pProc->Icode.GetIcode(defAt-1),
+                                            pProc, defAt-1, 
+                                            pProc->Icode.GetIcode(useAt-1), E_USE);
+                            lhs = dstIdent (pProc->Icode.GetIcode(defAt-1),
+                                            pProc, defAt-1, 
+                                            pProc->Icode.GetIcode(useAt-1), E_USE);
                             break;
 
-                        case iOR:
-                            lhs = defAt->hl()->asgn.lhs->clone();
-                            useAt->copyDU(*defAt, eUSE, eDEF);
-                            if (defAt->ll()->testFlags(B))
-                                rhs = COND_EXPR::idKte (0, 1);
-                            else
-                                rhs = COND_EXPR::idKte (0, 2);
+                          case iOR:
+                            lhs = copyCondExp (pProc->Icode.GetIcode(defAt-1)->ic.hl.oper.asgn.lhs);
+                            copyDU (pProc->Icode.GetIcode(useAt-1),
+                                    pProc->Icode.GetIcode(defAt-1), E_USE, E_DEF);
+							if (pProc->Icode.GetLlFlag(defAt-1) & B)
+                            	rhs = idCondExpKte (0, 1); 
+							else
+                            	rhs = idCondExpKte (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);
-                            if (defAt->ll()->testFlags(B))
-                                rhs = COND_EXPR::idKte (0, 1);
-                            else
-                                rhs = COND_EXPR::idKte (0, 2);
+                          case iTEST:
+                            rhs = srcIdent (pProc->Icode.GetIcode(defAt-1),
+                                            pProc, defAt-1, 
+                                            pProc->Icode.GetIcode(useAt-1), E_USE);
+                            lhs = dstIdent (pProc->Icode.GetIcode(defAt-1), 
+                                            pProc, defAt-1, 
+                                            pProc->Icode.GetIcode(useAt-1), E_USE);
+                            lhs = boolCondExp (lhs, rhs, AND);
+							if (pProc->Icode.GetLlFlag(defAt-1) & B)
+                            	rhs = idCondExpKte (0, 1); 
+							else
+                            	rhs = idCondExpKte (0, 2); 
                             break;
 
-                        default:
-                            notSup = true;
-                            std::cout << hex<<defAt->loc_ip;
-                            reportError (JX_NOT_DEF, defAt->ll()->getOpcode());
-                            flg |= PROC_ASM;		/* generate asm */
+                          default: 
+                            notSup = TRUE;
+							reportError (JX_NOT_DEF, pProc->Icode.GetLlOpcode(defAt-1));
+							pProc->flg |= PROC_ASM;		/* generate asm */
+                        }
+                        if (! notSup)
+                        {
+                            exp = boolCondExp (lhs, rhs,
+                              condOpJCond[pProc->Icode.GetLlOpcode(useAt-1)-iJB]);
+                            newJCondHlIcode (pProc->Icode.GetIcode(useAt-1), exp);
+                        }
                     }
-                    if (! notSup)
+                    
+                    else if (pProc->Icode.GetLlOpcode(useAt-1) == iJCXZ) 
                     {
-                        assert(lhs);
-                        assert(rhs);
-                        _expr = COND_EXPR::boolOp (lhs, rhs,condOpJCond[useAtOp-iJB]);
-                        useAt->setJCond(_expr);
+                        lhs = idCondExpReg (rCX, 0, &pProc->localId);
+                        setRegDU (pProc->Icode.GetIcode(useAt-1), rCX, E_USE);
+                        rhs = idCondExpKte (0, 2);
+                        exp = boolCondExp (lhs, rhs, EQUAL);
+                        newJCondHlIcode (pProc->Icode.GetIcode(useAt-1), exp);
                     }
-                }
 
-                else if (useAtOp == iJCXZ)
-                {
-                    lhs = COND_EXPR::idReg (rCX, 0, &localId);
-                    useAt->setRegDU (rCX, eUSE);
-                    rhs = COND_EXPR::idKte (0, 2);
-                    _expr = COND_EXPR::boolOp (lhs, rhs, EQUAL);
-                    useAt->setJCond(_expr);
-                }
-                //                    else if (useAt->getOpcode() == iRCL)
-                //                    {
-                //                    }
-                else
-                {
-                    ICODE &a(*defAt);
-                    ICODE &b(*useAt);
-                    reportError (NOT_DEF_USE,a.ll()->getOpcode(),b.ll()->getOpcode());
-                    flg |= PROC_ASM;		/* generate asm */
+                    else
+					{
+						reportError (NOT_DEF_USE, 
+                            pProc->Icode.GetLlOpcode(defAt-1),
+                            pProc->Icode.GetLlOpcode(useAt-1));
+						pProc->flg |= PROC_ASM;		/* generate asm */
+					}
+                    break;
                 }
-                break;
             }
 
             /* Check for extended basic block */
-            if ((pBB->size() == 1) &&(useAtOp >= iJB) && (useAtOp <= iJNS))
+            if ((pBB->length == 1) && 
+                (pProc->Icode.GetLlOpcode(useAt-1) >= iJB) &&
+                (pProc->Icode.GetLlOpcode(useAt-1) <= iJNS))
             {
-                ICODE & _prev(pBB->back()); /* For extended basic blocks - previous icode inst */
-                if (_prev.hl()->opcode == HLI_JCOND)
+                prev = pProc->Icode.GetIcode(pBB->inEdges[0]->start + 
+                                            pBB->inEdges[0]->length - 1);
+                if (prev->ic.hl.opcode == HLI_JCOND)
                 {
-                    _expr = _prev.hl()->expr()->clone();
-                    _expr->changeBoolOp (condOpJCond[useAtOp-iJB]);
-                    useAt->copyDU(_prev, eUSE, eUSE);
-                    useAt->setJCond(_expr);
+                    exp = copyCondExp (prev->ic.hl.oper.exp);
+                    changeBoolCondExpOp (exp, 
+                        condOpJCond[pProc->Icode.GetLlOpcode(useAt-1)-iJB]);
+                    copyDU (pProc->Icode.GetIcode(useAt-1), prev, E_USE, E_USE);
+                    newJCondHlIcode (pProc->Icode.GetIcode(useAt-1), exp);
                 }
             }
             /* Error - definition not found for use of a cond code */
-            else if (defAt == pBB->rend())
-            {
-                reportError(DEF_NOT_FOUND,useAtOp);
-                //fatalError (DEF_NOT_FOUND, Icode.getOpcode(useAt-1));
-            }
+            else if (defAt == pBB->start)
+                fatalError (DEF_NOT_FOUND, 
+                            pProc->Icode.GetLlOpcode(useAt-1));
         }
-    }
+  }
 }
 
 
-/** Generates the LiveUse() and Def() sets for each basic block in the graph.
+static void genLiveKtes (PPROC pproc)
+/* Generates the LiveUse() and Def() sets for each basic block in the graph.
  * Note: these sets are constant and could have been constructed during
- *       the construction of the graph, but since the code hasn't been
+ *       the construction of the graph, but since the code hasn't been 
  *       analyzed yet for idioms, the procedure preamble misleads the
  *       analysis (eg: push si, would include si in LiveUse; although it
  *       is not really meant to be a register that is used before defined). */
-void Function::genLiveKtes ()
-{
-    int i;
-    BB * pbb;
-    bitset<32> liveUse, def;
+{ Int i, j;
+  PBB pbb;
+  PICODE picode;
+  dword liveUse, def;
 
-    for (i = 0; i < numBBs; i++)
+    for (i = 0; i < pproc->numBBs; i++)
     {
-        liveUse.reset();
-        def.reset();
-        pbb = m_dfsLast[i];
-        if (pbb->flg & INVALID_BB)
-            continue;	// skip invalid BBs
-        for(ICODE &insn : *pbb)
+        liveUse = def = 0;
+        pbb = pproc->dfsLast[i];
+		if (pbb->flg & INVALID_BB)	continue;	/* skip invalid BBs */
+        for (j = pbb->start; j < (pbb->start + pbb->length); j++)
         {
-            if ((insn.type == HIGH_LEVEL) && ( insn.valid() ))
+            picode = pproc->Icode.GetIcode(j);
+            if ((picode->type == HIGH_LEVEL) && (picode->invalid == FALSE))
             {
-                liveUse |= (insn.du.use & ~def);
-                def |= insn.du.def;
+                liveUse |= (picode->du.use & ~def); 
+                def |= picode->du.def;
             }
         }
         pbb->liveUse = liveUse;
@@ -270,951 +211,888 @@ void Function::genLiveKtes ()
 }
 
 
+static void liveRegAnalysis (PPROC pproc, dword liveOut)
 /* Generates the liveIn() and liveOut() sets for each basic block via an
- * iterative approach.
+ * iterative approach.  
  * Propagates register usage information to the procedure call. */
-void Function::liveRegAnalysis (std::bitset<32> &in_liveOut)
-{
-    using namespace boost::adaptors;
-    using namespace boost::assign;
-    BB * pbb=0;              /* pointer to current basic block   */
-    Function * pcallee;        /* invoked subroutine               */
-    //ICODE  *ticode        /* icode that invokes a subroutine  */
-    ;
-    std::bitset<32> prevLiveOut,	/* previous live out 				*/
-            prevLiveIn;		/* previous live in					*/
-    boolT change;			/* is there change in the live sets?*/
+{ Int i, j;
+  PBB pbb;              /* pointer to current basic block   */
+  PPROC pcallee;        /* invoked subroutine               */
+  PICODE ticode,        /* icode that invokes a subroutine  */
+		 picode;		/* icode of function return			*/
+  dword prevLiveOut,	/* previous live out 				*/
+		prevLiveIn;		/* previous live in					*/
+  boolT change;			/* is there change in the live sets?*/
 
     /* liveOut for this procedure */
-    liveOut = in_liveOut;
-
-    change = true;
-    while (change)
+    pproc->liveOut = liveOut;
+
+  change = TRUE;
+  while (change)
+  {
+    /* Process nodes in reverse postorder order */
+	change = FALSE;
+    for (i = pproc->numBBs; i > 0; i--)
     {
-        /* Process nodes in reverse postorder order */
-        change = false;
-        auto valid_reversed_bbs = (m_dfsLast | reversed | filtered(BB::ValidFunctor()) );
-        for( BB * _pbb : valid_reversed_bbs)
+        pbb = pproc->dfsLast[i-1];
+		if (pbb->flg & INVALID_BB)		/* Do not process invalid BBs */
+			continue;
+
+		/* Get current liveIn() and liveOut() sets */
+		prevLiveIn = pbb->liveIn;
+		prevLiveOut = pbb->liveOut;
+
+        /* liveOut(b) = U LiveIn(s); where s is successor(b) 
+         * liveOut(b) = {liveOut}; when b is a HLI_RET node     */
+        if (pbb->numOutEdges == 0)      /* HLI_RET node         */
+		{
+            pbb->liveOut = liveOut;
+
+			/* Get return expression of function */
+			if (pproc->flg & PROC_IS_FUNC)
+			{
+				picode = pproc->Icode.GetIcode(pbb->start + pbb->length - 1);
+				if (picode->ic.hl.opcode == HLI_RET)
+				{
+					picode->ic.hl.oper.exp = idCondExpID (&pproc->retVal, 
+							&pproc->localId, pbb->start + pbb->length - 1);
+					picode->du.use = liveOut;
+				}
+			}
+		}
+        else                            /* Check successors */
         {
-            pbb = _pbb;//*iBB;//m_dfsLast[i-1];
+            for (j = 0; j < pbb->numOutEdges; j++)
+                pbb->liveOut |= pbb->edges[j].BBptr->liveIn;
 
-            /* Get current liveIn() and liveOut() sets */
-            prevLiveIn = pbb->liveIn;
-            prevLiveOut = pbb->liveOut;
-
-            /* liveOut(b) = U LiveIn(s); where s is successor(b)
-             * liveOut(b) = {liveOut}; when b is a HLI_RET node     */
-            if (pbb->edges.empty())      /* HLI_RET node         */
+            /* propagate to invoked procedure */
+            if (pbb->nodeType == CALL_NODE)
             {
-                pbb->liveOut = in_liveOut;
+                ticode = pproc->Icode.GetIcode(pbb->start + pbb->length - 1);
+                pcallee = ticode->ic.hl.oper.call.proc;
 
-                /* Get return expression of function */
-                if (flg & PROC_IS_FUNC)
+                /* user/runtime routine */
+                if (! (pcallee->flg & PROC_ISLIB))
                 {
-                    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->du.use = in_liveOut;
-                    }
-                }
-            }
-            else                            /* Check successors */
-            {
-                for(TYPEADR_TYPE &e : pbb->edges)
-                {
-                    pbb->liveOut |= e.BBptr->liveIn;
-                }
-
-                /* propagate to invoked procedure */
-                if (pbb->nodeType == CALL_NODE)
-                {
-                    ICODE &ticode(pbb->back());
-                    pcallee = ticode.hl()->call.proc;
-
-                    /* user/runtime routine */
-                    if (! (pcallee->flg & PROC_ISLIB))
-                    {
-                        if (pcallee->liveAnal == false) /* hasn't been processed */
-                            pcallee->dataFlow (pbb->liveOut);
-                        pbb->liveOut = pcallee->liveIn;
-                    }
-                    else    /* library routine */
-                    {
-                        if ( (pcallee->flg & PROC_IS_FUNC) && /* returns a value */
-                             (pcallee->liveOut & pbb->edges[0].BBptr->liveIn).any()
-                             )
-                            pbb->liveOut = pcallee->liveOut;
-                        else
-                            pbb->liveOut = 0;
-                    }
-
-                    if ((! (pcallee->flg & PROC_ISLIB)) || (pbb->liveOut != 0))
-                    {
-                        switch (pcallee->retVal.type) {
-                        case TYPE_LONG_SIGN: case TYPE_LONG_UNSIGN:
-                            ticode.du1.numRegsDef = 2;
-                            break;
-                        case TYPE_WORD_SIGN: case TYPE_WORD_UNSIGN:
-                        case TYPE_BYTE_SIGN: case TYPE_BYTE_UNSIGN:
-                            ticode.du1.numRegsDef = 1;
-                            break;
-                        default:
-                            ticode.du1.numRegsDef = 0;
-                            //fprintf(stderr,"Function::liveRegAnalysis : Unknown return type %d, assume 0\n",pcallee->retVal.type);
-                        } /*eos*/
-
-                        /* Propagate def/use results to calling icode */
-                        ticode.du.use = pcallee->liveIn;
-                        ticode.du.def = pcallee->liveOut;
-                    }
+                    if (pcallee->liveAnal == FALSE) /* hasn't been processed */
+                        dataFlow (pcallee, pbb->liveOut);
+                    pbb->liveOut = pcallee->liveIn;
                 }
+                else    /* library routine */
+				{
+					if ((pcallee->flg & PROC_IS_FUNC) && /* returns a value */
+						(pcallee->liveOut & pbb->edges[0].BBptr->liveIn)) 
+						pbb->liveOut = pcallee->liveOut;
+					else
+                    	pbb->liveOut = 0;
+				} 
+
+				if ((! (pcallee->flg & PROC_ISLIB)) || (pbb->liveOut != 0))
+				{
+					switch (pcallee->retVal.type) {
+				  	case TYPE_LONG_SIGN: case TYPE_LONG_UNSIGN:
+				  		ticode->du1.numRegsDef = 2;
+						break;
+				  	case TYPE_WORD_SIGN: case TYPE_WORD_UNSIGN:
+				  	case TYPE_BYTE_SIGN: case TYPE_BYTE_UNSIGN:
+                    	ticode->du1.numRegsDef = 1;
+						break;
+               	 	} /*eos*/
+
+                	/* Propagate def/use results to calling icode */
+                	ticode->du.use = pcallee->liveIn;
+                	ticode->du.def = pcallee->liveOut;
+				}
             }
+        }
 
-            /* liveIn(b) = liveUse(b) U (liveOut(b) - def(b) */
-            pbb->liveIn = pbb->liveUse | (pbb->liveOut & ~pbb->def);
+        /* liveIn(b) = liveUse(b) U (liveOut(b) - def(b) */
+        pbb->liveIn = pbb->liveUse | (pbb->liveOut & ~pbb->def);
 
-            /* Check if live sets have been modified */
-            if ((prevLiveIn != pbb->liveIn) || (prevLiveOut != pbb->liveOut))
-                change = true;
-        }
+		/* Check if live sets have been modified */
+		if ((prevLiveIn != pbb->liveIn) || (prevLiveOut != pbb->liveOut))
+			change = TRUE;
     }
+  }
 
     /* Propagate liveIn(b) to procedure header */
     if (pbb->liveIn != 0)   /* uses registers */
-        liveIn = pbb->liveIn;
-
-    /* Remove any references to register variables */
-    if (flg & SI_REGVAR)
-    {
-        liveIn &= maskDuReg[rSI];
-        pbb->liveIn &= maskDuReg[rSI];
-    }
-    if (flg & DI_REGVAR)
-    {
-        liveIn &= maskDuReg[rDI];
-        pbb->liveIn &= maskDuReg[rDI];
-    }
+        pproc->liveIn = pbb->liveIn;
+
+	/* Remove any references to register variables */
+	if (pproc->flg & SI_REGVAR)
+	{
+		pproc->liveIn &= maskDuReg[rSI];
+		pbb->liveIn &= maskDuReg[rSI];
+	}
+	if (pproc->flg & DI_REGVAR)
+	{
+		pproc->liveIn &= maskDuReg[rDI];
+		pbb->liveIn &= maskDuReg[rDI];
+	}
 }
 
-/* Check remaining instructions of the BB for all uses
- * of register regi, before any definitions of the
- * register */
-bool BB::FindUseBeforeDef(eReg regi, int defRegIdx, iICODE start_at)
-{
-    if ((regi == rDI) && (flg & DI_REGVAR))
-        return true;
-    if ((regi == rSI) && (flg & SI_REGVAR))
-        return true;
-    if (distance(start_at,end())>1) /* several instructions */
-    {
-        iICODE ticode=end();
-        auto hl_range=make_iterator_range(start_at,end()) | filtered(ICODE::select_high_level);
-        auto checked_icode=hl_range.begin();
-        ++checked_icode;
-        for (; checked_icode != hl_range.end(); checked_icode++)
-        {
-            if (checked_icode->type != HIGH_LEVEL) // Only check uses of HIGH_LEVEL icodes
-                continue;
-            /* if used, get icode index */
-            if ((checked_icode->du.use & duReg[regi]).any())
-                start_at->du1.recordUse(defRegIdx,checked_icode.base());
-            /* if defined, stop finding uses for this reg */
-            if ((checked_icode->du.def & duReg[regi]).any())
-            {
-                ticode=checked_icode.base();
-                break;
-            }
-        }
-        if(ticode==end())
-            ticode=(++riICODE(rbegin())).base();
-
-        /* Check if last definition of this register */
-        if ((not (ticode->du.def & duReg[regi]).any()) and (liveOut & duReg[regi]).any())
-            start_at->du.lastDefRegi |= duReg[regi];
-    }
-    else		/* only 1 instruction in this basic block */
-    {
-        /* Check if last definition of this register */
-        if ((liveOut & duReg[regi]).any())
-            start_at->du.lastDefRegi |= duReg[regi];
-    }
-    return false;
-}
-/* Find target icode for HLI_CALL icodes to procedures
- * that are functions.  The target icode is in the
- * next basic block (unoptimized code) or somewhere else
- * on optimized code. */
-void BB::ProcessUseDefForFunc(eReg regi, int defRegIdx, iICODE picode)
-{
-    if ((picode->hl()->opcode == HLI_CALL) &&
-            (picode->hl()->call.proc->flg & PROC_IS_FUNC))
-    {
-        BB *tbb = this->edges[0].BBptr;
-        auto target_instructions = tbb->instructions | filtered(ICODE::select_high_level);
-        for (auto iter=target_instructions.begin(); iter!=target_instructions.end(); ++iter)
-        {
-            /* if used, get icode index */
-            if ((iter->du.use & duReg[regi]).any())
-                picode->du1.recordUse(defRegIdx,iter.base());
-            /* if defined, stop finding uses for this reg */
-            if ((iter->du.def & duReg[regi]).any())
-                break;
-        }
 
-        /* if not used in this basic block, check if the
-         * register is live out, if so, make it the last
-         * definition of this register */
-        if ( picode->du1.used(defRegIdx) && (tbb->liveOut & duReg[regi]).any())
-            picode->du.lastDefRegi |= duReg[regi];
-    }
-}
+static void genDU1 (PPROC pProc)
+/* Generates the du chain of each instruction in a basic block */
+{ byte regi;            /* Register that was defined */
+  Int i, j, k, p, n, lastInst, defRegIdx, useIdx;
+  PICODE picode, ticode;/* Current and target bb    */
+  PBB pbb, tbb;         /* Current and target basic block */
+  boolT res;
+  COND_EXPR *exp, *lhs;
 
-/* If not used within this bb or in successors of this
- * bb (ie. not in liveOut), then register is useless,
- * thus remove it.  Also check that this is not a return
- * from a library function (routines such as printf
- * return an integer, which is normally not taken into
- * account by the programmer). 	*/
-void BB::RemoveUnusedDefs(eReg regi, int defRegIdx, iICODE picode)
-{
-    if (picode->valid() and not picode->du1.used(defRegIdx) and
-            (not (picode->du.lastDefRegi & duReg[regi]).any()) &&
-            (not ((picode->hl()->opcode == HLI_CALL) &&
-                  (picode->hl()->call.proc->flg & PROC_ISLIB))))
+    /* Traverse tree in dfsLast order */
+    for (i = 0; i < pProc->numBBs; i++)
     {
-        if (! (this->liveOut & duReg[regi]).any())	/* not liveOut */
+        pbb = pProc->dfsLast[i];
+		if (pbb->flg & INVALID_BB)	continue;
+
+        /* Process each register definition of a HIGH_LEVEL icode instruction.  
+         * Note that register variables should not be considered registers.  
+         */
+        lastInst = pbb->start + pbb->length;
+        for (j = pbb->start; j < lastInst; j++)
         {
-            bool res = picode->removeDefRegi (regi, defRegIdx+1,&Parent->localId);
-            if (res == true)
+            picode = pProc->Icode.GetIcode(j);
+            if (picode->type == HIGH_LEVEL)
             {
-
-                /* Backpatch any uses of this instruction, within
-                 * the same BB, if the instruction was invalidated */
-                rICODE the_rest(begin(),picode);
-                for ( ICODE &back_patch_at : the_rest|reversed)
+              regi = 0;
+              defRegIdx = 0;
+              for (k = 0; k < INDEXBASE; k++)
+              {
+                if ((picode->du.def & power2(k)) != 0)
                 {
-                    back_patch_at.du1.remove(0,picode);
+                    regi = (byte)(k + 1);       /* defined register */
+					picode->du1.regi[defRegIdx] = regi;
+
+                    /* Check remaining instructions of the BB for all uses
+                     * of register regi, before any definitions of the
+                     * register */
+                    if ((regi == rDI) && (pProc->flg & DI_REGVAR))
+                        continue;
+                    if ((regi == rSI) && (pProc->flg & SI_REGVAR))
+                        continue;
+                    if ((j + 1) < lastInst)		/* several instructions */
+                    {
+                        useIdx = 0;
+                        for (n = j+1; n < lastInst; n++)
+                        {
+                            /* Only check uses of HIGH_LEVEL icodes */
+                            ticode = pProc->Icode.GetIcode(n);
+                            if (ticode->type == HIGH_LEVEL) 
+                            {
+                                /* if used, get icode index */
+                                if (ticode->du.use & duReg[regi])
+                                    picode->du1.idx[defRegIdx][useIdx++] = n;
+
+                                /* if defined, stop finding uses for this reg */
+                                if (ticode->du.def & duReg[regi])
+                                    break;
+                            }
+                        }
+
+						/* Check if last definition of this register */
+						if ((! (ticode->du.def & duReg[regi])) &&
+                      		(pbb->liveOut & duReg[regi]))
+							picode->du.lastDefRegi |= duReg[regi]; 
+                    }
+					else		/* only 1 instruction in this basic block */
+					{
+						/* Check if last definition of this register */
+                      	if (pbb->liveOut & duReg[regi])
+							picode->du.lastDefRegi |= duReg[regi]; 
+					}
+
+					/* Find target icode for HLI_CALL icodes to procedures
+					 * that are functions.  The target icode is in the
+					 * next basic block (unoptimized code) or somewhere else
+					 * on optimized code. */
+					if ((picode->ic.hl.opcode == HLI_CALL) && 
+						(picode->ic.hl.oper.call.proc->flg & PROC_IS_FUNC))
+					{
+						tbb = pbb->edges[0].BBptr;
+						useIdx = 0;
+						for (n = tbb->start; n < tbb->start + tbb->length; n++)
+						{
+							ticode = pProc->Icode.GetIcode(n);
+							if (ticode->type == HIGH_LEVEL)
+							{
+                                /* if used, get icode index */
+                                if (ticode->du.use & duReg[regi])
+                                    picode->du1.idx[defRegIdx][useIdx++] = n;
+
+                                /* if defined, stop finding uses for this reg */
+                                if (ticode->du.def & duReg[regi])
+                                    break;
+							}
+						}
+
+						/* if not used in this basic block, check if the
+						 * register is live out, if so, make it the last
+						 * definition of this register */
+						if ((picode->du1.idx[defRegIdx][useIdx] == 0) &&
+							(tbb->liveOut & duReg[regi]))
+							picode->du.lastDefRegi |= duReg[regi];
+					}
+
+                    /* If not used within this bb or in successors of this
+                     * bb (ie. not in liveOut), then register is useless, 
+                     * thus remove it.  Also check that this is not a return
+					 * from a library function (routines such as printf 
+					 * return an integer, which is normally not taken into
+					 * account by the programmer). 	*/
+                    if ((picode->invalid == FALSE) &&
+						(picode->du1.idx[defRegIdx][0] == 0) &&
+						(! (picode->du.lastDefRegi & duReg[regi])) &&
+//						(! ((picode->ic.hl.opcode != HLI_CALL) &&
+						(! ((picode->ic.hl.opcode == HLI_CALL) &&
+							(picode->ic.hl.oper.call.proc->flg & PROC_ISLIB)))) 
+					{
+                      if (! (pbb->liveOut & duReg[regi]))	/* not liveOut */
+                      {
+                        res = removeDefRegi (regi, picode, defRegIdx+1,
+                                             &pProc->localId); 
+
+                        /* Backpatch any uses of this instruction, within
+                         * the same BB, if the instruction was invalidated */
+                        if (res == TRUE) 
+                            for (p = j; p > pbb->start; p--)
+                            {
+                                ticode = pProc->Icode.GetIcode(p-1);
+                                for (n = 0; n < MAX_USES; n++) 
+                                {
+                                    if (ticode->du1.idx[0][n] == j)
+                                    {
+                                        if (n < MAX_USES - 1)
+                                        {
+                                            memmove (&ticode->du1.idx[0][n],
+                                             &ticode->du1.idx[0][n+1], 
+                                             (size_t)((MAX_USES - n - 1) * sizeof(Int)));
+                                            n--;
+                                        }
+                                        ticode->du1.idx[0][MAX_USES - 1] = 0;
+                                    }
+                                }
+                            }
+                      }
+					  else		/* liveOut */
+						picode->du.lastDefRegi |= duReg[regi];
+					}
+                    defRegIdx++;
+
+                    /* Check if all defined registers have been processed */
+                    if ((defRegIdx >= picode->du1.numRegsDef) ||
+                        (defRegIdx == MAX_REGS_DEF))
+                        break;
                 }
-            }
+              }
+            }   
         }
-        else		/* liveOut */
-            picode->du.lastDefRegi |= duReg[regi];
     }
-}
 
-void BB::genDU1()
-{
-    /* Process each register definition of a HIGH_LEVEL icode instruction.
-     * Note that register variables should not be considered registers.
-     */
-    assert(0!=Parent);
-    ICODE::TypeFilter<HIGH_LEVEL> select_high_level;
-    auto all_high_levels =  instructions | filtered(select_high_level);
-    printf("\n");
-    for (auto picode=all_high_levels.begin(); picode!=all_high_levels.end(); ++picode)
-    {
-        int defRegIdx = 0;
-        // foreach defined register
-        for (int k = 0; k < INDEX_BX_SI; k++)
-        {
-            if (not picode->du.def.test(k))
-                continue;
-            eReg regi = (eReg)(k + 1);      /* Register that was defined */
-            picode->du1.regi[defRegIdx] = regi;
-
-            if(FindUseBeforeDef(regi,defRegIdx, picode.base()))
-                continue;
-
-            ProcessUseDefForFunc(regi, defRegIdx,picode.base());
-            RemoveUnusedDefs(regi, defRegIdx, picode.base());
-
-            defRegIdx++;
-
-            /* Check if all defined registers have been processed */
-            if ((defRegIdx >= picode->du1.numRegsDef) || (defRegIdx == MAX_REGS_DEF))
-                break;
-        }
-    }
 }
-/* Generates the du chain of each instruction in a basic block */
-void Function::genDU1 ()
-{
-    /* Traverse tree in dfsLast order */
-    assert(m_dfsLast.size()==numBBs);
-    for(BB *pbb : m_dfsLast | filtered(BB::ValidFunctor()))
-    {
-        pbb->genDU1();
-    }
 
-}
 
+static void forwardSubs (COND_EXPR *lhs, COND_EXPR *rhs, PICODE picode, 
+                         PICODE ticode, LOCAL_ID *locsym, Int *numHlIcodes)
 /* Substitutes the rhs (or lhs if rhs not possible) of ticode for the rhs
  * of picode. */
-void LOCAL_ID::forwardSubs (COND_EXPR *lhs, COND_EXPR *rhs, iICODE picode, iICODE ticode, int &numHlIcodes) const
-{
-    bool res;
+{ boolT res;
 
     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 = insertSubTreeReg (rhs, &ticode->ic.hl.oper.asgn.rhs, 
+                            locsym->id[lhs->expr.ident.idNode.regiIdx].id.regi,
+                            locsym);
     if (res)
-    {
-        picode->invalidate();
-        numHlIcodes--;
-    }
+	{
+        invalidateIcode (picode);   
+		(*numHlIcodes)--;
+	}
     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 = insertSubTreeReg (rhs, &ticode->ic.hl.oper.asgn.lhs,
+                            locsym->id[lhs->expr.ident.idNode.regiIdx].id.regi,
+                            locsym);
         if (res)
-        {
-            picode->invalidate();
-            numHlIcodes--;
-        }
+		{
+            invalidateIcode (picode);
+			(*numHlIcodes)--;
+		}
     }
 }
 
 
-/* Substitutes the rhs (or lhs if rhs not possible) of ticode for the
+static void forwardSubsLong (Int longIdx, COND_EXPR *exp, PICODE picode,
+							 PICODE ticode, Int *numHlIcodes) 
+/* Substitutes the rhs (or lhs if rhs not possible) of ticode for the 
  * expression exp given */
-static void forwardSubsLong (int longIdx, COND_EXPR *_exp, iICODE picode, iICODE ticode, int *numHlIcodes)
-{
-    bool res;
+{ boolT res;
 
-    if (_exp == NULL)        /* In case expression popped is NULL */
+    if (exp == NULL)        /* In case expression popped is NULL */
         return;
 
     /* Insert on rhs of ticode, if possible */
-    res = COND_EXPR::insertSubTreeLongReg (_exp, &ticode->hl()->asgn.rhs, longIdx);
+    res = insertSubTreeLongReg (exp, &ticode->ic.hl.oper.asgn.rhs, longIdx);
     if (res)
-    {
-        picode->invalidate();
-        (*numHlIcodes)--;
-    }
+	{
+        invalidateIcode (picode);   
+		(*numHlIcodes)--;
+	}
     else
     {
         /* Try to insert it on lhs of ticode*/
-        res = COND_EXPR::insertSubTreeLongReg (_exp, &ticode->hl()->asgn.lhs, longIdx);
+        res = insertSubTreeLongReg (exp, &ticode->ic.hl.oper.asgn.lhs, longIdx);
         if (res)
-        {
-            picode->invalidate();
-            (*numHlIcodes)--;
-        }
+		{
+            invalidateIcode (picode);
+			(*numHlIcodes)--;
+		}
     }
 }
 
 
+static boolT xClear (COND_EXPR *rhs, Int f, Int t, Int lastBBinst, PPROC pproc)
 /* 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);
-    } /* eos */
-    return false;
-}
-bool UnaryOperator::xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locs)
-{
-    if(0==unaryExp)
-        return false;
-    return unaryExp->xClear ( range_to_check, lastBBinst, locs);
+{ Int i;
+  boolT res;
+  byte regi;
+  PICODE picode;
+ 
+	if (rhs == NULL)
+		return (FALSE);
+
+	switch (rhs->type) {
+	  case IDENTIFIER:
+			if (rhs->expr.ident.idType == REGISTER)
+			{
+				picode = pproc->Icode.GetFirstIcode();
+				regi= pproc->localId.id[rhs->expr.ident.idNode.regiIdx].id.regi;
+				for (i = (f + 1); (i < lastBBinst) && (i < t); i++)
+					if ((picode[i].type == HIGH_LEVEL) &&
+						(picode[i].invalid == FALSE))
+					{
+						if (picode[i].du.def & duReg[regi])
+							return (FALSE);
+					}
+				if (i < lastBBinst)
+					return (TRUE);
+				else
+					return (FALSE);	
+			}
+			else
+				return (TRUE);
+			/* else if (rhs->expr.ident.idType == LONG_VAR)
+			{
+missing all other identifiers ****
+			} */
+
+	  case BOOLEAN_OP:
+			res = xClear (rhs->expr.boolExpr.rhs, f, t, lastBBinst, pproc);
+			if (res == FALSE)
+				return (FALSE);
+			return (xClear (rhs->expr.boolExpr.lhs, f, t, lastBBinst, pproc));
+
+	  case NEGATION:
+	  case ADDRESSOF:
+	  case DEREFERENCE:
+			return (xClear (rhs->expr.unaryExp, f, t, lastBBinst, pproc));
+	} /* eos */
+	return FALSE;
 }
 
-bool BinaryOperator::xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locs)
-{
-    if(0==m_rhs)
-        return false;
-    if ( ! m_rhs->xClear (range_to_check, lastBBinst, locs) )
-        return false;
-    if(0==m_lhs)
-        return false;
-    return m_lhs->xClear (range_to_check, lastBBinst, locs);
-}
+
+static void processCArg (PPROC pp, PPROC pProc, PICODE picode, Int numArgs,
+						 Int *k)
 /* 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.	*/
-/// @returns the type size of the stored Arg
-static int processCArg (Function * pp, Function * pProc, ICODE * picode, int numArgs)
-{
-    COND_EXPR *_exp;
-    bool res;
-
-    /* if (numArgs == 0)
-                return; */
-
-    _exp = g_exp_stk.pop();
-    if (pp->flg & PROC_ISLIB) /* library function */
-    {
-        if (pp->args.numArgs > 0)
-            if (pp->flg & PROC_VARARG)
-            {
-                if (numArgs < pp->args.size())
-                    adjustActArgType (_exp, pp->args[numArgs].type, pProc);
-            }
-            else
-                adjustActArgType (_exp, pp->args[numArgs].type, pProc);
-    }
-    else			/* user function */
-    {
-        if (pp->args.numArgs > 0)
-        {
-            if(_exp==NULL)
-                fprintf(stderr,"Would try to adjustForArgType with null _exp\n");
-            else
-                pp->args.adjustForArgType (numArgs, _exp->expType (pProc));
-        }
-    }
-    res = picode->newStkArg (_exp, (llIcode)picode->ll()->getOpcode(), pProc);
-
-    /* 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);
-    return 0; // be default we do not know the size of the argument
+{ COND_EXPR *exp;
+  boolT res;
+
+	/* if (numArgs == 0)
+		return; */
+
+	exp = popExpStk();
+	if (pp->flg & PROC_ISLIB) /* library function */
+	{
+	  if (pp->args.numArgs > 0)
+		if (pp->flg & PROC_VARARG) 
+		{
+			if (numArgs < pp->args.csym)
+				adjustActArgType (exp, pp->args.sym[numArgs].type, pProc);
+		}
+		else
+			adjustActArgType (exp, pp->args.sym[numArgs].type, pProc);
+	  res = newStkArg (picode, exp, picode->ic.ll.opcode, pProc);
+	}
+	else			/* user function */
+	{
+		if (pp->args.numArgs > 0)
+			adjustForArgType (&pp->args, numArgs, expType (exp, pProc));
+		res = newStkArg (picode, exp, picode->ic.ll.opcode, pProc);
+	}
+
+	/* Do not update the size of k if the expression was a segment register
+	 * in a near call */
+	if (res == FALSE)
+		*k += hlTypeSize (exp, pProc);
 }
 
-/** Eliminates extraneous intermediate icode instructions when finding
- * expressions.  Generates new hlIcodes in the form of expression trees.
- * For HLI_CALL hlIcodes, places the arguments in the argument list.    */
-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());
-    switch (t_hl.opcode)
-    {
-    case HLI_ASSIGN:
-        if(isLong)
-        {
-            forwardSubsLong (p_hl.asgn.lhs->expr.ident.idNode.longIdx,
-                             p_hl.asgn.rhs, picode,ticode,
-                             &numHlIcodes);
-        }
-        else
-            this->forwardSubs (p_hl.asgn.lhs, p_hl.asgn.rhs, picode, ticode, numHlIcodes);
-        break;
-
-    case HLI_JCOND:  case HLI_PUSH:  case HLI_RET:
-        if(isLong)
-        {
-            res = COND_EXPR::insertSubTreeLongReg (
-                        p_hl.asgn.rhs,
-                        &t_hl.exp.v,
-                        p_hl.asgn.lhs->expr.ident.idNode.longIdx);
-        }
-        else
-        {
-            res = COND_EXPR::insertSubTreeReg (
-                        t_hl.exp.v,
-                        p_hl.asgn.rhs,
-                        id_arr[p_hl.asgn.lhs->expr.ident.idNode.regiIdx].id.regi,
-                        this);
-        }
-        if (res)
-        {
-            picode->invalidate();
-            numHlIcodes--;
-        }
-        break;
 
-    case HLI_CALL:    /* register arguments */
-        newRegArg ( picode, ticode);
-        picode->invalidate();
-        numHlIcodes--;
-        break;
-    }
-}
+static void findExps (PPROC pProc)
+/* Eliminates extraneous intermediate icode instructions when finding
+ * expressions.  Generates new hlIcodes in the form of expression trees. 
+ * For HLI_CALL hlIcodes, places the arguments in the argument list.    */
+{ Int i, j, k, lastInst, lastInstN, numHlIcodes;
+  PICODE picode,        /* Current icode                            */
+         ticode;        /* Target icode                             */
+  PBB pbb, nbb;         /* Current and next basic block             */
+  boolT res;
+  COND_EXPR *exp,       /* expression pointer - for HLI_POP and HLI_CALL    */
+			*lhs;		/* exp ptr for return value of a HLI_CALL		*/
+  PSTKFRAME args;       /* pointer to arguments - for HLI_CALL          */
+  byte regi, regi2;		/* register(s) to be forward substituted	*/
+  ID *retVal;			/* function return value 					*/
+
+	/* Initialize expression stack */
+    initExpStk();
 
-void Function::processHliCall(COND_EXPR *_exp, iICODE picode)
-{
-    Function * pp;
-    int cb, numArgs;
-    boolT res;
-    int k;
-    pp = picode->hl()->call.proc;
-    if (pp->flg & CALL_PASCAL)
+    /* Traverse tree in dfsLast order */
+    for (i = 0; i < pProc->numBBs; i++)
     {
-        cb = pp->cbParam;	/* fixed # arguments */
-        k = 0;
-        numArgs = 0;
-        while(k<cb)
+        /* Process one BB */
+        pbb = pProc->dfsLast[i];
+		if (pbb->flg & INVALID_BB) 	continue;
+        lastInst = pbb->start + pbb->length;
+		numHlIcodes = 0;
+        for (j = pbb->start; j < lastInst; j++)
         {
-            _exp = g_exp_stk.pop();
-            if (pp->flg & PROC_ISLIB)	/* library function */
-            {
-                if (pp->args.numArgs > 0)
-                    adjustActArgType(_exp, pp->args[numArgs].type, this);
-                res = picode->newStkArg (_exp, (llIcode)picode->ll()->getOpcode(), this);
-            }
-            else			/* user function */
+            picode = pProc->Icode.GetIcode(j);
+            if ((picode->type == HIGH_LEVEL) && (picode->invalid == FALSE))
             {
-                if (pp->args.numArgs >0)
+				numHlIcodes++;
+                if (picode->du1.numRegsDef == 1)    /* byte/word regs */ 
                 {
-                    if(_exp==NULL)
+                    /* Check for only one use of this register.  If this is 
+					 * the last definition of the register in this BB, check
+					 * that it is not liveOut from this basic block */
+                    if ((picode->du1.idx[0][0] != 0) && 
+                        (picode->du1.idx[0][1] == 0)) 
                     {
-                        fprintf(stderr,"Would try to adjustForArgType with null _exp\n");
-                    }
-                    pp->args.adjustForArgType (numArgs,_exp->expType (this));
-                }
-                res = picode->newStkArg (_exp,(llIcode)picode->ll()->getOpcode(), this);
-            }
-            if (res == false)
-                k += hlTypeSize (_exp, this);
-            numArgs++;
-        }
-    }
-    else		/* CALL_C */
-    {
-        cb = picode->hl()->call.args->cb;
-        numArgs = 0;
-        k = 0;
-        if (cb)
-        {
-            while ( k < cb )
-            {
-                k+=processCArg (pp, this, &(*picode), numArgs);
-                numArgs++;
-            }
-        }
-        else if ((cb == 0) && picode->ll()->testFlags(REST_STK))
-        {
-            while (! g_exp_stk.empty())
-            {
-                k+=processCArg (pp, this, &(*picode), numArgs);
-                numArgs++;
-            }
-        }
-    }
-}
-
-
-int BB::findBBExps(LOCAL_ID &locals,Function *fnc)
-{
-    bool res;
-
-    ID *_retVal;         // function return value
-    COND_EXPR *_exp,     // expression pointer - for HLI_POP and HLI_CALL    */
-            *lhs;	// exp ptr for return value of a HLI_CALL		*/
-    iICODE ticode;     // Target icode                             */
-    HLTYPE *ti_hl=0;
-    uint8_t regi;
-    numHlIcodes = 0;
-    // register(s) to be forward substituted	*/
-    auto valid_and_highlevel = instructions | filtered(ICODE::TypeAndValidFilter<HIGH_LEVEL>());
-    for (auto picode = valid_and_highlevel.begin(); picode != valid_and_highlevel.end(); picode++)
-    {
-//        if ((picode->type != HIGH_LEVEL) || ( ! picode->valid() ))
-//            continue;
-        HLTYPE &_icHl(*picode->hl());
-        numHlIcodes++;
-        if (picode->du1.numRegsDef == 1)    /* uint8_t/uint16_t regs */
-        {
-            /* Check for only one use of this register.  If this is
-             * the last definition of the register in this BB, check
-             * that it is not liveOut from this basic block */
-            if (picode->du1.numUses(0)==1)
-            {
-                /* Check that this register is not liveOut, if it
-                 * is the last definition of the register */
-                regi = picode->du1.regi[0];
-
-                /* Check if we can forward substitute this register */
-                switch (_icHl.opcode)
-                {
-                    case HLI_ASSIGN:
-                        /* Replace rhs of current icode into target
-                         * icode expression */
-
-                        ticode = picode->du1.idx[0].uses.front();
-                        if ((picode->du.lastDefRegi & duReg[regi]).any() &&
-                                ((ticode->hl()->opcode != HLI_CALL) &&
-                                 (ticode->hl()->opcode != HLI_RET)))
-                            continue;
-
-                        if (_icHl.asgn.rhs->xClear (make_iterator_range(picode.base(),picode->du1.idx[0].uses[0]),
-                                                    end(), locals))
-                        {
-                            locals.processTargetIcode(picode.base(), numHlIcodes, ticode,false);
-                        }
-                        break;
-
-                    case HLI_POP:
-                        ticode = picode->du1.idx[0].uses.front();
-                        ti_hl = ticode->hl();
-                        if ((picode->du.lastDefRegi & duReg[regi]).any() &&
-                                ((ti_hl->opcode != HLI_CALL) &&
-                                 (ti_hl->opcode != HLI_RET)))
-                            continue;
-
-                        _exp = g_exp_stk.pop();  /* pop last exp pushed */
-                        switch (ticode->hl()->opcode) {
-                            case HLI_ASSIGN:
-                                locals.forwardSubs(_icHl.expr(), _exp, picode.base(), ticode, numHlIcodes);
-                                break;
+						/* Check that this register is not liveOut, if it
+						 * is the last definition of the register */
+						regi = picode->du1.regi[0];
+
+						/* Check if we can forward substitute this register */
+                        switch (picode->ic.hl.opcode) {
+                        case HLI_ASSIGN:    
+                            /* Replace rhs of current icode into target
+                             * icode expression */
+                            ticode = pProc->Icode.GetIcode(picode->du1.idx[0][0]);
+							if ((picode->du.lastDefRegi & duReg[regi]) &&
+								((ticode->ic.hl.opcode != HLI_CALL) &&
+								 (ticode->ic.hl.opcode != HLI_RET)))
+								continue;
+
+							if (xClear (picode->ic.hl.oper.asgn.rhs, j,
+									picode->du1.idx[0][0],  lastInst, pProc)) 
+							{
+                              switch (ticode->ic.hl.opcode) {
+							  case HLI_ASSIGN:
+                                    forwardSubs (picode->ic.hl.oper.asgn.lhs,
+                                            picode->ic.hl.oper.asgn.rhs,
+                                            picode, ticode, &pProc->localId,
+											&numHlIcodes);
+                                    break;
 
-                            case HLI_JCOND: case HLI_PUSH: case HLI_RET:
-                                res = COND_EXPR::insertSubTreeReg (ti_hl->exp.v,
-                                                                   _exp,
-                                                                   locals.id_arr[_icHl.expr()->expr.ident.idNode.regiIdx].id.regi,
-                                                                   &locals);
+                              case HLI_JCOND: case HLI_PUSH: case HLI_RET:
+                                res = insertSubTreeReg (
+                                    picode->ic.hl.oper.asgn.rhs,
+                                    &ticode->ic.hl.oper.exp,
+                                    pProc->localId.id[picode->ic.hl.oper.asgn.lhs->expr.ident.idNode.regiIdx].id.regi,
+                                    &pProc->localId);
                                 if (res)
-                                {
-                                    picode->invalidate();
-                                    numHlIcodes--;
-                                }
+								{
+                                    invalidateIcode (picode);
+									numHlIcodes--;
+								}
                                 break;
 
-                                /****case HLI_CALL:    /* register arguments
-                        newRegArg (pProc, picode, ticode);
-                        picode->invalidate();
-                        numHlIcodes--;
-                        break;	*/
-                        } /* eos */
-                        break;
-
-                    case HLI_CALL:
-                        ticode = picode->du1.idx[0].uses.front();
-                        ti_hl = ticode->hl();
-                        _retVal = &_icHl.call.proc->retVal;
-                        switch (ti_hl->opcode)
-                        {
-                            case HLI_ASSIGN:
-                                assert(ti_hl->asgn.rhs);
-                                _exp = _icHl.call.toId();
-                                res = COND_EXPR::insertSubTreeReg (ti_hl->asgn.rhs,_exp, _retVal->id.regi, &locals);
-                                if (! res)
-                                    COND_EXPR::insertSubTreeReg (ti_hl->asgn.lhs, _exp,_retVal->id.regi, &locals);
-                                //TODO: HERE missing: 2 regs
-                                picode->invalidate();
-                                numHlIcodes--;
+                              case HLI_CALL:    /* register arguments */
+                                newRegArg (pProc, picode, ticode);
+								invalidateIcode (picode);
+								numHlIcodes--;
                                 break;
+                              } /* eos */
+							}
+                            break;
 
-                            case HLI_PUSH: case HLI_RET:
-                                ti_hl->expr( _icHl.call.toId() );
-                                picode->invalidate();
-                                numHlIcodes--;
+                        case HLI_POP:
+                            ticode = pProc->Icode.GetIcode(picode->du1.idx[0][0]);
+							if ((picode->du.lastDefRegi & duReg[regi]) &&
+								((ticode->ic.hl.opcode != HLI_CALL) &&
+								 (ticode->ic.hl.opcode != HLI_RET)))
+								continue;
+
+                            exp = popExpStk();  /* pop last exp pushed */
+                            switch (ticode->ic.hl.opcode) {
+                              case HLI_ASSIGN:
+                                forwardSubs (picode->ic.hl.oper.exp, exp, 
+                                             picode, ticode, &pProc->localId,
+											 &numHlIcodes); 
                                 break;
 
-                            case HLI_JCOND:
-                                _exp = _icHl.call.toId();
-                                res = COND_EXPR::insertSubTreeReg (ti_hl->exp.v, _exp, _retVal->id.regi, &locals);
-                                if (res)	/* was substituted */
-                                {
-                                    picode->invalidate();
-                                    numHlIcodes--;
-                                }
-                                else	/* cannot substitute function */
-                                {
-                                    //picode->loc_ip
-                                    lhs = COND_EXPR::idID(_retVal,&locals,picode.base());
-                                    picode->setAsgn(lhs, _exp);
-                                }
+                              case HLI_JCOND: case HLI_PUSH: case HLI_RET:
+                                res = insertSubTreeReg (exp,
+                                    &ticode->ic.hl.oper.exp,
+                                    pProc->localId.id[picode->ic.hl.oper.exp->expr.ident.idNode.regiIdx].id.regi,
+                                    &pProc->localId);
+                                if (res)
+								{
+                                    invalidateIcode (picode);
+									numHlIcodes--;
+								}
                                 break;
-                        } /* eos */
-                        break;
-                } /* eos */
-            }
-        }
 
-        else if (picode->du1.numRegsDef == 2)   /* long regs */
-        {
-            /* Check for only one use of these registers */
-            if ((picode->du1.numUses(0) == 1) and (picode->du1.numUses(1) == 1))
-            {
-                regi = picode->du1.regi[0]; //TODO: verify that regi actually should be assigned this
+                              /****case HLI_CALL:    /* register arguments 
+                                newRegArg (pProc, picode, ticode);
+								invalidateIcode (picode);
+								numHlIcodes--;
+								break;	*/
+                            } /* eos */
+                            break;
 
-                switch (_icHl.opcode)
-                {
-                    case HLI_ASSIGN:
-                        /* Replace rhs of current icode into target
-                         * icode expression */
-                        if (picode->du1.idx[0].uses[0] == picode->du1.idx[1].uses[0])
-                        {
-                            ticode = picode->du1.idx[0].uses.front();
-                            if ((picode->du.lastDefRegi & duReg[regi]).any() &&
-                                    ((ticode->hl()->opcode != HLI_CALL) &&
-                                     (ticode->hl()->opcode != HLI_RET)))
-                                continue;
-                            locals.processTargetIcode(picode.base(), numHlIcodes, ticode,true);
-                        }
-                        break;
+                        case HLI_CALL:  
+							ticode = pProc->Icode.GetIcode(picode->du1.idx[0][0]);
+                            switch (ticode->ic.hl.opcode) {
+                              case HLI_ASSIGN:
+								  exp = idCondExpFunc (
+												picode->ic.hl.oper.call.proc,
+												picode->ic.hl.oper.call.args);
+                                  res = insertSubTreeReg (exp,
+                                    	&ticode->ic.hl.oper.asgn.rhs,
+										picode->ic.hl.oper.call.proc->retVal.id.regi,
+                                    	&pProc->localId);
+								  if (! res)
+                                  	insertSubTreeReg (exp,
+                                    	&ticode->ic.hl.oper.asgn.lhs,
+										picode->ic.hl.oper.call.proc->retVal.id.regi,
+                                    	&pProc->localId);
+	/***  HERE missing: 2 regs ****/
+                              	  invalidateIcode (picode); 
+								  numHlIcodes--;
+                              	  break;
+
+                              case HLI_PUSH: case HLI_RET:
+                              	  exp = idCondExpFunc (
+												picode->ic.hl.oper.call.proc,
+												picode->ic.hl.oper.call.args);
+							  	  ticode->ic.hl.oper.exp = exp;	
+							  	  invalidateIcode (picode);
+								  numHlIcodes--;
+                              	  break; 
+
+							  case HLI_JCOND:
+								exp = idCondExpFunc (
+												picode->ic.hl.oper.call.proc,
+												picode->ic.hl.oper.call.args);
+								retVal = &picode->ic.hl.oper.call.proc->retVal,
+                                res = insertSubTreeReg (exp, 
+										&ticode->ic.hl.oper.exp,
+										retVal->id.regi, &pProc->localId);
+                                if (res)	/* was substituted */
+								{
+                              		invalidateIcode (picode);
+									numHlIcodes--;
+								}
+								else	/* cannot substitute function */
+								{
+									lhs = idCondExpID(retVal,&pProc->localId,j);
+									newAsgnHlIcode (picode, lhs, exp);
+								}
+								break;
+                            } /* eos */
+                            break;
+                      } /* eos */
+                    }
+                }
 
-                    case HLI_POP:
-                        if (picode->du1.idx[0].uses[0] == picode->du1.idx[1].uses[0])
-                        {
-                            ticode = picode->du1.idx[0].uses.front();
-                            if ((picode->du.lastDefRegi & duReg[regi]).any() &&
-                                    ((ticode->hl()->opcode != HLI_CALL) &&
-                                     (ticode->hl()->opcode != HLI_RET)))
-                                continue;
-
-                            _exp = g_exp_stk.pop(); /* pop last exp pushed */
-                            switch (ticode->hl()->opcode) {
-                                case HLI_ASSIGN:
-                                    forwardSubsLong (_icHl.expr()->expr.ident.idNode.longIdx,
-                                                     _exp, picode.base(), ticode, &numHlIcodes);
+                else if (picode->du1.numRegsDef == 2)   /* long regs */
+                {
+                    /* Check for only one use of these registers */
+                    if ((picode->du1.idx[0][0] != 0) && 
+						(picode->du1.idx[0][1] == 0) && 
+                        (picode->du1.idx[1][0] != 0) &&
+                        (picode->du1.idx[1][1] == 0))
+                    {
+                        switch (picode->ic.hl.opcode) {
+                          case HLI_ASSIGN:  
+                            /* Replace rhs of current icode into target
+                             * icode expression */
+                            if (picode->du1.idx[0][0] == picode->du1.idx[1][0])
+                            {
+                                ticode = pProc->Icode.GetIcode(picode->du1.idx[0][0]);
+								if ((picode->du.lastDefRegi & duReg[regi]) &&
+									((ticode->ic.hl.opcode != HLI_CALL) &&
+								 	 (ticode->ic.hl.opcode != HLI_RET)))
+								continue;
+
+                                switch (ticode->ic.hl.opcode) {
+                                  case HLI_ASSIGN:
+									forwardSubsLong (picode->ic.hl.oper.asgn.lhs->expr.ident.idNode.longIdx,
+										picode->ic.hl.oper.asgn.rhs, picode,
+										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);
+
+                                  case HLI_JCOND:  case HLI_PUSH:  case HLI_RET:
+                                    res = insertSubTreeLongReg (
+                                        picode->ic.hl.oper.asgn.rhs,
+                                        &ticode->ic.hl.oper.exp,
+                                        picode->ic.hl.oper.asgn.lhs->expr.ident.idNode.longIdx);
                                     if (res)
-                                    {
-                                        picode->invalidate();
-                                        numHlIcodes--;
-                                    }
+									{
+                                        invalidateIcode (picode);
+										numHlIcodes--;
+									}
                                     break;
-                                case HLI_CALL:	/*** missing ***/
-                                    break;
-                            } /* eos */
-                        }
-                        break;
 
-                    case HLI_CALL:    /* check for function return */
-                        ticode = picode->du1.idx[0].uses.front();
-                        switch (ticode->hl()->opcode)
-                        {
-                            case HLI_ASSIGN:
-                                _exp = _icHl.call.toId();
-                                ticode->hl()->asgn.lhs =
-                                        COND_EXPR::idLong(&locals, DST,
-                                                          ticode,HIGH_FIRST, picode.base(),
-                                                          eDEF, *(++iICODE(ticode))->ll());
-                                ticode->hl()->asgn.rhs = _exp;
-                                picode->invalidate();
-                                numHlIcodes--;
+                              	  case HLI_CALL:    /* register arguments */
+                                	newRegArg (pProc, picode, ticode);
+									invalidateIcode (picode);
+									numHlIcodes--;
+                                	break;
+                                } /* eos */
+                            }
+                            break;
+
+                          case HLI_POP:
+                            if (picode->du1.idx[0][0] == picode->du1.idx[1][0])
+                            {
+                                ticode = pProc->Icode.GetIcode(picode->du1.idx[0][0]);
+								if ((picode->du.lastDefRegi & duReg[regi]) &&
+									((ticode->ic.hl.opcode != HLI_CALL) &&
+								 	 (ticode->ic.hl.opcode != HLI_RET)))
+								continue;
+
+                                exp = popExpStk(); /* pop last exp pushed */
+                            	switch (ticode->ic.hl.opcode) {
+                              	case HLI_ASSIGN:
+									forwardSubsLong (picode->ic.hl.oper.exp->expr.ident.idNode.longIdx,
+										exp, picode, ticode, &numHlIcodes);
+                                	break;
+                              	case HLI_JCOND: case HLI_PUSH:
+                                	res = insertSubTreeLongReg (exp,
+                                    	&ticode->ic.hl.oper.exp,
+										picode->ic.hl.oper.asgn.lhs->expr.ident.idNode.longIdx);
+                                	if (res)
+									{
+                                    	invalidateIcode (picode);
+										numHlIcodes--;
+									}
+                                	break;
+								case HLI_CALL:	/*** missing ***/
+									break;
+                            	} /* eos */
+							}
+                            break;
+
+                          case HLI_CALL:    /* check for function return */
+							ticode = pProc->Icode.GetIcode(picode->du1.idx[0][0]);
+                            switch (ticode->ic.hl.opcode) {
+                              case HLI_ASSIGN:
+								exp = idCondExpFunc (
+											picode->ic.hl.oper.call.proc,
+											picode->ic.hl.oper.call.args);
+								ticode->ic.hl.oper.asgn.lhs = 
+									idCondExpLong(&pProc->localId, DST, ticode,
+												  HIGH_FIRST, j, E_DEF, 1);
+                                ticode->ic.hl.oper.asgn.rhs = exp; 
+                                invalidateIcode (picode); 
+							    numHlIcodes--;
                                 break;
 
-                            case HLI_PUSH:  case HLI_RET:
-                                ticode->hl()->expr( _icHl.call.toId() );
-                                picode->invalidate();
-                                numHlIcodes--;
+                              case HLI_PUSH:  case HLI_RET:
+                                exp = idCondExpFunc (
+												picode->ic.hl.oper.call.proc,
+												picode->ic.hl.oper.call.args);
+                                ticode->ic.hl.oper.exp = exp; 
+                                invalidateIcode (picode); 
+							    numHlIcodes--;
                                 break;
 
-                            case HLI_JCOND:
-                                _exp = _icHl.call.toId();
-                                _retVal = &picode->hl()->call.proc->retVal;
-                                res = COND_EXPR::insertSubTreeLongReg (_exp,
-                                                                       &ticode->hl()->exp.v,
-                                                                       locals.newLongReg ( _retVal->type, _retVal->id.longId.h,
-                                                                                            _retVal->id.longId.l, picode.base()));
+							  case HLI_JCOND:
+							    exp = idCondExpFunc (
+												picode->ic.hl.oper.call.proc,
+												picode->ic.hl.oper.call.args);
+								retVal = &picode->ic.hl.oper.call.proc->retVal;
+                                res = insertSubTreeLongReg (exp,
+                                    	&ticode->ic.hl.oper.exp,
+										newLongRegId (&pProc->localId,
+											retVal->type, retVal->id.longId.h,
+											retVal->id.longId.l, j));
                                 if (res)	/* was substituted */
-                                {
-                                    picode->invalidate();
-                                    numHlIcodes--;
-                                }
-                                else	/* cannot substitute function */
-                                {
-                                    lhs = locals.createId(_retVal,picode.base());
-                                    picode->setAsgn(lhs, _exp);
-                                }
-                                break;
+								{
+                              		invalidateIcode (picode);
+									numHlIcodes--;
+								}
+								else	/* cannot substitute function */
+								{
+									lhs = idCondExpID(retVal,&pProc->localId,j);
+									newAsgnHlIcode (picode, lhs, exp);
+								}
+							    break;
+                            } /* eos */
                         } /* eos */
-                } /* eos */
-            }
-        }
-        /* HLI_PUSH doesn't define any registers, only uses registers.
-         * Push the associated expression to the register on the local
-         * expression stack */
-        else if (_icHl.opcode == HLI_PUSH)
-        {
-            g_exp_stk.processExpPush(numHlIcodes, picode.base());
-        }
-        else if(picode->du1.numRegsDef!=0)
-            printf("Num def %d\n",picode->du1.numRegsDef);
+                    }
+                }
 
-        /* For HLI_CALL instructions that use arguments from the stack,
-         * pop them from the expression stack and place them on the
-         * procedure's argument list */
-        if(_icHl.opcode == HLI_CALL)
-        {
-            if ( not _icHl.call.proc->hasRegArgs())
-            {
-                fnc->processHliCall(_exp, picode.base());
-            }
+                /* HLI_PUSH doesn't define any registers, only uses registers.
+                 * Push the associated expression to the register on the local 
+                 * expression stack */
+                else if (picode->ic.hl.opcode == HLI_PUSH)
+                {
+                    pushExpStk (picode->ic.hl.oper.exp);
+                    invalidateIcode (picode);
+					numHlIcodes--;
+                }
 
-            /* If we could not substitute the result of a function,
-             * 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());
-                picode->setAsgn(lhs, _exp);
+				/* For HLI_CALL instructions that use arguments from the stack,
+				 * pop them from the expression stack and place them on the 
+				 * procedure's argument list */
+                if ((picode->ic.hl.opcode == HLI_CALL) &&
+					! (picode->ic.hl.oper.call.proc->flg & REG_ARGS)) 
+                { PPROC pp;
+				  Int cb, numArgs;
+				  boolT res;
+
+					pp = picode->ic.hl.oper.call.proc;
+                    if (pp->flg & CALL_PASCAL)
+					{
+						cb = pp->cbParam;	/* fixed # arguments */
+						for (k = 0, numArgs = 0; k < cb; numArgs++)
+						{
+							exp = popExpStk();
+							if (pp->flg & PROC_ISLIB)	/* library function */
+							{
+								if (pp->args.numArgs > 0)
+									adjustActArgType(exp,
+											pp->args.sym[numArgs].type, pProc);
+								res = newStkArg (picode, exp, 
+												 picode->ic.ll.opcode, pProc);
+							}
+							else			/* user function */
+							{
+								if (pp->args.numArgs >0)
+									adjustForArgType (&pp->args, numArgs, 
+												  	  expType (exp, pProc));
+								res = newStkArg (picode, exp, 
+												 picode->ic.ll.opcode, pProc);
+							}
+							if (res == FALSE)
+								k += hlTypeSize (exp, pProc);
+						}
+					}
+                    else		/* CALL_C */
+					{
+						cb = picode->ic.hl.oper.call.args->cb;
+						numArgs = 0;
+						if (cb) 
+                        	for (k = 0; k < cb; numArgs++)
+								processCArg (pp, pProc, picode, numArgs, &k);
+						else if ((cb == 0) && (picode->ic.ll.flg & REST_STK))
+							while (! emptyExpStk())
+							{
+								processCArg (pp, pProc, picode, numArgs, &k);
+								numArgs++;
+							}
+					}
+                } 
+
+				/* If we could not substitute the result of a function, 
+				 * assign it to the corresponding registers */
+				if ((picode->ic.hl.opcode == HLI_CALL) &&
+					((picode->ic.hl.oper.call.proc->flg & PROC_ISLIB) !=
+					  PROC_ISLIB) && (picode->du1.idx[0][0] == 0) &&
+					(picode->du1.numRegsDef > 0))
+				{
+					exp = idCondExpFunc (picode->ic.hl.oper.call.proc,
+										 picode->ic.hl.oper.call.args);
+					lhs = idCondExpID (&picode->ic.hl.oper.call.proc->retVal,
+									   &pProc->localId, j);
+					newAsgnHlIcode (picode, lhs, exp);
+				}
             }
         }
-    }
-    /* Store number of high-level icodes in current basic block */
 
+		/* Store number of high-level icodes in current basic block */
+		pbb->numHlIcodes = numHlIcodes;
+    }
 }
 
-void Function::findExps()
-{
-    //int i, numHlIcodes;
-    //STKFRAME * args;  // pointer to arguments - for HLI_CALL          */
-
-    /* Initialize expression stack */
-    g_exp_stk.init();
 
-    /* Traverse tree in dfsLast order */
-//    for (i = 0; i < numBBs; i++)
-    for(BB *pbb : m_dfsLast)
-    {
-        /* Process one BB */
-//        pbb = m_dfsLast[i];
-        if (not pbb->valid())
-            continue;
-        pbb->findBBExps( this->localId, this);
+void dataFlow (PPROC pProc, dword liveOut)
+/* Invokes procedures related with data flow analysis.  Works on a procedure
+ * at a time basis. 
+ * Note: indirect recursion in liveRegAnalysis is possible. */
+{ boolT isAx, isBx, isCx, isDx;
+  Int idx;
 
-    }
-}
+	/* Remove references to register variables */
+	if (pProc->flg & SI_REGVAR)
+		liveOut &= maskDuReg[rSI];
+	if (pProc->flg & DI_REGVAR)
+		liveOut &= maskDuReg[rDI];
 
-void Function::preprocessReturnDU(std::bitset<32> &_liveOut)
-{
-    if (_liveOut.any())
+    /* Function - return value register(s) */
+    if (liveOut != 0)
     {
-        int idx;
-        bool isAx, isBx, isCx, isDx;
-        flg |= PROC_IS_FUNC;
-        isAx = _liveOut.test(rAX - rAX);
-        isBx = _liveOut.test(rBX - rAX);
-        isCx = _liveOut.test(rCX - rAX);
-        isDx = _liveOut.test(rDX - rAX);
-        bool isAL = !isAx && _liveOut.test(rAL - rAX);
-        bool isAH = !isAx && _liveOut.test(rAH - rAX);
-        bool isBL = !isBx && _liveOut.test(rBL - rAX);
-        bool isBH = !isBx && _liveOut.test(rBH - rAX);
-        bool isCL = !isCx && _liveOut.test(rCL - rAX);
-        bool isCH = !isCx && _liveOut.test(rCH - rAX);
-        bool isDL = !isDx && _liveOut.test(rDL - rAX);
-        bool isDH = !isDx && _liveOut.test(rDH - rAX);
-        if(isAL && isAH)
-        {
-            isAx = true;
-            isAH=isAL=false;
-        }
-        if(isDL && isDH)
-        {
-            isDx = true;
-            isDH=isDL=false;
-        }
-        if(isBL && isBH)
-        {
-            isBx = true;
-            isBH=isBL=false;
-        }
-        if(isCL && isCH)
-        {
-            isCx = true;
-            isCH=isCL=false;
-        }
+        pProc->flg |= PROC_IS_FUNC;
+        isAx = (boolT)(liveOut & power2(rAX - rAX));
+        isBx = (boolT)(liveOut & power2(rBX - rAX));
+        isCx = (boolT)(liveOut & power2(rCX - rAX));
+        isDx = (boolT)(liveOut & power2(rDX - rAX));
 
         if (isAx && isDx)       /* long or pointer */
         {
-            retVal.type = TYPE_LONG_SIGN;
-            retVal.loc = REG_FRAME;
-            retVal.id.longId.h = rDX;
-            retVal.id.longId.l = rAX;
-            idx = localId.newLongReg(TYPE_LONG_SIGN, rDX, rAX, Icode.begin()/*0*/);
-            localId.propLongId (rAX, rDX, "\0");
+            pProc->retVal.type = TYPE_LONG_SIGN;
+            pProc->retVal.loc = REG_FRAME;
+            pProc->retVal.id.longId.h = rDX;
+            pProc->retVal.id.longId.l = rAX;
+			idx = newLongRegId (&pProc->localId, TYPE_LONG_SIGN, rDX, rAX, 0);
+			propLongId (&pProc->localId, rAX, rDX, "\0"); 
         }
-        else if (isAx || isBx || isCx || isDx)	/* uint16_t */
+        else if (isAx || isBx || isCx || isDx)	/* word */
         {
-            retVal.type = TYPE_WORD_SIGN;
-            retVal.loc = REG_FRAME;
+            pProc->retVal.type = TYPE_WORD_SIGN;
+            pProc->retVal.loc = REG_FRAME;
             if (isAx)
-                retVal.id.regi = rAX;
+                pProc->retVal.id.regi = rAX;
             else if (isBx)
-                retVal.id.regi = rBX;
+                pProc->retVal.id.regi = rBX;
             else if (isCx)
-                retVal.id.regi = rCX;
-            else
-                retVal.id.regi = rDX;
-            idx = localId.newByteWordReg(TYPE_WORD_SIGN,retVal.id.regi);
-        }
-        else if(isAL||isBL||isCL||isDL)
-        {
-            retVal.type = TYPE_BYTE_SIGN;
-            retVal.loc = REG_FRAME;
-            if (isAL)
-                retVal.id.regi = rAL;
-            else if (isBL)
-                retVal.id.regi = rBL;
-            else if (isCL)
-                retVal.id.regi = rCL;
-            else
-                retVal.id.regi = rDL;
-            idx = localId.newByteWordReg(TYPE_BYTE_SIGN,retVal.id.regi);
-
+                pProc->retVal.id.regi = rCX;
+            else 
+                pProc->retVal.id.regi = rDX;
+			idx = newByteWordRegId (&pProc->localId, TYPE_WORD_SIGN,
+									pProc->retVal.id.regi);
         }
     }
-}
-/** Invokes procedures related with data flow analysis.  Works on a procedure
- * at a time basis.
- * Note: indirect recursion in liveRegAnalysis is possible. */
-void Function::dataFlow(std::bitset<32> &_liveOut)
-{
-
-    /* Remove references to register variables */
-    if (flg & SI_REGVAR)
-        _liveOut &= maskDuReg[rSI];
-    if (flg & DI_REGVAR)
-        _liveOut &= maskDuReg[rDI];
-
-    /* Function - return value register(s) */
-    preprocessReturnDU(_liveOut);
 
     /* Data flow analysis */
-    liveAnal = true;
-    elimCondCodes();
-    genLiveKtes();
-    liveRegAnalysis (_liveOut);   /* calls dataFlow() recursively */
-    if (! (flg & PROC_ASM))		/* can generate C for pProc		*/
-    {
-        genDU1 ();			/* generate def/use level 1 chain */
-        findExps (); 		/* forward substitution algorithm */
-    }
+    pProc->liveAnal = TRUE;
+    elimCondCodes (pProc);
+    genLiveKtes (pProc);
+    liveRegAnalysis (pProc, liveOut);   /* calls dataFlow() recursively */
+	if (! (pProc->flg & PROC_ASM))		/* can generate C for pProc		*/
+	{
+    	genDU1 (pProc);			/* generate def/use level 1 chain */
+    	findExps (pProc); 		/* forward substitution algorithm */ 
+	}
 }
 

+ 65 - 67
src/dcc.cpp

@@ -5,36 +5,37 @@
  ****************************************************************************/
 
 #include "dcc.h"
-#include "project.h"
 #include <string.h>
+#ifdef __UNIX__
+#include <unistd.h>
+#else
+#include <stdio.h>
+#include <io.h>				/* For unlink() */
+#endif
+
 
 /* Global variables - extern to other modules */
+char    *progname;          /* argv[0] - for error msgs 			  */
 char    *asm1_name, *asm2_name;     /* Assembler output filenames     */
 SYMTAB  symtab;             /* Global symbol table      			  */
 STATS   stats;              /* cfg statistics       				  */
-//PROG    prog;               /* programs fields      				  */
+PROG    prog;               /* programs fields      				  */
 OPTION  option;             /* Command line options     			  */
-//Function *   pProcList;			/* List of procedures, topologically sort */
-//Function *	pLastProc;			/* Pointer to last node in procedure list */
-//FunctionListType pProcList;
-//CALL_GRAPH	*callGraph;		/* Call graph of the program			  */
+PPROC   pProcList;			/* List of procedures, topologically sort */
+PPROC	pLastProc;			/* Pointer to last node in procedure list */
+CALL_GRAPH	*callGraph;		/* Call graph of the program			  */
 
 static char *initargs(int argc, char *argv[]);
-static void displayTotalStats(void);
-#include <llvm/Support/raw_os_ostream.h>
+static void displayTotalStats();
+
 
 /****************************************************************************
  * main
  ***************************************************************************/
-#include <iostream>
-extern Project g_proj;
+
+
 int main(int argc, char *argv[])
 {
-//     llvm::MCOperand op=llvm::MCOperand::CreateImm(11);
-//     llvm::MCAsmInfo info;
-//     llvm::raw_os_ostream wrap(std::cerr);
-//     op.print(wrap,&info);
-//     wrap.flush();
     /* Extract switches and filename */
     strcpy(option.filename, initargs(argc, argv));
 
@@ -42,9 +43,7 @@ int main(int argc, char *argv[])
      * building the call graph and attaching appropriate bits of code for
      * each procedure.
     */
-    DccFrontend fe(option.filename);
-    if(false==fe.FrontEnd ())
-        return -1;
+    FrontEnd (option.filename, &callGraph);
 
     /* In the middle is a so called Universal Decompiling Machine.
      * It processes the procedure list and I-code and attaches where it can
@@ -56,14 +55,14 @@ int main(int argc, char *argv[])
      * analysis, data flow etc. and outputs it to output file ready for
      * re-compilation.
     */
-    BackEnd(option.filename, g_proj.callGraph);
+    BackEnd(option.filename, callGraph);
 
-    g_proj.callGraph->write();
+    writeCallGraph (callGraph);
 
     if (option.Stats)
         displayTotalStats();
 
-    /*
+/*
     freeDataStructures(pProcList);
 */
     return 0;
@@ -75,51 +74,50 @@ int main(int argc, char *argv[])
 static char *initargs(int argc, char *argv[])
 {
     char *pc;
+    progname = *argv;   /* Save invocation name for error messages */
 
-    while (--argc > 0 && (*++argv)[0] == '-')
-    {
+    while (--argc > 0 && (*++argv)[0] == '-') {
         for (pc = argv[0]+1; *pc; pc++)
-            switch (*pc)
-            {
-                case 'a':       /* Print assembler listing */
-                    if (*(pc+1) == '2')
-                        option.asm2 = true;
-                    else
-                        option.asm1 = true;
-                    if (*(pc+1) == '1' || *(pc+1) == '2')
-                        pc++;
-                    break;
-                case 'c':
-                    option.Calls = true;
-                    break;
-                case 'i':
-                    option.Interact = true;
-                    break;
-                case 'm':       /* Print memory map */
-                    option.Map = true;
-                    break;
-                case 's':       /* Print Stats */
-                    option.Stats = true;
-                    break;
-                case 'V':       /* Very verbose => verbose */
-                    option.VeryVerbose = true;
-                case 'v':
-                    option.verbose = true; /* Make everything verbose */
-                    break;
-                case 'o':       /* assembler output file */
-                    if (*(pc+1)) {
-                        asm1_name = asm2_name = pc+1;
-                        goto NextArg;
-                    }
-                    else if (--argc > 0) {
-                        asm1_name = asm2_name = *++argv;
-                        goto NextArg;
-                    }
-                default:
-                    fatalError(INVALID_ARG, *pc);
-                    return *argv;
+            switch (*pc) {
+            case 'a':       /* Print assembler listing */
+                if (*(pc+1) == '2')
+                    option.asm2 = TRUE;
+                else
+                    option.asm1 = TRUE;
+                if (*(pc+1) == '1' || *(pc+1) == '2')
+                    pc++;
+                break;
+            case 'c':
+                option.Calls = TRUE;
+                break;
+            case 'i':
+                option.Interact = TRUE;
+                break;
+            case 'm':       /* Print memory map */
+                option.Map = TRUE;
+                break;
+            case 's':       /* Print Stats */
+                option.Stats = TRUE;
+                break;
+            case 'V':       /* Very verbose => verbose */
+                option.VeryVerbose = TRUE;
+            case 'v':       /* Make everything verbose */
+                option.verbose = TRUE;
+                break;
+            case 'o':       /* assembler output file */
+                if (*(pc+1)) {
+                    asm1_name = asm2_name = pc+1;
+                    goto NextArg;
+                }
+                else if (--argc > 0) {
+                    asm1_name = asm2_name = *++argv;
+                    goto NextArg;
+                }
+            default:
+                fatalError(INVALID_ARG, *pc);
+                return *argv;
             }
-NextArg:;
+    NextArg:;
     }
 
     if (argc == 1)
@@ -128,13 +126,13 @@ NextArg:;
         {
             if (! asm1_name)
             {
-                asm1_name = strcpy((char*)malloc(strlen(*argv)+4), *argv);
+                asm1_name = strcpy((char*)allocMem(strlen(*argv)+4), *argv);
                 pc = strrchr(asm1_name, '.');
                 if (pc > strrchr(asm1_name, '/'))
                 {
                     *pc = '\0';
                 }
-                asm2_name = (char*)malloc(strlen(asm1_name)+4) ;
+                asm2_name = (char*)allocMem(strlen(asm1_name)+4) ;
                 strcat(strcpy(asm2_name, asm1_name), ".a2");
                 unlink(asm2_name);
                 strcat(asm1_name, ".a1");
@@ -142,10 +140,10 @@ NextArg:;
             unlink(asm1_name);  /* Remove asm output files */
         }
         return *argv;       /* filename of the program to decompile */
-    }
+   }
 
     fatalError(USAGE);
-    return *argv; // does not reach this.
+    return *argv;
 }
 
 static void

File diff suppressed because it is too large
+ 511 - 329
src/disassem.cpp


+ 40 - 33
src/error.cpp

@@ -3,47 +3,54 @@
  * (C) Cristina Cifuentes
  ***************************************************************************/
 
-#include <stdio.h>
+#include "dcc.h"
+
+#include <stdio.h> 
 #include <stdlib.h>
-#include <map>
-#include <string>
+//#ifndef __UNIX__
+#if 1
 #include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
 
-#include "dcc.h"
+static char *errorMessage[] = {
+  "Invalid option -%c\n",                                   /* INVALID_ARG    */
+  "Invalid instruction %02X at location %06lX\n",           /* INVALID_OPCODE */
+  "Don't understand 80386 instruction %02X at location %06lX\n",
+															/* INVALID_386OP  */
+  "Segment override with no memory operand at location %06lX\n",
+															/* FUNNY_SEGOVR   */
+  "REP prefix without a string instruction at location %06lX\n",/* FUNNY_REP */
+  "Cannot open %s\n",                                       /* CANNOT_OPEN    */
+  "Error while reading %s\n",                               /* CANNOT_READ    */
+  "malloc of %ld bytes failed\n",                           /* MALLOC_FAILED  */
+  "Don't understand new EXE format\n",                      /* NEWEXE_FORMAT  */
+  "Failed to find a BB for jump to %ld in proc %s\n",    	/* NO_BB		  */
+  "Basic Block is a synthetic jump\n",                /* INVALID_SYNTHETIC_BB */
+  "Failed to find a BB for interval\n",                     /* INVALID_INT_BB */
+  "Instruction at location %06lX goes beyond loaded image\n",   
+															/* IP_OUT_OF_RANGE*/
+  "Definition not found for condition code usage at opcode %d\n",
+															/* DEF_NOT_FOUND */
+  "JX use, definition not supported at opcode #%d\n",		/* JX_NOT_DEF */
+  "Def - use not supported.  Def op = %d, use op = %d.\n",  /* NOT_DEF_USE */
+  "Failed to construct repeat..until() condition.\n",		/* REPEAT_FAIL */
+  "Failed to construct while() condition.\n",				/* WHILE_FAIL */
+};
 
-    static std::map<eErrorId,std::string> errorMessage =
-    {
-      {INVALID_ARG      ,"Invalid option -%c\n"},
-      {INVALID_OPCODE   ,"Invalid instruction %02X at location %06lX\n"},
-      {INVALID_386OP    ,"Don't understand 80386 instruction %02X at location %06lX\n"},
-      {FUNNY_SEGOVR     ,"Segment override with no memory operand at location %06lX\n"},
-      {FUNNY_REP        ,"REP prefix without a string instruction at location %06lX\n"},
-      {CANNOT_OPEN      ,"Cannot open %s\n"},
-      {CANNOT_READ      ,"Error while reading %s\n"},
-      {MALLOC_FAILED    ,"malloc of %ld bytes failed\n"},
-      {NEWEXE_FORMAT    ,"Don't understand new EXE format\n"},
-      {NO_BB            ,"Failed to find a BB for jump to %ld in proc %s\n"},
-      {INVALID_SYNTHETIC_BB,"Basic Block is a synthetic jump\n"},
-      {INVALID_INT_BB   ,"Failed to find a BB for interval\n"},
-      {IP_OUT_OF_RANGE  ,"Instruction at location %06lX goes beyond loaded image\n"},
-      {DEF_NOT_FOUND    ,"Definition not found for condition code usage at opcode %d\n"},
-      {JX_NOT_DEF       ,"JX use, definition not supported at opcode #%d\n"},
-      {NOT_DEF_USE      ,"Def - use not supported.  Def op = %d, use op = %d.\n"},
-      {REPEAT_FAIL      ,"Failed to construct repeat..until() condition.\n"},
-      {WHILE_FAIL       ,"Failed to construct while() condition.\n"},
-    };
 
 /****************************************************************************
  fatalError: displays error message and exits the program.
  ****************************************************************************/
-void fatalError(eErrorId errId, ...)
+void fatalError(Int errId, ...)
 {  va_list args;
 //#ifdef __UNIX__   /* ultrix */
 #if 0
-   int errId;
+   Int errId;
 
     va_start(args);
-    errId = va_arg(args, int);
+    errId = va_arg(args, Int);
 #else
     va_start(args, errId);
 #endif
@@ -52,7 +59,7 @@ void fatalError(eErrorId errId, ...)
        fprintf(stderr,"Usage: dcc [-a1a2cmpsvVi][-o asmfile] DOS_executable\n");
     else {
         fprintf(stderr, "dcc: ");
-        vfprintf(stderr, errorMessage[errId].c_str(), args);
+        vfprintf(stderr, errorMessage[errId - 1], args);
     }
     va_end(args);
     exit((int)errId);
@@ -62,18 +69,18 @@ void fatalError(eErrorId errId, ...)
 /****************************************************************************
  reportError: reports the warning/error and continues with the program.
  ****************************************************************************/
-void reportError(eErrorId errId, ...)
+void reportError(Int errId, ...)
 {  va_list args;
 //#ifdef __UNIX__   /* ultrix */
 #if 0
-   int errId;
+   Int errId;
 
     va_start(args);
-    errId = va_arg(args, int);
+    errId = va_arg(args, Int);
 #else           /* msdos or windows*/
     va_start(args, errId);
 #endif
     fprintf(stderr, "dcc: ");
-    vfprintf(stderr, errorMessage[errId].c_str(), args);
+    vfprintf(stderr, errorMessage[errId - 1], args);
     va_end(args);
 }

+ 71 - 67
src/fixwild.cpp

@@ -18,26 +18,29 @@
 
 #ifndef bool
 #define bool  unsigned char
-#define uint8_t  unsigned char
+#define TRUE  1
+#define FALSE 0
+#define byte  unsigned char
 #endif
 
 static int pc;                              /* Indexes into pat[] */
 
 /* prototypes */
-static bool ModRM(uint8_t pat[]);              /* Handle the mod/rm uint8_t */
-static bool TwoWild(uint8_t pat[]);            /* Make the next 2 bytes wild */
-static bool FourWild(uint8_t pat[]);           /* Make the next 4 bytes wild */
-       void fixWildCards(uint8_t pat[]);       /* Main routine */
+static bool ModRM(byte pat[]);              /* Handle the mod/rm byte */
+static bool TwoWild(byte pat[]);            /* Make the next 2 bytes wild */
+static bool FourWild(byte pat[]);           /* Make the next 4 bytes wild */
+       void fixWildCards(byte pat[]);       /* Main routine */
 
 
 /* Handle the mod/rm case. Returns true if pattern exhausted */
-static bool ModRM(uint8_t pat[])
+static bool
+ModRM(byte pat[])
 {
-    uint8_t op;
+    byte op;
 
-    /* A standard mod/rm uint8_t follows opcode */
-    op = pat[pc++];                         /* The mod/rm uint8_t */
-    if (pc >= PATLEN) return true;          /* Skip Mod/RM */
+    /* A standard mod/rm byte follows opcode */
+    op = pat[pc++];                         /* The mod/rm byte */
+    if (pc >= PATLEN) return TRUE;          /* Skip Mod/RM */
     switch (op & 0xC0)
     {
         case 0x00:                          /* [reg] or [nnnn] */
@@ -45,42 +48,42 @@ static bool ModRM(uint8_t pat[])
             {
                 /* Uses [nnnn] address mode */
                 pat[pc++] = WILD;
-                if (pc >= PATLEN) return true;
+                if (pc >= PATLEN) return TRUE;
                 pat[pc++] = WILD;
-                if (pc >= PATLEN) return true;
+                if (pc >= PATLEN) return TRUE;
             }
             break;
         case 0x40:                          /* [reg + nn] */
-            if ((pc+=1) >= PATLEN) return true;
+            if ((pc+=1) >= PATLEN) return TRUE;
             break;
         case 0x80:                          /* [reg + nnnn] */
             /* Possibly just a long constant offset from a register,
                 but often will be an index from a variable */
             pat[pc++] = WILD;
-            if (pc >= PATLEN) return true;
+            if (pc >= PATLEN) return TRUE;
             pat[pc++] = WILD;
-            if (pc >= PATLEN) return true;
+            if (pc >= PATLEN) return TRUE;
             break;
         case 0xC0:                          /* reg */
             break;
     }
-    return false;
+    return FALSE;
 }
 
 /* Change the next two bytes to wild cards */
 static bool
-TwoWild(uint8_t pat[])
+TwoWild(byte pat[])
 {
     pat[pc++] = WILD;
-    if (pc >= PATLEN) return true;      /* Pattern exhausted */
+    if (pc >= PATLEN) return TRUE;      /* Pattern exhausted */
     pat[pc++] = WILD;
-    if (pc >= PATLEN) return true;
-    return false;
+    if (pc >= PATLEN) return TRUE;
+    return FALSE;
 }
 
 /* Change the next four bytes to wild cards */
 static bool
-FourWild(uint8_t pat[])
+FourWild(byte pat[])
 {
             TwoWild(pat);
     return  TwoWild(pat);
@@ -89,21 +92,22 @@ FourWild(uint8_t pat[])
 /* Chop from the current point by wiping with zeroes. Can't rely on anything
     after this point */
 static void
-chop(uint8_t pat[])
+chop(byte pat[])
 {
     if (pc >= PATLEN) return;               /* Could go negative otherwise */
     memset(&pat[pc], 0, PATLEN - pc);
 }
 
-static bool op0F(uint8_t pat[])
+static bool
+op0F(byte pat[])
 {
-    /* The two uint8_t opcodes */
-    uint8_t op = pat[pc++];
+    /* The two byte opcodes */
+    byte op = pat[pc++];
     switch (op & 0xF0)
     {
         case 0x00:              /* 00 - 0F */
             if (op >= 0x06)     /* Clts, Invd, Wbinvd */
-                return false;
+                return FALSE;
             else
             {
                 /* Grp 6, Grp 7, LAR, LSL */
@@ -113,10 +117,10 @@ static bool op0F(uint8_t pat[])
             return ModRM(pat);
 
         case 0x80:
-            pc += 2;            /* uint16_t displacement cond jumps */
-            return false;
+            pc += 2;            /* Word displacement cond jumps */
+            return FALSE;
 
-        case 0x90:              /* uint8_t set on condition */
+        case 0x90:              /* Byte set on condition */
             return ModRM(pat);
 
         case 0xA0:
@@ -126,7 +130,7 @@ static bool op0F(uint8_t pat[])
                 case 0xA1:      /* Pop  FS */
                 case 0xA8:      /* Push GS */
                 case 0xA9:      /* Pop  GS */
-                    return false;
+                    return FALSE;
 
                 case 0xA3:      /* Bt  Ev,Gv */
                 case 0xAB:      /* Bts Ev,Gv */
@@ -134,9 +138,9 @@ static bool op0F(uint8_t pat[])
 
                 case 0xA4:      /* Shld EvGbIb */
                 case 0xAC:      /* Shrd EvGbIb */
-                    if (ModRM(pat)) return true;
+                    if (ModRM(pat)) return TRUE;
                     pc++;       /* The #num bits to shift */
-                    return false;
+                    return FALSE;
 
                 case 0xA5:      /* Shld EvGb CL */
                 case 0xAD:      /* Shrd EvGb CL */
@@ -150,9 +154,9 @@ static bool op0F(uint8_t pat[])
             if (op == 0xBA)
             {
                 /* Grp 8: bt/bts/btr/btc Ev,#nn */
-                if (ModRM(pat)) return true;
+                if (ModRM(pat)) return TRUE;
                 pc++;           /* The #num bits to shift */
-                return false;
+                return FALSE;
             }
             return ModRM(pat);
 
@@ -163,10 +167,10 @@ static bool op0F(uint8_t pat[])
                 return ModRM(pat);
             }
             /* Else BSWAP */
-            return false;
+            return FALSE;
 
         default:
-            return false;       /* Treat as double uint8_t opcodes */
+            return FALSE;       /* Treat as double byte opcodes */
 
     }
 
@@ -181,10 +185,10 @@ static bool op0F(uint8_t pat[])
     PATLEN bytes are scanned.
 */
 void
-fixWildCards(uint8_t pat[])
+fixWildCards(byte pat[])
 {
 
-    uint8_t op, quad, intArg;
+    byte op, quad, intArg;
 
 
     pc=0;
@@ -193,17 +197,17 @@ fixWildCards(uint8_t pat[])
         op = pat[pc++];
         if (pc >= PATLEN) return;
 
-        quad = (uint8_t) (op & 0xC0);			/* Quadrant of the opcode map */
+        quad = (byte) (op & 0xC0);			/* Quadrant of the opcode map */
         if (quad == 0)
         {
             /* Arithmetic group 00-3F */
 
             if ((op & 0xE7) == 0x26)        /* First check for the odds */
             {
-                /* Segment prefix: treat as 1 uint8_t opcode */
+                /* Segment prefix: treat as 1 byte opcode */
                 continue;
             }
-            if (op == 0x0F)                 /* 386 2 uint8_t opcodes */
+            if (op == 0x0F)                 /* 386 2 byte opcodes */
             {
                 if (op0F(pat)) return;
                 continue;
@@ -214,20 +218,20 @@ fixWildCards(uint8_t pat[])
                 /* All these are constant. Work out the instr length */
                 if (op & 2)
                 {
-                    /* Push, pop, other 1 uint8_t opcodes */
+                    /* Push, pop, other 1 byte opcodes */
                     continue;
                 }
                 else
                 {
                     if (op & 1)
                     {
-                        /* uint16_t immediate operands */
+                        /* Word immediate operands */
                         pc += 2;
                         continue;
                     }
                     else
                     {
-                        /* uint8_t immediate operands */
+                        /* Byte immediate operands */
                         pc++;
                         continue;
                     }
@@ -253,7 +257,7 @@ fixWildCards(uint8_t pat[])
                 /* 0x60 - 0x70 */
                 if (op & 0x10)
                 {
-                    /* 70-7F 2 uint8_t jump opcodes */
+                    /* 70-7F 2 byte jump opcodes */
                     pc++;
                     continue;
                 }
@@ -280,11 +284,11 @@ fixWildCards(uint8_t pat[])
                             if (TwoWild(pat)) return;
                             continue;
 
-                        case 0x68:  /* Push uint8_t */
-                        case 0x6A:  /* Push uint8_t */
+                        case 0x68:  /* Push byte */
+                        case 0x6A:  /* Push byte */
                         case 0x6D:  /* insb port */
                         case 0x6F:  /* outsb port */
-                            /* 2 uint8_t instr, no wilds */
+                            /* 2 byte instr, no wilds */
                             pc++;
                             continue;
 
@@ -298,14 +302,14 @@ fixWildCards(uint8_t pat[])
             switch (op & 0xF0)
             {
                 case 0x80:          /* 80 - 8F */
-                    /* All have a mod/rm uint8_t */
+                    /* All have a mod/rm byte */
                     if (ModRM(pat)) return;
                     /* These also have immediate values */
                     switch (op)
                     {
                         case 0x80:
                         case 0x83:
-                            /* One uint8_t immediate */
+                            /* One byte immediate */
                             pc++;
                             continue;
 
@@ -324,7 +328,7 @@ fixWildCards(uint8_t pat[])
                         if (FourWild(pat)) return;
                         continue;
                     }
-                    /* All others are 1 uint8_t opcodes */
+                    /* All others are 1 byte opcodes */
                     continue;
                 case 0xA0:          /* A0 - AF */
                     if ((op & 0x0C) == 0)
@@ -335,7 +339,7 @@ fixWildCards(uint8_t pat[])
                     }
                     else if ((op & 0xFE) == 0xA8)
                     {
-                        /* test al,#uint8_t or test ax,#uint16_t */
+                        /* test al,#byte or test ax,#word */
                         if (op & 1) pc += 2;
                         else        pc += 1;
                         continue;
@@ -364,10 +368,10 @@ fixWildCards(uint8_t pat[])
             /* In the last quadrant of the op code table */
             switch (op)
             {
-                case 0xC0:          /* 386: Rotate group 2 ModRM, uint8_t, #uint8_t */
-                case 0xC1:          /* 386: Rotate group 2 ModRM, uint16_t, #uint8_t */
+                case 0xC0:          /* 386: Rotate group 2 ModRM, byte, #byte */
+                case 0xC1:          /* 386: Rotate group 2 ModRM, word, #byte */
                     if (ModRM(pat)) return;
-                    /* uint8_t immediate value follows ModRM */
+                    /* Byte immediate value follows ModRM */
                     pc++;
                     continue;
 
@@ -388,27 +392,27 @@ fixWildCards(uint8_t pat[])
 
                 case 0xC6:          /* Mov ModRM, #nn */
                     if (ModRM(pat)) return;
-                    /* uint8_t immediate value follows ModRM */
+                    /* Byte immediate value follows ModRM */
                     pc++;
                     continue;
                 case 0xC7:          /* Mov ModRM, #nnnn */
                     if (ModRM(pat)) return;
-                    /* uint16_t immediate value follows ModRM */
+                    /* Word immediate value follows ModRM */
                     /* Immediate 16 bit values might be constant, but also
                         might be relocatable. For now, make them wild */
                     if (TwoWild(pat)) return;
                     continue;
 
                 case 0xC8:          /* Enter Iw, Ib */
-                    pc += 3;        /* Constant uint16_t, uint8_t */
+                    pc += 3;        /* Constant word, byte */
                     continue;
                 case 0xC9:          /* Leave */
                     continue;
 
-                case 0xCC:          /* int 3 */
+                case 0xCC:          /* Int 3 */
                     continue;
 
-                case 0xCD:          /* int nn */
+                case 0xCD:          /* Int nn */
                     intArg = pat[pc++];
                     if ((intArg >= 0x34) && (intArg <= 0x3B))
                     {
@@ -423,10 +427,10 @@ fixWildCards(uint8_t pat[])
                 case 0xCF:          /* Iret */
                     continue;
 
-                case 0xD0:          /* Group 2 rotate, uint8_t, 1 bit */
-                case 0xD1:          /* Group 2 rotate, uint16_t, 1 bit */
-                case 0xD2:          /* Group 2 rotate, uint8_t, CL bits */
-                case 0xD3:          /* Group 2 rotate, uint16_t, CL bits */
+                case 0xD0:          /* Group 2 rotate, byte, 1 bit */
+                case 0xD1:          /* Group 2 rotate, word, 1 bit */
+                case 0xD2:          /* Group 2 rotate, byte, CL bits */
+                case 0xD3:          /* Group 2 rotate, word, CL bits */
                     if (ModRM(pat)) return;
                     continue;
 
@@ -498,8 +502,8 @@ fixWildCards(uint8_t pat[])
                 case 0xFD:          /* Std */
                     continue;
 
-                case 0xF6:          /* Group 3 uint8_t test/not/mul/div */
-                case 0xF7:          /* Group 3 uint16_t test/not/mul/div */
+                case 0xF6:          /* Group 3 byte test/not/mul/div */
+                case 0xF7:          /* Group 3 word test/not/mul/div */
                 case 0xFE:          /* Inc/Dec group 4 */
                     if (ModRM(pat)) return;
                     continue;
@@ -509,7 +513,7 @@ fixWildCards(uint8_t pat[])
                     if (ModRM(pat)) return;
                     continue;
 
-                default:            /* Rest are single uint8_t opcodes */
+                default:            /* Rest are single byte opcodes */
                     continue;
             }
         }

+ 446 - 297
src/frontend.cpp

@@ -1,51 +1,54 @@
 /*****************************************************************************
-*			dcc project Front End module
-* Loads a program into simulated main memory and builds the procedure list.
-* (C) Cristina Cifuentes
-****************************************************************************/
+ *			dcc project Front End module
+ * Loads a program into simulated main memory and builds the procedure list.
+ * (C) Cristina Cifuentes
+ ****************************************************************************/
 
 #include "dcc.h"
-#include "disassem.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#ifdef __BORLAND__
+#include <alloc.h>
+#else
 #include <malloc.h>			/* For malloc, free, realloc */
-#include "project.h"
+#endif
+
 typedef struct {			/*        PSP structure					*/
-    uint16_t int20h;			/* interrupt 20h						*/
-    uint16_t eof;				/* segment, end of allocation block		*/
-    uint8_t res1;				/* reserved                         	*/
-    uint8_t dosDisp[5];		/* far call to DOS function dispatcher	*/
-    uint8_t int22h[4];			/* vector for terminate routine			*/
-    uint8_t int23h[4];			/* vector for ctrl+break routine		*/
-    uint8_t int24h[4];			/* vector for error routine				*/
-    uint8_t res2[22];			/* reserved								*/
-    uint16_t segEnv;			/* segment address of environment block	*/
-    uint8_t res3[34];			/* reserved								*/
-    uint8_t int21h[6];			/* opcode for int21h and far return		*/
-    uint8_t res4[6];			/* reserved								*/
-    uint8_t fcb1[16];			/* default file control block 1			*/
-    uint8_t fcb2[16];      	/* default file control block 2			*/
-    uint8_t res5[4];			/* reserved								*/
-    uint8_t cmdTail[0x80];		/* command tail and disk transfer area	*/
+	word int20h;			/* interrupt 20h						*/
+	word eof;				/* segment, end of allocation block		*/
+	byte res1;				/* reserved                         	*/
+	byte dosDisp[5];		/* far call to DOS function dispatcher	*/
+	byte int22h[4];			/* vector for terminate routine			*/
+	byte int23h[4];			/* vector for ctrl+break routine		*/
+	byte int24h[4];			/* vector for error routine				*/
+	byte res2[22];			/* reserved								*/
+	word segEnv;			/* segment address of environment block	*/
+	byte res3[34];			/* reserved								*/
+	byte int21h[6];			/* opcode for int21h and far return		*/
+	byte res4[6];			/* reserved								*/
+	byte fcb1[16];			/* default file control block 1			*/
+	byte fcb2[16];      	/* default file control block 2			*/
+	byte res5[4];			/* reserved								*/
+	byte cmdTail[0x80];		/* command tail and disk transfer area	*/
 } PSP;
 
 static struct {				/*      EXE file header		 	 */
-    uint8_t	sigLo;			/* .EXE signature: 0x4D 0x5A	 */
-    uint8_t	sigHi;
-    uint16_t	lastPageSize;	/* Size of the last page		 */
-    uint16_t	numPages;		/* Number of pages in the file	 */
-    uint16_t	numReloc;		/* Number of relocation items	 */
-    uint16_t	numParaHeader;	/* # of paragraphs in the header */
-    uint16_t	minAlloc;		/* Minimum number of paragraphs	 */
-    uint16_t	maxAlloc;		/* Maximum number of paragraphs	 */
-    uint16_t	initSS;			/* Segment displacement of stack */
-    uint16_t	initSP;			/* Contents of SP at entry       */
-    uint16_t	checkSum;		/* Complemented checksum         */
-    uint16_t	initIP;			/* Contents of IP at entry       */
-    uint16_t	initCS;			/* Segment displacement of code  */
-    uint16_t	relocTabOffset;	/* Relocation table offset       */
-    uint16_t	overlayNum;		/* Overlay number                */
+	 byte	sigLo;			/* .EXE signature: 0x4D 0x5A	 */
+	 byte	sigHi;
+	 word	lastPageSize;	/* Size of the last page		 */
+	 word	numPages;		/* Number of pages in the file	 */
+	 word	numReloc;		/* Number of relocation items	 */
+	 word	numParaHeader;	/* # of paragraphs in the header */
+	 word	minAlloc;		/* Minimum number of paragraphs	 */
+	 word	maxAlloc;		/* Maximum number of paragraphs	 */
+	 word	initSS;			/* Segment displacement of stack */
+	 word	initSP;			/* Contents of SP at entry       */
+	 word	checkSum;		/* Complemented checksum         */
+	 word	initIP;			/* Contents of IP at entry       */
+	 word	initCS;			/* Segment displacement of code  */
+	 word	relocTabOffset;	/* Relocation table offset       */
+	 word	overlayNum;		/* Overlay number                */
 } header;
 
 #define EXE_RELOCATION  0x10		/* EXE images rellocated to above PSP */
@@ -55,294 +58,440 @@ static void displayLoadInfo(void);
 static void displayMemMap(void);
 
 /*****************************************************************************
-* FrontEnd - invokes the loader, parser, disassembler (if asm1), icode
-* rewritter, and displays any useful information.
-****************************************************************************/
-extern Project g_proj;
-bool DccFrontend::FrontEnd ()
+ * FrontEnd - invokes the loader, parser, disassembler (if asm1), icode
+ * rewritter, and displays any useful information.
+ ****************************************************************************/
+void FrontEnd (char *filename, PCALL_GRAPH *pcallGraph)
 {
-
-    g_proj.callGraph = 0;
-    g_proj.m_fname = m_fname;
-
-    /* Load program into memory */
-    LoadImage(g_proj);
-
-    if (option.verbose)
-        displayLoadInfo();
-
-    /* Do depth first flow analysis building call graph and procedure list,
-     * and attaching the I-code to each procedure          */
-    parse (g_proj);
-
-    if (option.asm1)
-    {
-        printf("dcc: writing assembler file %s\n", asm1_name);
-    }
-
-    /* Search through code looking for impure references and flag them */
-    Disassembler ds(1);
-    for(Function &f : g_proj.pProcList)
-    {
-        f.markImpure();
-        if (option.asm1)
-        {
-            ds.disassem(&f);
-        }
-    }
-    if (option.Interact)
-    {
-        interactDis(&g_proj.pProcList.front(), 0);     /* Interactive disassembler */
-    }
-
-    /* Converts jump target addresses to icode offsets */
-    for(Function &f : g_proj.pProcList)
-    {
-        f.bindIcodeOff();
-    }
-    /* Print memory bitmap */
-    if (option.Map)
-        displayMemMap();
-    return(true); // we no longer own proj !
+	PPROC pProc;
+	PSYM psym;
+	Int	i, c;
+	
+	/* Load program into memory */
+	LoadImage(filename);
+
+	if (option.verbose)
+	{
+		displayLoadInfo();
+	}
+
+	/* Do depth first flow analysis building call graph and procedure list,
+	 * and attaching the I-code to each procedure          */
+	parse (pcallGraph);
+
+	if (option.asm1)
+	{
+		printf("dcc: writing assembler file %s\n", asm1_name);
+	}
+
+	/* Search through code looking for impure references and flag them */
+	for (pProc = pProcList; pProc; pProc = pProc->next)
+	{
+		for (i = 0; i < pProc->Icode.GetNumIcodes(); i++)
+		{
+			if (pProc->Icode.GetLlFlag(i) & (SYM_USE | SYM_DEF))
+			{
+				psym = &symtab.sym[pProc->Icode.GetIcode(i)->ic.ll.caseTbl.numEntries];
+				for (c = (Int)psym->label; c < (Int)psym->label+psym->size; c++)
+				{
+					if (BITMAP(c, BM_CODE))
+					{
+						pProc->Icode.SetLlFlag(i, IMPURE);
+						pProc->flg |= IMPURE;
+						break;
+					}
+				}
+			}
+		}
+		/* Print assembler listing */
+		if (option.asm1)
+			disassem(1, pProc);
+	}
+
+	if (option.Interact)
+	{
+		interactDis(pProcList, 0);			/* Interactive disassembler */
+	}
+
+	/* Converts jump target addresses to icode offsets */
+	for (pProc = pProcList; pProc; pProc = pProc->next)
+		bindIcodeOff (pProc); 
+
+	/* Print memory bitmap */
+	if (option.Map)
+		displayMemMap();
 }
 
 
 /****************************************************************************
-* displayLoadInfo - Displays low level loader type info.
-***************************************************************************/
+ * displayLoadInfo - Displays low level loader type info.
+ ***************************************************************************/
 static void displayLoadInfo(void)
 {
-    PROG &prog(Project::get()->prog);
-    int	i;
-
-    printf("File type is %s\n", (prog.fCOM)?"COM":"EXE");
-    if (! prog.fCOM) {
-        printf("Signature            = %02X%02X\n", header.sigLo, header.sigHi);
-        printf("File size %% 512     = %04X\n", LH(&header.lastPageSize));
-        printf("File size / 512      = %04X pages\n", LH(&header.numPages));
-        printf("# relocation items   = %04X\n", LH(&header.numReloc));
-        printf("Offset to load image = %04X paras\n", LH(&header.numParaHeader));
-        printf("Minimum allocation   = %04X paras\n", LH(&header.minAlloc));
-        printf("Maximum allocation   = %04X paras\n", LH(&header.maxAlloc));
-    }
-    printf("Load image size      = %04X\n", prog.cbImage - sizeof(PSP));
-    printf("Initial SS:SP        = %04X:%04X\n", prog.initSS, prog.initSP);
-    printf("Initial CS:IP        = %04X:%04X\n", prog.initCS, prog.initIP);
-
-    if (option.VeryVerbose && prog.cReloc)
-    {
-        printf("\nRelocation Table\n");
-        for (i = 0; i < prog.cReloc; i++)
-        {
-            printf("%06X -> [%04X]\n", prog.relocTable[i],LH(prog.Image + prog.relocTable[i]));
-        }
-    }
-    printf("\n");
+	Int	i;
+
+	printf("File type is %s\n", (prog.fCOM)?"COM":"EXE");
+	if (! prog.fCOM) {
+	    printf("Signature            = %02X%02X\n", header.sigLo, header.sigHi);
+	    printf("File size %% 512      = %04X\n", LH(&header.lastPageSize));
+	    printf("File size / 512      = %04X pages\n", LH(&header.numPages));
+	    printf("# relocation items   = %04X\n", LH(&header.numReloc));
+	    printf("Offset to load image = %04X paras\n", LH(&header.numParaHeader));
+		printf("Minimum allocation   = %04X paras\n", LH(&header.minAlloc));
+		printf("Maximum allocation   = %04X paras\n", LH(&header.maxAlloc));
+	}
+	printf("Load image size      = %04X\n", prog.cbImage - sizeof(PSP));
+	printf("Initial SS:SP        = %04X:%04X\n", prog.initSS, prog.initSP);
+	printf("Initial CS:IP        = %04X:%04X\n", prog.initCS, prog.initIP);
+
+	if (option.VeryVerbose && prog.cReloc)
+	{
+		printf("\nRelocation Table\n");
+		for (i = 0; i < prog.cReloc; i++)
+		{
+			printf("%06X -> [%04X]\n", prog.relocTable[i],
+					LH(prog.Image + prog.relocTable[i]));
+		}
+	}
+	printf("\n");
 }
 
 
 /*****************************************************************************
-* fill - Fills line for displayMemMap()
-****************************************************************************/
-static void fill(int ip, char *bf)
+ * fill - Fills line for displayMemMap()
+ ****************************************************************************/
+static void fill(Int ip, char *bf)
 {
-    PROG &prog(Project::get()->prog);
-    static uint8_t type[4] = {'.', 'd', 'c', 'x'};
-    uint8_t	i;
-
-    for (i = 0; i < 16; i++, ip++)
-    {
-        *bf++ = ' ';
-        *bf++ = (ip < prog.cbImage)? type[(prog.map[ip >> 2] >> ((ip & 3) * 2)) & 3]: ' ';
-    }
-    *bf = '\0';
+	static byte type[4] = {'.', 'd', 'c', 'x'};
+	byte	i;
+
+	for (i = 0; i < 16; i++, ip++)
+	{
+		*bf++ = ' ';
+		*bf++ = (ip < prog.cbImage)? 
+			type[(prog.map[ip >> 2] >> ((ip & 3) * 2)) & 3]: ' ';
+	}
+	*bf = '\0';
 }
 
 
 /*****************************************************************************
-* displayMemMap - Displays the memory bitmap
-****************************************************************************/
+ * displayMemMap - Displays the memory bitmap
+ ****************************************************************************/
 static void displayMemMap(void)
 {
-    PROG &prog(Project::get()->prog);
-
-    char	c, b1[33], b2[33], b3[33];
-    uint8_t i;
-    int ip = 0;
-
-    printf("\nMemory Map\n");
-    while (ip < prog.cbImage)
-    {
-        fill(ip, b1);
-        printf("%06X %s\n", ip, b1);
-        ip += 16;
-        for (i = 3, c = b1[1]; i < 32 && c == b1[i]; i += 2)
-            ;		/* Check if all same */
-        if (i > 32)
-        {
-            fill(ip, b2);	/* Skip until next two are not same */
-            fill(ip+16, b3);
-            if (! (strcmp(b1, b2) || strcmp(b1, b3)))
-            {
-                printf("                   :\n");
-                do
-                {
-                    ip += 16;
-                    fill(ip+16, b1);
-                } while (! strcmp(b1, b2));
-            }
-        }
-    }
-    printf("\n");
+	char	c, b1[33], b2[33], b3[33];
+	byte i;
+	Int ip = 0;
+
+	printf("\nMemory Map\n");
+	while (ip < prog.cbImage)
+	{
+		fill(ip, b1);
+		printf("%06X %s\n", ip, b1);
+		ip += 16;
+		for (i = 3, c = b1[1]; i < 32 && c == b1[i]; i += 2)
+			;		/* Check if all same */
+		if (i > 32)
+		{
+			fill(ip, b2);	/* Skip until next two are not same */
+			fill(ip+16, b3);
+			if (! (strcmp(b1, b2) || strcmp(b1, b3)))
+			{
+				printf("                   :\n");
+				do
+				{
+					ip += 16;
+					fill(ip+16, b1);
+				} while (! strcmp(b1, b2));
+			}
+		}
+	}
+	printf("\n");
 }
 
 
 /*****************************************************************************
-* LoadImage
-****************************************************************************/
-void DccFrontend::LoadImage(Project &proj)
+ * LoadImage
+ ****************************************************************************/
+static void LoadImage(char *filename)
+{
+	FILE   *fp;
+	Int		i, cb;
+	byte	buf[4];
+
+	/* Open the input file */
+	if ((fp = fopen(filename, "rb")) == NULL)
+	{
+		fatalError(CANNOT_OPEN, filename);
+	}
+
+	/* Read in first 2 bytes to check EXE signature */
+	if (fread(&header, 1, 2, fp) != 2)
+	{
+		fatalError(CANNOT_READ, filename);
+	}
+
+	if (! (prog.fCOM = (boolT)(header.sigLo != 0x4D || header.sigHi != 0x5A))) {
+		/* Read rest of header */
+		fseek(fp, 0, SEEK_SET);
+		if (fread(&header, sizeof(header), 1, fp) != 1)
+		{
+			fatalError(CANNOT_READ, filename);
+		}
+
+		/* This is a typical DOS kludge! */
+		if (LH(&header.relocTabOffset) == 0x40)
+		{
+			fatalError(NEWEXE_FORMAT);
+		}
+
+		/* Calculate the load module size.
+		 * This is the number of pages in the file
+		 * less the length of the header and reloc table
+		 * less the number of bytes unused on last page
+		*/
+		cb = (dword)LH(&header.numPages) * 512 - (dword)LH(&header.numParaHeader) * 16;
+		if (header.lastPageSize)
+		{
+			cb -= 512 - LH(&header.lastPageSize);
+		}
+		
+		/* We quietly ignore minAlloc and maxAlloc since for our
+		 * purposes it doesn't really matter where in real memory
+		 * the program would end up.  EXE programs can't really rely on
+		 * their load location so setting the PSP segment to 0 is fine.
+		 * Certainly programs that prod around in DOS or BIOS are going
+		 * to have to load DS from a constant so it'll be pretty 
+		 * obvious.
+		*/
+		prog.initCS = (int16)LH(&header.initCS) + EXE_RELOCATION;
+		prog.initIP = (int16)LH(&header.initIP);
+		prog.initSS = (int16)LH(&header.initSS) + EXE_RELOCATION;
+		prog.initSP = (int16)LH(&header.initSP);
+		prog.cReloc = (int16)LH(&header.numReloc);
+
+		/* Allocate the relocation table */
+		if (prog.cReloc)
+		{
+			prog.relocTable = (dword*)allocMem(prog.cReloc * sizeof(Int));
+			fseek(fp, LH(&header.relocTabOffset), SEEK_SET);
+
+			/* Read in seg:offset pairs and convert to Image ptrs */
+			for (i = 0; i < prog.cReloc; i++)
+			{
+				fread(buf, 1, 4, fp);
+				prog.relocTable[i] = LH(buf) + 
+					(((Int)LH(buf+2) + EXE_RELOCATION)<<4);
+			}
+		}
+		/* Seek to start of image */
+		fseek(fp, (Int)LH(&header.numParaHeader) * 16, SEEK_SET);
+	}
+	else
+	{	/* COM file
+		 * In this case the load module size is just the file length
+		*/
+		fseek(fp, 0, SEEK_END);
+		cb = ftell(fp);
+
+		/* COM programs start off with an ORG 100H (to leave room for a PSP)
+		 * This is also the implied start address so if we load the image
+		 * at offset 100H addresses should all line up properly again.
+		*/
+		prog.initCS = 0;
+		prog.initIP = 0x100;
+		prog.initSS = 0;
+		prog.initSP = 0xFFFE;
+		prog.cReloc = 0;
+
+		fseek(fp, 0, SEEK_SET);
+	}
+
+	/* Allocate a block of memory for the program. */
+	prog.cbImage  = cb + sizeof(PSP);
+	prog.Image    = (byte*)allocMem(prog.cbImage);
+	prog.Image[0] = 0xCD;		/* Fill in PSP Int 20h location */
+	prog.Image[1] = 0x20;		/* for termination checking     */
+
+	/* Read in the image past where a PSP would go */
+#ifdef __DOSWIN__
+	if (cb > 0xFFFF)
+	{
+		printf("Image size of %ld bytes too large for fread!\n", cb);
+		fatalError(CANNOT_READ, filename);
+	}
+#endif
+	if (cb != (Int)fread(prog.Image + sizeof(PSP), 1, (size_t)cb, fp))
+	{
+		fatalError(CANNOT_READ, filename);
+	}
+
+	/* Set up memory map */
+	cb = (prog.cbImage + 3) / 4;
+	prog.map = (byte *)memset(allocMem(cb), BM_UNKNOWN, (size_t)cb);
+
+	/* Relocate segment constants */
+	if (prog.cReloc)
+	{
+		for (i = 0; i < prog.cReloc; i++)
+		{
+			byte *p = &prog.Image[prog.relocTable[i]];
+			word  w = (word)LH(p) + EXE_RELOCATION;
+			*p++    = (byte)(w & 0x00FF);
+			*p      = (byte)((w & 0xFF00) >> 8);
+		}
+	}
+
+	fclose(fp);
+}
+
+
+/*****************************************************************************
+ * allocMem - malloc with failure test
+ ****************************************************************************/
+void *allocMem(Int cb)
+{
+	byte *p;
+
+//printf("Attempt to allocMem %5ld bytes\n", cb);
+
+#if 0		/* Microsoft specific heap debugging code */
+switch (_heapset('Z'))
 {
-    PROG &prog(Project::get()->prog);
-    FILE   *fp;
-    int		i, cb;
-    uint8_t	buf[4];
-
-    /* Open the input file */
-    if ((fp = fopen(proj.m_fname.c_str(), "rb")) == NULL)
-    {
-        fatalError(CANNOT_OPEN, proj.m_fname.c_str());
-    }
-
-    /* Read in first 2 bytes to check EXE signature */
-    if (fread(&header, 1, 2, fp) != 2)
-    {
-        fatalError(CANNOT_READ, proj.m_fname.c_str());
-    }
-
-    if (! (prog.fCOM = (boolT)(header.sigLo != 0x4D || header.sigHi != 0x5A))) {
-        /* Read rest of header */
-        fseek(fp, 0, SEEK_SET);
-        if (fread(&header, sizeof(header), 1, fp) != 1)
-        {
-            fatalError(CANNOT_READ, proj.m_fname.c_str());
-        }
-
-        /* This is a typical DOS kludge! */
-        if (LH(&header.relocTabOffset) == 0x40)
-        {
-            fatalError(NEWEXE_FORMAT);
-        }
-
-        /* Calculate the load module size.
-        * This is the number of pages in the file
-        * less the length of the header and reloc table
-        * less the number of bytes unused on last page
-        */
-        cb = (uint32_t)LH(&header.numPages) * 512 - (uint32_t)LH(&header.numParaHeader) * 16;
-        if (header.lastPageSize)
-        {
-            cb -= 512 - LH(&header.lastPageSize);
-        }
-
-        /* We quietly ignore minAlloc and maxAlloc since for our
-* purposes it doesn't really matter where in real memory
-* the program would end up.  EXE programs can't really rely on
-* their load location so setting the PSP segment to 0 is fine.
-* Certainly programs that prod around in DOS or BIOS are going
-* to have to load DS from a constant so it'll be pretty
-* obvious.
-*/
-        prog.initCS = (int16_t)LH(&header.initCS) + EXE_RELOCATION;
-        prog.initIP = (int16_t)LH(&header.initIP);
-        prog.initSS = (int16_t)LH(&header.initSS) + EXE_RELOCATION;
-        prog.initSP = (int16_t)LH(&header.initSP);
-        prog.cReloc = (int16_t)LH(&header.numReloc);
-
-        /* Allocate the relocation table */
-        if (prog.cReloc)
-        {
-            prog.relocTable = new uint32_t [prog.cReloc];
-            fseek(fp, LH(&header.relocTabOffset), SEEK_SET);
-
-            /* Read in seg:offset pairs and convert to Image ptrs */
-            for (i = 0; i < prog.cReloc; i++)
-            {
-                fread(buf, 1, 4, fp);
-                prog.relocTable[i] = LH(buf) +
-                        (((int)LH(buf+2) + EXE_RELOCATION)<<4);
-            }
-        }
-        /* Seek to start of image */
-        uint32_t start_of_image= LH(&header.numParaHeader) * 16;
-        fseek(fp, start_of_image, SEEK_SET);
-    }
-    else
-    {	/* COM file
-         * In this case the load module size is just the file length
-         */
-        fseek(fp, 0, SEEK_END);
-        cb = ftell(fp);
-
-        /* COM programs start off with an ORG 100H (to leave room for a PSP)
-         * This is also the implied start address so if we load the image
-         * at offset 100H addresses should all line up properly again.
-         */
-        prog.initCS = 0;
-        prog.initIP = 0x100;
-        prog.initSS = 0;
-        prog.initSP = 0xFFFE;
-        prog.cReloc = 0;
-
-        fseek(fp, 0, SEEK_SET);
-    }
-
-    /* Allocate a block of memory for the program. */
-    prog.cbImage  = cb + sizeof(PSP);
-    prog.Image    = new uint8_t [prog.cbImage];
-    prog.Image[0] = 0xCD;		/* Fill in PSP int 20h location */
-    prog.Image[1] = 0x20;		/* for termination checking     */
-
-    /* Read in the image past where a PSP would go */
-    if (cb != (int)fread(prog.Image + sizeof(PSP), 1, (size_t)cb, fp))
-    {
-        fatalError(CANNOT_READ, proj.m_fname.c_str());
-    }
-
-    /* Set up memory map */
-    cb = (prog.cbImage + 3) / 4;
-    prog.map = (uint8_t *)malloc(cb);
-    memset(prog.map, BM_UNKNOWN, (size_t)cb);
-
-    /* Relocate segment constants */
-    if (prog.cReloc)
-    {
-        for (i = 0; i < prog.cReloc; i++)
-        {
-            uint8_t *p = &prog.Image[prog.relocTable[i]];
-            uint16_t  w = (uint16_t)LH(p) + EXE_RELOCATION;
-            *p++    = (uint8_t)(w & 0x00FF);
-            *p      = (uint8_t)((w & 0xFF00) >> 8);
-        }
-    }
-
-    fclose(fp);
+	case _HEAPBADBEGIN: printf("aM: Bad heap begin\n"); break;
+	case _HEAPBADNODE:	printf("aM: Bad heap node\n");
+	printf("Attempt to allocMem %5d bytes\n", cb);
+	{
+		_HEAPINFO hinfo;
+		int heapstatus;
+		boolT cont = TRUE;
+
+		hinfo._pentry = NULL;
+
+		while (cont)
+		{
+			switch (heapstatus = _heapwalk(&hinfo))
+			{
+				case _HEAPOK:
+					printf("%6s block at %Fp of size %4.4X\n",
+						(hinfo._useflag == _USEDENTRY ? "USED" : "FREE"),
+						hinfo._pentry, hinfo._size);
+					break;
+				case _HEAPBADBEGIN:
+					printf("Heap bad begin\n");
+					break;
+				case _HEAPBADNODE:
+					printf("BAD NODE %6s block at %Fp of size %4.4X\n",
+						(hinfo._useflag == _USEDENTRY ? "USED" : "FREE"),
+						hinfo._pentry, hinfo._size);
+					break;
+				case _HEAPEND:
+					cont = FALSE;
+					break;
+				case _HEAPBADPTR:
+					printf("INFO BAD %6s block at %Fp of size %4.4X\n",
+						(hinfo._useflag == _USEDENTRY ? "USED" : "FREE"),
+						hinfo._pentry, hinfo._size);
+					cont=FALSE;
+
+			}
+		}
+	}
+	getchar();
+	exit(1);
+
+	case _HEAPEMPTY:	printf("aM: Heap empty\n");		getchar(); break;
+	case _HEAPOK:putchar('.');break;
+}
+#endif
+
+	if (! (p = (byte*)malloc((size_t)cb)))
+/*	if (! (p = (byte*)calloc((size_t)cb, 1)))	*/
+	{
+		fatalError(MALLOC_FAILED, cb);
+	}
+/*printf("allocMem: %p\n", p);/**/
+	return p;
 }
 
 
 /*****************************************************************************
-* allocMem - malloc with failure test
-****************************************************************************/
-void *allocMem(int cb)
+ * reallocVar - reallocs extra variable space
+ ****************************************************************************/
+void *reallocVar(void *p, Int newsize)
+{
+/*printf("Attempt to reallocVar %5d bytes\n", newsize);/**/
+#if 0
+switch (_heapset('Z'))
 {
-    uint8_t *p;
+	case _HEAPBADBEGIN: printf("aV: Bad heap begin\n"); /*getchar()*/; break;
+	case _HEAPBADNODE:	printf("aV: Bad heap node\n");
+	printf("Attempt to reallocVar %5d bytes at %p\n", newsize, p);/**/
+	{
+		_HEAPINFO hinfo;
+		int heapstatus;
+		boolT cont = TRUE;
+
+		hinfo._pentry = NULL;
+
+		while (cont)
+		{
+			switch (heapstatus = _heapwalk(&hinfo))
+			{
+				case _HEAPOK:
+					printf("%6s block at %Fp of size %4.4X\n",
+						(hinfo._useflag == _USEDENTRY ? "USED" : "FREE"),
+						hinfo._pentry, hinfo._size);
+					break;
+				case _HEAPBADBEGIN:
+					printf("Heap bad begin\n");
+					break;
+				case _HEAPBADNODE:
+					printf("BAD NODE %6s block at %Fp of size %4.4X\n",
+						(hinfo._useflag == _USEDENTRY ? "USED" : "FREE"),
+						hinfo._pentry, hinfo._size);
+					break;
+				case _HEAPEND:
+					cont = FALSE;
+					break;
+				case _HEAPBADPTR:
+					printf("INFO BAD %6s block at %Fp of size %4.4X\n",
+						(hinfo._useflag == _USEDENTRY ? "USED" : "FREE"),
+						hinfo._pentry, hinfo._size);
+					cont=FALSE;
+
+			}
+		}
+	}
+	getchar();
+	break;
+
+	case _HEAPEMPTY:	printf("aV: Heap empty\n");		getchar(); break;
+	case _HEAPOK:putchar('!');break;
+}
+#endif
 
-    //printf("Attempt to allocMem %5ld bytes\n", cb);
+	if (! (p = realloc((byte *)p, (size_t)newsize)))
+	{
+		fatalError(MALLOC_FAILED, newsize);
+	}
 
-    if (! (p = (uint8_t*)malloc((size_t)cb)))
-        /*	if (! (p = (uint8_t*)calloc((size_t)cb, 1)))	*/
-    {
-        fatalError(MALLOC_FAILED, cb);
-    }
-    // printf("allocMem: %p\n", p);
-    return p;
+/*printf("reallocVar: %p\n", p);/**/
+	return p;
 }
+
+#if 0
+void free(void *p)
+{
+	_ffree(p);
+switch (_heapset('Z'))
+{
+	case _HEAPBADBEGIN: printf("f: Bad heap begin\n"); getchar(); break;
+	case _HEAPBADNODE:	printf("f: Bad heap node\n");  getchar(); break;
+	case _HEAPEMPTY:	printf("f: Heap empty\n");		getchar(); break;
+	case _HEAPOK:putchar('!');break;
+}/**/
+}
+#endif
+

+ 348 - 358
src/graph.cpp

@@ -5,406 +5,396 @@
 
 #include "dcc.h"
 #include <string.h>
+#if __BORLAND__
+#include <alloc.h>
+#else
 #include <malloc.h>		/* For free() */
-#include "graph.h"
-#include "project.h"
-extern Project g_proj;
-//static BB *  rmJMP(Function * pProc, int marker, BB * pBB);
-static void mergeFallThrough(Function * pProc, BB * pBB);
-static void dfsNumbering(BB * pBB, std::vector<BB*> &dfsLast, int *first, int *last);
+#endif
+
+static PBB  rmJMP(PPROC pProc, Int marker, PBB pBB);
+static void mergeFallThrough(PPROC pProc, PBB pBB);
+static void dfsNumbering(PBB pBB, PBB *dfsLast, Int *first, Int *last);
 
 /*****************************************************************************
  * createCFG - Create the basic control flow graph
  ****************************************************************************/
-void Function::createCFG()
+PBB createCFG(PPROC pProc)
 {
-    /* Splits Icode associated with the procedure into Basic Blocks.
-     * The links between BBs represent the control flow graph of the
-     * procedure.
-     * A Basic Block is defined to end on one of the following instructions:
-     * 1) Conditional and unconditional jumps
-     * 2) CALL(F)
-     * 3) RET(F)
-     * 4) On the instruction before a join (a flagged TARGET)
-     * 5) Repeated string instructions
-     * 6) End of procedure
-     */
-    int		i;
-    int		ip;
-    BB *        psBB;
-    BB *        pBB;
-    iICODE 	pIcode = Icode.begin();
-    iICODE      iStart = Icode.begin();
-    stats.numBBbef = stats.numBBaft = 0;
-    for (; pIcode!=Icode.end(); ++pIcode)
-    {
-        iICODE nextIcode = ++iICODE(pIcode);
-        LLInst *ll = pIcode->ll();
-        /* Stick a NOWHERE_NODE on the end if we terminate
-                 * with anything other than a ret, jump or terminate */
-        if (nextIcode == Icode.end() and
-                (not ll->testFlags(TERMINATES)) and
-                (not ll->match(iJMP)) and (not ll->match(iJMPF)) and
-                (not ll->match(iRET)) and (not ll->match(iRETF)))
-        {
-            //pBB=BB::Create(start, ip, NOWHERE_NODE, 0, this);
-            pBB=BB::Create(iStart, pIcode, NOWHERE_NODE, 0, this);
-
-        }
-
-        /* Only process icodes that have valid instructions */
-        else if (not ll->testFlags(NO_CODE) )
-        {
-            switch (ll->getOpcode()) {
-                case iJB:  case iJBE:  case iJAE:  case iJA:
-                case iJL:  case iJLE:  case iJGE:  case iJG:
-                case iJE:  case iJNE:  case iJS:   case iJNS:
-                case iJO:  case iJNO:  case iJP:   case iJNP:
-                case iJCXZ:
-                    pBB = BB::Create(iStart, pIcode, TWO_BRANCH, 2, this);
-CondJumps:
-                    //start = ip + 1;
-                    iStart = ++iICODE(pIcode);
-                    pBB->edges[0].ip = (uint32_t)iStart->loc_ip;
-                    /* This is for jumps off into nowhere */
-                    if ( ll->testFlags(NO_LABEL) )
-                    {
-                        pBB->edges.pop_back();
-                    }
-                    else
-                        pBB->edges[1].ip = ll->src().getImm2();
-                    break;
-
-                case iLOOP: case iLOOPE: case iLOOPNE:
-                    //pBB = BB::Create(start, ip, LOOP_NODE, 2, this);
-                    pBB = BB::Create(iStart, pIcode, LOOP_NODE, 2, this);
-                    goto CondJumps;
-
-                case iJMPF: case iJMP:
-                    if (ll->testFlags(SWITCH))
-                    {
-                        //pBB = BB::Create(start, ip, MULTI_BRANCH, ll->caseTbl.numEntries, this);
-                        pBB = BB::Create(iStart, pIcode, MULTI_BRANCH, ll->caseTbl2.size(), this);
-                        for (i = 0; i < ll->caseTbl2.size(); i++)
-                            pBB->edges[i].ip = ll->caseTbl2[i];
-                        hasCase = true;
-                    }
-                    else if ((ll->getFlag() & (I | NO_LABEL)) == I) //TODO: WHY NO_LABEL TESTIT
-                    {
-                        //pBB = BB::Create(start, ip, ONE_BRANCH, 1, this);
-                        pBB = BB::Create(iStart, pIcode, ONE_BRANCH, 1, this);
-
-                        pBB->edges[0].ip = ll->src().getImm2();
-                    }
-                    else
-                        BB::Create(iStart, pIcode,  NOWHERE_NODE, 0, this);
-                    iStart = ++iICODE(pIcode);
-                    break;
-
-                case iCALLF: case iCALL:
-                {
-                    Function * p = ll->src().proc.proc;
-                    if (p)
-                        i = ((p->flg) & TERMINATES) ? 0 : 1;
-                    else
-                        i = 1;
-                    pBB = BB::Create(iStart, pIcode,  CALL_NODE, i, this);
-                    iStart = ++iICODE(pIcode);//start = ip + 1;
-                    if (i)
-                        pBB->edges[0].ip = iStart->loc_ip;//(uint32_t)start;
-                }
-                    break;
-
-                case iRET:  case iRETF:
-                    //BB::Create(start, ip, RETURN_NODE, 0, this);
-                    BB::Create(iStart, pIcode,  RETURN_NODE, 0, this);
-                    iStart = ++iICODE(pIcode);
-                    break;
-
-                default:
-                    /* Check for exit to DOS */
-                    iICODE next1=++iICODE(pIcode);
-                    if ( ll->testFlags(TERMINATES) )
-                    {
-                        pBB = BB::Create(iStart, pIcode,  TERMINATE_NODE, 0, this);
-                        //pBB = BB::Create(start, ip, TERMINATE_NODE, 0, this);
-                        iStart = ++iICODE(pIcode); // start = ip + 1;
-                    }
-                    /* Check for a fall through */
-                    else if (next1 != Icode.end())
-                    {
-                        if (next1->ll()->testFlags(TARGET | CASE))
-                        {
-                            //pBB = BB::Create(start, ip, FALL_NODE, 1, this);
-                            pBB = BB::Create(iStart, pIcode,  FALL_NODE, 1, this);
-                            iStart = ++iICODE(pIcode); // start = ip + 1;
-                            pBB->addOutEdge(iStart->loc_ip);
-                            pBB->edges[0].ip = iStart->loc_ip;//(uint32_t)start;
-                        }
-                    }
-                    break;
-            }
-        }
-    }
-    auto iter=heldBBs.begin();
-    /* Convert list of BBs into a graph */
-    for (; iter!=heldBBs.end(); ++iter)
-    {
-        pBB = *iter;
-        for (size_t edeg_idx = 0; edeg_idx < pBB->edges.size(); edeg_idx++)
-        {
-            uint32_t ip = pBB->edges[edeg_idx].ip;
-            if (ip >= SYNTHESIZED_MIN)
-            {
-                fatalError (INVALID_SYNTHETIC_BB);
-                return;
-            }
-            auto iter2=std::find_if(heldBBs.begin(),heldBBs.end(),
-                                    [ip](BB *psBB)->bool {return psBB->begin()->loc_ip==ip;});
-            if(iter2==heldBBs.end())
-                fatalError(NO_BB, ip, name.c_str());
-            psBB = *iter2;
-            pBB->edges[edeg_idx].BBptr = psBB;
-            psBB->inEdges.push_back((BB *)nullptr);
-        }
-    }
-}
-
-void Function::markImpure()
-{
-    PROG &prog(Project::get()->prog);
-    for(ICODE &icod : Icode)
-    {
-        if ( not icod.ll()->testFlags(SYM_USE | SYM_DEF))
-            continue;
-        //assert that case tbl has less entries then symbol table ????
-        //WARNING: Case entries are held in symbol table !
-        assert(g_proj.validSymIdx(icod.ll()->caseEntry));
-        const SYM &psym(g_proj.getSymByIdx(icod.ll()->caseEntry));
-        for (int c = (int)psym.label; c < (int)psym.label+psym.size; c++)
-        {
-            if (BITMAP(c, BM_CODE))
-            {
-                icod.ll()->setFlags(IMPURE);
-                flg |= IMPURE;
-                break;
-            }
-        }
-    }
-
+	/* Splits Icode associated with the procedure into Basic Blocks.
+	 * The links between BBs represent the control flow graph of the 
+	 * procedure.
+	 * A Basic Block is defined to end on one of the following instructions:
+	 * 1) Conditional and unconditional jumps
+	 * 2) CALL(F)
+	 * 3) RET(F)
+	 * 4) On the instruction before a join (a flagged TARGET)
+	 * 5) Repeated string instructions 
+	 * 6) End of procedure
+	*/   
+	Int		i;
+	Int		ip, start;
+	BB		cfg;
+	PBB		psBB;
+	PBB		pBB    = &cfg;
+	PICODE	pIcode = pProc->Icode.GetFirstIcode();
+
+	cfg.next = NULL;
+	stats.numBBbef = stats.numBBaft = 0;
+	for (ip = start = 0; pProc->Icode.IsValid(pIcode); ip++, pIcode++) 
+	{
+		/* Stick a NOWHERE_NODE on the end if we terminate
+		 * with anything other than a ret, jump or terminate */
+		if (ip + 1 == pProc->Icode.GetNumIcodes() && 
+			! (pIcode->ic.ll.flg & TERMINATES) &&
+			pIcode->ic.ll.opcode != iJMP && pIcode->ic.ll.opcode != iJMPF &&
+			pIcode->ic.ll.opcode != iRET && pIcode->ic.ll.opcode != iRETF)
+			newBB(pBB, start, ip, NOWHERE_NODE, 0, pProc);
+
+		/* Only process icodes that have valid instructions */
+		else if ((pIcode->ic.ll.flg & NO_CODE) != NO_CODE) 
+		{
+			switch (pIcode->ic.ll.opcode) {
+			case iJB:  case iJBE:  case iJAE:  case iJA:
+			case iJL:  case iJLE:  case iJGE:  case iJG:
+			case iJE:  case iJNE:  case iJS:   case iJNS:
+			case iJO:  case iJNO:  case iJP:   case iJNP:
+			case iJCXZ:
+				pBB = newBB(pBB, start, ip, TWO_BRANCH, 2, pProc);
+			CondJumps:
+				start = ip + 1;
+				pBB->edges[0].ip = (dword)start;
+				/* This is for jumps off into nowhere */
+				if (pIcode->ic.ll.flg & NO_LABEL)
+					pBB->numOutEdges--;
+				else
+					pBB->edges[1].ip = pIcode->ic.ll.immed.op;
+				break;
+
+			case iLOOP: case iLOOPE: case iLOOPNE:
+				pBB = newBB(pBB, start, ip, LOOP_NODE, 2, pProc);
+				goto CondJumps;
+
+			case iJMPF: case iJMP:
+				if (pIcode->ic.ll.flg & SWITCH)
+				{
+					pBB = newBB(pBB, start, ip, MULTI_BRANCH,
+							   pIcode->ic.ll.caseTbl.numEntries, pProc);
+					for (i = 0; i < pIcode->ic.ll.caseTbl.numEntries; i++)
+						pBB->edges[i].ip = pIcode->ic.ll.caseTbl.entries[i];
+					pProc->hasCase = TRUE;
+				}
+				else if ((pIcode->ic.ll.flg & (I | NO_LABEL)) == I) {
+				    pBB = newBB(pBB, start, ip, ONE_BRANCH, 1, pProc);
+					pBB->edges[0].ip = pIcode->ic.ll.immed.op;
+				}
+				else	
+					newBB(pBB, start, ip, NOWHERE_NODE, 0, pProc);
+				start = ip + 1;
+				break;
+
+			case iCALLF: case iCALL:
+				{ PPROC p = pIcode->ic.ll.immed.proc.proc;
+				  if (p)
+					  i = ((p->flg) & TERMINATES) ? 0 : 1;
+				  else
+					  i = 1;
+				  pBB = newBB(pBB, start, ip, CALL_NODE, i, pProc);
+				  start = ip + 1;
+				  if (i)
+					 pBB->edges[0].ip = (dword)start;
+				}
+				break;
+
+			case iRET:  case iRETF:
+				newBB(pBB, start, ip, RETURN_NODE, 0, pProc);
+				start = ip + 1;
+				break;
+
+			default:
+				/* Check for exit to DOS */
+				if (pIcode->ic.ll.flg & TERMINATES) 
+				{
+					pBB = newBB(pBB, start, ip, TERMINATE_NODE, 0, pProc);
+					start = ip + 1;
+				}
+				/* Check for a fall through */
+				else if (pProc->Icode.GetFirstIcode()[ip + 1].ic.ll.flg & (TARGET | CASE))
+				{
+					pBB = newBB(pBB, start, ip, FALL_NODE, 1, pProc);
+					start = ip + 1;
+					pBB->edges[0].ip = (dword)start;
+				}
+				break;
+			}
+		}
+	}
+
+	/* Convert list of BBs into a graph */
+	for (pBB = cfg.next; pBB; pBB = pBB->next)
+	{
+		for (i = 0; i < pBB->numOutEdges; i++)
+		{
+			ip = pBB->edges[i].ip;
+			if (ip >= SYNTHESIZED_MIN)
+				fatalError (INVALID_SYNTHETIC_BB);
+			else
+			{
+				for (psBB = cfg.next; psBB; psBB = psBB->next)
+					if (psBB->start == ip)
+					{
+						pBB->edges[i].BBptr = psBB;
+						psBB->numInEdges++;
+						break;
+					}
+				if (! psBB)
+					fatalError(NO_BB, ip, pProc->name);
+			}
+		}
+	}
+	return cfg.next;
 }
 
 
-
 /*****************************************************************************
  * newBB - Allocate new BB and link to end of list
  *****************************************************************************/
+PBB newBB (PBB pBB, Int start, Int ip, byte nodeType, Int numOutEdges, 
+		   PPROC pproc)
+{
+  PBB pnewBB;
+
+	pnewBB = allocStruc(BB);
+	memset (pnewBB, 0, sizeof(BB));
+	pnewBB->nodeType = nodeType;	/* Initialise */
+	pnewBB->start = start;
+	pnewBB->length = ip - start + 1;
+	pnewBB->numOutEdges = (byte)numOutEdges;
+	pnewBB->immedDom = NO_DOM;
+	pnewBB->loopHead = pnewBB->caseHead = pnewBB->caseTail =
+		pnewBB->latchNode= pnewBB->loopFollow = NO_NODE;
+
+	if (numOutEdges)
+		pnewBB->edges = (TYPEADR_TYPE*)allocMem(numOutEdges * sizeof(TYPEADR_TYPE));
+
+	/* Mark the basic block to which the icodes belong to, but only for
+	 * real code basic blocks (ie. not interval bbs) */
+	if (start >= 0)
+		pproc->Icode.SetInBB(start, ip, pnewBB);
+
+	while (pBB->next)		/* Link */
+		pBB = pBB->next;
+	pBB->next = pnewBB;
+
+	if (start != -1) {		/* Only for code BB's */
+		stats.numBBbef++;
+	}
+	return pnewBB;
+}
+
 
 /*****************************************************************************
  * freeCFG - Deallocates a cfg
  ****************************************************************************/
-void Function::freeCFG()
+void freeCFG(PBB cfg)
 {
-    for(BB *p : heldBBs)
-    {
-        delete p;
-    }
+	PBB	pBB;
+
+	for (pBB = cfg; pBB; pBB = cfg) {
+		if (pBB->inEdges)
+			free(pBB->inEdges);
+		if (pBB->edges)
+			free(pBB->edges);
+		cfg = pBB->next;
+		free(pBB);
+	}
 }
 
 
 /*****************************************************************************
  * compressCFG - Remove redundancies and add in-edge information
  ****************************************************************************/
-void Function::compressCFG()
-{
-    BB *pNxt;
-    int	ip, first=0, last;
-
-    /* First pass over BB list removes redundant jumps of the form
-         * (Un)Conditional -> Unconditional jump  */
-    for (BB *pBB : m_cfg)
-    {
-        if(pBB->inEdges.empty() || (pBB->nodeType != ONE_BRANCH && pBB->nodeType != TWO_BRANCH))
-            continue;
-        for (TYPEADR_TYPE &edgeRef : pBB->edges)
-        {
-            ip   = pBB->rbegin()->loc_ip;
-            pNxt = edgeRef.BBptr->rmJMP(ip, edgeRef.BBptr);
-
-            if (not pBB->edges.empty())   /* Might have been clobbered */
-            {
-                edgeRef.BBptr = pNxt;
-                assert(pBB->back().loc_ip==ip);
-                pBB->back().ll()->SetImmediateOp((uint32_t)pNxt->begin()->loc_ip);
-                //Icode[ip].SetImmediateOp((uint32_t)pNxt->begin());
-            }
-        }
-    }
-
-    /* Next is a depth-first traversal merging any FALL_NODE or
-     * ONE_BRANCH that fall through to a node with that as their only
-     * in-edge. */
-    m_cfg.front()->mergeFallThrough(Icode);
-
-    /* Remove redundant BBs created by the above compressions
-     * and allocate in-edge arrays as required. */
-    stats.numBBaft = stats.numBBbef;
-
-    for(auto iter=m_cfg.begin(); iter!=m_cfg.end(); ++iter)
-    {
-        BB * pBB = *iter;
-        if (pBB->inEdges.empty())
-        {
-            if (iter == m_cfg.begin())	/* Init it misses out on */
-                pBB->index = UN_INIT;
-            else
-            {
-                delete pBB;
-                stats.numBBaft--;
-            }
-        }
-        else
-        {
-            pBB->inEdgeCount = pBB->inEdges.size();
-        }
-    }
-
-    /* Allocate storage for dfsLast[] array */
-    numBBs = stats.numBBaft;
-    m_dfsLast.resize(numBBs,0); // = (BB **)allocMem(numBBs * sizeof(BB *))
-
-    /* Now do a dfs numbering traversal and fill in the inEdges[] array */
-    last = numBBs - 1;
-    m_cfg.front()->dfsNumbering(m_dfsLast, &first, &last);
+void compressCFG(PPROC pProc)
+{ PBB	pBB, pNxt;
+  Int	ip, first=0, last, i;
+
+	/* First pass over BB list removes redundant jumps of the form
+	 * (Un)Conditional -> Unconditional jump  */
+	for (pBB = pProc->cfg; pBB; pBB = pBB->next)
+		if (pBB->numInEdges != 0 && (pBB->nodeType == ONE_BRANCH ||
+			pBB->nodeType == TWO_BRANCH))
+			for (i = 0; i < pBB->numOutEdges; i++) 
+	{
+			ip   = pBB->start + pBB->length - 1;
+			pNxt = rmJMP(pProc, ip, pBB->edges[i].BBptr);
+
+			if (pBB->numOutEdges)   /* Might have been clobbered */
+			{
+				pBB->edges[i].BBptr = pNxt;
+				pProc->Icode.SetImmediateOp(ip, (dword)pNxt->start);
+			}
+	}
+
+	/* Next is a depth-first traversal merging any FALL_NODE or
+	 * ONE_BRANCH that fall through to a node with that as their only
+	 * in-edge. */
+	mergeFallThrough(pProc, pProc->cfg);
+
+	/* Remove redundant BBs created by the above compressions
+	 * and allocate in-edge arrays as required. */
+	stats.numBBaft = stats.numBBbef;
+
+	for (pBB = pProc->cfg; pBB; pBB = pNxt)
+	{
+		pNxt = pBB->next;
+		if (pBB->numInEdges == 0) 
+		{
+			if (pBB == pProc->cfg)	/* Init it misses out on */
+				pBB->index = UN_INIT;
+			else
+			{
+				if (pBB->numOutEdges)
+					free(pBB->edges);
+				free(pBB);
+				stats.numBBaft--;
+			}
+		}
+		else 
+		{
+			pBB->inEdgeCount = pBB->numInEdges;
+			pBB->inEdges = (PBB*)allocMem(pBB->numInEdges * sizeof(PBB));
+		}
+	}
+
+	/* Allocate storage for dfsLast[] array */
+	pProc->numBBs = stats.numBBaft;
+	pProc->dfsLast = (PBB*)allocMem(pProc->numBBs * sizeof(PBB)); 
+
+	/* Now do a dfs numbering traversal and fill in the inEdges[] array */
+	last = pProc->numBBs - 1;
+	dfsNumbering(pProc->cfg, pProc->dfsLast, &first, &last);
 }
 
 
 /****************************************************************************
  * rmJMP - If BB addressed is just a JMP it is replaced with its target
  ***************************************************************************/
-BB *BB::rmJMP(int marker, BB * pBB)
+static PBB rmJMP(PPROC pProc, Int marker, PBB pBB)
 {
-    marker += (int)DFS_JMP;
-
-    while (pBB->nodeType == ONE_BRANCH && pBB->size() == 1)
-    {
-        if (pBB->traversed != marker)
-        {
-            pBB->traversed = (eDFS)marker;
-            pBB->inEdges.pop_back();
-            if (not pBB->inEdges.empty())
-            {
-                pBB->edges[0].BBptr->inEdges.push_back((BB *)nullptr);
-            }
-            else
-            {
-                pBB->front().ll()->setFlags(NO_CODE);
-                pBB->front().invalidate(); //pProc->Icode.SetLlInvalid(pBB->begin(), true);
-            }
-
-            pBB = pBB->edges[0].BBptr;
-        }
-        else
-        {
-            /* We are going around in circles */
-            pBB->nodeType = NOWHERE_NODE;
-            pBB->front().ll()->replaceSrc(LLOperand::CreateImm2(pBB->front().loc_ip));
-            //pBB->front().ll()->src.immed.op = pBB->front().loc_ip;
-            do {
-                pBB = pBB->edges[0].BBptr;
-                pBB->inEdges.pop_back(); // was --numInedges
-                if (! pBB->inEdges.empty())
-                {
-                    pBB->front().ll()->setFlags(NO_CODE);
-                    pBB->front().invalidate();
-                    //                    pProc->Icode.setFlags(pBB->start, NO_CODE);
-                    //                    pProc->Icode.SetLlInvalid(pBB->start, true);
-                }
-            } while (pBB->nodeType != NOWHERE_NODE);
-
-            pBB->edges.clear();
-        }
-    }
-    return pBB;
+	marker += DFS_JMP;
+
+	while (pBB->nodeType == ONE_BRANCH && pBB->length == 1) {
+		if (pBB->traversed != marker) {
+			pBB->traversed = marker;
+			if (--pBB->numInEdges)
+				pBB->edges[0].BBptr->numInEdges++;
+			else
+			{
+				pProc->Icode.SetLlFlag(pBB->start, NO_CODE);
+				pProc->Icode.SetLlInvalid(pBB->start, TRUE);
+			}
+
+			pBB = pBB->edges[0].BBptr;
+		}
+		else {			/* We are going around in circles */
+			pBB->nodeType = NOWHERE_NODE;
+			pProc->Icode.GetIcode(pBB->start)->ic.ll.immed.op = (dword)pBB->start;
+			pProc->Icode.SetImmediateOp(pBB->start, (dword)pBB->start);
+			do {
+				pBB = pBB->edges[0].BBptr;
+				if (! --pBB->numInEdges)
+				{
+					pProc->Icode.SetLlFlag(pBB->start, NO_CODE);
+					pProc->Icode.SetLlInvalid(pBB->start, TRUE);
+				}
+			} while (pBB->nodeType != NOWHERE_NODE);
+
+			free(pBB->edges);
+			pBB->numOutEdges = 0;
+			pBB->edges       = NULL;
+		}
+	}
+	return pBB;
 }
 
 
 /*****************************************************************************
  * mergeFallThrough
  ****************************************************************************/
-void BB::mergeFallThrough( CIcodeRec &Icode)
+static void mergeFallThrough(PPROC pProc, PBB pBB)
 {
-    BB *	pChild;
-    int	i;
-
-    if (!this)
-    {
-        printf("mergeFallThrough on empty BB!\n");
-    }
-    while (nodeType == FALL_NODE || nodeType == ONE_BRANCH)
-    {
-        pChild = edges[0].BBptr;
-        /* Jump to next instruction can always be removed */
-        if (nodeType == ONE_BRANCH)
-        {
-            assert(Parent==pChild->Parent);
-            if(back().loc_ip>pChild->front().loc_ip) // back edege
-                break;
-            auto iter=std::find_if(this->end(),pChild->begin(),[](ICODE &c)
-            {return not c.ll()->testFlags(NO_CODE);});
-
-            if (iter != pChild->begin())
-                break;
-            back().ll()->setFlags(NO_CODE);
-            back().invalidate();
-            nodeType = FALL_NODE;
-            //instructions.advance_end(-1); //TODO: causes creation of empty BB
-        }
-        /* If there's no other edges into child can merge */
-        if (pChild->inEdges.size() != 1)
-            break;
-
-        nodeType = pChild->nodeType;
-        instructions = boost::make_iterator_range(begin(),pChild->end());
-        pChild->front().ll()->clrFlags(TARGET);
-        edges.swap(pChild->edges);
-
-        pChild->inEdges.clear();
-        pChild->edges.clear();
-    }
-    traversed = DFS_MERGE;
-
-    /* Process all out edges recursively */
-    for (i = 0; i < edges.size(); i++)
-    if (edges[i].BBptr->traversed != DFS_MERGE)
-    edges[i].BBptr->mergeFallThrough(Icode);
+	PBB	pChild;
+	Int	i, ip;
+
+	if (pBB) {
+		while (pBB->nodeType == FALL_NODE || pBB->nodeType == ONE_BRANCH) 
+		{
+			pChild = pBB->edges[0].BBptr;
+			/* Jump to next instruction can always be removed */
+			if (pBB->nodeType == ONE_BRANCH) 
+			{
+				ip = pBB->start + pBB->length;
+				for (i = ip; i < pChild->start
+					&& (pProc->Icode.GetLlFlag(i) & NO_CODE); i++);
+				if (i != pChild->start)
+					break;
+				pProc->Icode.SetLlFlag(ip - 1, NO_CODE);
+				pProc->Icode.SetLlInvalid(ip - 1, TRUE);
+				pBB->nodeType = FALL_NODE;
+				pBB->length--;
+
+			}
+			/* If there's no other edges into child can merge */
+			if (pChild->numInEdges != 1)
+				break;
+
+			pBB->nodeType = pChild->nodeType;
+			pBB->length = pChild->start + pChild->length - pBB->start;
+			pProc->Icode.ClearLlFlag(pChild->start, TARGET);
+			pBB->numOutEdges = pChild->numOutEdges;
+			free(pBB->edges);
+			pBB->edges = pChild->edges;
+
+			pChild->numOutEdges = pChild->numInEdges = 0;
+			pChild->edges = NULL;
+		}
+		pBB->traversed = DFS_MERGE;
+
+		/* Process all out edges recursively */
+		for (i = 0; i < pBB->numOutEdges; i++)
+			if (pBB->edges[i].BBptr->traversed != DFS_MERGE)
+				mergeFallThrough(pProc, pBB->edges[i].BBptr);
+	}
 }
 
 
 /*****************************************************************************
- * dfsNumbering - Numbers nodes during first and last visits and determine
+ * dfsNumbering - Numbers nodes during first and last visits and determine 
  * in-edges
  ****************************************************************************/
-void BB::dfsNumbering(std::vector<BB *> &dfsLast, int *first, int *last)
+static void dfsNumbering(PBB pBB, PBB *dfsLast, Int *first, Int *last)
 {
-    BB *		pChild;
-    traversed = DFS_NUM;
-    dfsFirstNum = (*first)++;
-
-    /* index is being used as an index to inEdges[]. */
-    //    for (i = 0; i < edges.size(); i++)
-    for(auto edge : edges)
-    {
-        pChild = edge.BBptr;
-        pChild->inEdges[pChild->index++] = this;
-
-        /* Is this the last visit? */
-        if (pChild->index == pChild->inEdges.size())
-            pChild->index = UN_INIT;
-
-        if (pChild->traversed != DFS_NUM)
-            pChild->dfsNumbering(dfsLast, first, last);
-    }
-    dfsLastNum = *last;
-    dfsLast[(*last)--] = this;
+	PBB		pChild;
+	byte	i;
+
+	if (pBB) 
+	{
+		pBB->traversed = DFS_NUM;
+		pBB->dfsFirstNum = (*first)++;
+
+		/* index is being used as an index to inEdges[]. */
+		for (i = 0; i < pBB->numOutEdges; i++) 
+		{
+			pChild = pBB->edges[i].BBptr;
+			pChild->inEdges[pChild->index++] = pBB;
+
+			/* Is this the last visit? */
+			if (pChild->index == pChild->numInEdges)
+				pChild->index = UN_INIT;
+
+			if (pChild->traversed != DFS_NUM)
+				dfsNumbering(pChild, dfsLast, first, last);
+		}
+		pBB->dfsLastNum = *last;
+		dfsLast[(*last)--] = pBB;
+	}
 }

+ 366 - 514
src/hlicode.cpp

@@ -4,631 +4,483 @@
  * Date:    September-October 1993
  * (C) Cristina Cifuentes
  */
-#include <cassert>
+
 #include <string.h>
-#include <string>
-#include <sstream>
 #include "dcc.h"
-using namespace std;
+
 #define ICODE_DELTA 25
 
 /* Masks off bits set by duReg[] */
-std::bitset<32> maskDuReg[] = { 0x00,
-                                0xFEEFFE, 0xFDDFFD, 0xFBB00B, 0xF77007, /* uint16_t regs */
-                                0xFFFFEF, 0xFFFFDF, 0xFFFFBF, 0xFFFF7F,
-                                0xFFFEFF, 0xFFFDFF, 0xFFFBFF, 0xFFF7FF, /* seg regs  */
-                                0xFFEFFF, 0xFFDFFF, 0xFFBFFF, 0xFF7FFF, /* uint8_t regs */
-                                0xFEFFFF, 0xFDFFFF, 0xFBFFFF, 0xF7FFFF,
-                                0xEFFFFF,                               /* tmp reg   */
-                                0xFFFFB7, 0xFFFF77, 0xFFFF9F, 0xFFFF5F, /* index regs */
-                                0xFFFFBF, 0xFFFF7F, 0xFFFFDF, 0xFFFFF7 };
+dword maskDuReg[] = { 0x00,
+            0xFEEFFE, 0xFDDFFD, 0xFBB00B, 0xF77007, /* word regs */
+            0xFFFFEF, 0xFFFFDF, 0xFFFFBF, 0xFFFF7F,
+            0xFFFEFF, 0xFFFDFF, 0xFFFBFF, 0xFFF7FF, /* seg regs  */
+            0xFFEFFF, 0xFFDFFF, 0xFFBFFF, 0xFF7FFF, /* byte regs */
+            0xFEFFFF, 0xFDFFFF, 0xFBFFFF, 0xF7FFFF,
+            0xEFFFFF,                               /* tmp reg   */
+            0xFFFFB7, 0xFFFF77, 0xFFFF9F, 0xFFFF5F, /* index regs */
+            0xFFFFBF, 0xFFFF7F, 0xFFFFDF, 0xFFFFF7 };
 
 static char buf[lineSize];     /* Line buffer for hl icode output */
 
 
 
+void newAsgnHlIcode (PICODE pIcode, COND_EXPR *lhs, COND_EXPR *rhs)
 /* Places the new HLI_ASSIGN high-level operand in the high-level icode array */
-void HLTYPE::setAsgn(COND_EXPR *lhs, COND_EXPR *rhs)
-{
-    set(lhs,rhs);
-
-}
-void ICODE::checkHlCall()
 {
-    //assert((ll()->immed.proc.cb != 0)||ll()->immed.proc.proc!=0);
+    pIcode->type = HIGH_LEVEL;
+    pIcode->ic.hl.opcode = HLI_ASSIGN;
+    pIcode->ic.hl.oper.asgn.lhs = lhs;
+    pIcode->ic.hl.oper.asgn.rhs = rhs;
 }
+
+
+void newCallHlIcode (PICODE pIcode)
 /* Places the new HLI_CALL high-level operand in the high-level icode array */
-void ICODE::newCallHl()
 {
-    type = HIGH_LEVEL;
-    hl()->opcode = HLI_CALL;
-    hl()->call.proc = ll()->src().proc.proc;
-    hl()->call.args = new STKFRAME;
-
-    if (ll()->src().proc.cb != 0)
-        hl()->call.args->cb = ll()->src().proc.cb;
-    else if(hl()->call.proc)
-        hl()->call.args->cb =hl()->call.proc->cbParam;
-    else
-    {
-        printf("Function with no cb set, and no valid oper.call.proc , probaby indirect call\n");
-        hl()->call.args->cb = 0;
-    }
+    pIcode->type = HIGH_LEVEL;
+    pIcode->ic.hl.opcode = HLI_CALL;
+    pIcode->ic.hl.oper.call.proc = pIcode->ic.ll.immed.proc.proc;
+	pIcode->ic.hl.oper.call.args = (STKFRAME*)allocMem (sizeof(STKFRAME));
+	memset (pIcode->ic.hl.oper.call.args, 0, sizeof(STKFRAME));
+	if (pIcode->ic.ll.immed.proc.cb != 0)
+		pIcode->ic.hl.oper.call.args->cb = pIcode->ic.ll.immed.proc.cb;
+	else
+		pIcode->ic.hl.oper.call.args->cb =pIcode->ic.hl.oper.call.proc->cbParam;
 }
 
 
-/* Places the new HLI_POP/HLI_PUSH/HLI_RET high-level operand in the high-level icode
+void newUnaryHlIcode (PICODE pIcode, hlIcode op, COND_EXPR *exp)
+/* Places the new HLI_POP/HLI_PUSH/HLI_RET high-level operand in the high-level icode 
  * array */
-void ICODE::setUnary(hlIcode op, COND_EXPR *_exp)
 {
-    type = HIGH_LEVEL;
-    hl()->set(op,_exp);
+    pIcode->type = HIGH_LEVEL;
+    pIcode->ic.hl.opcode = op;
+    pIcode->ic.hl.oper.exp = exp;
 }
 
 
+void newJCondHlIcode (PICODE pIcode, COND_EXPR *cexp)
 /* Places the new HLI_JCOND high-level operand in the high-level icode array */
-void ICODE::setJCond(COND_EXPR *cexp)
 {
-    type = HIGH_LEVEL;
-    hl()->set(HLI_JCOND,cexp);
+    pIcode->type = HIGH_LEVEL;
+    pIcode->ic.hl.opcode = HLI_JCOND;
+    pIcode->ic.hl.oper.exp = cexp;
 }
 
 
-/* Sets the invalid field to true as this low-level icode is no longer valid,
+void invalidateIcode (PICODE pIcode)
+/* Sets the invalid field to TRUE as this low-level icode is no longer valid,
  * it has been replaced by a high-level icode. */
-void ICODE ::invalidate()
 {
-    invalid = true;
+    pIcode->invalid = TRUE;
 }
 
 
-/* Removes the defined register regi from the lhs subtree.
- * If all registers
- * of this instruction are unused, the instruction is invalidated (ie. removed)
- */
-bool ICODE::removeDefRegi (eReg regi, int thisDefIdx, LOCAL_ID *locId)
-{
-    int numDefs;
+boolT removeDefRegi (byte regi, PICODE picode, Int thisDefIdx, LOCAL_ID *locId)
+/* Removes the defined register regi from the lhs subtree.  If all registers
+ * of this instruction are unused, the instruction is invalidated (ie.
+ * removed) */
+{ Int numDefs;
 
-    numDefs = du1.numRegsDef;
+    numDefs = picode->du1.numRegsDef;
     if (numDefs == thisDefIdx)
-    {
         for ( ; numDefs > 0; numDefs--)
         {
-
-            if (du1.used(numDefs-1)||(du.lastDefRegi[regi]))
+            if ((picode->du1.idx[numDefs-1][0] != 0)||(picode->du.lastDefRegi)) 
                 break;
         }
-    }
 
     if (numDefs == 0)
     {
-        invalidate();
-        return true;
+        invalidateIcode (picode);
+        return (TRUE);
     }
-    HlTypeSupport *p=hl()->get();
-    if(p and p->removeRegFromLong(regi,locId))
-    {
-        du1.numRegsDef--;
-        du.def &= maskDuReg[regi];
-    }
-    return false;
-}
-HLTYPE LLInst::createCall()
-{
-    HLTYPE res(HLI_CALL);
-    res.call.proc = src().proc.proc;
-    res.call.args = new STKFRAME;
-
-    if (src().proc.cb != 0)
-        res.call.args->cb = src().proc.cb;
-    else if(res.call.proc)
-        res.call.args->cb =res.call.proc->cbParam;
     else
     {
-        printf("Function with no cb set, and no valid oper.call.proc , probaby indirect call\n");
-        res.call.args->cb = 0;
+        switch (picode->ic.hl.opcode) {
+        case HLI_ASSIGN:    removeRegFromLong (regi, locId, 
+                                                picode->ic.hl.oper.asgn.lhs);
+                        picode->du1.numRegsDef--;
+                        picode->du.def &= maskDuReg[regi];
+                        break;
+        case HLI_POP:
+        case HLI_PUSH:      removeRegFromLong (regi, locId, picode->ic.hl.oper.exp);
+                        picode->du1.numRegsDef--;
+                        picode->du.def &= maskDuReg[regi];
+                        break;
+        }
+        return (FALSE);
     }
-    return res;
 }
-#if 0
-HLTYPE LLInst::toHighLevel(COND_EXPR *lhs,COND_EXPR *rhs,Function *func)
-{
-    HLTYPE res(HLI_INVALID);
-    if ( testFlags(NOT_HLL) )
-        return res;
-    flg = getFlag();
 
-    switch (getOpcode())
-    {
-        case iADD:
-            rhs = COND_EXPR::boolOp (lhs, rhs, ADD);
-            res.setAsgn(lhs, rhs);
-            break;
-
-        case iAND:
-            rhs = COND_EXPR::boolOp (lhs, rhs, AND);
-            res.setAsgn(lhs, rhs);
-            break;
-
-        case iCALL:
-        case iCALLF:
-            //TODO: this is noop pIcode->checkHlCall();
-            res=createCall();
-            break;
-
-        case iDEC:
-            rhs = COND_EXPR::idKte (1, 2);
-            rhs = COND_EXPR::boolOp (lhs, rhs, SUB);
-            res.setAsgn(lhs, rhs);
-            break;
-
-        case iDIV:
-        case iIDIV:/* should be signed div */
-            rhs = COND_EXPR::boolOp (lhs, rhs, DIV);
-            if ( ll->testFlags(B) )
-            {
-                lhs = COND_EXPR::idReg (rAL, 0, &localId);
-                pIcode->setRegDU( rAL, eDEF);
-            }
-            else
-            {
-                lhs = COND_EXPR::idReg (rAX, 0, &localId);
-                pIcode->setRegDU( rAX, eDEF);
-            }
-            res.setAsgn(lhs, rhs);
-            break;
-
-        case iIMUL:
-            rhs = COND_EXPR::boolOp (lhs, rhs, MUL);
-            lhs = COND_EXPR::id (*pIcode, LHS_OP, func, i, *pIcode, NONE);
-            res.setAsgn(lhs, rhs);
-            break;
-
-        case iINC:
-            rhs = COND_EXPR::idKte (1, 2);
-            rhs = COND_EXPR::boolOp (lhs, rhs, ADD);
-            res.setAsgn(lhs, rhs);
-            break;
-
-        case iLEA:
-            rhs = COND_EXPR::unary (ADDRESSOF, rhs);
-            res.setAsgn(lhs, rhs);
-            break;
-
-        case iMOD:
-            rhs = COND_EXPR::boolOp (lhs, rhs, MOD);
-            if ( ll->testFlags(B) )
-            {
-                lhs = COND_EXPR::idReg (rAH, 0, &localId);
-                pIcode->setRegDU( rAH, eDEF);
-            }
-            else
-            {
-                lhs = COND_EXPR::idReg (rDX, 0, &localId);
-                pIcode->setRegDU( rDX, eDEF);
-            }
-            res.setAsgn(lhs, rhs);
-            break;
-
-        case iMOV:    res.setAsgn(lhs, rhs);
-            break;
-
-        case iMUL:
-            rhs = COND_EXPR::boolOp (lhs, rhs, MUL);
-            lhs = COND_EXPR::id (*pIcode, LHS_OP, this, i, *pIcode, NONE);
-            res.setAsgn(lhs, rhs);
-            break;
-
-        case iNEG:
-            rhs = COND_EXPR::unary (NEGATION, lhs);
-            res.setAsgn(lhs, rhs);
-            break;
-
-        case iNOT:
-            rhs = COND_EXPR::boolOp (NULL, rhs, NOT);
-            res.setAsgn(lhs, rhs);
-            break;
-
-        case iOR:
-            rhs = COND_EXPR::boolOp (lhs, rhs, OR);
-            res.setAsgn(lhs, rhs);
-            break;
-
-        case iPOP:    res.set(HLI_POP, lhs);
-            break;
-
-        case iPUSH:   res.set(HLI_PUSH, lhs);
-            break;
-
-        case iRET:
-        case iRETF:
-            res.set(HLI_RET, NULL);
-            break;
-
-        case iSHL:
-            rhs = COND_EXPR::boolOp (lhs, rhs, SHL);
-            res.setAsgn(lhs, rhs);
-            break;
-
-        case iSAR:    /* signed */
-        case iSHR:
-            rhs = COND_EXPR::boolOp (lhs, rhs, SHR); /* unsigned*/
-            res.setAsgn(lhs, rhs);
-            break;
-
-        case iSIGNEX:
-            res.setAsgn(lhs, rhs);
-            break;
-
-        case iSUB:
-            rhs = COND_EXPR::boolOp (lhs, rhs, SUB);
-            res.setAsgn(lhs, rhs);
-            break;
-
-        case iXCHG:
-            break;
-
-        case iXOR:
-            rhs = COND_EXPR::boolOp (lhs, rhs, XOR);
-            res.setAsgn(lhs, rhs);
-            break;
-    }
-    return res;
-}
-#endif
+
+void highLevelGen (PPROC pProc)
 /* Translates LOW_LEVEL icodes to HIGH_LEVEL icodes - 1st stage.
  * Note: this process should be done before data flow analysis, which
  *       refines the HIGH_LEVEL icodes. */
-void Function::highLevelGen()
-{
-    int numIcode;         /* number of icode instructions */
-    iICODE pIcode;        /* ptr to current icode node */
-    COND_EXPR *lhs, *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)
+{ Int i,                /* idx into icode array */
+      numIcode;         /* number of icode instructions */ 
+  PICODE pIcode;        /* ptr to current icode node */
+  COND_EXPR *lhs, *rhs; /* left- and right-hand side of expression */
+  flags32 flg;          /* icode flags */
+
+    numIcode = pProc->Icode.GetNumIcodes();
+    for (i = 0; i < numIcode; i++)
     {
-        assert(numIcode==Icode.size());
-        pIcode = i; //Icode.GetIcode(i)
-        LLInst *ll = pIcode->ll();
-        if ( ll->testFlags(NOT_HLL) )
-            pIcode->invalidate();
-        if ((pIcode->type != LOW_LEVEL) or not pIcode->valid() )
-            continue;
-        _flg = ll->getFlag();
-        if ((_flg & IM_OPS) != IM_OPS)   /* not processing IM_OPS yet */
-            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);
-            }
-        switch (ll->getOpcode())
+        pIcode = pProc->Icode.GetIcode(i);
+        if ((pIcode->ic.ll.flg & NOT_HLL) == NOT_HLL)
+            invalidateIcode (pIcode);
+        if ((pIcode->type == LOW_LEVEL) && (pIcode->invalid == FALSE))
         {
-            case iADD:
-                rhs = COND_EXPR::boolOp (lhs, rhs, ADD);
-                pIcode->setAsgn(lhs, rhs);
-                break;
-
-            case iAND:
-                rhs = COND_EXPR::boolOp (lhs, rhs, AND);
-                pIcode->setAsgn(lhs, rhs);
-                break;
-
-            case iCALL:
-            case iCALLF:
-                pIcode->type = HIGH_LEVEL;
-                pIcode->hl( ll->createCall() );
-                break;
-
-            case iDEC:
-                rhs = COND_EXPR::idKte (1, 2);
-                rhs = COND_EXPR::boolOp (lhs, rhs, SUB);
-                pIcode->setAsgn(lhs, rhs);
-                break;
-
-            case iDIV:
-            case iIDIV:/* should be signed div */
-                rhs = COND_EXPR::boolOp (lhs, rhs, DIV);
-                if ( ll->testFlags(B) )
-                {
-                    lhs = COND_EXPR::idReg (rAL, 0, &localId);
-                    pIcode->setRegDU( rAL, eDEF);
-                }
-                else
-                {
-                    lhs = COND_EXPR::idReg (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);
-                pIcode->setAsgn(lhs, rhs);
-                break;
-
-            case iINC:
-                rhs = COND_EXPR::idKte (1, 2);
-                rhs = COND_EXPR::boolOp (lhs, rhs, ADD);
-                pIcode->setAsgn(lhs, rhs);
-                break;
-
-            case iLEA:
-                rhs = COND_EXPR::unary (ADDRESSOF, rhs);
-                pIcode->setAsgn(lhs, rhs);
-                break;
-
-            case iMOD:
-                rhs = COND_EXPR::boolOp (lhs, rhs, MOD);
-                if ( ll->testFlags(B) )
+            flg = pIcode->ic.ll.flg;
+            if ((flg & IM_OPS) != IM_OPS)   /* not processing IM_OPS yet */
+                if ((flg & NO_OPS) != NO_OPS)       /* if there are opers */
                 {
-                    lhs = COND_EXPR::idReg (rAH, 0, &localId);
-                    pIcode->setRegDU( rAH, eDEF);
+                    if ((flg & NO_SRC) != NO_SRC)   /* if there is src op */
+                        rhs = idCondExp (pIcode, SRC, pProc, i, pIcode, NONE);
+                    lhs = idCondExp (pIcode, DST, pProc, i, pIcode, NONE);
                 }
-                else
-                {
-                    lhs = COND_EXPR::idReg (rDX, 0, &localId);
-                    pIcode->setRegDU( rDX, eDEF);
-                }
-                pIcode->setAsgn(lhs, rhs);
-                break;
-
-            case iMOV:    pIcode->setAsgn(lhs, rhs);
-                break;
-
-            case iMUL:
-                rhs = COND_EXPR::boolOp (lhs, rhs, MUL);
-                lhs = COND_EXPR::id (*ll, LHS_OP, this, i, *pIcode, NONE);
-                pIcode->setAsgn(lhs, rhs);
-                break;
-
-            case iNEG:
-                rhs = COND_EXPR::unary (NEGATION, lhs);
-                pIcode->setAsgn(lhs, rhs);
-                break;
-
-            case iNOT:
-                rhs = COND_EXPR::boolOp (NULL, rhs, NOT);
-                pIcode->setAsgn(lhs, rhs);
-                break;
-
-            case iOR:
-                rhs = COND_EXPR::boolOp (lhs, rhs, OR);
-                pIcode->setAsgn(lhs, rhs);
-                break;
-
-            case iPOP:    pIcode->setUnary(HLI_POP, lhs);
-                break;
-
-            case iPUSH:   pIcode->setUnary(HLI_PUSH, lhs);
-                break;
-
-            case iRET:
-            case iRETF:   pIcode->setUnary(HLI_RET, NULL);
-                break;
-
-            case iSHL:
-                rhs = COND_EXPR::boolOp (lhs, rhs, SHL);
-                pIcode->setAsgn(lhs, rhs);
-                break;
 
-            case iSAR:    /* signed */
-            case iSHR:
-                rhs = COND_EXPR::boolOp (lhs, rhs, SHR); /* unsigned*/
-                pIcode->setAsgn(lhs, rhs);
-                break;
-
-            case iSIGNEX: pIcode->setAsgn(lhs, rhs);
-                break;
-
-            case iSUB:
-                rhs = COND_EXPR::boolOp (lhs, rhs, SUB);
-                pIcode->setAsgn(lhs, rhs);
-                break;
-
-            case iXCHG:
-                break;
-
-            case iXOR:
-                rhs = COND_EXPR::boolOp (lhs, rhs, XOR);
-                pIcode->setAsgn(lhs, rhs);
-                break;
+            switch (pIcode->ic.ll.opcode) {
+              case iADD:    rhs = boolCondExp (lhs, rhs, ADD);
+                            newAsgnHlIcode (pIcode, lhs, rhs);
+                            break;
+
+              case iAND:    rhs = boolCondExp (lhs, rhs, AND);
+                            newAsgnHlIcode (pIcode, lhs, rhs);
+                            break;
+
+              case iCALL:
+              case iCALLF:  newCallHlIcode (pIcode);
+                            break;
+
+              case iDEC:    rhs = idCondExpKte (1, 2);
+							rhs = boolCondExp (lhs, rhs, SUB);
+							newAsgnHlIcode (pIcode, lhs, rhs); 
+                            break;
+
+              case iDIV:    
+              case iIDIV:/* should be signed div */
+                            rhs = boolCondExp (lhs, rhs, DIV);  
+                            if (pIcode->ic.ll.flg & B)
+                            {
+                                lhs = idCondExpReg (rAL, 0, &pProc->localId);
+                                setRegDU (pIcode, rAL, E_DEF);
+                            }
+                            else
+                            {
+                                lhs = idCondExpReg (rAX, 0, &pProc->localId);
+                                setRegDU (pIcode, rAX, E_DEF);
+                            }
+                            newAsgnHlIcode (pIcode, lhs, rhs);
+                            break;
+
+              case iIMUL:   rhs = boolCondExp (lhs, rhs, MUL);
+                            lhs = idCondExp (pIcode, LHS_OP, pProc, i, pIcode,
+                                             NONE);
+                            newAsgnHlIcode (pIcode, lhs, rhs);
+                            break;
+
+              case iINC:    rhs = idCondExpKte (1, 2);
+							rhs = boolCondExp (lhs, rhs, ADD);
+							newAsgnHlIcode (pIcode, lhs, rhs);
+                            break;
+
+              case iLEA:    rhs = unaryCondExp (ADDRESSOF, rhs);
+                            newAsgnHlIcode (pIcode, lhs, rhs);
+                            break;
+
+              case iMOD:    rhs = boolCondExp (lhs, rhs, MOD);
+                            if (pIcode->ic.ll.flg & B)
+                            {
+                                lhs = idCondExpReg (rAH, 0, &pProc->localId);
+                                setRegDU (pIcode, rAH, E_DEF);
+                            }
+                            else
+                            {
+                                lhs = idCondExpReg (rDX, 0, &pProc->localId);
+                                setRegDU (pIcode, rDX, E_DEF);
+                            }
+                            newAsgnHlIcode (pIcode, lhs, rhs);
+                            break;
+
+              case iMOV:    newAsgnHlIcode (pIcode, lhs, rhs);
+                            break;
+
+              case iMUL:    rhs = boolCondExp (lhs, rhs, MUL);
+                            lhs = idCondExp (pIcode, LHS_OP, pProc, i, pIcode,
+                                             NONE);
+                            newAsgnHlIcode (pIcode, lhs, rhs);
+                            break;
+
+              case iNEG:    rhs = unaryCondExp (NEGATION, lhs);
+                            newAsgnHlIcode (pIcode, lhs, rhs);
+                            break;
+
+			  case iNOT:	rhs = boolCondExp (NULL, rhs, NOT);
+							newAsgnHlIcode (pIcode, lhs, rhs);
+							break;
+
+              case iOR:     rhs = boolCondExp (lhs, rhs, OR);
+                            newAsgnHlIcode (pIcode, lhs, rhs);
+                            break;
+
+              case iPOP:    newUnaryHlIcode (pIcode, HLI_POP, lhs);
+                            break;
+
+              case iPUSH:   newUnaryHlIcode (pIcode, HLI_PUSH, lhs);
+                            break;
+
+              case iRET:    
+              case iRETF:   newUnaryHlIcode (pIcode, HLI_RET, NULL);
+                            break;
+
+              case iSHL:    rhs = boolCondExp (lhs, rhs, SHL);
+                            newAsgnHlIcode (pIcode, lhs, rhs);
+                            break;
+
+              case iSAR:    /* signed */
+              case iSHR:    rhs = boolCondExp (lhs, rhs, SHR); /* unsigned*/
+                            newAsgnHlIcode (pIcode, lhs, rhs);
+                            break;
+
+              case iSIGNEX: newAsgnHlIcode (pIcode, lhs, rhs);  
+                            break;
+
+              case iSUB:    rhs = boolCondExp (lhs, rhs, SUB);
+                            newAsgnHlIcode (pIcode, lhs, rhs);
+                            break;
+
+              case iXCHG:   
+                            break;
+
+              case iXOR:    rhs = boolCondExp (lhs, rhs, XOR);
+                            newAsgnHlIcode (pIcode, lhs, rhs);
+                            break;
+            }
         }
+
     }
 
 }
 
 
+void inverseCondOp (COND_EXPR **exp)
 /* 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;
-
-            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;
-        } /* eos */
-
-    }
-    else if (m_type == NEGATION) //TODO: memleak here
-    {
-        return expr.unaryExp->clone();
-    }
-    return this->clone();
-    /* other types are left unmodified */
+{ 
+  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};
+	if (*exp == NULL) return;
+
+	if ((*exp)->type == BOOLEAN_OP)
+	{
+		switch ((*exp)->expr.boolExpr.op) {
+		  case LESS_EQUAL: case LESS: case EQUAL:
+		  case NOT_EQUAL: case GREATER: case GREATER_EQUAL:
+			(*exp)->expr.boolExpr.op = invCondOp[(*exp)->expr.boolExpr.op];
+			break;
+
+		  case AND: case OR: case XOR: case NOT: case ADD:
+		  case SUB: case MUL: case DIV: case SHR: case SHL: case MOD:
+			*exp = unaryCondExp (NEGATION, *exp);
+			break;
+
+		  case DBL_AND: case DBL_OR:
+			(*exp)->expr.boolExpr.op = invCondOp[(*exp)->expr.boolExpr.op];
+			inverseCondOp (&(*exp)->expr.boolExpr.lhs);
+			inverseCondOp (&(*exp)->expr.boolExpr.rhs);
+			break;
+		} /* eos */
+
+	}
+	else if ((*exp)->type == NEGATION)
+		*exp = (*exp)->expr.unaryExp;
+
+	/* other types are left unmodified */
 }
 
+
+char *writeCall (PPROC tproc, PSTKFRAME args, PPROC pproc, Int *numLoc)
 /* Returns the string that represents the procedure call of tproc (ie. with
  * actual parameters) */
-std::string writeCall (Function * tproc, STKFRAME & args, Function * pproc, int *numLoc)
-{
-    int i;                        /* counter of # arguments       */
-    string condExp;
-    ostringstream ostr;
-    ostr<<tproc->name<<" (";
-    for(const STKSYM &sym : args)
+{ Int i;                        /* counter of # arguments       */
+  char *s, *condExp;
+
+	s = (char*)allocMem (100 * sizeof(char));
+	s[0] = '\0';
+	sprintf (s, "%s (", tproc->name);
+    for (i = 0; i < args->csym; i++)
     {
-        ostr << walkCondExpr (sym.actual, pproc, numLoc);
-        if((&sym)!=&(args.back()))
-            ostr << ", ";
+        condExp = walkCondExpr (args->sym[i].actual, pproc, numLoc);
+        strcat (s, condExp);
+        if (i < (args->csym - 1))
+            strcat (s, ", ");
     }
-    ostr << ")";
-    return ostr.str();
+    strcat (s, ")"); 
+	return (s);
 }
 
 
+char *writeJcond (HLTYPE h, PPROC pProc, Int *numLoc)
 /* Displays the output of a HLI_JCOND icode. */
-char *writeJcond (const HLTYPE &h, Function * pProc, int *numLoc)
-{
-    assert(h.expr());
+{ char *e;
+
     memset (buf, ' ', sizeof(buf));
-    buf[0] = '\0';
+	buf[0] = '\0';
     strcat (buf, "if ");
-    COND_EXPR *inverted=h.expr()->inverse();
-    //inverseCondOp (&h.exp);
-    std::string e = walkCondExpr (inverted, pProc, numLoc);
-    delete inverted;
-    strcat (buf, e.c_str());
+	inverseCondOp (&h.oper.exp);
+    e = walkCondExpr (h.oper.exp, pProc, numLoc);
+    strcat (buf, e);
     strcat (buf, " {\n");
-    return (buf);
+	return (buf);
 }
 
 
+char *writeJcondInv (HLTYPE h, PPROC pProc, Int *numLoc)
 /* Displays the inverse output of a HLI_JCOND icode.  This is used in the case
  * when the THEN clause of an if..then..else is empty.  The clause is
  * negated and the ELSE clause is used instead.	*/
-char *writeJcondInv (HLTYPE h, Function * pProc, int *numLoc)
-{
+{ char *e;
+
     memset (buf, ' ', sizeof(buf));
-    buf[0] = '\0';
+	buf[0] = '\0';
     strcat (buf, "if ");
-    std::string e = walkCondExpr (h.expr(), pProc, numLoc);
-    strcat (buf, e.c_str());
+    e = walkCondExpr (h.oper.exp, pProc, numLoc);
+    strcat (buf, e);
     strcat (buf, " {\n");
-    return (buf);
+	return (buf);
 }
 
-string AssignType::writeOut(Function *pProc, int *numLoc)
-{
-    ostringstream ostr;
-    ostr << walkCondExpr (lhs, pProc, numLoc);
-    ostr << " = ";
-    ostr << walkCondExpr (rhs, pProc, numLoc);
-    ostr << ";\n";
-    return ostr.str();
-}
-string CallType::writeOut(Function *pProc, int *numLoc)
-{
-    ostringstream ostr;
-    ostr << writeCall (proc, *args, pProc,numLoc);
-    ostr << ";\n";
-    return ostr.str();
-}
-string ExpType::writeOut(Function *pProc, int *numLoc)
-{
-    return walkCondExpr (v, pProc, numLoc);
-}
 
+char *write1HlIcode (HLTYPE h, PPROC pProc, Int *numLoc)
 /* 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 e;
-    ostringstream ostr;
-    HlTypeSupport *p = get();
-    switch (opcode)
-    {
-        case HLI_ASSIGN:
-            return p->writeOut(pProc,numLoc);
-        case HLI_CALL:
-            return p->writeOut(pProc,numLoc);
-        case HLI_RET:
-            e = p->writeOut(pProc,numLoc);
-            if (! e.empty())
-                ostr << "return (" << e << ");\n";
-            break;
-        case HLI_POP:
-            ostr << "HLI_POP ";
-            ostr << p->writeOut(pProc,numLoc);
-            ostr << "\n";
-            break;
-        case HLI_PUSH:
-            ostr << "HLI_PUSH ";
-            ostr << p->writeOut(pProc,numLoc);
-            ostr << "\n";
-            break;
+{ char *e;
+
+    memset (buf, ' ', sizeof(buf));
+	buf[0] = '\0';
+    switch (h.opcode) {
+      case HLI_ASSIGN:  e = walkCondExpr (h.oper.asgn.lhs, pProc, numLoc);
+                    strcat (buf, e);
+                    strcat (buf, " = ");
+                    e = walkCondExpr (h.oper.asgn.rhs, pProc, numLoc);
+                    strcat (buf, e);
+                    strcat (buf, ";\n");
+                    break;
+      case HLI_CALL:    e = writeCall (h.oper.call.proc, h.oper.call.args, pProc,
+								   numLoc);
+                    strcat (buf, e);
+                    strcat (buf, ";\n");
+                    break;
+      case HLI_RET:     e = walkCondExpr (h.oper.exp, pProc, numLoc); 
+					if (e[0] != '\0')
+					{
+	  					strcat (buf, "return (");
+                    	strcat (buf, e);
+                    	strcat (buf, ");\n");
+					}
+                    break;
+      case HLI_POP:     strcat (buf, "HLI_POP ");
+                    e = walkCondExpr (h.oper.exp, pProc, numLoc);
+                    strcat (buf, e);
+                    strcat (buf, "\n");
+                    break;
+      case HLI_PUSH:    strcat (buf, "HLI_PUSH ");
+                    e = walkCondExpr (h.oper.exp, pProc, numLoc);
+                    strcat (buf, e);
+                    strcat (buf, "\n");
+                    break;
     }
-    return ostr.str();
+    return (buf);
 }
 
 
-//TODO: replace  all "< (INDEX_BX_SI-1)" with machine_x86::lastReg
-
-//TODO: replace all >= INDEX_BX_SI with machine_x86::isRegExpression
+Int power2 (Int i)
+/* Returns the value of 2 to the power of i */
+{
+    if (i == 0)
+        return (1);
+    return (2 << (i-1));
+}
 
 
+void writeDU (PICODE pIcode, Int idx)
 /* Writes the registers/stack variables that are used and defined by this
  * instruction. */
-void ICODE::writeDU()
-{
-    int my_idx = loc_ip;
+{ static char buf[100];
+  Int i, j;
+
+    memset (buf, ' ', sizeof(buf));
+    buf[0] = '\0';
+    for (i = 0; i < (INDEXBASE-1); i++)
     {
-        ostringstream ostr;
-        Machine_X86::writeRegVector(ostr,du.def);
-        if (!ostr.str().empty())
-            printf ("Def (reg) = %s\n", ostr.str().c_str());
+        if ((pIcode->du.def & power2(i)) != 0)
+        {
+            strcat (buf, allRegs[i]);
+            strcat (buf, " ");
+        }
     }
+    if (buf[0] != '\0')
+        printf ("Def (reg) = %s\n", buf);
+
+    memset (buf, ' ', sizeof(buf));
+    buf[0] = '\0';
+    for (i = 0; i < INDEXBASE; i++)
     {
-        ostringstream ostr;
-        Machine_X86::writeRegVector(ostr,du.use);
-        if (!ostr.str().empty())
-            printf ("Use (reg) = %s\n", ostr.str().c_str());
+        if ((pIcode->du.use & power2(i)) != 0)
+        {
+            strcat (buf, allRegs[i]);
+            strcat (buf, " ");
+        }
     }
+    if (buf[0] != '\0')
+        printf ("Use (reg) = %s\n", buf);
 
     /* Print du1 chain */
-    printf ("# regs defined = %d\n", du1.numRegsDef);
-    for (int i = 0; i < MAX_REGS_DEF; i++)
-    {
-        if (not du1.used(i))
-            continue;
-            printf ("%d: du1[%d][] = ", my_idx, i);
-            for(auto j : du1.idx[i].uses)
+    printf ("# regs defined = %d\n", pIcode->du1.numRegsDef);
+    for (i = 0; i < MAX_REGS_DEF; i++)
+        if (pIcode->du1.idx[i][0] != 0)
+        {
+            printf ("%d: du1[%d][] = ", idx, i);
+            for (j = 0; j < MAX_USES; j++)
             {
-                printf ("%d ", j->loc_ip);
+                if (pIcode->du1.idx[i][j] == 0)
+                    break;
+                printf ("%d ", pIcode->du1.idx[i][j]);
             }
             printf ("\n");
-    }
-
+        }
+    
     /* For HLI_CALL, print # parameter bytes */
-    if (hl()->opcode == HLI_CALL)
-        printf ("# param bytes = %d\n", hl()->call.args->cb);
+    if (pIcode->ic.hl.opcode == HLI_CALL)
+        printf ("# param bytes = %d\n", pIcode->ic.hl.oper.call.args->cb);
     printf ("\n");
 }
+
+
+void freeHlIcode (PICODE icode, Int numIcodes)
+/* Frees the storage allocated to h->hlIcode */
+{ Int i;
+  HLTYPE h;
+
+    for (i = 0; i < numIcodes; i++)
+    {
+        h = icode[i].ic.hl;
+        switch (h.opcode) {
+          case HLI_ASSIGN:  freeCondExpr (h.oper.asgn.lhs);
+                        freeCondExpr (h.oper.asgn.rhs);
+                        break;
+          case HLI_POP: case HLI_PUSH:  
+          case HLI_JCOND:   freeCondExpr (h.oper.exp);
+                        break;
+        }
+    }
+}
+

+ 99 - 58
src/icode.cpp

@@ -5,98 +5,139 @@
 #include <malloc.h>
 #include <memory.h>
 
-#include "dcc.h"
-#include "types.h"		// Common types like uint8_t, etc
+#include "types.h"		// Common types like byte, etc
 #include "ast.h"		// Some icode types depend on these
 #include "icode.h"
 
+void   *reallocVar(void *p, Int newsize);                   /* frontend.c !?   */
 #define ICODE_DELTA 25		// Amount to allocate for new chunk
 
-ICODE::TypeFilter<HIGH_LEVEL> ICODE::select_high_level;
-ICODE::TypeAndValidFilter<HIGH_LEVEL> ICODE::select_valid_high_level;
+
 CIcodeRec::CIcodeRec()
 {
+	numIcode = 0;
+	alloc = 0;
+	icode = 0;			// Initialise the pointer to 0
+}
+
+CIcodeRec::~CIcodeRec()
+{
+	if (icode)
+	{
+		free(icode);
+	}
 }
 
+PICODE CIcodeRec::addIcode(PICODE pIcode)
+
 /* Copies the icode that is pointed to by pIcode to the icode array.
  * If there is need to allocate extra memory, it is done so, and
  * the alloc variable is adjusted.        */
-ICODE * CIcodeRec::addIcode(ICODE *pIcode)
 {
-    push_back(*pIcode);
-    back().loc_ip = size()-1;
-    return &back();
-}
+	PICODE resIcode;
 
-void CIcodeRec::SetInBB(rCODE &rang, BB *pnewBB)
-{
-    for(ICODE &ic : rang)
+    if (numIcode == alloc)
     {
-        ic.setParent(pnewBB);
+        alloc += ICODE_DELTA;
+		icode = (PICODE)reallocVar(icode, alloc * sizeof(ICODE));
+		memset (&icode[numIcode], 0, ICODE_DELTA * sizeof(ICODE));
+
     }
+    resIcode = (PICODE)memcpy (&icode[numIcode], pIcode, 
+                               sizeof(ICODE));
+    numIcode++;
+    return (resIcode);
 }
 
-/* labelSrchRepl - Searches the icodes for instruction with label = target, and
-   replaces *pIndex with an icode index */
-bool CIcodeRec::labelSrch(uint32_t target, uint32_t &pIndex)
+PICODE CIcodeRec::GetFirstIcode()
 {
-    iICODE location=labelSrch(target);
-    if(end()==location)
-            return false;
-    pIndex=location->loc_ip;
-    return true;
+	return icode;
 }
-bool CIcodeRec::alreadyDecoded(uint32_t target)
+
+/* Don't need this; just pIcode++ since array is guaranteed to be contiguous
+PICODE CIcodeRec::GetNextIcode(PICODE pCurIcode)
 {
-    iICODE location=labelSrch(target);
-    if(end()==location)
-            return false;
-    return true;
+	int idx = pCurIcode - icode;		// Current index
+	ASSERT(idx+1 < numIcode);
+	return &icode[idx+1];
 }
-CIcodeRec::iterator CIcodeRec::labelSrch(uint32_t target)
+*/
+
+boolT CIcodeRec::IsValid(PICODE pCurIcode)
 {
-    return find_if(begin(),end(),[target](ICODE &l) -> bool {return l.ll()->label==target;});
+	int idx = pCurIcode - icode;		// Current index
+	return idx < numIcode;
 }
-ICODE * CIcodeRec::GetIcode(int ip)
+
+int CIcodeRec::GetNumIcodes()
 {
-    assert(ip>=0 && ip<size());
-    iICODE res=begin();
-    advance(res,ip);
-    return &(*res);
+	return numIcode;
 }
 
-extern int getNextLabel();
-extern bundle cCode;
-/* Checks the given icode to determine whether it has a label associated
- * to it.  If so, a goto is emitted to this label; otherwise, a new label
- * is created and a goto is also emitted.
- * Note: this procedure is to be used when the label is to be backpatched
- *       onto code in cCode.code */
-void LLInst::emitGotoLabel (int indLevel)
+void CIcodeRec::SetInBB(int start, int end, struct _BB* pnewBB)
 {
-    if ( not testFlags(HLL_LABEL) ) /* node hasn't got a lab */
-    {
-        /* Generate new label */
-        hllLabNum = getNextLabel();
-        setFlags(HLL_LABEL);
+	for (int i = start; i <= end; i++)
+	icode[i].inBB = pnewBB;
+}
 
-        /* Node has been traversed already, so backpatch this label into
-                 * the code */
-        cCode.code.addLabelBundle (codeIdx, hllLabNum);
-    }
-    cCode.appendCode( "%sgoto L%ld;\n", indentStr(indLevel), hllLabNum);
-    stats.numHLIcode++;
+void CIcodeRec::SetImmediateOp(int ip, dword dw)
+{
+	icode[ip].ic.ll.immed.op = dw;
+}
+
+void CIcodeRec::SetLlFlag(int ip, dword flag)
+{
+	icode[ip].ic.ll.flg |= flag;
+}
+
+dword CIcodeRec::GetLlFlag(int ip)
+{
+	return icode[ip].ic.ll.flg;
 }
 
+void CIcodeRec::ClearLlFlag(int ip, dword flag)
+{
+	icode[ip].ic.ll.flg &= (~flag);
+}
 
+void CIcodeRec::SetLlInvalid(int ip, boolT fInv)
+{
+	icode[ip].invalid = fInv;
+}
 
-bool LLOperand::isReg() const
+dword CIcodeRec::GetLlLabel(int ip)
 {
-    return (regi>=rAX) && (regi<=rTMP);
+	return icode[ip].ic.ll.label;
 }
-void LLOperand::addProcInformation(int param_count, uint32_t call_conv)
+
+llIcode CIcodeRec::GetLlOpcode(int ip)
 {
-    proc.proc->cbParam = (int16_t)param_count;
-    proc.cb = param_count;
-    proc.proc->flg |= call_conv;
+	return icode[ip].ic.ll.opcode;
 }
+
+
+boolT CIcodeRec::labelSrch(dword target, Int *pIndex)
+/* labelSrchRepl - Searches the icodes for instruction with label = target, and
+    replaces *pIndex with an icode index */
+{
+    Int  i;
+
+    for (i = 0; i < numIcode; i++)
+    {
+        if (icode[i].ic.ll.label == target)
+        {
+            *pIndex = i;
+            return TRUE;
+        }
+    }
+    return FALSE;
+}
+
+PICODE CIcodeRec::GetIcode(int ip)
+{
+	return &icode[ip];
+}
+
+
+
+

+ 1250 - 177
src/idioms.cpp

@@ -3,273 +3,1346 @@
  * (C) Cristina Cifuentes
  ****************************************************************************/
 
-#include <cstring>
-#include <deque>
-#include "idiom.h"
-#include "idiom1.h"
-#include "epilogue_idioms.h"
-#include "call_idioms.h"
-#include "mov_idioms.h"
-#include "xor_idioms.h"
-#include "neg_idioms.h"
-#include "shift_idioms.h"
-#include "arith_idioms.h"
 #include "dcc.h"
-#include <llvm/Support/PatternMatch.h>
-#include <boost/iterator/filter_iterator.hpp>
+#include <string.h>
+#ifdef __DOSWIN__
+#include <stdio.h>
+#endif
+
+
+/*****************************************************************************
+ * JmpInst - Returns TRUE if opcode is a conditional or unconditional jump
+ ****************************************************************************/
+boolT JmpInst(llIcode opcode)
+{
+    switch (opcode) {
+        case iJMP:  case iJMPF: case iJCXZ:
+        case iLOOP: case iLOOPE:case iLOOPNE:
+        case iJB:   case iJBE:  case iJAE:  case iJA:
+        case iJL:   case iJLE:  case iJGE:  case iJG: 
+        case iJE:   case iJNE:  case iJS:   case iJNS:
+        case iJO:   case iJNO:  case iJP:   case iJNP:
+            return TRUE;
+    }
+    return FALSE;
+}
+
+
 /*****************************************************************************
- * JmpInst - Returns true if opcode is a conditional or unconditional jump
+/* checkStkVars - Checks for PUSH SI
+ *                          [PUSH DI]
+ *                or         PUSH DI
+ *                          [PUSH SI]
+ * In which case, the stack variable flags are set 
  ****************************************************************************/
-bool LLInst::isJmpInst()
+static Int checkStkVars (PICODE pIcode, PICODE pEnd, PPROC pProc)
 {
-    switch (getOpcode())
+    /* Look for PUSH SI */
+    if ((pIcode < pEnd) && (pIcode->ic.ll.opcode == iPUSH) &&
+        (pIcode->ic.ll.dst.regi == rSI))
     {
-    case iJMP:  case iJMPF: case iJCXZ:
-    case iLOOP: case iLOOPE:case iLOOPNE:
-    case iJB:   case iJBE:  case iJAE:  case iJA:
-    case iJL:   case iJLE:  case iJGE:  case iJG:
-    case iJE:   case iJNE:  case iJS:   case iJNS:
-    case iJO:   case iJNO:  case iJP:   case iJNP:
-        return true;
+        pProc->flg |= SI_REGVAR;
+
+        /* Look for PUSH DI */
+        if (++pIcode < pEnd && (pIcode->ic.ll.opcode == iPUSH) &&
+            (pIcode->ic.ll.dst.regi == rDI))
+        {
+            pProc->flg |= DI_REGVAR;    
+            return 2;
+        }
+        else
+            return 1;
     }
-    return false;
+    else if ((pIcode < pEnd) && (pIcode->ic.ll.opcode == iPUSH) &&
+		(pIcode->ic.ll.dst.regi == rDI))
+	{
+		pProc->flg |= DI_REGVAR;
+
+		/* Look for PUSH SI */
+		if ((++pIcode < pEnd) && (pIcode->ic.ll.opcode == iPUSH) &&
+			(pIcode->ic.ll.dst.regi == rSI))
+		{
+			pProc->flg |= SI_REGVAR;
+			return 2;
+		}
+		else
+			return 1;
+	}
+	else
+        return 0;
 }
 
+
 /*****************************************************************************
- * findIdioms  - translates LOW_LEVEL icode idioms into HIGH_LEVEL icodes.
+ * idiom1 - HLL procedure prologue;  Returns number of instructions matched.
+ *          PUSH BP     ==> ENTER immed, 0
+ *          MOV  BP, SP     and sets PROC_HLL flag
+ *          [SUB  SP, immed]
+ *          [PUSH SI]
+ *          [PUSH DI]
+ *        - Second version: Push stack variables and then save BP
+ *          PUSH BP
+ *          PUSH SI
+ *          [PUSH DI]
+ *          MOV BP, SP
+ *        - Third version: Stack variables
+ *          [PUSH SI]
+ *          [PUSH DI]
+ ****************************************************************************/
+static Int idiom1(PICODE pIcode, PICODE pEnd, PPROC pProc)
+{ Int n;
+
+    /* PUSH BP as first instruction of procedure */
+    if ( !(pIcode->ic.ll.flg & I) && pIcode->ic.ll.src.regi == rBP)
+    {
+        /* MOV BP, SP as next instruction */
+        if (++pIcode < pEnd && ! (pIcode->ic.ll.flg & (I | TARGET | CASE))
+           && pIcode->ic.ll.opcode == iMOV && pIcode->ic.ll.dst.regi == rBP
+           && pIcode->ic.ll.src.regi == rSP)
+        {
+			pProc->args.minOff = 2;
+			pProc->flg |= PROC_IS_HLL;
+
+            /* Look for SUB SP, immed */
+            if ((++pIcode < pEnd) &&
+                (pIcode->ic.ll.flg & (I | TARGET | CASE)) == I &&
+                pIcode->ic.ll.opcode == iSUB && pIcode->ic.ll.dst.regi == rSP)
+            {
+                return (3 + checkStkVars (++pIcode, pEnd, pProc));
+            }
+            else
+                return (2 + checkStkVars (pIcode, pEnd, pProc));
+        }
+
+        /* PUSH SI
+         * [PUSH DI]
+         * MOV BP, SP */
+        else
+        {
+            n = checkStkVars (pIcode, pEnd, pProc);
+            if (n > 0)
+            {
+                /* Look for MOV BP, SP */
+                pIcode += n;
+                if (pIcode < pEnd && 
+                    ! (pIcode->ic.ll.flg & (I | TARGET | CASE)) && 
+                    pIcode->ic.ll.opcode == iMOV && 
+                    pIcode->ic.ll.dst.regi == rBP && 
+                    pIcode->ic.ll.src.regi == rSP)
+                {
+					pProc->args.minOff = 2 + (n * 2);
+                    return (2 + n);
+                }
+                else return 0;		// Cristina: check this please!
+            }
+            else return 0;			// Cristina: check this please!
+        }
+    }
+
+    else 
+        return (checkStkVars (pIcode, pEnd, pProc));
+}
+
+
+/*****************************************************************************
+ * popStkVars - checks for
+ *          [POP DI]
+ *          [POP SI]
+ *      or  [POP SI]
+ *          [POP DI]
  ****************************************************************************/
-void Function::findIdioms()
+static void popStkVars (PICODE pIcode, PICODE pEnd, PPROC pProc)
 {
-    //    int     ip;             /* Index to current icode                   */
-    iICODE  pEnd, pIcode;   /* Pointers to end of BB and current icodes */
-    int16_t   delta;
-
-    pIcode = Icode.begin();
-    pEnd = Icode.end();
-    Idiom1  i01(this);
-    Idiom2  i02(this);
-    Idiom3  i03(this);
-    Idiom4  i04(this);
-    Idiom13 i13(this);
-    Idiom14 i14(this);
-    Idiom17 i17(this);
-    // xor idioms
-    Idiom21 i21(this);
-    Idiom7 i07(this);
-    // or idioms
-    Idiom10 i10(this);
-    // neg idiom
-    Idiom11 i11(this);
-    Idiom16 i16(this);
-    // shift idioms
-    Idiom8 i08(this);
-    Idiom12 i12(this);
-    Idiom15 i15(this);
-    Idiom9 i09(this);
-    //arithmetic idioms
-    Idiom5 i05(this);
-    Idiom6 i06(this);
-    Idiom18 i18(this);
-    Idiom19 i19(this);
-    Idiom20 i20(this);
-    struct is_valid
+    /* Match [POP DI] */
+	if (pIcode->ic.ll.opcode == iPOP)
+    	if ((pProc->flg & DI_REGVAR) && (pIcode->ic.ll.dst.regi == rDI))
+        	invalidateIcode (pIcode);
+    	else if ((pProc->flg & SI_REGVAR) && (pIcode->ic.ll.dst.regi == rSI))
+        	invalidateIcode (pIcode);
+
+    /* Match [POP SI] */
+	if ((pIcode+1)->ic.ll.opcode == iPOP)
+    	if ((pProc->flg & SI_REGVAR) && ((pIcode+1)->ic.ll.dst.regi == rSI))
+        	invalidateIcode (pIcode+1);
+    	else if ((pProc->flg & DI_REGVAR) && ((pIcode+1)->ic.ll.dst.regi == rDI))
+        	invalidateIcode (pIcode+1);
+}
+
+
+/*****************************************************************************
+ * idiom2 - HLL procedure epilogue;  Returns number of instructions matched.
+ *          [POP DI]
+ *          [POP SI]
+ *          MOV  SP, BP 
+ *          POP  BP
+ *          RET(F)
+ *****************************************************************************/
+static Int idiom2(PICODE pIcode, PICODE pEnd, Int ip, PPROC pProc)
+{ PICODE nicode;
+ 
+    /* Match MOV SP, BP */
+    if (ip != 0 && ((pIcode->ic.ll.flg & I) != I) && 
+        pIcode->ic.ll.dst.regi == rSP && pIcode->ic.ll.src.regi == rBP)
     {
-        bool operator()(ICODE &z) { return z.valid();}
-    };
-    typedef boost::filter_iterator<is_valid,iICODE> ifICODE;
-    while (pIcode != pEnd)
+		/* Get next icode, skip over holes in the icode array */
+		nicode = pIcode + 1;
+		while (nicode->ic.ll.flg & NO_CODE)
+			nicode++;
+
+        /* Match POP BP */
+        if (nicode < pEnd &&
+            ! (nicode->ic.ll.flg & (I | TARGET | CASE)) &&
+            nicode->ic.ll.opcode == iPOP && 
+            nicode->ic.ll.dst.regi == rBP)
+        {
+			nicode++;
+			
+            /* Match RET(F) */
+            if (nicode < pEnd &&
+                ! (nicode->ic.ll.flg & (I | TARGET | CASE)) &&
+                (nicode->ic.ll.opcode == iRET || 
+                nicode->ic.ll.opcode == iRETF))
+            {
+                popStkVars (pIcode-2, pEnd, pProc);
+                return 2;
+            }
+        }
+    }
+    return 0;
+}
+
+
+
+/*****************************************************************************
+ * idiom3 - C calling convention.
+ *          CALL(F)  proc_X
+ *          ADD  SP, immed
+ *      Eg: CALL proc_X
+ *          ADD  SP, 6
+ *          =>  pProc->cbParam = immed
+ *		Special case: when the call is at the end of the procedure, 
+ *					  sometimes the stack gets restored by a MOV sp, bp.
+ *					  Need to flag the procedure in these cases.
+ *  Used by compilers to restore the stack when invoking a procedure using
+ *  the C calling convention.
+ ****************************************************************************/
+static Int idiom3(PICODE pIcode, PICODE pEnd)
+{ 
+    /* Match ADD  SP, immed */
+    if ((++pIcode < pEnd) && (pIcode->ic.ll.flg & I) &&
+        (pIcode->ic.ll.opcode == iADD) && (pIcode->ic.ll.dst.regi == rSP))
+        return (pIcode->ic.ll.immed.op);
+	else if ((pIcode->ic.ll.opcode == iMOV) && (pIcode->ic.ll.dst.regi == rSP)
+			 && (pIcode->ic.ll.src.regi == rBP))
+		(pIcode-1)->ic.ll.flg |= REST_STK;
+    return 0;
+}
+
+
+/*****************************************************************************
+ * idiom 17 - C calling convention.
+ *          CALL(F)  xxxx
+ *          POP reg
+ *          [POP reg]           reg in {AX, BX, CX, DX}
+ *      Eg: CALL proc_X
+ *          POP cx
+ *          POP cx      (4 bytes of arguments)
+ *          => pProc->cbParam = # pops * 2
+ *  Found in Turbo C when restoring the stack for a procedure that uses the
+ *  C calling convention.  Used to restore the stack of 2 or 4 bytes args.
+ ****************************************************************************/
+static Int idiom17 (PICODE pIcode, PICODE pEnd)
+{ Int i = 0;            /* Count on # pops */
+  byte regi;
+
+    /* Match POP reg */
+    if ((++pIcode < pEnd) && (pIcode->ic.ll.opcode == iPOP))
     {
-        switch (pIcode->ll()->getOpcode())
+        regi = pIcode->ic.ll.dst.regi;
+        if ((regi >= rAX) && (regi <= rBX))
+            i++;
+        while ((++pIcode)->ic.ll.opcode == iPOP)
         {
-        case iDEC: case iINC:
-            if (i18.match(pIcode))
-                advance(pIcode,i18.action());
-            else if (i19.match(pIcode))
-                advance(pIcode,i19.action());
-            else if (i20.match(pIcode))
-                advance(pIcode,i20.action());
+            if (pIcode->ic.ll.dst.regi == regi)
+                i++;
             else
-                pIcode++;
-            break;
+                break;
+        }
+        return (i * 2);
+    }
+    return (0);
+}
+
+
+/*****************************************************************************
+ * idiom4 - Pascal calling convention.
+ *          RET(F) immed   
+ *          ==> pProc->cbParam = immed
+ *              sets CALL_PASCAL flag 
+ *        - Second version: check for optional pop of stack vars
+ *          [POP DI]
+ *          [POP SI]
+ *          POP BP
+ *          RET(F) [immed]
+ *		  - Third version: pop stack vars
+ *			[POP DI]
+ *			[POP SI]
+ *			RET(F) [immed]
+ ****************************************************************************/
+static void idiom4 (PICODE pIcode, PICODE pEnd, PPROC pProc)
+{
+    /* Check for [POP DI]
+     *           [POP SI] */
+    popStkVars (pIcode-3, pEnd, pProc);
+
+    /* Check for POP BP */
+    if (((pIcode-1)->ic.ll.opcode == iPOP) && 
+        (((pIcode-1)->ic.ll.flg & I) != I) &&
+        ((pIcode-1)->ic.ll.dst.regi == rBP))
+        invalidateIcode (pIcode-1);
+	else
+		popStkVars (pIcode-2, pEnd, pProc);
+
+    /* Check for RET(F) immed */
+    if (pIcode->ic.ll.flg & I) 
+    {
+        pProc->cbParam = (int16)pIcode->ic.ll.immed.op;
+        pProc->flg |= CALL_PASCAL;
+    }
+}
+
+
+/*****************************************************************************
+ * idiom5 - Long addition.
+ *      ADD reg/stackOff, reg/stackOff
+ *      ADC reg/stackOff, reg/stackOff 
+ *      Eg:     ADD ax, [bp-4]
+ *              ADC dx, [bp-2]
+ *          =>  dx:ax = dx:ax + [bp-2]:[bp-4]
+ *      Found in Borland Turbo C code.
+ *      Commonly used idiom for long addition.
+ ****************************************************************************/
+static boolT idiom5 (PICODE pIcode, PICODE pEnd)
+{
+    if (pIcode < pEnd)
+        if ((pIcode+1)->ic.ll.opcode == iADC)
+            return (TRUE);
+    return (FALSE);
+}
+
+
+/*****************************************************************************
+ * idiom6 - Long substraction.
+ *      SUB reg/stackOff, reg/stackOff
+ *      SBB reg/stackOff, reg/stackOff 
+ *      Eg:     SUB ax, [bp-4]
+ *              SBB dx, [bp-2]
+ *          =>  dx:ax = dx:ax - [bp-2]:[bp-4]
+ *      Found in Borland Turbo C code.
+ *      Commonly used idiom for long substraction.
+ ****************************************************************************/
+static boolT idiom6 (PICODE pIcode, PICODE pEnd)
+{
+    if (pIcode < pEnd)
+        if ((pIcode+1)->ic.ll.opcode == iSBB)
+            return (TRUE);
+    return (FALSE);
+}
+
+
+/*****************************************************************************
+ * idiom7 - Assign zero
+ *      XOR reg/stackOff, reg/stackOff
+ *      Eg:     XOR ax, ax
+ *          =>  ax = 0
+ *      Found in Borland Turbo C and Microsoft C code.
+ ****************************************************************************/
+static boolT idiom7 (PICODE pIcode)
+{ PMEM dst, src;
+
+    dst = &pIcode->ic.ll.dst;
+    src = &pIcode->ic.ll.src;
+    if (dst->regi == 0)                 /* global variable */
+    {
+        if ((dst->segValue == src->segValue) && (dst->off == src->off))
+            return (TRUE);
+    }
+    else if (dst->regi < INDEXBASE)     /* register */
+    {
+        if (dst->regi == src->regi)
+            return (TRUE);
+    }
+    else if ((dst->off) && (dst->seg == rSS) && (dst->regi == INDEXBASE + 6))
+                                        /* offset from BP */
+    {
+        if ((dst->off == src->off) && (dst->seg == src->seg) &&
+            (dst->regi == src->regi))
+            return (TRUE);
+    }
+    return (FALSE);
+}
+
+
+/*****************************************************************************
+ * idiom21 - Assign long kte with high part zero
+ *		XOR regH, regH
+ *		MOV regL, kte
+ *		=> regH:regL = kte
+ *		Eg: XOR dx, dx
+ *			MOV ax, 3
+ *			=> dx:ax = 3
+ *		Note: only the following valid combinations are available:
+ *				dx:ax
+ *				cx:bx
+ *		Found in Borland Turbo C code.
+ ****************************************************************************/
+static boolT idiom21 (PICODE picode, PICODE pend)
+{ PMEM dst, src;
+
+    dst = &picode->ic.ll.dst;
+    src = &picode->ic.ll.src;
+	if (((picode+1) < pend) && ((picode+1)->ic.ll.flg & I))
+	{
+		if ((dst->regi == src->regi) && (dst->regi > 0) && 
+			(dst->regi < INDEXBASE))
+		{
+			if ((dst->regi == rDX) && ((picode+1)->ic.ll.dst.regi == rAX))
+				return (TRUE);
+			if ((dst->regi == rCX) && ((picode+1)->ic.ll.dst.regi == rBX))
+				return (TRUE);
+		}
+	}
+	return (FALSE);
+}
+
+
+/*****************************************************************************
+ * idiom8 - Shift right by 1 (signed long ops)
+ *      SAR reg, 1
+ *      RCR reg, 1
+ *      Eg:     SAR dx, 1
+ *              RCR ax, 1
+ *          =>  dx:ax = dx:ax >> 1      (dx:ax are signed long)
+ *      Found in Microsoft C code for long signed variable shift right.
+ ****************************************************************************/
+static boolT idiom8 (PICODE pIcode, PICODE pEnd)
+{
+    if (pIcode < pEnd)
+    {
+        if (((pIcode->ic.ll.flg & I) == I) && (pIcode->ic.ll.immed.op == 1))
+            if (((pIcode+1)->ic.ll.opcode == iRCR) &&   
+                (((pIcode+1)->ic.ll.flg & I) == I) && 
+                ((pIcode+1)->ic.ll.immed.op == 1))
+                return (TRUE);
+    }
+    return (FALSE);
+}
+
+
+/*****************************************************************************
+ * idiom 15 - Shift left by n 
+ *      SHL reg, 1
+ *      SHL reg, 1
+ *      [...]
+ *      [SHL    reg, 1]
+ *      Eg:     SHL ax, 1
+ *              SHL ax, 1
+ *          =>  ax = ax << 2
+ *      Found in Borland Turbo C code to index an array (array multiplication)
+ ****************************************************************************/
+static Int idiom15 (PICODE picode, PICODE pend)
+{ Int n = 1; 
+  byte regi;
 
-        case iPUSH:
+    if (picode < pend)
+    {
+        /* Match SHL reg, 1 */
+        if ((picode->ic.ll.flg & I) && (picode->ic.ll.immed.op == 1))
         {
-            /* Idiom 1 */
-            //TODO: add other push idioms.
-            advance(pIcode,i01(pIcode));
-            break;
+            regi = picode->ic.ll.dst.regi;
+            while (1)
+            {
+                if (((picode+n) < pend) &&
+                    ((picode+n)->ic.ll.opcode == iSHL) &&
+                    ((picode+n)->ic.ll.flg & I) && 
+                    ((picode+n)->ic.ll.immed.op == 1) &&
+                    ((picode+n)->ic.ll.dst.regi == regi))
+                    n++;
+                else
+                    break;
+            }
         }
+    }
+    if (n > 1)
+        return (n);
+    else
+        return (0);
+}
+
+
+/*****************************************************************************
+ * idiom12 - Shift left long by 1
+ *      SHL reg, 1
+ *      RCL reg, 1
+ *      Eg:     SHL ax, 1
+ *              RCL dx, 1
+ *          =>  dx:ax = dx:ax << 1
+ *      Found in Borland Turbo C code for long variable shift left.
+ ****************************************************************************/
+static boolT idiom12 (PICODE pIcode, PICODE pEnd)
+{
+    if (pIcode < pEnd)
+    {
+        if (((pIcode->ic.ll.flg & I) == I) && (pIcode->ic.ll.immed.op == 1))
+            if (((pIcode+1)->ic.ll.opcode == iRCL) &&   
+                (((pIcode+1)->ic.ll.flg & I) == I) && 
+                ((pIcode+1)->ic.ll.immed.op == 1))
+                return (TRUE);
+    }
+    return (FALSE);
+}
+
+
+/*****************************************************************************
+ * idiom9 - Shift right by 1 (unsigned long ops)
+ *      SHR reg, 1
+ *      RCR reg, 1
+ *      Eg:     SHR dx, 1
+ *              RCR ax, 1
+ *          =>  dx:ax = dx:ax >> 1   (dx:ax are unsigned long)
+ *      Found in Microsoft C code for long unsigned variable shift right.
+ ****************************************************************************/
+static boolT idiom9 (PICODE pIcode, PICODE pEnd)
+{
+    if (pIcode < pEnd)
+    {
+        if (((pIcode->ic.ll.flg & I) == I) && (pIcode->ic.ll.immed.op == 1))
+            if (((pIcode+1)->ic.ll.opcode == iRCR) &&   
+                (((pIcode+1)->ic.ll.flg & I) == I) && 
+                ((pIcode+1)->ic.ll.immed.op == 1))
+                return (TRUE);
+    }
+    return (FALSE);
+}
+
+
+/*****************************************************************************
+ * idiom10 - Jump if not equal to 0
+ *      OR  reg, reg
+ *      JNE labX
+ *      Eg:     OR  ax, ax
+ *              JNE labX
+ *      => HLI_JCOND (ax != 0) labX
+ *		Note: we also check that these instructions are not followed by
+ *			  CMP reg, kte
+ *			  JE  lab
+ *			  because this is most likely a long conditional equality test.
+ *      Found in Borland Turbo C.
+ ****************************************************************************/
+static boolT idiom10old (PICODE pIcode, PICODE pEnd)
+{
+    if (pIcode < pEnd)
+    {
+        /* Check OR reg, reg */
+        if (((pIcode->ic.ll.flg & I) != I) && 
+            (pIcode->ic.ll.src. regi > 0) && 
+            (pIcode->ic.ll.src.regi < INDEXBASE) && 
+            (pIcode->ic.ll.src.regi == pIcode->ic.ll.dst.regi))
+			if ((pIcode+3) < pEnd)
+			{
+				if (((pIcode+1)->ic.ll.opcode == iJNE) &&
+					((pIcode+2)->ic.ll.opcode != iCMP) &&
+					((pIcode+3)->ic.ll.opcode != iJE))
+					return (TRUE);
+			}
+			else	/* at the end of the procedure */
+            	if (((pIcode+1) < pEnd) && ((pIcode+1)->ic.ll.opcode == iJNE))
+                	return (TRUE);
+    }
+    return (FALSE);
+}
+
 
-        case iMOV:
+/*****************************************************************************
+ * idiom10 - Jump if not equal to 0
+ *      OR  reg, reg
+ *      JNE labX
+ *      Eg:     OR  ax, ax
+ *              JNE labX
+ *      => CMP reg 0
+ *		   JNE labX
+ *		This instruction is NOT converted into the equivalent high-level
+ *		instruction "HLI_JCOND (reg != 0) labX" because we do not know yet if
+ *		it forms part of a long register conditional test.  It is therefore
+ *		modified to simplify the analysis.
+ *      Found in Borland Turbo C.
+ ****************************************************************************/
+static void idiom10 (PICODE pIcode, PICODE pEnd)
+{
+    if (pIcode < pEnd)
+    {
+        /* Check OR reg, reg */
+        if (((pIcode->ic.ll.flg & I) != I) && 
+            (pIcode->ic.ll.src. regi > 0) && 
+            (pIcode->ic.ll.src.regi < INDEXBASE) && 
+            (pIcode->ic.ll.src.regi == pIcode->ic.ll.dst.regi))
+            if (((pIcode+1) < pEnd) && ((pIcode+1)->ic.ll.opcode == iJNE))
+			{
+				pIcode->ic.ll.opcode = iCMP;
+				pIcode->ic.ll.flg |= I;
+				pIcode->ic.ll.immed.op = 0;
+				pIcode->du.def = 0;
+				pIcode->du1.numRegsDef = 0;
+			}
+    }
+}
+
+
+/*****************************************************************************
+ * idiom 13 - Word assign
+ *      MOV regL, mem
+ *      MOV regH, 0
+ *      Eg:     MOV al, [bp-2]
+ *              MOV ah, 0
+ *      => MOV ax, [bp-2]
+ *      Found in Borland Turbo C, used for multiplication and division of
+ *      byte operands (ie. they need to be extended to words).
+ ****************************************************************************/
+static byte idiom13 (PICODE picode, PICODE pend)
+{ byte regi;
+
+    if (picode < pend)
+    {
+        /* Check for regL */
+        regi = picode->ic.ll.dst.regi;
+        if (((picode->ic.ll.flg & I) != I) && (regi >= rAL) && (regi <= rBH))
         {
-            if (i02.match(pIcode)) /* Idiom 2 */
-                advance(pIcode,i02.action());
-            else if (i14.match(pIcode))  /* Idiom 14 */
-                advance(pIcode,i14.action());
-            else if (i13.match(pIcode))      /* Idiom 13 */
-                advance(pIcode,i13.action());
+            /* Check for MOV regH, 0 */
+            if (((picode+1)->ic.ll.opcode == iMOV) &&
+                ((picode+1)->ic.ll.flg & I) &&
+                ((picode+1)->ic.ll.immed.op == 0))
+            {
+                if ((picode+1)->ic.ll.dst.regi == (regi + 4))
+                    return (regi - rAL + rAX);
+            }
+        }
+    }
+    return (0);
+}
+
+
+/*****************************************************************************
+ * idiom 14 - Long word assign
+ *      MOV regL, mem/reg
+ *      XOR regH, regH
+ *      Eg:     MOV ax, di 
+ *              XOR dx, dx
+ *      => MOV dx:ax, di 
+ *		Note: only the following combinations are allowed: 
+ *				dx:ax
+ *				cx:bx
+ *		this is to remove the possibility of making errors in situations
+ *		like this:
+ *			MOV dx, offH
+ *			MOV ax, offL
+ *			XOR	cx, cx
+ *      Found in Borland Turbo C, used for division of unsigned integer 
+ *      operands.
+ ****************************************************************************/
+static boolT idiom14 (PICODE picode, PICODE pend, byte *regL, byte *regH)
+{
+    if (picode < pend)
+    {
+        /* Check for regL */
+        *regL = picode->ic.ll.dst.regi;
+        if (((picode->ic.ll.flg & I) != I) && ((*regL == rAX) || (*regL ==rBX)))
+        {
+            /* Check for XOR regH, regH */
+            if (((picode+1)->ic.ll.opcode == iXOR) &&
+                (((picode+1)->ic.ll.flg & I) != I)) 
+            {
+                *regH = (picode+1)->ic.ll.dst.regi;
+				if (*regH == (picode+1)->ic.ll.src.regi)
+				{
+					if ((*regL == rAX) && (*regH == rDX))
+						return (TRUE);
+					if ((*regL == rBX) && (*regH == rCX))
+						return (TRUE);
+				}
+            }
+        }
+    }
+    return (FALSE);
+}
+
+/*****************************************************************************
+ * idiom11 - Negate long integer
+ *      NEG regH
+ *      NEG regL
+ *      SBB regH, 0
+ *      Eg:     NEG dx
+ *              NEG ax
+ *              SBB dx, 0
+ *      => dx:ax = - dx:ax
+ *      Found in Borland Turbo C.
+ ****************************************************************************/
+static boolT idiom11 (PICODE pIcode, PICODE pEnd)
+{ condId type;          /* type of argument */
+
+    if ((pIcode + 2) < pEnd)
+    {
+        type = idType  (pIcode, DST);
+        if ((type != CONSTANT) && (type != OTHER))
+        {
+            /* Check NEG reg/mem 
+             *       SBB reg/mem, 0*/
+            if (((pIcode+1)->ic.ll.opcode == iNEG) &&
+                ((pIcode+2)->ic.ll.opcode == iSBB))
+                switch (type) {
+                  case GLOB_VAR:    if (((pIcode+2)->ic.ll.dst.segValue ==
+                                        pIcode->ic.ll.dst.segValue) &&
+                                        ((pIcode+2)->ic.ll.dst.off ==
+                                        pIcode->ic.ll.dst.off))
+                                        return (TRUE);
+                                    break;
+                  case REGISTER:    if ((pIcode+2)->ic.ll.dst.regi ==
+                                        pIcode->ic.ll.dst.regi)
+                                        return (TRUE);
+                                    break;
+                  case PARAM:
+                  case LOCAL_VAR:   if ((pIcode+2)->ic.ll.dst.off ==
+                                        pIcode->ic.ll.dst.off)
+                                        return (TRUE);
+                                    break;
+                }
+        }
+    }
+    return (FALSE);
+}
+
+
+/*****************************************************************************
+ * idiom 16: Bitwise negation
+ *		NEG reg
+ *		SBB reg, reg
+ *		INC reg
+ *		=> ASGN reg, !reg
+ *		Eg:		NEG ax
+ *				SBB ax, ax
+ *				INC ax
+ *			=> ax = !ax
+ *		Found in Borland Turbo C when negating bitwise.
+ ****************************************************************************/
+static boolT idiom16 (PICODE picode, PICODE pend)
+{ byte regi;
+
+	if ((picode+2) < pend)
+	{
+		regi = picode->ic.ll.dst.regi;
+		if ((regi >= rAX) && (regi < INDEXBASE))
+		{
+			if (((picode+1)->ic.ll.opcode == iSBB) &&
+				((picode+2)->ic.ll.opcode == iINC))
+				if (((picode+1)->ic.ll.dst.regi == 
+											((picode+1)->ic.ll.src.regi)) &&
+					((picode+1)->ic.ll.dst.regi == regi) &&
+					((picode+2)->ic.ll.dst.regi == regi))
+					return (TRUE);
+		}
+	}
+	return (FALSE);
+}
+
+
+/*****************************************************************************
+ * idiom 18: Post-increment or post-decrement in a conditional jump
+ *		MOV  reg, var (including register variables)
+ *		INC	 var	or DEC var
+ *		CMP  var, Y
+ *		JX   label
+ *		=> HLI_JCOND (var++ X Y)
+ *		Eg:		MOV  ax, si
+ *				INC  si
+ *				CMP  ax, 8
+ *				JL   labX
+ *			=>  HLI_JCOND (si++ < 8)
+ * 		Found in Borland Turbo C.  Intrinsic to C languages.
+ ****************************************************************************/
+static boolT idiom18 (PICODE picode, PICODE pend, PPROC pproc)
+{ boolT type = 0;	/* type of variable: 1 = reg-var, 2 = local */
+  byte regi;		/* register of the MOV */
+
+	/* Get variable */
+	if (picode->ic.ll.dst.regi == 0)	/* global variable */
+		/* not supported yet */ ;
+	else if (picode->ic.ll.dst.regi < INDEXBASE)	/* register */
+	{
+		if ((picode->ic.ll.dst.regi == rSI) && (pproc->flg & SI_REGVAR))
+			type = 1;
+		else if ((picode->ic.ll.dst.regi == rDI) && (pproc->flg & DI_REGVAR))
+			type = 1;
+	}
+	else if (picode->ic.ll.dst.off)		/* local variable */
+		type = 2;
+	else		/* indexed */
+		/* not supported yet */ ;
+
+	/* Check previous instruction for a MOV */
+	if (type == 1)			/* register variable */
+	{
+		if (((picode-1)->ic.ll.opcode == iMOV) &&
+			((picode-1)->ic.ll.src.regi == picode->ic.ll.dst.regi))
+		{
+			regi = (picode-1)->ic.ll.dst.regi;
+			if ((regi > 0) && (regi < INDEXBASE))
+			{
+				if ((picode < pend) && ((picode+1) < pend) &&
+					((picode+1)->ic.ll.opcode == iCMP) &&
+					((picode+1)->ic.ll.dst.regi == regi) &&
+					(((picode+2)->ic.ll.opcode >= iJB) &&
+					 ((picode+2)->ic.ll.opcode < iJCXZ)))
+					return (TRUE);
+			}
+		}
+	}
+	else if (type == 2)		/* local */
+	{
+		if (((picode-1)->ic.ll.opcode == iMOV) && 
+			((picode-1)->ic.ll.src.off == picode->ic.ll.dst.off))
+		{
+			regi = (picode-1)->ic.ll.dst.regi;
+			if ((regi > 0) && (regi < INDEXBASE))
+			{
+				if ((picode < pend) && ((picode+1) < pend) &&
+					((picode+1)->ic.ll.opcode == iCMP) &&
+					((picode+1)->ic.ll.dst.regi == regi) &&
+					(((picode+2)->ic.ll.opcode >= iJB) && 
+					 ((picode+2)->ic.ll.opcode < iJCXZ)))
+					return (TRUE);
+			}
+		}
+	}
+	return (FALSE);
+}
+
+
+/*****************************************************************************
+ * idiom 19: pre-increment or pre-decrement in conditional jump, comparing
+ *			 against 0.
+ *		INC var			or DEC var		(including register vars)
+ *		JX	lab			   JX  lab
+ *		=>  HLI_JCOND (++var X 0) or HLI_JCOND (--var X 0)
+ *		Eg: INC [bp+4]
+ *			JG  lab2
+ *			=> HLI_JCOND (++[bp+4] > 0)
+ *		Found in Borland Turbo C.  Intrinsic to C language.
+ ****************************************************************************/
+static boolT idiom19 (PICODE picode, PICODE pend, PPROC pproc)
+{
+	if (picode->ic.ll.dst.regi == 0)	/* global variable */
+		/* not supported yet */ ;
+	else if (picode->ic.ll.dst.regi < INDEXBASE) /* register */
+	{
+		if (((picode->ic.ll.dst.regi == rSI) && (pproc->flg & SI_REGVAR)) ||
+			((picode->ic.ll.dst.regi == rDI) && (pproc->flg & DI_REGVAR)))
+			if ((picode < pend) && ((picode+1)->ic.ll.opcode >= iJB) && 
+				((picode+1)->ic.ll.opcode < iJCXZ))
+				return (TRUE);
+	}
+	else if (picode->ic.ll.dst.off)		/* stack variable */
+	{
+		if ((picode < pend) && ((picode+1)->ic.ll.opcode >= iJB) && 
+			((picode+1)->ic.ll.opcode < iJCXZ))
+			return (TRUE);
+	}
+	else	/* indexed */
+		/* not supported yet */ ;
+	return (FALSE);
+}
+
+
+/*****************************************************************************
+ * idiom20: Pre increment/decrement in conditional expression (compares
+ *			against a register, variable or constant different than 0).
+ *		INC var			or DEC var (including register vars)
+ *		MOV reg, var	   MOV reg, var
+ *		CMP reg, Y		   CMP reg, Y
+ *		JX  lab			   JX  lab
+ *		=> HLI_JCOND (++var X Y) or HLI_JCOND (--var X Y)
+ *		Eg: INC si	(si is a register variable)
+ *			MOV ax, si
+ *			CMP ax, 2
+ *			JL	lab4
+ *			=> HLI_JCOND (++si < 2)
+ *		Found in Turbo C.  Intrinsic to C language.
+ ****************************************************************************/
+static boolT idiom20 (PICODE picode, PICODE pend, PPROC pproc)
+{ boolT type = 0;	/* type of variable: 1 = reg-var, 2 = local */
+  byte regi;		/* register of the MOV */
+
+	/* Get variable */
+	if (picode->ic.ll.dst.regi == 0)	/* global variable */
+		/* not supported yet */ ;
+	else if (picode->ic.ll.dst.regi < INDEXBASE)	/* register */
+	{
+		if ((picode->ic.ll.dst.regi == rSI) && (pproc->flg & SI_REGVAR))
+			type = 1;
+		else if ((picode->ic.ll.dst.regi == rDI) && (pproc->flg & DI_REGVAR))
+			type = 1;
+	}
+	else if (picode->ic.ll.dst.off)		/* local variable */
+		type = 2;
+	else		/* indexed */
+		/* not supported yet */ ;
+
+	/* Check previous instruction for a MOV */
+	if (type == 1)			/* register variable */
+	{
+		if ((picode < pend) && ((picode+1)->ic.ll.opcode == iMOV) && 
+			((picode+1)->ic.ll.src.regi == picode->ic.ll.dst.regi))
+		{
+			regi = (picode+1)->ic.ll.dst.regi;
+			if ((regi > 0) && (regi < INDEXBASE))
+			{
+				if (((picode+1) < pend) && ((picode+2) < pend) &&
+					((picode+2)->ic.ll.opcode == iCMP) &&
+					((picode+2)->ic.ll.dst.regi == regi) &&
+					(((picode+3)->ic.ll.opcode >= iJB) && 
+					 ((picode+3)->ic.ll.opcode < iJCXZ)))
+					return (TRUE);
+			}
+		}
+	}
+	else if (type == 2)		/* local */
+	{
+		if ((picode < pend) && ((picode+1)->ic.ll.opcode == iMOV) && 
+			((picode+1)->ic.ll.src.off == picode->ic.ll.dst.off))
+		{
+			regi = (picode+1)->ic.ll.dst.regi;
+			if ((regi > 0) && (regi < INDEXBASE))
+			{
+				if (((picode+1) < pend) && ((picode+2) < pend) &&
+					((picode+2)->ic.ll.opcode == iCMP) &&
+					((picode+2)->ic.ll.dst.regi == regi) &&
+					(((picode+3)->ic.ll.opcode >= iJB) && 
+					 ((picode+3)->ic.ll.opcode < iJCXZ)))
+					return (TRUE);
+			}
+		}
+	}
+	return (FALSE);
+}
+
+
+/*****************************************************************************
+ * findIdioms  - translates LOW_LEVEL icode idioms into HIGH_LEVEL icodes.
+ ****************************************************************************/
+void findIdioms (PPROC pProc)
+{   Int     ip;             /* Index to current icode                   */
+    PICODE  pEnd, pIcode;   /* Pointers to end of BB and current icodes */
+    int16   delta;
+    COND_EXPR *rhs, *lhs;   /* Pointers to left and right hand side exps */
+    COND_EXPR *exp;         /* Pointer to temporal expression           */
+    Int     idx;            /* Index into local identifier table        */
+    byte    regH, regL;     /* High and low registers for long word reg */
+
+    pIcode = pProc->Icode.GetFirstIcode();
+    pEnd = pIcode + pProc->Icode.GetNumIcodes();
+    ip = 0;
+
+    while (pIcode < pEnd)
+    {
+        switch (pIcode->ic.ll.opcode) {
+		case iDEC: case iINC:
+			if (idiom18 (pIcode, pEnd, pProc))
+			{
+				lhs = idCondExp (pIcode-1, SRC, pProc, ip, pIcode, E_USE);
+				if (pIcode->ic.ll.opcode == iDEC)
+					lhs = unaryCondExp (POST_DEC, lhs);
+				else
+					lhs = unaryCondExp (POST_INC, lhs);
+                rhs = idCondExp (pIcode+1, SRC, pProc, ip, pIcode+2, E_USE);
+				exp = boolCondExp (lhs, rhs,
+								   condOpJCond[(pIcode+2)->ic.ll.opcode - iJB]);
+				newJCondHlIcode (pIcode+2, exp);
+				invalidateIcode (pIcode-1);
+				invalidateIcode (pIcode);
+				invalidateIcode (pIcode+1);
+				pIcode += 3;
+				ip += 2;
+			}
+			else if (idiom19 (pIcode, pEnd, pProc))
+			{
+				lhs = idCondExp (pIcode, DST, pProc, ip, pIcode+1, E_USE);
+				if (pIcode->ic.ll.opcode == iDEC)
+					lhs = unaryCondExp (PRE_DEC, lhs);
+				else
+					lhs = unaryCondExp (PRE_INC, lhs);
+				rhs = idCondExpKte (0, 2);
+				exp = boolCondExp (lhs, rhs,
+								   condOpJCond[(pIcode+1)->ic.ll.opcode - iJB]);
+				newJCondHlIcode (pIcode+1, exp);
+				invalidateIcode (pIcode);
+				pIcode += 2;
+				ip++;
+			}
+			else if (idiom20 (pIcode, pEnd, pProc))
+			{
+				lhs = idCondExp (pIcode+1, SRC, pProc, ip, pIcode, E_USE);
+				if (pIcode->ic.ll.opcode == iDEC)
+					lhs = unaryCondExp (PRE_DEC, lhs);
+				else
+					lhs = unaryCondExp (PRE_INC, lhs);
+                rhs = idCondExp (pIcode+2, SRC, pProc, ip, pIcode+3, E_USE);
+				exp = boolCondExp (lhs, rhs,
+								   condOpJCond[(pIcode+3)->ic.ll.opcode - iJB]);
+				newJCondHlIcode (pIcode+3, exp);
+				invalidateIcode (pIcode);
+				invalidateIcode (pIcode+1);
+				invalidateIcode (pIcode+2);
+				pIcode += 3;
+				ip += 2;
+			}
+			else
+				pIcode++;
+			break;
+
+        case iPUSH:             /* Idiom 1 */
+            if ((! (pProc->flg & PROC_HLL)) && 
+                (idx = idiom1 (pIcode, pEnd, pProc)))
+            {
+                pProc->flg |= PROC_HLL;
+                for ( ; idx > 0; idx--)
+                {
+                    invalidateIcode (pIcode++);
+                    ip++;
+                }
+                ip--;
+            }
+            else
+                pIcode++;
+            break;
+
+        case iMOV:              /* Idiom 2 */
+            if (idx = idiom2(pIcode, pEnd, ip, pProc))
+            {
+                invalidateIcode (pIcode);
+                invalidateIcode (pIcode+1);
+				pIcode += 3;
+                ip += 2;
+            }
+            else if (idiom14 (pIcode, pEnd, &regL, &regH))  /* Idiom 14 */ 
+            {
+                idx = newLongRegId (&pProc->localId, TYPE_LONG_SIGN,
+                                     regH, regL, ip);
+                lhs = idCondExpLongIdx (idx);
+                setRegDU (pIcode, regH, E_DEF);
+                rhs = idCondExp (pIcode, SRC, pProc, ip, pIcode, NONE);
+                newAsgnHlIcode (pIcode, lhs, rhs);
+                invalidateIcode (pIcode+1);
+                pIcode += 2;
+                ip++;
+            }
+            else if (idx = idiom13 (pIcode, pEnd))      /* Idiom 13 */ 
+            {
+                lhs = idCondExpReg (idx, 0, &pProc->localId);
+                setRegDU (pIcode, idx, E_DEF);
+                pIcode->du1.numRegsDef--;   	/* prev byte reg def */
+                rhs = idCondExp (pIcode, SRC, pProc, ip, pIcode, NONE);
+                newAsgnHlIcode (pIcode, lhs, rhs);
+                invalidateIcode (pIcode+1);
+                pIcode += 2;
+                ip++;
+            } 
             else
                 pIcode++;
             break;
-        }
 
         case iCALL:  case iCALLF:
-            /* Check for library functions that return a long register.
-                         * Propagate this result */
-            if (pIcode->ll()->src().proc.proc != 0)
-                if ((pIcode->ll()->src().proc.proc->flg & PROC_ISLIB) &&
-                        (pIcode->ll()->src().proc.proc->flg & PROC_IS_FUNC))
+			/* Check for library functions that return a long register.
+			 * Propagate this result */
+	if (pIcode->ic.ll.immed.proc.proc != 0)
+			if ((pIcode->ic.ll.immed.proc.proc->flg & PROC_ISLIB) &&
+				(pIcode->ic.ll.immed.proc.proc->flg & PROC_IS_FUNC))
+			{
+			   if ((pIcode->ic.ll.immed.proc.proc->retVal.type==TYPE_LONG_SIGN)	
+				  || (pIcode->ic.ll.immed.proc.proc->retVal.type ==
+				  											TYPE_LONG_UNSIGN))
+					newLongRegId(&pProc->localId, TYPE_LONG_SIGN, rDX, rAX, ip);
+			}
+
+			/* Check for idioms */
+            if (idx = idiom3(pIcode, pEnd))         /* idiom 3 */
+            {
+                if (pIcode->ic.ll.flg & I) 
                 {
-                    if ((pIcode->ll()->src().proc.proc->retVal.type==TYPE_LONG_SIGN)
-                            || (pIcode->ll()->src().proc.proc->retVal.type == TYPE_LONG_UNSIGN))
-                        localId.newLongReg(TYPE_LONG_SIGN, rDX, rAX, pIcode/*ip*/);
+                    (pIcode->ic.ll.immed.proc.proc)->cbParam = (int16)idx;
+					pIcode->ic.ll.immed.proc.cb = idx;
+                    (pIcode->ic.ll.immed.proc.proc)->flg |= CALL_C;
+                    pIcode++;
+                    invalidateIcode (pIcode++);
+                    ip++;
                 }
-
-            /* Check for idioms */
-            if (i03.match(pIcode))         /* idiom 3 */
-                advance(pIcode,i03.action());
-            else if (i17.match(pIcode))  /* idiom 17 */
-                advance(pIcode,i17.action());
+            }
+            else if (idx = idiom17 (pIcode, pEnd))  /* idiom 17 */
+            {
+                if (pIcode->ic.ll.flg & I)
+                {
+                    (pIcode->ic.ll.immed.proc.proc)->cbParam = (int16)idx;
+					pIcode->ic.ll.immed.proc.cb = idx;
+                    (pIcode->ic.ll.immed.proc.proc)->flg |= CALL_C;
+                    ip += idx/2 - 1;
+                    pIcode++;
+                    for (idx /= 2; idx > 0; idx--)
+                        invalidateIcode (pIcode++);
+                }
+            }
             else
                 pIcode++;
             break;
 
-        case iRET:          /* Idiom 4 */
-        case iRETF:
-            advance(pIcode,i04(pIcode));
+        case iRET:          /* Idiom 4 */   
+		case iRETF:
+            idiom4 (pIcode, pEnd, pProc);
+            pIcode++;
             break;
 
         case iADD:          /* Idiom 5 */
-            advance(pIcode,i05(pIcode));
+            if (idiom5 (pIcode, pEnd))
+            {
+                lhs = idCondExpLong (&pProc->localId, DST, pIcode, LOW_FIRST, 
+                                     ip, USE_DEF, 1); 
+                rhs = idCondExpLong (&pProc->localId, SRC, pIcode, LOW_FIRST, 
+                                     ip, E_USE, 1);
+                exp = boolCondExp (lhs, rhs, ADD);
+                newAsgnHlIcode (pIcode, lhs, exp);
+                invalidateIcode (pIcode + 1);
+                pIcode++;
+                ip++;
+            }
+            pIcode++;
             break;
 
         case iSAR:          /* Idiom 8 */
-            advance(pIcode,i08(pIcode));
+            if (idiom8 (pIcode, pEnd))
+            {
+                idx = newLongRegId (&pProc->localId, TYPE_LONG_SIGN,
+                        pIcode->ic.ll.dst.regi, (pIcode+1)->ic.ll.dst.regi,ip);
+                lhs = idCondExpLongIdx (idx);
+                setRegDU (pIcode, (pIcode+1)->ic.ll.dst.regi, USE_DEF);
+                rhs = idCondExpKte (1, 2);
+                exp = boolCondExp (lhs, rhs, SHR);
+                newAsgnHlIcode (pIcode, lhs, exp);
+                invalidateIcode (pIcode + 1);
+                pIcode++;
+                ip++;
+            }
+            pIcode++;
             break;
 
         case iSHL:
-            if (i15.match(pIcode))       /* idiom 15 */
-                advance(pIcode,i15.action());
-            else if (i12.match(pIcode))        /* idiom 12 */
-                advance(pIcode,i12.action());
+			if (idx = idiom15 (pIcode, pEnd))       /* idiom 15 */
+            {
+                lhs = idCondExpReg (pIcode->ic.ll.dst.regi, 
+                                    pIcode->ic.ll.flg & NO_SRC_B,
+                                    &pProc->localId);
+                rhs = idCondExpKte (idx, 2);
+                exp = boolCondExp (lhs, rhs, SHL);
+                newAsgnHlIcode (pIcode, lhs, exp);
+                pIcode++;
+                for (idx-- ; idx > 0; idx--)
+                {
+                    invalidateIcode (pIcode++);
+                    ip++;
+                }
+            }
+            else if (idiom12 (pIcode, pEnd))        /* idiom 12 */
+            {
+                idx = newLongRegId (&pProc->localId, TYPE_LONG_UNSIGN,
+                        (pIcode+1)->ic.ll.dst.regi, pIcode->ic.ll.dst.regi,ip);
+                lhs = idCondExpLongIdx (idx);
+                setRegDU (pIcode, (pIcode+1)->ic.ll.dst.regi, USE_DEF);
+                rhs = idCondExpKte (1, 2);
+                exp = boolCondExp (lhs, rhs, SHL);
+                newAsgnHlIcode (pIcode, lhs, exp);
+                invalidateIcode (pIcode + 1);
+                pIcode += 2;
+                ip++;
+            }
             else
                 pIcode++;
             break;
 
         case iSHR:          /* Idiom 9 */
-            advance(pIcode,i09(pIcode));
+            if (idiom9 (pIcode, pEnd))
+            {
+                idx = newLongRegId (&pProc->localId, TYPE_LONG_UNSIGN,
+                        pIcode->ic.ll.dst.regi, (pIcode+1)->ic.ll.dst.regi,ip);
+                lhs = idCondExpLongIdx (idx);
+                setRegDU (pIcode, (pIcode+1)->ic.ll.dst.regi, USE_DEF);
+                rhs = idCondExpKte (1, 2);
+                exp = boolCondExp (lhs, rhs, SHR);
+                newAsgnHlIcode (pIcode, lhs, exp);
+                invalidateIcode (pIcode + 1);
+                pIcode++;
+                ip++;
+            }
+            pIcode++;
             break;
 
         case iSUB:          /* Idiom 6 */
-            advance(pIcode,i06(pIcode));
+            if (idiom6 (pIcode, pEnd))
+            {
+                lhs = idCondExpLong (&pProc->localId, DST, pIcode, LOW_FIRST, 
+                                     ip, USE_DEF, 1);
+                rhs = idCondExpLong (&pProc->localId, SRC, pIcode, LOW_FIRST, 
+                                     ip, E_USE, 1);
+                exp = boolCondExp (lhs, rhs, SUB);
+                newAsgnHlIcode (pIcode, lhs, exp);
+                invalidateIcode (pIcode + 1);
+                pIcode++;
+                ip++;
+            }
+            pIcode++;
             break;
 
         case iOR:           /* Idiom 10 */
-            advance(pIcode,i10(pIcode));
+            idiom10 (pIcode, pEnd);
+            pIcode++;
             break;
 
         case iNEG:          /* Idiom 11 */
-            if (i11.match(pIcode))
-                advance(pIcode,i11.action());
-            else if (i16.match(pIcode))
-                advance(pIcode,i16.action());
-            else
-                pIcode++;
+            if (idiom11 (pIcode, pEnd))
+            {
+                lhs = idCondExpLong (&pProc->localId, DST, pIcode, HIGH_FIRST, 
+                                     ip, USE_DEF, 1);
+                rhs = unaryCondExp (NEGATION, lhs);
+                newAsgnHlIcode (pIcode, lhs, rhs);
+                invalidateIcode (pIcode+1);
+                invalidateIcode (pIcode+2);
+                pIcode += 3;
+                ip += 2;
+            }
+			else if (idiom16 (pIcode, pEnd))
+			{
+				lhs = idCondExpReg (pIcode->ic.ll.dst.regi, pIcode->ic.ll.flg,
+									&pProc->localId);
+				rhs = copyCondExp (lhs);
+				rhs = unaryCondExp (NEGATION, lhs);
+				newAsgnHlIcode (pIcode, lhs, rhs);
+				invalidateIcode (pIcode+1);
+				invalidateIcode (pIcode+2);
+				pIcode += 3;
+				ip += 2;
+			}
+			else
+            	pIcode++;
             break;
 
         case iNOP:
-            (pIcode++)->invalidate();
+            invalidateIcode (pIcode++);
             break;
 
         case iENTER:		/* ENTER is equivalent to init PUSH bp */
-            if (pIcode == Icode.begin()) //ip == 0
-            {
-                flg |= (PROC_HLL | PROC_IS_HLL);
-            }
+            if (ip == 0)
+                pProc->flg |= (PROC_HLL | PROC_IS_HLL);
             pIcode++;
             break;
 
         case iXOR:          /* Idiom 7 */
-            if (i21.match(pIcode))
-                advance(pIcode,i21.action());
-            else if (i07.match(pIcode))
-                advance(pIcode,i07.action());
-            else
-                ++pIcode;
+			if (idiom21 (pIcode, pEnd))
+			{
+				lhs = idCondExpLong (&pProc->localId, DST, pIcode,
+									 HIGH_FIRST, ip, E_DEF, 1);
+				rhs = idCondExpKte ((pIcode+1)->ic.ll.immed.op , 4);
+				newAsgnHlIcode (pIcode, lhs, rhs);
+				pIcode->du.use = 0;		/* clear register used in iXOR */
+				invalidateIcode (pIcode+1);
+				pIcode++;
+				ip++;
+			}
+            else if (idiom7 (pIcode))
+            {
+                lhs = idCondExp (pIcode, DST, pProc, ip, pIcode, NONE);
+                rhs = idCondExpKte (0, 2);
+                newAsgnHlIcode (pIcode, lhs, rhs);
+                pIcode->du.use = 0;    /* clear register used in iXOR */
+                pIcode->ic.ll.flg |= I;
+            } 
+            pIcode++;
             break;
 
         default:
             pIcode++;
         }
+        ip++;
     }
 
     /* Check if number of parameter bytes match their calling convention */
-    if ((flg & PROC_HLL) && (!args.empty()))
+    if ((pProc->flg & PROC_HLL) && (pProc->args.csym)) 
     {
-        args.m_minOff += (flg & PROC_FAR ? 4 : 2);
-        delta = args.maxOff - args.m_minOff;
-        if (cbParam != delta)
-        {
-            cbParam = delta;
-            flg |= (CALL_MASK & CALL_UNKNOWN);
-        }
-    }
+		pProc->args.minOff += (pProc->flg & PROC_FAR ? 4 : 2);
+		delta = pProc->args.maxOff - pProc->args.minOff;
+		if (pProc->cbParam != delta) 
+		{
+            pProc->cbParam = delta;
+            pProc->flg |= (CALL_MASK & CALL_UNKNOWN);
+		}
+    } 
 }
 
 
+void bindIcodeOff (PPROC pProc)
 /* Sets up the TARGET flag for jump target addresses, and
  * binds jump target addresses to icode offsets.    */
-void Function::bindIcodeOff()
-{
+{ Int i, j;                 /* idx into icode array */
+  PICODE pIcode;            /* ptr icode array      */
+  dword *p;                 /* for case table       */
 
-    iICODE pIcode;            /* ptr icode array      */
-    if (Icode.empty())        /* No Icode */
-        return;
-    pIcode = Icode.begin();
+    if (! pProc->Icode.GetNumIcodes())        /* No Icode */
+        return;             
+    pIcode = pProc->Icode.GetFirstIcode();
 
     /* Flag all jump targets for BB construction and disassembly stage 2 */
-    for(ICODE &c : Icode) // TODO: use filtered here
-    {
-        LLInst *ll=c.ll();
-        if (ll->testFlags(I) && ll->isJmpInst())
+    for (i = 0; i < pProc->Icode.GetNumIcodes(); i++)
+        if ((pIcode[i].ic.ll.flg & I) && JmpInst(pIcode[i].ic.ll.opcode))
         {
-            iICODE loc=Icode.labelSrch(ll->src().getImm2());
-            if (loc!=Icode.end())
-                loc->ll()->setFlags(TARGET);
+            if (pProc->Icode.labelSrch(pIcode[i].ic.ll.immed.op, &j))
+			{
+                pIcode[j].ic.ll.flg |= TARGET;
+			}
         }
-    }
 
     /* Finally bind jump targets to Icode offsets.  Jumps for which no label
-     * is found (no code at dest. of jump) are simply left unlinked and
+     * is found (no code at dest. of jump) are simply left unlinked and 
      * flagged as going nowhere.  */
-    //for (pIcode = Icode.begin(); pIcode!= Icode.end(); pIcode++)
-    for(ICODE &icode : Icode)
-    {
-        LLInst *ll=icode.ll();
-        if (not ll->isJmpInst())
-            continue;
-        if (ll->testFlags(I) )
-        {
-            uint32_t found;
-            if (! Icode.labelSrch(ll->src().getImm2(), found))
-                ll->setFlags( NO_LABEL );
-            else
-                ll->replaceSrc(LLOperand::CreateImm2(found));
-
-        }
-        else if (ll->testFlags(SWITCH) )
+    pIcode = pProc->Icode.GetFirstIcode();
+    for (i = 0; i < pProc->Icode.GetNumIcodes(); i++)
+        if (JmpInst(pIcode[i].ic.ll.opcode))
         {
-            /* for case table       */
-            for (uint32_t &p : ll->caseTbl2)
-                Icode.labelSrch(p, p); // for each entry in caseTable replace it with target insn Idx
+            if (pIcode[i].ic.ll.flg & I)
+            {
+                if (! pProc->Icode.labelSrch(pIcode[i].ic.ll.immed.op, 
+                                (Int *)&pIcode[i].ic.ll.immed.op))
+                    pIcode[i].ic.ll.flg |= NO_LABEL;
+            }
+            else if (pIcode[i].ic.ll.flg & SWITCH)
+            {
+                p = pIcode[i].ic.ll.caseTbl.entries;
+                for (j = 0; j < pIcode[i].ic.ll.caseTbl.numEntries; j++, p++)
+                    pProc->Icode.labelSrch(*p, (Int *)p);
+            }
         }
-    }
 }
 
-/** Performs idioms analysis, and propagates long operands, if any */
-void Function::lowLevelAnalysis ()
+
+void lowLevelAnalysis (PPROC pProc)
+/* Performs idioms analysis, and propagates long operands, if any */
 {
+    /* Idiom analysis - sets up some flags and creates some HIGH_LEVEL
+     * icodes */
+    findIdioms (pProc); 
 
-    findIdioms(); // Idiom analysis - sets up some flags and creates some HIGH_LEVEL icodes
-    propLong();   // Propagate HIGH_LEVEL idiom information for long operands
+    /* Propagate HIGH_LEVEL idiom information for long operands */
+    propLong (pProc);
 }

+ 0 - 314
src/idioms/arith_idioms.cpp

@@ -1,314 +0,0 @@
-#include "dcc.h"
-#include "arith_idioms.h"
-using namespace std;
-
-/*****************************************************************************
- * idiom5 - Long addition.
- *      ADD reg/stackOff, reg/stackOff
- *      ADC reg/stackOff, reg/stackOff
- *      Eg:     ADD ax, [bp-4]
- *              ADC dx, [bp-2]
- *          =>  dx:ax = dx:ax + [bp-2]:[bp-4]
- *      Found in Borland Turbo C code.
- *      Commonly used idiom for long addition.
- ****************************************************************************/
-bool Idiom5::match(iICODE pIcode)
-{
-    if(distance(pIcode,m_end)<2)
-        return false;
-    m_icodes[0]=pIcode++;
-    m_icodes[1]=pIcode++;
-    if (m_icodes[1]->ll()->match(iADC))
-        return true;
-    return false;
-}
-
-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);
-    m_icodes[0]->setAsgn(lhs, expr);
-    m_icodes[1]->invalidate();
-    return 2;
-
-}
-
-/*****************************************************************************
- * idiom6 - Long substraction.
- *      SUB reg/stackOff, reg/stackOff
- *      SBB reg/stackOff, reg/stackOff
- *      Eg:     SUB ax, [bp-4]
- *              SBB dx, [bp-2]
- *          =>  dx:ax = dx:ax - [bp-2]:[bp-4]
- *      Found in Borland Turbo C code.
- *      Commonly used idiom for long substraction.
- ****************************************************************************/
-bool Idiom6::match(iICODE pIcode)
-{
-    if(distance(pIcode,m_end)<2)
-        return false;
-    m_icodes[0]=pIcode++;
-    m_icodes[1]=pIcode++;
-    if (m_icodes[1]->ll()->match(iSBB))
-        return true;
-    return false;
-}
-
-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);
-    m_icodes[0]->setAsgn(lhs, expr);
-    m_icodes[1]->invalidate();
-    return 2;
-
-}
-
-
-/*****************************************************************************
- * idiom 18: Post-increment or post-decrement in a conditional jump
- * Used
- *	0	MOV  reg, var (including register variables)
- *	1	INC var	or DEC var <------------------------- input point
- *	2	CMP  var, Y
- *	3	JX   label
- *		=> HLI_JCOND (var++ X Y)
- *		Eg:		MOV  ax, si
- *				INC  si
- *				CMP  ax, 8
- *				JL   labX
- *			=>  HLI_JCOND (si++ < 8)
- * 		Found in Borland Turbo C.  Intrinsic to C languages.
- ****************************************************************************/
-bool Idiom18::match(iICODE picode)
-{
-    if(picode==m_func->Icode.begin())
-        return false;
-    if(std::distance(picode,m_end)<3)
-        return false;
-    --picode; //
-
-    for(int i=0; i<4; ++i)
-        m_icodes[i] =picode++;
-
-    m_is_dec = m_icodes[1]->ll()->match(iDEC);
-    int type = -1;	/* type of variable: 1 = reg-var, 2 = local */
-    uint8_t regi;		/* register of the MOV */
-
-    /* Get variable */
-    if (m_icodes[1]->ll()->dst.regi == 0)	/* global variable */
-    {
-        /* not supported yet */
-        type = 0;
-    }
-    else if ( m_icodes[1]->ll()->dst.isReg() )	/* register */
-    {
-        if ((m_icodes[1]->ll()->dst.regi == rSI) && (m_func->flg & SI_REGVAR))
-            type = 1;
-        else if ((m_icodes[1]->ll()->dst.regi == rDI) && (m_func->flg & DI_REGVAR))
-            type = 1;
-    }
-    else if (m_icodes[1]->ll()->dst.off)		/* local variable */
-        type = 2;
-    else		/* indexed */
-    {
-        type=3;
-        /* not supported yet */
-        printf("Unsupported idiom18 type: indexed");
-    }
-
-    switch(type)
-    {
-    case 0: // global
-        printf("Unsupported idiom18 type: global variable");
-        break;
-    case 1:  /* register variable */
-        /* Check previous instruction for a MOV */
-        if (m_icodes[0]->ll()->match(iMOV) && (m_icodes[0]->ll()->src().regi == m_icodes[1]->ll()->dst.regi))
-        {
-            regi = m_icodes[0]->ll()->dst.regi;
-            if ( m_icodes[0]->ll()->dst.isReg() )
-            {
-                if ( m_icodes[2]->ll()->match(iCMP) && (m_icodes[2]->ll()->dst.regi == regi) &&
-                     m_icodes[3]->ll()->conditionalJump() )
-                    return true;
-            }
-        }
-        break;
-    case 2: /* local */
-        if (m_icodes[0]->ll()->match(iMOV) && (m_icodes[0]->ll()->src().off == m_icodes[1]->ll()->dst.off))
-        {
-            regi = m_icodes[0]->ll()->dst.regi;
-            if ( m_icodes[0]->ll()->dst.isReg() )
-            {
-                if ( m_icodes[2]->ll()->match(iCMP) && (m_icodes[2]->ll()->dst.regi == regi) &&
-                     m_icodes[3]->ll()->conditionalJump() )
-                    return true;
-            }
-        }
-        break;
-    case 3: // indexed
-        printf("Unsupported idiom18 type: indexed");
-        break;
-    }
-    return false;
-}
-
-int Idiom18::action() // action length
-{
-    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]);
-    m_icodes[3]->setJCond(expr);
-
-    m_icodes[0]->invalidate();
-    m_icodes[1]->invalidate();
-    m_icodes[2]->invalidate();
-    return 3;
-}
-
-/*****************************************************************************
- * idiom 19: pre-increment or pre-decrement in conditional jump, comparing against 0.
- *		[INC | DEC] var (including register vars)
- *		JX	lab	JX  lab
- *		=>  HLI_JCOND (++var X 0) or HLI_JCOND (--var X 0)
- *		Eg: INC [bp+4]
- *                  JG  lab2
- *			=> HLI_JCOND (++[bp+4] > 0)
- *		Found in Borland Turbo C.  Intrinsic to C language.
- ****************************************************************************/
-bool Idiom19::match(iICODE picode)
-{
-    if(std::distance(picode,m_end)<2)
-        return false;
-
-    for(int i=0; i<2; ++i)
-        m_icodes[i] =picode++;
-    m_is_dec = m_icodes[0]->ll()->match(iDEC);
-    if (m_icodes[0]->ll()->dst.regi == 0)	/* global variable */
-        /* not supported yet */ ;
-    else if ( m_icodes[0]->ll()->dst.isReg() ) /* register */
-    {
-        //        if (((picode->ll()->dst.regi == rSI) && (pproc->flg & SI_REGVAR)) ||
-        //            ((picode->ll()->dst.regi == rDI) && (pproc->flg & DI_REGVAR)))
-        if (m_icodes[1]->ll()->conditionalJump())
-            return true;
-    }
-    else if (m_icodes[0]->ll()->dst.off)		/* stack variable */
-    {
-        if ( m_icodes[1]->ll()->conditionalJump() )
-            return true;
-    }
-    else	/* indexed */
-        /* not supported yet */ ;
-    return false;
-}
-int Idiom19::action()
-{
-    COND_EXPR *lhs,*rhs,*expr;
-    lhs = COND_EXPR::id (*m_icodes[1]->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]);
-    m_icodes[1]->setJCond(expr);
-    m_icodes[0]->invalidate();
-    return 2;
-}
-
-/*****************************************************************************
- * idiom20: Pre increment/decrement in conditional expression (compares
- *			against a register, variable or constant different than 0).
- *		INC var			or DEC var (including register vars)
- *		MOV reg, var	   MOV reg, var
- *		CMP reg, Y		   CMP reg, Y
- *		JX  lab			   JX  lab
- *		=> HLI_JCOND (++var X Y) or HLI_JCOND (--var X Y)
- *		Eg: INC si	(si is a register variable)
- *			MOV ax, si
- *			CMP ax, 2
- *			JL	lab4
- *			=> HLI_JCOND (++si < 2)
- *		Found in Turbo C.  Intrinsic to C language.
- ****************************************************************************/
-bool Idiom20::match(iICODE picode)
-{
-    uint8_t type = 0;	/* type of variable: 1 = reg-var, 2 = local */
-    uint8_t regi;		/* register of the MOV */
-    if(std::distance(picode,m_end)<4)
-        return false;
-    for(int i=0; i<4; ++i)
-        m_icodes[i] =picode++;
-
-    m_is_dec = m_icodes[0]->ll()->match(iDEC);
-
-    LLOperand &ll_dest(m_icodes[0]->ll()->dst);
-    /* Get variable */
-    if (ll_dest.regi == 0)	/* global variable */
-    {
-        /* not supported yet */ ;
-    }
-    else if ( ll_dest.isReg() )	/* register */
-    {
-        if ((ll_dest.regi == rSI) && (m_func->flg & SI_REGVAR))
-            type = 1;
-        else if ((ll_dest.regi == rDI) && (m_func->flg & DI_REGVAR))
-            type = 1;
-    }
-    else if (ll_dest.off)		/* local variable */
-        type = 2;
-    else		/* indexed */
-    {
-        printf("idiom20 : Unsupported type [indexed]\n");
-        /* not supported yet */ ;
-    }
-
-    /* Check previous instruction for a MOV */
-    if (type == 1)			/* register variable */
-    {
-        if (m_icodes[1]->ll()->match(iMOV) &&
-                (m_icodes[1]->ll()->src().regi == ll_dest.regi))
-        {
-            regi = m_icodes[1]->ll()->dst.regi;
-            if ( m_icodes[1]->ll()->dst.isReg() )
-            {
-                if (m_icodes[2]->ll()->match(iCMP,(eReg)regi) &&
-                        m_icodes[3]->ll()->conditionalJump())
-                    return true;
-            }
-        }
-    }
-    else if (type == 2)		/* local */
-    {
-        if ( m_icodes[0]->ll()->match(iMOV) &&
-             (m_icodes[1]->ll()->src().off == ll_dest.off))
-        {
-            regi = m_icodes[1]->ll()->dst.regi;
-            if ( m_icodes[1]->ll()->dst.isReg() )
-            {
-                if (m_icodes[2]->ll()->match(iCMP,(eReg)regi) &&
-                        m_icodes[3]->ll()->conditionalJump())
-                    return true;
-            }
-        }
-    }
-    return false;
-}
-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 ? PRE_DEC : PRE_INC, 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]);
-    m_icodes[3]->setJCond(expr);
-    for(int i=0; i<3; ++i)
-        m_icodes[i]->invalidate();
-    return 4;
-}

+ 0 - 111
src/idioms/call_idioms.cpp

@@ -1,111 +0,0 @@
-#include "dcc.h"
-#include "call_idioms.h"
-using namespace std;
-/*****************************************************************************
- * idiom3 - C calling convention.
- *          CALL(F)  proc_X
- *          ADD  SP, immed
- *      Eg: CALL proc_X
- *          ADD  SP, 6
- *          =>  pProc->cbParam = immed
- *		Special case: when the call is at the end of the procedure,
- *					  sometimes the stack gets restored by a MOV sp, bp.
- *					  Need to flag the procedure in these cases.
- *  Used by compilers to restore the stack when invoking a procedure using
- *  the C calling convention.
- ****************************************************************************/
-bool Idiom3::match(iICODE picode)
-{
-    if(distance(picode,m_end)<2)
-        return false;
-    m_param_count=0;
-    /* Match ADD  SP, immed */
-    for(int i=0; i<2; ++i)
-        m_icodes[i] = picode++;
-    if ( m_icodes[1]->ll()->testFlags(I) && m_icodes[1]->ll()->match(iADD,rSP))
-    {
-        m_param_count = m_icodes[1]->ll()->src().getImm2();
-        return true;
-    }
-    else if (m_icodes[1]->ll()->match(iMOV,rSP,rBP))
-    {
-        m_icodes[0]->ll()->setFlags(REST_STK);
-        return true;
-    }
-    return 0;
-}
-int Idiom3::action()
-{
-    if (m_icodes[0]->ll()->testFlags(I) )
-    {
-        m_icodes[0]->ll()->src().addProcInformation(m_param_count,CALL_C);
-    }
-    else
-    {
-        printf("Indirect call at idiom3\n");
-    }
-    m_icodes[1]->invalidate();
-    return 2;
-}
-
-
-/*****************************************************************************
- * idiom 17 - C calling convention.
- *          CALL(F)  xxxx
- *          POP reg
- *          [POP reg]           reg in {AX, BX, CX, DX}
- *      Eg: CALL proc_X
- *          POP cx
- *          POP cx      (4 bytes of arguments)
- *          => pProc->cbParam = # pops * 2
- *  Found in Turbo C when restoring the stack for a procedure that uses the
- *  C calling convention.  Used to restore the stack of 2 or 4 bytes args.
- ****************************************************************************/
-bool Idiom17::match(iICODE picode)
-{
-    if(distance(picode,m_end)<2)
-        return false;
-    m_param_count=0; /* Count on # pops */
-    m_icodes.clear();
-
-    /* Match ADD  SP, immed */
-    for(int i=0; i<2; ++i)
-        m_icodes.push_back(picode++);
-    uint8_t regi;
-
-    /* Match POP reg */
-    if (m_icodes[1]->ll()->match(iPOP))
-    {
-        int i=0;
-        regi = m_icodes[1]->ll()->dst.regi;
-        if ((regi >= rAX) && (regi <= rBX))
-            i++;
-
-        while (picode != m_end && picode->ll()->match(iPOP))
-        {
-            if (picode->ll()->dst.regi != regi)
-                break;
-            i++;
-            m_icodes.push_back(picode++);
-        }
-        m_param_count = i*2;
-    }
-    return m_param_count!=0;
-}
-int Idiom17::action()
-{
-    if (m_icodes[0]->ll()->testFlags(I))
-    {
-        m_icodes[0]->ll()->src().addProcInformation(m_param_count,CALL_C);
-        for(size_t idx=1; idx<m_icodes.size(); ++idx)
-        {
-            m_icodes[idx]->invalidate();
-        }
-    }
-    // TODO : it's a calculated call
-    else
-    {
-        printf("Indirect call at idiom17\n");
-    }
-    return m_icodes.size();
-}

+ 0 - 153
src/idioms/epilogue_idioms.cpp

@@ -1,153 +0,0 @@
-#include "dcc.h"
-#include "epilogue_idioms.h"
-
-/*****************************************************************************
- * popStkVars - checks for
- *          [POP DI]
- *          [POP SI]
- *      or  [POP SI]
- *          [POP DI]
- ****************************************************************************/
-void EpilogIdiom::popStkVars(iICODE pIcode)
-{
-    // TODO : only process SI-DI DI-SI pairings, no SI-SI, DI-DI like it's now
-    /* Match [POP DI] */
-    if (pIcode->ll()->match(iPOP))
-    {
-        if ((m_func->flg & DI_REGVAR) && pIcode->ll()->match(rDI))
-            m_icodes.push_front(pIcode);
-        else if ((m_func->flg & SI_REGVAR) && pIcode->ll()->match(rSI))
-            m_icodes.push_front(pIcode);
-    }
-    ++pIcode;
-    if(pIcode==m_end)
-        return;
-    /* Match [POP SI] */
-    if (pIcode->ll()->match(iPOP))
-    {
-        if ((m_func->flg & SI_REGVAR) && pIcode->ll()->match(rSI))
-            m_icodes.push_front(pIcode);
-        else if ((m_func->flg & DI_REGVAR) && pIcode->ll()->match(rDI))
-            m_icodes.push_front(pIcode);
-    }
-}
-
-
-/*****************************************************************************
- * idiom2 - HLL procedure epilogue;  Returns number of instructions matched.
- *          [POP DI]
- *          [POP SI]
- *          MOV  SP, BP
- *          POP  BP
- *          RET(F)
- *****************************************************************************/
-bool Idiom2::match(iICODE pIcode)
-{
-    iICODE nicode;
-    if(pIcode==m_func->Icode.begin()) // pIcode->loc_ip == 0
-        return false;
-    if ( pIcode->ll()->testFlags(I) || (not pIcode->ll()->match(rSP,rBP)) )
-        return false;
-    if(distance(pIcode,m_end)<3)
-        return false;
-    /* Matched MOV SP, BP */
-    m_icodes.clear();
-    m_icodes.push_back(pIcode);
-    /* Get next icode, skip over holes in the icode array */
-    nicode = ++iICODE(pIcode);
-    while (nicode->ll()->testFlags(NO_CODE) && (nicode != m_end))
-    {
-        nicode++;
-    }
-    if(nicode == m_end)
-        return false;
-
-    if (nicode->ll()->match(iPOP,rBP) && ! (nicode->ll()->testFlags(I | TARGET | CASE)) )
-    {
-        m_icodes.push_back(nicode++); // Matched POP BP
-
-        /* Match RET(F) */
-        if (    nicode != m_end &&
-                !(nicode->ll()->testFlags(I | TARGET | CASE)) &&
-                (nicode->ll()->match(iRET) || nicode->ll()->match(iRETF))
-                )
-        {
-            m_icodes.push_back(nicode); // Matched RET
-            advance(pIcode,-2); // move back before our start
-            popStkVars (pIcode); // and add optional pop di/si to m_icodes
-            return true;
-        }
-    }
-    return false;
-}
-int Idiom2::action()
-{
-    for(size_t idx=0; idx<m_icodes.size()-1; ++idx) // don't invalidate last entry
-        m_icodes[idx]->invalidate();
-    return 3;
-
-}
-
-/*****************************************************************************
- * idiom4 - Pascal calling convention.
- *          RET(F) immed
- *          ==> pProc->cbParam = immed
- *              sets CALL_PASCAL flag
- *        - Second version: check for optional pop of stack vars
- *          [POP DI]
- *          [POP SI]
- *          POP BP
- *          RET(F) [immed]
- *		  - Third version: pop stack vars
- *			[POP DI]
- *			[POP SI]
- *			RET(F) [immed]
- ****************************************************************************/
-bool Idiom4::match(iICODE pIcode)
-{
-    m_param_count = 0;
-    /* Check for [POP DI]
-     *           [POP SI] */
-    if(distance(m_func->Icode.begin(),pIcode)>=3)
-    {
-        iICODE search_at(pIcode);
-        advance(search_at,-3);
-        popStkVars(search_at);
-    }
-    if(pIcode != m_func->Icode.begin())
-    {
-        iICODE prev1 = --iICODE(pIcode);
-        /* Check for POP BP */
-        if (prev1->ll()->match(iPOP,rBP) && not prev1->ll()->testFlags(I) )
-            m_icodes.push_back(prev1);
-        else if(prev1!=m_func->Icode.begin())
-        {
-            iICODE search_at(pIcode);
-            advance(search_at,-2);
-            popStkVars (search_at);
-        }
-    }
-
-    /* Check for RET(F) immed */
-    if (pIcode->ll()->testFlags(I) )
-    {
-        m_param_count = (int16_t)pIcode->ll()->src().getImm2();
-        return true;
-    }
-    return false;
-}
-int Idiom4::action()
-{
-    if( ! m_icodes.empty()) // if not an empty RET[F] N
-    {
-    for(size_t idx=0; idx<m_icodes.size()-1; ++idx) // don't invalidate last entry
-            m_icodes[idx]->invalidate();
-    }
-    if(m_param_count)
-    {
-        m_func->cbParam = (int16_t)m_param_count;
-        m_func->flg |= CALL_PASCAL;
-    }
-    return 1;
-}
-

+ 0 - 137
src/idioms/idiom1.cpp

@@ -1,137 +0,0 @@
-#include "idiom1.h"
-#include "dcc.h"
-
-/*****************************************************************************
-/* checkStkVars - Checks for PUSH SI
- *                          [PUSH DI]
- *                or         PUSH DI
- *                          [PUSH SI]
- * In which case, the stack variable flags are set
- ****************************************************************************/
-int Idiom1::checkStkVars (iICODE pIcode)
-{
-    /* Look for PUSH SI */
-    int si_matched=0;
-    int di_matched=0;
-    if(pIcode==m_end)
-        return 0;
-    if (pIcode->ll()->match(iPUSH,rSI))
-    {
-        si_matched = 1;
-        ++pIcode;
-        if ((pIcode != m_end) && pIcode->ll()->match(iPUSH,rDI)) // Look for PUSH DI
-            di_matched = 1;
-    }
-    else if (pIcode->ll()->match(iPUSH,rDI))
-    {
-        di_matched = 1;
-        ++pIcode;
-        if ((pIcode != m_end) && pIcode->ll()->match(iPUSH,rSI)) // Look for PUSH SI
-            si_matched = 1;
-    }
-    m_func->flg |= (si_matched ? SI_REGVAR : 0) | (di_matched ? DI_REGVAR : 0);
-    return si_matched+di_matched;
-}
-/*****************************************************************************
- * idiom1 - HLL procedure prologue;  Returns number of instructions matched.
- *          PUSH BP     ==> ENTER immed, 0
- *          MOV  BP, SP     and sets PROC_HLL flag
- *          [SUB  SP, immed]
- *          [PUSH SI]
- *          [PUSH DI]
- *        - Second version: Push stack variables and then save BP
- *          PUSH BP
- *          PUSH SI
- *          [PUSH DI]
- *          MOV BP, SP
- *        - Third version: Stack variables
- *          [PUSH SI]
- *          [PUSH DI]
- ****************************************************************************/
-bool Idiom1::match(iICODE picode)
-{
-    //uint8_t type = 0;	/* type of variable: 1 = reg-var, 2 = local */
-    //uint8_t regi;		/* register of the MOV */
-    if(m_func->flg & PROC_HLL)
-        return false;
-    if(picode==m_end)
-        return false;
-    //int n;
-    m_icodes.clear();
-    m_min_off = 0;
-    /* PUSH BP as first instruction of procedure */
-    if ( (not picode->ll()->testFlags(I)) && picode->ll()->src().regi == rBP)
-    {
-        m_icodes.push_back( picode++ ); // insert iPUSH
-        if(picode==m_end)
-            return false;
-        /* MOV BP, SP as next instruction */
-        if ( !picode->ll()->testFlags(I | TARGET | CASE) && picode->ll()->match(iMOV ,rBP,rSP) )
-        {
-            m_icodes.push_back( picode++ ); // insert iMOV
-            if(picode==m_end)
-                return false;
-            m_min_off = 2;
-
-            /* Look for SUB SP, immed */
-            if (
-                picode->ll()->testFlags(I | TARGET | CASE) && picode->ll()->match(iSUB,rSP)
-                )
-            {
-                m_icodes.push_back( picode++ ); // insert iSUB
-                int n = checkStkVars (picode); // find iPUSH si [iPUSH di]
-                for(int i=0; i<n; ++i)
-                    m_icodes.push_back(picode++); // insert
-            }
-        }
-
-        /* PUSH SI
-         * [PUSH DI]
-         * MOV BP, SP */
-        else
-        {
-            int n = checkStkVars (picode);
-            if (n > 0)
-            {
-                for(int i=0; i<n; ++i)
-                    m_icodes.push_back(picode++);
-                if(picode == m_end)
-                    return false;
-                /* Look for MOV BP, SP */
-                if ( picode != m_end &&
-                    !picode->ll()->testFlags(I | TARGET | CASE) &&
-                     picode->ll()->match(iMOV,rBP,rSP))
-                {
-                    m_icodes.push_back(picode);
-                    m_min_off = 2 + (n * 2);
-                }
-                else
-                    return false;	// Cristina: check this please!
-            }
-            else
-                return false;	// Cristina: check this please!
-        }
-    }
-    else // push di [push si] / push si [push di]
-    {
-        size_t n = checkStkVars (picode);
-        for(int i=0; i<n; ++i)
-            m_icodes.push_back(picode++);
-
-    }
-    return !m_icodes.empty();
-}
-int Idiom1::action()
-{
-    for(iICODE ic : m_icodes)
-    {
-        ic->invalidate();
-    }
-    m_func->flg |= PROC_HLL;
-    if(0!=m_min_off)
-    {
-        m_func->args.m_minOff = m_min_off;
-        m_func->flg |= PROC_IS_HLL;
-    }
-    return m_icodes.size();
-}

+ 0 - 110
src/idioms/mov_idioms.cpp

@@ -1,110 +0,0 @@
-#include "dcc.h"
-#include "mov_idioms.h"
-using namespace std;
-
-/*****************************************************************************
- * idiom 14 - Long uint16_t assign
- *      MOV regL, mem/reg
- *      XOR regH, regH
- *      Eg:     MOV ax, di
- *              XOR dx, dx
- *      => MOV dx:ax, di
- *		Note: only the following combinations are allowed:
- *				dx:ax
- *				cx:bx
- *		this is to remove the possibility of making errors in situations
- *		like this:
- *			MOV dx, offH
- *			MOV ax, offL
- *			XOR	cx, cx
- *      Found in Borland Turbo C, used for division of unsigned integer
- *      operands.
- ****************************************************************************/
-
-bool Idiom14::match(iICODE pIcode)
-{
-    if(distance(pIcode,m_end)<2)
-        return false;
-    m_icodes[0]=pIcode++;
-    m_icodes[1]=pIcode++;
-    /* Check for regL */
-    m_regL = m_icodes[0]->ll()->dst.regi;
-    if (not m_icodes[0]->ll()->testFlags(I) && ((m_regL == rAX) || (m_regL ==rBX)))
-    {
-        /* Check for XOR regH, regH */
-        if (m_icodes[1]->ll()->match(iXOR) && not m_icodes[1]->ll()->testFlags(I))
-        {
-            m_regH = m_icodes[1]->ll()->dst.regi;
-            if (m_regH == m_icodes[1]->ll()->src().getReg2())
-            {
-                if ((m_regL == rAX) && (m_regH == rDX))
-                    return true;
-                if ((m_regL == rBX) && (m_regH == rCX))
-                    return true;
-            }
-        }
-    }
-    return false;
-}
-int Idiom14::action()
-{
-    int idx;
-    COND_EXPR *lhs,*rhs;
-    idx = m_func->localId.newLongReg (TYPE_LONG_SIGN, m_regH, m_regL, m_icodes[0]);
-    lhs = COND_EXPR::idLongIdx (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);
-    m_icodes[0]->setAsgn(lhs, rhs);
-    m_icodes[1]->invalidate();
-    return 2;
-}
-
-
-/*****************************************************************************
- * idiom 13 - uint16_t assign
- *      MOV regL, mem
- *      MOV regH, 0
- *      Eg:     MOV al, [bp-2]
- *              MOV ah, 0
- *      => MOV ax, [bp-2]
- *      Found in Borland Turbo C, used for multiplication and division of
- *      uint8_t operands (ie. they need to be extended to words).
- ****************************************************************************/
-bool Idiom13::match(iICODE pIcode)
-{
-    if(distance(pIcode,m_end)<2)
-        return false;
-    m_icodes[0]=pIcode++;
-    m_icodes[1]=pIcode++;
-    m_loaded_reg = rUNDEF;
-    eReg regi;
-
-    /* Check for regL */
-    regi = m_icodes[0]->ll()->dst.regi;
-    if (not m_icodes[0]->ll()->testFlags(I) && (regi >= rAL) && (regi <= rBH))
-    {
-        /* Check for MOV regH, 0 */
-        if (m_icodes[1]->ll()->match(iMOV,I) && (m_icodes[1]->ll()->src().getImm2() == 0))
-        {
-            if (m_icodes[1]->ll()->dst.regi == (regi + 4)) //WARNING: based on distance between AH-AL,BH-BL etc.
-            {
-                m_loaded_reg=(eReg)(regi - rAL + rAX);
-                return true;
-            }
-        }
-    }
-    return false;
-}
-
-int Idiom13::action()
-{
-    COND_EXPR *lhs,*rhs;
-    lhs = COND_EXPR::idReg (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);
-    m_icodes[0]->setAsgn(lhs, rhs);
-    m_icodes[1]->invalidate();
-    return 2;
-}
-

+ 0 - 102
src/idioms/neg_idioms.cpp

@@ -1,102 +0,0 @@
-#include "dcc.h"
-#include "neg_idioms.h"
-using namespace std;
-
-
-/*****************************************************************************
- * idiom11 - Negate long integer
- *      NEG regH
- *      NEG regL
- *      SBB regH, 0
- *      Eg:     NEG dx
- *              NEG ax
- *              SBB dx, 0
- *      => dx:ax = - dx:ax
- *      Found in Borland Turbo C.
- ****************************************************************************/
-bool Idiom11::match (iICODE picode)
-{
-    const char *matchstring="(oNEG rH) (oNEG rL) (SBB \rH i0)";
-    condId type;          /* type of argument */
-    if(distance(picode,m_end)<3)
-        return false;
-    for(int i=0; i<3; ++i)
-        m_icodes[i]=picode++;
-    type = m_icodes[0]->ll()->idType(DST);
-    if(type==CONSTANT || type == OTHER)
-        return false;
-    /* Check NEG reg/mem
-     *       SBB reg/mem, 0*/
-    if (not m_icodes[1]->ll()->match(iNEG) or not m_icodes[2]->ll()->match(iSBB))
-        return false;
-    switch (type)
-    {
-    case GLOB_VAR:
-        if ((m_icodes[2]->ll()->dst.segValue == m_icodes[0]->ll()->dst.segValue) &&
-                (m_icodes[2]->ll()->dst.off == m_icodes[0]->ll()->dst.off))
-            return true;
-        break;
-    case REGISTER:
-        if (m_icodes[2]->ll()->dst.regi == m_icodes[0]->ll()->dst.regi)
-            return true;
-        break;
-    case PARAM:
-    case LOCAL_VAR:
-        if (m_icodes[2]->ll()->dst.off == m_icodes[0]->ll()->dst.off)
-            return true;
-        break;
-    }
-    return false;
-}
-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);
-    m_icodes[0]->setAsgn(lhs, rhs);
-    m_icodes[1]->invalidate();
-    m_icodes[2]->invalidate();
-    return 3;
-}
-
-/*****************************************************************************
- * idiom 16: Bitwise negation
- *		NEG reg
- *		SBB reg, reg
- *		INC reg
- *		=> ASGN reg, !reg
- *		Eg:		NEG ax
- *				SBB ax, ax
- *				INC ax
- *			=> ax = !ax
- *		Found in Borland Turbo C when negating bitwise.
- ****************************************************************************/
-bool Idiom16::match (iICODE picode)
-{
-    const char *matchstring="(oNEG rR) (oSBB rR rR) (oINC rR)";
-    if(distance(picode,m_end)<3)
-        return false;
-    for(int i=0; i<3; ++i)
-        m_icodes[i]=picode++;
-
-    uint8_t regi = m_icodes[0]->ll()->dst.regi;
-    if ((regi >= rAX) && (regi < INDEX_BX_SI))
-    {
-        if (m_icodes[1]->ll()->match(iSBB) && m_icodes[2]->ll()->match(iINC))
-            if ((m_icodes[1]->ll()->dst.regi == (m_icodes[1]->ll()->src().getReg2())) &&
-                    m_icodes[1]->ll()->match((eReg)regi) &&
-                    m_icodes[2]->ll()->match((eReg)regi))
-                return true;
-    }
-    return false;
-}
-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());
-    m_icodes[0]->setAsgn(lhs, rhs);
-    m_icodes[1]->invalidate();
-    m_icodes[2]->invalidate();
-    return 3;
-}

+ 0 - 170
src/idioms/shift_idioms.cpp

@@ -1,170 +0,0 @@
-#include "dcc.h"
-#include "shift_idioms.h"
-using namespace std;
-
-
-/*****************************************************************************
- * idiom8 - Shift right by 1 (signed long ops)
- *      SAR reg, 1
- *      RCR reg, 1
- *      Eg:     SAR dx, 1
- *              RCR ax, 1
- *          =>  dx:ax = dx:ax >> 1      (dx:ax are signed long)
- *      Found in Microsoft C code for long signed variable shift right.
- ****************************************************************************/
-bool Idiom8::match(iICODE pIcode)
-{
-    if(distance(pIcode,m_end)<2)
-        return false;
-    m_icodes[0]=pIcode++;
-    m_icodes[1]=pIcode++;
-    if (m_icodes[0]->ll()->testFlags(I) && (m_icodes[0]->ll()->src().getImm2() == 1))
-        if ( m_icodes[1]->ll()->match(iRCR,I) &&
-            (m_icodes[1]->ll()->src().getImm2() == 1))
-            return true;
-    return false;
-}
-
-int Idiom8::action()
-{
-    int idx;
-    COND_EXPR *rhs,*lhs,*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);
-    m_icodes[0]->setRegDU( regL, USE_DEF);
-
-    rhs = COND_EXPR::idKte(1,2);
-    expr = COND_EXPR::boolOp(lhs, rhs, SHR);
-    m_icodes[0]->setAsgn(lhs, expr);
-    m_icodes[1]->invalidate();
-    return 2;
-}
-
-
-/*****************************************************************************
- * idiom 15 - Shift left by n
- *      SHL reg, 1
- *      SHL reg, 1
- *      [...]
- *      [SHL    reg, 1]
- *      Eg:     SHL ax, 1
- *              SHL ax, 1
- *          =>  ax = ax << 2
- *      Found in Borland Turbo C code to index an array (array multiplication)
- ****************************************************************************/
-bool Idiom15::match(iICODE pIcode)
-{
-    uint8_t regi;
-
-    if(distance(pIcode,m_end)<2)
-        return false;
-    /* Match SHL reg, 1 */
-    if (not pIcode->ll()->testFlags(I) or (pIcode->ll()->src().getImm2() != 1))
-        return false;
-    m_icodes.clear();
-    regi = pIcode->ll()->dst.regi;
-    m_icodes.push_back(pIcode++);
-    while(  (pIcode!=m_end) and
-            pIcode->ll()->match(iSHL,(eReg)regi,I) and
-            (pIcode->ll()->src().getImm2() == 1) )
-    {
-        m_icodes.push_back(pIcode++);
-    }
-    return m_icodes.size()>1;
-}
-
-int Idiom15::action()
-{
-    COND_EXPR *lhs,*rhs,*_exp;
-    lhs = COND_EXPR::idReg (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);
-    m_icodes[0]->setAsgn(lhs, _exp);
-    for (size_t i=1; i<m_icodes.size()-1; ++i)
-    {
-        m_icodes[i]->invalidate();
-    }
-    return m_icodes.size();
-}
-
-/*****************************************************************************
- * idiom12 - Shift left long by 1
- *      SHL reg, 1
- *      RCL reg, 1
- *      Eg:     SHL ax, 1
- *              RCL dx, 1
- *          =>  dx:ax = dx:ax << 1
- *      Found in Borland Turbo C code for long variable shift left.
- ****************************************************************************/
-bool Idiom12::match(iICODE pIcode)
-{
-    if(distance(pIcode,m_end)<2)
-        return false;
-    m_icodes[0]=pIcode++;
-    m_icodes[1]=pIcode++;
-    if (m_icodes[0]->ll()->testFlags(I) && (m_icodes[0]->ll()->src().getImm2() == 1))
-        if (m_icodes[1]->ll()->match(iRCL,I) && (m_icodes[1]->ll()->src().getImm2() == 1))
-            return true;
-    return false;
-}
-
-int Idiom12::action()
-{
-    int idx;
-    COND_EXPR *rhs,*lhs,*expr;
-    eReg regH,regL;
-    regL=m_icodes[0]->ll()->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);
-    m_icodes[0]->setRegDU( regH, USE_DEF);
-    rhs = COND_EXPR::idKte (1, 2);
-    expr = COND_EXPR::boolOp (lhs, rhs, SHL);
-    m_icodes[0]->setAsgn(lhs, expr);
-    m_icodes[1]->invalidate();
-    return 2;
-}
-
-/*****************************************************************************
- * idiom9 - Shift right by 1 (unsigned long ops)
- *      SHR reg, 1
- *      RCR reg, 1
- *      Eg:     SHR dx, 1
- *              RCR ax, 1
- *          =>  dx:ax = dx:ax >> 1   (dx:ax are unsigned long)
- *      Found in Microsoft C code for long unsigned variable shift right.
- ****************************************************************************/
-bool Idiom9::match(iICODE pIcode)
-{
-    if(distance(pIcode,m_end)<2)
-        return false;
-    m_icodes[0]=pIcode++;
-    m_icodes[1]=pIcode++;
-    if (m_icodes[0]->ll()->testFlags(I) && (m_icodes[0]->ll()->src().getImm2() == 1))
-        if (m_icodes[1]->ll()->match(iRCR,I) && (m_icodes[1]->ll()->src().getImm2() == 1))
-            return true;
-    return false;
-}
-
-int Idiom9::action()
-{
-    int idx;
-    COND_EXPR *rhs,*lhs,*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);
-    m_icodes[0]->setRegDU(regL, USE_DEF);
-    rhs = COND_EXPR::idKte (1, 2);
-    expr = COND_EXPR::boolOp (lhs, rhs, SHR);
-    m_icodes[0]->setAsgn(lhs, expr);
-    m_icodes[1]->invalidate();
-    return 2;
-}

+ 0 - 134
src/idioms/xor_idioms.cpp

@@ -1,134 +0,0 @@
-#include "dcc.h"
-#include "xor_idioms.h"
-using namespace std;
-
-/*****************************************************************************
- * idiom21 - Assign long kte with high part zero
- *		XOR regH, regH
- *		MOV regL, kte
- *		=> regH:regL = kte
- *		Eg: XOR dx, dx
- *			MOV ax, 3
- *			=> dx:ax = 3
- *		Note: only the following valid combinations are available:
- *				dx:ax
- *				cx:bx
- *		Found in Borland Turbo C code.
- ****************************************************************************/
-bool Idiom21::match (iICODE picode)
-{
-    LLOperand *dst, *src;
-    if(distance(picode,m_end)<2)
-        return false;
-    m_icodes[0]=picode++;
-    m_icodes[1]=picode++;
-
-    if (not m_icodes[1]->ll()->testFlags(I))
-        return false;
-
-    dst = &m_icodes[0]->ll()->dst;
-    src = &m_icodes[0]->ll()->src();
-    if ((dst->regi == src->getReg2()) && (dst->getReg2() > 0) && (dst->getReg2() < INDEX_BX_SI))
-    {
-        if ((dst->getReg2() == rDX) && m_icodes[1]->ll()->match(rAX))
-            return true;
-        if ((dst->getReg2() == rCX) && m_icodes[1]->ll()->match(rBX))
-            return true;
-    }
-    return false;
-}
-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);
-    m_icodes[0]->setAsgn(lhs, rhs);
-    m_icodes[0]->du.use = 0;		/* clear register used in iXOR */
-    m_icodes[1]->invalidate();
-    return 2;
-}
-
-/*****************************************************************************
- * idiom7 - Assign zero
- *      XOR reg/stackOff, reg/stackOff
- *      Eg:     XOR ax, ax
- *          =>  ax = 0
- *      Found in Borland Turbo C and Microsoft C code.
- ****************************************************************************/
-bool Idiom7::match(iICODE picode)
-{
-    if(picode==m_end)
-        return false;
-    const LLOperand *dst, *src;
-    m_icode=picode;
-    dst = &picode->ll()->dst;
-    src = &picode->ll()->src();
-    if (dst->regi == 0)                 /* global variable */
-    {
-        if ((dst->segValue == src->segValue) && (dst->off == src->off))
-            return true;
-    }
-    else if (dst->regi < INDEX_BX_SI)     /* register */
-    {
-        if (dst->regi == src->regi)
-            return true;
-    }
-    else if ((dst->off) && (dst->seg == rSS) && (dst->regi == INDEX_BP)) /* offset from BP */
-    {
-        if ((dst->off == src->off) && (dst->seg == src->seg) && (dst->regi == src->regi))
-            return true;
-    }
-    return false;
-}
-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);
-    m_icode->du.use = 0;    /* clear register used in iXOR */
-    m_icode->ll()->setFlags(I);
-    return 1;
-}
-
-
-/*****************************************************************************
- * idiom10 - Jump if not equal to 0
- *      OR  reg, reg
- *      JNE labX
- *      Eg:     OR  ax, ax
- *              JNE labX
- *      => CMP reg 0
- *		   JNE labX
- *		This instruction is NOT converted into the equivalent high-level
- *		instruction "HLI_JCOND (reg != 0) labX" because we do not know yet if
- *		it forms part of a long register conditional test.  It is therefore
- *		modified to simplify the analysis.
- *      Found in Borland Turbo C.
- ****************************************************************************/
-bool Idiom10::match(iICODE pIcode)
-{
-    if(distance(pIcode,m_end)<2)
-        return false;
-    m_icodes[0]=pIcode++;
-    m_icodes[1]=pIcode++;
-    /* Check OR reg, reg */
-    if (not m_icodes[0]->ll()->testFlags(I)  &&
-            m_icodes[0]->ll()->src().isReg() &&
-            (m_icodes[0]->ll()->src().getReg2() == m_icodes[0]->ll()->dst.getReg2()))
-        if (m_icodes[1]->ll()->match(iJNE)) //.conditionalJump()
-        {
-            return true;
-        }
-    return false;
-}
-
-int Idiom10::action()
-{
-    m_icodes[0]->ll()->set(iCMP,I);
-    m_icodes[0]->ll()->replaceSrc(LLOperand::CreateImm2(0));
-    m_icodes[0]->du.def = 0;
-    m_icodes[0]->du1.numRegsDef = 0;
-    return 2;
-
-}

+ 235 - 232
src/locident.cpp

@@ -5,324 +5,330 @@
  * (C) Cristina Cifuentes
  */
 
-#include <cstring>
-#include "locident.h"
 #include "dcc.h"
-bool LONGID_TYPE::srcDstRegMatch(iICODE a, iICODE b) const
-{
-    return (a->ll()->src().getReg2()==l) and (b->ll()->dst.getReg2()==h);
-}
-	
+#include <string.h>
 
-ID::ID() : type(TYPE_UNKNOWN),illegal(false),loc(STK_FRAME),hasMacro(false)
-{
-    name[0]=0;
-    macro[0]=0;
-    memset(&id,0,sizeof(id));
-}
-ID::ID(hlType t, frameType f) : type(t),illegal(false),hasMacro(false)
+
+#define LOCAL_ID_DELTA  25
+#define IDX_ARRAY_DELTA  5
+
+
+void insertIdx (IDX_ARRAY *list, Int idx)
+/* Inserts the new index at the end of the list.  If there is need to
+ * allocate extra storage, it does so.  */
 {
-    name[0]=0;
-    macro[0]=0;
-    memset(&id,0,sizeof(id));
-    loc=f;
+    if (list->csym == list->alloc)
+    {
+        list->alloc += IDX_ARRAY_DELTA;
+		list->idx = (Int*)reallocVar(list->idx, list->alloc * sizeof(Int));
+		memset (&list->idx[list->csym], 0, IDX_ARRAY_DELTA * sizeof(Int));
+    }
+    list->idx[list->csym] = idx;
+    list->csym++;
 }
 
 
-#define LOCAL_ID_DELTA  25
-#define IDX_ARRAY_DELTA  5
+static boolT inList (IDX_ARRAY *list, Int idx)
+/* Returns whether idx is in the list array or not */
+{ Int i;
+
+    for (i = 0; i < list->csym; i++)
+        if (list->idx[i] == idx)
+            return (TRUE);
+    return (FALSE);
+}
 
+
+static void newIdent (LOCAL_ID *locSym, hlType t, frameType f)
 /* Creates a new identifier node of type t and returns it.
  * Arguments: locSym : local long symbol table
  *            t : type of LONG identifier
  *            f : frame where this variable is located
  *            ix : index into icode array where this var is used */
-void LOCAL_ID::newIdent(hlType t, frameType f)
 {
-    ID newid(t,f);
-    id_arr.push_back(newid);
+    if (locSym->csym == locSym->alloc)
+    {
+        locSym->alloc += LOCAL_ID_DELTA;
+		locSym->id = (ID*)reallocVar(locSym->id, locSym->alloc * sizeof(ID));
+        memset (&locSym->id[locSym->csym], 0, LOCAL_ID_DELTA * sizeof(ID));
+    }
+    locSym->id[locSym->csym].type = t;
+    locSym->id[locSym->csym].loc = f;
+    locSym->csym++;
 }
 
 
+Int newByteWordRegId (LOCAL_ID *locSym, hlType t, byte regi)
 /* Creates a new register identifier node of TYPE_BYTE_(UN)SIGN or
  * TYPE_WORD_(UN)SIGN type.  Returns the index to this new entry.       */
-int LOCAL_ID::newByteWordReg(hlType t, eReg regi)
-{
-    int idx;
+{ Int idx;
 
     /* Check for entry in the table */
-    auto found=std::find_if(id_arr.begin(),id_arr.end(),[t,regi](ID &el)->bool {
-            return ((el.type == t) && (el.id.regi == regi));
-        });
-    if(found!=id_arr.end())
-        return found-id_arr.begin();
+    for (idx = 0; idx < locSym->csym; idx++)
+    {
+        if ((locSym->id[idx].type == t) &&
+            (locSym->id[idx].id.regi == regi))
+            return (idx);
+    }
+
     /* Not in table, create new identifier */
-    newIdent (t, REG_FRAME);
-    idx = id_arr.size() - 1;
-    id_arr[idx].id.regi = regi;
+    newIdent (locSym, t, REG_FRAME);
+    idx = locSym->csym - 1;
+    locSym->id[idx].id.regi = regi;
     return (idx);
 }
 
 
+static void flagByteWordId (LOCAL_ID *locsym, Int off)
 /* Flags the entry associated with the offset off to illegal, as this
- * offset is part of a long stack variable.
+ * offset is part of a long stack variable. 
  * Note: it is easier enough to remove this entry by moving the rest of
- *       the array 1 position.  The problem is that indexes into this
+ *       the array 1 position.  The problem is that indexes into this 
  *       array have already been saved in several positions; therefore,
  *       flagging this entry as illegal is all that can be done.    */
-void LOCAL_ID::flagByteWordId (int off)
-{
-    int idx;
-    auto found=std::find_if(id_arr.begin(),id_arr.end(),[off](ID &en)->bool {
-     //if (((en.type == TYPE_WORD_SIGN) || (en.type == TYPE_BYTE_SIGN)) &&
-     if ((en.typeBitsize()<=16) &&
-         (en.id.bwId.off == off) && (en.id.bwId.regOff == 0))
-        return true;
-     return false;
-    });
-    if(found==id_arr.end())
+{ Int idx;
+
+    for (idx = 0; idx < locsym->csym; idx++)
     {
-        printf("No entry to flag as invalid in LOCAL_ID::flagByteWordId \n");
-        return;
+        if (((locsym->id[idx].type == TYPE_WORD_SIGN) ||
+             (locsym->id[idx].type == TYPE_BYTE_SIGN)) &&
+            (locsym->id[idx].id.bwId.off == off) &&
+            (locsym->id[idx].id.bwId.regOff == 0))
+        {
+            locsym->id[idx].illegal = TRUE;
+            break;
+        }
     }
-    found->illegal = true;
 }
 
+
+Int newByteWordStkId (LOCAL_ID *locSym, hlType t, Int off, byte regOff) 
 /* Creates a new stack identifier node of TYPE_BYTE_(UN)SIGN or
  * TYPE_WORD_(UN)SIGN type.  Returns the index to this new entry.       */
-int LOCAL_ID::newByteWordStk(hlType t, int off, uint8_t regOff)
-{
-    int idx;
+{ Int idx;
 
     /* Check for entry in the table */
-    auto found=std::find_if(id_arr.begin(),id_arr.end(),[off,regOff](ID &el)->bool {
-            if ((el.id.bwId.off == off) && (el.id.bwId.regOff == regOff))
-                return true;
-            return false;
-        });
-    if(found!=id_arr.end())
-        return found-id_arr.begin(); //return Index to found element
+    for (idx = 0; idx < locSym->csym; idx++)
+    {
+        if ((locSym->id[idx].id.bwId.off == off) &&
+            (locSym->id[idx].id.bwId.regOff == regOff))
+            return (idx);
+    }
 
     /* Not in table, create new identifier */
-    newIdent (t, STK_FRAME);
-    idx = id_arr.size() - 1;
-    id_arr[idx].id.bwId.regOff = regOff;
-    id_arr[idx].id.bwId.off = off;
+    newIdent (locSym, t, STK_FRAME);
+    idx = locSym->csym - 1;
+    locSym->id[idx].id.bwId.regOff = regOff;
+    locSym->id[idx].id.bwId.off = off;
     return (idx);
 }
 
 
+Int newIntIdxId (LOCAL_ID *locSym, int16 seg, int16 off, byte regi, 
+                 Int ix, hlType t)
 /* Checks if the entry exists in the locSym, if so, returns the idx to this
- * entry; otherwise creates a new global identifier node of type
- * TYPE_WORD_(UN)SIGN and returns the index to this new entry.
+ * entry; otherwise creates a new global identifier node of type 
+ * TYPE_WORD_(UN)SIGN and returns the index to this new entry.  
  * Arguments: locSym : ptr to the local symbol table
  *            seg: segment value for global variable
  *            off: offset from segment
  *            regi: indexed register into global variable
  *            ix: index into icode array
  *            t: HIGH_LEVEL type            */
-int LOCAL_ID::newIntIdx(int16_t seg, int16_t off, eReg regi, int ix, hlType t)
-{
-    int idx;
+{ Int idx;
 
     /* Check for entry in the table */
-    for (idx = 0; idx < id_arr.size(); idx++)
+    for (idx = 0; idx < locSym->csym; idx++)
     {
         if (/*(locSym->id[idx].type == t) &&   Not checking type */
-            (id_arr[idx].id.bwGlb.seg == seg) &&
-            (id_arr[idx].id.bwGlb.off == off) &&
-            (id_arr[idx].id.bwGlb.regi == regi))
+            (locSym->id[idx].id.bwGlb.seg == seg) &&  
+            (locSym->id[idx].id.bwGlb.off == off) &&  
+            (locSym->id[idx].id.bwGlb.regi == regi))
             return (idx);
     }
 
     /* Not in the table, create new identifier */
-    newIdent (t, GLB_FRAME);
-    idx = id_arr.size() - 1;
-    id_arr[idx].id.bwGlb.seg = seg;
-    id_arr[idx].id.bwGlb.off = off;
-    id_arr[idx].id.bwGlb.regi = regi;
+    newIdent (locSym, t, GLB_FRAME);
+    idx = locSym->csym - 1;
+    locSym->id[idx].id.bwGlb.seg = seg;
+    locSym->id[idx].id.bwGlb.off = off;
+    locSym->id[idx].id.bwGlb.regi = regi;
     return (idx);
 }
 
 
+Int newLongRegId (LOCAL_ID *locSym, hlType t, byte regH, byte regL, Int ix)
 /* Checks if the entry exists in the locSym, if so, returns the idx to this
- * entry; otherwise creates a new register identifier node of type
+ * entry; otherwise creates a new register identifier node of type 
  * TYPE_LONG_(UN)SIGN and returns the index to this new entry.  */
-int LOCAL_ID::newLongReg(hlType t, eReg regH, eReg regL, iICODE ix_)
-{
-    size_t idx;
-    //iICODE ix_;
+{ Int idx;
+
     /* Check for entry in the table */
-    for (idx = 0; idx < id_arr.size(); idx++)
+    for (idx = 0; idx < locSym->csym; idx++)
     {
-        ID &entry(id_arr[idx]);
         if (/*(locSym->id[idx].type == t) &&   Not checking type */
-            (entry.id.longId.h == regH) &&
-            (entry.id.longId.l == regL))
+            (locSym->id[idx].id.longId.h == regH) &&  
+            (locSym->id[idx].id.longId.l == regL))
         {
             /* Check for occurrence in the list */
-            if (entry.idx.inList(ix_))
+            if (inList (&locSym->id[idx].idx, ix)) 
                 return (idx);
             else
             {
                 /* Insert icode index in list */
-                entry.idx.push_back(ix_);
-                //entry.idx.insert(ix_);
+                insertIdx (&locSym->id[idx].idx, ix);
                 return (idx);
             }
         }
     }
 
     /* Not in the table, create new identifier */
-    newIdent (t, REG_FRAME);
-    id_arr[id_arr.size()-1].idx.push_back(ix_);//insert(ix_);
-    idx = id_arr.size() - 1;
-    id_arr[idx].id.longId.h = regH;
-    id_arr[idx].id.longId.l = regL;
+    newIdent (locSym, t, REG_FRAME);
+    insertIdx (&locSym->id[locSym->csym-1].idx, ix);
+    idx = locSym->csym - 1;
+    locSym->id[idx].id.longId.h = regH;
+    locSym->id[idx].id.longId.l = regL;
     return (idx);
 }
-/* Returns an identifier conditional expression node of type TYPE_LONG or
- * TYPE_WORD_SIGN	*/
-COND_EXPR * LOCAL_ID::createId(const ID *retVal, iICODE ix_)
-{
-    return COND_EXPR::idID(retVal,this,ix_);
-}
 
+
+static Int newLongGlbId (LOCAL_ID *locSym, int16 seg, int16 offH, int16 offL,
+                         Int ix, hlType t)
 /* Checks if the entry exists in the locSym, if so, returns the idx to this
- * entry; otherwise creates a new global identifier node of type
+ * entry; otherwise creates a new global identifier node of type 
  * TYPE_LONG_(UN)SIGN and returns the index to this new entry.  */
-int LOCAL_ID::newLongGlb(int16_t seg, int16_t offH, int16_t offL,hlType t)
-{
-    size_t idx;
+{ Int idx;
 
     /* Check for entry in the table */
-    for (idx = 0; idx < id_arr.size(); idx++)
+    for (idx = 0; idx < locSym->csym; idx++)
     {
         if (/*(locSym->id[idx].type == t) &&   Not checking type */
-            (id_arr[idx].id.longGlb.seg == seg) &&
-            (id_arr[idx].id.longGlb.offH == offH) &&
-            (id_arr[idx].id.longGlb.offL == offL))
+            (locSym->id[idx].id.longGlb.seg == seg) &&  
+            (locSym->id[idx].id.longGlb.offH == offH) &&  
+            (locSym->id[idx].id.longGlb.offL == offL))
             return (idx);
     }
 
     /* Not in the table, create new identifier */
-    newIdent (t, GLB_FRAME);
-    idx = id_arr.size() - 1;
-    id_arr[idx].id.longGlb.seg = seg;
-    id_arr[idx].id.longGlb.offH = offH;
-    id_arr[idx].id.longGlb.offL = offL;
+    newIdent (locSym, t, GLB_FRAME);
+    idx = locSym->csym - 1;
+    locSym->id[idx].id.longGlb.seg = seg;
+    locSym->id[idx].id.longGlb.offH = offH;
+    locSym->id[idx].id.longGlb.offL = offL;
     return (idx);
 }
 
 
+static Int newLongIdxId (LOCAL_ID *locSym, int16 seg, int16 offH, int16 offL,
+                         byte regi, Int ix, hlType t)
 /* Checks if the entry exists in the locSym, if so, returns the idx to this
- * entry; otherwise creates a new global identifier node of type
+ * entry; otherwise creates a new global identifier node of type 
  * TYPE_LONG_(UN)SIGN and returns the index to this new entry.  */
-int LOCAL_ID::newLongIdx( int16_t seg, int16_t offH, int16_t offL,uint8_t regi, hlType t)
-{
-    size_t idx;
+{ Int idx;
 
     /* Check for entry in the table */
-    for (idx = 0; idx < id_arr.size(); idx++)
+    for (idx = 0; idx < locSym->csym; idx++)
     {
         if (/*(locSym->id[idx].type == t) &&   Not checking type */
-            (id_arr[idx].id.longGlb.seg == seg) &&
-            (id_arr[idx].id.longGlb.offH == offH) &&
-            (id_arr[idx].id.longGlb.offL == offL) &&
-            (id_arr[idx].id.longGlb.regi == regi))
+            (locSym->id[idx].id.longGlb.seg == seg) &&  
+            (locSym->id[idx].id.longGlb.offH == offH) &&  
+            (locSym->id[idx].id.longGlb.offL == offL) &&  
+            (locSym->id[idx].id.longGlb.regi == regi))
             return (idx);
     }
 
     /* Not in the table, create new identifier */
-    newIdent (t, GLB_FRAME);
-    idx = id_arr.size() - 1;
-    id_arr[idx].id.longGlb.seg = seg;
-    id_arr[idx].id.longGlb.offH = offH;
-    id_arr[idx].id.longGlb.offL = offL;
-    id_arr[idx].id.longGlb.regi = regi;
+    newIdent (locSym, t, GLB_FRAME);
+    idx = locSym->csym - 1;
+    locSym->id[idx].id.longGlb.seg = seg;
+    locSym->id[idx].id.longGlb.offH = offH;
+    locSym->id[idx].id.longGlb.offL = offL;
+    locSym->id[idx].id.longGlb.regi = regi;
     return (idx);
 }
 
 
+Int newLongStkId (LOCAL_ID *locSym, hlType t, Int offH, Int offL)
 /* Creates a new stack identifier node of type TYPE_LONG_(UN)SIGN.
  * Returns the index to this entry. */
-int LOCAL_ID::newLongStk(hlType t, int offH, int offL)
-{
-    size_t idx;
+{ Int idx;
 
     /* Check for entry in the table */
-    for (idx = 0; idx < id_arr.size(); idx++)
+    for (idx = 0; idx < locSym->csym; idx++)
     {
-        if ((id_arr[idx].type == t) &&
-            (id_arr[idx].id.longStkId.offH == offH) &&
-            (id_arr[idx].id.longStkId.offL == offL))
+        if ((locSym->id[idx].type == t) && 
+            (locSym->id[idx].id.longStkId.offH == offH) &&  
+            (locSym->id[idx].id.longStkId.offL == offL))
             return (idx);
     }
 
-    /* Not in the table; flag as invalid offH and offL */
-    flagByteWordId (offH);
-    flagByteWordId (offL);
+    /* Not in the table; flag as invalid offH and offL */ 
+    flagByteWordId (locSym, offH);
+    flagByteWordId (locSym, offL); 
 
     /* Create new identifier */
-    newIdent (t, STK_FRAME);
-    idx = id_arr.size() - 1;
-    id_arr[idx].id.longStkId.offH = offH;
-    id_arr[idx].id.longStkId.offL = offL;
+    newIdent (locSym, t, STK_FRAME);
+    idx = locSym->csym - 1;
+    locSym->id[idx].id.longStkId.offH = offH;
+    locSym->id[idx].id.longStkId.offL = offL;
     return (idx);
 }
 
 
-/* Returns the index to an appropriate long identifier.
+Int newLongId (LOCAL_ID *locSym, opLoc sd, PICODE pIcode, hlFirst f, Int ix,
+               operDu du, Int off)
+/* Returns the index to an appropriate long identifier. 
  * Note: long constants should be checked first and stored as a long integer
  *       number in an expression record.    */
-int LOCAL_ID::newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix,operDu du, LLInst &atOffset)
-{
-    size_t idx;
-    const LLOperand *pmH, *pmL;
-	LLInst &p_ll(*pIcode->ll());
+{ Int idx;
+  PMEM pmH, pmL;
+
     if (f == LOW_FIRST)
     {
-        pmL = p_ll.get(sd);
-        pmH = atOffset.get(sd);
+        pmL = (sd == SRC) ? &pIcode->ic.ll.src : &pIcode->ic.ll.dst;
+        pmH = (sd == SRC) ? &(pIcode+off)->ic.ll.src : &(pIcode+off)->ic.ll.dst;
     }
     else        /* HIGH_FIRST */
     {
-        pmL = atOffset.get(sd);
-        pmH = p_ll.get(sd);
+        pmH = (sd == SRC) ? &pIcode->ic.ll.src : &pIcode->ic.ll.dst;
+        pmL = (sd == SRC) ? &(pIcode+off)->ic.ll.src : &(pIcode+off)->ic.ll.dst;
     }
 
     if (pmL->regi == 0)                                 /* global variable */
-        idx = newLongGlb(pmH->segValue, pmH->off, pmL->off, TYPE_LONG_SIGN);
+        idx = newLongGlbId (locSym, pmH->segValue, pmH->off, pmL->off, ix, 
+                            TYPE_LONG_SIGN); 
 
-    else if (pmL->regi < INDEX_BX_SI)                     /* register */
+    else if (pmL->regi < INDEXBASE)                     /* register */
     {
-        idx = newLongReg(TYPE_LONG_SIGN, pmH->regi, pmL->regi, ix);
+        idx = newLongRegId (locSym, TYPE_LONG_SIGN, pmH->regi, pmL->regi, ix);
         if (f == HIGH_FIRST)
-            pIcode->setRegDU( pmL->regi, du);   /* low part */
+            setRegDU (pIcode, pmL->regi, du);   /* low part */
         else
-            pIcode->setRegDU( pmH->regi, du);   /* high part */
+            setRegDU (pIcode, pmH->regi, du);   /* high part */
     }
 
     else if (pmL->off) {                                /* offset */
-        if ((pmL->seg == rSS) && (pmL->regi == INDEX_BP)) /* idx on bp */
-            idx = newLongStk(TYPE_LONG_SIGN, pmH->off, pmL->off);
-        else if ((pmL->seg == rDS) && (pmL->regi == INDEX_BX))   /* bx */
+        if ((pmL->seg == rSS) && (pmL->regi == INDEXBASE + 6)) /* idx on bp */
+            idx = newLongStkId (locSym, TYPE_LONG_SIGN, pmH->off, pmL->off);
+        else if ((pmL->seg == rDS) && (pmL->regi == INDEXBASE + 7))   /* bx */
         {                                       /* glb var indexed on bx */
-            printf("Bx indexed global, BX is an unused parameter to newLongIdx\n");
-            idx = newLongIdx(pmH->segValue, pmH->off, pmL->off,rBX,TYPE_LONG_SIGN);
-            pIcode->setRegDU( rBX, eUSE);
+            idx = newLongIdxId (locSym, pmH->segValue, pmH->off, pmL->off,
+                                rBX, ix, TYPE_LONG_SIGN); 
+            setRegDU (pIcode, rBX, E_USE);
         }
         else                                            /* idx <> bp, bx */
             printf ("long not supported, idx <> bp\n");
     }
 
-    else  /* (pm->regi >= INDEXBASE && pm->off = 0) => indexed && no off */
+    else  /* (pm->regi >= INDEXBASE && pm->off = 0) => indexed && no off */ 
         printf ("long not supported, idx && no off\n");
 
     return (idx);
 }
 
 
+boolT checkLongEq (LONG_STKID_TYPE longId, PICODE pIcode, Int i, Int idx, 
+                  PPROC pProc, COND_EXPR **rhs, COND_EXPR **lhs, Int off)
 /* Checks whether the long stack identifier is equivalent to the source or
  * destination operands of pIcode and pIcode+1 (ie. these are LOW_LEVEL
  * icodes at present).  If so, returns the rhs and lhs of this instruction.
@@ -330,38 +336,36 @@ int LOCAL_ID::newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix,operDu du, L
  *            pIcode    : ptr to first LOW_LEVEL icode instruction
  *            i         : idx into local identifier table for longId
  *            idx       : idx into icode array
- *            pProc     : ptr to current procedure record
+ *            pProc     : ptr to current procedure record 
  *            rhs, lhs  : return expressions if successful. */
-boolT checkLongEq (LONG_STKID_TYPE longId, iICODE pIcode, int i, Function * pProc, Assignment &asgn, LLInst &atOffset)
-{
-    /* pointers to LOW_LEVEL icodes */
-    const LLOperand *pmHdst, *pmLdst, *pmHsrc, *pmLsrc;
+{ PMEM pmHdst, pmLdst, pmHsrc, pmLsrc;  /* pointers to LOW_LEVEL icodes */
 
-    pmHdst = &pIcode->ll()->dst;
-    pmLdst = &atOffset.dst;
-    pmHsrc = &pIcode->ll()->src();
-    pmLsrc = &atOffset.src();
+    pmHdst = &pIcode->ic.ll.dst;
+    pmLdst = &(pIcode+off)->ic.ll.dst;
+    pmHsrc = &pIcode->ic.ll.src;
+    pmLsrc = &(pIcode+off)->ic.ll.src;
 
     if ((longId.offH == pmHdst->off) && (longId.offL == pmLdst->off))
     {
-        asgn.lhs = COND_EXPR::idLongIdx (i);
-
-        if ( not pIcode->ll()->testFlags(NO_SRC) )
-        {
-            asgn.rhs = COND_EXPR::idLong (&pProc->localId, SRC, pIcode, HIGH_FIRST, pIcode, eUSE, atOffset);
-        }
-        return true;
+        *lhs = idCondExpLongIdx (i);
+        if ((pIcode->ic.ll.flg & NO_SRC) != NO_SRC)
+            *rhs = idCondExpLong (&pProc->localId, SRC, pIcode, HIGH_FIRST, 
+                                  idx, E_USE, off);
+        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);
-        return true;
+        *lhs = idCondExpLong (&pProc->localId, DST, pIcode, HIGH_FIRST, idx,
+							  E_DEF, off);
+        *rhs = idCondExpLongIdx (i);
+        return (TRUE);
     }
-    return false;
+    return (FALSE);
 }
 
 
+boolT checkLongRegEq (LONGID_TYPE longId, PICODE pIcode, Int i, Int idx, 
+                  PPROC pProc, COND_EXPR **rhs, COND_EXPR **lhs, Int off)
 /* Checks whether the long stack identifier is equivalent to the source or
  * destination operands of pIcode and pIcode+1 (ie. these are LOW_LEVEL
  * icodes at present).  If so, returns the rhs and lhs of this instruction.
@@ -369,47 +373,42 @@ boolT checkLongEq (LONG_STKID_TYPE longId, iICODE pIcode, int i, Function * pPro
  *            pIcode    : ptr to first LOW_LEVEL icode instruction
  *            i         : idx into local identifier table for longId
  *            idx       : idx into icode array
- *            pProc     : ptr to current procedure record
+ *            pProc     : ptr to current procedure record 
  *            rhs, lhs  : return expressions if successful. */
-boolT checkLongRegEq (LONGID_TYPE longId, iICODE pIcode, int i,
-                      Function * pProc, Assignment &asgn, LLInst &atOffset)
-{
-    /* pointers to LOW_LEVEL icodes */
-    const LLOperand *pmHdst, *pmLdst, *pmHsrc, *pmLsrc;
+{ PMEM pmHdst, pmLdst, pmHsrc, pmLsrc;  /* pointers to LOW_LEVEL icodes */
 
-    pmHdst = &pIcode->ll()->dst;
-    pmLdst = &atOffset.dst;
-    pmHsrc = &pIcode->ll()->src();
-    pmLsrc = &atOffset.src();
+    pmHdst = &pIcode->ic.ll.dst;
+    pmLdst = &(pIcode+off)->ic.ll.dst;
+    pmHsrc = &pIcode->ic.ll.src;
+    pmLsrc = &(pIcode+off)->ic.ll.src;
 
     if ((longId.h == pmHdst->regi) && (longId.l == pmLdst->regi))
     {
-        asgn.lhs = COND_EXPR::idLongIdx (i);
-        if ( not pIcode->ll()->testFlags(NO_SRC) )
-        {
-            asgn.rhs = COND_EXPR::idLong (&pProc->localId, SRC, pIcode, HIGH_FIRST,  pIcode, eUSE, atOffset);
-        }
-        return true;
+        *lhs = idCondExpLongIdx (i);
+        if ((pIcode->ic.ll.flg & NO_SRC) != NO_SRC)
+            *rhs = idCondExpLong (&pProc->localId, SRC, pIcode, HIGH_FIRST, 
+                                  idx, E_USE, off);
+        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);
-        return true;
+        *lhs = idCondExpLong (&pProc->localId, DST, pIcode, HIGH_FIRST, idx,
+							  E_DEF, off);
+        *rhs = idCondExpLongIdx (i);
+        return (TRUE);
     }
-    return false;
+    return (FALSE);
 }
 
 
 
+byte otherLongRegi (byte regi, Int idx, LOCAL_ID *locTbl)
 /* Given an index into the local identifier table for a long register
  * variable, determines whether regi is the high or low part, and returns
  * the other part   */
-eReg otherLongRegi (eReg regi, int idx, LOCAL_ID *locTbl)
-{
-    ID *id;
+{ ID *id;
 
-    id = &locTbl->id_arr[idx];
+    id = &locTbl->id[idx];
     if ((id->loc == REG_FRAME) && ((id->type == TYPE_LONG_SIGN) ||
         (id->type == TYPE_LONG_UNSIGN)))
     {
@@ -418,33 +417,37 @@ eReg otherLongRegi (eReg regi, int idx, LOCAL_ID *locTbl)
         else if (id->id.longId.l == regi)
             return (id->id.longId.h);
     }
-    return rUNDEF;	// Cristina: please check this!
+    return 0;			// Cristina: please check this!
 }
 
 
+void propLongId (LOCAL_ID *locid, byte regL, byte regH, char *name)
 /* Checks if the registers regL and regH have been used independently in
  * the local identifier table.  If so, macros for these registers are
- * placed in the local identifier table, as these registers belong to a
+ * placed in the local identifier table, as these registers belong to a 
  * long register identifier.	*/
-void LOCAL_ID::propLongId (uint8_t regL, uint8_t regH, const char *name)
-{
-    for (ID &rid : id_arr)
-    {
-        if (rid.typeBitsize()!=16)
-            continue;
-        if ( (rid.id.regi != regL) and (rid.id.regi != regH) )
-            continue;
-        // otherwise at least 1 is ok
-        rid.name = name;
-        rid.hasMacro = true;
-        rid.illegal = true;
-        if (rid.id.regi == regL)
-        {
-            strcpy (rid.macro, "LO");
-            }
-        else // if (rid.id.regi == regH)
-            {
-            strcpy (rid.macro, "HI");
-        }
-    }
+{ Int i;
+  ID *id;
+
+	for (i = 0; i < locid->csym; i++)
+	{
+		id = &locid->id[i];
+		if ((id->type == TYPE_WORD_SIGN) || (id->type == TYPE_WORD_UNSIGN)) 
+		{
+			if (id->id.regi == regL)
+			{
+				strcpy (id->name, name);
+				strcpy (id->macro, "LO");
+				id->hasMacro = TRUE;
+				id->illegal = TRUE;
+			}
+			else if (id->id.regi == regH)
+			{
+				strcpy (id->name, name);
+				strcpy (id->macro, "HI");
+				id->hasMacro = TRUE;
+				id->illegal = TRUE;
+			}
+		}	
+	}
 }

+ 0 - 111
src/machine_x86.cpp

@@ -1,111 +0,0 @@
-#include <cassert>
-#include "machine_x86.h"
-// Index registers **** temp solution
-static const std::string regNames[] = {
-    "undef",
-    "ax", "cx", "dx", "bx",
-    "sp", "bp", "si", "di",
-    "es", "cs", "ss", "ds",
-    "al", "cl", "dl", "bl",
-    "ah", "ch", "dh", "bh",
-    "tmp",
-    "bx+si", "bx+di", "bp+si", "bp+di",
-    "si", "di", "bp", "bx"
-};
-
-/* uint8_t and uint16_t registers */
-Machine_X86::Machine_X86()
-{
-    static_assert((sizeof(regNames)/sizeof(std::string))==LAST_REG,
-            "Reg count not equal number of strings");
-}
-
-const std::string &Machine_X86::regName(eReg r)
-{
-    assert(r<(sizeof(regNames)/sizeof(std::string)));
-    return regNames[r];
-}
-
-static const std::string szOps[] =
-{
-    "CBW",  "AAA",      "AAD",      "AAM",      "AAS",      "ADC",  "ADD",  "AND",
-    "BOUND","CALL",     "CALL",     "CLC",      "CLD",      "CLI",  "CMC",  "CMP",
-    "CMPS", "REPNE CMPS","REPE CMPS","DAA",     "DAS",      "DEC",  "DIV",  "ENTER",
-    "ESC",  "HLT",      "IDIV",     "IMUL",     "IN",       "INC",  "INS",  "REP INS",
-    "INT",  "IRET",     "JB",       "JBE",      "JAE",      "JA",   "JE",   "JNE",
-    "JL",   "JGE",      "JLE",      "JG",       "JS",       "JNS",  "JO",   "JNO",
-    "JP",   "JNP",      "JCXZ",     "JMP",      "JMP",      "LAHF", "LDS",  "LEA",
-    "LEAVE","LES",      "LOCK",     "LODS",     "REP LODS", "LOOP", "LOOPE","LOOPNE",
-    "MOV",  "MOVS",     "REP MOVS", "MUL",      "NEG",      "NOT",  "OR",   "OUT",
-    "OUTS", "REP OUTS", "POP",      "POPA",     "POPF",     "PUSH", "PUSHA","PUSHF",
-    "RCL",  "RCR",      "ROL",      "ROR",      "RET",      "RETF", "SAHF", "SAR",
-    "SHL",  "SHR",      "SBB",      "SCAS",     "REPNE SCAS","REPE SCAS",   "CWD",  "STC",
-    "STD",  "STI",      "STOS",     "REP STOS", "SUB",      "TEST", "WAIT", "XCHG",
-    "XLAT", "XOR",      "INTO",     "NOP",      "REPNE",    "REPE",	"MOD"
-};
-/* The following opcodes are for mod != 3 */
-static std::string szFlops1[] =
-{
-    /* 0        1        2       3        4        5        6        7  */
-    "FADD",  "FMUL",  "FCOM", "FCOMP", "FSUB",  "FSUBR", "FDIV",  "FDIVR",  /* 00 */
-    "FLD",   "???",   "FST",  "???",   "FLDENV","FLDCW", "FSTENV","FSTSW",  /* 08 */
-    "FIADD", "FIMUL", "FICOM","FICOMP","FISUB", "FISUBR","FIDIV", "FIDIVR", /* 10 */
-    "FILD",  "???",   "FIST", "FISTP", "???",   "???",   "???",   "FSTP",   /* 18 */
-    "FADD",  "FMUL",  "FCOM", "FCOMP", "FSUB",  "FSUBR", "FDIV",  "FDIVR",  /* 20 */
-    "FLD",   "FLD",   "FST",  "FSTP",  "FRESTOR","???",  "FSAVE", "FSTSW",  /* 28 */
-    "FIADD", "FIMUL", "FICOM","FICOMP","FISUB", "FISUBR","FIDIV", "FIDIVR", /* 30 */
-    "FILD",  "???",   "FIST", "FISTP", "FBLD",  "???",   "FBSTP", "FISTP"   /* 38 */
-};
-/* The following opcodes are for mod == 3 */
-static std::string szFlops2[] =
-{
-    /* 0        1        2       3        4        5        6        7  */
-    "FADD",  "FMUL",  "FCOM", "FCOMP", "FSUB",  "FSUBR", "FDIV",  "FDIVR",  /* 00 */
-    "FLD",   "FXCH",  "FNOP", "???",   "",      "",      "",      "",       /* 08 */
-    "FIADD", "FIMUL", "FICOM","FICOMP","FISUB", "",      "FIDIV", "FIDIVR", /* 10 */
-    "FILD",  "???",   "FIST", "FISTP", "???",   "???",   "???",   "FSTP",   /* 18 */
-    "FADD",  "FMUL",  "FCOM", "FCOMP", "FSUB",  "FSUBR", "FDIV",  "FDIVR",  /* 20 */
-    "FFREE", "FSTP",  "FST",  "???",   "FUCOM", "FUCOMP","???",   "???",    /* 28 */
-    "FADDP", "FMULP", "FICOM","",      "FSUBRP","FISUBR","FDIVRP","FDIVP",  /* 30 */
-    "FILD",  "???",   "FIST", "FISTP", "",      "???",   "FBSTP", "FISTP"   /* 38 */
-};
-
-const std::string &Machine_X86::opcodeName(unsigned r)
-{
-    assert(r<(sizeof(szOps)/sizeof(std::string)));
-    return szOps[r];
-}
-const std::string &Machine_X86::floatOpName(unsigned r)
-{
-    if(r>=(sizeof(szFlops1)/sizeof(std::string)))
-    {
-        r-= (sizeof(szFlops1)/sizeof(std::string));
-        assert(r<(sizeof(szFlops2)/sizeof(std::string)));
-        return szFlops2[r];
-    }
-    return szFlops1[r];
-}
-
-bool Machine_X86::physicalReg(eReg r)
-{
-    return (r>=rAX) && (r<rTMP);
-}
-bool Machine_X86::isMemOff(eReg r)
-{
-    return r == 0 || r >= INDEX_BX_SI;
-}
-//TODO: Move these to Machine_X86
-eReg Machine_X86::subRegH(eReg reg)
-{
-    return eReg((int)reg + (int)rAH-(int)rAX);
-}
-eReg Machine_X86::subRegL(eReg reg)
-{
-    return eReg((int)reg + (int)rAL-(int)rAX);
-}
-bool Machine_X86::isSubRegisterOf(eReg reg,eReg parent)
-{
-    if ((parent < rAX) || (parent > rBX))
-        return false; // only AX -> BX are coverede by subregisters
-    return ((reg==subRegH(parent)) || (reg == subRegL(parent)));
-}

File diff suppressed because it is too large
+ 442 - 490
src/parser.cpp


+ 371 - 26
src/perfhlib.cpp

@@ -11,21 +11,32 @@
 
 /* Private data structures */
 
-static  uint16_t    *T1, *T2;   /* Pointers to T1[i], T2[i] */
+static  int     NumEntry;   /* Number of entries in the hash table (# keys) */
+static  int     EntryLen;   /* Size (bytes) of each entry (size of keys) */
+static  int     SetSize;    /* Size of the char set */
+static  char    SetMin;     /* First char in the set */
+static  int     NumVert;    /* c times NumEntry */
+
+static  word    *T1base, *T2base;   /* Pointers to start of T1, T2 */
+static  word    *T1, *T2;   /* Pointers to T1[i], T2[i] */
+
+static  int     *graphNode; /* The array of edges */
+static  int     *graphNext; /* Linked list of edges */
+static  int     *graphFirst;/* First edge at a vertex */
+
 static  short   *g;         /* g[] */
 
 static  int     numEdges;   /* An edge counter */
-//static  bool    *visited;   /* Array of bools: whether visited */
+static  bool    *visited;   /* Array of bools: whether visited */
 
 /* Private prototypes */
 static void initGraph(void);
 static void addToGraph(int e, int v1, int v2);
 static bool isCycle(void);
 static void duplicateKeys(int v1, int v2);
-PatternHasher g_pattern_hasher;
-
+                     
 void
-PatternHasher::init(int _NumEntry, int _EntryLen, int _SetSize, char _SetMin,
+hashParams(int _NumEntry, int _EntryLen, int _SetSize, char _SetMin,
                     int _NumVert)
 {
     /* These parameters are stored in statics so as to obviate the need for
@@ -39,32 +50,316 @@ PatternHasher::init(int _NumEntry, int _EntryLen, int _SetSize, char _SetMin,
     NumVert  = _NumVert;
 
     /* Allocate the variable sized tables etc */
-    T1base = new uint16_t [EntryLen * SetSize];
-    T2base = new uint16_t [EntryLen * SetSize];
-    graphNode = new int [NumEntry*2 + 1];
-    graphNext = new int [NumEntry*2 + 1];
-    graphFirst = new int [NumVert + 1];
-    g = new short [NumVert + 1];
-//    visited = new bool [NumVert + 1];
+    if ((T1base = (word *)malloc(EntryLen * SetSize * sizeof(word))) == 0)
+    {
+        goto BadAlloc;
+    }
+    if ((T2base = (word *)malloc(EntryLen * SetSize * sizeof(word))) == 0)
+    {
+        goto BadAlloc;
+    }
+
+    if ((graphNode = (int *)malloc((NumEntry*2 + 1) * sizeof(int))) == 0)
+    {
+        goto BadAlloc;
+    }
+    if ((graphNext = (int *)malloc((NumEntry*2 + 1) * sizeof(int))) == 0)
+    {
+        goto BadAlloc;
+    }
+    if ((graphFirst = (int *)malloc((NumVert + 1) * sizeof(int))) == 0)
+    {
+        goto BadAlloc;
+    }
+
+    if ((g = (short *)malloc((NumVert+1) * sizeof(short))) == 0)
+    {
+        goto BadAlloc;
+    }
+    if ((visited = (bool *)malloc((NumVert+1) * sizeof(bool))) == 0)
+    {
+        goto BadAlloc;
+    }
     return;
 
+BadAlloc:
+    printf("Could not allocate memory\n");
+    hashCleanup();
+    exit(1);
 }
 
-void PatternHasher::cleanup(void)
+void
+hashCleanup(void)
 {
     /* Free the storage for variable sized tables etc */
-    delete [] T1base;
-    delete [] T2base;
-    delete [] graphNode;
-    delete [] graphNext;
-    delete [] graphFirst;
-    delete [] g;
-//    delete [] visited;
+    if (T1base) free(T1base);
+    if (T2base) free(T2base);
+    if (graphNode) free(graphNode);
+    if (graphNext) free(graphNext);
+    if (graphFirst) free(graphFirst);
+    if (g) free(g);
+}
+
+void
+map(void)
+{
+    int i, j, c;
+    word f1, f2;
+    bool cycle;
+    byte *keys;
+
+    c = 0;
+
+    do
+    {
+        initGraph();
+        cycle = FALSE;
+
+        /* Randomly generate T1 and T2 */
+        for (i=0; i < SetSize*EntryLen; i++)
+        {
+            T1base[i] = rand() % NumVert;
+            T2base[i] = rand() % NumVert;
+        }
+
+        for (i=0; i < NumEntry; i++)
+        {
+            f1 = 0; f2 = 0;
+            getKey(i, &keys);
+            for (j=0; j < EntryLen; j++)
+            {
+                T1 = T1base + j * SetSize;
+                T2 = T2base + j * SetSize;
+                f1 += T1[keys[j] - SetMin];
+                f2 += T2[keys[j] - SetMin];
+            }
+            f1 %= (word)NumVert;
+            f2 %= (word)NumVert;
+            if (f1 == f2)
+            {
+                /* A self loop. Reject! */
+                printf("Self loop on vertex %d!\n", f1);
+                cycle = TRUE;
+                break;
+            }
+            addToGraph(numEdges++, f1, f2);
+        }
+        if (cycle || (cycle = isCycle()))   /* OK - is there a cycle? */
+        {
+            printf("Iteration %d\n", ++c);
+        }
+        else
+        {
+            break;
+        }
+    }
+    while (/* there is a cycle */ 1);
+
 }
 
-int PatternHasher::hash(uint8_t *string)
+/* Initialise the graph */
+static void
+initGraph(void)
 {
-    uint16_t u, v;
+    int i;
+
+    for (i=1; i <= NumVert; i++)
+    {
+        graphFirst[i] = 0;
+    }
+
+    for (i= -NumEntry; i <= NumEntry; i++)
+    {
+        /* No need to init graphNode[] as they will all be filled by successive
+            calls to addToGraph() */
+        graphNext[NumEntry+i] = 0;
+    }
+
+    numEdges = 0;
+}
+
+/* Add an edge e between vertices v1 and v2 */
+/* e, v1, v2 are 0 based */
+static void
+addToGraph(int e, int v1, int v2)
+{
+    e++; v1++; v2++;                        /* So much more convenient */
+
+    graphNode[NumEntry+e] = v2;             /* Insert the edge information */
+    graphNode[NumEntry-e] = v1;
+
+    graphNext[NumEntry+e] = graphFirst[v1]; /* Insert v1 to list of alphas */
+    graphFirst[v1]= e;
+    graphNext[NumEntry-e] = graphFirst[v2]; /* Insert v2 to list of omegas */
+    graphFirst[v2]= -e;
+
+}
+
+bool DFS(int parentE, int v)
+{
+    int e, w;
+
+    /* Depth first search of the graph, starting at vertex v, looking for
+        cycles. parent and v are origin 1. Note parent is an EDGE,
+        not a vertex */
+
+    visited[v] = TRUE;
+
+    /* For each e incident with v .. */
+    for (e = graphFirst[v]; e; e = graphNext[NumEntry+e])
+    {
+        byte *key1;
+        
+        getKey(abs(e)-1, &key1);
+        if (*(long *)key1 == 0)
+        {
+            /* A deleted key. Just ignore it */
+            continue;
+        }
+        w = graphNode[NumEntry+e];
+        if (visited[w])
+        {
+            /* Did we just come through this edge? If so, ignore it. */
+            if (abs(e) != abs(parentE))
+            {
+                /* There is a cycle in the graph. There is some subtle code here
+                    to work around the distinct possibility that there may be
+                    duplicate keys. Duplicate keys will always cause unit
+                    cycles, since f1 and f2 (used to select v and w) will be the
+                    same for both. The edges (representing an index into the
+                    array of keys) are distinct, but the key values are not.
+                    The logic is as follows: for the candidate edge e, check to
+                    see if it terminates in the parent vertex. If so, we test
+                    the keys associated with e and the parent, and if they are
+                    the same, we can safely ignore e for the purposes of cycle
+                    detection, since edge e adds nothing to the cycle. Cycles
+                    involving v, w, and e0 will still be found. The parent
+                    edge was not similarly eliminated because at the time when
+                    it was a candidate, v was not yet visited.
+                    We still have to remove the key from further consideration,
+                    since each edge is visited twice, but with a different
+                    parent edge each time.
+                */
+                /* We save some stack space by calculating the parent vertex
+                    for these relatively few cases where it is needed */
+                int parentV = graphNode[NumEntry-parentE];
+
+                if (w == parentV)
+                {
+                    byte *key2;
+
+                    getKey(abs(parentE)-1,  &key2);
+                    if (memcmp(key1, key2, EntryLen) == 0)
+                    {
+                        printf("Duplicate keys with edges %d and %d (",
+                            e, parentE);
+                        dispKey(abs(e)-1);
+                        printf(" & ");
+                        dispKey(abs(parentE)-1);
+                        printf(")\n");
+/*                      *(long *)key1 = 0;      /* Wipe the key */
+memset(key1, 0, EntryLen);
+                    }
+                    else 
+                    {
+                        /* A genuine (unit) cycle. */
+printf("There is a unit cycle involving vertex %d and edge %d\n", v, e);
+                        return TRUE;
+                    }
+
+                }
+                else
+                {
+                    /* We have reached a previously visited vertex not the
+                        parent. Therefore, we have uncovered a genuine cycle */
+printf("There is a cycle involving vertex %d and edge %d\n", v, e);
+                    return TRUE;
+
+                }
+            }
+        }
+        else                                /* Not yet seen. Traverse it */
+        {
+            if (DFS(e, w))
+            {
+                /* Cycle found deeper down. Exit */
+                return TRUE;
+            }
+        }
+    }
+    return FALSE;
+}
+
+static bool
+isCycle(void)
+{
+    int v;
+
+    for (v=1; v <= NumVert; v++)
+    {
+        visited[v] = FALSE;
+    }
+    for (v=1; v <= NumVert; v++)
+    {
+        if (!visited[v])
+        {
+            if (DFS(-32767, v))
+            {
+                return TRUE;
+            }
+        }
+    }
+    return FALSE;
+}
+
+void
+traverse(int u)
+{
+    int w, e;
+
+    visited[u] = TRUE;
+    /* Find w, the neighbours of u, by searching the edges e associated with u */
+    e = graphFirst[1+u];
+    while (e)
+    {
+        w = graphNode[NumEntry+e]-1;
+        if (!visited[w])
+        {
+            g[w] = (abs(e)-1 - g[u]) % NumEntry;
+            if (g[w] < 0) g[w] += NumEntry;     /* Keep these positive */
+            traverse(w);
+        }
+        e = graphNext[NumEntry+e];
+    }
+
+}
+
+void
+assign(void)
+{
+    int v;
+
+    
+    for (v=0; v < NumVert; v++)
+    {
+        g[v] = 0;                           /* g is sparse; leave the gaps 0 */
+        visited[v] = FALSE;
+    }
+
+    for (v=0; v < NumVert; v++)
+    {
+        if (!visited[v])
+        {
+            g[v] = 0;
+            traverse(v);
+        }
+    }
+}
+
+int
+hash(byte *string)
+{
+    word u, v;
     int  j;
 
     u = 0;
@@ -86,18 +381,68 @@ int PatternHasher::hash(uint8_t *string)
     return (g[u] + g[v]) % NumEntry;
 }
 
-uint16_t * PatternHasher::readT1(void)
+word *
+readT1(void)
 {
     return T1base;
 }
 
-uint16_t *PatternHasher::readT2(void)
+word *
+readT2(void)
 {
     return T2base;
 }
 
-uint16_t * PatternHasher::readG(void)
+word *
+readG(void)
 {
-    return (uint16_t *)g;
+    return (word *)g;
 }
 
+#if 0
+void dispRecord(int i);
+
+void
+duplicateKeys(int v1, int v2)
+{
+    int i, j;
+    byte *keys;
+    int u, v;
+
+    v1--; v2--;             /* These guys are origin 1 */
+
+    printf("Duplicate keys:\n");
+
+    for (i=0; i < NumEntry; i++)
+    {
+        getKey(i, &keys);
+        u = 0;
+        for (j=0; j < EntryLen; j++)
+        {
+            T1 = T1base + j * SetSize;
+            u += T1[keys[j] - SetMin];
+        }
+        u %= NumVert;
+        if ((u != v1) && (u != v2)) continue;
+
+        v = 0;
+        for (j=0; j < EntryLen; j++)
+        {
+            T2 = T2base + j * SetSize;
+            v += T2[keys[j] - SetMin];
+        }
+        v %= NumVert;
+
+        if ((v == v2) || (v == v1))
+        {
+            printf("Entry #%d key: ", i+1);
+            for (j=0; j < EntryLen; j++) printf("%02X ", keys[j]);
+            printf("\n");
+            dispRecord(i+1);
+        }
+    }
+    exit(1);
+
+
+}
+#endif

+ 335 - 308
src/procs.cpp

@@ -5,382 +5,409 @@
  * (C) Cristina Cifuentes
  */
 
-#include <cstring>
-#include <cassert>
 #include "dcc.h"
-#include "project.h"
+#include <string.h>
+
 
-extern Project g_proj;
 /* Static indentation buffer */
-static constexpr int indSize=81;          /* size of indentation buffer; max 20 */
-static char indentBuf[indSize] =
-        "                                                                                ";
-// not static, used in icode.cpp at emitGotoLabel
-const char *indentStr(int indLevel) // Indentation according to the depth of the statement
-{
-    return (&indentBuf[indSize-(indLevel*4)-1]);
+#define indSize     61          /* size of indentation buffer; max 20 */
+static char indentBuf[indSize] = 
+    "                                                            ";
+
+static char *indent (Int indLevel)
+/* Indentation according to the depth of the statement */
+{ 
+    return (&indentBuf[indSize-(indLevel*3)-1]); 
 }
 
 
-/* Inserts an outEdge at the current callGraph pointer if the newProc does
+static void insertArc (PCALL_GRAPH pcallGraph, PPROC newProc)
+/* Inserts an outEdge at the current callGraph pointer if the newProc does 
  * not exist.  */
-void CALL_GRAPH::insertArc (ilFunction newProc)
-{
-    CALL_GRAPH *pcg;
-
+{ CALL_GRAPH *pcg;
+  Int i;
 
     /* Check if procedure already exists */
-    auto res=std::find_if(outEdges.begin(),outEdges.end(),[newProc](CALL_GRAPH *e) {return e->proc==newProc;});
-    if(res!=outEdges.end())
-        return;
+    for (i = 0;  i < pcallGraph->numOutEdges; i++)
+        if (pcallGraph->outEdges[i]->proc == newProc)
+            return;
+
+    /* Check if need to allocate more space */
+    if (pcallGraph->numOutEdges == pcallGraph->numAlloc)
+    {
+        pcallGraph->numAlloc += NUM_PROCS_DELTA;
+        pcallGraph->outEdges = (PCALL_GRAPH*)reallocVar(pcallGraph->outEdges,
+							pcallGraph->numAlloc * sizeof(PCALL_GRAPH));
+		memset (&pcallGraph->outEdges[pcallGraph->numOutEdges], 0,
+				NUM_PROCS_DELTA * sizeof(PCALL_GRAPH));
+    }
+
     /* Include new arc */
-    pcg = new CALL_GRAPH;
+    pcg = allocStruc(CALL_GRAPH); 
+	memset (pcg, 0, sizeof(CALL_GRAPH));
     pcg->proc = newProc;
-    outEdges.push_back(pcg);
+    pcallGraph->outEdges[pcallGraph->numOutEdges] = pcg;
+    pcallGraph->numOutEdges++;
 }
 
 
+boolT insertCallGraph (PCALL_GRAPH pcallGraph, PPROC caller, PPROC callee)
 /* Inserts a (caller, callee) arc in the call graph tree. */
-bool CALL_GRAPH::insertCallGraph(ilFunction caller, ilFunction callee)
-{
-    int i;
+{ Int i;
 
-    if (proc == caller)
+    if (pcallGraph->proc == caller)
     {
-        insertArc (callee);
-        return true;
+        insertArc (pcallGraph, callee);
+        return (TRUE);
     }
     else
     {
-        for (i = 0; i < outEdges.size(); i++)
-            if (outEdges[i]->insertCallGraph (caller, callee))
-                return true;
-        return (false);
+        for (i = 0; i < pcallGraph->numOutEdges; i++)
+            if (insertCallGraph (pcallGraph->outEdges[i], caller, callee))
+                return (TRUE);
+        return (FALSE);
     }
 }
 
-bool CALL_GRAPH::insertCallGraph(Function *caller, ilFunction callee)
-{
-    return insertCallGraph(g_proj.funcIter(caller),callee);
-}
-
 
+static void writeNodeCallGraph (PCALL_GRAPH pcallGraph, Int indIdx) 
 /* Displays the current node of the call graph, and invokes recursively on
  * the nodes the procedure invokes. */
-void CALL_GRAPH::writeNodeCallGraph(int indIdx)
-{
-    int i;
+{ Int i;
 
-    printf ("%s%s\n", indentStr(indIdx), proc->name.c_str());
-    for (i = 0; i < outEdges.size(); i++)
-        outEdges[i]->writeNodeCallGraph (indIdx + 1);
+    printf ("%s%s\n", indent(indIdx), pcallGraph->proc->name);
+    for (i = 0; i < pcallGraph->numOutEdges; i++)
+        writeNodeCallGraph (pcallGraph->outEdges[i], indIdx + 1);
 }
 
 
+void writeCallGraph (PCALL_GRAPH pcallGraph)
 /* Writes the header and invokes recursive procedure */
-void CALL_GRAPH::write()
-{
+{ 
     printf ("\nCall Graph:\n");
-    writeNodeCallGraph (0);
+    writeNodeCallGraph (pcallGraph, 0); 
 }
 
 
 /**************************************************************************
- *  Routines to support arguments
+ *  Routines to support arguments 
  *************************************************************************/
 
+void newRegArg (PPROC pproc, PICODE picode, PICODE ticode)
 /* Updates the argument table by including the register(s) (ie. lhs of
  * picode) and the actual expression (ie. rhs of picode).
  * Note: register(s) are only included once in the table.   */
-void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
-{
-    COND_EXPR *lhs;
-    STKFRAME * call_args_stackframe, *target_stackframe;
-    const ID *id;
-    int tidx;
-    boolT regExist;
-    condId type;
-    Function * tproc;
-    eReg regL, regH;		/* Registers involved in arguments */
-
-    /* Flag ticode as having register arguments */
-    tproc = ticode->hl()->call.proc;
-    tproc->flg |= REG_ARGS;
-
-    /* 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;
-    if (type == REGISTER)
-    {
-        regL = id_arr[lhs->expr.ident.idNode.regiIdx].id.regi;
-        if (regL < rAL)
-            tidx = tproc->localId.newByteWordReg(TYPE_WORD_SIGN, regL);
-        else
-            tidx = tproc->localId.newByteWordReg(TYPE_BYTE_SIGN, regL);
-    }
-    else if (type == LONG_VAR)
+{ COND_EXPR *lhs;
+  PSTKFRAME ps, ts;
+  ID *id;
+  Int i, tidx;
+  boolT regExist;
+  condId type;
+  PPROC tproc;
+  byte regL, regH;		/* Registers involved in arguments */
+
+	/* Flag ticode as having register arguments */
+	tproc = ticode->ic.hl.oper.call.proc;
+	tproc->flg |= REG_ARGS;
+
+	/* Get registers and index into target procedure's local list */
+	ps = ticode->ic.hl.oper.call.args;
+	ts = &tproc->args;
+	lhs = picode->ic.hl.oper.asgn.lhs;
+	type = lhs->expr.ident.idType;
+	if (type == REGISTER)
+	{
+		regL = pproc->localId.id[lhs->expr.ident.idNode.regiIdx].id.regi;
+		if (regL < rAL)
+			tidx = newByteWordRegId (&tproc->localId, TYPE_WORD_SIGN, regL);
+		else
+			tidx = newByteWordRegId (&tproc->localId, TYPE_BYTE_SIGN, regL);
+	}
+	else if (type == LONG_VAR)
+	{
+		regL = pproc->localId.id[lhs->expr.ident.idNode.longIdx].id.longId.l;
+		regH = pproc->localId.id[lhs->expr.ident.idNode.longIdx].id.longId.h;
+		tidx = newLongRegId (&tproc->localId, TYPE_LONG_SIGN, regH, regL, 0);
+	}
+
+	/* Check if register argument already on the formal argument list */
+	regExist = FALSE;
+	for (i = 0; i < ts->csym; i++)
+	{
+		if (type == REGISTER)
+		{
+			if ((ts->sym[i].regs != NULL) && 
+				(ts->sym[i].regs->expr.ident.idNode.regiIdx == tidx))
+			{
+				regExist = TRUE;
+				i = ts->csym;
+			}
+		}
+		else if (type == LONG_VAR)
+		{
+			if ((ts->sym[i].regs != NULL) && 
+				(ts->sym[i].regs->expr.ident.idNode.longIdx == tidx))
+			{
+				regExist = TRUE;
+				i = ts->csym;
+			}
+		}
+	}
+
+	/* Do ts (formal arguments) */
+	if (regExist == FALSE)
+	{
+    	if (ts->csym == ts->alloc) 
+    	{
+			ts->alloc += 5;
+			ts->sym = (STKSYM*)reallocVar(ts->sym, ts->alloc * sizeof(STKSYM));
+            memset (&ts->sym[ts->csym], 0, 5 * sizeof(STKSYM));
+    	}
+    	sprintf (ts->sym[ts->csym].name, "arg%ld", ts->csym);
+		if (type == REGISTER)
+		{
+			if (regL < rAL)
+			{
+    			ts->sym[ts->csym].type = TYPE_WORD_SIGN;
+    			ts->sym[ts->csym].regs = idCondExpRegIdx (tidx, WORD_REG);
+			}
+			else
+			{
+				ts->sym[ts->csym].type = TYPE_BYTE_SIGN;
+    			ts->sym[ts->csym].regs = idCondExpRegIdx (tidx, BYTE_REG);
+			}
+			sprintf (tproc->localId.id[tidx].name, "arg%ld", ts->csym);
+		}
+		else if (type == LONG_VAR)
+		{
+    		ts->sym[ts->csym].regs = idCondExpLongIdx (tidx);
+    		ts->sym[ts->csym].type = TYPE_LONG_SIGN; 
+			sprintf (tproc->localId.id[tidx].name, "arg%ld", ts->csym);
+			propLongId (&tproc->localId, regL, regH,
+										tproc->localId.id[tidx].name);
+		}
+
+		ts->csym++;
+		ts->numArgs++;
+	}
+
+	/* Do ps (actual arguments) */
+    if (ps->csym == ps->alloc) 
     {
-        int longIdx = lhs->expr.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*/);
+        ps->alloc += 5;
+		ps->sym = (STKSYM*)reallocVar(ps->sym, ps->alloc * sizeof(STKSYM));
+        memset (&ps->sym[ps->csym], 0, 5 * sizeof(STKSYM));
     }
+    sprintf (ps->sym[ps->csym].name, "arg%ld", ps->csym);
+    ps->sym[ps->csym].actual = picode->ic.hl.oper.asgn.rhs;
+    ps->sym[ps->csym].regs = lhs;
+
+	/* Mask off high and low register(s) in picode */
+	switch (type) {
+	  case REGISTER:	
+		id = &pproc->localId.id[lhs->expr.ident.idNode.regiIdx];
+		picode->du.def &= maskDuReg[id->id.regi];
+		if (id->id.regi < rAL)
+    		ps->sym[ps->csym].type = TYPE_WORD_SIGN;
+		else
+			ps->sym[ps->csym].type = TYPE_BYTE_SIGN;
+		break;
+	  case LONG_VAR: 
+		id = &pproc->localId.id[lhs->expr.ident.idNode.longIdx];
+		picode->du.def &= maskDuReg[id->id.longId.h];
+		picode->du.def &= maskDuReg[id->id.longId.l];
+    	ps->sym[ps->csym].type = TYPE_LONG_SIGN; 
+		break;
+	}
+
+	ps->csym++;
+	ps->numArgs++;
+}
 
-    /* Check if register argument already on the formal argument list */
-    regExist = false;
-    for(STKSYM &tgt_sym : *target_stackframe)
-    {
-        if( tgt_sym.regs == NULL ) // both REGISTER and LONG_VAR require this precondition
-            continue;
-        if (type == REGISTER)
-        {
-            if ( tgt_sym.regs->expr.ident.idNode.regiIdx == tidx )
-            {
-                regExist = true;
-            }
-        }
-        else if (type == LONG_VAR)
-        {
-            if ( tgt_sym.regs->expr.ident.idNode.longIdx == tidx )
-            {
-                regExist = true;
-            }
-        }
-        if(regExist == true)
-            break;
-    }
 
-    /* Do ts (formal arguments) */
-    if (regExist == false)
-    {
-        STKSYM newsym;
-
-        newsym.setArgName(target_stackframe->size());
-
-        if (type == REGISTER)
-        {
-            if (regL < rAL)
-            {
-                newsym.type = TYPE_WORD_SIGN;
-                newsym.regs = COND_EXPR::idRegIdx(tidx, WORD_REG);
-            }
-            else
-            {
-                newsym.type = TYPE_BYTE_SIGN;
-                newsym.regs = COND_EXPR::idRegIdx(tidx, BYTE_REG);
-            }
-            tproc->localId.id_arr[tidx].name = newsym.name;
-        }
-        else if (type == LONG_VAR)
-        {
-            newsym.regs = COND_EXPR::idLongIdx (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());
-        }
-        target_stackframe->push_back(newsym);
-        target_stackframe->numArgs++;
-    }
+void allocStkArgs (PICODE picode, Int num)
+/* Allocates num arguments in the actual argument list of the current
+ * icode picode.	*/
+/** NOTE: this function is not used ****/
+{ PSTKFRAME ps;      
 
-    /* Do ps (actual arguments) */
-    STKSYM newsym;
-    newsym.setArgName(call_args_stackframe->size());
-    newsym.actual = picode->hl()->asgn.rhs;
-    newsym.regs = lhs;
-    /* Mask off high and low register(s) in picode */
-    switch (type) {
-        case REGISTER:
-            id = &id_arr[lhs->expr.ident.idNode.regiIdx];
-            picode->du.def &= maskDuReg[id->id.regi];
-            if (id->id.regi < rAL)
-                newsym.type = TYPE_WORD_SIGN;
-            else
-                newsym.type = TYPE_BYTE_SIGN;
-            break;
-        case LONG_VAR:
-            id = &id_arr[lhs->expr.ident.idNode.longIdx];
-            picode->du.def &= maskDuReg[id->id.longId.h];
-            picode->du.def &= maskDuReg[id->id.longId.l];
-            newsym.type = TYPE_LONG_SIGN;
-            break;
-    }
-    call_args_stackframe->push_back(newsym);
-    call_args_stackframe->numArgs++;
+	ps = picode->ic.hl.oper.call.args;
+    ps->alloc = num;
+	ps->csym = num;
+	ps->numArgs = num;
+	ps->sym = (STKSYM*)reallocVar(ps->sym, ps->alloc * sizeof(STKSYM));
+    /**** memset here??? *****/
 }
 
 
-/** Inserts the new expression (ie. the actual parameter) on the argument
+boolT newStkArg (PICODE picode, COND_EXPR *exp, llIcode opcode, PPROC pproc)
+/* Inserts the new expression (ie. the actual parameter) on the argument
  * list.
- * @return true if it was a near call that made use of a segment register.
- *         false elsewhere
-*/
-bool CallType::newStkArg(COND_EXPR *exp, llIcode opcode, Function * pproc)
-{
-    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)
+ * Returns: TRUE if it was a near call that made use of a segment register.
+ *			FALSE elsewhere	*/
+{ PSTKFRAME ps;
+  byte 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 ((exp->type == IDENTIFIER) && (exp->expr.ident.idType == REGISTER))
+		{
+			regi =  pproc->localId.id[exp->expr.ident.idNode.regiIdx].id.regi;
+			if ((regi >= rES) && (regi <= rDS))
+				if (opcode == iCALLF)
+					return (FALSE);
+				else
+					return (TRUE);
+		}
+	}
+
+	/* Place register argument on the argument list */
+	ps = picode->ic.hl.oper.call.args;
+    if (ps->csym == ps->alloc) 
     {
-        if ((exp->m_type == IDENTIFIER) && (exp->expr.ident.idType == REGISTER))
-        {
-            regi =  pproc->localId.id_arr[exp->expr.ident.idNode.regiIdx].id.regi;
-            if ((regi >= rES) && (regi <= rDS))
-                if (opcode == iCALLF)
-                    return false;
-                else
-                    return true;
-        }
+        ps->alloc += 5;
+		ps->sym = (STKSYM*)reallocVar(ps->sym, ps->alloc * sizeof(STKSYM));
+    	memset (&ps->sym[ps->csym], 0, 5 * sizeof(STKSYM));
     }
-
-    /* Place register argument on the argument list */
-    STKSYM newsym;
-    newsym.actual = exp;
-    args->push_back(newsym);
-    args->numArgs++;
-    return false;
+    ps->sym[ps->csym].actual = exp;
+	ps->csym++;
+	ps->numArgs++;
+	return (FALSE);
 }
 
 
+void placeStkArg (PICODE picode, COND_EXPR *exp, Int pos)
 /* Places the actual argument exp in the position given by pos in the
  * argument list of picode.	*/
-void CallType::placeStkArg (COND_EXPR *exp, int pos)
-{
-    (*args)[pos].actual = exp;
-    (*args)[pos].setArgName(pos);
-}
+{ PSTKFRAME ps;
 
-COND_EXPR *CallType::toId()
-{
-    return COND_EXPR::idFunc( proc, args);
+	ps = picode->ic.hl.oper.call.args;
+	ps->sym[pos].actual = exp;
+	sprintf (ps->sym[pos].name, "arg%ld", pos);
 }
 
 
+void adjustActArgType (COND_EXPR *exp, hlType forType, PPROC pproc)
 /* 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)
-{
-    PROG &prog(Project::get()->prog);
-    hlType actType;
-    int offset, offL;
-
-    if (exp == NULL)
-        return;
-
-    actType = exp-> expType (pproc);
-    if (((actType == forType) || (exp->m_type != IDENTIFIER)))
-        return;
-    switch (forType)
-    {
-        case TYPE_UNKNOWN: case TYPE_BYTE_SIGN:
-        case TYPE_BYTE_UNSIGN: case TYPE_WORD_SIGN:
-        case TYPE_WORD_UNSIGN: case TYPE_LONG_SIGN:
-        case TYPE_LONG_UNSIGN: case TYPE_RECORD:
-            break;
-
-        case TYPE_PTR:
-        case TYPE_CONST:
-            break;
-
-        case TYPE_STR:
-            switch (actType) {
-                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;
-                    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;
-                    break;
-
-                case TYPE_PTR:
-                    /* It's a pointer to a char rather than a pointer to
-                                         * an integer */
-                    /***HERE - modify the type ****/
-                    break;
-
-                case TYPE_WORD_SIGN:
-
-                    break;
-            } /* eos */
-            break;
-    }
+{ hlType actType;
+  Int offset, offL;
+
+	if (exp == NULL)
+		return;
+
+	actType = expType (exp, pproc);
+	if ((actType != forType) && (exp->type == IDENTIFIER))
+	{
+		switch (forType) {
+		  case TYPE_UNKNOWN: case TYPE_BYTE_SIGN:
+		  case TYPE_BYTE_UNSIGN: case TYPE_WORD_SIGN:
+		  case TYPE_WORD_UNSIGN: case TYPE_LONG_SIGN:
+		  case TYPE_LONG_UNSIGN: case TYPE_RECORD:
+				break;
+
+		  case TYPE_PTR:
+		  case TYPE_CONST:
+				break;
+
+		  case TYPE_STR:
+				switch (actType) {
+				  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;
+					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;
+					break;
+
+				  case TYPE_PTR:
+					/* It's a pointer to a char rather than a pointer to 
+					 * an integer */
+					/***HERE - modify the type ****/
+					break;
+
+				  case TYPE_WORD_SIGN:
+
+					break;
+				} /* eos */
+				break;
+		}
+	}
 }
 
 
+void adjustForArgType (PSTKFRAME pstkFrame, Int numArg, hlType actType)
 /* Determines whether the formal argument has the same type as the given
- * type (type of the actual argument).  If not, the formal argument is
+ * type (type of the actual argument).  If not, the formal argument is 
  * changed its type */
-void STKFRAME::adjustForArgType(int numArg_, hlType actType_)
-{
-    hlType forType;
-    STKSYM * psym, * nsym;
-    int off, i;
-    /* If formal argument does not exist, do not create new ones, just
-     * ignore actual argument
-     */
-    if(numArg_>size())
-        return;
-
-    /* Find stack offset for this argument */
-    off = m_minOff;
-    i=0;
-    for(STKSYM &s : *this) // walk formal arguments upto numArg_
-    {
-        if(i>=numArg_)
-            break;
-        off+=s.size;
-        i++;
-    }
-
-    /* Find formal argument */
-    //psym = &at(numArg_);
-    //i = numArg_;
-        //auto iter=std::find_if(sym.begin(),sym.end(),[off](STKSYM &s)->bool {s.off==off;});
-    auto iter=std::find_if(begin()+numArg_,end(),[off](STKSYM &s)->bool {s.label==off;});
-    if(iter==end()) // symbol not found
-            return;
-        psym = &(*iter);
-
-    forType = psym->type;
-    if (forType != actType_)
-    {
-        switch (actType_) {
-            case TYPE_UNKNOWN: case TYPE_BYTE_SIGN:
-            case TYPE_BYTE_UNSIGN: case TYPE_WORD_SIGN:
-            case TYPE_WORD_UNSIGN: case TYPE_RECORD:
-                break;
-
-            case TYPE_LONG_UNSIGN: case TYPE_LONG_SIGN:
-                if ((forType == TYPE_WORD_UNSIGN) ||
-                        (forType == TYPE_WORD_SIGN) ||
-                        (forType == TYPE_UNKNOWN))
-                {
-                    /* Merge low and high */
-                    psym->type = actType_;
-                    psym->size = 4;
-                    nsym = psym + 1;
-                    nsym->macro = "HI";
-                    psym->macro = "LO";
-                    nsym->hasMacro = true;
-                    psym->hasMacro = true;
-                    nsym->name = psym->name;
-                    nsym->invalid = true;
-                    numArgs--;
-                }
-                break;
-
-            case TYPE_PTR:
-            case TYPE_CONST:
-            case TYPE_STR:
-                break;
-        } /* eos */
-    }
+{ hlType forType;
+  PSTKSYM psym, nsym;
+  Int off, i;
+
+	/* Find stack offset for this argument */
+	off = pstkFrame->minOff;
+	for (i = 0; i < numArg; i++)
+		off += pstkFrame->sym[i].size;
+
+	/* Find formal argument */
+	if (numArg < pstkFrame->csym)
+	{
+		psym = &pstkFrame->sym[numArg];
+		i = numArg;
+		while ((i < pstkFrame->csym) && (psym->off != off))
+		{
+			psym++;
+			i++;
+		}
+		if (numArg == pstkFrame->csym)
+			return;
+	}
+	/* If formal argument does not exist, do not create new ones, just
+	 * ignore actual argument */
+	else
+		return;
+
+	forType = psym->type;
+	if (forType != actType)
+	{
+		switch (actType) {
+		  case TYPE_UNKNOWN: case TYPE_BYTE_SIGN:
+		  case TYPE_BYTE_UNSIGN: case TYPE_WORD_SIGN:
+		  case TYPE_WORD_UNSIGN: case TYPE_RECORD:
+				break;
+
+		  case TYPE_LONG_UNSIGN: case TYPE_LONG_SIGN:
+				if ((forType == TYPE_WORD_UNSIGN) || 
+					(forType == TYPE_WORD_SIGN) ||
+					(forType == TYPE_UNKNOWN))
+				{
+					/* Merge low and high */
+					psym->type = actType;
+					psym->size = 4;
+					nsym = psym + 1;
+					sprintf (nsym->macro, "HI");
+					sprintf (psym->macro, "LO");
+					nsym->hasMacro = TRUE;
+					psym->hasMacro = TRUE;
+					sprintf (nsym->name, "%s", psym->name);
+					nsym->invalid = TRUE;
+					pstkFrame->numArgs--;
+				}
+				break;
+
+		  case TYPE_PTR:
+		  case TYPE_CONST:
+		  case TYPE_STR:
+				break;
+		} /* eos */
+	}
 }
 

+ 0 - 73
src/project.cpp

@@ -1,73 +0,0 @@
-#include <utility>
-#include "project.h"
-#include "Procedure.h"
-Project g_proj;
-bool Project::valid(ilFunction iter)
-{
-    return iter!=pProcList.end();
-}
-ilFunction Project::funcIter(Function *to_find)
-{
-    auto iter=std::find_if(pProcList.begin(),pProcList.end(),
-                             [to_find](const Function &f)->bool {return to_find==&f;});
-    assert(iter!=pProcList.end());
-    return iter;
-}
-
-ilFunction Project::findByEntry(uint32_t entry)
-{
-    /* Search procedure list for one with appropriate entry point */
-    ilFunction iter= std::find_if(pProcList.begin(),pProcList.end(),
-        [entry](const Function &f) ->
-            bool { return f.procEntry==entry; });
-return iter;
-}
-
-ilFunction Project::createFunction()
-{
-    pProcList.push_back(Function::Create());
-    return (++pProcList.rbegin()).base();
-}
-
-int Project::getSymIdxByAdd(uint32_t adr)
-{
-    size_t i;
-    for (i = 0; i < symtab.size(); i++)
-        if (symtab[i].label == adr)
-            break;
-    return i;
-}
-bool Project::validSymIdx(size_t idx)
-{
-    return idx<symtab.size();
-}
-const SYM &Project::getSymByIdx(size_t idx) const
-{
-    return symtab[idx];
-}
-size_t Project::symbolSize(size_t idx)
-{
-    assert(validSymIdx(idx));
-    return symtab[idx].size;
-}
-hlType Project::symbolType(size_t idx)
-{
-    assert(validSymIdx(idx));
-    return symtab[idx].type;
-}
-
-const std::string &Project::symbolName(size_t idx)
-{
-    assert(validSymIdx(idx));
-    return symtab[idx].name;
-}
-Project *Project::get()
-{
-    return &g_proj;
-}
-
-
-SourceMachine *Project::machine()
-{
-    return nullptr;
-}

+ 489 - 482
src/proplong.cpp

@@ -4,555 +4,562 @@
  *          registers) along the graph.  Structure the graph in this way.
  * (C) Cristina Cifuentes
  **************************************************************************/
-#include <string.h>
-#include <memory.h>
-#include <cassert>
-#include <algorithm>
 
 #include "dcc.h"
+#include "string.h"
+#ifdef __BORLAND__
+#include <mem.h>
+#else
+#include <memory.h>
+#endif
 
+
+static boolT isJCond (llIcode opcode)
 /* Returns whether the given icode opcode is within the range of valid
  * high-level conditional jump icodes (iJB..iJG) */
-static boolT isJCond (llIcode opcode)
 {
-    if ((opcode >= iJB) && (opcode <= iJG))
-        return true;
-    return false;
+	if ((opcode >= iJB) && (opcode <= iJG))
+		return (TRUE);
+	return (FALSE);
 }
 
 
+static boolT isLong23 (Int i, PBB pbb, PICODE icode, Int *off, Int *arc)
 /* Returns whether the conditions for a 2-3 long variable are satisfied */
-static bool isLong23 (BB * pbb, iICODE &off, int *arc)
-{
-    BB * t, * e, * obb2;
-
-    if (pbb->nodeType != TWO_BRANCH)
-        return false;
-    t = pbb->edges[THEN].BBptr;
-    e = pbb->edges[ELSE].BBptr;
-
-    /* Check along the THEN path */
-    if ((t->size() == 1) && (t->nodeType == TWO_BRANCH) && (t->inEdges.size() == 1))
-    {
-        obb2 = t->edges[THEN].BBptr;
-        if ((obb2->size() == 2) && (obb2->nodeType == TWO_BRANCH) && (obb2->front().ll()->getOpcode() == iCMP))
-        {
-            off = obb2->begin();//std::distance(iter,obb2->begin2());
-            *arc = THEN;
-            return true;
-        }
-    }
-
-    /* Check along the ELSE path  */
-    else if ((e->size() == 1) && (e->nodeType == TWO_BRANCH) && (e->inEdges.size() == 1))
-    {
-        obb2 = e->edges[THEN].BBptr;
-        if ((obb2->size() == 2) && (obb2->nodeType == TWO_BRANCH) &&  (obb2->front().ll()->getOpcode() == iCMP))
-        {
-            off = obb2->begin();//std::distance(iter,obb2->begin2());//obb2->front().loc_ip - i;
-            *arc = ELSE;
-            return true;
-        }
-    }
-    return false;
+{ PBB t, e, obb2;
+
+	if (pbb->nodeType != TWO_BRANCH)
+		return (FALSE);
+	t = pbb->edges[THEN].BBptr;
+	e = pbb->edges[ELSE].BBptr;
+
+	/* Check along the THEN path */
+	if ((t->length == 1) && (t->nodeType == TWO_BRANCH) && (t->numInEdges == 1))
+	{
+		obb2 = t->edges[THEN].BBptr;
+		if ((obb2->length == 2) && (obb2->nodeType == TWO_BRANCH) &&
+			(icode[obb2->start].ic.ll.opcode == iCMP))
+		{
+			*off = obb2->start - i;
+			*arc = THEN;
+			return (TRUE);
+		}
+	}
+
+	/* Check along the ELSE path  */
+	else if ((e->length == 1) && (e->nodeType == TWO_BRANCH) && 
+			 (e->numInEdges == 1))
+	{
+		obb2 = e->edges[THEN].BBptr;
+		if ((obb2->length == 2) && (obb2->nodeType == TWO_BRANCH) &&
+			(icode[obb2->start].ic.ll.opcode == iCMP))
+		{
+			*off = obb2->start - i;
+			*arc = ELSE;
+			return (TRUE);
+		}
+	}
+	return (FALSE);
 }
 
 
+static boolT isLong22 (PICODE pIcode, PICODE pEnd, Int *off)
 /* Returns whether the conditions for a 2-2 long variable are satisfied */
-static boolT isLong22 (iICODE pIcode, iICODE pEnd, iICODE &off)
 {
-    iICODE initial_icode=pIcode;
-    if(distance(pIcode,pEnd)<4)
-        return false;
-    // preincrement because pIcode is not checked here
-    iICODE icodes[] = { ++pIcode,++pIcode,++pIcode };
-    if (   icodes[1]->ll()->match(iCMP) &&
-           (isJCond ((llIcode)icodes[0]->ll()->getOpcode())) &&
-           (isJCond ((llIcode)icodes[2]->ll()->getOpcode())))
-    {
-        off = initial_icode;
-        advance(off,2);
-        return true;
-    }
-    return false;
+	if (((pIcode+2) < pEnd) && ((pIcode+2)->ic.ll.opcode == iCMP) &&
+		(isJCond ((pIcode+1)->ic.ll.opcode)) &&
+		(isJCond ((pIcode+3)->ic.ll.opcode)))
+	{
+		*off = 2;
+		return (TRUE);
+	}
+	return (FALSE);
 }
 
-/** Creates a long conditional <=, >=, <, or > at (pIcode+1).
- * Removes excess nodes from the graph by flagging them, and updates
- * the new edges for the remaining nodes.
- * @return number of ICODEs to skip
 
-*/
-static int longJCond23 (Assignment &asgn, iICODE pIcode, int arc, iICODE atOffset)
-{
-    BB * pbb, * obb1, * obb2, * tbb;
-    int skipped_insn=0;
-    if (arc == THEN)
-    {
-        /* Find intermediate basic blocks and target block */
-        pbb = pIcode->getParent();
-        obb1 = pbb->edges[THEN].BBptr;
-        obb2 = obb1->edges[THEN].BBptr;
-        tbb = obb2->edges[THEN].BBptr;
-
-        /* Modify out edge of header basic block */
-        pbb->edges[THEN].BBptr = tbb;
-
-        /* Modify in edges of target basic block */
-        auto newlast=std::remove_if(tbb->inEdges.begin(),tbb->inEdges.end(),
-                                    [obb1,obb2](BB *b) -> bool {
-                                    return (b==obb1) || (b==obb2); });
-        tbb->inEdges.erase(newlast,tbb->inEdges.end());
-        tbb->inEdges.push_back(pbb); /* looses 2 arcs, gains 1 arc */
-
-        /* Modify in edges of the ELSE basic block */
-        tbb = pbb->edges[ELSE].BBptr;
-        auto iter=std::find(tbb->inEdges.begin(),tbb->inEdges.end(),obb2);
-        assert(iter!=tbb->inEdges.end());
-        tbb->inEdges.erase(iter); /* looses 1 arc */
-        /* Update icode index */
-        skipped_insn = 5;
-    }
-    else  /* ELSE arc */
-    {
-        /* Find intermediate basic blocks and target block */
-        pbb = pIcode->getParent();
-        obb1 = pbb->edges[ELSE].BBptr;
-        obb2 = obb1->edges[THEN].BBptr;
-        tbb = obb2->edges[THEN].BBptr;
-
-        /* Modify in edges of target basic block */
-        auto iter=std::find(tbb->inEdges.begin(),tbb->inEdges.end(),obb2);
-        assert(iter!=tbb->inEdges.end());
-        tbb->inEdges.erase(iter); /* looses 1 arc */
-
-        /* Modify in edges of the ELSE basic block */
-        tbb = obb2->edges[ELSE].BBptr;
-        auto newlast=std::remove_if(tbb->inEdges.begin(),tbb->inEdges.end(),
-                                    [obb1,obb2](BB *b) -> bool { return (b==obb1) || (b==obb2); });
-        tbb->inEdges.erase(newlast,tbb->inEdges.end());
-        tbb->inEdges.push_back(pbb); /* looses 2 arcs, gains 1 arc */
-
-        /* Modify out edge of header basic block */
-        pbb->edges[ELSE].BBptr = tbb;
-
-        /* Update icode index */
-        skipped_insn = 2;
-    }
-    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]);
-    next1->setJCond(asgn.lhs);
-    next1->copyDU(*pIcode, eUSE, eUSE);
-    next1->du.use |= atOffset->du.use;
-
-    /* Update statistics */
-    obb1->flg |= INVALID_BB;
-    obb2->flg |= INVALID_BB;
-    stats.numBBaft -= 2;
-
-    pIcode->invalidate();
-    obb1->front().invalidate();
-    // invalidate 2 first instructions of BB 2
-    iICODE ibb2 = obb2->begin();
-    (ibb2++)->invalidate();
-    (ibb2++)->invalidate();
-    return skipped_insn;
+static void longJCond23 (COND_EXPR *rhs, COND_EXPR *lhs, PICODE pIcode, 
+						 Int *idx, PPROC pProc, Int arc, Int off)
+/* Creates a long conditional <=, >=, <, or > at (pIcode+1).
+ * Removes excess nodes from the graph by flagging them, and updates
+ * the new edges for the remaining nodes.	*/
+{ Int j;
+  PBB pbb, obb1, obb2, tbb;
+
+	if (arc == THEN)
+  	{
+		/* Find intermediate basic blocks and target block */
+		pbb = pIcode->inBB;
+		obb1 = pbb->edges[THEN].BBptr;
+		obb2 = obb1->edges[THEN].BBptr;
+		tbb = obb2->edges[THEN].BBptr;
+
+		/* Modify out edge of header basic block */
+		pbb->edges[THEN].BBptr = tbb;
+
+		/* Modify in edges of target basic block */
+		for (j = 0; j < (tbb->numInEdges-1); j++)
+		{
+			if ((tbb->inEdges[j] == obb1) || (tbb->inEdges[j] == obb2))
+			{
+				memmove (&tbb->inEdges[j], &tbb->inEdges[j+1],
+					 	(tbb->numInEdges - j-1) * sizeof(PBB));
+				memset (&tbb->inEdges[tbb->numInEdges-1], ' ',sizeof (PBB));
+				j--;
+			}
+		}
+		tbb->numInEdges--;	/* looses 2 arcs, gains 1 arc */
+		tbb->inEdges[tbb->numInEdges-1] = pbb;
+
+		/* Modify in edges of the ELSE basic block */
+		tbb = pbb->edges[ELSE].BBptr;
+		for (j = 0; j < (tbb->numInEdges-1); j++)
+		{
+			if (tbb->inEdges[j] == obb2)
+			{
+				memmove (&tbb->inEdges[j], &tbb->inEdges[j+1],
+					 	(tbb->numInEdges - j-1) * sizeof(PBB));
+				break;
+			}
+		}
+		tbb->numInEdges--;	/* looses 1 arc */
+
+		/* Update icode index */
+		(*idx) += 5; 
+  	}
+
+  	else  /* ELSE arc */
+  	{
+		/* Find intermediate basic blocks and target block */
+		pbb = pIcode->inBB;
+		obb1 = pbb->edges[ELSE].BBptr;
+		obb2 = obb1->edges[THEN].BBptr;
+		tbb = obb2->edges[THEN].BBptr;
+
+		/* Modify in edges of target basic block */
+		for (j = 0; j < (tbb->numInEdges-1); j++)
+		{
+			if (tbb->inEdges[j] == obb2)
+			{
+				memmove (&tbb->inEdges[j], &tbb->inEdges[j+1],
+					 	(tbb->numInEdges - j-1) * sizeof(PBB));
+				break;	
+			}
+		}
+		tbb->numInEdges--;	/* looses 1 arc */
+
+		/* Modify in edges of the ELSE basic block */
+		tbb = obb2->edges[ELSE].BBptr;
+		for (j = 0; j < (tbb->numInEdges-1); j++)
+		{
+			if ((tbb->inEdges[j] == obb2) || (tbb->inEdges[j] == obb1))
+			{
+				memmove (&tbb->inEdges[j], &tbb->inEdges[j+1],
+					 	(tbb->numInEdges - j-1) * sizeof(PBB));
+				memset (&tbb->inEdges[tbb->numInEdges-1], ' ',sizeof (PBB));
+				j--;
+			}
+		}
+		tbb->numInEdges--;	/* looses 2 arcs, gains 1 arc */
+		tbb->inEdges[tbb->numInEdges - 1] = pbb;
+
+		/* Modify out edge of header basic block */
+		pbb->edges[ELSE].BBptr = tbb;
+
+		/* Update icode index */
+		(*idx) += 2; 
+  	}
+
+	/* Create new HLI_JCOND and condition */
+	lhs = boolCondExp (lhs, rhs, condOpJCond[(pIcode+off+1)->ic.ll.opcode-iJB]);
+	newJCondHlIcode (pIcode+1, lhs);
+	copyDU (pIcode+1, pIcode, E_USE, E_USE);
+	(pIcode+1)->du.use |= (pIcode+off)->du.use;
+
+	/* Update statistics */
+	obb1->flg |= INVALID_BB;
+	obb2->flg |= INVALID_BB;
+	stats.numBBaft -= 2;
+
+	invalidateIcode (pIcode);
+	invalidateIcode (pProc->Icode.GetIcode(obb1->start));
+	invalidateIcode (pProc->Icode.GetIcode(obb2->start));
+	invalidateIcode (pProc->Icode.GetIcode(obb2->start+1));
 }
 
 
-/** Creates a long conditional equality or inequality at (pIcode+1).
+static void longJCond22 (COND_EXPR *rhs, COND_EXPR *lhs, PICODE pIcode,
+						 Int *idx)
+/* Creates a long conditional equality or inequality at (pIcode+1).
  * Removes excess nodes from the graph by flagging them, and updates
- * the new edges for the remaining nodes.
- * @return number of ICODE's to skip
-*/
-static int longJCond22 (Assignment &asgn, iICODE pIcode,iICODE pEnd)
-{
-
-    BB * pbb, * obb1, * tbb;
-    if(distance(pIcode,pEnd)<4)
-        return false;
-    // preincrement because pIcode is not checked here
-    iICODE icodes[] = { pIcode++,pIcode++,pIcode++,pIcode++ };
-
-    /* Form conditional expression */
-    asgn.lhs = COND_EXPR::boolOp (asgn.lhs, asgn.rhs, condOpJCond[icodes[3]->ll()->getOpcode() - iJB]);
-    icodes[1]->setJCond(asgn.lhs);
-    icodes[1]->copyDU (*icodes[0], eUSE, eUSE);
-    icodes[1]->du.use |= icodes[2]->du.use;
-
-    /* Adjust outEdges[0] to the new target basic block */
-    pbb = icodes[0]->getParent();
-    if (pbb->back().loc_ip == icodes[1]->loc_ip)
-    {
-        /* Find intermediate and target basic blocks */
-        obb1 = pbb->edges[THEN].BBptr;
-        tbb = obb1->edges[THEN].BBptr;
-
-        /* Modify THEN out edge of header basic block */
-        pbb->edges[THEN].BBptr = tbb;
-
-        /* Modify in edges of target basic block */
-        auto iter=std::find(tbb->inEdges.begin(),tbb->inEdges.end(),obb1);
-        assert(iter!=tbb->inEdges.end());
-        tbb->inEdges.erase(iter);
-
-        if (icodes[3]->ll()->getOpcode() != iJE)
-            tbb->inEdges.push_back(pbb); /* iJNE => replace arc */
-
-        /* Modify ELSE out edge of header basic block */
-        tbb = obb1->edges[ELSE].BBptr;
-        pbb->edges[ELSE].BBptr = tbb;
-
-        iter=std::find(tbb->inEdges.begin(),tbb->inEdges.end(),obb1);
-        assert(iter!=tbb->inEdges.end());
-        tbb->inEdges.erase(iter);
-        if (icodes[3]->ll()->getOpcode() == iJE)	/* replace */
-            tbb->inEdges.push_back(pbb);
-
-        /* Update statistics */
-        obb1->flg |= INVALID_BB;
-        stats.numBBaft--;
-    }
-
-    icodes[0]->invalidate();
-    icodes[2]->invalidate();
-    icodes[3]->invalidate();
-    return 4;
+ * the new edges for the remaining nodes.	*/
+{ Int j;
+  PBB pbb, obb1, tbb;
+
+	/* Form conditional expression */
+	lhs = boolCondExp (lhs, rhs, condOpJCond[(pIcode+3)->ic.ll.opcode - iJB]);
+	newJCondHlIcode (pIcode+1, lhs);
+	copyDU (pIcode+1, pIcode, E_USE, E_USE);
+	(pIcode+1)->du.use |= (pIcode+2)->du.use;
+
+	/* Adjust outEdges[0] to the new target basic block */ 
+	pbb = pIcode->inBB;
+	if ((pbb->start + pbb->length - 1) == (*idx + 1))
+	{
+		/* Find intermediate and target basic blocks */
+		obb1 = pbb->edges[THEN].BBptr;
+		tbb = obb1->edges[THEN].BBptr;
+
+		/* Modify THEN out edge of header basic block */
+		pbb->edges[THEN].BBptr = tbb;
+
+		/* Modify in edges of target basic block */
+		for (j = 0; j < (tbb->numInEdges-1); j++)
+		{
+			if (tbb->inEdges[j] == obb1)
+			{
+				memmove (&tbb->inEdges[j], &tbb->inEdges[j+1],
+						(tbb->numInEdges - j-1) * sizeof(PBB));
+				break;
+			}
+		}
+		if ((pIcode+3)->ic.ll.opcode == iJE)
+			tbb->numInEdges--;	/* looses 1 arc */
+		else					/* iJNE => replace arc */
+			tbb->inEdges[tbb->numInEdges-1] = pbb;
+
+		/* Modify ELSE out edge of header basic block */
+		tbb = obb1->edges[ELSE].BBptr;
+		pbb->edges[ELSE].BBptr = tbb;
+
+		/* Modify in edges of the ELSE basic block */
+		for (j = 0; j < (tbb->numInEdges-1); j++)
+		{
+			if (tbb->inEdges[j] == obb1)
+			{
+				memmove (&tbb->inEdges[j], &tbb->inEdges[j+1],
+						(tbb->numInEdges - j-1) * sizeof(PBB));
+				break;
+			}
+		}
+		if ((pIcode+3)->ic.ll.opcode == iJE)	/* replace */
+			tbb->inEdges[tbb->numInEdges-1] = pbb;	
+		else
+			tbb->numInEdges--;		/* iJNE => looses 1 arc */
+
+
+		/* Update statistics */
+		obb1->flg |= INVALID_BB;
+		stats.numBBaft--;
+	}
+
+	invalidateIcode (pIcode);
+	invalidateIcode (pIcode+2);
+	invalidateIcode (pIcode+3);
+	(*idx) += 4;
 }
 
+
+static void propLongStk (Int i, ID *pLocId, PPROC pProc)
 /* Propagates TYPE_LONG_(UN)SIGN icode information to the current pIcode
  * Pointer.
  * Arguments: i     : index into the local identifier table
- *            pLocId: ptr to the long local identifier
+ *            pLocId: ptr to the long local identifier 
  *            pProc : ptr to current procedure's record.        */
-void Function::propLongStk (int i, const ID &pLocId)
-{
-    int arc;
-    Assignment asgn;
-    //COND_EXPR *lhs, *rhs;     /* Pointers to left and right hand expression */
-    iICODE next1, pEnd;
-    iICODE l23;
-    /* Check all icodes for offHi:offLo */
-    pEnd = Icode.end();
-    int stat_size=Icode.size();
-//    for (idx = 0; idx < (Icode.size() - 1); idx++)
-    for(auto pIcode = Icode.begin(); ;++pIcode)
-    {
-        assert(Icode.size()==stat_size);
-        next1 = ++iICODE(pIcode);
-        if(next1==pEnd)
-            break;
-        if ((pIcode->type == HIGH_LEVEL) || ( not pIcode->valid() ))
-            continue;
-        if (pIcode->ll()->getOpcode() == next1->ll()->getOpcode())
-        {
-            if (checkLongEq (pLocId.id.longStkId, pIcode, i, this, asgn, *next1->ll()) == true)
-            {
-                switch (pIcode->ll()->getOpcode())
-                {
-                case iMOV:
-                    pIcode->setAsgn(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;
-                    }
-                    pIcode->setAsgn(asgn.lhs, asgn.rhs);
-                    next1->invalidate();
-                    break;
-
-                case iPUSH:
-                    pIcode->setUnary( HLI_PUSH, asgn.lhs);
-                    next1->invalidate();
-                    break;
-                default:
-                    printf("Wild ass checkLongEq success on opcode %d\n",pIcode->ll()->getOpcode());
-                } /*eos*/
-            }
-        }
-        //TODO: Simplify this!
-        /* Check long conditional (i.e. 2 CMPs and 3 branches */
-        else if ((pIcode->ll()->getOpcode() == iCMP) && (isLong23 (pIcode->getParent(), l23, &arc)))
-        {
-            if ( checkLongEq (pLocId.id.longStkId, pIcode, i, this, asgn, *l23->ll()) )
-            {
-                advance(pIcode,longJCond23 (asgn, pIcode, arc, l23));
-            }
-        }
-
-        /* Check for long conditional equality or inequality.  This requires
-                 * 2 CMPs and 2 branches */
-        else if ((pIcode->ll()->getOpcode() == iCMP) && isLong22 (pIcode, pEnd, l23))
-        {
-            if ( checkLongEq (pLocId.id.longStkId, pIcode, i, this,asgn, *l23->ll()) )
-            {
-                advance(pIcode,longJCond22 (asgn, pIcode,pEnd));
-            }
-        }
-    }
+{ Int idx, off, arc;
+  COND_EXPR *lhs, *rhs;     /* Pointers to left and right hand expression */
+  PICODE pIcode, pEnd;
+
+	/* Check all icodes for offHi:offLo */
+	pEnd = pProc->Icode.GetIcode(pProc->Icode.GetNumIcodes() -1);
+    for (idx = 0; idx < (pProc->Icode.GetNumIcodes() - 1); idx++)
+	{
+		pIcode = pProc->Icode.GetIcode(idx);
+    	if ((pIcode->type == HIGH_LEVEL) || (pIcode->invalid == TRUE))
+			continue;
+
+		if (pIcode->ic.ll.opcode == (pIcode+1)->ic.ll.opcode)
+		{
+			switch (pIcode->ic.ll.opcode) {
+			  case iMOV:
+            	if (checkLongEq (pLocId->id.longStkId, pIcode, i, idx, pProc, 
+                             &rhs, &lhs, 1) == TRUE)
+            	{
+                	newAsgnHlIcode (pIcode, lhs, rhs);
+                	invalidateIcode (pIcode + 1);
+                	idx++;
+            	}
+            	break;
+
+			  case iAND: case iOR: case iXOR:
+            	if (checkLongEq (pLocId->id.longStkId, pIcode, i, idx, pProc, 
+                             &rhs, &lhs, 1) == TRUE)
+            	{
+					switch (pIcode->ic.ll.opcode) {
+				  	case iAND: 	rhs = boolCondExp (lhs, rhs, AND);
+								break;
+				  	case iOR: 	rhs = boolCondExp (lhs, rhs, OR);
+								break;
+				  	case iXOR: 	rhs = boolCondExp (lhs, rhs, XOR);
+								break;
+					}
+                	newAsgnHlIcode (pIcode, lhs, rhs);
+                	invalidateIcode (pIcode + 1);
+                	idx++;
+            	}
+            	break;
+
+			  case iPUSH:
+            	if (checkLongEq (pLocId->id.longStkId, pIcode, i, idx, pProc,
+                             &rhs, &lhs, 1) == TRUE)
+            	{
+                	newUnaryHlIcode (pIcode, HLI_PUSH, lhs);
+                	invalidateIcode (pIcode + 1);
+                	idx++;
+            	}
+            	break;
+    		} /*eos*/
+		}
+
+		/* Check long conditional (i.e. 2 CMPs and 3 branches */ 
+		else if ((pIcode->ic.ll.opcode == iCMP) && 
+				 (isLong23 (idx, pIcode->inBB, pProc->Icode.GetFirstIcode(),
+				 &off, &arc)))
+		{
+			if (checkLongEq (pLocId->id.longStkId, pIcode, i, idx, pProc,
+							 &rhs, &lhs, off) == TRUE)
+				longJCond23 (rhs, lhs, pIcode, &idx, pProc, arc, off);
+		}
+
+		/* Check for long conditional equality or inequality.  This requires
+		 * 2 CMPs and 2 branches */ 
+		else if ((pIcode->ic.ll.opcode == iCMP) && 
+										isLong22 (pIcode, pEnd, &off))
+		{
+			if (checkLongEq (pLocId->id.longStkId, pIcode, i, idx, pProc,
+							 &rhs, &lhs, off) == TRUE)
+				longJCond22 (rhs, lhs, pIcode, &idx);
+		}
+	}
 }
-int Function::findBackwarLongDefs(int loc_ident_idx, const ID &pLocId, iICODE beg)
-{
-    Assignment asgn;
-    LLOperand * pmH,* pmL;
-    iICODE pIcode;
-    riICODE rev(beg);
-    bool forced_finish=false;
-    for (; not forced_finish and rev!=Icode.rend();rev++) //idx = pLocId_idx - 1; idx > 0 ; idx--
-    {
-        pIcode = (++riICODE(rev)).base();//forward iterator from rev
-        iICODE next1((++iICODE(pIcode))); // next instruction
-        ICODE &icode(*pIcode);
 
 
-        if ((icode.type == HIGH_LEVEL) || ( not icode.valid() ))
-            continue;
-        if (icode.ll()->getOpcode() != next1->ll()->getOpcode())
-            continue;
-
-        switch (icode.ll()->getOpcode())
-        {
-        case iMOV:
-            pmH = &icode.ll()->dst;
-            pmL = &next1->ll()->dst;
-            if ((pLocId.id.longId.h == pmH->regi) && (pLocId.id.longId.l == pmL->regi))
+static void propLongReg (Int i, ID *pLocId, PPROC pProc)
+/* Finds the definition of the long register pointed to by pLocId, and 
+ * transforms that instruction into a HIGH_LEVEL icode instruction.
+ * Arguments: i     : index into the local identifier table
+ *            pLocId: ptr to the long local identifier 
+ *            pProc : ptr to current procedure's record.        */
+{ COND_EXPR *lhs, *rhs; 
+  Int idx, j, off, arc;
+  PICODE pIcode, pEnd;
+  PMEM pmH, pmL;            /* Pointers to dst LOW_LEVEL icodes */
+
+  /* Process all definitions/uses of long registers at an icode position */
+  pEnd = pProc->Icode.GetIcode(pProc->Icode.GetNumIcodes() -1);
+  for (j = 0; j < pLocId->idx.csym; j++)
+  {
+    /* Check backwards for a definition of this long register */
+    for (idx = pLocId->idx.idx[j] - 1; idx > 0 ; idx--)
+    {
+      pIcode = pProc->Icode.GetIcode(idx-1);
+	  if ((pIcode->type == HIGH_LEVEL) || (pIcode->invalid == TRUE))
+			continue;
+
+      if (pIcode->ic.ll.opcode == (pIcode+1)->ic.ll.opcode)
+        switch (pIcode->ic.ll.opcode) {
+          case iMOV:
+            pmH = &pIcode->ic.ll.dst;
+            pmL = &(pIcode+1)->ic.ll.dst;
+            if ((pLocId->id.longId.h == pmH->regi) && 
+                (pLocId->id.longId.l == pmL->regi))
             {
-                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());
-                icode.setAsgn(asgn.lhs, asgn.rhs);
-                next1->invalidate();
-                forced_finish=true; /* to exit the loop */
+                lhs = idCondExpLongIdx (i);
+                insertIdx (&pProc->localId.id[i].idx, idx-1);
+                setRegDU (pIcode, pmL->regi, E_DEF);
+                rhs = idCondExpLong (&pProc->localId, SRC, pIcode, HIGH_FIRST, 
+                                     idx, E_USE, 1);
+                newAsgnHlIcode (pIcode, lhs, rhs);
+                invalidateIcode (pIcode + 1);
+                idx = 0;    /* to exit the loop */
             }
             break;
 
-        case iPOP:
-            pmH = &next1->ll()->dst;
-            pmL = &icode.ll()->dst;
-            if ((pLocId.id.longId.h == pmH->regi) && (pLocId.id.longId.l == pmL->regi))
+          case iPOP:
+            pmH = &(pIcode+1)->ic.ll.dst;
+            pmL = &pIcode->ic.ll.dst;
+            if ((pLocId->id.longId.h == pmH->regi) &&
+                (pLocId->id.longId.l == pmL->regi))
             {
-                asgn.lhs = COND_EXPR::idLongIdx (loc_ident_idx);
-                icode.setRegDU( pmH->regi, eDEF);
-                icode.setUnary(HLI_POP, asgn.lhs);
-                next1->invalidate();
-                asgn.lhs=0;
-                forced_finish=true;        /* to exit the loop */
+                lhs = idCondExpLongIdx (i);
+                setRegDU (pIcode, pmH->regi, E_DEF);
+                newUnaryHlIcode (pIcode, HLI_POP, lhs);
+                invalidateIcode (pIcode + 1);
+                idx = 0;        /* to exit the loop */
             }
             break;
-
-            //                /**** others missing ***/
-
-        case iAND: case iOR: case iXOR:
-            pmL = &icode.ll()->dst;
-            pmH = &next1->ll()->dst;
-            if ((pLocId.id.longId.h == pmH->regi) && (pLocId.id.longId.l == pmL->regi))
+	
+		  /**** others missing ***/
+
+		  case iAND: case iOR: case iXOR:
+            pmL = &pIcode->ic.ll.dst;
+            pmH = &(pIcode+1)->ic.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());
-                icode.setRegDU( pmH->regi, USE_DEF);
-                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;
-                } /* eos */
-                icode.setAsgn(asgn.lhs, asgn.rhs);
-                next1->invalidate();
-                forced_finish=true;        /* to exit the loop */
+                lhs = idCondExpLongIdx (i);
+                setRegDU (pIcode, pmH->regi, USE_DEF);
+                rhs = idCondExpLong (&pProc->localId, SRC, pIcode, LOW_FIRST, 
+                                     idx, E_USE, 1);
+				switch (pIcode->ic.ll.opcode) {
+				  case iAND: rhs = boolCondExp (lhs, rhs, AND);
+							 break;
+				  case iOR:	 rhs = boolCondExp (lhs, rhs, OR);
+							 break;
+				  case iXOR: rhs = boolCondExp (lhs, rhs, XOR);
+							 break;
+				} /* eos */
+                newAsgnHlIcode (pIcode, lhs, rhs);
+                invalidateIcode (pIcode + 1);
+                idx = 0;
             }
             break;
         } /* eos */
     }
-    return rev!=Icode.rend();
-}
-int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE beg)
-{
-    bool forced_finish=false;
-    auto pEnd=Icode.end();
-    iICODE long_loc;
-    Assignment asgn;
-    for (auto pIcode=beg; not forced_finish; ++pIcode)
-    {
-        iICODE next1(++iICODE(pIcode));
-        if(next1==pEnd)
-            break;
-        LLOperand * pmH,* pmL;            /* Pointers to dst LOW_LEVEL icodes */
-        int arc;
-
-        if ((pIcode->type == HIGH_LEVEL) || ( not pIcode->valid() ))
-            continue;
 
-        if (pIcode->ll()->getOpcode() == next1->ll()->getOpcode())
-            switch (pIcode->ll()->getOpcode())
-            {
-            case iMOV:
-                if ((pLocId.id.longId.h == pIcode->ll()->src().getReg2()) &&
-                        (pLocId.id.longId.l == next1->ll()->src().getReg2()))
+    /* If no definition backwards, check forward for a use of this long reg */
+    if (idx <= 0)
+      for (idx = pLocId->idx.idx[j] + 1; idx < pProc->Icode.GetNumIcodes() - 1; idx++)
+	  {
+        pIcode = pProc->Icode.GetIcode(idx);
+		if ((pIcode->type == HIGH_LEVEL) || (pIcode->invalid == TRUE))
+			continue;
+
+        if (pIcode->ic.ll.opcode == (pIcode+1)->ic.ll.opcode)
+            switch (pIcode->ic.ll.opcode) {
+              case iMOV:
+                if ((pLocId->id.longId.h == pIcode->ic.ll.src.regi) &&
+                    (pLocId->id.longId.l == (pIcode+1)->ic.ll.src.regi))
                 {
-                    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());
-
-                    pIcode->setAsgn(asgn.lhs, asgn.rhs);
-                    next1->invalidate();
-                    forced_finish =true; /* to exit the loop */
+                    rhs = idCondExpLongIdx (i);
+                    setRegDU (pIcode, (pIcode+1)->ic.ll.src.regi, E_USE); 
+                    lhs = idCondExpLong (&pProc->localId, DST, pIcode, 
+                                         HIGH_FIRST, idx, E_DEF, 1);
+                    newAsgnHlIcode (pIcode, lhs, rhs);
+                    invalidateIcode (pIcode + 1);
+                    idx = pProc->Icode.GetNumIcodes();    /* to exit the loop */ 
                 }
                 break;
 
-            case iPUSH:
-                if ((pLocId.id.longId.h == pIcode->ll()->src().getReg2()) &&
-                        (pLocId.id.longId.l == next1->ll()->src().getReg2()))
+              case iPUSH:
+                if ((pLocId->id.longId.h == pIcode->ic.ll.src.regi) &&
+                    (pLocId->id.longId.l == (pIcode+1)->ic.ll.src.regi))
                 {
-                    asgn.rhs = COND_EXPR::idLongIdx (loc_ident_idx);
-                    pIcode->setRegDU( next1->ll()->src().getReg2(), eUSE);
-                    pIcode->setUnary(HLI_PUSH, asgn.rhs);
-                    next1->invalidate();
+                    rhs = idCondExpLongIdx (i);
+                    setRegDU (pIcode, (pIcode+1)->ic.ll.src.regi, E_USE); 
+                    newUnaryHlIcode (pIcode, HLI_PUSH, lhs);
+                    invalidateIcode (pIcode + 1);
                 }
-                forced_finish =true; /* to exit the loop */
+                idx = pProc->Icode.GetNumIcodes();    /* to exit the loop  */
                 break;
 
-                /*** others missing ****/
-
-            case iAND: case iOR: case iXOR:
-                pmL = &pIcode->ll()->dst;
-                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);
-                    pIcode->setRegDU( pmH->regi, USE_DEF);
-                    asgn.rhs = COND_EXPR::idLong (&this->localId, SRC, pIcode,
-                                                  LOW_FIRST, pIcode, eUSE, *next1->ll());
-                    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;
-                    }
-                    pIcode->setAsgn(asgn.lhs, asgn.rhs);
-                    next1->invalidate();
-                    // ftw loop restart ????
-                    //idx = 0;
-                    // maybe this should end the loop instead
-                    forced_finish =true; /* to exit the loop */
-                }
-                break;
+			  /*** others missing ****/
+
+          	  case iAND: case iOR: case iXOR:
+            	pmL = &pIcode->ic.ll.dst;
+            	pmH = &(pIcode+1)->ic.ll.dst;
+            	if ((pLocId->id.longId.h == pmH->regi) &&
+                	(pLocId->id.longId.l == pmL->regi))
+            	{
+                	lhs = idCondExpLongIdx (i);
+                	setRegDU (pIcode, pmH->regi, USE_DEF);
+                	rhs = idCondExpLong (&pProc->localId, SRC, pIcode, 
+										 LOW_FIRST, idx, E_USE, 1);
+					switch (pIcode->ic.ll.opcode) {
+                	  case iAND: rhs = boolCondExp (lhs, rhs, AND);
+								 break;
+                	  case iOR:  rhs = boolCondExp (lhs, rhs, OR);
+								 break;
+                	  case iXOR: rhs = boolCondExp (lhs, rhs, XOR);
+								 break;
+					}
+                	newAsgnHlIcode (pIcode, lhs, rhs);
+                	invalidateIcode (pIcode + 1);
+                	idx = 0;
+            	}
+            	break;
             } /* eos */
 
-        /* Check long conditional (i.e. 2 CMPs and 3 branches */
-        else if ((pIcode->ll()->getOpcode() == iCMP) && (isLong23 (pIcode->getParent(), long_loc, &arc)))
-        {
-            if (checkLongRegEq (pLocId.id.longId, pIcode, loc_ident_idx, this, asgn, *long_loc->ll()))
-            {
-                                // reduce the advance by 1 here (loop increases) ?
-                advance(pIcode,longJCond23 (asgn, pIcode, arc, long_loc));
-            }
-        }
-
-        /* Check for long conditional equality or inequality.  This requires
-             * 2 CMPs and 2 branches */
-        else if (pIcode->ll()->match(iCMP) && (isLong22 (pIcode, pEnd, long_loc)))
-        {
-            if (checkLongRegEq (pLocId.id.longId, pIcode, loc_ident_idx, this, asgn, *long_loc->ll()) )
-            {
-                // TODO: verify that removing -1 does not change anything !
-                advance(pIcode,longJCond22 (asgn, pIcode,pEnd));
-            }
-        }
-
-        /* Check for OR regH, regL
-             *			 JX lab
-             *		=> HLI_JCOND (regH:regL X 0) lab
-             * This is better code than HLI_JCOND (HI(regH:regL) | LO(regH:regL)) */
-        else if (pIcode->ll()->match(iOR) && (next1 != pEnd) && (isJCond ((llIcode)next1->ll()->getOpcode())))
-        {
-            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]);
-                next1->setJCond(asgn.lhs);
-                next1->copyDU(*pIcode, eUSE, eUSE);
-                pIcode->invalidate();
-            }
-        }
-    } /* end for */
-}
-
-/** Finds the definition of the long register pointed to by pLocId, and
- * transforms that instruction into a HIGH_LEVEL icode instruction.
- * @arg i     index into the local identifier table
- * @arg pLocId ptr to the long local identifier
- *
- */
-void Function::propLongReg (int loc_ident_idx, const ID &pLocId)
-{
-    /* Process all definitions/uses of long registers at an icode position */
-    // WARNING: this loop modifies the iterated-over container.
-    size_t initial_size=pLocId.idx.size();
-    for (int j = 0; j < pLocId.idx.size(); j++)
-    {
-        auto idx_iter=pLocId.idx.begin();
-        std::advance(idx_iter,j);
-        /* Check backwards for a definition of this long register */
-        if (findBackwarLongDefs(loc_ident_idx,pLocId,*idx_iter))
-        {
-            //assert(initial_size==pLocId.idx.size());
-            continue;
-        }
-        /* If no definition backwards, check forward for a use of this long reg */
-        findForwardLongUses(loc_ident_idx,pLocId,*idx_iter);
-        //assert(initial_size==pLocId.idx.size());
-    } /* end for */
+		/* Check long conditional (i.e. 2 CMPs and 3 branches */ 
+		else if ((pIcode->ic.ll.opcode == iCMP) && 
+				 (isLong23 (idx, pIcode->inBB, pProc->Icode.GetFirstIcode(),
+				  &off, &arc)))
+		{
+			if (checkLongRegEq (pLocId->id.longId, pIcode, i, idx, pProc,
+							    &rhs, &lhs, off) == TRUE)
+				longJCond23 (rhs, lhs, pIcode, &idx, pProc, arc, off);
+		}
+
+		/* Check for long conditional equality or inequality.  This requires
+		 * 2 CMPs and 2 branches */ 
+		else if ((pIcode->ic.ll.opcode == iCMP) && 
+											(isLong22 (pIcode, pEnd, &off)))
+		{
+			if (checkLongRegEq (pLocId->id.longId, pIcode, i, idx, pProc,
+							    &rhs, &lhs, off) == TRUE)
+				longJCond22 (rhs, lhs, pIcode, &idx);
+		}
+		
+		/* Check for OR regH, regL
+		 *			 JX lab	
+		 *		=> HLI_JCOND (regH:regL X 0) lab
+		 * This is better code than HLI_JCOND (HI(regH:regL) | LO(regH:regL)) */
+		else if ((pIcode->ic.ll.opcode == iOR) && ((pIcode+1) < pEnd) &&
+				 (isJCond ((pIcode+1)->ic.ll.opcode)))
+		{
+			if ((pIcode->ic.ll.dst.regi == pLocId->id.longId.h) &&
+				(pIcode->ic.ll.src.regi == pLocId->id.longId.l))
+			{
+				lhs = idCondExpLongIdx (i);
+				rhs = idCondExpKte (0, 4);	/* long 0 */
+				lhs = boolCondExp (lhs, rhs, 
+								   condOpJCond[(pIcode+1)->ic.ll.opcode - iJB]);
+				newJCondHlIcode (pIcode+1, lhs);
+				copyDU (pIcode+1, pIcode, E_USE, E_USE);
+				invalidateIcode (pIcode);
+			}
+		}
+
+	  } /* end for */
+  } /* end for */
 }
 
 
-/* Propagates the long global address across all LOW_LEVEL icodes.
+static void propLongGlb (Int i, ID *pLocId, PPROC pProc)
+/* Propagates the long global address across all LOW_LEVEL icodes. 
  * Transforms some LOW_LEVEL icodes into HIGH_LEVEL     */
-void Function::propLongGlb (int i, const ID &pLocId)
 {
-    printf("WARN: Function::propLongGlb not implemented");
+
 }
 
 
+void propLong (PPROC pProc)
 /* Propagated identifier information, thus converting some LOW_LEVEL icodes
  * into HIGH_LEVEL icodes.  */
-void Function::propLong()
-{
-    int i;
-    /* Pointer to current local identifier */
+{ Int i;
+  ID *pLocId;           /* Pointer to current local identifier */
 
-    for (i = 0; i < localId.csym(); i++)
+    for (i = 0; i < pProc->localId.csym; i++)
     {
-        const ID &pLocId(localId.id_arr[i]);
-        if ((pLocId.type==TYPE_LONG_SIGN) || (pLocId.type==TYPE_LONG_UNSIGN))
+		pLocId = &pProc->localId.id[i];
+        if ((pLocId->type==TYPE_LONG_SIGN) || (pLocId->type==TYPE_LONG_UNSIGN))
         {
-            switch (pLocId.loc)
-            {
-            case STK_FRAME:
-                propLongStk (i, pLocId);
-                break;
-            case REG_FRAME:
-                propLongReg (i, pLocId);
-                break;
-            case GLB_FRAME:
-                propLongGlb (i, pLocId);
-                break;
+            switch (pLocId->loc) {
+			case STK_FRAME:	propLongStk (i, pLocId, pProc);
+                			break;
+            case REG_FRAME: propLongReg (i, pLocId, pProc);
+                			break;
+            case GLB_FRAME: propLongGlb (i, pLocId, pProc);
+                			break; 
             }
         }
     }

+ 284 - 254
src/reducible.cpp

@@ -3,388 +3,418 @@
  *  constructs an equivalent reducible graph if one is not found.
  * (C) Cristina Cifuentes
  ********************************************************************/
-#include <algorithm>
-#include <cassert>
+
 #include "dcc.h"
 #include <stdio.h>
+#ifdef __BORLAND__
+#include <alloc.h>
+#else
 #include <malloc.h>		/* For free() */
+#endif
 #include <string.h>
 
-static int      numInt;     /* Number of intervals      */
+static Int      numInt;     /* Number of intervals      */
 
 
 #define nonEmpty(q)     (q != NULL)
 /* Returns whether the queue q is empty or not */
-bool trivialGraph(BB *G)
-{
-    return G->edges.empty();
-}
+
+#define trivialGraph(G)     (G->numOutEdges == 0)
 /* Returns whether the graph is a trivial graph or not */
 
 
+static BB *firstOfQueue (queue **Q)
 /* Returns the first element in the queue Q, and removes this element
  * from the list.  Q is not an empty queue.                 */
-static BB *firstOfQueue (queue &Q)
-{
-    assert(!Q.empty());
-    BB *res=Q.front();
-    Q.pop_front();
-    return res;
+{ queue *elim;
+  BB *first;
+
+    elim  = *Q;         /* Pointer to first node */
+    first = (*Q)->node;     /* First element */
+    *Q    = (*Q)->next;     /* Pointer to next node */
+    free (elim);            /* Free storage */
+    return (first);
 }
 
 
+queue *appendQueue (queue **Q, BB *node)
 /* Appends pointer to node at the end of the queue Q if node is not present
  * in this queue.  Returns the queue node just appended.        */
-queue::iterator appendQueue (queue &Q, BB *node)
-{
-    auto iter=std::find(Q.begin(),Q.end(),node);
-    if(iter!=Q.end())
-        return iter;
-    Q.push_back(node);
-    iter=Q.end();
-    --iter;
-    return iter;
+{ queue *pq, *l;
+
+    pq = allocStruc(queue);
+    pq->node = node;
+    pq->next = NULL;
+
+    if (Q)
+        if (*Q)
+        {
+           for (l = *Q; l->next && l->node != node; l = l->next)
+              ;
+           if (l->node != node)
+              l->next = pq;
+        }
+        else        /* (*Q) == NULL */
+           *Q = pq;
+    return (pq);
 }
 
 
+static BB *firstOfInt (interval *pI)
 /* Returns the next unprocessed node of the interval list (pointed to by
  * pI->currNode).  Removes this element logically from the list, by updating
  * the currNode pointer to the next unprocessed element.  */
-BB *interval::firstOfInt ()
-{
-    auto pq = currNode;
-    if (pq == nodes.end())
-        return 0;
-    ++currNode;
-    return *pq;
+{ queue *pq;
+
+    pq = pI->currNode;
+    if (pq == NULL)
+       return (NULL);
+    pI->currNode = pq->next;
+    return (pq->node);
 }
 
 
-/* Appends node @node to the end of the interval list @pI, updates currNode
- * if necessary, and removes the node from the header list @pqH if it is
- * there.  The interval header information is placed in the field
+static queue *appendNodeInt (queue *pqH, BB *node, interval *pI)
+/* Appends node node to the end of the interval list I, updates currNode
+ * if necessary, and removes the node from the header list H if it is 
+ * there.  The interval header information is placed in the field 
  * node->inInterval.
  * Note: nodes are added to the interval list in interval order (which
  * topsorts the dominance relation).                    */
-static void appendNodeInt (queue &pqH, BB *node, interval *pI)
-{
-    queue::iterator pq;        /* Pointer to current node of the list      */
+{ queue *pq,        /* Pointer to current node of the list      */
+         *prev;     /* Pointer to previous node in the list     */
 
     /* Append node if it is not already in the interval list */
-    pq = appendQueue (pI->nodes, node);
+    pq = appendQueue (&pI->nodes, node);
 
     /* Update currNode if necessary */
-    if (pI->currNode == pI->nodes.end())
-        pI->currNode = pq;
+    if (pI->currNode == NULL)
+       pI->currNode = pq;
 
-    /* Check header list for occurrence of node, if found, remove it
+    /* Check header list for occurrence of node, if found, remove it 
      * and decrement number of out-edges from this interval.    */
-    if (node->beenOnH && !pqH.empty())
+    if (node->beenOnH && pqH)
     {
-        auto found_iter=std::find(pqH.begin(),pqH.end(),node);
-        if(found_iter!=pqH.end())
-        {
-            pI->numOutEdges -= (uint8_t)(*found_iter)->inEdges.size() - 1;
-            pqH.erase(found_iter);
-        }
+       prev = pqH;
+       for (pq = prev; pq && pq->node != node; pq = pq->next)
+          prev = pq;
+       if (pq == prev)
+       {
+          pqH = pqH->next;
+          pI->numOutEdges -= (byte)pq->node->numInEdges - 1;
+       }
+       else if (pq)
+       {
+          prev->next = pq->next;
+          pI->numOutEdges -= (byte)pq->node->numInEdges - 1;
+       }
     }
+
     /* Update interval header information for this basic block */
     node->inInterval = pI;
+
+    return (pqH);
 }
 
 
-/* Finds the intervals of graph derivedGi->Gi and places them in the list
+static void findIntervals (derSeq *derivedGi)
+/* Finds the intervals of graph derivedGi->Gi and places them in the list 
  * of intervals derivedGi->Ii.
  * Algorithm by M.S.Hecht.                      */
-void derSeq_Entry::findIntervals (Function *c)
-{
-    interval *pI,        /* Interval being processed         */
-            *J;         /* ^ last interval in derivedGi->Ii */
-    BB *h,           /* Node being processed         */
-            *header,          /* Current interval's header node   */
-            *succ;            /* Successor basic block        */
-    int i;           /* Counter              */
-    queue H;            /* Queue of possible header nodes   */
-    boolT first = true;       /* First pass through the loop      */
-
-    appendQueue (H, Gi);  /* H = {first node of G} */
-    Gi->beenOnH = true;
-    Gi->reachingInt = BB::Create(0,"",c); /* ^ empty BB */
+{  interval *pI,        /* Interval being processed         */ 
+        *J;         /* ^ last interval in derivedGi->Ii */
+   BB *h,           /* Node being processed         */
+      *header,          /* Current interval's header node   */
+      *succ;            /* Successor basic block        */
+   Int i;           /* Counter              */
+   queue *H;            /* Queue of possible header nodes   */
+   boolT first = TRUE;       /* First pass through the loop      */
+
+    H = appendQueue (NULL, derivedGi->Gi);  /* H = {first node of G} */
+    derivedGi->Gi->beenOnH = TRUE;
+    derivedGi->Gi->reachingInt = allocStruc(BB);    /* ^ empty BB */
+	memset (derivedGi->Gi->reachingInt, 0, sizeof(BB));
 
     /* Process header nodes list H */
-    while (!H.empty())
+    while (nonEmpty (H))
     {
-        header = firstOfQueue (H);
-        pI = new interval;
-        pI->numInt = (uint8_t)numInt++;
-        if (first)               /* ^ to first interval  */
-            Ii = J = pI;
-        appendNodeInt (H, header, pI);   /* pI(header) = {header} */
-
-        /* Process all nodes in the current interval list */
-        while ((h = pI->firstOfInt()) != NULL)
-        {
-            /* Check all immediate successors of h */
-            for (i = 0; i < h->edges.size(); i++)
-            {
-                succ = h->edges[i].BBptr;
-                succ->inEdgeCount--;
-
-                if (succ->reachingInt == NULL)   /* first visit */
-                {
-                    succ->reachingInt = header;
-                    if (succ->inEdgeCount == 0)
-                        appendNodeInt (H, succ, pI);
-                    else if (! succ->beenOnH) /* out edge */
-                    {
-                        appendQueue (H, succ);
-                        succ->beenOnH = true;
-                        pI->numOutEdges++;
-                    }
-                }
-                else     /* node has been visited before */
-                    if (succ->inEdgeCount == 0)
-                    {
-                        if (succ->reachingInt == header || succ->inInterval == pI) /* same interval */
-                        {
-                            if (succ != header)
-                                appendNodeInt (H, succ, pI);
-                        }
-                        else            /* out edge */
-                            pI->numOutEdges++;
-                    }
-                    else if (succ != header && succ->beenOnH)
-                        pI->numOutEdges++;
+       header = firstOfQueue (&H);
+	   pI = allocStruc(interval);
+	   memset (pI, 0, sizeof(interval));
+       pI->numInt = (byte)numInt++;
+       if (first)               /* ^ to first interval  */
+          derivedGi->Ii = J = pI;
+       H = appendNodeInt (H, header, pI);   /* pI(header) = {header} */
+
+       /* Process all nodes in the current interval list */
+       while ((h = firstOfInt (pI)) != NULL)
+       { 
+         /* Check all immediate successors of h */
+         for (i = 0; i < h->numOutEdges; i++)
+         {
+               succ = h->edges[i].BBptr;
+               succ->inEdgeCount--;
+
+               if (succ->reachingInt == NULL)   /* first visit */
+               {
+              succ->reachingInt = header;
+              if (succ->inEdgeCount == 0) 
+                     H = appendNodeInt (H, succ, pI);
+              else if (! succ->beenOnH) /* out edge */
+              {
+                 appendQueue (&H, succ);
+                 succ->beenOnH = TRUE;
+                 pI->numOutEdges++;
+              }
+               }
+               else     /* node has been visited before */
+              if (succ->inEdgeCount == 0)
+              {
+                 if (succ->reachingInt == header || 
+                 succ->inInterval == pI) /* same interval */
+                 {
+                    if (succ != header)
+                                H = appendNodeInt (H, succ, pI);
+                 }
+                 else            /* out edge */
+                pI->numOutEdges++;
+              }
+              else if (succ != header && succ->beenOnH)
+                   pI->numOutEdges++;
             }
-        }
-
-        /* Link interval I to list of intervals */
-        if (! first)
-        {
-            J->next = pI;
-            J = pI;
-        }
-        else     /* first interval */
-            first = false;
+       }
+
+       /* Link interval I to list of intervals */
+       if (! first)
+       {
+          J->next = pI;
+          J = pI;
+       }
+       else     /* first interval */
+          first = FALSE;
     }
 }
 
 
-/* Displays the intervals of the graph Gi.              */
 static void displayIntervals (interval *pI)
-{
+/* Displays the intervals of the graph Gi.              */
+{ queue *nodePtr;
 
     while (pI)
     {
-        printf ("  Interval #: %ld\t#OutEdges: %ld\n", pI->numInt, pI->numOutEdges);
-        for(BB *node : pI->nodes)
-        {
-            if (node->correspInt == NULL)    /* real BBs */
-                printf ("    Node: %ld\n", node->begin()->loc_ip);
-            else             // BBs represent intervals
-                printf ("   Node (corresp int): %d\n", node->correspInt->numInt);
-        }
-        pI = pI->next;
+       nodePtr = pI->nodes;
+       printf ("  Interval #: %ld\t#OutEdges: %ld\n", 
+           pI->numInt, pI->numOutEdges);
+
+       while (nodePtr)
+       {
+          if (nodePtr->node->correspInt == NULL)    /* real BBs */
+             printf ("    Node: %ld\n", nodePtr->node->start);
+          else              /* BBs represent intervals */
+         printf ("   Node (corresp int): %d\n",
+             nodePtr->node->correspInt->numInt);
+          nodePtr = nodePtr->next;
+       }
+       pI = pI->next;
     }
 }
 
 
+static derSeq *newDerivedSeq()
 /* Allocates space for a new derSeq node. */
-static derSeq_Entry *newDerivedSeq()
-{
-    return new derSeq_Entry;
+{ derSeq *pder;
+
+	pder = allocStruc(derSeq);
+	memset (pder, 0, sizeof(derSeq));
+    return (pder);
 }
 
 
+static void freeQueue (queue **q)
 /* Frees the storage allocated for the queue q*/
-static void freeQueue (queue &q)
-{
-    q.clear();
+{ queue *queuePtr;
+
+    for (queuePtr = *q; queuePtr; queuePtr = *q)
+    {
+       *q = (*q)->next;
+       free (queuePtr);
+    }
 }
 
 
-/* Frees the storage allocated for the interval pI */
 static void freeInterval (interval **pI)
-{
-    interval *Iptr;
+/* Frees the storage allocated for the interval pI */
+{ interval *Iptr;
 
     while (*pI)
     {
-        (*pI)->nodes.clear();
-        Iptr = *pI;
-        *pI = (*pI)->next;
-        delete (Iptr);
+       freeQueue (&((*pI)->nodes));
+       Iptr = *pI;
+       *pI = (*pI)->next;
+       free (Iptr);
     }
 }
 
 
-/* Frees the storage allocated by the derived sequence structure, except
+void freeDerivedSeq(derSeq *derivedG)
+/* Frees the storage allocated by the derived sequence structure, except 
  * for the original graph cfg (derivedG->Gi).               */
-void freeDerivedSeq(derSeq &derivedG)
-{
-    derivedG.clear();
-}
-derSeq_Entry::~derSeq_Entry()
-{
-    freeInterval (&Ii);
-    //    if(Gi && Gi->nodeType == INTERVAL_NODE)
-    //        freeCFG (Gi);
-}
+{ derSeq *derivedGi;
 
-/* Finds the next order graph of derivedGi->Gi according to its intervals
- * (derivedGi->Ii), and places it in derivedGi->next->Gi.       */
-bool Function::nextOrderGraph (derSeq &derivedGi)
-{
-    interval *Ii;   /* Interval being processed         */
-    BB *BBnode,     /* New basic block of intervals         */
-            *curr,      /* BB being checked for out edges       */
-            *succ       /* Successor node               */
-            ;
-    //queue *listIi;    /* List of intervals                */
-    int i,        /* Index to outEdges array          */
-        j;        /* Index to successors              */
-    boolT   sameGraph; /* Boolean, isomorphic graphs           */
-
-    /* Process Gi's intervals */
-    derSeq_Entry &prev_entry(derivedGi.back());
-    derivedGi.push_back(derSeq_Entry());
-    derSeq_Entry &new_entry(derivedGi.back());
-    Ii = prev_entry.Ii;
-    sameGraph = true;
-    BBnode = 0;
-    std::vector<BB *> bbs;
-    while (Ii)
+    while (derivedG)
     {
-        i = 0;
-        bbs.push_back(BB::Create(-1, -1, INTERVAL_NODE, Ii->numOutEdges, this));
-        BBnode = bbs.back();
-        BBnode->correspInt = Ii;
-        const queue &listIi(Ii->nodes);
-
-        /* Check for more than 1 interval */
-        if (sameGraph && (listIi.size()>1))
-            sameGraph = false;
+       freeInterval (&(derivedG->Ii));
+       if (derivedG->Gi->nodeType == INTERVAL_NODE)
+        freeCFG (derivedG->Gi);
+       derivedGi = derivedG;
+       derivedG  = derivedG->next;
+       free (derivedGi);
+    }
+}
 
-        /* Find out edges */
 
-        if (BBnode->edges.size() > 0)
-        {
-            for(BB *curr :  listIi)
-            {
-                for (j = 0; j < curr->edges.size(); j++)
-                {
-                    succ = curr->edges[j].BBptr;
-                    if (succ->inInterval != curr->inInterval)
-                        BBnode->edges[i++].intPtr = succ->inInterval;
-                }
-            }
-        }
+static boolT nextOrderGraph (derSeq *derivedGi)
+/* Finds the next order graph of derivedGi->Gi according to its intervals 
+ * (derivedGi->Ii), and places it in derivedGi->next->Gi.       */
+{ interval *Ii;     /* Interval being processed         */
+  BB *BBnode,       /* New basic block of intervals         */
+     *curr,     /* BB being checked for out edges       */
+     *succ,     /* Successor node               */
+     derInt;
+  queue *listIi;    /* List of intervals                */
+  Int i,        /* Index to outEdges array          */
+      j;        /* Index to successors              */
+  boolT   sameGraph; /* Boolean, isomorphic graphs           */
 
-        /* Next interval */
-        Ii = Ii->next;
+    /* Process Gi's intervals */
+    derivedGi->next = newDerivedSeq();
+    Ii = derivedGi->Ii;
+    sameGraph = TRUE;
+    derInt.next = NULL;
+    BBnode = &derInt;
+
+    while (Ii) {
+       i = 0;
+       BBnode = newBB (BBnode, -1, -1, INTERVAL_NODE, Ii->numOutEdges, NULL);
+       BBnode->correspInt = Ii;
+       listIi = Ii->nodes;
+
+       /* Check for more than 1 interval */
+       if (sameGraph && listIi->next)
+          sameGraph = FALSE;
+
+       /* Find out edges */
+       if (BBnode->numOutEdges > 0)
+          while (listIi) {
+         curr = listIi->node;
+         for (j = 0; j < curr->numOutEdges; j++) {
+             succ = curr->edges[j].BBptr;
+             if (succ->inInterval != curr->inInterval)
+                BBnode->edges[i++].intPtr = succ->inInterval;
+         }
+             listIi = listIi->next;
+          }
+
+       /* Next interval */
+       Ii = Ii->next;
     }
 
     /* Convert list of pointers to intervals into a real graph.
      * Determines the number of in edges to each new BB, and places it
      * in numInEdges and inEdgeCount for later interval processing. */
-    curr = new_entry.Gi = bbs.front();
-    for(BB *curr : bbs)
-    {
-        for(TYPEADR_TYPE &edge : curr->edges)
-        {
-            BBnode = new_entry.Gi;    /* BB of an interval */
-            auto iter= std::find_if(bbs.begin(),bbs.end(),
-                                    [&edge](BB *node)->bool { return edge.intPtr==node->correspInt;});
-            if(iter==bbs.end())
-                fatalError (INVALID_INT_BB);
-            edge.BBptr = *iter;
-            (*iter)->inEdges.push_back((BB *)nullptr);
-            (*iter)->inEdgeCount++;
-        }
+    curr = derivedGi->next->Gi = derInt.next;
+    while (curr) {
+       for (i = 0; i < curr->numOutEdges; i++) {
+           BBnode = derivedGi->next->Gi;    /* BB of an interval */
+           while (BBnode && curr->edges[i].intPtr != BBnode->correspInt)
+          BBnode = BBnode->next;
+           if (BBnode) {
+          curr->edges[i].BBptr = BBnode;
+          BBnode->numInEdges++;
+          BBnode->inEdgeCount++;
+           }
+           else
+          fatalError (INVALID_INT_BB);
+       }
+       curr = curr->next;
     }
     return (boolT)(! sameGraph);
 }
 
 
 
+static byte findDerivedSeq (derSeq *derivedGi)
 /* Finds the derived sequence of the graph derivedG->Gi (ie. cfg).
  * Constructs the n-th order graph and places all the intermediate graphs
  * in the derivedG list sequence.                   */
-uint8_t Function::findDerivedSeq (derSeq &derivedGi)
-{
-    BB *Gi;      /* Current derived sequence graph       */
+{  BB *Gi;      /* Current derived sequence graph       */
 
-    derSeq::iterator iter=derivedGi.begin();
-    Gi = iter->Gi;
+    Gi = derivedGi->Gi;
     while (! trivialGraph (Gi))
     {
-        /* Find the intervals of Gi and place them in derivedGi->Ii */
-        iter->findIntervals(this);
-
-        /* Create Gi+1 and check if it is equivalent to Gi */
-        if (! nextOrderGraph (derivedGi))
-            break;
-        ++iter;
-        Gi = iter->Gi;
-        stats.nOrder++;
+         /* Find the intervals of Gi and place them in derivedGi->Ii */
+         findIntervals (derivedGi);
+
+         /* Create Gi+1 and check if it is equivalent to Gi */
+         if (! nextOrderGraph (derivedGi))
+            break; 
+
+         derivedGi = derivedGi->next;
+         Gi = derivedGi->Gi;
+         stats.nOrder++;
     }
 
     if (! trivialGraph (Gi))
     {
-        ++iter;
-        derivedGi.erase(iter,derivedGi.end()); /* remove Gi+1 */
-        //        freeDerivedSeq(derivedGi->next);
-        //        derivedGi->next = NULL;
-        return false;
+        freeDerivedSeq(derivedGi->next);    /* remove Gi+1 */
+        derivedGi->next = NULL;
+        return FALSE;
     }
-    derivedGi.back().findIntervals (this);
-    return true;
+    findIntervals (derivedGi);
+    return TRUE;
 }
 
+
+static void nodeSplitting (BB *G)
 /* Converts the irreducible graph G into an equivalent reducible one, by
  * means of node splitting.  */
-static void nodeSplitting (std::list<BB *> &G)
 {
-    fprintf(stderr,"Attempt to perform node splitting: NOT IMPLEMENTED\n");
+
 }
 
+
+
+void displayDerivedSeq(derSeq *derGi)
 /* Displays the derived sequence and intervals of the graph G */
-void derSeq::display()
 {
-    int n = 1;      /* Derived sequence number */
+    Int n = 1;      /* Derived sequence number */
     printf ("\nDerived Sequence Intervals\n");
-    derSeq::iterator iter=this->begin();
-    while (iter!=this->end())
+    while (derGi)
     {
-        printf ("\nIntervals for G%lX\n", n++);
-        displayIntervals (iter->Ii);
-        ++iter;
+       printf ("\nIntervals for G%lX\n", n++);
+       displayIntervals (derGi->Ii);
+       derGi = derGi->next;
     }
 }
 
 
+void checkReducibility (PPROC pProc, derSeq **derivedG)
 /* Checks whether the control flow graph, cfg, is reducible or not.
  * If it is not reducible, it is converted into an equivalent reducible
  * graph by node splitting.  The derived sequence of graphs built from cfg
  * are returned in the pointer *derivedG.
  */
-derSeq * Function::checkReducibility()
-{
-    derSeq * der_seq;
-    uint8_t    reducible;  /* Reducible graph flag     */
+{ byte    reducible;            /* Reducible graph flag     */
 
     numInt = 1;         /* reinitialize no. of intervals*/
-    stats.nOrder = 1;   /* nOrder(cfg) = 1      */
-    der_seq = new derSeq;
-    der_seq->resize(1);
-    der_seq->back().Gi = m_cfg.front();
-    reducible = findDerivedSeq(*der_seq);
-
-    if (! reducible)
-    {
-        flg |= GRAPH_IRRED;
-        nodeSplitting (m_cfg);
+    stats.nOrder = 1;       /* nOrder(cfg) = 1      */
+    *derivedG = newDerivedSeq();
+    (*derivedG)->Gi = pProc->cfg;
+    reducible = findDerivedSeq(*derivedG);
+
+    if (! reducible) {
+       pProc->flg |= GRAPH_IRRED;
+       nodeSplitting (pProc->cfg);
     }
-    return der_seq;
 }
 

File diff suppressed because it is too large
+ 587 - 698
src/scanner.cpp


+ 506 - 118
src/symtab.cpp

@@ -10,7 +10,7 @@
 \* * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
 /* This file implements a symbol table with a symbolic name, a symbol value
-    (uint16_t), and a procedure number. Two tables are maintained, to be able to
+    (word), and a procedure number. Two tables are maintained, to be able to
     look up by name or by value. Pointers are used for the duplicated symbolic
     name to save space. Both tables have the same structure.
     The hash tables automatically expand when they get 90% full; they are
@@ -19,176 +19,564 @@
     Linear probing is used, due to the difficulty of implementing (e.g.)
     quadratic probing with a variable table size.
 */
-#include <cstdio>
-#include <cassert>
-#include <cstdlib>
-#include <cstring>
-#include <unordered_map>
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 #include "dcc.h"
 #include "symtab.h"
 
 #define TABLESIZE 16                /* Number of entries added each expansion */
-/* Probably has to be a power of 2 */
+                                    /* Probably has to be a power of 2 */
 #define STRTABSIZE 256              /* Size string table is inc'd by */
-#define NIL ((uint16_t)-1)
-using namespace std;
+#define NIL ((word)-1)
+
+
+
+static word numEntry;               /* Number of entries in this table */
+static word tableSize;              /* Size of the table (entries) */
+static SYMTABLE *symTab;            /* Pointer to the symbol hashed table */
+static SYMTABLE *valTab;            /* Pointer to the value  hashed table */
+
 static  char *pStrTab;              /* Pointer to the current string table */
 static  int   strTabNext;           /* Next free index into pStrTab */
-namespace std
-{
-template<>
-struct hash<SYMTABLE> : public unary_function<const SYMTABLE &,size_t>
-{
-    size_t operator()(const SYMTABLE & key) const
-    {
-        uint16_t h = 0;
-        h = (uint16_t)(key.symOff ^ (key.symOff >> 8));
-        return h;
-    }
 
-};
-}
 static  tableType curTableType; /* Which table is current */
-struct TABLEINFO_TYPE
+typedef struct _tableInfo
 {
-    TABLEINFO_TYPE()
-    {
-        symTab=valTab=0;
-    }
-    //void deleteVal(uint32_t symOff, Function *symProc, boolT bSymToo);
-    void create(tableType type);
-    void destroy();
-private:
+    SYMTABLE *symTab;
+    SYMTABLE *valTab;
+    word      numEntry;
+    word      tableSize;
+} TABLEINFO_TYPE;
 
-    SYMTABLE *symTab;   /* Pointer to the symbol hashed table */
-    SYMTABLE *valTab;   /* Pointer to the value  hashed table */
-    uint16_t      numEntry; /* Number of entries in this table */
-    uint16_t      tableSize;/* Size of the table (entries) */
-    unordered_map<string,SYMTABLE> z;
-    unordered_map<SYMTABLE,string> z2;
-};
+TABLEINFO_TYPE tableInfo[NUM_TABLE_TYPES];   /* Array of info about tables */
 
-static TABLEINFO_TYPE tableInfo[NUM_TABLE_TYPES];   /* Array of info about tables */
-static TABLEINFO_TYPE currentTabInfo;
 
-/* Create a new symbol table. Returns "handle" */
-void TABLEINFO_TYPE::create(tableType type)
-{
-    switch(type)
-    {
-        case Comment:
-            numEntry  = 0;
-            tableSize = TABLESIZE;
-            valTab = new SYMTABLE [TABLESIZE];
-            symTab = 0;
-            break;
-        case Label:
-            currentTabInfo.numEntry  = 0;
-            currentTabInfo.tableSize = TABLESIZE;
-            currentTabInfo.symTab = new SYMTABLE [TABLESIZE];
-            currentTabInfo.valTab = new SYMTABLE [TABLESIZE];
-            break;
-    }
-}
+/* Local prototypes */
+static  void    expandSym(void);
 
+/* Create a new symbol table. Returns "handle" */
 void createSymTables(void)
 {
     /* Initilise the comment table */
     /* NB - there is no symbol hashed comment table */
-    currentTabInfo.create(Comment);
-    tableInfo[Comment] = currentTabInfo;
 
+    numEntry  = 0;
+    tableSize = TABLESIZE;
+    valTab = (SYMTABLE*)allocMem(sizeof(SYMTABLE) * TABLESIZE);
+    memset(valTab, 0, sizeof(SYMTABLE) * TABLESIZE);
+
+    tableInfo[Comment].symTab = 0;
+    tableInfo[Comment].valTab = valTab;
+    tableInfo[Comment].numEntry = numEntry;
+    tableInfo[Comment].tableSize = tableSize;
+    
     /* Initialise the label table */
-    currentTabInfo.create(Label);
+    numEntry  = 0;
+    tableSize = TABLESIZE;
+    symTab = (SYMTABLE*)allocMem(sizeof(SYMTABLE) * TABLESIZE);
+    memset(symTab, 0, sizeof(SYMTABLE) * TABLESIZE);
+
+    valTab = (SYMTABLE*)allocMem(sizeof(SYMTABLE) * TABLESIZE);
+    memset(valTab, 0, sizeof(SYMTABLE) * TABLESIZE);
 
-    tableInfo[Label] = currentTabInfo;
+    tableInfo[Label].symTab = symTab;
+    tableInfo[Label].valTab = valTab;
+    tableInfo[Label].numEntry = numEntry;
+    tableInfo[Label].tableSize = tableSize;
     curTableType = Label;
 
     /* Now the string table */
     strTabNext = 0;
-    pStrTab = new char[STRTABSIZE];
+    pStrTab = (char *)allocMem(STRTABSIZE);
 
+    tableInfo[Label].symTab = symTab;
+    tableInfo[Label].valTab = valTab;
+    tableInfo[Label].numEntry = numEntry;
+    tableInfo[Label].tableSize = tableSize;
     curTableType = Label;
 
 }
 
-void selectTable(tableType tt)
+void
+selectTable(tableType tt)
 {
-    if (curTableType == tt)
-        return; /* Nothing to do */
-    currentTabInfo = tableInfo[tt];
+    if (curTableType == tt) return; /* Nothing to do */
+
+    symTab   = tableInfo[tt].symTab;
+    valTab   = tableInfo[tt].valTab;
+    numEntry = tableInfo[tt].numEntry;
+    tableSize= tableInfo[tt].tableSize;
     curTableType = tt;
 }
-void TABLEINFO_TYPE::destroy()
-{
-    delete [] symTab; // The symbol hashed label table
-    delete [] valTab; // And the value hashed label table
-}
+
 void destroySymTables(void)
 {
     selectTable(Label);
-    currentTabInfo.destroy();
+    free(symTab);                   /* The symbol hashed label table */
+    free(valTab);                   /* And the value hashed label table */
     selectTable(Comment);
-    currentTabInfo.destroy();
+    free(valTab);                   /* And the value hashed comment table */
 }
 
-/* Using the value, read the symbolic name */
-boolT readVal(std::ostringstream &symName, uint32_t symOff, Function * symProc)
+
+/* Hash the symbolic name */
+word symHash(char *name, word *pre)
 {
-    return false; // no symbolic names for now
+    int i;
+    word h = 0;
+    char ch;
+
+    for (i=0; i < (int)strlen(name); i++)
+    {
+        ch = name[i];
+        h = (h << 2) ^ ch;
+        h += (ch >> 2) + (ch << 5);
+    }
+
+    *pre = h;                       /* Pre modulo hash value */
+    return h % tableSize;           /* Post modulo hash value */
 }
 
-/* Updates the type of the symbol in the symbol table.  The size is updated
- * if necessary (0 means no update necessary).      */
-void SYMTAB::updateSymType (uint32_t symbol,const TypeContainer &tc)
+/* Hash the symOff and symProc fields */
+/* Note: for the time being, there no use is made of the symProc field */
+word
+valHash(dword symOff, PPROC symProc, word *pre)
 {
-    int i;
-    auto iter=findByLabel(symbol);
-    if(iter==end())
-        return;
-    iter->type = tc.m_type;
-    if (tc.m_size != 0)
-        iter->size = tc.m_size;
+    word h = 0;
+
+    h = (word)(symOff ^ (symOff >> 8));
+
+    *pre = h;                       /* Pre modulo hash value */
+    return h % tableSize;           /* Post modulo hash value */
 }
 
-/* Creates an entry in the global symbol table (symtab) if the variable
- * is not there yet.  If it is part of the symtab, the size of the variable
- * is checked and updated if the old size was less than the new size (ie.
- * the maximum size is always saved).   */
-//TODO: SYMTAB::updateGlobSym should be renamed to insertOrUpdateSym
-SYM * SYMTAB::updateGlobSym (uint32_t operand, int size, uint16_t duFlag,bool &inserted_new)
+
+void
+enterSym(char *symName, dword symOff, PPROC symProc, boolT bSymToo)
 {
-    /* Check for symbol in symbol table */
-    auto iter = findByLabel(operand);
-    if(iter!=end())
+    word h, pre, j;
+
+    if ((numEntry / 9 * 10) >= tableSize)
+    {
+        /* Table is full. Expand it */
+        expandSym();
+    }
+
+    /* Enter it into the value hashed table first */
+    h = valHash(symOff, symProc, &pre);     /* Ideal spot for this entry */
+    if (valTab[h].symProc == 0)             /* Collision? */
+    {
+        /* No. Just insert here */
+        valTab[h].pSymName= symName;        /* Symbol name ptr */
+        valTab[h].symOff    = symOff;       /* Offset of the symbol */
+        valTab[h].symProc   = symProc;      /* Symbol's proc num */
+        valTab[h].preHash = pre;            /* Pre modulo hash value */
+        valTab[h].postHash= h;              /* Post modulo hash value */
+        valTab[h].nextOvf = NIL;            /* No overflow */
+        valTab[h].prevOvf = NIL;            /* No back link */
+    }
+    else
     {
-        if(iter->size<size)
-            iter->size = size;
-        inserted_new=false;
-        return &(*iter);
+        /* Linear probing, for now */
+        j = (h+1) % tableSize;
+        while (j != h)
+        {
+            if (valTab[j].symProc == 0)
+            {
+                /* Insert here */
+                valTab[j].pSymName= symName;    /* Symbol name ptr */
+                valTab[j].symOff  = symOff;     /* Offset of the symbol */
+                valTab[j].symProc = symProc;    /* Symbol's proc num */
+                valTab[j].preHash = pre;        /* Pre modulo hash value */
+                valTab[j].postHash= h;          /* Post modulo hash value */
+                /* Insert after the primary entry in the table */
+                valTab[j].nextOvf = valTab[h].nextOvf;
+                valTab[h].nextOvf = j;
+                valTab[j].prevOvf = h;          /* The backlink */
+                break;
+            }
+            else
+            {
+                /* Probe further */
+                j = (j+1) % tableSize;
+            }
+        }
+        if (j == h)
+        {
+            printf("enterSym: val table overflow!\n");
+            exit(1);
+        }
     }
 
-    /* New symbol, not in symbol table */
-    SYM v;
-    char buf[32]={};
-    sprintf (buf, "var%05X", operand);
-    v.name  = buf;
-    v.label = operand;
-    v.size  = size;
-    v.type  = TypeContainer::defaultTypeForSize(size);
-    if (duFlag == eDuVal::USE)  /* must already have init value */
+    /* Now enter into the symbol hashed table as well, if reqd */
+    if (!bSymToo) return;
+    h = symHash(symName, &pre);             /* Ideal spot for this entry */
+    if (symTab[h].pSymName == 0)            /* Collision? */
     {
-        v.duVal.use =1; // USEVAL;
-        v.duVal.val =1;
+        /* No. Just insert here */
+        symTab[h].pSymName= symName;        /* Symbol name ptr */
+        symTab[h].symOff  = symOff;         /* Offset of the symbol */
+        symTab[h].symProc = symProc;        /* Symbol's proc num */
+        symTab[h].preHash = pre;            /* Pre modulo hash value */
+        symTab[h].postHash= h;              /* Post modulo hash value */
+        symTab[h].nextOvf = NIL;            /* No overflow */
+        symTab[h].prevOvf = NIL;            /* No back link */
     }
     else
     {
-        v.duVal.setFlags(duFlag);
+        /* Linear probing, for now */
+        j = (h+1) % tableSize;
+        while (j != h)
+        {
+            if (symTab[j].pSymName == 0)
+            {
+                /* Insert here */
+                symTab[j].pSymName= symName;    /* Symbol name ptr */
+                symTab[j].symOff  = symOff;     /* Offset of the symbol */
+                symTab[j].symProc = symProc;    /* Symbol's proc num */
+                symTab[j].preHash = pre;        /* Pre modulo hash value */
+                symTab[j].postHash= h;          /* Post modulo hash value */
+                /* Insert after the primary entry in the table */
+                symTab[j].nextOvf = symTab[h].nextOvf;
+                symTab[h].nextOvf = j;
+                symTab[j].prevOvf = h;          /* The backlink */
+                break;
+            }
+            else
+            {
+                /* Probe further */
+                j = (j+1) % tableSize;
+            }
+        }
+        if (j == h)
+        {
+            printf("enterSym: sym table overflow!\n");
+            exit(1);
+        }
+    }
+
+}
+
+
+boolT
+findSym(char *symName, word *pIndex)
+{
+    word h, j, pre;
+
+    h = symHash(symName, &pre);
+    j = h;
+    do
+    {
+        if (symTab[j].pSymName == 0)
+        {
+            return FALSE;                   /* No entry at all */
+        }
+        if (strcmp(symName, symTab[j].pSymName) == 0)
+        {
+            *pIndex = j;
+            return TRUE;                    /* Symbol found */
+        }
+        j = symTab[j].nextOvf;              /* Follow the chain */
     }
-    push_back(v);
-    inserted_new=true;
-    return (&back());
+    while (j != NIL);
+    return FALSE;                           /* End of chain */
 }
 
-//template<> class SymbolTableCommon<SYM>;
-//template<> class SymbolTableCommon<STKSYM>;
+/* Find symbol by value */
+boolT
+findVal(dword symOff, PPROC symProc, word *pIndex)
+{
+    word h, j, pre;
+
+    h = valHash(symOff, symProc, &pre);
+    j = h;
+    do
+    {
+        if (valTab[j].symProc == 0)
+        {
+            return FALSE;                   /* No entry at all */
+        }
+        if ((valTab[j].symOff == symOff)
+            /*&& (valTab[j].symProc == symProc)*/)
+        {
+            *pIndex = j;
+            return TRUE;                    /* Symbol found */
+        }
+        j = valTab[j].nextOvf;              /* Follow the chain */
+    }
+    while (j != NIL);
+    return FALSE;                           /* End of chain */
+}
+
+word
+findBlankSym(char *symName)
+{
+    word h, j, pre;
+
+    h = symHash(symName, &pre);
+    j = h;
+    do
+    {
+        if (symTab[j].pSymName == 0)
+        {
+            return j;                   /* Empty entry. Terminate probing */
+        }
+        j = (++j) % tableSize;              /* Linear probing */
+    }
+    while (j != h);
+    printf("Could not find blank entry in table! Num entries is %ld of %ld\n",
+        (long)numEntry, (long)tableSize);
+	return 0;
+}
+
+/* Using the symbolic name, read the value */
+boolT
+readSym(char *symName, dword *pSymOff, PPROC *pSymProc)
+{
+    word i;
+
+    if (!findSym(symName, &i))
+    {
+        return FALSE;
+    }
+    *pSymOff = symTab[i].symOff;
+    *pSymProc= symTab[i].symProc;
+    return TRUE;
+}
+
+/* Using the value, read the symbolic name */
+boolT
+readVal(char *symName, dword symOff, PPROC symProc)
+{
+    word i;
+
+    if (!findVal(symOff, symProc, &i))
+    {
+        return FALSE;
+    }
+    strcpy(symName, valTab[i].pSymName);
+    return TRUE;
+}
+
+
+
+/*  A doubly linked list of entries belonging to the same hash bucket is
+    maintained, to prevent the need for many entries to be moved when deleting
+    an entry. It is implemented with indexes, and is not an open hashing system.
+    Symbols are deleted from both hash tables.
+*/
+
+/* Known limitation: strings are never deleted from the string table */
+
+void
+deleteSym(char *symName)
+{
+    word i, j, back;
+    dword symOff;
+    PPROC symProc;
+
+    /* Delete from symbol hashed table first */
+    if (!findSym(symName, &i))
+    {
+        printf("Could not delete non existant symbol name %s\n", symName);
+        exit(1);
+    }
+    symOff = symTab[i].symOff;              /* Remember these for valTab */
+    symProc= symTab[i].symProc;
+    j = symTab[i].nextOvf;                  /* Look at next overflowed entry */
+    
+    if (j == NIL)                           /* Any overflows? */
+    {
+        /* No, so we just wipe out this record. Must NIL the pointer of
+            the previous record, however */
+        symTab[symTab[i].prevOvf].nextOvf = NIL;
+        j = i;                              /* So we wipe out the current name */
+    }
+    else 
+    {
+        /* Yes, move this entry to this vacated spot. Note that the nextOvf
+            field will still point to the next record in the overflow chain,
+            but we need to preserve the backlink for adjusting the current
+            item's backlink */
+        back = symTab[j].prevOvf;
+        memcpy(&symTab[i], &symTab[j], sizeof(SYMTABLE));
+        symTab[i].prevOvf = back;
+    }
+    /* And now mark the vacated record as empty */
+    symTab[j].pSymName = 0;             /* Rub out the name */
+
+    
+    /* Delete from value hashed table */
+    if (!findVal(symOff, symProc, &i))
+    {
+        printf("Could not delete non existant symbol off %04X proc %d\n",
+            symOff, symProc);
+        exit(1);
+    }
+    j = valTab[i].nextOvf;              /* Look at next overflowed entry */
+    
+    if (j == NIL)                       /* Any overflows? */
+    {
+        /* No, so we just wipe out this record. Must NIL the pointer of
+            the previous record, however */
+        valTab[valTab[i].prevOvf].nextOvf = NIL;
+        j = i;                          /* So we wipe out the current entry */
+    }
+    else 
+    {
+        /* Yes, move this entry to this vacated spot. Note that the nextOvf
+            field will still point to the next record in the overflow chain,
+            but we need to preserve the backlink for adjusting the current
+            item's backlink */
+        back = valTab[j].prevOvf;
+        memcpy(&valTab[i], &valTab[j], sizeof(SYMTABLE));
+        valTab[i].prevOvf = back;
+    }
+    /* And now mark the vacated record as empty */
+    valTab[j].symProc = 0;          /* Rub out the entry */
+}
+
+
+void
+deleteVal(dword symOff, PPROC symProc, boolT bSymToo)
+{
+    word i, j, back;
+    char *symName;
+
+    /* Delete from value hashed table */
+    if (!findVal(symOff, symProc, &i))
+    {
+        printf("Could not delete non existant symbol off %04X proc %p\n",
+            symOff, symProc);
+        exit(1);
+    }
+    symName = symTab[i].pSymName;       /* Remember this for symTab */
+    j = valTab[i].nextOvf;              /* Look at next overflowed entry */
+    
+    if (j == NIL)                       /* Any overflows? */
+    {
+        /* No, so we just wipe out this record. Must NIL the pointer of
+            the previous record, however */
+        valTab[valTab[i].prevOvf].nextOvf = NIL;
+        j = i;                          /* So we wipe out the current entry */
+    }
+    else 
+    {
+        /* Yes, move this entry to this vacated spot. Note that the nextOvf
+            field will still point to the next record in the overflow chain,
+            but we need to preserve the backlink for adjusting the current
+            item's backlink */
+        back = valTab[j].prevOvf;
+        memcpy(&valTab[i], &valTab[j], sizeof(SYMTABLE));
+        valTab[i].prevOvf = back;
+    }
+    /* And now mark the vacated record as empty */
+    valTab[j].symProc = 0;          /* Rub out the entry */
+
+    /* If requested, delete from symbol hashed table now */
+    if (!bSymToo) return;
+    if (!findSym(symName, &i))
+    {
+        printf("Could not delete non existant symbol name %s\n", symName);
+        exit(1);
+    }
+    j = symTab[i].nextOvf;                  /* Look at next overflowed entry */
+    
+    if (j == NIL)                           /* Any overflows? */
+    {
+        /* No, so we just wipe out this record. Must NIL the pointer of
+            the previous record, however */
+        symTab[symTab[i].prevOvf].nextOvf = NIL;
+        j = i;                              /* So we wipe out the current name */
+    }
+    else 
+    {
+        /* Yes, move this entry to this vacated spot. Note that the nextOvf
+            field will still point to the next record in the overflow chain,
+            but we need to preserve the backlink for adjusting the current
+            item's backlink */
+        back = symTab[j].prevOvf;
+        memcpy(&symTab[i], &symTab[j], sizeof(SYMTABLE));
+        symTab[i].prevOvf = back;
+    }
+    /* And now mark the vacated record as empty */
+    symTab[j].pSymName = 0;             /* Rub out the name */
+    
+}
+
+static void
+expandSym(void)
+{
+    word i, j, n, newPost;
+
+    printf("\nResizing table...\r");
+    /* We double the table size each time, so on average only half of the
+        entries move to the new half. This works because we are effectively
+        shifting the "binary point" of the hash value to the left each time,
+        thereby leaving the number unchanged or adding an MSBit of 1. */
+    tableSize <<= 2;
+    symTab = (SYMTABLE*)reallocVar(symTab, tableSize * sizeof(SYMTABLE));
+    memset (&symTab[tableSize/2], 0, (tableSize/2) * sizeof(SYMTABLE));
+
+    /* Now we have to move some of the entries to take advantage of the extra
+        space */
+
+    for (i=0; i < numEntry; i++)
+    {
+        newPost = symTab[i].preHash % tableSize;
+        if (newPost != symTab[i].postHash)
+        {
+            /* This entry is now in the wrong place. Copy it to the new position,
+                then delete it. */
+            j = findBlankSym(symTab[i].pSymName);
+            memcpy(&symTab[j], &symTab[i], sizeof(SYMTABLE));
+            /* Correct the post hash value */
+            symTab[j].postHash = newPost;
+
+            /* Now adjust links */
+            n = symTab[j].prevOvf;
+            if (n != NIL)
+            {
+                symTab[n].nextOvf = j;
+            }
+
+            n = symTab[j].nextOvf;
+            if (n != NIL)
+            {
+                symTab[n].prevOvf = j;
+            }
+            
+            /* Mark old position as deleted */
+            symTab[i].pSymName = 0;
+        }
+    }
+}
+
+/* This function adds to the string table. At this stage, strings are not
+    deleted */
+char *
+addStrTbl(char *pStr)
+{
+    char *p;
+
+    if ((strTabNext + strlen(pStr) + 1) >= STRTABSIZE)
+    {
+        /* We can't realloc the old string table pointer, since that will
+            potentially move the string table, and pointers will be invalid.
+            So we realloc this one to its present usage (hopefully it won't
+            move), and allocate a new one */
+        if (reallocVar((void *)pStrTab, strTabNext) != pStrTab)
+		{
+			printf("Damn it! String table moved on shrinking!\n");
+			exit(1);
+		}
+        pStrTab = (char *)allocMem(STRTABSIZE);
+        strTabNext = 0;
+    }
+    p = strcpy(&pStrTab[strTabNext], pStr);
+    strTabNext += strlen(pStr) +1;
+    return p;
+}

+ 0 - 14
src/tests/comwrite.cpp

@@ -1,14 +0,0 @@
-#include "dcc.h"
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-
-TEST(CowriteTest, HandlesZeroInput) {
-  EXPECT_EQ(1, 1);
-}
-
-int main(int argc, char** argv) {
-  // The following line must be executed to initialize Google Mock
-  // (and Google Test) before running the tests.
-  ::testing::InitGoogleMock(&argc, argv);
-  return RUN_ALL_TESTS();
-}

+ 120 - 70
src/udm.cpp

@@ -4,104 +4,154 @@
  *   that just plays with abstract cfg's and intervals and such like.
  * (C) Cristina Cifuentes
  ****************************************************************************/
-#include <list>
-#include <cassert>
-#include <stdio.h>
+
 #include "dcc.h"
-#include "disassem.h"
-#include "project.h"
+#include <stdio.h>
 
-extern Project g_proj;
-static void displayCFG(Function * pProc);
-static void displayDfs(BB * pBB);
+static void displayCFG(PPROC pProc);
+static void displayDfs(PBB pBB);
 
 /****************************************************************************
  * udm
  ****************************************************************************/
-void Function::buildCFG(Disassembler &ds)
-{
-    if(flg & PROC_ISLIB)
-        return; // Ignore library functions
-    createCFG();
-    if (option.VeryVerbose)
-        displayCFG();
+void udm(void)
+{   PPROC   pProc;
+    derSeq *derivedG;
 
-    compressCFG(); // Remove redundancies and add in-edge information
+	/* Build the control flow graph, find idioms, and convert low-level
+	 * icodes to high-level ones */
+    for (pProc = pLastProc; pProc; pProc = pProc->prev) 
+	{
 
-    if (option.asm2)
-    {
-        ds.disassem(this); // Print 2nd pass assembler listing
-    }
+		if (pProc->flg & PROC_ISLIB) 
+			continue;         /* Ignore library functions */
 
-    /* Idiom analysis and propagation of long type */
-    lowLevelAnalysis();
+        /* Create the basic control flow graph */
+        pProc->cfg = createCFG(pProc);
+        if (option.VeryVerbose)
+            displayCFG(pProc);
 
-    /* Generate HIGH_LEVEL icodes whenever possible */
-    highLevelGen();
-}
-void Function::controlFlowAnalysis()
-{
-    if (flg & PROC_ISLIB)
-        return;         /* Ignore library functions */
-    derSeq *derivedG=0;
+        /* Remove redundancies and add in-edge information */
+        compressCFG(pProc);
 
-    /* Make cfg reducible and build derived sequences */
-    derivedG=checkReducibility();
+        /* Print 2nd pass assembler listing */
+        if (option.asm2)
+            disassem(2, pProc);
 
-    if (option.VeryVerbose)
-        derivedG->display();
+		/* Idiom analysis and propagation of long type */
+		lowLevelAnalysis (pProc);
 
-    /* Structure the graph */
-    structure(derivedG);
+		/* Generate HIGH_LEVEL icodes whenever possible */
+		highLevelGen (pProc);
+	}
 
-    /* Check for compound conditions */
-    compoundCond ();
+    /* Data flow analysis - eliminate condition codes, extraneous registers
+	 * and intermediate instructions.  Find expressions by forward
+	 * substitution algorithm */
+    dataFlow (pProcList, 0); 
 
-    if (option.verbose)
-    {
-        printf("\nDepth first traversal - Proc %s\n", name.c_str());
-        m_cfg.front()->displayDfs();
-    }
+	/* Control flow analysis - structuring algorithm */
+    for (pProc = pLastProc; pProc; pProc = pProc->prev) 
+	{
+        
+		if (pProc->flg & PROC_ISLIB) 
+			continue;         /* Ignore library functions */
 
-    /* Free storage occupied by this procedure */
-    freeDerivedSeq(*derivedG);
+        /* Make cfg reducible and build derived sequences */
+        checkReducibility(pProc, &derivedG); 
 
-}
-void udm(void)
-{
+        if (option.VeryVerbose)
+           displayDerivedSeq(derivedG);  
 
-    /* Build the control flow graph, find idioms, and convert low-level
-     * icodes to high-level ones */
-    Disassembler ds(2);
-    for (auto iter = g_proj.pProcList.rbegin(); iter!=g_proj.pProcList.rend(); ++iter)
-    {
-        iter->buildCFG(ds);
-    }
+        /* Structure the graph */
+        structure(pProc, derivedG); 
 
+		/* Check for compound conditions */
+		compoundCond (pProc);
 
-    /* Data flow analysis - eliminate condition codes, extraneous registers
-     * and intermediate instructions.  Find expressions by forward
-     * substitution algorithm */
-    std::bitset<32> live_regs;
-    g_proj.pProcList.front().dataFlow (live_regs);
-
-    /* Control flow analysis - structuring algorithm */
-    for (auto iter = g_proj.pProcList.rbegin(); iter!=g_proj.pProcList.rend(); ++iter)
-    {
-        iter->controlFlowAnalysis();
+        if (option.verbose) {
+           printf("\nDepth first traversal - Proc %s\n", pProc->name);
+           displayDfs(pProc->cfg);
+        } 
+
+        /* Free storage occupied by this procedure */
+        freeDerivedSeq(derivedG); 
     }
 }
 
+
+static char *nodeType[] = {"branch", "if", "case", "fall", "return", "call",
+               "loop", "repeat", "interval", "cycleHead", 
+               "caseHead", "terminate",
+               "nowhere" };
+
+static char *loopType[] = {"noLoop", "while", "repeat", "loop", "for"};
+
+
 /****************************************************************************
  * displayCFG - Displays the Basic Block list
  ***************************************************************************/
-void Function::displayCFG()
+static void displayCFG(PPROC pProc)
 {
-    printf("\nBasic Block List - Proc %s", name.c_str());
-    for (BB *pBB : m_cfg)
-    {
-        pBB->display();
+    Int i;
+    PBB pBB;
+
+    printf("\nBasic Block List - Proc %s", pProc->name);
+
+    for (pBB = pProc->cfg; pBB; pBB = pBB->next) {
+        printf("\nnode type = %s, ", nodeType[pBB->nodeType]);
+        printf("start = %ld, length = %ld, #out edges = %ld\n",
+            pBB->start, pBB->length, pBB->numOutEdges);
+
+        for (i = 0; i < pBB->numOutEdges; i++)
+            printf(" outEdge[%2d] = %ld\n",i, pBB->edges[i].BBptr->start);
     }
 }
 
 
+/*****************************************************************************
+ * displayDfs - Displays the CFG using a depth first traversal
+ ****************************************************************************/
+static void displayDfs(PBB pBB)
+{
+    Int i;
+
+    if (! pBB)
+        return;
+    pBB->traversed = DFS_DISP;
+
+    printf("node type = %s, ", nodeType[pBB->nodeType]);
+    printf("start = %ld, length = %ld, #in-edges = %ld, #out-edges = %ld\n",
+        pBB->start, pBB->length, pBB->numInEdges, pBB->numOutEdges);
+    printf("dfsFirst = %ld, dfsLast = %ld, immed dom = %ld\n",
+        pBB->dfsFirstNum, pBB->dfsLastNum, 
+		pBB->immedDom == MAX ? -1 : pBB->immedDom);
+    printf("loopType = %s, loopHead = %ld, latchNode = %ld, follow = %ld\n",
+            loopType[pBB->loopType], 
+        pBB->loopHead == MAX ? -1 : pBB->loopHead, 
+        pBB->latchNode == MAX ? -1 : pBB->latchNode, 
+        pBB->loopFollow == MAX ? -1 : pBB->loopFollow);
+    printf ("ifFollow = %ld, caseHead = %ld, caseTail = %ld\n", 
+        pBB->ifFollow == MAX ? -1 : pBB->ifFollow,
+        pBB->caseHead == MAX ? -1 : pBB->caseHead,
+        pBB->caseTail == MAX ? -1 : pBB->caseTail);
+
+    if (pBB->nodeType == INTERVAL_NODE)
+        printf("corresponding interval = %ld\n", pBB->correspInt->numInt);
+    else for (i = 0; i < pBB->numInEdges; i++)
+        printf ("  inEdge[%ld] = %ld\n", i, pBB->inEdges[i]->start); 
+
+    /* Display out edges information */
+    for (i = 0; i < pBB->numOutEdges; i++)
+        if (pBB->nodeType == INTERVAL_NODE)
+            printf(" outEdge[%ld] = %ld\n", i,
+                pBB->edges[i].BBptr->correspInt->numInt);
+        else 
+            printf(" outEdge[%ld] = %ld\n", i, pBB->edges[i].BBptr->start);
+    printf("----\n");
+
+    /* Recursive call on successors of current node */
+    for (i = 0; i < pBB->numOutEdges; i++)
+        if (pBB->edges[i].BBptr->traversed != DFS_DISP)
+            displayDfs(pBB->edges[i].BBptr);
+}

Some files were not shown because too many files changed in this diff