From 0209b7ceb233e99be947f5589f440479e2f74d22 Mon Sep 17 00:00:00 2001 From: Artur K Date: Fri, 20 Jul 2012 18:18:25 +0200 Subject: [PATCH] Changes --- 3rd_party/libdisasm/ia32_implicit.cpp | 16 +- 3rd_party/libdisasm/ia32_operand.cpp | 20 +- 3rd_party/libdisasm/libdis.h | 711 +++++++++++++------------- 3rd_party/libdisasm/x86_insn.cpp | 1 - include/BasicBlock.h | 2 +- include/Procedure.h | 2 +- include/dcc.h | 8 +- include/icode.h | 155 ++++-- include/locident.h | 78 ++- include/machine_x86.h | 14 +- src/ast.cpp | 34 +- src/comwrite.cpp | 8 +- src/dataflow.cpp | 99 ++-- src/disassem.cpp | 31 +- src/hlicode.cpp | 82 +-- src/idioms.cpp | 2 +- src/idioms/arith_idioms.cpp | 30 +- src/idioms/call_idioms.cpp | 4 +- src/idioms/mov_idioms.cpp | 14 +- src/idioms/neg_idioms.cpp | 14 +- src/idioms/shift_idioms.cpp | 22 +- src/idioms/xor_idioms.cpp | 15 +- src/locident.cpp | 113 ++-- src/machine_x86.cpp | 12 +- src/parser.cpp | 126 +++-- src/procs.cpp | 18 +- src/proplong.cpp | 46 +- src/scanner.cpp | 119 ++++- 28 files changed, 1028 insertions(+), 768 deletions(-) diff --git a/3rd_party/libdisasm/ia32_implicit.cpp b/3rd_party/libdisasm/ia32_implicit.cpp index 0d42fae..c5adbef 100644 --- a/3rd_party/libdisasm/ia32_implicit.cpp +++ b/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->operandoperand-REG_DWORD_OFFSET)+REG_WORD_OFFSET); + assert((list->operand-REG_DWORD_OFFSET)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; diff --git a/3rd_party/libdisasm/ia32_operand.cpp b/3rd_party/libdisasm/ia32_operand.cpp index a36787d..cb804d5 100644 --- a/3rd_party/libdisasm/ia32_operand.cpp +++ b/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; diff --git a/3rd_party/libdisasm/libdis.h b/3rd_party/libdisasm/libdis.h index a9d6f08..42c08a9 100644 --- a/3rd_party/libdisasm/libdis.h +++ b/3rd_party/libdisasm/libdis.h @@ -8,15 +8,16 @@ #include #include #include + /* '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 @@ -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; + 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 + 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 ); diff --git a/3rd_party/libdisasm/x86_insn.cpp b/3rd_party/libdisasm/x86_insn.cpp index 3375182..22af097 100644 --- a/3rd_party/libdisasm/x86_insn.cpp +++ b/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); diff --git a/include/BasicBlock.h b/include/BasicBlock.h index ba6a6c3..3b82bf3 100644 --- a/include/BasicBlock.h +++ b/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) { diff --git a/include/Procedure.h b/include/Procedure.h index ae96d80..3d61d7d 100644 --- a/include/Procedure.h +++ b/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: diff --git a/include/dcc.h b/include/dcc.h index 93c5b99..7eb1b43 100644 --- a/include/dcc.h +++ b/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 *); diff --git a/include/icode.h b/include/icode.h index 2f28028..0de9d69 100644 --- a/include/icode.h +++ b/include/icode.h @@ -7,6 +7,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -29,21 +32,24 @@ typedef std::list::iterator iICODE; typedef std::list::reverse_iterator riICODE; typedef boost::iterator_range rCODE; -struct LivenessSet : public std::bitset<32> +struct LivenessSet { - LivenessSet(int val=0) : std::bitset<32>(val) {} - LivenessSet(const LivenessSet &other) + std::set registers; +public: + LivenessSet(const std::initializer_list &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 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 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 @@ -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 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 diff --git a/include/locident.h b/include/locident.h index 96ea12a..4d544af 100644 --- a/include/locident.h +++ b/include/locident.h @@ -31,37 +31,67 @@ struct IDX_ARRAY : public std::vector } }; -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 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); diff --git a/include/machine_x86.h b/include/machine_x86.h index 8d845b8..c876568 100644 --- a/include/machine_x86.h +++ b/include/machine_x86.h @@ -4,6 +4,7 @@ #include #include +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> ®i) - { - 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 ®i); static eReg subRegH(eReg reg); static eReg subRegL(eReg reg); static bool isMemOff(eReg r); diff --git a/src/ast.cpp b/src/ast.cpp index 7ebdaf0..9b6abcc 100644 --- a/src/ast.cpp +++ b/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 <type)<< " "<name<<"; "; - codeOut <<"/* "<id.longId.h) << ":" << - Machine_X86::regName(id->id.longId.l) << " */\n"; + codeOut <<"/* "<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! } diff --git a/src/comwrite.cpp b/src/comwrite.cpp index c7f5504..b38476e 100644 --- a/src/comwrite.cpp +++ b/src/comwrite.cpp @@ -154,7 +154,7 @@ void LLInst::writeIntComment (std::ostringstream &s) s<<"\t/* "; if (src_immed == 0x21) { - s < 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"; diff --git a/src/dataflow.cpp b/src/dataflow.cpp index 6cb5334..853e125 100644 --- a/src/dataflow.cpp +++ b/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(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(_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(_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 */ diff --git a/src/disassem.cpp b/src/disassem.cpp index 744af33..4ad73c1 100644 --- a/src/disassem.cpp +++ b/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< 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)) diff --git a/src/idioms.cpp b/src/idioms.cpp index e4a4003..c7066b8 100644 --- a/src/idioms.cpp +++ b/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 */ diff --git a/src/idioms/arith_idioms.cpp b/src/idioms/arith_idioms.cpp index d604333..99e4446 100644 --- a/src/idioms/arith_idioms.cpp +++ b/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()) { diff --git a/src/idioms/call_idioms.cpp b/src/idioms/call_idioms.cpp index 20c8567..784304c 100644 --- a/src/idioms/call_idioms.cpp +++ b/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++); diff --git a/src/idioms/mov_idioms.cpp b/src/idioms/mov_idioms.cpp index e5d16d2..4ba07e8 100644 --- a/src/idioms/mov_idioms.cpp +++ b/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(); diff --git a/src/idioms/neg_idioms.cpp b/src/idioms/neg_idioms.cpp index d950d34..a319d23 100644 --- a/src/idioms/neg_idioms.cpp +++ b/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(); diff --git a/src/idioms/shift_idioms.cpp b/src/idioms/shift_idioms.cpp index c3047e7..48d8552 100644 --- a/src/idioms/shift_idioms.cpp +++ b/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)); diff --git a/src/idioms/xor_idioms.cpp b/src/idioms/xor_idioms.cpp index 673e6c0..a7aefcb 100644 --- a/src/idioms/xor_idioms.cpp +++ b/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(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; } diff --git a/src/locident.cpp b/src/locident.cpp index c4d5c1e..c5e444a 100644 --- a/src/locident.cpp +++ b/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! } diff --git a/src/machine_x86.cpp b/src/machine_x86.cpp index b0e87cf..46e6afe 100644 --- a/src/machine_x86.cpp +++ b/src/machine_x86.cpp @@ -1,5 +1,6 @@ #include #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 ®i) +{ + int j; + for (j = rAX; j < INDEX_BX_SI; j++) + { + if (regi.testReg(j)) + ostr << regName(eReg(j))<<" "; + } +} diff --git a/src/parser.cpp b/src/parser.cpp index b787516..c92b265 100644 --- a/src/parser.cpp +++ b/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; } diff --git a/src/procs.cpp b/src/procs.cpp index a02d252..97141aa 100644 --- a/src/procs.cpp +++ b/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: diff --git a/src/proplong.cpp b/src/proplong.cpp index c8a48c6..734bccd 100644 --- a/src/proplong.cpp +++ b/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 */ diff --git a/src/scanner.cpp b/src/scanner.cpp index 1c1a365..af9f1b7 100644 --- a/src/scanner.cpp +++ b/src/scanner.cpp @@ -6,6 +6,8 @@ ****************************************************************************/ #include +#include +#include #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 ®) { + 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 nameToEnum = {{"es",rES},{"ds",rDS},{"cs",rCS},{"ss",rSS}}; + if(nameToEnum.find(reg.name)!=nameToEnum.end()) + return nameToEnum[reg.name]; assert(reg.iddst=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