Pre branch commit

This commit is contained in:
Artur K 2012-03-18 11:35:56 +01:00
parent fee4d6fe9a
commit 9cc5202ff7
12 changed files with 457 additions and 344 deletions

View File

@ -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);

View File

@ -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 */

View File

@ -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 caseEntry;
int numEntries; /* # entries in case table */ std::vector<uint32_t> caseTbl2;
uint32_t *entries; /* array of offsets */
} caseTbl;
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
{ {

View File

@ -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)

View File

@ -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);

View File

@ -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);
} }

View File

@ -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);

View File

@ -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); pBB = BB::Create(iStart, pIcode, MULTI_BRANCH, ll->caseTbl2.size(), this);
for (i = 0; i < ll->caseTbl.numEntries; i++) for (i = 0; i < ll->caseTbl2.size(); i++)
pBB->edges[i].ip = ll->caseTbl.entries[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)); assert(g_proj.validSymIdx(icod.ll()->caseEntry));
const SYM &psym(g_proj.getSymByIdx(icod.ll()->caseTbl.numEntries)); 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))

View File

@ -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 case table */
for (int j = 0; j < ll->caseTbl.numEntries; j++, p++) for (uint32_t &p : ll->caseTbl2)
Icode.labelSrch(*p, *p); Icode.labelSrch(p, p); // for each entry in caseTable replace it with target insn Idx
} }
} }
} }

View File

@ -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

View File

@ -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; //pIcode.ll()->caseTbl2.numEntries = (endTable - offTable) / 2;
assert(pIcode.ll()->caseTbl.numEntries<512);
psw = new uint32_t [pIcode.ll()->caseTbl.numEntries];
pIcode.ll()->caseTbl.entries = psw;
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 ix=Icode.size();
int i; LLInst &ll_ins(*pIcode.ll());
int sseg = (pIcode.ll()->src().seg)? pIcode.ll()->src().seg: rDS;
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;
} }

View File

