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

View File

@ -407,6 +407,20 @@ unsigned int Ia32_Decoder::ia32_insn_implicit_ops( unsigned int impl_idx ) {
if (!op) {
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 */

View File

@ -107,13 +107,13 @@ 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 );
size = 4;
} else {
x86_imm_sized( buf, buf_len,&op->data.absolute.offset.off16, 2 );
x86_imm_sized( buf, buf_len, &op->data.absolute.offset.off16, 2 );
size = 2;
}
x86_imm_sized( buf+size, buf_len-size, &op->data.absolute.segment, 2 );
@ -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;
size = x86_imm_signsized(buf, buf_len,&offset_val, 2);
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;

View File

@ -8,15 +8,16 @@
#include <cstdlib>
#include <cassert>
#include <stdint.h>
/* 'NEW" types
* __________________________________________________________________________*/
#ifndef LIBDISASM_QWORD_H /* do not interfere with qword.h */
#define LIBDISASM_QWORD_H
#ifdef _MSC_VER
typedef __int64 qword_t;
#else
typedef int64_t qword_t;
#endif
#define LIBDISASM_QWORD_H
#ifdef _MSC_VER
typedef __int64 qword_t;
#else
typedef int64_t qword_t;
#endif
#endif
#include <sys/types.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()
@ -707,9 +706,9 @@ public:
* (buf, buf_len, buf_rva, offset, len, insn, func, arg, resolve_func)
* ...but of course all of these are not used at the same time.
*/
class X86_Disasm
{
public:
class X86_Disasm
{
public:
/* Function prototype for caller-supplied callback routine
* These callbacks are intended to process 'insn' further, e.g. by
* adding it to a linked list, database, etc */
@ -725,12 +724,12 @@ public:
* should be returned. */
typedef int32_t (*DISASM_RESOLVER)( x86_op_t *op, x86_insn_t * current_insn,
void *arg );
protected:
protected:
DISASM_REPORTER __x86_reporter_func;
void * __x86_reporter_arg;
Ia32_Decoder m_decoder;
public:
public:
X86_Disasm( x86_options options=opt_none,DISASM_REPORTER reporter=0, void *arg=0 ) :
__x86_reporter_func(reporter),
__x86_reporter_arg(arg) {
@ -817,7 +816,7 @@ public:
unsigned int x86_ip_reg(void);
unsigned int x86_flag_reg(void);
};
};
/* Instruction operands: these are stored as a list of explicit and
* implicit operands. It is recommended that the 'foreach' routines

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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> &regi)
{
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 &regi);
static eReg subRegH(eReg reg);
static eReg subRegL(eReg reg);
static bool isMemOff(eReg r);

View File

@ -52,18 +52,23 @@ static const char *hexStr (uint16_t i)
void ICODE::setRegDU (eReg regi, operDu du_in)
{
// 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!
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 &regi)
{
int j;
for (j = rAX; j < INDEX_BX_SI; j++)
{
if (regi.testReg(j))
ostr << regName(eReg(j))<<" ";
}
}

View File

@ -146,8 +146,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
eIcode = ICODE();
eIcode.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;
}

View File

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

View File

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

View File

@ -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 &reg)
{
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;
//assert(conv==p.ll()->dst);
}
// 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