Artur K 11 years ago
parent
commit
0209b7ceb2

+ 15 - 1
3rd_party/libdisasm/ia32_implicit.cpp

@@ -407,7 +407,21 @@ unsigned int Ia32_Decoder::ia32_insn_implicit_ops( unsigned int impl_idx ) {
 		if (!op) {
 			op = m_decoded->x86_operand_new();
 			/* all implicit operands are registers */
-			handle_impl_reg( op, list->operand );
+                        if(m_decoded->addr_size==2)
+                        {
+                            if(list->operand==REG_EIP_INDEX)
+                                handle_impl_reg( op, REG_IP_INDEX );
+                            else if(list->operand<REG_WORD_OFFSET)
+                            {
+                                handle_impl_reg( op, (list->operand-REG_DWORD_OFFSET)+REG_WORD_OFFSET);
+                                assert((list->operand-REG_DWORD_OFFSET)<REG_WORD_OFFSET-REG_DWORD_OFFSET);
+                            }
+                            else
+                                handle_impl_reg( op, list->operand);
+
+                        }
+                        else
+							handle_impl_reg( op, list->operand );
 			/* decrement the 'explicit count' incremented by default in
 			 * x86_operand_new */
 			m_decoded->explicit_count = m_decoded->explicit_count -1;

+ 10 - 10
3rd_party/libdisasm/ia32_operand.cpp

@@ -107,13 +107,13 @@ size_t Ia32_Decoder::decode_operand_value( unsigned char *buf, size_t buf_len,
             /* No MODRM : note these set operand type explicitly */
         case ADDRMETH_A:	/* No modR/M -- direct addr */
             op->type = op_absolute;
-
+            //according to Intel Manuals, offset goes first
             /* segment:offset address used in far calls */
             if ( m_decoded->addr_size == 4 ) {
                 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 );
+                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 );
@@ -134,7 +134,7 @@ size_t Ia32_Decoder::decode_operand_value( unsigned char *buf, size_t buf_len,
             size = op_size;
             break;
         case ADDRMETH_J:	/* Rel offset to add to IP [jmp] */
-            /* this fills op->data.near_offset or
+                           /* this fills op->data.near_offset or
                            op->data.far_offset depending on the size of
                            the operand */
             op->flags.op_signed = true;
@@ -146,15 +146,15 @@ size_t Ia32_Decoder::decode_operand_value( unsigned char *buf, size_t buf_len,
                     size = x86_imm_signsized(buf, buf_len, &op->data.relative_near, 1);
                     break;
                 case 2:
+                    /* far offset...is this truly signed? */
                     op->type = op_relative_far;
-                    int16_t offset_val;
-                    size = x86_imm_signsized(buf, buf_len,&offset_val, 2);
+                    int16_t offset_val; // easier upcast to int32_t
+                    size = x86_imm_signsized(buf, buf_len, &offset_val, 2 );
                     op->data.relative_far=offset_val;
                     break;
                 default:
                     assert(false);
                     size=0;
-
             }
             break;
         case ADDRMETH_O:	/* No ModR/M; op is word/dword offset */
@@ -181,7 +181,7 @@ size_t Ia32_Decoder::decode_operand_value( unsigned char *buf, size_t buf_len,
             op->flags.op_pointer = true;
             op->flags.op_string = true;
             ia32_handle_register( &op->data.expression.base,
-                                  REG_DWORD_OFFSET + 6 );
+                                  gen_regs + 6 );
             break;
         case ADDRMETH_Y:	/* Memory addressed by ES:DI [string] */
             op->type = op_expression;
@@ -190,7 +190,7 @@ size_t Ia32_Decoder::decode_operand_value( unsigned char *buf, size_t buf_len,
             op->flags.op_pointer = true;
             op->flags.op_string = true;
             ia32_handle_register( &op->data.expression.base,
-                                  REG_DWORD_OFFSET + 7 );
+                                  gen_regs + 7 );
             break;
         case ADDRMETH_RR:	/* Gen Register hard-coded in opcode */
             op->type = op_register;
@@ -260,8 +260,8 @@ size_t Ia32_Decoder::decode_operand_size( unsigned int op_type, x86_op_t *op ) {
             break;
         case OPTYPE_p:	/* 32/48-bit ptr [op size attr] */
             /* technically these flags are not accurate: the
-                         * value s a 16:16 pointer or a 16:32 pointer, where
-                         * the first '16' is a segment */
+             * 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 == 6) ? op_descr32 : op_descr16;
             break;

+ 356 - 357
3rd_party/libdisasm/libdis.h

@@ -8,15 +8,16 @@
 #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 +37,7 @@ typedef int64_t         qword_t;
  *      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 +45,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 +69,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 +87,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 +111,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 +150,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 +251,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();
@@ -304,25 +305,23 @@ struct x86_op_t{
     int32_t getAddress()
     {
         assert(is_address()||is_relative());
-        switch(type)
-        {
+        switch ( type ) {
+            case op_relative_near:
+                return (int32_t) data.relative_near;
             case op_absolute:
-            {
                 if(datatype==op_descr16)
-                    return (int32_t(data.absolute.segment)<<4) + data.absolute.offset.off16;
+                    return int32_t((data.absolute.segment)<<4) + data.absolute.offset.off16;
                 else
-                    return (int32_t(data.absolute.segment)<<4) + data.absolute.offset.off32;
-            }
+                    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;
+                return (int32_t) data.relative_far;
             default:
                 assert(false);
-                return ~0;
+                break;
         }
+        return ~0;
     }
     char * format( enum x86_asm_format format );
     x86_op_t * copy()
@@ -342,119 +341,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
@@ -463,11 +462,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 */
@@ -481,22 +480,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
@@ -505,19 +504,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
@@ -528,22 +527,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: */
 };
 
 
@@ -558,15 +557,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
@@ -707,9 +706,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 */
@@ -724,28 +723,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
@@ -757,8 +756,8 @@ public:
      *      insn    : Structure to fill with disassembled instruction
      */
     unsigned int x86_disasm(const unsigned char *buf, unsigned int buf_len,
-                            uint32_t buf_rva, unsigned int offset,
-                            x86_insn_t * insn );
+                             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
@@ -817,7 +816,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
@@ -866,24 +865,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 );

+ 0 - 1
3rd_party/libdisasm/x86_insn.cpp

@@ -99,7 +99,6 @@ x86_op_t * x86_insn_t::get_dest() {
     if ( ! operands ) {
         return NULL;
     }
-    assert(this->x86_operand_count(op_dest)==1);
     for (op_lst = operands; op_lst; op_lst = op_lst->next ) {
         if ( op_lst->op.access & op_write)
             return &(op_lst->op);

+ 1 - 1
include/BasicBlock.h

@@ -36,7 +36,7 @@ private:
         numHlIcodes(0),flg(0),
         inEdges(0),
         edges(0),beenOnH(0),inEdgeCount(0),reachingInt(0),
-        inInterval(0),correspInt(0),liveUse(0),def(0),liveIn(0),liveOut(0),
+        inInterval(0),correspInt(0),
         dfsFirstNum(0),dfsLastNum(0),immedDom(0),ifFollow(0),loopType(0),latchNode(0),
         numBackEdges(0),loopHead(0),loopFollow(0),caseHead(0),caseTail(0),index(0)
     {

+ 1 - 1
include/Procedure.h

@@ -143,7 +143,7 @@ public:
     bool            liveAnal;	/* Procedure has been analysed already		 */
 
     Function(void */*ty*/=0) : procEntry(0),depth(0),flg(0),cbParam(0),m_cfg(0),m_dfsLast(0),numBBs(0),
-        hasCase(false),liveIn(0),liveOut(0),liveAnal(0)//,next(0),prev(0)
+        hasCase(false),liveAnal(0)//,next(0),prev(0)
     {
     }
 public:

+ 2 - 6
include/dcc.h

@@ -59,12 +59,8 @@ typedef struct {            /* Command line option flags */
 extern OPTION option;       /* Command line options             */
 
 #include "BinaryImage.h"
-extern LivenessSet duReg[30];   /* def/use bits for registers		*/
 
-//extern uint32_t duReg[30];		/* def/use bits for registers		*/
-extern LivenessSet maskDuReg[30];	/* masks off du bits for regs		*/
 
-/* Registers used by icode instructions */
 
 /* Memory map states */
 enum eAreaType
@@ -130,8 +126,8 @@ char 	*writeJcondInv (HLTYPE, Function *, int *);
 
 
 /* Exported funcions from locident.c */
-boolT checkLongEq (LONG_STKID_TYPE, iICODE, int, Function *, Assignment &asgn, LLInst &atOffset);
-boolT checkLongRegEq (LONGID_TYPE, iICODE, int, Function *, Assignment &asgn, LLInst &);
+bool checkLongEq(LONG_STKID_TYPE, iICODE, int, Function *, Assignment &asgn, LLInst &atOffset);
+bool checkLongRegEq(LONGID_TYPE, iICODE, int, Function *, Assignment &asgn, LLInst &);
 eReg otherLongRegi(eReg, int, LOCAL_ID *);
 
 

+ 116 - 39
include/icode.h

@@ -7,6 +7,9 @@
 #include <vector>
 #include <list>
 #include <bitset>
+#include <set>
+#include <algorithm>
+#include <initializer_list>
 #include <llvm/ADT/ilist.h>
 #include <llvm/ADT/ilist_node.h>
 #include <llvm/MC/MCInst.h>
@@ -29,21 +32,24 @@ typedef std::list<ICODE>::iterator iICODE;
 typedef std::list<ICODE>::reverse_iterator riICODE;
 typedef boost::iterator_range<iICODE> rCODE;
 
-struct LivenessSet : public std::bitset<32>
+struct LivenessSet
 {
-    LivenessSet(int val=0) : std::bitset<32>(val) {}
-    LivenessSet(const LivenessSet &other)
+    std::set<eReg> registers;
+public:
+    LivenessSet(const std::initializer_list<eReg> &init) : registers(init) {}
+    LivenessSet() {}
+    LivenessSet(const LivenessSet &other) : registers(other.registers)
     {
-        (std::bitset<32> &)*this = (std::bitset<32> &)other;
     }
-    LivenessSet(const std::bitset<32> &other)
+    void reset()
     {
-        (std::bitset<32> &)*this = other;
+        registers.clear();
     }
-//    LivenessSet(LivenessSet &&other) : LivenessSet()
-//    {
-//        swap(*this,other);
-//    }
+
+    //    LivenessSet(LivenessSet &&other) : LivenessSet()
+    //    {
+    //        swap(*this,other);
+    //    }
     LivenessSet &operator=(LivenessSet other)
     {
         swap(*this,other);
@@ -56,22 +62,65 @@ struct LivenessSet : public std::bitset<32>
 
         // by swapping the members of two classes,
         // the two classes are effectively swapped
-        swap((std::bitset<32> &)first, (std::bitset<32> &)second);
+        swap(first.registers, second.registers);
+    }
+    LivenessSet &operator|=(const LivenessSet &other)
+    {
+        registers.insert(other.registers.begin(),other.registers.end());
+        return *this;
+    }
+    LivenessSet &operator&=(const LivenessSet &other)
+    {
+        std::set<eReg> res;
+        std::set_intersection(registers.begin(),registers.end(),
+                              other.registers.begin(),other.registers.end(),
+                              std::inserter(res, res.end()));
+        registers = res;
+        return *this;
+    }
+    LivenessSet &operator-=(const LivenessSet &other)
+    {
+        std::set<eReg> res;
+        std::set_difference(registers.begin(),registers.end(),
+                            other.registers.begin(),other.registers.end(),
+                            std::inserter(res, res.end()));
+        registers = res;
+        return *this;
+    }
+    LivenessSet operator-(const LivenessSet &other) const
+    {
+        return LivenessSet(*this) -= other;
+    }
+    LivenessSet operator+(const LivenessSet &other) const
+    {
+        return LivenessSet(*this) |= other;
     }
+    LivenessSet operator &(const LivenessSet &other) const
+    {
+        return LivenessSet(*this) &= other;
+    }
+    bool any() const
+    {
+        return not registers.empty();
+    }
+    bool operator==(const LivenessSet &other) const
+    {
+        return registers==other.registers;
+    }
+    bool operator!=(const LivenessSet &other) const { return not(*this==other);}
 
     LivenessSet &setReg(int r);
     LivenessSet &addReg(int r);
-    bool testReg(int r)
+    bool testReg(int r) const
     {
-        return test(r-rAX);
+        return registers.find(eReg(r))!=registers.end();
     }
-public:
+    bool testRegAndSubregs(int r) const;
     LivenessSet &clrReg(int r);
 private:
     void postProcessCompositeRegs();
 };
 
-extern LivenessSet duReg[30];
 /* uint8_t and uint16_t registers */
 
 /* Def/use of flags - low 4 bits represent flags */
@@ -180,8 +229,8 @@ public:
     void setCall(Function *proc);
     HLTYPE(hlIcode op=HLI_INVALID) : opcode(op)
     {}
-//    HLTYPE() // help valgrind find uninitialized HLTYPES
-//    {}
+    //    HLTYPE() // help valgrind find uninitialized HLTYPES
+    //    {}
     HLTYPE & operator=(const HLTYPE &l)
     {
         exp     = l.exp;
@@ -197,7 +246,6 @@ public:
 /* LOW_LEVEL icode operand record */
 struct LLOperand
 {
-    llvm::MCOperand llvm_op;
     eReg     seg;               /* CS, DS, ES, SS                       */
     eReg     segOver;           /* CS, DS, ES, SS if segment override   */
     int16_t    segValue;          /* Value of segment seg during analysis */
@@ -245,6 +293,10 @@ struct LLOperand
         Op.regi = (eReg)Val;
         return Op;
     }
+    bool isSet()
+    {
+        return not (*this == LLOperand());
+    }
     void addProcInformation(int param_count,uint32_t call_conv);
 };
 struct LLInst : public llvm::MCInst //: public llvm::ilist_node<LLInst>
@@ -256,7 +308,7 @@ 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          */
+    LLOperand       m_dst;            /* destination operand          */
     DU              flagDU;         /* def/use of flags				*/
     int             caseEntry;
     std::vector<uint32_t> caseTbl2;
@@ -285,25 +337,29 @@ public:
     {
         return (getOpcode()==op);
     }
+    bool matchWithRegDst(llIcode op)
+    {
+        return (getOpcode()==op) and m_dst.isReg();
+    }
     bool match(llIcode op,eReg dest)
     {
-        return (getOpcode()==op)&&dst.regi==dest;
+        return (getOpcode()==op)&&m_dst.regi==dest;
     }
     bool match(llIcode op,eReg dest,uint32_t flgs)
     {
-        return (getOpcode()==op) and (dst.regi==dest) and testFlags(flgs);
+        return (getOpcode()==op) and (m_dst.regi==dest) and testFlags(flgs);
     }
     bool match(llIcode op,eReg dest,eReg src_reg)
     {
-        return (getOpcode()==op)&&(dst.regi==dest)&&(m_src.regi==src_reg);
+        return (getOpcode()==op)&&(m_dst.regi==dest)&&(m_src.regi==src_reg);
     }
     bool match(eReg dest,eReg src_reg)
     {
-        return (dst.regi==dest)&&(m_src.regi==src_reg);
+        return (m_dst.regi==dest)&&(m_src.regi==src_reg);
     }
     bool match(eReg dest)
     {
-        return (dst.regi==dest);
+        return (m_dst.regi==dest);
     }
     bool match(llIcode op,uint32_t flgs)
     {
@@ -314,6 +370,19 @@ public:
         setOpcode(op);
         flg =flags;
     }
+    void set(llIcode op,uint32_t flags,eReg dst_reg)
+    {
+        setOpcode(op);
+        m_dst = LLOperand::CreateReg2(dst_reg);
+        flg =flags;
+    }
+    void set(llIcode op,uint32_t flags,eReg dst_reg,const LLOperand &src_op)
+    {
+        setOpcode(op);
+        m_dst = LLOperand::CreateReg2(dst_reg);
+        m_src = src_op;
+        flg =flags;
+    }
     void emitGotoLabel(int indLevel);
     void findJumpTargets(CIcodeRec &_pc);
     void writeIntComment(std::ostringstream &s);
@@ -343,16 +412,16 @@ public:
     }
     void replaceDst(const LLOperand &with)
     {
-        dst = with;
-    }
-    void replaceDst(eReg r)
-    {
-        dst = LLOperand::CreateReg2(r);
+        m_dst = with;
     }
+//    void replaceDst(eReg r)
+//    {
+//        dst = LLOperand::CreateReg2(r);
+//    }
     ICODE *m_link;
     condId idType(opLoc sd) const;
-    const LLOperand *   get(opLoc sd) const { return (sd == SRC) ? &src() : &dst; }
-    LLOperand *         get(opLoc sd) { return (sd == SRC) ? &src() : &dst; }
+    const LLOperand *   get(opLoc sd) const { return (sd == SRC) ? &src() : &m_dst; }
+    LLOperand *         get(opLoc sd) { return (sd == SRC) ? &src() : &m_dst; }
 };
 
 /* Icode definition: LOW_LEVEL and HIGH_LEVEL */
@@ -407,6 +476,10 @@ public:
     };
     struct DU1
     {
+    protected:
+        int     numRegsDef;             /* # registers defined by this inst */
+
+    public:
         struct Use
         {
             int Reg; // used register
@@ -422,7 +495,6 @@ public:
             }
 
         };
-        int     numRegsDef;             /* # registers defined by this inst */
         uint8_t	regi[MAX_REGS_DEF+1];	/* registers defined by this inst   */
         Use     idx[MAX_REGS_DEF+1];
         //int     idx[MAX_REGS_DEF][MAX_USES];	/* inst that uses this def  */
@@ -447,6 +519,11 @@ public:
             Use &u(idx[regIdx]);
             u.removeUser(ic);
         }
+        int getNumRegsDef() const {return numRegsDef;}
+        void clearAllDefs() {numRegsDef=0;}
+        DU1 &addDef(eReg r) {numRegsDef++; return *this;}
+        DU1 &setDef(eReg r) {numRegsDef=1; return *this;}
+        void removeDef(eReg r) {numRegsDef--;}
         DU1() : numRegsDef(0)
         {
         }
@@ -460,13 +537,13 @@ public:
     const LLInst *      ll() const { return &m_ll;}
 
     HLTYPE *            hlU() {
-//        assert(type==HIGH_LEVEL);
-//        assert(m_hl.opcode!=HLI_INVALID);
+        //        assert(type==HIGH_LEVEL);
+        //        assert(m_hl.opcode!=HLI_INVALID);
         return &m_hl;
     }
     const HLTYPE *      hl() const {
-//        assert(type==HIGH_LEVEL);
-//        assert(m_hl.opcode!=HLI_INVALID);
+        //        assert(type==HIGH_LEVEL);
+        //        assert(m_hl.opcode!=HLI_INVALID);
         return &m_hl;
     }
     void                hl(const HLTYPE &v) { m_hl=v;}
@@ -501,9 +578,9 @@ public:
     {
     }
 public:
-  const MachineBasicBlock* getParent() const { return Parent; }
-  MachineBasicBlock* getParent() { return Parent; }
-  //unsigned getNumOperands() const { return (unsigned)Operands.size(); }
+    const MachineBasicBlock* getParent() const { return Parent; }
+    MachineBasicBlock* getParent() { return Parent; }
+    //unsigned getNumOperands() const { return (unsigned)Operands.size(); }
 
 };
 /** Map n low level instructions to m high level instructions

+ 57 - 21
include/locident.h

@@ -31,37 +31,67 @@ struct IDX_ARRAY : public std::vector<iICODE>
     }
 };
 
-typedef enum
+enum frameType
 {
     STK_FRAME,			/* For stack vars			*/
     REG_FRAME,			/* For register variables 	*/
     GLB_FRAME			/* For globals				*/
-} frameType;
+};
 