@ -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, B , iADD }, /* 00 */
{ modrm, none2, 0 , iADD , Sf | Zf | Cf , 0 }, /* 01 */ { modrm, none2, 0 , iADD }, /* 01 */
{ modrm, none2, TO_REG | B , iADD , Sf | Zf | Cf , 0 }, /* 02 */ { modrm, none2, TO_REG | B , iADD }, /* 02 */
{ modrm, none2, TO_REG , iADD , Sf | Zf | Cf , 0 }, /* 03 */ { modrm, none2, TO_REG , iADD }, /* 03 */
{ data1, axImp, B , iADD , Sf | Zf | Cf , 0 }, /* 04 */ { data1, axImp, B , iADD }, /* 04 */
{ data2, axImp, 0 , iADD , Sf | Zf | Cf , 0 }, /* 05 */ { data2, axImp, 0 , iADD }, /* 05 */
{ segop, none2, NO_SRC , iPUSH , 0 , 0 }, /* 06 */ { segop, none2, NO_SRC , iPUSH }, /* 06 */
{ segop, none2, NO_SRC , iPOP , 0 , 0 }, /* 07 */ { segop, none2, NO_SRC , iPOP }, /* 07 */
{ modrm, none2, B , iOR , Sf | Zf | Cf , 0 }, /* 08 */ { modrm, none2, B , iOR }, /* 08 */
{ modrm, none2, NSP , iOR , Sf | Zf | Cf , 0 }, /* 09 */ { modrm, none2, NSP , iOR }, /* 09 */
{ modrm, none2, TO_REG | B , iOR , Sf | Zf | Cf , 0 }, /* 0A */ { modrm, none2, TO_REG | B , iOR }, /* 0A */
{ modrm, none2, TO_REG | NSP , iOR , Sf | Zf | Cf , 0 }, /* 0B */ { modrm, none2, TO_REG | NSP , iOR }, /* 0B */
{ data1, axImp, B , iOR , Sf | Zf | Cf , 0 }, /* 0C */ { data1, axImp, B , iOR }, /* 0C */
{ data2, axImp, 0 , iOR , Sf | Zf | Cf , 0 }, /* 0D */ { data2, axImp, 0 , iOR }, /* 0D */
{ segop, none2, NO_SRC , iPUSH , 0 , 0 }, /* 0E */ { segop, none2, NO_SRC , iPUSH }, /* 0E */
{ none1, none2, OP386 , iZERO , 0 , 0 }, /* 0F */ { none1, none2, OP386 , iZERO }, /* 0F */
{ modrm, none2, B , iADC , Sf | Zf | Cf , Cf }, /* 10 */ { modrm, none2, B , iADC }, /* 10 */
{ modrm, none2, NSP , iADC , Sf | Zf | Cf , Cf }, /* 11 */ { modrm, none2, NSP , iADC }, /* 11 */
{ modrm, none2, TO_REG | B , iADC , Sf | Zf | Cf , Cf }, /* 12 */ { modrm, none2, TO_REG | B , iADC }, /* 12 */
{ modrm, none2, TO_REG | NSP , iADC , Sf | Zf | Cf , Cf }, /* 13 */ { modrm, none2, TO_REG | NSP , iADC }, /* 13 */
{ data1, axImp, B , iADC , Sf | Zf | Cf , Cf }, /* 14 */ { data1, axImp, B , iADC }, /* 14 */
{ data2, axImp, 0 , iADC , Sf | Zf | Cf , Cf }, /* 15 */ { data2, axImp, 0 , iADC }, /* 15 */
{ segop, none2, NOT_HLL | NO_SRC , iPUSH , 0 , 0 }, /* 16 */ { segop, none2, NOT_HLL | NO_SRC , iPUSH }, /* 16 */
{ segop, none2, NOT_HLL | NO_SRC , iPOP , 0 , 0 }, /* 17 */ { segop, none2, NOT_HLL | NO_SRC , iPOP }, /* 17 */
{ modrm, none2, B , iSBB , Sf | Zf | Cf , Cf }, /* 18 */ { modrm, none2, B , iSBB }, /* 18 */
{ modrm, none2, NSP , iSBB , Sf | Zf | Cf , Cf }, /* 19 */ { modrm, none2, NSP , iSBB }, /* 19 */
{ modrm, none2, TO_REG | B , iSBB , Sf | Zf | Cf , Cf }, /* 1A */ { modrm, none2, TO_REG | B , iSBB }, /* 1A */
{ modrm, none2, TO_REG | NSP , iSBB , Sf | Zf | Cf , Cf }, /* 1B */ { modrm, none2, TO_REG | NSP , iSBB }, /* 1B */
{ data1, axImp, B , iSBB , Sf | Zf | Cf , Cf }, /* 1C */ { data1, axImp, B , iSBB }, /* 1C */
{ data2, axImp, 0 , iSBB , Sf | Zf | Cf , Cf }, /* 1D */ { data2, axImp, 0 , iSBB }, /* 1D */
{ segop, none2, NO_SRC , iPUSH , 0 , 0 }, /* 1E */ { segop, none2, NO_SRC , iPUSH }, /* 1E */
{ segop, none2, NO_SRC , iPOP , 0 , 0 }, /* 1F */ { segop, none2, NO_SRC , iPOP }, /* 1F */
{ modrm, none2, B , iAND , Sf | Zf | Cf , 0 }, /* 20 */ { modrm, none2, B , iAND }, /* 20 */
{ modrm, none2, NSP , iAND , Sf | Zf | Cf , 0 }, /* 21 */ { modrm, none2, NSP , iAND }, /* 21 */
{ modrm, none2, TO_REG | B , iAND , Sf | Zf | Cf , 0 }, /* 22 */ { modrm, none2, TO_REG | B , iAND }, /* 22 */
{ modrm, none2, TO_REG | NSP , iAND , Sf | Zf | Cf , 0 }, /* 23 */ { modrm, none2, TO_REG | NSP , iAND }, /* 23 */
{ data1, axImp, B , iAND , Sf | Zf | Cf , 0 }, /* 24 */ { data1, axImp, B , iAND }, /* 24 */
{ data2, axImp, 0 , iAND , Sf | Zf | Cf , 0 }, /* 25 */ { data2, axImp, 0 , iAND }, /* 25 */
{ prefix, none2, 0 , (IC)rES,0 , 0 }, /* 26 */ { prefix, none2, 0 , (IC)rES}, /* 26 */
{ none1, axImp, NOT_HLL | B|NO_SRC , iDAA , Sf | Zf | Cf , 0 }, /* 27 */ { none1, axImp, NOT_HLL | B|NO_SRC , iDAA }, /* 27 */
{ modrm, none2, B , iSUB , Sf | Zf | Cf , 0 }, /* 28 */ { modrm, none2, B , iSUB }, /* 28 */
{ modrm, none2, 0 , iSUB , Sf | Zf | Cf , 0 }, /* 29 */ { modrm, none2, 0 , iSUB }, /* 29 */
{ modrm, none2, TO_REG | B , iSUB , Sf | Zf | Cf , 0 }, /* 2A */ { modrm, none2, TO_REG | B , iSUB }, /* 2A */
{ modrm, none2, TO_REG , iSUB , Sf | Zf | Cf , 0 }, /* 2B */ { modrm, none2, TO_REG , iSUB }, /* 2B */
{ data1, axImp, B , iSUB , Sf | Zf | Cf , 0 }, /* 2C */ { data1, axImp, B , iSUB }, /* 2C */
{ data2, axImp, 0 , iSUB , Sf | Zf | Cf , 0 }, /* 2D */ { data2, axImp, 0 , iSUB }, /* 2D */
{ prefix, none2, 0 , (IC)rCS,0 , 0 }, /* 2E */ { prefix, none2, 0 , (IC)rCS}, /* 2E */
{ none1, axImp, NOT_HLL | B|NO_SRC , iDAS , Sf | Zf | Cf , 0 }, /* 2F */ { none1, axImp, NOT_HLL | B|NO_SRC , iDAS }, /* 2F */
{ modrm, none2, B , iXOR , Sf | Zf | Cf , 0 }, /* 30 */ { modrm, none2, B , iXOR }, /* 30 */
{ modrm, none2, NSP , iXOR , Sf | Zf | Cf , 0 }, /* 31 */ { modrm, none2, NSP , iXOR }, /* 31 */
{ modrm, none2, TO_REG | B , iXOR , Sf | Zf | Cf , 0 }, /* 32 */ { modrm, none2, TO_REG | B , iXOR }, /* 32 */
{ modrm, none2, TO_REG | NSP , iXOR , Sf | Zf | Cf , 0 }, /* 33 */ { modrm, none2, TO_REG | NSP , iXOR }, /* 33 */
{ data1, axImp, B , iXOR , Sf | Zf | Cf , 0 }, /* 34 */ { data1, axImp, B , iXOR }, /* 34 */
{ data2, axImp, 0 , iXOR , Sf | Zf | Cf , 0 }, /* 35 */ { data2, axImp, 0 , iXOR }, /* 35 */
{ prefix, none2, 0 , (IC)rSS,0 , 0 }, /* 36 */ { prefix, none2, 0 , (IC)rSS}, /* 36 */
{ none1, axImp, NOT_HLL | NO_SRC , iAAA , Sf | Zf | Cf , 0 }, /* 37 */ { none1, axImp, NOT_HLL | NO_SRC , iAAA }, /* 37 */
{ modrm, none2, B , iCMP , Sf | Zf | Cf , 0 }, /* 38 */ { modrm, none2, B , iCMP }, /* 38 */
{ modrm, none2, NSP , iCMP , Sf | Zf | Cf , 0 }, /* 39 */ { modrm, none2, NSP , iCMP }, /* 39 */
{ modrm, none2, TO_REG | B , iCMP , Sf | Zf | Cf , 0 }, /* 3A */ { modrm, none2, TO_REG | B , iCMP }, /* 3A */
{ modrm, none2, TO_REG | NSP , iCMP , Sf | Zf | Cf , 0 }, /* 3B */ { modrm, none2, TO_REG | NSP , iCMP }, /* 3B */
{ data1, axImp, B , iCMP , Sf | Zf | Cf , 0 }, /* 3C */ { data1, axImp, B , iCMP }, /* 3C */
{ data2, axImp, 0 , iCMP , Sf | Zf | Cf , 0 }, /* 3D */ { data2, axImp, 0 , iCMP }, /* 3D */
{ prefix, none2, 0 , (IC)rDS,0 , 0 }, /* 3E */ { prefix, none2, 0 , (IC)rDS}, /* 3E */
{ none1, axImp, NOT_HLL | NO_SRC , iAAS , Sf | Zf | Cf , 0 }, /* 3F */ { none1, axImp, NOT_HLL | NO_SRC , iAAS }, /* 3F */
{ regop, none2, 0 , iINC , Sf | Zf , 0 }, /* 40 */ { regop, none2, 0 , iINC }, /* 40 */
{ regop, none2, 0 , iINC , Sf | Zf , 0 }, /* 41 */ { regop, none2, 0 , iINC }, /* 41 */
{ regop, none2, 0 , iINC , Sf | Zf , 0 }, /* 42 */ { regop, none2, 0 , iINC }, /* 42 */
{ regop, none2, 0 , iINC , Sf | Zf , 0 }, /* 43 */ { regop, none2, 0 , iINC }, /* 43 */
{ regop, none2, NOT_HLL , iINC , Sf | Zf , 0 }, /* 44 */ { regop, none2, NOT_HLL , iINC }, /* 44 */
{ regop, none2, 0 , iINC , Sf | Zf , 0 }, /* 45 */ { regop, none2, 0 , iINC }, /* 45 */
{ regop, none2, 0 , iINC , Sf | Zf , 0 }, /* 46 */ { regop, none2, 0 , iINC }, /* 46 */
{ regop, none2, 0 , iINC , Sf | Zf , 0 }, /* 47 */ { regop, none2, 0 , iINC }, /* 47 */
{ regop, none2, 0 , iDEC , Sf | Zf , 0 }, /* 48 */ { regop, none2, 0 , iDEC }, /* 48 */
{ regop, none2, 0 , iDEC , Sf | Zf , 0 }, /* 49 */ { regop, none2, 0 , iDEC }, /* 49 */
{ regop, none2, 0 , iDEC , Sf | Zf , 0 }, /* 4A */ { regop, none2, 0 , iDEC }, /* 4A */
{ regop, none2, 0 , iDEC , Sf | Zf , 0 }, /* 4B */ { regop, none2, 0 , iDEC }, /* 4B */
{ regop, none2, NOT_HLL , iDEC , Sf | Zf , 0 }, /* 4C */ { regop, none2, NOT_HLL , iDEC }, /* 4C */
{ regop, none2, 0 , iDEC , Sf | Zf , 0 }, /* 4D */ { regop, none2, 0 , iDEC }, /* 4D */
{ regop, none2, 0 , iDEC , Sf | Zf , 0 }, /* 4E */ { regop, none2, 0 , iDEC }, /* 4E */
{ regop, none2, 0 , iDEC , Sf | Zf , 0 }, /* 4F */ { regop, none2, 0 , iDEC }, /* 4F */
{ regop, none2, NO_SRC , iPUSH , 0 , 0 }, /* 50 */ { regop, none2, NO_SRC , iPUSH }, /* 50 */
{ regop, none2, NO_SRC , iPUSH , 0 , 0 }, /* 51 */ { regop, none2, NO_SRC , iPUSH }, /* 51 */
{ regop, none2, NO_SRC , iPUSH , 0 , 0 }, /* 52 */ { regop, none2, NO_SRC , iPUSH }, /* 52 */
{ regop, none2, NO_SRC , iPUSH , 0 , 0 }, /* 53 */ { regop, none2, NO_SRC , iPUSH }, /* 53 */
{ regop, none2, NOT_HLL | NO_SRC , iPUSH , 0 , 0 }, /* 54 */ { regop, none2, NOT_HLL | NO_SRC , iPUSH }, /* 54 */
{ regop, none2, NO_SRC , iPUSH , 0 , 0 }, /* 55 */ { regop, none2, NO_SRC , iPUSH }, /* 55 */
{ regop, none2, NO_SRC , iPUSH , 0 , 0 }, /* 56 */ { regop, none2, NO_SRC , iPUSH }, /* 56 */
{ regop, none2, NO_SRC , iPUSH , 0 , 0 }, /* 57 */ { regop, none2, NO_SRC , iPUSH }, /* 57 */
{ regop, none2, NO_SRC , iPOP , 0 , 0 }, /* 58 */ { regop, none2, NO_SRC , iPOP }, /* 58 */
{ regop, none2, NO_SRC , iPOP , 0 , 0 }, /* 59 */ { regop, none2, NO_SRC , iPOP }, /* 59 */
{ regop, none2, NO_SRC , iPOP , 0 , 0 }, /* 5A */ { regop, none2, NO_SRC , iPOP }, /* 5A */
{ regop, none2, NO_SRC , iPOP , 0 , 0 }, /* 5B */ { regop, none2, NO_SRC , iPOP }, /* 5B */
{ regop, none2, NOT_HLL | NO_SRC , iPOP , 0 , 0 }, /* 5C */ { regop, none2, NOT_HLL | NO_SRC , iPOP }, /* 5C */
{ regop, none2, NO_SRC , iPOP , 0 , 0 }, /* 5D */ { regop, none2, NO_SRC , iPOP }, /* 5D */
{ regop, none2, NO_SRC , iPOP , 0 , 0 }, /* 5E */ { regop, none2, NO_SRC , iPOP }, /* 5E */
{ regop, none2, NO_SRC , iPOP , 0 , 0 }, /* 5F */ { regop, none2, NO_SRC , iPOP }, /* 5F */
{ none1, none2, NOT_HLL | NO_OPS , iPUSHA, 0 , 0 }, /* 60 */ { none1, none2, NOT_HLL | NO_OPS , iPUSHA}, /* 60 */
{ none1, none2, NOT_HLL | NO_OPS , iPOPA , 0 , 0 }, /* 61 */ { none1, none2, NOT_HLL | NO_OPS , iPOPA }, /* 61 */
{ memOnly, modrm, TO_REG | NSP , iBOUND, 0 , 0 }, /* 62 */ { memOnly, modrm, TO_REG | NSP , iBOUND}, /* 62 */
{ none1, none2, OP386 , iZERO , 0 , 0 }, /* 63 */ { none1, none2, OP386 , iZERO }, /* 63 */
{ none1, none2, OP386 , iZERO , 0 , 0 }, /* 64 */ { none1, none2, OP386 , iZERO }, /* 64 */
{ none1, none2, OP386 , iZERO , 0 , 0 }, /* 65 */ { none1, none2, OP386 , iZERO }, /* 65 */
{ none1, none2, OP386 , iZERO , 0 , 0 }, /* 66 */ { none1, none2, OP386 , iZERO }, /* 66 */
{ none1, none2, OP386 , iZERO , 0 , 0 }, /* 67 */ { none1, none2, OP386 , iZERO }, /* 67 */
{ data2, none2, NO_SRC , iPUSH , 0 , 0 }, /* 68 */ { data2, none2, NO_SRC , iPUSH }, /* 68 */
{ modrm, data2, TO_REG | NSP , iIMUL , Sf | Zf | Cf , 0 }, /* 69 */ { modrm, data2, TO_REG | NSP , iIMUL }, /* 69 */
{ data1, none2, S_EXT | NO_SRC , iPUSH , 0 , 0 }, /* 6A */ { data1, none2, S_EXT | NO_SRC , iPUSH }, /* 6A */
{ modrm, data1, TO_REG | NSP | S_EXT , iIMUL , Sf | Zf | Cf , 0 }, /* 6B */ { modrm, data1, TO_REG | NSP | S_EXT , iIMUL }, /* 6B */
{ strop, memImp, NOT_HLL | B|IM_OPS , iINS , 0 , Df}, /* 6C */ { strop, memImp, NOT_HLL | B|IM_OPS , iINS }, /* 6C */
{ strop, memImp, NOT_HLL | IM_OPS , iINS , 0 , Df}, /* 6D */ { strop, memImp, NOT_HLL | IM_OPS , iINS }, /* 6D */
{ strop, memImp, NOT_HLL | B|IM_OPS , iOUTS , 0 , Df}, /* 6E */ { strop, memImp, NOT_HLL | B|IM_OPS , iOUTS }, /* 6E */
{ strop, memImp, NOT_HLL | IM_OPS , iOUTS , 0 , Df}, /* 6F */ { strop, memImp, NOT_HLL | IM_OPS , iOUTS }, /* 6F */
{ dispS, none2, NOT_HLL , iJO , 0 , 0 }, /* 70 */ { dispS, none2, NOT_HLL , iJO }, /* 70 */
{ dispS, none2, NOT_HLL , iJNO , 0 , 0 }, /* 71 */ { dispS, none2, NOT_HLL , iJNO }, /* 71 */
{ dispS, none2, 0 , iJB , 0 , Cf }, /* 72 */ { dispS, none2, 0 , iJB }, /* 72 */
{ dispS, none2, 0 , iJAE , 0 , Cf }, /* 73 */ { dispS, none2, 0 , iJAE }, /* 73 */
{ dispS, none2, 0 , iJE , 0 , Zf }, /* 74 */ { dispS, none2, 0 , iJE }, /* 74 */
{ dispS, none2, 0 , iJNE , 0 , Zf }, /* 75 */ { dispS, none2, 0 , iJNE }, /* 75 */
{ dispS, none2, 0 , iJBE , 0 , Zf | Cf }, /* 76 */ { dispS, none2, 0 , iJBE }, /* 76 */
{ dispS, none2, 0 , iJA , 0 , Zf | Cf }, /* 77 */ { dispS, none2, 0 , iJA }, /* 77 */
{ dispS, none2, 0 , iJS , 0 , Sf }, /* 78 */ { dispS, none2, 0 , iJS }, /* 78 */
{ dispS, none2, 0 , iJNS , 0 , Sf }, /* 79 */ { dispS, none2, 0 , iJNS }, /* 79 */
{ dispS, none2, NOT_HLL , iJP , 0 , 0 }, /* 7A */ { dispS, none2, NOT_HLL , iJP }, /* 7A */
{ dispS, none2, NOT_HLL , iJNP , 0 , 0 }, /* 7B */ { dispS, none2, NOT_HLL , iJNP }, /* 7B */
{ dispS, none2, 0 , iJL , 0 , Sf }, /* 7C */ { dispS, none2, 0 , iJL }, /* 7C */
{ dispS, none2, 0 , iJGE , 0 , Sf }, /* 7D */ { dispS, none2, 0 , iJGE }, /* 7D */
{ dispS, none2, 0 , iJLE , 0 , Sf | Zf }, /* 7E */ { dispS, none2, 0 , iJLE }, /* 7E */
{ dispS, none2, 0 , iJG , 0 , Sf | Zf }, /* 7F */ { dispS, none2, 0 , iJG }, /* 7F */
{ immed, data1, B , iZERO , 0 , 0 }, /* 80 */ { immed, data1, B , iZERO }, /* 80 */
{ immed, data2, NSP , iZERO , 0 , 0 }, /* 81 */ { immed, data2, NSP , iZERO }, /* 81 */
{ immed, data1, B , iZERO , 0 , 0 }, /* 82 */ /* ?? */ { immed, data1, B , iZERO }, /* 82 */ /* ?? */
{ immed, data1, NSP | S_EXT , iZERO , 0 , 0 }, /* 83 */ { immed, data1, NSP | S_EXT , iZERO }, /* 83 */
{ modrm, none2, TO_REG | B , iTEST , Sf | Zf | Cf, 0 }, /* 84 */ { modrm, none2, TO_REG | B , iTEST }, /* 84 */
{ modrm, none2, TO_REG | NSP , iTEST , Sf | Zf | Cf, 0 }, /* 85 */ { modrm, none2, TO_REG | NSP , iTEST }, /* 85 */
{ modrm, none2, TO_REG | B , iXCHG , 0 , 0 }, /* 86 */ { modrm, none2, TO_REG | B , iXCHG }, /* 86 */
{ modrm, none2, TO_REG | NSP , iXCHG , 0 , 0 }, /* 87 */ { modrm, none2, TO_REG | NSP , iXCHG }, /* 87 */
{ modrm, none2, B , iMOV , 0 , 0 }, /* 88 */ { modrm, none2, B , iMOV }, /* 88 */
{ modrm, none2, 0 , iMOV , 0 , 0 }, /* 89 */ { modrm, none2, 0 , iMOV }, /* 89 */
{ modrm, none2, TO_REG | B , iMOV , 0 , 0 }, /* 8A */ { modrm, none2, TO_REG | B , iMOV }, /* 8A */
{ modrm, none2, TO_REG , iMOV , 0 , 0 }, /* 8B */ { modrm, none2, TO_REG , iMOV }, /* 8B */
{ segrm, none2, NSP , iMOV , 0 , 0 }, /* 8C */ { segrm, none2, NSP , iMOV }, /* 8C */
{ memOnly, modrm, TO_REG | NSP , iLEA , 0 , 0 }, /* 8D */ { memOnly, modrm, TO_REG | NSP , iLEA }, /* 8D */
{ segrm, none2, TO_REG | NSP , iMOV , 0 , 0 }, /* 8E */ { segrm, none2, TO_REG | NSP , iMOV }, /* 8E */
{ memReg0, none2, NO_SRC , iPOP , 0 , 0 }, /* 8F */ { memReg0, none2, NO_SRC , iPOP }, /* 8F */
{ none1, none2, NO_OPS , iNOP , 0 , 0 }, /* 90 */ { none1, none2, NO_OPS , iNOP }, /* 90 */
{ regop, axImp, 0 , iXCHG , 0 , 0 }, /* 91 */ { regop, axImp, 0 , iXCHG }, /* 91 */
{ regop, axImp, 0 , iXCHG , 0 , 0 }, /* 92 */ { regop, axImp, 0 , iXCHG }, /* 92 */
{ regop, axImp, 0 , iXCHG , 0 , 0 }, /* 93 */ { regop, axImp, 0 , iXCHG }, /* 93 */
{ regop, axImp, NOT_HLL , iXCHG , 0 , 0 }, /* 94 */ { regop, axImp, NOT_HLL , iXCHG }, /* 94 */
{ regop, axImp, 0 , iXCHG , 0 , 0 }, /* 95 */ { regop, axImp, 0 , iXCHG }, /* 95 */
{ regop, axImp, 0 , iXCHG , 0 , 0 }, /* 96 */ { regop, axImp, 0 , iXCHG }, /* 96 */
{ regop, axImp, 0 , iXCHG , 0 , 0 }, /* 97 */ { regop, axImp, 0 , iXCHG }, /* 97 */
{ alImp, axImp, SRC_B | S_EXT , iSIGNEX,0 , 0 }, /* 98 */ { alImp, axImp, SRC_B | S_EXT , iSIGNEX}, /* 98 */
{axSrcIm, axImp, IM_DST | S_EXT , iSIGNEX,0 , 0 }, /* 99 */ {axSrcIm, axImp, IM_DST | S_EXT , iSIGNEX}, /* 99 */
{ dispF, none2, 0 , iCALLF ,0 , 0 }, /* 9A */ { dispF, none2, 0 , iCALLF }, /* 9A */
{ none1, none2, FLOAT_OP| NO_OPS , iWAIT , 0 , 0 }, /* 9B */ { none1, none2, FLOAT_OP| NO_OPS , iWAIT }, /* 9B */
{ none1, none2, NOT_HLL | NO_OPS , iPUSHF, 0 , 0 }, /* 9C */ { none1, none2, NOT_HLL | NO_OPS , iPUSHF}, /* 9C */
{ none1, none2, NOT_HLL | NO_OPS , iPOPF , Sf | Zf | Cf | Df,}, /* 9D */ { none1, none2, NOT_HLL | NO_OPS , iPOPF }, /* 9D */
{ none1, none2, NOT_HLL | NO_OPS , iSAHF , Sf | Zf | Cf, 0 }, /* 9E */ { none1, none2, NOT_HLL | NO_OPS , iSAHF }, /* 9E */
{ none1, none2, NOT_HLL | NO_OPS , iLAHF , 0 , Sf | Zf | Cf }, /* 9F */ { none1, none2, NOT_HLL | NO_OPS , iLAHF }, /* 9F */
{ dispM, axImp, B , iMOV , 0 , 0 }, /* A0 */ { dispM, axImp, B , iMOV }, /* A0 */
{ dispM, axImp, 0 , iMOV , 0 , 0 }, /* A1 */ { dispM, axImp, 0 , iMOV }, /* A1 */
{ dispM, axImp, TO_REG | B , iMOV , 0 , 0 }, /* A2 */ { dispM, axImp, TO_REG | B , iMOV }, /* A2 */
{ dispM, axImp, TO_REG , iMOV , 0 , 0 }, /* A3 */ { dispM, axImp, TO_REG , iMOV }, /* A3 */
{ strop, memImp, B | IM_OPS , iMOVS , 0 , Df }, /* A4 */ { strop, memImp, B | IM_OPS , iMOVS }, /* A4 */
{ strop, memImp, IM_OPS , iMOVS , 0 , Df }, /* A5 */ { strop, memImp, IM_OPS , iMOVS }, /* A5 */
{ strop, memImp, B | IM_OPS , iCMPS , Sf | Zf | Cf, Df }, /* A6 */ { strop, memImp, B | IM_OPS , iCMPS }, /* A6 */
{ strop, memImp, IM_OPS , iCMPS , Sf | Zf | Cf, Df }, /* A7 */ { strop, memImp, IM_OPS , iCMPS }, /* A7 */
{ data1, axImp, B , iTEST , Sf | Zf | Cf, 0 }, /* A8 */ { data1, axImp, B , iTEST }, /* A8 */
{ data2, axImp, 0 , iTEST , Sf | Zf | Cf, 0 }, /* A9 */ { data2, axImp, 0 , iTEST }, /* A9 */
{ strop, memImp, B | IM_OPS , iSTOS , 0 , Df }, /* AA */ { strop, memImp, B | IM_OPS , iSTOS }, /* AA */
{ strop, memImp, IM_OPS , iSTOS , 0 , Df }, /* AB */ { strop, memImp, IM_OPS , iSTOS }, /* AB */
{ strop, memImp, B | IM_OPS , iLODS , 0 , Df }, /* AC */ { strop, memImp, B | IM_OPS , iLODS }, /* AC */
{ strop, memImp, IM_OPS , iLODS , 0 , Df }, /* AD */ { strop, memImp, IM_OPS , iLODS }, /* AD */
{ strop, memImp, B | IM_OPS , iSCAS , Sf | Zf | Cf, Df }, /* AE */ { strop, memImp, B | IM_OPS , iSCAS }, /* AE */
{ strop, memImp, IM_OPS , iSCAS , Sf | Zf | Cf, Df }, /* AF */ { strop, memImp, IM_OPS , iSCAS }, /* AF */
{ regop, data1, B , iMOV , 0 , 0 }, /* B0 */ { regop, data1, B , iMOV }, /* B0 */
{ regop, data1, B , iMOV , 0 , 0 }, /* B1 */ { regop, data1, B , iMOV }, /* B1 */
{ regop, data1, B , iMOV , 0 , 0 }, /* B2 */ { regop, data1, B , iMOV }, /* B2 */
{ regop, data1, B , iMOV , 0 , 0 }, /* B3 */ { regop, data1, B , iMOV }, /* B3 */
{ regop, data1, B , iMOV , 0 , 0 }, /* B4 */ { regop, data1, B , iMOV }, /* B4 */
{ regop, data1, B , iMOV , 0 , 0 }, /* B5 */ { regop, data1, B , iMOV }, /* B5 */
{ regop, data1, B , iMOV , 0 , 0 }, /* B6 */ { regop, data1, B , iMOV }, /* B6 */
{ regop, data1, B , iMOV , 0 , 0 }, /* B7 */ { regop, data1, B , iMOV }, /* B7 */
{ regop, data2, 0 , iMOV , 0 , 0 }, /* B8 */ { regop, data2, 0 , iMOV }, /* B8 */
{ regop, data2, 0 , iMOV , 0 , 0 }, /* B9 */ { regop, data2, 0 , iMOV }, /* B9 */
{ regop, data2, 0 , iMOV , 0 , 0 }, /* BA */ { regop, data2, 0 , iMOV }, /* BA */
{ regop, data2, 0 , iMOV , 0 , 0 }, /* BB */ { regop, data2, 0 , iMOV }, /* BB */
{ regop, data2, NOT_HLL , iMOV , 0 , 0 }, /* BC */ { regop, data2, NOT_HLL , iMOV }, /* BC */
{ regop, data2, 0 , iMOV , 0 , 0 }, /* BD */ { regop, data2, 0 , iMOV }, /* BD */
{ regop, data2, 0 , iMOV , 0 , 0 }, /* BE */ { regop, data2, 0 , iMOV }, /* BE */
{ regop, data2, 0 , iMOV , 0 , 0 }, /* BF */ { regop, data2, 0 , iMOV }, /* BF */
{ shift, data1, B , iZERO , 0 , 0 }, /* C0 */ { shift, data1, B , iZERO }, /* C0 */
{ shift, data1, NSP | SRC_B , iZERO , 0 , 0 }, /* C1 */ { shift, data1, NSP | SRC_B , iZERO }, /* C1 */
{ data2, none2, 0 , iRET , 0 , 0 }, /* C2 */ { data2, none2, 0 , iRET }, /* C2 */
{ none1, none2, NO_OPS , iRET , 0 , 0 }, /* C3 */ { none1, none2, NO_OPS , iRET }, /* C3 */
{ memOnly, modrm, TO_REG | NSP , iLES , 0 , 0 }, /* C4 */ { memOnly, modrm, TO_REG | NSP , iLES }, /* C4 */
{ memOnly, modrm, TO_REG | NSP , iLDS , 0 , 0 }, /* C5 */ { memOnly, modrm, TO_REG | NSP , iLDS }, /* C5 */
{ memReg0, data1, B , iMOV , 0 , 0 }, /* C6 */ { memReg0, data1, B , iMOV }, /* C6 */
{ memReg0, data2, 0 , iMOV , 0 , 0 }, /* C7 */ { memReg0, data2, 0 , iMOV }, /* C7 */
{ data2, data1, 0 , iENTER, 0 , 0 }, /* C8 */ { data2, data1, 0 , iENTER}, /* C8 */
{ none1, none2, NO_OPS , iLEAVE, 0 , 0 }, /* C9 */ { none1, none2, NO_OPS , iLEAVE}, /* C9 */
{ data2, none2, 0 , iRETF , 0 , 0 }, /* CA */ { data2, none2, 0 , iRETF }, /* CA */
{ none1, none2, NO_OPS , iRETF , 0 , 0 }, /* CB */ { none1, none2, NO_OPS , iRETF }, /* CB */
{ const3, none2, NOT_HLL , iINT , 0 , 0 }, /* CC */ { const3, none2, NOT_HLL , iINT }, /* CC */
{ data1,checkInt, NOT_HLL , iINT , 0 , 0 }, /* CD */ { data1,checkInt, NOT_HLL , iINT }, /* CD */
{ none1, none2, NOT_HLL | NO_OPS , iINTO , 0 , 0 }, /* CE */ { none1, none2, NOT_HLL | NO_OPS , iINTO }, /* CE */
{ none1, none2, NOT_HLL | NO_OPS , iIRET , 0 , 0 }, /* Cf */ { none1, none2, NOT_HLL | NO_OPS , iIRET }, /* Cf */
{ shift, const1, B , iZERO , 0 , 0 }, /* D0 */ { shift, const1, B , iZERO }, /* D0 */
{ shift, const1, SRC_B , iZERO , 0 , 0 }, /* D1 */ { shift, const1, SRC_B , iZERO }, /* D1 */
{ shift, none1, B , iZERO , 0 , 0 }, /* D2 */ { shift, none1, B , iZERO }, /* D2 */
{ shift, none1, SRC_B , iZERO , 0 , 0 }, /* D3 */ { shift, none1, SRC_B , iZERO }, /* D3 */
{ data1, axImp, NOT_HLL , iAAM , Sf | Zf | Cf, 0 }, /* D4 */ { data1, axImp, NOT_HLL , iAAM }, /* D4 */
{ data1, axImp, NOT_HLL , iAAD , Sf | Zf | Cf, 0 }, /* D5 */ { data1, axImp, NOT_HLL , iAAD }, /* D5 */
{ none1, none2, 0 , iZERO , 0 , 0 }, /* D6 */ { none1, none2, 0 , iZERO }, /* D6 */
{ memImp, axImp, NOT_HLL | B| IM_OPS, iXLAT , 0 , 0 }, /* D7 */ { memImp, axImp, NOT_HLL | B| IM_OPS , iXLAT }, /* D7 */
{ escop, none2, FLOAT_OP , iESC , 0 , 0 }, /* D8 */ { escop, none2, FLOAT_OP , iESC }, /* D8 */
{ escop, none2, FLOAT_OP , iESC , 0 , 0 }, /* D9 */ { escop, none2, FLOAT_OP , iESC }, /* D9 */
{ escop, none2, FLOAT_OP , iESC , 0 , 0 }, /* DA */ { escop, none2, FLOAT_OP , iESC }, /* DA */
{ escop, none2, FLOAT_OP , iESC , 0 , 0 }, /* DB */ { escop, none2, FLOAT_OP , iESC }, /* DB */
{ escop, none2, FLOAT_OP , iESC , 0 , 0 }, /* DC */ { escop, none2, FLOAT_OP , iESC }, /* DC */
{ escop, none2, FLOAT_OP , iESC , 0 , 0 }, /* DD */ { escop, none2, FLOAT_OP , iESC }, /* DD */
{ escop, none2, FLOAT_OP , iESC , 0 , 0 }, /* DE */ { escop, none2, FLOAT_OP , iESC }, /* DE */
{ escop, none2, FLOAT_OP , iESC , 0 , 0 }, /* Df */ { escop, none2, FLOAT_OP , iESC }, /* Df */
{ dispS, none2, 0 , iLOOPNE,0 , Zf }, /* E0 */ { dispS, none2, 0 , iLOOPNE}, /* E0 */
{ dispS, none2, 0 , iLOOPE, 0 , Zf }, /* E1 */ { dispS, none2, 0 , iLOOPE}, /* E1 */
{ dispS, none2, 0 , iLOOP , 0 , 0 }, /* E2 */ { dispS, none2, 0 , iLOOP }, /* E2 */
{ dispS, none2, 0 , iJCXZ , 0 , 0 }, /* E3 */ { dispS, none2, 0 , iJCXZ }, /* E3 */
{ data1, axImp, NOT_HLL | B|NO_SRC , iIN , 0 , 0 }, /* E4 */ { data1, axImp, NOT_HLL | B|NO_SRC , iIN }, /* E4 */
{ data1, axImp, NOT_HLL | NO_SRC , iIN , 0 , 0 }, /* E5 */ { data1, axImp, NOT_HLL | NO_SRC , iIN }, /* E5 */
{ data1, axImp, NOT_HLL | B|NO_SRC , iOUT , 0 , 0 }, /* E6 */ { data1, axImp, NOT_HLL | B|NO_SRC , iOUT }, /* E6 */
{ data1, axImp, NOT_HLL | NO_SRC , iOUT , 0 , 0 }, /* E7 */ { data1, axImp, NOT_HLL | NO_SRC , iOUT }, /* E7 */
{ dispN, none2, 0 , iCALL , 0 , 0 }, /* E8 */ { dispN, none2, 0 , iCALL }, /* E8 */
{ dispN, none2, 0 , iJMP , 0 , 0 }, /* E9 */ { dispN, none2, 0 , iJMP }, /* E9 */
{ dispF, none2, 0 , iJMPF , 0 , 0 }, /* EA */ { dispF, none2, 0 , iJMPF }, /* EA */
{ dispS, none2, 0 , iJMP , 0 , 0 }, /* EB */ { dispS, none2, 0 , iJMP }, /* EB */
{ none1, axImp, NOT_HLL | B|NO_SRC , iIN , 0 , 0 }, /* EC */ { none1, axImp, NOT_HLL | B|NO_SRC , iIN }, /* EC */
{ none1, axImp, NOT_HLL | NO_SRC , iIN , 0 , 0 }, /* ED */ { none1, axImp, NOT_HLL | NO_SRC , iIN }, /* ED */
{ none1, axImp, NOT_HLL | B|NO_SRC , iOUT , 0 , 0 }, /* EE */ { none1, axImp, NOT_HLL | B|NO_SRC , iOUT }, /* EE */
{ none1, axImp, NOT_HLL | NO_SRC , iOUT , 0 , 0 }, /* EF */ { none1, axImp, NOT_HLL | NO_SRC , iOUT }, /* EF */
{ none1, none2, NOT_HLL | NO_OPS , iLOCK , 0 , 0 }, /* F0 */ { none1, none2, NOT_HLL | NO_OPS , iLOCK }, /* F0 */
{ none1, none2, 0 , iZERO , 0 , 0 }, /* F1 */ { none1, none2, 0 , iZERO }, /* F1 */
{ prefix, none2, 0 , iREPNE, 0 , 0 }, /* F2 */ { prefix, none2, 0 , iREPNE}, /* F2 */
{ prefix, none2, 0 , iREPE , 0 , 0 }, /* F3 */ { prefix, none2, 0 , iREPE }, /* F3 */
{ none1, none2, NOT_HLL | NO_OPS , iHLT , 0 , 0 }, /* F4 */ { none1, none2, NOT_HLL | NO_OPS , iHLT }, /* F4 */
{ none1, none2, NO_OPS , iCMC , Cf, Cf }, /* F5 */ { none1, none2, NO_OPS , iCMC }, /* F5 */
{ arith, none1, B , iZERO , 0 , 0 }, /* F6 */ { arith, none1, B , iZERO }, /* F6 */
{ arith, none1, NSP , iZERO , 0 , 0 }, /* F7 */ { arith, none1, NSP , iZERO }, /* F7 */
{ none1, none2, NO_OPS , iCLC , Cf, 0 }, /* F8 */ { none1, none2, NO_OPS , iCLC }, /* F8 */
{ none1, none2, NO_OPS , iSTC , Cf, 0 }, /* F9 */ { none1, none2, NO_OPS , iSTC }, /* F9 */
{ none1, none2, NOT_HLL | NO_OPS , iCLI , 0 , 0 }, /* FA */ { none1, none2, NOT_HLL | NO_OPS , iCLI }, /* FA */
{ none1, none2, NOT_HLL | NO_OPS , iSTI , 0 , 0 }, /* FB */ { none1, none2, NOT_HLL | NO_OPS , iSTI }, /* FB */
{ none1, none2, NO_OPS , iCLD , Df, 0 }, /* FC */ { none1, none2, NO_OPS , iCLD }, /* FC */
{ none1, none2, NO_OPS , iSTD , Df, 0 }, /* FD */ { none1, none2, NO_OPS , iSTD }, /* FD */
{ trans, none1, B , iZERO , 0 , 0 }, /* FE */ { trans, none1, B , iZERO }, /* FE */
{ trans, none1, NSP , iZERO , 0 , 0 } /* FF */ { 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)
{ {