This commit is contained in:
Artur K 2012-07-20 18:18:25 +02:00
parent f6118dc0c4
commit 0209b7ceb2
28 changed files with 1028 additions and 768 deletions

View File

@ -407,6 +407,20 @@ unsigned int Ia32_Decoder::ia32_insn_implicit_ops( unsigned int impl_idx ) {
if (!op) { if (!op) {
op = m_decoded->x86_operand_new(); op = m_decoded->x86_operand_new();
/* all implicit operands are registers */ /* all implicit operands are registers */
if(m_decoded->addr_size==2)
{
if(list->operand==REG_EIP_INDEX)
handle_impl_reg( op, REG_IP_INDEX );
else if(list->operand<REG_WORD_OFFSET)
{
handle_impl_reg( op, (list->operand-REG_DWORD_OFFSET)+REG_WORD_OFFSET);
assert((list->operand-REG_DWORD_OFFSET)<REG_WORD_OFFSET-REG_DWORD_OFFSET);
}
else
handle_impl_reg( op, list->operand);
}
else
handle_impl_reg( op, list->operand ); handle_impl_reg( op, list->operand );
/* decrement the 'explicit count' incremented by default in /* decrement the 'explicit count' incremented by default in
* x86_operand_new */ * x86_operand_new */

View File

@ -107,7 +107,7 @@ size_t Ia32_Decoder::decode_operand_value( unsigned char *buf, size_t buf_len,
/* No MODRM : note these set operand type explicitly */ /* No MODRM : note these set operand type explicitly */
case ADDRMETH_A: /* No modR/M -- direct addr */ case ADDRMETH_A: /* No modR/M -- direct addr */
op->type = op_absolute; op->type = op_absolute;
//according to Intel Manuals, offset goes first
/* segment:offset address used in far calls */ /* segment:offset address used in far calls */
if ( m_decoded->addr_size == 4 ) { if ( m_decoded->addr_size == 4 ) {
x86_imm_sized( buf, buf_len, &op->data.absolute.offset.off32, 4 ); x86_imm_sized( buf, buf_len, &op->data.absolute.offset.off32, 4 );
@ -146,15 +146,15 @@ size_t Ia32_Decoder::decode_operand_value( unsigned char *buf, size_t buf_len,
size = x86_imm_signsized(buf, buf_len, &op->data.relative_near, 1); size = x86_imm_signsized(buf, buf_len, &op->data.relative_near, 1);
break; break;
case 2: case 2:
/* far offset...is this truly signed? */
op->type = op_relative_far; op->type = op_relative_far;
int16_t offset_val; int16_t offset_val; // easier upcast to int32_t
size = x86_imm_signsized(buf, buf_len, &offset_val, 2 ); size = x86_imm_signsized(buf, buf_len, &offset_val, 2 );
op->data.relative_far=offset_val; op->data.relative_far=offset_val;
break; break;
default: default:
assert(false); assert(false);
size=0; size=0;
} }
break; break;
case ADDRMETH_O: /* No ModR/M; op is word/dword offset */ case ADDRMETH_O: /* No ModR/M; op is word/dword offset */
@ -181,7 +181,7 @@ size_t Ia32_Decoder::decode_operand_value( unsigned char *buf, size_t buf_len,
op->flags.op_pointer = true; op->flags.op_pointer = true;
op->flags.op_string = true; op->flags.op_string = true;
ia32_handle_register( &op->data.expression.base, ia32_handle_register( &op->data.expression.base,
REG_DWORD_OFFSET + 6 ); gen_regs + 6 );
break; break;
case ADDRMETH_Y: /* Memory addressed by ES:DI [string] */ case ADDRMETH_Y: /* Memory addressed by ES:DI [string] */
op->type = op_expression; op->type = op_expression;
@ -190,7 +190,7 @@ size_t Ia32_Decoder::decode_operand_value( unsigned char *buf, size_t buf_len,
op->flags.op_pointer = true; op->flags.op_pointer = true;
op->flags.op_string = true; op->flags.op_string = true;
ia32_handle_register( &op->data.expression.base, ia32_handle_register( &op->data.expression.base,
REG_DWORD_OFFSET + 7 ); gen_regs + 7 );
break; break;
case ADDRMETH_RR: /* Gen Register hard-coded in opcode */ case ADDRMETH_RR: /* Gen Register hard-coded in opcode */
op->type = op_register; op->type = op_register;

View File

@ -8,6 +8,7 @@
#include <cstdlib> #include <cstdlib>
#include <cassert> #include <cassert>
#include <stdint.h> #include <stdint.h>
/* 'NEW" types /* 'NEW" types
* __________________________________________________________________________*/ * __________________________________________________________________________*/
#ifndef LIBDISASM_QWORD_H /* do not interfere with qword.h */ #ifndef LIBDISASM_QWORD_H /* do not interfere with qword.h */
@ -304,25 +305,23 @@ struct x86_op_t{
int32_t getAddress() int32_t getAddress()
{ {
assert(is_address()||is_relative()); assert(is_address()||is_relative());
switch(type) switch ( type ) {
{ case op_relative_near:
return (int32_t) data.relative_near;
case op_absolute: case op_absolute:
{
if(datatype==op_descr16) if(datatype==op_descr16)
return (int32_t(data.absolute.segment)<<4) + data.absolute.offset.off16; return int32_t((data.absolute.segment)<<4) + data.absolute.offset.off16;
else else
return (int32_t(data.absolute.segment)<<4) + data.absolute.offset.off32; return int32_t((data.absolute.segment)<<4) + data.absolute.offset.off32;
}
case op_offset: case op_offset:
return data.offset; return data.offset;
case op_relative_near:
return data.relative_near;
case op_relative_far: case op_relative_far:
return data.relative_far; return (int32_t) data.relative_far;
default: default:
assert(false); assert(false);
return ~0; break;
} }
return ~0;
} }
char * format( enum x86_asm_format format ); char * format( enum x86_asm_format format );
x86_op_t * copy() x86_op_t * copy()

View File

@ -99,7 +99,6 @@ x86_op_t * x86_insn_t::get_dest() {
if ( ! operands ) { if ( ! operands ) {
return NULL; return NULL;
} }
assert(this->x86_operand_count(op_dest)==1);
for (op_lst = operands; op_lst; op_lst = op_lst->next ) { for (op_lst = operands; op_lst; op_lst = op_lst->next ) {
if ( op_lst->op.access & op_write) if ( op_lst->op.access & op_write)
return &(op_lst->op); return &(op_lst->op);

View File

@ -36,7 +36,7 @@ private:
numHlIcodes(0),flg(0), numHlIcodes(0),flg(0),
inEdges(0), inEdges(0),
edges(0),beenOnH(0),inEdgeCount(0),reachingInt(0), edges(0),beenOnH(0),inEdgeCount(0),reachingInt(0),
inInterval(0),correspInt(0),liveUse(0),def(0),liveIn(0),liveOut(0), inInterval(0),correspInt(0),
dfsFirstNum(0),dfsLastNum(0),immedDom(0),ifFollow(0),loopType(0),latchNode(0), dfsFirstNum(0),dfsLastNum(0),immedDom(0),ifFollow(0),loopType(0),latchNode(0),
numBackEdges(0),loopHead(0),loopFollow(0),caseHead(0),caseTail(0),index(0) numBackEdges(0),loopHead(0),loopFollow(0),caseHead(0),caseTail(0),index(0)
{ {

View File

@ -143,7 +143,7 @@ public:
bool liveAnal; /* Procedure has been analysed already */ bool liveAnal; /* Procedure has been analysed already */
Function(void */*ty*/=0) : procEntry(0),depth(0),flg(0),cbParam(0),m_cfg(0),m_dfsLast(0),numBBs(0), Function(void */*ty*/=0) : procEntry(0),depth(0),flg(0),cbParam(0),m_cfg(0),m_dfsLast(0),numBBs(0),
hasCase(false),liveIn(0),liveOut(0),liveAnal(0)//,next(0),prev(0) hasCase(false),liveAnal(0)//,next(0),prev(0)
{ {
} }
public: public:

View File

@ -59,12 +59,8 @@ 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 LivenessSet duReg[30]; /* def/use bits for registers */
//extern uint32_t duReg[30]; /* def/use bits for registers */
extern LivenessSet maskDuReg[30]; /* masks off du bits for regs */
/* Registers used by icode instructions */
/* Memory map states */ /* Memory map states */
enum eAreaType enum eAreaType
@ -130,8 +126,8 @@ char *writeJcondInv (HLTYPE, Function *, int *);
/* Exported funcions from locident.c */ /* Exported funcions from locident.c */
boolT checkLongEq (LONG_STKID_TYPE, iICODE, int, Function *, Assignment &asgn, LLInst &atOffset); bool checkLongEq(LONG_STKID_TYPE, iICODE, int, Function *, Assignment &asgn, LLInst &atOffset);
boolT checkLongRegEq (LONGID_TYPE, iICODE, int, Function *, Assignment &asgn, LLInst &); bool checkLongRegEq(LONGID_TYPE, iICODE, int, Function *, Assignment &asgn, LLInst &);
eReg otherLongRegi(eReg, int, LOCAL_ID *); eReg otherLongRegi(eReg, int, LOCAL_ID *);

View File

@ -7,6 +7,9 @@
#include <vector> #include <vector>
#include <list> #include <list>
#include <bitset> #include <bitset>
#include <set>
#include <algorithm>
#include <initializer_list>
#include <llvm/ADT/ilist.h> #include <llvm/ADT/ilist.h>
#include <llvm/ADT/ilist_node.h> #include <llvm/ADT/ilist_node.h>
#include <llvm/MC/MCInst.h> #include <llvm/MC/MCInst.h>
@ -29,17 +32,20 @@ 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;
struct LivenessSet : public std::bitset<32> struct LivenessSet
{ {
LivenessSet(int val=0) : std::bitset<32>(val) {} std::set<eReg> registers;
LivenessSet(const LivenessSet &other) public:
LivenessSet(const std::initializer_list<eReg> &init) : registers(init) {}
LivenessSet() {}
LivenessSet(const LivenessSet &other) : registers(other.registers)
{ {
(std::bitset<32> &)*this = (std::bitset<32> &)other;
} }
LivenessSet(const std::bitset<32> &other) void reset()
{ {
(std::bitset<32> &)*this = other; registers.clear();
} }
// LivenessSet(LivenessSet &&other) : LivenessSet() // LivenessSet(LivenessSet &&other) : LivenessSet()
// { // {
// swap(*this,other); // swap(*this,other);
@ -56,22 +62,65 @@ struct LivenessSet : public std::bitset<32>
// by swapping the members of two classes, // by swapping the members of two classes,
// the two classes are effectively swapped // the two classes are effectively swapped
swap((std::bitset<32> &)first, (std::bitset<32> &)second); swap(first.registers, second.registers);
} }
LivenessSet &operator|=(const LivenessSet &other)
{
registers.insert(other.registers.begin(),other.registers.end());
return *this;
}
LivenessSet &operator&=(const LivenessSet &other)
{
std::set<eReg> res;
std::set_intersection(registers.begin(),registers.end(),
other.registers.begin(),other.registers.end(),
std::inserter(res, res.end()));
registers = res;
return *this;
}
LivenessSet &operator-=(const LivenessSet &other)
{
std::set<eReg> res;
std::set_difference(registers.begin(),registers.end(),
other.registers.begin(),other.registers.end(),
std::inserter(res, res.end()));
registers = res;
return *this;
}
LivenessSet operator-(const LivenessSet &other) const
{
return LivenessSet(*this) -= other;
}
LivenessSet operator+(const LivenessSet &other) const
{
return LivenessSet(*this) |= other;
}
LivenessSet operator &(const LivenessSet &other) const
{
return LivenessSet(*this) &= other;
}
bool any() const
{
return not registers.empty();
}
bool operator==(const LivenessSet &other) const
{
return registers==other.registers;
}
bool operator!=(const LivenessSet &other) const { return not(*this==other);}
LivenessSet &setReg(int r); LivenessSet &setReg(int r);
LivenessSet &addReg(int r); LivenessSet &addReg(int r);
bool testReg(int r) bool testReg(int r) const
{ {
return test(r-rAX); return registers.find(eReg(r))!=registers.end();
} }
public: bool testRegAndSubregs(int r) const;
LivenessSet &clrReg(int r); LivenessSet &clrReg(int r);
private: private:
void postProcessCompositeRegs(); void postProcessCompositeRegs();
}; };
extern LivenessSet 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 */
@ -197,7 +246,6 @@ public:
/* LOW_LEVEL icode operand record */ /* LOW_LEVEL icode operand record */
struct LLOperand struct LLOperand
{ {
llvm::MCOperand llvm_op;
eReg seg; /* CS, DS, ES, SS */ eReg seg; /* CS, DS, ES, SS */
eReg segOver; /* CS, DS, ES, SS if segment override */ eReg segOver; /* CS, DS, ES, SS if segment override */
int16_t segValue; /* Value of segment seg during analysis */ int16_t segValue; /* Value of segment seg during analysis */
@ -245,6 +293,10 @@ struct LLOperand
Op.regi = (eReg)Val; Op.regi = (eReg)Val;
return Op; return Op;
} }
bool isSet()
{
return not (*this == LLOperand());
}
void addProcInformation(int param_count,uint32_t call_conv); void addProcInformation(int param_count,uint32_t call_conv);
}; };
struct LLInst : public llvm::MCInst //: public llvm::ilist_node<LLInst> struct LLInst : public llvm::MCInst //: public llvm::ilist_node<LLInst>
@ -256,7 +308,7 @@ 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 m_dst; /* destination operand */
DU flagDU; /* def/use of flags */ DU flagDU; /* def/use of flags */
int caseEntry; int caseEntry;
std::vector<uint32_t> caseTbl2; std::vector<uint32_t> caseTbl2;
@ -285,25 +337,29 @@ public:
{ {
return (getOpcode()==op); return (getOpcode()==op);
} }
bool matchWithRegDst(llIcode op)
{
return (getOpcode()==op) and m_dst.isReg();
}
bool match(llIcode op,eReg dest) bool match(llIcode op,eReg dest)
{ {
return (getOpcode()==op)&&dst.regi==dest; return (getOpcode()==op)&&m_dst.regi==dest;
} }
bool match(llIcode op,eReg dest,uint32_t flgs) bool match(llIcode op,eReg dest,uint32_t flgs)
{ {
return (getOpcode()==op) and (dst.regi==dest) and testFlags(flgs); return (getOpcode()==op) and (m_dst.regi==dest) and testFlags(flgs);
} }
bool match(llIcode op,eReg dest,eReg src_reg) bool match(llIcode op,eReg dest,eReg src_reg)
{ {
return (getOpcode()==op)&&(dst.regi==dest)&&(m_src.regi==src_reg); return (getOpcode()==op)&&(m_dst.regi==dest)&&(m_src.regi==src_reg);
} }
bool match(eReg dest,eReg src_reg) bool match(eReg dest,eReg src_reg)
{ {
return (dst.regi==dest)&&(m_src.regi==src_reg); return (m_dst.regi==dest)&&(m_src.regi==src_reg);
} }
bool match(eReg dest) bool match(eReg dest)
{ {
return (dst.regi==dest); return (m_dst.regi==dest);
} }
bool match(llIcode op,uint32_t flgs) bool match(llIcode op,uint32_t flgs)
{ {
@ -314,6 +370,19 @@ public:
setOpcode(op); setOpcode(op);
flg =flags; flg =flags;
} }
void set(llIcode op,uint32_t flags,eReg dst_reg)
{
setOpcode(op);
m_dst = LLOperand::CreateReg2(dst_reg);
flg =flags;
}
void set(llIcode op,uint32_t flags,eReg dst_reg,const LLOperand &src_op)
{
setOpcode(op);
m_dst = LLOperand::CreateReg2(dst_reg);
m_src = src_op;
flg =flags;
}
void emitGotoLabel(int indLevel); void emitGotoLabel(int indLevel);
void findJumpTargets(CIcodeRec &_pc); void findJumpTargets(CIcodeRec &_pc);
void writeIntComment(std::ostringstream &s); void writeIntComment(std::ostringstream &s);
@ -343,16 +412,16 @@ public:
} }
void replaceDst(const LLOperand &with) void replaceDst(const LLOperand &with)
{ {
dst = with; m_dst = with;
}
void replaceDst(eReg r)
{
dst = LLOperand::CreateReg2(r);
} }
// void replaceDst(eReg r)
// {
// dst = LLOperand::CreateReg2(r);
// }
ICODE *m_link; ICODE *m_link;
condId idType(opLoc sd) const; 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() : &m_dst; }
LLOperand * get(opLoc sd) { return (sd == SRC) ? &src() : &dst; } LLOperand * get(opLoc sd) { return (sd == SRC) ? &src() : &m_dst; }
}; };
/* Icode definition: LOW_LEVEL and HIGH_LEVEL */ /* Icode definition: LOW_LEVEL and HIGH_LEVEL */
@ -407,6 +476,10 @@ public:
}; };
struct DU1 struct DU1
{ {
protected:
int numRegsDef; /* # registers defined by this inst */
public:
struct Use struct Use
{ {
int Reg; // used register int Reg; // used register
@ -422,7 +495,6 @@ public:
} }
}; };
int numRegsDef; /* # registers defined by this inst */
uint8_t regi[MAX_REGS_DEF+1]; /* registers defined by this inst */ uint8_t regi[MAX_REGS_DEF+1]; /* registers defined by this inst */
Use idx[MAX_REGS_DEF+1]; Use idx[MAX_REGS_DEF+1];
//int idx[MAX_REGS_DEF][MAX_USES]; /* inst that uses this def */ //int idx[MAX_REGS_DEF][MAX_USES]; /* inst that uses this def */
@ -447,6 +519,11 @@ public:
Use &u(idx[regIdx]); Use &u(idx[regIdx]);
u.removeUser(ic); u.removeUser(ic);
} }
int getNumRegsDef() const {return numRegsDef;}
void clearAllDefs() {numRegsDef=0;}
DU1 &addDef(eReg r) {numRegsDef++; return *this;}
DU1 &setDef(eReg r) {numRegsDef=1; return *this;}
void removeDef(eReg r) {numRegsDef--;}
DU1() : numRegsDef(0) DU1() : numRegsDef(0)
{ {
} }