-typedef struct
+struct BWGLB_TYPE
 {
     int16_t	seg;			/*   segment value							 */
     int16_t	off;			/*   offset									 */
     eReg 	regi;			/*   optional indexed register				 */
-} BWGLB_TYPE;
+} ;
 
 
-typedef struct
-{ /* For TYPE_LONG_(UN)SIGN on the stack	     */
+/* For TYPE_LONG_(UN)SIGN on the stack	     */
+struct LONG_STKID_TYPE
+{
     int		offH;	/*   high offset from BP					 */
     int		offL;	/*   low offset from BP						 */
-}	LONG_STKID_TYPE;
+    LONG_STKID_TYPE(int h,int l) : offH(h),offL(l) {}
+};
+/* For TYPE_LONG_(UN)SIGN registers			 */
 struct LONGID_TYPE
-{		/* For TYPE_LONG_(UN)SIGN registers			 */
-    eReg	h;		/*   high register							 */
-    eReg	l;		/*   low register							 */
+{
+protected:
+    eReg	m_h;		/*   high register							 */
+    eReg	m_l;		/*   low register							 */
+public:
+    void set(eReg highpart,eReg lowpart)
+    {
+        m_h = highpart;
+        m_l = lowpart;
+    }
+    eReg l() const { return m_l; }
+    eReg h() const { return m_h; }
     bool srcDstRegMatch(iICODE a,iICODE b) const;
+    LONGID_TYPE() {} // uninitializing constructor to help valgrind catch uninit accesses
+    LONGID_TYPE(eReg h,eReg l) : m_h(h),m_l(l) {}
 };
 
-
+struct LONGGLB_TYPE /* For TYPE_LONG_(UN)SIGN globals			 */
+{
+    int16_t	seg;	/*   segment value                                              */
+    int16_t	offH;	/*   offset high                                                */
+    int16_t	offL;	/*   offset low                                                 */
+    uint8_t	regi;	/*   optional indexed register                                  */
+    LONGGLB_TYPE(int16_t _seg,int16_t _H,int16_t _L,int8_t _reg=0)
+    {
+        seg=_seg;
+        offH=_H;
+        offL=_L;
+        regi=_reg;
+    }
+};
 /* ID, LOCAL_ID */
 struct ID
 {
+protected:
+    LONGID_TYPE     m_longId; /* For TYPE_LONG_(UN)SIGN registers			 */
+public:
     hlType              type;       /* Probable type                            */
     bool                illegal;    /* Boolean: not a valid field any more      */
     //std::vector<iICODE> idx;
@@ -70,33 +100,39 @@ struct ID
     bool                hasMacro;   /* Identifier requires a macro              */
     char                macro[10];  /* Macro for this identifier                */
     std::string         name;       /* Identifier's name                        */
-    union {                         /* Different types of identifiers           */
+    union ID_UNION {                         /* Different types of identifiers           */
+        friend class ID;
+    protected:
+        LONG_STKID_TYPE	longStkId;  /* For TYPE_LONG_(UN)SIGN on the stack */
+    public:
         eReg		regi;       /* For TYPE_BYTE(uint16_t)_(UN)SIGN registers   */
         struct {                    /* For TYPE_BYTE(uint16_t)_(UN)SIGN on the stack */
             uint8_t	regOff;     /*    register offset (if any)              */
             int		off;        /*    offset from BP            		*/
         }               bwId;
         BWGLB_TYPE	bwGlb;	/* For TYPE_BYTE(uint16_t)_(UN)SIGN globals		 */
-        LONGID_TYPE     longId; /* For TYPE_LONG_(UN)SIGN registers			 */
-        LONG_STKID_TYPE	longStkId;  /* For TYPE_LONG_(UN)SIGN on the stack */
-        struct {			/* For TYPE_LONG_(UN)SIGN globals			 */
-            int16_t	seg;	/*   segment value                                              */
-            int16_t	offH;	/*   offset high                                                */
-            int16_t	offL;	/*   offset low                                                 */
-            uint8_t	regi;	/*   optional indexed register                                  */
-        }			longGlb;
+        LONGGLB_TYPE    longGlb;
         struct {			/* For TYPE_LONG_(UN)SIGN constants                     */
             uint32_t	h;		/*	 high uint16_t								 */
             uint32_t 	l;		/*	 low uint16_t								 */
         } longKte;
+        ID_UNION() { /*new (&longStkId) LONG_STKID_TYPE();*/}
     } id;
+    LONGID_TYPE &longId() {assert(isLong() && loc==REG_FRAME); return m_longId;}
+    const LONGID_TYPE &longId() const {assert(isLong() && loc==REG_FRAME); return m_longId;}
+    LONG_STKID_TYPE &longStkId() {assert(isLong() && loc==STK_FRAME); return id.longStkId;}
+    const LONG_STKID_TYPE &longStkId() const {assert(isLong() && loc==STK_FRAME); return id.longStkId;}
     ID();
     ID(hlType t, frameType f);
+    ID(hlType t, const LONGID_TYPE &s);
+    ID(hlType t, const LONG_STKID_TYPE &s);
+    ID(hlType t, const LONGGLB_TYPE &s);
     bool isSigned() const { return (type==TYPE_BYTE_SIGN)||(type==TYPE_WORD_SIGN)||(type==TYPE_LONG_SIGN);}
     uint16_t typeBitsize() const
     {
         return TypeContainer::typeSize(type)*8;
     }
+    bool isLong() const { return (type==TYPE_LONG_UNSIGN)||(type==TYPE_LONG_SIGN); }
     void setLocalName(int i)
     {
         char buf[32];
@@ -123,7 +159,7 @@ public:
     int newByteWordReg(hlType t, eReg regi);
     int newByteWordStk(hlType t, int off, uint8_t regOff);
     int newIntIdx(int16_t seg, int16_t off, eReg regi, hlType t);
-    int newLongReg(hlType t, eReg regH, eReg regL, iICODE ix_);
+    int newLongReg(hlType t, const LONGID_TYPE &longT, iICODE ix_);
     int newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix, operDu du, int off);
     int newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix, operDu du, LLInst &atOffset);
     void newIdent(hlType t, frameType f);

+ 4 - 10
include/machine_x86.h

@@ -4,6 +4,7 @@
 #include <sstream>
 #include <bitset>
 
+struct LivenessSet;
 /* Machine registers */
 enum eReg
 {
@@ -32,8 +33,9 @@ enum eReg
     rBH =       20,
 
     rTMP=       21, /* temp register for DIV/IDIV/MOD	*/
+    rTMP2=       22, /* temp register for DIV/IDIV/MOD	*/
     /* Indexed modes go from INDEXBASE to INDEXBASE+7  */
-    INDEX_BX_SI = 22, // "bx+si"
+    INDEX_BX_SI = 23, // "bx+si"
     INDEX_BX_DI, // "bx+di"
     INDEX_BP_SI, // "bp+si"
     INDEX_BP_DI, // "bp+di"
@@ -64,15 +66,7 @@ public:
     bool physicalReg(eReg r);
     /* Writes the registers that are set in the bitvector */
     //TODO: move this into Machine_X86 ?
-    static void writeRegVector (std::ostream &ostr,const std::bitset<32> &regi)
-    {
-        int j;
-        for (j = rAX; j < INDEX_BX_SI; j++)
-        {
-            if (regi.test(j-1))
-                ostr << regName(eReg(j))<<" ";
-        }
-    }
+    static void writeRegVector (std::ostream &ostr,const LivenessSet &regi);
     static eReg subRegH(eReg reg);
     static eReg subRegL(eReg reg);
     static bool isMemOff(eReg r);

+ 19 - 15
src/ast.cpp

@@ -52,18 +52,23 @@ static const char *hexStr (uint16_t i)
 void ICODE::setRegDU (eReg regi, operDu du_in)
 {
     //    printf("%s %d %x\n",__FUNCTION__,regi,int(du_in));
+    if(regi==rSP)
+    {
+        printf("Discarding SP def&use info for now\n");
+        return;
+    }
     switch (du_in)
     {
         case eDEF:
             du.def.addReg(regi);
-            du1.numRegsDef++;
+            du1.addDef(regi);
             break;
         case eUSE:
             du.use.addReg(regi);
             break;
         case USE_DEF:
             du.addDefinedAndUsed(regi);
-            du1.numRegsDef++;
+            du1.addDef(regi);
             break;
         case NONE:    /* do nothing */
             break;
@@ -233,9 +238,8 @@ AstIdent *AstIdent::Long(LOCAL_ID *localId, opLoc sd, iICODE pIcode, hlFirst f,
     else
     {
         newExp  = new AstIdent();
-        idx = localId->newLong(sd, pIcode, f, ix, du, atOffset);
         newExp->ident.idType = LONG_VAR;
-        newExp->ident.idNode.longIdx = idx;
+        newExp->ident.idNode.longIdx = localId->newLong(sd, pIcode, f, ix, du, atOffset);
     }
     return (newExp);
 }
@@ -265,7 +269,7 @@ AstIdent *AstIdent::idID (const ID *retVal, LOCAL_ID *locsym, iICODE ix_)
         case TYPE_LONG_SIGN:
         {
             newExp  = new AstIdent();
-            idx = locsym->newLongReg (TYPE_LONG_SIGN, retVal->id.longId.h,retVal->id.longId.l, ix_);
+            idx = locsym->newLongReg (TYPE_LONG_SIGN, retVal->longId(), ix_);
             newExp->ident.idType = LONG_VAR;
             newExp->ident.idNode.longIdx = idx;
             break;
@@ -294,13 +298,13 @@ Expr *AstIdent::id(const LLInst &ll_insn, opLoc sd, Function * pProc, iICODE ix_
 
     int idx;          /* idx into pIcode->localId table */
 
-    const LLOperand &pm((sd == SRC) ? ll_insn.src() : ll_insn.dst);
+    const LLOperand &pm((sd == SRC) ? ll_insn.src() : ll_insn.m_dst);
 
     if (    ((sd == DST) && ll_insn.testFlags(IM_DST)) or
             ((sd == SRC) && ll_insn.testFlags(IM_SRC)) or
             (sd == LHS_OP))             /* for MUL lhs */
     {                                                   /* implicit dx:ax */
-        idx = pProc->localId.newLongReg (TYPE_LONG_SIGN, rDX, rAX, ix_);
+        idx = pProc->localId.newLongReg (TYPE_LONG_SIGN, LONGID_TYPE(rDX, rAX), ix_);
         newExp = AstIdent::LongIdx (idx);
         duIcode.setRegDU (rDX, du);
         duIcode.setRegDU (rAX, du);
@@ -372,7 +376,7 @@ Expr *AstIdent::id(const LLInst &ll_insn, opLoc sd, Function * pProc, iICODE ix_
 /* Returns the identifier type */
 condId LLInst::idType(opLoc sd) const
 {
-    const LLOperand &pm((sd == SRC) ? src() : dst);
+    const LLOperand &pm((sd == SRC) ? src() : m_dst);
 
     if ((sd == SRC) && testFlags(I))
         return (CONSTANT);
@@ -582,10 +586,10 @@ string AstIdent::walkCondExpr(Function *pProc, int *numLoc) const
             {
                 id->setLocalName(++(*numLoc));
                 codeOut <<TypeContainer::typeName(id->type)<< " "<<id->name<<"; ";
-                codeOut <<"/* "<<Machine_X86::regName(id->id.longId.h) << ":" <<
-                          Machine_X86::regName(id->id.longId.l) << " */\n";
+                codeOut <<"/* "<<Machine_X86::regName(id->longId().h()) << ":" <<
+                          Machine_X86::regName(id->longId().l()) << " */\n";
                 o << id->name;
-                pProc->localId.propLongId (id->id.longId.l,id->id.longId.h, id->name.c_str());
+                pProc->localId.propLongId (id->longId().l(),id->longId().h(), id->name.c_str());
             }
             else    /* GLB_FRAME */
             {
@@ -884,10 +888,10 @@ eReg AstIdent::otherLongRegi (eReg regi, int idx, LOCAL_ID *locTbl)
     if ((id->loc == REG_FRAME) && ((id->type == TYPE_LONG_SIGN) ||
                                    (id->type == TYPE_LONG_UNSIGN)))
     {
-        if (id->id.longId.h == regi)
-            return (id->id.longId.l);
-        else if (id->id.longId.l == regi)
-            return (id->id.longId.h);
+        if (id->longId().h() == regi)
+            return (id->longId().l());
+        else if (id->longId().l() == regi)
+            return (id->longId().h());
     }
     return rUNDEF;	// Cristina: please check this!
 }

+ 4 - 4
src/comwrite.cpp

@@ -154,7 +154,7 @@ void LLInst::writeIntComment (std::ostringstream &s)
     s<<"\t/* ";
     if (src_immed == 0x21)
     {
-        s <<int21h[dst.off];
+        s <<int21h[m_dst.off];
     }
     else if (src_immed > 0x1F && src_immed < 0x2F)
     {
@@ -162,7 +162,7 @@ void LLInst::writeIntComment (std::ostringstream &s)
     }
     else if (src_immed == 0x2F)
     {
-        switch (dst.off)
+        switch (m_dst.off)
         {
             case 0x01 :
                 s << "Print spooler";
@@ -215,8 +215,8 @@ void Function::writeProcComments(std::ostream &ostr)
             else		/* long register */
             {
                 id = &this->localId.id_arr[psym->regs->ident.idNode.longIdx];
-                ostr << Machine_X86::regName(id->id.longId.h) << ":";
-                ostr << Machine_X86::regName(id->id.longId.l);
+                ostr << Machine_X86::regName(id->longId().h()) << ":";
+                ostr << Machine_X86::regName(id->longId().l());
             }
             ostr << ".\n";
 

+ 49 - 50
src/dataflow.cpp

@@ -60,7 +60,7 @@ void ExpStack::push(Expr *expr)
 Expr *ExpStack::pop()
 {
     if(expStk.empty())
-        return 0;
+        return expStk.back();
     Expr *topExp = expStk.back();
     expStk.pop_back();
     return topExp;
@@ -266,7 +266,7 @@ void Function::genLiveKtes ()
         {
             if ((insn.type == HIGH_LEVEL) && ( insn.valid() ))
             {
-                liveUse |= (insn.du.use & ~def);
+                liveUse |= (insn.du.use - def);
                 def |= insn.du.def;
             }
         }
@@ -358,14 +358,15 @@ void Function::liveRegAnalysis (LivenessSet &in_liveOut)
                     {
                         switch (pcallee->retVal.type) {
                             case TYPE_LONG_SIGN: case TYPE_LONG_UNSIGN:
-                                ticode.du1.numRegsDef = 2;
+                                ticode.du1.setDef(rAX).addDef(rDX);
+                                //TODO: use Calling convention to properly set regs here
                                 break;
                             case TYPE_WORD_SIGN: case TYPE_WORD_UNSIGN:
                             case TYPE_BYTE_SIGN: case TYPE_BYTE_UNSIGN:
-                                ticode.du1.numRegsDef = 1;
+                                ticode.du1.setDef(rAX);
                                 break;
                             default:
-                                ticode.du1.numRegsDef = 0;
+                                ticode.du1 = ICODE::DU1(); // was .numRegsDef = 0
                                 //fprintf(stderr,"Function::liveRegAnalysis : Unknown return type %d, assume 0\n",pcallee->retVal.type);
                         } /*eos*/
 
@@ -377,7 +378,7 @@ void Function::liveRegAnalysis (LivenessSet &in_liveOut)
             }
 
             /* liveIn(b) = liveUse(b) U (liveOut(b) - def(b) */
-            pbb->liveIn = LivenessSet(pbb->liveUse | (pbb->liveOut & ~pbb->def));
+            pbb->liveIn = LivenessSet(pbb->liveUse + (pbb->liveOut - pbb->def));
 
             /* Check if live sets have been modified */
             if ((prevLiveIn != pbb->liveIn) || (prevLiveOut != pbb->liveOut))
@@ -422,10 +423,10 @@ bool BB::FindUseBeforeDef(eReg regi, int defRegIdx, iICODE start_at)
             if (checked_icode->type != HIGH_LEVEL) // Only check uses of HIGH_LEVEL icodes
                 continue;
             /* if used, get icode index */
-            if ((checked_icode->du.use & duReg[regi]).any())
+            if ( checked_icode->du.use.testRegAndSubregs(regi) )
                 start_at->du1.recordUse(defRegIdx,checked_icode.base());
             /* if defined, stop finding uses for this reg */
-            if ((checked_icode->du.def & duReg[regi]).any())
+            if (checked_icode->du.def.testRegAndSubregs(regi))
             {
                 ticode=checked_icode.base();
                 break;
@@ -435,13 +436,13 @@ bool BB::FindUseBeforeDef(eReg regi, int defRegIdx, iICODE start_at)
             ticode=(++riICODE(rbegin())).base();
 
         /* Check if last definition of this register */
-        if ((not (ticode->du.def & duReg[regi]).any()) and (liveOut & duReg[regi]).any())
+        if (not ticode->du.def.testRegAndSubregs(regi) and liveOut.testRegAndSubregs(regi) )
             start_at->du.lastDefRegi.addReg(regi);
     }
     else		/* only 1 instruction in this basic block */
     {
         /* Check if last definition of this register */
-        if ((liveOut & duReg[regi]).any())
+        if ( liveOut.testRegAndSubregs(regi) )
             start_at->du.lastDefRegi.addReg(regi);
     }
     return false;
@@ -460,17 +461,17 @@ void BB::ProcessUseDefForFunc(eReg regi, int defRegIdx, ICODE &picode)
         for (auto iter=target_instructions.begin(); iter!=target_instructions.end(); ++iter)
         {
             /* if used, get icode index */
-            if ((iter->du.use & duReg[regi]).any())
+            if ( iter->du.use.testRegAndSubregs(regi) )
                 picode.du1.recordUse(defRegIdx,iter.base());
             /* if defined, stop finding uses for this reg */
-            if ((iter->du.def & duReg[regi]).any())
+            if (iter->du.def.testRegAndSubregs(regi))
                 break;
         }
 
         /* if not used in this basic block, check if the
          * register is live out, if so, make it the last
          * definition of this register */
-        if ( picode.du1.used(defRegIdx) && (tbb->liveOut & duReg[regi]).any())
+        if ( picode.du1.used(defRegIdx) && tbb->liveOut.testRegAndSubregs(regi))
             picode.du.lastDefRegi.addReg(regi);
     }
 }
@@ -484,11 +485,11 @@ void BB::ProcessUseDefForFunc(eReg regi, int defRegIdx, ICODE &picode)
 void BB::RemoveUnusedDefs(eReg regi, int defRegIdx, iICODE picode)
 {
     if (picode->valid() and not picode->du1.used(defRegIdx) and
-            (not (picode->du.lastDefRegi & duReg[regi]).any()) &&
+            (not picode->du.lastDefRegi.testRegAndSubregs(regi)) &&
             (not ((picode->hl()->opcode == HLI_CALL) &&
                   (picode->hl()->call.proc->flg & PROC_ISLIB))))
     {
-        if (! (this->liveOut & duReg[regi]).any())	/* not liveOut */
+        if (! (this->liveOut.testRegAndSubregs(regi)))	/* not liveOut */
         {
             bool res = picode->removeDefRegi (regi, defRegIdx+1,&Parent->localId);
             if (res == true)
@@ -537,7 +538,7 @@ void BB::genDU1()
             defRegIdx++;
 
             /* Check if all defined registers have been processed */
-            if ((defRegIdx >= picode->du1.numRegsDef) || (defRegIdx == MAX_REGS_DEF))
+            if ((defRegIdx >= picode->du1.getNumRegsDef()) || (defRegIdx == MAX_REGS_DEF))
                 break;
         }
     }
@@ -736,18 +737,18 @@ void LOCAL_ID::processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode
             {
                 assert(lhs_ident);
                 res = Expr::insertSubTreeLongReg (
-                          p_hl.asgn.rhs,
-                          t_hl.exp.v,
-                          lhs_ident->ident.idNode.longIdx);
+                            p_hl.asgn.rhs,
+                            t_hl.exp.v,
+                            lhs_ident->ident.idNode.longIdx);
             }
             else
             {
                 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_reg->regiIdx].id.regi,
+                            t_hl.exp.v,
+                            p_hl.asgn.rhs,
+                            id_arr[lhs_reg->regiIdx].id.regi,
                         this);
             }
             if (res)
@@ -848,7 +849,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
     {
         HLTYPE &_icHl(*picode->hlU());
         numHlIcodes++;
-        if (picode->du1.numRegsDef == 1)    /* uint8_t/uint16_t regs */
+        if (picode->du1.getNumRegsDef() == 1)    /* uint8_t/uint16_t regs */
         {
             /* Check for only one use of this register.  If this is
              * the last definition of the register in this BB, check
@@ -867,7 +868,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
                          * icode expression */
 
                         ticode = picode->du1.idx[0].uses.front();
-                        if ((picode->du.lastDefRegi & duReg[regi]).any() &&
+                        if ((picode->du.lastDefRegi.testRegAndSubregs(regi)) &&
                                 ((ticode->hl()->opcode != HLI_CALL) &&
                                  (ticode->hl()->opcode != HLI_RET)))
                             continue;
@@ -886,7 +887,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
                         //   call F() <- somehow this is marked as user of POP ?
                         ticode = picode->du1.idx[0].uses.front();
                         ti_hl = ticode->hlU();
-                        if ((picode->du.lastDefRegi & duReg[regi]).any() &&
+                        if ((picode->du.lastDefRegi.testRegAndSubregs(regi)) &&
                                 ((ti_hl->opcode != HLI_CALL) &&
                                  (ti_hl->opcode != HLI_RET)))
                             continue;
@@ -902,8 +903,8 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
                                 RegisterNode *v = dynamic_cast<RegisterNode *>(_icHl.expr());
                                 assert(v);
                                 res = Expr::insertSubTreeReg (ti_hl->exp.v,
-                                                                   _exp,
-                                                                   locals.id_arr[v->regiIdx].id.regi,
+                                                              _exp,
+                                                              locals.id_arr[v->regiIdx].id.regi,
                                         &locals);
                                 if (res)
                                 {
@@ -971,7 +972,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
             }
         }
 
-        else if (picode->du1.numRegsDef == 2)   /* long regs */
+        else if (picode->du1.getNumRegsDef() == 2)   /* long regs */
         {
             /* Check for only one use of these registers */
             if ((picode->du1.numUses(0) == 1) and (picode->du1.numUses(1) == 1))
@@ -986,7 +987,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
                         if (picode->du1.idx[0].uses[0] == picode->du1.idx[1].uses[0])
                         {
                             ticode = picode->du1.idx[0].uses.front();
-                            if ((picode->du.lastDefRegi & duReg[regi]).any() &&
+                            if ((picode->du.lastDefRegi.testRegAndSubregs(regi)) &&
                                     ((ticode->hl()->opcode != HLI_CALL) &&
                                      (ticode->hl()->opcode != HLI_RET)))
                                 continue;
@@ -998,7 +999,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
                         if (picode->du1.idx[0].uses[0] == picode->du1.idx[1].uses[0])
                         {
                             ticode = picode->du1.idx[0].uses.front();
-                            if ((picode->du.lastDefRegi & duReg[regi]).any() &&
+                            if ((picode->du.lastDefRegi.testRegAndSubregs(regi)) &&
                                     ((ticode->hl()->opcode != HLI_CALL) &&
                                      (ticode->hl()->opcode != HLI_RET)))
                                 continue;
@@ -1011,7 +1012,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
                                     break;
                                 case HLI_JCOND: case HLI_PUSH:
                                     res = Expr::insertSubTreeLongReg (_exp,
-                                                                           ticode->hlU()->exp.v,
+                                                                      ticode->hlU()->exp.v,
                                                                       dynamic_cast<AstIdent *>(_icHl.asgn.lhs())->ident.idNode.longIdx);
                                     if (res)
                                     {
@@ -1034,9 +1035,9 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
                             case HLI_ASSIGN:
                                 _exp = _icHl.call.toAst();
                                 ticode->hlU()->asgn.lhs(
-                                        AstIdent::Long(&locals, DST,
-                                                          ticode,HIGH_FIRST, picode.base(),
-                                                          eDEF, *(++iICODE(ticode))->ll()));
+                                            AstIdent::Long(&locals, DST,
+                                                           ticode,HIGH_FIRST, picode.base(),
+                                                           eDEF, *(++iICODE(ticode))->ll()));
                                 ticode->hlU()->asgn.rhs = _exp;
                                 picode->invalidate();
                                 numHlIcodes--;
@@ -1052,9 +1053,8 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
                                 _exp = _icHl.call.toAst();
                                 _retVal = &picode->hl()->call.proc->retVal;
                                 res = Expr::insertSubTreeLongReg (_exp,
-                                                                       ticode->hlU()->exp.v,
-                                                                       locals.newLongReg ( _retVal->type, _retVal->id.longId.h,
-                                                                                           _retVal->id.longId.l, picode.base()));
+                                                                  ticode->hlU()->exp.v,
+                                                                  locals.newLongReg ( _retVal->type, _retVal->longId(), picode.base()));
                                 if (res)	/* was substituted */
                                 {
                                     picode->invalidate();
@@ -1083,8 +1083,8 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
         {
             g_exp_stk.processExpPush(numHlIcodes, picode.base());
         }
-        else if(picode->du1.numRegsDef!=0)
-            printf("Num def %d\n",picode->du1.numRegsDef);
+        else if(picode->du1.getNumRegsDef()!=0)
+            printf("Num def %d\n",picode->du1.getNumRegsDef());
 
         /* For HLI_CALL instructions that use arguments from the stack,
          * pop them from the expression stack and place them on the
@@ -1098,7 +1098,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
 
             /* If we could not substitute the result of a function,
              * assign it to the corresponding registers */
-            if ( not _icHl.call.proc->isLibrary() and (not picode->du1.used(0)) and (picode->du1.numRegsDef > 0))
+            if ( not _icHl.call.proc->isLibrary() and (not picode->du1.used(0)) and (picode->du1.getNumRegsDef() > 0))
             {
                 _exp = new FuncNode(_icHl.call.proc, _icHl.call.args);
                 auto lhs = AstIdent::idID (&_icHl.call.proc->retVal, &locals, picode.base());
@@ -1131,13 +1131,13 @@ void Function::preprocessReturnDU(LivenessSet &_liveOut)
         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;
-        }
+            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);
@@ -1176,9 +1176,8 @@ void Function::preprocessReturnDU(LivenessSet &_liveOut)
         {
             retVal.type = TYPE_LONG_SIGN;
             retVal.loc = REG_FRAME;
-            retVal.id.longId.h = rDX;
-            retVal.id.longId.l = rAX;
-            /*idx = */localId.newLongReg(TYPE_LONG_SIGN, rDX, rAX, Icode.begin()/*0*/);
+            retVal.longId() = LONGID_TYPE(rDX,rAX);
+            /*idx = */localId.newLongReg(TYPE_LONG_SIGN, LONGID_TYPE(rDX,rAX), Icode.begin());
             localId.propLongId (rAX, rDX, "\0");
         }
         else if (isAx || isBx || isCx || isDx)	/* uint16_t */

+ 15 - 16
src/disassem.cpp

@@ -70,7 +70,7 @@ static const char *szFlops3C[] =
 
 static const char *szPtr[2]   = { "word ptr ", "byte ptr " };
 
-static void  formatRM(ostringstream &p, uint32_t flg, const LLOperand &pm);
+static void  formatRM(ostringstream &p, const LLOperand &pm);
 static ostringstream &strDst(ostringstream &os, uint32_t flg, const LLOperand &pm);
 
 static char *strHex(uint32_t d);
@@ -283,7 +283,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
     {
         case iADD:  case iADC:  case iSUB:  case iSBB:  case iAND:  case iOR:
         case iXOR:  case iTEST: case iCMP:  case iMOV:  case iLEA:  case iXCHG:
-            strDst(operands_s,inst.getFlag(), inst.dst);
+            strDst(operands_s,inst.getFlag(), inst.m_dst);
             inst.strSrc(operands_s);
             break;
 
@@ -293,7 +293,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
 
         case iSAR:  case iSHL:  case iSHR:  case iRCL:  case iRCR:  case iROL:
         case iROR:
-            strDst(operands_s,inst.getFlag() | I, inst.dst);
+            strDst(operands_s,inst.getFlag() | I, inst.m_dst);
             if(inst.testFlags(I))
                 inst.strSrc(operands_s);
             else
@@ -301,7 +301,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
             break;
 
         case iINC:  case iDEC:  case iNEG:  case iNOT:  case iPOP:
-            strDst(operands_s,inst.getFlag() | I, inst.dst);
+            strDst(operands_s,inst.getFlag() | I, inst.m_dst);
             break;
 
         case iPUSH:
@@ -311,15 +311,15 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
             }
             else
             {
-                strDst(operands_s,inst.getFlag() | I, inst.dst);
+                strDst(operands_s,inst.getFlag() | I, inst.m_dst);
             }
             break;
 
         case iDIV:  case iIDIV:  case iMUL: case iIMUL: case iMOD:
             if (inst.testFlags(I))
             {
-                strDst(operands_s,inst.getFlag(), inst.dst) <<", ";
-                formatRM(operands_s, inst.getFlag(), inst.src());
+                strDst(operands_s,inst.getFlag(), inst.m_dst) <<", ";
+                formatRM(operands_s, inst.src());
                 inst.strSrc(operands_s);
             }
             else
@@ -327,7 +327,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
             break;
 
         case iLDS:  case iLES:  case iBOUND:
-            strDst(operands_s,inst.getFlag(), inst.dst)<<", dword ptr";
+            strDst(operands_s,inst.getFlag(), inst.m_dst)<<", dword ptr";
             inst.strSrc(operands_s,true);
             break;
 
@@ -397,8 +397,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
             break;
 
         case iENTER:
-            operands_s<<strHex(inst.dst.off)<<", ";
-            operands_s<<strHex(inst.src().getImm2());
+            operands_s<<strHex(inst.m_dst.off) << ", " << strHex(inst.src().getImm2());
             break;
 
         case iRET:  case iRETF:  case iINT:
@@ -552,7 +551,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
 /****************************************************************************
  * formatRM
  ***************************************************************************/
-static void formatRM(std::ostringstream &p, uint32_t /*flg*/, const LLOperand &pm)
+static void formatRM(std::ostringstream &p, const LLOperand &pm)
 {
     //char    seg[4];
 
@@ -595,7 +594,7 @@ static ostringstream & strDst(ostringstream &os,uint32_t flg, const LLOperand &p
     //os << setw(WID_PTR);
     if ((flg & I) and not pm.isReg())
         os << szPtr[flg & B];
-    formatRM(os, flg, pm);
+    formatRM(os, pm);
     return os;
 }
 
@@ -612,7 +611,7 @@ ostringstream &LLInst::strSrc(ostringstream &os,bool skip_comma)
     else if (testFlags(IM_SRC))		/* level 2 */
         os<<"dx:ax";
     else
-        formatRM(os, getFlag(), src());
+        formatRM(os, src());
 
     return os;
 }
@@ -649,7 +648,7 @@ void LLInst::flops(std::ostringstream &out)
     /* Note that op is set to the escape number, e.g.
         esc 0x38 is FILD */
 
-    if ( not dst.isReg() )
+    if ( not m_dst.isReg() )
     {
         /* The mod/rm mod bits are not set to 11 (i.e. register). This is the normal floating point opcode */
         out<<Machine_X86::floatOpName(op)<<' ';
@@ -685,7 +684,7 @@ void LLInst::flops(std::ostringstream &out)
                 }
         }
 
-        formatRM(out, getFlag(), dst);
+        formatRM(out, m_dst);
     }
     else
     {
@@ -694,7 +693,7 @@ void LLInst::flops(std::ostringstream &out)
             normal opcodes. Because the opcodes are slightly different for
             this case (e.g. op=04 means FSUB if reg != 3, but FSUBR for
             reg == 3), a separate table is used (szFlops2). */
-        int destRegIdx=dst.regi - rAX;
+        int destRegIdx=m_dst.regi - rAX;
         switch (op)
         {
             case 0x0C:

+ 51 - 31
src/hlicode.cpp

@@ -11,27 +11,6 @@
 #include "dcc.h"
 using namespace std;
 
-/* Masks off bits set by duReg[] */
-LivenessSet maskDuReg[] = { 0x00,
-                            /* uint16_t regs */
-                            0xFEEFFE, //rAX
-                            0xFDDFFD, //rCX
-                            0xFBB00B, //rDX
-                            0xF77007, //rBX
-                            0xFFFFEF, //rSP
-                            0xFFFFDF, //rBP
-                            0xFFFFBF, //rSI
-                            0xFFFF7F, //rDI
-                            0xFFFEFF,
-                            0xFFFDFF,
-                            0xFFFBFF,
-                            0xFFF7FF, /* seg regs  */
-                            0xFFEFFF, 0xFFDFFF, 0xFFBFFF, 0xFF7FFF, /* uint8_t regs */
-                            0xFEFFFF, 0xFDFFFF, 0xFBFFFF, 0xF7FFFF,
-                            0xEFFFFF,                               /* tmp reg   */
-                            0xFFFFB7, 0xFFFF77, 0xFFFF9F, 0xFFFF5F, /* index regs */
-                            0xFFFFBF, 0xFFFF7F, 0xFFFFDF, 0xFFFFF7 };
-
 static char buf[lineSize];     /* Line buffer for hl icode output */
 
 
@@ -98,13 +77,13 @@ bool ICODE::removeDefRegi (eReg regi, int thisDefIdx, LOCAL_ID *locId)
 {
     int numDefs;
 
-    numDefs = du1.numRegsDef;
+    numDefs = du1.getNumRegsDef();
     if (numDefs == thisDefIdx)
     {
         for ( ; numDefs > 0; numDefs--)
         {
 
-            if (du1.used(numDefs-1)||(du.lastDefRegi[regi]))
+            if (du1.used(numDefs-1)||(du.lastDefRegi.testReg(regi)))
                 break;
         }
     }
@@ -117,8 +96,9 @@ bool ICODE::removeDefRegi (eReg regi, int thisDefIdx, LOCAL_ID *locId)
     HlTypeSupport *p=hlU()->get();
     if(p and p->removeRegFromLong(regi,locId))
     {
-        du1.numRegsDef--;
-        du.def &= maskDuReg[regi];
+        du1.removeDef(regi); //du1.numRegsDef--;
+		//du.def &= maskDuReg[regi];
+        du.def.clrReg(regi);
     }
     return false;
 }
@@ -285,6 +265,41 @@ HLTYPE LLInst::toHighLevel(COND_EXPR *lhs,COND_EXPR *rhs,Function *func)
     return res;
 }
 #endif
+static bool  needsLhs(unsigned opc)
+{
+    switch (opc)
+    {
+        case iCALL:
+        case iCALLF:
+        case iRET:
+        case iRETF:
+        default: return false;
+        case iADD:
+        case iAND:
+        case iDEC:
+        case iDIV:
+        case iIDIV:/* should be signed div */
+        case iIMUL:
+        case iINC:
+        case iLEA:
+        case iMOD:
+        case iMOV:
+        case iMUL:
+        case iNEG:
+        case iNOT:
+        case iOR:
+        case iPOP:
+        case iPUSH:
+        case iSHL:
+        case iSAR:    /* signed */
+        case iSHR:
+        case iSIGNEX:
+        case iSUB:
+        case iXCHG:
+        case iXOR:
+            return true;
+    }
+}
 /* Translates LOW_LEVEL icodes to HIGH_LEVEL icodes - 1st stage.
  * Note: this process should be done before data flow analysis, which
  *       refines the HIGH_LEVEL icodes. */
@@ -292,12 +307,12 @@ void Function::highLevelGen()
 {
     size_t numIcode;         /* number of icode instructions */
     iICODE pIcode;        /* ptr to current icode node */
-    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)
     {
+        Expr *lhs=nullptr;
         assert(numIcode==Icode.size());
         pIcode = i; //Icode.GetIcode(i)
         LLInst *ll = pIcode->ll();
@@ -306,13 +321,16 @@ void Function::highLevelGen()
         if ((pIcode->type != LOW_LEVEL) or not pIcode->valid() )
             continue;
         _flg = ll->getFlag();
-        if ((_flg & IM_OPS) != IM_OPS)   /* not processing IM_OPS yet */
-            if ((_flg & NO_OPS) != NO_OPS)       /* if there are opers */
+        if (not ll->testFlags(IM_OPS))   /* not processing IM_OPS yet */
+            if ( not ll->testFlags(NO_OPS) )       /* if there are opers */
             {
                 if ( not ll->testFlags(NO_SRC) )   /* if there is src op */
                     rhs = AstIdent::id (*pIcode->ll(), SRC, this, i, *pIcode, NONE);
+                if(ll->m_dst.isSet() || (ll->getOpcode()==iMOD))
                 lhs = AstIdent::id (*pIcode->ll(), DST, this, i, *pIcode, NONE);
             }
+        if(needsLhs(ll->getOpcode()))
+            assert(lhs!=nullptr);
         switch (ll->getOpcode())
         {
             case iADD:
@@ -406,10 +424,12 @@ void Function::highLevelGen()
                 pIcode->setAsgn(lhs, rhs);
                 break;
 
-            case iPOP:    pIcode->setUnary(HLI_POP, lhs);
+            case iPOP:
+                pIcode->setUnary(HLI_POP, lhs);
                 break;
 
-            case iPUSH:   pIcode->setUnary(HLI_PUSH, lhs);
+            case iPUSH:
+                pIcode->setUnary(HLI_PUSH, lhs);
                 break;
 
             case iRET:
@@ -613,7 +633,7 @@ void ICODE::writeDU()
     }
 
     /* Print du1 chain */
-    printf ("# regs defined = %d\n", du1.numRegsDef);
+    printf ("# regs defined = %d\n", du1.getNumRegsDef());
     for (int i = 0; i < MAX_REGS_DEF; i++)
     {
         if (not du1.used(i))

+ 1 - 1
src/idioms.cpp

@@ -122,7 +122,7 @@ void Function::findIdioms()
                 {
                     if ((pIcode->ll()->src().proc.proc->retVal.type==TYPE_LONG_SIGN)
                             || (pIcode->ll()->src().proc.proc->retVal.type == TYPE_LONG_UNSIGN))
-                        localId.newLongReg(TYPE_LONG_SIGN, rDX, rAX, pIcode/*ip*/);
+                        localId.newLongReg(TYPE_LONG_SIGN, LONGID_TYPE(rDX,rAX), pIcode/*ip*/);
                 }
 
             /* Check for idioms */

+ 15 - 15
src/idioms/arith_idioms.cpp

@@ -102,20 +102,20 @@ 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() ))
+    if(not m_icodes[0]->ll()->matchWithRegDst(iMOV) )
         return false;
-    regi = m_icodes[0]->ll()->dst.regi;
-    if( not ( m_icodes[2]->ll()->match(iCMP) && (m_icodes[2]->ll()->dst.regi == regi) &&
+    regi = m_icodes[0]->ll()->m_dst.regi;
+    if( not ( m_icodes[2]->ll()->match(iCMP,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 */
+    if (m_icodes[1]->ll()->m_dst.regi == 0)	/* global variable */
     {
         /* not supported yet */
         m_idiom_type = 0;
     }
-    else if ( m_icodes[1]->ll()->dst.isReg() )	/* register */
+    else if ( m_icodes[1]->ll()->m_dst.isReg() )	/* register */
     {
         m_idiom_type = 1;
 //        if ((m_icodes[1]->ll()->dst.regi == rSI) && (m_func->flg & SI_REGVAR))
@@ -123,7 +123,7 @@ bool Idiom18::match(iICODE picode)
 //        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 */
+    else if (m_icodes[1]->ll()->m_dst.off)		/* local variable */
         m_idiom_type = 2;
     else		/* indexed */
     {
@@ -141,20 +141,20 @@ bool Idiom18::match(iICODE picode)
             break;
         case 1:  /* register variable */
             /* Check previous instruction for a MOV */
-            if ( (m_icodes[0]->ll()->src().regi == m_icodes[1]->ll()->dst.regi))
+            if ( (m_icodes[0]->ll()->src().regi == m_icodes[1]->ll()->m_dst.regi))
             {
                 return true;
             }
             break;
         case 2: /* local */
-            if ((m_icodes[0]->ll()->src().off == m_icodes[1]->ll()->dst.off))
+            if ((m_icodes[0]->ll()->src().off == m_icodes[1]->ll()->m_dst.off))
             {
                 return true;
             }
             break;
         case 3: // indexed
             printf("Untested idiom18 type: indexed\n");
-            if ((m_icodes[0]->ll()->src() == m_icodes[1]->ll()->dst))
+            if ((m_icodes[0]->ll()->src() == m_icodes[1]->ll()->m_dst))
             {
                 return true;
             }
@@ -200,15 +200,15 @@ bool Idiom19::match(iICODE 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 */
+    if (m_icodes[0]->ll()->m_dst.regi == 0)	/* global variable */
         /* not supported yet */ ;
-    else if ( m_icodes[0]->ll()->dst.isReg() ) /* register */
+    else if ( m_icodes[0]->ll()->m_dst.isReg() ) /* register */
     {
         //        if (((picode->ll()->dst.regi == rSI) && (pproc->flg & SI_REGVAR)) ||
         //            ((picode->ll()->dst.regi == rDI) && (pproc->flg & DI_REGVAR)))
         return true;
     }
-    else if (m_icodes[0]->ll()->dst.off)		/* stack variable */
+    else if (m_icodes[0]->ll()->m_dst.off)		/* stack variable */
     {
         return true;
     }
@@ -257,12 +257,12 @@ bool Idiom20::match(iICODE picode)
     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()))
+    if( not m_icodes[1]->ll()->matchWithRegDst(iMOV) )
         return false;
 
     m_is_dec = m_icodes[0]->ll()->match(iDEC) ? PRE_DEC : PRE_INC;
 
-    LLOperand &ll_dest(m_icodes[0]->ll()->dst);
+    const LLOperand &ll_dest(m_icodes[0]->ll()->m_dst);
     /* Get variable */
     if (ll_dest.regi == 0)	/* global variable */
     {
@@ -284,7 +284,7 @@ bool Idiom20::match(iICODE picode)
         type = 3;
         /* not supported yet */ ;
     }
-    regi = m_icodes[1]->ll()->dst.regi;
+    regi = m_icodes[1]->ll()->m_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())
     {

+ 2 - 2
src/idioms/call_idioms.cpp

@@ -77,13 +77,13 @@ bool Idiom17::match(iICODE picode)
     if (m_icodes[1]->ll()->match(iPOP))
     {
         int i=0;
-        regi = m_icodes[1]->ll()->dst.regi;
+        regi = m_icodes[1]->ll()->m_dst.regi;
         if ((regi >= rAX) && (regi <= rBX))
             i++;
 
         while (picode != m_end && picode->ll()->match(iPOP))
         {
-            if (picode->ll()->dst.regi != regi)
+            if (picode->ll()->m_dst.regi != regi)
                 break;
             i++;
             m_icodes.push_back(picode++);

+ 8 - 6
src/idioms/mov_idioms.cpp

@@ -28,13 +28,13 @@ bool Idiom14::match(iICODE pIcode)
     m_icodes[0]=pIcode++;
     m_icodes[1]=pIcode++;
     /* Check for regL */
-    m_regL = m_icodes[0]->ll()->dst.regi;
+    m_regL = m_icodes[0]->ll()->m_dst.regi;
     if (not m_icodes[0]->ll()->testFlags(I) && ((m_regL == rAX) || (m_regL ==rBX)))
     {
         /* Check for XOR regH, regH */
         if (m_icodes[1]->ll()->match(iXOR) && not m_icodes[1]->ll()->testFlags(I))
         {
-            m_regH = m_icodes[1]->ll()->dst.regi;
+            m_regH = m_icodes[1]->ll()->m_dst.regi;
             if (m_regH == m_icodes[1]->ll()->src().getReg2())
             {
                 if ((m_regL == rAX) && (m_regH == rDX))
@@ -52,7 +52,7 @@ int Idiom14::action()
     AstIdent *lhs;
     Expr *rhs;
 
-    idx = m_func->localId.newLongReg (TYPE_LONG_SIGN, m_regH, m_regL, m_icodes[0]);
+    idx = m_func->localId.newLongReg (TYPE_LONG_SIGN, LONGID_TYPE(m_regH,m_regL), m_icodes[0]);
     lhs = AstIdent::LongIdx (idx);
     m_icodes[0]->setRegDU( m_regH, eDEF);
     rhs = AstIdent::id (*m_icodes[0]->ll(), SRC, m_func, m_icodes[0], *m_icodes[0], NONE);
@@ -82,13 +82,13 @@ bool Idiom13::match(iICODE pIcode)
     eReg regi;
 
     /* Check for regL */
-    regi = m_icodes[0]->ll()->dst.regi;
+    regi = m_icodes[0]->ll()->m_dst.regi;
     if (not m_icodes[0]->ll()->testFlags(I) && (regi >= rAL) && (regi <= rBH))
     {
         /* Check for MOV regH, 0 */
         if (m_icodes[1]->ll()->match(iMOV,I) && (m_icodes[1]->ll()->src().getImm2() == 0))
         {
-            if (m_icodes[1]->ll()->dst.regi == (regi + 4)) //WARNING: based on distance between AH-AL,BH-BL etc.
+            if (m_icodes[1]->ll()->m_dst.regi == (regi + 4)) //WARNING: based on distance between AH-AL,BH-BL etc.
             {
                 m_loaded_reg=(eReg)(regi - rAL + rAX);
                 return true;
@@ -102,9 +102,11 @@ int Idiom13::action()
 {
     AstIdent *lhs;
     Expr *rhs;
+    eReg regi = m_icodes[0]->ll()->m_dst.regi;
+    m_icodes[0]->du1.removeDef(regi);
+    //m_icodes[0]->du1.numRegsDef--;   	/* prev uint8_t reg def */
     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);
     m_icodes[0]->setAsgn(lhs, rhs);
     m_icodes[1]->invalidate();

+ 7 - 7
src/idioms/neg_idioms.cpp

@@ -32,17 +32,17 @@ bool Idiom11::match (iICODE picode)
     switch (type)
     {
         case GLOB_VAR:
-            if ((m_icodes[2]->ll()->dst.segValue == m_icodes[0]->ll()->dst.segValue) &&
-                    (m_icodes[2]->ll()->dst.off == m_icodes[0]->ll()->dst.off))
+            if ((m_icodes[2]->ll()->m_dst.segValue == m_icodes[0]->ll()->m_dst.segValue) &&
+                    (m_icodes[2]->ll()->m_dst.off == m_icodes[0]->ll()->m_dst.off))
                 return true;
             break;
         case REGISTER:
-            if (m_icodes[2]->ll()->dst.regi == m_icodes[0]->ll()->dst.regi)
+            if (m_icodes[2]->ll()->m_dst.regi == m_icodes[0]->ll()->m_dst.regi)
                 return true;
             break;
         case PARAM:
         case LOCAL_VAR:
-            if (m_icodes[2]->ll()->dst.off == m_icodes[0]->ll()->dst.off)
+            if (m_icodes[2]->ll()->m_dst.off == m_icodes[0]->ll()->m_dst.off)
                 return true;
             break;
         default:
@@ -82,11 +82,11 @@ bool Idiom16::match (iICODE picode)
     for(int i=0; i<3; ++i)
         m_icodes[i]=picode++;
 
-    uint8_t regi = m_icodes[0]->ll()->dst.regi;
+    uint8_t regi = m_icodes[0]->ll()->m_dst.regi;
     if ((regi >= rAX) && (regi < INDEX_BX_SI))
     {
         if (m_icodes[1]->ll()->match(iSBB) && m_icodes[2]->ll()->match(iINC))
-            if ((m_icodes[1]->ll()->dst.regi == (m_icodes[1]->ll()->src().getReg2())) &&
+            if ((m_icodes[1]->ll()->m_dst.regi == (m_icodes[1]->ll()->src().getReg2())) &&
                     m_icodes[1]->ll()->match((eReg)regi) &&
                     m_icodes[2]->ll()->match((eReg)regi))
                 return true;
@@ -97,7 +97,7 @@ int Idiom16::action()
 {
     AstIdent *lhs;
     Expr *rhs;
-    lhs = new RegisterNode(m_icodes[0]->ll()->dst.regi, m_icodes[0]->ll()->getFlag(),&m_func->localId);
+    lhs = new RegisterNode(m_icodes[0]->ll()->m_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();

+ 11 - 11
src/idioms/shift_idioms.cpp

@@ -31,9 +31,9 @@ int Idiom8::action()
     AstIdent *lhs;
     Expr *expr;
     eReg regH,regL;
-    regH=m_icodes[0]->ll()->dst.regi;
-    regL=m_icodes[1]->ll()->dst.regi;
-    idx = m_func->localId.newLongReg (TYPE_LONG_SIGN, regH, regL, m_icodes[0]);
+    regH=m_icodes[0]->ll()->m_dst.regi;
+    regL=m_icodes[1]->ll()->m_dst.regi;
+    idx = m_func->localId.newLongReg (TYPE_LONG_SIGN, LONGID_TYPE(regH,regL), m_icodes[0]);
     lhs = AstIdent::LongIdx (idx);
     m_icodes[0]->setRegDU( regL, USE_DEF);
 
@@ -65,7 +65,7 @@ bool Idiom15::match(iICODE pIcode)
     if (not pIcode->ll()->testFlags(I) or (pIcode->ll()->src().getImm2() != 1))
         return false;
     m_icodes.clear();
-    regi = pIcode->ll()->dst.regi;
+    regi = pIcode->ll()->m_dst.regi;
     m_icodes.push_back(pIcode++);
     while(  (pIcode!=m_end) and
             pIcode->ll()->match(iSHL,(eReg)regi,I) and
@@ -81,7 +81,7 @@ int Idiom15::action()
     AstIdent *lhs;
 
     Expr *rhs,*_exp;
-    lhs = new RegisterNode(m_icodes[0]->ll()->dst.regi,
+    lhs = new RegisterNode(m_icodes[0]->ll()->m_dst.regi,
                             m_icodes[0]->ll()->getFlag() & NO_SRC_B,
                              &m_func->localId);
     rhs = new Constant(m_icodes.size(), 2);
@@ -122,10 +122,10 @@ int Idiom12::action()
     AstIdent *lhs;
 
     eReg regH,regL;
-    regL=m_icodes[0]->ll()->dst.regi;
-    regH=m_icodes[1]->ll()->dst.regi;
+    regL=m_icodes[0]->ll()->m_dst.regi;
+    regH=m_icodes[1]->ll()->m_dst.regi;
 
-    idx = m_func->localId.newLongReg (TYPE_LONG_UNSIGN, regH, regL,m_icodes[0]);
+    idx = m_func->localId.newLongReg (TYPE_LONG_UNSIGN, LONGID_TYPE(regH,regL),m_icodes[0]);
     lhs = AstIdent::LongIdx (idx);
     m_icodes[0]->setRegDU( regH, USE_DEF);
     expr = new BinaryOperator(SHL,lhs, new Constant(1, 2));
@@ -161,9 +161,9 @@ int Idiom9::action()
     AstIdent *lhs;
     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]);
+    regL=m_icodes[1]->ll()->m_dst.regi;
+    regH=m_icodes[0]->ll()->m_dst.regi;
+    idx = m_func->localId.newLongReg (TYPE_LONG_UNSIGN,LONGID_TYPE(regH,regL),m_icodes[0]);
     lhs = AstIdent::LongIdx (idx);
     m_icodes[0]->setRegDU(regL, USE_DEF);
     expr = new BinaryOperator(SHR,lhs, new Constant(1, 2));

+ 8 - 7
src/idioms/xor_idioms.cpp

@@ -26,7 +26,7 @@ bool Idiom21::match (iICODE picode)
     if (not m_icodes[1]->ll()->testFlags(I))
         return false;
 
-    dst = &m_icodes[0]->ll()->dst;
+    dst = &m_icodes[0]->ll()->m_dst;
     src = &m_icodes[0]->ll()->src();
     if ((dst->regi == src->getReg2()) && (dst->getReg2() > 0) && (dst->getReg2() < INDEX_BX_SI))
     {
@@ -45,7 +45,7 @@ int Idiom21::action()
     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[0]->du.use.reset();		/* clear register used in iXOR */
     m_icodes[1]->invalidate();
     return 2;
 }
@@ -63,7 +63,7 @@ bool Idiom7::match(iICODE picode)
         return false;
     const LLOperand *dst, *src;
     m_icode=picode;
-    dst = &picode->ll()->dst;
+    dst = &picode->ll()->m_dst;
     src = &picode->ll()->src();
     if (dst->regi == 0)                 /* global variable */
     {
@@ -87,7 +87,7 @@ int Idiom7::action()
     Expr *lhs;
     lhs = AstIdent::id (*m_icode->ll(), DST, m_func, m_icode, *m_icode, NONE);
     m_icode->setAsgn(dynamic_cast<AstIdent *>(lhs), new Constant(0, 2));
-    m_icode->du.use = 0;    /* clear register used in iXOR */
+    m_icode->du.use.reset();    /* clear register used in iXOR */
     m_icode->ll()->setFlags(I);
     return 1;
 }
@@ -116,7 +116,7 @@ bool Idiom10::match(iICODE pIcode)
     /* Check OR reg, reg */
     if (not m_icodes[0]->ll()->testFlags(I)  &&
             m_icodes[0]->ll()->src().isReg() &&
-            (m_icodes[0]->ll()->src().getReg2() == m_icodes[0]->ll()->dst.getReg2()))
+            (m_icodes[0]->ll()->src().getReg2() == m_icodes[0]->ll()->m_dst.getReg2()))
         if (m_icodes[1]->ll()->match(iJNE)) //.conditionalJump()
         {
             return true;
@@ -128,8 +128,9 @@ int Idiom10::action()
 {
     m_icodes[0]->ll()->set(iCMP,I);
     m_icodes[0]->ll()->replaceSrc(LLOperand::CreateImm2(0));
-    m_icodes[0]->du.def = 0;
-    m_icodes[0]->du1.numRegsDef = 0;
+    m_icodes[0]->du.def.reset();  //TODO: this defines FLAGS
+    m_icodes[0]->du1.clearAllDefs();
+    //m_icodes[0]->du1.numRegsDef = 0;
     return 2;
 
 }

+ 76 - 37
src/locident.cpp

@@ -10,10 +10,9 @@
 #include "dcc.h"
 bool LONGID_TYPE::srcDstRegMatch(iICODE a, iICODE b) const
 {
-    return (a->ll()->src().getReg2()==l) and (b->ll()->dst.getReg2()==h);
+    return (a->ll()->src().getReg2()==m_l) and (b->ll()->m_dst.getReg2()==m_h);
 }
 
-
 ID::ID() : type(TYPE_UNKNOWN),illegal(false),loc(STK_FRAME),hasMacro(false)
 {
     macro[0]=0;
@@ -24,6 +23,32 @@ ID::ID(hlType t, frameType f) : type(t),illegal(false),hasMacro(false)
     macro[0]=0;
     memset(&id,0,sizeof(id));
     loc=f;
+    assert(not ((t==TYPE_LONG_SIGN)||(t==TYPE_LONG_UNSIGN)));
+}
+ID::ID(hlType t,const LONGID_TYPE &s) : type(t),illegal(false),hasMacro(false)
+{
+    macro[0]=0;
+    memset(&id,0,sizeof(id));
+    loc=REG_FRAME;
+    m_longId = s;
+    assert((t==TYPE_LONG_SIGN)||(t==TYPE_LONG_UNSIGN));
+}
+ID::ID(hlType t,const LONG_STKID_TYPE &s) : type(t),illegal(false),hasMacro(false)
+{
+    macro[0]=0;
+    memset(&id,0,sizeof(id));
+    loc=STK_FRAME;
+    id.longStkId = s;
+    assert((t==TYPE_LONG_SIGN)||(t==TYPE_LONG_UNSIGN));
+}
+
+ID::ID(hlType t, const LONGGLB_TYPE &s)
+{
+    macro[0]=0;
+    memset(&id,0,sizeof(id));
+    loc=GLB_FRAME;
+    id.longGlb = s;
+    assert((t==TYPE_LONG_SIGN)||(t==TYPE_LONG_UNSIGN));
 }
 
 
@@ -142,17 +167,22 @@ int LOCAL_ID::newIntIdx(int16_t seg, int16_t off, eReg regi, hlType t)
 /* Checks if the entry exists in the locSym, if so, returns the idx to this
  * entry; otherwise creates a new register identifier node of type
  * TYPE_LONG_(UN)SIGN and returns the index to this new entry.  */
-int LOCAL_ID::newLongReg(hlType t, eReg regH, eReg regL, iICODE ix_)
+int LOCAL_ID::newLongReg(hlType t, const LONGID_TYPE &longT, iICODE ix_)
 {
+    eReg regH,regL;
+    regL = longT.l();
+    regH = longT.h();
     size_t idx;
     //iICODE ix_;
     /* Check for entry in the table */
     for (idx = 0; idx < id_arr.size(); idx++)
     {
         ID &entry(id_arr[idx]);
+        if(!entry.isLong() || (entry.loc != REG_FRAME))
+            continue;
         if (/*(locSym->id[idx].type == t) &&   Not checking type */
-            (entry.id.longId.h == regH) &&
-            (entry.id.longId.l == regL))
+                (entry.longId().h() == regH) &&
+                (entry.longId().l() == regL))
         {
             /* Check for occurrence in the list */
             if (entry.idx.inList(ix_))
@@ -167,12 +197,9 @@ int LOCAL_ID::newLongReg(hlType t, eReg regH, eReg regL, iICODE ix_)
     }
 
     /* Not in the table, create new identifier */
-    newIdent (t, REG_FRAME);
-    id_arr[id_arr.size()-1].idx.push_back(ix_);
-    idx = id_arr.size() - 1;
-    id_arr[idx].id.longId.h = regH;
-    id_arr[idx].id.longId.l = regL;
-    return (idx);
+    id_arr.push_back(ID(t, LONGID_TYPE(regH,regL)));
+    id_arr.back().idx.push_back(ix_);
+    return (id_arr.size() - 1);
 }
 /* Returns an identifier conditional expression node of type TYPE_LONG or
  * TYPE_WORD_SIGN	*/
@@ -199,12 +226,9 @@ int LOCAL_ID::newLongGlb(int16_t seg, int16_t offH, int16_t offL,hlType t)
     }
 
     /* Not in the table, create new identifier */
-    newIdent (t, GLB_FRAME);
-    idx = id_arr.size() - 1;
-    id_arr[idx].id.longGlb.seg = seg;
-    id_arr[idx].id.longGlb.offH = offH;
-    id_arr[idx].id.longGlb.offL = offL;
-    return (idx);
+    id_arr.push_back(ID(t, LONGGLB_TYPE(seg,offH,offL)));
+    return (id_arr.size() - 1);
+
 }
 
 
@@ -246,9 +270,11 @@ int LOCAL_ID::newLongStk(hlType t, int offH, int offL)
     /* Check for entry in the table */
     for (idx = 0; idx < id_arr.size(); idx++)
     {
+        if(id_arr[idx].loc!=STK_FRAME)
+            continue;
         if ((id_arr[idx].type == t) &&
-            (id_arr[idx].id.longStkId.offH == offH) &&
-            (id_arr[idx].id.longStkId.offL == offL))
+            (id_arr[idx].longStkId().offH == offH) &&
+            (id_arr[idx].longStkId().offL == offL))
             return (idx);
     }
 
@@ -257,11 +283,8 @@ int LOCAL_ID::newLongStk(hlType t, int offH, int offL)
     flagByteWordId (offL);
 
     /* Create new identifier */
-    newIdent (t, STK_FRAME);
-    idx = id_arr.size() - 1;
-    id_arr[idx].id.longStkId.offH = offH;
-    id_arr[idx].id.longStkId.offL = offL;
-    return (idx);
+    id_arr.push_back(ID(t,LONG_STKID_TYPE(offH,offL)));
+    return (id_arr.size() - 1);
 }
 
 
@@ -289,7 +312,7 @@ int LOCAL_ID::newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix,operDu du, L
 
     else if (pmL->regi < INDEX_BX_SI)                     /* register */
     {
-        idx = newLongReg(TYPE_LONG_SIGN, pmH->regi, pmL->regi, ix);
+        idx = newLongReg(TYPE_LONG_SIGN, LONGID_TYPE(pmH->regi, pmL->regi), ix);
         if (f == HIGH_FIRST)
             pIcode->setRegDU( pmL->regi, du);   /* low part */
         else
@@ -325,15 +348,31 @@ int LOCAL_ID::newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix,operDu du, L
  *            idx       : idx into icode array
  *            pProc     : ptr to current procedure record
  *            rhs, lhs  : return expressions if successful. */
-boolT checkLongEq (LONG_STKID_TYPE longId, iICODE pIcode, int i, Function * pProc, Assignment &asgn, LLInst &atOffset)
+bool checkLongEq (LONG_STKID_TYPE longId, iICODE pIcode, int i, Function * pProc, Assignment &asgn, LLInst &atOffset)
 {
     /* pointers to LOW_LEVEL icodes */
     const LLOperand *pmHdst, *pmLdst, *pmHsrc, *pmLsrc;
 
-    pmHdst = &pIcode->ll()->dst;
-    pmLdst = &atOffset.dst;
+    pmHdst = &pIcode->ll()->m_dst;
+    pmLdst = &atOffset.m_dst;
     pmHsrc = &pIcode->ll()->src();
     pmLsrc = &atOffset.src();
+//    if ((longId.offH == pmHsrc->off) && (longId.offL == pmLsrc->off))
+//    {
+//        asgn.lhs = AstIdent::LongIdx (i);
+
+//        if ( not pIcode->ll()->testFlags(NO_SRC) )
+//        {
+//            asgn.rhs = AstIdent::Long (&pProc->localId, SRC, pIcode, HIGH_FIRST, pIcode, eUSE, atOffset);
+//        }
+//        return true;
+//    }
+//    else if ((longId.offH == pmHdst->off) && (longId.offL == pmLdst->off))
+//    {
+//        asgn.lhs = AstIdent::Long (&pProc->localId, DST, pIcode, HIGH_FIRST, pIcode,eDEF, atOffset);
+//        asgn.rhs = AstIdent::LongIdx (i);
+//        return true;
+//    }
 
     if ((longId.offH == pmHdst->off) && (longId.offL == pmLdst->off))
     {
@@ -364,18 +403,18 @@ boolT checkLongEq (LONG_STKID_TYPE longId, iICODE pIcode, int i, Function * pPro
  *            idx       : idx into icode array
  *            pProc     : ptr to current procedure record
  *            rhs, lhs  : return expressions if successful. */
-boolT checkLongRegEq (LONGID_TYPE longId, iICODE pIcode, int i,
+bool checkLongRegEq (LONGID_TYPE longId, iICODE pIcode, int i,
                       Function * pProc, Assignment &asgn, LLInst &atOffset)
 {
     /* pointers to LOW_LEVEL icodes */
     const LLOperand *pmHdst, *pmLdst, *pmHsrc, *pmLsrc;
 
-    pmHdst = &pIcode->ll()->dst;
-    pmLdst = &atOffset.dst;
+    pmHdst = &pIcode->ll()->m_dst;
+    pmLdst = &atOffset.m_dst;
     pmHsrc = &pIcode->ll()->src();
     pmLsrc = &atOffset.src();
 
-    if ((longId.h == pmHdst->regi) && (longId.l == pmLdst->regi))
+    if ((longId.h() == pmHdst->regi) && (longId.l() == pmLdst->regi))
     {
         asgn.lhs = AstIdent::LongIdx (i);
         if ( not pIcode->ll()->testFlags(NO_SRC) )
@@ -384,7 +423,7 @@ boolT checkLongRegEq (LONGID_TYPE longId, iICODE pIcode, int i,
         }
         return true;
     }
-    else if ((longId.h == pmHsrc->regi) && (longId.l == pmLsrc->regi))
+    else if ((longId.h() == pmHsrc->regi) && (longId.l() == pmLsrc->regi))
     {
         asgn.lhs = AstIdent::Long (&pProc->localId, DST, pIcode, HIGH_FIRST, pIcode, eDEF, atOffset);
         asgn.rhs = AstIdent::LongIdx (i);
@@ -406,10 +445,10 @@ eReg otherLongRegi (eReg regi, int idx, LOCAL_ID *locTbl)
     if ((id->loc == REG_FRAME) && ((id->type == TYPE_LONG_SIGN) ||
         (id->type == TYPE_LONG_UNSIGN)))
     {
-        if (id->id.longId.h == regi)
-            return (id->id.longId.l);
-        else if (id->id.longId.l == regi)
-            return (id->id.longId.h);
+        if (id->longId().h() == regi)
+            return (id->longId().l());
+        else if (id->longId().l() == regi)
+            return (id->longId().h());
     }
     return rUNDEF;	// Cristina: please check this!
 }

+ 11 - 1
src/machine_x86.cpp

@@ -1,5 +1,6 @@
 #include <cassert>
 #include "machine_x86.h"
+#include "icode.h"
 // Index registers **** temp solution
 static const std::string regNames[] = {
     "undef",
@@ -8,7 +9,7 @@ static const std::string regNames[] = {
     "es", "cs", "ss", "ds",
     "al", "cl", "dl", "bl",
     "ah", "ch", "dh", "bh",
-    "tmp",
+    "tmp","tmp2",
     "bx+si", "bx+di", "bp+si", "bp+di",
     "si", "di", "bp", "bx"
 };
@@ -132,3 +133,12 @@ eReg Machine_X86::compositeParent(eReg reg)
     }
     return rUNDEF;
 }
+void Machine_X86::writeRegVector (std::ostream &ostr,const LivenessSet &regi)
+{
+    int j;
+    for (j = rAX; j < INDEX_BX_SI; j++)
+    {
+        if (regi.testReg(j))
+            ostr << regName(eReg(j))<<" ";
+    }
+}

+ 59 - 67
src/parser.cpp

@@ -146,8 +146,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
             eIcode = ICODE();
 
             eIcode.type = LOW_LEVEL;
-            eIcode.ll()->set(iMOV,0);
-            eIcode.ll()->replaceDst(rTMP);
+            eIcode.ll()->set(iMOV,0,rTMP);
             if (ll->testFlags(B) )
             {
                 eIcode.ll()->setFlags( B );
@@ -171,10 +170,9 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
             /* iMOD */
             eIcode = ICODE();
             eIcode.type = LOW_LEVEL;
-            eIcode.ll()->set(iMOD,0);
+            eIcode.ll()->set(iMOD,ll->getFlag() | SYNTHETIC  | IM_TMP_DST);
             eIcode.ll()->replaceSrc(_Icode.ll()->src());
             eIcode.du = _Icode.du;
-            eIcode.ll()->setFlags( ( ll->getFlag() | SYNTHETIC  | IM_TMP_DST) );
             eIcode.ll()->label = SynthLab++;
             pIcode = Icode.addIcode(&eIcode);
         }
@@ -183,9 +181,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
             /* MOV rTMP, regDst */
             eIcode = ICODE();
             eIcode.type = LOW_LEVEL;
-            eIcode.ll()->set(iMOV,SYNTHETIC);
-            eIcode.ll()->replaceDst(LLOperand::CreateReg2(rTMP));
-            eIcode.ll()->replaceSrc(_Icode.ll()->dst);
+            eIcode.ll()->set(iMOV,SYNTHETIC,rTMP,_Icode.ll()->m_dst);
             eIcode.setRegDU( rTMP, eDEF);
             if(eIcode.ll()->src().getReg2())
             {
@@ -207,11 +203,11 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
             eIcode.type = LOW_LEVEL;
             eIcode.ll()->set(iMOV,SYNTHETIC);
             eIcode.ll()->replaceDst(ll->src());
-            if(eIcode.ll()->dst.regi)
+            if(eIcode.ll()->m_dst.regi)
             {
-                if((eIcode.ll()->dst.regi>=rAL) && (eIcode.ll()->dst.regi<=rBH))
+                if((eIcode.ll()->m_dst.regi>=rAL) && (eIcode.ll()->m_dst.regi<=rBH))
                     eIcode.ll()->setFlags( B );
-                eIcode.setRegDU( eIcode.ll()->dst.regi, eDEF);
+                eIcode.setRegDU( eIcode.ll()->m_dst.regi, eDEF);
             }
             eIcode.ll()->replaceSrc(rTMP);
             eIcode.setRegDU( rTMP, eUSE);
@@ -246,7 +242,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
                     if (ll->match(iJA) || ll->match(iJBE) )
                         pstate->JCond.immed++;
                     if (ll->getOpcode() == iJAE || ll->getOpcode() == iJA)
-                        pstate->JCond.regi = prev.ll()->dst.regi;
+                        pstate->JCond.regi = prev.ll()->m_dst.regi;
                     fBranch = (bool)
                               (ll->getOpcode() == iJB || ll->getOpcode() == iJBE);
                 }
@@ -258,7 +254,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
 
                 if (fBranch)                /* Do branching code */
                 {
-                    pstate->JCond.regi = prev.ll()->dst.regi;
+                    pstate->JCond.regi = prev.ll()->m_dst.regi;
                 }
                 /* Next icode. Note: not the same as GetLastIcode() because of the call
                                 to FollowCtrl() */
@@ -297,7 +293,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
                     int size;
 
                     /* Save function number */
-                    Icode.back().ll()->dst.off = (int16_t)funcNum;
+                    Icode.back().ll()->m_dst.off = (int16_t)funcNum;
                     //Icode.GetIcode(Icode.GetNumIcodes() - 1)->
 
                     /* Program termination: int21h, fn 00h, 31h, 4Ch */
@@ -318,7 +314,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
                 }
                 else if ((ll->src().getImm2() == 0x2F) && (pstate->f[rAH]))
                 {
-                    Icode.back().ll()->dst.off = pstate->r[rAH];
+                    Icode.back().ll()->m_dst.off = pstate->r[rAH];
                 }
                 else    /* Program termination: int20h, int27h */
                     done = (boolT)(ll->src().getImm2() == 0x20 ||
@@ -337,7 +333,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
             break; **** HERE ***/
 
             case iSHL:
-                if (pstate->JCond.regi == ll->dst.regi)
+                if (pstate->JCond.regi == ll->m_dst.regi)
                 {
                     if ((ll->testFlags(I)) && ll->src().getImm2() == 1)
                         pstate->JCond.immed *= 2;
@@ -348,7 +344,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
 
             case iLEA:
                 if (ll->src().getReg2()== rUNDEF)      /* direct mem offset */
-                    pstate->setState( ll->dst.getReg2(), ll->src().off);
+                    pstate->setState( ll->m_dst.getReg2(), ll->src().off);
                 break;
 
             case iLDS: case iLES:
@@ -358,7 +354,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
                     offset = LH(&prog.image()[psym->label]);
                     pstate->setState( (ll->getOpcode() == iLDS)? rDS: rES,
                                       LH(&prog.image()[psym->label + 2]));
-                    pstate->setState( ll->dst.regi, (int16_t)offset);
+                    pstate->setState( ll->m_dst.regi, (int16_t)offset);
                     psym->type = TYPE_PTR;
                 }
                 break;
@@ -564,7 +560,7 @@ boolT Function::process_CALL (ICODE & pIcode, CALL_GRAPH * pcallGraph, STATE *ps
     {
         /* Not immediate, i.e. indirect call */
 
-        if (pIcode.ll()->dst.regi && (!option.Calls))
+        if (pIcode.ll()->m_dst.regi && (!option.Calls))
         {
             /* We have not set the brave option to attempt to follow
                 the execution path through register indirect calls.
@@ -579,25 +575,25 @@ boolT Function::process_CALL (ICODE & pIcode, CALL_GRAPH * pcallGraph, STATE *ps
                         es:0 where es:0 is the start of the image. This is
                         usually wrong! Consider also CALL [BP+0E] in which the
                         segment for the pointer is in SS! - Mike */
-        if(pIcode.ll()->dst.isReg())
+        if(pIcode.ll()->m_dst.isReg())
         {
-            if( not  pstate->isKnown(pIcode.ll()->dst.regi)
+            if( not  pstate->isKnown(pIcode.ll()->m_dst.regi)
                     or
-                    not  pstate->isKnown(pIcode.ll()->dst.seg)
+                    not  pstate->isKnown(pIcode.ll()->m_dst.seg)
                     )
             {
-                fprintf(stderr,"Indirect call with unkown register values\n");
+                fprintf(stderr,"Indirect call with unknown register values\n");
                 return false;
             }
-            off = pstate->r[pIcode.ll()->dst.seg];
+            off = pstate->r[pIcode.ll()->m_dst.seg];
             off <<=4;
-            off += pstate->r[pIcode.ll()->dst.regi];
+            off += pstate->r[pIcode.ll()->m_dst.regi];
 
         }
         else
         {
-            off = (uint32_t)(uint16_t)pIcode.ll()->dst.off +
-                  ((uint32_t)(uint16_t)pIcode.ll()->dst.segValue << 4);
+            off = (uint32_t)(uint16_t)pIcode.ll()->m_dst.off +
+                  ((uint32_t)(uint16_t)pIcode.ll()->m_dst.segValue << 4);
         }
 
         /* Address of function is given by 4 (CALLF) or 2 (CALL) bytes at
@@ -684,7 +680,7 @@ static void process_MOV(LLInst & ll, STATE * pstate)
 {
     PROG &prog(Project::get()->prog);
     SYM *  psym, *psym2;        /* Pointer to symbol in global symbol table */
-    uint8_t  dstReg = ll.dst.regi;
+    uint8_t  dstReg = ll.m_dst.regi;
     uint8_t  srcReg = ll.src().regi;
     if (dstReg > 0 && dstReg < INDEX_BX_SI)
     {
@@ -709,7 +705,7 @@ static void process_MOV(LLInst & ll, STATE * pstate)
         int size=2;
         if((ll.src().regi>=rAL)&&(ll.src().regi<=rBH))
             size=1;
-        psym = lookupAddr (&ll.dst, pstate, size, eDEF);
+        psym = lookupAddr (&ll.m_dst, pstate, size, eDEF);
         if (psym && ! (psym->duVal.val))      /* no initial value yet */
         {
             if (ll.testFlags(I))   /* immediate */
@@ -898,19 +894,6 @@ static void setBits(int16_t type, uint32_t start, uint32_t len)
     }
 }
 
-/* DU bit definitions for each reg value - including index registers */
-LivenessSet duReg[] = { 0x00,
-                        //AH AL . . AX, BH
-                        0x11001, 0x22002, 0x44004, 0x88008, /* uint16_t regs    */
-                        0x10, 0x20, 0x40, 0x80,
-                        0x100, 0x200, 0x400, 0x800,         /* seg regs     */
-                        0x1000, 0x2000, 0x4000, 0x8000,     /* uint8_t regs    */
-                        0x10000, 0x20000, 0x40000, 0x80000,
-                        0x100000,                           /* tmp reg      */
-                        0x48, 0x88, 0x60, 0xA0,             /* index regs   */
-                        0x40, 0x80, 0x20, 0x08 };
-
-
 /* Checks which registers were used and updates the du.u flag.
  * Places local variables on the local symbol table.
  * Arguments: d     : SRC or DST icode operand
@@ -945,7 +928,7 @@ static void use (opLoc d, ICODE & pIcode, Function * pProc, STATE * pstate, int
                 if (pm->off > 0)    /* global indexed variable */
                     pProc->localId.newIntIdx(pm->segValue, pm->off, rBX,TYPE_WORD_SIGN);
             }
-            pIcode.du.use |= duReg[pm->regi];
+            pIcode.du.use.addReg(pm->regi);
         }
 
         else
@@ -963,7 +946,7 @@ static void use (opLoc d, ICODE & pIcode, Function * pProc, STATE * pstate, int
 
     /* Use of register */
     else if ((d == DST) || ((d == SRC) && (not pIcode.ll()->testFlags(I))))
-        pIcode.du.use |= duReg[pm->regi];
+        pIcode.du.use.addReg(pm->regi);
 }
 
 
@@ -1007,14 +990,15 @@ static void def (opLoc d, ICODE & pIcode, Function * pProc, STATE * pstate, int
                 if (pm->off > 0)        /* global var */
                     pProc->localId.newIntIdx(pm->segValue, pm->off, rBX,TYPE_WORD_SIGN);
             }
-            pIcode.du.use |= duReg[pm->regi];
+            pIcode.du.use.addReg(pm->regi);
         }
     }
     /* Definition of register */
     else if ((d == DST) || ((d == SRC) && (not pIcode.ll()->testFlags(I))))
     {
-        pIcode.du.def |= duReg[pm->regi];
-        pIcode.du1.numRegsDef++;
+        assert(not pIcode.ll()->match(iPUSH));
+        pIcode.du1.addDef(pm->regi);
+        pIcode.du.def.addReg(pm->regi);
     }
 }
 
@@ -1030,8 +1014,9 @@ static void use_def(opLoc d, ICODE & pIcode, Function * pProc, STATE * pstate, i
 
     if (pm->regi < INDEX_BX_SI)                   /* register */
     {
-        pIcode.du.def |= duReg[pm->regi];
-        pIcode.du1.numRegsDef++;
+        assert(not pIcode.ll()->match(iPUSH));
+        pIcode.du1.addDef(pm->regi);
+        pIcode.du.def.addReg(pm->regi);
     }
 }
 
@@ -1090,12 +1075,12 @@ void Function::process_operands(ICODE & pIcode,  STATE * pstate)
                 if (cb == 1)
                 {
                     pIcode.du.def.addReg(rAX);
-                    pIcode.du1.numRegsDef++;
+                    pIcode.du1.addDef(rAX);
                 }
                 else
                 {
                     pIcode.du.def.addReg(rAX).addReg(rDX);
-                    pIcode.du1.numRegsDef += 2;
+                    pIcode.du1.addDef(rAX).addDef(rDX);
                 }
             }
             else
@@ -1107,13 +1092,13 @@ void Function::process_operands(ICODE & pIcode,  STATE * pstate)
             if (cb == 1)                    /* uint8_t */
             {
                 pIcode.du.def.addReg(rAX);
-                pIcode.du1.numRegsDef++;
+                pIcode.du1.addDef(rAX);
                 pIcode.du.use.addReg(rAL);
             }
             else                            /* uint16_t */
             {
                 pIcode.du.def.addReg(rDX).addReg(rAX);
-                pIcode.du1.numRegsDef += 2;
+                pIcode.du1.addDef(rAX).addDef(rDX);
                 pIcode.du.use.addReg(rAX);
             }
             break;
@@ -1134,9 +1119,13 @@ void Function::process_operands(ICODE & pIcode,  STATE * pstate)
             break;
 
         case iLDS:  case iLES:
-            pIcode.du.def.addReg(((pIcode.ll()->getOpcode() == iLDS) ? rDS : rES));
-            pIcode.du1.numRegsDef++;
+		{
+			eReg r=((pIcode.ll()->getOpcode() == iLDS) ? rDS : rES);
+            pIcode.du.def.addReg(r);
+            pIcode.du1.addDef(r);
             cb = 4;
+            // fallthrough
+		}
         case iMOV:
             use(SRC, pIcode, this, pstate, cb);
             def(DST, pIcode, this, pstate, cb);
@@ -1161,27 +1150,27 @@ void Function::process_operands(ICODE & pIcode,  STATE * pstate)
 
         case iLOOP:  case iLOOPE:  case iLOOPNE:
             pIcode.du.def.addReg(rCX);
-            pIcode.du1.numRegsDef++;
+            pIcode.du1.addDef(rCX);
         case iJCXZ:
             pIcode.du.use.addReg(rCX);
             break;
 
         case iREPNE_CMPS: case iREPE_CMPS:  case iREP_MOVS:
             pIcode.du.addDefinedAndUsed(rCX);
-            pIcode.du1.numRegsDef++;
+            pIcode.du1.addDef(rCX);
         case iCMPS:  case iMOVS:
             pIcode.du.addDefinedAndUsed(rSI);
             pIcode.du.addDefinedAndUsed(rDI);
-            pIcode.du1.numRegsDef += 2;
+            pIcode.du1.addDef(rSI).addDef(rDI);
             pIcode.du.use.addReg(rES).addReg(sseg);
             break;
 
         case iREPNE_SCAS: case iREPE_SCAS:  case iREP_STOS:  case iREP_INS:
             pIcode.du.addDefinedAndUsed(rCX);
-            pIcode.du1.numRegsDef++;
+            pIcode.du1.addDef(rCX);
         case iSCAS:  case iSTOS:  case iINS:
             pIcode.du.def.addReg(rDI);
-            pIcode.du1.numRegsDef++;
+            pIcode.du1.addDef(rDI);
             if (pIcode.ll()->getOpcode() == iREP_INS || pIcode.ll()->getOpcode()== iINS)
             {
                 pIcode.du.use.addReg(rDI).addReg(rES).addReg(rDX);
@@ -1194,28 +1183,31 @@ void Function::process_operands(ICODE & pIcode,  STATE * pstate)
 
         case iREP_LODS:
             pIcode.du.addDefinedAndUsed(rCX);
-            pIcode.du1.numRegsDef++;
+            pIcode.du1.addDef(rCX);
         case iLODS:
+		{
+            eReg r = (cb==2)? rAX: rAL;
             pIcode.du.addDefinedAndUsed(rSI);
-            pIcode.du.def.addReg((cb==2)? rAX: rAL);
-            pIcode.du1.numRegsDef += 2;
+            pIcode.du1.addDef(rSI);
+            pIcode.du.def.addReg(r);
+            pIcode.du1.addDef(r);
             pIcode.du.use.addReg(sseg);
+		}
             break;
-
         case iREP_OUTS:
             pIcode.du.addDefinedAndUsed(rCX);
-            pIcode.du1.numRegsDef++;
+            pIcode.du1.addDef(rCX);
         case iOUTS:
             pIcode.du.addDefinedAndUsed(rSI);
-            pIcode.du1.numRegsDef++;
-            pIcode.du.use |= duReg[rDX] | duReg[sseg];
+            pIcode.du1.addDef(rSI);
+            pIcode.du.use.addReg(rDX).addReg(sseg);
             break;
 
         case iIN:  case iOUT:
             def(DST, pIcode, this, pstate, cb);
             if (! Imm)
             {
-                pIcode.du.use |= duReg[rDX];
+                pIcode.du.use.addReg(rDX);
             }
             break;
     }

+ 11 - 7
src/procs.cpp

@@ -97,7 +97,8 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
     bool regExist=false;
     condId type;
     Function * tproc;
-    eReg regL, regH;		/* Registers involved in arguments */
+    eReg regL = rUNDEF;
+    eReg regH;		/* Registers involved in arguments */
 
     /* Flag ticode as having register arguments */
     tproc = ticode->hl()->call.proc;
@@ -113,6 +114,7 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
     if (lhs_reg)
     {
         regL = id_arr[lhs_reg->regiIdx].id.regi;
+        assert(regL!=rUNDEF);
         if (regL < rAL)
             tidx = tproc->localId.newByteWordReg(TYPE_WORD_SIGN, regL);
         else
@@ -133,9 +135,10 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
     else if (type == LONG_VAR)
     {
         int longIdx = lhs->ident.idNode.longIdx;
-        regL = id_arr[longIdx].id.longId.l;
-        regH = id_arr[longIdx].id.longId.h;
-        tidx = tproc->localId.newLongReg(TYPE_LONG_SIGN, regH, regL, tproc->Icode.begin() /*0*/);
+        LONGID_TYPE regHL = id_arr[longIdx].longId();
+        regH=regHL.h();
+        regL=regHL.l();
+        tidx = tproc->localId.newLongReg(TYPE_LONG_SIGN, regHL, tproc->Icode.begin() /*0*/);
         /* Check if register argument already on the formal argument list */
         for(STKSYM &tgt_sym : *target_stackframe)
         {
@@ -175,6 +178,7 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
         {
             newsym.regs = AstIdent::LongIdx (tidx);
             newsym.type = TYPE_LONG_SIGN;
+            assert(regL!=rUNDEF);
             tproc->localId.id_arr[tidx].name = newsym.name;
             tproc->localId.propLongId (regL, regH, tproc->localId.id_arr[tidx].name.c_str());
         }
@@ -191,7 +195,7 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
     switch (type) {
         case REGISTER:
             id = &id_arr[lhs_reg->regiIdx];
-            picode->du.def &= maskDuReg[id->id.regi];
+            picode->du.def.clrReg(id->id.regi);
             if (id->id.regi < rAL)
                 newsym.type = TYPE_WORD_SIGN;
             else
@@ -199,8 +203,8 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
             break;
         case LONG_VAR:
             id = &id_arr[lhs->ident.idNode.longIdx];
-            picode->du.def &= maskDuReg[id->id.longId.h];
-            picode->du.def &= maskDuReg[id->id.longId.l];
+            picode->du.def.clrReg(id->longId().h());
+            picode->du.def.clrReg(id->longId().l());
             newsym.type = TYPE_LONG_SIGN;
             break;
         default:

+ 22 - 24
src/proplong.cpp

@@ -250,7 +250,7 @@ void Function::propLongStk (int i, const ID &pLocId)
             continue;
         if (pIcode->ll()->getOpcode() == next1->ll()->getOpcode())
         {
-            if (checkLongEq (pLocId.id.longStkId, pIcode, i, this, asgn, *next1->ll()) == true)
+            if (checkLongEq (pLocId.longStkId(), pIcode, i, this, asgn, *next1->ll()) == true)
             {
                 switch (pIcode->ll()->getOpcode())
                 {
@@ -290,7 +290,7 @@ void Function::propLongStk (int i, const ID &pLocId)
         /* Check long conditional (i.e. 2 CMPs and 3 branches */
         else if ((pIcode->ll()->getOpcode() == iCMP) && (isLong23 (pIcode->getParent(), l23, &arc)))
         {
-            if ( checkLongEq (pLocId.id.longStkId, pIcode, i, this, asgn, *l23->ll()) )
+            if ( checkLongEq (pLocId.longStkId(), pIcode, i, this, asgn, *l23->ll()) )
             {
                 advance(pIcode,longJCond23 (asgn, pIcode, arc, l23));
             }
@@ -300,7 +300,7 @@ void Function::propLongStk (int i, const ID &pLocId)
                  * 2 CMPs and 2 branches */
         else if ((pIcode->ll()->getOpcode() == iCMP) && isLong22 (pIcode, pEnd, l23))
         {
-            if ( checkLongEq (pLocId.id.longStkId, pIcode, i, this,asgn, *l23->ll()) )
+            if ( checkLongEq (pLocId.longStkId(), pIcode, i, this,asgn, *l23->ll()) )
             {
                 advance(pIcode,longJCond22 (asgn, pIcode,pEnd));
             }
@@ -329,9 +329,9 @@ int Function::findBackwarLongDefs(int loc_ident_idx, const ID &pLocId, iICODE be
         switch (icode.ll()->getOpcode())
         {
         case iMOV:
-            pmH = &icode.ll()->dst;
-            pmL = &next1->ll()->dst;
-            if ((pLocId.id.longId.h == pmH->regi) && (pLocId.id.longId.l == pmL->regi))
+            pmH = &icode.ll()->m_dst;
+            pmL = &next1->ll()->m_dst;
+            if ((pLocId.longId().h() == pmH->regi) && (pLocId.longId().l() == pmL->regi))
             {
                 localId.id_arr[loc_ident_idx].idx.push_back(pIcode);//idx-1//insert
                 icode.setRegDU( pmL->regi, eDEF);
@@ -344,9 +344,9 @@ int Function::findBackwarLongDefs(int loc_ident_idx, const ID &pLocId, iICODE be
             break;
 
         case iPOP:
-            pmH = &next1->ll()->dst;
-            pmL = &icode.ll()->dst;
-            if ((pLocId.id.longId.h == pmH->regi) && (pLocId.id.longId.l == pmL->regi))
+            pmH = &next1->ll()->m_dst;
+            pmL = &icode.ll()->m_dst;
+            if ((pLocId.longId().h() == pmH->regi) && (pLocId.longId().l() == pmL->regi))
             {
                 asgn.lhs = AstIdent::LongIdx (loc_ident_idx);
                 icode.setRegDU( pmH->regi, eDEF);
@@ -360,9 +360,9 @@ int Function::findBackwarLongDefs(int loc_ident_idx, const ID &pLocId, iICODE be
             //                /**** others missing ***/
 
         case iAND: case iOR: case iXOR:
-            pmL = &icode.ll()->dst;
-            pmH = &next1->ll()->dst;
-            if ((pLocId.id.longId.h == pmH->regi) && (pLocId.id.longId.l == pmL->regi))
+            pmL = &icode.ll()->m_dst;
+            pmH = &next1->ll()->m_dst;
+            if ((pLocId.longId().h() == pmH->regi) && (pLocId.longId().l() == pmL->regi))
             {
                 asgn.lhs = AstIdent::LongIdx (loc_ident_idx);
                 asgn.rhs = AstIdent::Long (&this->localId, SRC, pIcode, LOW_FIRST, pIcode, eUSE, *next1->ll());
@@ -407,12 +407,12 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be
             {
             case iMOV:
                 {
-                    const LONGID_TYPE &ref_long(pLocId.id.longId);
+                    const LONGID_TYPE &ref_long(pLocId.longId());
                     const LLOperand &src_op1(pIcode->ll()->src());
                     const LLOperand &src_op2(next1->ll()->src());
                     eReg srcReg1=src_op1.getReg2();
                     eReg nextReg2=src_op2.getReg2();
-                    if ((ref_long.h == srcReg1) && (ref_long.l == nextReg2))
+                    if ((ref_long.h() == srcReg1) && (ref_long.l() == nextReg2))
                     {
                         pIcode->setRegDU( nextReg2, eUSE);
 
@@ -428,11 +428,10 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be
 
             case iPUSH:
                 {
-                    const LONGID_TYPE &ref_long(pLocId.id.longId);
+                    const LONGID_TYPE &ref_long(pLocId.longId());
                     const LLOperand &src_op1(pIcode->ll()->src());
                     const LLOperand &src_op2(next1->ll()->src());
-                    if ((ref_long.h == src_op1.getReg2()) &&
-                            (ref_long.l == src_op2.getReg2()))
+                    if ((ref_long.h() == src_op1.getReg2()) && (ref_long.l() == src_op2.getReg2()))
                     {
                         asgn.rhs = AstIdent::LongIdx (loc_ident_idx);
                         pIcode->setRegDU( next1->ll()->src().getReg2(), eUSE);
@@ -446,10 +445,9 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be
                 /*** others missing ****/
 
             case iAND: case iOR: case iXOR:
-                pmL = &pIcode->ll()->dst;
-                pmH = &next1->ll()->dst;
-                if ((pLocId.id.longId.h == pmH->regi) &&
-                        (pLocId.id.longId.l == pmL->regi))
+                pmL = &pIcode->ll()->m_dst;
+                pmH = &next1->ll()->m_dst;
+                if ((pLocId.longId().h() == pmH->regi) && (pLocId.longId().l() == pmL->regi))
                 {
                     asgn.lhs = AstIdent::LongIdx (loc_ident_idx);
                     pIcode->setRegDU( pmH->regi, USE_DEF);
@@ -478,7 +476,7 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be
         /* Check long conditional (i.e. 2 CMPs and 3 branches */
         else if ((pIcode->ll()->getOpcode() == iCMP) && (isLong23 (pIcode->getParent(), long_loc, &arc)))
         {
-            if (checkLongRegEq (pLocId.id.longId, pIcode, loc_ident_idx, this, asgn, *long_loc->ll()))
+            if (checkLongRegEq (pLocId.longId(), pIcode, loc_ident_idx, this, asgn, *long_loc->ll()))
             {
                 // reduce the advance by 1 here (loop increases) ?
                 advance(pIcode,longJCond23 (asgn, pIcode, arc, long_loc));
@@ -489,7 +487,7 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be
              * 2 CMPs and 2 branches */
         else if (pIcode->ll()->match(iCMP) && (isLong22 (pIcode, pEnd, long_loc)))
         {
-            if (checkLongRegEq (pLocId.id.longId, pIcode, loc_ident_idx, this, asgn, *long_loc->ll()) )
+            if (checkLongRegEq (pLocId.longId(), pIcode, loc_ident_idx, this, asgn, *long_loc->ll()) )
             {
                 // TODO: verify that removing -1 does not change anything !
                 advance(pIcode,longJCond22 (asgn, pIcode,pEnd));
@@ -502,7 +500,7 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be
          * This is better code than HLI_JCOND (HI(regH:regL) | LO(regH:regL)) */
         else if (pIcode->ll()->match(iOR) && (next1 != pEnd) && (isJCond ((llIcode)next1->ll()->getOpcode())))
         {
-            if (pLocId.id.longId.srcDstRegMatch(pIcode,pIcode))
+            if (pLocId.longId().srcDstRegMatch(pIcode,pIcode))
             {
                 asgn.lhs = AstIdent::LongIdx (loc_ident_idx);
                 asgn.rhs = new Constant(0, 4);	/* long 0 */

+ 98 - 21
src/scanner.cpp

@@ -6,6 +6,8 @@
  ****************************************************************************/
 
 #include <cstring>
+#include <map>
+#include <string>
 #include "dcc.h"
 #include "scanner.h"
 #include "project.h"
@@ -411,33 +413,116 @@ int disassembleOneLibDisasm(uint32_t ip,x86_insn_t &l)
 }
 eReg convertRegister(const x86_reg_t &reg)
 {
+    if( (reg_pc==reg.type) || (0==reg.id))
+        return rUNDEF;
 
     eReg regmap[]={ rUNDEF,
                     rUNDEF,rUNDEF,rUNDEF,rUNDEF,   //eax ecx ebx edx
-                    rSP,rUNDEF,rUNDEF,rUNDEF,   //esp ebp esi edi
+                    rSP,rUNDEF,rUNDEF,rDI,   //esp ebp esi edi
                     rAX,rCX,rDX,rBX,
                     rSP,rBP,rSI,rDI,
                     rAL,rCL,rDL,rBL,
                     rAH,rCH,rDH,rBH
                   };
+    std::map<std::string,eReg> nameToEnum = {{"es",rES},{"ds",rDS},{"cs",rCS},{"ss",rSS}};
+    if(nameToEnum.find(reg.name)!=nameToEnum.end())
+        return nameToEnum[reg.name];
     assert(reg.id<sizeof(regmap)/sizeof(eReg));
     assert(regmap[reg.id]!=rUNDEF);
     return regmap[reg.id];
 }
+LLOperand convertExpression(const x86_ea_t &from)
+{
+    // BASE + Scale*Index + Disp
+    LLOperand res;
+    res.seg = rDS;
+    /*
+    INDEX_BX_SI = 22, // "bx+si"
+    INDEX_BX_DI, // "bx+di"
+    INDEX_BP_SI, // "bp+si"
+    INDEX_BP_DI, // "bp+di"
+    INDEX_SI, // "si"
+    INDEX_DI, // "di"
+    INDEX_BP, // "bp"
+    INDEX_BX, // "bx"
+    */
+    if(from.base.id)
+    {
+        eReg base_reg = convertRegister(from.base);
+        eReg index_reg = convertRegister(from.index);
+//        if(base_reg==rBX)
+        switch(base_reg)
+        {
+            case rDI:
+                res.regi = INDEX_DI; break;
+            case rBP:
+                res.seg=rSS;
+                switch(index_reg)
+                {
+                    case rDI:
+                        res.regi = INDEX_BP_DI; break;
+                    case rSI:
+                        res.regi = INDEX_BP_SI; break;
+                    case rUNDEF:
+                        res.regi = INDEX_BP; break;
+                    default:
+                        assert(false);
+                }
+                break;
+            case rBX:
+                switch(index_reg)
+                {
+                    case rDI:
+                        res.regi = INDEX_BX_DI; break;
+                    case rSI:
+                        res.regi = INDEX_BX_SI; break;
+                    case rUNDEF:
+                        res.regi = INDEX_BX; break;
+                    default:
+                        assert(false);
+                }
+                break;
+            default:
+                assert(false);
+        }
+        assert(index_reg==rUNDEF);
+    }
+    assert(from.scale==0);
+    if(from.index.id)
+    {
+        assert(false);
+    }
+    res.off = from.disp;
+    return res;
+}
 LLOperand convertOperand(const x86_op_t &from)
 {
+    LLOperand res;
     switch(from.type)
     {
         case op_unused:
             break;
         case op_register:
-            return LLOperand::CreateReg2(convertRegister(from.data.reg));
+            res.regi = convertRegister(from.data.reg); break;
         case op_immediate:
-            return LLOperand::CreateImm2(from.data.sdword);
+            res.opz = from.data.sdword;
+        case op_expression:
+            res = convertExpression(from.data.expression); break;
+        case op_offset:
+        {
+            LLOperand res;
+            res.seg = rDS;
+            res.off = from.data.offset;
+            break;
+        }
         default:
             fprintf(stderr,"convertOperand does not know how to convert %d\n",from.type);
     }
-    return LLOperand::CreateImm2(0);
+    if(res.isSet() && (res.seg == rUNDEF))
+    {
+        res.seg = rDS;
+    }
+    return res;
 }
 /*****************************************************************************
  Scans one machine instruction at offset ip in prog.Image and returns error.
@@ -481,15 +566,8 @@ eErrorId scan(uint32_t ip, ICODE &p)
         if(p.insn.x86_get_branch_target())
             decodeBranchTgt(p.insn);
     }
-    x86_op_t *dst_op = p.insn.get_dest();
-    static int only_first=1;
-    if(dst_op && only_first)
-    {
-        only_first = 0;
-        LLOperand conv = convertOperand(*dst_op);
-        p.ll()->dst=conv;
-        //assert(conv==p.ll()->dst);
-    }
+//    LLOperand conv = convertOperand(*p.insn.get_dest());
+//    assert(conv==p.ll()->dst);
     if (p.ll()->getOpcode())
     {
         /* Save bytes of image used */
@@ -552,7 +630,7 @@ static void setAddress(int i, bool fdst, uint16_t seg, int16_t reg, uint16_t off
 
     /* 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()->m_dst : &pIcode->ll()->src();
 
     /* Set segment.  A later procedure (lookupAddr in proclist.c) will
          * provide the value of this segment in the field segValue.  */
@@ -619,7 +697,7 @@ static void rm(int i)
     }
     //pIcode->insn.get_dest()->
     if ((stateTable[i].flg & NSP) && (pIcode->ll()->src().getReg2()==rSP ||
-                                      pIcode->ll()->dst.getReg2()==rSP))
+                                      pIcode->ll()->m_dst.getReg2()==rSP))
         pIcode->ll()->setFlags(NOT_HLL);
 }
 
@@ -656,10 +734,9 @@ static void segrm(int i)
 static void regop(int i)
 {
     setAddress(i, false, 0, ((int16_t)i & 7) + rAX, 0);
-    pIcode->ll()->replaceDst(LLOperand::CreateReg2(pIcode->ll()->src().getReg2()));
-    //    pIcode->ll()->dst.regi = pIcode->ll()->src.regi;
-}
+    pIcode->ll()->replaceDst(pIcode->ll()->src());
 
+}
 
 /*****************************************************************************
  segop - seg encoded in middle of opcode
@@ -767,7 +844,7 @@ static void trans(int i)
     if ((uint8_t)REG(*pInst) < 2 || !(stateTable[i].flg & B)) { /* INC & DEC */
         ll->setOpcode(transTable[REG(*pInst)]);   /* valid on bytes */
         rm(i);
-        ll->replaceSrc( pIcode->ll()->dst );
+        ll->replaceSrc( pIcode->ll()->m_dst );
         if (ll->match(iJMP) || ll->match(iCALL) || ll->match(iCALLF))
             ll->setFlags(NO_OPS);
         else if (ll->match(iINC) || ll->match(iPUSH) || ll->match(iDEC))
@@ -799,7 +876,7 @@ static void arith(int i)
     }
     else if (!(opcode == iNOT || opcode == iNEG))
     {
-        pIcode->ll()->replaceSrc( pIcode->ll()->dst );
+        pIcode->ll()->replaceSrc( pIcode->ll()->m_dst );
         setAddress(i, true, 0, rAX, 0);			/* dst = AX  */
     }
     else if (opcode == iNEG || opcode == iNOT)
@@ -838,7 +915,7 @@ static void data2(int )
          * set to NO_OPS.	*/
     if (pIcode->ll()->getOpcode() == iENTER)
     {
-        pIcode->ll()->dst.off = getWord();
+        pIcode->ll()->m_dst.off = getWord();
         pIcode->ll()->setFlags(NO_OPS);
     }
     else