Browse Source

Pre branch commit

Artur K 12 years ago
parent
commit
9cc5202ff7
12 changed files with 457 additions and 344 deletions
  1. 3 1
      include/Procedure.h
  2. 0 2
      include/dcc.h
  3. 11 10
      include/icode.h
  4. 2 2
      include/machine_x86.h
  5. 3 3
      src/ast.cpp
  6. 4 1
      src/bundle.cpp
  7. 3 3
      src/disassem.cpp
  8. 5 6
      src/graph.cpp
  9. 3 5
      src/idioms.cpp
  10. 1 1
      src/idioms/neg_idioms.cpp
  11. 69 30
      src/parser.cpp
  12. 353 280
      src/scanner.cpp

+ 3 - 1
include/Procedure.h

@@ -150,7 +150,7 @@ public:
     void findImmedDom();
     void findImmedDom();
     void FollowCtrl(CALL_GRAPH *pcallGraph, STATE *pstate);
     void FollowCtrl(CALL_GRAPH *pcallGraph, STATE *pstate);
     void process_operands(ICODE &pIcode, STATE *pstate);
     void process_operands(ICODE &pIcode, STATE *pstate);
-    boolT process_JMP(ICODE &pIcode, STATE *pstate, CALL_GRAPH *pcallGraph);
+    bool process_JMP(ICODE &pIcode, STATE *pstate, CALL_GRAPH *pcallGraph);
     boolT process_CALL(ICODE &pIcode, CALL_GRAPH *pcallGraph, STATE *pstate);
     boolT process_CALL(ICODE &pIcode, CALL_GRAPH *pcallGraph, STATE *pstate);
     void freeCFG();
     void freeCFG();
     void codeGen(std::ostream &fs);
     void codeGen(std::ostream &fs);
@@ -168,6 +168,8 @@ public:
 
 
     void preprocessReturnDU(std::bitset<32> &_liveOut);
     void preprocessReturnDU(std::bitset<32> &_liveOut);
 protected:
 protected:
+    void extractJumpTableRange(ICODE& pIcode, STATE *pstate, JumpTable &table);
+    bool followAllTableEntries(JumpTable &table, uint32_t cs, ICODE &pIcode, CALL_GRAPH *pcallGraph, STATE *pstate);
     bool removeInEdge_Flag_and_ProcessLatch(BB *pbb, BB *a, BB *b);
     bool removeInEdge_Flag_and_ProcessLatch(BB *pbb, BB *a, BB *b);
     bool Case_X_and_Y(BB* pbb, BB* thenBB, BB* elseBB);
     bool Case_X_and_Y(BB* pbb, BB* thenBB, BB* elseBB);
     bool Case_X_or_Y(BB* pbb, BB* thenBB, BB* elseBB);
     bool Case_X_or_Y(BB* pbb, BB* thenBB, BB* elseBB);

+ 0 - 2
include/dcc.h

