Changes
This commit is contained in:
parent
f6118dc0c4
commit
0209b7ceb2
14
3rd_party/libdisasm/ia32_implicit.cpp
vendored
14
3rd_party/libdisasm/ia32_implicit.cpp
vendored
@ -407,6 +407,20 @@ unsigned int Ia32_Decoder::ia32_insn_implicit_ops( unsigned int impl_idx ) {
|
||||
if (!op) {
|
||||
op = m_decoded->x86_operand_new();
|
||||
/* 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 );
|
||||
/* decrement the 'explicit count' incremented by default in
|
||||
* x86_operand_new */
|
||||
|
||||
10
3rd_party/libdisasm/ia32_operand.cpp
vendored
10
3rd_party/libdisasm/ia32_operand.cpp
vendored
@ -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 */
|
||||
case ADDRMETH_A: /* No modR/M -- direct addr */
|
||||
op->type = op_absolute;
|
||||
|
||||
//according to Intel Manuals, offset goes first
|
||||
/* segment:offset address used in far calls */
|
||||
if ( m_decoded->addr_size == 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);
|
||||
break;
|
||||
case 2:
|
||||
/* far offset...is this truly signed? */
|
||||
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 );
|
||||
op->data.relative_far=offset_val;
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
size=0;
|
||||
|
||||
}
|
||||
break;
|
||||
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_string = true;
|
||||
ia32_handle_register( &op->data.expression.base,
|
||||
REG_DWORD_OFFSET + 6 );
|
||||
gen_regs + 6 );
|
||||
break;
|
||||
case ADDRMETH_Y: /* Memory addressed by ES:DI [string] */
|
||||
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_string = true;
|
||||
ia32_handle_register( &op->data.expression.base,
|
||||
REG_DWORD_OFFSET + 7 );
|
||||
gen_regs + 7 );
|
||||
break;
|
||||
case ADDRMETH_RR: /* Gen Register hard-coded in opcode */
|
||||
op->type = op_register;
|
||||
|
||||
19
3rd_party/libdisasm/libdis.h
vendored
19
3rd_party/libdisasm/libdis.h
vendored
@ -8,6 +8,7 @@
|
||||
#include <cstdlib>
|
||||
#include <cassert>
|
||||
#include <stdint.h>
|
||||
|
||||
/* 'NEW" types
|
||||
* __________________________________________________________________________*/
|
||||
#ifndef LIBDISASM_QWORD_H /* do not interfere with qword.h */
|
||||
@ -304,25 +305,23 @@ struct x86_op_t{
|
||||
int32_t getAddress()
|
||||
{
|
||||
assert(is_address()||is_relative());
|
||||
switch(type)
|
||||
{
|
||||
switch ( type ) {
|
||||
case op_relative_near:
|
||||
return (int32_t) data.relative_near;
|
||||
case op_absolute:
|
||||
{
|
||||
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
|
||||
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:
|
||||
return data.offset;
|
||||
case op_relative_near:
|
||||
return data.relative_near;
|
||||
case op_relative_far:
|
||||
return data.relative_far;
|
||||
return (int32_t) data.relative_far;
|
||||
default:
|
||||
assert(false);
|
||||
return ~0;
|
||||
break;
|
||||
}
|
||||
return ~0;
|
||||
}
|
||||
char * format( enum x86_asm_format format );
|
||||
x86_op_t * copy()
|
||||
|
||||
1
3rd_party/libdisasm/x86_insn.cpp
vendored
1
3rd_party/libdisasm/x86_insn.cpp
vendored
@ -99,7 +99,6 @@ x86_op_t * x86_insn_t::get_dest() {
|
||||
if ( ! operands ) {
|
||||
return NULL;
|
||||
}
|
||||
assert(this->x86_operand_count(op_dest)==1);
|
||||
for (op_lst = operands; op_lst; op_lst = op_lst->next ) {
|
||||
if ( op_lst->op.access & op_write)
|
||||
return &(op_lst->op);
|
||||
|
||||
@ -36,7 +36,7 @@ private:
|
||||
numHlIcodes(0),flg(0),
|
||||
inEdges(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),
|
||||
numBackEdges(0),loopHead(0),loopFollow(0),caseHead(0),caseTail(0),index(0)
|
||||
{
|
||||
|
||||
@ -143,7 +143,7 @@ public:
|
||||
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),
|
||||
hasCase(false),liveIn(0),liveOut(0),liveAnal(0)//,next(0),prev(0)
|
||||
hasCase(false),liveAnal(0)//,next(0),prev(0)
|
||||
{
|
||||
}
|
||||
public:
|
||||
|
||||
@ -59,12 +59,8 @@ typedef struct { /* Command line option flags */
|
||||
extern OPTION option; /* Command line options */
|
||||
|
||||
#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 */
|
||||
enum eAreaType
|
||||
@ -130,8 +126,8 @@ char *writeJcondInv (HLTYPE, Function *, int *);
|
||||
|
||||
|
||||
/* Exported funcions from locident.c */
|
||||
boolT checkLongEq (LONG_STKID_TYPE, iICODE, int, Function *, Assignment &asgn, LLInst &atOffset);
|
||||
boolT checkLongRegEq (LONGID_TYPE, iICODE, int, Function *, Assignment &asgn, LLInst &);
|
||||
bool checkLongEq(LONG_STKID_TYPE, iICODE, int, Function *, Assignment &asgn, LLInst &atOffset);
|
||||
bool checkLongRegEq(LONGID_TYPE, iICODE, int, Function *, Assignment &asgn, LLInst &);
|
||||
eReg otherLongRegi(eReg, int, LOCAL_ID *);
|
||||
|
||||
|
||||
|
||||
129
include/icode.h
129
include/icode.h
@ -7,6 +7,9 @@
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <bitset>
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
#include <initializer_list>
|
||||
#include <llvm/ADT/ilist.h>
|
||||
#include <llvm/ADT/ilist_node.h>
|
||||
#include <llvm/MC/MCInst.h>
|
||||
@ -29,17 +32,20 @@ typedef std::list<ICODE>::iterator iICODE;
|
||||
typedef std::list<ICODE>::reverse_iterator riICODE;
|
||||
typedef boost::iterator_range<iICODE> rCODE;
|
||||
|
||||
struct LivenessSet : public std::bitset<32>
|
||||
struct LivenessSet
|
||||
{
|
||||
LivenessSet(int val=0) : std::bitset<32>(val) {}
|
||||
LivenessSet(const LivenessSet &other)
|
||||
std::set<eReg> registers;
|
||||
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()
|
||||
// {
|
||||
// swap(*this,other);
|
||||
@ -56,22 +62,65 @@ struct LivenessSet : public std::bitset<32>
|
||||
|
||||
// by swapping the members of two classes,
|
||||
// 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 &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);
|
||||
private:
|
||||
void postProcessCompositeRegs();
|
||||
};
|
||||
|
||||
extern LivenessSet duReg[30];
|
||||
/* uint8_t and uint16_t registers */
|
||||
|
||||
/* Def/use of flags - low 4 bits represent flags */
|
||||
@ -197,7 +246,6 @@ public:
|
||||
/* LOW_LEVEL icode operand record */
|
||||
struct LLOperand
|
||||
{
|
||||
llvm::MCOperand llvm_op;
|
||||
eReg seg; /* CS, DS, ES, SS */
|
||||
eReg segOver; /* CS, DS, ES, SS if segment override */
|
||||
int16_t segValue; /* Value of segment seg during analysis */
|
||||
@ -245,6 +293,10 @@ struct LLOperand
|
||||
Op.regi = (eReg)Val;
|
||||
return Op;
|
||||
}
|
||||
bool isSet()
|
||||
{
|
||||
return not (*this == LLOperand());
|
||||
}
|
||||
void addProcInformation(int param_count,uint32_t call_conv);
|
||||
};
|
||||
struct LLInst : public llvm::MCInst //: public llvm::ilist_node<LLInst>
|
||||
@ -256,7 +308,7 @@ public:
|
||||
int codeIdx; /* Index into cCode.code */
|
||||
uint8_t numBytes; /* Number of bytes this instr */
|
||||
uint32_t label; /* offset in image (20-bit adr) */
|
||||
LLOperand dst; /* destination operand */
|
||||
LLOperand m_dst; /* destination operand */
|
||||
DU flagDU; /* def/use of flags */
|
||||
int caseEntry;
|
||||
std::vector<uint32_t> caseTbl2;
|
||||
@ -285,25 +337,29 @@ public:
|
||||
{
|
||||
return (getOpcode()==op);
|
||||
}
|
||||
bool matchWithRegDst(llIcode op)
|
||||
{
|
||||
return (getOpcode()==op) and m_dst.isReg();
|
||||
}
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
return (dst.regi==dest)&&(m_src.regi==src_reg);
|
||||
return (m_dst.regi==dest)&&(m_src.regi==src_reg);
|
||||
}
|
||||
bool match(eReg dest)
|
||||
{
|
||||
return (dst.regi==dest);
|
||||
return (m_dst.regi==dest);
|
||||
}
|
||||
bool match(llIcode op,uint32_t flgs)
|
||||
{
|
||||
@ -314,6 +370,19 @@ public:
|
||||
setOpcode(op);
|
||||
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 findJumpTargets(CIcodeRec &_pc);
|
||||
void writeIntComment(std::ostringstream &s);
|
||||
@ -343,16 +412,16 @@ public:
|
||||
}
|
||||
void replaceDst(const LLOperand &with)
|
||||
{
|
||||
dst = with;
|
||||
}
|
||||
void replaceDst(eReg r)
|
||||
{
|
||||
dst = LLOperand::CreateReg2(r);
|
||||
m_dst = with;
|
||||
}
|
||||
// void replaceDst(eReg r)
|
||||
// {
|
||||
// dst = LLOperand::CreateReg2(r);
|
||||
// }
|
||||
ICODE *m_link;
|
||||
condId idType(opLoc sd) const;
|
||||
const LLOperand * get(opLoc sd) const { return (sd == SRC) ? &src() : &dst; }
|
||||
LLOperand * get(opLoc sd) { return (sd == SRC) ? &src() : &dst; }
|
||||
const LLOperand * get(opLoc sd) const { return (sd == SRC) ? &src() : &m_dst; }
|
||||
LLOperand * get(opLoc sd) { return (sd == SRC) ? &src() : &m_dst; }
|
||||
};
|
||||
|
||||
/* Icode definition: LOW_LEVEL and HIGH_LEVEL */
|
||||
@ -407,6 +476,10 @@ public:
|
||||
};
|
||||
struct DU1
|
||||
{
|
||||
protected:
|
||||
int numRegsDef; /* # registers defined by this inst */
|
||||
|
||||
public:
|
||||
struct Use
|
||||
{
|
||||
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 */
|
||||
Use idx[MAX_REGS_DEF+1];
|
||||
//int idx[MAX_REGS_DEF][MAX_USES]; /* inst that uses this def */
|
||||
@ -447,6 +519,11 @@ public:
|
||||
Use &u(idx[regIdx]);
|
||||
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)
|
||||
{
|
||||
}
|
||||
|
||||
@ -31,37 +31,67 @@ struct IDX_ARRAY : public std::vector<iICODE>
|
||||
}
|
||||
};
|
||||
|
||||
typedef enum
|
||||
enum frameType
|
||||
{
|
||||
STK_FRAME, /* For stack vars */
|
||||
REG_FRAME, /* For register variables */
|
||||
GLB_FRAME /* For globals */
|
||||
} frameType;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
struct BWGLB_TYPE
|
||||
{
|
||||
int16_t seg; /* segment value */
|
||||
int16_t off; /* offset */
|
||||
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 */
|
||||
struct ID
|
||||
{
|
||||
protected:
|
||||
LONGID_TYPE m_longId; /* For TYPE_LONG_(UN)SIGN registers */
|
||||
public:
|
||||
hlType type; /* Probable type */
|
||||
bool illegal; /* Boolean: not a valid field any more */
|
||||
//std::vector<iICODE> idx;
|
||||
@ -70,33 +100,39 @@ struct ID
|
||||
bool hasMacro; /* Identifier requires a macro */
|
||||
char macro[10]; /* Macro for this identifier */
|
||||
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 */
|
||||
struct { /* For TYPE_BYTE(uint16_t)_(UN)SIGN on the stack */
|
||||
uint8_t regOff; /* register offset (if any) */
|
||||
int off; /* offset from BP */
|
||||
} bwId;
|
||||
BWGLB_TYPE bwGlb; /* For TYPE_BYTE(uint16_t)_(UN)SIGN globals */
|
||||
LONGID_TYPE longId; /* For TYPE_LONG_(UN)SIGN registers */
|
||||
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;
|
||||
LONGGLB_TYPE longGlb;
|
||||
struct { /* For TYPE_LONG_(UN)SIGN constants */
|
||||
uint32_t h; /* high uint16_t */
|
||||
uint32_t l; /* low uint16_t */
|
||||
} longKte;
|
||||
ID_UNION() { /*new (&longStkId) LONG_STKID_TYPE();*/}
|
||||
} 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(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);}
|
||||
uint16_t typeBitsize() const
|
||||
{
|
||||
return TypeContainer::typeSize(type)*8;
|
||||
}
|
||||
bool isLong() const { return (type==TYPE_LONG_UNSIGN)||(type==TYPE_LONG_SIGN); }
|
||||
void setLocalName(int i)
|
||||
{
|
||||
char buf[32];
|
||||
@ -123,7 +159,7 @@ public:
|
||||
int newByteWordReg(hlType t, eReg regi);
|
||||
int newByteWordStk(hlType t, int off, uint8_t regOff);
|
||||
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, LLInst &atOffset);
|
||||
void newIdent(hlType t, frameType f);
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
#include <sstream>
|
||||
#include <bitset>
|
||||
|
||||
struct LivenessSet;
|
||||
/* Machine registers */
|
||||
enum eReg
|
||||
{
|
||||
@ -32,8 +33,9 @@ enum eReg
|
||||
rBH = 20,
|
||||
|
||||
rTMP= 21, /* temp register for DIV/IDIV/MOD */
|
||||
rTMP2= 22, /* temp register for DIV/IDIV/MOD */
|
||||
/* 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_BP_SI, // "bp+si"
|
||||
INDEX_BP_DI, // "bp+di"
|
||||
@ -64,15 +66,7 @@ public:
|
||||
bool physicalReg(eReg r);
|
||||
/* Writes the registers that are set in the bitvector */
|
||||
//TODO: move this into Machine_X86 ?
|
||||
static void writeRegVector (std::ostream &ostr,const std::bitset<32> ®i)
|
||||
{
|
||||
int j;
|
||||
for (j = rAX; j < INDEX_BX_SI; j++)
|
||||
{
|
||||
if (regi.test(j-1))
|
||||
ostr << regName(eReg(j))<<" ";
|
||||
}
|
||||
}
|
||||
static void writeRegVector (std::ostream &ostr,const LivenessSet ®i);
|
||||
static eReg subRegH(eReg reg);
|
||||
static eReg subRegL(eReg reg);
|
||||
static bool isMemOff(eReg r);
|
||||
|
||||
34
src/ast.cpp
34
src/ast.cpp
@ -52,18 +52,23 @@ static const char *hexStr (uint16_t i)
|
||||
void ICODE::setRegDU (eReg regi, operDu 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)
|
||||
{
|
||||
case eDEF:
|
||||
du.def.addReg(regi);
|
||||
du1.numRegsDef++;
|
||||
du1.addDef(regi);
|
||||
break;
|
||||
case eUSE:
|
||||
du.use.addReg(regi);
|
||||
break;
|
||||
case USE_DEF:
|
||||
du.addDefinedAndUsed(regi);
|
||||
du1.numRegsDef++;
|
||||
du1.addDef(regi);
|
||||
break;
|
||||
case NONE: /* do nothing */
|
||||
break;
|
||||
@ -233,9 +238,8 @@ AstIdent *AstIdent::Long(LOCAL_ID *localId, opLoc sd, iICODE pIcode, hlFirst f,
|
||||
else
|
||||
{
|
||||
newExp = new AstIdent();
|
||||
idx = localId->newLong(sd, pIcode, f, ix, du, atOffset);
|
||||
newExp->ident.idType = LONG_VAR;
|
||||
newExp->ident.idNode.longIdx = idx;
|
||||
newExp->ident.idNode.longIdx = localId->newLong(sd, pIcode, f, ix, du, atOffset);
|
||||
}
|
||||
return (newExp);
|
||||
}
|
||||
@ -265,7 +269,7 @@ AstIdent *AstIdent::idID (const ID *retVal, LOCAL_ID *locsym, iICODE ix_)
|
||||
case TYPE_LONG_SIGN:
|
||||
{
|
||||
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.idNode.longIdx = idx;
|
||||
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 */
|
||||
|
||||
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
|
||||
((sd == SRC) && ll_insn.testFlags(IM_SRC)) or
|
||||
(sd == LHS_OP)) /* for MUL lhs */
|
||||
{ /* 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);
|
||||
duIcode.setRegDU (rDX, 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 */
|
||||
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))
|
||||
return (CONSTANT);
|
||||
@ -582,10 +586,10 @@ string AstIdent::walkCondExpr(Function *pProc, int *numLoc) const
|
||||
{
|
||||
id->setLocalName(++(*numLoc));
|
||||
codeOut <<TypeContainer::typeName(id->type)<< " "<<id->name<<"; ";
|
||||
codeOut <<"/* "<<Machine_X86::regName(id->id.longId.h) << ":" <<
|
||||
Machine_X86::regName(id->id.longId.l) << " */\n";
|
||||
codeOut <<"/* "<<Machine_X86::regName(id->longId().h()) << ":" <<
|
||||
Machine_X86::regName(id->longId().l()) << " */\n";
|
||||
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 */
|
||||
{
|
||||
@ -884,10 +888,10 @@ eReg AstIdent::otherLongRegi (eReg regi, int idx, LOCAL_ID *locTbl)
|
||||
if ((id->loc == REG_FRAME) && ((id->type == TYPE_LONG_SIGN) ||
|
||||
(id->type == TYPE_LONG_UNSIGN)))
|
||||
{
|
||||
if (id->id.longId.h == regi)
|
||||
return (id->id.longId.l);
|
||||
else if (id->id.longId.l == regi)
|
||||
return (id->id.longId.h);
|
||||
if (id->longId().h() == regi)
|
||||
return (id->longId().l());
|
||||
else if (id->longId().l() == regi)
|
||||
return (id->longId().h());
|
||||
}
|
||||
return rUNDEF; // Cristina: please check this!
|
||||
}
|
||||
|
||||
@ -154,7 +154,7 @@ void LLInst::writeIntComment (std::ostringstream &s)
|
||||
s<<"\t/* ";
|
||||
if (src_immed == 0x21)
|
||||
{
|
||||
s <<int21h[dst.off];
|
||||
s <<int21h[m_dst.off];
|
||||
}
|
||||
else if (src_immed > 0x1F && src_immed < 0x2F)
|
||||
{
|
||||
@ -162,7 +162,7 @@ void LLInst::writeIntComment (std::ostringstream &s)
|
||||
}
|
||||
else if (src_immed == 0x2F)
|
||||
{
|
||||
switch (dst.off)
|
||||
switch (m_dst.off)
|
||||
{
|
||||
case 0x01 :
|
||||
s << "Print spooler";
|
||||
@ -215,8 +215,8 @@ void Function::writeProcComments(std::ostream &ostr)
|
||||
else /* long register */
|
||||
{
|
||||
id = &this->localId.id_arr[psym->regs->ident.idNode.longIdx];
|
||||
ostr << Machine_X86::regName(id->id.longId.h) << ":";
|
||||
ostr << Machine_X86::regName(id->id.longId.l);
|
||||
ostr << Machine_X86::regName(id->longId().h()) << ":";
|
||||
ostr << Machine_X86::regName(id->longId().l());
|
||||
}
|
||||
ostr << ".\n";
|
||||
|
||||
|
||||
@ -60,7 +60,7 @@ void ExpStack::push(Expr *expr)
|
||||
Expr *ExpStack::pop()
|
||||
{
|
||||
if(expStk.empty())
|
||||
return 0;
|
||||
return expStk.back();
|
||||
Expr *topExp = expStk.back();
|
||||
expStk.pop_back();
|
||||
return topExp;
|
||||
@ -266,7 +266,7 @@ void Function::genLiveKtes ()
|
||||
{
|
||||
if ((insn.type == HIGH_LEVEL) && ( insn.valid() ))
|
||||
{
|
||||
liveUse |= (insn.du.use & ~def);
|
||||
liveUse |= (insn.du.use - def);
|
||||
def |= insn.du.def;
|
||||
}
|
||||
}
|
||||
@ -358,14 +358,15 @@ void Function::liveRegAnalysis (LivenessSet &in_liveOut)
|
||||
{
|
||||
switch (pcallee->retVal.type) {
|
||||
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;
|
||||
case TYPE_WORD_SIGN: case TYPE_WORD_UNSIGN:
|
||||
case TYPE_BYTE_SIGN: case TYPE_BYTE_UNSIGN:
|
||||
ticode.du1.numRegsDef = 1;
|
||||
ticode.du1.setDef(rAX);
|
||||
break;
|
||||
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);
|
||||
} /*eos*/
|
||||
|
||||
@ -377,7 +378,7 @@ void Function::liveRegAnalysis (LivenessSet &in_liveOut)
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
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
|
||||
continue;
|
||||
/* 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());
|
||||
/* 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();
|
||||
break;
|
||||
@ -435,13 +436,13 @@ bool BB::FindUseBeforeDef(eReg regi, int defRegIdx, iICODE start_at)
|
||||
ticode=(++riICODE(rbegin())).base();
|
||||
|
||||
/* 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);
|
||||
}
|
||||
else /* only 1 instruction in this basic block */
|
||||
{
|
||||
/* Check if last definition of this register */
|
||||
if ((liveOut & duReg[regi]).any())
|
||||
if ( liveOut.testRegAndSubregs(regi) )
|
||||
start_at->du.lastDefRegi.addReg(regi);
|
||||
}
|
||||
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)
|
||||
{
|
||||
/* if used, get icode index */
|
||||
if ((iter->du.use & duReg[regi]).any())
|
||||
if ( iter->du.use.testRegAndSubregs(regi) )
|
||||
picode.du1.recordUse(defRegIdx,iter.base());
|
||||
/* if defined, stop finding uses for this reg */
|
||||
if ((iter->du.def & duReg[regi]).any())
|
||||
if (iter->du.def.testRegAndSubregs(regi))
|
||||
break;
|
||||
}
|
||||
|
||||
/* if not used in this basic block, check if the
|
||||
* register is live out, if so, make it the last
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
@ -484,11 +485,11 @@ void BB::ProcessUseDefForFunc(eReg regi, int defRegIdx, ICODE &picode)
|
||||
void BB::RemoveUnusedDefs(eReg regi, int defRegIdx, iICODE picode)
|
||||
{
|
||||
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) &&
|
||||
(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);
|
||||
if (res == true)
|
||||
@ -537,7 +538,7 @@ void BB::genDU1()
|
||||
defRegIdx++;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
@ -848,7 +849,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
|
||||
{
|
||||
HLTYPE &_icHl(*picode->hlU());
|
||||
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
|
||||
* the last definition of the register in this BB, check
|
||||
@ -867,7 +868,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
|
||||
* icode expression */
|
||||
|
||||
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_RET)))
|
||||
continue;
|
||||
@ -886,7 +887,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
|
||||
// call F() <- somehow this is marked as user of POP ?
|
||||
ticode = picode->du1.idx[0].uses.front();
|
||||
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_RET)))
|
||||
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 */
|
||||
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])
|
||||
{
|
||||
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_RET)))
|
||||
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])
|
||||
{
|
||||
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_RET)))
|
||||
continue;
|
||||
@ -1053,8 +1054,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
|
||||
_retVal = &picode->hl()->call.proc->retVal;
|
||||
res = Expr::insertSubTreeLongReg (_exp,
|
||||
ticode->hlU()->exp.v,
|
||||
locals.newLongReg ( _retVal->type, _retVal->id.longId.h,
|
||||
_retVal->id.longId.l, picode.base()));
|
||||
locals.newLongReg ( _retVal->type, _retVal->longId(), picode.base()));
|
||||
if (res) /* was substituted */
|
||||
{
|
||||
picode->invalidate();
|
||||
@ -1083,8 +1083,8 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
|
||||
{
|
||||
g_exp_stk.processExpPush(numHlIcodes, picode.base());
|
||||
}
|
||||
else if(picode->du1.numRegsDef!=0)
|
||||
printf("Num def %d\n",picode->du1.numRegsDef);
|
||||
else if(picode->du1.getNumRegsDef()!=0)
|
||||
printf("Num def %d\n",picode->du1.getNumRegsDef());
|
||||
|
||||
/* For HLI_CALL instructions that use arguments from the stack,
|
||||
* 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,
|
||||
* 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);
|
||||
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.loc = REG_FRAME;
|
||||
retVal.id.longId.h = rDX;
|
||||
retVal.id.longId.l = rAX;
|
||||
/*idx = */localId.newLongReg(TYPE_LONG_SIGN, rDX, rAX, Icode.begin()/*0*/);
|
||||
retVal.longId() = LONGID_TYPE(rDX,rAX);
|
||||
/*idx = */localId.newLongReg(TYPE_LONG_SIGN, LONGID_TYPE(rDX,rAX), Icode.begin());
|
||||
localId.propLongId (rAX, rDX, "\0");
|
||||
}
|
||||
else if (isAx || isBx || isCx || isDx) /* uint16_t */
|
||||
|
||||
@ -70,7 +70,7 @@ static const char *szFlops3C[] =
|
||||
|
||||
static const char *szPtr[2] = { "word ptr ", "byte ptr " };
|
||||
|
||||
static void formatRM(ostringstream &p, uint32_t flg, const LLOperand &pm);
|
||||
static void formatRM(ostringstream &p, const LLOperand &pm);
|
||||
static ostringstream &strDst(ostringstream &os, uint32_t flg, const LLOperand &pm);
|
||||
|
||||
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 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);
|
||||
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 iROR:
|
||||
strDst(operands_s,inst.getFlag() | I, inst.dst);
|
||||
strDst(operands_s,inst.getFlag() | I, inst.m_dst);
|
||||
if(inst.testFlags(I))
|
||||
inst.strSrc(operands_s);
|
||||
else
|
||||
@ -301,7 +301,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
|
||||
break;
|
||||
|
||||
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;
|
||||
|
||||
case iPUSH:
|
||||
@ -311,15 +311,15 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
|
||||
}
|
||||
else
|
||||
{
|
||||
strDst(operands_s,inst.getFlag() | I, inst.dst);
|
||||
strDst(operands_s,inst.getFlag() | I, inst.m_dst);
|
||||
}
|
||||
break;
|
||||
|
||||
case iDIV: case iIDIV: case iMUL: case iIMUL: case iMOD:
|
||||
if (inst.testFlags(I))
|
||||
{
|
||||
strDst(operands_s,inst.getFlag(), inst.dst) <<", ";
|
||||
formatRM(operands_s, inst.getFlag(), inst.src());
|
||||
strDst(operands_s,inst.getFlag(), inst.m_dst) <<", ";
|
||||
formatRM(operands_s, inst.src());
|
||||
inst.strSrc(operands_s);
|
||||
}
|
||||
else
|
||||
@ -327,7 +327,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
|
||||
break;
|
||||
|
||||
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);
|
||||
break;
|
||||
|
||||
@ -397,8 +397,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
|
||||
break;
|
||||
|
||||
case iENTER:
|
||||
operands_s<<strHex(inst.dst.off)<<", ";
|
||||
operands_s<<strHex(inst.src().getImm2());
|
||||
operands_s<<strHex(inst.m_dst.off) << ", " << strHex(inst.src().getImm2());
|
||||
break;
|
||||
|
||||
case iRET: case iRETF: case iINT:
|
||||
@ -552,7 +551,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
|
||||
/****************************************************************************
|
||||
* 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];
|
||||
|
||||
@ -595,7 +594,7 @@ static ostringstream & strDst(ostringstream &os,uint32_t flg, const LLOperand &p
|
||||
//os << setw(WID_PTR);
|
||||
if ((flg & I) and not pm.isReg())
|
||||
os << szPtr[flg & B];
|
||||
formatRM(os, flg, pm);
|
||||
formatRM(os, pm);
|
||||
return os;
|
||||
}
|
||||
|
||||
@ -612,7 +611,7 @@ ostringstream &LLInst::strSrc(ostringstream &os,bool skip_comma)
|
||||
else if (testFlags(IM_SRC)) /* level 2 */
|
||||
os<<"dx:ax";
|
||||
else
|
||||
formatRM(os, getFlag(), src());
|
||||
formatRM(os, src());
|
||||
|
||||
return os;
|
||||
}
|
||||
@ -649,7 +648,7 @@ void LLInst::flops(std::ostringstream &out)
|
||||
/* Note that op is set to the escape number, e.g.
|
||||
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 */
|
||||
out<<Machine_X86::floatOpName(op)<<' ';
|
||||
@ -685,7 +684,7 @@ void LLInst::flops(std::ostringstream &out)
|
||||
}
|
||||
}
|
||||
|
||||
formatRM(out, getFlag(), dst);
|
||||
formatRM(out, m_dst);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -694,7 +693,7 @@ void LLInst::flops(std::ostringstream &out)
|
||||
normal opcodes. Because the opcodes are slightly different for
|
||||
this case (e.g. op=04 means FSUB if reg != 3, but FSUBR for
|
||||
reg == 3), a separate table is used (szFlops2). */
|
||||
int destRegIdx=dst.regi - rAX;
|
||||
int destRegIdx=m_dst.regi - rAX;
|
||||
switch (op)
|
||||
{
|
||||
case 0x0C:
|
||||
|
||||
@ -11,27 +11,6 @@
|
||||
#include "dcc.h"
|
||||
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 */
|
||||
|
||||
|
||||
@ -98,13 +77,13 @@ bool ICODE::removeDefRegi (eReg regi, int thisDefIdx, LOCAL_ID *locId)
|
||||
{
|
||||
int numDefs;
|
||||
|
||||
numDefs = du1.numRegsDef;
|
||||
numDefs = du1.getNumRegsDef();
|
||||
if (numDefs == thisDefIdx)
|
||||
{
|
||||
for ( ; numDefs > 0; numDefs--)
|
||||
{
|
||||
|
||||
if (du1.used(numDefs-1)||(du.lastDefRegi[regi]))
|
||||
if (du1.used(numDefs-1)||(du.lastDefRegi.testReg(regi)))
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -117,8 +96,9 @@ bool ICODE::removeDefRegi (eReg regi, int thisDefIdx, LOCAL_ID *locId)
|
||||
HlTypeSupport *p=hlU()->get();
|
||||
if(p and p->removeRegFromLong(regi,locId))
|
||||
{
|
||||
du1.numRegsDef--;
|
||||
du.def &= maskDuReg[regi];
|
||||
du1.removeDef(regi); //du1.numRegsDef--;
|
||||
//du.def &= maskDuReg[regi];
|
||||
du.def.clrReg(regi);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -285,6 +265,41 @@ HLTYPE LLInst::toHighLevel(COND_EXPR *lhs,COND_EXPR *rhs,Function *func)
|
||||
return res;
|
||||
}
|
||||
#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.
|
||||
* Note: this process should be done before data flow analysis, which
|
||||
* refines the HIGH_LEVEL icodes. */
|
||||
@ -292,12 +307,12 @@ void Function::highLevelGen()
|
||||
{
|
||||
size_t numIcode; /* number of icode instructions */
|
||||
iICODE pIcode; /* ptr to current icode node */
|
||||
Expr *lhs;
|
||||
Expr *rhs; /* left- and right-hand side of expression */
|
||||
uint32_t _flg; /* icode flags */
|
||||
numIcode = Icode.size();
|
||||
for (iICODE i = Icode.begin(); i!=Icode.end() ; ++i)
|
||||
{
|
||||
Expr *lhs=nullptr;
|
||||
assert(numIcode==Icode.size());
|
||||
pIcode = i; //Icode.GetIcode(i)
|
||||
LLInst *ll = pIcode->ll();
|
||||
@ -306,13 +321,16 @@ void Function::highLevelGen()
|
||||
if ((pIcode->type != LOW_LEVEL) or not pIcode->valid() )
|
||||
continue;
|
||||
_flg = ll->getFlag();
|
||||
if ((_flg & IM_OPS) != IM_OPS) /* not processing IM_OPS yet */
|
||||
if ((_flg & NO_OPS) != NO_OPS) /* if there are opers */
|
||||
if (not ll->testFlags(IM_OPS)) /* not processing IM_OPS yet */
|
||||
if ( not ll->testFlags(NO_OPS) ) /* if there are opers */
|
||||
{
|
||||
if ( not ll->testFlags(NO_SRC) ) /* if there is src op */
|
||||
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);
|
||||
}
|
||||
if(needsLhs(ll->getOpcode()))
|
||||
assert(lhs!=nullptr);
|
||||
switch (ll->getOpcode())
|
||||
{
|
||||
case iADD:
|
||||
@ -406,10 +424,12 @@ void Function::highLevelGen()
|
||||
pIcode->setAsgn(lhs, rhs);
|
||||
break;
|
||||
|
||||
case iPOP: pIcode->setUnary(HLI_POP, lhs);
|
||||
case iPOP:
|
||||
pIcode->setUnary(HLI_POP, lhs);
|
||||
break;
|
||||
|
||||
case iPUSH: pIcode->setUnary(HLI_PUSH, lhs);
|
||||
case iPUSH:
|
||||
pIcode->setUnary(HLI_PUSH, lhs);
|
||||
break;
|
||||
|
||||
case iRET:
|
||||
@ -613,7 +633,7 @@ void ICODE::writeDU()
|
||||
}
|
||||
|
||||
/* 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++)
|
||||
{
|
||||
if (not du1.used(i))
|
||||
|
||||
@ -122,7 +122,7 @@ void Function::findIdioms()
|
||||
{
|
||||
if ((pIcode->ll()->src().proc.proc->retVal.type==TYPE_LONG_SIGN)
|
||||
|| (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 */
|
||||
|
||||
@ -102,20 +102,20 @@ bool Idiom18::match(iICODE picode)
|
||||
m_is_dec = m_icodes[1]->ll()->match(iDEC);
|
||||
|
||||
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;
|
||||
regi = m_icodes[0]->ll()->dst.regi;
|
||||
if( not ( m_icodes[2]->ll()->match(iCMP) && (m_icodes[2]->ll()->dst.regi == regi) &&
|
||||
regi = m_icodes[0]->ll()->m_dst.regi;
|
||||
if( not ( m_icodes[2]->ll()->match(iCMP,regi) &&
|
||||
m_icodes[3]->ll()->conditionalJump() ) )
|
||||
return false;
|
||||
// Simple matching finished, select apropriate matcher based on dst type
|
||||
/* 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 */
|
||||
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;
|
||||
// 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))
|
||||
// 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;
|
||||
else /* indexed */
|
||||
{
|
||||
@ -141,20 +141,20 @@ bool Idiom18::match(iICODE picode)
|
||||
break;
|
||||
case 1: /* register variable */
|
||||
/* 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;
|
||||
}
|
||||
break;
|
||||
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;
|
||||
}
|
||||
break;
|
||||
case 3: // indexed
|
||||
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;
|
||||
}
|
||||
@ -200,15 +200,15 @@ bool Idiom19::match(iICODE picode)
|
||||
m_is_dec = m_icodes[0]->ll()->match(iDEC);
|
||||
if ( not m_icodes[1]->ll()->conditionalJump() )
|
||||
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 */ ;
|
||||
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)) ||
|
||||
// ((picode->ll()->dst.regi == rDI) && (pproc->flg & DI_REGVAR)))
|
||||
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;
|
||||
}
|
||||
@ -257,12 +257,12 @@ bool Idiom20::match(iICODE picode)
|
||||
for(int i=0; i<4; ++i)
|
||||
m_icodes[i] =picode++;
|
||||
/* 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;
|
||||
|
||||
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 */
|
||||
if (ll_dest.regi == 0) /* global variable */
|
||||
{
|
||||
@ -284,7 +284,7 @@ bool Idiom20::match(iICODE picode)
|
||||
type = 3;
|
||||
/* 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());
|
||||
if (m_icodes[2]->ll()->match(iCMP,(eReg)regi) && m_icodes[3]->ll()->conditionalJump())
|
||||
{
|
||||
|
||||
@ -77,13 +77,13 @@ bool Idiom17::match(iICODE picode)
|
||||
if (m_icodes[1]->ll()->match(iPOP))
|
||||
{
|
||||
int i=0;
|
||||
regi = m_icodes[1]->ll()->dst.regi;
|
||||
regi = m_icodes[1]->ll()->m_dst.regi;
|
||||
if ((regi >= rAX) && (regi <= rBX))
|
||||
i++;
|
||||
|
||||
while (picode != m_end && picode->ll()->match(iPOP))
|
||||
{
|
||||
if (picode->ll()->dst.regi != regi)
|
||||
if (picode->ll()->m_dst.regi != regi)
|
||||
break;
|
||||
i++;
|
||||
m_icodes.push_back(picode++);
|
||||
|
||||
@ -28,13 +28,13 @@ bool Idiom14::match(iICODE pIcode)
|
||||
m_icodes[0]=pIcode++;
|
||||
m_icodes[1]=pIcode++;
|
||||
/* 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)))
|
||||
{
|
||||
/* Check for XOR regH, regH */
|
||||
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_regL == rAX) && (m_regH == rDX))
|
||||
@ -52,7 +52,7 @@ int Idiom14::action()
|
||||
AstIdent *lhs;
|
||||
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);
|
||||
m_icodes[0]->setRegDU( m_regH, eDEF);
|
||||
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;
|
||||
|
||||
/* 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))
|
||||
{
|
||||
/* 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()->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);
|
||||
return true;
|
||||
@ -102,9 +102,11 @@ int Idiom13::action()
|
||||
{
|
||||
AstIdent *lhs;
|
||||
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);
|
||||
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);
|
||||
m_icodes[0]->setAsgn(lhs, rhs);
|
||||
m_icodes[1]->invalidate();
|
||||
|
||||
@ -32,17 +32,17 @@ bool Idiom11::match (iICODE picode)
|
||||
switch (type)
|
||||
{
|
||||
case GLOB_VAR:
|
||||
if ((m_icodes[2]->ll()->dst.segValue == m_icodes[0]->ll()->dst.segValue) &&
|
||||
(m_icodes[2]->ll()->dst.off == m_icodes[0]->ll()->dst.off))
|
||||
if ((m_icodes[2]->ll()->m_dst.segValue == m_icodes[0]->ll()->m_dst.segValue) &&
|
||||
(m_icodes[2]->ll()->m_dst.off == m_icodes[0]->ll()->m_dst.off))
|
||||
return true;
|
||||
break;
|
||||
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;
|
||||
break;
|
||||
case PARAM:
|
||||
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;
|
||||
break;
|
||||
default:
|
||||
@ -82,11 +82,11 @@ bool Idiom16::match (iICODE picode)
|
||||
for(int i=0; i<3; ++i)
|
||||
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 (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[2]->ll()->match((eReg)regi))
|
||||
return true;
|
||||
@ -97,7 +97,7 @@ int Idiom16::action()
|
||||
{
|
||||
AstIdent *lhs;
|
||||
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());
|
||||
m_icodes[0]->setAsgn(lhs, rhs);
|
||||
m_icodes[1]->invalidate();
|
||||
|
||||
@ -31,9 +31,9 @@ int Idiom8::action()
|
||||
AstIdent *lhs;
|
||||
Expr *expr;
|
||||
eReg regH,regL;
|
||||
regH=m_icodes[0]->ll()->dst.regi;
|
||||
regL=m_icodes[1]->ll()->dst.regi;
|
||||
idx = m_func->localId.newLongReg (TYPE_LONG_SIGN, regH, regL, m_icodes[0]);
|
||||
regH=m_icodes[0]->ll()->m_dst.regi;
|
||||
regL=m_icodes[1]->ll()->m_dst.regi;
|
||||
idx = m_func->localId.newLongReg (TYPE_LONG_SIGN, LONGID_TYPE(regH,regL), m_icodes[0]);
|
||||
lhs = AstIdent::LongIdx (idx);
|
||||
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))
|
||||
return false;
|
||||
m_icodes.clear();
|
||||
regi = pIcode->ll()->dst.regi;
|
||||
regi = pIcode->ll()->m_dst.regi;
|
||||
m_icodes.push_back(pIcode++);
|
||||
while( (pIcode!=m_end) and
|
||||
pIcode->ll()->match(iSHL,(eReg)regi,I) and
|
||||
@ -81,7 +81,7 @@ int Idiom15::action()
|
||||
AstIdent *lhs;
|
||||
|
||||
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_func->localId);
|
||||
rhs = new Constant(m_icodes.size(), 2);
|
||||
@ -122,10 +122,10 @@ int Idiom12::action()
|
||||
AstIdent *lhs;
|
||||
|
||||
eReg regH,regL;
|
||||
regL=m_icodes[0]->ll()->dst.regi;
|
||||
regH=m_icodes[1]->ll()->dst.regi;
|
||||
regL=m_icodes[0]->ll()->m_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);
|
||||
m_icodes[0]->setRegDU( regH, USE_DEF);
|
||||
expr = new BinaryOperator(SHL,lhs, new Constant(1, 2));
|
||||
@ -161,9 +161,9 @@ int Idiom9::action()
|
||||
AstIdent *lhs;
|
||||
Expr *rhs,*expr;
|
||||
eReg regH,regL;
|
||||
regL=m_icodes[1]->ll()->dst.regi;
|
||||
regH=m_icodes[0]->ll()->dst.regi;
|
||||
idx = m_func->localId.newLongReg (TYPE_LONG_UNSIGN,regH,regL,m_icodes[0]);
|
||||
regL=m_icodes[1]->ll()->m_dst.regi;
|
||||
regH=m_icodes[0]->ll()->m_dst.regi;
|
||||
idx = m_func->localId.newLongReg (TYPE_LONG_UNSIGN,LONGID_TYPE(regH,regL),m_icodes[0]);
|
||||
lhs = AstIdent::LongIdx (idx);
|
||||
m_icodes[0]->setRegDU(regL, USE_DEF);
|
||||
expr = new BinaryOperator(SHR,lhs, new Constant(1, 2));
|
||||
|
||||
@ -26,7 +26,7 @@ bool Idiom21::match (iICODE picode)
|
||||
if (not m_icodes[1]->ll()->testFlags(I))
|
||||
return false;
|
||||
|
||||
dst = &m_icodes[0]->ll()->dst;
|
||||
dst = &m_icodes[0]->ll()->m_dst;
|
||||
src = &m_icodes[0]->ll()->src();
|
||||
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());
|
||||
rhs = new Constant(m_icodes[1]->ll()->src().getImm2(), 4);
|
||||
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();
|
||||
return 2;
|
||||
}
|
||||
@ -63,7 +63,7 @@ bool Idiom7::match(iICODE picode)
|
||||
return false;
|
||||
const LLOperand *dst, *src;
|
||||
m_icode=picode;
|
||||
dst = &picode->ll()->dst;
|
||||
dst = &picode->ll()->m_dst;
|
||||
src = &picode->ll()->src();
|
||||
if (dst->regi == 0) /* global variable */
|
||||
{
|
||||
@ -87,7 +87,7 @@ int Idiom7::action()
|
||||
Expr *lhs;
|
||||
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->du.use = 0; /* clear register used in iXOR */
|
||||
m_icode->du.use.reset(); /* clear register used in iXOR */
|
||||
m_icode->ll()->setFlags(I);
|
||||
return 1;
|
||||
}
|
||||
@ -116,7 +116,7 @@ bool Idiom10::match(iICODE pIcode)
|
||||
/* Check OR reg, reg */
|
||||
if (not m_icodes[0]->ll()->testFlags(I) &&
|
||||
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()
|
||||
{
|
||||
return true;
|
||||
@ -128,8 +128,9 @@ int Idiom10::action()
|
||||
{
|
||||
m_icodes[0]->ll()->set(iCMP,I);
|
||||
m_icodes[0]->ll()->replaceSrc(LLOperand::CreateImm2(0));
|
||||
m_icodes[0]->du.def = 0;
|
||||
m_icodes[0]->du1.numRegsDef = 0;
|
||||
m_icodes[0]->du.def.reset(); //TODO: this defines FLAGS
|
||||
m_icodes[0]->du1.clearAllDefs();
|
||||
//m_icodes[0]->du1.numRegsDef = 0;
|
||||
return 2;
|
||||
|
||||
}
|
||||
|
||||
113
src/locident.cpp
113
src/locident.cpp
@ -10,10 +10,9 @@
|
||||
#include "dcc.h"
|
||||
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)
|
||||
{
|
||||
macro[0]=0;
|
||||
@ -24,6 +23,32 @@ ID::ID(hlType t, frameType f) : type(t),illegal(false),hasMacro(false)
|
||||
macro[0]=0;
|
||||
memset(&id,0,sizeof(id));
|
||||
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
|
||||
* entry; otherwise creates a new register identifier node of type
|
||||
* 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;
|
||||
//iICODE ix_;
|
||||
/* Check for entry in the table */
|
||||
for (idx = 0; idx < id_arr.size(); idx++)
|
||||
{
|
||||
ID &entry(id_arr[idx]);
|
||||
if(!entry.isLong() || (entry.loc != REG_FRAME))
|
||||
continue;
|
||||
if (/*(locSym->id[idx].type == t) && Not checking type */
|
||||
(entry.id.longId.h == regH) &&
|
||||
(entry.id.longId.l == regL))
|
||||
(entry.longId().h() == regH) &&
|
||||
(entry.longId().l() == regL))
|
||||
{
|
||||
/* Check for occurrence in the list */
|
||||
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 */
|
||||
newIdent (t, REG_FRAME);
|
||||
id_arr[id_arr.size()-1].idx.push_back(ix_);
|
||||
idx = id_arr.size() - 1;
|
||||
id_arr[idx].id.longId.h = regH;
|
||||
id_arr[idx].id.longId.l = regL;
|
||||
return (idx);
|
||||
id_arr.push_back(ID(t, LONGID_TYPE(regH,regL)));
|
||||
id_arr.back().idx.push_back(ix_);
|
||||
return (id_arr.size() - 1);
|
||||
}
|
||||
/* Returns an identifier conditional expression node of type TYPE_LONG or
|
||||
* 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 */
|
||||
newIdent (t, GLB_FRAME);
|
||||
idx = 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);
|
||||
id_arr.push_back(ID(t, LONGGLB_TYPE(seg,offH,offL)));
|
||||
return (id_arr.size() - 1);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -246,9 +270,11 @@ int LOCAL_ID::newLongStk(hlType t, int offH, int offL)
|
||||
/* Check for entry in the table */
|
||||
for (idx = 0; idx < id_arr.size(); idx++)
|
||||
{
|
||||
if(id_arr[idx].loc!=STK_FRAME)
|
||||
continue;
|
||||
if ((id_arr[idx].type == t) &&
|
||||
(id_arr[idx].id.longStkId.offH == offH) &&
|
||||
(id_arr[idx].id.longStkId.offL == offL))
|
||||
(id_arr[idx].longStkId().offH == offH) &&
|
||||
(id_arr[idx].longStkId().offL == offL))
|
||||
return (idx);
|
||||
}
|
||||
|
||||
@ -257,11 +283,8 @@ int LOCAL_ID::newLongStk(hlType t, int offH, int offL)
|
||||
flagByteWordId (offL);
|
||||
|
||||
/* Create new identifier */
|
||||
newIdent (t, STK_FRAME);
|
||||
idx = id_arr.size() - 1;
|
||||
id_arr[idx].id.longStkId.offH = offH;
|
||||
id_arr[idx].id.longStkId.offL = offL;
|
||||
return (idx);
|
||||
id_arr.push_back(ID(t,LONG_STKID_TYPE(offH,offL)));
|
||||
return (id_arr.size() - 1);
|
||||
}
|
||||
|
||||
|
||||
@ -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 */
|
||||
{
|
||||
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)
|
||||
pIcode->setRegDU( pmL->regi, du); /* low part */
|
||||
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
|
||||
* pProc : ptr to current procedure record
|
||||
* 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 */
|
||||
const LLOperand *pmHdst, *pmLdst, *pmHsrc, *pmLsrc;
|
||||
|
||||
pmHdst = &pIcode->ll()->dst;
|
||||
pmLdst = &atOffset.dst;
|
||||
pmHdst = &pIcode->ll()->m_dst;
|
||||
pmLdst = &atOffset.m_dst;
|
||||
pmHsrc = &pIcode->ll()->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))
|
||||
{
|
||||
@ -364,18 +403,18 @@ boolT checkLongEq (LONG_STKID_TYPE longId, iICODE pIcode, int i, Function * pPro
|
||||
* idx : idx into icode array
|
||||
* pProc : ptr to current procedure record
|
||||
* 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)
|
||||
{
|
||||
/* pointers to LOW_LEVEL icodes */
|
||||
const LLOperand *pmHdst, *pmLdst, *pmHsrc, *pmLsrc;
|
||||
|
||||
pmHdst = &pIcode->ll()->dst;
|
||||
pmLdst = &atOffset.dst;
|
||||
pmHdst = &pIcode->ll()->m_dst;
|
||||
pmLdst = &atOffset.m_dst;
|
||||
pmHsrc = &pIcode->ll()->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);
|
||||
if ( not pIcode->ll()->testFlags(NO_SRC) )
|
||||
@ -384,7 +423,7 @@ boolT checkLongRegEq (LONGID_TYPE longId, iICODE pIcode, int i,
|
||||
}
|
||||
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.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) ||
|
||||
(id->type == TYPE_LONG_UNSIGN)))
|
||||
{
|
||||
if (id->id.longId.h == regi)
|
||||
return (id->id.longId.l);
|
||||
else if (id->id.longId.l == regi)
|
||||
return (id->id.longId.h);
|
||||
if (id->longId().h() == regi)
|
||||
return (id->longId().l());
|
||||
else if (id->longId().l() == regi)
|
||||
return (id->longId().h());
|
||||
}
|
||||
return rUNDEF; // Cristina: please check this!
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
#include <cassert>
|
||||
#include "machine_x86.h"
|
||||
#include "icode.h"
|
||||
// Index registers **** temp solution
|
||||
static const std::string regNames[] = {
|
||||
"undef",
|
||||
@ -8,7 +9,7 @@ static const std::string regNames[] = {
|
||||
"es", "cs", "ss", "ds",
|
||||
"al", "cl", "dl", "bl",
|
||||
"ah", "ch", "dh", "bh",
|
||||
"tmp",
|
||||
"tmp","tmp2",
|
||||
"bx+si", "bx+di", "bp+si", "bp+di",
|
||||
"si", "di", "bp", "bx"
|
||||
};
|
||||
@ -132,3 +133,12 @@ eReg Machine_X86::compositeParent(eReg reg)
|
||||
}
|
||||
return rUNDEF;
|
||||
}
|
||||
void Machine_X86::writeRegVector (std::ostream &ostr,const LivenessSet ®i)
|
||||
{
|
||||
int j;
|
||||
for (j = rAX; j < INDEX_BX_SI; j++)
|
||||
{
|
||||
if (regi.testReg(j))
|
||||
ostr << regName(eReg(j))<<" ";
|
||||
}
|
||||
}
|
||||
|
||||
126
src/parser.cpp
126
src/parser.cpp
@ -146,8 +146,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
|
||||
eIcode = ICODE();
|
||||
|
||||
eIcode.type = LOW_LEVEL;
|
||||
eIcode.ll()->set(iMOV,0);
|
||||
eIcode.ll()->replaceDst(rTMP);
|
||||
eIcode.ll()->set(iMOV,0,rTMP);
|
||||
if (ll->testFlags(B) )
|
||||
{
|
||||
eIcode.ll()->setFlags( B );
|
||||
@ -171,10 +170,9 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
|
||||
/* iMOD */
|
||||
eIcode = ICODE();
|
||||
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.du = _Icode.du;
|
||||
eIcode.ll()->setFlags( ( ll->getFlag() | SYNTHETIC | IM_TMP_DST) );
|
||||
eIcode.ll()->label = SynthLab++;
|
||||
pIcode = Icode.addIcode(&eIcode);
|
||||
}
|
||||
@ -183,9 +181,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
|
||||
/* MOV rTMP, regDst */
|
||||
eIcode = ICODE();
|
||||
eIcode.type = LOW_LEVEL;
|
||||
eIcode.ll()->set(iMOV,SYNTHETIC);
|
||||
eIcode.ll()->replaceDst(LLOperand::CreateReg2(rTMP));
|
||||
eIcode.ll()->replaceSrc(_Icode.ll()->dst);
|
||||
eIcode.ll()->set(iMOV,SYNTHETIC,rTMP,_Icode.ll()->m_dst);
|
||||
eIcode.setRegDU( rTMP, eDEF);
|
||||
if(eIcode.ll()->src().getReg2())
|
||||
{
|
||||
@ -207,11 +203,11 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
|
||||
eIcode.type = LOW_LEVEL;
|
||||
eIcode.ll()->set(iMOV,SYNTHETIC);
|
||||
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.setRegDU( eIcode.ll()->dst.regi, eDEF);
|
||||
eIcode.setRegDU( eIcode.ll()->m_dst.regi, eDEF);
|
||||
}
|
||||
eIcode.ll()->replaceSrc(rTMP);
|
||||
eIcode.setRegDU( rTMP, eUSE);
|
||||
@ -246,7 +242,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
|
||||
if (ll->match(iJA) || ll->match(iJBE) )
|
||||
pstate->JCond.immed++;
|
||||
if (ll->getOpcode() == iJAE || ll->getOpcode() == iJA)
|
||||
pstate->JCond.regi = prev.ll()->dst.regi;
|
||||
pstate->JCond.regi = prev.ll()->m_dst.regi;
|
||||
fBranch = (bool)
|
||||
(ll->getOpcode() == iJB || ll->getOpcode() == iJBE);
|
||||
}
|
||||
@ -258,7 +254,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
|
||||
|
||||
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
|
||||
to FollowCtrl() */
|
||||
@ -297,7 +293,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
|
||||
int size;
|
||||
|
||||
/* 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)->
|
||||
|
||||
/* 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]))
|
||||
{
|
||||
Icode.back().ll()->dst.off = pstate->r[rAH];
|
||||
Icode.back().ll()->m_dst.off = pstate->r[rAH];
|
||||
}
|
||||
else /* Program termination: int20h, int27h */
|
||||
done = (boolT)(ll->src().getImm2() == 0x20 ||
|
||||
@ -337,7 +333,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
|
||||
break; **** HERE ***/
|
||||
|
||||
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)
|
||||
pstate->JCond.immed *= 2;
|
||||
@ -348,7 +344,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
|
||||
|
||||
case iLEA:
|
||||
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;
|
||||
|
||||
case iLDS: case iLES:
|
||||
@ -358,7 +354,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
|
||||
offset = LH(&prog.image()[psym->label]);
|
||||
pstate->setState( (ll->getOpcode() == iLDS)? rDS: rES,
|
||||
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;
|
||||
}
|
||||
break;
|
||||
@ -564,7 +560,7 @@ boolT Function::process_CALL (ICODE & pIcode, CALL_GRAPH * pcallGraph, STATE *ps
|
||||
{
|
||||
/* 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
|
||||
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
|
||||
usually wrong! Consider also CALL [BP+0E] in which the
|
||||
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
|
||||
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;
|
||||
}
|
||||
off = pstate->r[pIcode.ll()->dst.seg];
|
||||
off = pstate->r[pIcode.ll()->m_dst.seg];
|
||||
off <<=4;
|
||||
off += pstate->r[pIcode.ll()->dst.regi];
|
||||
off += pstate->r[pIcode.ll()->m_dst.regi];
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
off = (uint32_t)(uint16_t)pIcode.ll()->dst.off +
|
||||
((uint32_t)(uint16_t)pIcode.ll()->dst.segValue << 4);
|
||||
off = (uint32_t)(uint16_t)pIcode.ll()->m_dst.off +
|
||||
((uint32_t)(uint16_t)pIcode.ll()->m_dst.segValue << 4);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
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;
|
||||
if (dstReg > 0 && dstReg < INDEX_BX_SI)
|
||||
{
|
||||
@ -709,7 +705,7 @@ static void process_MOV(LLInst & ll, STATE * pstate)
|
||||
int size=2;
|
||||
if((ll.src().regi>=rAL)&&(ll.src().regi<=rBH))
|
||||
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 (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.
|
||||
* Places local variables on the local symbol table.
|
||||
* 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 */
|
||||
pProc->localId.newIntIdx(pm->segValue, pm->off, rBX,TYPE_WORD_SIGN);
|
||||
}
|
||||
pIcode.du.use |= duReg[pm->regi];
|
||||
pIcode.du.use.addReg(pm->regi);
|
||||
}
|
||||
|
||||
else
|
||||
@ -963,7 +946,7 @@ static void use (opLoc d, ICODE & pIcode, Function * pProc, STATE * pstate, int
|
||||
|
||||
/* Use of register */
|
||||
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 */
|
||||
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 */
|
||||
else if ((d == DST) || ((d == SRC) && (not pIcode.ll()->testFlags(I))))
|
||||
{
|
||||
pIcode.du.def |= duReg[pm->regi];
|
||||
pIcode.du1.numRegsDef++;
|
||||
assert(not pIcode.ll()->match(iPUSH));
|
||||
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 */
|
||||
{
|
||||
pIcode.du.def |= duReg[pm->regi];
|
||||
pIcode.du1.numRegsDef++;
|
||||
assert(not pIcode.ll()->match(iPUSH));
|
||||
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)
|
||||
{
|
||||
pIcode.du.def.addReg(rAX);
|
||||
pIcode.du1.numRegsDef++;
|
||||
pIcode.du1.addDef(rAX);
|
||||
}
|
||||
else
|
||||
{
|
||||
pIcode.du.def.addReg(rAX).addReg(rDX);
|
||||
pIcode.du1.numRegsDef += 2;
|
||||
pIcode.du1.addDef(rAX).addDef(rDX);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1107,13 +1092,13 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate)
|
||||
if (cb == 1) /* uint8_t */
|
||||
{
|
||||
pIcode.du.def.addReg(rAX);
|
||||
pIcode.du1.numRegsDef++;
|
||||
pIcode.du1.addDef(rAX);
|
||||
pIcode.du.use.addReg(rAL);
|
||||
}
|
||||
else /* uint16_t */
|
||||
{
|
||||
pIcode.du.def.addReg(rDX).addReg(rAX);
|
||||
pIcode.du1.numRegsDef += 2;
|
||||
pIcode.du1.addDef(rAX).addDef(rDX);
|
||||
pIcode.du.use.addReg(rAX);
|
||||
}
|
||||
break;
|
||||
@ -1134,9 +1119,13 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate)
|
||||
break;
|
||||
|
||||
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;
|
||||
// fallthrough
|
||||
}
|
||||
case iMOV:
|
||||
use(SRC, 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:
|
||||
pIcode.du.def.addReg(rCX);
|
||||
pIcode.du1.numRegsDef++;
|
||||
pIcode.du1.addDef(rCX);
|
||||
case iJCXZ:
|
||||
pIcode.du.use.addReg(rCX);
|
||||
break;
|
||||
|
||||
case iREPNE_CMPS: case iREPE_CMPS: case iREP_MOVS:
|
||||
pIcode.du.addDefinedAndUsed(rCX);
|
||||
pIcode.du1.numRegsDef++;
|
||||
pIcode.du1.addDef(rCX);
|
||||
case iCMPS: case iMOVS:
|
||||
pIcode.du.addDefinedAndUsed(rSI);
|
||||
pIcode.du.addDefinedAndUsed(rDI);
|
||||
pIcode.du1.numRegsDef += 2;
|
||||
pIcode.du1.addDef(rSI).addDef(rDI);
|
||||
pIcode.du.use.addReg(rES).addReg(sseg);
|
||||
break;
|
||||
|
||||
case iREPNE_SCAS: case iREPE_SCAS: case iREP_STOS: case iREP_INS:
|
||||
pIcode.du.addDefinedAndUsed(rCX);
|
||||
pIcode.du1.numRegsDef++;
|
||||
pIcode.du1.addDef(rCX);
|
||||
case iSCAS: case iSTOS: case iINS:
|
||||
pIcode.du.def.addReg(rDI);
|
||||
pIcode.du1.numRegsDef++;
|
||||
pIcode.du1.addDef(rDI);
|
||||
if (pIcode.ll()->getOpcode() == iREP_INS || pIcode.ll()->getOpcode()== iINS)
|
||||
{
|
||||
pIcode.du.use.addReg(rDI).addReg(rES).addReg(rDX);
|
||||
@ -1194,28 +1183,31 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate)
|
||||
|
||||
case iREP_LODS:
|
||||
pIcode.du.addDefinedAndUsed(rCX);
|
||||
pIcode.du1.numRegsDef++;
|
||||
pIcode.du1.addDef(rCX);
|
||||
case iLODS:
|
||||
{
|
||||
eReg r = (cb==2)? rAX: rAL;
|
||||
pIcode.du.addDefinedAndUsed(rSI);
|
||||
pIcode.du.def.addReg((cb==2)? rAX: rAL);
|
||||
pIcode.du1.numRegsDef += 2;
|
||||
pIcode.du1.addDef(rSI);
|
||||
pIcode.du.def.addReg(r);
|
||||
pIcode.du1.addDef(r);
|
||||
pIcode.du.use.addReg(sseg);
|
||||
}
|
||||
break;
|
||||
|
||||
case iREP_OUTS:
|
||||
pIcode.du.addDefinedAndUsed(rCX);
|
||||
pIcode.du1.numRegsDef++;
|
||||
pIcode.du1.addDef(rCX);
|
||||
case iOUTS:
|
||||
pIcode.du.addDefinedAndUsed(rSI);
|
||||
pIcode.du1.numRegsDef++;
|
||||
pIcode.du.use |= duReg[rDX] | duReg[sseg];
|
||||
pIcode.du1.addDef(rSI);
|
||||
pIcode.du.use.addReg(rDX).addReg(sseg);
|
||||
break;
|
||||
|
||||
case iIN: case iOUT:
|
||||
def(DST, pIcode, this, pstate, cb);
|
||||
if (! Imm)
|
||||
{
|
||||
pIcode.du.use |= duReg[rDX];
|
||||
pIcode.du.use.addReg(rDX);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -97,7 +97,8 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
|
||||
bool regExist=false;
|
||||
condId type;
|
||||
Function * tproc;
|
||||
eReg regL, regH; /* Registers involved in arguments */
|
||||
eReg regL = rUNDEF;
|
||||
eReg regH; /* Registers involved in arguments */
|
||||
|
||||
/* Flag ticode as having register arguments */
|
||||
tproc = ticode->hl()->call.proc;
|
||||
@ -113,6 +114,7 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
|
||||
if (lhs_reg)
|
||||
{
|
||||
regL = id_arr[lhs_reg->regiIdx].id.regi;
|
||||
assert(regL!=rUNDEF);
|
||||
if (regL < rAL)
|
||||
tidx = tproc->localId.newByteWordReg(TYPE_WORD_SIGN, regL);
|
||||
else
|
||||
@ -133,9 +135,10 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
|
||||
else if (type == LONG_VAR)
|
||||
{
|
||||
int longIdx = lhs->ident.idNode.longIdx;
|
||||
regL = id_arr[longIdx].id.longId.l;
|
||||
regH = id_arr[longIdx].id.longId.h;
|
||||
tidx = tproc->localId.newLongReg(TYPE_LONG_SIGN, regH, regL, tproc->Icode.begin() /*0*/);
|
||||
LONGID_TYPE regHL = id_arr[longIdx].longId();
|
||||
regH=regHL.h();
|
||||
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 */
|
||||
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.type = TYPE_LONG_SIGN;
|
||||
assert(regL!=rUNDEF);
|
||||
tproc->localId.id_arr[tidx].name = newsym.name;
|
||||
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) {
|
||||
case REGISTER:
|
||||
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)
|
||||
newsym.type = TYPE_WORD_SIGN;
|
||||
else
|
||||
@ -199,8 +203,8 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
|
||||
break;
|
||||
case LONG_VAR:
|
||||
id = &id_arr[lhs->ident.idNode.longIdx];
|
||||
picode->du.def &= maskDuReg[id->id.longId.h];
|
||||
picode->du.def &= maskDuReg[id->id.longId.l];
|
||||
picode->du.def.clrReg(id->longId().h());
|
||||
picode->du.def.clrReg(id->longId().l());
|
||||
newsym.type = TYPE_LONG_SIGN;
|
||||
break;
|
||||
default:
|
||||
|
||||
@ -250,7 +250,7 @@ void Function::propLongStk (int i, const ID &pLocId)
|
||||
continue;
|
||||
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())
|
||||
{
|
||||
@ -290,7 +290,7 @@ void Function::propLongStk (int i, const ID &pLocId)
|
||||
/* Check long conditional (i.e. 2 CMPs and 3 branches */
|
||||
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));
|
||||
}
|
||||
@ -300,7 +300,7 @@ void Function::propLongStk (int i, const ID &pLocId)
|
||||
* 2 CMPs and 2 branches */
|
||||
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));
|
||||
}
|
||||
@ -329,9 +329,9 @@ int Function::findBackwarLongDefs(int loc_ident_idx, const ID &pLocId, iICODE be
|
||||
switch (icode.ll()->getOpcode())
|
||||
{
|
||||
case iMOV:
|
||||
pmH = &icode.ll()->dst;
|
||||
pmL = &next1->ll()->dst;
|
||||
if ((pLocId.id.longId.h == pmH->regi) && (pLocId.id.longId.l == pmL->regi))
|
||||
pmH = &icode.ll()->m_dst;
|
||||
pmL = &next1->ll()->m_dst;
|
||||
if ((pLocId.longId().h() == pmH->regi) && (pLocId.longId().l() == pmL->regi))
|
||||
{
|
||||
localId.id_arr[loc_ident_idx].idx.push_back(pIcode);//idx-1//insert
|
||||
icode.setRegDU( pmL->regi, eDEF);
|
||||
@ -344,9 +344,9 @@ int Function::findBackwarLongDefs(int loc_ident_idx, const ID &pLocId, iICODE be
|
||||
break;
|
||||
|
||||
case iPOP:
|
||||
pmH = &next1->ll()->dst;
|
||||
pmL = &icode.ll()->dst;
|
||||
if ((pLocId.id.longId.h == pmH->regi) && (pLocId.id.longId.l == pmL->regi))
|
||||
pmH = &next1->ll()->m_dst;
|
||||
pmL = &icode.ll()->m_dst;
|
||||
if ((pLocId.longId().h() == pmH->regi) && (pLocId.longId().l() == pmL->regi))
|
||||
{
|
||||
asgn.lhs = AstIdent::LongIdx (loc_ident_idx);
|
||||
icode.setRegDU( pmH->regi, eDEF);
|
||||
@ -360,9 +360,9 @@ int Function::findBackwarLongDefs(int loc_ident_idx, const ID &pLocId, iICODE be
|
||||
// /**** others missing ***/
|
||||
|
||||
case iAND: case iOR: case iXOR:
|
||||
pmL = &icode.ll()->dst;
|
||||
pmH = &next1->ll()->dst;
|
||||
if ((pLocId.id.longId.h == pmH->regi) && (pLocId.id.longId.l == pmL->regi))
|
||||
pmL = &icode.ll()->m_dst;
|
||||
pmH = &next1->ll()->m_dst;
|
||||
if ((pLocId.longId().h() == pmH->regi) && (pLocId.longId().l() == pmL->regi))
|
||||
{
|
||||
asgn.lhs = AstIdent::LongIdx (loc_ident_idx);
|
||||
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:
|
||||
{
|
||||
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_op2(next1->ll()->src());
|
||||
eReg srcReg1=src_op1.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);
|
||||
|
||||
@ -428,11 +428,10 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be
|
||||
|
||||
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_op2(next1->ll()->src());
|
||||
if ((ref_long.h == src_op1.getReg2()) &&
|
||||
(ref_long.l == src_op2.getReg2()))
|
||||
if ((ref_long.h() == src_op1.getReg2()) && (ref_long.l() == src_op2.getReg2()))
|
||||
{
|
||||
asgn.rhs = AstIdent::LongIdx (loc_ident_idx);
|
||||
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 ****/
|
||||
|
||||
case iAND: case iOR: case iXOR:
|
||||
pmL = &pIcode->ll()->dst;
|
||||
pmH = &next1->ll()->dst;
|
||||
if ((pLocId.id.longId.h == pmH->regi) &&
|
||||
(pLocId.id.longId.l == pmL->regi))
|
||||
pmL = &pIcode->ll()->m_dst;
|
||||
pmH = &next1->ll()->m_dst;
|
||||
if ((pLocId.longId().h() == pmH->regi) && (pLocId.longId().l() == pmL->regi))
|
||||
{
|
||||
asgn.lhs = AstIdent::LongIdx (loc_ident_idx);
|
||||
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 */
|
||||
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) ?
|
||||
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 */
|
||||
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 !
|
||||
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)) */
|
||||
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.rhs = new Constant(0, 4); /* long 0 */
|
||||
|
||||
117
src/scanner.cpp
117
src/scanner.cpp
@ -6,6 +6,8 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include <cstring>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include "dcc.h"
|
||||
#include "scanner.h"
|
||||
#include "project.h"
|
||||
@ -411,33 +413,116 @@ int disassembleOneLibDisasm(uint32_t ip,x86_insn_t &l)
|
||||
}
|
||||
eReg convertRegister(const x86_reg_t ®)
|
||||
{
|
||||
if( (reg_pc==reg.type) || (0==reg.id))
|
||||
return rUNDEF;
|
||||
|
||||
eReg regmap[]={ rUNDEF,
|
||||
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,
|
||||
rSP,rBP,rSI,rDI,
|
||||
rAL,rCL,rDL,rBL,
|
||||
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(regmap[reg.id]!=rUNDEF);
|
||||
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 res;
|
||||
switch(from.type)
|
||||
{
|
||||
case op_unused:
|
||||
break;
|
||||
case op_register:
|
||||
return LLOperand::CreateReg2(convertRegister(from.data.reg));
|
||||
res.regi = convertRegister(from.data.reg); break;
|
||||
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:
|
||||
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.
|
||||
@ -481,15 +566,8 @@ eErrorId scan(uint32_t ip, ICODE &p)
|
||||
if(p.insn.x86_get_branch_target())
|
||||
decodeBranchTgt(p.insn);
|
||||
}
|
||||
x86_op_t *dst_op = 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;
|
||||
// LLOperand conv = convertOperand(*p.insn.get_dest());
|
||||
// assert(conv==p.ll()->dst);
|
||||
}
|
||||
if (p.ll()->getOpcode())
|
||||
{
|
||||
/* 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 */
|
||||
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
|
||||
* provide the value of this segment in the field segValue. */
|
||||
@ -619,7 +697,7 @@ static void rm(int i)
|
||||
}
|
||||
//pIcode->insn.get_dest()->
|
||||
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);
|
||||
}
|
||||
|
||||
@ -656,10 +734,9 @@ static void segrm(int i)
|
||||
static void regop(int i)
|
||||
{
|
||||
setAddress(i, false, 0, ((int16_t)i & 7) + rAX, 0);
|
||||
pIcode->ll()->replaceDst(LLOperand::CreateReg2(pIcode->ll()->src().getReg2()));
|
||||
// pIcode->ll()->dst.regi = pIcode->ll()->src.regi;
|
||||
}
|
||||
pIcode->ll()->replaceDst(pIcode->ll()->src());
|
||||
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
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 */
|
||||
ll->setOpcode(transTable[REG(*pInst)]); /* valid on bytes */
|
||||
rm(i);
|
||||
ll->replaceSrc( pIcode->ll()->dst );
|
||||
ll->replaceSrc( pIcode->ll()->m_dst );
|
||||
if (ll->match(iJMP) || ll->match(iCALL) || ll->match(iCALLF))
|
||||
ll->setFlags(NO_OPS);
|
||||
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))
|
||||
{
|
||||
pIcode->ll()->replaceSrc( pIcode->ll()->dst );
|
||||
pIcode->ll()->replaceSrc( pIcode->ll()->m_dst );
|
||||
setAddress(i, true, 0, rAX, 0); /* dst = AX */
|
||||
}
|
||||
else if (opcode == iNEG || opcode == iNOT)
|
||||
@ -838,7 +915,7 @@ static void data2(int )
|
||||
* set to NO_OPS. */
|
||||
if (pIcode->ll()->getOpcode() == iENTER)
|
||||
{
|
||||
pIcode->ll()->dst.off = getWord();
|
||||
pIcode->ll()->m_dst.off = getWord();
|
||||
pIcode->ll()->setFlags(NO_OPS);
|
||||
}
|
||||
else
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user