More logic operator replacements.
Use Qt string classes.
This commit is contained in:
parent
9cd3226536
commit
d6249916e1
@ -333,7 +333,7 @@ void PerfectHash::traverse(int u)
|
|||||||
while (e)
|
while (e)
|
||||||
{
|
{
|
||||||
w = graphNode[NumEntry+e]-1;
|
w = graphNode[NumEntry+e]-1;
|
||||||
if (!visited[w])
|
if (not visited[w])
|
||||||
{
|
{
|
||||||
g[w] = (abs(e)-1 - g[u]) % NumEntry;
|
g[w] = (abs(e)-1 - g[u]) % NumEntry;
|
||||||
if (g[w] < 0) g[w] += NumEntry; /* Keep these positive */
|
if (g[w] < 0) g[w] += NumEntry; /* Keep these positive */
|
||||||
@ -357,7 +357,7 @@ void PerfectHash::assign(void)
|
|||||||
|
|
||||||
for (v=0; v < NumVert; v++)
|
for (v=0; v < NumVert; v++)
|
||||||
{
|
{
|
||||||
if (!visited[v])
|
if (not visited[v])
|
||||||
{
|
{
|
||||||
g[v] = 0;
|
g[v] = 0;
|
||||||
traverse(v);
|
traverse(v);
|
||||||
|
|||||||
@ -111,7 +111,7 @@ public:
|
|||||||
///
|
///
|
||||||
const Function *getParent() const { return Parent; }
|
const Function *getParent() const { return Parent; }
|
||||||
Function *getParent() { return Parent; }
|
Function *getParent() { return Parent; }
|
||||||
void writeBB(std::ostream &ostr, int lev, Function *pProc, int *numLoc);
|
void writeBB(QTextStream & ostr, int lev, Function *pProc, int *numLoc);
|
||||||
BB * rmJMP(int marker, BB *pBB);
|
BB * rmJMP(int marker, BB *pBB);
|
||||||
void genDU1();
|
void genDU1();
|
||||||
void findBBExps(LOCAL_ID &locals, Function *f);
|
void findBBExps(LOCAL_ID &locals, Function *f);
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "ast.h"
|
#include "ast.h"
|
||||||
|
|
||||||
|
class QTextStream;
|
||||||
|
|
||||||
struct CConv {
|
struct CConv {
|
||||||
enum Type {
|
enum Type {
|
||||||
UNKNOWN=0,
|
UNKNOWN=0,
|
||||||
@ -8,7 +10,7 @@ struct CConv {
|
|||||||
PASCAL
|
PASCAL
|
||||||
};
|
};
|
||||||
virtual void processHLI(Function *func, Expr *_exp, iICODE picode)=0;
|
virtual void processHLI(Function *func, Expr *_exp, iICODE picode)=0;
|
||||||
virtual void writeComments(std::ostream &)=0;
|
virtual void writeComments(QTextStream &)=0;
|
||||||
static CConv * create(Type v);
|
static CConv * create(Type v);
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
@ -16,16 +18,16 @@ protected:
|
|||||||
|
|
||||||
struct C_CallingConvention : public CConv {
|
struct C_CallingConvention : public CConv {
|
||||||
virtual void processHLI(Function *func, Expr *_exp, iICODE picode);
|
virtual void processHLI(Function *func, Expr *_exp, iICODE picode);
|
||||||
virtual void writeComments(std::ostream &);
|
virtual void writeComments(QTextStream &);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int processCArg(Function *callee, Function *pProc, ICODE *picode, size_t numArgs);
|
int processCArg(Function *callee, Function *pProc, ICODE *picode, size_t numArgs);
|
||||||
};
|
};
|
||||||
struct Pascal_CallingConvention : public CConv {
|
struct Pascal_CallingConvention : public CConv {
|
||||||
virtual void processHLI(Function *func, Expr *_exp, iICODE picode);
|
virtual void processHLI(Function *func, Expr *_exp, iICODE picode);
|
||||||
virtual void writeComments(std::ostream &);
|
virtual void writeComments(QTextStream &);
|
||||||
};
|
};
|
||||||
struct Unknown_CallingConvention : public CConv {
|
struct Unknown_CallingConvention : public CConv {
|
||||||
void processHLI(Function *func, Expr *_exp, iICODE picode) {}
|
void processHLI(Function *func, Expr *_exp, iICODE picode) {}
|
||||||
virtual void writeComments(std::ostream &);
|
virtual void writeComments(QTextStream &);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,14 +1,20 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <llvm/ADT/ilist.h>
|
|
||||||
//#include <llvm/ADT/ilist_node.h>
|
|
||||||
#include <bitset>
|
|
||||||
#include <map>
|
|
||||||
#include "BasicBlock.h"
|
#include "BasicBlock.h"
|
||||||
#include "locident.h"
|
#include "locident.h"
|
||||||
#include "state.h"
|
#include "state.h"
|
||||||
#include "icode.h"
|
#include "icode.h"
|
||||||
#include "StackFrame.h"
|
#include "StackFrame.h"
|
||||||
#include "CallConvention.h"
|
#include "CallConvention.h"
|
||||||
|
|
||||||
|
#include <llvm/ADT/ilist.h>
|
||||||
|
//#include <llvm/ADT/ilist_node.h>
|
||||||
|
#include <QtCore/QString>
|
||||||
|
#include <bitset>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
class QIODevice;
|
||||||
|
class QTextStream;
|
||||||
|
|
||||||
/* PROCEDURE NODE */
|
/* PROCEDURE NODE */
|
||||||
struct CALL_GRAPH;
|
struct CALL_GRAPH;
|
||||||
struct Expr;
|
struct Expr;
|
||||||
@ -126,8 +132,8 @@ public:
|
|||||||
FunctionType * type;
|
FunctionType * type;
|
||||||
CConv * m_call_conv;
|
CConv * m_call_conv;
|
||||||
uint32_t procEntry; /* label number */
|
uint32_t procEntry; /* label number */
|
||||||
std::string name; /* Meaningful name for this proc */
|
QString name; /* Meaningful name for this proc */
|
||||||
STATE state; /* Entry state */
|
STATE state; /* Entry state */
|
||||||
int depth; /* Depth at which we found it - for printing */
|
int depth; /* Depth at which we found it - for printing */
|
||||||
uint32_t flg; /* Combination of Icode & Proc flags */
|
uint32_t flg; /* Combination of Icode & Proc flags */
|
||||||
int16_t cbParam; /* Probable no. of bytes of parameters */
|
int16_t cbParam; /* Probable no. of bytes of parameters */
|
||||||
@ -153,7 +159,7 @@ public:
|
|||||||
delete type;
|
delete type;
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
static Function *Create(FunctionType *ty=0,int /*Linkage*/=0,const std::string &nm="",void */*module*/=0)
|
static Function *Create(FunctionType *ty=0,int /*Linkage*/=0,const QString &nm="",void */*module*/=0)
|
||||||
{
|
{
|
||||||
Function *r=new Function(ty);
|
Function *r=new Function(ty);
|
||||||
r->name = nm;
|
r->name = nm;
|
||||||
@ -185,14 +191,14 @@ public:
|
|||||||
bool process_JMP(ICODE &pIcode, STATE *pstate, CALL_GRAPH *pcallGraph);
|
bool process_JMP(ICODE &pIcode, STATE *pstate, CALL_GRAPH *pcallGraph);
|
||||||
bool process_CALL(ICODE &pIcode, CALL_GRAPH *pcallGraph, STATE *pstate);
|
bool process_CALL(ICODE &pIcode, CALL_GRAPH *pcallGraph, STATE *pstate);
|
||||||
void freeCFG();
|
void freeCFG();
|
||||||
void codeGen(std::ostream &fs);
|
void codeGen(QIODevice & fs);
|
||||||
void mergeFallThrough(BB *pBB);
|
void mergeFallThrough(BB *pBB);
|
||||||
void structIfs();
|
void structIfs();
|
||||||
void structLoops(derSeq *derivedG);
|
void structLoops(derSeq *derivedG);
|
||||||
void buildCFG(Disassembler &ds);
|
void buildCFG(Disassembler &ds);
|
||||||
void controlFlowAnalysis();
|
void controlFlowAnalysis();
|
||||||
void newRegArg(iICODE picode, iICODE ticode);
|
void newRegArg(iICODE picode, iICODE ticode);
|
||||||
void writeProcComments(std::ostream &ostr);
|
void writeProcComments(QTextStream & ostr);
|
||||||
|
|
||||||
void displayCFG();
|
void displayCFG();
|
||||||
void displayStats();
|
void displayStats();
|
||||||
@ -200,7 +206,7 @@ public:
|
|||||||
|
|
||||||
void preprocessReturnDU(LivenessSet &_liveOut);
|
void preprocessReturnDU(LivenessSet &_liveOut);
|
||||||
Expr * adjustActArgType(Expr *_exp, hlType forType);
|
Expr * adjustActArgType(Expr *_exp, hlType forType);
|
||||||
std::string writeCall(Function *tproc, STKFRAME &args, int *numLoc);
|
QString writeCall(Function *tproc, STKFRAME &args, int *numLoc);
|
||||||
void processDosInt(STATE *pstate, PROG &prog, bool done);
|
void processDosInt(STATE *pstate, PROG &prog, bool done);
|
||||||
ICODE *translate_DIV(LLInst *ll, ICODE &_Icode);
|
ICODE *translate_DIV(LLInst *ll, ICODE &_Icode);
|
||||||
ICODE *translate_XCHG(LLInst *ll, ICODE &_Icode);
|
ICODE *translate_XCHG(LLInst *ll, ICODE &_Icode);
|
||||||
|
|||||||
@ -58,7 +58,7 @@ public:
|
|||||||
/** Recursively deallocates the abstract syntax tree rooted at *exp */
|
/** Recursively deallocates the abstract syntax tree rooted at *exp */
|
||||||
virtual ~Expr() {}
|
virtual ~Expr() {}
|
||||||
public:
|
public:
|
||||||
virtual std::string walkCondExpr (Function * pProc, int* numLoc) const=0;
|
virtual QString walkCondExpr (Function * pProc, int* numLoc) const=0;
|
||||||
virtual Expr *inverse() const=0; // return new COND_EXPR that is invarse of this
|
virtual Expr *inverse() const=0; // return new COND_EXPR that is invarse of this
|
||||||
virtual bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locId)=0;
|
virtual bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locId)=0;
|
||||||
virtual Expr *insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *locsym)=0;
|
virtual Expr *insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *locsym)=0;
|
||||||
@ -100,10 +100,12 @@ struct UnaryOperator : public Expr
|
|||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
int hlTypeSize(Function *pproc) const;
|
int hlTypeSize(Function *pproc) const;
|
||||||
virtual std::string walkCondExpr(Function *pProc, int *numLoc) const;
|
virtual QString walkCondExpr(Function *pProc, int *numLoc) const;
|
||||||
virtual Expr *insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *locsym);
|
virtual Expr *insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *locsym);
|
||||||
virtual hlType expType(Function *pproc) const;
|
virtual hlType expType(Function *pproc) const;
|
||||||
virtual Expr *insertSubTreeLongReg(Expr *_expr, int longIdx);
|
virtual Expr *insertSubTreeLongReg(Expr *_expr, int longIdx);
|
||||||
|
private:
|
||||||
|
QString wrapUnary(Function *pProc, int *numLoc, QChar op) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BinaryOperator : public Expr
|
struct BinaryOperator : public Expr
|
||||||
@ -188,7 +190,7 @@ struct BinaryOperator : public Expr
|
|||||||
condOp op() const { return m_op;}
|
condOp op() const { return m_op;}
|
||||||
/* Changes the boolean conditional operator at the root of this expression */
|
/* Changes the boolean conditional operator at the root of this expression */
|
||||||
void op(condOp o) { m_op=o;}
|
void op(condOp o) { m_op=o;}
|
||||||
std::string walkCondExpr (Function * pProc, int* numLoc) const;
|
QString walkCondExpr(Function * pProc, int* numLoc) const;
|
||||||
public:
|
public:
|
||||||
hlType expType(Function *pproc) const;
|
hlType expType(Function *pproc) const;
|
||||||
int hlTypeSize(Function *pproc) const;
|
int hlTypeSize(Function *pproc) const;
|
||||||
@ -215,7 +217,7 @@ struct AstIdent : public UnaryOperator
|
|||||||
virtual int hlTypeSize(Function *pproc) const;
|
virtual int hlTypeSize(Function *pproc) const;
|
||||||
virtual hlType expType(Function *pproc) const;
|
virtual hlType expType(Function *pproc) const;
|
||||||
virtual Expr * performLongRemoval(eReg regi, LOCAL_ID *locId);
|
virtual Expr * performLongRemoval(eReg regi, LOCAL_ID *locId);
|
||||||
virtual std::string walkCondExpr(Function *pProc, int *numLoc) const;
|
virtual QString walkCondExpr(Function *pProc, int *numLoc) const;
|
||||||
virtual Expr *insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *locsym);
|
virtual Expr *insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *locsym);
|
||||||
virtual Expr *insertSubTreeLongReg(Expr *_expr, int longIdx);
|
virtual Expr *insertSubTreeLongReg(Expr *_expr, int longIdx);
|
||||||
virtual bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locId);
|
virtual bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locId);
|
||||||
@ -232,7 +234,7 @@ struct GlobalVariable : public AstIdent
|
|||||||
return new GlobalVariable(*this);
|
return new GlobalVariable(*this);
|
||||||
}
|
}
|
||||||
GlobalVariable(int16_t segValue, int16_t off);
|
GlobalVariable(int16_t segValue, int16_t off);
|
||||||
std::string walkCondExpr(Function *pProc, int *numLoc) const;
|
QString walkCondExpr(Function *pProc, int *numLoc) const;
|
||||||
int hlTypeSize(Function *pproc) const;
|
int hlTypeSize(Function *pproc) const;
|
||||||
hlType expType(Function *pproc) const;
|
hlType expType(Function *pproc) const;
|
||||||
};
|
};
|
||||||
@ -246,7 +248,7 @@ struct GlobalVariableIdx : public AstIdent
|
|||||||
return new GlobalVariableIdx(*this);
|
return new GlobalVariableIdx(*this);
|
||||||
}
|
}
|
||||||
GlobalVariableIdx(int16_t segValue, int16_t off, uint8_t regi, const LOCAL_ID *locSym);
|
GlobalVariableIdx(int16_t segValue, int16_t off, uint8_t regi, const LOCAL_ID *locSym);
|
||||||
std::string walkCondExpr(Function *pProc, int *numLoc) const;
|
QString walkCondExpr(Function *pProc, int *numLoc) const;
|
||||||
int hlTypeSize(Function *pproc) const;
|
int hlTypeSize(Function *pproc) const;
|
||||||
hlType expType(Function *pproc) const;
|
hlType expType(Function *pproc) const;
|
||||||
};
|
};
|
||||||
@ -268,7 +270,7 @@ struct Constant : public AstIdent
|
|||||||
{
|
{
|
||||||
return new Constant(*this);
|
return new Constant(*this);
|
||||||
}
|
}
|
||||||
std::string walkCondExpr(Function *pProc, int *numLoc) const;
|
QString walkCondExpr(Function *pProc, int *numLoc) const;
|
||||||
int hlTypeSize(Function *pproc) const;
|
int hlTypeSize(Function *pproc) const;
|
||||||
hlType expType(Function *pproc) const;
|
hlType expType(Function *pproc) const;
|
||||||
};
|
};
|
||||||
@ -288,7 +290,7 @@ struct FuncNode : public AstIdent
|
|||||||
{
|
{
|
||||||
return new FuncNode(*this);
|
return new FuncNode(*this);
|
||||||
}
|
}
|
||||||
std::string walkCondExpr(Function *pProc, int *numLoc) const;
|
QString walkCondExpr(Function *pProc, int *numLoc) const;
|
||||||
int hlTypeSize(Function *pproc) const;
|
int hlTypeSize(Function *pproc) const;
|
||||||
hlType expType(Function *pproc) const;
|
hlType expType(Function *pproc) const;
|
||||||
};
|
};
|
||||||
@ -314,7 +316,7 @@ struct RegisterNode : public AstIdent
|
|||||||
{
|
{
|
||||||
return new RegisterNode(*this);
|
return new RegisterNode(*this);
|
||||||
}
|
}
|
||||||
std::string walkCondExpr(Function *pProc, int *numLoc) const;
|
QString walkCondExpr(Function *pProc, int *numLoc) const;
|
||||||
int hlTypeSize(Function *) const;
|
int hlTypeSize(Function *) const;
|
||||||
hlType expType(Function *pproc) const;
|
hlType expType(Function *pproc) const;
|
||||||
bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locId);
|
bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locId);
|
||||||
|
|||||||
@ -7,8 +7,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <QtCore/QString>
|
||||||
struct strTable : std::vector<std::string>
|
#include <QtCore/QIODevice>
|
||||||
|
|
||||||
|
struct strTable : std::vector<QString>
|
||||||
{
|
{
|
||||||
/* Returns the next available index into the table */
|
/* Returns the next available index into the table */
|
||||||
size_t nextIdx() {return size();}
|
size_t nextIdx() {return size();}
|
||||||
@ -20,9 +22,9 @@ struct bundle
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void appendCode(const char *format, ...);
|
void appendCode(const char *format, ...);
|
||||||
void appendCode(const std::string &s);
|
void appendCode(const QString &s);
|
||||||
void appendDecl(const char *format, ...);
|
void appendDecl(const char *format, ...);
|
||||||
void appendDecl(const std::string &);
|
void appendDecl(const QString &);
|
||||||
void init()
|
void init()
|
||||||
{
|
{
|
||||||
decl.clear();
|
decl.clear();
|
||||||
@ -37,6 +39,6 @@ extern bundle cCode;
|
|||||||
#define lineSize 360 /* 3 lines in the mean time */
|
#define lineSize 360 /* 3 lines in the mean time */
|
||||||
|
|
||||||
//void newBundle (bundle *procCode);
|
//void newBundle (bundle *procCode);
|
||||||
void writeBundle (std::ostream &ios, bundle procCode);
|
void writeBundle (QIODevice & ios, bundle procCode);
|
||||||
void freeBundle (bundle *procCode);
|
void freeBundle (bundle *procCode);
|
||||||
|
|
||||||
|
|||||||
@ -93,8 +93,8 @@ bool LibCheck(Function &p); /* chklib.c */
|
|||||||
|
|
||||||
|
|
||||||
/* Exported functions from hlicode.c */
|
/* Exported functions from hlicode.c */
|
||||||
const char *writeJcond(const HLTYPE &, Function *, int *);
|
QString writeJcond(const HLTYPE &, Function *, int *);
|
||||||
const char *writeJcondInv (HLTYPE, Function *, int *);
|
QString writeJcondInv(HLTYPE, Function *, int *);
|
||||||
|
|
||||||
|
|
||||||
/* Exported funcions from locident.c */
|
/* Exported funcions from locident.c */
|
||||||
|
|||||||
@ -5,9 +5,12 @@
|
|||||||
***************************************************************************
|
***************************************************************************
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include "bundle.h"
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "bundle.h"
|
#include <QString>
|
||||||
|
#include <QTextStream>
|
||||||
struct LLInst;
|
struct LLInst;
|
||||||
struct Function;
|
struct Function;
|
||||||
struct Disassembler
|
struct Disassembler
|
||||||
@ -16,7 +19,8 @@ protected:
|
|||||||
int pass;
|
int pass;
|
||||||
int g_lab;
|
int g_lab;
|
||||||
//bundle &cCode;
|
//bundle &cCode;
|
||||||
std::ofstream m_fp;
|
QIODevice *m_disassembly_target;
|
||||||
|
QTextStream m_fp;
|
||||||
std::vector<std::string> m_decls;
|
std::vector<std::string> m_decls;
|
||||||
std::vector<std::string> m_code;
|
std::vector<std::string> m_code;
|
||||||
|
|
||||||
|
|||||||
@ -15,6 +15,7 @@
|
|||||||
#include <llvm/MC/MCInst.h>
|
#include <llvm/MC/MCInst.h>
|
||||||
#include <llvm/IR/Instruction.h>
|
#include <llvm/IR/Instruction.h>
|
||||||
#include <boost/range/iterator_range.hpp>
|
#include <boost/range/iterator_range.hpp>
|
||||||
|
#include <QtCore/QString>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -145,8 +146,8 @@ struct UnaryOperator;
|
|||||||
struct HlTypeSupport
|
struct HlTypeSupport
|
||||||
{
|
{
|
||||||
//hlIcode opcode; /* hlIcode opcode */
|
//hlIcode opcode; /* hlIcode opcode */
|
||||||
virtual bool removeRegFromLong(eReg regi, LOCAL_ID *locId)=0;
|
virtual bool removeRegFromLong(eReg regi, LOCAL_ID *locId)=0;
|
||||||
virtual std::string writeOut(Function *pProc, int *numLoc) const=0;
|
virtual QString writeOut(Function *pProc, int *numLoc) const=0;
|
||||||
protected:
|
protected:
|
||||||
Expr * performLongRemoval (eReg regi, LOCAL_ID *locId, Expr *tree);
|
Expr * performLongRemoval (eReg regi, LOCAL_ID *locId, Expr *tree);
|
||||||
};
|
};
|
||||||
@ -166,7 +167,7 @@ public:
|
|||||||
printf("CallType : removeRegFromLong not supproted");
|
printf("CallType : removeRegFromLong not supproted");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
std::string writeOut(Function *pProc, int *numLoc) const;
|
QString writeOut(Function *pProc, int *numLoc) const;
|
||||||
};
|
};
|
||||||
struct AssignType : public HlTypeSupport
|
struct AssignType : public HlTypeSupport
|
||||||
{
|
{
|
||||||
@ -179,7 +180,7 @@ public:
|
|||||||
Expr *lhs() const {return m_lhs;}
|
Expr *lhs() const {return m_lhs;}
|
||||||
void lhs(Expr *l);
|
void lhs(Expr *l);
|
||||||
bool removeRegFromLong(eReg regi, LOCAL_ID *locId);
|
bool removeRegFromLong(eReg regi, LOCAL_ID *locId);
|
||||||
std::string writeOut(Function *pProc, int *numLoc) const;
|
QString writeOut(Function *pProc, int *numLoc) const;
|
||||||
};
|
};
|
||||||
struct ExpType : public HlTypeSupport
|
struct ExpType : public HlTypeSupport
|
||||||
{
|
{
|
||||||
@ -191,7 +192,7 @@ struct ExpType : public HlTypeSupport
|
|||||||
v=performLongRemoval(regi,locId,v);
|
v=performLongRemoval(regi,locId,v);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
std::string writeOut(Function *pProc, int *numLoc) const;
|
QString writeOut(Function *pProc, int *numLoc) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct HLTYPE
|
struct HLTYPE
|
||||||
@ -245,7 +246,7 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
std::string write1HlIcode(Function *pProc, int *numLoc) const;
|
QString write1HlIcode(Function *pProc, int *numLoc) const;
|
||||||
void setAsgn(Expr *lhs, Expr *rhs);
|
void setAsgn(Expr *lhs, Expr *rhs);
|
||||||
} ;
|
} ;
|
||||||
/* LOW_LEVEL icode operand record */
|
/* LOW_LEVEL icode operand record */
|
||||||
@ -404,11 +405,11 @@ public:
|
|||||||
}
|
}
|
||||||
void emitGotoLabel(int indLevel);
|
void emitGotoLabel(int indLevel);
|
||||||
void findJumpTargets(CIcodeRec &_pc);
|
void findJumpTargets(CIcodeRec &_pc);
|
||||||
void writeIntComment(std::ostringstream &s);
|
void writeIntComment(QTextStream & s);
|
||||||
void dis1Line(int loc_ip, int pass);
|
void dis1Line(int loc_ip, int pass);
|
||||||
std::ostringstream &strSrc(std::ostringstream &os,bool skip_comma=false);
|
QTextStream & strSrc(QTextStream & os, bool skip_comma=false);
|
||||||
|
|
||||||
void flops(std::ostringstream &out);
|
void flops(QTextStream & out);
|
||||||
bool isJmpInst();
|
bool isJmpInst();
|
||||||
HLTYPE createCall();
|
HLTYPE createCall();
|
||||||
LLInst(ICODE *container) : flg(0),codeIdx(0),numBytes(0),m_link(container)
|
LLInst(ICODE *container) : flg(0),codeIdx(0),numBytes(0),m_link(container)
|
||||||
|
|||||||
@ -11,6 +11,7 @@
|
|||||||
#include "Enums.h"
|
#include "Enums.h"
|
||||||
#include "machine_x86.h"
|
#include "machine_x86.h"
|
||||||
|
|
||||||
|
#include <QtCore/QString>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <list>
|
#include <list>
|
||||||
@ -101,7 +102,7 @@ public:
|
|||||||
frameType loc; /* Frame location */
|
frameType loc; /* Frame location */
|
||||||
bool hasMacro; /* Identifier requires a macro */
|
bool hasMacro; /* Identifier requires a macro */
|
||||||
char macro[10]; /* Macro for this identifier */
|
char macro[10]; /* Macro for this identifier */
|
||||||
std::string name; /* Identifier's name */
|
QString name; /* Identifier's name */
|
||||||
union ID_UNION { /* Different types of identifiers */
|
union ID_UNION { /* Different types of identifiers */
|
||||||
friend struct ID;
|
friend struct ID;
|
||||||
protected:
|
protected:
|
||||||
@ -167,7 +168,7 @@ public:
|
|||||||
int newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix, operDu du, LLInst &atOffset);
|
int newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix, operDu du, LLInst &atOffset);
|
||||||
void newIdent(hlType t, frameType f);
|
void newIdent(hlType t, frameType f);
|
||||||
void flagByteWordId(int off);
|
void flagByteWordId(int off);
|
||||||
void propLongId(uint8_t regL, uint8_t regH, const char *name);
|
void propLongId(uint8_t regL, uint8_t regH, const QString & name);
|
||||||
size_t csym() const {return id_arr.size();}
|
size_t csym() const {return id_arr.size();}
|
||||||
void newRegArg(iICODE picode, iICODE ticode) const;
|
void newRegArg(iICODE picode, iICODE ticode) const;
|
||||||
void processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode, bool isLong) const;
|
void processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode, bool isLong) const;
|
||||||
|
|||||||
@ -1,9 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <QtCore/QString>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string>
|
|
||||||
#include <sstream>
|
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
|
|
||||||
|
class QTextStream;
|
||||||
|
|
||||||
struct LivenessSet;
|
struct LivenessSet;
|
||||||
/* Machine registers */
|
/* Machine registers */
|
||||||
enum eReg
|
enum eReg
|
||||||
@ -60,13 +62,13 @@ class Machine_X86 : public SourceMachine
|
|||||||
public:
|
public:
|
||||||
Machine_X86();
|
Machine_X86();
|
||||||
virtual ~Machine_X86() {}
|
virtual ~Machine_X86() {}
|
||||||
static const std::string ®Name(eReg r);
|
static const QString & regName(eReg r);
|
||||||
static const std::string &opcodeName(unsigned r);
|
static const QString & opcodeName(unsigned r);
|
||||||
static const std::string &floatOpName(unsigned r);
|
static const QString & floatOpName(unsigned r);
|
||||||
bool physicalReg(eReg r);
|
bool physicalReg(eReg r);
|
||||||
/* Writes the registers that are set in the bitvector */
|
/* Writes the registers that are set in the bitvector */
|
||||||
//TODO: move this into Machine_X86 ?
|
//TODO: move this into Machine_X86 ?
|
||||||
static void writeRegVector (std::ostream &ostr,const LivenessSet ®i);
|
static void writeRegVector (QTextStream & ostr, const LivenessSet ®i);
|
||||||
static eReg subRegH(eReg reg);
|
static eReg subRegH(eReg reg);
|
||||||
static eReg subRegL(eReg reg);
|
static eReg subRegL(eReg reg);
|
||||||
static bool isMemOff(eReg r);
|
static bool isMemOff(eReg r);
|
||||||
|
|||||||
@ -52,14 +52,14 @@ public:
|
|||||||
QString output_name(const char *ext);
|
QString output_name(const char *ext);
|
||||||
ilFunction funcIter(Function *to_find);
|
ilFunction funcIter(Function *to_find);
|
||||||
ilFunction findByEntry(uint32_t entry);
|
ilFunction findByEntry(uint32_t entry);
|
||||||
ilFunction createFunction(FunctionType *f,const std::string &name);
|
ilFunction createFunction(FunctionType *f, const QString & name);
|
||||||
bool valid(ilFunction iter);
|
bool valid(ilFunction iter);
|
||||||
|
|
||||||
int getSymIdxByAdd(uint32_t adr);
|
int getSymIdxByAdd(uint32_t adr);
|
||||||
bool validSymIdx(size_t idx);
|
bool validSymIdx(size_t idx);
|
||||||
size_t symbolSize(size_t idx);
|
size_t symbolSize(size_t idx);
|
||||||
hlType symbolType(size_t idx);
|
hlType symbolType(size_t idx);
|
||||||
const std::string &symbolName(size_t idx);
|
const QString & symbolName(size_t idx);
|
||||||
const SYM &getSymByIdx(size_t idx) const;
|
const SYM &getSymByIdx(size_t idx) const;
|
||||||
|
|
||||||
static Project *get();
|
static Project *get();
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "msvc_fixes.h"
|
#include "msvc_fixes.h"
|
||||||
|
|
||||||
|
#include <QtCore/QString>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
struct Expr;
|
struct Expr;
|
||||||
@ -17,7 +18,7 @@ struct TypeContainer;
|
|||||||
/* * * * * * * * * * * * * * * * * */
|
/* * * * * * * * * * * * * * * * * */
|
||||||
struct SymbolCommon
|
struct SymbolCommon
|
||||||
{
|
{
|
||||||
std::string name; /* New name for this variable/symbol/argument */
|
QString name; /* New name for this variable/symbol/argument */
|
||||||
int size; /* Size/maximum size */
|
int size; /* Size/maximum size */
|
||||||
hlType type; /* probable type */
|
hlType type; /* probable type */
|
||||||
eDuVal duVal; /* DEF, USE, VAL */
|
eDuVal duVal; /* DEF, USE, VAL */
|
||||||
@ -38,12 +39,12 @@ struct SYM : public SymbolCommon
|
|||||||
struct STKSYM : public SymbolCommon
|
struct STKSYM : public SymbolCommon
|
||||||
{
|
{
|
||||||
typedef int16_t tLabel;
|
typedef int16_t tLabel;
|
||||||
Expr *actual=0; /* Expression tree of actual parameter */
|
Expr * actual=0; /* Expression tree of actual parameter */
|
||||||
AstIdent *regs=0; /* For register arguments only */
|
AstIdent * regs=0; /* For register arguments only */
|
||||||
tLabel label=0; /* Immediate off from BP (+:args, -:params) */
|
tLabel label=0; /* Immediate off from BP (+:args, -:params) */
|
||||||
uint8_t regOff=0; /* Offset is a register (e.g. SI, DI) */
|
uint8_t regOff=0; /* Offset is a register (e.g. SI, DI) */
|
||||||
bool hasMacro=false; /* This type needs a macro */
|
bool hasMacro=false; /* This type needs a macro */
|
||||||
std::string macro; /* Macro name */
|
QString macro; /* Macro name */
|
||||||
bool invalid=false; /* Boolean: invalid entry in formal arg list*/
|
bool invalid=false; /* Boolean: invalid entry in formal arg list*/
|
||||||
void setArgName(int i)
|
void setArgName(int i)
|
||||||
{
|
{
|
||||||
@ -106,6 +107,6 @@ constexpr int NUM_TABLE_TYPES = int(Comment)+1; /* Number of entries: must be la
|
|||||||
|
|
||||||
void createSymTables(void);
|
void createSymTables(void);
|
||||||
void destroySymTables(void);
|
void destroySymTables(void);
|
||||||
bool readVal (std::ostringstream &symName, uint32_t symOff, Function *symProc);
|
bool readVal (QTextStream & symName, uint32_t symOff, Function *symProc);
|
||||||
void selectTable(tableType); /* Select a particular table */
|
void selectTable(tableType); /* Select a particular table */
|
||||||
|
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
#include "dcc.h"
|
#include "dcc.h"
|
||||||
#include "msvc_fixes.h"
|
#include "msvc_fixes.h"
|
||||||
|
|
||||||
|
#include <QtCore/QTextStream>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <boost/range/rbegin.hpp>
|
#include <boost/range/rbegin.hpp>
|
||||||
@ -143,7 +144,8 @@ ICODE* BB::writeLoopHeader(int &indLevel, Function* pProc, int *numLoc, BB *&lat
|
|||||||
if(loopType == eNodeHeaderType::NO_TYPE)
|
if(loopType == eNodeHeaderType::NO_TYPE)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
latch = pProc->m_dfsLast[this->latchNode];
|
latch = pProc->m_dfsLast[this->latchNode];
|
||||||
std::ostringstream ostr;
|
QString ostr_contents;
|
||||||
|
QTextStream ostr(&ostr_contents);
|
||||||
ICODE* picode;
|
ICODE* picode;
|
||||||
switch (loopType)
|
switch (loopType)
|
||||||
{
|
{
|
||||||
@ -169,7 +171,7 @@ ICODE* BB::writeLoopHeader(int &indLevel, Function* pProc, int *numLoc, BB *&lat
|
|||||||
picode->hlU()->replaceExpr(picode->hl()->expr()->inverse());
|
picode->hlU()->replaceExpr(picode->hl()->expr()->inverse());
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
string e=picode->hl()->expr()->walkCondExpr (pProc, numLoc);
|
QString e=picode->hl()->expr()->walkCondExpr (pProc, numLoc);
|
||||||
ostr << "\n"<<indentStr(indLevel)<<"while ("<<e<<") {\n";
|
ostr << "\n"<<indentStr(indLevel)<<"while ("<<e<<") {\n";
|
||||||
}
|
}
|
||||||
picode->invalidate();
|
picode->invalidate();
|
||||||
@ -186,7 +188,8 @@ ICODE* BB::writeLoopHeader(int &indLevel, Function* pProc, int *numLoc, BB *&lat
|
|||||||
picode = &latch->back();
|
picode = &latch->back();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
cCode.appendCode(ostr.str());
|
ostr.flush();
|
||||||
|
cCode.appendCode(ostr_contents);
|
||||||
stats.numHLIcode += 1;
|
stats.numHLIcode += 1;
|
||||||
indLevel++;
|
indLevel++;
|
||||||
return picode;
|
return picode;
|
||||||
@ -199,11 +202,11 @@ bool BB::isEndOfPath(int latch_node_idx) const
|
|||||||
void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode, int _ifFollow)
|
void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode, int _ifFollow)
|
||||||
{
|
{
|
||||||
int follow; /* ifFollow */
|
int follow; /* ifFollow */
|
||||||
BB * succ, *latch; /* Successor and latching node */
|
BB * succ, *latch; /* Successor and latching node */
|
||||||
ICODE * picode; /* Pointer to HLI_JCOND instruction */
|
ICODE * picode; /* Pointer to HLI_JCOND instruction */
|
||||||
std::string l; /* Pointer to HLI_JCOND expression */
|
QString l; /* Pointer to HLI_JCOND expression */
|
||||||
bool emptyThen, /* THEN clause is empty */
|
bool emptyThen, /* THEN clause is empty */
|
||||||
repCond; /* Repeat condition for while() */
|
repCond; /* Repeat condition for while() */
|
||||||
|
|
||||||
/* Check if this basic block should be analysed */
|
/* Check if this basic block should be analysed */
|
||||||
if ((_ifFollow != UN_INIT) and (this == pProc->m_dfsLast[_ifFollow]))
|
if ((_ifFollow != UN_INIT) and (this == pProc->m_dfsLast[_ifFollow]))
|
||||||
@ -221,9 +224,11 @@ void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode,
|
|||||||
/* Write the code for this basic block */
|
/* Write the code for this basic block */
|
||||||
if (repCond == false)
|
if (repCond == false)
|
||||||
{
|
{
|
||||||
std::ostringstream ostr;
|
QString ostr_contents;
|
||||||
|
QTextStream ostr(&ostr_contents);
|
||||||
writeBB(ostr,indLevel, pProc, numLoc);
|
writeBB(ostr,indLevel, pProc, numLoc);
|
||||||
cCode.appendCode(ostr.str());
|
ostr.flush();
|
||||||
|
cCode.appendCode(ostr_contents);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for end of path */
|
/* Check for end of path */
|
||||||
@ -254,7 +259,8 @@ void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode,
|
|||||||
indLevel--;
|
indLevel--;
|
||||||
if (loopType == eNodeHeaderType::WHILE_TYPE)
|
if (loopType == eNodeHeaderType::WHILE_TYPE)
|
||||||
{
|
{
|
||||||
std::ostringstream ostr;
|
QString ostr_contents;
|
||||||
|
QTextStream ostr(&ostr_contents);
|
||||||
/* Check if there is need to repeat other statements involved
|
/* Check if there is need to repeat other statements involved
|
||||||
* in while condition, then, emit the loop trailer */
|
* in while condition, then, emit the loop trailer */
|
||||||
if (repCond)
|
if (repCond)
|
||||||
@ -262,13 +268,14 @@ void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode,
|
|||||||
writeBB(ostr,indLevel+1, pProc, numLoc);
|
writeBB(ostr,indLevel+1, pProc, numLoc);
|
||||||
}
|
}
|
||||||
ostr <<indentStr(indLevel)<< "} /* end of while */\n";
|
ostr <<indentStr(indLevel)<< "} /* end of while */\n";
|
||||||
cCode.appendCode(ostr.str());
|
ostr.flush();
|
||||||
|
cCode.appendCode(ostr_contents);
|
||||||
}
|
}
|
||||||
else if (loopType == eNodeHeaderType::ENDLESS_TYPE)
|
else if (loopType == eNodeHeaderType::ENDLESS_TYPE)
|
||||||
cCode.appendCode( "%s} /* end of loop */\n",indentStr(indLevel));
|
cCode.appendCode( "%s} /* end of loop */\n",indentStr(indLevel));
|
||||||
else if (loopType == eNodeHeaderType::REPEAT_TYPE)
|
else if (loopType == eNodeHeaderType::REPEAT_TYPE)
|
||||||
{
|
{
|
||||||
string e = "//*failed*//";
|
QString e = "//*failed*//";
|
||||||
if (picode->hl()->opcode != HLI_JCOND)
|
if (picode->hl()->opcode != HLI_JCOND)
|
||||||
{
|
{
|
||||||
reportError (REPEAT_FAIL);
|
reportError (REPEAT_FAIL);
|
||||||
@ -277,7 +284,7 @@ void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode,
|
|||||||
{
|
{
|
||||||
e=picode->hl()->expr()->walkCondExpr (pProc, numLoc);
|
e=picode->hl()->expr()->walkCondExpr (pProc, numLoc);
|
||||||
}
|
}
|
||||||
cCode.appendCode( "%s} while (%s);\n", indentStr(indLevel),e.c_str());
|
cCode.appendCode( "%s} while (%s);\n", indentStr(indLevel),qPrintable(e));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Recurse on the loop follow */
|
/* Recurse on the loop follow */
|
||||||
@ -309,13 +316,13 @@ void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode,
|
|||||||
if (succ->dfsLastNum != follow) /* THEN part */
|
if (succ->dfsLastNum != follow) /* THEN part */
|
||||||
{
|
{
|
||||||
l = writeJcond ( *back().hl(), pProc, numLoc);
|
l = writeJcond ( *back().hl(), pProc, numLoc);
|
||||||
cCode.appendCode( "\n%s%s", indentStr(indLevel-1), l.c_str());
|
cCode.appendCode( "\n%s%s", indentStr(indLevel-1), qPrintable(l));
|
||||||
succ->writeCode (indLevel, pProc, numLoc, _latchNode,follow);
|
succ->writeCode (indLevel, pProc, numLoc, _latchNode,follow);
|
||||||
}
|
}
|
||||||
else /* empty THEN part => negate ELSE part */
|
else /* empty THEN part => negate ELSE part */
|
||||||
{
|
{
|
||||||
l = writeJcondInv ( *back().hl(), pProc, numLoc);
|
l = writeJcondInv ( *back().hl(), pProc, numLoc);
|
||||||
cCode.appendCode( "\n%s%s", indentStr(indLevel-1), l.c_str());
|
cCode.appendCode( "\n%s%s", indentStr(indLevel-1), qPrintable(l));
|
||||||
edges[ELSE].BBptr->writeCode (indLevel, pProc, numLoc, _latchNode, follow);
|
edges[ELSE].BBptr->writeCode (indLevel, pProc, numLoc, _latchNode, follow);
|
||||||
emptyThen = true;
|
emptyThen = true;
|
||||||
}
|
}
|
||||||
@ -335,7 +342,7 @@ void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode,
|
|||||||
}
|
}
|
||||||
/* else (empty ELSE part) */
|
/* else (empty ELSE part) */
|
||||||
}
|
}
|
||||||
else if (! emptyThen) /* already visited => emit label */
|
else if (not emptyThen) /* already visited => emit label */
|
||||||
{
|
{
|
||||||
cCode.appendCode( "%s}\n%selse {\n",
|
cCode.appendCode( "%s}\n%selse {\n",
|
||||||
indentStr(indLevel-1), indentStr(indLevel - 1));
|
indentStr(indLevel-1), indentStr(indLevel - 1));
|
||||||
@ -351,7 +358,7 @@ void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode,
|
|||||||
else /* no follow => if..then..else */
|
else /* no follow => if..then..else */
|
||||||
{
|
{
|
||||||
l = writeJcond ( *back().hl(), pProc, numLoc);
|
l = writeJcond ( *back().hl(), pProc, numLoc);
|
||||||
cCode.appendCode( "%s%s", indentStr(indLevel-1), l.c_str());
|
cCode.appendCode( "%s%s", indentStr(indLevel-1), qPrintable(l));
|
||||||
edges[THEN].BBptr->writeCode (indLevel, pProc, numLoc, _latchNode, _ifFollow);
|
edges[THEN].BBptr->writeCode (indLevel, pProc, numLoc, _latchNode, _ifFollow);
|
||||||
cCode.appendCode( "%s}\n%selse {\n", indentStr(indLevel-1), indentStr(indLevel - 1));
|
cCode.appendCode( "%s}\n%selse {\n", indentStr(indLevel-1), indentStr(indLevel - 1));
|
||||||
edges[ELSE].BBptr->writeCode (indLevel, pProc, numLoc, _latchNode, _ifFollow);
|
edges[ELSE].BBptr->writeCode (indLevel, pProc, numLoc, _latchNode, _ifFollow);
|
||||||
@ -374,7 +381,7 @@ void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode,
|
|||||||
* Args: pBB: pointer to the current basic block.
|
* Args: pBB: pointer to the current basic block.
|
||||||
* Icode: pointer to the array of icodes for current procedure.
|
* Icode: pointer to the array of icodes for current procedure.
|
||||||
* lev: indentation level - used for formatting. */
|
* lev: indentation level - used for formatting. */
|
||||||
void BB::writeBB(std::ostream &ostr,int lev, Function * pProc, int *numLoc)
|
void BB::writeBB(QTextStream &ostr,int lev, Function * pProc, int *numLoc)
|
||||||
{
|
{
|
||||||
/* Save the index into the code table in case there is a later goto
|
/* Save the index into the code table in case there is a later goto
|
||||||
* into this instruction (first instruction of the BB) */
|
* into this instruction (first instruction of the BB) */
|
||||||
@ -386,8 +393,8 @@ void BB::writeBB(std::ostream &ostr,int lev, Function * pProc, int *numLoc)
|
|||||||
{
|
{
|
||||||
if ((pHli.type == HIGH_LEVEL) and ( pHli.valid() )) //TODO: use filtering range here.
|
if ((pHli.type == HIGH_LEVEL) and ( pHli.valid() )) //TODO: use filtering range here.
|
||||||
{
|
{
|
||||||
std::string line = pHli.hl()->write1HlIcode(pProc, numLoc);
|
QString line = pHli.hl()->write1HlIcode(pProc, numLoc);
|
||||||
if (!line.empty())
|
if (not line.isEmpty())
|
||||||
{
|
{
|
||||||
ostr<<indentStr(lev)<<line;
|
ostr<<indentStr(lev)<<line;
|
||||||
stats.numHLIcode++;
|
stats.numHLIcode++;
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include "CallConvention.h"
|
#include "CallConvention.h"
|
||||||
|
#include <QtCore/QTextStream>
|
||||||
|
|
||||||
CConv *CConv::create(Type v)
|
CConv *CConv::create(Type v)
|
||||||
{
|
{
|
||||||
@ -22,15 +23,15 @@ CConv *CConv::create(Type v)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void C_CallingConvention::writeComments(std::ostream &ostr)
|
void C_CallingConvention::writeComments(QTextStream & ostr)
|
||||||
{
|
{
|
||||||
ostr << " * C calling convention.\n";
|
ostr << " * C calling convention.\n";
|
||||||
}
|
}
|
||||||
void Pascal_CallingConvention::writeComments(std::ostream &ostr)
|
void Pascal_CallingConvention::writeComments(QTextStream & ostr)
|
||||||
{
|
{
|
||||||
ostr << " * Pascal calling convention.\n";
|
ostr << " * Pascal calling convention.\n";
|
||||||
}
|
}
|
||||||
void Unknown_CallingConvention::writeComments(std::ostream &ostr)
|
void Unknown_CallingConvention::writeComments(QTextStream & ostr)
|
||||||
{
|
{
|
||||||
ostr << " * Unknown calling convention.\n";
|
ostr << " * Unknown calling convention.\n";
|
||||||
}
|
}
|
||||||
|
|||||||
@ -332,7 +332,7 @@ bool Project::load()
|
|||||||
const char *fname = binary_path().toLocal8Bit().data();
|
const char *fname = binary_path().toLocal8Bit().data();
|
||||||
QFile finfo(binary_path());
|
QFile finfo(binary_path());
|
||||||
/* Open the input file */
|
/* Open the input file */
|
||||||
if(!finfo.open(QFile::ReadOnly)) {
|
if(not finfo.open(QFile::ReadOnly)) {
|
||||||
fatalError(CANNOT_OPEN, fname);
|
fatalError(CANNOT_OPEN, fname);
|
||||||
}
|
}
|
||||||
/* Read in first 2 bytes to check EXE signature */
|
/* Read in first 2 bytes to check EXE signature */
|
||||||
|
|||||||
@ -28,7 +28,7 @@ void JumpTable::pruneEntries(uint16_t cs)
|
|||||||
{
|
{
|
||||||
uint32_t target = cs + LH(&prg->image()[i]);
|
uint32_t target = cs + LH(&prg->image()[i]);
|
||||||
/* Be wary of 00 00 as code - it's probably data */
|
/* Be wary of 00 00 as code - it's probably data */
|
||||||
if (! (prg->image()[target] or prg->image()[target+1]) or scan(target, _Icode))
|
if (not (prg->image()[target] or prg->image()[target+1]) or scan(target, _Icode))
|
||||||
finish = i;
|
finish = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -56,26 +56,26 @@ RegisterNode::RegisterNode(const LLOperand &op, LOCAL_ID *locsym)
|
|||||||
// regiType = reg_type;
|
// regiType = reg_type;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
string RegisterNode::walkCondExpr(Function *pProc, int *numLoc) const
|
QString RegisterNode::walkCondExpr(Function *pProc, int *numLoc) const
|
||||||
{
|
{
|
||||||
std::ostringstream codeOut;
|
QString codeOut;
|
||||||
|
|
||||||
std::ostringstream o;
|
QString o;
|
||||||
assert(&pProc->localId==m_syms);
|
assert(&pProc->localId==m_syms);
|
||||||
ID *id = &pProc->localId.id_arr[regiIdx];
|
ID *id = &pProc->localId.id_arr[regiIdx];
|
||||||
if (id->name[0] == '\0') /* no name */
|
if (id->name[0] == '\0') /* no name */
|
||||||
{
|
{
|
||||||
id->setLocalName(++(*numLoc));
|
id->setLocalName(++(*numLoc));
|
||||||
codeOut <<TypeContainer::typeName(id->type)<< " "<<id->name<<"; ";
|
codeOut += QString("%1 %2; ").arg(TypeContainer::typeName(id->type)).arg(id->name);
|
||||||
codeOut <<"/* "<<Machine_X86::regName(id->id.regi)<<" */\n";
|
codeOut += QString("/* %1 */\n").arg(Machine_X86::regName(id->id.regi));
|
||||||
}
|
}
|
||||||
if (id->hasMacro)
|
if (id->hasMacro)
|
||||||
o << id->macro << "("<<id->name<<")";
|
o += QString("%1(%2)").arg(id->macro).arg(id->name);
|
||||||
else
|
else
|
||||||
o << id->name;
|
o += id->name;
|
||||||
|
|
||||||
cCode.appendDecl(codeOut.str());
|
cCode.appendDecl(codeOut);
|
||||||
return o.str();
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
int RegisterNode::hlTypeSize(Function *) const
|
int RegisterNode::hlTypeSize(Function *) const
|
||||||
|
|||||||
493
src/ast.cpp
493
src/ast.cpp
@ -12,6 +12,7 @@
|
|||||||
#include "machine_x86.h"
|
#include "machine_x86.h"
|
||||||
#include "project.h"
|
#include "project.h"
|
||||||
|
|
||||||
|
#include <QtCore/QTextStream>
|
||||||
#include <boost/range.hpp>
|
#include <boost/range.hpp>
|
||||||
#include <boost/range/adaptors.hpp>
|
#include <boost/range/adaptors.hpp>
|
||||||
#include <boost/range/algorithm.hpp>
|
#include <boost/range/algorithm.hpp>
|
||||||
@ -61,19 +62,19 @@ void ICODE::setRegDU (eReg regi, operDu du_in)
|
|||||||
}
|
}
|
||||||
switch (du_in)
|
switch (du_in)
|
||||||
{
|
{
|
||||||
case eDEF:
|
case eDEF:
|
||||||
du.def.addReg(regi);
|
du.def.addReg(regi);
|
||||||
du1.addDef(regi);
|
du1.addDef(regi);
|
||||||
break;
|
break;
|
||||||
case eUSE:
|
case eUSE:
|
||||||
du.use.addReg(regi);
|
du.use.addReg(regi);
|
||||||
break;
|
break;
|
||||||
case USE_DEF:
|
case USE_DEF:
|
||||||
du.addDefinedAndUsed(regi);
|
du.addDefinedAndUsed(regi);
|
||||||
du1.addDef(regi);
|
du1.addDef(regi);
|
||||||
break;
|
break;
|
||||||
case NONE: /* do nothing */
|
case NONE: /* do nothing */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,24 +84,24 @@ void ICODE::copyDU(const ICODE &duIcode, operDu _du, operDu duDu)
|
|||||||
{
|
{
|
||||||
switch (_du)
|
switch (_du)
|
||||||
{
|
{
|
||||||
case eDEF:
|
case eDEF:
|
||||||
if (duDu == eDEF)
|
if (duDu == eDEF)
|
||||||
du.def=duIcode.du.def;
|
du.def=duIcode.du.def;
|
||||||
else
|
else
|
||||||
du.def=duIcode.du.use;
|
du.def=duIcode.du.use;
|
||||||
break;
|
break;
|
||||||
case eUSE:
|
case eUSE:
|
||||||
if (duDu == eDEF)
|
if (duDu == eDEF)
|
||||||
du.use = duIcode.du.def;
|
du.use = duIcode.du.def;
|
||||||
else
|
else
|
||||||
du.use = duIcode.du.use;
|
du.use = duIcode.du.use;
|
||||||
break;
|
break;
|
||||||
case USE_DEF:
|
case USE_DEF:
|
||||||
du = duIcode.du;
|
du = duIcode.du;
|
||||||
break;
|
break;
|
||||||
case NONE:
|
case NONE:
|
||||||
assert(false);
|
assert(false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,7 +133,7 @@ GlobalVariable::GlobalVariable(int16_t segValue, int16_t off)
|
|||||||
globIdx = i;
|
globIdx = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
string GlobalVariable::walkCondExpr(Function *, int *) const
|
QString GlobalVariable::walkCondExpr(Function *, int *) const
|
||||||
{
|
{
|
||||||
if(valid)
|
if(valid)
|
||||||
return Project::get()->symtab[globIdx].name;
|
return Project::get()->symtab[globIdx].name;
|
||||||
@ -190,12 +191,10 @@ GlobalVariableIdx::GlobalVariableIdx (int16_t segValue, int16_t off, uint8_t reg
|
|||||||
printf ("Error, indexed-glob var not found in local id table\n");
|
printf ("Error, indexed-glob var not found in local id table\n");
|
||||||
idxGlbIdx = i;
|
idxGlbIdx = i;
|
||||||
}
|
}
|
||||||
string GlobalVariableIdx::walkCondExpr(Function *pProc, int *) const
|
QString GlobalVariableIdx::walkCondExpr(Function *pProc, int *) const
|
||||||
{
|
{
|
||||||
ostringstream o;
|
|
||||||
auto bwGlb = &pProc->localId.id_arr[idxGlbIdx].id.bwGlb;
|
auto bwGlb = &pProc->localId.id_arr[idxGlbIdx].id.bwGlb;
|
||||||
o << (bwGlb->seg << 4) + bwGlb->off << "["<<Machine_X86::regName(bwGlb->regi)<<"]";
|
return QString("%1[%2]").arg((bwGlb->seg << 4) + bwGlb->off).arg(Machine_X86::regName(bwGlb->regi));
|
||||||
return o.str();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -264,22 +263,22 @@ AstIdent *AstIdent::idID (const ID *retVal, LOCAL_ID *locsym, iICODE ix_)
|
|||||||
AstIdent *newExp=nullptr;
|
AstIdent *newExp=nullptr;
|
||||||
switch(retVal->type)
|
switch(retVal->type)
|
||||||
{
|
{
|
||||||
case TYPE_LONG_SIGN:
|
case TYPE_LONG_SIGN:
|
||||||
{
|
{
|
||||||
newExp = new AstIdent();
|
newExp = new AstIdent();
|
||||||
idx = locsym->newLongReg (TYPE_LONG_SIGN, retVal->longId(), ix_);
|
idx = locsym->newLongReg (TYPE_LONG_SIGN, retVal->longId(), ix_);
|
||||||
newExp->ident.idType = LONG_VAR;
|
newExp->ident.idType = LONG_VAR;
|
||||||
newExp->ident.idNode.longIdx = idx;
|
newExp->ident.idNode.longIdx = idx;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TYPE_WORD_SIGN:
|
case TYPE_WORD_SIGN:
|
||||||
newExp = new RegisterNode(locsym->newByteWordReg(retVal->type, retVal->id.regi),WORD_REG,locsym);
|
newExp = new RegisterNode(locsym->newByteWordReg(retVal->type, retVal->id.regi),WORD_REG,locsym);
|
||||||
break;
|
break;
|
||||||
case TYPE_BYTE_SIGN:
|
case TYPE_BYTE_SIGN:
|
||||||
newExp = new RegisterNode(locsym->newByteWordReg(retVal->type, retVal->id.regi),BYTE_REG,locsym);
|
newExp = new RegisterNode(locsym->newByteWordReg(retVal->type, retVal->id.regi),BYTE_REG,locsym);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr,"AstIdent::idID unhandled type %d\n",retVal->type);
|
fprintf(stderr,"AstIdent::idID unhandled type %d\n",retVal->type);
|
||||||
}
|
}
|
||||||
return (newExp);
|
return (newExp);
|
||||||
}
|
}
|
||||||
@ -353,13 +352,13 @@ Expr *AstIdent::id(const LLInst &ll_insn, opLoc sd, Function * pProc, iICODE ix_
|
|||||||
{
|
{
|
||||||
eReg selected;
|
eReg selected;
|
||||||
switch (pm.regi) {
|
switch (pm.regi) {
|
||||||
case INDEX_SI: selected = rSI; break;
|
case INDEX_SI: selected = rSI; break;
|
||||||
case INDEX_DI: selected = rDI; break;
|
case INDEX_DI: selected = rDI; break;
|
||||||
case INDEX_BP: selected = rBP; break;
|
case INDEX_BP: selected = rBP; break;
|
||||||
case INDEX_BX: selected = rBX; break;
|
case INDEX_BX: selected = rBX; break;
|
||||||
default:
|
default:
|
||||||
newExp = nullptr;
|
newExp = nullptr;
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
//NOTICE: was selected, 0
|
//NOTICE: was selected, 0
|
||||||
newExp = new RegisterNode(LLOperand(selected, 0), &pProc->localId);
|
newExp = new RegisterNode(LLOperand(selected, 0), &pProc->localId);
|
||||||
@ -430,22 +429,22 @@ int AstIdent::hlTypeSize(Function *pproc) const
|
|||||||
{
|
{
|
||||||
switch (ident.idType)
|
switch (ident.idType)
|
||||||
{
|
{
|
||||||
case GLOB_VAR:
|
case GLOB_VAR:
|
||||||
assert(false);
|
assert(false);
|
||||||
return 1;
|
return 1;
|
||||||
case LOCAL_VAR:
|
case LOCAL_VAR:
|
||||||
return (hlSize[pproc->localId.id_arr[ident.idNode.localIdx].type]);
|
return (hlSize[pproc->localId.id_arr[ident.idNode.localIdx].type]);
|
||||||
case PARAM:
|
case PARAM:
|
||||||
return (hlSize[pproc->args[ident.idNode.paramIdx].type]);
|
return (hlSize[pproc->args[ident.idNode.paramIdx].type]);
|
||||||
case STRING:
|
case STRING:
|
||||||
return (2);
|
return (2);
|
||||||
case LONG_VAR:
|
case LONG_VAR:
|
||||||
return (4);
|
return (4);
|
||||||
case OTHER:
|
case OTHER:
|
||||||
return (2);
|
return (2);
|
||||||
default:
|
default:
|
||||||
assert(false);
|
assert(false);
|
||||||
return -1;
|
return -1;
|
||||||
} /* eos */
|
} /* eos */
|
||||||
}
|
}
|
||||||
hlType BinaryOperator::expType(Function *pproc) const
|
hlType BinaryOperator::expType(Function *pproc) const
|
||||||
@ -479,24 +478,24 @@ hlType AstIdent::expType(Function *pproc) const
|
|||||||
{
|
{
|
||||||
switch (ident.idType)
|
switch (ident.idType)
|
||||||
{
|
{
|
||||||
case UNDEF:
|
case UNDEF:
|
||||||
case CONSTANT:
|
case CONSTANT:
|
||||||
case FUNCTION:
|
case FUNCTION:
|
||||||
case REGISTER:
|
case REGISTER:
|
||||||
case GLOB_VAR:
|
case GLOB_VAR:
|
||||||
case GLOB_VAR_IDX:
|
case GLOB_VAR_IDX:
|
||||||
assert(false);
|
assert(false);
|
||||||
return TYPE_UNKNOWN;
|
return TYPE_UNKNOWN;
|
||||||
case LOCAL_VAR:
|
case LOCAL_VAR:
|
||||||
return (pproc->localId.id_arr[ident.idNode.localIdx].type);
|
return (pproc->localId.id_arr[ident.idNode.localIdx].type);
|
||||||
case PARAM:
|
case PARAM:
|
||||||
return (pproc->args[ident.idNode.paramIdx].type);
|
return (pproc->args[ident.idNode.paramIdx].type);
|
||||||
case STRING:
|
case STRING:
|
||||||
return (TYPE_STR);
|
return (TYPE_STR);
|
||||||
case LONG_VAR:
|
case LONG_VAR:
|
||||||
return (pproc->localId.id_arr[ident.idNode.longIdx].type);
|
return (pproc->localId.id_arr[ident.idNode.longIdx].type);
|
||||||
default:
|
default:
|
||||||
return (TYPE_UNKNOWN);
|
return (TYPE_UNKNOWN);
|
||||||
} /* eos */
|
} /* eos */
|
||||||
return (TYPE_UNKNOWN);
|
return (TYPE_UNKNOWN);
|
||||||
}
|
}
|
||||||
@ -509,177 +508,159 @@ hlType AstIdent::expType(Function *pproc) const
|
|||||||
Expr * HlTypeSupport::performLongRemoval (eReg regi, LOCAL_ID *locId, Expr *tree)
|
Expr * HlTypeSupport::performLongRemoval (eReg regi, LOCAL_ID *locId, Expr *tree)
|
||||||
{
|
{
|
||||||
switch (tree->m_type) {
|
switch (tree->m_type) {
|
||||||
case BOOLEAN_OP:
|
case BOOLEAN_OP:
|
||||||
case POST_INC: case POST_DEC:
|
case POST_INC: case POST_DEC:
|
||||||
case PRE_INC: case PRE_DEC:
|
case PRE_INC: case PRE_DEC:
|
||||||
case NEGATION: case ADDRESSOF:
|
case NEGATION: case ADDRESSOF:
|
||||||
case DEREFERENCE:
|
case DEREFERENCE:
|
||||||
case IDENTIFIER:
|
case IDENTIFIER:
|
||||||
return tree->performLongRemoval(regi,locId);
|
return tree->performLongRemoval(regi,locId);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr,"performLongRemoval attemped on %d\n",tree->m_type);
|
fprintf(stderr,"performLongRemoval attemped on %d\n",tree->m_type);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return tree;
|
return tree;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returns the string located in image, formatted in C format. */
|
/* Returns the string located in image, formatted in C format. */
|
||||||
static std::string getString (int offset)
|
static QString getString (int offset)
|
||||||
{
|
{
|
||||||
PROG &prog(Project::get()->prog);
|
PROG &prog(Project::get()->prog);
|
||||||
ostringstream o;
|
QString o;
|
||||||
int strLen, i;
|
int strLen, i;
|
||||||
|
|
||||||
strLen = strSize (&prog.image()[offset], '\0');
|
strLen = strSize (&prog.image()[offset], '\0');
|
||||||
o << '"';
|
o += '"';
|
||||||
for (i = 0; i < strLen; i++)
|
for (i = 0; i < strLen; i++)
|
||||||
o<<cChar(prog.image()[offset+i]);
|
o += cChar(prog.image()[offset+i]);
|
||||||
o << "\"\0";
|
o += "\"\0";
|
||||||
return (o.str());
|
return o;
|
||||||
}
|
}
|
||||||
string BinaryOperator::walkCondExpr(Function * pProc, int* numLoc) const
|
QString BinaryOperator::walkCondExpr(Function * pProc, int* numLoc) const
|
||||||
{
|
{
|
||||||
std::ostringstream outStr;
|
|
||||||
outStr << "(";
|
|
||||||
if(m_op!=NOT)
|
|
||||||
{
|
|
||||||
outStr << lhs()->walkCondExpr(pProc, numLoc);
|
|
||||||
}
|
|
||||||
assert(rhs());
|
assert(rhs());
|
||||||
outStr << condOpSym[m_op];
|
|
||||||
outStr << rhs()->walkCondExpr(pProc, numLoc);
|
return QString("(%1%2%3)")
|
||||||
outStr << ")";
|
.arg((m_op!=NOT) ? lhs()->walkCondExpr(pProc, numLoc) : "")
|
||||||
return outStr.str();
|
.arg(condOpSym[m_op])
|
||||||
|
.arg(rhs()->walkCondExpr(pProc, numLoc));
|
||||||
}
|
}
|
||||||
string AstIdent::walkCondExpr(Function *pProc, int *numLoc) const
|
QString AstIdent::walkCondExpr(Function *pProc, int *numLoc) const
|
||||||
{
|
{
|
||||||
int16_t off; /* temporal - for OTHER */
|
int16_t off; /* temporal - for OTHER */
|
||||||
ID* id; /* Pointer to local identifier table */
|
ID* id; /* Pointer to local identifier table */
|
||||||
BWGLB_TYPE* bwGlb; /* Ptr to BWGLB_TYPE (global indexed var) */
|
BWGLB_TYPE* bwGlb; /* Ptr to BWGLB_TYPE (global indexed var) */
|
||||||
STKSYM * psym; /* Pointer to argument in the stack */
|
STKSYM * psym; /* Pointer to argument in the stack */
|
||||||
std::ostringstream outStr,codeOut;
|
QString codeContents;
|
||||||
|
QString collectedContents;
|
||||||
|
|
||||||
|
QTextStream codeOut(&codeContents);
|
||||||
|
QTextStream o(&collectedContents);
|
||||||
|
|
||||||
std::ostringstream o;
|
|
||||||
switch (ident.idType)
|
switch (ident.idType)
|
||||||
{
|
{
|
||||||
case LOCAL_VAR:
|
case LOCAL_VAR:
|
||||||
o << pProc->localId.id_arr[ident.idNode.localIdx].name;
|
o << pProc->localId.id_arr[ident.idNode.localIdx].name;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PARAM:
|
case PARAM:
|
||||||
psym = &pProc->args[ident.idNode.paramIdx];
|
psym = &pProc->args[ident.idNode.paramIdx];
|
||||||
if (psym->hasMacro)
|
if (psym->hasMacro)
|
||||||
o << psym->macro<<"("<<psym->name<< ")";
|
o << psym->macro<<"("<<psym->name<< ")";
|
||||||
else
|
else
|
||||||
o << psym->name;
|
o << psym->name;
|
||||||
break;
|
break;
|
||||||
case STRING:
|
case STRING:
|
||||||
o << getString (ident.idNode.strIdx);
|
o << getString (ident.idNode.strIdx);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LONG_VAR:
|
case LONG_VAR:
|
||||||
id = &pProc->localId.id_arr[ident.idNode.longIdx];
|
id = &pProc->localId.id_arr[ident.idNode.longIdx];
|
||||||
if (id->name[0] != '\0') /* STK_FRAME & REG w/name*/
|
if (id->name[0] != '\0') /* STK_FRAME & REG w/name*/
|
||||||
o << id->name;
|
o << id->name;
|
||||||
else if (id->loc == REG_FRAME)
|
else if (id->loc == REG_FRAME)
|
||||||
{
|
{
|
||||||
id->setLocalName(++(*numLoc));
|
id->setLocalName(++(*numLoc));
|
||||||
codeOut <<TypeContainer::typeName(id->type)<< " "<<id->name<<"; ";
|
codeOut <<TypeContainer::typeName(id->type)<< " "<<id->name<<"; ";
|
||||||
codeOut <<"/* "<<Machine_X86::regName(id->longId().h()) << ":" <<
|
codeOut <<"/* "<<Machine_X86::regName(id->longId().h()) << ":" <<
|
||||||
Machine_X86::regName(id->longId().l()) << " */\n";
|
Machine_X86::regName(id->longId().l()) << " */\n";
|
||||||
o << id->name;
|
o << id->name;
|
||||||
pProc->localId.propLongId (id->longId().l(),id->longId().h(), id->name.c_str());
|
pProc->localId.propLongId (id->longId().l(),id->longId().h(), id->name);
|
||||||
}
|
}
|
||||||
else /* GLB_FRAME */
|
else /* GLB_FRAME */
|
||||||
{
|
{
|
||||||
if (id->id.longGlb.regi == 0) /* not indexed */
|
if (id->id.longGlb.regi == 0) /* not indexed */
|
||||||
o << "[" << (id->id.longGlb.seg<<4) + id->id.longGlb.offH <<"]";
|
o << "[" << (id->id.longGlb.seg<<4) + id->id.longGlb.offH <<"]";
|
||||||
else if (id->id.longGlb.regi == rBX)
|
else if (id->id.longGlb.regi == rBX)
|
||||||
o << "[" << (id->id.longGlb.seg<<4) + id->id.longGlb.offH <<"][bx]";
|
o << "[" << (id->id.longGlb.seg<<4) + id->id.longGlb.offH <<"][bx]";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OTHER:
|
case OTHER:
|
||||||
off = ident.idNode.other.off;
|
off = ident.idNode.other.off;
|
||||||
o << Machine_X86::regName(ident.idNode.other.seg)<< "[";
|
o << Machine_X86::regName(ident.idNode.other.seg)<< "[";
|
||||||
o << Machine_X86::regName(ident.idNode.other.regi);
|
o << Machine_X86::regName(ident.idNode.other.regi);
|
||||||
if (off < 0)
|
if (off < 0)
|
||||||
o << "-"<< hexStr (-off);
|
o << "-"<< hexStr (-off);
|
||||||
else if (off>0)
|
else if (off>0)
|
||||||
o << "+"<< hexStr (off);
|
o << "+"<< hexStr (off);
|
||||||
o << "]";
|
o << "]";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(false);
|
assert(false);
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
|
|
||||||
} /* eos */
|
} /* eos */
|
||||||
outStr << o.str();
|
cCode.appendDecl(codeContents);
|
||||||
cCode.appendDecl(codeOut.str());
|
return collectedContents;
|
||||||
return outStr.str();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
string UnaryOperator::walkCondExpr(Function *pProc, int *numLoc) const
|
QString UnaryOperator::wrapUnary(Function *pProc, int *numLoc,QChar op) const
|
||||||
{
|
{
|
||||||
std::ostringstream outStr;
|
QString outStr = op;
|
||||||
bool needBracket=true;
|
QString inner = unaryExp->walkCondExpr (pProc, numLoc);
|
||||||
|
if (unaryExp->m_type == IDENTIFIER)
|
||||||
|
outStr += inner;
|
||||||
|
else
|
||||||
|
outStr += "("+inner+')';
|
||||||
|
return outStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString UnaryOperator::walkCondExpr(Function *pProc, int *numLoc) const
|
||||||
|
{
|
||||||
|
QString outStr;
|
||||||
switch(m_type)
|
switch(m_type)
|
||||||
{
|
{
|
||||||
case NEGATION:
|
case NEGATION:
|
||||||
if (unaryExp->m_type == IDENTIFIER)
|
outStr+=wrapUnary(pProc,numLoc,'!');
|
||||||
{
|
break;
|
||||||
needBracket = false;
|
|
||||||
outStr << "!";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
outStr << "! (";
|
|
||||||
outStr << unaryExp->walkCondExpr (pProc, numLoc);
|
|
||||||
if (needBracket == true)
|
|
||||||
outStr << ")";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ADDRESSOF:
|
case ADDRESSOF:
|
||||||
if (unaryExp->m_type == IDENTIFIER)
|
outStr+=wrapUnary(pProc,numLoc,'&');
|
||||||
{
|
break;
|
||||||
needBracket = false;
|
|
||||||
outStr << "&";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
outStr << "&(";
|
|
||||||
outStr << unaryExp->walkCondExpr (pProc, numLoc);
|
|
||||||
if (needBracket == true)
|
|
||||||
outStr << ")";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DEREFERENCE:
|
case DEREFERENCE:
|
||||||
outStr << "*";
|
outStr+=wrapUnary(pProc,numLoc,'*');
|
||||||
if (unaryExp->m_type == IDENTIFIER)
|
break;
|
||||||
needBracket = false;
|
|
||||||
else
|
|
||||||
outStr << "(";
|
|
||||||
outStr << unaryExp->walkCondExpr (pProc, numLoc);
|
|
||||||
if (needBracket == true)
|
|
||||||
outStr << ")";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case POST_INC:
|
case POST_INC:
|
||||||
outStr << unaryExp->walkCondExpr (pProc, numLoc) << "++";
|
outStr += unaryExp->walkCondExpr (pProc, numLoc) + "++";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case POST_DEC:
|
case POST_DEC:
|
||||||
outStr << unaryExp->walkCondExpr (pProc, numLoc) << "--";
|
outStr += unaryExp->walkCondExpr (pProc, numLoc) + "--";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PRE_INC:
|
case PRE_INC:
|
||||||
outStr << "++"<< unaryExp->walkCondExpr (pProc, numLoc);
|
outStr += "++" + unaryExp->walkCondExpr (pProc, numLoc);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PRE_DEC:
|
case PRE_DEC:
|
||||||
outStr << "--"<< unaryExp->walkCondExpr (pProc, numLoc);
|
outStr += "--" + unaryExp->walkCondExpr (pProc, numLoc);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return outStr.str();
|
return outStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Walks the conditional expression tree and returns the result on a string */
|
/* Walks the conditional expression tree and returns the result on a string */
|
||||||
@ -726,18 +707,18 @@ Expr *UnaryOperator::insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *lo
|
|||||||
Expr *temp;
|
Expr *temp;
|
||||||
|
|
||||||
switch (m_type) {
|
switch (m_type) {
|
||||||
case NEGATION:
|
case NEGATION:
|
||||||
case ADDRESSOF:
|
case ADDRESSOF:
|
||||||
case DEREFERENCE:
|
case DEREFERENCE:
|
||||||
temp = unaryExp->insertSubTreeReg( _expr, regi, locsym);
|
temp = unaryExp->insertSubTreeReg( _expr, regi, locsym);
|
||||||
if (nullptr!=temp)
|
if (nullptr!=temp)
|
||||||
{
|
{
|
||||||
unaryExp = temp;
|
unaryExp = temp;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr,"insertSubTreeReg attempt on unhandled type %d\n",m_type);
|
fprintf(stderr,"insertSubTreeReg attempt on unhandled type %d\n",m_type);
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -843,22 +824,22 @@ Expr *BinaryOperator::inverse() const
|
|||||||
BinaryOperator *res=reinterpret_cast<BinaryOperator *>(this->clone());
|
BinaryOperator *res=reinterpret_cast<BinaryOperator *>(this->clone());
|
||||||
switch (m_op)
|
switch (m_op)
|
||||||
{
|
{
|
||||||
case LESS_EQUAL: case LESS: case EQUAL:
|
case LESS_EQUAL: case LESS: case EQUAL:
|
||||||
case NOT_EQUAL: case GREATER: case GREATER_EQUAL:
|
case NOT_EQUAL: case GREATER: case GREATER_EQUAL:
|
||||||
res->m_op = invCondOp[m_op];
|
res->m_op = invCondOp[m_op];
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
case AND: case OR: case XOR: case NOT: case ADD:
|
case AND: case OR: case XOR: case NOT: case ADD:
|
||||||
case SUB: case MUL: case DIV: case SHR: case SHL: case MOD:
|
case SUB: case MUL: case DIV: case SHR: case SHL: case MOD:
|
||||||
return UnaryOperator::Create(NEGATION, res);
|
return UnaryOperator::Create(NEGATION, res);
|
||||||
|
|
||||||
case DBL_AND: case DBL_OR:
|
case DBL_AND: case DBL_OR:
|
||||||
res->m_op = invCondOp[m_op];
|
res->m_op = invCondOp[m_op];
|
||||||
res->m_lhs=m_lhs->inverse ();
|
res->m_lhs=m_lhs->inverse ();
|
||||||
res->m_rhs=m_rhs->inverse ();
|
res->m_rhs=m_rhs->inverse ();
|
||||||
return res;
|
return res;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr,"BinaryOperator::inverse attempt on unhandled op %d\n",m_op);
|
fprintf(stderr,"BinaryOperator::inverse attempt on unhandled op %d\n",m_op);
|
||||||
} /* eos */
|
} /* eos */
|
||||||
assert(false);
|
assert(false);
|
||||||
return res;
|
return res;
|
||||||
@ -880,7 +861,7 @@ eReg AstIdent::otherLongRegi (eReg regi, int idx, LOCAL_ID *locTbl)
|
|||||||
{
|
{
|
||||||
ID *id = &locTbl->id_arr[idx];
|
ID *id = &locTbl->id_arr[idx];
|
||||||
if ((id->loc == REG_FRAME) and ((id->type == TYPE_LONG_SIGN) or
|
if ((id->loc == REG_FRAME) and ((id->type == TYPE_LONG_SIGN) or
|
||||||
(id->type == TYPE_LONG_UNSIGN)))
|
(id->type == TYPE_LONG_UNSIGN)))
|
||||||
{
|
{
|
||||||
if (id->longId().h() == regi)
|
if (id->longId().h() == regi)
|
||||||
return (id->longId().l());
|
return (id->longId().l());
|
||||||
@ -891,14 +872,12 @@ eReg AstIdent::otherLongRegi (eReg regi, int idx, LOCAL_ID *locTbl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
string Constant::walkCondExpr(Function *, int *) const
|
QString Constant::walkCondExpr(Function *, int *) const
|
||||||
{
|
{
|
||||||
ostringstream o;
|
|
||||||
if (kte.kte < 1000)
|
if (kte.kte < 1000)
|
||||||
o << kte.kte;
|
return QString::number(kte.kte);
|
||||||
else
|
else
|
||||||
o << "0x"<<std::hex << kte.kte;
|
return "0x" + QString::number(kte.kte,16);
|
||||||
return o.str();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int Constant::hlTypeSize(Function *) const
|
int Constant::hlTypeSize(Function *) const
|
||||||
@ -911,7 +890,7 @@ hlType Constant::expType(Function *pproc) const
|
|||||||
return TYPE_CONST;
|
return TYPE_CONST;
|
||||||
}
|
}
|
||||||
|
|
||||||
string FuncNode::walkCondExpr(Function *pProc, int *numLoc) const
|
QString FuncNode::walkCondExpr(Function *pProc, int *numLoc) const
|
||||||
{
|
{
|
||||||
return pProc->writeCall(call.proc,*call.args, numLoc);
|
return pProc->writeCall(call.proc,*call.args, numLoc);
|
||||||
}
|
}
|
||||||
|
|||||||
110
src/backend.cpp
110
src/backend.cpp
@ -10,8 +10,10 @@
|
|||||||
#include "project.h"
|
#include "project.h"
|
||||||
#include "CallGraph.h"
|
#include "CallGraph.h"
|
||||||
|
|
||||||
#include <QDir>
|
#include <QtCore/QDir>
|
||||||
#include <QFile>
|
#include <QtCore/QFile>
|
||||||
|
#include <QtCore/QStringList>
|
||||||
|
#include <QtCore/QDebug>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <boost/range.hpp>
|
#include <boost/range.hpp>
|
||||||
@ -41,14 +43,14 @@ int getNextLabel()
|
|||||||
/* displays statistics on the subroutine */
|
/* displays statistics on the subroutine */
|
||||||
void Function::displayStats ()
|
void Function::displayStats ()
|
||||||
{
|
{
|
||||||
printf("\nStatistics - Subroutine %s\n", name.c_str());
|
qDebug() << "\nStatistics - Subroutine" << name;
|
||||||
printf ("Number of Icode instructions:\n");
|
qDebug() << "Number of Icode instructions:";
|
||||||
printf (" Low-level : %4d\n", stats.numLLIcode);
|
qDebug() << " Low-level :" << stats.numLLIcode;
|
||||||
if (! (flg & PROC_ASM))
|
if (not (flg & PROC_ASM))
|
||||||
{
|
{
|
||||||
printf (" High-level: %4d\n", stats.numHLIcode);
|
qDebug() << " High-level:"<<stats.numHLIcode;
|
||||||
printf (" Percentage reduction: %2.2f%%\n", 100.0 - (stats.numHLIcode *
|
qDebug() << QString(" Percentage reduction: %1%%").arg(100.0 - (stats.numHLIcode *
|
||||||
100.0) / stats.numLLIcode);
|
100.0) / stats.numLLIcode,4,'f',2,QChar('0'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,7 +108,7 @@ char *cChar (uint8_t c)
|
|||||||
* Note: to get to the value of the variable:
|
* Note: to get to the value of the variable:
|
||||||
* com file: prog.Image[operand]
|
* com file: prog.Image[operand]
|
||||||
* exe file: prog.Image[operand+0x100] */
|
* exe file: prog.Image[operand+0x100] */
|
||||||
static void printGlobVar (std::ostream &ostr,SYM * psym)
|
static void printGlobVar (QTextStream &ostr,SYM * psym)
|
||||||
{
|
{
|
||||||
int j;
|
int j;
|
||||||
PROG &prog(Project::get()->prog);
|
PROG &prog(Project::get()->prog);
|
||||||
@ -129,10 +131,10 @@ static void printGlobVar (std::ostream &ostr,SYM * psym)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
ostringstream strContents;
|
QString strContents;
|
||||||
for (j=0; j < psym->size; j++)
|
for (j=0; j < psym->size; j++)
|
||||||
strContents << cChar(prog.image()[relocOp + j]);
|
strContents += cChar(prog.image()[relocOp + j]);
|
||||||
ostr << "char\t*"<<psym->name<<" = \""<<strContents.str()<<"\";\n";
|
ostr << "char\t*"<<psym->name<<" = \""<<strContents<<"\";\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -143,7 +145,8 @@ static void printGlobVar (std::ostream &ostr,SYM * psym)
|
|||||||
* initialization. */
|
* initialization. */
|
||||||
void Project::writeGlobSymTable()
|
void Project::writeGlobSymTable()
|
||||||
{
|
{
|
||||||
std::ostringstream ostr;
|
QString contents;
|
||||||
|
QTextStream ostr(&contents);
|
||||||
|
|
||||||
if (symtab.empty())
|
if (symtab.empty())
|
||||||
return;
|
return;
|
||||||
@ -151,7 +154,7 @@ void Project::writeGlobSymTable()
|
|||||||
for (SYM &sym : symtab)
|
for (SYM &sym : symtab)
|
||||||
{
|
{
|
||||||
if (sym.duVal.isUSE_VAL()) /* first used */
|
if (sym.duVal.isUSE_VAL()) /* first used */
|
||||||
printGlobVar (ostr,&sym);
|
printGlobVar (ostr,&sym);
|
||||||
else { /* first defined */
|
else { /* first defined */
|
||||||
switch (sym.size) {
|
switch (sym.size) {
|
||||||
case 1: ostr<<"uint8_t\t"; break;
|
case 1: ostr<<"uint8_t\t"; break;
|
||||||
@ -167,13 +170,14 @@ void Project::writeGlobSymTable()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ostr<< "\n";
|
ostr<< "\n";
|
||||||
cCode.appendDecl( ostr.str() );
|
ostr.flush();
|
||||||
|
cCode.appendDecl( contents );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Writes the header information and global variables to the output C file
|
/* Writes the header information and global variables to the output C file
|
||||||
* fp. */
|
* fp. */
|
||||||
static void writeHeader (std::ostream &_ios, const std::string &fileName)
|
static void writeHeader (QIODevice &_ios, const std::string &fileName)
|
||||||
{
|
{
|
||||||
PROG &prog(Project::get()->prog);
|
PROG &prog(Project::get()->prog);
|
||||||
/* Write header information */
|
/* Write header information */
|
||||||
@ -210,10 +214,11 @@ static void emitFwdGotoLabel (ICODE * pt, int indLevel)
|
|||||||
|
|
||||||
/* Writes the procedure's declaration (including arguments), local variables,
|
/* Writes the procedure's declaration (including arguments), local variables,
|
||||||
* and invokes the procedure that writes the code of the given record *hli */
|
* and invokes the procedure that writes the code of the given record *hli */
|
||||||
void Function::codeGen (std::ostream &fs)
|
void Function::codeGen (QIODevice &fs)
|
||||||
{
|
{
|
||||||
int numLoc;
|
int numLoc;
|
||||||
ostringstream ostr;
|
QString ostr_contents;
|
||||||
|
QTextStream ostr(&ostr_contents);
|
||||||
//STKFRAME * args; /* Procedure arguments */
|
//STKFRAME * args; /* Procedure arguments */
|
||||||
//char buf[200], /* Procedure's definition */
|
//char buf[200], /* Procedure's definition */
|
||||||
// arg[30]; /* One argument */
|
// arg[30]; /* One argument */
|
||||||
@ -222,30 +227,27 @@ void Function::codeGen (std::ostream &fs)
|
|||||||
/* Write procedure/function header */
|
/* Write procedure/function header */
|
||||||
cCode.init();
|
cCode.init();
|
||||||
if (flg & PROC_IS_FUNC) /* Function */
|
if (flg & PROC_IS_FUNC) /* Function */
|
||||||
ostr<< "\n"<<TypeContainer::typeName(retVal.type)<<" "<<name<<" (";
|
ostr << QString("\n%1 %2 (").arg(TypeContainer::typeName(retVal.type)).arg(name);
|
||||||
else /* Procedure */
|
else /* Procedure */
|
||||||
ostr<< "\nvoid "<<name<<" (";
|
ostr << "\nvoid "+name+" (";
|
||||||
|
|
||||||
/* Write arguments */
|
/* Write arguments */
|
||||||
struct validArg
|
struct validArg
|
||||||
{
|
{
|
||||||
bool operator()(STKSYM &s) { return s.invalid==false;}
|
bool operator()(STKSYM &s) { return s.invalid==false;}
|
||||||
};
|
};
|
||||||
auto valid_args = args | filtered(validArg());
|
QStringList parts;
|
||||||
int count_valid = std::distance(valid_args.begin(),valid_args.end());
|
for (STKSYM &arg : (args | filtered(validArg())))
|
||||||
for (STKSYM &arg : valid_args)
|
|
||||||
{
|
{
|
||||||
ostr<<hlTypes[arg.type]<<" "<<arg.name;
|
parts << QString("%1 %2").arg(hlTypes[arg.type]).arg(arg.name);
|
||||||
if(--count_valid!=0)
|
|
||||||
ostr<<", ";
|
|
||||||
}
|
}
|
||||||
ostr<<")\n";
|
ostr << parts.join(", ")+")\n";
|
||||||
|
|
||||||
/* Write comments */
|
/* Write comments */
|
||||||
writeProcComments( ostr );
|
writeProcComments( ostr );
|
||||||
|
|
||||||
/* Write local variables */
|
/* Write local variables */
|
||||||
if (! (flg & PROC_ASM))
|
if (not (flg & PROC_ASM))
|
||||||
{
|
{
|
||||||
numLoc = 0;
|
numLoc = 0;
|
||||||
for (ID &refId : localId )
|
for (ID &refId : localId )
|
||||||
@ -273,7 +275,9 @@ void Function::codeGen (std::ostream &fs)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fs<<ostr.str();
|
ostr.flush();
|
||||||
|
fs.write(ostr_contents.toLatin1());
|
||||||
|
|
||||||
/* Write procedure's code */
|
/* Write procedure's code */
|
||||||
if (flg & PROC_ASM) /* generate assembler */
|
if (flg & PROC_ASM) /* generate assembler */
|
||||||
{
|
{
|
||||||
@ -290,30 +294,35 @@ void Function::codeGen (std::ostream &fs)
|
|||||||
freeBundle (&cCode);
|
freeBundle (&cCode);
|
||||||
|
|
||||||
/* Write Live register analysis information */
|
/* Write Live register analysis information */
|
||||||
if (option.verbose)
|
if (option.verbose) {
|
||||||
|
QString debug_contents;
|
||||||
|
QTextStream debug_stream(&debug_contents);
|
||||||
for (size_t i = 0; i < numBBs; i++)
|
for (size_t i = 0; i < numBBs; i++)
|
||||||
{
|
{
|
||||||
pBB = m_dfsLast[i];
|
pBB = m_dfsLast[i];
|
||||||
if (pBB->flg & INVALID_BB) continue; /* skip invalid BBs */
|
if (pBB->flg & INVALID_BB) continue; /* skip invalid BBs */
|
||||||
cout << "BB "<<i<<"\n";
|
debug_stream << "BB "<<i<<"\n";
|
||||||
cout << " Start = "<<pBB->begin()->loc_ip;
|
debug_stream << " Start = "<<pBB->begin()->loc_ip;
|
||||||
cout << ", end = "<<pBB->begin()->loc_ip+pBB->size()<<"\n";
|
debug_stream << ", end = "<<pBB->begin()->loc_ip+pBB->size()<<"\n";
|
||||||
cout << " LiveUse = ";
|
debug_stream << " LiveUse = ";
|
||||||
Machine_X86::writeRegVector(cout,pBB->liveUse);
|
Machine_X86::writeRegVector(debug_stream,pBB->liveUse);
|
||||||
cout << "\n Def = ";
|
debug_stream << "\n Def = ";
|
||||||
Machine_X86::writeRegVector(cout,pBB->def);
|
Machine_X86::writeRegVector(debug_stream,pBB->def);
|
||||||
cout << "\n LiveOut = ";
|
debug_stream << "\n LiveOut = ";
|
||||||
Machine_X86::writeRegVector(cout,pBB->liveOut);
|
Machine_X86::writeRegVector(debug_stream,pBB->liveOut);
|
||||||
cout << "\n LiveIn = ";
|
debug_stream << "\n LiveIn = ";
|
||||||
Machine_X86::writeRegVector(cout,pBB->liveIn);
|
Machine_X86::writeRegVector(debug_stream,pBB->liveIn);
|
||||||
cout <<"\n\n";
|
debug_stream <<"\n\n";
|
||||||
}
|
}
|
||||||
|
debug_stream.flush();
|
||||||
|
qDebug() << debug_contents.toLatin1();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Recursive procedure. Displays the procedure's code in depth-first order
|
/* Recursive procedure. Displays the procedure's code in depth-first order
|
||||||
* of the call graph. */
|
* of the call graph. */
|
||||||
static void backBackEnd (CALL_GRAPH * pcallGraph, std::ostream &_ios)
|
static void backBackEnd (CALL_GRAPH * pcallGraph, QIODevice &_ios)
|
||||||
{
|
{
|
||||||
|
|
||||||
// IFace.Yield(); /* This is a good place to yield to other apps */
|
// IFace.Yield(); /* This is a good place to yield to other apps */
|
||||||
@ -338,7 +347,7 @@ static void backBackEnd (CALL_GRAPH * pcallGraph, std::ostream &_ios)
|
|||||||
/* Generate statistics */
|
/* Generate statistics */
|
||||||
if (option.Stats)
|
if (option.Stats)
|
||||||
pcallGraph->proc->displayStats ();
|
pcallGraph->proc->displayStats ();
|
||||||
if (! (pcallGraph->proc->flg & PROC_ASM))
|
if (not (pcallGraph->proc->flg & PROC_ASM))
|
||||||
{
|
{
|
||||||
stats.totalLL += stats.numLLIcode;
|
stats.totalLL += stats.numLLIcode;
|
||||||
stats.totalHL += stats.numHLIcode;
|
stats.totalHL += stats.numHLIcode;
|
||||||
@ -349,16 +358,15 @@ static void backBackEnd (CALL_GRAPH * pcallGraph, std::ostream &_ios)
|
|||||||
/* Invokes the necessary routines to produce code one procedure at a time. */
|
/* Invokes the necessary routines to produce code one procedure at a time. */
|
||||||
void BackEnd(CALL_GRAPH * pcallGraph)
|
void BackEnd(CALL_GRAPH * pcallGraph)
|
||||||
{
|
{
|
||||||
std::ofstream fs; /* Output C file */
|
|
||||||
|
|
||||||
/* Get output file name */
|
/* Get output file name */
|
||||||
QString outNam(Project::get()->output_name("b")); /* b for beta */
|
QString outNam(Project::get()->output_name("b")); /* b for beta */
|
||||||
|
QFile fs(outNam); /* Output C file */
|
||||||
|
|
||||||
/* Open output file */
|
/* Open output file */
|
||||||
fs.open(outNam.toStdString());
|
if(not fs.open(QFile::WriteOnly|QFile::Text))
|
||||||
if(!fs.is_open())
|
|
||||||
fatalError (CANNOT_OPEN, outNam.toStdString().c_str());
|
fatalError (CANNOT_OPEN, outNam.toStdString().c_str());
|
||||||
std::cout<<"dcc: Writing C beta file "<<outNam.toStdString()<<"\n";
|
|
||||||
|
qDebug()<<"dcc: Writing C beta file"<<outNam;
|
||||||
|
|
||||||
/* Header information */
|
/* Header information */
|
||||||
writeHeader (fs, option.filename.toStdString());
|
writeHeader (fs, option.filename.toStdString());
|
||||||
@ -372,7 +380,7 @@ void BackEnd(CALL_GRAPH * pcallGraph)
|
|||||||
|
|
||||||
/* Close output file */
|
/* Close output file */
|
||||||
fs.close();
|
fs.close();
|
||||||
std::cout << "dcc: Finished writing C beta file\n";
|
qDebug() << "dcc: Finished writing C beta file";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,7 @@
|
|||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <QtCore/QIODevice>
|
||||||
#define deltaProcLines 20
|
#define deltaProcLines 20
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@ -21,26 +21,26 @@ using namespace std;
|
|||||||
* tab is removed and replaced by this label */
|
* tab is removed and replaced by this label */
|
||||||
void strTable::addLabelBundle (int idx, int label)
|
void strTable::addLabelBundle (int idx, int label)
|
||||||
{
|
{
|
||||||
char s[16];
|
QString &processedLine(at(idx));
|
||||||
sprintf (s, "l%d: ", label);
|
QString s = QString("l%1: ").arg(label);
|
||||||
if(at(idx).size()<4)
|
if(processedLine.size()<4)
|
||||||
at(idx)=s;
|
processedLine = s;
|
||||||
else
|
else
|
||||||
at(idx) = string(s)+at(idx).substr(4);
|
processedLine = s+processedLine.mid(4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Writes the contents of the string table on the file fp. */
|
/* Writes the contents of the string table on the file fp. */
|
||||||
static void writeStrTab (std::ostream &ios, strTable &strTab)
|
static void writeStrTab (QIODevice &ios, strTable &strTab)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < strTab.size(); i++)
|
for (size_t i = 0; i < strTab.size(); i++)
|
||||||
ios << strTab[i];
|
ios.write(strTab[i].toLatin1());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Writes the contents of the bundle (procedure code and declaration) to
|
/* Writes the contents of the bundle (procedure code and declaration) to
|
||||||
* a file. */
|
* a file. */
|
||||||
void writeBundle (std::ostream &ios, bundle procCode)
|
void writeBundle (QIODevice &ios, bundle procCode)
|
||||||
{
|
{
|
||||||
writeStrTab (ios, procCode.decl);
|
writeStrTab (ios, procCode.decl);
|
||||||
writeStrTab (ios, procCode.code);
|
writeStrTab (ios, procCode.code);
|
||||||
@ -70,7 +70,7 @@ void bundle::appendCode(const char *format,...)
|
|||||||
code.push_back(buf);
|
code.push_back(buf);
|
||||||
va_end (args);
|
va_end (args);
|
||||||
}
|
}
|
||||||
void bundle::appendCode(const std::string &s)
|
void bundle::appendCode(const QString & s)
|
||||||
{
|
{
|
||||||
code.push_back(s);
|
code.push_back(s);
|
||||||
}
|
}
|
||||||
@ -85,7 +85,7 @@ void bundle::appendDecl(const char *format,...)
|
|||||||
va_end (args);
|
va_end (args);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bundle::appendDecl(const std::string &v)
|
void bundle::appendDecl(const QString &v)
|
||||||
{
|
{
|
||||||
decl.push_back(v);
|
decl.push_back(v);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,7 +11,9 @@
|
|||||||
#include "perfhlib.h"
|
#include "perfhlib.h"
|
||||||
#include "dcc_interface.h"
|
#include "dcc_interface.h"
|
||||||
|
|
||||||
#include <QDir>
|
#include <QtCore/QDir>
|
||||||
|
#include <QtCore/QString>
|
||||||
|
#include <QtCore/QDebug>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
@ -468,7 +470,7 @@ bool LibCheck(Function & pProc)
|
|||||||
if (memcmp(ht[h].htPat, pat, PATLEN) == 0)
|
if (memcmp(ht[h].htPat, pat, PATLEN) == 0)
|
||||||
{
|
{
|
||||||
/* We have a match. Save the name, if not already set */
|
/* We have a match. Save the name, if not already set */
|
||||||
if (pProc.name.empty() ) /* Don't overwrite existing name */
|
if (pProc.name.isEmpty() ) /* Don't overwrite existing name */
|
||||||
{
|
{
|
||||||
/* Give proc the new name */
|
/* Give proc the new name */
|
||||||
pProc.name = ht[h].htSym;
|
pProc.name = ht[h].htSym;
|
||||||
@ -510,7 +512,8 @@ bool LibCheck(Function & pProc)
|
|||||||
pProc.liveOut.setReg(rAX).addReg(rDS);
|
pProc.liveOut.setReg(rAX).addReg(rDS);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr,"Unknown retval type %d for %s in LibCheck\n",pProc.retVal.type,pProc.name.c_str());
|
qCritical() << QString("Unknown retval type %1 for %2 in LibCheck")
|
||||||
|
.arg(pProc.retVal.type).arg(pProc.name);
|
||||||
/*** other types are not considered yet ***/
|
/*** other types are not considered yet ***/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <QTextStream>
|
||||||
using namespace std;
|
using namespace std;
|
||||||
#define intSize 40
|
#define intSize 40
|
||||||
|
|
||||||
@ -150,7 +151,7 @@ static const char *intOthers[] = {
|
|||||||
|
|
||||||
/* Writes the description of the current interrupt. Appends it to the
|
/* Writes the description of the current interrupt. Appends it to the
|
||||||
* string s. */
|
* string s. */
|
||||||
void LLInst::writeIntComment (std::ostringstream &s)
|
void LLInst::writeIntComment (QTextStream &s)
|
||||||
{
|
{
|
||||||
uint32_t src_immed=src().getImm2();
|
uint32_t src_immed=src().getImm2();
|
||||||
s<<"\t/* ";
|
s<<"\t/* ";
|
||||||
@ -188,12 +189,15 @@ void LLInst::writeIntComment (std::ostringstream &s)
|
|||||||
//, &cCode.decl
|
//, &cCode.decl
|
||||||
void Function::writeProcComments()
|
void Function::writeProcComments()
|
||||||
{
|
{
|
||||||
std::ostringstream ostr;
|
QString dest_str;
|
||||||
writeProcComments(ostr);
|
{
|
||||||
cCode.appendDecl(ostr.str());
|
QTextStream ostr(&dest_str);
|
||||||
|
writeProcComments(ostr);
|
||||||
|
}
|
||||||
|
cCode.appendDecl(dest_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Function::writeProcComments(std::ostream &ostr)
|
void Function::writeProcComments(QTextStream &ostr)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
ID *id; /* Pointer to register argument identifier */
|
ID *id; /* Pointer to register argument identifier */
|
||||||
|
|||||||
@ -470,7 +470,7 @@ void Function::structIfs ()
|
|||||||
if ((follow != 0) and (followInEdges > 1))
|
if ((follow != 0) and (followInEdges > 1))
|
||||||
{
|
{
|
||||||
currNode->ifFollow = follow;
|
currNode->ifFollow = follow;
|
||||||
if (!unresolved.empty())
|
if (not unresolved.empty())
|
||||||
flagNodes (unresolved, follow, this);
|
flagNodes (unresolved, follow, this);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -624,7 +624,7 @@ void Function::compoundCond()
|
|||||||
--i;
|
--i;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check (!X and Y) case */
|
/* Check (not X and Y) case */
|
||||||
else if ((thenBB->nodeType == TWO_BRANCH) and (thenBB->numHlIcodes == 1) and
|
else if ((thenBB->nodeType == TWO_BRANCH) and (thenBB->numHlIcodes == 1) and
|
||||||
(thenBB->inEdges.size() == 1) and (thenBB->edges[THEN].BBptr == elseBB))
|
(thenBB->inEdges.size() == 1) and (thenBB->edges[THEN].BBptr == elseBB))
|
||||||
{
|
{
|
||||||
@ -640,7 +640,7 @@ void Function::compoundCond()
|
|||||||
--i;
|
--i;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check (!X or Y) case */
|
/* Check (not X or Y) case */
|
||||||
else if ((elseBB->nodeType == TWO_BRANCH) and (elseBB->numHlIcodes == 1) and
|
else if ((elseBB->nodeType == TWO_BRANCH) and (elseBB->numHlIcodes == 1) and
|
||||||
(elseBB->inEdges.size() == 1) and (elseBB->edges[ELSE].BBptr == thenBB))
|
(elseBB->inEdges.size() == 1) and (elseBB->edges[ELSE].BBptr == thenBB))
|
||||||
{
|
{
|
||||||
|
|||||||
@ -222,7 +222,7 @@ void Function::elimCondCodes ()
|
|||||||
{
|
{
|
||||||
ICODE &a(*defAt);
|
ICODE &a(*defAt);
|
||||||
ICODE &b(*useAt);
|
ICODE &b(*useAt);
|
||||||
reportError (NOT_DEF_USE,a.ll()->getOpcode(),b.ll()->getOpcode());
|
reportError (NOT_DEF_USE,a.ll()->label,a.ll()->getOpcode(),b.ll()->getOpcode());
|
||||||
flg |= PROC_ASM; /* generate asm */
|
flg |= PROC_ASM; /* generate asm */
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -364,7 +364,8 @@ void Function::liveRegAnalysis (LivenessSet &in_liveOut)
|
|||||||
if ((not (pcallee->flg & PROC_ISLIB)) or ( pbb->liveOut.any() ))
|
if ((not (pcallee->flg & PROC_ISLIB)) or ( pbb->liveOut.any() ))
|
||||||
{
|
{
|
||||||
switch (pcallee->retVal.type) {
|
switch (pcallee->retVal.type) {
|
||||||
case TYPE_LONG_SIGN: case TYPE_LONG_UNSIGN:
|
case TYPE_LONG_SIGN:
|
||||||
|
case TYPE_LONG_UNSIGN:
|
||||||
ticode.du1.setDef(rAX).addDef(rDX);
|
ticode.du1.setDef(rAX).addDef(rDX);
|
||||||
//TODO: use Calling convention to properly set regs here
|
//TODO: use Calling convention to properly set regs here
|
||||||
break;
|
break;
|
||||||
@ -977,7 +978,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
|
|||||||
assert(ti_hl->asgn.rhs);
|
assert(ti_hl->asgn.rhs);
|
||||||
_exp = _icHl.call.toAst();
|
_exp = _icHl.call.toAst();
|
||||||
res = Expr::insertSubTreeReg (ti_hl->asgn.rhs,_exp, _retVal->id.regi, &locals);
|
res = Expr::insertSubTreeReg (ti_hl->asgn.rhs,_exp, _retVal->id.regi, &locals);
|
||||||
if (! res)
|
if (not res)
|
||||||
Expr::insertSubTreeReg (ti_hl->asgn.m_lhs, _exp,_retVal->id.regi, &locals);
|
Expr::insertSubTreeReg (ti_hl->asgn.m_lhs, _exp,_retVal->id.regi, &locals);
|
||||||
//TODO: HERE missing: 2 regs
|
//TODO: HERE missing: 2 regs
|
||||||
picode->invalidate();
|
picode->invalidate();
|
||||||
@ -1225,7 +1226,7 @@ void Function::preprocessReturnDU(LivenessSet &_liveOut)
|
|||||||
retVal.loc = REG_FRAME;
|
retVal.loc = REG_FRAME;
|
||||||
retVal.longId() = LONGID_TYPE(rDX,rAX);
|
retVal.longId() = LONGID_TYPE(rDX,rAX);
|
||||||
/*idx = */localId.newLongReg(TYPE_LONG_SIGN, LONGID_TYPE(rDX,rAX), Icode.begin());
|
/*idx = */localId.newLongReg(TYPE_LONG_SIGN, LONGID_TYPE(rDX,rAX), Icode.begin());
|
||||||
localId.propLongId (rAX, rDX, "\0");
|
localId.propLongId (rAX, rDX, "");
|
||||||
}
|
}
|
||||||
else if (isAx or isBx or isCx or isDx) /* uint16_t */
|
else if (isAx or isBx or isCx or isDx) /* uint16_t */
|
||||||
{
|
{
|
||||||
@ -1291,7 +1292,7 @@ void Function::dataFlow(LivenessSet &_liveOut)
|
|||||||
elimCondCodes();
|
elimCondCodes();
|
||||||
genLiveKtes();
|
genLiveKtes();
|
||||||
liveRegAnalysis (_liveOut); /* calls dataFlow() recursively */
|
liveRegAnalysis (_liveOut); /* calls dataFlow() recursively */
|
||||||
if (! (flg & PROC_ASM)) /* can generate C for pProc */
|
if (not (flg & PROC_ASM)) /* can generate C for pProc */
|
||||||
{
|
{
|
||||||
genDU1 (); /* generate def/use level 1 chain */
|
genDU1 (); /* generate def/use level 1 chain */
|
||||||
findExps (); /* forward substitution algorithm */
|
findExps (); /* forward substitution algorithm */
|
||||||
|
|||||||
@ -188,7 +188,7 @@ int main(int argc, char **argv)
|
|||||||
Project::get()->create(option.filename);
|
Project::get()->create(option.filename);
|
||||||
|
|
||||||
DccFrontend fe(&app);
|
DccFrontend fe(&app);
|
||||||
if(!Project::get()->load()) {
|
if(not Project::get()->load()) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (option.verbose)
|
if (option.verbose)
|
||||||
|
|||||||
130
src/disassem.cpp
130
src/disassem.cpp
@ -9,6 +9,8 @@
|
|||||||
#include "symtab.h"
|
#include "symtab.h"
|
||||||
#include "project.h"
|
#include "project.h"
|
||||||
|
|
||||||
|
#include <QtCore/QFile>
|
||||||
|
#include <QtCore/QDebug>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
@ -16,6 +18,7 @@
|
|||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
// Note: for the time being, there is no interactive disassembler
|
// Note: for the time being, there is no interactive disassembler
|
||||||
// for unix
|
// for unix
|
||||||
|
|
||||||
@ -72,8 +75,8 @@ static const char *szFlops3C[] =
|
|||||||
|
|
||||||
static const char *szPtr[2] = { "word ptr ", "byte ptr " };
|
static const char *szPtr[2] = { "word ptr ", "byte ptr " };
|
||||||
|
|
||||||
static void formatRM(ostringstream &p, const LLOperand &pm);
|
static void formatRM(QTextStream & p, const LLOperand &pm);
|
||||||
static ostringstream &strDst(ostringstream &os, uint32_t flg, const LLOperand &pm);
|
static QTextStream & strDst(QTextStream & os, uint32_t flg, const LLOperand &pm);
|
||||||
|
|
||||||
static char *strHex(uint32_t d);
|
static char *strHex(uint32_t d);
|
||||||
//static int checkScanned(uint32_t pcCur);
|
//static int checkScanned(uint32_t pcCur);
|
||||||
@ -152,11 +155,11 @@ void Disassembler::disassem(Function * ppProc)
|
|||||||
if (pass != 3)
|
if (pass != 3)
|
||||||
{
|
{
|
||||||
auto p = (pass == 1)? asm1_name: asm2_name;
|
auto p = (pass == 1)? asm1_name: asm2_name;
|
||||||
m_fp.open(p.toStdString(),ios_base::app);
|
m_disassembly_target = new QFile(p);
|
||||||
if (!m_fp.is_open())
|
if(!m_disassembly_target->open(QFile::WriteOnly|QFile::Text|QFile::Append)) {
|
||||||
{
|
|
||||||
fatalError(CANNOT_OPEN, p.toStdString().c_str());
|
fatalError(CANNOT_OPEN, p.toStdString().c_str());
|
||||||
}
|
}
|
||||||
|
m_fp.setDevice(m_disassembly_target);
|
||||||
}
|
}
|
||||||
/* Create temporary code array */
|
/* Create temporary code array */
|
||||||
// Mike: needs objectising!
|
// Mike: needs objectising!
|
||||||
@ -179,7 +182,7 @@ void Disassembler::disassem(Function * ppProc)
|
|||||||
/* Write procedure header */
|
/* Write procedure header */
|
||||||
if (pass != 3)
|
if (pass != 3)
|
||||||
{
|
{
|
||||||
std::string near_far=(pProc->flg & PROC_FAR)? "FAR": "NEAR";
|
const char * near_far=(pProc->flg & PROC_FAR)? "FAR": "NEAR";
|
||||||
m_fp << "\t\t"<<pProc->name<<" PROC "<< near_far<<"\n";
|
m_fp << "\t\t"<<pProc->name<<" PROC "<< near_far<<"\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,7 +197,10 @@ void Disassembler::disassem(Function * ppProc)
|
|||||||
if (pass != 3)
|
if (pass != 3)
|
||||||
{
|
{
|
||||||
m_fp << "\n\t\t"<<pProc->name<<" ENDP\n\n";
|
m_fp << "\n\t\t"<<pProc->name<<" ENDP\n\n";
|
||||||
m_fp.close();
|
m_fp.setDevice(nullptr);
|
||||||
|
m_disassembly_target->close();
|
||||||
|
delete m_disassembly_target;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pc.clear();
|
pc.clear();
|
||||||
@ -208,16 +214,20 @@ void Disassembler::disassem(Function * ppProc)
|
|||||||
void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
|
void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
|
||||||
{
|
{
|
||||||
PROG &prog(Project::get()->prog);
|
PROG &prog(Project::get()->prog);
|
||||||
ostringstream oper_stream;
|
QString oper_contents;
|
||||||
ostringstream hex_bytes;
|
QTextStream oper_stream(&oper_contents);
|
||||||
ostringstream result_stream;
|
QString hex_bytes;
|
||||||
ostringstream opcode_with_mods;
|
QString result_contents;
|
||||||
ostringstream operands_s;
|
QTextStream result_stream(&result_contents);
|
||||||
oper_stream << uppercase;
|
QString opcode_with_mods;
|
||||||
hex_bytes << uppercase;
|
|
||||||
|
QString operands_contents;
|
||||||
|
QTextStream operands_s(&operands_contents);
|
||||||
|
oper_stream.setNumberFlags(QTextStream::UppercaseBase|QTextStream::UppercaseDigits);
|
||||||
|
|
||||||
/* Disassembly stage 1 --
|
/* Disassembly stage 1 --
|
||||||
* Do not try to display NO_CODE entries or synthetic instructions,
|
* Do not try to display NO_CODE entries or synthetic instructions,
|
||||||
* other than JMPs, that have been introduced for def/use analysis. */
|
* other than JMPs, that have been introduced for def/use analysis. */
|
||||||
if ((option.asm1) and
|
if ((option.asm1) and
|
||||||
( inst.testFlags(NO_CODE) or
|
( inst.testFlags(NO_CODE) or
|
||||||
(inst.testFlags(SYNTHETIC) and (inst.getOpcode() != iJMP))))
|
(inst.testFlags(SYNTHETIC) and (inst.getOpcode() != iJMP))))
|
||||||
@ -244,25 +254,28 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
|
|||||||
cb = (uint32_t) inst.numBytes;
|
cb = (uint32_t) inst.numBytes;
|
||||||
nextInst = inst.label + cb;
|
nextInst = inst.label + cb;
|
||||||
|
|
||||||
/* Output hexa code in program image */
|
/* Output hex code in program image */
|
||||||
if (pass != 3)
|
if (pass != 3)
|
||||||
{
|
{
|
||||||
for (j = 0; j < cb; j++)
|
for (j = 0; j < cb; j++)
|
||||||
{
|
{
|
||||||
hex_bytes << hex << setw(2) << setfill('0') << uint16_t(prog.image()[inst.label + j]);
|
hex_bytes += QString("%1").arg(uint16_t(prog.image()[inst.label + j]),2,16,QChar('0')).toUpper();
|
||||||
}
|
}
|
||||||
hex_bytes << ' ';
|
hex_bytes += ' ';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
oper_stream << setw(POS_LAB) << left<< hex_bytes.str();
|
oper_stream.setFieldWidth(POS_LAB);
|
||||||
|
oper_stream.setFieldAlignment(QTextStream::AlignLeft);
|
||||||
|
oper_stream << hex_bytes;
|
||||||
/* Check if there is a symbol here */
|
/* Check if there is a symbol here */
|
||||||
selectTable(Label);
|
selectTable(Label);
|
||||||
oper_stream << setw(5)<<left; // align for the labels
|
oper_stream.setFieldWidth(5); // align for the labels
|
||||||
{
|
{
|
||||||
ostringstream lab_contents;
|
QString lab_contents;
|
||||||
if (readVal(lab_contents, inst.label, nullptr))
|
QTextStream lab_stream(&lab_contents);
|
||||||
|
if (readVal(lab_stream, inst.label, nullptr))
|
||||||
{
|
{
|
||||||
lab_contents << ':'; /* Also removes the null */
|
lab_stream << ':'; /* Also removes the null */
|
||||||
}
|
}
|
||||||
else if (inst.testFlags(TARGET)) /* Symbols override Lnn labels */
|
else if (inst.testFlags(TARGET)) /* Symbols override Lnn labels */
|
||||||
{
|
{
|
||||||
@ -271,15 +284,17 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
|
|||||||
{
|
{
|
||||||
pl[loc_ip] = ++g_lab;
|
pl[loc_ip] = ++g_lab;
|
||||||
}
|
}
|
||||||
lab_contents<< "L"<<pl[loc_ip]<<':';
|
lab_stream<< "L"<<pl[loc_ip]<<':';
|
||||||
}
|
}
|
||||||
oper_stream<< lab_contents.str();
|
lab_stream.flush();
|
||||||
|
oper_stream << lab_contents;
|
||||||
|
oper_stream.setFieldWidth(0);
|
||||||
}
|
}
|
||||||
if ((inst.getOpcode()==iSIGNEX )and inst.testFlags(B))
|
if ((inst.getOpcode()==iSIGNEX )and inst.testFlags(B))
|
||||||
{
|
{
|
||||||
inst.setOpcode(iCBW);
|
inst.setOpcode(iCBW);
|
||||||
}
|
}
|
||||||
opcode_with_mods<<Machine_X86::opcodeName(inst.getOpcode());
|
opcode_with_mods += Machine_X86::opcodeName(inst.getOpcode());
|
||||||
|
|
||||||
switch ( inst.getOpcode() )
|
switch ( inst.getOpcode() )
|
||||||
{
|
{
|
||||||
@ -383,11 +398,10 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
|
|||||||
case iCALL: case iCALLF:
|
case iCALL: case iCALLF:
|
||||||
if (inst.testFlags(I))
|
if (inst.testFlags(I))
|
||||||
{
|
{
|
||||||
if((inst.getOpcode() == iCALL))
|
QString oper = QString("%1 ptr %2")
|
||||||
operands_s<< "near";
|
.arg((inst.getOpcode() == iCALL) ? "near" : "far")
|
||||||
else
|
.arg((inst.src().proc.proc)->name);
|
||||||
operands_s<< " far";
|
operands_s<< qPrintable(oper);
|
||||||
operands_s<<" ptr "<<(inst.src().proc.proc)->name;
|
|
||||||
}
|
}
|
||||||
else if (inst.getOpcode() == iCALLF)
|
else if (inst.getOpcode() == iCALLF)
|
||||||
{
|
{
|
||||||
@ -438,7 +452,10 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
(inst.getFlag() & B)? opcode_with_mods<< "B": opcode_with_mods<< "W";
|
if(inst.getFlag() & B)
|
||||||
|
opcode_with_mods+='B';
|
||||||
|
else
|
||||||
|
opcode_with_mods+='W';
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -457,8 +474,8 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
|
|||||||
|
|
||||||
case iOUT:
|
case iOUT:
|
||||||
{
|
{
|
||||||
std::string d1=((inst.testFlags(I))? strHex(inst.src().getImm2()): "dx");
|
QString d1=((inst.testFlags(I))? strHex(inst.src().getImm2()): "dx");
|
||||||
std::string d2=((inst.getFlag() & B) ? ", al": ", ax");
|
QString d2=((inst.getFlag() & B) ? ", al": ", ax");
|
||||||
operands_s<<d1 << d2;
|
operands_s<<d1 << d2;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -466,8 +483,9 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
oper_stream << setw(15) << left <<opcode_with_mods.str();
|
oper_stream.setFieldWidth(15);
|
||||||
oper_stream << operands_s.str();
|
operands_s.flush();
|
||||||
|
oper_stream << qSetFieldWidth(15) << opcode_with_mods << qSetFieldWidth(0) << operands_contents;
|
||||||
/* Comments */
|
/* Comments */
|
||||||
if (inst.testFlags(SYNTHETIC))
|
if (inst.testFlags(SYNTHETIC))
|
||||||
{
|
{
|
||||||
@ -480,14 +498,18 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
|
|||||||
fImpure |= BITMAP(j, BM_DATA);
|
fImpure |= BITMAP(j, BM_DATA);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
result_stream.setFieldWidth(54);
|
||||||
result_stream << setw(54) << left << oper_stream.str();
|
result_stream.setFieldAlignment(QTextStream::AlignLeft);
|
||||||
|
oper_stream.flush();
|
||||||
|
result_stream << oper_contents;
|
||||||
/* Check for user supplied comment */
|
/* Check for user supplied comment */
|
||||||
selectTable(Comment);
|
selectTable(Comment);
|
||||||
ostringstream cbuf;
|
QString cbuf_contents;
|
||||||
|
QTextStream cbuf(&cbuf_contents);
|
||||||
if (readVal(cbuf, inst.label, nullptr))
|
if (readVal(cbuf, inst.label, nullptr))
|
||||||
{
|
{
|
||||||
result_stream <<"; "<<cbuf.str();
|
cbuf.flush();
|
||||||
|
result_stream <<"; "<<*cbuf.string();
|
||||||
}
|
}
|
||||||
else if (fImpure or (inst.testFlags(SWITCH | CASE | SEG_IMMED | IMPURE | SYNTHETIC | TERMINATES)))
|
else if (fImpure or (inst.testFlags(SWITCH | CASE | SEG_IMMED | IMPURE | SYNTHETIC | TERMINATES)))
|
||||||
{
|
{
|
||||||
@ -527,8 +549,9 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
|
|||||||
/* output to .b code buffer */
|
/* output to .b code buffer */
|
||||||
if (inst.testFlags(SYNTHETIC))
|
if (inst.testFlags(SYNTHETIC))
|
||||||
result_stream<<";Synthetic inst";
|
result_stream<<";Synthetic inst";
|
||||||
if (pass == 3) /* output to .b code buffer */
|
if (pass == 3) { /* output to .b code buffer */
|
||||||
cCode.appendCode("%s\n", result_stream.str().c_str());
|
cCode.appendCode("%s\n", qPrintable(result_contents));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -544,7 +567,8 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
|
|||||||
sprintf(buf,"%03d ",loc_ip);
|
sprintf(buf,"%03d ",loc_ip);
|
||||||
result_stream<<";Synthetic inst";
|
result_stream<<";Synthetic inst";
|
||||||
}
|
}
|
||||||
m_fp<<buf<< " " << result_stream.str() << "\n";
|
result_stream.flush();
|
||||||
|
m_fp<<buf<< " " << result_contents << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -553,7 +577,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* formatRM
|
* formatRM
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
static void formatRM(std::ostringstream &p, const LLOperand &pm)
|
static void formatRM(QTextStream &p, const LLOperand &pm)
|
||||||
{
|
{
|
||||||
//char seg[4];
|
//char seg[4];
|
||||||
|
|
||||||
@ -590,7 +614,7 @@ static void formatRM(std::ostringstream &p, const LLOperand &pm)
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* strDst
|
* strDst
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
static ostringstream & strDst(ostringstream &os,uint32_t flg, const LLOperand &pm)
|
static QTextStream & strDst(QTextStream &os,uint32_t flg, const LLOperand &pm)
|
||||||
{
|
{
|
||||||
/* Immediates to memory require size descriptor */
|
/* Immediates to memory require size descriptor */
|
||||||
//os << setw(WID_PTR);
|
//os << setw(WID_PTR);
|
||||||
@ -604,7 +628,7 @@ static ostringstream & strDst(ostringstream &os,uint32_t flg, const LLOperand &p
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* strSrc *
|
* strSrc *
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
ostringstream &LLInst::strSrc(ostringstream &os,bool skip_comma)
|
QTextStream &LLInst::strSrc(QTextStream &os,bool skip_comma)
|
||||||
{
|
{
|
||||||
if(false==skip_comma)
|
if(false==skip_comma)
|
||||||
os<<", ";
|
os<<", ";
|
||||||
@ -637,16 +661,16 @@ static char *strHex(uint32_t d)
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
void interactDis(Function * initProc, int initIC)
|
void interactDis(Function * initProc, int initIC)
|
||||||
{
|
{
|
||||||
const char *procname = "UNKNOWN";
|
QString procname = "UNKNOWN";
|
||||||
if(initProc)
|
if(initProc)
|
||||||
procname = initProc->name.c_str();
|
procname = initProc->name;
|
||||||
|
|
||||||
printf("Wanted to start interactive disasassembler for %s:%d\n",procname,initIC);
|
qDebug() << "Wanted to start interactive disasassembler for "<<procname<<":"<<initIC;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle the floating point opcodes (icode iESC) */
|
/* Handle the floating point opcodes (icode iESC) */
|
||||||
void LLInst::flops(std::ostringstream &out)
|
void LLInst::flops(QTextStream &out)
|
||||||
{
|
{
|
||||||
//char bf[30];
|
//char bf[30];
|
||||||
uint8_t op = (uint8_t)src().getImm2();
|
uint8_t op = (uint8_t)src().getImm2();
|
||||||
@ -658,7 +682,7 @@ void LLInst::flops(std::ostringstream &out)
|
|||||||
{
|
{
|
||||||
/* The mod/rm mod bits are not set to 11 (i.e. register). This is the normal floating point opcode */
|
/* The mod/rm mod bits are not set to 11 (i.e. register). This is the normal floating point opcode */
|
||||||
out<<Machine_X86::floatOpName(op)<<' ';
|
out<<Machine_X86::floatOpName(op)<<' ';
|
||||||
out <<setw(10);
|
out.setFieldWidth(10);
|
||||||
if ((op == 0x29) or (op == 0x1F))
|
if ((op == 0x29) or (op == 0x1F))
|
||||||
{
|
{
|
||||||
out << "tbyte ptr ";
|
out << "tbyte ptr ";
|
||||||
@ -689,7 +713,7 @@ void LLInst::flops(std::ostringstream &out)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
out.setFieldWidth(0);
|
||||||
formatRM(out, m_dst);
|
formatRM(out, m_dst);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@ -28,7 +28,7 @@
|
|||||||
{IP_OUT_OF_RANGE ,"Instruction at location %06lX goes beyond loaded image\n"},
|
{IP_OUT_OF_RANGE ,"Instruction at location %06lX goes beyond loaded image\n"},
|
||||||
{DEF_NOT_FOUND ,"Definition not found for condition code usage at opcode %d\n"},
|
{DEF_NOT_FOUND ,"Definition not found for condition code usage at opcode %d\n"},
|
||||||
{JX_NOT_DEF ,"JX use, definition not supported at opcode #%d\n"},
|
{JX_NOT_DEF ,"JX use, definition not supported at opcode #%d\n"},
|
||||||
{NOT_DEF_USE ,"Def - use not supported. Def op = %d, use op = %d.\n"},
|
{NOT_DEF_USE ,"%x: Def - use not supported. Def op = %d, use op = %d.\n"},
|
||||||
{REPEAT_FAIL ,"Failed to construct repeat..until() condition.\n"},
|
{REPEAT_FAIL ,"Failed to construct repeat..until() condition.\n"},
|
||||||
{WHILE_FAIL ,"Failed to construct while() condition.\n"},
|
{WHILE_FAIL ,"Failed to construct while() condition.\n"},
|
||||||
};
|
};
|
||||||
|
|||||||
@ -155,7 +155,7 @@ void Function::createCFG()
|
|||||||
}
|
}
|
||||||
auto iter2=m_ip_to_bb.find(ip);
|
auto iter2=m_ip_to_bb.find(ip);
|
||||||
if(iter2==m_ip_to_bb.end())
|
if(iter2==m_ip_to_bb.end())
|
||||||
fatalError(NO_BB, ip, name.c_str());
|
fatalError(NO_BB, ip, qPrintable(name));
|
||||||
psBB = iter2->second;
|
psBB = iter2->second;
|
||||||
elem.BBptr = psBB;
|
elem.BBptr = psBB;
|
||||||
psBB->inEdges.push_back((BB *)nullptr);
|
psBB->inEdges.push_back((BB *)nullptr);
|
||||||
|
|||||||
147
src/hlicode.cpp
147
src/hlicode.cpp
@ -4,17 +4,17 @@
|
|||||||
* Date: September-October 1993
|
* Date: September-October 1993
|
||||||
* (C) Cristina Cifuentes
|
* (C) Cristina Cifuentes
|
||||||
*/
|
*/
|
||||||
|
#include "dcc.h"
|
||||||
|
|
||||||
|
#include <QtCore/QDebug>
|
||||||
|
#include <QtCore/QString>
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include "dcc.h"
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
static char buf[lineSize]; /* Line buffer for hl icode output */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Places the new HLI_ASSIGN high-level operand in the high-level icode array */
|
/* Places the new HLI_ASSIGN high-level operand in the high-level icode array */
|
||||||
void HLTYPE::setAsgn(Expr *lhs, Expr *rhs)
|
void HLTYPE::setAsgn(Expr *lhs, Expr *rhs)
|
||||||
{
|
{
|
||||||
@ -477,82 +477,68 @@ void Function::highLevelGen()
|
|||||||
|
|
||||||
/* Returns the string that represents the procedure call of tproc (ie. with
|
/* Returns the string that represents the procedure call of tproc (ie. with
|
||||||
* actual parameters) */
|
* actual parameters) */
|
||||||
std::string Function::writeCall (Function * tproc, STKFRAME & args, int *numLoc)
|
QString Function::writeCall (Function * tproc, STKFRAME & args, int *numLoc)
|
||||||
{
|
{
|
||||||
//string condExp;
|
//string condExp;
|
||||||
ostringstream ostr;
|
QString ostr;
|
||||||
ostr<<tproc->name<<" (";
|
ostr+=tproc->name+" (";
|
||||||
for(const STKSYM &sym : args)
|
for(const STKSYM &sym : args)
|
||||||
{
|
{
|
||||||
if(sym.actual)
|
if(sym.actual)
|
||||||
ostr << sym.actual->walkCondExpr (this, numLoc);
|
ostr += sym.actual->walkCondExpr(this, numLoc);
|
||||||
else
|
else
|
||||||
ostr << "";
|
ostr += "";
|
||||||
if((&sym)!=&(args.back()))
|
if((&sym)!=&(args.back()))
|
||||||
ostr << ", ";
|
ostr += ", ";
|
||||||
}
|
}
|
||||||
ostr << ")";
|
ostr += ")";
|
||||||
return ostr.str();
|
return ostr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Displays the output of a HLI_JCOND icode. */
|
/* Displays the output of a HLI_JCOND icode. */
|
||||||
const char *writeJcond (const HLTYPE &h, Function * pProc, int *numLoc)
|
QString writeJcond (const HLTYPE &h, Function * pProc, int *numLoc)
|
||||||
{
|
{
|
||||||
memset (buf, ' ', sizeof(buf));
|
|
||||||
buf[0] = '\0';
|
|
||||||
strcat (buf, "if ");
|
|
||||||
if(h.opcode==HLI_INVALID)
|
if(h.opcode==HLI_INVALID)
|
||||||
{
|
{
|
||||||
return "if (*HLI_INVALID*) {\n";
|
return "if (*HLI_INVALID*) {\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(h.expr());
|
assert(h.expr());
|
||||||
Expr *inverted=h.expr()->inverse();
|
Expr *inverted=h.expr()->inverse();
|
||||||
//inverseCondOp (&h.exp);
|
//inverseCondOp (&h.exp);
|
||||||
std::string e = inverted->walkCondExpr (pProc, numLoc);
|
QString inverted_form = inverted->walkCondExpr (pProc, numLoc);
|
||||||
delete inverted;
|
delete inverted;
|
||||||
strcat (buf, e.c_str());
|
|
||||||
strcat (buf, " {\n");
|
return QString("if %1 {\n").arg(inverted_form);
|
||||||
return (buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Displays the inverse output of a HLI_JCOND icode. This is used in the case
|
/* Displays the inverse output of a HLI_JCOND icode. This is used in the case
|
||||||
* when the THEN clause of an if..then..else is empty. The clause is
|
* when the THEN clause of an if..then..else is empty. The clause is
|
||||||
* negated and the ELSE clause is used instead. */
|
* negated and the ELSE clause is used instead. */
|
||||||
const char *writeJcondInv(HLTYPE h, Function * pProc, int *numLoc)
|
QString writeJcondInv(HLTYPE h, Function * pProc, int *numLoc)
|
||||||
{
|
{
|
||||||
memset (buf, ' ', sizeof(buf));
|
QString _form;
|
||||||
buf[0] = '\0';
|
|
||||||
strcat (buf, "if ");
|
|
||||||
std::string e;
|
|
||||||
if(h.expr()==nullptr)
|
if(h.expr()==nullptr)
|
||||||
e = "( *failed condition recovery* )";
|
_form = "( *failed condition recovery* )";
|
||||||
else
|
else
|
||||||
e = h.expr()->walkCondExpr (pProc, numLoc);
|
_form = h.expr()->walkCondExpr (pProc, numLoc);
|
||||||
|
return QString("if %1 {\n").arg(_form);
|
||||||
strcat (buf, e.c_str());
|
|
||||||
strcat (buf, " {\n");
|
|
||||||
return (buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
string AssignType::writeOut(Function *pProc, int *numLoc) const
|
QString AssignType::writeOut(Function *pProc, int *numLoc) const
|
||||||
{
|
{
|
||||||
ostringstream ostr;
|
return QString("%1 = %2;\n")
|
||||||
ostr << m_lhs->walkCondExpr (pProc, numLoc);
|
.arg(m_lhs->walkCondExpr (pProc, numLoc))
|
||||||
ostr << " = ";
|
.arg(rhs->walkCondExpr (pProc, numLoc));
|
||||||
ostr << rhs->walkCondExpr (pProc, numLoc);
|
|
||||||
ostr << ";\n";
|
|
||||||
return ostr.str();
|
|
||||||
}
|
}
|
||||||
string CallType::writeOut(Function *pProc, int *numLoc) const
|
QString CallType::writeOut(Function *pProc, int *numLoc) const
|
||||||
{
|
{
|
||||||
ostringstream ostr;
|
return pProc->writeCall (proc, *args, numLoc) + ";\n";
|
||||||
ostr << pProc->writeCall (proc, *args, numLoc);
|
|
||||||
ostr << ";\n";
|
|
||||||
return ostr.str();
|
|
||||||
}
|
}
|
||||||
string ExpType::writeOut(Function *pProc, int *numLoc) const
|
QString ExpType::writeOut(Function *pProc, int *numLoc) const
|
||||||
{
|
{
|
||||||
if(v==nullptr)
|
if(v==nullptr)
|
||||||
return "";
|
return "";
|
||||||
@ -573,38 +559,33 @@ void HLTYPE::set(Expr *l, Expr *r)
|
|||||||
* Note: this routine does not output the contens of HLI_JCOND icodes. This is
|
* Note: this routine does not output the contens of HLI_JCOND icodes. This is
|
||||||
* done in a separate routine to be able to support the removal of
|
* done in a separate routine to be able to support the removal of
|
||||||
* empty THEN clauses on an if..then..else. */
|
* empty THEN clauses on an if..then..else. */
|
||||||
string HLTYPE::write1HlIcode (Function * pProc, int *numLoc) const
|
QString HLTYPE::write1HlIcode (Function * pProc, int *numLoc) const
|
||||||
{
|
{
|
||||||
string e;
|
|
||||||
ostringstream ostr;
|
|
||||||
const HlTypeSupport *p = get();
|
const HlTypeSupport *p = get();
|
||||||
switch (opcode)
|
switch (opcode)
|
||||||
{
|
{
|
||||||
case HLI_ASSIGN:
|
case HLI_ASSIGN:
|
||||||
return p->writeOut(pProc,numLoc);
|
return p->writeOut(pProc,numLoc);
|
||||||
case HLI_CALL:
|
case HLI_CALL:
|
||||||
return p->writeOut(pProc,numLoc);
|
return p->writeOut(pProc,numLoc);
|
||||||
case HLI_RET:
|
case HLI_RET:
|
||||||
e = p->writeOut(pProc,numLoc);
|
{
|
||||||
if (! e.empty())
|
QString e;
|
||||||
ostr << "return (" << e << ");\n";
|
e = p->writeOut(pProc,numLoc);
|
||||||
break;
|
if (not e.isEmpty())
|
||||||
case HLI_POP:
|
return QString("return (%1);\n").arg(e);
|
||||||
ostr << "HLI_POP ";
|
break;
|
||||||
ostr << p->writeOut(pProc,numLoc);
|
|
||||||
ostr << "\n";
|
|
||||||
break;
|
|
||||||
case HLI_PUSH:
|
|
||||||
ostr << "HLI_PUSH ";
|
|
||||||
ostr << p->writeOut(pProc,numLoc);
|
|
||||||
ostr << "\n";
|
|
||||||
break;
|
|
||||||
case HLI_JCOND: //Handled elsewhere
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
fprintf(stderr," HLTYPE::write1HlIcode - Unhandled opcode %d\n",opcode);
|
|
||||||
}
|
}
|
||||||
return ostr.str();
|
case HLI_POP:
|
||||||
|
return QString("HLI_POP %1\n").arg(p->writeOut(pProc,numLoc));
|
||||||
|
case HLI_PUSH:
|
||||||
|
return QString("HLI_PUSH %1\n").arg(p->writeOut(pProc,numLoc));
|
||||||
|
case HLI_JCOND: //Handled elsewhere
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
qCritical() << " HLTYPE::write1HlIcode - Unhandled opcode" << opcode;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -619,16 +600,22 @@ void ICODE::writeDU()
|
|||||||
{
|
{
|
||||||
int my_idx = loc_ip;
|
int my_idx = loc_ip;
|
||||||
{
|
{
|
||||||
ostringstream ostr;
|
QString ostr_contents;
|
||||||
Machine_X86::writeRegVector(ostr,du.def);
|
{
|
||||||
if (!ostr.str().empty())
|
QTextStream ostr(&ostr_contents);
|
||||||
printf ("Def (reg) = %s\n", ostr.str().c_str());
|
Machine_X86::writeRegVector(ostr,du.def);
|
||||||
|
}
|
||||||
|
if (not ostr_contents.isEmpty())
|
||||||
|
qDebug() << QString("Def (reg) = %1\n").arg(ostr_contents);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
ostringstream ostr;
|
QString ostr_contents;
|
||||||
Machine_X86::writeRegVector(ostr,du.use);
|
{
|
||||||
if (!ostr.str().empty())
|
QTextStream ostr(&ostr_contents);
|
||||||
printf ("Use (reg) = %s\n", ostr.str().c_str());
|
Machine_X86::writeRegVector(ostr,du.use);
|
||||||
|
}
|
||||||
|
if (not ostr_contents.isEmpty())
|
||||||
|
qDebug() << QString("Use (reg) = %1\n").arg(ostr_contents);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Print du1 chain */
|
/* Print du1 chain */
|
||||||
|
|||||||
@ -211,7 +211,7 @@ void Function::findIdioms()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Check if number of parameter bytes match their calling convention */
|
/* Check if number of parameter bytes match their calling convention */
|
||||||
if ((flg & PROC_HLL) and (!args.empty()))
|
if ((flg & PROC_HLL) and (not args.empty()))
|
||||||
{
|
{
|
||||||
args.m_minOff += (flg & PROC_FAR ? 4 : 2);
|
args.m_minOff += (flg & PROC_FAR ? 4 : 2);
|
||||||
delta = args.maxOff - args.m_minOff;
|
delta = args.maxOff - args.m_minOff;
|
||||||
@ -258,7 +258,7 @@ void Function::bindIcodeOff()
|
|||||||
if (ll->testFlags(I) )
|
if (ll->testFlags(I) )
|
||||||
{
|
{
|
||||||
uint32_t found;
|
uint32_t found;
|
||||||
if (! Icode.labelSrch(ll->src().getImm2(), found))
|
if (not Icode.labelSrch(ll->src().getImm2(), found))
|
||||||
ll->setFlags( NO_LABEL );
|
ll->setFlags( NO_LABEL );
|
||||||
else
|
else
|
||||||
ll->replaceSrc(LLOperand::CreateImm2(found));
|
ll->replaceSrc(LLOperand::CreateImm2(found));
|
||||||
|
|||||||
@ -3,6 +3,8 @@
|
|||||||
#include "dcc.h"
|
#include "dcc.h"
|
||||||
#include "msvc_fixes.h"
|
#include "msvc_fixes.h"
|
||||||
|
|
||||||
|
#include <QtCore/QDebug>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
@ -134,7 +136,8 @@ bool Idiom18::match(iICODE picode)
|
|||||||
/* not supported yet */
|
/* not supported yet */
|
||||||
ICODE &ic(*picode);
|
ICODE &ic(*picode);
|
||||||
const Function *my_proc(ic.getParent()->getParent());
|
const Function *my_proc(ic.getParent()->getParent());
|
||||||
printf("Unsupported idiom18 type at %x in %s:%x : indexed\n",ic.loc_ip,my_proc->name.c_str(),my_proc->procEntry);
|
qWarning() << "Unsupported idiom18 type at"<< QString::number(ic.loc_ip,16)
|
||||||
|
<< "in"<< my_proc->name <<':'<< QString::number(my_proc->procEntry,16) << "- indexed";
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(m_idiom_type)
|
switch(m_idiom_type)
|
||||||
|
|||||||
@ -64,13 +64,13 @@ bool Idiom2::match(iICODE pIcode)
|
|||||||
if(nicode == m_end)
|
if(nicode == m_end)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (nicode->ll()->match(iPOP,rBP) and ! (nicode->ll()->testFlags(I | TARGET | CASE)) )
|
if (nicode->ll()->match(iPOP,rBP) and not (nicode->ll()->testFlags(I | TARGET | CASE)) )
|
||||||
{
|
{
|
||||||
m_icodes.push_back(nicode++); // Matched POP BP
|
m_icodes.push_back(nicode++); // Matched POP BP
|
||||||
|
|
||||||
/* Match RET(F) */
|
/* Match RET(F) */
|
||||||
if ( nicode != m_end and
|
if ( nicode != m_end and
|
||||||
!(nicode->ll()->testFlags(I | TARGET | CASE)) and
|
not (nicode->ll()->testFlags(I | TARGET | CASE)) and
|
||||||
(nicode->ll()->match(iRET) or nicode->ll()->match(iRETF))
|
(nicode->ll()->match(iRET) or nicode->ll()->match(iRETF))
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@ -140,7 +140,7 @@ bool Idiom4::match(iICODE pIcode)
|
|||||||
}
|
}
|
||||||
int Idiom4::action()
|
int Idiom4::action()
|
||||||
{
|
{
|
||||||
if( ! m_icodes.empty()) // if not an empty RET[F] N
|
if( not m_icodes.empty()) // if not an empty RET[F] N
|
||||||
{
|
{
|
||||||
for(size_t idx=0; idx<m_icodes.size()-1; ++idx) // don't invalidate last entry
|
for(size_t idx=0; idx<m_icodes.size()-1; ++idx) // don't invalidate last entry
|
||||||
m_icodes[idx]->invalidate();
|
m_icodes[idx]->invalidate();
|
||||||
|
|||||||
@ -122,7 +122,7 @@ bool Idiom1::match(iICODE picode)
|
|||||||
m_icodes.push_back(picode++);
|
m_icodes.push_back(picode++);
|
||||||
|
|
||||||
}
|
}
|
||||||
return !m_icodes.empty();
|
return not m_icodes.empty();
|
||||||
}
|
}
|
||||||
int Idiom1::action()
|
int Idiom1::action()
|
||||||
{
|
{
|
||||||
|
|||||||
@ -181,7 +181,7 @@ int LOCAL_ID::newLongReg(hlType t, const LONGID_TYPE &longT, iICODE ix_)
|
|||||||
for (idx = 0; idx < id_arr.size(); idx++)
|
for (idx = 0; idx < id_arr.size(); idx++)
|
||||||
{
|
{
|
||||||
ID &entry(id_arr[idx]);
|
ID &entry(id_arr[idx]);
|
||||||
if(!entry.isLong() or (entry.loc != REG_FRAME))
|
if(not entry.isLong() or (entry.loc != REG_FRAME))
|
||||||
continue;
|
continue;
|
||||||
if (/*(locSym->id[idx].type == t) and Not checking type */
|
if (/*(locSym->id[idx].type == t) and Not checking type */
|
||||||
(entry.longId().h() == regH) and
|
(entry.longId().h() == regH) and
|
||||||
@ -461,7 +461,7 @@ eReg otherLongRegi (eReg regi, int idx, LOCAL_ID *locTbl)
|
|||||||
* the local identifier table. If so, macros for these registers are
|
* the local identifier table. If so, macros for these registers are
|
||||||
* placed in the local identifier table, as these registers belong to a
|
* placed in the local identifier table, as these registers belong to a
|
||||||
* long register identifier. */
|
* long register identifier. */
|
||||||
void LOCAL_ID::propLongId (uint8_t regL, uint8_t regH, const char *name)
|
void LOCAL_ID::propLongId (uint8_t regL, uint8_t regH, const QString &name)
|
||||||
{
|
{
|
||||||
for (ID &rid : id_arr)
|
for (ID &rid : id_arr)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -3,10 +3,11 @@
|
|||||||
#include "msvc_fixes.h"
|
#include "msvc_fixes.h"
|
||||||
#include "icode.h"
|
#include "icode.h"
|
||||||
|
|
||||||
|
#include <QtCore/QTextStream>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
// Index registers **** temp solution
|
// Index registers **** temp solution
|
||||||
static const std::string regNames[] = {
|
static const QString regNames[] = {
|
||||||
"undef",
|
"undef",
|
||||||
"ax", "cx", "dx", "bx",
|
"ax", "cx", "dx", "bx",
|
||||||
"sp", "bp", "si", "di",
|
"sp", "bp", "si", "di",
|
||||||
@ -21,17 +22,17 @@ static const std::string regNames[] = {
|
|||||||
/* uint8_t and uint16_t registers */
|
/* uint8_t and uint16_t registers */
|
||||||
Machine_X86::Machine_X86()
|
Machine_X86::Machine_X86()
|
||||||
{
|
{
|
||||||
static_assert((sizeof(regNames)/sizeof(std::string))==LAST_REG,
|
static_assert((sizeof(regNames)/sizeof(QString))==LAST_REG,
|
||||||
"Reg count not equal number of strings");
|
"Reg count not equal number of strings");
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string &Machine_X86::regName(eReg r)
|
const QString &Machine_X86::regName(eReg r)
|
||||||
{
|
{
|
||||||
assert(r<(sizeof(regNames)/sizeof(std::string)));
|
assert(r<(sizeof(regNames)/sizeof(QString)));
|
||||||
return regNames[r];
|
return regNames[r];
|
||||||
}
|
}
|
||||||
|
|
||||||
static const std::string szOps[] =
|
static const QString szOps[] =
|
||||||
{
|
{
|
||||||
"CBW", "AAA", "AAD", "AAM", "AAS", "ADC", "ADD", "AND",
|
"CBW", "AAA", "AAD", "AAM", "AAS", "ADC", "ADD", "AND",
|
||||||
"BOUND","CALL", "CALL", "CLC", "CLD", "CLI", "CMC", "CMP",
|
"BOUND","CALL", "CALL", "CLC", "CLD", "CLI", "CMC", "CMP",
|
||||||
@ -49,7 +50,7 @@ static const std::string szOps[] =
|
|||||||
"XLAT", "XOR", "INTO", "NOP", "REPNE", "REPE", "MOD"
|
"XLAT", "XOR", "INTO", "NOP", "REPNE", "REPE", "MOD"
|
||||||
};
|
};
|
||||||
/* The following opcodes are for mod != 3 */
|
/* The following opcodes are for mod != 3 */
|
||||||
static std::string szFlops1[] =
|
static const QString szFlops1[] =
|
||||||
{
|
{
|
||||||
/* 0 1 2 3 4 5 6 7 */
|
/* 0 1 2 3 4 5 6 7 */
|
||||||
"FADD", "FMUL", "FCOM", "FCOMP", "FSUB", "FSUBR", "FDIV", "FDIVR", /* 00 */
|
"FADD", "FMUL", "FCOM", "FCOMP", "FSUB", "FSUBR", "FDIV", "FDIVR", /* 00 */
|
||||||
@ -62,7 +63,7 @@ static std::string szFlops1[] =
|
|||||||
"FILD", "???", "FIST", "FISTP", "FBLD", "???", "FBSTP", "FISTP" /* 38 */
|
"FILD", "???", "FIST", "FISTP", "FBLD", "???", "FBSTP", "FISTP" /* 38 */
|
||||||
};
|
};
|
||||||
/* The following opcodes are for mod == 3 */
|
/* The following opcodes are for mod == 3 */
|
||||||
static std::string szFlops2[] =
|
static const QString szFlops2[] =
|
||||||
{
|
{
|
||||||
/* 0 1 2 3 4 5 6 7 */
|
/* 0 1 2 3 4 5 6 7 */
|
||||||
"FADD", "FMUL", "FCOM", "FCOMP", "FSUB", "FSUBR", "FDIV", "FDIVR", /* 00 */
|
"FADD", "FMUL", "FCOM", "FCOMP", "FSUB", "FSUBR", "FDIV", "FDIVR", /* 00 */
|
||||||
@ -75,17 +76,17 @@ static std::string szFlops2[] =
|
|||||||
"FILD", "???", "FIST", "FISTP", "", "???", "FBSTP", "FISTP" /* 38 */
|
"FILD", "???", "FIST", "FISTP", "", "???", "FBSTP", "FISTP" /* 38 */
|
||||||
};
|
};
|
||||||
|
|
||||||
const std::string &Machine_X86::opcodeName(unsigned r)
|
const QString &Machine_X86::opcodeName(unsigned r)
|
||||||
{
|
{
|
||||||
assert(r<(sizeof(szOps)/sizeof(std::string)));
|
assert(r<(sizeof(szOps)/sizeof(QString)));
|
||||||
return szOps[r];
|
return szOps[r];
|
||||||
}
|
}
|
||||||
const std::string &Machine_X86::floatOpName(unsigned r)
|
const QString &Machine_X86::floatOpName(unsigned r)
|
||||||
{
|
{
|
||||||
if(r>=(sizeof(szFlops1)/sizeof(std::string)))
|
if(r>=(sizeof(szFlops1)/sizeof(QString)))
|
||||||
{
|
{
|
||||||
r-= (sizeof(szFlops1)/sizeof(std::string));
|
r-= (sizeof(szFlops1)/sizeof(QString));
|
||||||
assert(r<(sizeof(szFlops2)/sizeof(std::string)));
|
assert(r<(sizeof(szFlops2)/sizeof(QString)));
|
||||||
return szFlops2[r];
|
return szFlops2[r];
|
||||||
}
|
}
|
||||||
return szFlops1[r];
|
return szFlops1[r];
|
||||||
@ -137,7 +138,7 @@ eReg Machine_X86::compositeParent(eReg reg)
|
|||||||
}
|
}
|
||||||
return rUNDEF;
|
return rUNDEF;
|
||||||
}
|
}
|
||||||
void Machine_X86::writeRegVector (std::ostream &ostr,const LivenessSet ®i)
|
void Machine_X86::writeRegVector (QTextStream &ostr,const LivenessSet ®i)
|
||||||
{
|
{
|
||||||
int j;
|
int j;
|
||||||
for (j = rAX; j < INDEX_BX_SI; j++)
|
for (j = rAX; j < INDEX_BX_SI; j++)
|
||||||
|
|||||||
@ -124,7 +124,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
|
|||||||
eErrorId err;
|
eErrorId err;
|
||||||
bool done = false;
|
bool done = false;
|
||||||
SYMTAB &global_symbol_table(Project::get()->symtab);
|
SYMTAB &global_symbol_table(Project::get()->symtab);
|
||||||
if (name.find("chkstk") != string::npos)
|
if (name.contains("chkstk"))
|
||||||
{
|
{
|
||||||
// Danger! Dcc will likely fall over in this code.
|
// Danger! Dcc will likely fall over in this code.
|
||||||
// So we act as though we have done with this proc
|
// So we act as though we have done with this proc
|
||||||
@ -136,7 +136,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
|
|||||||
}
|
}
|
||||||
if (option.VeryVerbose)
|
if (option.VeryVerbose)
|
||||||
{
|
{
|
||||||
printf("Parsing proc %s at %X\n", name.c_str(), pstate->IP);
|
qDebug() << "Parsing proc" << name << "at"<< QString::number(pstate->IP,16).toUpper();
|
||||||
}
|
}
|
||||||
|
|
||||||
while (not done )
|
while (not done )
|
||||||
@ -759,11 +759,9 @@ bool Function::process_CALL(ICODE & pIcode, CALL_GRAPH * pcallGraph, STATE *psta
|
|||||||
if (indirect)
|
if (indirect)
|
||||||
x.flg |= PROC_ICALL;
|
x.flg |= PROC_ICALL;
|
||||||
|
|
||||||
if (x.name.empty()) /* Don't overwrite existing name */
|
if (x.name.isEmpty()) /* Don't overwrite existing name */
|
||||||
{
|
{
|
||||||
ostringstream os;
|
x.name = QString("proc_%1").arg(++prog.cProcs);
|
||||||
os<<"proc_"<< ++prog.cProcs;
|
|
||||||
x.name = os.str();
|
|
||||||
}
|
}
|
||||||
x.depth = x.depth + 1;
|
x.depth = x.depth + 1;
|
||||||
x.flg |= TERMINATES;
|
x.flg |= TERMINATES;
|
||||||
@ -1194,7 +1192,7 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate)
|
|||||||
|
|
||||||
case iMUL: case iIMUL:
|
case iMUL: case iIMUL:
|
||||||
use(SRC, pIcode, this, pstate, cb);
|
use(SRC, pIcode, this, pstate, cb);
|
||||||
if (! Imm)
|
if (not Imm)
|
||||||
{
|
{
|
||||||
use (DST, pIcode, this, pstate, cb);
|
use (DST, pIcode, this, pstate, cb);
|
||||||
if (cb == 1)
|
if (cb == 1)
|
||||||
@ -1231,7 +1229,7 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate)
|
|||||||
case iCALLF: /* Ignore def's on CS for now */
|
case iCALLF: /* Ignore def's on CS for now */
|
||||||
cb = 4;
|
cb = 4;
|
||||||
case iCALL: case iPUSH: case iPOP:
|
case iCALL: case iPUSH: case iPOP:
|
||||||
if (! Imm) {
|
if (not Imm) {
|
||||||
if (pIcode.ll()->getOpcode() == iPOP)
|
if (pIcode.ll()->getOpcode() == iPOP)
|
||||||
def(DST, pIcode, this, pstate, cb);
|
def(DST, pIcode, this, pstate, cb);
|
||||||
else
|
else
|
||||||
@ -1269,7 +1267,7 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate)
|
|||||||
case iJMPF:
|
case iJMPF:
|
||||||
cb = 4;
|
cb = 4;
|
||||||
case iJMP:
|
case iJMP:
|
||||||
if (! Imm)
|
if (not Imm)
|
||||||
use(SRC, pIcode, this, pstate, cb);
|
use(SRC, pIcode, this, pstate, cb);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1330,7 +1328,7 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate)
|
|||||||
|
|
||||||
case iIN: case iOUT:
|
case iIN: case iOUT:
|
||||||
def(DST, pIcode, this, pstate, cb);
|
def(DST, pIcode, this, pstate, cb);
|
||||||
if (! Imm)
|
if (not Imm)
|
||||||
{
|
{
|
||||||
pIcode.du.use.addReg(rDX);
|
pIcode.du.use.addReg(rDX);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,6 +10,7 @@
|
|||||||
#include "project.h"
|
#include "project.h"
|
||||||
#include "CallGraph.h"
|
#include "CallGraph.h"
|
||||||
|
|
||||||
|
#include <QtCore/QDebug>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
@ -66,7 +67,7 @@ bool CALL_GRAPH::insertCallGraph(Function *caller, ilFunction callee)
|
|||||||
* the nodes the procedure invokes. */
|
* the nodes the procedure invokes. */
|
||||||
void CALL_GRAPH::writeNodeCallGraph(int indIdx)
|
void CALL_GRAPH::writeNodeCallGraph(int indIdx)
|
||||||
{
|
{
|
||||||
printf ("%s%s\n", indentStr(indIdx), proc->name.c_str());
|
qDebug() << indentStr(indIdx)+proc->name;
|
||||||
for (CALL_GRAPH *cg : outEdges)
|
for (CALL_GRAPH *cg : outEdges)
|
||||||
cg->writeNodeCallGraph (indIdx + 1);
|
cg->writeNodeCallGraph (indIdx + 1);
|
||||||
}
|
}
|
||||||
@ -178,7 +179,7 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
|
|||||||
newsym.type = TYPE_LONG_SIGN;
|
newsym.type = TYPE_LONG_SIGN;
|
||||||
assert(regL!=rUNDEF);
|
assert(regL!=rUNDEF);
|
||||||
tproc->localId.id_arr[tidx].name = newsym.name;
|
tproc->localId.id_arr[tidx].name = newsym.name;
|
||||||
tproc->localId.propLongId (regL, regH, tproc->localId.id_arr[tidx].name.c_str());
|
tproc->localId.propLongId (regL, regH, tproc->localId.id_arr[tidx].name);
|
||||||
}
|
}
|
||||||
target_stackframe->push_back(newsym);
|
target_stackframe->push_back(newsym);
|
||||||
target_stackframe->numArgs++;
|
target_stackframe->numArgs++;
|
||||||
|
|||||||
@ -54,7 +54,7 @@ ilFunction Project::findByEntry(uint32_t entry)
|
|||||||
return iter;
|
return iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
ilFunction Project::createFunction(FunctionType *f,const std::string &name)
|
ilFunction Project::createFunction(FunctionType *f,const QString &name)
|
||||||
{
|
{
|
||||||
pProcList.push_back(Function::Create(f,0,name,0));
|
pProcList.push_back(Function::Create(f,0,name,0));
|
||||||
return (++pProcList.rbegin()).base();
|
return (++pProcList.rbegin()).base();
|
||||||
@ -87,7 +87,7 @@ hlType Project::symbolType(size_t idx)
|
|||||||
return symtab[idx].type;
|
return symtab[idx].type;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string &Project::symbolName(size_t idx)
|
const QString &Project::symbolName(size_t idx)
|
||||||
{
|
{
|
||||||
assert(validSymIdx(idx));
|
assert(validSymIdx(idx));
|
||||||
return symtab[idx].name;
|
return symtab[idx].name;
|
||||||
|
|||||||
@ -28,7 +28,7 @@ bool trivialGraph(BB *G)
|
|||||||
* from the list. Q is not an empty queue. */
|
* from the list. Q is not an empty queue. */
|
||||||
static BB *firstOfQueue (queue &Q)
|
static BB *firstOfQueue (queue &Q)
|
||||||
{
|
{
|
||||||
assert(!Q.empty());
|
assert(not Q.empty());
|
||||||
BB *res=Q.front();
|
BB *res=Q.front();
|
||||||
Q.pop_front();
|
Q.pop_front();
|
||||||
return res;
|
return res;
|
||||||
@ -81,7 +81,7 @@ void interval::appendNodeInt(queue &pqH, BB *node)
|
|||||||
|
|
||||||
/* Check header list for occurrence of node, if found, remove it
|
/* Check header list for occurrence of node, if found, remove it
|
||||||
* and decrement number of out-edges from this interval. */
|
* and decrement number of out-edges from this interval. */
|
||||||
if (node->beenOnH and !pqH.empty())
|
if (node->beenOnH and not pqH.empty())
|
||||||
{
|
{
|
||||||
auto found_iter=std::find(pqH.begin(),pqH.end(),node);
|
auto found_iter=std::find(pqH.begin(),pqH.end(),node);
|
||||||
if(found_iter!=pqH.end())
|
if(found_iter!=pqH.end())
|
||||||
@ -113,7 +113,7 @@ void derSeq_Entry::findIntervals (Function *c)
|
|||||||
Gi->reachingInt = BB::Create(nullptr,"",c); /* ^ empty BB */
|
Gi->reachingInt = BB::Create(nullptr,"",c); /* ^ empty BB */
|
||||||
|
|
||||||
/* Process header nodes list H */
|
/* Process header nodes list H */
|
||||||
while (!H.empty())
|
while (not H.empty())
|
||||||
{
|
{
|
||||||
header = firstOfQueue (H);
|
header = firstOfQueue (H);
|
||||||
pI = new interval;
|
pI = new interval;
|
||||||
@ -139,7 +139,7 @@ void derSeq_Entry::findIntervals (Function *c)
|
|||||||
succ->reachingInt = header;
|
succ->reachingInt = header;
|
||||||
if (succ->inEdgeCount == 0)
|
if (succ->inEdgeCount == 0)
|
||||||
pI->appendNodeInt (H, succ);
|
pI->appendNodeInt (H, succ);
|
||||||
else if (! succ->beenOnH) /* out edge */
|
else if (not succ->beenOnH) /* out edge */
|
||||||
{
|
{
|
||||||
appendQueue (H, succ);
|
appendQueue (H, succ);
|
||||||
succ->beenOnH = true;
|
succ->beenOnH = true;
|
||||||
@ -163,7 +163,7 @@ void derSeq_Entry::findIntervals (Function *c)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Link interval I to list of intervals */
|
/* Link interval I to list of intervals */
|
||||||
if (! first)
|
if (not first)
|
||||||
{
|
{
|
||||||
m_intervals.push_back(pI);
|
m_intervals.push_back(pI);
|
||||||
J->next = pI;
|
J->next = pI;
|
||||||
@ -311,20 +311,20 @@ bool Function::findDerivedSeq (derSeq &derivedGi)
|
|||||||
derSeq::iterator iter=derivedGi.begin();
|
derSeq::iterator iter=derivedGi.begin();
|
||||||
assert(iter!=derivedGi.end());
|
assert(iter!=derivedGi.end());
|
||||||
BB *Gi = iter->Gi; /* Current derived sequence graph */
|
BB *Gi = iter->Gi; /* Current derived sequence graph */
|
||||||
while (! trivialGraph (Gi))
|
while (not trivialGraph (Gi))
|
||||||
{
|
{
|
||||||
/* Find the intervals of Gi and place them in derivedGi->Ii */
|
/* Find the intervals of Gi and place them in derivedGi->Ii */
|
||||||
iter->findIntervals(this);
|
iter->findIntervals(this);
|
||||||
|
|
||||||
/* Create Gi+1 and check if it is equivalent to Gi */
|
/* Create Gi+1 and check if it is equivalent to Gi */
|
||||||
if (! nextOrderGraph (derivedGi))
|
if (not nextOrderGraph (derivedGi))
|
||||||
break;
|
break;
|
||||||
++iter;
|
++iter;
|
||||||
Gi = iter->Gi;
|
Gi = iter->Gi;
|
||||||
stats.nOrder++;
|
stats.nOrder++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! trivialGraph (Gi))
|
if (not trivialGraph (Gi))
|
||||||
{
|
{
|
||||||
++iter;
|
++iter;
|
||||||
derivedGi.erase(iter,derivedGi.end()); /* remove Gi+1 */
|
derivedGi.erase(iter,derivedGi.end()); /* remove Gi+1 */
|
||||||
@ -368,7 +368,7 @@ derSeq * Function::checkReducibility()
|
|||||||
der_seq->back().Gi = *m_actual_cfg.begin(); /*m_cfg.front()*/;
|
der_seq->back().Gi = *m_actual_cfg.begin(); /*m_cfg.front()*/;
|
||||||
reducible = findDerivedSeq(*der_seq);
|
reducible = findDerivedSeq(*der_seq);
|
||||||
|
|
||||||
if (! reducible)
|
if (not reducible)
|
||||||
{
|
{
|
||||||
flg |= GRAPH_IRRED;
|
flg |= GRAPH_IRRED;
|
||||||
m_actual_cfg.nodeSplitting();
|
m_actual_cfg.nodeSplitting();
|
||||||
|
|||||||
@ -214,7 +214,7 @@ static struct {
|
|||||||
{ regop, axImp, 0 , iXCHG }, /* 97 */
|
{ regop, axImp, 0 , iXCHG }, /* 97 */
|
||||||
{ alImp, axImp, SRC_B | S_EXT , iSIGNEX}, /* 98 */
|
{ alImp, axImp, SRC_B | S_EXT , iSIGNEX}, /* 98 */
|
||||||
{axSrcIm, axImp, IM_DST | S_EXT , iSIGNEX}, /* 99 */
|
{axSrcIm, axImp, IM_DST | S_EXT , iSIGNEX}, /* 99 */
|
||||||
{ dispF, none2, 0 , iCALLF }, /* 9A */
|
{ dispF, none2, TO_REG , iCALLF }, /* 9A */ // TO_REG set to use SRC when processing setAddress
|
||||||
{ none1, none2, FLOAT_OP| NO_OPS , iWAIT }, /* 9B */
|
{ none1, none2, FLOAT_OP| NO_OPS , iWAIT }, /* 9B */
|
||||||
{ none1, none2, NOT_HLL | NO_OPS , iPUSHF}, /* 9C */
|
{ none1, none2, NOT_HLL | NO_OPS , iPUSHF}, /* 9C */
|
||||||
{ none1, none2, NOT_HLL | NO_OPS , iPOPF }, /* 9D */
|
{ none1, none2, NOT_HLL | NO_OPS , iPOPF }, /* 9D */
|
||||||
@ -508,7 +508,7 @@ LLOperand convertOperand(const x86_op_t &from)
|
|||||||
case op_register:
|
case op_register:
|
||||||
res.regi = convertRegister(from.data.reg); break;
|
res.regi = convertRegister(from.data.reg); break;
|
||||||
case op_immediate:
|
case op_immediate:
|
||||||
res.opz = from.data.sdword;
|
res.opz = from.data.sdword; break;
|
||||||
case op_expression:
|
case op_expression:
|
||||||
res = convertExpression(from.data.expression); break;
|
res = convertExpression(from.data.expression); break;
|
||||||
case op_offset:
|
case op_offset:
|
||||||
@ -630,7 +630,7 @@ static int signex(uint8_t b)
|
|||||||
static void setAddress(int i, bool fdst, uint16_t seg, int16_t reg, uint16_t off)
|
static void setAddress(int i, bool fdst, uint16_t seg, int16_t reg, uint16_t off)
|
||||||
{
|
{
|
||||||
/* If not to register (i.e. to r/m), and talking about r/m, then this is dest */
|
/* If not to register (i.e. to r/m), and talking about r/m, then this is dest */
|
||||||
LLOperand *pm = ((stateTable[i].flg & TO_REG) != fdst) ? &pIcode->ll()->m_dst : &pIcode->ll()->src();
|
LLOperand *pm = (! (stateTable[i].flg & TO_REG) == fdst) ? &pIcode->ll()->m_dst : &pIcode->ll()->src();
|
||||||
|
|
||||||
/* Set segment. A later procedure (lookupAddr in proclist.c) will
|
/* Set segment. A later procedure (lookupAddr in proclist.c) will
|
||||||
* provide the value of this segment in the field segValue.
|
* provide the value of this segment in the field segValue.
|
||||||
@ -973,6 +973,7 @@ static void dispF(int i)
|
|||||||
{
|
{
|
||||||
uint16_t off = (unsigned)getWord();
|
uint16_t off = (unsigned)getWord();
|
||||||
uint16_t seg = (unsigned)getWord();
|
uint16_t seg = (unsigned)getWord();
|
||||||
|
// FIXME: this is wrong since seg here is seg value, but setAddress treats it as register id
|
||||||
setAddress(i, true, seg, 0, off);
|
setAddress(i, true, seg, 0, off);
|
||||||
// decodeBranchTgt();
|
// decodeBranchTgt();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -133,7 +133,7 @@ void destroySymTables(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Using the value, read the symbolic name */
|
/* Using the value, read the symbolic name */
|
||||||
bool readVal(std::ostringstream &/*symName*/, uint32_t /*symOff*/, Function * /*symProc*/)
|
bool readVal(QTextStream &/*symName*/, uint32_t /*symOff*/, Function * /*symProc*/)
|
||||||
{
|
{
|
||||||
return false; // no symbolic names for now
|
return false; // no symbolic names for now
|
||||||
}
|
}
|
||||||
|
|||||||
11
src/udm.cpp
11
src/udm.cpp
@ -4,13 +4,14 @@
|
|||||||
* that just plays with abstract cfg's and intervals and such like.
|
* that just plays with abstract cfg's and intervals and such like.
|
||||||
* (C) Cristina Cifuentes
|
* (C) Cristina Cifuentes
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
#include <list>
|
|
||||||
#include <cassert>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "dcc.h"
|
#include "dcc.h"
|
||||||
#include "disassem.h"
|
#include "disassem.h"
|
||||||
#include "project.h"
|
#include "project.h"
|
||||||
|
|
||||||
|
#include <QtCore/QDebug>
|
||||||
|
#include <list>
|
||||||
|
#include <cassert>
|
||||||
|
#include <stdio.h>
|
||||||
extern Project g_proj;
|
extern Project g_proj;
|
||||||
//static void displayCFG(Function * pProc);
|
//static void displayCFG(Function * pProc);
|
||||||
//static void displayDfs(BB * pBB);
|
//static void displayDfs(BB * pBB);
|
||||||
@ -60,7 +61,7 @@ void Function::controlFlowAnalysis()
|
|||||||
|
|
||||||
if (option.verbose)
|
if (option.verbose)
|
||||||
{
|
{
|
||||||
printf("\nDepth first traversal - Proc %s\n", name.c_str());
|
qDebug() <<"\nDepth first traversal - Proc" <<name;
|
||||||
(*m_actual_cfg.begin())->displayDfs();
|
(*m_actual_cfg.begin())->displayDfs();
|
||||||
//m_cfg.front()->displayDfs();
|
//m_cfg.front()->displayDfs();
|
||||||
}
|
}
|
||||||
@ -101,7 +102,7 @@ void udm(void)
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
void Function::displayCFG()
|
void Function::displayCFG()
|
||||||
{
|
{
|
||||||
printf("\nBasic Block List - Proc %s", name.c_str());
|
qDebug() << "\nBasic Block List - Proc"<<name;
|
||||||
for (BB *pBB : /*m_cfg*/m_actual_cfg)
|
for (BB *pBB : /*m_cfg*/m_actual_cfg)
|
||||||
{
|
{
|
||||||
pBB->display();
|
pBB->display();
|
||||||
|
|||||||
@ -52,7 +52,7 @@ int LIB_PatternCollector::readSyms(FILE *fl)
|
|||||||
exit(10);
|
exit(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!feof(fl))
|
while (not feof(fl))
|
||||||
{
|
{
|
||||||
type = readByte(fl);
|
type = readByte(fl);
|
||||||
len = readWord(fl);
|
len = readWord(fl);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user