Extracted commonalities between SYM and STKSYM into SymbolCommon and
between SYMTAB and STKFRAME into SymbolTableCommon<STKSYM>
This commit is contained in:
parent
d3e62a99aa
commit
902a5ec3d8
@ -3,39 +3,22 @@
|
||||
#include <cstring>
|
||||
#include "types.h"
|
||||
#include "Enums.h"
|
||||
struct COND_EXPR;
|
||||
/* STACK FRAME */
|
||||
struct STKSYM
|
||||
{
|
||||
COND_EXPR *actual; /* Expression tree of actual parameter */
|
||||
COND_EXPR *regs; /* For register arguments only */
|
||||
int16_t off; /* Immediate off from BP (+:args, -:params) */
|
||||
uint8_t regOff; /* Offset is a register (e.g. SI, DI) */
|
||||
int size; /* Size */
|
||||
hlType type; /* Probable type */
|
||||
eDuVal duVal; /* DEF, USE, VAL */
|
||||
boolT hasMacro; /* This type needs a macro */
|
||||
char macro[10]; /* Macro name */
|
||||
char name[10]; /* Name for this symbol/argument */
|
||||
bool invalid; /* Boolean: invalid entry in formal arg list*/
|
||||
STKSYM()
|
||||
{
|
||||
memset(this,0,sizeof(STKSYM));
|
||||
}
|
||||
};
|
||||
#include "symtab.h"
|
||||
|
||||
struct STKFRAME
|
||||
struct STKFRAME : public SymbolTableCommon<STKSYM>
|
||||
{
|
||||
std::vector<STKSYM> sym;
|
||||
//std::vector<STKSYM> sym;
|
||||
//STKSYM * sym; /* Symbols */
|
||||
int16_t m_minOff; /* Initial offset in stack frame*/
|
||||
int16_t maxOff; /* Maximum offset in stack frame*/
|
||||
int cb; /* Number of bytes in arguments */
|
||||
int numArgs; /* No. of arguments in the table*/
|
||||
void adjustForArgType(int numArg_, hlType actType_);
|
||||
STKFRAME() : sym(0),m_minOff(0),maxOff(0),cb(0),numArgs(0)
|
||||
STKFRAME() : m_minOff(0),maxOff(0),cb(0),numArgs(0)
|
||||
{
|
||||
|
||||
}
|
||||
size_t getLocVar(int off);
|
||||
public:
|
||||
void updateFrameOff(int16_t off, int size, uint16_t duFlag);
|
||||
};
|
||||
|
||||
@ -21,27 +21,6 @@
|
||||
#include "Procedure.h"
|
||||
#include "BasicBlock.h"
|
||||
|
||||
typedef llvm::iplist<Function> FunctionListType;
|
||||
typedef FunctionListType lFunction;
|
||||
typedef lFunction::iterator ilFunction;
|
||||
|
||||
|
||||
/* SYMBOL TABLE */
|
||||
struct SYM
|
||||
{
|
||||
SYM() : label(0),size(0),flg(0),type(TYPE_UNKNOWN)
|
||||
{
|
||||
|
||||
}
|
||||
char name[10]; /* New name for this variable */
|
||||
uint32_t label; /* physical address (20 bit) */
|
||||
int size; /* maximum size */
|
||||
uint32_t flg; /* SEG_IMMED, IMPURE, WORD_OFF */
|
||||
hlType type; /* probable type */
|
||||
eDuVal duVal; /* DEF, USE, VAL */
|
||||
};
|
||||
|
||||
typedef std::vector<SYM> SYMTAB;
|
||||
/* CALL GRAPH NODE */
|
||||
struct CALL_GRAPH
|
||||
{
|
||||
@ -134,7 +113,6 @@ extern STATS stats; /* Icode statistics */
|
||||
/**** Global function prototypes ****/
|
||||
|
||||
void FrontEnd(char *filename, CALL_GRAPH * *); /* frontend.c */
|
||||
void *allocMem(int cb); /* frontend.c */
|
||||
|
||||
void udm(void); /* udm.c */
|
||||
void freeCFG(BB * cfg); /* graph.c */
|
||||
@ -167,7 +145,7 @@ hlType expType (const COND_EXPR *, Function *);
|
||||
|
||||
|
||||
/* Exported functions from hlicode.c */
|
||||
std::string writeCall (Function *, STKFRAME *, Function *, int *);
|
||||
std::string writeCall (Function *, STKFRAME &, Function *, int *);
|
||||
char *writeJcond (const HLTYPE &, Function *, int *);
|
||||
char *writeJcondInv (HLTYPE, Function *, int *);
|
||||
|
||||
|
||||
@ -65,7 +65,7 @@ struct ID
|
||||
frameType loc; /* Frame location */
|
||||
bool hasMacro; /* Identifier requires a macro */
|
||||
char macro[10]; /* Macro for this identifier */
|
||||
char name[20]; /* Identifier's name */
|
||||
std::string name; /* Identifier's name */
|
||||
union { /* Different types of identifiers */
|
||||
eReg regi; /* For TYPE_BYTE(uint16_t)_(UN)SIGN registers */
|
||||
struct { /* For TYPE_BYTE(uint16_t)_(UN)SIGN on the stack */
|
||||
@ -95,9 +95,9 @@ struct ID
|
||||
}
|
||||
void setLocalName(int i)
|
||||
{
|
||||
// char buf[32];
|
||||
//sprintf (buf, "loc%ld", i);
|
||||
//name=buf;
|
||||
char buf[32];
|
||||
sprintf (buf, "loc%ld", i);
|
||||
name=buf;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -12,6 +12,76 @@ struct TypeContainer;
|
||||
/* * * * * * * * * * * * * * * * * */
|
||||
/* Symbol table structs and protos */
|
||||
/* * * * * * * * * * * * * * * * * */
|
||||
struct SymbolCommon
|
||||
{
|
||||
std::string name; /* New name for this variable/symbol/argument */
|
||||
int size; /* Size/maximum size */
|
||||
hlType type; /* probable type */
|
||||
eDuVal duVal; /* DEF, USE, VAL */
|
||||
SymbolCommon() : size(0),type(TYPE_UNKNOWN)
|
||||
{}
|
||||
};
|
||||
struct SYM : public SymbolCommon
|
||||
{
|
||||
SYM() : label(0),flg(0)
|
||||
{
|
||||
|
||||
}
|
||||
int32_t label; /* physical address (20 bit) */
|
||||
uint32_t flg; /* SEG_IMMED, IMPURE, WORD_OFF */
|
||||
};
|
||||
/* STACK FRAME */
|
||||
struct STKSYM : public SymbolCommon
|
||||
{
|
||||
COND_EXPR *actual; /* Expression tree of actual parameter */
|
||||
COND_EXPR *regs; /* For register arguments only */
|
||||
int16_t label; /* Immediate off from BP (+:args, -:params) */
|
||||
uint8_t regOff; /* Offset is a register (e.g. SI, DI) */
|
||||
bool hasMacro; /* This type needs a macro */
|
||||
std::string macro; /* Macro name */
|
||||
bool invalid; /* Boolean: invalid entry in formal arg list*/
|
||||
STKSYM()
|
||||
{
|
||||
actual=regs=0;
|
||||
label=0;
|
||||
regOff=0;
|
||||
invalid=hasMacro = false;
|
||||
}
|
||||
void setArgName(int i)
|
||||
{
|
||||
char buf[32];
|
||||
sprintf (buf, "arg%ld", i);
|
||||
name = buf;
|
||||
}
|
||||
};
|
||||
template<class T>
|
||||
class SymbolTableCommon : public std::vector<T>
|
||||
{
|
||||
public:
|
||||
typedef typename std::vector<T>::iterator iterator;
|
||||
typedef typename std::vector<T>::const_iterator const_iterator;
|
||||
iterator findByLabel(int lab)
|
||||
{
|
||||
auto iter = std::find_if(this->begin(),this->end(),
|
||||
[lab](T &s)->bool {return s.label==lab;});
|
||||
return iter;
|
||||
}
|
||||
const_iterator findByLabel(int lab) const
|
||||
{
|
||||
auto iter = std::find_if(this->begin(),this->end(),
|
||||
[lab](const T &s)->bool {return s.label==lab;});
|
||||
return iter;
|
||||
}
|
||||
|
||||
};
|
||||
/* SYMBOL TABLE */
|
||||
class SYMTAB : public SymbolTableCommon<SYM>
|
||||
{
|
||||
|
||||
public:
|
||||
void updateSymType(uint32_t symbol, const TypeContainer &tc);
|
||||
SYM *updateGlobSym(uint32_t operand, int size, uint16_t duFlag, bool &inserted_new);
|
||||
};
|
||||
struct Function;
|
||||
struct SYMTABLE
|
||||
{
|
||||
|
||||
27
src/ast.cpp
27
src/ast.cpp
@ -183,7 +183,7 @@ COND_EXPR *COND_EXPR::idLoc(int off, LOCAL_ID *localId)
|
||||
if (i == localId->csym())
|
||||
printf ("Error, cannot find local var\n");
|
||||
newExp->expr.ident.idNode.localIdx = i;
|
||||
sprintf (localId->id_arr[i].name, "loc%ld", i);
|
||||
localId->id_arr[i].setLocalName(i);
|
||||
return (newExp);
|
||||
}
|
||||
|
||||
@ -192,15 +192,13 @@ COND_EXPR *COND_EXPR::idLoc(int off, LOCAL_ID *localId)
|
||||
COND_EXPR *COND_EXPR::idParam(int off, const STKFRAME * argSymtab)
|
||||
{
|
||||
COND_EXPR *newExp;
|
||||
size_t i;
|
||||
|
||||
newExp = new COND_EXPR(IDENTIFIER);
|
||||
newExp->expr.ident.idType = PARAM;
|
||||
for (i = 0; i < argSymtab->sym.size(); i++)
|
||||
if (argSymtab->sym[i].off == off)
|
||||
break;
|
||||
if (i == argSymtab->sym.size()) printf ("Error, cannot find argument var\n");
|
||||
newExp->expr.ident.idNode.localIdx = i;
|
||||
auto iter=argSymtab->findByLabel(off);
|
||||
if (iter == argSymtab->end())
|
||||
printf ("Error, cannot find argument var\n");
|
||||
newExp->expr.ident.idNode.localIdx = distance(argSymtab->begin(),iter);
|
||||
return (newExp);
|
||||
}
|
||||
|
||||
@ -489,7 +487,7 @@ int hlTypeSize (const COND_EXPR *expr, Function * pproc)
|
||||
case LOCAL_VAR:
|
||||
return (hlSize[pproc->localId.id_arr[expr->expr.ident.idNode.localIdx].type]);
|
||||
case PARAM:
|
||||
return (hlSize[pproc->args.sym[expr->expr.ident.idNode.paramIdx].type]);
|
||||
return (hlSize[pproc->args[expr->expr.ident.idNode.paramIdx].type]);
|
||||
case GLOB_VAR_IDX:
|
||||
return (hlSize[pproc->localId.id_arr[expr->expr.ident.idNode.idxGlbIdx].type]);
|
||||
case CONSTANT:
|
||||
@ -552,7 +550,7 @@ hlType expType (const COND_EXPR *expr, Function * pproc)
|
||||
case LOCAL_VAR:
|
||||
return (pproc->localId.id_arr[expr->expr.ident.idNode.localIdx].type);
|
||||
case PARAM:
|
||||
return (pproc->args.sym[expr->expr.ident.idNode.paramIdx].type);
|
||||
return (pproc->args[expr->expr.ident.idNode.paramIdx].type);
|
||||
case GLOB_VAR_IDX:
|
||||
return (pproc->localId.id_arr[expr->expr.ident.idNode.idxGlbIdx].type);
|
||||
case CONSTANT:
|
||||
@ -708,7 +706,7 @@ string walkCondExpr (const COND_EXPR* expr, Function * pProc, int* numLoc)
|
||||
id = &pProc->localId.id_arr[expr->expr.ident.idNode.regiIdx];
|
||||
if (id->name[0] == '\0') /* no name */
|
||||
{
|
||||
sprintf (id->name, "loc%ld", ++(*numLoc));
|
||||
id->setLocalName(++(*numLoc));
|
||||
codeOut <<TypeContainer::typeName(id->type)<< " "<<id->name<<"; ";
|
||||
codeOut <<"/* "<<Machine_X86::regName(id->id.regi)<<" */\n";
|
||||
}
|
||||
@ -723,7 +721,7 @@ string walkCondExpr (const COND_EXPR* expr, Function * pProc, int* numLoc)
|
||||
break;
|
||||
|
||||
case PARAM:
|
||||
psym = &pProc->args.sym[expr->expr.ident.idNode.paramIdx];
|
||||
psym = &pProc->args[expr->expr.ident.idNode.paramIdx];
|
||||
if (psym->hasMacro)
|
||||
o << psym->macro<<"("<<psym->name<< ")";
|
||||
else
|
||||
@ -752,12 +750,12 @@ string walkCondExpr (const COND_EXPR* expr, Function * pProc, int* numLoc)
|
||||
o << id->name;
|
||||
else if (id->loc == REG_FRAME)
|
||||
{
|
||||
sprintf (id->name, "loc%ld", ++(*numLoc));
|
||||
id->setLocalName(++(*numLoc));
|
||||
codeOut <<TypeContainer::typeName(id->type)<< " "<<id->name<<"; ";
|
||||
codeOut <<"/* "<<Machine_X86::regName(id->id.longId.h) << ":" <<
|
||||
Machine_X86::regName(id->id.longId.l) << " */\n";
|
||||
o << id->name;
|
||||
pProc->localId.propLongId (id->id.longId.l,id->id.longId.h, id->name);
|
||||
pProc->localId.propLongId (id->id.longId.l,id->id.longId.h, id->name.c_str());
|
||||
}
|
||||
else /* GLB_FRAME */
|
||||
{
|
||||
@ -769,7 +767,7 @@ string walkCondExpr (const COND_EXPR* expr, Function * pProc, int* numLoc)
|
||||
break;
|
||||
|
||||
case FUNCTION:
|
||||
o << writeCall (expr->expr.ident.idNode.call.proc,expr->expr.ident.idNode.call.args, pProc, numLoc);
|
||||
o << writeCall (expr->expr.ident.idNode.call.proc,*expr->expr.ident.idNode.call.args, pProc, numLoc);
|
||||
break;
|
||||
|
||||
case OTHER:
|
||||
@ -786,7 +784,6 @@ string walkCondExpr (const COND_EXPR* expr, Function * pProc, int* numLoc)
|
||||
break;
|
||||
}
|
||||
cCode.appendDecl(codeOut.str());
|
||||
|
||||
return outStr.str();
|
||||
}
|
||||
|
||||
|
||||
@ -94,35 +94,39 @@ char *cChar (uint8_t c)
|
||||
* Note: to get to the value of the variable:
|
||||
* com file: prog.Image[operand]
|
||||
* exe file: prog.Image[operand+0x100] */
|
||||
static void printGlobVar (std::ostream &ostr,SYM * psym);
|
||||
static void printGlobVar (SYM * psym)
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
printGlobVar(ostr,psym);
|
||||
cCode.appendDecl(ostr.str());
|
||||
}
|
||||
static void printGlobVar (std::ostream &ostr,SYM * psym)
|
||||
{
|
||||
int j;
|
||||
uint32_t relocOp = prog.fCOM ? psym->label : psym->label + 0x100;
|
||||
|
||||
switch (psym->size)
|
||||
{
|
||||
case 1: cCode.appendDecl( "uint8_t\t%s = %ld;\n",
|
||||
psym->name, prog.Image[relocOp]);
|
||||
case 1:
|
||||
ostr << "uint8_t\t"<<psym->name<<" = "<<prog.Image[relocOp]<<";\n";
|
||||
break;
|
||||
case 2: cCode.appendDecl( "uint16_t\t%s = %ld;\n",
|
||||
psym->name, LH(prog.Image+relocOp));
|
||||
case 2:
|
||||
ostr << "uint16_t\t"<<psym->name<<" = "<<LH(prog.Image+relocOp)<<";\n";
|
||||
break;
|
||||
case 4: if (psym->type == TYPE_PTR) /* pointer */
|
||||
cCode.appendDecl( "uint16_t\t*%s = %ld;\n",
|
||||
psym->name, LH(prog.Image+relocOp));
|
||||
ostr << "uint16_t *\t"<<psym->name<<" = "<<LH(prog.Image+relocOp)<<";\n";
|
||||
else /* char */
|
||||
cCode.appendDecl(
|
||||
"char\t%s[4] = \"%c%c%c%c\";\n",
|
||||
psym->name, prog.Image[relocOp],
|
||||
prog.Image[relocOp+1], prog.Image[relocOp+2],
|
||||
prog.Image[relocOp+3]);
|
||||
ostr << "char\t"<<psym->name<<"[4] = \""<<
|
||||
prog.Image[relocOp]<<prog.Image[relocOp+1]<<
|
||||
prog.Image[relocOp+2]<<prog.Image[relocOp+3]<<";\n";
|
||||
break;
|
||||
default:
|
||||
{
|
||||
ostringstream strContents;
|
||||
for (j=0; j < psym->size; j++)
|
||||
strContents << cChar(prog.Image[relocOp + j]);
|
||||
cCode.appendDecl( "char\t*%s = \"%s\";\n", psym->name, strContents.str().c_str());
|
||||
ostr << "char\t*"<<psym->name<<" = \""<<strContents.str()<<"\";\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -133,32 +137,31 @@ static void printGlobVar (SYM * psym)
|
||||
* initialization. */
|
||||
static void writeGlobSymTable()
|
||||
{
|
||||
char type[10];
|
||||
std::ostringstream ostr;
|
||||
|
||||
if (not symtab.empty())
|
||||
{
|
||||
cCode.appendDecl( "/* Global variables */\n");
|
||||
if (symtab.empty())
|
||||
return;
|
||||
ostr<<"/* Global variables */\n";
|
||||
for (SYM &sym : symtab)
|
||||
{
|
||||
if (sym.duVal.isUSE_VAL()) /* first used */
|
||||
printGlobVar (&sym);
|
||||
printGlobVar (ostr,&sym);
|
||||
else { /* first defined */
|
||||
switch (sym.size) {
|
||||
case 1: strcpy (type, "uint8_t\t"); break;
|
||||
case 2: strcpy (type, "int\t"); break;
|
||||
case 1: ostr<<"uint8_t\t"; break;
|
||||
case 2: ostr<<"int\t"; break;
|
||||
case 4: if (sym.type == TYPE_PTR)
|
||||
strcpy (type, "int\t*");
|
||||
ostr<<"int\t*";
|
||||
else
|
||||
strcpy (type, "char\t*");
|
||||
ostr<<"char\t*";
|
||||
break;
|
||||
default: strcpy (type, "char\t*");
|
||||
default: ostr<<"char\t*";
|
||||
}
|
||||
cCode.appendDecl( "%s%s;\t/* size = %ld */\n",
|
||||
type, sym.name, sym.size);
|
||||
ostr<<sym.name<<";\t/* size = "<<sym.size<<" */\n";
|
||||
}
|
||||
}
|
||||
cCode.appendDecl( "\n");
|
||||
}
|
||||
ostr<< "\n";
|
||||
cCode.appendDecl( ostr.str() );
|
||||
}
|
||||
|
||||
|
||||
@ -202,7 +205,7 @@ static void emitFwdGotoLabel (ICODE * pt, int indLevel)
|
||||
void Function::codeGen (std::ostream &fs)
|
||||
{
|
||||
int numLoc;
|
||||
ostringstream buf;
|
||||
ostringstream ostr;
|
||||
//STKFRAME * args; /* Procedure arguments */
|
||||
//char buf[200], /* Procedure's definition */
|
||||
// arg[30]; /* One argument */
|
||||
@ -211,22 +214,21 @@ void Function::codeGen (std::ostream &fs)
|
||||
/* Write procedure/function header */
|
||||
newBundle (&cCode);
|
||||
if (flg & PROC_IS_FUNC) /* Function */
|
||||
cCode.appendDecl( "\n%s %s (", hlTypes[retVal.type],name.c_str());
|
||||
ostr<< "\n"<<TypeContainer::typeName(retVal.type)<<" "<<name<<" (";
|
||||
else /* Procedure */
|
||||
cCode.appendDecl( "\nvoid %s (", name.c_str());
|
||||
ostr<< "\nvoid "<<name<<" (";
|
||||
|
||||
/* Write arguments */
|
||||
for (size_t i = 0; i < args.sym.size(); i++)
|
||||
for (size_t i = 0; i < args.size(); i++)
|
||||
{
|
||||
if (args.sym[i].invalid == false)
|
||||
{
|
||||
buf<<hlTypes[args.sym[i].type]<<" "<<args.sym[i].name;
|
||||
if (i < (args.sym.size() - 1))
|
||||
buf<<", ";
|
||||
if ( args[i].invalid )
|
||||
continue;
|
||||
ostr<<hlTypes[args[i].type]<<" "<<args[i].name;
|
||||
if (i < (args.size() - 1))
|
||||
ostr<<", ";
|
||||
}
|
||||
}
|
||||
buf<<")\n";
|
||||
cCode.appendDecl( buf.str() );
|
||||
ostr<<")\n";
|
||||
cCode.appendDecl( ostr.str() );
|
||||
|
||||
/* Write comments */
|
||||
writeProcComments();
|
||||
@ -238,27 +240,25 @@ void Function::codeGen (std::ostream &fs)
|
||||
for (ID &refId : localId )
|
||||
{
|
||||
/* Output only non-invalidated entries */
|
||||
if (refId.illegal == false)
|
||||
{
|
||||
if ( refId.illegal )
|
||||
continue;
|
||||
if (refId.loc == REG_FRAME)
|
||||
{
|
||||
/* Register variables are assigned to a local variable */
|
||||
if (((flg & SI_REGVAR) && (refId.id.regi == rSI)) ||
|
||||
((flg & DI_REGVAR) && (refId.id.regi == rDI)))
|
||||
{
|
||||
sprintf (refId.name, "loc%ld", ++numLoc);
|
||||
cCode.appendDecl( "int %s;\n", refId.name);
|
||||
refId.setLocalName(++numLoc);
|
||||
cCode.appendDecl( "int %s;\n", refId.name.c_str());
|
||||
}
|
||||
/* Other registers are named when they are first used in
|
||||
* the output C code, and appended to the proc decl. */
|
||||
}
|
||||
|
||||
else if (refId.loc == STK_FRAME)
|
||||
{
|
||||
/* Name local variables and output appropriate type */
|
||||
sprintf (refId.name, "loc%ld", ++numLoc);
|
||||
cCode.appendDecl( "%s %s;\n",hlTypes[refId.type], refId.name);
|
||||
}
|
||||
refId.setLocalName(++numLoc);
|
||||
cCode.appendDecl( "%s %s;\n",hlTypes[refId.type], refId.name.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -480,10 +480,10 @@ bool LibCheck(Function & pProc)
|
||||
the appropriate field */
|
||||
arg = pFunc[i].firstArg;
|
||||
pProc.args.numArgs = pFunc[i].numArg;
|
||||
pProc.args.sym.resize(pFunc[i].numArg);
|
||||
pProc.args.resize(pFunc[i].numArg);
|
||||
for (j=0; j < pFunc[i].numArg; j++)
|
||||
{
|
||||
pProc.args.sym[j].type = pArg[arg++];
|
||||
pProc.args[j].type = pArg[arg++];
|
||||
}
|
||||
if (pFunc[i].typ != TYPE_UNKNOWN)
|
||||
{
|
||||
|
||||
@ -204,7 +204,7 @@ void Function::writeProcComments(std::ostream &ostr)
|
||||
ostr << "/* Uses register arguments:\n";
|
||||
for (i = 0; i < this->args.numArgs; i++)
|
||||
{
|
||||
psym = &this->args.sym[i];
|
||||
psym = &this->args[i];
|
||||
ostr << " * "<<psym->name<<" = ";
|
||||
if (psym->regs->expr.ident.idType == REGISTER)
|
||||
{
|
||||
|
||||
@ -75,12 +75,8 @@ ExpStack g_exp_stk;
|
||||
* is in the stack frame provided. */
|
||||
size_t STKFRAME::getLocVar(int off)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < sym.size(); i++)
|
||||
if (sym[i].off == off)
|
||||
break;
|
||||
return (i);
|
||||
auto iter=findByLabel(off);
|
||||
return distance(begin(),iter);
|
||||
}
|
||||
|
||||
|
||||
@ -686,11 +682,11 @@ static int processCArg (Function * pp, Function * pProc, ICODE * picode, int num
|
||||
if (pp->args.numArgs > 0)
|
||||
if (pp->flg & PROC_VARARG)
|
||||
{
|
||||
if (numArgs < pp->args.sym.size())
|
||||
adjustActArgType (_exp, pp->args.sym[numArgs].type, pProc);
|
||||
if (numArgs < pp->args.size())
|
||||
adjustActArgType (_exp, pp->args[numArgs].type, pProc);
|
||||
}
|
||||
else
|
||||
adjustActArgType (_exp, pp->args.sym[numArgs].type, pProc);
|
||||
adjustActArgType (_exp, pp->args[numArgs].type, pProc);
|
||||
}
|
||||
else /* user function */
|
||||
{
|
||||
@ -774,7 +770,7 @@ void Function::processHliCall(COND_EXPR *_exp, iICODE picode)
|
||||
if (pp->flg & PROC_ISLIB) /* library function */
|
||||
{
|
||||
if (pp->args.numArgs > 0)
|
||||
adjustActArgType(_exp, pp->args.sym[numArgs].type, this);
|
||||
adjustActArgType(_exp, pp->args[numArgs].type, this);
|
||||
res = picode->newStkArg (_exp, (llIcode)picode->ll()->getOpcode(), this);
|
||||
}
|
||||
else /* user function */
|
||||
|
||||
@ -487,20 +487,20 @@ COND_EXPR *COND_EXPR::inverse () const
|
||||
|
||||
/* Returns the string that represents the procedure call of tproc (ie. with
|
||||
* actual parameters) */
|
||||
std::string writeCall (Function * tproc, STKFRAME * args, Function * pproc, int *numLoc)
|
||||
std::string writeCall (Function * tproc, STKFRAME & args, Function * pproc, int *numLoc)
|
||||
{
|
||||
int i; /* counter of # arguments */
|
||||
string condExp;
|
||||
ostringstream s;
|
||||
s<<tproc->name<<" (";
|
||||
for (i = 0; i < args->sym.size(); i++)
|
||||
ostringstream ostr;
|
||||
ostr<<tproc->name<<" (";
|
||||
for(const STKSYM &sym : args)
|
||||
{
|
||||
s << walkCondExpr (args->sym[i].actual, pproc, numLoc);
|
||||
if (i < (args->sym.size() - 1))
|
||||
s << ", ";
|
||||
ostr << walkCondExpr (sym.actual, pproc, numLoc);
|
||||
if((&sym)!=&(args.back()))
|
||||
ostr << ", ";
|
||||
}
|
||||
s << ")";
|
||||
return s.str();
|
||||
ostr << ")";
|
||||
return ostr.str();
|
||||
}
|
||||
|
||||
|
||||
@ -547,7 +547,7 @@ string AssignType::writeOut(Function *pProc, int *numLoc)
|
||||
string CallType::writeOut(Function *pProc, int *numLoc)
|
||||
{
|
||||
ostringstream ostr;
|
||||
ostr << writeCall (proc, args, pProc,numLoc);
|
||||
ostr << writeCall (proc, *args, pProc,numLoc);
|
||||
ostr << ";\n";
|
||||
return ostr.str();
|
||||
}
|
||||
|
||||
@ -204,7 +204,7 @@ void Function::findIdioms()
|
||||
}
|
||||
|
||||
/* Check if number of parameter bytes match their calling convention */
|
||||
if ((flg & PROC_HLL) && (!args.sym.empty()))
|
||||
if ((flg & PROC_HLL) && (!args.empty()))
|
||||
{
|
||||
args.m_minOff += (flg & PROC_FAR ? 4 : 2);
|
||||
delta = args.maxOff - args.m_minOff;
|
||||
|
||||
@ -420,28 +420,23 @@ eReg otherLongRegi (eReg regi, int idx, LOCAL_ID *locTbl)
|
||||
* long register identifier. */
|
||||
void LOCAL_ID::propLongId (uint8_t regL, uint8_t regH, const char *name)
|
||||
{
|
||||
int i;
|
||||
ID *_id;
|
||||
|
||||
for (i = 0; i < id_arr.size(); i++)
|
||||
for (ID &rid : id_arr)
|
||||
{
|
||||
_id = &id_arr[i];
|
||||
if (_id->typeBitsize()==16)
|
||||
if (rid.typeBitsize()!=16)
|
||||
continue;
|
||||
if ( (rid.id.regi != regL) and (rid.id.regi != regH) )
|
||||
continue;
|
||||
// otherwise at least 1 is ok
|
||||
rid.name = name;
|
||||
rid.hasMacro = true;
|
||||
rid.illegal = true;
|
||||
if (rid.id.regi == regL)
|
||||
{
|
||||
if (_id->id.regi == regL)
|
||||
{
|
||||
strcpy (_id->name, name);
|
||||
strcpy (_id->macro, "LO");
|
||||
_id->hasMacro = true;
|
||||
_id->illegal = true;
|
||||
strcpy (rid.macro, "LO");
|
||||
}
|
||||
else if (_id->id.regi == regH)
|
||||
else // if (rid.id.regi == regH)
|
||||
{
|
||||
strcpy (_id->name, name);
|
||||
strcpy (_id->macro, "HI");
|
||||
_id->hasMacro = true;
|
||||
_id->illegal = true;
|
||||
}
|
||||
strcpy (rid.macro, "HI");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
123
src/parser.cpp
123
src/parser.cpp
@ -14,7 +14,7 @@ using namespace std;
|
||||
//static void FollowCtrl (Function * pProc, CALL_GRAPH * pcallGraph, STATE * pstate);
|
||||
static boolT process_JMP (ICODE * pIcode, STATE * pstate, CALL_GRAPH * pcallGraph);
|
||||
static void setBits(int16_t type, uint32_t start, uint32_t len);
|
||||
static SYM * updateGlobSym(uint32_t operand, int size, uint16_t duFlag);
|
||||
//static SYM * updateGlobSym(uint32_t operand, int size, uint16_t duFlag,bool &created);
|
||||
static void process_MOV(LLInst &ll, STATE * pstate);
|
||||
static SYM * lookupAddr (LLOperand *pm, STATE * pstate, int size, uint16_t duFlag);
|
||||
void interactDis(Function * initProc, int ic);
|
||||
@ -718,77 +718,32 @@ static void process_MOV(LLInst & ll, STATE * pstate)
|
||||
}
|
||||
|
||||
|
||||
/* Type of the symbol according to the number of bytes it uses */
|
||||
static hlType cbType[] = {TYPE_UNKNOWN, TYPE_BYTE_UNSIGN, TYPE_WORD_SIGN,
|
||||
TYPE_UNKNOWN, TYPE_LONG_SIGN};
|
||||
|
||||
/* Creates an entry in the global symbol table (symtab) if the variable
|
||||
* is not there yet. If it is part of the symtab, the size of the variable
|
||||
* is checked and updated if the old size was less than the new size (ie.
|
||||
* the maximum size is always saved). */
|
||||
static SYM * updateGlobSym (uint32_t operand, int size, uint16_t duFlag)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Check for symbol in symbol table */
|
||||
for (i = 0; i < symtab.size(); i++)
|
||||
if (symtab[i].label == operand)
|
||||
{
|
||||
if (symtab[i].size < size)
|
||||
symtab[i].size = size;
|
||||
break;
|
||||
}
|
||||
|
||||
/* New symbol, not in symbol table */
|
||||
if (i == symtab.size())
|
||||
{
|
||||
SYM v;
|
||||
sprintf (v.name, "var%05lX", operand);
|
||||
v.label = operand;
|
||||
v.size = size;
|
||||
v.type = cbType[size];
|
||||
if (duFlag == eDuVal::USE) /* must already have init value */
|
||||
{
|
||||
v.duVal.use =1; // USEVAL;
|
||||
v.duVal.val =1;
|
||||
}
|
||||
else
|
||||
{
|
||||
v.duVal.setFlags(duFlag);
|
||||
}
|
||||
symtab.push_back(v);
|
||||
}
|
||||
return (&symtab[i]);
|
||||
}
|
||||
|
||||
|
||||
/* Updates the offset entry to the stack frame table (arguments),
|
||||
* and returns a pointer to such entry. */
|
||||
static void updateFrameOff (STKFRAME * ps, int16_t off, int size, uint16_t duFlag)
|
||||
void STKFRAME::updateFrameOff ( int16_t off, int _size, uint16_t duFlag)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Check for symbol in stack frame table */
|
||||
for (i = 0; i < ps->sym.size(); i++)
|
||||
auto iter=findByLabel(off);
|
||||
if(iter!=end())
|
||||
{
|
||||
if (ps->sym[i].off == off)
|
||||
if (iter->size < _size)
|
||||
{
|
||||
if (ps->sym[i].size < size)
|
||||
{
|
||||
ps->sym[i].size = size;
|
||||
}
|
||||
break;
|
||||
iter->size = _size;
|
||||
}
|
||||
}
|
||||
|
||||
/* New symbol, not in table */
|
||||
if (i == ps->sym.size())
|
||||
else
|
||||
{
|
||||
char nm[16];
|
||||
STKSYM new_sym;
|
||||
sprintf (new_sym.name, "arg%ld", i);
|
||||
new_sym.off = off;
|
||||
new_sym.size = size;
|
||||
new_sym.type = cbType[size];
|
||||
|
||||
sprintf (nm, "arg%ld", size());
|
||||
new_sym.name = nm;
|
||||
new_sym.label= off;
|
||||
new_sym.size = _size;
|
||||
new_sym.type = TypeContainer::defaultTypeForSize(_size);
|
||||
if (duFlag == eDuVal::USE) /* must already have init value */
|
||||
{
|
||||
new_sym.duVal.use=1;
|
||||
@ -798,13 +753,13 @@ static void updateFrameOff (STKFRAME * ps, int16_t off, int size, uint16_t duFla
|
||||
{
|
||||
new_sym.duVal.setFlags(duFlag);
|
||||
}
|
||||
ps->sym.push_back(new_sym);
|
||||
ps->numArgs++;
|
||||
push_back(new_sym);
|
||||
this->numArgs++;
|
||||
}
|
||||
|
||||
/* Save maximum argument offset */
|
||||
if ((uint32_t)ps->maxOff < (off + (uint32_t)size))
|
||||
ps->maxOff = off + (int16_t)size;
|
||||
if ((uint32_t)this->maxOff < (off + (uint32_t)_size))
|
||||
this->maxOff = off + (int16_t)_size;
|
||||
}
|
||||
|
||||
|
||||
@ -815,29 +770,26 @@ static void updateFrameOff (STKFRAME * ps, int16_t off, int size, uint16_t duFla
|
||||
static SYM * lookupAddr (LLOperand *pm, STATE *pstate, int size, uint16_t duFlag)
|
||||
{
|
||||
int i;
|
||||
SYM * psym;
|
||||
SYM * psym=nullptr;
|
||||
uint32_t operand;
|
||||
bool created_new=false;
|
||||
if (pm->regi != rUNDEF)
|
||||
return nullptr; // register or indexed
|
||||
|
||||
if (pm->regi == 0)
|
||||
{
|
||||
/* Global var */
|
||||
if (pm->segValue) { /* there is a value in the seg field */
|
||||
if (pm->segValue) /* there is a value in the seg field */
|
||||
{
|
||||
operand = opAdr (pm->segValue, pm->off);
|
||||
psym = updateGlobSym (operand, size, duFlag);
|
||||
|
||||
/* Check for out of bounds */
|
||||
if (psym->label >= (uint32_t)prog.cbImage)
|
||||
return (NULL);
|
||||
return (psym);
|
||||
psym = symtab.updateGlobSym (operand, size, duFlag,created_new);
|
||||
}
|
||||
else if (pstate->f[pm->seg]) { /* new value */
|
||||
else if (pstate->f[pm->seg]) /* new value */
|
||||
{
|
||||
pm->segValue = pstate->r[pm->seg];
|
||||
operand = opAdr(pm->segValue, pm->off);
|
||||
i = symtab.size();
|
||||
psym = updateGlobSym (operand, size, duFlag);
|
||||
psym = symtab.updateGlobSym (operand, size, duFlag,created_new);
|
||||
|
||||
/* Flag new memory locations that are segment values */
|
||||
if (symtab.size() > i)
|
||||
if (created_new)
|
||||
{
|
||||
if (size == 4)
|
||||
operand += 2; /* High uint16_t */
|
||||
@ -847,14 +799,11 @@ static SYM * lookupAddr (LLOperand *pm, STATE *pstate, int size, uint16_t duFlag
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/* Check for out of bounds */
|
||||
if (psym->label >= (uint32_t)prog.cbImage)
|
||||
return (NULL);
|
||||
return (psym);
|
||||
}
|
||||
}
|
||||
return (NULL);
|
||||
if (psym && (psym->label>=0) and (psym->label < (uint32_t)prog.cbImage))
|
||||
return psym;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@ -944,7 +893,7 @@ static void use (opLoc d, ICODE & pIcode, Function * pProc, STATE * pstate, int
|
||||
if (pm->regi == INDEX_BP) /* indexed on bp */
|
||||
{
|
||||
if (pm->off >= 2)
|
||||
updateFrameOff (&pProc->args, pm->off, size, eDuVal::USE);
|
||||
pProc->args.updateFrameOff ( pm->off, size, eDuVal::USE);
|
||||
else if (pm->off < 0)
|
||||
pProc->localId.newByteWordStk (TYPE_WORD_SIGN, pm->off, 0);
|
||||
}
|
||||
@ -991,7 +940,7 @@ static void def (opLoc d, ICODE & pIcode, Function * pProc, STATE * pstate, int
|
||||
if (pm->regi == INDEX_BP) /* indexed on bp */
|
||||
{
|
||||
if (pm->off >= 2)
|
||||
updateFrameOff (&pProc->args, pm->off, size, eDEF);
|
||||
pProc->args.updateFrameOff ( pm->off, size, eDEF);
|
||||
else if (pm->off < 0)
|
||||
pProc->localId.newByteWordStk (TYPE_WORD_SIGN, pm->off, 0);
|
||||
}
|
||||
@ -1016,7 +965,7 @@ static void def (opLoc d, ICODE & pIcode, Function * pProc, STATE * pstate, int
|
||||
{
|
||||
setBits(BM_DATA, psym->label, (uint32_t)size);
|
||||
pIcode.ll()->setFlags(SYM_DEF);
|
||||
pIcode.ll()->caseTbl.numEntries = psym - &symtab[0];
|
||||
pIcode.ll()->caseTbl.numEntries = distance(&symtab[0],psym);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -132,7 +132,7 @@ void Function::newRegArg(iICODE picode, iICODE ticode)
|
||||
|
||||
/* Check if register argument already on the formal argument list */
|
||||
regExist = false;
|
||||
for(STKSYM &tgt_sym : target_stackframe->sym)
|
||||
for(STKSYM &tgt_sym : *target_stackframe)
|
||||
{
|
||||
if (type == REGISTER)
|
||||
{
|
||||
@ -158,7 +158,9 @@ void Function::newRegArg(iICODE picode, iICODE ticode)
|
||||
if (regExist == false)
|
||||
{
|
||||
STKSYM newsym;
|
||||
sprintf (newsym.name, "arg%ld", target_stackframe->sym.size());
|
||||
|
||||
newsym.setArgName(target_stackframe->size());
|
||||
|
||||
if (type == REGISTER)
|
||||
{
|
||||
if (regL < rAL)
|
||||
@ -171,23 +173,22 @@ void Function::newRegArg(iICODE picode, iICODE ticode)
|
||||
newsym.type = TYPE_BYTE_SIGN;
|
||||
newsym.regs = COND_EXPR::idRegIdx(tidx, BYTE_REG);
|
||||
}
|
||||
sprintf (tproc->localId.id_arr[tidx].name, "arg%ld", target_stackframe->sym.size());
|
||||
tproc->localId.id_arr[tidx].name = newsym.name;
|
||||
}
|
||||
else if (type == LONG_VAR)
|
||||
{
|
||||
newsym.regs = COND_EXPR::idLongIdx (tidx);
|
||||
newsym.type = TYPE_LONG_SIGN;
|
||||
sprintf (tproc->localId.id_arr[tidx].name, "arg%ld", target_stackframe->sym.size());
|
||||
tproc->localId.propLongId (regL, regH,
|
||||
tproc->localId.id_arr[tidx].name);
|
||||
tproc->localId.id_arr[tidx].name = newsym.name;
|
||||
tproc->localId.propLongId (regL, regH, tproc->localId.id_arr[tidx].name.c_str());
|
||||
}
|
||||
target_stackframe->sym.push_back(newsym);
|
||||
target_stackframe->push_back(newsym);
|
||||
target_stackframe->numArgs++;
|
||||
}
|
||||
|
||||
/* Do ps (actual arguments) */
|
||||
STKSYM newsym;
|
||||
sprintf (newsym.name, "arg%ld", call_args_stackframe->sym.size());
|
||||
newsym.setArgName(call_args_stackframe->size());
|
||||
newsym.actual = picode->hl()->asgn.rhs;
|
||||
newsym.regs = lhs;
|
||||
/* Mask off high and low register(s) in picode */
|
||||
@ -207,15 +208,15 @@ void Function::newRegArg(iICODE picode, iICODE ticode)
|
||||
newsym.type = TYPE_LONG_SIGN;
|
||||
break;
|
||||
}
|
||||
call_args_stackframe->sym.push_back(newsym);
|
||||
call_args_stackframe->push_back(newsym);
|
||||
call_args_stackframe->numArgs++;
|
||||
}
|
||||
|
||||
|
||||
/** Inserts the new expression (ie. the actual parameter) on the argument
|
||||
* list.
|
||||
* @return TRUE if it was a near call that made use of a segment register.
|
||||
* FALSE elsewhere
|
||||
* @return true if it was a near call that made use of a segment register.
|
||||
* false elsewhere
|
||||
*/
|
||||
bool CallType::newStkArg(COND_EXPR *exp, llIcode opcode, Function * pproc)
|
||||
{
|
||||
@ -239,7 +240,7 @@ bool CallType::newStkArg(COND_EXPR *exp, llIcode opcode, Function * pproc)
|
||||
/* Place register argument on the argument list */
|
||||
STKSYM newsym;
|
||||
newsym.actual = exp;
|
||||
args->sym.push_back(newsym);
|
||||
args->push_back(newsym);
|
||||
args->numArgs++;
|
||||
return false;
|
||||
}
|
||||
@ -249,8 +250,8 @@ bool CallType::newStkArg(COND_EXPR *exp, llIcode opcode, Function * pproc)
|
||||
* argument list of picode. */
|
||||
void CallType::placeStkArg (COND_EXPR *exp, int pos)
|
||||
{
|
||||
args->sym[pos].actual = exp;
|
||||
sprintf (args->sym[pos].name, "arg%ld", pos);
|
||||
(*args)[pos].actual = exp;
|
||||
(*args)[pos].setArgName(pos);
|
||||
}
|
||||
|
||||
|
||||
@ -317,35 +318,32 @@ void STKFRAME::adjustForArgType(int numArg_, hlType actType_)
|
||||
hlType forType;
|
||||
STKSYM * psym, * nsym;
|
||||
int off, i;
|
||||
|
||||
/* Find stack offset for this argument */
|
||||
off = m_minOff;
|
||||
for (i = 0; i < numArg_; i++)
|
||||
{
|
||||
if(i>=sym.size())
|
||||
{
|
||||
break; //TODO: verify
|
||||
}
|
||||
off += sym[i].size;
|
||||
}
|
||||
|
||||
/* Find formal argument */
|
||||
if (numArg_ < sym.size())
|
||||
{
|
||||
psym = &sym[numArg_];
|
||||
i = numArg_;
|
||||
//auto iter=std::find_if(sym.begin(),sym.end(),[off](STKSYM &s)->bool {s.off==off;});
|
||||
auto iter=std::find_if(sym.begin()+numArg_,sym.end(),[off](STKSYM &s)->bool {s.off==off;});
|
||||
if(iter==sym.end()) // symbol not found
|
||||
return;
|
||||
psym = &(*iter);
|
||||
}
|
||||
/* If formal argument does not exist, do not create new ones, just
|
||||
* ignore actual argument
|
||||
*/
|
||||
else
|
||||
if(numArg_>size())
|
||||
return;
|
||||
|
||||
/* Find stack offset for this argument */
|
||||
off = m_minOff;
|
||||
i=0;
|
||||
for(STKSYM &s : *this) // walk formal arguments upto numArg_
|
||||
{
|
||||
if(i>=numArg_)
|
||||
break;
|
||||
off+=s.size;
|
||||
i++;
|
||||
}
|
||||
|
||||
/* Find formal argument */
|
||||
//psym = &at(numArg_);
|
||||
//i = numArg_;
|
||||
//auto iter=std::find_if(sym.begin(),sym.end(),[off](STKSYM &s)->bool {s.off==off;});
|
||||
auto iter=std::find_if(begin()+numArg_,end(),[off](STKSYM &s)->bool {s.label==off;});
|
||||
if(iter==end()) // symbol not found
|
||||
return;
|
||||
psym = &(*iter);
|
||||
|
||||
forType = psym->type;
|
||||
if (forType != actType_)
|
||||
{
|
||||
@ -364,11 +362,11 @@ void STKFRAME::adjustForArgType(int numArg_, hlType actType_)
|
||||
psym->type = actType_;
|
||||
psym->size = 4;
|
||||
nsym = psym + 1;
|
||||
sprintf (nsym->macro, "HI");
|
||||
sprintf (psym->macro, "LO");
|
||||
nsym->macro = "HI";
|
||||
psym->macro = "LO";
|
||||
nsym->hasMacro = true;
|
||||
psym->hasMacro = true;
|
||||
sprintf (nsym->name, "%s", psym->name);
|
||||
nsym->name = psym->name;
|
||||
nsym->invalid = true;
|
||||
numArgs--;
|
||||
}
|
||||
|
||||
@ -137,3 +137,58 @@ boolT readVal(std::ostringstream &symName, uint32_t symOff, Function * symProc)
|
||||
{
|
||||
return false; // no symbolic names for now
|
||||
}
|
||||
|
||||
/* Updates the type of the symbol in the symbol table. The size is updated
|
||||
* if necessary (0 means no update necessary). */
|
||||
void SYMTAB::updateSymType (uint32_t symbol,const TypeContainer &tc)
|
||||
{
|
||||
int i;
|
||||
auto iter=findByLabel(symbol);
|
||||
if(iter==end())
|
||||
return;
|
||||
iter->type = tc.m_type;
|
||||
if (tc.m_size != 0)
|
||||
iter->size = tc.m_size;
|
||||
}
|
||||
|
||||
/* Creates an entry in the global symbol table (symtab) if the variable
|
||||
* is not there yet. If it is part of the symtab, the size of the variable
|
||||
* is checked and updated if the old size was less than the new size (ie.
|
||||
* the maximum size is always saved). */
|
||||
//TODO: SYMTAB::updateGlobSym should be renamed to insertOrUpdateSym
|
||||
SYM * SYMTAB::updateGlobSym (uint32_t operand, int size, uint16_t duFlag,bool &inserted_new)
|
||||
{
|
||||
/* Check for symbol in symbol table */
|
||||
auto iter = findByLabel(operand);
|
||||
if(iter!=end())
|
||||
{
|
||||
if(iter->size<size)
|
||||
iter->size = size;
|
||||
inserted_new=false;
|
||||
return &(*iter);
|
||||
}
|
||||
|
||||
/* New symbol, not in symbol table */
|
||||
SYM v;
|
||||
char buf[32]={};
|
||||
sprintf (buf, "var%05X", operand);
|
||||
v.name = buf;
|
||||
v.label = operand;
|
||||
v.size = size;
|
||||
v.type = TypeContainer::defaultTypeForSize(size);
|
||||
if (duFlag == eDuVal::USE) /* must already have init value */
|
||||
{
|
||||
v.duVal.use =1; // USEVAL;
|
||||
v.duVal.val =1;
|
||||
}
|
||||
else
|
||||
{
|
||||
v.duVal.setFlags(duFlag);
|
||||
}
|
||||
push_back(v);
|
||||
inserted_new=true;
|
||||
return (&back());
|
||||
}
|
||||
|
||||
//template<> class SymbolTableCommon<SYM>;
|
||||
//template<> class SymbolTableCommon<STKSYM>;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user