Fix to idiom19 and fixFloatEmulation()
This commit is contained in:
parent
c19231a1bd
commit
ca129c5177
@ -65,6 +65,8 @@ struct LivenessSet : public std::bitset<32>
|
|||||||
{
|
{
|
||||||
return test(r-rAX);
|
return test(r-rAX);
|
||||||
}
|
}
|
||||||
|
private:
|
||||||
|
void postProcessCompositeRegs();
|
||||||
};
|
};
|
||||||
|
|
||||||
extern LivenessSet duReg[30];
|
extern LivenessSet duReg[30];
|
||||||
|
|||||||
@ -37,6 +37,8 @@ struct Idiom18 : public Idiom
|
|||||||
protected:
|
protected:
|
||||||
iICODE m_icodes[4];
|
iICODE m_icodes[4];
|
||||||
bool m_is_dec;
|
bool m_is_dec;
|
||||||
|
/* type of variable: 1 = reg-var, 2 = local */
|
||||||
|
int m_idiom_type;
|
||||||
public:
|
public:
|
||||||
Idiom18(Function *f) : Idiom(f)
|
Idiom18(Function *f) : Idiom(f)
|
||||||
{
|
{
|
||||||
@ -64,7 +66,7 @@ struct Idiom20 : public Idiom
|
|||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
iICODE m_icodes[4];
|
iICODE m_icodes[4];
|
||||||
bool m_is_dec;
|
condNodeType m_is_dec;
|
||||||
public:
|
public:
|
||||||
Idiom20(Function *f) : Idiom(f)
|
Idiom20(Function *f) : Idiom(f)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -75,8 +75,11 @@ public:
|
|||||||
}
|
}
|
||||||
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);
|
||||||
static bool isSubRegisterOf(eReg reg, eReg parent);
|
static bool isSubRegisterOf(eReg reg, eReg parent);
|
||||||
|
static bool hasSubregisters(eReg reg);
|
||||||
|
|
||||||
|
static bool isPartOfComposite(eReg reg);
|
||||||
|
static eReg compositeParent(eReg reg);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -16,6 +16,7 @@ def perform_test(exepath,filepath,outname,args)
|
|||||||
printf("calling:" + "#{exepath} -a1 #{joined_args} -o#{output_path}.a1 #{filepath}\n")
|
printf("calling:" + "#{exepath} -a1 #{joined_args} -o#{output_path}.a1 #{filepath}\n")
|
||||||
result = `#{exepath} -a1 -o#{output_path}.a1 #{filepath}`
|
result = `#{exepath} -a1 -o#{output_path}.a1 #{filepath}`
|
||||||
result = `#{exepath} -a2 #{joined_args} -o#{output_path}.a2 #{filepath}`
|
result = `#{exepath} -a2 #{joined_args} -o#{output_path}.a2 #{filepath}`
|
||||||
|
result = `#{exepath} #{joined_args} -o#{output_path} #{filepath}`
|
||||||
puts result
|
puts result
|
||||||
p $?
|
p $?
|
||||||
end
|
end
|
||||||
|
|||||||
@ -297,7 +297,7 @@ void Function::codeGen (std::ostream &fs)
|
|||||||
|
|
||||||
/* 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 (char *filename, CALL_GRAPH * pcallGraph, std::ostream &_ios)
|
static void backBackEnd (CALL_GRAPH * pcallGraph, std::ostream &_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 */
|
||||||
@ -311,7 +311,7 @@ static void backBackEnd (char *filename, CALL_GRAPH * pcallGraph, std::ostream &
|
|||||||
/* Dfs if this procedure has any successors */
|
/* Dfs if this procedure has any successors */
|
||||||
for (size_t i = 0; i < pcallGraph->outEdges.size(); i++)
|
for (size_t i = 0; i < pcallGraph->outEdges.size(); i++)
|
||||||
{
|
{
|
||||||
backBackEnd (filename, pcallGraph->outEdges[i], _ios);
|
backBackEnd (pcallGraph->outEdges[i], _ios);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generate code for this procedure */
|
/* Generate code for this procedure */
|
||||||
@ -346,14 +346,14 @@ void BackEnd (char *fileName, CALL_GRAPH * pcallGraph)
|
|||||||
printf ("dcc: Writing C beta file %s\n", outNam.c_str());
|
printf ("dcc: Writing C beta file %s\n", outNam.c_str());
|
||||||
|
|
||||||
/* Header information */
|
/* Header information */
|
||||||
writeHeader (fs, fileName);
|
writeHeader (fs, option.filename);
|
||||||
|
|
||||||
/* Initialize total Icode instructions statistics */
|
/* Initialize total Icode instructions statistics */
|
||||||
stats.totalLL = 0;
|
stats.totalLL = 0;
|
||||||
stats.totalHL = 0;
|
stats.totalHL = 0;
|
||||||
|
|
||||||
/* Process each procedure at a time */
|
/* Process each procedure at a time */
|
||||||
backBackEnd (fileName, pcallGraph, fs);
|
backBackEnd (pcallGraph, fs);
|
||||||
|
|
||||||
/* Close output file */
|
/* Close output file */
|
||||||
fs.close();
|
fs.close();
|
||||||
|
|||||||
@ -492,7 +492,7 @@ bool LibCheck(Function & pProc)
|
|||||||
pProc.flg |= PROC_IS_FUNC;
|
pProc.flg |= PROC_IS_FUNC;
|
||||||
switch (pProc.retVal.type) {
|
switch (pProc.retVal.type) {
|
||||||
case TYPE_LONG_SIGN: case TYPE_LONG_UNSIGN:
|
case TYPE_LONG_SIGN: case TYPE_LONG_UNSIGN:
|
||||||
pProc.liveOut.setReg(rDX) |= duReg[rAX];
|
pProc.liveOut.setReg(rDX).addReg(rAX);
|
||||||
break;
|
break;
|
||||||
case TYPE_WORD_SIGN: case TYPE_WORD_UNSIGN:
|
case TYPE_WORD_SIGN: case TYPE_WORD_UNSIGN:
|
||||||
pProc.liveOut.setReg(rAX);
|
pProc.liveOut.setReg(rAX);
|
||||||
@ -500,8 +500,12 @@ bool LibCheck(Function & pProc)
|
|||||||
case TYPE_BYTE_SIGN: case TYPE_BYTE_UNSIGN:
|
case TYPE_BYTE_SIGN: case TYPE_BYTE_UNSIGN:
|
||||||
pProc.liveOut.setReg(rAL);
|
pProc.liveOut.setReg(rAL);
|
||||||
break;
|
break;
|
||||||
|
case TYPE_PTR:
|
||||||
|
fprintf(stderr,"Warning assuming Large memory model\n");
|
||||||
|
pProc.liveOut.setReg(rAX).addReg(rDS);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr,"Unknown retval type %d in LibCheck\n",pProc.retVal.type);
|
fprintf(stderr,"Unknown retval type %d for %s in LibCheck\n",pProc.retVal.type,pProc.name.c_str());
|
||||||
/*** other types are not considered yet ***/
|
/*** other types are not considered yet ***/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,16 +4,18 @@
|
|||||||
* Purpose: Data flow analysis module.
|
* Purpose: Data flow analysis module.
|
||||||
* (C) Cristina Cifuentes
|
* (C) Cristina Cifuentes
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
#include <stdint.h>
|
||||||
#include "dcc.h"
|
#include <cstring>
|
||||||
|
#include <iostream>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <cstdio>
|
||||||
#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>
|
||||||
#include <boost/assign.hpp>
|
#include <boost/assign.hpp>
|
||||||
#include <string.h>
|
|
||||||
#include <iostream>
|
#include "dcc.h"
|
||||||
#include <iomanip>
|
|
||||||
#include <stdio.h>
|
|
||||||
using namespace boost;
|
using namespace boost;
|
||||||
using namespace boost::adaptors;
|
using namespace boost::adaptors;
|
||||||
struct ExpStack
|
struct ExpStack
|
||||||
@ -232,11 +234,11 @@ void Function::elimCondCodes ()
|
|||||||
|
|
||||||
|
|
||||||
/** Generates the LiveUse() and Def() sets for each basic block in the graph.
|
/** Generates the LiveUse() and Def() sets for each basic block in the graph.
|
||||||
* Note: these sets are constant and could have been constructed during
|
\note these sets are constant and could have been constructed during
|
||||||
* the construction of the graph, but since the code hasn't been
|
the construction of the graph, but since the code hasn't been
|
||||||
* analyzed yet for idioms, the procedure preamble misleads the
|
analyzed yet for idioms, the procedure preamble misleads the
|
||||||
* analysis (eg: push si, would include si in LiveUse; although it
|
analysis (eg: push si, would include si in LiveUse; although it
|
||||||
* is not really meant to be a register that is used before defined). */
|
is not really meant to be a register that is used before defined). */
|
||||||
void Function::genLiveKtes ()
|
void Function::genLiveKtes ()
|
||||||
{
|
{
|
||||||
BB * pbb;
|
BB * pbb;
|
||||||
@ -291,7 +293,7 @@ void Function::liveRegAnalysis (LivenessSet &in_liveOut)
|
|||||||
{
|
{
|
||||||
|
|
||||||
/* Get current liveIn() and liveOut() sets */
|
/* Get current liveIn() and liveOut() sets */
|
||||||
prevLiveIn = pbb->liveIn;
|
prevLiveIn = pbb->liveIn;
|
||||||
prevLiveOut = pbb->liveOut;
|
prevLiveOut = pbb->liveOut;
|
||||||
|
|
||||||
/* liveOut(b) = U LiveIn(s); where s is successor(b)
|
/* liveOut(b) = U LiveIn(s); where s is successor(b)
|
||||||
@ -503,22 +505,22 @@ void BB::genDU1()
|
|||||||
assert(0!=Parent);
|
assert(0!=Parent);
|
||||||
ICODE::TypeFilter<HIGH_LEVEL> select_high_level;
|
ICODE::TypeFilter<HIGH_LEVEL> select_high_level;
|
||||||
auto all_high_levels = instructions | filtered(select_high_level);
|
auto all_high_levels = instructions | filtered(select_high_level);
|
||||||
printf("\n");
|
|
||||||
for (auto picode=all_high_levels.begin(); picode!=all_high_levels.end(); ++picode)
|
for (auto picode=all_high_levels.begin(); picode!=all_high_levels.end(); ++picode)
|
||||||
{
|
{
|
||||||
|
ICODE &ic = *picode;
|
||||||
int defRegIdx = 0;
|
int defRegIdx = 0;
|
||||||
// foreach defined register
|
// foreach defined register
|
||||||
for (int k = 0; k < INDEX_BX_SI; k++)
|
for (int k = rAX; k < INDEX_BX_SI; k++)
|
||||||
{
|
{
|
||||||
if (not picode->du.def.test(k))
|
if (not ic.du.def.testReg(k))
|
||||||
continue;
|
continue;
|
||||||
eReg regi = (eReg)(k + 1); /* Register that was defined */
|
eReg regi = (eReg)(k); /* Register that was defined */
|
||||||
picode->du1.regi[defRegIdx] = regi;
|
picode->du1.regi[defRegIdx] = regi;
|
||||||
|
|
||||||
if(FindUseBeforeDef(regi,defRegIdx, picode.base()))
|
if(FindUseBeforeDef(regi,defRegIdx, picode.base()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ProcessUseDefForFunc(regi, defRegIdx,*picode);
|
ProcessUseDefForFunc(regi, defRegIdx,ic);
|
||||||
RemoveUnusedDefs(regi, defRegIdx, picode.base());
|
RemoveUnusedDefs(regi, defRegIdx, picode.base());
|
||||||
|
|
||||||
defRegIdx++;
|
defRegIdx++;
|
||||||
@ -541,8 +543,7 @@ void Function::genDU1 ()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Substitutes the rhs (or lhs if rhs not possible) of ticode for the rhs
|
/* Substitutes the rhs (or lhs if rhs not possible) of ticode for the rhs of picode. */
|
||||||
* of picode. */
|
|
||||||
void LOCAL_ID::forwardSubs (COND_EXPR *lhs, COND_EXPR *rhs, iICODE picode, iICODE ticode, int &numHlIcodes) const
|
void LOCAL_ID::forwardSubs (COND_EXPR *lhs, COND_EXPR *rhs, iICODE picode, iICODE ticode, int &numHlIcodes) const
|
||||||
{
|
{
|
||||||
bool res;
|
bool res;
|
||||||
@ -570,8 +571,7 @@ void LOCAL_ID::forwardSubs (COND_EXPR *lhs, COND_EXPR *rhs, iICODE picode, iICOD
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Substitutes the rhs (or lhs if rhs not possible) of ticode for the
|
/* Substitutes the rhs (or lhs if rhs not possible) of ticode for the expression exp given */
|
||||||
* expression exp given */
|
|
||||||
static void forwardSubsLong (int longIdx, COND_EXPR *_exp, iICODE picode, iICODE ticode, int *numHlIcodes)
|
static void forwardSubsLong (int longIdx, COND_EXPR *_exp, iICODE picode, iICODE ticode, int *numHlIcodes)
|
||||||
{
|
{
|
||||||
bool res;
|
bool res;
|
||||||
|
|||||||
@ -44,18 +44,21 @@ int main(int argc, char *argv[])
|
|||||||
DccFrontend fe(option.filename);
|
DccFrontend fe(option.filename);
|
||||||
if(false==fe.FrontEnd ())
|
if(false==fe.FrontEnd ())
|
||||||
return -1;
|
return -1;
|
||||||
|
if(option.asm1)
|
||||||
|
return 0;
|
||||||
/* In the middle is a so called Universal Decompiling Machine.
|
/* In the middle is a so called Universal Decompiling Machine.
|
||||||
* It processes the procedure list and I-code and attaches where it can
|
* It processes the procedure list and I-code and attaches where it can
|
||||||
* to each procedure an optimised cfg and ud lists
|
* to each procedure an optimised cfg and ud lists
|
||||||
*/
|
*/
|
||||||
udm();
|
udm();
|
||||||
|
if(option.asm2)
|
||||||
|
return 0;
|
||||||
|
|
||||||
/* Back end converts each procedure into C using I-code, interval
|
/* Back end converts each procedure into C using I-code, interval
|
||||||
* analysis, data flow etc. and outputs it to output file ready for
|
* analysis, data flow etc. and outputs it to output file ready for
|
||||||
* re-compilation.
|
* re-compilation.
|
||||||
*/
|
*/
|
||||||
BackEnd(option.filename, Project::get()->callGraph);
|
BackEnd(asm1_name ? asm1_name:option.filename, Project::get()->callGraph);
|
||||||
|
|
||||||
Project::get()->callGraph->write();
|
Project::get()->callGraph->write();
|
||||||
|
|
||||||
|
|||||||
@ -95,65 +95,68 @@ bool Idiom18::match(iICODE picode)
|
|||||||
for(int i=0; i<4; ++i)
|
for(int i=0; i<4; ++i)
|
||||||
m_icodes[i] =picode++;
|
m_icodes[i] =picode++;
|
||||||
|
|
||||||
|
m_idiom_type=-1;
|
||||||
m_is_dec = m_icodes[1]->ll()->match(iDEC);
|
m_is_dec = m_icodes[1]->ll()->match(iDEC);
|
||||||
int type = -1; /* type of variable: 1 = reg-var, 2 = local */
|
|
||||||
uint8_t regi; /* register of the MOV */
|
uint8_t regi; /* register of the MOV */
|
||||||
|
|
||||||
/* Get variable */
|
/* Get variable */
|
||||||
if (m_icodes[1]->ll()->dst.regi == 0) /* global variable */
|
if (m_icodes[1]->ll()->dst.regi == 0) /* global variable */
|
||||||
{
|
{
|
||||||
/* not supported yet */
|
/* not supported yet */
|
||||||
type = 0;
|
m_idiom_type = 0;
|
||||||
}
|
}
|
||||||
else if ( m_icodes[1]->ll()->dst.isReg() ) /* register */
|
else if ( m_icodes[1]->ll()->dst.isReg() ) /* register */
|
||||||
{
|
{
|
||||||
if ((m_icodes[1]->ll()->dst.regi == rSI) && (m_func->flg & SI_REGVAR))
|
if ((m_icodes[1]->ll()->dst.regi == rSI) && (m_func->flg & SI_REGVAR))
|
||||||
type = 1;
|
m_idiom_type = 1;
|
||||||
else if ((m_icodes[1]->ll()->dst.regi == rDI) && (m_func->flg & DI_REGVAR))
|
else if ((m_icodes[1]->ll()->dst.regi == rDI) && (m_func->flg & DI_REGVAR))
|
||||||
type = 1;
|
m_idiom_type = 1;
|
||||||
}
|
}
|
||||||
else if (m_icodes[1]->ll()->dst.off) /* local variable */
|
else if (m_icodes[1]->ll()->dst.off) /* local variable */
|
||||||
type = 2;
|
m_idiom_type = 2;
|
||||||
else /* indexed */
|
else /* indexed */
|
||||||
{
|
{
|
||||||
type=3;
|
m_idiom_type=3;
|
||||||
/* not supported yet */
|
/* not supported yet */
|
||||||
printf("Unsupported idiom18 type: indexed");
|
ICODE &ic(*picode);
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(type)
|
switch(m_idiom_type)
|
||||||
{
|
{
|
||||||
case 0: // global
|
case 0: // global
|
||||||
printf("Unsupported idiom18 type: global variable");
|
printf("Unsupported idiom18 type at %x : global variable\n",picode->loc_ip);
|
||||||
break;
|
break;
|
||||||
case 1: /* register variable */
|
case 1: /* register variable */
|
||||||
/* Check previous instruction for a MOV */
|
/* Check previous instruction for a MOV */
|
||||||
if (m_icodes[0]->ll()->match(iMOV) && (m_icodes[0]->ll()->src().regi == m_icodes[1]->ll()->dst.regi))
|
if (m_icodes[0]->ll()->match(iMOV) && (m_icodes[0]->ll()->src().regi == m_icodes[1]->ll()->dst.regi))
|
||||||
{
|
|
||||||
regi = m_icodes[0]->ll()->dst.regi;
|
|
||||||
if ( m_icodes[0]->ll()->dst.isReg() )
|
|
||||||
{
|
{
|
||||||
if ( m_icodes[2]->ll()->match(iCMP) && (m_icodes[2]->ll()->dst.regi == regi) &&
|
regi = m_icodes[0]->ll()->dst.regi;
|
||||||
m_icodes[3]->ll()->conditionalJump() )
|
if ( m_icodes[0]->ll()->dst.isReg() )
|
||||||
return true;
|
{
|
||||||
|
if ( m_icodes[2]->ll()->match(iCMP) && (m_icodes[2]->ll()->dst.regi == regi) &&
|
||||||
|
m_icodes[3]->ll()->conditionalJump() )
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
break;
|
case 2: /* local */
|
||||||
case 2: /* local */
|
if (m_icodes[0]->ll()->match(iMOV) && (m_icodes[0]->ll()->src().off == m_icodes[1]->ll()->dst.off))
|
||||||
if (m_icodes[0]->ll()->match(iMOV) && (m_icodes[0]->ll()->src().off == m_icodes[1]->ll()->dst.off))
|
|
||||||
{
|
|
||||||
regi = m_icodes[0]->ll()->dst.regi;
|
|
||||||
if ( m_icodes[0]->ll()->dst.isReg() )
|
|
||||||
{
|
{
|
||||||
if ( m_icodes[2]->ll()->match(iCMP) && (m_icodes[2]->ll()->dst.regi == regi) &&
|
regi = m_icodes[0]->ll()->dst.regi;
|
||||||
m_icodes[3]->ll()->conditionalJump() )
|
if ( m_icodes[0]->ll()->dst.isReg() )
|
||||||
return true;
|
{
|
||||||
|
if ( m_icodes[2]->ll()->match(iCMP) && (m_icodes[2]->ll()->dst.regi == regi) &&
|
||||||
|
m_icodes[3]->ll()->conditionalJump() )
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
break;
|
case 3: // indexed
|
||||||
case 3: // indexed
|
printf("Unsupported idiom18 type: indexed");
|
||||||
printf("Unsupported idiom18 type: indexed");
|
break;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -188,6 +191,7 @@ bool Idiom19::match(iICODE picode)
|
|||||||
{
|
{
|
||||||
if(std::distance(picode,m_end)<2)
|
if(std::distance(picode,m_end)<2)
|
||||||
return false;
|
return false;
|
||||||
|
ICODE &ic(*picode);
|
||||||
|
|
||||||
for(int i=0; i<2; ++i)
|
for(int i=0; i<2; ++i)
|
||||||
m_icodes[i] =picode++;
|
m_icodes[i] =picode++;
|
||||||
@ -215,7 +219,8 @@ bool Idiom19::match(iICODE picode)
|
|||||||
int Idiom19::action()
|
int Idiom19::action()
|
||||||
{
|
{
|
||||||
COND_EXPR *lhs,*rhs,*expr;
|
COND_EXPR *lhs,*rhs,*expr;
|
||||||
lhs = COND_EXPR::id (*m_icodes[1]->ll(), DST, m_func, m_icodes[0], *m_icodes[1], eUSE);
|
ICODE &ic1(*m_icodes[1]);
|
||||||
|
lhs = COND_EXPR::id (*m_icodes[0]->ll(), DST, m_func, m_icodes[0], *m_icodes[1], eUSE);
|
||||||
lhs = COND_EXPR::unary (m_is_dec ? PRE_DEC : PRE_INC, lhs);
|
lhs = COND_EXPR::unary (m_is_dec ? PRE_DEC : PRE_INC, lhs);
|
||||||
rhs = COND_EXPR::idKte (0, 2);
|
rhs = COND_EXPR::idKte (0, 2);
|
||||||
expr = COND_EXPR::boolOp (lhs, rhs, condOpJCond[m_icodes[1]->ll()->getOpcode() - iJB]);
|
expr = COND_EXPR::boolOp (lhs, rhs, condOpJCond[m_icodes[1]->ll()->getOpcode() - iJB]);
|
||||||
@ -248,7 +253,7 @@ bool Idiom20::match(iICODE picode)
|
|||||||
for(int i=0; i<4; ++i)
|
for(int i=0; i<4; ++i)
|
||||||
m_icodes[i] =picode++;
|
m_icodes[i] =picode++;
|
||||||
|
|
||||||
m_is_dec = m_icodes[0]->ll()->match(iDEC);
|
m_is_dec = m_icodes[0]->ll()->match(iDEC) ? PRE_DEC : PRE_INC;
|
||||||
|
|
||||||
LLOperand &ll_dest(m_icodes[0]->ll()->dst);
|
LLOperand &ll_dest(m_icodes[0]->ll()->dst);
|
||||||
/* Get variable */
|
/* Get variable */
|
||||||
@ -306,7 +311,7 @@ int Idiom20::action()
|
|||||||
{
|
{
|
||||||
COND_EXPR *lhs,*rhs,*expr;
|
COND_EXPR *lhs,*rhs,*expr;
|
||||||
lhs = COND_EXPR::id (*m_icodes[1]->ll(), SRC, m_func, m_icodes[0], *m_icodes[0], eUSE);
|
lhs = COND_EXPR::id (*m_icodes[1]->ll(), SRC, m_func, m_icodes[0], *m_icodes[0], eUSE);
|
||||||
lhs = COND_EXPR::unary (m_is_dec ? PRE_DEC : PRE_INC, lhs);
|
lhs = COND_EXPR::unary (m_is_dec, lhs);
|
||||||
rhs = COND_EXPR::id (*m_icodes[2]->ll(), SRC, m_func, m_icodes[0], *m_icodes[3], eUSE);
|
rhs = COND_EXPR::id (*m_icodes[2]->ll(), SRC, m_func, m_icodes[0], *m_icodes[3], eUSE);
|
||||||
expr = COND_EXPR::boolOp (lhs, rhs, condOpJCond[m_icodes[3]->ll()->getOpcode() - iJB]);
|
expr = COND_EXPR::boolOp (lhs, rhs, condOpJCond[m_icodes[3]->ll()->getOpcode() - iJB]);
|
||||||
m_icodes[3]->setJCond(expr);
|
m_icodes[3]->setJCond(expr);
|
||||||
|
|||||||
@ -161,7 +161,6 @@ int LOCAL_ID::newLongReg(hlType t, eReg regH, eReg regL, iICODE ix_)
|
|||||||
{
|
{
|
||||||
/* Insert icode index in list */
|
/* Insert icode index in list */
|
||||||
entry.idx.push_back(ix_);
|
entry.idx.push_back(ix_);
|
||||||
//entry.idx.insert(ix_);
|
|
||||||
return (idx);
|
return (idx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -169,7 +168,7 @@ int LOCAL_ID::newLongReg(hlType t, eReg regH, eReg regL, iICODE ix_)
|
|||||||
|
|
||||||
/* Not in the table, create new identifier */
|
/* Not in the table, create new identifier */
|
||||||
newIdent (t, REG_FRAME);
|
newIdent (t, REG_FRAME);
|
||||||
id_arr[id_arr.size()-1].idx.push_back(ix_);//insert(ix_);
|
id_arr[id_arr.size()-1].idx.push_back(ix_);
|
||||||
idx = id_arr.size() - 1;
|
idx = id_arr.size() - 1;
|
||||||
id_arr[idx].id.longId.h = regH;
|
id_arr[idx].id.longId.h = regH;
|
||||||
id_arr[idx].id.longId.l = regL;
|
id_arr[idx].id.longId.l = regL;
|
||||||
|
|||||||
@ -17,7 +17,7 @@ static const std::string regNames[] = {
|
|||||||
Machine_X86::Machine_X86()
|
Machine_X86::Machine_X86()
|
||||||
{
|
{
|
||||||
static_assert((sizeof(regNames)/sizeof(std::string))==LAST_REG,
|
static_assert((sizeof(regNames)/sizeof(std::string))==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 std::string &Machine_X86::regName(eReg r)
|
||||||
@ -109,3 +109,26 @@ bool Machine_X86::isSubRegisterOf(eReg reg,eReg parent)
|
|||||||
return false; // only AX -> BX are coverede by subregisters
|
return false; // only AX -> BX are coverede by subregisters
|
||||||
return ((reg==subRegH(parent)) || (reg == subRegL(parent)));
|
return ((reg==subRegH(parent)) || (reg == subRegL(parent)));
|
||||||
}
|
}
|
||||||
|
bool Machine_X86::hasSubregisters(eReg reg)
|
||||||
|
{
|
||||||
|
return ((reg >= rAX) && (reg <= rBX));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Machine_X86::isPartOfComposite(eReg reg)
|
||||||
|
{
|
||||||
|
return ((reg >= rAL) && (reg <= rBH));
|
||||||
|
}
|
||||||
|
|
||||||
|
eReg Machine_X86::compositeParent(eReg reg)
|
||||||
|
{
|
||||||
|
switch(reg)
|
||||||
|
{
|
||||||
|
case rAL: case rAH: return rAX;
|
||||||
|
case rCL: case rCH: return rCX;
|
||||||
|
case rDL: case rDH: return rDX;
|
||||||
|
case rBL: case rBH: return rBX;
|
||||||
|
default:
|
||||||
|
return rUNDEF;
|
||||||
|
}
|
||||||
|
return rUNDEF;
|
||||||
|
}
|
||||||
|
|||||||
@ -350,6 +350,8 @@ static void convertUsedFlags(x86_insn_t &from,ICODE &to)
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
static void fixFloatEmulation(x86_insn_t &insn)
|
static void fixFloatEmulation(x86_insn_t &insn)
|
||||||
{
|
{
|
||||||
|
if(insn.operand_count==0)
|
||||||
|
return;
|
||||||
if(insn.group!=x86_insn_t::insn_interrupt)
|
if(insn.group!=x86_insn_t::insn_interrupt)
|
||||||
return;
|
return;
|
||||||
PROG &prog(Project::get()->prog);
|
PROG &prog(Project::get()->prog);
|
||||||
|
|||||||
@ -31,6 +31,7 @@ void Function::buildCFG(Disassembler &ds)
|
|||||||
if (option.asm2)
|
if (option.asm2)
|
||||||
{
|
{
|
||||||
ds.disassem(this); // Print 2nd pass assembler listing
|
ds.disassem(this); // Print 2nd pass assembler listing
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Idiom analysis and propagation of long type */
|
/* Idiom analysis and propagation of long type */
|
||||||
@ -78,6 +79,8 @@ void udm(void)
|
|||||||
{
|
{
|
||||||
iter->buildCFG(ds);
|
iter->buildCFG(ds);
|
||||||
}
|
}
|
||||||
|
if (option.asm2)
|
||||||
|
return;
|
||||||
|
|
||||||
|
|
||||||
/* Data flow analysis - eliminate condition codes, extraneous registers
|
/* Data flow analysis - eliminate condition codes, extraneous registers
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user