Changes
This commit is contained in:
@@ -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 *);
|
||||
|
||||
|
||||
|
||||
155
include/icode.h
155
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,21 +32,24 @@ 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);
|
||||
// }
|
||||
|
||||
// LivenessSet(LivenessSet &&other) : LivenessSet()
|
||||
// {
|
||||
// swap(*this,other);
|
||||
// }
|
||||
LivenessSet &operator=(LivenessSet other)
|
||||
{
|
||||
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 */
|
||||
@@ -180,8 +229,8 @@ public:
|
||||
void setCall(Function *proc);
|
||||
HLTYPE(hlIcode op=HLI_INVALID) : opcode(op)
|
||||
{}
|
||||
// HLTYPE() // help valgrind find uninitialized HLTYPES
|
||||
// {}
|
||||
// HLTYPE() // help valgrind find uninitialized HLTYPES
|
||||
// {}
|
||||
HLTYPE & operator=(const HLTYPE &l)
|
||||
{
|
||||
exp = l.exp;
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
@@ -460,13 +537,13 @@ public:
|
||||
const LLInst * ll() const { return &m_ll;}
|
||||
|
||||
HLTYPE * hlU() {
|
||||
// assert(type==HIGH_LEVEL);
|
||||
// assert(m_hl.opcode!=HLI_INVALID);
|
||||
// assert(type==HIGH_LEVEL);
|
||||
// assert(m_hl.opcode!=HLI_INVALID);
|
||||
return &m_hl;
|
||||
}
|
||||
const HLTYPE * hl() const {
|
||||
// assert(type==HIGH_LEVEL);
|
||||
// assert(m_hl.opcode!=HLI_INVALID);
|
||||
// assert(type==HIGH_LEVEL);
|
||||
// assert(m_hl.opcode!=HLI_INVALID);
|
||||
return &m_hl;
|
||||
}
|
||||
void hl(const HLTYPE &v) { m_hl=v;}
|
||||
@@ -501,9 +578,9 @@ public:
|
||||
{
|
||||
}
|
||||
public:
|
||||
const MachineBasicBlock* getParent() const { return Parent; }
|
||||
MachineBasicBlock* getParent() { return Parent; }
|
||||
//unsigned getNumOperands() const { return (unsigned)Operands.size(); }
|
||||
const MachineBasicBlock* getParent() const { return Parent; }
|
||||
MachineBasicBlock* getParent() { return Parent; }
|
||||
//unsigned getNumOperands() const { return (unsigned)Operands.size(); }
|
||||
|
||||
};
|
||||
/** Map n low level instructions to m high level instructions
|
||||
|
||||
@@ -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 */
|
||||
/* 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;
|
||||
LONG_STKID_TYPE(int h,int l) : offH(h),offL(l) {}
|
||||
};
|
||||
/* For TYPE_LONG_(UN)SIGN registers */
|
||||
struct LONGID_TYPE
|
||||
{ /* For TYPE_LONG_(UN)SIGN registers */
|
||||
eReg h; /* high register */
|
||||
eReg l; /* low register */
|
||||
{
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user