Add iInvalid enum value for invalid instructions
Various cleanups.
This commit is contained in:
parent
d7acc8cd4d
commit
d6af9c1555
@ -99,7 +99,7 @@ enum icodeType
|
|||||||
/* LOW_LEVEL icode opcodes */
|
/* LOW_LEVEL icode opcodes */
|
||||||
enum llIcode
|
enum llIcode
|
||||||
{
|
{
|
||||||
//iINVALID,
|
iINVALID=-1,
|
||||||
iCBW, /* 0 */
|
iCBW, /* 0 */
|
||||||
iAAA,
|
iAAA,
|
||||||
iAAD,
|
iAAD,
|
||||||
|
|||||||
@ -313,7 +313,7 @@ struct LLOperand
|
|||||||
struct LLInst
|
struct LLInst
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
uint32_t m_opcode; // Low level opcode identifier
|
llIcode m_opcode; // Low level opcode identifier
|
||||||
uint32_t flg; /* icode flags */
|
uint32_t flg; /* icode flags */
|
||||||
LLOperand m_src; /* source operand */
|
LLOperand m_src; /* source operand */
|
||||||
public:
|
public:
|
||||||
@ -326,8 +326,8 @@ public:
|
|||||||
std::vector<uint32_t> caseTbl2;
|
std::vector<uint32_t> caseTbl2;
|
||||||
int hllLabNum; /* label # for hll codegen */
|
int hllLabNum; /* label # for hll codegen */
|
||||||
|
|
||||||
uint32_t getOpcode() const { return m_opcode;}
|
llIcode getOpcode() const { return m_opcode;}
|
||||||
void setOpcode(uint32_t op) { m_opcode=op; }
|
void setOpcode(uint32_t op) { m_opcode=(llIcode)op; }
|
||||||
bool conditionalJump()
|
bool conditionalJump()
|
||||||
{
|
{
|
||||||
return (getOpcode() >= iJB) and (getOpcode() < iJCXZ);
|
return (getOpcode() >= iJB) and (getOpcode() < iJCXZ);
|
||||||
|
|||||||
@ -28,7 +28,7 @@ struct LLInst;
|
|||||||
typedef std::list<ICODE>::iterator iICODE;
|
typedef std::list<ICODE>::iterator iICODE;
|
||||||
struct IDX_ARRAY : public std::vector<iICODE>
|
struct IDX_ARRAY : public std::vector<iICODE>
|
||||||
{
|
{
|
||||||
bool inList(iICODE idx)
|
bool inList(iICODE idx) const
|
||||||
{
|
{
|
||||||
return std::find(begin(),end(),idx)!=end();
|
return std::find(begin(),end(),idx)!=end();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -54,7 +54,7 @@ public:
|
|||||||
ilFunction createFunction(FunctionType *f, const QString & name);
|
ilFunction createFunction(FunctionType *f, const QString & name);
|
||||||
bool valid(ilFunction iter);
|
bool valid(ilFunction iter);
|
||||||
|
|
||||||
int getSymIdxByAdd(uint32_t adr);
|
int getSymIdxByAddr(uint32_t adr);
|
||||||
bool validSymIdx(size_t idx);
|
bool validSymIdx(size_t idx);
|
||||||
size_t symbolSize(size_t idx);
|
size_t symbolSize(size_t idx);
|
||||||
hlType symbolType(size_t idx);
|
hlType symbolType(size_t idx);
|
||||||
|
|||||||
526
src/ast.cpp
526
src/ast.cpp
@ -13,6 +13,7 @@
|
|||||||
#include "project.h"
|
#include "project.h"
|
||||||
|
|
||||||
#include <QtCore/QTextStream>
|
#include <QtCore/QTextStream>
|
||||||
|
#include <QtCore/QDebug>
|
||||||
#include <boost/range.hpp>
|
#include <boost/range.hpp>
|
||||||
#include <boost/range/adaptor/filtered.hpp>
|
#include <boost/range/adaptor/filtered.hpp>
|
||||||
#include <boost/range/algorithm.hpp>
|
#include <boost/range/algorithm.hpp>
|
||||||
@ -29,12 +30,15 @@ using namespace boost::adaptors;
|
|||||||
|
|
||||||
extern int strSize (const uint8_t *, char);
|
extern int strSize (const uint8_t *, char);
|
||||||
extern char *cChar(uint8_t c);
|
extern char *cChar(uint8_t c);
|
||||||
|
namespace
|
||||||
|
{
|
||||||
// Conditional operator symbols in C. Index by condOp enumeration type
|
// Conditional operator symbols in C. Index by condOp enumeration type
|
||||||
static const char * const condOpSym[] = { " <= ", " < ", " == ", " != ", " > ", " >= ",
|
constexpr const char * condOpSym[] = { " <= ", " < ", " == ", " != ", " > ", " >= ",
|
||||||
" & ", " | ", " ^ ", " ~ ",
|
" & ", " | ", " ^ ", " ~ ",
|
||||||
" + ", " - ", " * ", " / ",
|
" + ", " - ", " * ", " / ",
|
||||||
" >> ", " << ", " % ", " && ", " || " };
|
" >> ", " << ", " % ", " && ", " || " };
|
||||||
|
/* Size of hl types */
|
||||||
|
constexpr const int hlSize[] = {2, 1, 1, 2, 2, 4, 4, 4, 2, 2, 1, 4, 4};
|
||||||
|
|
||||||
/* Local expression stack */
|
/* Local expression stack */
|
||||||
//typedef struct _EXP_STK {
|
//typedef struct _EXP_STK {
|
||||||
@ -43,13 +47,13 @@ static const char * const condOpSym[] = { " <= ", " < ", " == ", " != ", " > ",
|
|||||||
//} EXP_STK; - for local expression stack
|
//} EXP_STK; - for local expression stack
|
||||||
|
|
||||||
/* Returns the integer i in C hexadecimal format */
|
/* Returns the integer i in C hexadecimal format */
|
||||||
static const char *hexStr (uint16_t i)
|
const char *hexStr (uint16_t i)
|
||||||
{
|
{
|
||||||
static char buf[10];
|
static char buf[10];
|
||||||
sprintf (buf, "%s%x", (i > 9) ? "0x" : "", i);
|
sprintf (buf, "%s%x", (i > 9) ? "0x" : "", i);
|
||||||
return (buf);
|
return buf;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Sets the du record for registers according to the du flag */
|
/* Sets the du record for registers according to the du flag */
|
||||||
void ICODE::setRegDU (eReg regi, operDu du_in)
|
void ICODE::setRegDU (eReg regi, operDu du_in)
|
||||||
@ -62,19 +66,19 @@ void ICODE::setRegDU (eReg regi, operDu du_in)
|
|||||||
}
|
}
|
||||||
switch (du_in)
|
switch (du_in)
|
||||||
{
|
{
|
||||||
case eDEF:
|
case eDEF:
|
||||||
du.def.addReg(regi);
|
du.def.addReg(regi);
|
||||||
du1.addDef(regi);
|
du1.addDef(regi);
|
||||||
break;
|
break;
|
||||||
case eUSE:
|
case eUSE:
|
||||||
du.use.addReg(regi);
|
du.use.addReg(regi);
|
||||||
break;
|
break;
|
||||||
case USE_DEF:
|
case USE_DEF:
|
||||||
du.addDefinedAndUsed(regi);
|
du.addDefinedAndUsed(regi);
|
||||||
du1.addDef(regi);
|
du1.addDef(regi);
|
||||||
break;
|
break;
|
||||||
case NONE: /* do nothing */
|
case NONE: /* do nothing */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,24 +88,24 @@ void ICODE::copyDU(const ICODE &duIcode, operDu _du, operDu duDu)
|
|||||||
{
|
{
|
||||||
switch (_du)
|
switch (_du)
|
||||||
{
|
{
|
||||||
case eDEF:
|
case eDEF:
|
||||||
if (duDu == eDEF)
|
if (duDu == eDEF)
|
||||||
du.def=duIcode.du.def;
|
du.def=duIcode.du.def;
|
||||||
else
|
else
|
||||||
du.def=duIcode.du.use;
|
du.def=duIcode.du.use;
|
||||||
break;
|
break;
|
||||||
case eUSE:
|
case eUSE:
|
||||||
if (duDu == eDEF)
|
if (duDu == eDEF)
|
||||||
du.use = duIcode.du.def;
|
du.use = duIcode.du.def;
|
||||||
else
|
else
|
||||||
du.use = duIcode.du.use;
|
du.use = duIcode.du.use;
|
||||||
break;
|
break;
|
||||||
case USE_DEF:
|
case USE_DEF:
|
||||||
du = duIcode.du;
|
du = duIcode.du;
|
||||||
break;
|
break;
|
||||||
case NONE:
|
case NONE:
|
||||||
assert(false);
|
assert(false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,7 +128,7 @@ GlobalVariable::GlobalVariable(int16_t segValue, int16_t off)
|
|||||||
valid = true;
|
valid = true;
|
||||||
ident.idType = GLOB_VAR;
|
ident.idType = GLOB_VAR;
|
||||||
adr = opAdr(segValue, off);
|
adr = opAdr(segValue, off);
|
||||||
auto i=Project::get()->getSymIdxByAdd(adr);
|
auto i=Project::get()->getSymIdxByAddr(adr);
|
||||||
if ( not Project::get()->validSymIdx(i) )
|
if ( not Project::get()->validSymIdx(i) )
|
||||||
{
|
{
|
||||||
printf ("Error, glob var not found in symtab\n");
|
printf ("Error, glob var not found in symtab\n");
|
||||||
@ -136,7 +140,7 @@ GlobalVariable::GlobalVariable(int16_t segValue, int16_t off)
|
|||||||
QString GlobalVariable::walkCondExpr(Function *, int *) const
|
QString GlobalVariable::walkCondExpr(Function *, int *) const
|
||||||
{
|
{
|
||||||
if(valid)
|
if(valid)
|
||||||
return Project::get()->symtab[globIdx].name;
|
return Project::get()->symbolName(globIdx);
|
||||||
return "INVALID GlobalVariable";
|
return "INVALID GlobalVariable";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,7 +168,7 @@ AstIdent *AstIdent::Loc(int off, LOCAL_ID *localId)
|
|||||||
AstIdent *AstIdent::Param(int off, const STKFRAME * argSymtab)
|
AstIdent *AstIdent::Param(int off, const STKFRAME * argSymtab)
|
||||||
{
|
{
|
||||||
AstIdent *newExp;
|
AstIdent *newExp;
|
||||||
|
|
||||||
newExp = new AstIdent();
|
newExp = new AstIdent();
|
||||||
newExp->ident.idType = PARAM;
|
newExp->ident.idType = PARAM;
|
||||||
auto iter=argSymtab->findByLabel(off);
|
auto iter=argSymtab->findByLabel(off);
|
||||||
@ -262,22 +266,22 @@ AstIdent *AstIdent::idID (const ID *retVal, LOCAL_ID *locsym, iICODE ix_)
|
|||||||
AstIdent *newExp=nullptr;
|
AstIdent *newExp=nullptr;
|
||||||
switch(retVal->type)
|
switch(retVal->type)
|
||||||
{
|
{
|
||||||
case TYPE_LONG_SIGN:
|
case TYPE_LONG_SIGN:
|
||||||
{
|
{
|
||||||
newExp = new AstIdent();
|
newExp = new AstIdent();
|
||||||
int idx = locsym->newLongReg (TYPE_LONG_SIGN, retVal->longId(), ix_);
|
int idx = locsym->newLongReg (TYPE_LONG_SIGN, retVal->longId(), ix_);
|
||||||
newExp->ident.idType = LONG_VAR;
|
newExp->ident.idType = LONG_VAR;
|
||||||
newExp->ident.idNode.longIdx = idx;
|
newExp->ident.idNode.longIdx = idx;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TYPE_WORD_SIGN:
|
case TYPE_WORD_SIGN:
|
||||||
newExp = new RegisterNode(locsym->newByteWordReg(retVal->type, retVal->id.regi),WORD_REG,locsym);
|
newExp = new RegisterNode(locsym->newByteWordReg(retVal->type, retVal->id.regi),WORD_REG,locsym);
|
||||||
break;
|
break;
|
||||||
case TYPE_BYTE_SIGN:
|
case TYPE_BYTE_SIGN:
|
||||||
newExp = new RegisterNode(locsym->newByteWordReg(retVal->type, retVal->id.regi),BYTE_REG,locsym);
|
newExp = new RegisterNode(locsym->newByteWordReg(retVal->type, retVal->id.regi),BYTE_REG,locsym);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr,"AstIdent::idID unhandled type %d\n",retVal->type);
|
fprintf(stderr,"AstIdent::idID unhandled type %d\n",retVal->type);
|
||||||
}
|
}
|
||||||
return (newExp);
|
return (newExp);
|
||||||
}
|
}
|
||||||
@ -291,11 +295,11 @@ AstIdent *AstIdent::idID (const ID *retVal, LOCAL_ID *locsym, iICODE ix_)
|
|||||||
Expr *AstIdent::id(const LLInst &ll_insn, opLoc sd, Function * pProc, iICODE ix_,ICODE &duIcode, operDu du)
|
Expr *AstIdent::id(const LLInst &ll_insn, opLoc sd, Function * pProc, iICODE ix_,ICODE &duIcode, operDu du)
|
||||||
{
|
{
|
||||||
Expr *newExp;
|
Expr *newExp;
|
||||||
|
|
||||||
int idx; /* idx into pIcode->localId table */
|
int idx; /* idx into pIcode->localId table */
|
||||||
|
|
||||||
const LLOperand &pm(*ll_insn.get(sd));
|
const LLOperand &pm(*ll_insn.get(sd));
|
||||||
|
|
||||||
if ( ((sd == DST) and ll_insn.testFlags(IM_DST)) or
|
if ( ((sd == DST) and ll_insn.testFlags(IM_DST)) or
|
||||||
((sd == SRC) and ll_insn.testFlags(IM_SRC)) or
|
((sd == SRC) and ll_insn.testFlags(IM_SRC)) or
|
||||||
(sd == LHS_OP)) /* for MUL lhs */
|
(sd == LHS_OP)) /* for MUL lhs */
|
||||||
@ -305,13 +309,13 @@ Expr *AstIdent::id(const LLInst &ll_insn, opLoc sd, Function * pProc, iICODE ix_
|
|||||||
duIcode.setRegDU (rDX, du);
|
duIcode.setRegDU (rDX, du);
|
||||||
duIcode.setRegDU (rAX, du);
|
duIcode.setRegDU (rAX, du);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if ((sd == DST) and ll_insn.testFlags(IM_TMP_DST))
|
else if ((sd == DST) and ll_insn.testFlags(IM_TMP_DST))
|
||||||
{ /* implicit tmp */
|
{ /* implicit tmp */
|
||||||
newExp = new RegisterNode(LLOperand(rTMP,2), &pProc->localId);
|
newExp = new RegisterNode(LLOperand(rTMP,2), &pProc->localId);
|
||||||
duIcode.setRegDU(rTMP, (operDu)eUSE);
|
duIcode.setRegDU(rTMP, (operDu)eUSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if ((sd == SRC) and ll_insn.testFlags(I)) /* constant */
|
else if ((sd == SRC) and ll_insn.testFlags(I)) /* constant */
|
||||||
newExp = new Constant(ll_insn.src().getImm2(), 2);
|
newExp = new Constant(ll_insn.src().getImm2(), 2);
|
||||||
else if (pm.regi == rUNDEF) /* global variable */
|
else if (pm.regi == rUNDEF) /* global variable */
|
||||||
@ -322,7 +326,7 @@ Expr *AstIdent::id(const LLInst &ll_insn, opLoc sd, Function * pProc, iICODE ix_
|
|||||||
newExp = new RegisterNode(pm, &pProc->localId);
|
newExp = new RegisterNode(pm, &pProc->localId);
|
||||||
duIcode.setRegDU( pm.regi, du);
|
duIcode.setRegDU( pm.regi, du);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (pm.off) /* offset */
|
else if (pm.off) /* offset */
|
||||||
{ // TODO: this is ABI specific, should be actually based on Function calling conv
|
{ // TODO: this is ABI specific, should be actually based on Function calling conv
|
||||||
if ((pm.seg == rSS) and (pm.regi == INDEX_BP)) /* idx on bp */
|
if ((pm.seg == rSS) and (pm.regi == INDEX_BP)) /* idx on bp */
|
||||||
@ -344,20 +348,19 @@ Expr *AstIdent::id(const LLInst &ll_insn, opLoc sd, Function * pProc, iICODE ix_
|
|||||||
newExp = AstIdent::Other (pm.seg, pm.regi, pm.off);
|
newExp = AstIdent::Other (pm.seg, pm.regi, pm.off);
|
||||||
/**** check long ops, indexed global var *****/
|
/**** check long ops, indexed global var *****/
|
||||||
}
|
}
|
||||||
|
|
||||||
else /* (pm->regi >= INDEXBASE and pm->off = 0) => indexed and no off */
|
else /* (pm->regi >= INDEXBASE and pm->off = 0) => indexed and no off */
|
||||||
{
|
{
|
||||||
if ((pm.seg == rDS) and (pm.regi > INDEX_BP_DI)) /* dereference */
|
if ((pm.seg == rDS) and (pm.regi > INDEX_BP_DI)) /* dereference */
|
||||||
{
|
{
|
||||||
eReg selected;
|
eReg selected;
|
||||||
switch (pm.regi) {
|
switch (pm.regi) {
|
||||||
case INDEX_SI: selected = rSI; break;
|
case INDEX_SI: selected = rSI; break;
|
||||||
case INDEX_DI: selected = rDI; break;
|
case INDEX_DI: selected = rDI; break;
|
||||||
case INDEX_BP: selected = rBP; break;
|
case INDEX_BP: selected = rBP; break;
|
||||||
case INDEX_BX: selected = rBX; break;
|
case INDEX_BX: selected = rBX; break;
|
||||||
default:
|
default:
|
||||||
newExp = nullptr;
|
newExp = nullptr;
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
//NOTICE: was selected, 0
|
//NOTICE: was selected, 0
|
||||||
newExp = new RegisterNode(LLOperand(selected, 0), &pProc->localId);
|
newExp = new RegisterNode(LLOperand(selected, 0), &pProc->localId);
|
||||||
@ -367,7 +370,7 @@ Expr *AstIdent::id(const LLInst &ll_insn, opLoc sd, Function * pProc, iICODE ix_
|
|||||||
else
|
else
|
||||||
newExp = AstIdent::Other (pm.seg, pm.regi, 0);
|
newExp = AstIdent::Other (pm.seg, pm.regi, 0);
|
||||||
}
|
}
|
||||||
return (newExp);
|
return newExp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -375,33 +378,30 @@ Expr *AstIdent::id(const LLInst &ll_insn, opLoc sd, Function * pProc, iICODE ix_
|
|||||||
condId LLInst::idType(opLoc sd) const
|
condId LLInst::idType(opLoc sd) const
|
||||||
{
|
{
|
||||||
const LLOperand &pm((sd == SRC) ? src() : m_dst);
|
const LLOperand &pm((sd == SRC) ? src() : m_dst);
|
||||||
|
|
||||||
if ((sd == SRC) and testFlags(I))
|
if ((sd == SRC) and testFlags(I))
|
||||||
return (CONSTANT);
|
return CONSTANT;
|
||||||
else if (pm.regi == 0)
|
else if (pm.regi == 0)
|
||||||
return (GLOB_VAR);
|
return GLOB_VAR;
|
||||||
else if ( pm.isReg() )
|
else if ( pm.isReg() )
|
||||||
return (REGISTER);
|
return REGISTER;
|
||||||
else if ((pm.seg == rSS) and (pm.regi == INDEX_BP))
|
else if ((pm.seg == rSS) and (pm.regi == INDEX_BP)) // TODO: this assumes BP-based function frames !
|
||||||
{
|
{
|
||||||
//TODO: which pm.seg/pm.regi pairs should produce PARAM/LOCAL_VAR ?
|
//TODO: which pm.seg/pm.regi pairs should produce PARAM/LOCAL_VAR ?
|
||||||
if (pm.off >= 0)
|
if (pm.off >= 0)
|
||||||
return (PARAM);
|
return PARAM;
|
||||||
else
|
return LOCAL_VAR;
|
||||||
return (LOCAL_VAR);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return (OTHER);
|
return OTHER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Size of hl types */
|
|
||||||
int hlSize[] = {2, 1, 1, 2, 2, 4, 4, 4, 2, 2, 1, 4, 4};
|
|
||||||
|
|
||||||
int Expr::hlTypeSize(Function * pproc) const
|
int Expr::hlTypeSize(Function * pproc) const
|
||||||
{
|
{
|
||||||
if (this == nullptr)
|
if (this == nullptr)
|
||||||
return (2); /* for TYPE_UNKNOWN */
|
return 2; /* for TYPE_UNKNOWN */
|
||||||
fprintf(stderr,"hlTypeSize queried for Unkown type %d \n",m_type);
|
fprintf(stderr,"hlTypeSize queried for Unkown type %d \n",m_type);
|
||||||
return 2; // CC: is this correct?
|
return 2; // CC: is this correct?
|
||||||
}
|
}
|
||||||
@ -428,22 +428,22 @@ int AstIdent::hlTypeSize(Function *pproc) const
|
|||||||
{
|
{
|
||||||
switch (ident.idType)
|
switch (ident.idType)
|
||||||
{
|
{
|
||||||
case GLOB_VAR:
|
case GLOB_VAR:
|
||||||
assert(false);
|
assert(false);
|
||||||
return 1;
|
return 1;
|
||||||
case LOCAL_VAR:
|
case LOCAL_VAR:
|
||||||
return (hlSize[pproc->localId.id_arr[ident.idNode.localIdx].type]);
|
return (hlSize[pproc->localId.id_arr[ident.idNode.localIdx].type]);
|
||||||
case PARAM:
|
case PARAM:
|
||||||
return (hlSize[pproc->args[ident.idNode.paramIdx].type]);
|
return (hlSize[pproc->args[ident.idNode.paramIdx].type]);
|
||||||
case STRING:
|
case STRING:
|
||||||
return (2);
|
return 2;
|
||||||
case LONG_VAR:
|
case LONG_VAR:
|
||||||
return (4);
|
return 4;
|
||||||
case OTHER:
|
case OTHER:
|
||||||
return (2);
|
return 2;
|
||||||
default:
|
default:
|
||||||
assert(false);
|
assert(false);
|
||||||
return -1;
|
return -1;
|
||||||
} /* eos */
|
} /* eos */
|
||||||
}
|
}
|
||||||
hlType BinaryOperator::expType(Function *pproc) const
|
hlType BinaryOperator::expType(Function *pproc) const
|
||||||
@ -477,24 +477,24 @@ hlType AstIdent::expType(Function *pproc) const
|
|||||||
{
|
{
|
||||||
switch (ident.idType)
|
switch (ident.idType)
|
||||||
{
|
{
|
||||||
case UNDEF:
|
case UNDEF:
|
||||||
case CONSTANT:
|
case CONSTANT:
|
||||||
case FUNCTION:
|
case FUNCTION:
|
||||||
case REGISTER:
|
case REGISTER:
|
||||||
case GLOB_VAR:
|
case GLOB_VAR:
|
||||||
case GLOB_VAR_IDX:
|
case GLOB_VAR_IDX:
|
||||||
assert(false);
|
assert(false);
|
||||||
return TYPE_UNKNOWN;
|
return TYPE_UNKNOWN;
|
||||||
case LOCAL_VAR:
|
case LOCAL_VAR:
|
||||||
return (pproc->localId.id_arr[ident.idNode.localIdx].type);
|
return (pproc->localId.id_arr[ident.idNode.localIdx].type);
|
||||||
case PARAM:
|
case PARAM:
|
||||||
return (pproc->args[ident.idNode.paramIdx].type);
|
return (pproc->args[ident.idNode.paramIdx].type);
|
||||||
case STRING:
|
case STRING:
|
||||||
return (TYPE_STR);
|
return (TYPE_STR);
|
||||||
case LONG_VAR:
|
case LONG_VAR:
|
||||||
return (pproc->localId.id_arr[ident.idNode.longIdx].type);
|
return (pproc->localId.id_arr[ident.idNode.longIdx].type);
|
||||||
default:
|
default:
|
||||||
return (TYPE_UNKNOWN);
|
return (TYPE_UNKNOWN);
|
||||||
} /* eos */
|
} /* eos */
|
||||||
return (TYPE_UNKNOWN);
|
return (TYPE_UNKNOWN);
|
||||||
}
|
}
|
||||||
@ -507,17 +507,17 @@ hlType AstIdent::expType(Function *pproc) const
|
|||||||
Expr * HlTypeSupport::performLongRemoval (eReg regi, LOCAL_ID *locId, Expr *tree)
|
Expr * HlTypeSupport::performLongRemoval (eReg regi, LOCAL_ID *locId, Expr *tree)
|
||||||
{
|
{
|
||||||
switch (tree->m_type) {
|
switch (tree->m_type) {
|
||||||
case BOOLEAN_OP:
|
case BOOLEAN_OP:
|
||||||
case POST_INC: case POST_DEC:
|
case POST_INC: case POST_DEC:
|
||||||
case PRE_INC: case PRE_DEC:
|
case PRE_INC: case PRE_DEC:
|
||||||
case NEGATION: case ADDRESSOF:
|
case NEGATION: case ADDRESSOF:
|
||||||
case DEREFERENCE:
|
case DEREFERENCE:
|
||||||
case IDENTIFIER:
|
case IDENTIFIER:
|
||||||
return tree->performLongRemoval(regi,locId);
|
return tree->performLongRemoval(regi,locId);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr,"performLongRemoval attemped on %d\n",tree->m_type);
|
fprintf(stderr,"performLongRemoval attemped on %d\n",tree->m_type);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return tree;
|
return tree;
|
||||||
}
|
}
|
||||||
@ -528,7 +528,7 @@ static QString getString (int offset)
|
|||||||
PROG &prog(Project::get()->prog);
|
PROG &prog(Project::get()->prog);
|
||||||
QString o;
|
QString o;
|
||||||
int strLen, i;
|
int strLen, i;
|
||||||
|
|
||||||
strLen = strSize (&prog.image()[offset], '\0');
|
strLen = strSize (&prog.image()[offset], '\0');
|
||||||
o += '"';
|
o += '"';
|
||||||
for (i = 0; i < strLen; i++)
|
for (i = 0; i < strLen; i++)
|
||||||
@ -539,7 +539,7 @@ static QString getString (int offset)
|
|||||||
QString BinaryOperator::walkCondExpr(Function * pProc, int* numLoc) const
|
QString BinaryOperator::walkCondExpr(Function * pProc, int* numLoc) const
|
||||||
{
|
{
|
||||||
assert(rhs());
|
assert(rhs());
|
||||||
|
|
||||||
return QString("(%1%2%3)")
|
return QString("(%1%2%3)")
|
||||||
.arg((m_op!=NOT) ? lhs()->walkCondExpr(pProc, numLoc) : "")
|
.arg((m_op!=NOT) ? lhs()->walkCondExpr(pProc, numLoc) : "")
|
||||||
.arg(condOpSym[m_op])
|
.arg(condOpSym[m_op])
|
||||||
@ -553,67 +553,71 @@ QString AstIdent::walkCondExpr(Function *pProc, int *numLoc) const
|
|||||||
STKSYM * psym; /* Pointer to argument in the stack */
|
STKSYM * psym; /* Pointer to argument in the stack */
|
||||||
QString codeContents;
|
QString codeContents;
|
||||||
QString collectedContents;
|
QString collectedContents;
|
||||||
|
|
||||||
QTextStream codeOut(&codeContents);
|
QTextStream codeOut(&codeContents);
|
||||||
QTextStream o(&collectedContents);
|
QTextStream o(&collectedContents);
|
||||||
|
|
||||||
switch (ident.idType)
|
switch (ident.idType)
|
||||||
{
|
{
|
||||||
case LOCAL_VAR:
|
case LOCAL_VAR:
|
||||||
o << pProc->localId.id_arr[ident.idNode.localIdx].name;
|
o << pProc->localId.id_arr[ident.idNode.localIdx].name;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PARAM:
|
case PARAM:
|
||||||
psym = &pProc->args[ident.idNode.paramIdx];
|
psym = &pProc->args[ident.idNode.paramIdx];
|
||||||
if (psym->hasMacro)
|
if (psym->hasMacro)
|
||||||
o << psym->macro<<"("<<psym->name<< ")";
|
o << psym->macro<<"("<<psym->name<< ")";
|
||||||
else
|
else
|
||||||
o << psym->name;
|
o << psym->name;
|
||||||
break;
|
break;
|
||||||
case STRING:
|
case STRING:
|
||||||
o << getString (ident.idNode.strIdx);
|
o << getString (ident.idNode.strIdx);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LONG_VAR:
|
case LONG_VAR:
|
||||||
id = &pProc->localId.id_arr[ident.idNode.longIdx];
|
id = &pProc->localId.id_arr[ident.idNode.longIdx];
|
||||||
if (id->name[0] != '\0') /* STK_FRAME & REG w/name*/
|
if (id->name[0] != '\0') /* STK_FRAME & REG w/name*/
|
||||||
o << id->name;
|
o << id->name;
|
||||||
else if (id->loc == REG_FRAME)
|
else if (id->loc == REG_FRAME)
|
||||||
{
|
{
|
||||||
id->setLocalName(++(*numLoc));
|
id->setLocalName(++(*numLoc));
|
||||||
codeOut <<TypeContainer::typeName(id->type)<< " "<<id->name<<"; ";
|
codeOut <<TypeContainer::typeName(id->type)<< " "<<id->name<<"; ";
|
||||||
codeOut <<"/* "<<Machine_X86::regName(id->longId().h()) << ":" <<
|
codeOut <<"/* "<<Machine_X86::regName(id->longId().h()) << ":" <<
|
||||||
Machine_X86::regName(id->longId().l()) << " */\n";
|
Machine_X86::regName(id->longId().l()) << " */\n";
|
||||||
o << id->name;
|
o << id->name;
|
||||||
pProc->localId.propLongId (id->longId().l(),id->longId().h(), id->name);
|
pProc->localId.propLongId (id->longId().l(),id->longId().h(), id->name);
|
||||||
}
|
}
|
||||||
else /* GLB_FRAME */
|
else /* GLB_FRAME */
|
||||||
{
|
{
|
||||||
if (id->id.longGlb.regi == 0) /* not indexed */
|
if (id->id.longGlb.regi == 0) /* not indexed */
|
||||||
o << "[" << (id->id.longGlb.seg<<4) + id->id.longGlb.offH <<"]";
|
o << "[" << (id->id.longGlb.seg<<4) + id->id.longGlb.offH <<"]";
|
||||||
else if (id->id.longGlb.regi == rBX)
|
else if (id->id.longGlb.regi == rBX)
|
||||||
o << "[" << (id->id.longGlb.seg<<4) + id->id.longGlb.offH <<"][bx]";
|
o << "[" << (id->id.longGlb.seg<<4) + id->id.longGlb.offH <<"][bx]";
|
||||||
}
|
else {
|
||||||
break;
|
qCritical() << "AstIdent::walkCondExpr unhandled LONG_VAR in GLB_FRAME";
|
||||||
case OTHER:
|
assert(false);
|
||||||
off = ident.idNode.other.off;
|
}
|
||||||
o << Machine_X86::regName(ident.idNode.other.seg)<< "[";
|
}
|
||||||
o << Machine_X86::regName(ident.idNode.other.regi);
|
break;
|
||||||
if (off < 0)
|
case OTHER:
|
||||||
o << "-"<< hexStr (-off);
|
off = ident.idNode.other.off;
|
||||||
else if (off>0)
|
o << Machine_X86::regName(ident.idNode.other.seg)<< "[";
|
||||||
o << "+"<< hexStr (off);
|
o << Machine_X86::regName(ident.idNode.other.regi);
|
||||||
o << "]";
|
if (off < 0)
|
||||||
break;
|
o << "-"<< hexStr (-off);
|
||||||
default:
|
else if (off>0)
|
||||||
assert(false);
|
o << "+"<< hexStr (off);
|
||||||
return "";
|
o << "]";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
return "";
|
||||||
|
|
||||||
|
|
||||||
} /* eos */
|
} /* eos */
|
||||||
cCode.appendDecl(codeContents);
|
cCode.appendDecl(codeContents);
|
||||||
return collectedContents;
|
return collectedContents;
|
||||||
|
|
||||||
}
|
}
|
||||||
QString UnaryOperator::wrapUnary(Function *pProc, int *numLoc,QChar op) const
|
QString UnaryOperator::wrapUnary(Function *pProc, int *numLoc,QChar op) const
|
||||||
{
|
{
|
||||||
@ -631,33 +635,33 @@ QString UnaryOperator::walkCondExpr(Function *pProc, int *numLoc) const
|
|||||||
QString outStr;
|
QString outStr;
|
||||||
switch(m_type)
|
switch(m_type)
|
||||||
{
|
{
|
||||||
case NEGATION:
|
case NEGATION:
|
||||||
outStr+=wrapUnary(pProc,numLoc,'!');
|
outStr+=wrapUnary(pProc,numLoc,'!');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ADDRESSOF:
|
case ADDRESSOF:
|
||||||
outStr+=wrapUnary(pProc,numLoc,'&');
|
outStr+=wrapUnary(pProc,numLoc,'&');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DEREFERENCE:
|
case DEREFERENCE:
|
||||||
outStr+=wrapUnary(pProc,numLoc,'*');
|
outStr+=wrapUnary(pProc,numLoc,'*');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case POST_INC:
|
case POST_INC:
|
||||||
outStr += unaryExp->walkCondExpr (pProc, numLoc) + "++";
|
outStr += unaryExp->walkCondExpr (pProc, numLoc) + "++";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case POST_DEC:
|
case POST_DEC:
|
||||||
outStr += unaryExp->walkCondExpr (pProc, numLoc) + "--";
|
outStr += unaryExp->walkCondExpr (pProc, numLoc) + "--";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PRE_INC:
|
case PRE_INC:
|
||||||
outStr += "++" + unaryExp->walkCondExpr (pProc, numLoc);
|
outStr += "++" + unaryExp->walkCondExpr (pProc, numLoc);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PRE_DEC:
|
case PRE_DEC:
|
||||||
outStr += "--" + unaryExp->walkCondExpr (pProc, numLoc);
|
outStr += "--" + unaryExp->walkCondExpr (pProc, numLoc);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return outStr;
|
return outStr;
|
||||||
}
|
}
|
||||||
@ -665,9 +669,6 @@ QString UnaryOperator::walkCondExpr(Function *pProc, int *numLoc) const
|
|||||||
/* Walks the conditional expression tree and returns the result on a string */
|
/* Walks the conditional expression tree and returns the result on a string */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Changes the boolean conditional operator at the root of this expression */
|
/* Changes the boolean conditional operator at the root of this expression */
|
||||||
void BinaryOperator::changeBoolOp (condOp newOp)
|
void BinaryOperator::changeBoolOp (condOp newOp)
|
||||||
{
|
{
|
||||||
@ -689,7 +690,7 @@ bool Expr::insertSubTreeReg (AstIdent *&tree, Expr *_expr, eReg regi,const LOCAL
|
|||||||
* register regi */
|
* register regi */
|
||||||
bool Expr::insertSubTreeReg (Expr *&tree, Expr *_expr, eReg regi,const LOCAL_ID *locsym)
|
bool Expr::insertSubTreeReg (Expr *&tree, Expr *_expr, eReg regi,const LOCAL_ID *locsym)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (tree == nullptr)
|
if (tree == nullptr)
|
||||||
return false;
|
return false;
|
||||||
Expr *temp=tree->insertSubTreeReg(_expr,regi,locsym);
|
Expr *temp=tree->insertSubTreeReg(_expr,regi,locsym);
|
||||||
@ -704,20 +705,20 @@ bool Expr::insertSubTreeReg (Expr *&tree, Expr *_expr, eReg regi,const LOCAL_ID
|
|||||||
Expr *UnaryOperator::insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *locsym)
|
Expr *UnaryOperator::insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *locsym)
|
||||||
{
|
{
|
||||||
Expr *temp;
|
Expr *temp;
|
||||||
|
|
||||||
switch (m_type) {
|
switch (m_type) {
|
||||||
case NEGATION:
|
case NEGATION:
|
||||||
case ADDRESSOF:
|
case ADDRESSOF:
|
||||||
case DEREFERENCE:
|
case DEREFERENCE:
|
||||||
temp = unaryExp->insertSubTreeReg( _expr, regi, locsym);
|
temp = unaryExp->insertSubTreeReg( _expr, regi, locsym);
|
||||||
if (nullptr!=temp)
|
if (nullptr!=temp)
|
||||||
{
|
{
|
||||||
unaryExp = temp;
|
unaryExp = temp;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr,"insertSubTreeReg attempt on unhandled type %d\n",m_type);
|
fprintf(stderr,"insertSubTreeReg attempt on unhandled type %d\n",m_type);
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -798,9 +799,8 @@ Expr *BinaryOperator::insertSubTreeLongReg(Expr *_expr, int longIdx)
|
|||||||
Expr *AstIdent::insertSubTreeLongReg(Expr *_expr, int longIdx)
|
Expr *AstIdent::insertSubTreeLongReg(Expr *_expr, int longIdx)
|
||||||
{
|
{
|
||||||
if (ident.idNode.longIdx == longIdx)
|
if (ident.idNode.longIdx == longIdx)
|
||||||
{
|
|
||||||
return _expr;
|
return _expr;
|
||||||
}
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -816,53 +816,51 @@ Expr *BinaryOperator::clone() const
|
|||||||
|
|
||||||
Expr *BinaryOperator::inverse() const
|
Expr *BinaryOperator::inverse() const
|
||||||
{
|
{
|
||||||
static condOp invCondOp[] = {GREATER, GREATER_EQUAL, NOT_EQUAL, EQUAL,
|
constexpr static condOp invCondOp[] = {GREATER, GREATER_EQUAL, NOT_EQUAL, EQUAL,
|
||||||
LESS_EQUAL, LESS, DUMMY,DUMMY,DUMMY,DUMMY,
|
LESS_EQUAL, LESS, DUMMY,DUMMY,DUMMY,DUMMY,
|
||||||
DUMMY, DUMMY, DUMMY, DUMMY, DUMMY, DUMMY,
|
DUMMY, DUMMY, DUMMY, DUMMY, DUMMY, DUMMY,
|
||||||
DUMMY, DBL_OR, DBL_AND};
|
DUMMY, DBL_OR, DBL_AND};
|
||||||
BinaryOperator *res=reinterpret_cast<BinaryOperator *>(this->clone());
|
BinaryOperator *res=reinterpret_cast<BinaryOperator *>(this->clone());
|
||||||
switch (m_op)
|
switch (m_op)
|
||||||
{
|
{
|
||||||
case LESS_EQUAL: case LESS: case EQUAL:
|
case LESS_EQUAL: case LESS: case EQUAL:
|
||||||
case NOT_EQUAL: case GREATER: case GREATER_EQUAL:
|
case NOT_EQUAL: case GREATER: case GREATER_EQUAL:
|
||||||
res->m_op = invCondOp[m_op];
|
res->m_op = invCondOp[m_op];
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
case AND: case OR: case XOR: case NOT: case ADD:
|
case AND: case OR: case XOR: case NOT: case ADD:
|
||||||
case SUB: case MUL: case DIV: case SHR: case SHL: case MOD:
|
case SUB: case MUL: case DIV: case SHR: case SHL: case MOD:
|
||||||
return UnaryOperator::Create(NEGATION, res);
|
return UnaryOperator::Create(NEGATION, res);
|
||||||
|
|
||||||
case DBL_AND: case DBL_OR:
|
case DBL_AND: case DBL_OR:
|
||||||
res->m_op = invCondOp[m_op];
|
res->m_op = invCondOp[m_op];
|
||||||
res->m_lhs=m_lhs->inverse ();
|
res->m_lhs=m_lhs->inverse ();
|
||||||
res->m_rhs=m_rhs->inverse ();
|
res->m_rhs=m_rhs->inverse ();
|
||||||
return res;
|
return res;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr,"BinaryOperator::inverse attempt on unhandled op %d\n",m_op);
|
fprintf(stderr,"BinaryOperator::inverse attempt on unhandled op %d\n",m_op);
|
||||||
} /* eos */
|
} /* eos */
|
||||||
assert(false);
|
assert(false);
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
}
|
}
|
||||||
Expr *AstIdent::performLongRemoval(eReg regi, LOCAL_ID *locId)
|
Expr *AstIdent::performLongRemoval(eReg regi, LOCAL_ID *locId)
|
||||||
{
|
{
|
||||||
eReg otherRegi; /* high or low part of long register */
|
eReg otherRegi; /* high or low part of long register */
|
||||||
|
|
||||||
if (ident.idType == LONG_VAR)
|
if (ident.idType != LONG_VAR)
|
||||||
{
|
return this;
|
||||||
otherRegi = locId->getPairedRegisterAt(ident.idNode.longIdx,regi);
|
otherRegi = locId->getPairedRegisterAt(ident.idNode.longIdx,regi);
|
||||||
delete this;
|
bool long_was_signed = locId->id_arr[ident.idNode.longIdx].isSigned();
|
||||||
return new RegisterNode(locId->newByteWordReg(TYPE_WORD_SIGN,otherRegi),WORD_REG,locId);
|
delete this;
|
||||||
}
|
return new RegisterNode(locId->newByteWordReg(long_was_signed ? TYPE_WORD_SIGN : TYPE_WORD_UNSIGN,otherRegi),WORD_REG,locId);
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Constant::walkCondExpr(Function *, int *) const
|
QString Constant::walkCondExpr(Function *, int *) const
|
||||||
{
|
{
|
||||||
if (kte.kte < 1000)
|
if (kte.kte < 1000)
|
||||||
return QString::number(kte.kte);
|
return QString::number(kte.kte);
|
||||||
else
|
return "0x" + QString::number(kte.kte,16);
|
||||||
return "0x" + QString::number(kte.kte,16);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int Constant::hlTypeSize(Function *) const
|
int Constant::hlTypeSize(Function *) const
|
||||||
@ -870,8 +868,6 @@ int Constant::hlTypeSize(Function *) const
|
|||||||
return kte.size;
|
return kte.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
QString FuncNode::walkCondExpr(Function *pProc, int *numLoc) const
|
QString FuncNode::walkCondExpr(Function *pProc, int *numLoc) const
|
||||||
{
|
{
|
||||||
return pProc->writeCall(call.proc,*call.args, numLoc);
|
return pProc->writeCall(call.proc,*call.args, numLoc);
|
||||||
|
|||||||
@ -158,9 +158,9 @@ void Project::writeGlobSymTable()
|
|||||||
else { /* first defined */
|
else { /* first defined */
|
||||||
switch (sym.size) {
|
switch (sym.size) {
|
||||||
case 1: ostr<<"uint8_t\t"; break;
|
case 1: ostr<<"uint8_t\t"; break;
|
||||||
case 2: ostr<<"int\t"; break;
|
case 2: ostr<<"int16_t\t"; break;
|
||||||
case 4: if (sym.type == TYPE_PTR)
|
case 4: if (sym.type == TYPE_PTR)
|
||||||
ostr<<"int\t*";
|
ostr<<"int32_t\t*";
|
||||||
else
|
else
|
||||||
ostr<<"char\t*";
|
ostr<<"char\t*";
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -735,7 +735,7 @@ int C_CallingConvention::processCArg (Function * callee, Function * pProc, ICODE
|
|||||||
callee->args.adjustForArgType (numArgs, _exp->expType (pProc));
|
callee->args.adjustForArgType (numArgs, _exp->expType (pProc));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
res = picode->newStkArg (_exp, (llIcode)picode->ll()->getOpcode(), pProc);
|
res = picode->newStkArg (_exp, picode->ll()->getOpcode(), pProc);
|
||||||
/* Do not update the size of k if the expression was a segment register
|
/* Do not update the size of k if the expression was a segment register
|
||||||
* in a near call */
|
* in a near call */
|
||||||
if (res == false)
|
if (res == false)
|
||||||
@ -850,7 +850,7 @@ void Pascal_CallingConvention::processHLI(Function *func,Expr *_exp, iICODE pico
|
|||||||
{
|
{
|
||||||
if (pp->args.numArgs > 0)
|
if (pp->args.numArgs > 0)
|
||||||
_exp = func->adjustActArgType(_exp, pp->args[numArgs].type);
|
_exp = func->adjustActArgType(_exp, pp->args[numArgs].type);
|
||||||
res = picode->newStkArg (_exp, (llIcode)picode->ll()->getOpcode(), func);
|
res = picode->newStkArg (_exp, picode->ll()->getOpcode(), func);
|
||||||
}
|
}
|
||||||
else /* user function */
|
else /* user function */
|
||||||
{
|
{
|
||||||
@ -863,7 +863,7 @@ void Pascal_CallingConvention::processHLI(Function *func,Expr *_exp, iICODE pico
|
|||||||
else
|
else
|
||||||
pp->args.adjustForArgType (numArgs,_exp->expType (func));
|
pp->args.adjustForArgType (numArgs,_exp->expType (func));
|
||||||
}
|
}
|
||||||
res = picode->newStkArg (_exp,(llIcode)picode->ll()->getOpcode(), func);
|
res = picode->newStkArg (_exp, picode->ll()->getOpcode(), func);
|
||||||
}
|
}
|
||||||
if (res == false)
|
if (res == false)
|
||||||
k += _exp->hlTypeSize (func);
|
k += _exp->hlTypeSize (func);
|
||||||
|
|||||||
@ -75,8 +75,7 @@ eReg ID::getPairedRegister(eReg first) const {
|
|||||||
* ix : index into icode array where this var is used */
|
* ix : index into icode array where this var is used */
|
||||||
void LOCAL_ID::newIdent(hlType t, frameType f)
|
void LOCAL_ID::newIdent(hlType t, frameType f)
|
||||||
{
|
{
|
||||||
ID newid(t,f);
|
id_arr.emplace_back(t,f);
|
||||||
id_arr.push_back(newid);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -92,9 +91,8 @@ int LOCAL_ID::newByteWordReg(hlType t, eReg regi)
|
|||||||
return found-id_arr.begin();
|
return found-id_arr.begin();
|
||||||
/* Not in table, create new identifier */
|
/* Not in table, create new identifier */
|
||||||
newIdent (t, REG_FRAME);
|
newIdent (t, REG_FRAME);
|
||||||
int idx = id_arr.size() - 1;
|
id_arr.back().id.regi = regi;
|
||||||
id_arr[idx].id.regi = regi;
|
return id_arr.size() - 1;
|
||||||
return (idx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -5,12 +5,11 @@
|
|||||||
#include "CallGraph.h"
|
#include "CallGraph.h"
|
||||||
#include "project.h"
|
#include "project.h"
|
||||||
#include "Procedure.h"
|
#include "Procedure.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
//Project g_proj;
|
|
||||||
QString asm1_name, asm2_name; /* Assembler output filenames */
|
QString asm1_name, asm2_name; /* Assembler output filenames */
|
||||||
SYMTAB symtab; /* Global symbol table */
|
|
||||||
STATS stats; /* cfg statistics */
|
STATS stats; /* cfg statistics */
|
||||||
//PROG prog; /* programs fields */
|
|
||||||
OPTION option; /* Command line options */
|
OPTION option; /* Command line options */
|
||||||
Project *Project::s_instance = nullptr;
|
Project *Project::s_instance = nullptr;
|
||||||
Project::Project() : callGraph(nullptr)
|
Project::Project() : callGraph(nullptr)
|
||||||
@ -40,7 +39,7 @@ bool Project::valid(ilFunction iter)
|
|||||||
ilFunction Project::funcIter(Function *to_find)
|
ilFunction Project::funcIter(Function *to_find)
|
||||||
{
|
{
|
||||||
auto iter=std::find_if(pProcList.begin(),pProcList.end(),
|
auto iter=std::find_if(pProcList.begin(),pProcList.end(),
|
||||||
[to_find](const Function &f)->bool {return to_find==&f;});
|
[to_find](const Function &f)->bool {return to_find==&f;});
|
||||||
assert(iter!=pProcList.end());
|
assert(iter!=pProcList.end());
|
||||||
return iter;
|
return iter;
|
||||||
}
|
}
|
||||||
@ -49,8 +48,8 @@ ilFunction Project::findByEntry(uint32_t entry)
|
|||||||
{
|
{
|
||||||
/* Search procedure list for one with appropriate entry point */
|
/* Search procedure list for one with appropriate entry point */
|
||||||
ilFunction iter= std::find_if(pProcList.begin(),pProcList.end(),
|
ilFunction iter= std::find_if(pProcList.begin(),pProcList.end(),
|
||||||
[entry](const Function &f) { return f.procEntry==entry; });
|
[entry](const Function &f) { return f.procEntry==entry; });
|
||||||
return iter;
|
return iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
ilFunction Project::createFunction(FunctionType *f,const QString &name)
|
ilFunction Project::createFunction(FunctionType *f,const QString &name)
|
||||||
@ -59,7 +58,7 @@ ilFunction Project::createFunction(FunctionType *f,const QString &name)
|
|||||||
return (++pProcList.rbegin()).base();
|
return (++pProcList.rbegin()).base();
|
||||||
}
|
}
|
||||||
|
|
||||||
int Project::getSymIdxByAdd(uint32_t adr)
|
int Project::getSymIdxByAddr(uint32_t adr)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
for (i = 0; i < symtab.size(); i++)
|
for (i = 0; i < symtab.size(); i++)
|
||||||
@ -98,8 +97,6 @@ Project *Project::get()
|
|||||||
s_instance=new Project;
|
s_instance=new Project;
|
||||||
return s_instance;
|
return s_instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SourceMachine *Project::machine()
|
SourceMachine *Project::machine()
|
||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|||||||
@ -69,8 +69,8 @@ static bool isLong22 (iICODE pIcode, iICODE pEnd, iICODE &off)
|
|||||||
// preincrement because pIcode is not checked here
|
// preincrement because pIcode is not checked here
|
||||||
iICODE icodes[] = { ++pIcode,++pIcode,++pIcode };
|
iICODE icodes[] = { ++pIcode,++pIcode,++pIcode };
|
||||||
if ( icodes[1]->ll()->match(iCMP) and
|
if ( icodes[1]->ll()->match(iCMP) and
|
||||||
(isJCond ((llIcode)icodes[0]->ll()->getOpcode())) and
|
(isJCond (icodes[0]->ll()->getOpcode())) and
|
||||||
(isJCond ((llIcode)icodes[2]->ll()->getOpcode())))
|
(isJCond (icodes[2]->ll()->getOpcode())))
|
||||||
{
|
{
|
||||||
off = initial_icode;
|
off = initial_icode;
|
||||||
advance(off,2);
|
advance(off,2);
|
||||||
@ -500,7 +500,7 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be
|
|||||||
* JX lab
|
* JX lab
|
||||||
* => HLI_JCOND (regH:regL X 0) lab
|
* => HLI_JCOND (regH:regL X 0) lab
|
||||||
* This is better code than HLI_JCOND (HI(regH:regL) | LO(regH:regL)) */
|
* This is better code than HLI_JCOND (HI(regH:regL) | LO(regH:regL)) */
|
||||||
else if (pIcode->ll()->match(iOR) and (next1 != pEnd) and (isJCond ((llIcode)next1->ll()->getOpcode())))
|
else if (pIcode->ll()->match(iOR) and (next1 != pEnd) and (isJCond (next1->ll()->getOpcode())))
|
||||||
{
|
{
|
||||||
if (pLocId.longId().srcDstRegMatch(pIcode,pIcode))
|
if (pLocId.longId().srcDstRegMatch(pIcode,pIcode))
|
||||||
{
|
{
|
||||||
|
|||||||
601
src/scanner.cpp
601
src/scanner.cpp
@ -1,5 +1,5 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* dcc project scanner module
|
* dcc project scanner module
|
||||||
* Implements a simple state driven scanner to convert 8086 machine code into
|
* Implements a simple state driven scanner to convert 8086 machine code into
|
||||||
* I-code
|
* I-code
|
||||||
* (C) Cristina Cifuentes, Jeff Ledermann
|
* (C) Cristina Cifuentes, Jeff Ledermann
|
||||||
@ -19,7 +19,6 @@
|
|||||||
#define S_EXT 0x000200 /* sign extend */
|
#define S_EXT 0x000200 /* sign extend */
|
||||||
#define OP386 0x000400 /* 386 op-code */
|
#define OP386 0x000400 /* 386 op-code */
|
||||||
#define NSP 0x000800 /* NOT_HLL if SP is src or dst */
|
#define NSP 0x000800 /* NOT_HLL if SP is src or dst */
|
||||||
// defined in Enums.h #define ICODEMASK 0xFF00FF /* Masks off parser flags */
|
|
||||||
|
|
||||||
static void rm(int i);
|
static void rm(int i);
|
||||||
static void modrm(int i);
|
static void modrm(int i);
|
||||||
@ -51,276 +50,276 @@ static void none1(int i);
|
|||||||
static void none2(int i);
|
static void none2(int i);
|
||||||
static void checkInt(int i);
|
static void checkInt(int i);
|
||||||
|
|
||||||
#define iZERO (llIcode)0 // For neatness
|
#define IC llIcode
|
||||||
#define IC llIcode
|
|
||||||
|
|
||||||
static struct {
|
struct StateTabelEntry {
|
||||||
void (*state1)(int);
|
void (*state1)(int);
|
||||||
void (*state2)(int);
|
void (*state2)(int);
|
||||||
uint32_t flg;
|
uint32_t flg;
|
||||||
llIcode opcode;
|
llIcode opcode;
|
||||||
} stateTable[] = {
|
};
|
||||||
{ modrm, none2, B , iADD }, /* 00 */
|
static const StateTabelEntry stateTable[] = {
|
||||||
{ modrm, none2, 0 , iADD }, /* 01 */
|
{ modrm, none2, B , iADD }, /* 00 */
|
||||||
{ modrm, none2, TO_REG | B , iADD }, /* 02 */
|
{ modrm, none2, 0 , iADD }, /* 01 */
|
||||||
{ modrm, none2, TO_REG , iADD }, /* 03 */
|
{ modrm, none2, TO_REG | B , iADD }, /* 02 */
|
||||||
{ data1, axImp, B , iADD }, /* 04 */
|
{ modrm, none2, TO_REG , iADD }, /* 03 */
|
||||||
{ data2, axImp, 0 , iADD }, /* 05 */
|
{ data1, axImp, B , iADD }, /* 04 */
|
||||||
{ segop, none2, NO_SRC , iPUSH }, /* 06 */
|
{ data2, axImp, 0 , iADD }, /* 05 */
|
||||||
{ segop, none2, NO_SRC , iPOP }, /* 07 */
|
{ segop, none2, NO_SRC , iPUSH }, /* 06 */
|
||||||
{ modrm, none2, B , iOR }, /* 08 */
|
{ segop, none2, NO_SRC , iPOP }, /* 07 */
|
||||||
{ modrm, none2, NSP , iOR }, /* 09 */
|
{ modrm, none2, B , iOR }, /* 08 */
|
||||||
{ modrm, none2, TO_REG | B , iOR }, /* 0A */
|
{ modrm, none2, NSP , iOR }, /* 09 */
|
||||||
{ modrm, none2, TO_REG | NSP , iOR }, /* 0B */
|
{ modrm, none2, TO_REG | B , iOR }, /* 0A */
|
||||||
{ data1, axImp, B , iOR }, /* 0C */
|
{ modrm, none2, TO_REG | NSP , iOR }, /* 0B */
|
||||||
{ data2, axImp, 0 , iOR }, /* 0D */
|
{ data1, axImp, B , iOR }, /* 0C */
|
||||||
{ segop, none2, NO_SRC , iPUSH }, /* 0E */
|
{ data2, axImp, 0 , iOR }, /* 0D */
|
||||||
{ none1, none2, OP386 , iZERO }, /* 0F */
|
{ segop, none2, NO_SRC , iPUSH }, /* 0E */
|
||||||
{ modrm, none2, B , iADC }, /* 10 */
|
{ none1, none2, OP386 , iINVALID }, /* 0F */
|
||||||
{ modrm, none2, NSP , iADC }, /* 11 */
|
{ modrm, none2, B , iADC }, /* 10 */
|
||||||
{ modrm, none2, TO_REG | B , iADC }, /* 12 */
|
{ modrm, none2, NSP , iADC }, /* 11 */
|
||||||
{ modrm, none2, TO_REG | NSP , iADC }, /* 13 */
|
{ modrm, none2, TO_REG | B , iADC }, /* 12 */
|
||||||
{ data1, axImp, B , iADC }, /* 14 */
|
{ modrm, none2, TO_REG | NSP , iADC }, /* 13 */
|
||||||
{ data2, axImp, 0 , iADC }, /* 15 */
|
{ data1, axImp, B , iADC }, /* 14 */
|
||||||
{ segop, none2, NOT_HLL | NO_SRC , iPUSH }, /* 16 */
|
{ data2, axImp, 0 , iADC }, /* 15 */
|
||||||
{ segop, none2, NOT_HLL | NO_SRC , iPOP }, /* 17 */
|
{ segop, none2, NOT_HLL | NO_SRC , iPUSH }, /* 16 */
|
||||||
{ modrm, none2, B , iSBB }, /* 18 */
|
{ segop, none2, NOT_HLL | NO_SRC , iPOP }, /* 17 */
|
||||||
{ modrm, none2, NSP , iSBB }, /* 19 */
|
{ modrm, none2, B , iSBB }, /* 18 */
|
||||||
{ modrm, none2, TO_REG | B , iSBB }, /* 1A */
|
{ modrm, none2, NSP , iSBB }, /* 19 */
|
||||||
{ modrm, none2, TO_REG | NSP , iSBB }, /* 1B */
|
{ modrm, none2, TO_REG | B , iSBB }, /* 1A */
|
||||||
{ data1, axImp, B , iSBB }, /* 1C */
|
{ modrm, none2, TO_REG | NSP , iSBB }, /* 1B */
|
||||||
{ data2, axImp, 0 , iSBB }, /* 1D */
|
{ data1, axImp, B , iSBB }, /* 1C */
|
||||||
{ segop, none2, NO_SRC , iPUSH }, /* 1E */
|
{ data2, axImp, 0 , iSBB }, /* 1D */
|
||||||
{ segop, none2, NO_SRC , iPOP }, /* 1F */
|
{ segop, none2, NO_SRC , iPUSH }, /* 1E */
|
||||||
{ modrm, none2, B , iAND }, /* 20 */
|
{ segop, none2, NO_SRC , iPOP }, /* 1F */
|
||||||
{ modrm, none2, NSP , iAND }, /* 21 */
|
{ modrm, none2, B , iAND }, /* 20 */
|
||||||
{ modrm, none2, TO_REG | B , iAND }, /* 22 */
|
{ modrm, none2, NSP , iAND }, /* 21 */
|
||||||
{ modrm, none2, TO_REG | NSP , iAND }, /* 23 */
|
{ modrm, none2, TO_REG | B , iAND }, /* 22 */
|
||||||
{ data1, axImp, B , iAND }, /* 24 */
|
{ modrm, none2, TO_REG | NSP , iAND }, /* 23 */
|
||||||
{ data2, axImp, 0 , iAND }, /* 25 */
|
{ data1, axImp, B , iAND }, /* 24 */
|
||||||
{ prefix, none2, 0 , (IC)rES}, /* 26 */
|
{ data2, axImp, 0 , iAND }, /* 25 */
|
||||||
{ none1, axImp, NOT_HLL | B|NO_SRC , iDAA }, /* 27 */
|
{ prefix, none2, 0 , (IC)rES}, /* 26 */
|
||||||
{ modrm, none2, B , iSUB }, /* 28 */
|
{ none1, axImp, NOT_HLL | B|NO_SRC , iDAA }, /* 27 */
|
||||||
{ modrm, none2, 0 , iSUB }, /* 29 */
|
{ modrm, none2, B , iSUB }, /* 28 */
|
||||||
{ modrm, none2, TO_REG | B , iSUB }, /* 2A */
|
{ modrm, none2, 0 , iSUB }, /* 29 */
|
||||||
{ modrm, none2, TO_REG , iSUB }, /* 2B */
|
{ modrm, none2, TO_REG | B , iSUB }, /* 2A */
|
||||||
{ data1, axImp, B , iSUB }, /* 2C */
|
{ modrm, none2, TO_REG , iSUB }, /* 2B */
|
||||||
{ data2, axImp, 0 , iSUB }, /* 2D */
|
{ data1, axImp, B , iSUB }, /* 2C */
|
||||||
{ prefix, none2, 0 , (IC)rCS}, /* 2E */
|
{ data2, axImp, 0 , iSUB }, /* 2D */
|
||||||
{ none1, axImp, NOT_HLL | B|NO_SRC , iDAS }, /* 2F */
|
{ prefix, none2, 0 , (IC)rCS}, /* 2E */
|
||||||
{ modrm, none2, B , iXOR }, /* 30 */
|
{ none1, axImp, NOT_HLL | B|NO_SRC , iDAS }, /* 2F */
|
||||||
{ modrm, none2, NSP , iXOR }, /* 31 */
|
{ modrm, none2, B , iXOR }, /* 30 */
|
||||||
{ modrm, none2, TO_REG | B , iXOR }, /* 32 */
|
{ modrm, none2, NSP , iXOR }, /* 31 */
|
||||||
{ modrm, none2, TO_REG | NSP , iXOR }, /* 33 */
|
{ modrm, none2, TO_REG | B , iXOR }, /* 32 */
|
||||||
{ data1, axImp, B , iXOR }, /* 34 */
|
{ modrm, none2, TO_REG | NSP , iXOR }, /* 33 */
|
||||||
{ data2, axImp, 0 , iXOR }, /* 35 */
|
{ data1, axImp, B , iXOR }, /* 34 */
|
||||||
{ prefix, none2, 0 , (IC)rSS}, /* 36 */
|
{ data2, axImp, 0 , iXOR }, /* 35 */
|
||||||
{ none1, axImp, NOT_HLL | NO_SRC , iAAA }, /* 37 */
|
{ prefix, none2, 0 , (IC)rSS}, /* 36 */
|
||||||
{ modrm, none2, B , iCMP }, /* 38 */
|
{ none1, axImp, NOT_HLL | NO_SRC , iAAA }, /* 37 */
|
||||||
{ modrm, none2, NSP , iCMP }, /* 39 */
|
{ modrm, none2, B , iCMP }, /* 38 */
|
||||||
{ modrm, none2, TO_REG | B , iCMP }, /* 3A */
|
{ modrm, none2, NSP , iCMP }, /* 39 */
|
||||||
{ modrm, none2, TO_REG | NSP , iCMP }, /* 3B */
|
{ modrm, none2, TO_REG | B , iCMP }, /* 3A */
|
||||||
{ data1, axImp, B , iCMP }, /* 3C */
|
{ modrm, none2, TO_REG | NSP , iCMP }, /* 3B */
|
||||||
{ data2, axImp, 0 , iCMP }, /* 3D */
|
{ data1, axImp, B , iCMP }, /* 3C */
|
||||||
{ prefix, none2, 0 , (IC)rDS}, /* 3E */
|
{ data2, axImp, 0 , iCMP }, /* 3D */
|
||||||
{ none1, axImp, NOT_HLL | NO_SRC , iAAS }, /* 3F */
|
{ prefix, none2, 0 , (IC)rDS}, /* 3E */
|
||||||
{ regop, none2, 0 , iINC }, /* 40 */
|
{ none1, axImp, NOT_HLL | NO_SRC , iAAS }, /* 3F */
|
||||||
{ regop, none2, 0 , iINC }, /* 41 */
|
{ regop, none2, 0 , iINC }, /* 40 */
|
||||||
{ regop, none2, 0 , iINC }, /* 42 */
|
{ regop, none2, 0 , iINC }, /* 41 */
|
||||||
{ regop, none2, 0 , iINC }, /* 43 */
|
{ regop, none2, 0 , iINC }, /* 42 */
|
||||||
{ regop, none2, NOT_HLL , iINC }, /* 44 */
|
{ regop, none2, 0 , iINC }, /* 43 */
|
||||||
{ regop, none2, 0 , iINC }, /* 45 */
|
{ regop, none2, NOT_HLL , iINC }, /* 44 */
|
||||||
{ regop, none2, 0 , iINC }, /* 46 */
|
{ regop, none2, 0 , iINC }, /* 45 */
|
||||||
{ regop, none2, 0 , iINC }, /* 47 */
|
{ regop, none2, 0 , iINC }, /* 46 */
|
||||||
{ regop, none2, 0 , iDEC }, /* 48 */
|
{ regop, none2, 0 , iINC }, /* 47 */
|
||||||
{ regop, none2, 0 , iDEC }, /* 49 */
|
{ regop, none2, 0 , iDEC }, /* 48 */
|
||||||
{ regop, none2, 0 , iDEC }, /* 4A */
|
{ regop, none2, 0 , iDEC }, /* 49 */
|
||||||
{ regop, none2, 0 , iDEC }, /* 4B */
|
{ regop, none2, 0 , iDEC }, /* 4A */
|
||||||
{ regop, none2, NOT_HLL , iDEC }, /* 4C */
|
{ regop, none2, 0 , iDEC }, /* 4B */
|
||||||
{ regop, none2, 0 , iDEC }, /* 4D */
|
{ regop, none2, NOT_HLL , iDEC }, /* 4C */
|
||||||
{ regop, none2, 0 , iDEC }, /* 4E */
|
{ regop, none2, 0 , iDEC }, /* 4D */
|
||||||
{ regop, none2, 0 , iDEC }, /* 4F */
|
{ regop, none2, 0 , iDEC }, /* 4E */
|
||||||
{ regop, none2, NO_SRC , iPUSH }, /* 50 */
|
{ regop, none2, 0 , iDEC }, /* 4F */
|
||||||
{ regop, none2, NO_SRC , iPUSH }, /* 51 */
|
{ regop, none2, NO_SRC , iPUSH }, /* 50 */
|
||||||
{ regop, none2, NO_SRC , iPUSH }, /* 52 */
|
{ regop, none2, NO_SRC , iPUSH }, /* 51 */
|
||||||
{ regop, none2, NO_SRC , iPUSH }, /* 53 */
|
{ regop, none2, NO_SRC , iPUSH }, /* 52 */
|
||||||
{ regop, none2, NOT_HLL | NO_SRC , iPUSH }, /* 54 */
|
{ regop, none2, NO_SRC , iPUSH }, /* 53 */
|
||||||
{ regop, none2, NO_SRC , iPUSH }, /* 55 */
|
{ regop, none2, NOT_HLL | NO_SRC , iPUSH }, /* 54 */
|
||||||
{ regop, none2, NO_SRC , iPUSH }, /* 56 */
|
{ regop, none2, NO_SRC , iPUSH }, /* 55 */
|
||||||
{ regop, none2, NO_SRC , iPUSH }, /* 57 */
|
{ regop, none2, NO_SRC , iPUSH }, /* 56 */
|
||||||
{ regop, none2, NO_SRC , iPOP }, /* 58 */
|
{ regop, none2, NO_SRC , iPUSH }, /* 57 */
|
||||||
{ regop, none2, NO_SRC , iPOP }, /* 59 */
|
{ regop, none2, NO_SRC , iPOP }, /* 58 */
|
||||||
{ regop, none2, NO_SRC , iPOP }, /* 5A */
|
{ regop, none2, NO_SRC , iPOP }, /* 59 */
|
||||||
{ regop, none2, NO_SRC , iPOP }, /* 5B */
|
{ regop, none2, NO_SRC , iPOP }, /* 5A */
|
||||||
{ regop, none2, NOT_HLL | NO_SRC , iPOP }, /* 5C */
|
{ regop, none2, NO_SRC , iPOP }, /* 5B */
|
||||||
{ regop, none2, NO_SRC , iPOP }, /* 5D */
|
{ regop, none2, NOT_HLL | NO_SRC , iPOP }, /* 5C */
|
||||||
{ regop, none2, NO_SRC , iPOP }, /* 5E */
|
{ regop, none2, NO_SRC , iPOP }, /* 5D */
|
||||||
{ regop, none2, NO_SRC , iPOP }, /* 5F */
|
{ regop, none2, NO_SRC , iPOP }, /* 5E */
|
||||||
{ none1, none2, NOT_HLL | NO_OPS , iPUSHA}, /* 60 */
|
{ regop, none2, NO_SRC , iPOP }, /* 5F */
|
||||||
{ none1, none2, NOT_HLL | NO_OPS , iPOPA }, /* 61 */
|
{ none1, none2, NOT_HLL | NO_OPS , iPUSHA}, /* 60 */
|
||||||
{ memOnly, modrm, TO_REG | NSP , iBOUND}, /* 62 */
|
{ none1, none2, NOT_HLL | NO_OPS , iPOPA }, /* 61 */
|
||||||
{ none1, none2, OP386 , iZERO }, /* 63 */
|
{ memOnly, modrm, TO_REG | NSP , iBOUND}, /* 62 */
|
||||||
{ none1, none2, OP386 , iZERO }, /* 64 */
|
{ none1, none2, OP386 , iINVALID }, /* 63 */
|
||||||
{ none1, none2, OP386 , iZERO }, /* 65 */
|
{ none1, none2, OP386 , iINVALID }, /* 64 */
|
||||||
{ none1, none2, OP386 , iZERO }, /* 66 */
|
{ none1, none2, OP386 , iINVALID }, /* 65 */
|
||||||
{ none1, none2, OP386 , iZERO }, /* 67 */
|
{ none1, none2, OP386 , iINVALID }, /* 66 */
|
||||||
{ data2, none2, NO_SRC , iPUSH }, /* 68 */
|
{ none1, none2, OP386 , iINVALID }, /* 67 */
|
||||||
{ modrm, data2, TO_REG | NSP , iIMUL }, /* 69 */
|
{ data2, none2, NO_SRC , iPUSH }, /* 68 */
|
||||||
{ data1, none2, S_EXT | NO_SRC , iPUSH }, /* 6A */
|
{ modrm, data2, TO_REG | NSP , iIMUL }, /* 69 */
|
||||||
{ modrm, data1, TO_REG | NSP | S_EXT , iIMUL }, /* 6B */
|
{ data1, none2, S_EXT | NO_SRC , iPUSH }, /* 6A */
|
||||||
{ strop, memImp, NOT_HLL | B|IM_OPS , iINS }, /* 6C */
|
{ modrm, data1, TO_REG | NSP | S_EXT , iIMUL }, /* 6B */
|
||||||
{ strop, memImp, NOT_HLL | IM_OPS , iINS }, /* 6D */
|
{ strop, memImp, NOT_HLL | B|IM_OPS , iINS }, /* 6C */
|
||||||
{ strop, memImp, NOT_HLL | B|IM_OPS , iOUTS }, /* 6E */
|
{ strop, memImp, NOT_HLL | IM_OPS , iINS }, /* 6D */
|
||||||
{ strop, memImp, NOT_HLL | IM_OPS , iOUTS }, /* 6F */
|
{ strop, memImp, NOT_HLL | B|IM_OPS , iOUTS }, /* 6E */
|
||||||
{ dispS, none2, NOT_HLL , iJO }, /* 70 */
|
{ strop, memImp, NOT_HLL | IM_OPS , iOUTS }, /* 6F */
|
||||||
{ dispS, none2, NOT_HLL , iJNO }, /* 71 */
|
{ dispS, none2, NOT_HLL , iJO }, /* 70 */
|
||||||
{ dispS, none2, 0 , iJB }, /* 72 */
|
{ dispS, none2, NOT_HLL , iJNO }, /* 71 */
|
||||||
{ dispS, none2, 0 , iJAE }, /* 73 */
|
{ dispS, none2, 0 , iJB }, /* 72 */
|
||||||
{ dispS, none2, 0 , iJE }, /* 74 */
|
{ dispS, none2, 0 , iJAE }, /* 73 */
|
||||||
{ dispS, none2, 0 , iJNE }, /* 75 */
|
{ dispS, none2, 0 , iJE }, /* 74 */
|
||||||
{ dispS, none2, 0 , iJBE }, /* 76 */
|
{ dispS, none2, 0 , iJNE }, /* 75 */
|
||||||
{ dispS, none2, 0 , iJA }, /* 77 */
|
{ dispS, none2, 0 , iJBE }, /* 76 */
|
||||||
{ dispS, none2, 0 , iJS }, /* 78 */
|
{ dispS, none2, 0 , iJA }, /* 77 */
|
||||||
{ dispS, none2, 0 , iJNS }, /* 79 */
|
{ dispS, none2, 0 , iJS }, /* 78 */
|
||||||
{ dispS, none2, NOT_HLL , iJP }, /* 7A */
|
{ dispS, none2, 0 , iJNS }, /* 79 */
|
||||||
{ dispS, none2, NOT_HLL , iJNP }, /* 7B */
|
{ dispS, none2, NOT_HLL , iJP }, /* 7A */
|
||||||
{ dispS, none2, 0 , iJL }, /* 7C */
|
{ dispS, none2, NOT_HLL , iJNP }, /* 7B */
|
||||||
{ dispS, none2, 0 , iJGE }, /* 7D */
|
{ dispS, none2, 0 , iJL }, /* 7C */
|
||||||
{ dispS, none2, 0 , iJLE }, /* 7E */
|
{ dispS, none2, 0 , iJGE }, /* 7D */
|
||||||
{ dispS, none2, 0 , iJG }, /* 7F */
|
{ dispS, none2, 0 , iJLE }, /* 7E */
|
||||||
{ immed, data1, B , iZERO }, /* 80 */
|
{ dispS, none2, 0 , iJG }, /* 7F */
|
||||||
{ immed, data2, NSP , iZERO }, /* 81 */
|
{ immed, data1, B , iINVALID }, /* 80 */
|
||||||
{ immed, data1, B , iZERO }, /* 82 */ /* ?? */
|
{ immed, data2, NSP , iINVALID }, /* 81 */
|
||||||
{ immed, data1, NSP | S_EXT , iZERO }, /* 83 */
|
{ immed, data1, B , iINVALID }, /* 82 */ /* ?? */
|
||||||
{ modrm, none2, TO_REG | B , iTEST }, /* 84 */
|
{ immed, data1, NSP | S_EXT , iINVALID }, /* 83 */
|
||||||
{ modrm, none2, TO_REG | NSP , iTEST }, /* 85 */
|
{ modrm, none2, TO_REG | B , iTEST }, /* 84 */
|
||||||
{ modrm, none2, TO_REG | B , iXCHG }, /* 86 */
|
{ modrm, none2, TO_REG | NSP , iTEST }, /* 85 */
|
||||||
{ modrm, none2, TO_REG | NSP , iXCHG }, /* 87 */
|
{ modrm, none2, TO_REG | B , iXCHG }, /* 86 */
|
||||||
{ modrm, none2, B , iMOV }, /* 88 */
|
{ modrm, none2, TO_REG | NSP , iXCHG }, /* 87 */
|
||||||
{ modrm, none2, 0 , iMOV }, /* 89 */
|
{ modrm, none2, B , iMOV }, /* 88 */
|
||||||
{ modrm, none2, TO_REG | B , iMOV }, /* 8A */
|
{ modrm, none2, 0 , iMOV }, /* 89 */
|
||||||
{ modrm, none2, TO_REG , iMOV }, /* 8B */
|
{ modrm, none2, TO_REG | B , iMOV }, /* 8A */
|
||||||
{ segrm, none2, NSP , iMOV }, /* 8C */
|
{ modrm, none2, TO_REG , iMOV }, /* 8B */
|
||||||
{ memOnly, modrm, TO_REG | NSP , iLEA }, /* 8D */
|
{ segrm, none2, NSP , iMOV }, /* 8C */
|
||||||
{ segrm, none2, TO_REG | NSP , iMOV }, /* 8E */
|
{ memOnly, modrm, TO_REG | NSP , iLEA }, /* 8D */
|
||||||
{ memReg0, none2, NO_SRC , iPOP }, /* 8F */
|
{ segrm, none2, TO_REG | NSP , iMOV }, /* 8E */
|
||||||
{ none1, none2, NO_OPS , iNOP }, /* 90 */
|
{ memReg0, none2, NO_SRC , iPOP }, /* 8F */
|
||||||
{ regop, axImp, 0 , iXCHG }, /* 91 */
|
{ none1, none2, NO_OPS , iNOP }, /* 90 */
|
||||||
{ regop, axImp, 0 , iXCHG }, /* 92 */
|
{ regop, axImp, 0 , iXCHG }, /* 91 */
|
||||||
{ regop, axImp, 0 , iXCHG }, /* 93 */
|
{ regop, axImp, 0 , iXCHG }, /* 92 */
|
||||||
{ regop, axImp, NOT_HLL , iXCHG }, /* 94 */
|
{ regop, axImp, 0 , iXCHG }, /* 93 */
|
||||||
{ regop, axImp, 0 , iXCHG }, /* 95 */
|
{ regop, axImp, NOT_HLL , iXCHG }, /* 94 */
|
||||||
{ regop, axImp, 0 , iXCHG }, /* 96 */
|
{ regop, axImp, 0 , iXCHG }, /* 95 */
|
||||||
{ regop, axImp, 0 , iXCHG }, /* 97 */
|
{ regop, axImp, 0 , iXCHG }, /* 96 */
|
||||||
{ alImp, axImp, SRC_B | S_EXT , iSIGNEX}, /* 98 */
|
{ regop, axImp, 0 , iXCHG }, /* 97 */
|
||||||
{axSrcIm, axImp, IM_DST | S_EXT , iSIGNEX}, /* 99 */
|
{ alImp, axImp, SRC_B | S_EXT , iSIGNEX}, /* 98 */
|
||||||
{ dispF, none2, TO_REG , iCALLF }, /* 9A */ // TO_REG set to use SRC when processing setAddress
|
{axSrcIm, axImp, IM_DST | S_EXT , iSIGNEX}, /* 99 */
|
||||||
{ none1, none2, FLOAT_OP| NO_OPS , iWAIT }, /* 9B */
|
{ dispF, none2, TO_REG , iCALLF }, /* 9A */ // TO_REG set to use SRC when processing setAddress
|
||||||
{ none1, none2, NOT_HLL | NO_OPS , iPUSHF}, /* 9C */
|
{ none1, none2, FLOAT_OP| NO_OPS , iWAIT }, /* 9B */
|
||||||
{ none1, none2, NOT_HLL | NO_OPS , iPOPF }, /* 9D */
|
{ none1, none2, NOT_HLL | NO_OPS , iPUSHF}, /* 9C */
|
||||||
{ none1, none2, NOT_HLL | NO_OPS , iSAHF }, /* 9E */
|
{ none1, none2, NOT_HLL | NO_OPS , iPOPF }, /* 9D */
|
||||||
{ none1, none2, NOT_HLL | NO_OPS , iLAHF }, /* 9F */
|
{ none1, none2, NOT_HLL | NO_OPS , iSAHF }, /* 9E */
|
||||||
{ dispM, axImp, B , iMOV }, /* A0 */
|
{ none1, none2, NOT_HLL | NO_OPS , iLAHF }, /* 9F */
|
||||||
{ dispM, axImp, 0 , iMOV }, /* A1 */
|
{ dispM, axImp, B , iMOV }, /* A0 */
|
||||||
{ dispM, axImp, TO_REG | B , iMOV }, /* A2 */
|
{ dispM, axImp, 0 , iMOV }, /* A1 */
|
||||||
{ dispM, axImp, TO_REG , iMOV }, /* A3 */
|
{ dispM, axImp, TO_REG | B , iMOV }, /* A2 */
|
||||||
{ strop, memImp, B | IM_OPS , iMOVS }, /* A4 */
|
{ dispM, axImp, TO_REG , iMOV }, /* A3 */
|
||||||
{ strop, memImp, IM_OPS , iMOVS }, /* A5 */
|
{ strop, memImp, B | IM_OPS , iMOVS }, /* A4 */
|
||||||
{ strop, memImp, B | IM_OPS , iCMPS }, /* A6 */
|
{ strop, memImp, IM_OPS , iMOVS }, /* A5 */
|
||||||
{ strop, memImp, IM_OPS , iCMPS }, /* A7 */
|
{ strop, memImp, B | IM_OPS , iCMPS }, /* A6 */
|
||||||
{ data1, axImp, B , iTEST }, /* A8 */
|
{ strop, memImp, IM_OPS , iCMPS }, /* A7 */
|
||||||
{ data2, axImp, 0 , iTEST }, /* A9 */
|
{ data1, axImp, B , iTEST }, /* A8 */
|
||||||
{ strop, memImp, B | IM_OPS , iSTOS }, /* AA */
|
{ data2, axImp, 0 , iTEST }, /* A9 */
|
||||||
{ strop, memImp, IM_OPS , iSTOS }, /* AB */
|
{ strop, memImp, B | IM_OPS , iSTOS }, /* AA */
|
||||||
{ strop, memImp, B | IM_OPS , iLODS }, /* AC */
|
{ strop, memImp, IM_OPS , iSTOS }, /* AB */
|
||||||
{ strop, memImp, IM_OPS , iLODS }, /* AD */
|
{ strop, memImp, B | IM_OPS , iLODS }, /* AC */
|
||||||
{ strop, memImp, B | IM_OPS , iSCAS }, /* AE */
|
{ strop, memImp, IM_OPS , iLODS }, /* AD */
|
||||||
{ strop, memImp, IM_OPS , iSCAS }, /* AF */
|
{ strop, memImp, B | IM_OPS , iSCAS }, /* AE */
|
||||||
{ regop, data1, B , iMOV }, /* B0 */
|
{ strop, memImp, IM_OPS , iSCAS }, /* AF */
|
||||||
{ regop, data1, B , iMOV }, /* B1 */
|
{ regop, data1, B , iMOV }, /* B0 */
|
||||||
{ regop, data1, B , iMOV }, /* B2 */
|
{ regop, data1, B , iMOV }, /* B1 */
|
||||||
{ regop, data1, B , iMOV }, /* B3 */
|
{ regop, data1, B , iMOV }, /* B2 */
|
||||||
{ regop, data1, B , iMOV }, /* B4 */
|
{ regop, data1, B , iMOV }, /* B3 */
|
||||||
{ regop, data1, B , iMOV }, /* B5 */
|
{ regop, data1, B , iMOV }, /* B4 */
|
||||||
{ regop, data1, B , iMOV }, /* B6 */
|
{ regop, data1, B , iMOV }, /* B5 */
|
||||||
{ regop, data1, B , iMOV }, /* B7 */
|
{ regop, data1, B , iMOV }, /* B6 */
|
||||||
{ regop, data2, 0 , iMOV }, /* B8 */
|
{ regop, data1, B , iMOV }, /* B7 */
|
||||||
{ regop, data2, 0 , iMOV }, /* B9 */
|
{ regop, data2, 0 , iMOV }, /* B8 */
|
||||||
{ regop, data2, 0 , iMOV }, /* BA */
|
{ regop, data2, 0 , iMOV }, /* B9 */
|
||||||
{ regop, data2, 0 , iMOV }, /* BB */
|
{ regop, data2, 0 , iMOV }, /* BA */
|
||||||
{ regop, data2, NOT_HLL , iMOV }, /* BC */
|
{ regop, data2, 0 , iMOV }, /* BB */
|
||||||
{ regop, data2, 0 , iMOV }, /* BD */
|
{ regop, data2, NOT_HLL , iMOV }, /* BC */
|
||||||
{ regop, data2, 0 , iMOV }, /* BE */
|
{ regop, data2, 0 , iMOV }, /* BD */
|
||||||
{ regop, data2, 0 , iMOV }, /* BF */
|
{ regop, data2, 0 , iMOV }, /* BE */
|
||||||
{ shift, data1, B , iZERO }, /* C0 */
|
{ regop, data2, 0 , iMOV }, /* BF */
|
||||||
{ shift, data1, NSP | SRC_B , iZERO }, /* C1 */
|
{ shift, data1, B , iINVALID }, /* C0 */
|
||||||
{ data2, none2, 0 , iRET }, /* C2 */
|
{ shift, data1, NSP | SRC_B , iINVALID }, /* C1 */
|
||||||
{ none1, none2, NO_OPS , iRET }, /* C3 */
|
{ data2, none2, 0 , iRET }, /* C2 */
|
||||||
{ memOnly, modrm, TO_REG | NSP , iLES }, /* C4 */
|
{ none1, none2, NO_OPS , iRET }, /* C3 */
|
||||||
{ memOnly, modrm, TO_REG | NSP , iLDS }, /* C5 */
|
{ memOnly, modrm, TO_REG | NSP , iLES }, /* C4 */
|
||||||
{ memReg0, data1, B , iMOV }, /* C6 */
|
{ memOnly, modrm, TO_REG | NSP , iLDS }, /* C5 */
|
||||||
{ memReg0, data2, 0 , iMOV }, /* C7 */
|
{ memReg0, data1, B , iMOV }, /* C6 */
|
||||||
{ data2, data1, 0 , iENTER}, /* C8 */
|
{ memReg0, data2, 0 , iMOV }, /* C7 */
|
||||||
{ none1, none2, NO_OPS , iLEAVE}, /* C9 */
|
{ data2, data1, 0 , iENTER}, /* C8 */
|
||||||
{ data2, none2, 0 , iRETF }, /* CA */
|
{ none1, none2, NO_OPS , iLEAVE}, /* C9 */
|
||||||
{ none1, none2, NO_OPS , iRETF }, /* CB */
|
{ data2, none2, 0 , iRETF }, /* CA */
|
||||||
{ const3, none2, NOT_HLL , iINT }, /* CC */
|
{ none1, none2, NO_OPS , iRETF }, /* CB */
|
||||||
{ data1,checkInt, NOT_HLL , iINT }, /* CD */
|
{ const3, none2, NOT_HLL , iINT }, /* CC */
|
||||||
{ none1, none2, NOT_HLL | NO_OPS , iINTO }, /* CE */
|
{ data1,checkInt, NOT_HLL , iINT }, /* CD */
|
||||||
{ none1, none2, NOT_HLL | NO_OPS , iIRET }, /* Cf */
|
{ none1, none2, NOT_HLL | NO_OPS , iINTO }, /* CE */
|
||||||
{ shift, const1, B , iZERO }, /* D0 */
|
{ none1, none2, NOT_HLL | NO_OPS , iIRET }, /* Cf */
|
||||||
{ shift, const1, SRC_B , iZERO }, /* D1 */
|
{ shift, const1, B , iINVALID }, /* D0 */
|
||||||
{ shift, none1, B , iZERO }, /* D2 */
|
{ shift, const1, SRC_B , iINVALID }, /* D1 */
|
||||||
{ shift, none1, SRC_B , iZERO }, /* D3 */
|
{ shift, none1, B , iINVALID }, /* D2 */
|
||||||
{ data1, axImp, NOT_HLL , iAAM }, /* D4 */
|
{ shift, none1, SRC_B , iINVALID }, /* D3 */
|
||||||
{ data1, axImp, NOT_HLL , iAAD }, /* D5 */
|
{ data1, axImp, NOT_HLL , iAAM }, /* D4 */
|
||||||
{ none1, none2, 0 , iZERO }, /* D6 */
|
{ data1, axImp, NOT_HLL , iAAD }, /* D5 */
|
||||||
{ memImp, axImp, NOT_HLL | B| IM_OPS , iXLAT }, /* D7 */
|
{ none1, none2, 0 , iINVALID }, /* D6 */
|
||||||
{ escop, none2, FLOAT_OP , iESC }, /* D8 */
|
{ memImp, axImp, NOT_HLL | B| IM_OPS , iXLAT }, /* D7 */
|
||||||
{ escop, none2, FLOAT_OP , iESC }, /* D9 */
|
{ escop, none2, FLOAT_OP , iESC }, /* D8 */
|
||||||
{ escop, none2, FLOAT_OP , iESC }, /* DA */
|
{ escop, none2, FLOAT_OP , iESC }, /* D9 */
|
||||||
{ escop, none2, FLOAT_OP , iESC }, /* DB */
|
{ escop, none2, FLOAT_OP , iESC }, /* DA */
|
||||||
{ escop, none2, FLOAT_OP , iESC }, /* DC */
|
{ escop, none2, FLOAT_OP , iESC }, /* DB */
|
||||||
{ escop, none2, FLOAT_OP , iESC }, /* DD */
|
{ escop, none2, FLOAT_OP , iESC }, /* DC */
|
||||||
{ escop, none2, FLOAT_OP , iESC }, /* DE */
|
{ escop, none2, FLOAT_OP , iESC }, /* DD */
|
||||||
{ escop, none2, FLOAT_OP , iESC }, /* Df */
|
{ escop, none2, FLOAT_OP , iESC }, /* DE */
|
||||||
{ dispS, none2, 0 , iLOOPNE}, /* E0 */
|
{ escop, none2, FLOAT_OP , iESC }, /* Df */
|
||||||
{ dispS, none2, 0 , iLOOPE}, /* E1 */
|
{ dispS, none2, 0 , iLOOPNE}, /* E0 */
|
||||||
{ dispS, none2, 0 , iLOOP }, /* E2 */
|
{ dispS, none2, 0 , iLOOPE}, /* E1 */
|
||||||
{ dispS, none2, 0 , iJCXZ }, /* E3 */
|
{ dispS, none2, 0 , iLOOP }, /* E2 */
|
||||||
{ data1, axImp, NOT_HLL | B|NO_SRC , iIN }, /* E4 */
|
{ dispS, none2, 0 , iJCXZ }, /* E3 */
|
||||||
{ data1, axImp, NOT_HLL | NO_SRC , iIN }, /* E5 */
|
{ data1, axImp, NOT_HLL | B|NO_SRC , iIN }, /* E4 */
|
||||||
{ data1, axImp, NOT_HLL | B|NO_SRC , iOUT }, /* E6 */
|
{ data1, axImp, NOT_HLL | NO_SRC , iIN }, /* E5 */
|
||||||
{ data1, axImp, NOT_HLL | NO_SRC , iOUT }, /* E7 */
|
{ data1, axImp, NOT_HLL | B|NO_SRC , iOUT }, /* E6 */
|
||||||
{ dispN, none2, 0 , iCALL }, /* E8 */
|
{ data1, axImp, NOT_HLL | NO_SRC , iOUT }, /* E7 */
|
||||||
{ dispN, none2, 0 , iJMP }, /* E9 */
|
{ dispN, none2, 0 , iCALL }, /* E8 */
|
||||||
{ dispF, none2, 0 , iJMPF }, /* EA */
|
{ dispN, none2, 0 , iJMP }, /* E9 */
|
||||||
{ dispS, none2, 0 , iJMP }, /* EB */
|
{ dispF, none2, 0 , iJMPF }, /* EA */
|
||||||
{ none1, axImp, NOT_HLL | B|NO_SRC , iIN }, /* EC */
|
{ dispS, none2, 0 , iJMP }, /* EB */
|
||||||
{ none1, axImp, NOT_HLL | NO_SRC , iIN }, /* ED */
|
{ none1, axImp, NOT_HLL | B|NO_SRC , iIN }, /* EC */
|
||||||
{ none1, axImp, NOT_HLL | B|NO_SRC , iOUT }, /* EE */
|
{ none1, axImp, NOT_HLL | NO_SRC , iIN }, /* ED */
|
||||||
{ none1, axImp, NOT_HLL | NO_SRC , iOUT }, /* EF */
|
{ none1, axImp, NOT_HLL | B|NO_SRC , iOUT }, /* EE */
|
||||||
{ none1, none2, NOT_HLL | NO_OPS , iLOCK }, /* F0 */
|
{ none1, axImp, NOT_HLL | NO_SRC , iOUT }, /* EF */
|
||||||
{ none1, none2, 0 , iZERO }, /* F1 */
|
{ none1, none2, NOT_HLL | NO_OPS , iLOCK }, /* F0 */
|
||||||
{ prefix, none2, 0 , iREPNE}, /* F2 */
|
{ none1, none2, 0 , iINVALID }, /* F1 */
|
||||||
{ prefix, none2, 0 , iREPE }, /* F3 */
|
{ prefix, none2, 0 , iREPNE}, /* F2 */
|
||||||
{ none1, none2, NOT_HLL | NO_OPS , iHLT }, /* F4 */
|
{ prefix, none2, 0 , iREPE }, /* F3 */
|
||||||
{ none1, none2, NO_OPS , iCMC }, /* F5 */
|
{ none1, none2, NOT_HLL | NO_OPS , iHLT }, /* F4 */
|
||||||
{ arith, none1, B , iZERO }, /* F6 */
|
{ none1, none2, NO_OPS , iCMC }, /* F5 */
|
||||||
{ arith, none1, NSP , iZERO }, /* F7 */
|
{ arith, none1, B , iINVALID }, /* F6 */
|
||||||
{ none1, none2, NO_OPS , iCLC }, /* F8 */
|
{ arith, none1, NSP , iINVALID }, /* F7 */
|
||||||
{ none1, none2, NO_OPS , iSTC }, /* F9 */
|
{ none1, none2, NO_OPS , iCLC }, /* F8 */
|
||||||
{ none1, none2, NOT_HLL | NO_OPS , iCLI }, /* FA */
|
{ none1, none2, NO_OPS , iSTC }, /* F9 */
|
||||||
{ none1, none2, NOT_HLL | NO_OPS , iSTI }, /* FB */
|
{ none1, none2, NOT_HLL | NO_OPS , iCLI }, /* FA */
|
||||||
{ none1, none2, NO_OPS , iCLD }, /* FC */
|
{ none1, none2, NOT_HLL | NO_OPS , iSTI }, /* FB */
|
||||||
{ none1, none2, NO_OPS , iSTD }, /* FD */
|
{ none1, none2, NO_OPS , iCLD }, /* FC */
|
||||||
{ trans, none1, B , iZERO }, /* FE */
|
{ none1, none2, NO_OPS , iSTD }, /* FD */
|
||||||
{ trans, none1, NSP , iZERO } /* FF */
|
{ trans, none1, B , iINVALID }, /* FE */
|
||||||
|
{ trans, none1, NSP , iINVALID } /* FF */
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
static uint16_t SegPrefix, RepPrefix;
|
static uint16_t SegPrefix, RepPrefix;
|
||||||
static const uint8_t *pInst; /* Ptr. to current uint8_t of instruction */
|
static const uint8_t *pInst; /* Ptr. to current uint8_t of instruction */
|
||||||
static ICODE * pIcode; /* Ptr to Icode record filled in by scan() */
|
static ICODE * pIcode; /* Ptr to Icode record filled in by scan() */
|
||||||
|
|
||||||
|
|
||||||
static void decodeBranchTgt(x86_insn_t &insn)
|
static void decodeBranchTgt(x86_insn_t &insn)
|
||||||
@ -338,7 +337,7 @@ static void decodeBranchTgt(x86_insn_t &insn)
|
|||||||
pIcode->ll()->replaceSrc((uint32_t)addr);
|
pIcode->ll()->replaceSrc((uint32_t)addr);
|
||||||
pIcode->ll()->setFlags(I);
|
pIcode->ll()->setFlags(I);
|
||||||
// PROG &prog(Project::get()->prog);
|
// PROG &prog(Project::get()->prog);
|
||||||
// long off = (short)getWord(); /* Signed displacement */
|
// long off = (short)getWord(); /* Signed displacement */
|
||||||
// assert(addr==(uint32_t)(off + (unsigned)(pInst - prog.image())));
|
// assert(addr==(uint32_t)(off + (unsigned)(pInst - prog.image())));
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -538,7 +537,7 @@ eErrorId scan(uint32_t ip, ICODE &p)
|
|||||||
int op;
|
int op;
|
||||||
p = ICODE();
|
p = ICODE();
|
||||||
p.type = LOW_LEVEL_ICODE;
|
p.type = LOW_LEVEL_ICODE;
|
||||||
p.ll()->label = ip; /* ip is absolute offset into image*/
|
p.ll()->label = ip; /* ip is absolute offset into image*/
|
||||||
if (ip >= (uint32_t)prog.cbImage)
|
if (ip >= (uint32_t)prog.cbImage)
|
||||||
{
|
{
|
||||||
return (IP_OUT_OF_RANGE);
|
return (IP_OUT_OF_RANGE);
|
||||||
@ -557,13 +556,13 @@ 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);
|
||||||
(*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.insn.group == x86_insn_t::insn_controlflow)
|
if(p.insn.group == x86_insn_t::insn_controlflow)
|
||||||
{
|
{
|
||||||
if(p.insn.x86_get_branch_target())
|
if(p.insn.x86_get_branch_target())
|
||||||
@ -571,7 +570,7 @@ eErrorId scan(uint32_t ip, ICODE &p)
|
|||||||
}
|
}
|
||||||
// LLOperand conv = convertOperand(*p.insn.get_dest());
|
// LLOperand conv = convertOperand(*p.insn.get_dest());
|
||||||
// assert(conv==p.ll()->dst);
|
// assert(conv==p.ll()->dst);
|
||||||
if (p.ll()->getOpcode())
|
if (p.ll()->getOpcode()!=iINVALID)
|
||||||
{
|
{
|
||||||
/* 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);
|
||||||
@ -591,8 +590,8 @@ eErrorId scan(uint32_t ip, ICODE &p)
|
|||||||
static bool relocItem(const uint8_t *p)
|
static bool relocItem(const uint8_t *p)
|
||||||
{
|
{
|
||||||
PROG &prog(Project::get()->prog);
|
PROG &prog(Project::get()->prog);
|
||||||
int i;
|
int i;
|
||||||
uint32_t off = p - prog.image();
|
uint32_t off = p - prog.image();
|
||||||
|
|
||||||
for (i = 0; i < prog.cReloc; i++)
|
for (i = 0; i < prog.cReloc; i++)
|
||||||
if (prog.relocTable[i] == off)
|
if (prog.relocTable[i] == off)
|
||||||
@ -623,9 +622,9 @@ static int signex(uint8_t b)
|
|||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* setAddress - Updates the source or destination field for the current
|
* setAddress - Updates the source or destination field for the current
|
||||||
* icode, based on fdst and the TO_REG flag.
|
* icode, based on fdst and the TO_REG flag.
|
||||||
* Note: fdst == true is for the r/m part of the field (dest, unless TO_REG)
|
* Note: fdst == true is for the r/m part of the field (dest, unless TO_REG)
|
||||||
* fdst == false is for reg part of the field
|
* fdst == false is for reg part of the field
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
static void setAddress(int i, bool fdst, uint16_t seg, int16_t reg, uint16_t off)
|
static void setAddress(int i, bool fdst, uint16_t seg, int16_t reg, uint16_t off)
|
||||||
{
|
{
|
||||||
@ -635,19 +634,19 @@ static void setAddress(int i, bool fdst, uint16_t seg, int16_t reg, uint16_t off
|
|||||||
/* Set segment. A later procedure (lookupAddr in proclist.c) will
|
/* Set segment. A later procedure (lookupAddr in proclist.c) will
|
||||||
* provide the value of this segment in the field segValue.
|
* provide the value of this segment in the field segValue.
|
||||||
*/
|
*/
|
||||||
if (seg) /* segment override */
|
if (seg) /* segment override */
|
||||||
{
|
{
|
||||||
pm->seg = pm->segOver = (eReg)seg;
|
pm->seg = pm->segOver = (eReg)seg;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ /* no override, check indexed register */
|
{ /* no override, check indexed register */
|
||||||
if ((reg >= INDEX_BX_SI) and (reg == INDEX_BP_SI or reg == INDEX_BP_DI or reg == INDEX_BP))
|
if ((reg >= INDEX_BX_SI) and (reg == INDEX_BP_SI or reg == INDEX_BP_DI or reg == INDEX_BP))
|
||||||
{
|
{
|
||||||
pm->seg = rSS; /* indexed on bp */
|
pm->seg = rSS; /* indexed on bp */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pm->seg = rDS; /* any other indexed reg */
|
pm->seg = rDS; /* any other indexed reg */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -658,7 +657,7 @@ static void setAddress(int i, bool fdst, uint16_t seg, int16_t reg, uint16_t off
|
|||||||
pm->regi = Machine_X86::subRegL(pm->regi);
|
pm->regi = Machine_X86::subRegL(pm->regi);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (seg) /* So we can catch invalid use of segment overrides */
|
if (seg) /* So we can catch invalid use of segment overrides */
|
||||||
{
|
{
|
||||||
SegPrefix = 0;
|
SegPrefix = 0;
|
||||||
}
|
}
|
||||||
@ -674,7 +673,7 @@ static void rm(int i)
|
|||||||
uint8_t rm = *pInst++ & 7;
|
uint8_t rm = *pInst++ & 7;
|
||||||
|
|
||||||
switch (mod) {
|
switch (mod) {
|
||||||
case 0: /* No disp unless rm == 6 */
|
case 0: /* No disp unless rm == 6 */
|
||||||
if (rm == 6) {
|
if (rm == 6) {
|
||||||
setAddress(i, true, SegPrefix, 0, getWord());
|
setAddress(i, true, SegPrefix, 0, getWord());
|
||||||
pIcode->ll()->setFlags(WORD_OFF);
|
pIcode->ll()->setFlags(WORD_OFF);
|
||||||
@ -683,16 +682,16 @@ static void rm(int i)
|
|||||||
setAddress(i, true, SegPrefix, rm + INDEX_BX_SI, 0);
|
setAddress(i, true, SegPrefix, rm + INDEX_BX_SI, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1: /* 1 uint8_t disp */
|
case 1: /* 1 uint8_t disp */
|
||||||
setAddress(i, true, SegPrefix, rm+INDEX_BX_SI, (uint16_t)signex(*pInst++));
|
setAddress(i, true, SegPrefix, rm+INDEX_BX_SI, (uint16_t)signex(*pInst++));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2: /* 2 uint8_t disp */
|
case 2: /* 2 uint8_t disp */
|
||||||
setAddress(i, true, SegPrefix, rm + INDEX_BX_SI, getWord());
|
setAddress(i, true, SegPrefix, rm + INDEX_BX_SI, getWord());
|
||||||
pIcode->ll()->setFlags(WORD_OFF);
|
pIcode->ll()->setFlags(WORD_OFF);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3: /* reg */
|
case 3: /* reg */
|
||||||
setAddress(i, true, 0, rm + rAX, 0);
|
setAddress(i, true, 0, rm + rAX, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -718,7 +717,7 @@ static void modrm(int i)
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
static void segrm(int i)
|
static void segrm(int i)
|
||||||
{
|
{
|
||||||
int reg = REG(*pInst) + rES;
|
int reg = REG(*pInst) + rES;
|
||||||
|
|
||||||
if (reg > rDS or (reg == rCS and (stateTable[i].flg & TO_REG)))
|
if (reg > rDS or (reg == rCS and (stateTable[i].flg & TO_REG)))
|
||||||
pIcode->ll()->setOpcode((llIcode)0); // setCBW because it has that index
|
pIcode->ll()->setOpcode((llIcode)0); // setCBW because it has that index
|
||||||
@ -787,7 +786,7 @@ static void memImp(int i)
|
|||||||
static void memOnly(int )
|
static void memOnly(int )
|
||||||
{
|
{
|
||||||
if ((*pInst & 0xC0) == 0xC0)
|
if ((*pInst & 0xC0) == 0xC0)
|
||||||
pIcode->ll()->setOpcode((llIcode)0);
|
pIcode->ll()->setOpcode(iINVALID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -797,7 +796,7 @@ static void memOnly(int )
|
|||||||
static void memReg0(int i)
|
static void memReg0(int i)
|
||||||
{
|
{
|
||||||
if (REG(*pInst) or (*pInst & 0xC0) == 0xC0)
|
if (REG(*pInst) or (*pInst & 0xC0) == 0xC0)
|
||||||
pIcode->ll()->setOpcode((llIcode)0);
|
pIcode->ll()->setOpcode(iINVALID);
|
||||||
else
|
else
|
||||||
rm(i);
|
rm(i);
|
||||||
}
|
}
|
||||||
@ -814,7 +813,7 @@ static void immed(int i)
|
|||||||
rm(i);
|
rm(i);
|
||||||
|
|
||||||
if (pIcode->ll()->getOpcode() == iADD or pIcode->ll()->getOpcode() == iSUB)
|
if (pIcode->ll()->getOpcode() == iADD or pIcode->ll()->getOpcode() == iSUB)
|
||||||
pIcode->ll()->clrFlags(NOT_HLL); /* Allow ADD/SUB SP, immed */
|
pIcode->ll()->clrFlags(NOT_HLL); /* Allow ADD/SUB SP, immed */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -826,7 +825,7 @@ static void shift(int i)
|
|||||||
static llIcode shiftTable[8] =
|
static llIcode shiftTable[8] =
|
||||||
{
|
{
|
||||||
(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};
|
||||||
|
|
||||||
pIcode->ll()->setOpcode(shiftTable[REG(*pInst)]);
|
pIcode->ll()->setOpcode(shiftTable[REG(*pInst)]);
|
||||||
rm(i);
|
rm(i);
|
||||||
@ -841,8 +840,8 @@ static void trans(int i)
|
|||||||
{
|
{
|
||||||
static llIcode transTable[8] =
|
static llIcode transTable[8] =
|
||||||
{
|
{
|
||||||
(llIcode)iINC, iDEC, (llIcode)iCALL, (llIcode)iCALLF,
|
iINC, iDEC, iCALL, iCALLF,
|
||||||
(llIcode)iJMP, (llIcode)iJMPF,(llIcode)iPUSH, (llIcode)0
|
iJMP, iJMPF,iPUSH, (llIcode)0
|
||||||
};
|
};
|
||||||
LLInst *ll = pIcode->ll();
|
LLInst *ll = pIcode->ll();
|
||||||
// if(transTable[REG(*pInst)]==iPUSH) {
|
// if(transTable[REG(*pInst)]==iPUSH) {
|
||||||
@ -868,8 +867,8 @@ static void arith(int i)
|
|||||||
uint8_t opcode;
|
uint8_t opcode;
|
||||||
static llIcode arithTable[8] =
|
static llIcode arithTable[8] =
|
||||||
{
|
{
|
||||||
iTEST, (llIcode)0, iNOT, iNEG,
|
iTEST, iINVALID, iNOT, iNEG,
|
||||||
iMUL , iIMUL, iDIV, iIDIV
|
iMUL , iIMUL, iDIV, iIDIV
|
||||||
};
|
};
|
||||||
opcode = arithTable[REG(*pInst)];
|
opcode = arithTable[REG(*pInst)];
|
||||||
pIcode->ll()->setOpcode((llIcode)opcode);
|
pIcode->ll()->setOpcode((llIcode)opcode);
|
||||||
@ -884,7 +883,7 @@ static void arith(int i)
|
|||||||
else if (not (opcode == iNOT or opcode == iNEG))
|
else if (not (opcode == iNOT or opcode == iNEG))
|
||||||
{
|
{
|
||||||
pIcode->ll()->replaceSrc( pIcode->ll()->m_dst );
|
pIcode->ll()->replaceSrc( pIcode->ll()->m_dst );
|
||||||
setAddress(i, true, 0, rAX, 0); /* dst = AX */
|
setAddress(i, true, 0, rAX, 0); /* dst = AX */
|
||||||
}
|
}
|
||||||
else if (opcode == iNEG or opcode == iNOT)
|
else if (opcode == iNEG or opcode == iNOT)
|
||||||
pIcode->ll()->setFlags(NO_SRC);
|
pIcode->ll()->setFlags(NO_SRC);
|
||||||
@ -919,7 +918,7 @@ static void data2(int )
|
|||||||
* but this field is being used as the number of bytes to allocate
|
* but this field is being used as the number of bytes to allocate
|
||||||
* on the stack. The procedure level is stored in the immediate
|
* on the stack. The procedure level is stored in the immediate
|
||||||
* field. There is no source operand; therefore, the flag flg is
|
* field. There is no source operand; therefore, the flag flg is
|
||||||
* set to NO_OPS. */
|
* set to NO_OPS. */
|
||||||
if (pIcode->ll()->getOpcode() == iENTER)
|
if (pIcode->ll()->getOpcode() == iENTER)
|
||||||
{
|
{
|
||||||
pIcode->ll()->m_dst.off = getWord();
|
pIcode->ll()->m_dst.off = getWord();
|
||||||
@ -946,7 +945,7 @@ static void dispN(int )
|
|||||||
{
|
{
|
||||||
|
|
||||||
//PROG &prog(Project::get()->prog);
|
//PROG &prog(Project::get()->prog);
|
||||||
/*long off = (short)*/getWord(); /* Signed displacement */
|
/*long off = (short)*/getWord(); /* Signed displacement */
|
||||||
|
|
||||||
/* Note: the result of the subtraction could be between 32k and 64k, and
|
/* Note: the result of the subtraction could be between 32k and 64k, and
|
||||||
still be positive; it is an offset from prog.Image. So this must be
|
still be positive; it is an offset from prog.Image. So this must be
|
||||||
@ -960,7 +959,7 @@ static void dispN(int )
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
static void dispS(int )
|
static void dispS(int )
|
||||||
{
|
{
|
||||||
/*long off =*/ signex(*pInst++); /* Signed displacement */
|
/*long off =*/ signex(*pInst++); /* Signed displacement */
|
||||||
|
|
||||||
// decodeBranchTgt();
|
// decodeBranchTgt();
|
||||||
}
|
}
|
||||||
@ -985,7 +984,7 @@ static void dispF(int i)
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
static void prefix(int )
|
static void prefix(int )
|
||||||
{
|
{
|
||||||
if (pIcode->ll()->getOpcode() == iREPE or pIcode->ll()->getOpcode() == iREPNE)
|
if ((pIcode->ll()->getOpcode() == iREPE) or (pIcode->ll()->getOpcode() == iREPNE))
|
||||||
RepPrefix = pIcode->ll()->getOpcode();
|
RepPrefix = pIcode->ll()->getOpcode();
|
||||||
else
|
else
|
||||||
SegPrefix = pIcode->ll()->getOpcode();
|
SegPrefix = pIcode->ll()->getOpcode();
|
||||||
@ -993,8 +992,8 @@ static void prefix(int )
|
|||||||
|
|
||||||
inline void BumpOpcode(LLInst &ll)
|
inline void BumpOpcode(LLInst &ll)
|
||||||
{
|
{
|
||||||
llIcode ic((llIcode)ll.getOpcode());
|
llIcode ic(ll.getOpcode());
|
||||||
ic = (llIcode)(((int)ic)+1); // Bump this icode via the int type
|
ic = (llIcode)(((int)ic)+1); // Bump this icode via the int type
|
||||||
ll.setOpcode(ic);
|
ll.setOpcode(ic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user