Pre branch commit
This commit is contained in:
parent
fee4d6fe9a
commit
9cc5202ff7
@ -150,7 +150,7 @@ public:
|
||||
void findImmedDom();
|
||||
void FollowCtrl(CALL_GRAPH *pcallGraph, 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);
|
||||
void freeCFG();
|
||||
void codeGen(std::ostream &fs);
|
||||
@ -168,6 +168,8 @@ public:
|
||||
|
||||
void preprocessReturnDU(std::bitset<32> &_liveOut);
|
||||
protected:
|
||||
void extractJumpTableRange(ICODE& pIcode, STATE *pstate, JumpTable &table);
|
||||
bool followAllTableEntries(JumpTable &table, uint32_t cs, ICODE &pIcode, CALL_GRAPH *pcallGraph, STATE *pstate);
|
||||
bool removeInEdge_Flag_and_ProcessLatch(BB *pbb, BB *a, BB *b);
|
||||
bool Case_X_and_Y(BB* pbb, BB* thenBB, BB* elseBB);
|
||||
bool Case_X_or_Y(BB* pbb, BB* thenBB, BB* elseBB);
|
||||
|
||||
@ -62,8 +62,6 @@ typedef struct { /* Command line option flags */
|
||||
extern OPTION option; /* Command line options */
|
||||
|
||||
#include "BinaryImage.h"
|
||||
|
||||
//extern PROG prog; /* Loaded program image parameters */
|
||||
extern std::bitset<32> duReg[30]; /* def/use bits for registers */
|
||||
|
||||
//extern uint32_t duReg[30]; /* def/use bits for registers */
|
||||
|
||||
@ -31,7 +31,7 @@ struct bundle;
|
||||
typedef std::list<ICODE>::iterator iICODE;
|
||||
typedef std::list<ICODE>::reverse_iterator riICODE;
|
||||
typedef boost::iterator_range<iICODE> rCODE;
|
||||
|
||||
extern std::bitset<32> duReg[30];
|
||||
/* uint8_t and uint16_t registers */
|
||||
|
||||
/* Def/use of flags - low 4 bits represent flags */
|
||||
@ -214,19 +214,15 @@ struct LLInst : public llvm::MCInst //: public llvm::ilist_node<LLInst>
|
||||
{
|
||||
protected:
|
||||
uint32_t flg; /* icode flags */
|
||||
// llIcode opcode; /* llIcode instruction */
|
||||
LLOperand m_src; /* source operand */
|
||||
public:
|
||||
int codeIdx; /* Index into cCode.code */
|
||||
uint8_t numBytes; /* Number of bytes this instr */
|
||||
uint32_t label; /* offset in image (20-bit adr) */
|
||||
LLOperand dst; /* destination operand */
|
||||
LLOperand m_src; /* source operand */
|
||||
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 */
|
||||
bool conditionalJump()
|
||||
{
|
||||
@ -295,8 +291,6 @@ public:
|
||||
HLTYPE createCall();
|
||||
LLInst(ICODE *container) : flg(0),codeIdx(0),numBytes(0),m_link(container)
|
||||
{
|
||||
caseTbl.entries=0;
|
||||
caseTbl.numEntries=0;
|
||||
setOpcode(0);
|
||||
}
|
||||
const LLOperand &src() const {return m_src;}
|
||||
@ -322,6 +316,7 @@ public:
|
||||
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; }
|
||||
};
|
||||
@ -370,6 +365,12 @@ public:
|
||||
std::bitset<32> def; // For Registers: position in bitset is reg index
|
||||
std::bitset<32> use; // For Registers: position in uint32_t is reg index
|
||||
std::bitset<32> lastDefRegi;// Bit set if last def of this register in BB
|
||||
void addDefinedAndUsed(eReg r)
|
||||
{
|
||||
def |= duReg[r];
|
||||
use |= duReg[r];
|
||||
|
||||
}
|
||||
};
|
||||
struct DU1
|
||||
{
|
||||
|
||||
@ -46,7 +46,7 @@ enum eReg
|
||||
class SourceMachine
|
||||
{
|
||||
public:
|
||||
// virtual bool physicalReg(eReg r)=0;
|
||||
virtual bool physicalReg(eReg r)=0;
|
||||
|
||||
};
|
||||
//class Machine_X86_Disassembler
|
||||
@ -61,7 +61,7 @@ public:
|
||||
static const std::string ®Name(eReg r);
|
||||
static const std::string &opcodeName(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 */
|
||||
//TODO: move this into Machine_X86 ?
|
||||
static void writeRegVector (std::ostream &ostr,const std::bitset<32> ®i)
|
||||
|
||||
@ -424,11 +424,11 @@ COND_EXPR *COND_EXPR::id(const LLInst &ll_insn, opLoc sd, Function * pProc, iICO
|
||||
|
||||
|
||||
/* 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);
|
||||
else if (pm.regi == 0)
|
||||
return (GLOB_VAR);
|
||||
|
||||
@ -23,6 +23,9 @@ void strTable::addLabelBundle (int idx, int label)
|
||||
{
|
||||
char s[16];
|
||||
sprintf (s, "l%d: ", label);
|
||||
if(at(idx).size()<4)
|
||||
at(idx)=s;
|
||||
else
|
||||
at(idx) = string(s)+at(idx).substr(4);
|
||||
}
|
||||
|
||||
|
||||
@ -71,7 +71,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 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 int checkScanned(uint32_t pcCur);
|
||||
@ -492,7 +492,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
|
||||
{
|
||||
if (inst.testFlags(CASE))
|
||||
{
|
||||
result_stream << ";Case l"<< inst.caseTbl.numEntries;
|
||||
result_stream << ";Case l"<< inst.caseEntry;
|
||||
}
|
||||
if (inst.testFlags(SWITCH))
|
||||
{
|
||||
@ -589,7 +589,7 @@ static void formatRM(std::ostringstream &p, uint32_t flg, const LLOperand &pm)
|
||||
/*****************************************************************************
|
||||
* 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 */
|
||||
//os << setw(WID_PTR);
|
||||
|
||||
@ -84,9 +84,9 @@ CondJumps:
|
||||
if (ll->testFlags(SWITCH))
|
||||
{
|
||||
//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;
|
||||
}
|
||||
else if ((ll->getFlag() & (I | NO_LABEL)) == I) //TODO: WHY NO_LABEL TESTIT
|
||||
@ -173,15 +173,14 @@ CondJumps:
|
||||
void Function::markImpure()
|
||||
{
|
||||
PROG &prog(Project::get()->prog);
|
||||
SYM * psym;
|
||||
for(ICODE &icod : Icode)
|
||||
{
|
||||
if ( not icod.ll()->testFlags(SYM_USE | SYM_DEF))
|
||||
continue;
|
||||
//assert that case tbl has less entries then symbol table ????
|
||||
//WARNING: Case entries are held in symbol table !
|
||||
assert(g_proj.validSymIdx(icod.ll()->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++)
|
||||
{
|
||||
if (BITMAP(c, BM_CODE))
|
||||
|
||||
@ -223,8 +223,6 @@ void Function::bindIcodeOff()
|
||||
{
|
||||
|
||||
iICODE pIcode; /* ptr icode array */
|
||||
uint32_t *p; /* for case table */
|
||||
|
||||
if (Icode.empty()) /* No Icode */
|
||||
return;
|
||||
pIcode = Icode.begin();
|
||||
@ -261,9 +259,9 @@ void Function::bindIcodeOff()
|
||||
}
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,7 +22,7 @@ bool Idiom11::match (iICODE picode)
|
||||
return false;
|
||||
for(int i=0; i<3; ++i)
|
||||
m_icodes[i]=picode++;
|
||||
type = m_icodes[0]->idType(DST);
|
||||
type = m_icodes[0]->ll()->idType(DST);
|
||||
if(type==CONSTANT || type == OTHER)
|
||||
return false;
|
||||
/* Check NEG reg/mem
|
||||
|
||||
@ -231,7 +231,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
|
||||
case iJCXZ:
|
||||
{ STATE StCopy;
|
||||
int ip = Icode.size()-1; /* Index of this jump */
|
||||
ICODE &prev(Icode.back()); /* Previous icode */
|
||||
ICODE &prev(*(++Icode.rbegin())); /* Previous icode */
|
||||
boolT fBranch = false;
|
||||
|
||||
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 */
|
||||
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);
|
||||
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 Icode.labelSrch(i, tmp);
|
||||
return Icode.alreadyDecoded(i);
|
||||
}
|
||||
|
||||
/* 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(). */
|
||||
if (offTable < endTable)
|
||||
{
|
||||
assert(((endTable - offTable) / 2)<512);
|
||||
STATE StCopy;
|
||||
int ip;
|
||||
uint32_t *psw;
|
||||
@ -466,10 +507,7 @@ boolT Function::process_JMP (ICODE & pIcode, STATE *pstate, CALL_GRAPH * pcallGr
|
||||
setBits(BM_DATA, offTable, endTable - offTable);
|
||||
|
||||
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)
|
||||
{
|
||||
@ -480,9 +518,9 @@ boolT Function::process_JMP (ICODE & pIcode, STATE *pstate, CALL_GRAPH * pcallGr
|
||||
|
||||
FollowCtrl (pcallGraph, &StCopy);
|
||||
++last_current_insn;
|
||||
last_current_insn->ll()->caseTbl.numEntries = k++;
|
||||
last_current_insn->ll()->caseEntry = k++;
|
||||
last_current_insn->ll()->setFlags(CASE);
|
||||
*psw++ = last_current_insn->ll()->GetLlLabel();
|
||||
pIcode.ll()->caseTbl2.push_back( last_current_insn->ll()->GetLlLabel() );
|
||||
|
||||
}
|
||||
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);
|
||||
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);
|
||||
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
|
||||
* bitmap */
|
||||
extern LLOperand convertOperand(const x86_op_t &from);
|
||||
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;
|
||||
LLInst &ll_ins(*pIcode.ll());
|
||||
|
||||
int sseg = (ll_ins.src().seg)? ll_ins.src().seg: rDS;
|
||||
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()) {
|
||||
case iAND: case iOR: case iXOR:
|
||||
@ -1108,19 +1149,18 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate)
|
||||
break;
|
||||
|
||||
case iREPNE_CMPS: case iREPE_CMPS: case iREP_MOVS:
|
||||
pIcode.du.def |= duReg[rCX];
|
||||
pIcode.du.addDefinedAndUsed(rCX);
|
||||
pIcode.du1.numRegsDef++;
|
||||
pIcode.du.use |= duReg[rCX];
|
||||
case iCMPS: case iMOVS:
|
||||
pIcode.du.def |= duReg[rSI] | duReg[rDI];
|
||||
pIcode.du.addDefinedAndUsed(rSI);
|
||||
pIcode.du.addDefinedAndUsed(rDI);
|
||||
pIcode.du1.numRegsDef += 2;
|
||||
pIcode.du.use |= duReg[rSI] | duReg[rDI] | duReg[rES] | duReg[sseg];
|
||||
pIcode.du.use |= duReg[rES] | duReg[sseg];
|
||||
break;
|
||||
|
||||
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.du.use |= duReg[rCX];
|
||||
case iSCAS: case iSTOS: case iINS:
|
||||
pIcode.du.def |= duReg[rDI];
|
||||
pIcode.du1.numRegsDef++;
|
||||
@ -1135,23 +1175,22 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate)
|
||||
break;
|
||||
|
||||
case iREP_LODS:
|
||||
pIcode.du.def |= duReg[rCX];
|
||||
pIcode.du.addDefinedAndUsed(rCX);
|
||||
pIcode.du1.numRegsDef++;
|
||||
pIcode.du.use |= duReg[rCX];
|
||||
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.du.use |= duReg[rSI] | duReg[sseg];
|
||||
pIcode.du.use |= duReg[sseg];
|
||||
break;
|
||||
|
||||
case iREP_OUTS:
|
||||
pIcode.du.def |= duReg[rCX];
|
||||
pIcode.du.addDefinedAndUsed(rCX);
|
||||
pIcode.du1.numRegsDef++;
|
||||
pIcode.du.use |= duReg[rCX];
|
||||
case iOUTS:
|
||||
pIcode.du.def |= duReg[rSI];
|
||||
pIcode.du.addDefinedAndUsed(rSI);
|
||||
pIcode.du1.numRegsDef++;
|
||||
pIcode.du.use |= duReg[rSI] | duReg[rDX] | duReg[sseg];
|
||||
pIcode.du.use |= duReg[rDX] | duReg[sseg];
|
||||
break;
|
||||
|
||||
case iIN: case iOUT:
|
||||
@ -1163,7 +1202,7 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate)
|
||||
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))
|
||||
pstate->f[i] = false;
|
||||
}
|
||||
|
||||
629
src/scanner.cpp
629
src/scanner.cpp
@ -6,7 +6,6 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include "dcc.h"
|
||||
#include "scanner.h"
|
||||
#include "project.h"
|
||||
@ -55,265 +54,263 @@ static struct {
|
||||
void (*state2)(int);
|
||||
uint32_t flg;
|
||||
llIcode opcode;
|
||||
uint8_t df;
|
||||
uint8_t uf;
|
||||
} 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;
|
||||
@ -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.
|
||||
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 ®)
|
||||
{
|
||||
|
||||
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)
|
||||
{
|
||||
PROG &prog(Project::get()->prog);
|
||||
@ -336,6 +421,11 @@ eErrorId scan(uint32_t ip, ICODE &p)
|
||||
{
|
||||
return (IP_OUT_OF_RANGE);
|
||||
}
|
||||
int cnt=disassembleOneLibDisasm(ip,p.insn);
|
||||
if(cnt)
|
||||
{
|
||||
convertUsedFlags(p.insn,p);
|
||||
}
|
||||
|
||||
SegPrefix = RepPrefix = 0;
|
||||
pInst = prog.Image + ip;
|
||||
@ -346,18 +436,16 @@ eErrorId scan(uint32_t ip, ICODE &p)
|
||||
op = *pInst++; /* First state - trivial */
|
||||
/* Convert to Icode.opcode */
|
||||
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].state2)(op); /* Third state */
|
||||
|
||||
} while (stateTable[op].state1 == prefix); /* Loop if prefix */
|
||||
|
||||
if (p.ll()->getOpcode())
|
||||
{
|
||||
/* Save bytes of image used */
|
||||
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 */
|
||||
(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);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
relocItem - returns true if uint16_t pointed at is in relocation table
|
||||
**************************************************************************/
|
||||
@ -590,11 +677,8 @@ static void memReg0(int i)
|
||||
static void immed(int i)
|
||||
{
|
||||
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()->flagDU.u = uf[REG(*pInst)];
|
||||
pIcode->ll()->flagDU.d = (Sf | Zf | Cf);
|
||||
rm(i);
|
||||
|
||||
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)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()->flagDU.u = uf[REG(*pInst)];
|
||||
pIcode->ll()->flagDU.d = df[REG(*pInst)];
|
||||
rm(i);
|
||||
pIcode->ll()->replaceSrc(rCL); //src.regi =
|
||||
}
|
||||
@ -633,11 +712,9 @@ static void trans(int i)
|
||||
(llIcode)iINC, (llIcode)iDEC, (llIcode)iCALL, (llIcode)iCALLF,
|
||||
(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();
|
||||
if ((uint8_t)REG(*pInst) < 2 || !(stateTable[i].flg & B)) { /* INC & DEC */
|
||||
ll->setOpcode(transTable[REG(*pInst)]); /* valid on bytes */
|
||||
ll->flagDU.d = df[REG(*pInst)];
|
||||
rm(i);
|
||||
ll->replaceSrc( pIcode->ll()->dst );
|
||||
if (ll->match(iJMP) || ll->match(iCALL) || ll->match(iCALLF))
|
||||
@ -659,12 +736,8 @@ static void arith(int i)
|
||||
iTEST , (llIcode)0, iNOT, iNEG,
|
||||
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)];
|
||||
pIcode->ll()->setOpcode((llIcode)opcode);
|
||||
pIcode->ll()->flagDU.d = df[REG(*pInst)];
|
||||
rm(i);
|
||||
if (opcode == iTEST)
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user