View File

@ -31,37 +31,67 @@ struct IDX_ARRAY : public std::vector<iICODE>
} }
}; };
typedef enum enum frameType
{ {
STK_FRAME, /* For stack vars */ STK_FRAME, /* For stack vars */
REG_FRAME, /* For register variables */ REG_FRAME, /* For register variables */
GLB_FRAME /* For globals */ GLB_FRAME /* For globals */
} frameType; };
typedef struct struct BWGLB_TYPE
{ {
int16_t seg; /* segment value */ int16_t seg; /* segment value */
int16_t off; /* offset */ int16_t off; /* offset */
eReg regi; /* optional indexed register */ eReg regi; /* optional indexed register */
} BWGLB_TYPE;
typedef struct
{ /* For TYPE_LONG_(UN)SIGN on the stack */
int offH; /* high offset from BP */
int offL; /* low offset from BP */
} LONG_STKID_TYPE;
struct LONGID_TYPE
{ /* For TYPE_LONG_(UN)SIGN registers */
eReg h; /* high register */
eReg l; /* low register */
bool srcDstRegMatch(iICODE a,iICODE b) const;
} ; } ;
/* For TYPE_LONG_(UN)SIGN on the stack */
struct LONG_STKID_TYPE
{
int offH; /* high offset from BP */
int offL; /* low offset from BP */
LONG_STKID_TYPE(int h,int l) : offH(h),offL(l) {}
};
/* For TYPE_LONG_(UN)SIGN registers */
struct LONGID_TYPE
{
protected:
eReg m_h; /* high register */
eReg m_l; /* low register */
public:
void set(eReg highpart,eReg lowpart)
{
m_h = highpart;
m_l = lowpart;
}
eReg l() const { return m_l; }
eReg h() const { return m_h; }
bool srcDstRegMatch(iICODE a,iICODE b) const;
LONGID_TYPE() {} // uninitializing constructor to help valgrind catch uninit accesses
LONGID_TYPE(eReg h,eReg l) : m_h(h),m_l(l) {}
};
struct LONGGLB_TYPE /* For TYPE_LONG_(UN)SIGN globals */
{
int16_t seg; /* segment value */
int16_t offH; /* offset high */
int16_t offL; /* offset low */
uint8_t regi; /* optional indexed register */
LONGGLB_TYPE(int16_t _seg,int16_t _H,int16_t _L,int8_t _reg=0)
{
seg=_seg;
offH=_H;
offL=_L;
regi=_reg;
}
};
/* ID, LOCAL_ID */ /* ID, LOCAL_ID */
struct ID struct ID
{ {
protected:
LONGID_TYPE m_longId; /* For TYPE_LONG_(UN)SIGN registers */
public:
hlType type; /* Probable type */ hlType type; /* Probable type */
bool illegal; /* Boolean: not a valid field any more */ bool illegal; /* Boolean: not a valid field any more */
//std::vector<iICODE> idx; //std::vector<iICODE> idx;
@ -70,33 +100,39 @@ struct ID
bool hasMacro; /* Identifier requires a macro */ bool hasMacro; /* Identifier requires a macro */
char macro[10]; /* Macro for this identifier */ char macro[10]; /* Macro for this identifier */
std::string name; /* Identifier's name */ std::string name; /* Identifier's name */
union { /* Different types of identifiers */ union ID_UNION { /* Different types of identifiers */
friend class ID;
protected:
LONG_STKID_TYPE longStkId; /* For TYPE_LONG_(UN)SIGN on the stack */
public:
eReg regi; /* For TYPE_BYTE(uint16_t)_(UN)SIGN registers */ eReg regi; /* For TYPE_BYTE(uint16_t)_(UN)SIGN registers */
struct { /* For TYPE_BYTE(uint16_t)_(UN)SIGN on the stack */ struct { /* For TYPE_BYTE(uint16_t)_(UN)SIGN on the stack */
uint8_t regOff; /* register offset (if any) */ uint8_t regOff; /* register offset (if any) */
int off; /* offset from BP */ int off; /* offset from BP */
} bwId; } bwId;
BWGLB_TYPE bwGlb; /* For TYPE_BYTE(uint16_t)_(UN)SIGN globals */ BWGLB_TYPE bwGlb; /* For TYPE_BYTE(uint16_t)_(UN)SIGN globals */
LONGID_TYPE longId; /* For TYPE_LONG_(UN)SIGN registers */ LONGGLB_TYPE longGlb;
LONG_STKID_TYPE longStkId; /* For TYPE_LONG_(UN)SIGN on the stack */
struct { /* For TYPE_LONG_(UN)SIGN globals */
int16_t seg; /* segment value */
int16_t offH; /* offset high */
int16_t offL; /* offset low */
uint8_t regi; /* optional indexed register */
} longGlb;
struct { /* For TYPE_LONG_(UN)SIGN constants */ struct { /* For TYPE_LONG_(UN)SIGN constants */
uint32_t h; /* high uint16_t */ uint32_t h; /* high uint16_t */
uint32_t l; /* low uint16_t */ uint32_t l; /* low uint16_t */
} longKte; } longKte;
ID_UNION() { /*new (&longStkId) LONG_STKID_TYPE();*/}
} id; } id;
LONGID_TYPE &longId() {assert(isLong() && loc==REG_FRAME); return m_longId;}
const LONGID_TYPE &longId() const {assert(isLong() && loc==REG_FRAME); return m_longId;}
LONG_STKID_TYPE &longStkId() {assert(isLong() && loc==STK_FRAME); return id.longStkId;}
const LONG_STKID_TYPE &longStkId() const {assert(isLong() && loc==STK_FRAME); return id.longStkId;}
ID(); ID();
ID(hlType t, frameType f); ID(hlType t, frameType f);
ID(hlType t, const LONGID_TYPE &s);
ID(hlType t, const LONG_STKID_TYPE &s);
ID(hlType t, const LONGGLB_TYPE &s);
bool isSigned() const { return (type==TYPE_BYTE_SIGN)||(type==TYPE_WORD_SIGN)||(type==TYPE_LONG_SIGN);} bool isSigned() const { return (type==TYPE_BYTE_SIGN)||(type==TYPE_WORD_SIGN)||(type==TYPE_LONG_SIGN);}
uint16_t typeBitsize() const uint16_t typeBitsize() const
{ {
return TypeContainer::typeSize(type)*8; return TypeContainer::typeSize(type)*8;
} }
bool isLong() const { return (type==TYPE_LONG_UNSIGN)||(type==TYPE_LONG_SIGN); }
void setLocalName(int i) void setLocalName(int i)
{ {
char buf[32]; char buf[32];
@ -123,7 +159,7 @@ public:
int newByteWordReg(hlType t, eReg regi); int newByteWordReg(hlType t, eReg regi);
int newByteWordStk(hlType t, int off, uint8_t regOff); int newByteWordStk(hlType t, int off, uint8_t regOff);
int newIntIdx(int16_t seg, int16_t off, eReg regi, hlType t); int newIntIdx(int16_t seg, int16_t off, eReg regi, hlType t);
int newLongReg(hlType t, eReg regH, eReg regL, iICODE ix_); int newLongReg(hlType t, const LONGID_TYPE &longT, iICODE ix_);
int newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix, operDu du, int off); int newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix, operDu du, int off);
int newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix, operDu du, LLInst &atOffset); int newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix, operDu du, LLInst &atOffset);
void newIdent(hlType t, frameType f); void newIdent(hlType t, frameType f);

View File

