Browse Source

Fixes to libdisasm, also use it a bit more

Artur K 11 years ago
parent
commit
d5e1fc733f

+ 24 - 19
3rd_party/libdisasm/ia32_operand.cpp

@@ -109,17 +109,15 @@ size_t Ia32_Decoder::decode_operand_value( unsigned char *buf, size_t buf_len,
             op->type = op_absolute;
 
             /* segment:offset address used in far calls */
-            x86_imm_sized( buf, buf_len,
-                           &op->data.absolute.segment, 2 );
             if ( m_decoded->addr_size == 4 ) {
-                x86_imm_sized( buf, buf_len,
-                               &op->data.absolute.offset.off32, 4 );
-                size = 6;
-            } else {
-                x86_imm_sized( buf, buf_len,
-                               &op->data.absolute.offset.off16, 2 );
+                x86_imm_sized( buf, buf_len, &op->data.absolute.offset.off32, 4 );
                 size = 4;
+            } else {
+                x86_imm_sized( buf, buf_len,&op->data.absolute.offset.off16, 2 );
+                size = 2;
             }
+            x86_imm_sized( buf+size, buf_len-size, &op->data.absolute.segment, 2 );
+            size+=2;
 
             break;
         case ADDRMETH_I:	/* Immediate val */
@@ -140,17 +138,24 @@ size_t Ia32_Decoder::decode_operand_value( unsigned char *buf, size_t buf_len,
                            op->data.far_offset depending on the size of
                            the operand */
             op->flags.op_signed = true;
-            if ( op_size == 1 ) {
-                /* one-byte near offset */
-                op->type = op_relative_near;
-                x86_imm_signsized(buf, buf_len, &op->data.relative_near, 1);
-            } else {
-                /* far offset...is this truly signed? */
-                op->type = op_relative_far;
-                x86_imm_signsized(buf, buf_len,
-                                  &op->data.relative_far, op_size );
+            switch(op_size)
+            {
+                case 1:
+                    /* one-byte near offset */
+                    op->type = op_relative_near;
+                    size = x86_imm_signsized(buf, buf_len, &op->data.relative_near, 1);
+                    break;
+                case 2:
+                    op->type = op_relative_far;
+                    int16_t offset_val;
+                    size = x86_imm_signsized(buf, buf_len,&offset_val, 2);
+                    op->data.relative_far=offset_val;
+                    break;
+                default:
+                    assert(false);
+                    size=0;
+
             }
-            size = op_size;
             break;
         case ADDRMETH_O:	/* No ModR/M; op is word/dword offset */
             /* NOTE: these are actually RVAs not offsets to seg!! */
@@ -258,7 +263,7 @@ size_t Ia32_Decoder::decode_operand_size( unsigned int op_type, x86_op_t *op ) {
                          * value s a 16:16 pointer or a 16:32 pointer, where
                          * the first '16' is a segment */
             size = (m_decoded->addr_size == 4) ? 6 : 4;
-            op->datatype = (size == 4) ? op_descr32 : op_descr16;
+            op->datatype = (size == 6) ? op_descr32 : op_descr16;
             break;
         case OPTYPE_b:	/* byte, ignore op-size */
             size = 1;

+ 372 - 349
3rd_party/libdisasm/libdis.h

@@ -6,17 +6,17 @@
 #endif
 #include <cstring>
 #include <cstdlib>
+#include <cassert>
 #include <stdint.h>
-
 /* 'NEW" types
  * __________________________________________________________________________*/
 #ifndef LIBDISASM_QWORD_H       /* do not interfere with qword.h */
-        #define LIBDISASM_QWORD_H
-        #ifdef _MSC_VER
-                typedef __int64         qword_t;
-        #else
-                typedef int64_t         qword_t;
-        #endif
+#define LIBDISASM_QWORD_H
+#ifdef _MSC_VER
+typedef __int64         qword_t;
+#else
+typedef int64_t         qword_t;
+#endif
 #endif
 
 #include <sys/types.h>
@@ -36,7 +36,7 @@
  *      this allows the report to recover from errors, or just log them.
  */
 enum x86_report_codes {
-        report_disasm_bounds,   /* RVA OUT OF BOUNDS : The disassembler could
+    report_disasm_bounds,   /* RVA OUT OF BOUNDS : The disassembler could
                                    not disassemble the supplied RVA as it is
                                    out of the range of the buffer. The
                                    application should store the address and
@@ -44,21 +44,21 @@ enum x86_report_codes {
                                    binary it is in, then disassemble the
                                    address from the bytes in that section.
                                         data: uint32_t rva */
-        report_insn_bounds,     /* INSTRUCTION OUT OF BOUNDS: The disassembler
+    report_insn_bounds,     /* INSTRUCTION OUT OF BOUNDS: The disassembler
                                    could not disassemble the instruction as
                                    the instruction would require bytes beyond
                                    the end of the current buffer. This usually
                                    indicated garbage bytes at the end of a
                                    buffer, or an incorrectly-sized buffer.
                                         data: uint32_t rva */
-        report_invalid_insn,    /* INVALID INSTRUCTION: The disassembler could
+    report_invalid_insn,    /* INVALID INSTRUCTION: The disassembler could
                                    not disassemble the instruction as it has an
                                    invalid combination of opcodes and operands.
                                    This will stop automated disassembly; the
                                    application can restart the disassembly
                                    after the invalid instruction.
                                         data: uint32_t rva */
-        report_unknown
+    report_unknown
 };
 /* Disassembly formats:
  *      AT&T is standard AS/GAS-style: "mnemonic\tsrc, dest, imm"
@@ -68,12 +68,12 @@ enum x86_report_codes {
  *      Raw is addr|offset|size|bytes|prefix... see libdisasm_formats.7
  */
 enum x86_asm_format {
-        unknown_syntax = 0,		/* never use! */
-        native_syntax, 			/* header: 35 bytes */
-        intel_syntax, 			/* header: 23 bytes */
-        att_syntax,  			/* header: 23 bytes */
-        xml_syntax,			/* header: 679 bytes */
-        raw_syntax			/* header: 172 bytes */
+    unknown_syntax = 0,		/* never use! */
+    native_syntax, 			/* header: 35 bytes */
+    intel_syntax, 			/* header: 23 bytes */
+    att_syntax,  			/* header: 23 bytes */
+    xml_syntax,			/* header: 679 bytes */
+    raw_syntax			/* header: 172 bytes */
 };
 
 /* 'arg' is optional arbitrary data provided by the code passing the
@@ -86,10 +86,10 @@ typedef void (*DISASM_REPORTER)( enum x86_report_codes code,
 
 /* ========================================= Libdisasm Management Routines */
 enum x86_options {		/* these can be ORed together */
-        opt_none= 0,
-        opt_ignore_nulls=1,     /* ignore sequences of > 4 NULL bytes */
-        opt_16_bit=2,           /* 16-bit/DOS disassembly */
-        opt_att_mnemonics=4    /* use AT&T syntax names for alternate opcode mnemonics */
+    opt_none= 0,
+    opt_ignore_nulls=1,     /* ignore sequences of > 4 NULL bytes */
+    opt_16_bit=2,           /* 16-bit/DOS disassembly */
+    opt_att_mnemonics=4    /* use AT&T syntax names for alternate opcode mnemonics */
 };
 
 /* ========================================= Instruction Representation */
@@ -110,35 +110,35 @@ enum x86_options {		/* these can be ORed together */
 #define MAX_INSN_XML_STRING 4096   /* 2 * 8 * MAX_OP_XML_STRING */
 
 enum x86_reg_type {     /* NOTE: these may be ORed together */
-        reg_undef       = 0x00000,      // used only in ia32_reg_table initializater
-        reg_gen         = 0x00001,      /* general purpose */
-        reg_in          = 0x00002,      /* incoming args, ala RISC */
-        reg_out         = 0x00004,      /* args to calls, ala RISC */
-        reg_local       = 0x00008,      /* local vars, ala RISC */
-        reg_fpu         = 0x00010,      /* FPU data register */
-        reg_seg         = 0x00020,      /* segment register */
-        reg_simd        = 0x00040,      /* SIMD/MMX reg */
-        reg_sys         = 0x00080,      /* restricted/system register */
-        reg_sp          = 0x00100,      /* stack pointer */
-        reg_fp          = 0x00200,      /* frame pointer */
-        reg_pc          = 0x00400,      /* program counter */
-        reg_retaddr     = 0x00800,      /* return addr for func */
-        reg_cond        = 0x01000,      /* condition code / flags */
-        reg_zero        = 0x02000,      /* zero register, ala RISC */
-        reg_ret         = 0x04000,      /* return value */
-        reg_src         = 0x10000,      /* array/rep source */
-        reg_dest        = 0x20000,      /* array/rep destination */
-        reg_count       = 0x40000       /* array/rep/loop counter */
+    reg_undef       = 0x00000,      // used only in ia32_reg_table initializater
+    reg_gen         = 0x00001,      /* general purpose */
+    reg_in          = 0x00002,      /* incoming args, ala RISC */
+    reg_out         = 0x00004,      /* args to calls, ala RISC */
+    reg_local       = 0x00008,      /* local vars, ala RISC */
+    reg_fpu         = 0x00010,      /* FPU data register */
+    reg_seg         = 0x00020,      /* segment register */
+    reg_simd        = 0x00040,      /* SIMD/MMX reg */
+    reg_sys         = 0x00080,      /* restricted/system register */
+    reg_sp          = 0x00100,      /* stack pointer */
+    reg_fp          = 0x00200,      /* frame pointer */
+    reg_pc          = 0x00400,      /* program counter */
+    reg_retaddr     = 0x00800,      /* return addr for func */
+    reg_cond        = 0x01000,      /* condition code / flags */
+    reg_zero        = 0x02000,      /* zero register, ala RISC */
+    reg_ret         = 0x04000,      /* return value */
+    reg_src         = 0x10000,      /* array/rep source */
+    reg_dest        = 0x20000,      /* array/rep destination */
+    reg_count       = 0x40000       /* array/rep/loop counter */
 };
 
 /* x86_reg_t : an X86 CPU register */
 struct x86_reg_t {
-        char name[MAX_REGNAME];
-        enum x86_reg_type type;         /* what register is used for */
-        unsigned int size;              /* size of register in bytes */
-        unsigned int id;                /* register ID #, for quick compares */
-        unsigned int alias;		/* ID of reg this is an alias for */
-        unsigned int shift;		/* amount to shift aliased reg by */
+    char name[MAX_REGNAME];
+    enum x86_reg_type type;         /* what register is used for */
+    unsigned int size;              /* size of register in bytes */
+    unsigned int id;                /* register ID #, for quick compares */
+    unsigned int alias;		/* ID of reg this is an alias for */
+    unsigned int shift;		/* amount to shift aliased reg by */
     x86_reg_t * aliased_reg( ) {
         x86_reg_t * reg = (x86_reg_t * )calloc( sizeof(x86_reg_t), 1 );
         reg->x86_reg_from_id( id );
@@ -149,92 +149,92 @@ struct x86_reg_t {
 
 /* x86_ea_t : an X86 effective address (address expression) */
 typedef struct {
-        unsigned int     scale;         /* scale factor */
-        x86_reg_t        index, base;   /* index, base registers */
-        int32_t          disp;          /* displacement */
-        char             disp_sign;     /* is negative? 1/0 */
-        char             disp_size;     /* 0, 1, 2, 4 */
+    unsigned int     scale;         /* scale factor */
+    x86_reg_t        index, base;   /* index, base registers */
+    int32_t          disp;          /* displacement */
+    char             disp_sign;     /* is negative? 1/0 */
+    char             disp_size;     /* 0, 1, 2, 4 */
 } x86_ea_t;
 
 /* x86_absolute_t : an X86 segment:offset address (descriptor) */
 typedef struct {
-        unsigned short	segment;	/* loaded directly into CS */
-        union {
-                unsigned short	off16;	/* loaded directly into IP */
-                uint32_t		off32;	/* loaded directly into EIP */
-        } offset;
+    unsigned short	segment;	/* loaded directly into CS */
+    union {
+        unsigned short	off16;	/* loaded directly into IP */
+        uint32_t		off32;	/* loaded directly into EIP */
+    } offset;
 } x86_absolute_t;
 
 enum x86_op_type {      /* mutually exclusive */
-        op_unused = 0,          /* empty/unused operand: should never occur */
-        op_register = 1,        /* CPU register */
-        op_immediate = 2,       /* Immediate Value */
-        op_relative_near = 3,   /* Relative offset from IP */
-        op_relative_far = 4,    /* Relative offset from IP */
-        op_absolute = 5,        /* Absolute address (ptr16:32) */
-        op_expression = 6,      /* Address expression (scale/index/base/disp) */
-        op_offset = 7,          /* Offset from start of segment (m32) */
-        op_unknown
+    op_unused = 0,          /* empty/unused operand: should never occur */
+    op_register = 1,        /* CPU register */
+    op_immediate = 2,       /* Immediate Value */
+    op_relative_near = 3,   /* Relative offset from IP */
+    op_relative_far = 4,    /* Relative offset from IP */
+    op_absolute = 5,        /* Absolute address (ptr16:32) */
+    op_expression = 6,      /* Address expression (scale/index/base/disp) */
+    op_offset = 7,          /* Offset from start of segment (m32) */
+    op_unknown
 };
 
 #define x86_optype_is_address( optype ) \
-        ( optype == op_absolute || optype == op_offset )
+    ( optype == op_absolute || optype == op_offset )
 #define x86_optype_is_relative( optype ) \
-        ( optype == op_relative_near || optype == op_relative_far )
+    ( optype == op_relative_near || optype == op_relative_far )
 #define x86_optype_is_memory( optype ) \
-        ( optype > op_immediate && optype < op_unknown )
+    ( optype > op_immediate && optype < op_unknown )
 
 enum x86_op_datatype {          /* these use Intel's lame terminology */
-        op_byte = 1,            /* 1 byte integer */
-        op_word = 2,            /* 2 byte integer */
-        op_dword = 3,           /* 4 byte integer */
-        op_qword = 4,           /* 8 byte integer */
-        op_dqword = 5,          /* 16 byte integer */
-        op_sreal = 6,           /* 4 byte real (single real) */
-        op_dreal = 7,           /* 8 byte real (double real) */
-        op_extreal = 8,         /* 10 byte real (extended real) */
-        op_bcd = 9,             /* 10 byte binary-coded decimal */
-        op_ssimd = 10,          /* 16 byte : 4 packed single FP (SIMD, MMX) */
-        op_dsimd = 11,          /* 16 byte : 2 packed double FP (SIMD, MMX) */
-        op_sssimd = 12,         /* 4 byte : scalar single FP (SIMD, MMX) */
-        op_sdsimd = 13,         /* 8 byte : scalar double FP (SIMD, MMX) */
-        op_descr32 = 14,	/* 6 byte Intel descriptor 2:4 */
-        op_descr16 = 15,	/* 4 byte Intel descriptor 2:2 */
-        op_pdescr32 = 16,	/* 6 byte Intel pseudo-descriptor 32:16 */
-        op_pdescr16 = 17,	/* 6 byte Intel pseudo-descriptor 8:24:16 */
-        op_bounds16 = 18,	/* signed 16:16 lower:upper bounds */
-        op_bounds32 = 19,	/* signed 32:32 lower:upper bounds */
-        op_fpuenv16 = 20,	/* 14 byte FPU control/environment data */
-        op_fpuenv32 = 21,	/* 28 byte FPU control/environment data */
-        op_fpustate16 = 22,	/* 94 byte FPU state (env & reg stack) */
-        op_fpustate32 = 23,	/* 108 byte FPU state (env & reg stack) */
-        op_fpregset = 24,	/* 512 bytes: register set */
-        op_fpreg = 25,		/* FPU register */
-        op_none = 0xFF     /* operand without a datatype (INVLPG) */
+    op_byte = 1,            /* 1 byte integer */
+    op_word = 2,            /* 2 byte integer */
+    op_dword = 3,           /* 4 byte integer */
+    op_qword = 4,           /* 8 byte integer */
+    op_dqword = 5,          /* 16 byte integer */
+    op_sreal = 6,           /* 4 byte real (single real) */
+    op_dreal = 7,           /* 8 byte real (double real) */
+    op_extreal = 8,         /* 10 byte real (extended real) */
+    op_bcd = 9,             /* 10 byte binary-coded decimal */
+    op_ssimd = 10,          /* 16 byte : 4 packed single FP (SIMD, MMX) */
+    op_dsimd = 11,          /* 16 byte : 2 packed double FP (SIMD, MMX) */
+    op_sssimd = 12,         /* 4 byte : scalar single FP (SIMD, MMX) */
+    op_sdsimd = 13,         /* 8 byte : scalar double FP (SIMD, MMX) */
+    op_descr32 = 14,	/* 6 byte Intel descriptor 2:4 */
+    op_descr16 = 15,	/* 4 byte Intel descriptor 2:2 */
+    op_pdescr32 = 16,	/* 6 byte Intel pseudo-descriptor 32:16 */
+    op_pdescr16 = 17,	/* 6 byte Intel pseudo-descriptor 8:24:16 */
+    op_bounds16 = 18,	/* signed 16:16 lower:upper bounds */
+    op_bounds32 = 19,	/* signed 32:32 lower:upper bounds */
+    op_fpuenv16 = 20,	/* 14 byte FPU control/environment data */
+    op_fpuenv32 = 21,	/* 28 byte FPU control/environment data */
+    op_fpustate16 = 22,	/* 94 byte FPU state (env & reg stack) */
+    op_fpustate32 = 23,	/* 108 byte FPU state (env & reg stack) */
+    op_fpregset = 24,	/* 512 bytes: register set */
+    op_fpreg = 25,		/* FPU register */
+    op_none = 0xFF     /* operand without a datatype (INVLPG) */
 };
 
 enum x86_op_access {    /* ORed together */
-        op_read = 1,
-        op_write = 2,
-        op_execute = 4
+    op_read = 1,
+    op_write = 2,
+    op_execute = 4
 };
 
 struct x86_op_flags {     /* ORed together, but segs are mutually exclusive */
     union {
         unsigned int op_signed:1,          /* signed integer */
-                     op_string:1,// = 2,          /* possible string or array */
-                    op_constant:1,// = 4,        /* symbolic constant */
-                    op_pointer:1,// = 8,         /* operand points to a memory address */
-                    op_sysref:1,// = 0x010,	/* operand is a syscall number */
-                    op_implied:1,// = 0x020,	/* operand is implicit in the insn */
-                    op_hardcode:1,// = 0x40,	/* operand is hardcoded in insn definition */
-        /* NOTE: an 'implied' operand is one which can be considered a side
-         * effect of the insn, e.g. %esp being modified by PUSH or POP. A
-         * 'hard-coded' operand is one which is specified in the instruction
-         * definition, e.g. %es:%edi in MOVSB or 1 in ROL Eb, 1. The difference
-         * is that hard-coded operands are printed by disassemblers and are
-         * required to re-assemble, while implicit operands are invisible. */
-                    op_seg : 3;
+            op_string:1,// = 2,          /* possible string or array */
+            op_constant:1,// = 4,        /* symbolic constant */
+            op_pointer:1,// = 8,         /* operand points to a memory address */
+            op_sysref:1,// = 0x010,	/* operand is a syscall number */
+            op_implied:1,// = 0x020,	/* operand is implicit in the insn */
+            op_hardcode:1,// = 0x40,	/* operand is hardcoded in insn definition */
+            /* NOTE: an 'implied' operand is one which can be considered a side
+                 * effect of the insn, e.g. %esp being modified by PUSH or POP. A
+                 * 'hard-coded' operand is one which is specified in the instruction
+                 * definition, e.g. %es:%edi in MOVSB or 1 in ROL Eb, 1. The difference
+                 * is that hard-coded operands are printed by disassemblers and are
+                 * required to re-assemble, while implicit operands are invisible. */
+            op_seg : 3;
         unsigned int whole;
     };
     enum {
@@ -250,43 +250,43 @@ struct x86_op_flags {     /* ORed together, but segs are mutually exclusive */
 /* x86_op_t : an X86 instruction operand */
 struct x86_op_t{
     friend struct x86_insn_t;
-        enum x86_op_type        type;           /* operand type */
-        enum x86_op_datatype    datatype;       /* operand size */
-        enum x86_op_access      access;         /* operand access [RWX] */
-        x86_op_flags       flags;          /* misc flags */
-        union {
-                /* sizeof will have to work on these union members! */
-                /* immediate values */
-                char            sbyte;
-                short           sword;
-                int32_t         sdword;
-                qword_t         sqword;
-                unsigned char   byte;
-                unsigned short  word;
-                uint32_t        dword;
-                qword_t         qword;
-                float           sreal;
-                double          dreal;
-                /* misc large/non-native types */
-                unsigned char   extreal[10];
-                unsigned char   bcd[10];
-                qword_t         dqword[2];
-                unsigned char   simd[16];
-                unsigned char   fpuenv[28];
-                /* offset from segment */
-                uint32_t        offset;
-                /* ID of CPU register */
-                x86_reg_t       reg;
-                /* offsets from current insn */
-                char            relative_near;
-                int32_t         relative_far;
-                /* segment:offset */
-                x86_absolute_t	absolute;
-                /* effective address [expression] */
-                x86_ea_t        expression;
-        } data;
-        /* this is needed to make formatting operands more sane */
-        void * insn;		/* pointer to x86_insn_t owning operand */
+    enum x86_op_type        type;           /* operand type */
+    enum x86_op_datatype    datatype;       /* operand size */
+    enum x86_op_access      access;         /* operand access [RWX] */
+    x86_op_flags       flags;          /* misc flags */
+    union {
+        /* sizeof will have to work on these union members! */
+        /* immediate values */
+        char            sbyte;
+        short           sword;
+        int32_t         sdword;
+        qword_t         sqword;
+        unsigned char   byte;
+        unsigned short  word;
+        uint32_t        dword;
+        qword_t         qword;
+        float           sreal;
+        double          dreal;
+        /* misc large/non-native types */
+        unsigned char   extreal[10];
+        unsigned char   bcd[10];
+        qword_t         dqword[2];
+        unsigned char   simd[16];
+        unsigned char   fpuenv[28];
+        /* offset from segment */
+        uint32_t        offset;
+        /* ID of CPU register */
+        x86_reg_t       reg;
+        /* offsets from current insn */
+        char            relative_near;
+        int32_t         relative_far;
+        /* segment:offset */
+        x86_absolute_t	absolute;
+        /* effective address [expression] */
+        x86_ea_t        expression;
+    } data;
+    /* this is needed to make formatting operands more sane */
+    void * insn;		/* pointer to x86_insn_t owning operand */
     size_t size()
     {
         return operand_size();
@@ -301,6 +301,29 @@ struct x86_op_t{
     bool is_relative( ) {
         return ( type == op_relative_near || type == op_relative_far );
     }
+    int32_t getAddress()
+    {
+        assert(is_address()||is_relative());
+        switch(type)
+        {
+            case op_absolute:
+            {
+                if(datatype==op_descr16)
+                    return (int32_t(data.absolute.segment)<<4) + data.absolute.offset.off16;
+                else
+                    return (int32_t(data.absolute.segment)<<4) + data.absolute.offset.off32;
+            }
+            case op_offset:
+                return data.offset;
+            case op_relative_near:
+                return data.relative_near;
+            case op_relative_far:
+                return data.relative_far;
+            default:
+                assert(false);
+                return ~0;
+        }
+    }
     char * format( enum x86_asm_format format );
     x86_op_t * copy()
     {
@@ -319,119 +342,119 @@ private:
  * list in an insn. Users wishing to add operands to this list, e.g. to add
  * implicit operands, should use x86_operand_new in x86_operand_list.h */
 struct  x86_oplist_t {
-        x86_op_t op;
-        struct  x86_oplist_t *next;
+    x86_op_t op;
+    struct  x86_oplist_t *next;
 };
 
 enum x86_insn_type {
-        insn_invalid = 0,	/* invalid instruction */
-        /* insn_controlflow */
-        insn_jmp = 0x1001,
-        insn_jcc = 0x1002,
-        insn_call = 0x1003,
-        insn_callcc = 0x1004,
-        insn_return = 0x1005,
-        /* insn_arithmetic */
-        insn_add = 0x2001,
-        insn_sub = 0x2002,
-        insn_mul = 0x2003,
-        insn_div = 0x2004,
-        insn_inc = 0x2005,
-        insn_dec = 0x2006,
-        insn_shl = 0x2007,
-        insn_shr = 0x2008,
-        insn_rol = 0x2009,
-        insn_ror = 0x200A,
-        /* insn_logic */
-        insn_and = 0x3001,
-        insn_or = 0x3002,
-        insn_xor = 0x3003,
-        insn_not = 0x3004,
-        insn_neg = 0x3005,
-        /* insn_stack */
-        insn_push = 0x4001,
-        insn_pop = 0x4002,
-        insn_pushregs = 0x4003,
-        insn_popregs = 0x4004,
-        insn_pushflags = 0x4005,
-        insn_popflags = 0x4006,
-        insn_enter = 0x4007,
-        insn_leave = 0x4008,
-        /* insn_comparison */
-        insn_test = 0x5001,
-        insn_cmp = 0x5002,
-        /* insn_move */
-        insn_mov = 0x6001,      /* move */
-        insn_movcc = 0x6002,    /* conditional move */
-        insn_xchg = 0x6003,     /* exchange */
-        insn_xchgcc = 0x6004,   /* conditional exchange */
-        /* insn_string */
-        insn_strcmp = 0x7001,
-        insn_strload = 0x7002,
-        insn_strmov = 0x7003,
-        insn_strstore = 0x7004,
-        insn_translate = 0x7005,        /* xlat */
-        /* insn_bit_manip */
-        insn_bittest = 0x8001,
-        insn_bitset = 0x8002,
-        insn_bitclear = 0x8003,
-        /* insn_flag_manip */
-        insn_clear_carry = 0x9001,
-        insn_clear_zero = 0x9002,
-        insn_clear_oflow = 0x9003,
-        insn_clear_dir = 0x9004,
-        insn_clear_sign = 0x9005,
-        insn_clear_parity = 0x9006,
-        insn_set_carry = 0x9007,
-        insn_set_zero = 0x9008,
-        insn_set_oflow = 0x9009,
-        insn_set_dir = 0x900A,
-        insn_set_sign = 0x900B,
-        insn_set_parity = 0x900C,
-        insn_tog_carry = 0x9010,
-        insn_tog_zero = 0x9020,
-        insn_tog_oflow = 0x9030,
-        insn_tog_dir = 0x9040,
-        insn_tog_sign = 0x9050,
-        insn_tog_parity = 0x9060,
-        /* insn_fpu */
-        insn_fmov = 0xA001,
-        insn_fmovcc = 0xA002,
-        insn_fneg = 0xA003,
-        insn_fabs = 0xA004,
-        insn_fadd = 0xA005,
-        insn_fsub = 0xA006,
-        insn_fmul = 0xA007,
-        insn_fdiv = 0xA008,
-        insn_fsqrt = 0xA009,
-        insn_fcmp = 0xA00A,
-        insn_fcos = 0xA00C,
-        insn_fldpi = 0xA00D,
-        insn_fldz = 0xA00E,
-        insn_ftan = 0xA00F,
-        insn_fsine = 0xA010,
-        insn_fsys = 0xA020,
-        /* insn_interrupt */
-        insn_int = 0xD001,
-        insn_intcc = 0xD002,    /* not present in x86 ISA */
-        insn_iret = 0xD003,
-        insn_bound = 0xD004,
-        insn_debug = 0xD005,
-        insn_trace = 0xD006,
-        insn_invalid_op = 0xD007,
-        insn_oflow = 0xD008,
-        /* insn_system */
-        insn_halt = 0xE001,
-        insn_in = 0xE002,       /* input from port/bus */
-        insn_out = 0xE003,      /* output to port/bus */
-        insn_cpuid = 0xE004,
-        insn_lmsw = 0xE005,
-        insn_smsw = 0xE006,
-        insn_clts = 0xE007,
-        /* insn_other */
-        insn_nop = 0xF001,
-        insn_bcdconv = 0xF002,  /* convert to or from BCD */
-        insn_szconv = 0xF003    /* change size of operand */
+    insn_invalid = 0,	/* invalid instruction */
+    /* insn_controlflow */
+    insn_jmp = 0x1001,
+    insn_jcc = 0x1002,
+    insn_call = 0x1003,
+    insn_callcc = 0x1004,
+    insn_return = 0x1005,
+    /* insn_arithmetic */
+    insn_add = 0x2001,
+    insn_sub = 0x2002,
+    insn_mul = 0x2003,
+    insn_div = 0x2004,
+    insn_inc = 0x2005,
+    insn_dec = 0x2006,
+    insn_shl = 0x2007,
+    insn_shr = 0x2008,
+    insn_rol = 0x2009,
+    insn_ror = 0x200A,
+    /* insn_logic */
+    insn_and = 0x3001,
+    insn_or = 0x3002,
+    insn_xor = 0x3003,
+    insn_not = 0x3004,
+    insn_neg = 0x3005,
+    /* insn_stack */
+    insn_push = 0x4001,
+    insn_pop = 0x4002,
+    insn_pushregs = 0x4003,
+    insn_popregs = 0x4004,
+    insn_pushflags = 0x4005,
+    insn_popflags = 0x4006,
+    insn_enter = 0x4007,
+    insn_leave = 0x4008,
+    /* insn_comparison */
+    insn_test = 0x5001,
+    insn_cmp = 0x5002,
+    /* insn_move */
+    insn_mov = 0x6001,      /* move */
+    insn_movcc = 0x6002,    /* conditional move */
+    insn_xchg = 0x6003,     /* exchange */
+    insn_xchgcc = 0x6004,   /* conditional exchange */
+    /* insn_string */
+    insn_strcmp = 0x7001,
+    insn_strload = 0x7002,
+    insn_strmov = 0x7003,
+    insn_strstore = 0x7004,
+    insn_translate = 0x7005,        /* xlat */
+    /* insn_bit_manip */
+    insn_bittest = 0x8001,
+    insn_bitset = 0x8002,
+    insn_bitclear = 0x8003,
+    /* insn_flag_manip */
+    insn_clear_carry = 0x9001,
+    insn_clear_zero = 0x9002,
+    insn_clear_oflow = 0x9003,
+    insn_clear_dir = 0x9004,
+    insn_clear_sign = 0x9005,
+    insn_clear_parity = 0x9006,
+    insn_set_carry = 0x9007,
+    insn_set_zero = 0x9008,
+    insn_set_oflow = 0x9009,
+    insn_set_dir = 0x900A,
+    insn_set_sign = 0x900B,
+    insn_set_parity = 0x900C,
+    insn_tog_carry = 0x9010,
+    insn_tog_zero = 0x9020,
+    insn_tog_oflow = 0x9030,
+    insn_tog_dir = 0x9040,
+    insn_tog_sign = 0x9050,
+    insn_tog_parity = 0x9060,
+    /* insn_fpu */
+    insn_fmov = 0xA001,
+    insn_fmovcc = 0xA002,
+    insn_fneg = 0xA003,
+    insn_fabs = 0xA004,
+    insn_fadd = 0xA005,
+    insn_fsub = 0xA006,
+    insn_fmul = 0xA007,
+    insn_fdiv = 0xA008,
+    insn_fsqrt = 0xA009,
+    insn_fcmp = 0xA00A,
+    insn_fcos = 0xA00C,
+    insn_fldpi = 0xA00D,
+    insn_fldz = 0xA00E,
+    insn_ftan = 0xA00F,
+    insn_fsine = 0xA010,
+    insn_fsys = 0xA020,
+    /* insn_interrupt */
+    insn_int = 0xD001,
+    insn_intcc = 0xD002,    /* not present in x86 ISA */
+    insn_iret = 0xD003,
+    insn_bound = 0xD004,
+    insn_debug = 0xD005,
+    insn_trace = 0xD006,
+    insn_invalid_op = 0xD007,
+    insn_oflow = 0xD008,
+    /* insn_system */
+    insn_halt = 0xE001,
+    insn_in = 0xE002,       /* input from port/bus */
+    insn_out = 0xE003,      /* output to port/bus */
+    insn_cpuid = 0xE004,
+    insn_lmsw = 0xE005,
+    insn_smsw = 0xE006,
+    insn_clts = 0xE007,
+    /* insn_other */
+    insn_nop = 0xF001,
+    insn_bcdconv = 0xF002,  /* convert to or from BCD */
+    insn_szconv = 0xF003    /* change size of operand */
 };
 
 /* These flags specify special characteristics of the instruction, such as
@@ -440,11 +463,11 @@ enum x86_insn_type {
  * NOTE : These may not be accurate for all instructions; updates to the
  * opcode tables have not been completed. */
 enum x86_insn_note {
-        insn_note_ring0		= 1,	/* Only available in ring 0 */
-        insn_note_smm		= 2,	/* "" in System Management Mode */
-        insn_note_serial	= 4,	/* Serializing instruction */
-        insn_note_nonswap	= 8,	/* Does not swap arguments in att-style formatting */
-        insn_note_nosuffix  = 16	/* Does not have size suffix in att-style formatting */
+    insn_note_ring0		= 1,	/* Only available in ring 0 */
+    insn_note_smm		= 2,	/* "" in System Management Mode */
+    insn_note_serial	= 4,	/* Serializing instruction */
+    insn_note_nonswap	= 8,	/* Does not swap arguments in att-style formatting */
+    insn_note_nosuffix  = 16	/* Does not have size suffix in att-style formatting */
 };
 
 /* This specifies what effects the instruction has on the %eflags register */
@@ -458,22 +481,22 @@ enum x86_eflags
     insn_eflag_parity
 };
 enum x86_flag_status {
-        insn_carry_set = 0x1,			/* CF */
-        insn_zero_set = 0x2,			/* ZF */
-        insn_oflow_set = 0x4,			/* OF */
-        insn_dir_set = 0x8,			/* DF */
-        insn_sign_set = 0x10,			/* SF */
-        insn_parity_set = 0x20,			/* PF */
-        insn_carry_or_zero_set = 0x40,
-        insn_zero_set_or_sign_ne_oflow = 0x80,
-        insn_carry_clear = 0x100,
-        insn_zero_clear = 0x200,
-        insn_oflow_clear = 0x400,
-        insn_dir_clear = 0x800,
-        insn_sign_clear = 0x1000,
-        insn_parity_clear = 0x2000,
-        insn_sign_eq_oflow = 0x4000,
-        insn_sign_ne_oflow = 0x8000
+    insn_carry_set = 0x1,			/* CF */
+    insn_zero_set = 0x2,			/* ZF */
+    insn_oflow_set = 0x4,			/* OF */
+    insn_dir_set = 0x8,			/* DF */
+    insn_sign_set = 0x10,			/* SF */
+    insn_parity_set = 0x20,			/* PF */
+    insn_carry_or_zero_set = 0x40,
+    insn_zero_set_or_sign_ne_oflow = 0x80,
+    insn_carry_clear = 0x100,
+    insn_zero_clear = 0x200,
+    insn_oflow_clear = 0x400,
+    insn_dir_clear = 0x800,
+    insn_sign_clear = 0x1000,
+    insn_parity_clear = 0x2000,
+    insn_sign_eq_oflow = 0x4000,
+    insn_sign_ne_oflow = 0x8000
 };
 
 /* The CPU model in which the insturction first appeared; this can be used
@@ -482,19 +505,19 @@ enum x86_flag_status {
  * NOTE : These may not be accurate for all instructions; updates to the
  * opcode tables have not been completed. */
 enum x86_insn_cpu {
-        cpu_8086 	= 1,	/* Intel */
-        cpu_80286	= 2,
-        cpu_80386	= 3,
-        cpu_80387	= 4,
-        cpu_80486	= 5,
-        cpu_pentium	= 6,
-        cpu_pentiumpro	= 7,
-        cpu_pentium2	= 8,
-        cpu_pentium3	= 9,
-        cpu_pentium4	= 10,
-        cpu_k6		= 16,	/* AMD */
-        cpu_k7		= 32,
-        cpu_athlon	= 48
+    cpu_8086 	= 1,	/* Intel */
+    cpu_80286	= 2,
+    cpu_80386	= 3,
+    cpu_80387	= 4,
+    cpu_80486	= 5,
+    cpu_pentium	= 6,
+    cpu_pentiumpro	= 7,
+    cpu_pentium2	= 8,
+    cpu_pentium3	= 9,
+    cpu_pentium4	= 10,
+    cpu_k6		= 16,	/* AMD */
+    cpu_k7		= 32,
+    cpu_athlon	= 48
 };
 
 /* CPU ISA subsets: These are derived from the Instruction Groups in
@@ -505,22 +528,22 @@ enum x86_insn_cpu {
  * NOTE : These may not be accurate for all instructions; updates to the
  * opcode tables have not been completed. */
 enum x86_insn_isa {
-        isa_gp		= 1,	/* general purpose */
-        isa_fp		= 2,	/* floating point */
-        isa_fpumgt	= 3,	/* FPU/SIMD management */
-        isa_mmx		= 4,	/* Intel MMX */
-        isa_sse1	= 5,	/* Intel SSE SIMD */
-        isa_sse2	= 6,	/* Intel SSE2 SIMD */
-        isa_sse3	= 7,	/* Intel SSE3 SIMD */
-        isa_3dnow	= 8,	/* AMD 3DNow! SIMD */
-        isa_sys		= 9	/* system instructions */
+    isa_gp		= 1,	/* general purpose */
+    isa_fp		= 2,	/* floating point */
+    isa_fpumgt	= 3,	/* FPU/SIMD management */
+    isa_mmx		= 4,	/* Intel MMX */
+    isa_sse1	= 5,	/* Intel SSE SIMD */
+    isa_sse2	= 6,	/* Intel SSE2 SIMD */
+    isa_sse3	= 7,	/* Intel SSE3 SIMD */
+    isa_3dnow	= 8,	/* AMD 3DNow! SIMD */
+    isa_sys		= 9	/* system instructions */
 };
 
 enum x86_insn_prefix {
-        insn_no_prefix = 0,
-        insn_rep_zero = 1,	/* REPZ and REPE */
-        insn_rep_notzero = 2,	/* REPNZ and REPNZ */
-        insn_lock = 4		/* LOCK: */
+    insn_no_prefix = 0,
+    insn_rep_zero = 1,	/* REPZ and REPE */
+    insn_rep_notzero = 2,	/* REPNZ and REPNZ */
+    insn_lock = 4		/* LOCK: */
 };
 
 
@@ -535,15 +558,15 @@ enum x86_insn_prefix {
  * The "type" (implicit or explicit) and the access method can
  * be ORed together, e.g. op_wo | op_explicit */
 enum x86_op_foreach_type {
-        op_any 	= 0,		/* ALL operands (explicit, implicit, rwx) */
-        op_dest = 1,		/* operands with Write access */
-        op_src 	= 2,		/* operands with Read access */
-        op_ro 	= 3,		/* operands with Read but not Write access */
-        op_wo 	= 4,		/* operands with Write but not Read access */
-        op_xo 	= 5,		/* operands with Execute access */
-        op_rw 	= 6,		/* operands with Read AND Write access */
-        op_implicit = 0x10,	/* operands that are implied by the opcode */
-        op_explicit = 0x20	/* operands that are not side-effects */
+    op_any 	= 0,		/* ALL operands (explicit, implicit, rwx) */
+    op_dest = 1,		/* operands with Write access */
+    op_src 	= 2,		/* operands with Read access */
+    op_ro 	= 3,		/* operands with Read but not Write access */
+    op_wo 	= 4,		/* operands with Write but not Read access */
+    op_xo 	= 5,		/* operands with Execute access */
+    op_rw 	= 6,		/* operands with Read AND Write access */
+    op_implicit = 0x10,	/* operands that are implied by the opcode */
+    op_explicit = 0x20	/* operands that are not side-effects */
 };
 
 /* Operand FOREACH callback: 'arg' is an abritrary parameter passed to the
@@ -684,9 +707,9 @@ public:
 *        (buf, buf_len, buf_rva, offset, len, insn, func, arg, resolve_func)
  *      ...but of course all of these are not used at the same time.
  */
- class X86_Disasm
- {
- public:
+class X86_Disasm
+{
+public:
     /* Function prototype for caller-supplied callback routine
      *      These callbacks are intended to process 'insn' further, e.g. by
      *      adding it to a linked list, database, etc */
@@ -701,28 +724,28 @@ public:
      *      should return -1; in all other cases the RVA to be disassembled next
      *      should be returned. */
     typedef int32_t (*DISASM_RESOLVER)( x86_op_t *op, x86_insn_t * current_insn,
-                                     void *arg );
- protected:
-     DISASM_REPORTER __x86_reporter_func;
-     void * __x86_reporter_arg;
-     Ia32_Decoder m_decoder;
-
- public:
-     X86_Disasm( x86_options options=opt_none,DISASM_REPORTER reporter=0, void *arg=0 ) :
-                __x86_reporter_func(reporter),
-                __x86_reporter_arg(arg) {
-         x86_init( options,reporter,arg);
-     }
-     /* management routines */
-     /* 'arg' is caller-specific data which is passed as the first argument
+                                        void *arg );
+protected:
+    DISASM_REPORTER __x86_reporter_func;
+    void * __x86_reporter_arg;
+    Ia32_Decoder m_decoder;
+
+public:
+    X86_Disasm( x86_options options=opt_none,DISASM_REPORTER reporter=0, void *arg=0 ) :
+        __x86_reporter_func(reporter),
+        __x86_reporter_arg(arg) {
+        x86_init( options,reporter,arg);
+    }
+    /* management routines */
+    /* 'arg' is caller-specific data which is passed as the first argument
      * to the reporter callback routine */
-     int x86_init( x86_options options, DISASM_REPORTER reporter, void *arg);
-     void x86_set_reporter( DISASM_REPORTER reporter, void *arg);
-     void x86_set_options( x86_options options );
-     x86_options x86_get_options( void );
-     int x86_cleanup(void);
+    int x86_init( x86_options options, DISASM_REPORTER reporter, void *arg);
+    void x86_set_reporter( DISASM_REPORTER reporter, void *arg);
+    void x86_set_options( x86_options options );
+    x86_options x86_get_options( void );
+    int x86_cleanup(void);
 
-     /* x86_disasm: Disassemble a single instruction from a buffer of bytes.
+    /* x86_disasm: Disassemble a single instruction from a buffer of bytes.
      *             Returns size of instruction in bytes.
      *             Caller is responsible for calling x86_oplist_free() on
      *             a reused "insn" to avoid leaking memory when calling this
@@ -733,9 +756,9 @@ public:
      *      offset  : Offset in buffer to disassemble
      *      insn    : Structure to fill with disassembled instruction
      */
-    unsigned int x86_disasm( unsigned char *buf, unsigned int buf_len,
-                             uint32_t buf_rva, unsigned int offset,
-                             x86_insn_t * insn );
+    unsigned int x86_disasm(const unsigned char *buf, unsigned int buf_len,
+                            uint32_t buf_rva, unsigned int offset,
+                            x86_insn_t * insn );
     /* x86_disasm_range: Sequential disassembly of a range of bytes in a buffer,
      *                   invoking a callback function each time an instruction
      *                   is successfully disassembled. The 'range' refers to the
@@ -794,7 +817,7 @@ public:
     unsigned int x86_ip_reg(void);
     unsigned int x86_flag_reg(void);
 
- };
+};
 
 /* Instruction operands: these are stored as a list of explicit and
  * implicit operands. It is recommended that the 'foreach' routines
@@ -843,24 +866,24 @@ public:
 #define X86_WILDCARD_BYTE 0xF4
 
 struct x86_invariant_op_t{
-        enum x86_op_type        type;           /* operand type */
-        enum x86_op_datatype    datatype;       /* operand size */
-        enum x86_op_access      access;         /* operand access [RWX] */
-        x86_op_flags       flags;          /* misc flags */
+    enum x86_op_type        type;           /* operand type */
+    enum x86_op_datatype    datatype;       /* operand size */
+    enum x86_op_access      access;         /* operand access [RWX] */
+    x86_op_flags       flags;          /* misc flags */
 };
 
 struct x86_invariant_t {
-        unsigned char bytes[64];	/* invariant representation */
-        unsigned int  size;		/* number of bytes in insn */
+    unsigned char bytes[64];	/* invariant representation */
+    unsigned int  size;		/* number of bytes in insn */
     x86_insn_t::x86_insn_group group;      /* meta-type, e.g. INS_EXEC */
-        enum x86_insn_type type;        /* type, e.g. INS_BRANCH */
-        x86_invariant_op_t operands[3];	/* operands: dest, src, imm */
+    enum x86_insn_type type;        /* type, e.g. INS_BRANCH */
+    x86_invariant_op_t operands[3];	/* operands: dest, src, imm */
 } ;
 
 
 /* return a version of the instruction with the variant bytes masked out */
 size_t x86_invariant_disasm( unsigned char *buf, int buf_len,
-                          x86_invariant_t *inv );
+                             x86_invariant_t *inv );
 /* return the size in bytes of the intruction pointed to by 'buf';
  * this used x86_invariant_disasm since it faster than x86_disasm */
 size_t x86_size_disasm( unsigned char *buf, unsigned int buf_len );

+ 1 - 1
3rd_party/libdisasm/x86_disasm.cpp

@@ -21,7 +21,7 @@ void x86_insn_t::make_invalid(unsigned char *buf)
     type = insn_invalid;
     memcpy( bytes, buf, 1 );
 }
-unsigned int X86_Disasm::x86_disasm( unsigned char *buf, unsigned int buf_len,
+unsigned int X86_Disasm::x86_disasm( const unsigned char *buf, unsigned int buf_len,
                                      uint32_t buf_rva, unsigned int offset,
                                      x86_insn_t *insn ){
     int len, size;

+ 2 - 1
CMakeLists.txt

@@ -25,7 +25,7 @@ ENDIF()
 
 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 tablegen)
 INCLUDE_DIRECTORIES(
     3rd_party/libdisasm
     include
@@ -50,6 +50,7 @@ set(dcc_LIB_SOURCES
     src/hltype.cpp
     src/machine_x86.cpp
     src/icode.cpp
+    src/RegisterNode
     src/idioms.cpp
     src/idioms/idiom1.cpp
     src/idioms/arith_idioms.cpp

+ 1 - 1
base_regression.sh

@@ -3,4 +3,4 @@
 #make -j5
 #cd ..
 ./test_use_base.sh
-./regression_tester.rb ./dcc_original -s -c 2>stderr >stdout; diff tests/prev/ tests/outputs/
+./regression_tester.rb ./dcc_original -s -c 2>stderr >stdout; diff -wB tests/prev/ tests/outputs/

+ 1 - 1
full_regression.sh

@@ -1,3 +1,3 @@
 #!/bin/bash
 ./test_use_all.sh
-./regression_tester.rb ./dcc_original -s -c 2>stderr >stdout; diff tests/prev/ tests/outputs/
+./regression_tester.rb ./dcc_original -s -c 2>stderr >stdout; diff -wB tests/prev/ tests/outputs/

+ 2 - 1
include/BinaryImage.h

@@ -15,6 +15,7 @@ struct PROG /* Loaded program image parameters  */
     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 */
+    const uint8_t *image() const {return Imagez;}
+    uint8_t *   Imagez;      /* Allocated by loader to hold entire program image */
 };
 

+ 1 - 0
include/Enums.h

@@ -8,6 +8,7 @@ enum regType
 };
 enum condId
 {
+    UNDEF=0,
     GLOB_VAR,       /* global variable  */
     REGISTER,       /* register         */
     LOCAL_VAR,      /* negative disp    */

+ 11 - 14
include/IdentType.h

@@ -2,32 +2,29 @@
 #include "ast.h"
 #include "types.h"
 #include "machine_x86.h"
-
+struct GlobalVariable;
+struct AstIdent;
 struct IDENTTYPE
 {
+    friend struct GlobalVariable;
+    friend struct Constant;
+    friend struct AstIdent;
+protected:
     condId           idType;
-    regType          regiType;  /* for REGISTER only                */
+public:
+    condId           type() {return idType;}
+    void             type(condId t) {idType=t;}
     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;
+    IDENTTYPE() : idType(UNDEF)
+    {}
 };

+ 6 - 4
include/Procedure.h

@@ -9,7 +9,7 @@
 #include "StackFrame.h"
 /* PROCEDURE NODE */
 struct CALL_GRAPH;
-struct COND_EXPR;
+struct Expr;
 struct Disassembler;
 struct Function;
 struct CALL_GRAPH;
@@ -74,8 +74,8 @@ struct FunctionType
 };
 struct Assignment
 {
-    COND_EXPR *lhs;
-    COND_EXPR *rhs;
+    Expr *lhs;
+    Expr *rhs;
 };
 struct JumpTable
 {
@@ -184,9 +184,11 @@ public:
 
     void displayCFG();
     void displayStats();
-    void processHliCall(COND_EXPR *exp, iICODE picode);
+    void processHliCall(Expr *exp, iICODE picode);
 
     void preprocessReturnDU(LivenessSet &_liveOut);
+    Expr * adjustActArgType(Expr *_exp, hlType forType);
+    std::string writeCall(Function *tproc, STKFRAME &args, int *numLoc);
 protected:
     void extractJumpTableRange(ICODE& pIcode, STATE *pstate, JumpTable &table);
     bool followAllTableEntries(JumpTable &table, uint32_t cs, ICODE &pIcode, CALL_GRAPH *pcallGraph, STATE *pstate);

+ 144 - 60
include/ast.h

@@ -5,6 +5,7 @@
  * (C) Cristina Cifuentes
  */
 #pragma once
+#include <stdint.h>
 #include <cstring>
 #include <list>
 #include <boost/range/iterator_range.hpp>
@@ -34,37 +35,37 @@ typedef boost::iterator_range<iICODE> rICODE;
 #include "IdentType.h"
 
 /* Expression data type */
-struct COND_EXPR
+struct Expr
 {
 public:
     condNodeType            m_type;     /* Conditional Expression Node Type */
 public:
-    static bool         insertSubTreeLongReg(COND_EXPR *exp, COND_EXPR *&tree, int longIdx);
-    static bool         insertSubTreeReg(COND_EXPR *&tree, COND_EXPR *_expr, eReg regi, const LOCAL_ID *locsym);
-    static bool         insertSubTreeReg(AstIdent *&tree, COND_EXPR *_expr, eReg regi, const LOCAL_ID *locsym);
+    static bool         insertSubTreeLongReg(Expr *exp, Expr *&tree, int longIdx);
+    static bool         insertSubTreeReg(Expr *&tree, Expr *_expr, eReg regi, const LOCAL_ID *locsym);
+    static bool         insertSubTreeReg(AstIdent *&tree, Expr *_expr, eReg regi, const LOCAL_ID *locsym);
 public:
-    virtual COND_EXPR *clone() const;
-    void release();
-    COND_EXPR(condNodeType t=UNKNOWN_OP) : m_type(t)
+
+    virtual Expr *clone() const=0;  //!< Makes a deep copy of the given expression
+    Expr(condNodeType t=UNKNOWN_OP) : m_type(t)
     {
 
     }
-    virtual ~COND_EXPR();
+    virtual ~Expr();
 public:
     virtual std::string walkCondExpr (Function * pProc, int* numLoc) const=0;
-    virtual COND_EXPR *inverse() const=0; // return new COND_EXPR that is invarse of this
+    virtual Expr *inverse() const=0; // return new COND_EXPR that is invarse of this
     virtual bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locId)=0;
-    virtual COND_EXPR *insertSubTreeReg(COND_EXPR *_expr, eReg regi, const LOCAL_ID *locsym)=0;
-    virtual COND_EXPR *insertSubTreeLongReg(COND_EXPR *_expr, int longIdx)=0;
-    virtual hlType expType(Function *pproc) const;
+    virtual Expr *insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *locsym)=0;
+    virtual Expr *insertSubTreeLongReg(Expr *_expr, int longIdx)=0;
+    virtual hlType expType(Function *pproc) const=0;
     virtual int hlTypeSize(Function *pproc) const=0;
-    virtual void performLongRemoval(eReg regi, LOCAL_ID *locId) {}
+    virtual Expr * performLongRemoval(eReg regi, LOCAL_ID *locId) { return this; }
 };
-struct UnaryOperator : public COND_EXPR
+struct UnaryOperator : public Expr
 {
-    UnaryOperator(condNodeType t=UNKNOWN_OP) : COND_EXPR(t),unaryExp(nullptr) {}
-    COND_EXPR *unaryExp;
-    virtual COND_EXPR *inverse() const
+    UnaryOperator(condNodeType t=UNKNOWN_OP) : Expr(t),unaryExp(nullptr) {}
+    Expr *unaryExp;
+    virtual Expr *inverse() const
     {
         if (m_type == NEGATION) //TODO: memleak here
         {
@@ -72,14 +73,14 @@ struct UnaryOperator : public COND_EXPR
         }
         return this->clone();
     }
-    virtual COND_EXPR *clone() const
+    virtual Expr *clone() const
     {
         UnaryOperator *newExp = new UnaryOperator(*this);
         newExp->unaryExp = unaryExp->clone();
         return newExp;
     }
     virtual bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locs);
-    static UnaryOperator *Create(condNodeType t, COND_EXPR *sub_expr)
+    static UnaryOperator *Create(condNodeType t, Expr *sub_expr)
     {
         UnaryOperator *newExp = new UnaryOperator();
         newExp->m_type = t;
@@ -94,22 +95,22 @@ struct UnaryOperator : public COND_EXPR
 public:
     int hlTypeSize(Function *pproc) const;
     virtual std::string walkCondExpr(Function *pProc, int *numLoc) const;
-    virtual COND_EXPR *insertSubTreeReg(COND_EXPR *_expr, eReg regi, const LOCAL_ID *locsym);
+    virtual Expr *insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *locsym);
     virtual hlType expType(Function *pproc) const;
-    virtual COND_EXPR *insertSubTreeLongReg(COND_EXPR *_expr, int longIdx);
+    virtual Expr *insertSubTreeLongReg(Expr *_expr, int longIdx);
 };
 
-struct BinaryOperator : public COND_EXPR
+struct BinaryOperator : public Expr
 {
     condOp      m_op;
-    COND_EXPR *m_lhs;
-    COND_EXPR *m_rhs;
-    BinaryOperator(condOp o) : COND_EXPR(BOOLEAN_OP)
+    Expr *m_lhs;
+    Expr *m_rhs;
+    BinaryOperator(condOp o) : Expr(BOOLEAN_OP)
     {
         m_op = o;
         m_lhs=m_rhs=nullptr;
     }
-    BinaryOperator(condOp o,COND_EXPR *l,COND_EXPR *r) : COND_EXPR(BOOLEAN_OP)
+    BinaryOperator(condOp o,Expr *l,Expr *r) : Expr(BOOLEAN_OP)
     {
         m_op = o;
         m_lhs=l;
@@ -121,51 +122,51 @@ struct BinaryOperator : public COND_EXPR
         delete m_lhs;
         delete m_rhs;
     }
-    static BinaryOperator *Create(condOp o,COND_EXPR *l,COND_EXPR *r)
+    static BinaryOperator *Create(condOp o,Expr *l,Expr *r)
     {
         BinaryOperator *res = new BinaryOperator(o);
         res->m_lhs = l;
         res->m_rhs = r;
         return res;
     }
-    static BinaryOperator *LogicAnd(COND_EXPR *l,COND_EXPR *r)
+    static BinaryOperator *LogicAnd(Expr *l,Expr *r)
     {
         return new BinaryOperator(DBL_AND,l,r);
     }
-    static BinaryOperator *And(COND_EXPR *l,COND_EXPR *r)
+    static BinaryOperator *And(Expr *l,Expr *r)
     {
         return new BinaryOperator(AND,l,r);
     }
-    static BinaryOperator *Or(COND_EXPR *l,COND_EXPR *r)
+    static BinaryOperator *Or(Expr *l,Expr *r)
     {
         return new BinaryOperator(OR,l,r);
     }
-    static BinaryOperator *LogicOr(COND_EXPR *l,COND_EXPR *r)
+    static BinaryOperator *LogicOr(Expr *l,Expr *r)
     {
         return new BinaryOperator(DBL_OR,l,r);
     }
-    static BinaryOperator *CreateAdd(COND_EXPR *l,COND_EXPR *r);
+    static BinaryOperator *CreateAdd(Expr *l,Expr *r);
     void changeBoolOp(condOp newOp);
-    virtual COND_EXPR *inverse() const;
-    virtual COND_EXPR *clone() const;
+    virtual Expr *inverse() const;
+    virtual Expr *clone() const;
     virtual bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locs);
-    virtual COND_EXPR *insertSubTreeReg(COND_EXPR *_expr, eReg regi, const LOCAL_ID *locsym);
-    virtual COND_EXPR *insertSubTreeLongReg(COND_EXPR *_expr, int longIdx);
-    const COND_EXPR *lhs() const
+    virtual Expr *insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *locsym);
+    virtual Expr *insertSubTreeLongReg(Expr *_expr, int longIdx);
+    const Expr *lhs() const
     {
-        return const_cast<const COND_EXPR *>(const_cast<BinaryOperator *>(this)->lhs());
+        return const_cast<const Expr *>(const_cast<BinaryOperator *>(this)->lhs());
     }
-    const COND_EXPR *rhs() const
+    const Expr *rhs() const
     {
-        return const_cast<const COND_EXPR *>(const_cast<BinaryOperator *>(this)->rhs());
+        return const_cast<const Expr *>(const_cast<BinaryOperator *>(this)->rhs());
     }
 
-    COND_EXPR *lhs()
+    Expr *lhs()
     {
         assert(m_type==BOOLEAN_OP);
         return m_lhs;
     }
-    COND_EXPR *rhs()
+    Expr *rhs()
     {
         assert(m_type==BOOLEAN_OP);
         return m_rhs;
@@ -182,31 +183,27 @@ struct AstIdent : public UnaryOperator
 {
     AstIdent() : UnaryOperator(IDENTIFIER)
     {
-        memset(&ident,0,sizeof(ident));
-    }
-    virtual COND_EXPR *clone() const
-    {
-        return new AstIdent(*this);
     }
     IDENTTYPE   ident;              /* for IDENTIFIER                   */
-    static AstIdent *  RegIdx(int idx, regType reg_type);
-    static AstIdent *  Kte(uint32_t kte, uint8_t size);
     static AstIdent *  Loc(int off, LOCAL_ID *localId);
-    static AstIdent *  Reg(eReg regi, uint32_t icodeFlg, LOCAL_ID *locsym);
     static AstIdent *  LongIdx(int idx);
+    static AstIdent *  String(uint32_t idx);
     static AstIdent *  Other(eReg seg, eReg regi, int16_t off);
-    static AstIdent *  idParam(int off, const STKFRAME *argSymtab);
-    static AstIdent *  idLong(LOCAL_ID *localId, opLoc sd, iICODE pIcode, hlFirst f, iICODE ix, operDu du, LLInst &atOffset);
-    static AstIdent *  idFunc(Function *pproc, STKFRAME *args);
+    static AstIdent *  Param(int off, const STKFRAME *argSymtab);
+    static AstIdent *  Long(LOCAL_ID *localId, opLoc sd, iICODE pIcode, hlFirst f, iICODE ix, operDu du, LLInst &atOffset);
     static AstIdent *  idID(const ID *retVal, LOCAL_ID *locsym, iICODE ix_);
-    static COND_EXPR * id(const LLInst &ll_insn, opLoc sd, Function *pProc, iICODE ix_, ICODE &duIcode, operDu du);
+    static Expr * id(const LLInst &ll_insn, opLoc sd, Function *pProc, iICODE ix_, ICODE &duIcode, operDu du);
 
+    virtual Expr *clone() const
+    {
+        return new AstIdent(*this);
+    }
     virtual int hlTypeSize(Function *pproc) const;
     virtual hlType expType(Function *pproc) const;
-    virtual void performLongRemoval(eReg regi, LOCAL_ID *locId);
+    virtual Expr * performLongRemoval(eReg regi, LOCAL_ID *locId);
     virtual std::string walkCondExpr(Function *pProc, int *numLoc) const;
-    virtual COND_EXPR *insertSubTreeReg(COND_EXPR *_expr, eReg regi, const LOCAL_ID *locsym);
-    virtual COND_EXPR *insertSubTreeLongReg(COND_EXPR *_expr, int longIdx);
+    virtual Expr *insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *locsym);
+    virtual Expr *insertSubTreeLongReg(Expr *_expr, int longIdx);
     virtual bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locId);
 protected:
     eReg otherLongRegi (eReg regi, int idx, LOCAL_ID *locTbl);
@@ -214,7 +211,94 @@ protected:
 };
 struct GlobalVariable : public AstIdent
 {
-    static AstIdent *Create(int16_t segValue, int16_t off);
+    bool valid;
+    int globIdx;
+    virtual Expr *clone() const
+    {
+        return new GlobalVariable(*this);
+    }
+    GlobalVariable(int16_t segValue, int16_t off);
+    std::string walkCondExpr(Function *pProc, int *numLoc) const;
+    int hlTypeSize(Function *pproc) const;
+    hlType expType(Function *pproc) const;
+};
+struct GlobalVariableIdx : public AstIdent
+{
+    bool valid;
+    int idxGlbIdx;	/* idx into localId, GLOB_VAR_IDX   */
+
+    virtual Expr *clone() const
+    {
+        return new GlobalVariableIdx(*this);
+    }
+    GlobalVariableIdx(int16_t segValue, int16_t off, uint8_t regi, const LOCAL_ID *locSym);
+    std::string walkCondExpr(Function *pProc, int *numLoc) const;
+    int hlTypeSize(Function *pproc) const;
+    hlType expType(Function *pproc) const;
+};
+struct Constant : public AstIdent
+{
+    struct _kte
+    {			/* for CONSTANT only					*/
+        uint32_t   kte;   	/*   value of the constant			*/
+        uint8_t    size;       /*   #bytes size constant	 		*/
+    } kte;
+
+    Constant(uint32_t _kte, uint8_t size)
+    {
+        ident.idType = CONSTANT;
+        kte.kte = _kte;
+        kte.size = size;
+    }
+    virtual Expr *clone() const
+    {
+        return new Constant(*this);
+    }
+    std::string walkCondExpr(Function *pProc, int *numLoc) const;
+    int hlTypeSize(Function *pproc) const;
+    hlType expType(Function *pproc) const;
+};
+struct FuncNode : public AstIdent
+{
+    struct _call {			/* for FUNCTION only				*/
+        Function     *proc;
+        STKFRAME *args;
+    } call;
+
+    FuncNode(Function *pproc, STKFRAME *args)
+    {
+        call.proc = pproc;
+        call.args = args;
+    }
+    virtual Expr *clone() const
+    {
+        return new FuncNode(*this);
+    }
+    std::string walkCondExpr(Function *pProc, int *numLoc) const;
+    int hlTypeSize(Function *pproc) const;
+    hlType expType(Function *pproc) const;
+};
+struct RegisterNode : public AstIdent
+{
+    regType     regiType;  /* for REGISTER only                */
+    int         regiIdx;   /* index into localId, REGISTER		*/
+
+    virtual Expr *insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *locsym);
+
+    RegisterNode(int idx, regType reg_type)
+    {
+        ident.type(REGISTER);
+        regiType = reg_type;
+        regiIdx = idx;
+    }
+
+    RegisterNode(eReg regi, uint32_t icodeFlg, LOCAL_ID *locsym);
+    virtual Expr *clone() const
+    {
+        return new RegisterNode(*this);
+    }
+    std::string walkCondExpr(Function *pProc, int *numLoc) const;
+    int hlTypeSize(Function *) const;
+    hlType expType(Function *pproc) const;
+    bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locId);
 };
-struct Constant : public COND_EXPR
-{};

+ 1 - 1
include/bundle.h

@@ -33,7 +33,7 @@ public:
     int current_indent;
 };
 
-
+extern bundle cCode;
 #define lineSize	360		/* 3 lines in the mean time */
 
 //void    newBundle (bundle *procCode);

+ 2 - 7
include/dcc.h

@@ -37,9 +37,6 @@ public:
         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     */
 extern bundle cCode;			/* Output C procedure's declaration and code */
 
@@ -110,11 +107,11 @@ 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    */
+extern 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     */
+extern int     strSize (const uint8_t *, char);             /* parser.c     */
 //void    disassem(int pass, Function * pProc);             /* disassem.c   */
 void    interactDis(Function *, int initIC);       /* disassem.c   */
 bool    JmpInst(llIcode opcode);                            /* idioms.c     */
@@ -126,10 +123,8 @@ bool    LibCheck(Function &p);                              /* chklib.c     */
 
 /* Exported functions from procs.c */
 boolT	insertCallGraph (CALL_GRAPH *, ilFunction, ilFunction);
-void	adjustActArgType (COND_EXPR *, hlType, Function *);
 
 /* Exported functions from hlicode.c */
-std::string writeCall (Function *, STKFRAME &, Function *, int *);
 char 	*writeJcond (const HLTYPE &, Function *, int *);
 char 	*writeJcondInv (HLTYPE, Function *, int *);
 

+ 5 - 2
include/error.h

@@ -1,7 +1,10 @@
-/*****************************************************************************
+/*
+
+****************************************************************************
  * Error codes
  * (C) Cristina Cifuentes
- ****************************************************************************/
+***************************************************************************
+*/
 #pragma once
 
 /* These definitions refer to errorMessage in error.c */

+ 53 - 40
include/icode.h

@@ -65,6 +65,8 @@ struct LivenessSet : public std::bitset<32>
     {
         return test(r-rAX);
     }
+public:
+    LivenessSet &clrReg(int r);
 private:
     void postProcessCompositeRegs();
 };
@@ -83,15 +85,16 @@ struct DU
 #define MAX_REGS_DEF	4		/* 2 regs def'd for long-reg vars */
 
 
-struct COND_EXPR;
+struct Expr;
 struct AstIdent;
+struct UnaryOperator;
 struct HlTypeSupport
 {
     //hlIcode              opcode;    /* hlIcode opcode           */
     virtual bool        removeRegFromLong(eReg regi, LOCAL_ID *locId)=0;
     virtual std::string writeOut(Function *pProc, int *numLoc) const=0;
 protected:
-    void performLongRemoval (eReg regi, LOCAL_ID *locId, COND_EXPR *tree);
+    Expr * performLongRemoval (eReg regi, LOCAL_ID *locId, Expr *tree);
 };
 
 struct CallType : public HlTypeSupport
@@ -100,9 +103,9 @@ struct CallType : public HlTypeSupport
     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();
+    bool newStkArg(Expr *exp, llIcode opcode, Function *pproc);
+    void placeStkArg(Expr *exp, int pos);
+    virtual Expr * toAst();
 public:
     bool removeRegFromLong(eReg /*regi*/, LOCAL_ID */*locId*/)
     {
@@ -114,20 +117,24 @@ public:
 struct AssignType : public HlTypeSupport
 {
     /* for HLI_ASSIGN */
-    COND_EXPR    *lhs;
-    COND_EXPR    *rhs;
-    AssignType() : lhs(0),rhs(0) {}
+protected:
+public:
+    Expr    *m_lhs;
+    Expr    *rhs;
+    AssignType() {}
+    Expr *lhs() const {return m_lhs;}
+    void lhs(Expr *l);
     bool removeRegFromLong(eReg regi, LOCAL_ID *locId);
     std::string writeOut(Function *pProc, int *numLoc) const;
 };
 struct ExpType : public HlTypeSupport
 {
     /* for HLI_JCOND, HLI_RET, HLI_PUSH, HLI_POP*/
-    COND_EXPR    *v;
+    Expr    *v;
     ExpType() : v(0) {}
     bool removeRegFromLong(eReg regi, LOCAL_ID *locId)
     {
-        performLongRemoval(regi,locId,v);
+        v=performLongRemoval(regi,locId,v);
         return true;
     }
     std::string writeOut(Function *pProc, int *numLoc) const;
@@ -147,15 +154,21 @@ public:
         return const_cast<const HlTypeSupport *>(const_cast<HLTYPE*>(this)->get());
     }
 
-    void expr(COND_EXPR *e)
+    void expr(Expr *e)
     {
         assert(e);
         exp.v=e;
     }
-    void replaceExpr(COND_EXPR *e);
-    COND_EXPR * expr() { return exp.v;}
-    const COND_EXPR * expr() const  { return exp.v;}
-    void set(hlIcode i,COND_EXPR *e)
+    Expr *getMyExpr()
+    {
+        if(opcode==HLI_CALL)
+            return call.toAst();
+        return expr();
+    }
+    void replaceExpr(Expr *e);
+    Expr * expr() { return exp.v;}
+    const Expr * expr() const  { return exp.v;}
+    void set(hlIcode i,Expr *e)
     {
         if(i!=HLI_RET)
             assert(e);
@@ -163,7 +176,7 @@ public:
         opcode=i;
         exp.v=e;
     }
-    void set(COND_EXPR *l,COND_EXPR *r);
+    void set(Expr *l,Expr *r);
     void setCall(Function *proc);
     HLTYPE(hlIcode op=HLI_INVALID) : opcode(op)
     {}
@@ -179,7 +192,7 @@ public:
     }
 public:
     std::string write1HlIcode(Function *pProc, int *numLoc) const;
-    void setAsgn(COND_EXPR *lhs, COND_EXPR *rhs);
+    void setAsgn(Expr *lhs, Expr *rhs);
 } ;
 /* LOW_LEVEL icode operand record */
 struct LLOperand
@@ -201,6 +214,16 @@ struct LLOperand
         proc.proc=0;
         proc.cb=0;
     }
+    bool operator==(const LLOperand &with) const
+    {
+        return (seg==with.seg) &&
+                (segOver==with.segOver) &&
+                (segValue==with.segValue) &&
+                (regi == with.regi) &&
+                (off == with.off) &&
+                (opz==with.opz) &&
+                (proc.proc==with.proc.proc);
+    }
     int64_t getImm2() const {return opz;}
     void SetImmediateOp(uint32_t dw)
     {
@@ -219,8 +242,6 @@ struct LLOperand
     static LLOperand CreateReg2(unsigned Val)
     {
         LLOperand Op;
-//        Op.Kind = kRegister;
-//        Op.RegVal = Reg;
         Op.regi = (eReg)Val;
         return Op;
     }
@@ -229,20 +250,15 @@ struct LLOperand
 struct LLInst : public llvm::MCInst //: public llvm::ilist_node<LLInst>
 {
 protected:
-    uint32_t     flg;            /* icode flags                  */
-//    LLOperand &get(int idx)
-//    {
-//        assert(idx<size());
-//        return getOperand(idx);
-//    }
-    LLOperand    m_src;            /* source operand               */
+    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;
+    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()
@@ -260,9 +276,7 @@ public:
         flg &= ~flag;
     }
     uint32_t getFlag() const {return flg;}
-    //llIcode getOpcode() const { return opcode; }
-
-    uint32_t  GetLlLabel() const { return label;}
+    uint32_t GetLlLabel() const { return label;}
 
     void SetImmediateOp(uint32_t dw) {m_src.SetImmediateOp(dw);}
 
@@ -308,7 +322,6 @@ public:
 
     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)
     {
@@ -465,13 +478,13 @@ public:
     condId idType(opLoc sd);
     // HLL setting functions
     // set this icode to be an assign
-    void setAsgn(COND_EXPR *lhs, COND_EXPR *rhs)
+    void setAsgn(Expr *lhs, Expr *rhs)
     {
         type=HIGH_LEVEL;
         hlU()->setAsgn(lhs,rhs);
     }
-    void setUnary(hlIcode op, COND_EXPR *_exp);
-    void setJCond(COND_EXPR *cexp);
+    void setUnary(hlIcode op, Expr *_exp);
+    void setJCond(Expr *cexp);
 
     void emitGotoLabel(int indLevel);
     void copyDU(const ICODE &duIcode, operDu _du, operDu duDu);
@@ -480,7 +493,7 @@ public:
 public:
     bool removeDefRegi(eReg regi, int thisDefIdx, LOCAL_ID *locId);
     void checkHlCall();
-    bool newStkArg(COND_EXPR *exp, llIcode opcode, Function *pproc)
+    bool newStkArg(Expr *exp, llIcode opcode, Function *pproc)
     {
         return hlU()->call.newStkArg(exp,opcode,pproc);
     }

+ 2 - 2
include/locident.h

@@ -18,7 +18,7 @@
 /* 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 Expr;
 struct AstIdent;
 struct ICODE;
 struct LLInst;
@@ -132,7 +132,7 @@ public:
     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;
+    void forwardSubs(Expr *lhs, Expr *rhs, iICODE picode, iICODE ticode, int &numHlIcodes) const;
     AstIdent *createId(const ID *retVal, iICODE ix_);
 };
 

+ 4 - 0
include/state.h

@@ -30,6 +30,10 @@ struct STATE
         memset(r,0,sizeof(int16_t)*INDEX_BX_SI); //TODO: move this to machine_x86
         memset(f,0,sizeof(uint8_t)*INDEX_BX_SI);
     }
+    void setMemoryByte(uint32_t addr,uint8_t val)
+    {
+        //TODO: make this into a full scale value tracking class !
+    };
 };
 
 

+ 2 - 2
include/symtab.h

@@ -7,7 +7,7 @@
 #include <stdint.h>
 #include "Enums.h"
 #include "types.h"
-struct COND_EXPR;
+struct Expr;
 struct AstIdent;
 struct TypeContainer;
 /* * * * * * * * * * * * * * * * * */
@@ -36,7 +36,7 @@ struct SYM : public SymbolCommon
 struct STKSYM : public SymbolCommon
 {
     typedef int16_t tLabel;
-    COND_EXPR	*actual;	/* Expression tree of actual parameter 		*/
+    Expr	*actual;	/* Expression tree of actual parameter 		*/
     AstIdent 	*regs;		/* For register arguments only				*/
     tLabel      label;        /* Immediate off from BP (+:args, -:params) */
     uint8_t     regOff;     /* Offset is a register (e.g. SI, DI)       */

+ 1 - 0
regression_tester.rb

@@ -14,6 +14,7 @@ def perform_test(exepath,filepath,outname,args)
 	filepath=path_local(filepath)
 	joined_args = args.join(' ')
 	printf("calling:" + "#{exepath} -a1 #{joined_args} -o#{output_path}.a1 #{filepath}\n")
+	STDERR << "Errors for : #{filepath}"
 	result = `#{exepath} -a1 -o#{output_path}.a1 #{filepath}`
 	result = `#{exepath} -a2 #{joined_args} -o#{output_path}.a2 #{filepath}`
 	result = `#{exepath} #{joined_args} -o#{output_path} #{filepath}`

+ 0 - 1
src/BasicBlock.cpp

@@ -408,7 +408,6 @@ ICODE &BB::back()
 
 size_t BB::size()
 {
-
     return distance(instructions.begin(),instructions.end());
 }
 

+ 3 - 3
src/Procedure.cpp

@@ -14,7 +14,7 @@ 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]);
+        uint32_t target = cs + LH(&prg->image()[i]);
         if (target < finish && target >= start)
             finish = target;
         else if (target >= (uint32_t)prg->cbImage)
@@ -23,9 +23,9 @@ void JumpTable::pruneEntries(uint16_t cs)
     ICODE _Icode; // used as scan input
     for (uint32_t i = start; i < finish; i += 2)
     {
-        uint32_t target = cs + LH(&prg->Image[i]);
+        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))
+        if (! (prg->image()[target] || prg->image()[target+1]) || scan(target, _Icode))
             finish = i;
     }
 

+ 193 - 308
src/ast.cpp

@@ -9,11 +9,24 @@
 #include <sstream>
 #include <iostream>
 #include <cassert>
+#include <boost/range.hpp>
+#include <boost/range/adaptors.hpp>
+#include <boost/range/algorithm.hpp>
+#include <boost/assign.hpp>
+
 #include "types.h"
-#include "dcc.h"
+#include "ast.h"
+#include "bundle.h"
 #include "machine_x86.h"
 #include "project.h"
 using namespace std;
+using namespace boost;
+using namespace boost::adaptors;
+extern int     strSize (const uint8_t *, char);
+extern char   *cChar(uint8_t c);
+
+
+
 // Conditional operator symbols in C.  Index by condOp enumeration type
 static const char * const condOpSym[] = { " <= ", " < ", " == ", " != ", " > ", " >= ",
                                           " & ", " | ", " ^ ", " ~ ",
@@ -97,61 +110,27 @@ void ICODE::copyDU(const ICODE &duIcode, operDu _du, operDu duDu)
 
 
 /* Returns an identifier conditional expression node of type GLOB_VAR */
-AstIdent *GlobalVariable::Create(int16_t segValue, int16_t off)
+GlobalVariable::GlobalVariable(int16_t segValue, int16_t off)
 {
-    AstIdent *newExp;
     uint32_t adr;
-
-    newExp = new AstIdent();
-    newExp->ident.idType = GLOB_VAR;
+    valid = true;
+    ident.idType = GLOB_VAR;
     adr = opAdr(segValue, off);
     auto i=Project::get()->getSymIdxByAdd(adr);
     if ( not Project::get()->validSymIdx(i) )
     {
         printf ("Error, glob var not found in symtab\n");
-        delete newExp;
-        return 0;
+        valid = false;
     }
-    newExp->ident.idNode.globIdx = i;
-    return (newExp);
+    globIdx = i;
 }
 
-
-/* Returns an identifier conditional expression node of type REGISTER */
-AstIdent *AstIdent::Reg(eReg regi, uint32_t icodeFlg, LOCAL_ID *locsym)
+string GlobalVariable::walkCondExpr(Function *, int *) const
 {
-    AstIdent *newExp;
-
-    newExp = new AstIdent();
-    newExp->ident.idType = REGISTER;
-    hlType type_sel;
-    regType reg_type;
-    if ((icodeFlg & B) || (icodeFlg & SRC_B))
-    {
-        type_sel = TYPE_BYTE_SIGN;
-        reg_type = BYTE_REG;
-    }
-    else    /* uint16_t */
-    {
-        type_sel = TYPE_WORD_SIGN;
-        reg_type = WORD_REG;
-    }
-    newExp->ident.idNode.regiIdx = locsym->newByteWordReg(type_sel, regi);
-    newExp->ident.regiType = reg_type;
-    return (newExp);
-}
-
-
-/* Returns an identifier conditional expression node of type REGISTER */
-AstIdent *AstIdent::RegIdx(int idx, regType reg_type)
-{
-    AstIdent *newExp;
-
-    newExp = new AstIdent();
-    newExp->ident.idType = REGISTER;
-    newExp->ident.regiType = reg_type;
-    newExp->ident.idNode.regiIdx = idx;
-    return (newExp);
+    if(valid)
+        return Project::get()->symtab[globIdx].name;
+    else
+        return "INVALID GlobalVariable";
 }
 
 /* Returns an identifier conditional expression node of type LOCAL_VAR */
@@ -177,7 +156,7 @@ AstIdent *AstIdent::Loc(int off, LOCAL_ID *localId)
 
 
 /* Returns an identifier conditional expression node of type PARAM */
-AstIdent *AstIdent::idParam(int off, const STKFRAME * argSymtab)
+AstIdent *AstIdent::Param(int off, const STKFRAME * argSymtab)
 {
     AstIdent *newExp;
 
@@ -193,11 +172,10 @@ AstIdent *AstIdent::idParam(int off, const STKFRAME * argSymtab)
 
 /* Returns an identifier conditional expression node of type GLOB_VAR_IDX.
  * This global variable is indexed by regi.     */
-AstIdent *idCondExpIdxGlob (int16_t segValue, int16_t off, uint8_t regi, const LOCAL_ID *locSym)
+GlobalVariableIdx::GlobalVariableIdx (int16_t segValue, int16_t off, uint8_t regi, const LOCAL_ID *locSym)
 {
     size_t i;
-    AstIdent *newExp  = new AstIdent();
-    newExp->ident.idType = GLOB_VAR_IDX;
+    ident.type(GLOB_VAR_IDX);
     for (i = 0; i < locSym->csym(); i++)
     {
         const BWGLB_TYPE &lID(locSym->id_arr[i].id.bwGlb);
@@ -206,19 +184,14 @@ AstIdent *idCondExpIdxGlob (int16_t segValue, int16_t off, uint8_t regi, const L
     }
     if (i == locSym->csym())
         printf ("Error, indexed-glob var not found in local id table\n");
-    newExp->ident.idNode.idxGlbIdx = i;
-    return (newExp);
+    idxGlbIdx = i;
 }
-
-
-/* Returns an identifier conditional expression node of type CONSTANT */
-AstIdent *AstIdent::Kte(uint32_t kte, uint8_t size)
+string GlobalVariableIdx::walkCondExpr(Function *pProc, int *) const
 {
-    AstIdent *newExp = new AstIdent();
-    newExp->ident.idType = CONSTANT;
-    newExp->ident.idNode.kte.kte = kte;
-    newExp->ident.idNode.kte.size = size;
-    return (newExp);
+    ostringstream o;
+    auto bwGlb = &pProc->localId.id_arr[idxGlbIdx].id.bwGlb;
+    o << (bwGlb->seg << 4) + bwGlb->off <<  "["<<Machine_X86::regName(bwGlb->regi)<<"]";
+    return o.str();
 }
 
 
@@ -232,27 +205,34 @@ AstIdent *AstIdent::LongIdx (int idx)
     return (newExp);
 }
 
+AstIdent *AstIdent::String(uint32_t idx)
+{
+    AstIdent *newExp = new AstIdent;
+    newExp->ident.idNode.strIdx = idx;
+    newExp->ident.type(STRING);
+    return newExp;
+}
+
 
 /* Returns an identifier conditional expression node of type LONG_VAR */
-AstIdent *AstIdent::idLong(LOCAL_ID *localId, opLoc sd, iICODE pIcode, hlFirst f, iICODE ix, operDu du, LLInst &atOffset)
+AstIdent *AstIdent::Long(LOCAL_ID *localId, opLoc sd, iICODE pIcode, hlFirst f, iICODE ix, operDu du, LLInst &atOffset)
 {
     int idx;
-    AstIdent *newExp  = new AstIdent();
+    AstIdent *newExp;
     /* Check for long constant and save it as a constant expression */
     if ((sd == SRC) && pIcode->ll()->testFlags(I))  /* constant */
     {
-        newExp->ident.idType = CONSTANT;
         int value;
         if (f == HIGH_FIRST)
             value = (pIcode->ll()->src().getImm2() << 16) + atOffset.src().getImm2();
         else/* LOW_FIRST */
             value = (atOffset.src().getImm2() << 16)+ pIcode->ll()->src().getImm2();
-        newExp->ident.idNode.kte.kte = value;
-        newExp->ident.idNode.kte.size = 4;
+        newExp = new Constant(value,4);
     }
     /* Save it as a long expression (reg, stack or glob) */
     else
     {
+        newExp  = new AstIdent();
         idx = localId->newLong(sd, pIcode, f, ix, du, atOffset);
         newExp->ident.idType = LONG_VAR;
         newExp->ident.idNode.longIdx = idx;
@@ -260,19 +240,6 @@ AstIdent *AstIdent::idLong(LOCAL_ID *localId, opLoc sd, iICODE pIcode, hlFirst f
     return (newExp);
 }
 
-
-/* Returns an identifier conditional expression node of type FUNCTION */
-AstIdent *AstIdent::idFunc(Function * pproc, STKFRAME * args)
-{
-    AstIdent *newExp  = new AstIdent();
-
-    newExp->ident.idType = FUNCTION;
-    newExp->ident.idNode.call.proc = pproc;
-    newExp->ident.idNode.call.args = args;
-    return (newExp);
-}
-
-
 /* Returns an identifier conditional expression node of type OTHER.
  * Temporary solution, should really be encoded as an indexed type (eg.
  * arrays). */
@@ -291,20 +258,26 @@ AstIdent *AstIdent::Other(eReg seg, eReg regi, int16_t off)
  * TYPE_WORD_SIGN	*/
 AstIdent *AstIdent::idID (const ID *retVal, LOCAL_ID *locsym, iICODE ix_)
 {
-    AstIdent *newExp  = new AstIdent();
     int idx;
-
-    if (retVal->type == TYPE_LONG_SIGN)
-    {
-        idx = locsym->newLongReg (TYPE_LONG_SIGN, retVal->id.longId.h,retVal->id.longId.l, ix_);
-        newExp->ident.idType = LONG_VAR;
-        newExp->ident.idNode.longIdx = idx;
-    }
-    else if (retVal->type == TYPE_WORD_SIGN)
+    AstIdent *newExp=nullptr;
+    switch(retVal->type)
     {
-        newExp->ident.idType = REGISTER;
-        newExp->ident.idNode.regiIdx = locsym->newByteWordReg(TYPE_WORD_SIGN, retVal->id.regi);
-        newExp->ident.regiType = WORD_REG;
+        case TYPE_LONG_SIGN:
+        {
+            newExp  = new AstIdent();
+            idx = locsym->newLongReg (TYPE_LONG_SIGN, retVal->id.longId.h,retVal->id.longId.l, ix_);
+            newExp->ident.idType = LONG_VAR;
+            newExp->ident.idNode.longIdx = idx;
+            break;
+        }
+        case TYPE_WORD_SIGN:
+            newExp = new RegisterNode(locsym->newByteWordReg(retVal->type, retVal->id.regi),WORD_REG);
+            break;
+        case TYPE_BYTE_SIGN:
+            newExp = new RegisterNode(locsym->newByteWordReg(retVal->type, retVal->id.regi),BYTE_REG);
+            break;
+        default:
+            fprintf(stderr,"AstIdent::idID unhandled type %d\n",retVal->type);
     }
     return (newExp);
 }
@@ -315,9 +288,9 @@ AstIdent *AstIdent::idID (const ID *retVal, LOCAL_ID *locsym, iICODE ix_)
  * Arguments:
  *            duIcode: icode instruction that needs the du set.
  *            du: operand is defined or used in current instruction.    */
-COND_EXPR *AstIdent::id(const LLInst &ll_insn, opLoc sd, Function * pProc, iICODE ix_,ICODE &duIcode, operDu du)
+Expr *AstIdent::id(const LLInst &ll_insn, opLoc sd, Function * pProc, iICODE ix_,ICODE &duIcode, operDu du)
 {
-    COND_EXPR *newExp;
+    Expr *newExp;
 
     int idx;          /* idx into pIcode->localId table */
 
@@ -335,35 +308,33 @@ COND_EXPR *AstIdent::id(const LLInst &ll_insn, opLoc sd, Function * pProc, iICOD
 
     else if ((sd == DST) && ll_insn.testFlags(IM_TMP_DST))
     {                                                   /* implicit tmp */
-        newExp = AstIdent::Reg (rTMP, 0, &pProc->localId);
+        newExp = new RegisterNode(rTMP, 0, &pProc->localId);
         duIcode.setRegDU(rTMP, (operDu)eUSE);
     }
 
     else if ((sd == SRC) && ll_insn.testFlags(I)) /* constant */
-        newExp = AstIdent::Kte (ll_insn.src().getImm2(), 2);
+        newExp = new Constant(ll_insn.src().getImm2(), 2);
     else if (pm.regi == rUNDEF) /* global variable */
-        newExp = GlobalVariable::Create(pm.segValue, pm.off);
+        newExp = new GlobalVariable(pm.segValue, pm.off);
     else if ( pm.isReg() )      /* register */
     {
-        newExp = AstIdent::Reg (pm.regi, (sd == SRC) ? ll_insn.getFlag() :
-                                                       ll_insn.getFlag() & NO_SRC_B,
-                                &pProc->localId);
+        newExp = new RegisterNode(pm.regi, (sd == SRC) ? ll_insn.getFlag() : ll_insn.getFlag() & NO_SRC_B, &pProc->localId);
         duIcode.setRegDU( pm.regi, du);
     }
 
     else if (pm.off)                                   /* offset */
-    {
+    { // TODO: this is ABI specific, should be actually based on Function calling conv
         if ((pm.seg == rSS) && (pm.regi == INDEX_BP)) /* idx on bp */
         {
             if (pm.off >= 0)                           /* argument */
-                newExp = AstIdent::idParam (pm.off, &pProc->args);
+                newExp = AstIdent::Param (pm.off, &pProc->args);
             else                                        /* local variable */
                 newExp = AstIdent::Loc (pm.off, &pProc->localId);
         }
         else if ((pm.seg == rDS) && (pm.regi == INDEX_BX)) /* bx */
         {
             if (pm.off > 0)        /* global variable */
-                newExp = idCondExpIdxGlob (pm.segValue, pm.off, rBX,&pProc->localId);
+                newExp = new GlobalVariableIdx(pm.segValue, pm.off, rBX,&pProc->localId);
             else
                 newExp = AstIdent::Other (pm.seg, pm.regi, pm.off);
             duIcode.setRegDU( rBX, eUSE);
@@ -377,26 +348,18 @@ COND_EXPR *AstIdent::id(const LLInst &ll_insn, opLoc sd, Function * pProc, iICOD
     {
         if ((pm.seg == rDS) && (pm.regi > INDEX_BP_DI)) /* dereference */
         {
+            eReg selected;
             switch (pm.regi) {
-                case INDEX_SI:
-                    newExp = AstIdent::Reg(rSI, 0, &pProc->localId);
-                    duIcode.setRegDU( rSI, du);
-                    break;
-                case INDEX_DI:
-                    newExp = AstIdent::Reg(rDI, 0, &pProc->localId);
-                    duIcode.setRegDU( rDI, du);
-                    break;
-                case INDEX_BP:
-                    newExp = AstIdent::Reg(rBP, 0, &pProc->localId);
-                    break;
-                case INDEX_BX:
-                    newExp = AstIdent::Reg(rBX, 0, &pProc->localId);
-                    duIcode.setRegDU( rBX, du);
-                    break;
+                case INDEX_SI: selected = rSI; break;
+                case INDEX_DI: selected = rDI; break;
+                case INDEX_BP: selected = rBP; break;
+                case INDEX_BX: selected = rBX; break;
                 default:
                     newExp = 0;
                     assert(false);
             }
+            newExp = new RegisterNode(selected, 0, &pProc->localId);
+            duIcode.setRegDU( selected, du);
             newExp = UnaryOperator::Create(DEREFERENCE, newExp);
         }
         else
@@ -433,30 +396,11 @@ 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 COND_EXPR::hlTypeSize(Function * pproc) const
+int Expr::hlTypeSize(Function * pproc) const
 {
     if (this == NULL)
         return (2);		/* for TYPE_UNKNOWN */
-
-    switch (m_type) {
-        case BOOLEAN_OP:
-            assert(false);
-            return 0;
-            //            return expr->hlTypeSize(pproc);
-        case NEGATION:	case ADDRESSOF:
-        case POST_INC:	case POST_DEC:
-        case PRE_INC:		case PRE_DEC:
-        case DEREFERENCE:
-            assert(false);
-            return 0;
-            //return expr->hlTypeSize(pproc);
-        case IDENTIFIER:
-            assert(false);
-            return 0;
-        default:
-            fprintf(stderr,"hlTypeSize queried for Unkown type %d \n",m_type);
-            break;
-    }
+    fprintf(stderr,"hlTypeSize queried for Unkown type %d \n",m_type);
     return 2;			// CC: is this correct?
 }
 
@@ -469,33 +413,35 @@ int UnaryOperator::hlTypeSize(Function *pproc) const
 {
     return (unaryExp->hlTypeSize (pproc));
 }
+int GlobalVariable::hlTypeSize(Function *pproc) const
+{
+    return (Project::get()->symbolSize(globIdx));
+}
+int GlobalVariableIdx::hlTypeSize(Function *pproc) const
+{
+    return (hlSize[pproc->localId.id_arr[idxGlbIdx].type]);
+}
+
 int AstIdent::hlTypeSize(Function *pproc) const
 {
     switch (ident.idType)
     {
         case GLOB_VAR:
-            return (Project::get()->symbolSize(ident.idNode.globIdx));
-        case REGISTER:
-            if (ident.regiType == BYTE_REG)
-                return (1);
-            else
-                return (2);
+            assert(false);
+            return 1;
         case LOCAL_VAR:
             return (hlSize[pproc->localId.id_arr[ident.idNode.localIdx].type]);
         case PARAM:
             return (hlSize[pproc->args[ident.idNode.paramIdx].type]);
-        case GLOB_VAR_IDX:
-            return (hlSize[pproc->localId.id_arr[ident.idNode.idxGlbIdx].type]);
-        case CONSTANT:
-            return (ident.idNode.kte.size);
         case STRING:
             return (2);
         case LONG_VAR:
             return (4);
-        case FUNCTION:
-            return (hlSize[ident.idNode.call.proc->retVal.type]);
         case OTHER:
             return (2);
+        default:
+            assert(false);
+            return -1;
     } /* eos */
 }
 hlType BinaryOperator::expType(Function *pproc) const
@@ -516,70 +462,47 @@ hlType UnaryOperator::expType(Function *pproc) const
 {
     return unaryExp->expType (pproc);
 }
+hlType GlobalVariable::expType(Function *pproc) const
+{
+    return Project::get()->symbolType(globIdx);
+}
+hlType GlobalVariableIdx::expType(Function *pproc) const
+{
+    return (pproc->localId.id_arr[idxGlbIdx].type);
+}
+
 hlType AstIdent::expType(Function *pproc) const
 {
     switch (ident.idType)
     {
-        case GLOB_VAR:
-            return Project::get()->symbolType(ident.idNode.globIdx);
+        case UNDEF:
+        case CONSTANT:
+        case FUNCTION:
         case REGISTER:
-            if (ident.regiType == BYTE_REG)
-                return (TYPE_BYTE_SIGN);
-            else
-                return (TYPE_WORD_SIGN);
+        case GLOB_VAR:
+        case GLOB_VAR_IDX:
+            assert(false);
+            return TYPE_UNKNOWN;
         case LOCAL_VAR:
             return (pproc->localId.id_arr[ident.idNode.localIdx].type);
         case PARAM:
             return (pproc->args[ident.idNode.paramIdx].type);
-        case GLOB_VAR_IDX:
-            return (pproc->localId.id_arr[ident.idNode.idxGlbIdx].type);
-        case CONSTANT:
-            return (TYPE_CONST);
         case STRING:
             return (TYPE_STR);
         case LONG_VAR:
             return (pproc->localId.id_arr[ident.idNode.longIdx].type);
-        case FUNCTION:
-            return (ident.idNode.call.proc->retVal.type);
         default:
             return (TYPE_UNKNOWN);
     } /* eos */
     return (TYPE_UNKNOWN);
 }
 /* Returns the type of the expression */
-hlType COND_EXPR::expType(Function * pproc) const
-{
-
-    if (this == nullptr)
-        return (TYPE_UNKNOWN);
-
-    switch (m_type)
-    {
-        case BOOLEAN_OP:
-            assert(false);
-            return TYPE_UNKNOWN;
-        case POST_INC: case POST_DEC:
-        case PRE_INC:  case PRE_DEC:
-        case NEGATION:
-            assert(false);
-            return TYPE_UNKNOWN;
-        case ADDRESSOF:	return (TYPE_PTR);		/***????****/
-        case DEREFERENCE:	return (TYPE_PTR);
-        case IDENTIFIER:
-            assert(false);
-            return TYPE_UNKNOWN;
-        case UNKNOWN_OP:
-            assert(false);
-            return (TYPE_UNKNOWN);
-    }
-    return TYPE_UNKNOWN;		// CC: Correct?
-}
 
 
 /* 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)
+Expr * HlTypeSupport::performLongRemoval (eReg regi, LOCAL_ID *locId, Expr *tree)
 {
     switch (tree->m_type) {
         case BOOLEAN_OP:
@@ -588,12 +511,13 @@ void HlTypeSupport::performLongRemoval (eReg regi, LOCAL_ID *locId, COND_EXPR *t
         case NEGATION: case ADDRESSOF:
         case DEREFERENCE:
         case IDENTIFIER:
-            tree->performLongRemoval(regi,locId);
+            return tree->performLongRemoval(regi,locId);
             break;
         default:
             fprintf(stderr,"performLongRemoval attemped on %d\n",tree->m_type);
             break;
     }
+    return tree;
 }
 
 /* Returns the string located in image, formatted in C format. */
@@ -603,10 +527,10 @@ static std::string getString (int offset)
     ostringstream o;
     int strLen, i;
 
-    strLen = strSize (&prog.Image[offset], '\0');
+    strLen = strSize (&prog.image()[offset], '\0');
     o << '"';
     for (i = 0; i < strLen; i++)
-        o<<cChar(prog.Image[offset+i]);
+        o<<cChar(prog.image()[offset+i]);
     o << "\"\0";
     return (o.str());
 }
@@ -614,7 +538,11 @@ string BinaryOperator::walkCondExpr(Function * pProc, int* numLoc) const
 {
     std::ostringstream outStr;
     outStr << "(";
-    outStr << lhs()->walkCondExpr(pProc, numLoc);
+    if(m_op!=NOT)
+    {
+        outStr << lhs()->walkCondExpr(pProc, numLoc);
+    }
+    assert(rhs());
     outStr << condOpSym[m_op];
     outStr << rhs()->walkCondExpr(pProc, numLoc);
     outStr << ")";
@@ -631,23 +559,6 @@ string AstIdent::walkCondExpr(Function *pProc, int *numLoc) const
     std::ostringstream o;
     switch (ident.idType)
     {
-        case GLOB_VAR:
-            o << Project::get()->symtab[ident.idNode.globIdx].name;
-            break;
-        case REGISTER:
-            id = &pProc->localId.id_arr[ident.idNode.regiIdx];
-            if (id->name[0] == '\0')	/* no name */
-            {
-                id->setLocalName(++(*numLoc));
-                codeOut <<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[ident.idNode.localIdx].name;
             break;
@@ -659,19 +570,6 @@ string AstIdent::walkCondExpr(Function *pProc, int *numLoc) const
             else
                 o << psym->name;
             break;
-
-        case GLOB_VAR_IDX:
-            bwGlb = &pProc->localId.id_arr[ident.idNode.idxGlbIdx].id.bwGlb;
-            o << (bwGlb->seg << 4) + bwGlb->off <<  "["<<Machine_X86::regName(bwGlb->regi)<<"]";
-            break;
-
-        case CONSTANT:
-            if (ident.idNode.kte.kte < 1000)
-                o << ident.idNode.kte.kte;
-            else
-                o << "0x"<<std::hex << ident.idNode.kte.kte;
-            break;
-
         case STRING:
             o << getString (ident.idNode.strIdx);
             break;
@@ -697,11 +595,6 @@ string AstIdent::walkCondExpr(Function *pProc, int *numLoc) const
                     o << "[" << (id->id.longGlb.seg<<4) + id->id.longGlb.offH <<"][bx]";
             }
             break;
-
-        case FUNCTION:
-            o << writeCall (ident.idNode.call.proc,*ident.idNode.call.args, pProc, numLoc);
-            break;
-
         case OTHER:
             off = ident.idNode.other.off;
             o << Machine_X86::regName(ident.idNode.other.seg)<< "[";
@@ -711,6 +604,12 @@ string AstIdent::walkCondExpr(Function *pProc, int *numLoc) const
             else if (off>0)
                 o << "+"<< hexStr (off);
             o << "]";
+            break;
+        default:
+            assert(false);
+            return "";
+
+
     } /* eos */
     outStr << o.str();
     cCode.appendDecl(codeOut.str());
@@ -783,35 +682,6 @@ string UnaryOperator::walkCondExpr(Function *pProc, int *numLoc) const
 
 
 
-/* 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=nullptr;        /* Expression node copy */
-
-    switch (m_type)
-    {
-        case BOOLEAN_OP:
-            assert(false);
-            break;
-
-        case NEGATION:
-        case ADDRESSOF:
-        case DEREFERENCE:
-        case PRE_DEC: case POST_DEC:
-        case PRE_INC: case POST_INC:
-            assert(false);
-            break;
-
-        case IDENTIFIER:
-            assert(false);
-            break;
-
-        default:
-            fprintf(stderr,"Clone attempt on unhandled type %d\n",m_type);
-    }
-    return (newExp);
-}
 
 
 /* Changes the boolean conditional operator at the root of this expression */
@@ -819,9 +689,9 @@ void BinaryOperator::changeBoolOp (condOp newOp)
 {
     m_op = newOp;
 }
-bool COND_EXPR::insertSubTreeReg (AstIdent *&tree, COND_EXPR *_expr, eReg regi,const LOCAL_ID *locsym)
+bool Expr::insertSubTreeReg (AstIdent *&tree, Expr *_expr, eReg regi,const LOCAL_ID *locsym)
 {
-    COND_EXPR *nd = tree;
+    Expr *nd = tree;
     bool res=insertSubTreeReg (nd, _expr, regi,locsym);
     if(res)
     {
@@ -833,12 +703,12 @@ bool COND_EXPR::insertSubTreeReg (AstIdent *&tree, COND_EXPR *_expr, eReg regi,c
 }
 /* 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)
+bool Expr::insertSubTreeReg (Expr *&tree, Expr *_expr, eReg regi,const LOCAL_ID *locsym)
 {
 
     if (tree == NULL)
         return false;
-    COND_EXPR *temp=tree->insertSubTreeReg(_expr,regi,locsym);
+    Expr *temp=tree->insertSubTreeReg(_expr,regi,locsym);
     if(nullptr!=temp)
     {
         tree=temp;
@@ -847,11 +717,9 @@ bool COND_EXPR::insertSubTreeReg (COND_EXPR *&tree, COND_EXPR *_expr, eReg regi,
     return false;
 }
 
-COND_EXPR *UnaryOperator::insertSubTreeReg(COND_EXPR *_expr, eReg regi, const LOCAL_ID *locsym)
+Expr *UnaryOperator::insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *locsym)
 {
-
-    eReg treeReg;
-    COND_EXPR *temp;
+    Expr *temp;
 
     switch (m_type) {
         case NEGATION:
@@ -869,9 +737,9 @@ COND_EXPR *UnaryOperator::insertSubTreeReg(COND_EXPR *_expr, eReg regi, const LO
     }
     return nullptr;
 }
-COND_EXPR *BinaryOperator::insertSubTreeReg(COND_EXPR *_expr, eReg regi, const LOCAL_ID *locsym)
+Expr *BinaryOperator::insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *locsym)
 {
-    COND_EXPR *r;
+    Expr *r;
     if(this->op()!=NOT)
     {
         assert(m_lhs);
@@ -891,30 +759,21 @@ COND_EXPR *BinaryOperator::insertSubTreeReg(COND_EXPR *_expr, eReg regi, const L
     }
     return nullptr;
 }
-COND_EXPR *AstIdent::insertSubTreeReg(COND_EXPR *_expr, eReg regi, const LOCAL_ID *locsym)
+Expr *AstIdent::insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *locsym)
 {
-    eReg treeReg;
     if (ident.idType == REGISTER)
     {
-        treeReg = locsym->id_arr[ident.idNode.regiIdx].id.regi;
-        if (treeReg == regi)                        /* uint16_t reg */
-        {
-            return _expr;
-        }
-        else if(Machine_X86::isSubRegisterOf(treeReg,regi))    /* uint16_t/uint8_t reg */
-        {
-            return _expr;
-        }
+        assert(false);
     }
     return nullptr;
 }
 /* Inserts the expression exp into the tree at the location specified by the
  * long register index longIdx*/
-bool COND_EXPR::insertSubTreeLongReg(COND_EXPR *_expr, COND_EXPR *&tree, int longIdx)
+bool Expr::insertSubTreeLongReg(Expr *_expr, Expr *&tree, int longIdx)
 {
     if (tree == NULL)
         return false;
-    COND_EXPR *temp=tree->insertSubTreeLongReg(_expr,longIdx);
+    Expr *temp=tree->insertSubTreeLongReg(_expr,longIdx);
     if(nullptr!=temp)
     {
         tree=temp;
@@ -922,9 +781,9 @@ bool COND_EXPR::insertSubTreeLongReg(COND_EXPR *_expr, COND_EXPR *&tree, int lon
     }
     return false;
 }
-COND_EXPR *UnaryOperator::insertSubTreeLongReg(COND_EXPR *_expr, int longIdx)
+Expr *UnaryOperator::insertSubTreeLongReg(Expr *_expr, int longIdx)
 {
-    COND_EXPR *temp = unaryExp->insertSubTreeLongReg(_expr,longIdx);
+    Expr *temp = unaryExp->insertSubTreeLongReg(_expr,longIdx);
     if (nullptr!=temp)
     {
         unaryExp = temp;
@@ -932,9 +791,9 @@ COND_EXPR *UnaryOperator::insertSubTreeLongReg(COND_EXPR *_expr, int longIdx)
     }
     return nullptr;
 }
-COND_EXPR *BinaryOperator::insertSubTreeLongReg(COND_EXPR *_expr, int longIdx)
+Expr *BinaryOperator::insertSubTreeLongReg(Expr *_expr, int longIdx)
 {
-    COND_EXPR *r;
+    Expr *r;
     if(m_op!=NOT)
     {
         r=m_lhs->insertSubTreeLongReg(_expr,longIdx);
@@ -952,7 +811,7 @@ COND_EXPR *BinaryOperator::insertSubTreeLongReg(COND_EXPR *_expr, int longIdx)
     }
     return nullptr;
 }
-COND_EXPR *AstIdent::insertSubTreeLongReg(COND_EXPR *_expr, int longIdx)
+Expr *AstIdent::insertSubTreeLongReg(Expr *_expr, int longIdx)
 {
     if (ident.idNode.longIdx == longIdx)
     {
@@ -962,24 +821,12 @@ COND_EXPR *AstIdent::insertSubTreeLongReg(COND_EXPR *_expr, int longIdx)
 }
 
 /* Recursively deallocates the abstract syntax tree rooted at *exp */
-COND_EXPR::~COND_EXPR()
-{
-    switch (m_type)
-    {
-        case BOOLEAN_OP:
-        case NEGATION:
-        case ADDRESSOF:
-        case DEREFERENCE:
-        case IDENTIFIER:
-            break;
-        default:
-            fprintf(stderr,"release attempt on unhandled type %d\n",m_type);
-    }
-}
+Expr::~Expr(){}
+
 /* Makes a copy of the given expression.  Allocates newExp storage for each
  * node.  Returns the copy. */
 
-COND_EXPR *BinaryOperator::clone() const
+Expr *BinaryOperator::clone() const
 {
     BinaryOperator* newExp=new BinaryOperator(m_op);        /* Expression node copy */
     newExp->m_lhs = m_lhs->clone();
@@ -987,7 +834,7 @@ COND_EXPR *BinaryOperator::clone() const
     return newExp;
 }
 
-COND_EXPR *BinaryOperator::inverse() const
+Expr *BinaryOperator::inverse() const
 {
     static condOp invCondOp[] = {GREATER, GREATER_EQUAL, NOT_EQUAL, EQUAL,
                                  LESS_EQUAL, LESS, DUMMY,DUMMY,DUMMY,DUMMY,
@@ -1017,18 +864,17 @@ COND_EXPR *BinaryOperator::inverse() const
     return res;
 
 }
-void AstIdent::performLongRemoval(eReg regi, LOCAL_ID *locId)
+Expr *AstIdent::performLongRemoval(eReg regi, LOCAL_ID *locId)
 {
     eReg otherRegi;         /* high or low part of long register */
 
-    IDENTTYPE* ident_2 = &ident;
-    if (ident_2->idType == LONG_VAR)
+    if (ident.idType == LONG_VAR)
     {
-        otherRegi = otherLongRegi (regi, ident_2->idNode.longIdx, locId);
-        ident_2->idType = REGISTER;
-        ident_2->regiType = WORD_REG;
-        ident_2->idNode.regiIdx = locId->newByteWordReg(TYPE_WORD_SIGN,otherRegi);
+        otherRegi = otherLongRegi (regi, ident.idNode.longIdx, locId);
+        delete this;
+        return new RegisterNode(locId->newByteWordReg(TYPE_WORD_SIGN,otherRegi),WORD_REG);
     }
+    return this;
 }
 eReg AstIdent::otherLongRegi (eReg regi, int idx, LOCAL_ID *locTbl)
 {
@@ -1045,3 +891,42 @@ eReg AstIdent::otherLongRegi (eReg regi, int idx, LOCAL_ID *locTbl)
     }
     return rUNDEF;	// Cristina: please check this!
 }
+
+
+string Constant::walkCondExpr(Function *, int *) const
+{
+    ostringstream o;
+    if (kte.kte < 1000)
+        o << kte.kte;
+    else
+        o << "0x"<<std::hex << kte.kte;
+    return o.str();
+}
+
+int Constant::hlTypeSize(Function *) const
+{
+    return kte.size;
+}
+
+hlType Constant::expType(Function *pproc) const
+{
+    return TYPE_CONST;
+}
+
+string FuncNode::walkCondExpr(Function *pProc, int *numLoc) const
+{
+    return pProc->writeCall(call.proc,*call.args, numLoc);
+}
+
+int FuncNode::hlTypeSize(Function *) const
+{
+    return hlSize[call.proc->retVal.type];
+}
+
+hlType FuncNode::expType(Function *) const
+{
+    return call.proc->retVal.type;
+}
+
+
+

+ 6 - 6
src/backend.cpp

@@ -108,23 +108,23 @@ static void printGlobVar (std::ostream &ostr,SYM * psym)
     switch (psym->size)
     {
         case 1:
-            ostr << "uint8_t\t"<<psym->name<<" = "<<prog.Image[relocOp]<<";\n";
+            ostr << "uint8_t\t"<<psym->name<<" = "<<prog.image()[relocOp]<<";\n";
             break;
         case 2:
-            ostr << "uint16_t\t"<<psym->name<<" = "<<LH(prog.Image+relocOp)<<";\n";
+            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";
+                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";
+                        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]);
+                strContents << cChar(prog.image()[relocOp + j]);
             ostr << "char\t*"<<psym->name<<" = \""<<strContents.str()<<"\";\n";
         }
     }

+ 37 - 37
src/chklib.cpp

@@ -74,7 +74,7 @@ void checkHeap(char *msg);              /* For debugging */
 
 void fixWildCards(uint8_t pat[]);			/* In fixwild.c */
 
-static boolT locatePattern(uint8_t *source, int iMin, int iMax, uint8_t *pattern,
+static boolT locatePattern(const uint8_t *source, int iMin, int iMax, uint8_t *pattern,
                            int iPatLen, int *index);
 
 /*  *   *   *   *   *   *   *   *   *   *   *   *   *   *   *\
@@ -457,8 +457,8 @@ bool LibCheck(Function & pProc)
         pProc.name = "main";
         return false;
     }
-    memcpy(pat, &prog.Image[fileOffset], PATLEN);
-    //memmove(pat, &prog.Image[fileOffset], PATLEN);
+    memcpy(pat, &prog.image()[fileOffset], PATLEN);
+    //memmove(pat, &prog.image()[fileOffset], PATLEN);
     fixWildCards(pat);                  /* Fix wild cards in the copy */
     h = g_pattern_hasher.hash(pat);                      /* Hash the found proc */
     /* We always have to compare keys, because the hash function will always return a valid index */
@@ -520,7 +520,7 @@ bool LibCheck(Function & pProc)
             pProc.flg |= PROC_RUNTIME;		/* => is a runtime routine */
         }
     }
-    if (locatePattern(prog.Image, pProc.procEntry,
+    if (locatePattern(prog.image(), pProc.procEntry,
                       pProc.procEntry+sizeof(pattMsChkstk),
                       pattMsChkstk, sizeof(pattMsChkstk), &Idx))
     {
@@ -587,11 +587,11 @@ void dispKey(int /*i*/)
     iPatLen). The pattern can contain wild bytes; if you really want to match
     for the pattern that is used up by the WILD uint8_t, tough - it will match with
     everything else as well. */
-static boolT locatePattern(uint8_t *source, int iMin, int iMax, uint8_t *pattern, int iPatLen,
+static boolT locatePattern(const uint8_t *source, int iMin, int iMax, uint8_t *pattern, int iPatLen,
                            int *index)
 {
     int i, j;
-    uint8_t *pSrc;                             /* Pointer to start of considered source */
+    const uint8_t *pSrc;                             /* Pointer to start of considered source */
     int iLast;
 
     iLast = iMax - iPatLen;                 /* Last source uint8_t to consider */
@@ -645,18 +645,18 @@ void STATE::checkStartup()
 
     /* Check the Turbo Pascal signatures first, since they involve only the
                 first 3 bytes, and false positives may be founf with the others later */
-    if (locatePattern(prog.Image, startOff, startOff+5, pattBorl4on,sizeof(pattBorl4on), &i))
+    if (locatePattern(prog.image(), startOff, startOff+5, pattBorl4on,sizeof(pattBorl4on), &i))
     {
         /* The first 5 bytes are a far call. Follow that call and
                         determine the version from that */
-        rel = LH(&prog.Image[startOff+1]);  	 /* This is abs off of init */
-        para= LH(&prog.Image[startOff+3]);/* This is abs seg of init */
+        rel = LH(&prog.image()[startOff+1]);  	 /* This is abs off of init */
+        para= LH(&prog.image()[startOff+3]);/* This is abs seg of init */
         init = ((uint32_t)para << 4) + rel;
-        if (locatePattern(prog.Image, init, init+26, pattBorl4Init,
+        if (locatePattern(prog.image(), init, init+26, pattBorl4Init,
                           sizeof(pattBorl4Init), &i))
         {
 
-            setState(rDS, LH(&prog.Image[i+1]));
+            setState(rDS, LH(&prog.image()[i+1]));
             printf("Borland Pascal v4 detected\n");
             chVendor = 't';                     /* Trubo */
             chModel  = 'p';						/* Pascal */
@@ -665,11 +665,11 @@ void STATE::checkStartup()
             prog.segMain = prog.initCS;			/* At the 5 uint8_t jump */
             goto gotVendor;                     /* Already have vendor */
         }
-        else if (locatePattern(prog.Image, init, init+26, pattBorl5Init,
+        else if (locatePattern(prog.image(), init, init+26, pattBorl5Init,
                                sizeof(pattBorl5Init), &i))
         {
 
-            setState( rDS, LH(&prog.Image[i+1]));
+            setState( rDS, LH(&prog.image()[i+1]));
             printf("Borland Pascal v5.0 detected\n");
             chVendor = 't';                     /* Trubo */
             chModel  = 'p';						/* Pascal */
@@ -678,11 +678,11 @@ void STATE::checkStartup()
             prog.segMain = prog.initCS;
             goto gotVendor;                     /* Already have vendor */
         }
-        else if (locatePattern(prog.Image, init, init+26, pattBorl7Init,
+        else if (locatePattern(prog.image(), init, init+26, pattBorl7Init,
                                sizeof(pattBorl7Init), &i))
         {
 
-            setState( rDS, LH(&prog.Image[i+1]));
+            setState( rDS, LH(&prog.image()[i+1]));
             printf("Borland Pascal v7 detected\n");
             chVendor = 't';                     /* Trubo */
             chModel  = 'p';						/* Pascal */
@@ -701,43 +701,43 @@ void STATE::checkStartup()
         as near data, just more pushes at the start. */
     if(prog.cbImage>int(startOff+0x180+sizeof(pattMainLarge)))
     {
-        if (locatePattern(prog.Image, startOff, startOff+0x180, pattMainLarge,sizeof(pattMainLarge), &i))
+        if (locatePattern(prog.image(), startOff, startOff+0x180, pattMainLarge,sizeof(pattMainLarge), &i))
         {
-            rel = LH(&prog.Image[i+OFFMAINLARGE]);  /* This is abs off of main */
-            para= LH(&prog.Image[i+OFFMAINLARGE+2]);/* This is abs seg of main */
+            rel = LH(&prog.image()[i+OFFMAINLARGE]);  /* This is abs off of main */
+            para= LH(&prog.image()[i+OFFMAINLARGE+2]);/* This is abs seg of main */
             /* Save absolute image offset */
             prog.offMain = ((uint32_t)para << 4) + rel;
             prog.segMain = (uint16_t)para;
             chModel = 'l';                          /* Large model */
         }
-        else if (locatePattern(prog.Image, startOff, startOff+0x180, pattMainCompact,
+        else if (locatePattern(prog.image(), startOff, startOff+0x180, pattMainCompact,
                                sizeof(pattMainCompact), &i))
         {
-            rel = LH_SIGNED(&prog.Image[i+OFFMAINCOMPACT]);/* This is the rel addr of main */
+            rel = LH_SIGNED(&prog.image()[i+OFFMAINCOMPACT]);/* This is the rel addr of main */
             prog.offMain = i+OFFMAINCOMPACT+2+rel;  /* Save absolute image offset */
             prog.segMain = prog.initCS;
             chModel = 'c';                          /* Compact model */
         }
-        else if (locatePattern(prog.Image, startOff, startOff+0x180, pattMainMedium,
+        else if (locatePattern(prog.image(), startOff, startOff+0x180, pattMainMedium,
                                sizeof(pattMainMedium), &i))
         {
-            rel = LH(&prog.Image[i+OFFMAINMEDIUM]);  /* This is abs off of main */
-            para= LH(&prog.Image[i+OFFMAINMEDIUM+2]);/* This is abs seg of main */
+            rel = LH(&prog.image()[i+OFFMAINMEDIUM]);  /* This is abs off of main */
+            para= LH(&prog.image()[i+OFFMAINMEDIUM+2]);/* This is abs seg of main */
             prog.offMain = ((uint32_t)para << 4) + rel;
             prog.segMain = (uint16_t)para;
             chModel = 'm';                          /* Medium model */
         }
-        else if (locatePattern(prog.Image, startOff, startOff+0x180, pattMainSmall,
+        else if (locatePattern(prog.image(), startOff, startOff+0x180, pattMainSmall,
                                sizeof(pattMainSmall), &i))
         {
-            rel = LH_SIGNED(&prog.Image[i+OFFMAINSMALL]); /* This is rel addr of main */
+            rel = LH_SIGNED(&prog.image()[i+OFFMAINSMALL]); /* This is rel addr of main */
             prog.offMain = i+OFFMAINSMALL+2+rel;    /* Save absolute image offset */
             prog.segMain = prog.initCS;
             chModel = 's';                          /* Small model */
         }
-        else if (memcmp(&prog.Image[startOff], pattTPasStart, sizeof(pattTPasStart)) == 0)
+        else if (memcmp(&prog.image()[startOff], pattTPasStart, sizeof(pattTPasStart)) == 0)
         {
-            rel = LH_SIGNED(&prog.Image[startOff+1]);     /* Get the jump offset */
+            rel = LH_SIGNED(&prog.image()[startOff+1]);     /* Get the jump offset */
             prog.offMain = rel+startOff+3;          /* Save absolute image offset */
             prog.offMain += 0x20;                   /* These first 32 bytes are setting up */
             prog.segMain = prog.initCS;
@@ -764,27 +764,27 @@ void STATE::checkStartup()
 
 
     /* Now decide the compiler vendor and version number */
-    if (memcmp(&prog.Image[startOff], pattMsC5Start, sizeof(pattMsC5Start)) == 0)
+    if (memcmp(&prog.image()[startOff], pattMsC5Start, sizeof(pattMsC5Start)) == 0)
     {
         /* Yes, this is Microsoft startup code. The DS is sitting right here
             in the next 2 bytes */
-        setState( rDS, LH(&prog.Image[startOff+sizeof(pattMsC5Start)]));
+        setState( rDS, LH(&prog.image()[startOff+sizeof(pattMsC5Start)]));
         chVendor = 'm';                     /* Microsoft compiler */
         chVersion = '5';                    /* Version 5 */
         printf("MSC 5 detected\n");
     }
 
     /* The C8 startup pattern is different from C5's */
-    else if (memcmp(&prog.Image[startOff], pattMsC8Start, sizeof(pattMsC8Start)) == 0)
+    else if (memcmp(&prog.image()[startOff], pattMsC8Start, sizeof(pattMsC8Start)) == 0)
     {
-        setState( rDS, LH(&prog.Image[startOff+sizeof(pattMsC8Start)]));
+        setState( rDS, LH(&prog.image()[startOff+sizeof(pattMsC8Start)]));
         printf("MSC 8 detected\n");
         chVendor = 'm';                     /* Microsoft compiler */
         chVersion = '8';                    /* Version 8 */
     }
 
     /* The C8 .com startup pattern is different again! */
-    else if (memcmp(&prog.Image[startOff], pattMsC8ComStart,
+    else if (memcmp(&prog.image()[startOff], pattMsC8ComStart,
                     sizeof(pattMsC8ComStart)) == 0)
     {
         printf("MSC 8 .com detected\n");
@@ -792,27 +792,27 @@ void STATE::checkStartup()
         chVersion = '8';                    /* Version 8 */
     }
 
-    else if (locatePattern(prog.Image, startOff, startOff+0x30, pattBorl2Start,
+    else if (locatePattern(prog.image(), startOff, startOff+0x30, pattBorl2Start,
                            sizeof(pattBorl2Start), &i))
     {
         /* Borland startup. DS is at the second uint8_t (offset 1) */
-        setState( rDS, LH(&prog.Image[i+1]));
+        setState( rDS, LH(&prog.image()[i+1]));
         printf("Borland v2 detected\n");
         chVendor = 'b';                     /* Borland compiler */
         chVersion = '2';                    /* Version 2 */
     }
 
-    else if (locatePattern(prog.Image, startOff, startOff+0x30, pattBorl3Start,
+    else if (locatePattern(prog.image(), startOff, startOff+0x30, pattBorl3Start,
                            sizeof(pattBorl3Start), &i))
     {
         /* Borland startup. DS is at the second uint8_t (offset 1) */
-        setState( rDS, LH(&prog.Image[i+1]));
+        setState( rDS, LH(&prog.image()[i+1]));
         printf("Borland v3 detected\n");
         chVendor = 'b';                     /* Borland compiler */
         chVersion = '3';                    /* Version 3 */
     }
 
-    else if (locatePattern(prog.Image, startOff, startOff+0x30, pattLogiStart,
+    else if (locatePattern(prog.image(), startOff, startOff+0x30, pattLogiStart,
                            sizeof(pattLogiStart), &i))
     {
         /* Logitech modula startup. DS is 0, despite appearances */

+ 2 - 2
src/comwrite.cpp

@@ -207,9 +207,9 @@ void Function::writeProcComments(std::ostream &ostr)
         {
             psym = &this->args[i];
             ostr << " *     "<<psym->name<<" = ";
-            if (psym->regs->ident.idType == REGISTER)
+            if (psym->regs->ident.type() == REGISTER)
             {
-                id = &this->localId.id_arr[psym->regs->ident.idNode.regiIdx];
+                id = &this->localId.id_arr[((RegisterNode *)psym->regs)->regiIdx];
                 ostr << Machine_X86::regName(id->id.regi);
             }
             else		/* long register */

+ 4 - 2
src/control.cpp

@@ -529,9 +529,11 @@ bool Function::Case_X_and_Y(BB* pbb, BB* thenBB, BB* elseBB)
     HLTYPE &hl1(*pbb->back().hlU());
     HLTYPE &hl2(*thenBB->back().hlU());
     BB* obb = elseBB->edges[ELSE].BBptr;
-
+    Expr * hl2_expr =  hl2.getMyExpr();
     /* Construct compound DBL_AND expression */
-    hl1.expr(BinaryOperator::Create(DBL_AND,hl1.expr(),hl2.expr()));
+    assert(hl1.expr());
+    assert(hl2_expr);
+    hl1.expr(BinaryOperator::Create(DBL_AND,hl1.expr(),hl2_expr));
 
     /* Replace in-edge to obb from e to pbb */
     replaceInEdge(obb,elseBB,pbb);

+ 110 - 95
src/dataflow.cpp

@@ -20,12 +20,12 @@ using namespace boost;
 using namespace boost::adaptors;
 struct ExpStack
 {
-    typedef std::list<COND_EXPR *> EXP_STK;
+    typedef std::list<Expr *> EXP_STK;
     EXP_STK expStk;      /* local expression stack */
 
     void        init();
-    void        push(COND_EXPR *);
-    COND_EXPR * pop();
+    void        push(Expr *);
+    Expr * pop();
     int         numElem();
     boolT	empty();
     void processExpPush(int &numHlIcodes, iICODE picode)
@@ -48,7 +48,7 @@ void ExpStack::init()
 }
 
 /* Pushes the given expression onto the local stack (expStk). */
-void ExpStack::push(COND_EXPR *expr)
+void ExpStack::push(Expr *expr)
 {
     expStk.push_back(expr);
 }
@@ -57,11 +57,11 @@ void ExpStack::push(COND_EXPR *expr)
 /* 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()
+Expr *ExpStack::pop()
 {
     if(expStk.empty())
         return 0;
-    COND_EXPR *topExp = expStk.back();
+    Expr *topExp = expStk.back();
     expStk.pop_back();
     return topExp;
 }
@@ -91,13 +91,13 @@ size_t STKFRAME::getLocVar(int off)
 
 
 /* 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)
+static 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 AstIdent::Kte (ll_insn.src().getImm2(), 1);
-        return AstIdent::Kte (ll_insn.src().getImm2(), 2);
+            return new Constant(ll_insn.src().getImm2(), 1);
+        return new Constant(ll_insn.src().getImm2(), 2);
     }
     // otherwise
     return AstIdent::id (ll_insn, SRC, pProc, i, duIcode, du);
@@ -105,9 +105,9 @@ static COND_EXPR *srcIdent (const LLInst &ll_insn, Function * pProc, iICODE i, I
 
 
 /* Returns the destination operand */
-static COND_EXPR *dstIdent (const LLInst & ll_insn, Function * pProc, iICODE i, ICODE & duIcode, operDu du)
+static Expr *dstIdent (const LLInst & ll_insn, Function * pProc, iICODE i, ICODE & duIcode, operDu du)
 {
-    COND_EXPR *n;
+    Expr *n;
     n = AstIdent::id (ll_insn, DST, pProc, i, duIcode, du);
     /** Is it needed? (pIcode->ll()->flg) & NO_SRC_B **/
     return (n);
@@ -120,8 +120,8 @@ void Function::elimCondCodes ()
     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                    */
+    Expr *rhs;     /* Source operand                         */
+    Expr *lhs;     /* Destination operand                    */
     BinaryOperator *_expr;   /* Boolean expression                     */
     //BB * pBB;           /* Pointer to BBs in dfs last ordering    */
     riICODE useAt;      /* Instruction that used flag    */
@@ -159,12 +159,12 @@ void Function::elimCondCodes ()
                             break;
 
                         case iOR:
-                            lhs = defAt->hl()->asgn.lhs->clone();
+                            lhs = defAt->hl()->asgn.lhs()->clone();
                             useAt->copyDU(*defAt, eUSE, eDEF);
                             if (defAt->ll()->testFlags(B))
-                                rhs = AstIdent::Kte (0, 1);
+                                rhs = new Constant(0, 1);
                             else
-                                rhs = AstIdent::Kte (0, 2);
+                                rhs = new Constant(0, 2);
                             break;
 
                         case iTEST:
@@ -172,18 +172,18 @@ void Function::elimCondCodes ()
                             lhs = dstIdent (*defAt->ll(),this, befDefAt,*useAt, eUSE);
                             lhs = BinaryOperator::And(lhs, rhs);
                             if (defAt->ll()->testFlags(B))
-                                rhs = AstIdent::Kte (0, 1);
+                                rhs = new Constant(0, 1);
                             else
-                                rhs = AstIdent::Kte (0, 2);
+                                rhs = new Constant(0, 2);
                             break;
                         case iINC:
                         case iDEC: //WARNING: verbatim copy from iOR needs fixing ?
-                            lhs = defAt->hl()->asgn.lhs->clone();
+                            lhs = defAt->hl()->asgn.lhs()->clone();
                             useAt->copyDU(*defAt, eUSE, eDEF);
                             if (defAt->ll()->testFlags(B))
-                                rhs = AstIdent::Kte (0, 1);
+                                rhs = new Constant(0, 1);
                             else
-                                rhs = AstIdent::Kte (0, 2);
+                                rhs = new Constant(0, 2);
                             break;
                         default:
                             notSup = true;
@@ -202,9 +202,9 @@ void Function::elimCondCodes ()
 
                 else if (useAtOp == iJCXZ)
                 {
-                    lhs = AstIdent::Reg (rCX, 0, &localId);
+                    lhs = new RegisterNode(rCX, 0, &localId);
                     useAt->setRegDU (rCX, eUSE);
-                    rhs = AstIdent::Kte (0, 2);
+                    rhs = new Constant(0, 2);
                     _expr = BinaryOperator::Create(EQUAL,lhs,rhs);
                     useAt->setJCond(_expr);
                 }
@@ -319,7 +319,7 @@ void Function::liveRegAnalysis (LivenessSet &in_liveOut)
                     auto picode = pbb->rbegin(); /* icode of function return */
                     if (picode->hl()->opcode == HLI_RET)
                     {
-                        picode->hlU()->expr(AstIdent::idID (&retVal, &localId, (++pbb->rbegin()).base()));
+                        picode->hlU()->expr(AstIdent::idID(&retVal, &localId, (++pbb->rbegin()).base()));
                         picode->du.use = in_liveOut;
                     }
                 }
@@ -392,13 +392,13 @@ void Function::liveRegAnalysis (LivenessSet &in_liveOut)
     /* Remove any references to register variables */
     if (flg & SI_REGVAR)
     {
-        liveIn.set(rSI,0);
-        pbb->liveIn.set(rSI,0);
+        liveIn.clrReg(rSI);
+        pbb->liveIn.clrReg(rSI);
     }
     if (flg & DI_REGVAR)
     {
-        liveIn.set(rDI,0);
-        pbb->liveIn.set(rDI,0);
+        liveIn.clrReg(rDI);
+        pbb->liveIn.clrReg(rDI);
     }
 }
 
@@ -555,23 +555,23 @@ void Function::genDU1 ()
 }
 
 /* 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
+void LOCAL_ID::forwardSubs (Expr *lhs, Expr *rhs, iICODE picode, iICODE ticode, int &numHlIcodes) const
 {
     bool res;
     UnaryOperator *lhs_unary;
-    while(lhs_unary = dynamic_cast<UnaryOperator *>(lhs))
+    while( (lhs_unary = dynamic_cast<UnaryOperator *>(lhs)) )
     {
         if(dynamic_cast<AstIdent *>(lhs_unary))
             break;
         lhs = lhs_unary->unaryExp;
     }
-    AstIdent * lhs_id=dynamic_cast<AstIdent *>(lhs_unary);
-    assert(lhs_id);
+    RegisterNode * lhs_reg=dynamic_cast<RegisterNode *>(lhs_unary);
+    assert(lhs_reg);
     if (rhs == NULL)        /* In case expression popped is NULL */
         return;
 
     /* Insert on rhs of ticode, if possible */
-    res = COND_EXPR::insertSubTreeReg (ticode->hlU()->asgn.rhs,rhs, id_arr[lhs_id->ident.idNode.regiIdx].id.regi, this);
+    res = Expr::insertSubTreeReg (ticode->hlU()->asgn.rhs,rhs, id_arr[lhs_reg->regiIdx].id.regi, this);
     if (res)
     {
         picode->invalidate();
@@ -580,7 +580,18 @@ void LOCAL_ID::forwardSubs (COND_EXPR *lhs, COND_EXPR *rhs, iICODE picode, iICOD
     else
     {
         /* Try to insert it on lhs of ticode*/
-        res = COND_EXPR::insertSubTreeReg (ticode->hlU()->asgn.lhs,rhs, id_arr[lhs_id->ident.idNode.regiIdx].id.regi, this);
+        RegisterNode *op = dynamic_cast<RegisterNode *>(ticode->hlU()->asgn.m_lhs);
+        if(op)
+        {
+            eReg inserted = id_arr[lhs_reg->regiIdx].id.regi;
+            eReg lhsReg =   id_arr[op->regiIdx].id.regi;
+            if((lhsReg==inserted)||Machine_X86::isSubRegisterOf(lhsReg,inserted))
+            {
+                // Do not replace ax = XYZ; given ax = H << P;  with H << P  =
+                return;
+            }
+        }
+        res = Expr::insertSubTreeReg (ticode->hlU()->asgn.m_lhs,rhs, id_arr[lhs_reg->regiIdx].id.regi, this);
         if (res)
         {
             picode->invalidate();
@@ -591,7 +602,7 @@ void LOCAL_ID::forwardSubs (COND_EXPR *lhs, COND_EXPR *rhs, iICODE picode, iICOD
 
 
 /* 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)
+static void forwardSubsLong (int longIdx, Expr *_exp, iICODE picode, iICODE ticode, int *numHlIcodes)
 {
     bool res;
 
@@ -599,7 +610,7 @@ static void forwardSubsLong (int longIdx, COND_EXPR *_exp, iICODE picode, iICODE
         return;
 
     /* Insert on rhs of ticode, if possible */
-    res = COND_EXPR::insertSubTreeLongReg (_exp, ticode->hlU()->asgn.rhs, longIdx);
+    res = Expr::insertSubTreeLongReg (_exp, ticode->hlU()->asgn.rhs, longIdx);
     if (res)
     {
         picode->invalidate();
@@ -608,7 +619,7 @@ static void forwardSubsLong (int longIdx, COND_EXPR *_exp, iICODE picode, iICODE
     else
     {
         /* Try to insert it on lhs of ticode*/
-        res = COND_EXPR::insertSubTreeLongReg (_exp, ticode->hlU()->asgn.lhs, longIdx);
+        res = Expr::insertSubTreeLongReg (_exp, ticode->hlU()->asgn.m_lhs, longIdx);
         if (res)
         {
             picode->invalidate();
@@ -639,19 +650,9 @@ bool BinaryOperator::xClear(rICODE range_to_check, iICODE lastBBinst, const LOCA
 }
 bool AstIdent::xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locId)
 {
-    iICODE i;
-    uint8_t regi;
     if (ident.idType == REGISTER)
     {
-        regi= locId.id_arr[ident.idNode.regiIdx].id.regi;
-        range_to_check.advance_begin(1);
-        auto all_valid_and_high_level_after_start = range_to_check | filtered(ICODE::select_valid_high_level);
-        for (ICODE &i : all_valid_and_high_level_after_start)
-            if ((i.du.def & duReg[regi]).any())
-                return false;
-        if (all_valid_and_high_level_after_start.end().base() != lastBBinst)
-            return true;
-        return false;
+        assert(false);
     }
     else
         return true;
@@ -663,7 +664,7 @@ bool AstIdent::xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &
 /// @returns the type size of the stored Arg
 static int processCArg (Function * pp, Function * pProc, ICODE * picode, size_t numArgs)
 {
-    COND_EXPR *_exp;
+    Expr *_exp;
     bool res;
 
     /* if (numArgs == 0)
@@ -677,10 +678,10 @@ static int processCArg (Function * pp, Function * pProc, ICODE * picode, size_t
             if (pp->flg & PROC_VARARG)
             {
                 if (numArgs < pp->args.size())
-                    adjustActArgType (_exp, pp->args[numArgs].type, pProc);
+                    _exp = pProc->adjustActArgType (_exp, pp->args[numArgs].type);
             }
             else
-                adjustActArgType (_exp, pp->args[numArgs].type, pProc);
+                _exp = pProc->adjustActArgType (_exp, pp->args[numArgs].type);
         }
     }
     else			/* user function */
@@ -714,14 +715,14 @@ void LOCAL_ID::processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode
     boolT res;
     HLTYPE &p_hl(*picode->hlU());
     HLTYPE &t_hl(*ticode->hlU());
-    AstIdent *lhs_ident = dynamic_cast<AstIdent *>(p_hl.asgn.lhs);
 
+    AstIdent *lhs_ident = dynamic_cast<AstIdent *>(p_hl.asgn.lhs());
     switch (t_hl.opcode)
     {
         case HLI_ASSIGN:
+            assert(lhs_ident);
             if(isLong)
             {
-                assert(lhs_ident);
                 forwardSubsLong (lhs_ident->ident.idNode.longIdx,
                                  p_hl.asgn.rhs, picode,ticode,
                                  &numHlIcodes);
@@ -734,18 +735,19 @@ void LOCAL_ID::processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode
             if(isLong)
             {
                 assert(lhs_ident);
-                res = COND_EXPR::insertSubTreeLongReg (
+                res = Expr::insertSubTreeLongReg (
                           p_hl.asgn.rhs,
                           t_hl.exp.v,
                           lhs_ident->ident.idNode.longIdx);
             }
             else
             {
-                assert(lhs_ident);
-                res = COND_EXPR::insertSubTreeReg (
+                RegisterNode *lhs_reg = dynamic_cast<RegisterNode *>(p_hl.asgn.lhs());
+                assert(lhs_reg);
+                res = Expr::insertSubTreeReg (
                           t_hl.exp.v,
                           p_hl.asgn.rhs,
-                          id_arr[lhs_ident->ident.idNode.regiIdx].id.regi,
+                          id_arr[lhs_reg->regiIdx].id.regi,
                         this);
             }
             if (res)
@@ -766,7 +768,7 @@ void LOCAL_ID::processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode
     }
 }
 
-void Function::processHliCall(COND_EXPR *_exp, iICODE picode)
+void Function::processHliCall(Expr *_exp, iICODE picode)
 {
     Function * pp;
     int cb, numArgs;
@@ -784,7 +786,7 @@ void Function::processHliCall(COND_EXPR *_exp, iICODE picode)
             if (pp->flg & PROC_ISLIB)	/* library function */
             {
                 if (pp->args.numArgs > 0)
-                    adjustActArgType(_exp, pp->args[numArgs].type, this);
+                    _exp = adjustActArgType(_exp, pp->args[numArgs].type);
                 res = picode->newStkArg (_exp, (llIcode)picode->ll()->getOpcode(), this);
             }
             else			/* user function */
@@ -834,8 +836,8 @@ void 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		*/
+    Expr *_exp;     // expression pointer - for HLI_POP and HLI_CALL    */
+    //Expr *lhs;	// exp ptr for return value of a HLI_CALL		*/
     iICODE ticode;     // Target icode                             */
     HLTYPE *ti_hl=0;
     uint8_t regi;
@@ -897,11 +899,11 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
 
                             case HLI_JCOND: case HLI_PUSH: case HLI_RET:
                             {
-                                AstIdent *v = dynamic_cast<AstIdent *>(_icHl.expr());
+                                RegisterNode *v = dynamic_cast<RegisterNode *>(_icHl.expr());
                                 assert(v);
-                                res = COND_EXPR::insertSubTreeReg (ti_hl->exp.v,
+                                res = Expr::insertSubTreeReg (ti_hl->exp.v,
                                                                    _exp,
-                                                                   locals.id_arr[v->ident.idNode.regiIdx].id.regi,
+                                                                   locals.id_arr[v->regiIdx].id.regi,
                                         &locals);
                                 if (res)
                                 {
@@ -930,24 +932,24 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
                         {
                             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);
+                                _exp = _icHl.call.toAst();
+                                res = 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);
+                                    Expr::insertSubTreeReg (ti_hl->asgn.m_lhs, _exp,_retVal->id.regi, &locals);
                                 //TODO: HERE missing: 2 regs
                                 picode->invalidate();
                                 numHlIcodes--;
                                 break;
 
                             case HLI_PUSH: case HLI_RET:
-                                ti_hl->expr( _icHl.call.toId() );
+                                ti_hl->expr( _icHl.call.toAst() );
                                 picode->invalidate();
                                 numHlIcodes--;
                                 break;
 
                             case HLI_JCOND:
-                                _exp = _icHl.call.toId();
-                                res = COND_EXPR::insertSubTreeReg (ti_hl->exp.v, _exp, _retVal->id.regi, &locals);
+                                _exp = _icHl.call.toAst();
+                                res = Expr::insertSubTreeReg (ti_hl->exp.v, _exp, _retVal->id.regi, &locals);
                                 if (res)	/* was substituted */
                                 {
                                     picode->invalidate();
@@ -1008,9 +1010,9 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
                                                      _exp, picode.base(), ticode, &numHlIcodes);
                                     break;
                                 case HLI_JCOND: case HLI_PUSH:
-                                    res = COND_EXPR::insertSubTreeLongReg (_exp,
+                                    res = Expr::insertSubTreeLongReg (_exp,
                                                                            ticode->hlU()->exp.v,
-                                                                           dynamic_cast<AstIdent *>(_icHl.asgn.lhs)->ident.idNode.longIdx);
+                                                                      dynamic_cast<AstIdent *>(_icHl.asgn.lhs())->ident.idNode.longIdx);
                                     if (res)
                                     {
                                         picode->invalidate();
@@ -1030,26 +1032,26 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
                         switch (ticode->hl()->opcode)
                         {
                             case HLI_ASSIGN:
-                                _exp = _icHl.call.toId();
-                                ticode->hlU()->asgn.lhs =
-                                        AstIdent::idLong(&locals, DST,
+                                _exp = _icHl.call.toAst();
+                                ticode->hlU()->asgn.lhs(
+                                        AstIdent::Long(&locals, DST,
                                                           ticode,HIGH_FIRST, picode.base(),
-                                                          eDEF, *(++iICODE(ticode))->ll());
+                                                          eDEF, *(++iICODE(ticode))->ll()));
                                 ticode->hlU()->asgn.rhs = _exp;
                                 picode->invalidate();
                                 numHlIcodes--;
                                 break;
 
                             case HLI_PUSH:  case HLI_RET:
-                                ticode->hlU()->expr( _icHl.call.toId() );
+                                ticode->hlU()->expr( _icHl.call.toAst() );
                                 picode->invalidate();
                                 numHlIcodes--;
                                 break;
 
                             case HLI_JCOND:
-                                _exp = _icHl.call.toId();
+                                _exp = _icHl.call.toAst();
                                 _retVal = &picode->hl()->call.proc->retVal;
-                                res = COND_EXPR::insertSubTreeLongReg (_exp,
+                                res = Expr::insertSubTreeLongReg (_exp,
                                                                        ticode->hlU()->exp.v,
                                                                        locals.newLongReg ( _retVal->type, _retVal->id.longId.h,
                                                                                            _retVal->id.longId.l, picode.base()));
@@ -1098,7 +1100,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
              * assign it to the corresponding registers */
             if ( not _icHl.call.proc->isLibrary() and (not picode->du1.used(0)) and (picode->du1.numRegsDef > 0))
             {
-                _exp = AstIdent::idFunc (_icHl.call.proc, _icHl.call.args);
+                _exp = new FuncNode(_icHl.call.proc, _icHl.call.args);
                 auto lhs = AstIdent::idID (&_icHl.call.proc->retVal, &locals, picode.base());
                 picode->setAsgn(lhs, _exp);
             }
@@ -1110,22 +1112,13 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
 
 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)
+    for(BB *pbb : m_dfsLast | filtered(BB::ValidFunctor()))
     {
-        /* Process one BB */
-        //        pbb = m_dfsLast[i];
-        if (not pbb->valid())
-            continue;
+        /* Process one valid BB */
         pbb->findBBExps( this->localId, this);
-
     }
 }
 
@@ -1135,6 +1128,16 @@ void Function::preprocessReturnDU(LivenessSet &_liveOut)
     {
         //        int idx;
         bool isAx, isBx, isCx, isDx;
+        eReg bad_regs[] = {rES,rCS,rDS,rSS};
+        constexpr char * names[] ={"ES","CS","DS","SS"};
+        for(int i=0; i<4; ++i)
+        if(_liveOut.testReg(bad_regs[i]))
+        {
+            fprintf(stderr,"LivenessSet probably screwed up, %s register as an liveOut in preprocessReturnDU\n",names[i]);
+            _liveOut.clrReg(bad_regs[i]);
+            if(not _liveOut.any())
+                return;
+        }
         flg |= PROC_IS_FUNC;
         isAx = _liveOut.testReg(rAX);
         isBx = _liveOut.testReg(rBX);
@@ -1205,7 +1208,20 @@ void Function::preprocessReturnDU(LivenessSet &_liveOut)
             else
                 retVal.id.regi = rDL;
             /*idx = */localId.newByteWordReg(TYPE_BYTE_SIGN,retVal.id.regi);
-
+        }
+        else if(isAH||isBH||isCH||isDH)
+        {
+            retVal.type = TYPE_BYTE_SIGN;
+            retVal.loc = REG_FRAME;
+            if (isAH)
+                retVal.id.regi = rAH;
+            else if (isBH)
+                retVal.id.regi = rBH;
+            else if (isCH)
+                retVal.id.regi = rCH;
+            else
+                retVal.id.regi = rDH;
+            /*idx = */localId.newByteWordReg(TYPE_BYTE_SIGN,retVal.id.regi);
         }
     }
 }
@@ -1217,9 +1233,9 @@ void Function::dataFlow(LivenessSet &_liveOut)
 
     /* Remove references to register variables */
     if (flg & SI_REGVAR)
-        _liveOut.set(rSI,0);
+        _liveOut.clrReg(rSI);
     if (flg & DI_REGVAR)
-        _liveOut.set(rDI,0);
+        _liveOut.clrReg(rDI);
 
     /* Function - return value register(s) */
     preprocessReturnDU(_liveOut);
@@ -1235,4 +1251,3 @@ void Function::dataFlow(LivenessSet &_liveOut)
         findExps (); 		/* forward substitution algorithm */
     }
 }
-

+ 92 - 8
src/dcc.cpp

@@ -4,9 +4,9 @@
  * (C) Cristina Cifuentes
  ****************************************************************************/
 
+#include <cstring>
 #include "dcc.h"
 #include "project.h"
-#include <string.h>
 
 /* Global variables - extern to other modules */
 extern char    *asm1_name, *asm2_name;     /* Assembler output filenames     */
@@ -22,18 +22,102 @@ extern OPTION  option;             /* Command line options     			  */
 static char *initargs(int argc, char *argv[]);
 static void displayTotalStats(void);
 #include <llvm/Support/raw_os_ostream.h>
-
+#include <llvm/Support/CommandLine.h>
+#include <llvm/Support/TargetSelect.h>
+#include <llvm/Support/TargetRegistry.h>
+#include <llvm/Support/PrettyStackTrace.h>
+#include <llvm/Support/Signals.h>
+#include <llvm/Support/Host.h>
+#include <llvm/Target/TargetMachine.h>
+#include <llvm/Target/TargetInstrInfo.h>
+#include <llvm/MC/MCAsmInfo.h>
+#include <llvm/CodeGen/MachineInstrBuilder.h>
+
+#include <llvm/TableGen/Main.h>
+#include <llvm/TableGen/TableGenAction.h>
+#include <llvm/TableGen/Record.h>
 /****************************************************************************
  * main
  ***************************************************************************/
 #include <iostream>
-int main(int argc, char *argv[])
+using namespace llvm;
+class TVisitor : public TableGenAction {
+public:
+    virtual bool operator()(raw_ostream &OS, RecordKeeper &Records)
+    {
+        Record *rec = Records.getDef("ADD8i8");
+        if(rec)
+        {
+            if(not rec->getTemplateArgs().empty())
+                std::cout << "Has template args\n";
+            auto classes(rec->getSuperClasses());
+            for(auto val : rec->getSuperClasses())
+                std::cout << "Super "<<val->getName()<<"\n";
+
+//          DagInit * in = rec->getValueAsDag(val.getName());
+//          in->dump();
+            for(const RecordVal &val : rec->getValues())
+            {
+//                val.dump();
+            }
+            rec->dump();
+
+        }
+        //        rec = Records.getDef("CCR");
+        //        if(rec)
+        //            rec->dump();
+        for(auto val : Records.getDefs())
+        {
+            //std::cout<< "Def "<<val.first<<"\n";
+        }
+        return false;
+    }
+};
+int testTblGen(int argc, char **argv)
+{
+    using namespace llvm;
+    sys::PrintStackTraceOnErrorSignal();
+    PrettyStackTraceProgram(argc,argv);
+    cl::ParseCommandLineOptions(argc,argv);
+    TVisitor tz;
+
+    return llvm::TableGenMain(argv[0],tz);
+    InitializeNativeTarget();
+    Triple TheTriple;
+    std::string  def = sys::getDefaultTargetTriple();
+    std::string MCPU="i386";
+    std::string MARCH="x86";
+    InitializeAllTargetInfos();
+    InitializeAllTargetMCs();
+    InitializeAllAsmPrinters();
+    InitializeAllAsmParsers();
+    InitializeAllDisassemblers();
+    std::string TargetTriple("i386-pc-linux-gnu");
+    TheTriple = Triple(Triple::normalize(TargetTriple));
+    MCOperand op=llvm::MCOperand::CreateImm(11);
+    MCAsmInfo info;
+    raw_os_ostream wrap(std::cerr);
+    op.print(wrap,&info);
+    wrap.flush();
+    std::cerr<<"\n";
+    std::string lookuperr;
+    TargetRegistry::printRegisteredTargetsForVersion();
+    const Target *t = TargetRegistry::lookupTarget(MARCH,TheTriple,lookuperr);
+    TargetOptions opts;
+    std::string Features;
+    opts.PrintMachineCode=1;
+    TargetMachine *tm = t->createTargetMachine(TheTriple.getTriple(),MCPU,Features,opts);
+    std::cerr<<tm->getInstrInfo()->getName(97)<<"\n";
+    const MCInstrDesc &ds(tm->getInstrInfo()->get(97));
+    const MCOperandInfo *op1=ds.OpInfo;
+    uint16_t impl_def = ds.getImplicitDefs()[0];
+    std::cerr<<lookuperr<<"\n";
+
+    exit(0);
+
+}
+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));
 

+ 1 - 1
src/disassem.cpp

@@ -247,7 +247,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
         {
             for (j = 0; j < cb; j++)
             {
-                hex_bytes << hex << setw(2) << setfill('0') << uint16_t(prog.Image[inst.label + j]);
+                hex_bytes << hex << setw(2) << setfill('0') << uint16_t(prog.image()[inst.label + j]);
             }
             hex_bytes << ' ';
         }

+ 6 - 6
src/frontend.cpp

@@ -139,7 +139,7 @@ static void displayLoadInfo(void)
         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("%06X -> [%04X]\n", prog.relocTable[i],LH(prog.image() + prog.relocTable[i]));
         }
     }
     printf("\n");
@@ -303,12 +303,12 @@ void DccFrontend::LoadImage(Project &proj)
 
     /* 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     */
+    prog.Imagez    = new uint8_t [prog.cbImage];
+    prog.Imagez[0] = 0xCD;		/* Fill in PSP int 20h location */
+    prog.Imagez[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))
+    if (cb != (int)fread(prog.Imagez + sizeof(PSP), 1, (size_t)cb, fp))
     {
         fatalError(CANNOT_READ, proj.binary_path().c_str());
     }
@@ -323,7 +323,7 @@ void DccFrontend::LoadImage(Project &proj)
     {
         for (i = 0; i < prog.cReloc; i++)
         {
-            uint8_t *p = &prog.Image[prog.relocTable[i]];
+            uint8_t *p = &prog.Imagez[prog.relocTable[i]];
             uint16_t  w = (uint16_t)LH(p) + EXE_RELOCATION;
             *p++    = (uint8_t)(w & 0x00FF);
             *p      = (uint8_t)((w & 0xFF00) >> 8);

+ 36 - 30
src/hlicode.cpp

@@ -11,7 +11,6 @@
 #include "dcc.h"
 using namespace std;
 
-
 /* Masks off bits set by duReg[] */
 LivenessSet maskDuReg[] = { 0x00,
                             /* uint16_t regs */
@@ -38,7 +37,7 @@ static char buf[lineSize];     /* Line buffer for hl icode output */
 
 
 /* Places the new HLI_ASSIGN high-level operand in the high-level icode array */
-void HLTYPE::setAsgn(COND_EXPR *lhs, COND_EXPR *rhs)
+void HLTYPE::setAsgn(Expr *lhs, Expr *rhs)
 {
     assert(lhs);
     set(lhs,rhs);
@@ -68,7 +67,7 @@ void ICODE::newCallHl()
 
 /* 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)
+void ICODE::setUnary(hlIcode op, Expr *_exp)
 {
     type = HIGH_LEVEL;
     hlU()->set(op,_exp);
@@ -76,7 +75,7 @@ void ICODE::setUnary(hlIcode op, COND_EXPR *_exp)
 
 
 /* Places the new HLI_JCOND high-level operand in the high-level icode array */
-void ICODE::setJCond(COND_EXPR *cexp)
+void ICODE::setJCond(Expr *cexp)
 {
     type = HIGH_LEVEL;
     hlU()->set(HLI_JCOND,cexp);
@@ -293,8 +292,8 @@ void Function::highLevelGen()
 {
     size_t numIcode;         /* number of icode instructions */
     iICODE pIcode;        /* ptr to current icode node */
-    COND_EXPR *lhs;
-    COND_EXPR *rhs; /* left- and right-hand side of expression */
+    Expr *lhs;
+    Expr *rhs; /* left- and right-hand side of expression */
     uint32_t _flg;          /* icode flags */
     numIcode = Icode.size();
     for (iICODE i = Icode.begin(); i!=Icode.end() ; ++i)
@@ -333,8 +332,7 @@ void Function::highLevelGen()
                 break;
 
             case iDEC:
-                rhs = AstIdent::Kte (1, 2);
-                rhs = new BinaryOperator(SUB,lhs, rhs);
+                rhs = new BinaryOperator(SUB,lhs, new Constant(1, 2));
                 pIcode->setAsgn(lhs, rhs);
                 break;
 
@@ -343,12 +341,12 @@ void Function::highLevelGen()
                 rhs = new BinaryOperator(DIV,lhs, rhs);
                 if ( ll->testFlags(B) )
                 {
-                    lhs = AstIdent::Reg (rAL, 0, &localId);
+                    lhs = new RegisterNode(rAL, 0, &localId);
                     pIcode->setRegDU( rAL, eDEF);
                 }
                 else
                 {
-                    lhs = AstIdent::Reg (rAX, 0, &localId);
+                    lhs = new RegisterNode(rAX, 0, &localId);
                     pIcode->setRegDU( rAX, eDEF);
                 }
                 pIcode->setAsgn(lhs, rhs);
@@ -361,8 +359,7 @@ void Function::highLevelGen()
                 break;
 
             case iINC:
-                rhs = AstIdent::Kte (1, 2);
-                rhs = new BinaryOperator(ADD,lhs, rhs);
+                rhs = new BinaryOperator(ADD,lhs, new Constant(1, 2));
                 pIcode->setAsgn(lhs, rhs);
                 break;
 
@@ -373,16 +370,15 @@ void Function::highLevelGen()
 
             case iMOD:
                 rhs = new BinaryOperator(MOD,lhs, rhs);
+                eReg lhs_reg;
+
                 if ( ll->testFlags(B) )
-                {
-                    lhs = AstIdent::Reg (rAH, 0, &localId);
-                    pIcode->setRegDU( rAH, eDEF);
-                }
+                    lhs_reg = rAH;
                 else
-                {
-                    lhs = AstIdent::Reg (rDX, 0, &localId);
-                    pIcode->setRegDU( rDX, eDEF);
-                }
+                    lhs_reg = rDX;
+
+                lhs = new RegisterNode(lhs_reg, 0, &localId);
+                pIcode->setRegDU( lhs_reg, eDEF);
                 pIcode->setAsgn(lhs, rhs);
                 break;
 
@@ -462,7 +458,7 @@ void Function::highLevelGen()
 
 /* 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)
+std::string Function::writeCall (Function * tproc, STKFRAME & args, int *numLoc)
 {
     //string condExp;
     ostringstream ostr;
@@ -470,7 +466,7 @@ std::string writeCall (Function * tproc, STKFRAME & args, Function * pproc, int
     for(const STKSYM &sym : args)
     {
         if(sym.actual)
-            ostr << sym.actual->walkCondExpr (pproc, numLoc);
+            ostr << sym.actual->walkCondExpr (this, numLoc);
         else
             ostr <<  "";
         if((&sym)!=&(args.back()))
@@ -484,11 +480,15 @@ std::string writeCall (Function * tproc, STKFRAME & args, Function * pproc, int
 /* Displays the output of a HLI_JCOND icode. */
 char *writeJcond (const HLTYPE &h, Function * pProc, int *numLoc)
 {
-    assert(h.expr());
     memset (buf, ' ', sizeof(buf));
     buf[0] = '\0';
     strcat (buf, "if ");
-    COND_EXPR *inverted=h.expr()->inverse();
+    if(h.opcode==HLI_INVALID)
+    {
+        return "if (*HLI_INVALID*) {\n";
+    }
+    assert(h.expr());
+    Expr *inverted=h.expr()->inverse();
     //inverseCondOp (&h.exp);
     std::string e = inverted->walkCondExpr (pProc, numLoc);
     delete inverted;
@@ -506,7 +506,12 @@ char *writeJcondInv (HLTYPE h, Function * pProc, int *numLoc)
     memset (buf, ' ', sizeof(buf));
     buf[0] = '\0';
     strcat (buf, "if ");
-    std::string e = h.expr()->walkCondExpr (pProc, numLoc);
+    std::string e;
+    if(h.expr()==nullptr)
+        e = "( *failed condition recovery* )";
+    else
+        e = h.expr()->walkCondExpr (pProc, numLoc);
+
     strcat (buf, e.c_str());
     strcat (buf, " {\n");
     return (buf);
@@ -515,7 +520,7 @@ char *writeJcondInv (HLTYPE h, Function * pProc, int *numLoc)
 string AssignType::writeOut(Function *pProc, int *numLoc) const
 {
     ostringstream ostr;
-    ostr << lhs->walkCondExpr (pProc, numLoc);
+    ostr << m_lhs->walkCondExpr (pProc, numLoc);
     ostr << " = ";
     ostr << rhs->walkCondExpr (pProc, numLoc);
     ostr << ";\n";
@@ -524,7 +529,7 @@ string AssignType::writeOut(Function *pProc, int *numLoc) const
 string CallType::writeOut(Function *pProc, int *numLoc) const
 {
     ostringstream ostr;
-    ostr << writeCall (proc, *args, pProc,numLoc);
+    ostr << pProc->writeCall (proc, *args, numLoc);
     ostr << ";\n";
     return ostr.str();
 }
@@ -535,13 +540,14 @@ string ExpType::writeOut(Function *pProc, int *numLoc) const
     return v->walkCondExpr (pProc, numLoc);
 }
 
-void HLTYPE::set(COND_EXPR *l, COND_EXPR *r)
+void HLTYPE::set(Expr *l, Expr *r)
 {
     assert(l);
     assert(r);
     opcode = HLI_ASSIGN;
-    assert((asgn.lhs==0) and (asgn.rhs==0)); //prevent memory leaks
-    asgn.lhs=l;
+    //assert((asgn.lhs==0) and (asgn.rhs==0)); //prevent memory leaks
+    assert(dynamic_cast<UnaryOperator *>(l));
+    asgn.m_lhs=l;
     asgn.rhs=r;
 }
 /* Returns a string with the contents of the current high-level icode.

+ 1 - 1
src/hltype.cpp

@@ -1,7 +1,7 @@
 #include "icode.h"
 #include "ast.h"
 
-void HLTYPE::replaceExpr(COND_EXPR *e)
+void HLTYPE::replaceExpr(Expr *e)
 {
     assert(e);
     delete exp.v;

+ 7 - 1
src/icode.cpp

@@ -103,6 +103,12 @@ void HLTYPE::setCall(Function *proc)
 }
 bool AssignType::removeRegFromLong(eReg regi, LOCAL_ID *locId)
 {
-    lhs->performLongRemoval(regi,locId);
+    m_lhs=lhs()->performLongRemoval(regi,locId);
     return true;
 }
+void AssignType::lhs(Expr *l)
+{
+    assert(dynamic_cast<UnaryOperator *>(l));
+    m_lhs=l;
+}
+

+ 72 - 69
src/idioms/arith_idioms.cpp

@@ -26,9 +26,9 @@ bool Idiom5::match(iICODE pIcode)
 int Idiom5::action()
 {
     AstIdent *rhs,*lhs;
-    COND_EXPR *expr;
-    lhs = AstIdent::idLong (&m_func->localId, DST, m_icodes[0], LOW_FIRST, m_icodes[0], USE_DEF, *m_icodes[1]->ll());
-    rhs = AstIdent::idLong (&m_func->localId, SRC, m_icodes[0], LOW_FIRST, m_icodes[0], eUSE, *m_icodes[1]->ll());
+    Expr *expr;
+    lhs = AstIdent::Long (&m_func->localId, DST, m_icodes[0], LOW_FIRST, m_icodes[0], USE_DEF, *m_icodes[1]->ll());
+    rhs = AstIdent::Long (&m_func->localId, SRC, m_icodes[0], LOW_FIRST, m_icodes[0], eUSE, *m_icodes[1]->ll());
     expr = new BinaryOperator(ADD,lhs, rhs);
     m_icodes[0]->setAsgn(lhs, expr);
     m_icodes[1]->invalidate();
@@ -61,9 +61,9 @@ int Idiom6::action()
 {
 
     AstIdent *rhs,*lhs;
-    COND_EXPR *expr;
-    lhs = AstIdent::idLong (&m_func->localId, DST, m_icodes[0], LOW_FIRST, m_icodes[0], USE_DEF, *m_icodes[1]->ll());
-    rhs = AstIdent::idLong (&m_func->localId, SRC, m_icodes[0], LOW_FIRST, m_icodes[0], eUSE, *m_icodes[1]->ll());
+    Expr *expr;
+    lhs = AstIdent::Long (&m_func->localId, DST, m_icodes[0], LOW_FIRST, m_icodes[0], USE_DEF, *m_icodes[1]->ll());
+    rhs = AstIdent::Long (&m_func->localId, SRC, m_icodes[0], LOW_FIRST, m_icodes[0], eUSE, *m_icodes[1]->ll());
     expr = new BinaryOperator(SUB,lhs, rhs);
     m_icodes[0]->setAsgn(lhs, expr);
     m_icodes[1]->invalidate();
@@ -102,7 +102,13 @@ bool Idiom18::match(iICODE picode)
     m_is_dec = m_icodes[1]->ll()->match(iDEC);
 
     uint8_t regi;		/* register of the MOV */
-
+    if(not (m_icodes[0]->ll()->match(iMOV) and m_icodes[0]->ll()->dst.isReg() ))
+        return false;
+    regi = m_icodes[0]->ll()->dst.regi;
+    if( not ( m_icodes[2]->ll()->match(iCMP) && (m_icodes[2]->ll()->dst.regi == regi) &&
+              m_icodes[3]->ll()->conditionalJump() ) )
+        return false;
+    // Simple matching finished, select apropriate matcher based on dst type
     /* Get variable */
     if (m_icodes[1]->ll()->dst.regi == 0)	/* global variable */
     {
@@ -111,10 +117,11 @@ bool Idiom18::match(iICODE picode)
     }
     else if ( m_icodes[1]->ll()->dst.isReg() )	/* register */
     {
-        if ((m_icodes[1]->ll()->dst.regi == rSI) && (m_func->flg & SI_REGVAR))
-            m_idiom_type = 1;
-        else if ((m_icodes[1]->ll()->dst.regi == rDI) && (m_func->flg & DI_REGVAR))
-            m_idiom_type = 1;
+        m_idiom_type = 1;
+//        if ((m_icodes[1]->ll()->dst.regi == rSI) && (m_func->flg & SI_REGVAR))
+//            m_idiom_type = 1;
+//        else if ((m_icodes[1]->ll()->dst.regi == rDI) && (m_func->flg & DI_REGVAR))
+//            m_idiom_type = 1;
     }
     else if (m_icodes[1]->ll()->dst.off)		/* local variable */
         m_idiom_type = 2;
@@ -134,31 +141,23 @@ bool Idiom18::match(iICODE picode)
             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))
+            if ( (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;
-                }
+                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))
+            if ((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;
-                }
+                return true;
             }
             break;
         case 3: // indexed
-            printf("Unsupported idiom18 type: indexed");
+            printf("Untested idiom18 type: indexed\n");
+            if ((m_icodes[0]->ll()->src() == m_icodes[1]->ll()->dst))
+            {
+                return true;
+            }
             break;
     }
     return false;
@@ -166,8 +165,8 @@ bool Idiom18::match(iICODE picode)
 
 int Idiom18::action() // action length
 {
-    COND_EXPR *rhs,*lhs;/* Pointers to left and right hand side exps */
-    COND_EXPR *expr;
+    Expr *rhs,*lhs;/* Pointers to left and right hand side exps */
+    Expr *expr;
     lhs     = AstIdent::id (*m_icodes[0]->ll(), SRC, m_func, m_icodes[1], *m_icodes[1], eUSE);
     lhs     = UnaryOperator::Create(m_is_dec ? POST_DEC : POST_INC, lhs);
     rhs     = AstIdent::id (*m_icodes[2]->ll(), SRC, m_func, m_icodes[1], *m_icodes[3], eUSE);
@@ -195,38 +194,40 @@ bool Idiom19::match(iICODE picode)
     if(std::distance(picode,m_end)<2)
         return false;
     ICODE &ic(*picode);
-
+    int type;
     for(int i=0; i<2; ++i)
         m_icodes[i] =picode++;
     m_is_dec = m_icodes[0]->ll()->match(iDEC);
+    if ( not m_icodes[1]->ll()->conditionalJump() )
+        return false;
     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;
+        return true;
     }
     else if (m_icodes[0]->ll()->dst.off)		/* stack variable */
     {
-        if ( m_icodes[1]->ll()->conditionalJump() )
-            return true;
+        return true;
     }
     else	/* indexed */
     {
+        fprintf(stderr,"idiom19 : Untested type [indexed]\n");
+        return true;
+
         /* not supported yet */
     }
     return false;
 }
 int Idiom19::action()
 {
-    COND_EXPR *lhs,*rhs,*expr;
-    ICODE &ic1(*m_icodes[1]);
+    Expr *lhs,*expr;
+
     lhs = AstIdent::id (*m_icodes[0]->ll(), DST, m_func, m_icodes[0], *m_icodes[1], eUSE);
     lhs = UnaryOperator::Create(m_is_dec ? PRE_DEC : PRE_INC, lhs);
-    rhs = AstIdent::Kte (0, 2);
-    expr = new BinaryOperator(condOpJCond[m_icodes[1]->ll()->getOpcode() - iJB],lhs, rhs);
+    expr = new BinaryOperator(condOpJCond[m_icodes[1]->ll()->getOpcode() - iJB],lhs, new Constant(0, 2));
     m_icodes[1]->setJCond(expr);
     m_icodes[0]->invalidate();
     return 2;
@@ -255,6 +256,9 @@ bool Idiom20::match(iICODE picode)
         return false;
     for(int i=0; i<4; ++i)
         m_icodes[i] =picode++;
+    /* Check second instruction for a MOV */
+    if(not (m_icodes[1]->ll()->match(iMOV) && m_icodes[1]->ll()->dst.isReg()))
+        return false;
 
     m_is_dec = m_icodes[0]->ll()->match(iDEC) ? PRE_DEC : PRE_INC;
 
@@ -266,53 +270,52 @@ bool Idiom20::match(iICODE picode)
     }
     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;
+        type = 1;
+//        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");
+        printf("idiom20 : Untested type [indexed]\n");
+        type = 3;
         /* not supported yet */ ;
     }
-
-    /* Check previous instruction for a MOV */
-    if (type == 1)			/* register variable */
+    regi = m_icodes[1]->ll()->dst.regi;
+    const LLOperand &mov_src(m_icodes[1]->ll()->src());
+    if (m_icodes[2]->ll()->match(iCMP,(eReg)regi) && m_icodes[3]->ll()->conditionalJump())
     {
-        if (m_icodes[1]->ll()->match(iMOV) &&
-                (m_icodes[1]->ll()->src().regi == ll_dest.regi))
+        switch(type)
         {
-            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())
+            case 1: /* register variable */
+                if ((mov_src.regi == ll_dest.regi))
+                {
                     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())
+                }
+                break;
+            case 2: // local
+                if ((mov_src.off == ll_dest.off))
+                {
                     return true;
-            }
+                }
+                break;
+            case 3:
+                fprintf(stderr,"Test 3 ");
+                if ((mov_src == ll_dest))
+                {
+                    return true;
+                }
+                break;
         }
     }
     return false;
 }
 int Idiom20::action()
 {
-    COND_EXPR *lhs,*rhs,*expr;
+    Expr *lhs,*rhs,*expr;
     lhs  = AstIdent::id (*m_icodes[1]->ll(), SRC, m_func, m_icodes[0], *m_icodes[0], eUSE);
     lhs  = UnaryOperator::Create(m_is_dec, lhs);
     rhs  = AstIdent::id (*m_icodes[2]->ll(), SRC, m_func, m_icodes[0], *m_icodes[3], eUSE);

+ 3 - 3
src/idioms/mov_idioms.cpp

@@ -50,7 +50,7 @@ int Idiom14::action()
 {
     int idx;
     AstIdent *lhs;
-    COND_EXPR *rhs;
+    Expr *rhs;
 
     idx = m_func->localId.newLongReg (TYPE_LONG_SIGN, m_regH, m_regL, m_icodes[0]);
     lhs = AstIdent::LongIdx (idx);
@@ -101,8 +101,8 @@ bool Idiom13::match(iICODE pIcode)
 int Idiom13::action()
 {
     AstIdent *lhs;
-    COND_EXPR *rhs;
-    lhs = AstIdent::Reg (m_loaded_reg, 0, &m_func->localId);
+    Expr *rhs;
+    lhs = new RegisterNode(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 = AstIdent::id (*m_icodes[0]->ll(), SRC, m_func, m_icodes[0], *m_icodes[0], NONE);

+ 4 - 4
src/idioms/neg_idioms.cpp

@@ -53,8 +53,8 @@ bool Idiom11::match (iICODE picode)
 int Idiom11::action()
 {
     AstIdent *lhs;
-    COND_EXPR *rhs;
-    lhs = AstIdent::idLong (&m_func->localId, DST, m_icodes[0], HIGH_FIRST,m_icodes[0], USE_DEF, *m_icodes[1]->ll());
+    Expr *rhs;
+    lhs = AstIdent::Long (&m_func->localId, DST, m_icodes[0], HIGH_FIRST,m_icodes[0], USE_DEF, *m_icodes[1]->ll());
     rhs = UnaryOperator::Create(NEGATION, lhs);
     m_icodes[0]->setAsgn(lhs, rhs);
     m_icodes[1]->invalidate();
@@ -96,8 +96,8 @@ bool Idiom16::match (iICODE picode)
 int Idiom16::action()
 {
     AstIdent *lhs;
-    COND_EXPR *rhs;
-    lhs = AstIdent::Reg (m_icodes[0]->ll()->dst.regi, m_icodes[0]->ll()->getFlag(),&m_func->localId);
+    Expr *rhs;
+    lhs = new RegisterNode(m_icodes[0]->ll()->dst.regi, m_icodes[0]->ll()->getFlag(),&m_func->localId);
     rhs = UnaryOperator::Create(NEGATION, lhs->clone());
     m_icodes[0]->setAsgn(lhs, rhs);
     m_icodes[1]->invalidate();

+ 9 - 12
src/idioms/shift_idioms.cpp

@@ -29,7 +29,7 @@ int Idiom8::action()
 {
     int idx;
     AstIdent *lhs;
-    COND_EXPR *rhs,*expr;
+    Expr *expr;
     eReg regH,regL;
     regH=m_icodes[0]->ll()->dst.regi;
     regL=m_icodes[1]->ll()->dst.regi;
@@ -37,8 +37,7 @@ int Idiom8::action()
     lhs = AstIdent::LongIdx (idx);
     m_icodes[0]->setRegDU( regL, USE_DEF);
 
-    rhs = AstIdent::Kte(1,2);
-    expr = new BinaryOperator(SHR,lhs, rhs);
+    expr = new BinaryOperator(SHR,lhs, new Constant(1, 2));
     m_icodes[0]->setAsgn(lhs, expr);
     m_icodes[1]->invalidate();
     return 2;
@@ -81,11 +80,11 @@ int Idiom15::action()
 {
     AstIdent *lhs;
 
-    COND_EXPR *rhs,*_exp;
-    lhs = AstIdent::Reg (m_icodes[0]->ll()->dst.regi,
+    Expr *rhs,*_exp;
+    lhs = new RegisterNode(m_icodes[0]->ll()->dst.regi,
                             m_icodes[0]->ll()->getFlag() & NO_SRC_B,
                              &m_func->localId);
-    rhs = AstIdent::Kte (m_icodes.size(), 2);
+    rhs = new Constant(m_icodes.size(), 2);
     _exp = new BinaryOperator(SHL,lhs, rhs);
     m_icodes[0]->setAsgn(lhs, _exp);
     for (size_t i=1; i<m_icodes.size()-1; ++i)
@@ -119,7 +118,7 @@ bool Idiom12::match(iICODE pIcode)
 int Idiom12::action()
 {
     int idx;
-    COND_EXPR *rhs,*expr;
+    Expr *expr;
     AstIdent *lhs;
 
     eReg regH,regL;
@@ -129,8 +128,7 @@ int Idiom12::action()
     idx = m_func->localId.newLongReg (TYPE_LONG_UNSIGN, regH, regL,m_icodes[0]);
     lhs = AstIdent::LongIdx (idx);
     m_icodes[0]->setRegDU( regH, USE_DEF);
-    rhs = AstIdent::Kte (1, 2);
-    expr = new BinaryOperator(SHL,lhs, rhs);
+    expr = new BinaryOperator(SHL,lhs, new Constant(1, 2));
     m_icodes[0]->setAsgn(lhs, expr);
     m_icodes[1]->invalidate();
     return 2;
@@ -161,15 +159,14 @@ int Idiom9::action()
 {
     int idx;
     AstIdent *lhs;
-    COND_EXPR *rhs,*expr;
+    Expr *rhs,*expr;
     eReg regH,regL;
     regL=m_icodes[1]->ll()->dst.regi;
     regH=m_icodes[0]->ll()->dst.regi;
     idx = m_func->localId.newLongReg (TYPE_LONG_UNSIGN,regH,regL,m_icodes[0]);
     lhs = AstIdent::LongIdx (idx);
     m_icodes[0]->setRegDU(regL, USE_DEF);
-    rhs = AstIdent::Kte (1, 2);
-    expr = new BinaryOperator(SHR,lhs, rhs);
+    expr = new BinaryOperator(SHR,lhs, new Constant(1, 2));
     m_icodes[0]->setAsgn(lhs, expr);
     m_icodes[1]->invalidate();
     return 2;

+ 5 - 7
src/idioms/xor_idioms.cpp

@@ -39,11 +39,11 @@ bool Idiom21::match (iICODE picode)
 }
 int Idiom21::action()
 {
-    COND_EXPR *rhs;
+    Expr *rhs;
     AstIdent *lhs;
 
-    lhs = AstIdent::idLong (&m_func->localId, DST, m_icodes[0],HIGH_FIRST, m_icodes[0], eDEF, *m_icodes[1]->ll());
-    rhs = AstIdent::Kte (m_icodes[1]->ll()->src().getImm2() , 4);
+    lhs = AstIdent::Long (&m_func->localId, DST, m_icodes[0],HIGH_FIRST, m_icodes[0], eDEF, *m_icodes[1]->ll());
+    rhs = new Constant(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();
@@ -84,11 +84,9 @@ bool Idiom7::match(iICODE picode)
 }
 int Idiom7::action()
 {
-    COND_EXPR *lhs;
-    COND_EXPR *rhs;
+    Expr *lhs;
     lhs = AstIdent::id (*m_icode->ll(), DST, m_func, m_icode, *m_icode, NONE);
-    rhs = AstIdent::Kte (0, 2);
-    m_icode->setAsgn(dynamic_cast<AstIdent *>(lhs), rhs);
+    m_icode->setAsgn(dynamic_cast<AstIdent *>(lhs), new Constant(0, 2));
     m_icode->du.use = 0;    /* clear register used in iXOR */
     m_icode->ll()->setFlags(I);
     return 1;

+ 4 - 4
src/locident.cpp

@@ -341,13 +341,13 @@ boolT checkLongEq (LONG_STKID_TYPE longId, iICODE pIcode, int i, Function * pPro
 
         if ( not pIcode->ll()->testFlags(NO_SRC) )
         {
-            asgn.rhs = AstIdent::idLong (&pProc->localId, SRC, pIcode, HIGH_FIRST, pIcode, eUSE, atOffset);
+            asgn.rhs = AstIdent::Long (&pProc->localId, SRC, pIcode, HIGH_FIRST, pIcode, eUSE, atOffset);
         }
         return true;
     }
     else if ((longId.offH == pmHsrc->off) && (longId.offL == pmLsrc->off))
     {
-        asgn.lhs = AstIdent::idLong (&pProc->localId, DST, pIcode, HIGH_FIRST, pIcode,eDEF, atOffset);
+        asgn.lhs = AstIdent::Long (&pProc->localId, DST, pIcode, HIGH_FIRST, pIcode,eDEF, atOffset);
         asgn.rhs = AstIdent::LongIdx (i);
         return true;
     }
@@ -380,13 +380,13 @@ boolT checkLongRegEq (LONGID_TYPE longId, iICODE pIcode, int i,
         asgn.lhs = AstIdent::LongIdx (i);
         if ( not pIcode->ll()->testFlags(NO_SRC) )
         {
-            asgn.rhs = AstIdent::idLong (&pProc->localId, SRC, pIcode, HIGH_FIRST,  pIcode, eUSE, atOffset);
+            asgn.rhs = AstIdent::Long (&pProc->localId, SRC, pIcode, HIGH_FIRST,  pIcode, eUSE, atOffset);
         }
         return true;
     }
     else if ((longId.h == pmHsrc->regi) && (longId.l == pmLsrc->regi))
     {
-        asgn.lhs = AstIdent::idLong (&pProc->localId, DST, pIcode, HIGH_FIRST, pIcode, eDEF, atOffset);
+        asgn.lhs = AstIdent::Long (&pProc->localId, DST, pIcode, HIGH_FIRST, pIcode, eDEF, atOffset);
         asgn.rhs = AstIdent::LongIdx (i);
         return true;
     }

+ 36 - 24
src/parser.cpp

@@ -81,11 +81,11 @@ void DccFrontend::parse(Project &proj)
 
 /* Returns the size of the string pointed by sym and delimited by delim.
  * Size includes delimiter.     */
-int strSize (uint8_t *sym, char delim)
+int strSize (const uint8_t *sym, char delim)
 {
     PROG &prog(Project::get()->prog);
-    int till_end = sym-prog.Image;
-    uint8_t *end_ptr=std::find(sym,sym+(prog.cbImage-(till_end)),delim);
+    int till_end = sym-prog.image();
+    const uint8_t *end_ptr=std::find(sym,sym+(prog.cbImage-(till_end)),delim);
     return end_ptr-sym+1;
 }
 Function *fakeproc=Function::Create(0,0,"fake");
@@ -311,8 +311,8 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
                             operand = ((uint32_t)(uint16_t)pstate->r[rDS]<<4) +
                                       (uint32_t)(uint16_t)pstate->r[rDX];
                             size = prog.fCOM ?
-                                       strSize (&prog.Image[operand], '$') :
-                                       strSize (&prog.Image[operand], '$'); // + 0x100
+                                       strSize (&prog.image()[operand], '$') :
+                                       strSize (&prog.image()[operand], '$'); // + 0x100
                             global_symbol_table.updateSymType (operand, TypeContainer(TYPE_STR, size));
                         }
                 }
@@ -355,9 +355,9 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
                 if ((psym = lookupAddr(&ll->src(), pstate, 4, eDuVal::USE))
                         /* && (Icode.ll()->flg & SEG_IMMED) */ )
                 {
-                    offset = LH(&prog.Image[psym->label]);
+                    offset = LH(&prog.image()[psym->label]);
                     pstate->setState( (ll->getOpcode() == iLDS)? rDS: rES,
-                                      LH(&prog.Image[psym->label + 2]));
+                                      LH(&prog.image()[psym->label + 2]));
                     pstate->setState( ll->dst.regi, (int16_t)offset);
                     psym->type = TYPE_PTR;
                 }
@@ -370,7 +370,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
 
         if (err == INVALID_386OP || err == INVALID_OPCODE)
         {
-            fatalError(err, prog.Image[_Icode.ll()->label], _Icode.ll()->label);
+            fatalError(err, prog.image()[_Icode.ll()->label], _Icode.ll()->label);
             this->flg |= PROC_BADINST;
         }
         else if (err == IP_OUT_OF_RANGE)
@@ -410,7 +410,7 @@ bool Function::followAllTableEntries(JumpTable &table, uint32_t cs, ICODE& pIcod
     for (size_t i = table.start; i < table.finish; i += 2)
     {
         StCopy = *pstate;
-        StCopy.IP = cs + LH(&prog.Image[i]);
+        StCopy.IP = cs + LH(&prog.image()[i]);
         iICODE last_current_insn = (++Icode.rbegin()).base();
 
         FollowCtrl (pcallGraph, &StCopy);
@@ -434,7 +434,7 @@ bool Function::process_JMP (ICODE & pIcode, STATE *pstate, CALL_GRAPH * pcallGra
     if (pIcode.ll()->testFlags(I))
     {
         if (pIcode.ll()->getOpcode() == iJMPF)
-            pstate->setState( rCS, LH(prog.Image + pIcode.ll()->label + 3));
+            pstate->setState( rCS, LH(prog.image() + pIcode.ll()->label + 3));
         pstate->IP = pIcode.ll()->src().getImm2();
         int64_t i = pIcode.ll()->src().getImm2();
         if (i < 0)
@@ -483,7 +483,7 @@ bool Function::process_JMP (ICODE & pIcode, STATE *pstate, CALL_GRAPH * pcallGra
         cs = (uint32_t)(uint16_t)pstate->r[rCS] << 4;
         for (i = offTable; i < endTable; i += 2)
         {
-            target = cs + LH(&prog.Image[i]);
+            target = cs + LH(&prog.image()[i]);
             if (target < endTable && target >= offTable)
                 endTable = target;
             else if (target >= (uint32_t)prog.cbImage)
@@ -492,9 +492,9 @@ bool Function::process_JMP (ICODE & pIcode, STATE *pstate, CALL_GRAPH * pcallGra
 
         for (i = offTable; i < endTable; i += 2)
         {
-            target = cs + LH(&prog.Image[i]);
+            target = cs + LH(&prog.image()[i]);
             /* Be wary of 00 00 as code - it's probably data */
-            if (! (prog.Image[target] || prog.Image[target+1]) ||
+            if (! (prog.image()[target] || prog.image()[target+1]) ||
                     scan(target, _Icode))
                 endTable = i;
         }
@@ -516,7 +516,7 @@ bool Function::process_JMP (ICODE & pIcode, STATE *pstate, CALL_GRAPH * pcallGra
             for (i = offTable, k = 0; i < endTable; i += 2)
             {
                 StCopy = *pstate;
-                StCopy.IP = cs + LH(&prog.Image[i]);
+                StCopy.IP = cs + LH(&prog.image()[i]);
                 iICODE last_current_insn = (++Icode.rbegin()).base();
                 //ip = Icode.size();
 
@@ -604,9 +604,9 @@ boolT Function::process_CALL (ICODE & pIcode, CALL_GRAPH * pcallGraph, STATE *ps
                  * previous offset into the program image */
         uint32_t tgtAddr=0;
         if (pIcode.ll()->getOpcode() == iCALLF)
-            tgtAddr= LH(&prog.Image[off]) + ((uint32_t)(LH(&prog.Image[off+2])) << 4);
+            tgtAddr= LH(&prog.image()[off]) + ((uint32_t)(LH(&prog.image()[off+2])) << 4);
         else
-            tgtAddr= LH(&prog.Image[off]) + ((uint32_t)(uint16_t)state.r[rCS] << 4);
+            tgtAddr= LH(&prog.image()[off]) + ((uint32_t)(uint16_t)state.r[rCS] << 4);
         pIcode.ll()->replaceSrc(LLOperand::CreateImm2( tgtAddr ) );
         pIcode.ll()->setFlags(I);
         indirect = true;
@@ -651,7 +651,7 @@ boolT Function::process_CALL (ICODE & pIcode, CALL_GRAPH * pcallGraph, STATE *ps
             localState = *pstate;
             pstate->IP = pIcode.ll()->src().getImm2();
             if (pIcode.ll()->getOpcode() == iCALLF)
-                pstate->setState( rCS, LH(prog.Image + pIcode.ll()->label + 3));
+                pstate->setState( rCS, LH(prog.image() + pIcode.ll()->label + 3));
             x.state = *pstate;
 
             /* Insert new procedure in call graph */
@@ -694,7 +694,7 @@ static void process_MOV(LLInst & ll, STATE * pstate)
         {
             psym = lookupAddr(&ll.src(), pstate, 2, eDuVal::USE);
             if (psym && ((psym->flg & SEG_IMMED) || psym->duVal.val))
-                pstate->setState( dstReg, LH(&prog.Image[psym->label]));
+                pstate->setState( dstReg, LH(&prog.image()[psym->label]));
         }
         else if (srcReg < INDEX_BX_SI && pstate->f[srcReg])  /* reg */
         {
@@ -714,9 +714,13 @@ static void process_MOV(LLInst & ll, STATE * pstate)
         {
             if (ll.testFlags(I))   /* immediate */
             {
-                prog.Image[psym->label] = (uint8_t)ll.src().getImm2();
+                //prog.image()[psym->label] = (uint8_t)ll.src().getImm2();
+                pstate->setMemoryByte(psym->label,(uint8_t)ll.src().getImm2());
                 if(psym->size>1)
-                    prog.Image[psym->label+1] = (uint8_t)(ll.src().getImm2()>>8);
+                {
+                    pstate->setMemoryByte(psym->label+1,uint8_t(ll.src().getImm2()>>8));
+                    //prog.image()[psym->label+1] = (uint8_t)(ll.src().getImm2()>>8);
+                }
                 psym->duVal.val = 1;
             }
             else if (srcReg == 0) /* direct mem offset */
@@ -724,18 +728,26 @@ static void process_MOV(LLInst & ll, STATE * pstate)
                 psym2 = lookupAddr (&ll.src(), pstate, 2, eDuVal::USE);
                 if (psym2 && ((psym->flg & SEG_IMMED) || (psym->duVal.val)))
                 {
-                    prog.Image[psym->label] = (uint8_t)prog.Image[psym2->label];
+                    //prog.image()[psym->label] = (uint8_t)prog.image()[psym2->label];
+                    pstate->setMemoryByte(psym->label,(uint8_t)prog.image()[psym2->label]);
                     if(psym->size>1)
-                        prog.Image[psym->label+1] = prog.Image[psym2->label+1];//(uint8_t)(prog.Image[psym2->label+1] >> 8);
+                    {
+                        pstate->setMemoryByte(psym->label+1,(uint8_t)prog.image()[psym2->label+1]);
+                        //prog.image()[psym->label+1] = prog.image()[psym2->label+1];//(uint8_t)(prog.image()[psym2->label+1] >> 8);
+                    }
                     psym->duVal.setFlags(eDuVal::DEF);
                     psym2->duVal.setFlags(eDuVal::USE);
                 }
             }
             else if (srcReg < INDEX_BX_SI && pstate->f[srcReg])  /* reg */
             {
-                prog.Image[psym->label] = (uint8_t)pstate->r[srcReg];
+                //prog.image()[psym->label] = (uint8_t)pstate->r[srcReg];
+                pstate->setMemoryByte(psym->label,(uint8_t)pstate->r[srcReg]);
                 if(psym->size>1)
-                    prog.Image[psym->label+1] = (uint8_t)(pstate->r[srcReg] >> 8);
+                {
+                    pstate->setMemoryByte(psym->label,(uint8_t)pstate->r[srcReg]>>8);
+                    //prog.image()[psym->label+1] = (uint8_t)(pstate->r[srcReg] >> 8);
+                }
                 psym->duVal.setFlags(eDuVal::DEF);
             }
         }

+ 55 - 52
src/procs.cpp

@@ -94,7 +94,7 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
     STKFRAME * call_args_stackframe, *target_stackframe;
     const ID *id;
     int tidx;
-    boolT regExist;
+    bool regExist=false;
     condId type;
     Function * tproc;
     eReg regL, regH;		/* Registers involved in arguments */
@@ -106,16 +106,29 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
     /* Get registers and index into target procedure's local list */
     call_args_stackframe = ticode->hl()->call.args;
     target_stackframe = &tproc->args;
-    lhs = dynamic_cast<AstIdent *>(picode->hl()->asgn.lhs);
+    lhs = dynamic_cast<AstIdent *>(picode->hl()->asgn.lhs());
+    RegisterNode *lhs_reg = dynamic_cast<RegisterNode *>(lhs);
     assert(lhs);
-    type = lhs->ident.idType;
-    if (type == REGISTER)
+    type = lhs->ident.type();
+    if (lhs_reg)
     {
-        regL = id_arr[lhs->ident.idNode.regiIdx].id.regi;
+        regL = id_arr[lhs_reg->regiIdx].id.regi;
         if (regL < rAL)
             tidx = tproc->localId.newByteWordReg(TYPE_WORD_SIGN, regL);
         else
             tidx = tproc->localId.newByteWordReg(TYPE_BYTE_SIGN, regL);
+        /* Check if register argument already on the formal argument list */
+        for(STKSYM &tgt_sym : *target_stackframe)
+        {
+            RegisterNode *tgt_sym_regs = dynamic_cast<RegisterNode *>(tgt_sym.regs);
+            if( tgt_sym_regs == NULL ) // both REGISTER and LONG_VAR require this precondition
+                continue;
+            if ( tgt_sym_regs->regiIdx == tidx )
+            {
+                regExist = true;
+                break;
+            }
+        }
     }
     else if (type == LONG_VAR)
     {
@@ -123,32 +136,20 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
         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*/);
-    }
-
-    /* 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->ident.idNode.regiIdx == tidx )
-            {
-                regExist = true;
-            }
-        }
-        else if (type == LONG_VAR)
+        /* Check if register argument already on the formal argument list */
+        for(STKSYM &tgt_sym : *target_stackframe)
         {
+            if( tgt_sym.regs == NULL ) // both REGISTER and LONG_VAR require this precondition
+                continue;
             if ( tgt_sym.regs->ident.idNode.longIdx == tidx )
             {
                 regExist = true;
+                break;
             }
         }
-        if(regExist == true)
-            break;
     }
-
+    else
+        ;//regExist = false;
     /* Do ts (formal arguments) */
     if (regExist == false)
     {
@@ -161,12 +162,12 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
             if (regL < rAL)
             {
                 newsym.type = TYPE_WORD_SIGN;
-                newsym.regs = AstIdent::RegIdx(tidx, WORD_REG);
+                newsym.regs = new RegisterNode(tidx, WORD_REG);
             }
             else
             {
                 newsym.type = TYPE_BYTE_SIGN;
-                newsym.regs = AstIdent::RegIdx(tidx, BYTE_REG);
+                newsym.regs = new RegisterNode(tidx, BYTE_REG);
             }
             tproc->localId.id_arr[tidx].name = newsym.name;
         }
@@ -189,7 +190,7 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
     /* Mask off high and low register(s) in picode */
     switch (type) {
         case REGISTER:
-            id = &id_arr[lhs->ident.idNode.regiIdx];
+            id = &id_arr[lhs_reg->regiIdx];
             picode->du.def &= maskDuReg[id->id.regi];
             if (id->id.regi < rAL)
                 newsym.type = TYPE_WORD_SIGN;
@@ -215,9 +216,9 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
  * @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)
+bool CallType::newStkArg(Expr *exp, llIcode opcode, Function * pproc)
 {
-    AstIdent *expr = dynamic_cast<AstIdent *>(exp);
+    RegisterNode *expr = dynamic_cast<RegisterNode *>(exp);
 
     uint8_t regi;
     /* Check for far procedure call, in which case, references to segment
@@ -225,16 +226,13 @@ bool CallType::newStkArg(COND_EXPR *exp, llIcode opcode, Function * pproc)
          * long references to another segment) */
     if (expr)
     {
-        if (expr->ident.idType == REGISTER)
+        regi =  pproc->localId.id_arr[expr->regiIdx].id.regi;
+        if ((regi >= rES) && (regi <= rDS))
         {
-            regi =  pproc->localId.id_arr[expr->ident.idNode.regiIdx].id.regi;
-            if ((regi >= rES) && (regi <= rDS))
-            {
-                if (opcode == iCALLF)
-                    return false;
-                else
-                    return true;
-            }
+            if (opcode == iCALLF)
+                return false;
+            else
+                return true;
         }
     }
 
@@ -249,22 +247,22 @@ bool CallType::newStkArg(COND_EXPR *exp, llIcode opcode, Function * pproc)
 
 /* 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)
+void CallType::placeStkArg (Expr *exp, int pos)
 {
     (*args)[pos].actual = exp;
     (*args)[pos].setArgName(pos);
 }
 
-COND_EXPR *CallType::toId()
+Expr *CallType::toAst()
 {
-    return AstIdent::idFunc( proc, args);
+    return new FuncNode( proc, args);
 }
 
 
 /* Checks to determine whether the expression (actual argument) has the
  * same type as the given type (from the procedure's formal list).  If not,
  * the actual argument gets modified */
-void adjustActArgType (COND_EXPR *_exp, hlType forType, Function * pproc)
+Expr *Function::adjustActArgType (Expr *_exp, hlType forType)
 {
     AstIdent *expr = dynamic_cast<AstIdent *>(_exp);
     PROG &prog(Project::get()->prog);
@@ -272,11 +270,11 @@ void adjustActArgType (COND_EXPR *_exp, hlType forType, Function * pproc)
     int offset, offL;
 
     if (expr == NULL)
-        return;
+        return _exp;
 
-    actType = expr-> expType (pproc);
+    actType = expr-> expType (this);
     if (actType == forType)
-        return;
+        return _exp;
     switch (forType)
     {
         case TYPE_UNKNOWN: case TYPE_BYTE_SIGN:
@@ -292,16 +290,20 @@ void adjustActArgType (COND_EXPR *_exp, hlType forType, Function * pproc)
         case TYPE_STR:
             switch (actType) {
                 case TYPE_CONST:
-                    /* It's an offset into image where a string is
-                                         * found.  Point to the string.	*/
-                    offL = expr->ident.idNode.kte.kte;
+                    /* It's an offset into image where a string is found.  Point to the string.	*/
+                {
+                    Constant *c=dynamic_cast<Constant *>(expr);
+                    assert(c);
+                    offL = c->kte.kte;
                     if (prog.fCOM)
-                        offset = (pproc->state.r[rDS]<<4) + offL + 0x100;
+                        offset = (state.r[rDS]<<4) + offL + 0x100;
                     else
-                        offset = (pproc->state.r[rDS]<<4) + offL;
+                        offset = (state.r[rDS]<<4) + offL;
                     expr->ident.idNode.strIdx = offset;
-                    expr->ident.idType = STRING;
-                    break;
+                    expr->ident.type(STRING);
+                    delete c;
+                    return AstIdent::String(offset);
+                }
 
                 case TYPE_PTR:
                     /* It's a pointer to a char rather than a pointer to
@@ -319,6 +321,7 @@ void adjustActArgType (COND_EXPR *_exp, hlType forType, Function * pproc)
         default:
             fprintf(stderr,"adjustForArgType unhandled forType %d \n",forType);
     }
+    return _exp;
 }
 
 

+ 8 - 8
src/proplong.cpp

@@ -336,7 +336,7 @@ int Function::findBackwarLongDefs(int loc_ident_idx, const ID &pLocId, iICODE be
                 localId.id_arr[loc_ident_idx].idx.push_back(pIcode);//idx-1//insert
                 icode.setRegDU( pmL->regi, eDEF);
                 asgn.lhs = AstIdent::LongIdx (loc_ident_idx);
-                asgn.rhs = AstIdent::idLong (&this->localId, SRC, pIcode, HIGH_FIRST, pIcode, eUSE, *next1->ll());
+                asgn.rhs = AstIdent::Long (&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 */
@@ -365,7 +365,7 @@ int Function::findBackwarLongDefs(int loc_ident_idx, const ID &pLocId, iICODE be
             if ((pLocId.id.longId.h == pmH->regi) && (pLocId.id.longId.l == pmL->regi))
             {
                 asgn.lhs = AstIdent::LongIdx (loc_ident_idx);
-                asgn.rhs = AstIdent::idLong (&this->localId, SRC, pIcode, LOW_FIRST, pIcode, eUSE, *next1->ll());
+                asgn.rhs = AstIdent::Long (&this->localId, SRC, pIcode, LOW_FIRST, pIcode, eUSE, *next1->ll());
                 icode.setRegDU( pmH->regi, USE_DEF);
                 condOp toCreate=DUMMY;
                 switch (icode.ll()->getOpcode())
@@ -411,13 +411,13 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be
                     const LLOperand &src_op1(pIcode->ll()->src());
                     const LLOperand &src_op2(next1->ll()->src());
                     eReg srcReg1=src_op1.getReg2();
-                    eReg srcReg2=src_op2.getReg2();
-                    if ((ref_long.h == srcReg1) && (ref_long.l == srcReg2))
+                    eReg nextReg2=src_op2.getReg2();
+                    if ((ref_long.h == srcReg1) && (ref_long.l == nextReg2))
                     {
-                        pIcode->setRegDU( next1->ll()->src().getReg2(), eUSE);
+                        pIcode->setRegDU( nextReg2, eUSE);
 
                         asgn.rhs = AstIdent::LongIdx (loc_ident_idx);
-                        asgn.lhs = AstIdent::idLong (&this->localId, DST, pIcode,HIGH_FIRST, pIcode, eDEF, *next1->ll());
+                        asgn.lhs = AstIdent::Long (&this->localId, DST, pIcode,HIGH_FIRST, pIcode, eDEF, *next1->ll());
 
                         pIcode->setAsgn(dynamic_cast<AstIdent *>(asgn.lhs), asgn.rhs);
                         next1->invalidate();
@@ -453,7 +453,7 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be
                 {
                     asgn.lhs = AstIdent::LongIdx (loc_ident_idx);
                     pIcode->setRegDU( pmH->regi, USE_DEF);
-                    asgn.rhs = AstIdent::idLong (&this->localId, SRC, pIcode,
+                    asgn.rhs = AstIdent::Long (&this->localId, SRC, pIcode,
                                                   LOW_FIRST, pIcode, eUSE, *next1->ll());
                     condOp toCreate=DUMMY;
                     switch (pIcode->ll()->getOpcode()) {
@@ -505,7 +505,7 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be
             if (pLocId.id.longId.srcDstRegMatch(pIcode,pIcode))
             {
                 asgn.lhs = AstIdent::LongIdx (loc_ident_idx);
-                asgn.rhs = AstIdent::Kte (0, 4);	/* long 0 */
+                asgn.rhs = new Constant(0, 4);	/* long 0 */
                 asgn.lhs = new BinaryOperator(condOpJCond[next1->ll()->getOpcode() - iJB],asgn.lhs, asgn.rhs);
                 next1->setJCond(asgn.lhs);
                 next1->copyDU(*pIcode, eUSE, eUSE);

+ 75 - 38
src/scanner.cpp

@@ -314,14 +314,29 @@ static struct {
 } ;
 
 static uint16_t    SegPrefix, RepPrefix;
-static uint8_t  *pInst;		/* Ptr. to current uint8_t of instruction */
+static const uint8_t  *pInst;		/* Ptr. to current uint8_t of instruction */
 static ICODE * pIcode;		/* Ptr to Icode record filled in by scan() */
 
 
-/*****************************************************************************
- Scans one machine instruction at offset ip in prog.Image and returns error.
- At the same time, fill in low-level icode details for the scanned inst.
- ****************************************************************************/
+static void decodeBranchTgt(x86_insn_t &insn)
+{
+    x86_op_t *tgt_op = insn.x86_get_branch_target();
+    if(tgt_op->type==op_expression)
+        return; // unhandled for now
+    if(tgt_op->type==op_register)
+        return; // unhandled for now
+    int32_t addr = tgt_op->getAddress();
+    if(tgt_op->is_relative())
+    {
+        addr +=  insn.addr+insn.size;
+    }
+    pIcode->ll()->replaceSrc((uint32_t)addr);
+    pIcode->ll()->setFlags(I);
+    //    PROG &prog(Project::get()->prog);
+    //    long off = (short)getWord();	/* Signed displacement */
+    //    assert(addr==(uint32_t)(off + (unsigned)(pInst - prog.image())));
+
+}
 
 static void convertUsedFlags(x86_insn_t &from,ICODE &to)
 {
@@ -345,6 +360,13 @@ static void convertUsedFlags(x86_insn_t &from,ICODE &to)
     if(from.containsFlag(insn_eflag_direction,from.flags_tested))
         to.ll()->flagDU.u |= Df;
 }
+static void convertPrefix(x86_insn_prefix prefix,ICODE &to)
+{
+    if(prefix ==insn_no_prefix)
+        return;
+    // insn_lock - no need to handle
+    RepPrefix = (uint16_t)prefix & ~insn_lock;
+}
 /****************************************************************************
  Checks for int 34 to int 3B - if so, converts to ESC nn instruction
  ****************************************************************************/
@@ -362,7 +384,7 @@ static void fixFloatEmulation(x86_insn_t &insn)
     /* This is a Borland/Microsoft floating point emulation instruction. Treat as if it is an ESC opcode */
 
     int actual_valid_bytes=std::min(16U,prog.cbImage-insn.offset);
-    memcpy(buf,prog.Image+insn.offset,actual_valid_bytes);
+    memcpy(buf,prog.image()+insn.offset,actual_valid_bytes);
     X86_Disasm ds(opt_16_bit);
     x86_insn_t patched_insn;
     //patch actual instruction into buffer;
@@ -378,7 +400,7 @@ int disassembleOneLibDisasm(uint32_t ip,x86_insn_t &l)
 {
     PROG &prog(Project::get()->prog);
     X86_Disasm ds(opt_16_bit);
-    int cnt=ds.x86_disasm(prog.Image,prog.cbImage,0,ip,&l);
+    int cnt=ds.x86_disasm(prog.image(),prog.cbImage,0,ip,&l);
     if(cnt && l.is_valid())
     {
         fixFloatEmulation(l); //can change 'l'
@@ -416,6 +438,11 @@ LLOperand convertOperand(const x86_op_t &from)
     }
     return LLOperand::CreateImm2(0);
 }
+/*****************************************************************************
+ Scans one machine instruction at offset ip in prog.Image and returns error.
+ At the same time, fill in low-level icode details for the scanned inst.
+ ****************************************************************************/
+
 eErrorId scan(uint32_t ip, ICODE &p)
 {
     PROG &prog(Project::get()->prog);
@@ -431,10 +458,12 @@ eErrorId scan(uint32_t ip, ICODE &p)
     if(cnt)
     {
         convertUsedFlags(p.insn,p);
+        convertPrefix(p.insn.prefix,p);
+
     }
 
     SegPrefix = RepPrefix = 0;
-    pInst    = prog.Image + ip;
+    pInst    = prog.image() + ip;
     pIcode   = &p;
 
     do
@@ -446,12 +475,20 @@ eErrorId scan(uint32_t ip, ICODE &p)
         (*stateTable[op].state2)(op);		/* Third state  */
 
     } while (stateTable[op].state1 == prefix);	/* Loop if prefix */
+    if(p.insn.group == x86_insn_t::insn_controlflow)
+    {
+        if(p.insn.x86_get_branch_target())
+            decodeBranchTgt(p.insn);
+    }
+//    LLOperand conv = convertOperand(*p.insn.get_dest());
+//    assert(conv==p.ll()->dst);
     if (p.ll()->getOpcode())
     {
         /* Save bytes of image used */
-        p.ll()->numBytes = (uint8_t)((pInst - prog.Image) - ip);
+        p.ll()->numBytes = (uint8_t)((pInst - prog.image()) - ip);
         if(p.insn.is_valid())
             assert(p.ll()->numBytes == p.insn.size);
+        p.ll()->numBytes = p.insn.size;
         return ((SegPrefix)? FUNNY_SEGOVR:  /* Seg. Override invalid */
                              (RepPrefix ? FUNNY_REP: NO_ERR));/* REP prefix invalid */
     }
@@ -462,11 +499,11 @@ eErrorId scan(uint32_t ip, ICODE &p)
 /***************************************************************************
  relocItem - returns true if uint16_t pointed at is in relocation table
  **************************************************************************/
-static bool relocItem(uint8_t *p)
+static bool relocItem(const uint8_t *p)
 {
     PROG &prog(Project::get()->prog);
     int		i;
-    uint32_t	off = p - prog.Image;
+    uint32_t	off = p - prog.image();
 
     for (i = 0; i < prog.cReloc; i++)
         if (prog.relocTable[i] == off)
@@ -501,13 +538,13 @@ static int signex(uint8_t b)
  * 	Note: fdst == true is for the r/m part of the field (dest, unless TO_REG)
  *	      fdst == false is for reg part of the field
  ***************************************************************************/
-static void setAddress(int i, boolT fdst, uint16_t seg, int16_t reg, uint16_t off)
+static void setAddress(int i, bool fdst, uint16_t seg, int16_t reg, uint16_t off)
 {
     LLOperand *pm;
 
     /* If not to register (i.e. to r/m), and talking about r/m, then this is dest */
     pm = (!(stateTable[i].flg & TO_REG) == fdst) ?
-             &pIcode->ll()->dst : &pIcode->ll()->src();
+                &pIcode->ll()->dst : &pIcode->ll()->src();
 
     /* Set segment.  A later procedure (lookupAddr in proclist.c) will
          * provide the value of this segment in the field segValue.  */
@@ -572,7 +609,7 @@ static void rm(int i)
             setAddress(i, true, 0, rm + rAX, 0);
             break;
     }
-
+    //pIcode->insn.get_dest()->
     if ((stateTable[i].flg & NSP) && (pIcode->ll()->src().getReg2()==rSP ||
                                       pIcode->ll()->dst.getReg2()==rSP))
         pIcode->ll()->setFlags(NOT_HLL);
@@ -739,7 +776,7 @@ static void arith(int i)
     uint8_t opcode;
     static llIcode arithTable[8] =
     {
-        iTEST , (llIcode)0, iNOT, iNEG,
+        iTEST,  (llIcode)0, iNOT, iNEG,
         iMUL ,       iIMUL, iDIV, iIDIV
     };
     opcode = arithTable[REG(*pInst)];
@@ -810,47 +847,40 @@ static void dispM(int i)
 {
     setAddress(i, false, SegPrefix, 0, getWord());
 }
-
-
 /****************************************************************************
  dispN - 2 uint8_t disp as immed relative to ip
  ****************************************************************************/
 static void dispN(int )
 {
-    PROG &prog(Project::get()->prog);
-    long off = (short)getWord();	/* Signed displacement */
+    //PROG &prog(Project::get()->prog);
+    /*long off = (short)*/getWord();	/* Signed displacement */
 
     /* Note: the result of the subtraction could be between 32k and 64k, and
         still be positive; it is an offset from prog.Image. So this must be
         treated as unsigned */
-    pIcode->ll()->replaceSrc((uint32_t)(off + (unsigned)(pInst - prog.Image)));
-    pIcode->ll()->setFlags(I);
+    //    decodeBranchTgt();
 }
 
 
 /***************************************************************************
- dispS - 1 uint8_t disp as immed relative to ip
+ dispS - 1 byte disp as immed relative to ip
  ***************************************************************************/
 static void dispS(int )
 {
-    PROG &prog(Project::get()->prog);
-    long off = signex(*pInst++); 	/* Signed displacement */
+    /*long off =*/ signex(*pInst++); 	/* Signed displacement */
 
-    pIcode->ll()->replaceSrc((uint32_t)(off + (unsigned)(pInst - prog.Image)));
-    pIcode->ll()->setFlags(I);
+    //    decodeBranchTgt();
 }
 
 
 /****************************************************************************
- dispF - 4 uint8_t disp as immed 20-bit target address
+ dispF - 4 byte disp as immed 20-bit target address
  ***************************************************************************/
 static void dispF(int )
 {
-    uint32_t off = (unsigned)getWord();
-    uint32_t seg = (unsigned)getWord();
-
-    pIcode->ll()->replaceSrc(off + ((uint32_t)(unsigned)seg << 4));
-    pIcode->ll()->setFlags(I);
+    /*off = */(unsigned)getWord();
+    /*seg = */(unsigned)getWord();
+    //    decodeBranchTgt();
 }
 
 
@@ -880,12 +910,19 @@ static void strop(int )
 {
     if (RepPrefix)
     {
-        //		pIcode->ll()->getOpcode() += ((pIcode->ll()->getOpcode() == iCMPS ||
-        //								  pIcode->ll()->getOpcode() == iSCAS)
-        //								&& RepPrefix == iREPE)? 2: 1;
-        if ((pIcode->ll()->match(iCMPS) || pIcode->ll()->match(iSCAS) ) && RepPrefix == iREPE)
-            BumpOpcode(*pIcode->ll());	// += 2
-        BumpOpcode(*pIcode->ll());		// else += 1
+        if ( pIcode->ll()->match(iCMPS) || pIcode->ll()->match(iSCAS) )
+        {
+            if(pIcode->insn.prefix &  insn_rep_zero)
+            {
+                BumpOpcode(*pIcode->ll()); // iCMPS -> iREPE_CMPS
+                BumpOpcode(*pIcode->ll());
+            }
+            else if(pIcode->insn.prefix &  insn_rep_notzero)
+                BumpOpcode(*pIcode->ll()); // iX -> iREPNE_X
+        }
+        else
+            if(pIcode->insn.prefix &  insn_rep_zero)
+                BumpOpcode(*pIcode->ll()); // iX -> iREPE_X
         if (pIcode->ll()->match(iREP_LODS) )
             pIcode->ll()->setFlags(NOT_HLL);
         RepPrefix = 0;

+ 49 - 96
tests/prev_base/DHAMP.b

@@ -13,16 +13,15 @@ int proc_2 (long arg0, long arg1)
  */
 {
 char loc1; /* al */
-int loc2; /* al */
-int loc3; /* bx */
+int loc2; /* bx */
 
     do {
         arg0 = (arg0 + 1);
         loc1 = es[bx];
         arg1 = (arg1 + 1);
         es[bx] = loc1;
-    } while ((loc2 != 0));
-    return (loc3);
+    } while ((loc1 != 0));
+    return (loc2);
 }
 
 
@@ -35,7 +34,6 @@ int proc_3 (long arg0, long arg1)
 int loc1; /* ax */
 
     while ((es[bx] == es[bx])) {
-
         if (es[bx] == 0) {
             loc1 = 0;
             return (loc1);
@@ -57,9 +55,9 @@ int proc_1 (int arg0, int arg1, int arg2, int arg3)
 {
 int loc1; /* si */
 int loc2; /* di */
+
     loc1 = 0;
     loc2 = 0;
-
     while ((loc1 < 0x2328)) {
         proc_2 (arg1, arg0, 311);
         proc_2 (arg3, arg2, 328);
@@ -79,13 +77,12 @@ int loc1;
 int loc2;
 int loc3;
 int loc4;
-    loc3 = 0;
 
+    loc3 = 0;
     while ((loc3 < 0x3e8)) {
         loc1 = 0;
         loc4 = 0;
         loc2 = 1;
-
         while ((loc4 < 179)) {
             loc1 = (loc1 + loc2);
             loc2 = (loc2 + 2);
@@ -105,8 +102,8 @@ int proc_5 (int arg0)
 {
 int loc1; /* si */
 int loc2; /* ax */
-    loc1 = arg0;
 
+    loc1 = arg0;
     if (loc1 > 2) {
         loc2 = (proc_5 ((loc1 - 1)) + proc_5 ((loc1 + 0xfffe)));
     }
@@ -179,7 +176,7 @@ void proc_8 (int arg0)
 }
 
 
- proc_7 (int arg0, int arg1, int arg2, int arg3)
+void proc_7 (int arg0, int arg1, int arg2, int arg3)
 /* Takes 8 bytes of parameters.
  * High-level language prologue code.
  * Untranslatable routine.  Assembler provided.
@@ -245,7 +242,7 @@ void proc_8 (int arg0)
 }
 
 
- proc_9 (int arg0)
+void proc_9 (int arg0)
 /* Takes 8 bytes of parameters.
  * High-level language prologue code.
  * C calling convention.
@@ -256,106 +253,62 @@ void proc_8 (int arg0)
 int loc1;
 int loc2;
 int loc3; /* ax */
+
     loc2 = 100;
     loc3 = loc2;
     loc2 = (loc2 - 1);
-
     while (((loc3 | loc3) != 0)) {
         loc3 = loc2;
         loc2 = (loc2 - 1);
     }	/* end of while */
-    return (var06278);
 }
 
 
 int proc_10 ()
 /* Takes no parameters.
  * High-level language prologue code.
- * Untranslatable routine.  Assembler provided.
- * Return value in register ax.
  * Contains instructions not normally used by compilers.
  */
 {
-                    PUSH           bp                 
-                    MOV            bp, sp             
-                    SUB            sp, 68h            
-                    PUSH           si                 
-                    PUSH           di                 
-                    PUSH           ds                 
-                    MOV            ax, 159h           
-                    PUSH           ax                 
-                    PUSH           ss                 
-                    LEA            ax, [bp-64h]       
-                    PUSH           ax                 
-                    PUSH           cs                 
-                    CALL           near ptr proc_2    
-                    ADD            sp, 8              
-                    PUSH           ds                 
-                    MOV            ax, 170h           
-                    PUSH           ax                 
-                    PUSH           ds                 
-                    MOV            ax, 167h           
-                    PUSH           ax                 
-                    CALL            far ptr fopen     
-                    ADD            sp, 8              
-                    MOV            [bp-66h], dx       
-                    MOV            [bp-68h], ax       
-                    OR             dx, ax             
-                    JNE            L1                 
-                    PUSH           ds                 
-                    MOV            ax, 172h           
-                    PUSH           ax                 
-                    CALL            far ptr printf    
-                    POP            cx                 
-                    POP            cx                 
-                    MOV            ax, 0FFFFh         
-                    PUSH           ax                 
-                    CALL            far ptr exit      
-                    POP            cx                 
-
-               L1:  XOR            di, 0              
-
-               L2:  INC            di                 
-                    MOV            ax, di             
-                    CMP            ax, 3E8h           
-                    JL             L3                 
-                    PUSH           word ptr [bp-66h]  
-                    PUSH           word ptr [bp-68h]  
-                    CALL            far ptr fclose    
-                    POP            cx                 
-                    POP            cx                 
-                    MOV            ax, di             
-                    POP            di                 
-                    POP            si                 
-                    MOV            sp, bp             
-                    POP            bp                 
-                    RETF                              
+int loc1;
+int loc2;
+int loc3;
+int loc4;
+int loc5;
+int loc6; /* bx */
+int loc7; /* dx */
+int loc8; /* ax */
+    loc6 = proc_2 (&loc1, 345, , );
+    fopen ("zyxw.vut", 368);
+    loc2 = loc7;
+    loc3 = loc8;
+
+    if ((loc7 | loc8) == 0) {
+        printf ("Cannot open file");
+        exit (0xffff);
+    }
+l1: 
+    if (++loc5 >= 0x3e8) {
+        fclose (loc3, loc2);
+        return (loc5);
+    }
+    else {
+        loc4 = 0;
+
+        while ((ss[bp+si-0x64] != 0)) {
 
-               L3:  XOR            si, 0              
-
-               L4:  CMP            byte ptr ss:[bp+si-64h], 0
-                    JNE            L5                 
-
-               L5:  LES            bx, dword ptr[bp-68h]
-                    INC            word ptr es:[bx]   
-                    JGE            L6                 
-                    MOV            al, ss:[bp+si-64h] 
-                    LES            bx, dword ptr[bp-68h]
-                    INC            word ptr es:[bx+0Ch]
-                    LES            bx, dword ptres:[bx+0Ch]
-                    DEC            bx                 
-                    MOV            es:[bx], al        
-                    MOV            ah, 0              
-
-               L7:  INC            si                 
-                    JMP            L4                 ;Synthetic inst
-
-               L6:  PUSH           word ptr [bp-66h]  
-                    PUSH           word ptr [bp-68h]  
-                    PUSH           word ptr ss:[bp+si-64h]
-                    CALL            far ptr _fputc    
-                    ADD            sp, 6              
-                    JMP            L7                 ;Synthetic inst
+            if (++es[bx] < 0) {
+                es[bx+0xc] = (es[bx+0xc] + 1);
+                loc6 = (loc6 - 1);
+                es[bx] = ss[bp+si-0x64];
+            }
+            else {
+                _fputc (ss[bp+si-0x64], loc3, loc2);
+            }
+            loc4 = (loc4 + 1);
+        }	/* end of while */
+        goto L1;
+    }
 }
 
 
@@ -379,11 +332,11 @@ int loc10;
 int loc11;
 int loc12; /* ax */
 int loc13; /* bx */
-    printf ("Start...%c\n\n", 7);
 
+    loc11 = 0;
+    printf ("Start...%c\n\n", 7);
     while ((loc11 < 6)) {
         loc12 = loc11;
-
         if (loc12 <= 5) {
             loc13 = (loc12 << 1);
             var06278 = proc_1 (&loc2, &loc1, , );

+ 8 - 5
tests/prev_base/LONGOPS.b

@@ -15,30 +15,32 @@ long LXMUL@ (long arg0, long arg1)
 {
 int loc1;
 int loc2; /* tmp */
+
     loc2 = LO(arg0);
     LO(arg0) = loc1;
     loc1 = loc2;
     loc2 = LO(arg0);
     LO(arg0) = HI(arg0);
-
     if ((LO(arg0) & LO(arg0)) != 0) {
+        LO(arg0) = (LO(arg0) * LO(arg1));
     }
     loc2 = LO(arg0);
     LO(arg0) = HI(arg1);
     HI(arg1) = loc2;
-
     if ((LO(arg0) & LO(arg0)) != 0) {
         LO(arg0) = (LO(arg0) * loc1);
         HI(arg1) = (HI(arg1) + LO(arg0));
     }
     loc2 = LO(arg0);
-    arg0 = (loc1 * LO(arg1));
+    LO(arg0) = loc1;
+    loc1 = loc2;
+    arg0 = (LO(arg0) * LO(arg1));
     HI(arg0) = (HI(arg0) + HI(arg1));
     return (arg0);
 }
 
 
-long LDIV@ (long arg0, int arg3)
+long LDIV@ (long arg0, long arg2)
 /* Takes 8 bytes of parameters.
  * Runtime support routine of the compiler.
  * High-level language prologue code.
@@ -131,7 +133,7 @@ long LDIV@ (long arg0, int arg3)
 }
 
 
-long LMOD@ (long arg0, int arg3)
+long LMOD@ (long arg0, long arg2)
 /* Takes 8 bytes of parameters.
  * Runtime support routine of the compiler.
  * High-level language prologue code.
@@ -280,6 +282,7 @@ void main ()
 {
 long loc1;
 long loc2;
+
     loc2 = 255;
     loc1 = 143;
     loc1 = (loc2 + loc1);

+ 3 - 4
tests/prev_base/MATRIXMU.b

@@ -15,16 +15,14 @@ void proc_1 (int arg0, int arg1, int arg2)
 int loc1;
 int loc2;
 int loc3;
-    loc2 = 0;
 
+    loc2 = 0;
     while ((loc2 < 5)) {
         loc3 = 0;
-
         while ((loc3 < 4)) {
             loc1 = 0;
-
             while ((loc1 < 4)) {
-                *((((loc2 * 10) + arg2) + (loc3 << 1))) = ((*(((((loc2 << 3) << 1) + arg0) + (loc1 << 1))) * *((((loc1 * 10) + arg1) + (loc3 << 1)))) + *((((loc2 * 10) + arg2) + (loc3 << 1))));
+                *((((loc2 * 10) + arg2) + (loc3 << 1))) = ((*((((loc2 << 3) + arg0) + (loc1 << 1))) * *((((loc1 * 10) + arg1) + (loc3 << 1)))) + *((((loc2 * 10) + arg2) + (loc3 << 1))));
                 loc1 = (loc1 + 1);
             }	/* end of while */
             loc3 = (loc3 + 1);
@@ -42,6 +40,7 @@ void main ()
 int loc1;
 int loc2;
 int loc3;
+
     proc_1 (&loc3, &loc2, &loc1);
 }