@@ -62,8 +62,6 @@ typedef struct {            /* Command line option flags */
 extern OPTION option;       /* Command line options             */
 extern OPTION option;       /* Command line options             */
 
 
 #include "BinaryImage.h"
 #include "BinaryImage.h"
-
-//extern PROG prog;   		/* Loaded program image parameters  */
 extern std::bitset<32> duReg[30];   /* def/use bits for registers		*/
 extern std::bitset<32> duReg[30];   /* def/use bits for registers		*/
 
 
 //extern uint32_t duReg[30];		/* def/use bits for registers		*/
 //extern uint32_t duReg[30];		/* def/use bits for registers		*/

+ 11 - 10
include/icode.h

@@ -31,7 +31,7 @@ struct bundle;
 typedef std::list<ICODE>::iterator iICODE;
 typedef std::list<ICODE>::iterator iICODE;
 typedef std::list<ICODE>::reverse_iterator riICODE;
 typedef std::list<ICODE>::reverse_iterator riICODE;
 typedef boost::iterator_range<iICODE> rCODE;
 typedef boost::iterator_range<iICODE> rCODE;
-
+extern std::bitset<32> duReg[30];
 /* uint8_t and uint16_t registers */
 /* uint8_t and uint16_t registers */
 
 
 /* Def/use of flags - low 4 bits represent flags */
 /* Def/use of flags - low 4 bits represent flags */
@@ -214,19 +214,15 @@ struct LLInst : public llvm::MCInst //: public llvm::ilist_node<LLInst>
 {
 {
 protected:
 protected:
     uint32_t     flg;            /* icode flags                  */
     uint32_t     flg;            /* icode flags                  */
-//    llIcode      opcode;         /* llIcode instruction          */
+    LLOperand    m_src;            /* source operand               */
 public:
 public:
     int          codeIdx;    	/* Index into cCode.code            */
     int          codeIdx;    	/* Index into cCode.code            */
     uint8_t      numBytes;       /* Number of bytes this instr   */
     uint8_t      numBytes;       /* Number of bytes this instr   */
     uint32_t     label;          /* offset in image (20-bit adr) */
     uint32_t     label;          /* offset in image (20-bit adr) */
     LLOperand    dst;            /* destination operand          */
     LLOperand    dst;            /* destination operand          */
-    LLOperand    m_src;            /* source operand               */
     DU           flagDU;         /* def/use of flags				*/
     DU           flagDU;         /* def/use of flags				*/
-    struct {                    /* Case table if op==JMP && !I  */
-        int     numEntries;     /*   # entries in case table    */
-        uint32_t  *entries;        /*   array of offsets           */
-
-    }           caseTbl;
+        int caseEntry;
+    std::vector<uint32_t> caseTbl2;
     int         hllLabNum;      /* label # for hll codegen      */
     int         hllLabNum;      /* label # for hll codegen      */
     bool conditionalJump()
     bool conditionalJump()
     {
     {
@@ -295,8 +291,6 @@ public:
     HLTYPE createCall();
     HLTYPE createCall();
     LLInst(ICODE *container) : flg(0),codeIdx(0),numBytes(0),m_link(container)
     LLInst(ICODE *container) : flg(0),codeIdx(0),numBytes(0),m_link(container)
     {
     {
-        caseTbl.entries=0;
-        caseTbl.numEntries=0;
         setOpcode(0);
         setOpcode(0);
     }
     }
     const LLOperand &src() const {return m_src;}
     const LLOperand &src() const {return m_src;}
@@ -322,6 +316,7 @@ public:
         dst = LLOperand::CreateReg2(r);
         dst = LLOperand::CreateReg2(r);
     }
     }
     ICODE *m_link;
     ICODE *m_link;
+    condId idType(opLoc sd) const;
     const LLOperand *   get(opLoc sd) const { return (sd == SRC) ? &src() : &dst; }
     const LLOperand *   get(opLoc sd) const { return (sd == SRC) ? &src() : &dst; }
     LLOperand *         get(opLoc sd) { return (sd == SRC) ? &src() : &dst; }
     LLOperand *         get(opLoc sd) { return (sd == SRC) ? &src() : &dst; }
 };
 };
@@ -370,6 +365,12 @@ public:
         std::bitset<32> def;        // For Registers: position in bitset is reg index
         std::bitset<32> def;        // For Registers: position in bitset is reg index
         std::bitset<32> use;	// For Registers: position in uint32_t is reg index
         std::bitset<32> use;	// For Registers: position in uint32_t is reg index
         std::bitset<32> lastDefRegi;// Bit set if last def of this register in BB
         std::bitset<32> lastDefRegi;// Bit set if last def of this register in BB
+        void addDefinedAndUsed(eReg r)
+        {
+            def |= duReg[r];
+            use |= duReg[r];
+
+        }
     };
     };
     struct DU1
     struct DU1
     {
     {

+ 2 - 2
include/machine_x86.h

@@ -46,7 +46,7 @@ enum eReg
 class SourceMachine
 class SourceMachine
 {
 {
 public:
 public:
-//    virtual bool physicalReg(eReg r)=0;
+    virtual bool physicalReg(eReg r)=0;
 
 
 };
 };
 //class Machine_X86_Disassembler
 //class Machine_X86_Disassembler
@@ -61,7 +61,7 @@ public:
     static const std::string &regName(eReg r);
     static const std::string &regName(eReg r);
     static const std::string &opcodeName(unsigned r);
     static const std::string &opcodeName(unsigned r);
     static const std::string &floatOpName(unsigned r);
     static const std::string &floatOpName(unsigned r);
-    static bool physicalReg(eReg r);
+    bool physicalReg(eReg r);
     /* Writes the registers that are set in the bitvector */
     /* Writes the registers that are set in the bitvector */
     //TODO: move this into Machine_X86 ?
     //TODO: move this into Machine_X86 ?
     static void writeRegVector (std::ostream &ostr,const std::bitset<32> &regi)
     static void writeRegVector (std::ostream &ostr,const std::bitset<32> &regi)

+ 3 - 3
src/ast.cpp

@@ -424,11 +424,11 @@ COND_EXPR *COND_EXPR::id(const LLInst &ll_insn, opLoc sd, Function * pProc, iICO
 
 
 
 
 /* Returns the identifier type */
 /* Returns the identifier type */
-condId ICODE::idType(opLoc sd)
+condId LLInst::idType(opLoc sd) const
 {
 {
-    LLOperand &pm(*ll()->get(sd));
+    const LLOperand &pm((sd == SRC) ? src() : dst);
 
 
-    if ((sd == SRC) && ll()->testFlags(I))
+    if ((sd == SRC) && testFlags(I))
         return (CONSTANT);
         return (CONSTANT);
     else if (pm.regi == 0)
     else if (pm.regi == 0)
         return (GLOB_VAR);
         return (GLOB_VAR);

+ 4 - 1
src/bundle.cpp

@@ -23,7 +23,10 @@ void strTable::addLabelBundle (int idx, int label)
 {
 {
     char s[16];
     char s[16];
     sprintf (s, "l%d: ", label);
     sprintf (s, "l%d: ", label);
-    at(idx) = string(s)+at(idx).substr(4);
+    if(at(idx).size()<4)
+        at(idx)=s;
+    else
+        at(idx) = string(s)+at(idx).substr(4);
 }
 }
 
 
 
 

+ 3 - 3
src/disassem.cpp

@@ -71,7 +71,7 @@ static const char *szFlops3C[] =
 static const char *szPtr[2]   = { "word ptr ", "byte ptr " };
 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, uint32_t flg, const LLOperand &pm);
-static ostringstream &strDst(ostringstream &os, uint32_t flg, LLOperand &pm);
+static ostringstream &strDst(ostringstream &os, uint32_t flg, const LLOperand &pm);
 
 
 static char *strHex(uint32_t d);
 static char *strHex(uint32_t d);
 //static int   checkScanned(uint32_t pcCur);
 //static int   checkScanned(uint32_t pcCur);
@@ -492,7 +492,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
     {
     {
         if (inst.testFlags(CASE))
         if (inst.testFlags(CASE))
         {
         {
-            result_stream << ";Case l"<< inst.caseTbl.numEntries;
+            result_stream << ";Case l"<< inst.caseEntry;
         }
         }
         if (inst.testFlags(SWITCH))
         if (inst.testFlags(SWITCH))
         {
         {
@@ -589,7 +589,7 @@ static void formatRM(std::ostringstream &p, uint32_t flg, const LLOperand &pm)
 /*****************************************************************************
 /*****************************************************************************
  * strDst
  * strDst
  ****************************************************************************/
  ****************************************************************************/
-static ostringstream & strDst(ostringstream &os,uint32_t flg, LLOperand &pm)
+static ostringstream & strDst(ostringstream &os,uint32_t flg, const LLOperand &pm)
 {
 {
     /* Immediates to memory require size descriptor */
     /* Immediates to memory require size descriptor */
     //os << setw(WID_PTR);
     //os << setw(WID_PTR);

+ 5 - 6
src/graph.cpp

@@ -84,9 +84,9 @@ CondJumps:
                     if (ll->testFlags(SWITCH))
                     if (ll->testFlags(SWITCH))
                     {
                     {
                         //pBB = BB::Create(start, ip, MULTI_BRANCH, ll->caseTbl.numEntries, this);
                         //pBB = BB::Create(start, ip, MULTI_BRANCH, ll->caseTbl.numEntries, this);
-                        pBB = BB::Create(iStart, pIcode, MULTI_BRANCH, ll->caseTbl.numEntries, this);
-                        for (i = 0; i < ll->caseTbl.numEntries; i++)
-                            pBB->edges[i].ip = ll->caseTbl.entries[i];
+                        pBB = BB::Create(iStart, pIcode, MULTI_BRANCH, ll->caseTbl2.size(), this);
+                        for (i = 0; i < ll->caseTbl2.size(); i++)
+                            pBB->edges[i].ip = ll->caseTbl2[i];
                         hasCase = true;
                         hasCase = true;
                     }
                     }
                     else if ((ll->getFlag() & (I | NO_LABEL)) == I) //TODO: WHY NO_LABEL TESTIT
                     else if ((ll->getFlag() & (I | NO_LABEL)) == I) //TODO: WHY NO_LABEL TESTIT
@@ -173,15 +173,14 @@ CondJumps:
 void Function::markImpure()
 void Function::markImpure()
 {
 {
     PROG &prog(Project::get()->prog);
     PROG &prog(Project::get()->prog);
-    SYM * psym;
     for(ICODE &icod : Icode)
     for(ICODE &icod : Icode)
     {
     {
         if ( not icod.ll()->testFlags(SYM_USE | SYM_DEF))
         if ( not icod.ll()->testFlags(SYM_USE | SYM_DEF))
             continue;
             continue;
         //assert that case tbl has less entries then symbol table ????
         //assert that case tbl has less entries then symbol table ????
         //WARNING: Case entries are held in symbol table !
         //WARNING: Case entries are held in symbol table !
-        assert(g_proj.validSymIdx(icod.ll()->caseTbl.numEntries));
-        const SYM &psym(g_proj.getSymByIdx(icod.ll()->caseTbl.numEntries));
+        assert(g_proj.validSymIdx(icod.ll()->caseEntry));
+        const SYM &psym(g_proj.getSymByIdx(icod.ll()->caseEntry));
         for (int c = (int)psym.label; c < (int)psym.label+psym.size; c++)
         for (int c = (int)psym.label; c < (int)psym.label+psym.size; c++)
         {
         {
             if (BITMAP(c, BM_CODE))
             if (BITMAP(c, BM_CODE))

+ 3 - 5
src/idioms.cpp

@@ -223,8 +223,6 @@ void Function::bindIcodeOff()
 {
 {
 
 
     iICODE pIcode;            /* ptr icode array      */
     iICODE pIcode;            /* ptr icode array      */
-    uint32_t *p;                 /* for case table       */
-
     if (Icode.empty())        /* No Icode */
     if (Icode.empty())        /* No Icode */
         return;
         return;
     pIcode = Icode.begin();
     pIcode = Icode.begin();
@@ -261,9 +259,9 @@ void Function::bindIcodeOff()
         }
         }
         else if (ll->testFlags(SWITCH) )
         else if (ll->testFlags(SWITCH) )
         {
         {
-            p = ll->caseTbl.entries;
-            for (int j = 0; j < ll->caseTbl.numEntries; j++, p++)
-                Icode.labelSrch(*p, *p);
+            /* for case table       */
+            for (uint32_t &p : ll->caseTbl2)
+                Icode.labelSrch(p, p); // for each entry in caseTable replace it with target insn Idx
         }
         }
     }
     }
 }
 }

+ 1 - 1
src/idioms/neg_idioms.cpp

@@ -22,7 +22,7 @@ bool Idiom11::match (iICODE picode)
         return false;
         return false;
     for(int i=0; i<3; ++i)
     for(int i=0; i<3; ++i)
         m_icodes[i]=picode++;
         m_icodes[i]=picode++;
-    type = m_icodes[0]->idType(DST);
+    type = m_icodes[0]->ll()->idType(DST);
     if(type==CONSTANT || type == OTHER)
     if(type==CONSTANT || type == OTHER)
         return false;
         return false;
     /* Check NEG reg/mem
     /* Check NEG reg/mem

+ 69 - 30
src/parser.cpp

@@ -231,7 +231,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
             case iJCXZ:
             case iJCXZ:
             {   STATE   StCopy;
             {   STATE   StCopy;
                 int     ip      = Icode.size()-1;	/* Index of this jump */
                 int     ip      = Icode.size()-1;	/* Index of this jump */
-                ICODE  &prev(Icode.back()); /* Previous icode */
+                ICODE  &prev(*(++Icode.rbegin())); /* Previous icode */
                 boolT   fBranch = false;
                 boolT   fBranch = false;
 
 
                 pstate->JCond.regi = 0;
                 pstate->JCond.regi = 0;
@@ -377,9 +377,49 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
     }
     }
 }
 }
 
 
+/* Firstly look for a leading range check of the form:-
+ *      CMP {BX | SI | DI}, immed
+ *      JA | JAE | JB | JBE
+ * This is stored in the current state as if we had just
+ * followed a JBE branch (i.e. [reg] lies between 0 - immed).
+*/
+void Function::extractJumpTableRange(ICODE& pIcode, STATE *pstate, JumpTable &table)
+{
+    static uint8_t i2r[4] = {rSI, rDI, rBP, rBX};
+    if (pstate->JCond.regi == i2r[pIcode.ll()->src().getReg2()-INDEX_SI])
+        table.finish = table.start + pstate->JCond.immed;
+    else
+        table.finish = table.start + 2;
+}
 
 
 /* process_JMP - Handles JMPs, returns true if we should end recursion  */
 /* process_JMP - Handles JMPs, returns true if we should end recursion  */
-boolT Function::process_JMP (ICODE & pIcode, STATE *pstate, CALL_GRAPH * pcallGraph)
+bool Function::followAllTableEntries(JumpTable &table, uint32_t cs, ICODE& pIcode, CALL_GRAPH* pcallGraph, STATE *pstate)
+{
+    PROG &prog(Project::get()->prog);
+    STATE   StCopy;
+
+    setBits(BM_DATA, table.start, table.size()*table.entrySize());
+
+    pIcode.ll()->setFlags(SWITCH);
+    pIcode.ll()->caseTbl2.resize( table.size() );
+    assert(pIcode.ll()->caseTbl2.size()<512);
+    uint32_t k=0;
+    for (int i = table.start; i < table.finish; i += 2)
+    {
+        StCopy = *pstate;
+        StCopy.IP = cs + LH(&prog.Image[i]);
+        iICODE last_current_insn = (++Icode.rbegin()).base();
+
+        FollowCtrl (pcallGraph, &StCopy);
+
+        ++last_current_insn; // incremented here because FollowCtrl might have adde more instructions after the Jmp
+        last_current_insn->ll()->caseEntry = k++;
+        last_current_insn->ll()->setFlags(CASE);
+        pIcode.ll()->caseTbl2.push_back( last_current_insn->ll()->GetLlLabel() );
+    }
+}
+
+bool Function::process_JMP (ICODE & pIcode, STATE *pstate, CALL_GRAPH * pcallGraph)
 {
 {
     PROG &prog(Project::get()->prog);
     PROG &prog(Project::get()->prog);
     static uint8_t i2r[4] = {rSI, rDI, rBP, rBX};
     static uint8_t i2r[4] = {rSI, rDI, rBP, rBX};
@@ -399,7 +439,7 @@ boolT Function::process_JMP (ICODE & pIcode, STATE *pstate, CALL_GRAPH * pcallGr
         }
         }
 
 
         /* Return true if jump target is already parsed */
         /* Return true if jump target is already parsed */
-        return Icode.labelSrch(i, tmp);
+        return Icode.alreadyDecoded(i);
     }
     }
 
 
     /* We've got an indirect JMP - look for switch() stmt. idiom of the form
     /* We've got an indirect JMP - look for switch() stmt. idiom of the form
@@ -459,6 +499,7 @@ boolT Function::process_JMP (ICODE & pIcode, STATE *pstate, CALL_GRAPH * pcallGr
          * state and recursively call FollowCtrl(). */
          * state and recursively call FollowCtrl(). */
         if (offTable < endTable)
         if (offTable < endTable)
         {
         {
+            assert(((endTable - offTable) / 2)<512);
             STATE   StCopy;
             STATE   StCopy;
             int     ip;
             int     ip;
             uint32_t  *psw;
             uint32_t  *psw;
@@ -466,10 +507,7 @@ boolT Function::process_JMP (ICODE & pIcode, STATE *pstate, CALL_GRAPH * pcallGr
             setBits(BM_DATA, offTable, endTable - offTable);
             setBits(BM_DATA, offTable, endTable - offTable);
 
 
             pIcode.ll()->setFlags(SWITCH);
             pIcode.ll()->setFlags(SWITCH);
-            pIcode.ll()->caseTbl.numEntries = (endTable - offTable) / 2;
-            assert(pIcode.ll()->caseTbl.numEntries<512);
-            psw = new uint32_t [pIcode.ll()->caseTbl.numEntries];
-            pIcode.ll()->caseTbl.entries = psw;
+            //pIcode.ll()->caseTbl2.numEntries = (endTable - offTable) / 2;
 
 
             for (i = offTable, k = 0; i < endTable; i += 2)
             for (i = offTable, k = 0; i < endTable; i += 2)
             {
             {
@@ -480,9 +518,9 @@ boolT Function::process_JMP (ICODE & pIcode, STATE *pstate, CALL_GRAPH * pcallGr
 
 
                 FollowCtrl (pcallGraph, &StCopy);
                 FollowCtrl (pcallGraph, &StCopy);
                 ++last_current_insn;
                 ++last_current_insn;
-                last_current_insn->ll()->caseTbl.numEntries = k++;
+                last_current_insn->ll()->caseEntry = k++;
                 last_current_insn->ll()->setFlags(CASE);
                 last_current_insn->ll()->setFlags(CASE);
-                *psw++ = last_current_insn->ll()->GetLlLabel();
+                pIcode.ll()->caseTbl2.push_back( last_current_insn->ll()->GetLlLabel() );
 
 
             }
             }
             return true;
             return true;
@@ -898,7 +936,7 @@ static void use (opLoc d, ICODE & pIcode, Function * pProc, STATE * pstate, int
         {
         {
             setBits (BM_DATA, psym->label, (uint32_t)size);
             setBits (BM_DATA, psym->label, (uint32_t)size);
             pIcode.ll()->setFlags(SYM_USE);
             pIcode.ll()->setFlags(SYM_USE);
-            pIcode.ll()->caseTbl.numEntries = distance(&g_proj.symtab[0],psym);
+            pIcode.ll()->caseEntry = distance(&g_proj.symtab[0],psym); //WARNING: was setting case count
 
 
         }
         }
     }
     }
@@ -948,7 +986,7 @@ static void def (opLoc d, ICODE & pIcode, Function * pProc, STATE * pstate, int
         {
         {
             setBits(BM_DATA, psym->label, (uint32_t)size);
             setBits(BM_DATA, psym->label, (uint32_t)size);
             pIcode.ll()->setFlags(SYM_DEF);
             pIcode.ll()->setFlags(SYM_DEF);
-            pIcode.ll()->caseTbl.numEntries = distance(&g_proj.symtab[0],psym);
+            pIcode.ll()->caseEntry = distance(&g_proj.symtab[0],psym); // WARNING: was setting Case count
         }
         }
     }
     }
 
 
@@ -981,13 +1019,16 @@ static void use_def(opLoc d, ICODE & pIcode, Function * pProc, STATE * pstate, i
 
 
 /* Set DU vector, local variables and arguments, and DATA bits in the
 /* Set DU vector, local variables and arguments, and DATA bits in the
  * bitmap       */
  * bitmap       */
+extern LLOperand convertOperand(const x86_op_t &from);
 void Function::process_operands(ICODE & pIcode,  STATE * pstate)
 void Function::process_operands(ICODE & pIcode,  STATE * pstate)
 {
 {
-    int ix=Icode.size();
-    int   i;
-    int   sseg = (pIcode.ll()->src().seg)? pIcode.ll()->src().seg: rDS;
+    int  ix=Icode.size();
+    LLInst &ll_ins(*pIcode.ll());
+
+    int   sseg = (ll_ins.src().seg)? ll_ins.src().seg: rDS;
     int   cb   = pIcode.ll()->testFlags(B) ? 1: 2;
     int   cb   = pIcode.ll()->testFlags(B) ? 1: 2;
-    uint32_t Imm  = (pIcode.ll()->testFlags(I));
+    //x86_op_t *im= pIcode.insn.x86_get_imm();
+    bool Imm  = (pIcode.ll()->testFlags(I));
 
 
     switch (pIcode.ll()->getOpcode()) {
     switch (pIcode.ll()->getOpcode()) {
         case iAND:  case iOR:   case iXOR:
         case iAND:  case iOR:   case iXOR:
@@ -1108,19 +1149,18 @@ void Function::process_operands(ICODE & pIcode,  STATE * pstate)
             break;
             break;
 
 
         case iREPNE_CMPS: case iREPE_CMPS:  case iREP_MOVS:
         case iREPNE_CMPS: case iREPE_CMPS:  case iREP_MOVS:
-            pIcode.du.def |= duReg[rCX];
+            pIcode.du.addDefinedAndUsed(rCX);
             pIcode.du1.numRegsDef++;
             pIcode.du1.numRegsDef++;
-            pIcode.du.use |= duReg[rCX];
         case iCMPS:  case iMOVS:
         case iCMPS:  case iMOVS:
-            pIcode.du.def |= duReg[rSI] | duReg[rDI];
+            pIcode.du.addDefinedAndUsed(rSI);
+            pIcode.du.addDefinedAndUsed(rDI);
             pIcode.du1.numRegsDef += 2;
             pIcode.du1.numRegsDef += 2;
-            pIcode.du.use |= duReg[rSI] | duReg[rDI] | duReg[rES] | duReg[sseg];
+            pIcode.du.use |= duReg[rES] | duReg[sseg];
             break;
             break;
 
 
         case iREPNE_SCAS: case iREPE_SCAS:  case iREP_STOS:  case iREP_INS:
         case iREPNE_SCAS: case iREPE_SCAS:  case iREP_STOS:  case iREP_INS:
-            pIcode.du.def |= duReg[rCX];
+            pIcode.du.addDefinedAndUsed(rCX);
             pIcode.du1.numRegsDef++;
             pIcode.du1.numRegsDef++;
-            pIcode.du.use |= duReg[rCX];
         case iSCAS:  case iSTOS:  case iINS:
         case iSCAS:  case iSTOS:  case iINS:
             pIcode.du.def |= duReg[rDI];
             pIcode.du.def |= duReg[rDI];
             pIcode.du1.numRegsDef++;
             pIcode.du1.numRegsDef++;
@@ -1135,23 +1175,22 @@ void Function::process_operands(ICODE & pIcode,  STATE * pstate)
             break;
             break;
 
 
         case iREP_LODS:
         case iREP_LODS:
-            pIcode.du.def |= duReg[rCX];
+            pIcode.du.addDefinedAndUsed(rCX);
             pIcode.du1.numRegsDef++;
             pIcode.du1.numRegsDef++;
-            pIcode.du.use |= duReg[rCX];
         case iLODS:
         case iLODS:
-            pIcode.du.def |= duReg[rSI] | duReg[(cb==2)? rAX: rAL];
+            pIcode.du.addDefinedAndUsed(rSI);
+            pIcode.du.def |= duReg[(cb==2)? rAX: rAL];
             pIcode.du1.numRegsDef += 2;
             pIcode.du1.numRegsDef += 2;
-            pIcode.du.use |= duReg[rSI] | duReg[sseg];
+            pIcode.du.use |= duReg[sseg];
             break;
             break;
 
 
         case iREP_OUTS:
         case iREP_OUTS:
-            pIcode.du.def |= duReg[rCX];
+            pIcode.du.addDefinedAndUsed(rCX);
             pIcode.du1.numRegsDef++;
             pIcode.du1.numRegsDef++;
-            pIcode.du.use |= duReg[rCX];
         case iOUTS:
         case iOUTS:
-            pIcode.du.def |= duReg[rSI];
+            pIcode.du.addDefinedAndUsed(rSI);
             pIcode.du1.numRegsDef++;
             pIcode.du1.numRegsDef++;
-            pIcode.du.use |= duReg[rSI] | duReg[rDX] | duReg[sseg];
+            pIcode.du.use |= duReg[rDX] | duReg[sseg];
             break;
             break;
 
 
         case iIN:  case iOUT:
         case iIN:  case iOUT:
@@ -1163,7 +1202,7 @@ void Function::process_operands(ICODE & pIcode,  STATE * pstate)
             break;
             break;
     }
     }
 
 
-    for (i = rSP; i <= rBH; i++)        /* Kill all defined registers */
+    for (int i = rSP; i <= rBH; i++)        /* Kill all defined registers */
         if (pIcode.ll()->flagDU.d & (1 << i))
         if (pIcode.ll()->flagDU.d & (1 << i))
             pstate->f[i] = false;
             pstate->f[i] = false;
 }
 }

+ 353 - 280
src/scanner.cpp

@@ -6,7 +6,6 @@
  ****************************************************************************/
  ****************************************************************************/
 
 
 #include <cstring>
 #include <cstring>
-
 #include "dcc.h"
 #include "dcc.h"
 #include "scanner.h"
 #include "scanner.h"
 #include "project.h"
 #include "project.h"
@@ -55,265 +54,263 @@ static struct {
     void (*state2)(int);
     void (*state2)(int);
     uint32_t flg;
     uint32_t flg;
     llIcode opcode;
     llIcode opcode;
-    uint8_t df;
-    uint8_t uf;
 } stateTable[] = {
 } stateTable[] = {
-    {  modrm,   none2, B                        , iADD	, Sf | Zf | Cf  , 0     },  /* 00 */
-    {  modrm,   none2, 0                        , iADD	, Sf | Zf | Cf  , 0     },  /* 01 */
-    {  modrm,   none2, TO_REG | B               , iADD	, Sf | Zf | Cf  , 0     },  /* 02 */
-    {  modrm,   none2, TO_REG 			, iADD	, Sf | Zf | Cf  , 0     },  /* 03 */
-    {  data1,   axImp, B                        , iADD	, Sf | Zf | Cf  , 0     },  /* 04 */
-    {  data2,   axImp, 0                        , iADD	, Sf | Zf | Cf  , 0     },  /* 05 */
-    {  segop,   none2, NO_SRC                   , iPUSH	, 0             , 0     },  /* 06 */
-    {  segop,   none2, NO_SRC 			, iPOP	, 0             , 0     },  /* 07 */
-    {  modrm,   none2, B                        , iOR	, Sf | Zf | Cf  , 0 	},  /* 08 */
-    {  modrm,   none2, NSP                      , iOR	, Sf | Zf | Cf  , 0     },  /* 09 */
-    {  modrm,   none2, TO_REG | B               , iOR	, Sf | Zf | Cf  , 0     },  /* 0A */
-    {  modrm,   none2, TO_REG | NSP		, iOR	, Sf | Zf | Cf  , 0     },  /* 0B */
-    {  data1,   axImp, B                        , iOR	, Sf | Zf | Cf  , 0     },  /* 0C */
-    {  data2,   axImp, 0                        , iOR	, Sf | Zf | Cf  , 0     },	/* 0D */
-    {  segop,   none2, NO_SRC                   , iPUSH	, 0             , 0     },	/* 0E */
-    {  none1,   none2, OP386                    , iZERO , 0             , 0     },	/* 0F */
-    {  modrm,   none2, B                        , iADC	, Sf | Zf | Cf  , Cf    },	/* 10 */
-    {  modrm,   none2, NSP                      , iADC	, Sf | Zf | Cf  , Cf    },	/* 11 */
-    {  modrm,   none2, TO_REG | B               , iADC	, Sf | Zf | Cf  , Cf    },	/* 12 */
-    {  modrm,   none2, TO_REG | NSP		, iADC	, Sf | Zf | Cf  , Cf    },	/* 13 */
-    {  data1,   axImp, B                        , iADC	, Sf | Zf | Cf  , Cf    },	/* 14 */
-    {  data2,   axImp, 0			, iADC	, Sf | Zf | Cf  , Cf    },	/* 15 */
-    {  segop,   none2, NOT_HLL | NO_SRC         , iPUSH	, 0             , 0     },	/* 16 */
-    {  segop,   none2, NOT_HLL | NO_SRC         , iPOP	, 0             , 0     },	/* 17 */
-    {  modrm,   none2, B			, iSBB	, Sf | Zf | Cf  , Cf    },	/* 18 */
-    {  modrm,   none2, NSP                      , iSBB	, Sf | Zf | Cf  , Cf    },	/* 19 */
-    {  modrm,   none2, TO_REG | B               , iSBB	, Sf | Zf | Cf  , Cf    },	/* 1A */
-    {  modrm,   none2, TO_REG | NSP		, iSBB	, Sf | Zf | Cf  , Cf    },	/* 1B */
-    {  data1,   axImp, B            		, iSBB	, Sf | Zf | Cf  , Cf    },	/* 1C */
-    {  data2,   axImp, 0                        , iSBB  , Sf | Zf | Cf  , Cf    },	/* 1D */
-    {  segop,   none2, NO_SRC                   , iPUSH	, 0             , 0     },	/* 1E */
-    {  segop,   none2, NO_SRC                   , iPOP	, 0             , 0     },	/* 1F */
-    {  modrm,   none2, B                        , iAND	, Sf | Zf | Cf  , 0     },	/* 20 */
-    {  modrm,   none2, NSP                      , iAND	, Sf | Zf | Cf  , 0     },	/* 21 */
-    {  modrm,   none2, TO_REG | B               , iAND	, Sf | Zf | Cf  , 0     },	/* 22 */
-    {  modrm,   none2, TO_REG | NSP             , iAND	, Sf | Zf | Cf  , 0     },	/* 23 */
-    {  data1,   axImp, B                        , iAND	, Sf | Zf | Cf  , 0     },	/* 24 */
-    {  data2,   axImp, 0                        , iAND	, Sf | Zf | Cf  , 0     },	/* 25 */
-    { prefix,   none2, 0                        , (IC)rES,0             , 0     },	/* 26 */
-    {  none1,   axImp, NOT_HLL | B|NO_SRC	, iDAA	, Sf | Zf | Cf  , 0     },	/* 27 */
-    {  modrm,   none2, B                        , iSUB	, Sf | Zf | Cf  , 0     },	/* 28 */
-    {  modrm,   none2, 0                        , iSUB	, Sf | Zf | Cf  , 0     },	/* 29 */
-    {  modrm,   none2, TO_REG | B               , iSUB	, Sf | Zf | Cf  , 0     },	/* 2A */
-    {  modrm,   none2, TO_REG                   , iSUB	, Sf | Zf | Cf  , 0     },	/* 2B */
-    {  data1,   axImp, B                        , iSUB	, Sf | Zf | Cf  , 0     },	/* 2C */
-    {  data2,   axImp, 0                        , iSUB	, Sf | Zf | Cf  , 0     },	/* 2D */
-    { prefix,   none2, 0                        , (IC)rCS,0             , 0     },	/* 2E */
-    {  none1,   axImp, NOT_HLL | B|NO_SRC       , iDAS  , Sf | Zf | Cf  , 0     },	/* 2F */
-    {  modrm,   none2, B                        , iXOR  , Sf | Zf | Cf  , 0     },	/* 30 */
-    {  modrm,   none2, NSP                      , iXOR  , Sf | Zf | Cf  , 0     },	/* 31 */
-    {  modrm,   none2, TO_REG | B               , iXOR  , Sf | Zf | Cf  , 0     },	/* 32 */
-    {  modrm,   none2, TO_REG | NSP             , iXOR  , Sf | Zf | Cf  , 0     },	/* 33 */
-    {  data1,   axImp, B                        , iXOR	, Sf | Zf | Cf  , 0     },	/* 34 */
-    {  data2,   axImp, 0                        , iXOR	, Sf | Zf | Cf  , 0     },	/* 35 */
-    { prefix,   none2, 0                        , (IC)rSS,0             , 0     },	/* 36 */
-    {  none1,   axImp, NOT_HLL | NO_SRC         , iAAA  , Sf | Zf | Cf  , 0     },	/* 37 */
-    {  modrm,   none2, B                        , iCMP	, Sf | Zf | Cf  , 0 },	/* 38 */
-    {  modrm,   none2, NSP                      , iCMP	, Sf | Zf | Cf  , 0 },	/* 39 */
-    {  modrm,   none2, TO_REG | B               , iCMP	, Sf | Zf | Cf  , 0 },	/* 3A */
-    {  modrm,   none2, TO_REG | NSP             , iCMP	, Sf | Zf | Cf  , 0 },	/* 3B */
-    {  data1,   axImp, B                        , iCMP	, Sf | Zf | Cf  , 0 },	/* 3C */
-    {  data2,   axImp, 0                        , iCMP	, Sf | Zf | Cf  , 0 },	/* 3D */
-    { prefix,   none2, 0                        , (IC)rDS,0             , 0 },	/* 3E */
-    {  none1,   axImp, NOT_HLL | NO_SRC         , iAAS  , Sf | Zf | Cf  , 0 },	/* 3F */
-    {  regop,   none2, 0                        , iINC	, Sf | Zf       , 0 },	/* 40 */
-    {  regop,   none2, 0                        , iINC	, Sf | Zf       , 0 },	/* 41 */
-    {  regop,   none2, 0                        , iINC	, Sf | Zf       , 0 },	/* 42 */
-    {  regop,   none2, 0                        , iINC	, Sf | Zf       , 0 },	/* 43 */
-    {  regop,   none2, NOT_HLL			, iINC	, Sf | Zf       , 0 },	/* 44 */
-    {  regop,   none2, 0                        , iINC	, Sf | Zf       , 0 },	/* 45 */
-    {  regop,   none2, 0                        , iINC	, Sf | Zf       , 0 },	/* 46 */
-    {  regop,   none2, 0                        , iINC	, Sf | Zf       , 0 },	/* 47 */
-    {  regop,   none2, 0                        , iDEC	, Sf | Zf       , 0 },	/* 48 */
-    {  regop,   none2, 0                        , iDEC	, Sf | Zf       , 0 },	/* 49 */
-    {  regop,   none2, 0                        , iDEC	, Sf | Zf       , 0 },	/* 4A */
-    {  regop,   none2, 0                        , iDEC	, Sf | Zf       , 0 },	/* 4B */
-    {  regop,   none2, NOT_HLL			, iDEC	, Sf | Zf       , 0 },	/* 4C */
-    {  regop,   none2, 0                        , iDEC	, Sf | Zf       , 0 },	/* 4D */
-    {  regop,   none2, 0                        , iDEC	, Sf | Zf       , 0 },	/* 4E */
-    {  regop,   none2, 0                        , iDEC	, Sf | Zf       , 0 },	/* 4F */
-    {  regop,   none2, NO_SRC                   , iPUSH , 0             , 0 },	/* 50 */
-    {  regop,   none2, NO_SRC                   , iPUSH , 0             , 0 },	/* 51 */
-    {  regop,   none2, NO_SRC                   , iPUSH , 0             , 0 },	/* 52 */
-    {  regop,   none2, NO_SRC                   , iPUSH , 0             , 0 },	/* 53 */
-    {  regop,   none2, NOT_HLL | NO_SRC         , iPUSH , 0             , 0 },	/* 54 */
-    {  regop,   none2, NO_SRC                   , iPUSH , 0             , 0 },	/* 55 */
-    {  regop,   none2, NO_SRC                   , iPUSH , 0             , 0 },	/* 56 */
-    {  regop,   none2, NO_SRC                   , iPUSH , 0             , 0 },	/* 57 */
-    {  regop,   none2, NO_SRC                   , iPOP  , 0             , 0 },	/* 58 */
-    {  regop,   none2, NO_SRC                   , iPOP  , 0             , 0 },	/* 59 */
-    {  regop,   none2, NO_SRC 			, iPOP  , 0             , 0 },	/* 5A */
-    {  regop,   none2, NO_SRC                   , iPOP	, 0             , 0 },	/* 5B */
-    {  regop,   none2, NOT_HLL | NO_SRC         , iPOP  , 0             , 0 },	/* 5C */
-    {  regop,   none2, NO_SRC                   , iPOP  , 0             , 0 },	/* 5D */
-    {  regop,   none2, NO_SRC                   , iPOP  , 0             , 0 },	/* 5E */
-    {  regop,   none2, NO_SRC                   , iPOP  , 0             , 0 },	/* 5F */
-    {  none1,   none2, NOT_HLL | NO_OPS         , iPUSHA, 0             , 0 },	/* 60 */
-    {  none1,   none2, NOT_HLL | NO_OPS         , iPOPA , 0             , 0 },	/* 61 */
-    { memOnly,  modrm, TO_REG | NSP		, iBOUND, 0             , 0 },	/* 62 */
-    {  none1,   none2, OP386                    , iZERO , 0             , 0 },	/* 63 */
-    {  none1,   none2, OP386                    , iZERO , 0             , 0 },	/* 64 */
-    {  none1,   none2, OP386                    , iZERO , 0             , 0 },	/* 65 */
-    {  none1,   none2, OP386                    , iZERO , 0             , 0 },	/* 66 */
-    {  none1,   none2, OP386                    , iZERO , 0             , 0 },	/* 67 */
-    {  data2,   none2, NO_SRC                   , iPUSH , 0             , 0 },	/* 68 */
-    {  modrm,   data2, TO_REG | NSP             , iIMUL , Sf | Zf | Cf  , 0 },	/* 69 */
-    {  data1,   none2, S_EXT | NO_SRC           , iPUSH , 0             , 0 },	/* 6A */
-    {  modrm,   data1, TO_REG | NSP | S_EXT	, iIMUL , Sf | Zf | Cf  , 0 },	/* 6B */
-    {  strop,  memImp, NOT_HLL | B|IM_OPS       , iINS  , 0             , Df},	/* 6C */
-    {  strop,  memImp, NOT_HLL | IM_OPS         , iINS  , 0             , Df},	/* 6D */
-    {  strop,  memImp, NOT_HLL | B|IM_OPS       , iOUTS , 0             , Df},	/* 6E */
-    {  strop,  memImp, NOT_HLL | IM_OPS         , iOUTS , 0             , Df},	/* 6F */
-    {  dispS,   none2, NOT_HLL			, iJO	, 0             , 0 },	/* 70 */
-    {  dispS,   none2, NOT_HLL			, iJNO	, 0             , 0 },	/* 71 */
-    {  dispS,   none2, 0					, iJB	, 0	, Cf			},	/* 72 */
-    {  dispS,   none2, 0					, iJAE	, 0	, Cf			},	/* 73 */
-    {  dispS,   none2, 0					, iJE	, 0	, Zf			},	/* 74 */
-    {  dispS,   none2, 0					, iJNE	, 0	, Zf			},	/* 75 */
-    {  dispS,   none2, 0					, iJBE	, 0	, Zf | Cf 		},	/* 76 */
-    {  dispS,   none2, 0					, iJA	, 0	, Zf | Cf 		},	/* 77 */
-    {  dispS,   none2, 0					, iJS	, 0	, Sf			},	/* 78 */
-    {  dispS,   none2, 0					, iJNS	, 0	, Sf			},	/* 79 */
-    {  dispS,   none2, NOT_HLL			, iJP	, 0	, 0 },	/* 7A */
-    {  dispS,   none2, NOT_HLL			, iJNP	, 0	, 0 },	/* 7B */
-    {  dispS,   none2, 0					, iJL	, 0	, Sf			},	/* 7C */
-    {  dispS,   none2, 0					, iJGE	, 0	, Sf			},	/* 7D */
-    {  dispS,   none2, 0					, iJLE	, 0	, Sf | Zf 		},	/* 7E */
-    {  dispS,   none2, 0					, iJG	, 0	, Sf | Zf	 	},	/* 7F */
-    {  immed,   data1, B					, iZERO	, 0	, 0 },	/* 80 */
-    {  immed,   data2, NSP				, iZERO	, 0	, 0 },	/* 81 */
-    {  immed,   data1, B					, iZERO	, 0	, 0 },	/* 82 */ /* ?? */
-    {  immed,   data1, NSP | S_EXT			, iZERO	, 0	, 0 },	/* 83 */
-    {  modrm,   none2, TO_REG | B			, iTEST	, Sf | Zf | Cf, 0 },	/* 84 */
-    {  modrm,   none2, TO_REG | NSP		, iTEST	, Sf | Zf | Cf, 0 },	/* 85 */
-    {  modrm,   none2, TO_REG | B			, iXCHG	, 0	, 0 },	/* 86 */
-    {  modrm,   none2, TO_REG | NSP		, iXCHG	, 0	, 0 },	/* 87 */
-    {  modrm,   none2, B					, iMOV	, 0	, 0 },	/* 88 */
-    {  modrm,   none2, 0					, iMOV	, 0	, 0 },	/* 89 */
-    {  modrm,   none2, TO_REG | B			, iMOV	, 0	, 0 },	/* 8A */
-    {  modrm,   none2, TO_REG 			, iMOV	, 0	, 0 },	/* 8B */
-    {  segrm,   none2, NSP				, iMOV	, 0	, 0 },	/* 8C */
-    { memOnly,  modrm, TO_REG | NSP		, iLEA	, 0	, 0 },	/* 8D */
-    {  segrm,   none2, TO_REG | NSP		, iMOV	, 0	, 0 },	/* 8E */
-    { memReg0,  none2, NO_SRC				, iPOP	, 0	, 0 },	/* 8F */
-    {   none1,  none2, NO_OPS				, iNOP	, 0	, 0 },	/* 90 */
-    {  regop,   axImp, 0					, iXCHG	, 0	, 0 },	/* 91 */
-    {  regop,   axImp, 0					, iXCHG	, 0	, 0 },	/* 92 */
-    {  regop,   axImp, 0					, iXCHG	, 0	, 0 },	/* 93 */
-    {  regop,   axImp, NOT_HLL			, iXCHG	, 0	, 0 },	/* 94 */
-    {  regop,   axImp, 0					, iXCHG	, 0	, 0 },	/* 95 */
-    {  regop,   axImp, 0					, iXCHG	, 0	, 0 },	/* 96 */
-    {  regop,   axImp, 0					, iXCHG	, 0	, 0 },	/* 97 */
-    {  alImp,   axImp, SRC_B | S_EXT			, iSIGNEX,0	, 0 },	/* 98 */
-    {axSrcIm,   axImp, IM_DST | S_EXT			, iSIGNEX,0	, 0 },	/* 99 */
-    {  dispF,   none2, 0					, iCALLF ,0	, 0 },	/* 9A */
-    {  none1,   none2, FLOAT_OP| NO_OPS	, iWAIT	, 0	, 0 },	/* 9B */
-    {  none1,   none2, NOT_HLL | NO_OPS	, iPUSHF, 0	, 0 },	/* 9C */
-    {  none1,   none2, NOT_HLL | NO_OPS	, iPOPF	, Sf | Zf | Cf | Df,},	/* 9D */
-    {  none1,   none2, NOT_HLL | NO_OPS	, iSAHF	, Sf | Zf | Cf, 0 },	/* 9E */
-    {  none1,   none2, NOT_HLL | NO_OPS	, iLAHF	, 0 , Sf | Zf | Cf 	},	/* 9F */
-    {  dispM,   axImp, B					, iMOV	, 0	, 0 },	/* A0 */
-    {  dispM,   axImp, 0					, iMOV	, 0	, 0 },	/* A1 */
-    {  dispM,   axImp, TO_REG | B			, iMOV	, 0	, 0 },	/* A2 */
-    {  dispM,   axImp, TO_REG 			, iMOV	, 0	, 0 },	/* A3 */
-    {  strop,  memImp, B | IM_OPS			, iMOVS	, 0	, Df			},	/* A4 */
-    {  strop,  memImp, IM_OPS				, iMOVS	, 0	, Df			},	/* A5 */
-    {  strop,  memImp, B | IM_OPS			, iCMPS	, Sf | Zf | Cf, Df	},	/* A6 */
-    {  strop,  memImp, IM_OPS				, iCMPS	, Sf | Zf | Cf, Df	},	/* A7 */
-    {  data1,   axImp, B					, iTEST	, Sf | Zf | Cf, 0 },	/* A8 */
-    {  data2,   axImp, 0					, iTEST	, Sf | Zf | Cf, 0 },	/* A9 */
-    {  strop,  memImp, B | IM_OPS			, iSTOS	, 0	, Df			},	/* AA */
-    {  strop,  memImp, IM_OPS				, iSTOS	, 0	, Df			},	/* AB */
-    {  strop,  memImp, B | IM_OPS			, iLODS	, 0	, Df			},	/* AC */
-    {  strop,  memImp, IM_OPS				, iLODS	, 0	, Df			},	/* AD */
-    {  strop,  memImp, B | IM_OPS			, iSCAS	, Sf | Zf | Cf, Df  },	/* AE */
-    {  strop,  memImp, IM_OPS				, iSCAS	, Sf | Zf | Cf, Df	},	/* AF */
-    {  regop,   data1, B					, iMOV	, 0	, 0 },	/* B0 */
-    {  regop,   data1, B					, iMOV	, 0	, 0 },	/* B1 */
-    {  regop,   data1, B					, iMOV	, 0	, 0 },	/* B2 */
-    {  regop,   data1, B					, iMOV	, 0	, 0 },	/* B3 */
-    {  regop,   data1, B					, iMOV	, 0	, 0 },	/* B4 */
-    {  regop,   data1, B					, iMOV	, 0	, 0 },	/* B5 */
-    {  regop,   data1, B					, iMOV	, 0	, 0 },	/* B6 */
-    {  regop,   data1, B					, iMOV	, 0	, 0 },	/* B7 */
-    {  regop,   data2, 0					, iMOV	, 0	, 0 },	/* B8 */
-    {  regop,   data2, 0					, iMOV	, 0	, 0 },	/* B9 */
-    {  regop,   data2, 0					, iMOV	, 0	, 0 },	/* BA */
-    {  regop,   data2, 0					, iMOV	, 0	, 0 },	/* BB */
-    {  regop,   data2, NOT_HLL			, iMOV	, 0	, 0 },	/* BC */
-    {  regop,   data2, 0					, iMOV	, 0	, 0 },	/* BD */
-    {  regop,   data2, 0					, iMOV	, 0	, 0 },	/* BE */
-    {  regop,   data2, 0					, iMOV	, 0	, 0 },	/* BF */
-    {  shift,   data1, B					, iZERO	, 0	, 0 },	/* C0 */
-    {  shift,   data1, NSP | SRC_B		, iZERO	, 0	, 0 },	/* C1 */
-    {  data2,   none2, 0					, iRET	, 0	, 0 },	/* C2 */
-    {  none1,   none2, NO_OPS				, iRET	, 0	, 0 },	/* C3 */
-    { memOnly,  modrm, TO_REG | NSP		, iLES	, 0	, 0 },	/* C4 */
-    { memOnly,  modrm, TO_REG | NSP		, iLDS	, 0	, 0 },	/* C5 */
-    { memReg0,  data1, B					, iMOV	, 0	, 0 },	/* C6 */
-    { memReg0,  data2, 0					, iMOV	, 0	, 0 },	/* C7 */
-    {  data2,   data1, 0					, iENTER, 0	, 0 },	/* C8 */
-    {  none1,   none2, NO_OPS				, iLEAVE, 0	, 0 },	/* C9 */
-    {  data2,   none2, 0					, iRETF	, 0	, 0 },	/* CA */
-    {  none1,   none2, NO_OPS				, iRETF	, 0	, 0 },	/* CB */
-    { const3,   none2, NOT_HLL			, iINT	, 0	, 0 },	/* CC */
-    {  data1,checkInt, NOT_HLL			, iINT	, 0	, 0 },	/* CD */
-    {  none1,   none2, NOT_HLL | NO_OPS	, iINTO	, 0	, 0 },	/* CE */
-    {  none1,   none2, NOT_HLL | NO_OPS	, iIRET	, 0	, 0 },	/* Cf */
-    {  shift,  const1, B					, iZERO	, 0	, 0 },	/* D0 */
-    {  shift,  const1, SRC_B				, iZERO	, 0	, 0 },	/* D1 */
-    {  shift,   none1, B					, iZERO	, 0	, 0 },	/* D2 */
-    {  shift,   none1, SRC_B				, iZERO	, 0	, 0 },	/* D3 */
-    {  data1,   axImp, NOT_HLL			, iAAM	, Sf | Zf | Cf, 0 },	/* D4 */
-    {  data1,   axImp, NOT_HLL			, iAAD	, Sf | Zf | Cf, 0 },	/* D5 */
-    {  none1,   none2, 0					, iZERO	, 0	, 0 },	/* D6 */
-    { memImp,   axImp, NOT_HLL | B| IM_OPS, iXLAT	, 0	, 0 },	/* D7 */
-    {  escop,   none2, FLOAT_OP			, iESC	, 0	, 0 },	/* D8 */
-    {  escop,   none2, FLOAT_OP			, iESC	, 0	, 0 },	/* D9 */
-    {  escop,   none2, FLOAT_OP			, iESC	, 0	, 0 },	/* DA */
-    {  escop,   none2, FLOAT_OP			, iESC	, 0	, 0 },	/* DB */
-    {  escop,   none2, FLOAT_OP			, iESC	, 0	, 0 },	/* DC */
-    {  escop,   none2, FLOAT_OP			, iESC	, 0	, 0 },	/* DD */
-    {  escop,   none2, FLOAT_OP			, iESC	, 0	, 0 },	/* DE */
-    {  escop,   none2, FLOAT_OP			, iESC	, 0	, 0 },	/* Df */
-    {  dispS,   none2, 0					, iLOOPNE,0	, Zf			},	/* E0 */
-    {  dispS,   none2, 0					, iLOOPE, 0	, Zf			},	/* E1 */
-    {  dispS,   none2, 0					, iLOOP	, 0	, 0 },	/* E2 */
-    {  dispS,   none2, 0					, iJCXZ	, 0	, 0 },	/* E3 */
-    {  data1,   axImp, NOT_HLL | B|NO_SRC , iIN	, 0	, 0 },	/* E4 */
-    {  data1,   axImp, NOT_HLL | NO_SRC	, iIN	, 0	, 0 },	/* E5 */
-    {  data1,   axImp, NOT_HLL | B|NO_SRC , iOUT	, 0	, 0 },	/* E6 */
-    {  data1,   axImp, NOT_HLL | NO_SRC	, iOUT	, 0	, 0 },	/* E7 */
-    {  dispN,   none2, 0					, iCALL	, 0	, 0 },	/* E8 */
-    {  dispN,   none2, 0					, iJMP	, 0	, 0 },	/* E9 */
-    {  dispF,   none2, 0					, iJMPF	, 0	, 0 },	/* EA */
-    {  dispS,   none2, 0					, iJMP	, 0	, 0 },	/* EB */
-    {  none1,   axImp, NOT_HLL | B|NO_SRC , iIN	, 0	, 0 },	/* EC */
-    {  none1,   axImp, NOT_HLL | NO_SRC	, iIN	, 0	, 0 },	/* ED */
-    {  none1,   axImp, NOT_HLL | B|NO_SRC , iOUT	, 0	, 0 },	/* EE */
-    {  none1,   axImp, NOT_HLL | NO_SRC	, iOUT	, 0	, 0 },	/* EF */
-    {  none1,   none2, NOT_HLL | NO_OPS	, iLOCK	, 0	, 0 },	/* F0 */
-    {  none1,   none2, 0					, iZERO	, 0	, 0 },	/* F1 */
-    { prefix,   none2, 0					, iREPNE, 0	, 0 },	/* F2 */
-    { prefix,   none2, 0					, iREPE	, 0	, 0 },	/* F3 */
-    {  none1,   none2, NOT_HLL | NO_OPS	, iHLT	, 0	, 0 },	/* F4 */
-    {  none1,   none2, NO_OPS				, iCMC	, Cf, Cf			},	/* F5 */
-    {  arith,   none1, B					, iZERO	, 0	, 0 },	/* F6 */
-    {  arith,   none1, NSP				, iZERO	, 0	, 0 },	/* F7 */
-    {  none1,   none2, NO_OPS				, iCLC	, Cf, 0 },	/* F8 */
-    {  none1,   none2, NO_OPS				, iSTC	, Cf, 0 },	/* F9 */
-    {  none1,   none2, NOT_HLL | NO_OPS	, iCLI	, 0	, 0 },	/* FA */
-    {  none1,   none2, NOT_HLL | NO_OPS	, iSTI	, 0	, 0 },	/* FB */
-    {  none1,   none2, NO_OPS				, iCLD	, Df, 0 },	/* FC */
-    {  none1,   none2, NO_OPS				, iSTD	, Df, 0 },	/* FD */
-    {  trans,   none1, B					, iZERO	, 0	, 0 },	/* FE */
-    {  trans,   none1, NSP				, iZERO	, 0	, 0 }	/* FF */
+    {  modrm,   none2, B                        , iADD	},  /* 00 */
+    {  modrm,   none2, 0                        , iADD	},  /* 01 */
+    {  modrm,   none2, TO_REG | B               , iADD	},  /* 02 */
+    {  modrm,   none2, TO_REG 			, iADD	},  /* 03 */
+    {  data1,   axImp, B                        , iADD	},  /* 04 */
+    {  data2,   axImp, 0                        , iADD	},  /* 05 */
+    {  segop,   none2, NO_SRC                   , iPUSH	},  /* 06 */
+    {  segop,   none2, NO_SRC 			, iPOP	},  /* 07 */
+    {  modrm,   none2, B                        , iOR	},  /* 08 */
+    {  modrm,   none2, NSP                      , iOR	},  /* 09 */
+    {  modrm,   none2, TO_REG | B               , iOR	},  /* 0A */
+    {  modrm,   none2, TO_REG | NSP		, iOR	},  /* 0B */
+    {  data1,   axImp, B                        , iOR	},  /* 0C */
+    {  data2,   axImp, 0                        , iOR	},	/* 0D */
+    {  segop,   none2, NO_SRC                   , iPUSH	},	/* 0E */
+    {  none1,   none2, OP386                    , iZERO },	/* 0F */
+    {  modrm,   none2, B                        , iADC	},	/* 10 */
+    {  modrm,   none2, NSP                      , iADC	},	/* 11 */
+    {  modrm,   none2, TO_REG | B               , iADC	},	/* 12 */
+    {  modrm,   none2, TO_REG | NSP		, iADC	},	/* 13 */
+    {  data1,   axImp, B                        , iADC	},	/* 14 */
+    {  data2,   axImp, 0			, iADC	},	/* 15 */
+    {  segop,   none2, NOT_HLL | NO_SRC         , iPUSH	},	/* 16 */
+    {  segop,   none2, NOT_HLL | NO_SRC         , iPOP	},	/* 17 */
+    {  modrm,   none2, B			, iSBB	},	/* 18 */
+    {  modrm,   none2, NSP                      , iSBB	},	/* 19 */
+    {  modrm,   none2, TO_REG | B               , iSBB	},	/* 1A */
+    {  modrm,   none2, TO_REG | NSP		, iSBB	},	/* 1B */
+    {  data1,   axImp, B            		, iSBB	},	/* 1C */
+    {  data2,   axImp, 0                        , iSBB  },	/* 1D */
+    {  segop,   none2, NO_SRC                   , iPUSH	},	/* 1E */
+    {  segop,   none2, NO_SRC                   , iPOP	},	/* 1F */
+    {  modrm,   none2, B                        , iAND	},	/* 20 */
+    {  modrm,   none2, NSP                      , iAND	},	/* 21 */
+    {  modrm,   none2, TO_REG | B               , iAND	},	/* 22 */
+    {  modrm,   none2, TO_REG | NSP             , iAND	},	/* 23 */
+    {  data1,   axImp, B                        , iAND	},	/* 24 */
+    {  data2,   axImp, 0                        , iAND	},	/* 25 */
+    { prefix,   none2, 0                        , (IC)rES},	/* 26 */
+    {  none1,   axImp, NOT_HLL | B|NO_SRC	, iDAA	},	/* 27 */
+    {  modrm,   none2, B                        , iSUB	},	/* 28 */
+    {  modrm,   none2, 0                        , iSUB	},	/* 29 */
+    {  modrm,   none2, TO_REG | B               , iSUB	},	/* 2A */
+    {  modrm,   none2, TO_REG                   , iSUB	},	/* 2B */
+    {  data1,   axImp, B                        , iSUB	},	/* 2C */
+    {  data2,   axImp, 0                        , iSUB	},	/* 2D */
+    { prefix,   none2, 0                        , (IC)rCS},	/* 2E */
+    {  none1,   axImp, NOT_HLL | B|NO_SRC       , iDAS  },	/* 2F */
+    {  modrm,   none2, B                        , iXOR  },	/* 30 */
+    {  modrm,   none2, NSP                      , iXOR  },	/* 31 */
+    {  modrm,   none2, TO_REG | B               , iXOR  },	/* 32 */
+    {  modrm,   none2, TO_REG | NSP             , iXOR  },	/* 33 */
+    {  data1,   axImp, B                        , iXOR	},	/* 34 */
+    {  data2,   axImp, 0                        , iXOR	},	/* 35 */
+    { prefix,   none2, 0                        , (IC)rSS},	/* 36 */
+    {  none1,   axImp, NOT_HLL | NO_SRC         , iAAA  },	/* 37 */
+    {  modrm,   none2, B                        , iCMP	},	/* 38 */
+    {  modrm,   none2, NSP                      , iCMP	},	/* 39 */
+    {  modrm,   none2, TO_REG | B               , iCMP	},	/* 3A */
+    {  modrm,   none2, TO_REG | NSP             , iCMP	},	/* 3B */
+    {  data1,   axImp, B                        , iCMP	},	/* 3C */
+    {  data2,   axImp, 0                        , iCMP	},	/* 3D */
+    { prefix,   none2, 0                        , (IC)rDS},	/* 3E */
+    {  none1,   axImp, NOT_HLL | NO_SRC         , iAAS  },	/* 3F */
+    {  regop,   none2, 0                        , iINC	},	/* 40 */
+    {  regop,   none2, 0                        , iINC	},	/* 41 */
+    {  regop,   none2, 0                        , iINC	},	/* 42 */
+    {  regop,   none2, 0                        , iINC	},	/* 43 */
+    {  regop,   none2, NOT_HLL			, iINC	},	/* 44 */
+    {  regop,   none2, 0                        , iINC	},	/* 45 */
+    {  regop,   none2, 0                        , iINC	},	/* 46 */
+    {  regop,   none2, 0                        , iINC	},	/* 47 */
+    {  regop,   none2, 0                        , iDEC	},	/* 48 */
+    {  regop,   none2, 0                        , iDEC	},	/* 49 */
+    {  regop,   none2, 0                        , iDEC	},	/* 4A */
+    {  regop,   none2, 0                        , iDEC	},	/* 4B */
+    {  regop,   none2, NOT_HLL			, iDEC	},	/* 4C */
+    {  regop,   none2, 0                        , iDEC	},	/* 4D */
+    {  regop,   none2, 0                        , iDEC	},	/* 4E */
+    {  regop,   none2, 0                        , iDEC	},	/* 4F */
+    {  regop,   none2, NO_SRC                   , iPUSH },	/* 50 */
+    {  regop,   none2, NO_SRC                   , iPUSH },	/* 51 */
+    {  regop,   none2, NO_SRC                   , iPUSH },	/* 52 */
+    {  regop,   none2, NO_SRC                   , iPUSH },	/* 53 */
+    {  regop,   none2, NOT_HLL | NO_SRC         , iPUSH },	/* 54 */
+    {  regop,   none2, NO_SRC                   , iPUSH },	/* 55 */
+    {  regop,   none2, NO_SRC                   , iPUSH },	/* 56 */
+    {  regop,   none2, NO_SRC                   , iPUSH },	/* 57 */
+    {  regop,   none2, NO_SRC                   , iPOP  },	/* 58 */
+    {  regop,   none2, NO_SRC                   , iPOP  },	/* 59 */
+    {  regop,   none2, NO_SRC 			, iPOP  },	/* 5A */
+    {  regop,   none2, NO_SRC                   , iPOP	},	/* 5B */
+    {  regop,   none2, NOT_HLL | NO_SRC         , iPOP  },	/* 5C */
+    {  regop,   none2, NO_SRC                   , iPOP  },	/* 5D */
+    {  regop,   none2, NO_SRC                   , iPOP  },	/* 5E */
+    {  regop,   none2, NO_SRC                   , iPOP  },	/* 5F */
+    {  none1,   none2, NOT_HLL | NO_OPS         , iPUSHA},	/* 60 */
+    {  none1,   none2, NOT_HLL | NO_OPS         , iPOPA },	/* 61 */
+    { memOnly,  modrm, TO_REG | NSP		, iBOUND},	/* 62 */
+    {  none1,   none2, OP386                    , iZERO },	/* 63 */
+    {  none1,   none2, OP386                    , iZERO },	/* 64 */
+    {  none1,   none2, OP386                    , iZERO },	/* 65 */
+    {  none1,   none2, OP386                    , iZERO },	/* 66 */
+    {  none1,   none2, OP386                    , iZERO },	/* 67 */
+    {  data2,   none2, NO_SRC                   , iPUSH },	/* 68 */
+    {  modrm,   data2, TO_REG | NSP             , iIMUL },	/* 69 */
+    {  data1,   none2, S_EXT | NO_SRC           , iPUSH },	/* 6A */
+    {  modrm,   data1, TO_REG | NSP | S_EXT	, iIMUL },	/* 6B */
+    {  strop,  memImp, NOT_HLL | B|IM_OPS       , iINS  },	/* 6C */
+    {  strop,  memImp, NOT_HLL | IM_OPS         , iINS  },	/* 6D */
+    {  strop,  memImp, NOT_HLL | B|IM_OPS       , iOUTS },	/* 6E */
+    {  strop,  memImp, NOT_HLL | IM_OPS         , iOUTS },	/* 6F */
+    {  dispS,   none2, NOT_HLL			, iJO	},	/* 70 */
+    {  dispS,   none2, NOT_HLL			, iJNO	},	/* 71 */
+    {  dispS,   none2, 0                        , iJB	},	/* 72 */
+    {  dispS,   none2, 0                        , iJAE	},	/* 73 */
+    {  dispS,   none2, 0                        , iJE	},	/* 74 */
+    {  dispS,   none2, 0                        , iJNE	},	/* 75 */
+    {  dispS,   none2, 0                        , iJBE	},	/* 76 */
+    {  dispS,   none2, 0                        , iJA	},	/* 77 */
+    {  dispS,   none2, 0                        , iJS	},	/* 78 */
+    {  dispS,   none2, 0                        , iJNS	},	/* 79 */
+    {  dispS,   none2, NOT_HLL			, iJP	},	/* 7A */
+    {  dispS,   none2, NOT_HLL			, iJNP	},	/* 7B */
+    {  dispS,   none2, 0                        , iJL	},	/* 7C */
+    {  dispS,   none2, 0                        , iJGE	},	/* 7D */
+    {  dispS,   none2, 0                        , iJLE	},	/* 7E */
+    {  dispS,   none2, 0                        , iJG	},	/* 7F */
+    {  immed,   data1, B                        , iZERO	},	/* 80 */
+    {  immed,   data2, NSP                      , iZERO	},	/* 81 */
+    {  immed,   data1, B                        , iZERO	},	/* 82 */ /* ?? */
+    {  immed,   data1, NSP | S_EXT		, iZERO	},	/* 83 */
+    {  modrm,   none2, TO_REG | B		, iTEST	},	/* 84 */
+    {  modrm,   none2, TO_REG | NSP		, iTEST	},	/* 85 */
+    {  modrm,   none2, TO_REG | B               , iXCHG	},	/* 86 */
+    {  modrm,   none2, TO_REG | NSP		, iXCHG	},	/* 87 */
+    {  modrm,   none2, B                        , iMOV	},	/* 88 */
+    {  modrm,   none2, 0            		, iMOV	},	/* 89 */
+    {  modrm,   none2, TO_REG | B               , iMOV	},	/* 8A */
+    {  modrm,   none2, TO_REG 			, iMOV	},	/* 8B */
+    {  segrm,   none2, NSP                      , iMOV	},	/* 8C */
+    { memOnly,  modrm, TO_REG | NSP		, iLEA	},	/* 8D */
+    {  segrm,   none2, TO_REG | NSP		, iMOV	},	/* 8E */
+    { memReg0,  none2, NO_SRC                   , iPOP	},	/* 8F */
+    {   none1,  none2, NO_OPS                   , iNOP	},	/* 90 */
+    {  regop,   axImp, 0                        , iXCHG	},	/* 91 */
+    {  regop,   axImp, 0                        , iXCHG	},	/* 92 */
+    {  regop,   axImp, 0                        , iXCHG	},	/* 93 */
+    {  regop,   axImp, NOT_HLL			, iXCHG	},	/* 94 */
+    {  regop,   axImp, 0                        , iXCHG	},	/* 95 */
+    {  regop,   axImp, 0                        , iXCHG	},	/* 96 */
+    {  regop,   axImp, 0                        , iXCHG	},	/* 97 */
+    {  alImp,   axImp, SRC_B | S_EXT            , iSIGNEX},	/* 98 */
+    {axSrcIm,   axImp, IM_DST | S_EXT           , iSIGNEX},	/* 99 */
+    {  dispF,   none2, 0                        , iCALLF },	/* 9A */
+    {  none1,   none2, FLOAT_OP| NO_OPS         , iWAIT	},	/* 9B */
+    {  none1,   none2, NOT_HLL | NO_OPS         , iPUSHF},	/* 9C */
+    {  none1,   none2, NOT_HLL | NO_OPS         , iPOPF	},	/* 9D */
+    {  none1,   none2, NOT_HLL | NO_OPS         , iSAHF	},	/* 9E */
+    {  none1,   none2, NOT_HLL | NO_OPS         , iLAHF	},	/* 9F */
+    {  dispM,   axImp, B                        , iMOV	},	/* A0 */
+    {  dispM,   axImp, 0                        , iMOV	},	/* A1 */
+    {  dispM,   axImp, TO_REG | B               , iMOV	},	/* A2 */
+    {  dispM,   axImp, TO_REG 			, iMOV	},	/* A3 */
+    {  strop,  memImp, B | IM_OPS               , iMOVS	},	/* A4 */
+    {  strop,  memImp, IM_OPS                   , iMOVS	},	/* A5 */
+    {  strop,  memImp, B | IM_OPS               , iCMPS	},	/* A6 */
+    {  strop,  memImp, IM_OPS                   , iCMPS	},	/* A7 */
+    {  data1,   axImp, B                        , iTEST	},	/* A8 */
+    {  data2,   axImp, 0                        , iTEST	},	/* A9 */
+    {  strop,  memImp, B | IM_OPS               , iSTOS	},	/* AA */
+    {  strop,  memImp, IM_OPS                   , iSTOS	},	/* AB */
+    {  strop,  memImp, B | IM_OPS               , iLODS	},	/* AC */
+    {  strop,  memImp, IM_OPS                   , iLODS	},	/* AD */
+    {  strop,  memImp, B | IM_OPS               , iSCAS	},	/* AE */
+    {  strop,  memImp, IM_OPS                   , iSCAS	},	/* AF */
+    {  regop,   data1, B                        , iMOV	},	/* B0 */
+    {  regop,   data1, B                        , iMOV	},	/* B1 */
+    {  regop,   data1, B                        , iMOV	},	/* B2 */
+    {  regop,   data1, B                        , iMOV	},	/* B3 */
+    {  regop,   data1, B                        , iMOV	},	/* B4 */
+    {  regop,   data1, B                        , iMOV	},	/* B5 */
+    {  regop,   data1, B                        , iMOV	},	/* B6 */
+    {  regop,   data1, B                        , iMOV	},	/* B7 */
+    {  regop,   data2, 0                        , iMOV	},	/* B8 */
+    {  regop,   data2, 0                        , iMOV	},	/* B9 */
+    {  regop,   data2, 0                        , iMOV	},	/* BA */
+    {  regop,   data2, 0                        , iMOV	},	/* BB */
+    {  regop,   data2, NOT_HLL			, iMOV	},	/* BC */
+    {  regop,   data2, 0                        , iMOV	},	/* BD */
+    {  regop,   data2, 0                        , iMOV	},	/* BE */
+    {  regop,   data2, 0                        , iMOV	},	/* BF */
+    {  shift,   data1, B                        , iZERO	},	/* C0 */
+    {  shift,   data1, NSP | SRC_B		, iZERO	},	/* C1 */
+    {  data2,   none2, 0                        , iRET	},	/* C2 */
+    {  none1,   none2, NO_OPS                   , iRET	},	/* C3 */
+    { memOnly,  modrm, TO_REG | NSP		, iLES	},	/* C4 */
+    { memOnly,  modrm, TO_REG | NSP		, iLDS	},	/* C5 */
+    { memReg0,  data1, B                        , iMOV	},	/* C6 */
+    { memReg0,  data2, 0			, iMOV	},	/* C7 */
+    {  data2,   data1, 0                        , iENTER},	/* C8 */
+    {  none1,   none2, NO_OPS                   , iLEAVE},	/* C9 */
+    {  data2,   none2, 0                        , iRETF	},	/* CA */
+    {  none1,   none2, NO_OPS                   , iRETF	},	/* CB */
+    { const3,   none2, NOT_HLL			, iINT	},	/* CC */
+    {  data1,checkInt, NOT_HLL			, iINT	},	/* CD */
+    {  none1,   none2, NOT_HLL | NO_OPS         , iINTO	},	/* CE */
+    {  none1,   none2, NOT_HLL | NO_OPS         , iIRET	},	/* Cf */
+    {  shift,  const1, B                        , iZERO	},	/* D0 */
+    {  shift,  const1, SRC_B                    , iZERO	},	/* D1 */
+    {  shift,   none1, B                        , iZERO	},	/* D2 */
+    {  shift,   none1, SRC_B                    , iZERO	},	/* D3 */
+    {  data1,   axImp, NOT_HLL			, iAAM	},	/* D4 */
+    {  data1,   axImp, NOT_HLL			, iAAD	},	/* D5 */
+    {  none1,   none2, 0                        , iZERO	},	/* D6 */
+    { memImp,   axImp, NOT_HLL | B| IM_OPS      , iXLAT	},	/* D7 */
+    {  escop,   none2, FLOAT_OP			, iESC	},	/* D8 */
+    {  escop,   none2, FLOAT_OP			, iESC	},	/* D9 */
+    {  escop,   none2, FLOAT_OP			, iESC	},	/* DA */
+    {  escop,   none2, FLOAT_OP			, iESC	},	/* DB */
+    {  escop,   none2, FLOAT_OP			, iESC	},	/* DC */
+    {  escop,   none2, FLOAT_OP			, iESC	},	/* DD */
+    {  escop,   none2, FLOAT_OP			, iESC	},	/* DE */
+    {  escop,   none2, FLOAT_OP			, iESC	},	/* Df */
+    {  dispS,   none2, 0                        , iLOOPNE},	/* E0 */
+    {  dispS,   none2, 0                        , iLOOPE},	/* E1 */
+    {  dispS,   none2, 0                        , iLOOP	},	/* E2 */
+    {  dispS,   none2, 0                        , iJCXZ	},	/* E3 */
+    {  data1,   axImp, NOT_HLL | B|NO_SRC       , iIN	},	/* E4 */
+    {  data1,   axImp, NOT_HLL | NO_SRC         , iIN	},	/* E5 */
+    {  data1,   axImp, NOT_HLL | B|NO_SRC       , iOUT	},	/* E6 */
+    {  data1,   axImp, NOT_HLL | NO_SRC         , iOUT	},	/* E7 */
+    {  dispN,   none2, 0                        , iCALL	},	/* E8 */
+    {  dispN,   none2, 0                        , iJMP	},	/* E9 */
+    {  dispF,   none2, 0                        , iJMPF	},	/* EA */
+    {  dispS,   none2, 0                        , iJMP	},	/* EB */
+    {  none1,   axImp, NOT_HLL | B|NO_SRC       , iIN	},	/* EC */
+    {  none1,   axImp, NOT_HLL | NO_SRC         , iIN	},	/* ED */
+    {  none1,   axImp, NOT_HLL | B|NO_SRC       , iOUT	},	/* EE */
+    {  none1,   axImp, NOT_HLL | NO_SRC         , iOUT	},	/* EF */
+    {  none1,   none2, NOT_HLL | NO_OPS         , iLOCK	},	/* F0 */
+    {  none1,   none2, 0                        , iZERO	},	/* F1 */
+    { prefix,   none2, 0                        , iREPNE},	/* F2 */
+    { prefix,   none2, 0                        , iREPE	},	/* F3 */
+    {  none1,   none2, NOT_HLL | NO_OPS         , iHLT	},	/* F4 */
+    {  none1,   none2, NO_OPS                   , iCMC	},	/* F5 */
+    {  arith,   none1, B                        , iZERO	},	/* F6 */
+    {  arith,   none1, NSP			, iZERO	},	/* F7 */
+    {  none1,   none2, NO_OPS                   , iCLC	},	/* F8 */
+    {  none1,   none2, NO_OPS                   , iSTC	},	/* F9 */
+    {  none1,   none2, NOT_HLL | NO_OPS         , iCLI	},	/* FA */
+    {  none1,   none2, NOT_HLL | NO_OPS         , iSTI	},	/* FB */
+    {  none1,   none2, NO_OPS                   , iCLD	},	/* FC */
+    {  none1,   none2, NO_OPS                   , iSTD	},	/* FD */
+    {  trans,   none1, B                        , iZERO	},	/* FE */
+    {  trans,   none1, NSP                      , iZERO	}	/* FF */
 } ;
 } ;
 
 
 static uint16_t    SegPrefix, RepPrefix;
 static uint16_t    SegPrefix, RepPrefix;
@@ -325,6 +322,94 @@ static ICODE * pIcode;		/* Ptr to Icode record filled in by scan() */
  Scans one machine instruction at offset ip in prog.Image and returns error.
  Scans one machine instruction at offset ip in prog.Image and returns error.
  At the same time, fill in low-level icode details for the scanned inst.
  At the same time, fill in low-level icode details for the scanned inst.
  ****************************************************************************/
  ****************************************************************************/
+
+static void convertUsedFlags(x86_insn_t &from,ICODE &to)
+{
+    to.ll()->flagDU.d=0;
+    to.ll()->flagDU.u=0;
+    if(from.containsFlag(insn_eflag_carry,from.flags_set))
+        to.ll()->flagDU.d |= Cf;
+    if(from.containsFlag(insn_eflag_sign,from.flags_set))
+        to.ll()->flagDU.d |= Sf;
+    if(from.containsFlag(insn_eflag_zero,from.flags_set))
+        to.ll()->flagDU.d |= Zf;
+    if(from.containsFlag(insn_eflag_direction,from.flags_set))
+        to.ll()->flagDU.d |= Df;
+
+    if(from.containsFlag(insn_eflag_carry,from.flags_tested))
+        to.ll()->flagDU.u |= Cf;
+    if(from.containsFlag(insn_eflag_sign,from.flags_tested))
+        to.ll()->flagDU.u |= Sf;
+    if(from.containsFlag(insn_eflag_zero,from.flags_tested))
+        to.ll()->flagDU.u |= Zf;
+    if(from.containsFlag(insn_eflag_direction,from.flags_tested))
+        to.ll()->flagDU.u |= Df;
+}
+/****************************************************************************
+ Checks for int 34 to int 3B - if so, converts to ESC nn instruction
+ ****************************************************************************/
+static void fixFloatEmulation(x86_insn_t &insn)
+{
+    if(insn.group!=x86_insn_t::insn_interrupt)
+        return;
+    PROG &prog(Project::get()->prog);
+    uint16_t wOp=insn.x86_get_imm()->data.word;
+    if ((wOp < 0x34) || (wOp > 0x3B))
+        return;
+    uint8_t buf[16];
+    /* This is a Borland/Microsoft floating point emulation instruction.
+       Treat as if it is an ESC opcode */
+
+    int actual_valid_bytes=std::min(16U,prog.cbImage-insn.offset);
+    memcpy(buf,prog.Image+insn.offset,actual_valid_bytes);
+    X86_Disasm ds(opt_16_bit);
+    x86_insn_t patched_insn;
+    //patch actual instruction into buffer;
+    buf[1] = wOp-0x34+0xD8;
+    ds.x86_disasm(buf,actual_valid_bytes,0,1,&patched_insn);
+    patched_insn.addr   = insn.addr; // actual address
+    patched_insn.offset = insn.offset; // actual offset
+    insn = patched_insn;
+    insn.size += 1; // to account for emulator call INT
+}
+
+int disassembleOneLibDisasm(uint32_t ip,x86_insn_t &l)
+{
+    PROG &prog(Project::get()->prog);
+    X86_Disasm ds(opt_16_bit);
+    int cnt=ds.x86_disasm(prog.Image,prog.cbImage,0,ip,&l);
+    if(cnt && l.is_valid())
+    {
+        fixFloatEmulation(l); //can change 'l'
+    }
+    if(l.is_valid())
+        return l.size;
+    return 0;
+}
+eReg convertRegister(const x86_reg_t &reg)
+{
+
+    eReg regmap[]={ rUNDEF,
+                    rUNDEF,rUNDEF,rUNDEF,rUNDEF,   //eax ecx ebx edx
+                    rUNDEF,rUNDEF,rUNDEF,rUNDEF,   //esp ebp esi edi
+                    rAX,rCX,rDX,rBX,
+                    rSP,rBP,rSI,rDI,
+                    rAL,rCL,rDL,rBL,
+                    rAH,rCH,rDH,rBH
+                  };
+    assert(reg.id<sizeof(regmap)/sizeof(eReg));
+    return regmap[reg.id];
+}
+LLOperand convertOperand(const x86_op_t &from)
+{
+    switch(from.type)
+    {
+        case op_unused:
+            break;
+        case op_register:
+            return LLOperand::CreateReg2(convertRegister(from.data.reg));
+    }
+}
 eErrorId scan(uint32_t ip, ICODE &p)
 eErrorId scan(uint32_t ip, ICODE &p)
 {
 {
     PROG &prog(Project::get()->prog);
     PROG &prog(Project::get()->prog);
@@ -336,6 +421,11 @@ eErrorId scan(uint32_t ip, ICODE &p)
     {
     {
         return (IP_OUT_OF_RANGE);
         return (IP_OUT_OF_RANGE);
     }
     }
+    int cnt=disassembleOneLibDisasm(ip,p.insn);
+    if(cnt)
+    {
+        convertUsedFlags(p.insn,p);
+    }
 
 
     SegPrefix = RepPrefix = 0;
     SegPrefix = RepPrefix = 0;
     pInst    = prog.Image + ip;
     pInst    = prog.Image + ip;
@@ -344,20 +434,18 @@ eErrorId scan(uint32_t ip, ICODE &p)
     do
     do
     {
     {
         op = *pInst++;						/* First state - trivial   */
         op = *pInst++;						/* First state - trivial   */
-          /* Convert to Icode.opcode */
+        /* Convert to Icode.opcode */
         p.ll()->set(stateTable[op].opcode,stateTable[op].flg & ICODEMASK);
         p.ll()->set(stateTable[op].opcode,stateTable[op].flg & ICODEMASK);
-        p.ll()->flagDU.d = stateTable[op].df;
-        p.ll()->flagDU.u = stateTable[op].uf;
-
         (*stateTable[op].state1)(op);		/* Second state */
         (*stateTable[op].state1)(op);		/* Second state */
         (*stateTable[op].state2)(op);		/* Third state  */
         (*stateTable[op].state2)(op);		/* Third state  */
 
 
     } while (stateTable[op].state1 == prefix);	/* Loop if prefix */
     } while (stateTable[op].state1 == prefix);	/* Loop if prefix */
-
     if (p.ll()->getOpcode())
     if (p.ll()->getOpcode())
     {
     {
         /* Save bytes of image used */
         /* Save bytes of image used */
         p.ll()->numBytes = (uint8_t)((pInst - prog.Image) - ip);
         p.ll()->numBytes = (uint8_t)((pInst - prog.Image) - ip);
+        if(p.insn.is_valid())
+            assert(p.ll()->numBytes == p.insn.size);
         return ((SegPrefix)? FUNNY_SEGOVR:  /* Seg. Override invalid */
         return ((SegPrefix)? FUNNY_SEGOVR:  /* Seg. Override invalid */
                              (RepPrefix ? FUNNY_REP: NO_ERR));/* REP prefix invalid */
                              (RepPrefix ? FUNNY_REP: NO_ERR));/* REP prefix invalid */
     }
     }
@@ -365,7 +453,6 @@ eErrorId scan(uint32_t ip, ICODE &p)
     return ((stateTable[op].flg & OP386)? INVALID_386OP: INVALID_OPCODE);
     return ((stateTable[op].flg & OP386)? INVALID_386OP: INVALID_OPCODE);
 }
 }
 
 
-
 /***************************************************************************
 /***************************************************************************
  relocItem - returns true if uint16_t pointed at is in relocation table
  relocItem - returns true if uint16_t pointed at is in relocation table
  **************************************************************************/
  **************************************************************************/
@@ -519,7 +606,7 @@ static void regop(int i)
 {
 {
     setAddress(i, false, 0, ((int16_t)i & 7) + rAX, 0);
     setAddress(i, false, 0, ((int16_t)i & 7) + rAX, 0);
     pIcode->ll()->replaceDst(LLOperand::CreateReg2(pIcode->ll()->src().getReg2()));
     pIcode->ll()->replaceDst(LLOperand::CreateReg2(pIcode->ll()->src().getReg2()));
-//    pIcode->ll()->dst.regi = pIcode->ll()->src.regi;
+    //    pIcode->ll()->dst.regi = pIcode->ll()->src.regi;
 }
 }
 
 
 
 
@@ -590,11 +677,8 @@ static void memReg0(int i)
 static void immed(int i)
 static void immed(int i)
 {
 {
     static llIcode immedTable[8] = {iADD, iOR, iADC, iSBB, iAND, iSUB, iXOR, iCMP};
     static llIcode immedTable[8] = {iADD, iOR, iADC, iSBB, iAND, iSUB, iXOR, iCMP};
-    static uint8_t uf[8] = { 0,  0,  Cf,  Cf,  0,   0,   0,   0  };
 
 
     pIcode->ll()->setOpcode(immedTable[REG(*pInst)]) ;
     pIcode->ll()->setOpcode(immedTable[REG(*pInst)]) ;
-    pIcode->ll()->flagDU.u = uf[REG(*pInst)];
-    pIcode->ll()->flagDU.d = (Sf | Zf | Cf);
     rm(i);
     rm(i);
 
 
     if (pIcode->ll()->getOpcode() == iADD || pIcode->ll()->getOpcode() == iSUB)
     if (pIcode->ll()->getOpcode() == iADD || pIcode->ll()->getOpcode() == iSUB)
@@ -611,13 +695,8 @@ static void shift(int i)
     {
     {
         (llIcode)iROL, (llIcode)iROR, (llIcode)iRCL, (llIcode)iRCR,
         (llIcode)iROL, (llIcode)iROR, (llIcode)iRCL, (llIcode)iRCR,
         (llIcode)iSHL, (llIcode)iSHR, (llIcode)0,	 (llIcode)iSAR};
         (llIcode)iSHL, (llIcode)iSHR, (llIcode)0,	 (llIcode)iSAR};
-    static uint8_t uf[8]	  = {0,   0,   Cf,  Cf,  0,   0,   0, 0  };
-    static uint8_t df[8]	  = {Cf,  Cf,  Cf,  Cf, Sf | Zf | Cf,
-                             Sf | Zf | Cf, 0, Sf | Zf | Cf};
 
 
     pIcode->ll()->setOpcode(shiftTable[REG(*pInst)]);
     pIcode->ll()->setOpcode(shiftTable[REG(*pInst)]);
-    pIcode->ll()->flagDU.u = uf[REG(*pInst)];
-    pIcode->ll()->flagDU.d = df[REG(*pInst)];
     rm(i);
     rm(i);
     pIcode->ll()->replaceSrc(rCL); //src.regi =
     pIcode->ll()->replaceSrc(rCL); //src.regi =
 }
 }
@@ -633,11 +712,9 @@ static void trans(int i)
         (llIcode)iINC, (llIcode)iDEC, (llIcode)iCALL, (llIcode)iCALLF,
         (llIcode)iINC, (llIcode)iDEC, (llIcode)iCALL, (llIcode)iCALLF,
         (llIcode)iJMP, (llIcode)iJMPF,(llIcode)iPUSH, (llIcode)0
         (llIcode)iJMP, (llIcode)iJMPF,(llIcode)iPUSH, (llIcode)0
     };
     };
-    static uint8_t df[8]	= {Sf | Zf, Sf | Zf, 0, 0, 0, 0, 0, 0};
     LLInst *ll = pIcode->ll();
     LLInst *ll = pIcode->ll();
     if ((uint8_t)REG(*pInst) < 2 || !(stateTable[i].flg & B)) { /* INC & DEC */
     if ((uint8_t)REG(*pInst) < 2 || !(stateTable[i].flg & B)) { /* INC & DEC */
         ll->setOpcode(transTable[REG(*pInst)]);   /* valid on bytes */
         ll->setOpcode(transTable[REG(*pInst)]);   /* valid on bytes */
-        ll->flagDU.d = df[REG(*pInst)];
         rm(i);
         rm(i);
         ll->replaceSrc( pIcode->ll()->dst );
         ll->replaceSrc( pIcode->ll()->dst );
         if (ll->match(iJMP) || ll->match(iCALL) || ll->match(iCALLF))
         if (ll->match(iJMP) || ll->match(iCALL) || ll->match(iCALLF))
@@ -659,12 +736,8 @@ static void arith(int i)
         iTEST , (llIcode)0, iNOT, iNEG,
         iTEST , (llIcode)0, iNOT, iNEG,
         iMUL ,       iIMUL, iDIV, iIDIV
         iMUL ,       iIMUL, iDIV, iIDIV
     };
     };
-    static uint8_t df[8]	  = {Sf | Zf | Cf, 0, 0, Sf | Zf | Cf,
-                             Sf | Zf | Cf, Sf | Zf | Cf, Sf | Zf | Cf,
-                             Sf | Zf | Cf};
     opcode = arithTable[REG(*pInst)];
     opcode = arithTable[REG(*pInst)];
     pIcode->ll()->setOpcode((llIcode)opcode);
     pIcode->ll()->setOpcode((llIcode)opcode);
-    pIcode->ll()->flagDU.d = df[REG(*pInst)];
     rm(i);
     rm(i);
     if (opcode == iTEST)
     if (opcode == iTEST)
     {
     {