@ -4,6 +4,7 @@
#include <sstream> #include <sstream>
#include <bitset> #include <bitset>
struct LivenessSet;
/* Machine registers */ /* Machine registers */
enum eReg enum eReg
{ {
@ -32,8 +33,9 @@ enum eReg
rBH = 20, rBH = 20,
rTMP= 21, /* temp register for DIV/IDIV/MOD */ rTMP= 21, /* temp register for DIV/IDIV/MOD */
rTMP2= 22, /* temp register for DIV/IDIV/MOD */
/* Indexed modes go from INDEXBASE to INDEXBASE+7 */ /* Indexed modes go from INDEXBASE to INDEXBASE+7 */
INDEX_BX_SI = 22, // "bx+si" INDEX_BX_SI = 23, // "bx+si"
INDEX_BX_DI, // "bx+di" INDEX_BX_DI, // "bx+di"
INDEX_BP_SI, // "bp+si" INDEX_BP_SI, // "bp+si"
INDEX_BP_DI, // "bp+di" INDEX_BP_DI, // "bp+di"
@ -64,15 +66,7 @@ public:
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 LivenessSet &regi);
{
int j;
for (j = rAX; j < INDEX_BX_SI; j++)
{
if (regi.test(j-1))
ostr << regName(eReg(j))<<" ";
}
}
static eReg subRegH(eReg reg); static eReg subRegH(eReg reg);
static eReg subRegL(eReg reg); static eReg subRegL(eReg reg);
static bool isMemOff(eReg r); static bool isMemOff(eReg r);

View File

@ -52,18 +52,23 @@ static const char *hexStr (uint16_t i)
void ICODE::setRegDU (eReg regi, operDu du_in) void ICODE::setRegDU (eReg regi, operDu du_in)
{ {
// printf("%s %d %x\n",__FUNCTION__,regi,int(du_in)); // printf("%s %d %x\n",__FUNCTION__,regi,int(du_in));
if(regi==rSP)
{
printf("Discarding SP def&use info for now\n");
return;
}
switch (du_in) switch (du_in)
{ {
case eDEF: case eDEF:
du.def.addReg(regi); du.def.addReg(regi);
du1.numRegsDef++; 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.numRegsDef++; du1.addDef(regi);
break; break;
case NONE: /* do nothing */ case NONE: /* do nothing */
break; break;
@ -233,9 +238,8 @@ AstIdent *AstIdent::Long(LOCAL_ID *localId, opLoc sd, iICODE pIcode, hlFirst f,
else else
{ {
newExp = new AstIdent(); newExp = new AstIdent();
idx = localId->newLong(sd, pIcode, f, ix, du, atOffset);
newExp->ident.idType = LONG_VAR; newExp->ident.idType = LONG_VAR;
newExp->ident.idNode.longIdx = idx; newExp->ident.idNode.longIdx = localId->newLong(sd, pIcode, f, ix, du, atOffset);
} }
return (newExp); return (newExp);
} }
@ -265,7 +269,7 @@ AstIdent *AstIdent::idID (const ID *retVal, LOCAL_ID *locsym, iICODE ix_)
case TYPE_LONG_SIGN: case TYPE_LONG_SIGN:
{ {
newExp = new AstIdent(); newExp = new AstIdent();
idx = locsym->newLongReg (TYPE_LONG_SIGN, retVal->id.longId.h,retVal->id.longId.l, ix_); idx = locsym->newLongReg (TYPE_LONG_SIGN, retVal->longId(), ix_);
newExp->ident.idType = LONG_VAR; newExp->ident.idType = LONG_VAR;
newExp->ident.idNode.longIdx = idx; newExp->ident.idNode.longIdx = idx;
break; break;
@ -294,13 +298,13 @@ Expr *AstIdent::id(const LLInst &ll_insn, opLoc sd, Function * pProc, iICODE ix_
int idx; /* idx into pIcode->localId table */ int idx; /* idx into pIcode->localId table */
const LLOperand &pm((sd == SRC) ? ll_insn.src() : ll_insn.dst); const LLOperand &pm((sd == SRC) ? ll_insn.src() : ll_insn.m_dst);
if ( ((sd == DST) && ll_insn.testFlags(IM_DST)) or if ( ((sd == DST) && ll_insn.testFlags(IM_DST)) or
((sd == SRC) && ll_insn.testFlags(IM_SRC)) or ((sd == SRC) && ll_insn.testFlags(IM_SRC)) or
(sd == LHS_OP)) /* for MUL lhs */ (sd == LHS_OP)) /* for MUL lhs */
{ /* implicit dx:ax */ { /* implicit dx:ax */
idx = pProc->localId.newLongReg (TYPE_LONG_SIGN, rDX, rAX, ix_); idx = pProc->localId.newLongReg (TYPE_LONG_SIGN, LONGID_TYPE(rDX, rAX), ix_);
newExp = AstIdent::LongIdx (idx); newExp = AstIdent::LongIdx (idx);
duIcode.setRegDU (rDX, du); duIcode.setRegDU (rDX, du);
duIcode.setRegDU (rAX, du); duIcode.setRegDU (rAX, du);
@ -372,7 +376,7 @@ Expr *AstIdent::id(const LLInst &ll_insn, opLoc sd, Function * pProc, iICODE ix_
/* Returns the identifier type */ /* Returns the identifier type */
condId LLInst::idType(opLoc sd) const condId LLInst::idType(opLoc sd) const
{ {
const LLOperand &pm((sd == SRC) ? src() : dst); const LLOperand &pm((sd == SRC) ? src() : m_dst);
if ((sd == SRC) && testFlags(I)) if ((sd == SRC) && testFlags(I))
return (CONSTANT); return (CONSTANT);
@ -582,10 +586,10 @@ string AstIdent::walkCondExpr(Function *pProc, int *numLoc) const
{ {
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->id.longId.h) << ":" << codeOut <<"/* "<<Machine_X86::regName(id->longId().h()) << ":" <<
Machine_X86::regName(id->id.longId.l) << " */\n"; Machine_X86::regName(id->longId().l()) << " */\n";
o << id->name; o << id->name;
pProc->localId.propLongId (id->id.longId.l,id->id.longId.h, id->name.c_str()); pProc->localId.propLongId (id->longId().l(),id->longId().h(), id->name.c_str());
} }
else /* GLB_FRAME */ else /* GLB_FRAME */
{ {
@ -884,10 +888,10 @@ eReg AstIdent::otherLongRegi (eReg regi, int idx, LOCAL_ID *locTbl)
if ((id->loc == REG_FRAME) && ((id->type == TYPE_LONG_SIGN) || if ((id->loc == REG_FRAME) && ((id->type == TYPE_LONG_SIGN) ||
(id->type == TYPE_LONG_UNSIGN))) (id->type == TYPE_LONG_UNSIGN)))
{ {
if (id->id.longId.h == regi) if (id->longId().h() == regi)
return (id->id.longId.l); return (id->longId().l());
else if (id->id.longId.l == regi) else if (id->longId().l() == regi)
return (id->id.longId.h); return (id->longId().h());
} }
return rUNDEF; // Cristina: please check this! return rUNDEF; // Cristina: please check this!
} }

View File

@ -154,7 +154,7 @@ void LLInst::writeIntComment (std::ostringstream &s)
s<<"\t/* "; s<<"\t/* ";
if (src_immed == 0x21) if (src_immed == 0x21)
{ {
s <<int21h[dst.off]; s <<int21h[m_dst.off];
} }
else if (src_immed > 0x1F && src_immed < 0x2F) else if (src_immed > 0x1F && src_immed < 0x2F)
{ {
@ -162,7 +162,7 @@ void LLInst::writeIntComment (std::ostringstream &s)
} }
else if (src_immed == 0x2F) else if (src_immed == 0x2F)
{ {
switch (dst.off) switch (m_dst.off)
{ {
case 0x01 : case 0x01 :
s << "Print spooler"; s << "Print spooler";
@ -215,8 +215,8 @@ void Function::writeProcComments(std::ostream &ostr)
else /* long register */ else /* long register */
{ {
id = &this->localId.id_arr[psym->regs->ident.idNode.longIdx]; id = &this->localId.id_arr[psym->regs->ident.idNode.longIdx];
ostr << Machine_X86::regName(id->id.longId.h) << ":"; ostr << Machine_X86::regName(id->longId().h()) << ":";
ostr << Machine_X86::regName(id->id.longId.l); ostr << Machine_X86::regName(id->longId().l());
} }
ostr << ".\n"; ostr << ".\n";

View File

@ -60,7 +60,7 @@ void ExpStack::push(Expr *expr)
Expr *ExpStack::pop() Expr *ExpStack::pop()
{ {
if(expStk.empty()) if(expStk.empty())
return 0; return expStk.back();
Expr *topExp = expStk.back(); Expr *topExp = expStk.back();
expStk.pop_back(); expStk.pop_back();
return topExp; return topExp;
@ -266,7 +266,7 @@ void Function::genLiveKtes ()
{ {
if ((insn.type == HIGH_LEVEL) && ( insn.valid() )) if ((insn.type == HIGH_LEVEL) && ( insn.valid() ))
{ {
liveUse |= (insn.du.use & ~def); liveUse |= (insn.du.use - def);
def |= insn.du.def; def |= insn.du.def;
} }
} }
@ -358,14 +358,15 @@ void Function::liveRegAnalysis (LivenessSet &in_liveOut)
{ {
switch (pcallee->retVal.type) { switch (pcallee->retVal.type) {
case TYPE_LONG_SIGN: case TYPE_LONG_UNSIGN: case TYPE_LONG_SIGN: case TYPE_LONG_UNSIGN:
ticode.du1.numRegsDef = 2; ticode.du1.setDef(rAX).addDef(rDX);
//TODO: use Calling convention to properly set regs here
break; break;
case TYPE_WORD_SIGN: case TYPE_WORD_UNSIGN: case TYPE_WORD_SIGN: case TYPE_WORD_UNSIGN:
case TYPE_BYTE_SIGN: case TYPE_BYTE_UNSIGN: case TYPE_BYTE_SIGN: case TYPE_BYTE_UNSIGN:
ticode.du1.numRegsDef = 1; ticode.du1.setDef(rAX);
break; break;
default: default:
ticode.du1.numRegsDef = 0; ticode.du1 = ICODE::DU1(); // was .numRegsDef = 0
//fprintf(stderr,"Function::liveRegAnalysis : Unknown return type %d, assume 0\n",pcallee->retVal.type); //fprintf(stderr,"Function::liveRegAnalysis : Unknown return type %d, assume 0\n",pcallee->retVal.type);
} /*eos*/ } /*eos*/
@ -377,7 +378,7 @@ void Function::liveRegAnalysis (LivenessSet &in_liveOut)
} }
/* liveIn(b) = liveUse(b) U (liveOut(b) - def(b) */ /* liveIn(b) = liveUse(b) U (liveOut(b) - def(b) */
pbb->liveIn = LivenessSet(pbb->liveUse | (pbb->liveOut & ~pbb->def)); pbb->liveIn = LivenessSet(pbb->liveUse + (pbb->liveOut - pbb->def));
/* Check if live sets have been modified */ /* Check if live sets have been modified */
if ((prevLiveIn != pbb->liveIn) || (prevLiveOut != pbb->liveOut)) if ((prevLiveIn != pbb->liveIn) || (prevLiveOut != pbb->liveOut))
@ -422,10 +423,10 @@ bool BB::FindUseBeforeDef(eReg regi, int defRegIdx, iICODE start_at)
if (checked_icode->type != HIGH_LEVEL) // Only check uses of HIGH_LEVEL icodes if (checked_icode->type != HIGH_LEVEL) // Only check uses of HIGH_LEVEL icodes
continue; continue;
/* if used, get icode index */ /* if used, get icode index */
if ((checked_icode->du.use & duReg[regi]).any()) if ( checked_icode->du.use.testRegAndSubregs(regi) )
start_at->du1.recordUse(defRegIdx,checked_icode.base()); start_at->du1.recordUse(defRegIdx,checked_icode.base());
/* if defined, stop finding uses for this reg */ /* if defined, stop finding uses for this reg */
if ((checked_icode->du.def & duReg[regi]).any()) if (checked_icode->du.def.testRegAndSubregs(regi))
{ {
ticode=checked_icode.base(); ticode=checked_icode.base();
break; break;
@ -435,13 +436,13 @@ bool BB::FindUseBeforeDef(eReg regi, int defRegIdx, iICODE start_at)
ticode=(++riICODE(rbegin())).base(); ticode=(++riICODE(rbegin())).base();
/* Check if last definition of this register */ /* Check if last definition of this register */
if ((not (ticode->du.def & duReg[regi]).any()) and (liveOut & duReg[regi]).any()) if (not ticode->du.def.testRegAndSubregs(regi) and liveOut.testRegAndSubregs(regi) )
start_at->du.lastDefRegi.addReg(regi); start_at->du.lastDefRegi.addReg(regi);
} }
else /* only 1 instruction in this basic block */ else /* only 1 instruction in this basic block */
{ {
/* Check if last definition of this register */ /* Check if last definition of this register */
if ((liveOut & duReg[regi]).any()) if ( liveOut.testRegAndSubregs(regi) )
start_at->du.lastDefRegi.addReg(regi); start_at->du.lastDefRegi.addReg(regi);
} }
return false; return false;
@ -460,17 +461,17 @@ void BB::ProcessUseDefForFunc(eReg regi, int defRegIdx, ICODE &picode)
for (auto iter=target_instructions.begin(); iter!=target_instructions.end(); ++iter) for (auto iter=target_instructions.begin(); iter!=target_instructions.end(); ++iter)
{ {
/* if used, get icode index */ /* if used, get icode index */
if ((iter->du.use & duReg[regi]).any()) if ( iter->du.use.testRegAndSubregs(regi) )
picode.du1.recordUse(defRegIdx,iter.base()); picode.du1.recordUse(defRegIdx,iter.base());
/* if defined, stop finding uses for this reg */ /* if defined, stop finding uses for this reg */
if ((iter->du.def & duReg[regi]).any()) if (iter->du.def.testRegAndSubregs(regi))
break; break;
} }
/* if not used in this basic block, check if the /* if not used in this basic block, check if the
* register is live out, if so, make it the last * register is live out, if so, make it the last
* definition of this register */ * definition of this register */
if ( picode.du1.used(defRegIdx) && (tbb->liveOut & duReg[regi]).any()) if ( picode.du1.used(defRegIdx) && tbb->liveOut.testRegAndSubregs(regi))
picode.du.lastDefRegi.addReg(regi); picode.du.lastDefRegi.addReg(regi);
} }
} }
@ -484,11 +485,11 @@ void BB::ProcessUseDefForFunc(eReg regi, int defRegIdx, ICODE &picode)
void BB::RemoveUnusedDefs(eReg regi, int defRegIdx, iICODE picode) void BB::RemoveUnusedDefs(eReg regi, int defRegIdx, iICODE picode)
{ {
if (picode->valid() and not picode->du1.used(defRegIdx) and if (picode->valid() and not picode->du1.used(defRegIdx) and
(not (picode->du.lastDefRegi & duReg[regi]).any()) && (not picode->du.lastDefRegi.testRegAndSubregs(regi)) &&
(not ((picode->hl()->opcode == HLI_CALL) && (not ((picode->hl()->opcode == HLI_CALL) &&
(picode->hl()->call.proc->flg & PROC_ISLIB)))) (picode->hl()->call.proc->flg & PROC_ISLIB))))
{ {
if (! (this->liveOut & duReg[regi]).any()) /* not liveOut */ if (! (this->liveOut.testRegAndSubregs(regi))) /* not liveOut */
{ {
bool res = picode->removeDefRegi (regi, defRegIdx+1,&Parent->localId); bool res = picode->removeDefRegi (regi, defRegIdx+1,&Parent->localId);
if (res == true) if (res == true)
@ -537,7 +538,7 @@ void BB::genDU1()
defRegIdx++; defRegIdx++;
/* Check if all defined registers have been processed */ /* Check if all defined registers have been processed */
if ((defRegIdx >= picode->du1.numRegsDef) || (defRegIdx == MAX_REGS_DEF)) if ((defRegIdx >= picode->du1.getNumRegsDef()) || (defRegIdx == MAX_REGS_DEF))
break; break;
} }
} }
@ -848,7 +849,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
{ {
HLTYPE &_icHl(*picode->hlU()); HLTYPE &_icHl(*picode->hlU());
numHlIcodes++; numHlIcodes++;
if (picode->du1.numRegsDef == 1) /* uint8_t/uint16_t regs */ if (picode->du1.getNumRegsDef() == 1) /* uint8_t/uint16_t regs */
{ {
/* Check for only one use of this register. If this is /* Check for only one use of this register. If this is
* the last definition of the register in this BB, check * the last definition of the register in this BB, check
@ -867,7 +868,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
* icode expression */ * icode expression */
ticode = picode->du1.idx[0].uses.front(); ticode = picode->du1.idx[0].uses.front();
if ((picode->du.lastDefRegi & duReg[regi]).any() && if ((picode->du.lastDefRegi.testRegAndSubregs(regi)) &&
((ticode->hl()->opcode != HLI_CALL) && ((ticode->hl()->opcode != HLI_CALL) &&
(ticode->hl()->opcode != HLI_RET))) (ticode->hl()->opcode != HLI_RET)))
continue; continue;
@ -886,7 +887,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
// call F() <- somehow this is marked as user of POP ? // call F() <- somehow this is marked as user of POP ?
ticode = picode->du1.idx[0].uses.front(); ticode = picode->du1.idx[0].uses.front();
ti_hl = ticode->hlU(); ti_hl = ticode->hlU();
if ((picode->du.lastDefRegi & duReg[regi]).any() && if ((picode->du.lastDefRegi.testRegAndSubregs(regi)) &&
((ti_hl->opcode != HLI_CALL) && ((ti_hl->opcode != HLI_CALL) &&
(ti_hl->opcode != HLI_RET))) (ti_hl->opcode != HLI_RET)))
continue; continue;
@ -971,7 +972,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
} }
} }
else if (picode->du1.numRegsDef == 2) /* long regs */ else if (picode->du1.getNumRegsDef() == 2) /* long regs */
{ {
/* Check for only one use of these registers */ /* Check for only one use of these registers */
if ((picode->du1.numUses(0) == 1) and (picode->du1.numUses(1) == 1)) if ((picode->du1.numUses(0) == 1) and (picode->du1.numUses(1) == 1))
@ -986,7 +987,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
if (picode->du1.idx[0].uses[0] == picode->du1.idx[1].uses[0]) if (picode->du1.idx[0].uses[0] == picode->du1.idx[1].uses[0])
{ {
ticode = picode->du1.idx[0].uses.front(); ticode = picode->du1.idx[0].uses.front();
if ((picode->du.lastDefRegi & duReg[regi]).any() && if ((picode->du.lastDefRegi.testRegAndSubregs(regi)) &&
((ticode->hl()->opcode != HLI_CALL) && ((ticode->hl()->opcode != HLI_CALL) &&
(ticode->hl()->opcode != HLI_RET))) (ticode->hl()->opcode != HLI_RET)))
continue; continue;
@ -998,7 +999,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
if (picode->du1.idx[0].uses[0] == picode->du1.idx[1].uses[0]) if (picode->du1.idx[0].uses[0] == picode->du1.idx[1].uses[0])
{ {
ticode = picode->du1.idx[0].uses.front(); ticode = picode->du1.idx[0].uses.front();
if ((picode->du.lastDefRegi & duReg[regi]).any() && if ((picode->du.lastDefRegi.testRegAndSubregs(regi)) &&
((ticode->hl()->opcode != HLI_CALL) && ((ticode->hl()->opcode != HLI_CALL) &&
(ticode->hl()->opcode != HLI_RET))) (ticode->hl()->opcode != HLI_RET)))
continue; continue;
@ -1053,8 +1054,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
_retVal = &picode->hl()->call.proc->retVal; _retVal = &picode->hl()->call.proc->retVal;
res = Expr::insertSubTreeLongReg (_exp, res = Expr::insertSubTreeLongReg (_exp,
ticode->hlU()->exp.v, ticode->hlU()->exp.v,
locals.newLongReg ( _retVal->type, _retVal->id.longId.h, locals.newLongReg ( _retVal->type, _retVal->longId(), picode.base()));
_retVal->id.longId.l, picode.base()));
if (res) /* was substituted */ if (res) /* was substituted */
{ {
picode->invalidate(); picode->invalidate();
@ -1083,8 +1083,8 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
{ {
g_exp_stk.processExpPush(numHlIcodes, picode.base()); g_exp_stk.processExpPush(numHlIcodes, picode.base());
} }
else if(picode->du1.numRegsDef!=0) else if(picode->du1.getNumRegsDef()!=0)
printf("Num def %d\n",picode->du1.numRegsDef); printf("Num def %d\n",picode->du1.getNumRegsDef());
/* For HLI_CALL instructions that use arguments from the stack, /* For HLI_CALL instructions that use arguments from the stack,
* pop them from the expression stack and place them on the * pop them from the expression stack and place them on the
@ -1098,7 +1098,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
/* If we could not substitute the result of a function, /* If we could not substitute the result of a function,
* assign it to the corresponding registers */ * assign it to the corresponding registers */
if ( not _icHl.call.proc->isLibrary() and (not picode->du1.used(0)) and (picode->du1.numRegsDef > 0)) if ( not _icHl.call.proc->isLibrary() and (not picode->du1.used(0)) and (picode->du1.getNumRegsDef() > 0))
{ {
_exp = new FuncNode(_icHl.call.proc, _icHl.call.args); _exp = new FuncNode(_icHl.call.proc, _icHl.call.args);
auto lhs = AstIdent::idID (&_icHl.call.proc->retVal, &locals, picode.base()); auto lhs = AstIdent::idID (&_icHl.call.proc->retVal, &locals, picode.base());
@ -1176,9 +1176,8 @@ void Function::preprocessReturnDU(LivenessSet &_liveOut)
{ {
retVal.type = TYPE_LONG_SIGN; retVal.type = TYPE_LONG_SIGN;
retVal.loc = REG_FRAME; retVal.loc = REG_FRAME;
retVal.id.longId.h = rDX; retVal.longId() = LONGID_TYPE(rDX,rAX);
retVal.id.longId.l = rAX; /*idx = */localId.newLongReg(TYPE_LONG_SIGN, LONGID_TYPE(rDX,rAX), Icode.begin());
/*idx = */localId.newLongReg(TYPE_LONG_SIGN, rDX, rAX, Icode.begin()/*0*/);
localId.propLongId (rAX, rDX, "\0"); localId.propLongId (rAX, rDX, "\0");
} }
else if (isAx || isBx || isCx || isDx) /* uint16_t */ else if (isAx || isBx || isCx || isDx) /* uint16_t */

View File

@ -70,7 +70,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, const LLOperand &pm);
static ostringstream &strDst(ostringstream &os, uint32_t flg, const 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);
@ -283,7 +283,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
{ {
case iADD: case iADC: case iSUB: case iSBB: case iAND: case iOR: case iADD: case iADC: case iSUB: case iSBB: case iAND: case iOR:
case iXOR: case iTEST: case iCMP: case iMOV: case iLEA: case iXCHG: case iXOR: case iTEST: case iCMP: case iMOV: case iLEA: case iXCHG:
strDst(operands_s,inst.getFlag(), inst.dst); strDst(operands_s,inst.getFlag(), inst.m_dst);
inst.strSrc(operands_s); inst.strSrc(operands_s);
break; break;
@ -293,7 +293,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
case iSAR: case iSHL: case iSHR: case iRCL: case iRCR: case iROL: case iSAR: case iSHL: case iSHR: case iRCL: case iRCR: case iROL:
case iROR: case iROR:
strDst(operands_s,inst.getFlag() | I, inst.dst); strDst(operands_s,inst.getFlag() | I, inst.m_dst);
if(inst.testFlags(I)) if(inst.testFlags(I))
inst.strSrc(operands_s); inst.strSrc(operands_s);
else else
@ -301,7 +301,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
break; break;
case iINC: case iDEC: case iNEG: case iNOT: case iPOP: case iINC: case iDEC: case iNEG: case iNOT: case iPOP:
strDst(operands_s,inst.getFlag() | I, inst.dst); strDst(operands_s,inst.getFlag() | I, inst.m_dst);
break; break;
case iPUSH: case iPUSH:
@ -311,15 +311,15 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
} }
else else
{ {
strDst(operands_s,inst.getFlag() | I, inst.dst); strDst(operands_s,inst.getFlag() | I, inst.m_dst);
} }
break; break;
case iDIV: case iIDIV: case iMUL: case iIMUL: case iMOD: case iDIV: case iIDIV: case iMUL: case iIMUL: case iMOD:
if (inst.testFlags(I)) if (inst.testFlags(I))
{ {
strDst(operands_s,inst.getFlag(), inst.dst) <<", "; strDst(operands_s,inst.getFlag(), inst.m_dst) <<", ";
formatRM(operands_s, inst.getFlag(), inst.src()); formatRM(operands_s, inst.src());
inst.strSrc(operands_s); inst.strSrc(operands_s);
} }
else else
@ -327,7 +327,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
break; break;
case iLDS: case iLES: case iBOUND: case iLDS: case iLES: case iBOUND:
strDst(operands_s,inst.getFlag(), inst.dst)<<", dword ptr"; strDst(operands_s,inst.getFlag(), inst.m_dst)<<", dword ptr";
inst.strSrc(operands_s,true); inst.strSrc(operands_s,true);
break; break;
@ -397,8 +397,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
break; break;
case iENTER: case iENTER:
operands_s<<strHex(inst.dst.off)<<", "; operands_s<<strHex(inst.m_dst.off) << ", " << strHex(inst.src().getImm2());
operands_s<<strHex(inst.src().getImm2());
break; break;
case iRET: case iRETF: case iINT: case iRET: case iRETF: case iINT:
@ -552,7 +551,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
/**************************************************************************** /****************************************************************************
* formatRM * formatRM
***************************************************************************/ ***************************************************************************/
static void formatRM(std::ostringstream &p, uint32_t /*flg*/, const LLOperand &pm) static void formatRM(std::ostringstream &p, const LLOperand &pm)
{ {
//char seg[4]; //char seg[4];
@ -595,7 +594,7 @@ static ostringstream & strDst(ostringstream &os,uint32_t flg, const LLOperand &p
//os << setw(WID_PTR); //os << setw(WID_PTR);
if ((flg & I) and not pm.isReg()) if ((flg & I) and not pm.isReg())
os << szPtr[flg & B]; os << szPtr[flg & B];
formatRM(os, flg, pm); formatRM(os, pm);
return os; return os;
} }
@ -612,7 +611,7 @@ ostringstream &LLInst::strSrc(ostringstream &os,bool skip_comma)
else if (testFlags(IM_SRC)) /* level 2 */ else if (testFlags(IM_SRC)) /* level 2 */
os<<"dx:ax"; os<<"dx:ax";
else else
formatRM(os, getFlag(), src()); formatRM(os, src());
return os; return os;
} }
@ -649,7 +648,7 @@ void LLInst::flops(std::ostringstream &out)
/* Note that op is set to the escape number, e.g. /* Note that op is set to the escape number, e.g.
esc 0x38 is FILD */ esc 0x38 is FILD */
if ( not dst.isReg() ) if ( not m_dst.isReg() )
{ {
/* The mod/rm mod bits are not set to 11 (i.e. register). This is the normal floating point opcode */ /* The mod/rm mod bits are not set to 11 (i.e. register). This is the normal floating point opcode */
out<<Machine_X86::floatOpName(op)<<' '; out<<Machine_X86::floatOpName(op)<<' ';
@ -685,7 +684,7 @@ void LLInst::flops(std::ostringstream &out)
} }
} }
formatRM(out, getFlag(), dst); formatRM(out, m_dst);
} }
else else
{ {
@ -694,7 +693,7 @@ void LLInst::flops(std::ostringstream &out)
normal opcodes. Because the opcodes are slightly different for normal opcodes. Because the opcodes are slightly different for
this case (e.g. op=04 means FSUB if reg != 3, but FSUBR for this case (e.g. op=04 means FSUB if reg != 3, but FSUBR for
reg == 3), a separate table is used (szFlops2). */ reg == 3), a separate table is used (szFlops2). */
int destRegIdx=dst.regi - rAX; int destRegIdx=m_dst.regi - rAX;
switch (op) switch (op)
{ {
case 0x0C: case 0x0C:

View File

@ -11,27 +11,6 @@
#include "dcc.h" #include "dcc.h"
using namespace std; using namespace std;
/* Masks off bits set by duReg[] */
LivenessSet maskDuReg[] = { 0x00,
/* uint16_t regs */
0xFEEFFE, //rAX
0xFDDFFD, //rCX
0xFBB00B, //rDX
0xF77007, //rBX
0xFFFFEF, //rSP
0xFFFFDF, //rBP
0xFFFFBF, //rSI
0xFFFF7F, //rDI
0xFFFEFF,
0xFFFDFF,
0xFFFBFF,
0xFFF7FF, /* seg regs */
0xFFEFFF, 0xFFDFFF, 0xFFBFFF, 0xFF7FFF, /* uint8_t regs */
0xFEFFFF, 0xFDFFFF, 0xFBFFFF, 0xF7FFFF,
0xEFFFFF, /* tmp reg */
0xFFFFB7, 0xFFFF77, 0xFFFF9F, 0xFFFF5F, /* index regs */
0xFFFFBF, 0xFFFF7F, 0xFFFFDF, 0xFFFFF7 };
static char buf[lineSize]; /* Line buffer for hl icode output */ static char buf[lineSize]; /* Line buffer for hl icode output */
@ -98,13 +77,13 @@ bool ICODE::removeDefRegi (eReg regi, int thisDefIdx, LOCAL_ID *locId)
{ {
int numDefs; int numDefs;
numDefs = du1.numRegsDef; numDefs = du1.getNumRegsDef();
if (numDefs == thisDefIdx) if (numDefs == thisDefIdx)
{ {
for ( ; numDefs > 0; numDefs--) for ( ; numDefs > 0; numDefs--)
{ {
if (du1.used(numDefs-1)||(du.lastDefRegi[regi])) if (du1.used(numDefs-1)||(du.lastDefRegi.testReg(regi)))
break; break;
} }
} }
@ -117,8 +96,9 @@ bool ICODE::removeDefRegi (eReg regi, int thisDefIdx, LOCAL_ID *locId)
HlTypeSupport *p=hlU()->get(); HlTypeSupport *p=hlU()->get();
if(p and p->removeRegFromLong(regi,locId)) if(p and p->removeRegFromLong(regi,locId))
{ {
du1.numRegsDef--; du1.removeDef(regi); //du1.numRegsDef--;
du.def &= maskDuReg[regi]; //du.def &= maskDuReg[regi];
du.def.clrReg(regi);
} }
return false; return false;
} }
@ -285,6 +265,41 @@ HLTYPE LLInst::toHighLevel(COND_EXPR *lhs,COND_EXPR *rhs,Function *func)
return res; return res;
} }
#endif #endif
static bool needsLhs(unsigned opc)
{
switch (opc)
{
case iCALL:
case iCALLF:
case iRET:
case iRETF:
default: return false;
case iADD:
case iAND:
case iDEC:
case iDIV:
case iIDIV:/* should be signed div */
case iIMUL:
case iINC:
case iLEA:
case iMOD:
case iMOV:
case iMUL:
case iNEG:
case iNOT:
case iOR:
case iPOP:
case iPUSH:
case iSHL:
case iSAR: /* signed */
case iSHR:
case iSIGNEX:
case iSUB:
case iXCHG:
case iXOR:
return true;
}
}
/* Translates LOW_LEVEL icodes to HIGH_LEVEL icodes - 1st stage. /* Translates LOW_LEVEL icodes to HIGH_LEVEL icodes - 1st stage.
* Note: this process should be done before data flow analysis, which * Note: this process should be done before data flow analysis, which
* refines the HIGH_LEVEL icodes. */ * refines the HIGH_LEVEL icodes. */
@ -292,12 +307,12 @@ void Function::highLevelGen()
{ {
size_t numIcode; /* number of icode instructions */ size_t numIcode; /* number of icode instructions */
iICODE pIcode; /* ptr to current icode node */ iICODE pIcode; /* ptr to current icode node */
Expr *lhs;
Expr *rhs; /* left- and right-hand side of expression */ Expr *rhs; /* left- and right-hand side of expression */
uint32_t _flg; /* icode flags */ uint32_t _flg; /* icode flags */
numIcode = Icode.size(); numIcode = Icode.size();
for (iICODE i = Icode.begin(); i!=Icode.end() ; ++i) for (iICODE i = Icode.begin(); i!=Icode.end() ; ++i)
{ {
Expr *lhs=nullptr;
assert(numIcode==Icode.size()); assert(numIcode==Icode.size());
pIcode = i; //Icode.GetIcode(i) pIcode = i; //Icode.GetIcode(i)
LLInst *ll = pIcode->ll(); LLInst *ll = pIcode->ll();
@ -306,13 +321,16 @@ void Function::highLevelGen()
if ((pIcode->type != LOW_LEVEL) or not pIcode->valid() ) if ((pIcode->type != LOW_LEVEL) or not pIcode->valid() )
continue; continue;
_flg = ll->getFlag(); _flg = ll->getFlag();
if ((_flg & IM_OPS) != IM_OPS) /* not processing IM_OPS yet */ if (not ll->testFlags(IM_OPS)) /* not processing IM_OPS yet */
if ((_flg & NO_OPS) != NO_OPS) /* if there are opers */ if ( not ll->testFlags(NO_OPS) ) /* if there are opers */
{ {
if ( not ll->testFlags(NO_SRC) ) /* if there is src op */ if ( not ll->testFlags(NO_SRC) ) /* if there is src op */
rhs = AstIdent::id (*pIcode->ll(), SRC, this, i, *pIcode, NONE); rhs = AstIdent::id (*pIcode->ll(), SRC, this, i, *pIcode, NONE);
if(ll->m_dst.isSet() || (ll->getOpcode()==iMOD))
lhs = AstIdent::id (*pIcode->ll(), DST, this, i, *pIcode, NONE); lhs = AstIdent::id (*pIcode->ll(), DST, this, i, *pIcode, NONE);
} }
if(needsLhs(ll->getOpcode()))
assert(lhs!=nullptr);
switch (ll->getOpcode()) switch (ll->getOpcode())
{ {
case iADD: case iADD:
@ -406,10 +424,12 @@ void Function::highLevelGen()
pIcode->setAsgn(lhs, rhs); pIcode->setAsgn(lhs, rhs);
break; break;
case iPOP: pIcode->setUnary(HLI_POP, lhs); case iPOP:
pIcode->setUnary(HLI_POP, lhs);
break; break;
case iPUSH: pIcode->setUnary(HLI_PUSH, lhs); case iPUSH:
pIcode->setUnary(HLI_PUSH, lhs);
break; break;
case iRET: case iRET:
@ -613,7 +633,7 @@ void ICODE::writeDU()
} }
/* Print du1 chain */ /* Print du1 chain */
printf ("# regs defined = %d\n", du1.numRegsDef); printf ("# regs defined = %d\n", du1.getNumRegsDef());
for (int i = 0; i < MAX_REGS_DEF; i++) for (int i = 0; i < MAX_REGS_DEF; i++)
{ {
if (not du1.used(i)) if (not du1.used(i))

View File

@ -122,7 +122,7 @@ void Function::findIdioms()
{ {
if ((pIcode->ll()->src().proc.proc->retVal.type==TYPE_LONG_SIGN) if ((pIcode->ll()->src().proc.proc->retVal.type==TYPE_LONG_SIGN)
|| (pIcode->ll()->src().proc.proc->retVal.type == TYPE_LONG_UNSIGN)) || (pIcode->ll()->src().proc.proc->retVal.type == TYPE_LONG_UNSIGN))
localId.newLongReg(TYPE_LONG_SIGN, rDX, rAX, pIcode/*ip*/); localId.newLongReg(TYPE_LONG_SIGN, LONGID_TYPE(rDX,rAX), pIcode/*ip*/);
} }
/* Check for idioms */ /* Check for idioms */

View File

@ -102,20 +102,20 @@ bool Idiom18::match(iICODE picode)
m_is_dec = m_icodes[1]->ll()->match(iDEC); m_is_dec = m_icodes[1]->ll()->match(iDEC);
uint8_t regi; /* register of the MOV */ uint8_t regi; /* register of the MOV */
if(not (m_icodes[0]->ll()->match(iMOV) and m_icodes[0]->ll()->dst.isReg() )) if(not m_icodes[0]->ll()->matchWithRegDst(iMOV) )
return false; return false;
regi = m_icodes[0]->ll()->dst.regi; regi = m_icodes[0]->ll()->m_dst.regi;
if( not ( m_icodes[2]->ll()->match(iCMP) && (m_icodes[2]->ll()->dst.regi == regi) && if( not ( m_icodes[2]->ll()->match(iCMP,regi) &&
m_icodes[3]->ll()->conditionalJump() ) ) m_icodes[3]->ll()->conditionalJump() ) )
return false; return false;
// Simple matching finished, select apropriate matcher based on dst type // Simple matching finished, select apropriate matcher based on dst type
/* Get variable */ /* Get variable */
if (m_icodes[1]->ll()->dst.regi == 0) /* global variable */ if (m_icodes[1]->ll()->m_dst.regi == 0) /* global variable */
{ {
/* not supported yet */ /* not supported yet */
m_idiom_type = 0; m_idiom_type = 0;
} }
else if ( m_icodes[1]->ll()->dst.isReg() ) /* register */ else if ( m_icodes[1]->ll()->m_dst.isReg() ) /* register */
{ {
m_idiom_type = 1; m_idiom_type = 1;
// if ((m_icodes[1]->ll()->dst.regi == rSI) && (m_func->flg & SI_REGVAR)) // if ((m_icodes[1]->ll()->dst.regi == rSI) && (m_func->flg & SI_REGVAR))
@ -123,7 +123,7 @@ bool Idiom18::match(iICODE picode)
// else if ((m_icodes[1]->ll()->dst.regi == rDI) && (m_func->flg & DI_REGVAR)) // else if ((m_icodes[1]->ll()->dst.regi == rDI) && (m_func->flg & DI_REGVAR))
// m_idiom_type = 1; // m_idiom_type = 1;
} }
else if (m_icodes[1]->ll()->dst.off) /* local variable */ else if (m_icodes[1]->ll()->m_dst.off) /* local variable */
m_idiom_type = 2; m_idiom_type = 2;
else /* indexed */ else /* indexed */
{ {
@ -141,20 +141,20 @@ bool Idiom18::match(iICODE picode)
break; break;
case 1: /* register variable */ case 1: /* register variable */
/* Check previous instruction for a MOV */ /* Check previous instruction for a MOV */
if ( (m_icodes[0]->ll()->src().regi == m_icodes[1]->ll()->dst.regi)) if ( (m_icodes[0]->ll()->src().regi == m_icodes[1]->ll()->m_dst.regi))
{ {
return true; return true;
} }
break; break;
case 2: /* local */ case 2: /* local */
if ((m_icodes[0]->ll()->src().off == m_icodes[1]->ll()->dst.off)) if ((m_icodes[0]->ll()->src().off == m_icodes[1]->ll()->m_dst.off))
{ {
return true; return true;
} }
break; break;
case 3: // indexed case 3: // indexed
printf("Untested idiom18 type: indexed\n"); printf("Untested idiom18 type: indexed\n");
if ((m_icodes[0]->ll()->src() == m_icodes[1]->ll()->dst)) if ((m_icodes[0]->ll()->src() == m_icodes[1]->ll()->m_dst))
{ {
return true; return true;
} }
@ -200,15 +200,15 @@ bool Idiom19::match(iICODE picode)
m_is_dec = m_icodes[0]->ll()->match(iDEC); m_is_dec = m_icodes[0]->ll()->match(iDEC);
if ( not m_icodes[1]->ll()->conditionalJump() ) if ( not m_icodes[1]->ll()->conditionalJump() )
return false; return false;
if (m_icodes[0]->ll()->dst.regi == 0) /* global variable */ if (m_icodes[0]->ll()->m_dst.regi == 0) /* global variable */
/* not supported yet */ ; /* not supported yet */ ;
else if ( m_icodes[0]->ll()->dst.isReg() ) /* register */ else if ( m_icodes[0]->ll()->m_dst.isReg() ) /* register */
{ {
// if (((picode->ll()->dst.regi == rSI) && (pproc->flg & SI_REGVAR)) || // if (((picode->ll()->dst.regi == rSI) && (pproc->flg & SI_REGVAR)) ||
// ((picode->ll()->dst.regi == rDI) && (pproc->flg & DI_REGVAR))) // ((picode->ll()->dst.regi == rDI) && (pproc->flg & DI_REGVAR)))
return true; return true;
} }
else if (m_icodes[0]->ll()->dst.off) /* stack variable */ else if (m_icodes[0]->ll()->m_dst.off) /* stack variable */
{ {
return true; return true;
} }
@ -257,12 +257,12 @@ bool Idiom20::match(iICODE picode)
for(int i=0; i<4; ++i) for(int i=0; i<4; ++i)
m_icodes[i] =picode++; m_icodes[i] =picode++;
/* Check second instruction for a MOV */ /* Check second instruction for a MOV */
if(not (m_icodes[1]->ll()->match(iMOV) && m_icodes[1]->ll()->dst.isReg())) if( not m_icodes[1]->ll()->matchWithRegDst(iMOV) )
return false; return false;
m_is_dec = m_icodes[0]->ll()->match(iDEC) ? PRE_DEC : PRE_INC; m_is_dec = m_icodes[0]->ll()->match(iDEC) ? PRE_DEC : PRE_INC;
LLOperand &ll_dest(m_icodes[0]->ll()->dst); const LLOperand &ll_dest(m_icodes[0]->ll()->m_dst);
/* Get variable */ /* Get variable */
if (ll_dest.regi == 0) /* global variable */ if (ll_dest.regi == 0) /* global variable */
{ {
@ -284,7 +284,7 @@ bool Idiom20::match(iICODE picode)
type = 3; type = 3;
/* not supported yet */ ; /* not supported yet */ ;
} }
regi = m_icodes[1]->ll()->dst.regi; regi = m_icodes[1]->ll()->m_dst.regi;
const LLOperand &mov_src(m_icodes[1]->ll()->src()); const LLOperand &mov_src(m_icodes[1]->ll()->src());
if (m_icodes[2]->ll()->match(iCMP,(eReg)regi) && m_icodes[3]->ll()->conditionalJump()) if (m_icodes[2]->ll()->match(iCMP,(eReg)regi) && m_icodes[3]->ll()->conditionalJump())
{ {

View File

@ -77,13 +77,13 @@ bool Idiom17::match(iICODE picode)
if (m_icodes[1]->ll()->match(iPOP)) if (m_icodes[1]->ll()->match(iPOP))
{ {
int i=0; int i=0;
regi = m_icodes[1]->ll()->dst.regi; regi = m_icodes[1]->ll()->m_dst.regi;
if ((regi >= rAX) && (regi <= rBX)) if ((regi >= rAX) && (regi <= rBX))
i++; i++;
while (picode != m_end && picode->ll()->match(iPOP)) while (picode != m_end && picode->ll()->match(iPOP))
{ {
if (picode->ll()->dst.regi != regi) if (picode->ll()->m_dst.regi != regi)
break; break;
i++; i++;
m_icodes.push_back(picode++); m_icodes.push_back(picode++);

View File

@ -28,13 +28,13 @@ bool Idiom14::match(iICODE pIcode)
m_icodes[0]=pIcode++; m_icodes[0]=pIcode++;
m_icodes[1]=pIcode++; m_icodes[1]=pIcode++;
/* Check for regL */ /* Check for regL */
m_regL = m_icodes[0]->ll()->dst.regi; m_regL = m_icodes[0]->ll()->m_dst.regi;
if (not m_icodes[0]->ll()->testFlags(I) && ((m_regL == rAX) || (m_regL ==rBX))) if (not m_icodes[0]->ll()->testFlags(I) && ((m_regL == rAX) || (m_regL ==rBX)))
{ {
/* Check for XOR regH, regH */ /* Check for XOR regH, regH */
if (m_icodes[1]->ll()->match(iXOR) && not m_icodes[1]->ll()->testFlags(I)) if (m_icodes[1]->ll()->match(iXOR) && not m_icodes[1]->ll()->testFlags(I))
{ {
m_regH = m_icodes[1]->ll()->dst.regi; m_regH = m_icodes[1]->ll()->m_dst.regi;
if (m_regH == m_icodes[1]->ll()->src().getReg2()) if (m_regH == m_icodes[1]->ll()->src().getReg2())
{ {
if ((m_regL == rAX) && (m_regH == rDX)) if ((m_regL == rAX) && (m_regH == rDX))
@ -52,7 +52,7 @@ int Idiom14::action()
AstIdent *lhs; AstIdent *lhs;
Expr *rhs; Expr *rhs;
idx = m_func->localId.newLongReg (TYPE_LONG_SIGN, m_regH, m_regL, m_icodes[0]); idx = m_func->localId.newLongReg (TYPE_LONG_SIGN, LONGID_TYPE(m_regH,m_regL), m_icodes[0]);
lhs = AstIdent::LongIdx (idx); lhs = AstIdent::LongIdx (idx);
m_icodes[0]->setRegDU( m_regH, eDEF); m_icodes[0]->setRegDU( m_regH, eDEF);
rhs = AstIdent::id (*m_icodes[0]->ll(), SRC, m_func, m_icodes[0], *m_icodes[0], NONE); rhs = AstIdent::id (*m_icodes[0]->ll(), SRC, m_func, m_icodes[0], *m_icodes[0], NONE);
@ -82,13 +82,13 @@ bool Idiom13::match(iICODE pIcode)
eReg regi; eReg regi;
/* Check for regL */ /* Check for regL */
regi = m_icodes[0]->ll()->dst.regi; regi = m_icodes[0]->ll()->m_dst.regi;
if (not m_icodes[0]->ll()->testFlags(I) && (regi >= rAL) && (regi <= rBH)) if (not m_icodes[0]->ll()->testFlags(I) && (regi >= rAL) && (regi <= rBH))
{ {
/* Check for MOV regH, 0 */ /* Check for MOV regH, 0 */
if (m_icodes[1]->ll()->match(iMOV,I) && (m_icodes[1]->ll()->src().getImm2() == 0)) if (m_icodes[1]->ll()->match(iMOV,I) && (m_icodes[1]->ll()->src().getImm2() == 0))
{ {
if (m_icodes[1]->ll()->dst.regi == (regi + 4)) //WARNING: based on distance between AH-AL,BH-BL etc. if (m_icodes[1]->ll()->m_dst.regi == (regi + 4)) //WARNING: based on distance between AH-AL,BH-BL etc.
{ {
m_loaded_reg=(eReg)(regi - rAL + rAX); m_loaded_reg=(eReg)(regi - rAL + rAX);
return true; return true;
@ -102,9 +102,11 @@ int Idiom13::action()
{ {
AstIdent *lhs; AstIdent *lhs;
Expr *rhs; Expr *rhs;
eReg regi = m_icodes[0]->ll()->m_dst.regi;
m_icodes[0]->du1.removeDef(regi);
//m_icodes[0]->du1.numRegsDef--; /* prev uint8_t reg def */
lhs = new RegisterNode(m_loaded_reg, 0, &m_func->localId); lhs = new RegisterNode(m_loaded_reg, 0, &m_func->localId);
m_icodes[0]->setRegDU( m_loaded_reg, eDEF); m_icodes[0]->setRegDU( m_loaded_reg, eDEF);
m_icodes[0]->du1.numRegsDef--; /* prev uint8_t reg def */
rhs = AstIdent::id (*m_icodes[0]->ll(), SRC, m_func, m_icodes[0], *m_icodes[0], NONE); rhs = AstIdent::id (*m_icodes[0]->ll(), SRC, m_func, m_icodes[0], *m_icodes[0], NONE);
m_icodes[0]->setAsgn(lhs, rhs); m_icodes[0]->setAsgn(lhs, rhs);
m_icodes[1]->invalidate(); m_icodes[1]->invalidate();

View File

@ -32,17 +32,17 @@ bool Idiom11::match (iICODE picode)
switch (type) switch (type)
{ {
case GLOB_VAR: case GLOB_VAR:
if ((m_icodes[2]->ll()->dst.segValue == m_icodes[0]->ll()->dst.segValue) && if ((m_icodes[2]->ll()->m_dst.segValue == m_icodes[0]->ll()->m_dst.segValue) &&
(m_icodes[2]->ll()->dst.off == m_icodes[0]->ll()->dst.off)) (m_icodes[2]->ll()->m_dst.off == m_icodes[0]->ll()->m_dst.off))
return true; return true;
break; break;
case REGISTER: case REGISTER:
if (m_icodes[2]->ll()->dst.regi == m_icodes[0]->ll()->dst.regi) if (m_icodes[2]->ll()->m_dst.regi == m_icodes[0]->ll()->m_dst.regi)
return true; return true;
break; break;
case PARAM: case PARAM:
case LOCAL_VAR: case LOCAL_VAR:
if (m_icodes[2]->ll()->dst.off == m_icodes[0]->ll()->dst.off) if (m_icodes[2]->ll()->m_dst.off == m_icodes[0]->ll()->m_dst.off)
return true; return true;
break; break;
default: default:
@ -82,11 +82,11 @@ bool Idiom16::match (iICODE picode)
for(int i=0; i<3; ++i) for(int i=0; i<3; ++i)
m_icodes[i]=picode++; m_icodes[i]=picode++;
uint8_t regi = m_icodes[0]->ll()->dst.regi; uint8_t regi = m_icodes[0]->ll()->m_dst.regi;
if ((regi >= rAX) && (regi < INDEX_BX_SI)) if ((regi >= rAX) && (regi < INDEX_BX_SI))
{ {
if (m_icodes[1]->ll()->match(iSBB) && m_icodes[2]->ll()->match(iINC)) if (m_icodes[1]->ll()->match(iSBB) && m_icodes[2]->ll()->match(iINC))
if ((m_icodes[1]->ll()->dst.regi == (m_icodes[1]->ll()->src().getReg2())) && if ((m_icodes[1]->ll()->m_dst.regi == (m_icodes[1]->ll()->src().getReg2())) &&
m_icodes[1]->ll()->match((eReg)regi) && m_icodes[1]->ll()->match((eReg)regi) &&
m_icodes[2]->ll()->match((eReg)regi)) m_icodes[2]->ll()->match((eReg)regi))
return true; return true;
@ -97,7 +97,7 @@ int Idiom16::action()
{ {
AstIdent *lhs; AstIdent *lhs;
Expr *rhs; Expr *rhs;
lhs = new RegisterNode(m_icodes[0]->ll()->dst.regi, m_icodes[0]->ll()->getFlag(),&m_func->localId); lhs = new RegisterNode(m_icodes[0]->ll()->m_dst.regi, m_icodes[0]->ll()->getFlag(),&m_func->localId);
rhs = UnaryOperator::Create(NEGATION, lhs->clone()); rhs = UnaryOperator::Create(NEGATION, lhs->clone());
m_icodes[0]->setAsgn(lhs, rhs); m_icodes[0]->setAsgn(lhs, rhs);
m_icodes[1]->invalidate(); m_icodes[1]->invalidate();

View File

@ -31,9 +31,9 @@ int Idiom8::action()
AstIdent *lhs; AstIdent *lhs;
Expr *expr; Expr *expr;
eReg regH,regL; eReg regH,regL;
regH=m_icodes[0]->ll()->dst.regi; regH=m_icodes[0]->ll()->m_dst.regi;
regL=m_icodes[1]->ll()->dst.regi; regL=m_icodes[1]->ll()->m_dst.regi;
idx = m_func->localId.newLongReg (TYPE_LONG_SIGN, regH, regL, m_icodes[0]); idx = m_func->localId.newLongReg (TYPE_LONG_SIGN, LONGID_TYPE(regH,regL), m_icodes[0]);
lhs = AstIdent::LongIdx (idx); lhs = AstIdent::LongIdx (idx);
m_icodes[0]->setRegDU( regL, USE_DEF); m_icodes[0]->setRegDU( regL, USE_DEF);
@ -65,7 +65,7 @@ bool Idiom15::match(iICODE pIcode)
if (not pIcode->ll()->testFlags(I) or (pIcode->ll()->src().getImm2() != 1)) if (not pIcode->ll()->testFlags(I) or (pIcode->ll()->src().getImm2() != 1))
return false; return false;
m_icodes.clear(); m_icodes.clear();
regi = pIcode->ll()->dst.regi; regi = pIcode->ll()->m_dst.regi;
m_icodes.push_back(pIcode++); m_icodes.push_back(pIcode++);
while( (pIcode!=m_end) and while( (pIcode!=m_end) and
pIcode->ll()->match(iSHL,(eReg)regi,I) and pIcode->ll()->match(iSHL,(eReg)regi,I) and
@ -81,7 +81,7 @@ int Idiom15::action()
AstIdent *lhs; AstIdent *lhs;
Expr *rhs,*_exp; Expr *rhs,*_exp;
lhs = new RegisterNode(m_icodes[0]->ll()->dst.regi, lhs = new RegisterNode(m_icodes[0]->ll()->m_dst.regi,
m_icodes[0]->ll()->getFlag() & NO_SRC_B, m_icodes[0]->ll()->getFlag() & NO_SRC_B,
&m_func->localId); &m_func->localId);
rhs = new Constant(m_icodes.size(), 2); rhs = new Constant(m_icodes.size(), 2);
@ -122,10 +122,10 @@ int Idiom12::action()
AstIdent *lhs; AstIdent *lhs;
eReg regH,regL; eReg regH,regL;
regL=m_icodes[0]->ll()->dst.regi; regL=m_icodes[0]->ll()->m_dst.regi;
regH=m_icodes[1]->ll()->dst.regi; regH=m_icodes[1]->ll()->m_dst.regi;
idx = m_func->localId.newLongReg (TYPE_LONG_UNSIGN, regH, regL,m_icodes[0]); idx = m_func->localId.newLongReg (TYPE_LONG_UNSIGN, LONGID_TYPE(regH,regL),m_icodes[0]);
lhs = AstIdent::LongIdx (idx); lhs = AstIdent::LongIdx (idx);
m_icodes[0]->setRegDU( regH, USE_DEF); m_icodes[0]->setRegDU( regH, USE_DEF);
expr = new BinaryOperator(SHL,lhs, new Constant(1, 2)); expr = new BinaryOperator(SHL,lhs, new Constant(1, 2));
@ -161,9 +161,9 @@ int Idiom9::action()
AstIdent *lhs; AstIdent *lhs;
Expr *rhs,*expr; Expr *rhs,*expr;
eReg regH,regL; eReg regH,regL;
regL=m_icodes[1]->ll()->dst.regi; regL=m_icodes[1]->ll()->m_dst.regi;
regH=m_icodes[0]->ll()->dst.regi; regH=m_icodes[0]->ll()->m_dst.regi;
idx = m_func->localId.newLongReg (TYPE_LONG_UNSIGN,regH,regL,m_icodes[0]); idx = m_func->localId.newLongReg (TYPE_LONG_UNSIGN,LONGID_TYPE(regH,regL),m_icodes[0]);
lhs = AstIdent::LongIdx (idx); lhs = AstIdent::LongIdx (idx);
m_icodes[0]->setRegDU(regL, USE_DEF); m_icodes[0]->setRegDU(regL, USE_DEF);
expr = new BinaryOperator(SHR,lhs, new Constant(1, 2)); expr = new BinaryOperator(SHR,lhs, new Constant(1, 2));

View File

@ -26,7 +26,7 @@ bool Idiom21::match (iICODE picode)
if (not m_icodes[1]->ll()->testFlags(I)) if (not m_icodes[1]->ll()->testFlags(I))
return false; return false;
dst = &m_icodes[0]->ll()->dst; dst = &m_icodes[0]->ll()->m_dst;
src = &m_icodes[0]->ll()->src(); src = &m_icodes[0]->ll()->src();
if ((dst->regi == src->getReg2()) && (dst->getReg2() > 0) && (dst->getReg2() < INDEX_BX_SI)) if ((dst->regi == src->getReg2()) && (dst->getReg2() > 0) && (dst->getReg2() < INDEX_BX_SI))
{ {
@ -45,7 +45,7 @@ int Idiom21::action()
lhs = AstIdent::Long (&m_func->localId, DST, m_icodes[0],HIGH_FIRST, m_icodes[0], eDEF, *m_icodes[1]->ll()); lhs = AstIdent::Long (&m_func->localId, DST, m_icodes[0],HIGH_FIRST, m_icodes[0], eDEF, *m_icodes[1]->ll());
rhs = new Constant(m_icodes[1]->ll()->src().getImm2(), 4); rhs = new Constant(m_icodes[1]->ll()->src().getImm2(), 4);
m_icodes[0]->setAsgn(lhs, rhs); m_icodes[0]->setAsgn(lhs, rhs);
m_icodes[0]->du.use = 0; /* clear register used in iXOR */ m_icodes[0]->du.use.reset(); /* clear register used in iXOR */
m_icodes[1]->invalidate(); m_icodes[1]->invalidate();
return 2; return 2;
} }
@ -63,7 +63,7 @@ bool Idiom7::match(iICODE picode)
return false; return false;
const LLOperand *dst, *src; const LLOperand *dst, *src;
m_icode=picode; m_icode=picode;
dst = &picode->ll()->dst; dst = &picode->ll()->m_dst;
src = &picode->ll()->src(); src = &picode->ll()->src();
if (dst->regi == 0) /* global variable */ if (dst->regi == 0) /* global variable */
{ {
@ -87,7 +87,7 @@ int Idiom7::action()
Expr *lhs; Expr *lhs;
lhs = AstIdent::id (*m_icode->ll(), DST, m_func, m_icode, *m_icode, NONE); lhs = AstIdent::id (*m_icode->ll(), DST, m_func, m_icode, *m_icode, NONE);
m_icode->setAsgn(dynamic_cast<AstIdent *>(lhs), new Constant(0, 2)); m_icode->setAsgn(dynamic_cast<AstIdent *>(lhs), new Constant(0, 2));
m_icode->du.use = 0; /* clear register used in iXOR */ m_icode->du.use.reset(); /* clear register used in iXOR */
m_icode->ll()->setFlags(I); m_icode->ll()->setFlags(I);
return 1; return 1;
} }
@ -116,7 +116,7 @@ bool Idiom10::match(iICODE pIcode)
/* Check OR reg, reg */ /* Check OR reg, reg */
if (not m_icodes[0]->ll()->testFlags(I) && if (not m_icodes[0]->ll()->testFlags(I) &&
m_icodes[0]->ll()->src().isReg() && m_icodes[0]->ll()->src().isReg() &&
(m_icodes[0]->ll()->src().getReg2() == m_icodes[0]->ll()->dst.getReg2())) (m_icodes[0]->ll()->src().getReg2() == m_icodes[0]->ll()->m_dst.getReg2()))
if (m_icodes[1]->ll()->match(iJNE)) //.conditionalJump() if (m_icodes[1]->ll()->match(iJNE)) //.conditionalJump()
{ {
return true; return true;
@ -128,8 +128,9 @@ int Idiom10::action()
{ {
m_icodes[0]->ll()->set(iCMP,I); m_icodes[0]->ll()->set(iCMP,I);
m_icodes[0]->ll()->replaceSrc(LLOperand::CreateImm2(0)); m_icodes[0]->ll()->replaceSrc(LLOperand::CreateImm2(0));
m_icodes[0]->du.def = 0; m_icodes[0]->du.def.reset(); //TODO: this defines FLAGS
m_icodes[0]->du1.numRegsDef = 0; m_icodes[0]->du1.clearAllDefs();
//m_icodes[0]->du1.numRegsDef = 0;
return 2; return 2;
} }

View File

@ -10,10 +10,9 @@
#include "dcc.h" #include "dcc.h"
bool LONGID_TYPE::srcDstRegMatch(iICODE a, iICODE b) const bool LONGID_TYPE::srcDstRegMatch(iICODE a, iICODE b) const
{ {
return (a->ll()->src().getReg2()==l) and (b->ll()->dst.getReg2()==h); return (a->ll()->src().getReg2()==m_l) and (b->ll()->m_dst.getReg2()==m_h);
} }
ID::ID() : type(TYPE_UNKNOWN),illegal(false),loc(STK_FRAME),hasMacro(false) ID::ID() : type(TYPE_UNKNOWN),illegal(false),loc(STK_FRAME),hasMacro(false)
{ {
macro[0]=0; macro[0]=0;
@ -24,6 +23,32 @@ ID::ID(hlType t, frameType f) : type(t),illegal(false),hasMacro(false)
macro[0]=0; macro[0]=0;
memset(&id,0,sizeof(id)); memset(&id,0,sizeof(id));
loc=f; loc=f;
assert(not ((t==TYPE_LONG_SIGN)||(t==TYPE_LONG_UNSIGN)));
}
ID::ID(hlType t,const LONGID_TYPE &s) : type(t),illegal(false),hasMacro(false)
{
macro[0]=0;
memset(&id,0,sizeof(id));
loc=REG_FRAME;
m_longId = s;
assert((t==TYPE_LONG_SIGN)||(t==TYPE_LONG_UNSIGN));
}
ID::ID(hlType t,const LONG_STKID_TYPE &s) : type(t),illegal(false),hasMacro(false)
{
macro[0]=0;
memset(&id,0,sizeof(id));
loc=STK_FRAME;
id.longStkId = s;
assert((t==TYPE_LONG_SIGN)||(t==TYPE_LONG_UNSIGN));
}
ID::ID(hlType t, const LONGGLB_TYPE &s)
{
macro[0]=0;
memset(&id,0,sizeof(id));
loc=GLB_FRAME;
id.longGlb = s;
assert((t==TYPE_LONG_SIGN)||(t==TYPE_LONG_UNSIGN));
} }
@ -142,17 +167,22 @@ int LOCAL_ID::newIntIdx(int16_t seg, int16_t off, eReg regi, hlType t)
/* Checks if the entry exists in the locSym, if so, returns the idx to this /* Checks if the entry exists in the locSym, if so, returns the idx to this
* entry; otherwise creates a new register identifier node of type * entry; otherwise creates a new register identifier node of type
* TYPE_LONG_(UN)SIGN and returns the index to this new entry. */ * TYPE_LONG_(UN)SIGN and returns the index to this new entry. */
int LOCAL_ID::newLongReg(hlType t, eReg regH, eReg regL, iICODE ix_) int LOCAL_ID::newLongReg(hlType t, const LONGID_TYPE &longT, iICODE ix_)
{ {
eReg regH,regL;
regL = longT.l();
regH = longT.h();
size_t idx; size_t idx;
//iICODE ix_; //iICODE ix_;
/* Check for entry in the table */ /* Check for entry in the table */
for (idx = 0; idx < id_arr.size(); idx++) for (idx = 0; idx < id_arr.size(); idx++)
{ {
ID &entry(id_arr[idx]); ID &entry(id_arr[idx]);
if(!entry.isLong() || (entry.loc != REG_FRAME))
continue;
if (/*(locSym->id[idx].type == t) && Not checking type */ if (/*(locSym->id[idx].type == t) && Not checking type */
(entry.id.longId.h == regH) && (entry.longId().h() == regH) &&
(entry.id.longId.l == regL)) (entry.longId().l() == regL))
{ {
/* Check for occurrence in the list */ /* Check for occurrence in the list */
if (entry.idx.inList(ix_)) if (entry.idx.inList(ix_))
@ -167,12 +197,9 @@ int LOCAL_ID::newLongReg(hlType t, eReg regH, eReg regL, iICODE ix_)
} }
/* Not in the table, create new identifier */ /* Not in the table, create new identifier */
newIdent (t, REG_FRAME); id_arr.push_back(ID(t, LONGID_TYPE(regH,regL)));
id_arr[id_arr.size()-1].idx.push_back(ix_); id_arr.back().idx.push_back(ix_);
idx = id_arr.size() - 1; return (id_arr.size() - 1);
id_arr[idx].id.longId.h = regH;
id_arr[idx].id.longId.l = regL;
return (idx);
} }
/* Returns an identifier conditional expression node of type TYPE_LONG or /* Returns an identifier conditional expression node of type TYPE_LONG or
* TYPE_WORD_SIGN */ * TYPE_WORD_SIGN */
@ -199,12 +226,9 @@ int LOCAL_ID::newLongGlb(int16_t seg, int16_t offH, int16_t offL,hlType t)
} }
/* Not in the table, create new identifier */ /* Not in the table, create new identifier */
newIdent (t, GLB_FRAME); id_arr.push_back(ID(t, LONGGLB_TYPE(seg,offH,offL)));
idx = id_arr.size() - 1; return (id_arr.size() - 1);
id_arr[idx].id.longGlb.seg = seg;
id_arr[idx].id.longGlb.offH = offH;
id_arr[idx].id.longGlb.offL = offL;
return (idx);
} }
@ -246,9 +270,11 @@ int LOCAL_ID::newLongStk(hlType t, int offH, int offL)
/* Check for entry in the table */ /* Check for entry in the table */
for (idx = 0; idx < id_arr.size(); idx++) for (idx = 0; idx < id_arr.size(); idx++)
{ {
if(id_arr[idx].loc!=STK_FRAME)
continue;
if ((id_arr[idx].type == t) && if ((id_arr[idx].type == t) &&
(id_arr[idx].id.longStkId.offH == offH) && (id_arr[idx].longStkId().offH == offH) &&
(id_arr[idx].id.longStkId.offL == offL)) (id_arr[idx].longStkId().offL == offL))
return (idx); return (idx);
} }
@ -257,11 +283,8 @@ int LOCAL_ID::newLongStk(hlType t, int offH, int offL)
flagByteWordId (offL); flagByteWordId (offL);
/* Create new identifier */ /* Create new identifier */
newIdent (t, STK_FRAME); id_arr.push_back(ID(t,LONG_STKID_TYPE(offH,offL)));
idx = id_arr.size() - 1; return (id_arr.size() - 1);
id_arr[idx].id.longStkId.offH = offH;
id_arr[idx].id.longStkId.offL = offL;
return (idx);
} }
@ -289,7 +312,7 @@ int LOCAL_ID::newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix,operDu du, L
else if (pmL->regi < INDEX_BX_SI) /* register */ else if (pmL->regi < INDEX_BX_SI) /* register */
{ {
idx = newLongReg(TYPE_LONG_SIGN, pmH->regi, pmL->regi, ix); idx = newLongReg(TYPE_LONG_SIGN, LONGID_TYPE(pmH->regi, pmL->regi), ix);
if (f == HIGH_FIRST) if (f == HIGH_FIRST)
pIcode->setRegDU( pmL->regi, du); /* low part */ pIcode->setRegDU( pmL->regi, du); /* low part */
else else
@ -325,15 +348,31 @@ int LOCAL_ID::newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix,operDu du, L
* idx : idx into icode array * idx : idx into icode array
* pProc : ptr to current procedure record * pProc : ptr to current procedure record
* rhs, lhs : return expressions if successful. */ * rhs, lhs : return expressions if successful. */
boolT checkLongEq (LONG_STKID_TYPE longId, iICODE pIcode, int i, Function * pProc, Assignment &asgn, LLInst &atOffset) bool checkLongEq (LONG_STKID_TYPE longId, iICODE pIcode, int i, Function * pProc, Assignment &asgn, LLInst &atOffset)
{ {
/* pointers to LOW_LEVEL icodes */ /* pointers to LOW_LEVEL icodes */
const LLOperand *pmHdst, *pmLdst, *pmHsrc, *pmLsrc; const LLOperand *pmHdst, *pmLdst, *pmHsrc, *pmLsrc;
pmHdst = &pIcode->ll()->dst; pmHdst = &pIcode->ll()->m_dst;
pmLdst = &atOffset.dst; pmLdst = &atOffset.m_dst;
pmHsrc = &pIcode->ll()->src(); pmHsrc = &pIcode->ll()->src();
pmLsrc = &atOffset.src(); pmLsrc = &atOffset.src();
// if ((longId.offH == pmHsrc->off) && (longId.offL == pmLsrc->off))
// {
// asgn.lhs = AstIdent::LongIdx (i);
// if ( not pIcode->ll()->testFlags(NO_SRC) )
// {
// asgn.rhs = AstIdent::Long (&pProc->localId, SRC, pIcode, HIGH_FIRST, pIcode, eUSE, atOffset);
// }
// return true;
// }
// else if ((longId.offH == pmHdst->off) && (longId.offL == pmLdst->off))
// {
// asgn.lhs = AstIdent::Long (&pProc->localId, DST, pIcode, HIGH_FIRST, pIcode,eDEF, atOffset);
// asgn.rhs = AstIdent::LongIdx (i);
// return true;
// }
if ((longId.offH == pmHdst->off) && (longId.offL == pmLdst->off)) if ((longId.offH == pmHdst->off) && (longId.offL == pmLdst->off))
{ {
@ -364,18 +403,18 @@ boolT checkLongEq (LONG_STKID_TYPE longId, iICODE pIcode, int i, Function * pPro
* idx : idx into icode array * idx : idx into icode array
* pProc : ptr to current procedure record * pProc : ptr to current procedure record
* rhs, lhs : return expressions if successful. */ * rhs, lhs : return expressions if successful. */
boolT checkLongRegEq (LONGID_TYPE longId, iICODE pIcode, int i, bool checkLongRegEq (LONGID_TYPE longId, iICODE pIcode, int i,
Function * pProc, Assignment &asgn, LLInst &atOffset) Function * pProc, Assignment &asgn, LLInst &atOffset)
{ {
/* pointers to LOW_LEVEL icodes */ /* pointers to LOW_LEVEL icodes */
const LLOperand *pmHdst, *pmLdst, *pmHsrc, *pmLsrc; const LLOperand *pmHdst, *pmLdst, *pmHsrc, *pmLsrc;
pmHdst = &pIcode->ll()->dst; pmHdst = &pIcode->ll()->m_dst;
pmLdst = &atOffset.dst; pmLdst = &atOffset.m_dst;
pmHsrc = &pIcode->ll()->src(); pmHsrc = &pIcode->ll()->src();
pmLsrc = &atOffset.src(); pmLsrc = &atOffset.src();
if ((longId.h == pmHdst->regi) && (longId.l == pmLdst->regi)) if ((longId.h() == pmHdst->regi) && (longId.l() == pmLdst->regi))
{ {
asgn.lhs = AstIdent::LongIdx (i); asgn.lhs = AstIdent::LongIdx (i);
if ( not pIcode->ll()->testFlags(NO_SRC) ) if ( not pIcode->ll()->testFlags(NO_SRC) )
@ -384,7 +423,7 @@ boolT checkLongRegEq (LONGID_TYPE longId, iICODE pIcode, int i,
} }
return true; return true;
} }
else if ((longId.h == pmHsrc->regi) && (longId.l == pmLsrc->regi)) else if ((longId.h() == pmHsrc->regi) && (longId.l() == pmLsrc->regi))
{ {
asgn.lhs = AstIdent::Long (&pProc->localId, DST, pIcode, HIGH_FIRST, pIcode, eDEF, atOffset); asgn.lhs = AstIdent::Long (&pProc->localId, DST, pIcode, HIGH_FIRST, pIcode, eDEF, atOffset);
asgn.rhs = AstIdent::LongIdx (i); asgn.rhs = AstIdent::LongIdx (i);
@ -406,10 +445,10 @@ eReg otherLongRegi (eReg regi, int idx, LOCAL_ID *locTbl)
if ((id->loc == REG_FRAME) && ((id->type == TYPE_LONG_SIGN) || if ((id->loc == REG_FRAME) && ((id->type == TYPE_LONG_SIGN) ||
(id->type == TYPE_LONG_UNSIGN))) (id->type == TYPE_LONG_UNSIGN)))
{ {
if (id->id.longId.h == regi) if (id->longId().h() == regi)
return (id->id.longId.l); return (id->longId().l());
else if (id->id.longId.l == regi) else if (id->longId().l() == regi)
return (id->id.longId.h); return (id->longId().h());
} }
return rUNDEF; // Cristina: please check this! return rUNDEF; // Cristina: please check this!
} }

View File

@ -1,5 +1,6 @@
#include <cassert> #include <cassert>
#include "machine_x86.h" #include "machine_x86.h"
#include "icode.h"
// Index registers **** temp solution // Index registers **** temp solution
static const std::string regNames[] = { static const std::string regNames[] = {
"undef", "undef",
@ -8,7 +9,7 @@ static const std::string regNames[] = {
"es", "cs", "ss", "ds", "es", "cs", "ss", "ds",
"al", "cl", "dl", "bl", "al", "cl", "dl", "bl",
"ah", "ch", "dh", "bh", "ah", "ch", "dh", "bh",
"tmp", "tmp","tmp2",
"bx+si", "bx+di", "bp+si", "bp+di", "bx+si", "bx+di", "bp+si", "bp+di",
"si", "di", "bp", "bx" "si", "di", "bp", "bx"
}; };
@ -132,3 +133,12 @@ eReg Machine_X86::compositeParent(eReg reg)
} }
return rUNDEF; return rUNDEF;
} }
void Machine_X86::writeRegVector (std::ostream &ostr,const LivenessSet &regi)
{
int j;
for (j = rAX; j < INDEX_BX_SI; j++)
{
if (regi.testReg(j))
ostr << regName(eReg(j))<<" ";
}
}

View File

@ -146,8 +146,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
eIcode = ICODE(); eIcode = ICODE();
eIcode.type = LOW_LEVEL; eIcode.type = LOW_LEVEL;
eIcode.ll()->set(iMOV,0); eIcode.ll()->set(iMOV,0,rTMP);
eIcode.ll()->replaceDst(rTMP);
if (ll->testFlags(B) ) if (ll->testFlags(B) )
{ {
eIcode.ll()->setFlags( B ); eIcode.ll()->setFlags( B );
@ -171,10 +170,9 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
/* iMOD */ /* iMOD */
eIcode = ICODE(); eIcode = ICODE();
eIcode.type = LOW_LEVEL; eIcode.type = LOW_LEVEL;
eIcode.ll()->set(iMOD,0); eIcode.ll()->set(iMOD,ll->getFlag() | SYNTHETIC | IM_TMP_DST);
eIcode.ll()->replaceSrc(_Icode.ll()->src()); eIcode.ll()->replaceSrc(_Icode.ll()->src());
eIcode.du = _Icode.du; eIcode.du = _Icode.du;
eIcode.ll()->setFlags( ( ll->getFlag() | SYNTHETIC | IM_TMP_DST) );
eIcode.ll()->label = SynthLab++; eIcode.ll()->label = SynthLab++;
pIcode = Icode.addIcode(&eIcode); pIcode = Icode.addIcode(&eIcode);
} }
@ -183,9 +181,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
/* MOV rTMP, regDst */ /* MOV rTMP, regDst */
eIcode = ICODE(); eIcode = ICODE();
eIcode.type = LOW_LEVEL; eIcode.type = LOW_LEVEL;
eIcode.ll()->set(iMOV,SYNTHETIC); eIcode.ll()->set(iMOV,SYNTHETIC,rTMP,_Icode.ll()->m_dst);
eIcode.ll()->replaceDst(LLOperand::CreateReg2(rTMP));
eIcode.ll()->replaceSrc(_Icode.ll()->dst);
eIcode.setRegDU( rTMP, eDEF); eIcode.setRegDU( rTMP, eDEF);
if(eIcode.ll()->src().getReg2()) if(eIcode.ll()->src().getReg2())
{ {
@ -207,11 +203,11 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
eIcode.type = LOW_LEVEL; eIcode.type = LOW_LEVEL;
eIcode.ll()->set(iMOV,SYNTHETIC); eIcode.ll()->set(iMOV,SYNTHETIC);
eIcode.ll()->replaceDst(ll->src()); eIcode.ll()->replaceDst(ll->src());
if(eIcode.ll()->dst.regi) if(eIcode.ll()->m_dst.regi)
{ {
if((eIcode.ll()->dst.regi>=rAL) && (eIcode.ll()->dst.regi<=rBH)) if((eIcode.ll()->m_dst.regi>=rAL) && (eIcode.ll()->m_dst.regi<=rBH))
eIcode.ll()->setFlags( B ); eIcode.ll()->setFlags( B );
eIcode.setRegDU( eIcode.ll()->dst.regi, eDEF); eIcode.setRegDU( eIcode.ll()->m_dst.regi, eDEF);
} }
eIcode.ll()->replaceSrc(rTMP); eIcode.ll()->replaceSrc(rTMP);
eIcode.setRegDU( rTMP, eUSE); eIcode.setRegDU( rTMP, eUSE);
@ -246,7 +242,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
if (ll->match(iJA) || ll->match(iJBE) ) if (ll->match(iJA) || ll->match(iJBE) )
pstate->JCond.immed++; pstate->JCond.immed++;
if (ll->getOpcode() == iJAE || ll->getOpcode() == iJA) if (ll->getOpcode() == iJAE || ll->getOpcode() == iJA)
pstate->JCond.regi = prev.ll()->dst.regi; pstate->JCond.regi = prev.ll()->m_dst.regi;
fBranch = (bool) fBranch = (bool)
(ll->getOpcode() == iJB || ll->getOpcode() == iJBE); (ll->getOpcode() == iJB || ll->getOpcode() == iJBE);
} }
@ -258,7 +254,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
if (fBranch) /* Do branching code */ if (fBranch) /* Do branching code */
{ {
pstate->JCond.regi = prev.ll()->dst.regi; pstate->JCond.regi = prev.ll()->m_dst.regi;
} }
/* Next icode. Note: not the same as GetLastIcode() because of the call /* Next icode. Note: not the same as GetLastIcode() because of the call
to FollowCtrl() */ to FollowCtrl() */
@ -297,7 +293,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
int size; int size;
/* Save function number */ /* Save function number */
Icode.back().ll()->dst.off = (int16_t)funcNum; Icode.back().ll()->m_dst.off = (int16_t)funcNum;
//Icode.GetIcode(Icode.GetNumIcodes() - 1)-> //Icode.GetIcode(Icode.GetNumIcodes() - 1)->
/* Program termination: int21h, fn 00h, 31h, 4Ch */ /* Program termination: int21h, fn 00h, 31h, 4Ch */
@ -318,7 +314,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
} }
else if ((ll->src().getImm2() == 0x2F) && (pstate->f[rAH])) else if ((ll->src().getImm2() == 0x2F) && (pstate->f[rAH]))
{ {
Icode.back().ll()->dst.off = pstate->r[rAH]; Icode.back().ll()->m_dst.off = pstate->r[rAH];
} }
else /* Program termination: int20h, int27h */ else /* Program termination: int20h, int27h */
done = (boolT)(ll->src().getImm2() == 0x20 || done = (boolT)(ll->src().getImm2() == 0x20 ||
@ -337,7 +333,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
break; **** HERE ***/ break; **** HERE ***/
case iSHL: case iSHL:
if (pstate->JCond.regi == ll->dst.regi) if (pstate->JCond.regi == ll->m_dst.regi)
{ {
if ((ll->testFlags(I)) && ll->src().getImm2() == 1) if ((ll->testFlags(I)) && ll->src().getImm2() == 1)
pstate->JCond.immed *= 2; pstate->JCond.immed *= 2;
@ -348,7 +344,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
case iLEA: case iLEA:
if (ll->src().getReg2()== rUNDEF) /* direct mem offset */ if (ll->src().getReg2()== rUNDEF) /* direct mem offset */
pstate->setState( ll->dst.getReg2(), ll->src().off); pstate->setState( ll->m_dst.getReg2(), ll->src().off);
break; break;
case iLDS: case iLES: case iLDS: case iLES:
@ -358,7 +354,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
offset = LH(&prog.image()[psym->label]); offset = LH(&prog.image()[psym->label]);
pstate->setState( (ll->getOpcode() == iLDS)? rDS: rES, pstate->setState( (ll->getOpcode() == iLDS)? rDS: rES,
LH(&prog.image()[psym->label + 2])); LH(&prog.image()[psym->label + 2]));
pstate->setState( ll->dst.regi, (int16_t)offset); pstate->setState( ll->m_dst.regi, (int16_t)offset);
psym->type = TYPE_PTR; psym->type = TYPE_PTR;
} }
break; break;
@ -564,7 +560,7 @@ boolT Function::process_CALL (ICODE & pIcode, CALL_GRAPH * pcallGraph, STATE *ps
{ {
/* Not immediate, i.e. indirect call */ /* Not immediate, i.e. indirect call */
if (pIcode.ll()->dst.regi && (!option.Calls)) if (pIcode.ll()->m_dst.regi && (!option.Calls))
{ {
/* We have not set the brave option to attempt to follow /* We have not set the brave option to attempt to follow
the execution path through register indirect calls. the execution path through register indirect calls.
@ -579,25 +575,25 @@ boolT Function::process_CALL (ICODE & pIcode, CALL_GRAPH * pcallGraph, STATE *ps
es:0 where es:0 is the start of the image. This is es:0 where es:0 is the start of the image. This is
usually wrong! Consider also CALL [BP+0E] in which the usually wrong! Consider also CALL [BP+0E] in which the
segment for the pointer is in SS! - Mike */ segment for the pointer is in SS! - Mike */
if(pIcode.ll()->dst.isReg()) if(pIcode.ll()->m_dst.isReg())
{ {
if( not pstate->isKnown(pIcode.ll()->dst.regi) if( not pstate->isKnown(pIcode.ll()->m_dst.regi)
or or
not pstate->isKnown(pIcode.ll()->dst.seg) not pstate->isKnown(pIcode.ll()->m_dst.seg)
) )
{ {
fprintf(stderr,"Indirect call with unkown register values\n"); fprintf(stderr,"Indirect call with unknown register values\n");
return false; return false;
} }
off = pstate->r[pIcode.ll()->dst.seg]; off = pstate->r[pIcode.ll()->m_dst.seg];
off <<=4; off <<=4;
off += pstate->r[pIcode.ll()->dst.regi]; off += pstate->r[pIcode.ll()->m_dst.regi];
} }
else else
{ {
off = (uint32_t)(uint16_t)pIcode.ll()->dst.off + off = (uint32_t)(uint16_t)pIcode.ll()->m_dst.off +
((uint32_t)(uint16_t)pIcode.ll()->dst.segValue << 4); ((uint32_t)(uint16_t)pIcode.ll()->m_dst.segValue << 4);
} }
/* Address of function is given by 4 (CALLF) or 2 (CALL) bytes at /* Address of function is given by 4 (CALLF) or 2 (CALL) bytes at
@ -684,7 +680,7 @@ static void process_MOV(LLInst & ll, STATE * pstate)
{ {
PROG &prog(Project::get()->prog); PROG &prog(Project::get()->prog);
SYM * psym, *psym2; /* Pointer to symbol in global symbol table */ SYM * psym, *psym2; /* Pointer to symbol in global symbol table */
uint8_t dstReg = ll.dst.regi; uint8_t dstReg = ll.m_dst.regi;
uint8_t srcReg = ll.src().regi; uint8_t srcReg = ll.src().regi;
if (dstReg > 0 && dstReg < INDEX_BX_SI) if (dstReg > 0 && dstReg < INDEX_BX_SI)
{ {
@ -709,7 +705,7 @@ static void process_MOV(LLInst & ll, STATE * pstate)
int size=2; int size=2;
if((ll.src().regi>=rAL)&&(ll.src().regi<=rBH)) if((ll.src().regi>=rAL)&&(ll.src().regi<=rBH))
size=1; size=1;
psym = lookupAddr (&ll.dst, pstate, size, eDEF); psym = lookupAddr (&ll.m_dst, pstate, size, eDEF);
if (psym && ! (psym->duVal.val)) /* no initial value yet */ if (psym && ! (psym->duVal.val)) /* no initial value yet */
{ {
if (ll.testFlags(I)) /* immediate */ if (ll.testFlags(I)) /* immediate */
@ -898,19 +894,6 @@ static void setBits(int16_t type, uint32_t start, uint32_t len)
} }
} }
/* DU bit definitions for each reg value - including index registers */
LivenessSet duReg[] = { 0x00,
//AH AL . . AX, BH
0x11001, 0x22002, 0x44004, 0x88008, /* uint16_t regs */
0x10, 0x20, 0x40, 0x80,
0x100, 0x200, 0x400, 0x800, /* seg regs */
0x1000, 0x2000, 0x4000, 0x8000, /* uint8_t regs */
0x10000, 0x20000, 0x40000, 0x80000,
0x100000, /* tmp reg */
0x48, 0x88, 0x60, 0xA0, /* index regs */
0x40, 0x80, 0x20, 0x08 };
/* Checks which registers were used and updates the du.u flag. /* Checks which registers were used and updates the du.u flag.
* Places local variables on the local symbol table. * Places local variables on the local symbol table.
* Arguments: d : SRC or DST icode operand * Arguments: d : SRC or DST icode operand
@ -945,7 +928,7 @@ static void use (opLoc d, ICODE & pIcode, Function * pProc, STATE * pstate, int
if (pm->off > 0) /* global indexed variable */ if (pm->off > 0) /* global indexed variable */
pProc->localId.newIntIdx(pm->segValue, pm->off, rBX,TYPE_WORD_SIGN); pProc->localId.newIntIdx(pm->segValue, pm->off, rBX,TYPE_WORD_SIGN);
} }
pIcode.du.use |= duReg[pm->regi]; pIcode.du.use.addReg(pm->regi);
} }
else else
@ -963,7 +946,7 @@ static void use (opLoc d, ICODE & pIcode, Function * pProc, STATE * pstate, int
/* Use of register */ /* Use of register */
else if ((d == DST) || ((d == SRC) && (not pIcode.ll()->testFlags(I)))) else if ((d == DST) || ((d == SRC) && (not pIcode.ll()->testFlags(I))))
pIcode.du.use |= duReg[pm->regi]; pIcode.du.use.addReg(pm->regi);
} }
@ -1007,14 +990,15 @@ static void def (opLoc d, ICODE & pIcode, Function * pProc, STATE * pstate, int
if (pm->off > 0) /* global var */ if (pm->off > 0) /* global var */
pProc->localId.newIntIdx(pm->segValue, pm->off, rBX,TYPE_WORD_SIGN); pProc->localId.newIntIdx(pm->segValue, pm->off, rBX,TYPE_WORD_SIGN);
} }
pIcode.du.use |= duReg[pm->regi]; pIcode.du.use.addReg(pm->regi);
} }
} }
/* Definition of register */ /* Definition of register */
else if ((d == DST) || ((d == SRC) && (not pIcode.ll()->testFlags(I)))) else if ((d == DST) || ((d == SRC) && (not pIcode.ll()->testFlags(I))))
{ {
pIcode.du.def |= duReg[pm->regi]; assert(not pIcode.ll()->match(iPUSH));
pIcode.du1.numRegsDef++; pIcode.du1.addDef(pm->regi);
pIcode.du.def.addReg(pm->regi);
} }
} }
@ -1030,8 +1014,9 @@ static void use_def(opLoc d, ICODE & pIcode, Function * pProc, STATE * pstate, i
if (pm->regi < INDEX_BX_SI) /* register */ if (pm->regi < INDEX_BX_SI) /* register */
{ {
pIcode.du.def |= duReg[pm->regi]; assert(not pIcode.ll()->match(iPUSH));
pIcode.du1.numRegsDef++; pIcode.du1.addDef(pm->regi);
pIcode.du.def.addReg(pm->regi);
} }
} }
@ -1090,12 +1075,12 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate)
if (cb == 1) if (cb == 1)
{ {
pIcode.du.def.addReg(rAX); pIcode.du.def.addReg(rAX);
pIcode.du1.numRegsDef++; pIcode.du1.addDef(rAX);
} }
else else
{ {
pIcode.du.def.addReg(rAX).addReg(rDX); pIcode.du.def.addReg(rAX).addReg(rDX);
pIcode.du1.numRegsDef += 2; pIcode.du1.addDef(rAX).addDef(rDX);
} }
} }
else else
@ -1107,13 +1092,13 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate)
if (cb == 1) /* uint8_t */ if (cb == 1) /* uint8_t */
{ {
pIcode.du.def.addReg(rAX); pIcode.du.def.addReg(rAX);
pIcode.du1.numRegsDef++; pIcode.du1.addDef(rAX);
pIcode.du.use.addReg(rAL); pIcode.du.use.addReg(rAL);
} }
else /* uint16_t */ else /* uint16_t */
{ {
pIcode.du.def.addReg(rDX).addReg(rAX); pIcode.du.def.addReg(rDX).addReg(rAX);
pIcode.du1.numRegsDef += 2; pIcode.du1.addDef(rAX).addDef(rDX);
pIcode.du.use.addReg(rAX); pIcode.du.use.addReg(rAX);
} }
break; break;
@ -1134,9 +1119,13 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate)
break; break;
case iLDS: case iLES: case iLDS: case iLES:
pIcode.du.def.addReg(((pIcode.ll()->getOpcode() == iLDS) ? rDS : rES)); {
pIcode.du1.numRegsDef++; eReg r=((pIcode.ll()->getOpcode() == iLDS) ? rDS : rES);
pIcode.du.def.addReg(r);
pIcode.du1.addDef(r);
cb = 4; cb = 4;
// fallthrough
}
case iMOV: case iMOV:
use(SRC, pIcode, this, pstate, cb); use(SRC, pIcode, this, pstate, cb);
def(DST, pIcode, this, pstate, cb); def(DST, pIcode, this, pstate, cb);
@ -1161,27 +1150,27 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate)
case iLOOP: case iLOOPE: case iLOOPNE: case iLOOP: case iLOOPE: case iLOOPNE:
pIcode.du.def.addReg(rCX); pIcode.du.def.addReg(rCX);
pIcode.du1.numRegsDef++; pIcode.du1.addDef(rCX);
case iJCXZ: case iJCXZ:
pIcode.du.use.addReg(rCX); pIcode.du.use.addReg(rCX);
break; break;
case iREPNE_CMPS: case iREPE_CMPS: case iREP_MOVS: case iREPNE_CMPS: case iREPE_CMPS: case iREP_MOVS:
pIcode.du.addDefinedAndUsed(rCX); pIcode.du.addDefinedAndUsed(rCX);
pIcode.du1.numRegsDef++; pIcode.du1.addDef(rCX);
case iCMPS: case iMOVS: case iCMPS: case iMOVS:
pIcode.du.addDefinedAndUsed(rSI); pIcode.du.addDefinedAndUsed(rSI);
pIcode.du.addDefinedAndUsed(rDI); pIcode.du.addDefinedAndUsed(rDI);
pIcode.du1.numRegsDef += 2; pIcode.du1.addDef(rSI).addDef(rDI);
pIcode.du.use.addReg(rES).addReg(sseg); pIcode.du.use.addReg(rES).addReg(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.addDefinedAndUsed(rCX); pIcode.du.addDefinedAndUsed(rCX);
pIcode.du1.numRegsDef++; pIcode.du1.addDef(rCX);
case iSCAS: case iSTOS: case iINS: case iSCAS: case iSTOS: case iINS:
pIcode.du.def.addReg(rDI); pIcode.du.def.addReg(rDI);
pIcode.du1.numRegsDef++; pIcode.du1.addDef(rDI);
if (pIcode.ll()->getOpcode() == iREP_INS || pIcode.ll()->getOpcode()== iINS) if (pIcode.ll()->getOpcode() == iREP_INS || pIcode.ll()->getOpcode()== iINS)
{ {
pIcode.du.use.addReg(rDI).addReg(rES).addReg(rDX); pIcode.du.use.addReg(rDI).addReg(rES).addReg(rDX);
@ -1194,28 +1183,31 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate)
case iREP_LODS: case iREP_LODS:
pIcode.du.addDefinedAndUsed(rCX); pIcode.du.addDefinedAndUsed(rCX);
pIcode.du1.numRegsDef++; pIcode.du1.addDef(rCX);
case iLODS: case iLODS:
{
eReg r = (cb==2)? rAX: rAL;
pIcode.du.addDefinedAndUsed(rSI); pIcode.du.addDefinedAndUsed(rSI);
pIcode.du.def.addReg((cb==2)? rAX: rAL); pIcode.du1.addDef(rSI);
pIcode.du1.numRegsDef += 2; pIcode.du.def.addReg(r);
pIcode.du1.addDef(r);
pIcode.du.use.addReg(sseg); pIcode.du.use.addReg(sseg);
}
break; break;
case iREP_OUTS: case iREP_OUTS:
pIcode.du.addDefinedAndUsed(rCX); pIcode.du.addDefinedAndUsed(rCX);
pIcode.du1.numRegsDef++; pIcode.du1.addDef(rCX);
case iOUTS: case iOUTS:
pIcode.du.addDefinedAndUsed(rSI); pIcode.du.addDefinedAndUsed(rSI);
pIcode.du1.numRegsDef++; pIcode.du1.addDef(rSI);
pIcode.du.use |= duReg[rDX] | duReg[sseg]; pIcode.du.use.addReg(rDX).addReg(sseg);
break; break;
case iIN: case iOUT: case iIN: case iOUT:
def(DST, pIcode, this, pstate, cb); def(DST, pIcode, this, pstate, cb);
if (! Imm) if (! Imm)
{ {
pIcode.du.use |= duReg[rDX]; pIcode.du.use.addReg(rDX);
} }
break; break;
} }

View File

@ -97,7 +97,8 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
bool regExist=false; bool regExist=false;
condId type; condId type;
Function * tproc; Function * tproc;
eReg regL, regH; /* Registers involved in arguments */ eReg regL = rUNDEF;
eReg regH; /* Registers involved in arguments */
/* Flag ticode as having register arguments */ /* Flag ticode as having register arguments */
tproc = ticode->hl()->call.proc; tproc = ticode->hl()->call.proc;
@ -113,6 +114,7 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
if (lhs_reg) if (lhs_reg)
{ {
regL = id_arr[lhs_reg->regiIdx].id.regi; regL = id_arr[lhs_reg->regiIdx].id.regi;
assert(regL!=rUNDEF);
if (regL < rAL) if (regL < rAL)
tidx = tproc->localId.newByteWordReg(TYPE_WORD_SIGN, regL); tidx = tproc->localId.newByteWordReg(TYPE_WORD_SIGN, regL);
else else
@ -133,9 +135,10 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
else if (type == LONG_VAR) else if (type == LONG_VAR)
{ {
int longIdx = lhs->ident.idNode.longIdx; int longIdx = lhs->ident.idNode.longIdx;
regL = id_arr[longIdx].id.longId.l; LONGID_TYPE regHL = id_arr[longIdx].longId();
regH = id_arr[longIdx].id.longId.h; regH=regHL.h();
tidx = tproc->localId.newLongReg(TYPE_LONG_SIGN, regH, regL, tproc->Icode.begin() /*0*/); regL=regHL.l();
tidx = tproc->localId.newLongReg(TYPE_LONG_SIGN, regHL, tproc->Icode.begin() /*0*/);
/* Check if register argument already on the formal argument list */ /* Check if register argument already on the formal argument list */
for(STKSYM &tgt_sym : *target_stackframe) for(STKSYM &tgt_sym : *target_stackframe)
{ {
@ -175,6 +178,7 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
{ {
newsym.regs = AstIdent::LongIdx (tidx); newsym.regs = AstIdent::LongIdx (tidx);
newsym.type = TYPE_LONG_SIGN; newsym.type = TYPE_LONG_SIGN;
assert(regL!=rUNDEF);
tproc->localId.id_arr[tidx].name = newsym.name; tproc->localId.id_arr[tidx].name = newsym.name;
tproc->localId.propLongId (regL, regH, tproc->localId.id_arr[tidx].name.c_str()); tproc->localId.propLongId (regL, regH, tproc->localId.id_arr[tidx].name.c_str());
} }
@ -191,7 +195,7 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
switch (type) { switch (type) {
case REGISTER: case REGISTER:
id = &id_arr[lhs_reg->regiIdx]; id = &id_arr[lhs_reg->regiIdx];
picode->du.def &= maskDuReg[id->id.regi]; picode->du.def.clrReg(id->id.regi);
if (id->id.regi < rAL) if (id->id.regi < rAL)
newsym.type = TYPE_WORD_SIGN; newsym.type = TYPE_WORD_SIGN;
else else
@ -199,8 +203,8 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
break; break;
case LONG_VAR: case LONG_VAR:
id = &id_arr[lhs->ident.idNode.longIdx]; id = &id_arr[lhs->ident.idNode.longIdx];
picode->du.def &= maskDuReg[id->id.longId.h]; picode->du.def.clrReg(id->longId().h());
picode->du.def &= maskDuReg[id->id.longId.l]; picode->du.def.clrReg(id->longId().l());
newsym.type = TYPE_LONG_SIGN; newsym.type = TYPE_LONG_SIGN;
break; break;
default: default:

View File

@ -250,7 +250,7 @@ void Function::propLongStk (int i, const ID &pLocId)
continue; continue;
if (pIcode->ll()->getOpcode() == next1->ll()->getOpcode()) if (pIcode->ll()->getOpcode() == next1->ll()->getOpcode())
{ {
if (checkLongEq (pLocId.id.longStkId, pIcode, i, this, asgn, *next1->ll()) == true) if (checkLongEq (pLocId.longStkId(), pIcode, i, this, asgn, *next1->ll()) == true)
{ {
switch (pIcode->ll()->getOpcode()) switch (pIcode->ll()->getOpcode())
{ {
@ -290,7 +290,7 @@ void Function::propLongStk (int i, const ID &pLocId)
/* Check long conditional (i.e. 2 CMPs and 3 branches */ /* Check long conditional (i.e. 2 CMPs and 3 branches */
else if ((pIcode->ll()->getOpcode() == iCMP) && (isLong23 (pIcode->getParent(), l23, &arc))) else if ((pIcode->ll()->getOpcode() == iCMP) && (isLong23 (pIcode->getParent(), l23, &arc)))
{ {
if ( checkLongEq (pLocId.id.longStkId, pIcode, i, this, asgn, *l23->ll()) ) if ( checkLongEq (pLocId.longStkId(), pIcode, i, this, asgn, *l23->ll()) )
{ {
advance(pIcode,longJCond23 (asgn, pIcode, arc, l23)); advance(pIcode,longJCond23 (asgn, pIcode, arc, l23));
} }
@ -300,7 +300,7 @@ void Function::propLongStk (int i, const ID &pLocId)
* 2 CMPs and 2 branches */ * 2 CMPs and 2 branches */
else if ((pIcode->ll()->getOpcode() == iCMP) && isLong22 (pIcode, pEnd, l23)) else if ((pIcode->ll()->getOpcode() == iCMP) && isLong22 (pIcode, pEnd, l23))
{ {
if ( checkLongEq (pLocId.id.longStkId, pIcode, i, this,asgn, *l23->ll()) ) if ( checkLongEq (pLocId.longStkId(), pIcode, i, this,asgn, *l23->ll()) )
{ {
advance(pIcode,longJCond22 (asgn, pIcode,pEnd)); advance(pIcode,longJCond22 (asgn, pIcode,pEnd));
} }
@ -329,9 +329,9 @@ int Function::findBackwarLongDefs(int loc_ident_idx, const ID &pLocId, iICODE be
switch (icode.ll()->getOpcode()) switch (icode.ll()->getOpcode())
{ {
case iMOV: case iMOV:
pmH = &icode.ll()->dst; pmH = &icode.ll()->m_dst;
pmL = &next1->ll()->dst; pmL = &next1->ll()->m_dst;
if ((pLocId.id.longId.h == pmH->regi) && (pLocId.id.longId.l == pmL->regi)) if ((pLocId.longId().h() == pmH->regi) && (pLocId.longId().l() == pmL->regi))
{ {
localId.id_arr[loc_ident_idx].idx.push_back(pIcode);//idx-1//insert localId.id_arr[loc_ident_idx].idx.push_back(pIcode);//idx-1//insert
icode.setRegDU( pmL->regi, eDEF); icode.setRegDU( pmL->regi, eDEF);
@ -344,9 +344,9 @@ int Function::findBackwarLongDefs(int loc_ident_idx, const ID &pLocId, iICODE be
break; break;
case iPOP: case iPOP:
pmH = &next1->ll()->dst; pmH = &next1->ll()->m_dst;
pmL = &icode.ll()->dst; pmL = &icode.ll()->m_dst;
if ((pLocId.id.longId.h == pmH->regi) && (pLocId.id.longId.l == pmL->regi)) if ((pLocId.longId().h() == pmH->regi) && (pLocId.longId().l() == pmL->regi))
{ {
asgn.lhs = AstIdent::LongIdx (loc_ident_idx); asgn.lhs = AstIdent::LongIdx (loc_ident_idx);
icode.setRegDU( pmH->regi, eDEF); icode.setRegDU( pmH->regi, eDEF);
@ -360,9 +360,9 @@ int Function::findBackwarLongDefs(int loc_ident_idx, const ID &pLocId, iICODE be
// /**** others missing ***/ // /**** others missing ***/
case iAND: case iOR: case iXOR: case iAND: case iOR: case iXOR:
pmL = &icode.ll()->dst; pmL = &icode.ll()->m_dst;
pmH = &next1->ll()->dst; pmH = &next1->ll()->m_dst;
if ((pLocId.id.longId.h == pmH->regi) && (pLocId.id.longId.l == pmL->regi)) if ((pLocId.longId().h() == pmH->regi) && (pLocId.longId().l() == pmL->regi))
{ {
asgn.lhs = AstIdent::LongIdx (loc_ident_idx); asgn.lhs = AstIdent::LongIdx (loc_ident_idx);
asgn.rhs = AstIdent::Long (&this->localId, SRC, pIcode, LOW_FIRST, pIcode, eUSE, *next1->ll()); asgn.rhs = AstIdent::Long (&this->localId, SRC, pIcode, LOW_FIRST, pIcode, eUSE, *next1->ll());
@ -407,12 +407,12 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be
{ {
case iMOV: case iMOV:
{ {
const LONGID_TYPE &ref_long(pLocId.id.longId); const LONGID_TYPE &ref_long(pLocId.longId());
const LLOperand &src_op1(pIcode->ll()->src()); const LLOperand &src_op1(pIcode->ll()->src());
const LLOperand &src_op2(next1->ll()->src()); const LLOperand &src_op2(next1->ll()->src());
eReg srcReg1=src_op1.getReg2(); eReg srcReg1=src_op1.getReg2();
eReg nextReg2=src_op2.getReg2(); eReg nextReg2=src_op2.getReg2();
if ((ref_long.h == srcReg1) && (ref_long.l == nextReg2)) if ((ref_long.h() == srcReg1) && (ref_long.l() == nextReg2))
{ {
pIcode->setRegDU( nextReg2, eUSE); pIcode->setRegDU( nextReg2, eUSE);
@ -428,11 +428,10 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be
case iPUSH: case iPUSH:
{ {
const LONGID_TYPE &ref_long(pLocId.id.longId); const LONGID_TYPE &ref_long(pLocId.longId());
const LLOperand &src_op1(pIcode->ll()->src()); const LLOperand &src_op1(pIcode->ll()->src());
const LLOperand &src_op2(next1->ll()->src()); const LLOperand &src_op2(next1->ll()->src());
if ((ref_long.h == src_op1.getReg2()) && if ((ref_long.h() == src_op1.getReg2()) && (ref_long.l() == src_op2.getReg2()))
(ref_long.l == src_op2.getReg2()))
{ {
asgn.rhs = AstIdent::LongIdx (loc_ident_idx); asgn.rhs = AstIdent::LongIdx (loc_ident_idx);
pIcode->setRegDU( next1->ll()->src().getReg2(), eUSE); pIcode->setRegDU( next1->ll()->src().getReg2(), eUSE);
@ -446,10 +445,9 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be
/*** others missing ****/ /*** others missing ****/
case iAND: case iOR: case iXOR: case iAND: case iOR: case iXOR:
pmL = &pIcode->ll()->dst; pmL = &pIcode->ll()->m_dst;
pmH = &next1->ll()->dst; pmH = &next1->ll()->m_dst;
if ((pLocId.id.longId.h == pmH->regi) && if ((pLocId.longId().h() == pmH->regi) && (pLocId.longId().l() == pmL->regi))
(pLocId.id.longId.l == pmL->regi))
{ {
asgn.lhs = AstIdent::LongIdx (loc_ident_idx); asgn.lhs = AstIdent::LongIdx (loc_ident_idx);
pIcode->setRegDU( pmH->regi, USE_DEF); pIcode->setRegDU( pmH->regi, USE_DEF);
@ -478,7 +476,7 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be
/* Check long conditional (i.e. 2 CMPs and 3 branches */ /* Check long conditional (i.e. 2 CMPs and 3 branches */
else if ((pIcode->ll()->getOpcode() == iCMP) && (isLong23 (pIcode->getParent(), long_loc, &arc))) else if ((pIcode->ll()->getOpcode() == iCMP) && (isLong23 (pIcode->getParent(), long_loc, &arc)))
{ {
if (checkLongRegEq (pLocId.id.longId, pIcode, loc_ident_idx, this, asgn, *long_loc->ll())) if (checkLongRegEq (pLocId.longId(), pIcode, loc_ident_idx, this, asgn, *long_loc->ll()))
{ {
// reduce the advance by 1 here (loop increases) ? // reduce the advance by 1 here (loop increases) ?
advance(pIcode,longJCond23 (asgn, pIcode, arc, long_loc)); advance(pIcode,longJCond23 (asgn, pIcode, arc, long_loc));
@ -489,7 +487,7 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be
* 2 CMPs and 2 branches */ * 2 CMPs and 2 branches */
else if (pIcode->ll()->match(iCMP) && (isLong22 (pIcode, pEnd, long_loc))) else if (pIcode->ll()->match(iCMP) && (isLong22 (pIcode, pEnd, long_loc)))
{ {
if (checkLongRegEq (pLocId.id.longId, pIcode, loc_ident_idx, this, asgn, *long_loc->ll()) ) if (checkLongRegEq (pLocId.longId(), pIcode, loc_ident_idx, this, asgn, *long_loc->ll()) )
{ {
// TODO: verify that removing -1 does not change anything ! // TODO: verify that removing -1 does not change anything !
advance(pIcode,longJCond22 (asgn, pIcode,pEnd)); advance(pIcode,longJCond22 (asgn, pIcode,pEnd));
@ -502,7 +500,7 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be
* This is better code than HLI_JCOND (HI(regH:regL) | LO(regH:regL)) */ * This is better code than HLI_JCOND (HI(regH:regL) | LO(regH:regL)) */
else if (pIcode->ll()->match(iOR) && (next1 != pEnd) && (isJCond ((llIcode)next1->ll()->getOpcode()))) else if (pIcode->ll()->match(iOR) && (next1 != pEnd) && (isJCond ((llIcode)next1->ll()->getOpcode())))
{ {
if (pLocId.id.longId.srcDstRegMatch(pIcode,pIcode)) if (pLocId.longId().srcDstRegMatch(pIcode,pIcode))
{ {
asgn.lhs = AstIdent::LongIdx (loc_ident_idx); asgn.lhs = AstIdent::LongIdx (loc_ident_idx);
asgn.rhs = new Constant(0, 4); /* long 0 */ asgn.rhs = new Constant(0, 4); /* long 0 */

View File

@ -6,6 +6,8 @@
****************************************************************************/ ****************************************************************************/
#include <cstring> #include <cstring>
#include <map>
#include <string>
#include "dcc.h" #include "dcc.h"
#include "scanner.h" #include "scanner.h"
#include "project.h" #include "project.h"
@ -411,33 +413,116 @@ int disassembleOneLibDisasm(uint32_t ip,x86_insn_t &l)
} }
eReg convertRegister(const x86_reg_t &reg) eReg convertRegister(const x86_reg_t &reg)
{ {
if( (reg_pc==reg.type) || (0==reg.id))
return rUNDEF;
eReg regmap[]={ rUNDEF, eReg regmap[]={ rUNDEF,
rUNDEF,rUNDEF,rUNDEF,rUNDEF, //eax ecx ebx edx rUNDEF,rUNDEF,rUNDEF,rUNDEF, //eax ecx ebx edx
rSP,rUNDEF,rUNDEF,rUNDEF, //esp ebp esi edi rSP,rUNDEF,rUNDEF,rDI, //esp ebp esi edi
rAX,rCX,rDX,rBX, rAX,rCX,rDX,rBX,
rSP,rBP,rSI,rDI, rSP,rBP,rSI,rDI,
rAL,rCL,rDL,rBL, rAL,rCL,rDL,rBL,
rAH,rCH,rDH,rBH rAH,rCH,rDH,rBH
}; };
std::map<std::string,eReg> nameToEnum = {{"es",rES},{"ds",rDS},{"cs",rCS},{"ss",rSS}};
if(nameToEnum.find(reg.name)!=nameToEnum.end())
return nameToEnum[reg.name];
assert(reg.id<sizeof(regmap)/sizeof(eReg)); assert(reg.id<sizeof(regmap)/sizeof(eReg));
assert(regmap[reg.id]!=rUNDEF); assert(regmap[reg.id]!=rUNDEF);
return regmap[reg.id]; return regmap[reg.id];
} }
LLOperand convertExpression(const x86_ea_t &from)
{
// BASE + Scale*Index + Disp
LLOperand res;
res.seg = rDS;
/*
INDEX_BX_SI = 22, // "bx+si"
INDEX_BX_DI, // "bx+di"
INDEX_BP_SI, // "bp+si"
INDEX_BP_DI, // "bp+di"
INDEX_SI, // "si"
INDEX_DI, // "di"
INDEX_BP, // "bp"
INDEX_BX, // "bx"
*/
if(from.base.id)
{
eReg base_reg = convertRegister(from.base);
eReg index_reg = convertRegister(from.index);
// if(base_reg==rBX)
switch(base_reg)
{
case rDI:
res.regi = INDEX_DI; break;
case rBP:
res.seg=rSS;
switch(index_reg)
{
case rDI:
res.regi = INDEX_BP_DI; break;
case rSI:
res.regi = INDEX_BP_SI; break;
case rUNDEF:
res.regi = INDEX_BP; break;
default:
assert(false);
}
break;
case rBX:
switch(index_reg)
{
case rDI:
res.regi = INDEX_BX_DI; break;
case rSI:
res.regi = INDEX_BX_SI; break;
case rUNDEF:
res.regi = INDEX_BX; break;
default:
assert(false);
}
break;
default:
assert(false);
}
assert(index_reg==rUNDEF);
}
assert(from.scale==0);
if(from.index.id)
{
assert(false);
}
res.off = from.disp;
return res;
}
LLOperand convertOperand(const x86_op_t &from) LLOperand convertOperand(const x86_op_t &from)
{ {
LLOperand res;
switch(from.type) switch(from.type)
{ {
case op_unused: case op_unused:
break; break;
case op_register: case op_register:
return LLOperand::CreateReg2(convertRegister(from.data.reg)); res.regi = convertRegister(from.data.reg); break;
case op_immediate: case op_immediate:
return LLOperand::CreateImm2(from.data.sdword); res.opz = from.data.sdword;
case op_expression:
res = convertExpression(from.data.expression); break;
case op_offset:
{
LLOperand res;
res.seg = rDS;
res.off = from.data.offset;
break;
}
default: default:
fprintf(stderr,"convertOperand does not know how to convert %d\n",from.type); fprintf(stderr,"convertOperand does not know how to convert %d\n",from.type);
} }
return LLOperand::CreateImm2(0); if(res.isSet() && (res.seg == rUNDEF))
{
res.seg = rDS;
}
return res;
} }
/***************************************************************************** /*****************************************************************************
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.
@ -481,15 +566,8 @@ eErrorId scan(uint32_t ip, ICODE &p)
if(p.insn.x86_get_branch_target()) if(p.insn.x86_get_branch_target())
decodeBranchTgt(p.insn); decodeBranchTgt(p.insn);
} }
x86_op_t *dst_op = p.insn.get_dest(); // LLOperand conv = convertOperand(*p.insn.get_dest());
static int only_first=1;
if(dst_op && only_first)
{
only_first = 0;
LLOperand conv = convertOperand(*dst_op);
p.ll()->dst=conv;
// assert(conv==p.ll()->dst); // assert(conv==p.ll()->dst);
}
if (p.ll()->getOpcode()) if (p.ll()->getOpcode())
{ {
/* Save bytes of image used */ /* Save bytes of image used */
@ -552,7 +630,7 @@ static void setAddress(int i, bool fdst, uint16_t seg, int16_t reg, uint16_t off
/* If not to register (i.e. to r/m), and talking about r/m, then this is dest */ /* If not to register (i.e. to r/m), and talking about r/m, then this is dest */
pm = (!(stateTable[i].flg & TO_REG) == fdst) ? pm = (!(stateTable[i].flg & TO_REG) == fdst) ?
&pIcode->ll()->dst : &pIcode->ll()->src(); &pIcode->ll()->m_dst : &pIcode->ll()->src();
/* Set segment. A later procedure (lookupAddr in proclist.c) will /* 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. */
@ -619,7 +697,7 @@ static void rm(int i)
} }
//pIcode->insn.get_dest()-> //pIcode->insn.get_dest()->
if ((stateTable[i].flg & NSP) && (pIcode->ll()->src().getReg2()==rSP || if ((stateTable[i].flg & NSP) && (pIcode->ll()->src().getReg2()==rSP ||
pIcode->ll()->dst.getReg2()==rSP)) pIcode->ll()->m_dst.getReg2()==rSP))
pIcode->ll()->setFlags(NOT_HLL); pIcode->ll()->setFlags(NOT_HLL);
} }
@ -656,10 +734,9 @@ static void segrm(int i)
static void regop(int i) 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(pIcode->ll()->src());
// pIcode->ll()->dst.regi = pIcode->ll()->src.regi;
}
}
/***************************************************************************** /*****************************************************************************
segop - seg encoded in middle of opcode segop - seg encoded in middle of opcode
@ -767,7 +844,7 @@ static void trans(int i)
if ((uint8_t)REG(*pInst) < 2 || !(stateTable[i].flg & B)) { /* INC & DEC */ 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 */
rm(i); rm(i);
ll->replaceSrc( pIcode->ll()->dst ); ll->replaceSrc( pIcode->ll()->m_dst );
if (ll->match(iJMP) || ll->match(iCALL) || ll->match(iCALLF)) if (ll->match(iJMP) || ll->match(iCALL) || ll->match(iCALLF))
ll->setFlags(NO_OPS); ll->setFlags(NO_OPS);
else if (ll->match(iINC) || ll->match(iPUSH) || ll->match(iDEC)) else if (ll->match(iINC) || ll->match(iPUSH) || ll->match(iDEC))
@ -799,7 +876,7 @@ static void arith(int i)
} }
else if (!(opcode == iNOT || opcode == iNEG)) else if (!(opcode == iNOT || opcode == iNEG))
{ {
pIcode->ll()->replaceSrc( pIcode->ll()->dst ); pIcode->ll()->replaceSrc( pIcode->ll()->m_dst );
setAddress(i, true, 0, rAX, 0); /* dst = AX */ setAddress(i, true, 0, rAX, 0); /* dst = AX */
} }
else if (opcode == iNEG || opcode == iNOT) else if (opcode == iNEG || opcode == iNOT)
@ -838,7 +915,7 @@ static void data2(int )
* set to NO_OPS. */ * set to NO_OPS. */
if (pIcode->ll()->getOpcode() == iENTER) if (pIcode->ll()->getOpcode() == iENTER)
{ {
pIcode->ll()->dst.off = getWord(); pIcode->ll()->m_dst.off = getWord();
pIcode->ll()->setFlags(NO_OPS); pIcode->ll()->setFlags(NO_OPS);
} }
else else