forked from OSchip/llvm-project
Changed lowering and asmprinter to use ABI Names class called PAN.
llvm-svn: 71386
This commit is contained in:
parent
3978f7972d
commit
258f851629
|
@ -18,6 +18,7 @@
|
|||
#include "llvm/Target/TargetMachine.h"
|
||||
#include <iosfwd>
|
||||
#include <cassert>
|
||||
#include <sstream>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
|
@ -41,19 +42,22 @@ namespace PIC16CC {
|
|||
UGE
|
||||
};
|
||||
}
|
||||
// A Central object to manage all ABI naming conventions.
|
||||
class PIC16ABINames {
|
||||
// A Central class to manage all ABI naming conventions.
|
||||
// PAN - [P]ic16 [A]BI [N]ames
|
||||
class PAN {
|
||||
public:
|
||||
// Map the name of the symbol to its section name.
|
||||
// Current ABI:
|
||||
// -----------------------------------------------------
|
||||
// ALL Names are prefixed with the symobl '@'.
|
||||
// ------------------------------------------------------
|
||||
// Global variables do not have any '.' in their names.
|
||||
// they are prefixed with @
|
||||
// These are maily function names and global variable names.
|
||||
// Example - @foo, @i
|
||||
// -------------------------------------------------------
|
||||
// Functions and auto variables.
|
||||
// Names are mangled as <prefix><funcname>.<id>.<varname>
|
||||
// Where prefix is a special char '@' and id is any one of
|
||||
// Names are mangled as <prefix><funcname>.<tag>.<varname>
|
||||
// Where <prefix> is '@' and <tag> is any one of
|
||||
// the following
|
||||
// .auto. - an automatic var of a function.
|
||||
// .temp. - temproray data of a function.
|
||||
|
@ -74,106 +78,218 @@ namespace PIC16CC {
|
|||
// To pass args: @sra_i8.args.
|
||||
// To return val: @sra_i8.ret.
|
||||
//----------------------------------------------
|
||||
// SECTION Names
|
||||
// uninitialized globals - @udata.<num>.#
|
||||
// initialized globals - @idata.<num>.#
|
||||
// Function frame - @<func>.frame_section.
|
||||
// Function autos - @<func>.autos_section.
|
||||
// Declarations - @section.0
|
||||
//----------------------------------------------------------
|
||||
|
||||
enum IDs {
|
||||
// Tags used to mangle different names.
|
||||
enum TAGS {
|
||||
PREFIX_SYMBOL,
|
||||
|
||||
FUNC_AUTOS,
|
||||
FUNC_FRAME,
|
||||
FUNC_RET,
|
||||
FUNC_ARGS,
|
||||
FUNC_TEMPS,
|
||||
GLOBAL,
|
||||
STATIC_LOCAL,
|
||||
AUTOS_LABEL,
|
||||
FRAME_LABEL,
|
||||
RET_LABEL,
|
||||
ARGS_LABEL,
|
||||
TEMPS_LABEL,
|
||||
|
||||
LIBCALL,
|
||||
|
||||
FRAME_SECTION,
|
||||
AUTOS_SECTION
|
||||
AUTOS_SECTION,
|
||||
CODE_SECTION
|
||||
};
|
||||
|
||||
inline static const char *getIDName(IDs id) {
|
||||
switch (id) {
|
||||
default: assert(0 && "Unknown id");
|
||||
// Textual names of the tags.
|
||||
inline static const char *getTagName(TAGS tag) {
|
||||
switch (tag) {
|
||||
default: return "";
|
||||
case PREFIX_SYMBOL: return "@";
|
||||
case FUNC_AUTOS: return ".auto.";
|
||||
case FUNC_FRAME: return ".frame.";
|
||||
case FUNC_TEMPS: return ".temp.";
|
||||
case FUNC_ARGS: return ".args.";
|
||||
case FUNC_RET: return ".ret.";
|
||||
case FRAME_SECTION: return "fpdata";
|
||||
case AUTOS_SECTION: return "fadata";
|
||||
case AUTOS_LABEL: return ".auto.";
|
||||
case FRAME_LABEL: return ".frame.";
|
||||
case TEMPS_LABEL: return ".temp.";
|
||||
case ARGS_LABEL: return ".args.";
|
||||
case RET_LABEL: return ".ret.";
|
||||
case LIBCALL: return ".lib.";
|
||||
case FRAME_SECTION: return ".fpdata.";
|
||||
case AUTOS_SECTION: return ".fadata.";
|
||||
case CODE_SECTION: return "code";
|
||||
}
|
||||
}
|
||||
|
||||
inline static IDs getID(const std::string &Sym) {
|
||||
if (Sym.find(getIDName(FUNC_TEMPS)))
|
||||
return FUNC_TEMPS;
|
||||
// Get tag type for the Symbol.
|
||||
inline static TAGS getSymbolTag(const std::string &Sym) {
|
||||
if (Sym.find(getTagName(TEMPS_LABEL)) != std::string::npos)
|
||||
return TEMPS_LABEL;
|
||||
|
||||
if (Sym.find(getIDName(FUNC_FRAME)))
|
||||
return FUNC_FRAME;
|
||||
if (Sym.find(getTagName(FRAME_LABEL)) != std::string::npos)
|
||||
return FRAME_LABEL;
|
||||
|
||||
if (Sym.find(getIDName(FUNC_RET)))
|
||||
return FUNC_RET;
|
||||
if (Sym.find(getTagName(RET_LABEL)) != std::string::npos)
|
||||
return RET_LABEL;
|
||||
|
||||
if (Sym.find(getIDName(FUNC_ARGS)))
|
||||
return FUNC_ARGS;
|
||||
if (Sym.find(getTagName(ARGS_LABEL)) != std::string::npos)
|
||||
return ARGS_LABEL;
|
||||
|
||||
if (Sym.find(getIDName(FUNC_AUTOS)))
|
||||
return FUNC_AUTOS;
|
||||
if (Sym.find(getTagName(AUTOS_LABEL)) != std::string::npos)
|
||||
return AUTOS_LABEL;
|
||||
|
||||
if (Sym.find(getIDName(LIBCALL)))
|
||||
if (Sym.find(getTagName(LIBCALL)) != std::string::npos)
|
||||
return LIBCALL;
|
||||
|
||||
// It does not have any ID. So its a global.
|
||||
assert (0 && "Could not determine ID symbol type");
|
||||
// It does not have any Tag. So its a true global or static local.
|
||||
if (Sym.find(".") == std::string::npos)
|
||||
return GLOBAL;
|
||||
|
||||
// If a . is there, then it may be static local.
|
||||
// We should mangle these as well in clang.
|
||||
if (Sym.find(".") != std::string::npos)
|
||||
return STATIC_LOCAL;
|
||||
|
||||
assert (0 && "Could not determine Symbol's tag");
|
||||
}
|
||||
|
||||
// Get func name from a mangled name.
|
||||
// In all cases func name is the first component before a '.'.
|
||||
static inline std::string getFuncNameForSym(const std::string &Sym) {
|
||||
const char *prefix = getIDName (PREFIX_SYMBOL);
|
||||
// addPrefix - add prefix symbol to a name if there isn't one already.
|
||||
inline static std::string addPrefix (const std::string &Name) {
|
||||
std::string prefix = getTagName (PREFIX_SYMBOL);
|
||||
|
||||
// If this name has a prefix, func name start after prfix in that case.
|
||||
size_t func_name_start = 0;
|
||||
if (Sym.find(prefix, 0, strlen(prefix)) != std::string::npos)
|
||||
func_name_start = strlen(prefix);
|
||||
// If this name already has a prefix, nothing to do.
|
||||
if (Name.compare(0, prefix.size(), prefix) == 0)
|
||||
return Name;
|
||||
|
||||
return prefix + Name;
|
||||
}
|
||||
|
||||
// Get mangled func name from a mangled sym name.
|
||||
// In all cases func name is the first component before a '.'.
|
||||
static inline std::string getFuncNameForSym(const std::string &Sym1) {
|
||||
assert (getSymbolTag(Sym1) != GLOBAL && "not belongs to a function");
|
||||
|
||||
std::string Sym = addPrefix(Sym1);
|
||||
|
||||
// Position of the . after func name. That's where func name ends.
|
||||
size_t func_name_end = Sym.find ('.', func_name_start);
|
||||
size_t func_name_end = Sym.find ('.');
|
||||
|
||||
return Sym.substr (func_name_start, func_name_end);
|
||||
return Sym.substr (0, func_name_end);
|
||||
}
|
||||
|
||||
// Form a section name given the section type and func name.
|
||||
static std::string
|
||||
getSectionNameForFunc (const std::string &Fname, const IDs sec_id) {
|
||||
std::string sec_id_string = getIDName(sec_id);
|
||||
return sec_id_string + "." + Fname + ".#";
|
||||
// Get Frame start label for a func.
|
||||
static std::string getFrameLabel(const std::string &Func) {
|
||||
std::string Func1 = addPrefix(Func);
|
||||
std::string tag = getTagName(FRAME_LABEL);
|
||||
return Func1 + tag;
|
||||
}
|
||||
|
||||
static std::string getRetvalLabel(const std::string &Func) {
|
||||
std::string Func1 = addPrefix(Func);
|
||||
std::string tag = getTagName(RET_LABEL);
|
||||
return Func1 + tag;
|
||||
}
|
||||
|
||||
static std::string getArgsLabel(const std::string &Func) {
|
||||
std::string Func1 = addPrefix(Func);
|
||||
std::string tag = getTagName(ARGS_LABEL);
|
||||
return Func1 + tag;
|
||||
}
|
||||
|
||||
static std::string getTempdataLabel(const std::string &Func) {
|
||||
std::string Func1 = addPrefix(Func);
|
||||
std::string tag = getTagName(TEMPS_LABEL);
|
||||
return Func1 + tag;
|
||||
}
|
||||
|
||||
static std::string getFrameSectionName(const std::string &Func) {
|
||||
std::string Func1 = addPrefix(Func);
|
||||
std::string tag = getTagName(FRAME_SECTION);
|
||||
return Func1 + tag + " UDATA_OVR";
|
||||
}
|
||||
|
||||
static std::string getAutosSectionName(const std::string &Func) {
|
||||
std::string Func1 = addPrefix(Func);
|
||||
std::string tag = getTagName(AUTOS_SECTION);
|
||||
return Func1 + tag + " UDATA_OVR";
|
||||
}
|
||||
|
||||
static std::string getCodeSectionName(const std::string &Func) {
|
||||
std::string Func1 = addPrefix(Func);
|
||||
std::string tag = getTagName(CODE_SECTION);
|
||||
return Func1 + tag + " CODE";
|
||||
}
|
||||
|
||||
// udata and idata section names are generated by a given number.
|
||||
// @udata.<num>.#
|
||||
static std::string getUdataSectionName(unsigned num) {
|
||||
std::ostringstream o;
|
||||
o << getTagName(PREFIX_SYMBOL) << "udata." << num << ".# UDATA";
|
||||
return o.str();
|
||||
}
|
||||
|
||||
static std::string getIdataSectionName(unsigned num) {
|
||||
std::ostringstream o;
|
||||
o << getTagName(PREFIX_SYMBOL) << "idata." << num << ".# IDATA";
|
||||
return o.str();
|
||||
}
|
||||
|
||||
inline static bool isLocalName (const std::string &Name) {
|
||||
if (getSymbolTag(Name) == AUTOS_LABEL)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
inline static bool isLocalToFunc (std::string &Func, std::string &Var) {
|
||||
if (! isLocalName(Var)) return false;
|
||||
|
||||
std::string Func1 = addPrefix(Func);
|
||||
// Extract func name of the varilable.
|
||||
const std::string &fname = getFuncNameForSym(Var);
|
||||
|
||||
if (fname.compare(Func1) == 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Get the section for the given external symbol names.
|
||||
// This tries to find the type (ID) of the symbol from its mangled name
|
||||
// This tries to find the type (Tag) of the symbol from its mangled name
|
||||
// and return appropriate section name for it.
|
||||
static inline std::string getSectionNameForSym(const std::string &Sym) {
|
||||
static inline std::string getSectionNameForSym(const std::string &Sym1) {
|
||||
std::string Sym = addPrefix(Sym1);
|
||||
|
||||
std::string SectionName;
|
||||
|
||||
IDs id = getID (Sym);
|
||||
std::string Fname = getFuncNameForSym (Sym);
|
||||
TAGS id = getSymbolTag (Sym);
|
||||
|
||||
switch (id) {
|
||||
default : assert (0 && "Could not determine external symbol type");
|
||||
case FUNC_FRAME:
|
||||
case FUNC_RET:
|
||||
case FUNC_TEMPS:
|
||||
case FUNC_ARGS: {
|
||||
return getSectionNameForFunc (Fname, FRAME_SECTION);
|
||||
case FRAME_LABEL:
|
||||
case RET_LABEL:
|
||||
case TEMPS_LABEL:
|
||||
case ARGS_LABEL: {
|
||||
return getFrameSectionName(Fname);
|
||||
}
|
||||
case FUNC_AUTOS: {
|
||||
return getSectionNameForFunc (Fname, AUTOS_SECTION);
|
||||
case AUTOS_LABEL: {
|
||||
return getAutosSectionName(Fname);
|
||||
}
|
||||
}
|
||||
}
|
||||
}; // class PIC16ABINames.
|
||||
|
||||
}; // class PAN.
|
||||
|
||||
|
||||
// External symbol names require memory to live till the program end.
|
||||
// So we have to allocate it and keep.
|
||||
inline static const char *createESName (const std::string &name) {
|
||||
char *tmpName = new char[name.size() + 1];
|
||||
strcpy (tmpName, name.c_str());
|
||||
return tmpName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -218,7 +334,6 @@ namespace PIC16CC {
|
|||
bool Verbose);
|
||||
// Banksel optimzer pass.
|
||||
FunctionPass *createPIC16MemSelOptimizerPass();
|
||||
std::string getSectionNameForSym(const std::string &Sym);
|
||||
} // end namespace llvm;
|
||||
|
||||
// Defines symbolic names for PIC16 registers. This defines a mapping from
|
||||
|
|
|
@ -28,22 +28,6 @@ using namespace llvm;
|
|||
|
||||
#include "PIC16GenAsmWriter.inc"
|
||||
|
||||
inline static bool isLocalToFunc (std::string &FuncName, std::string &VarName) {
|
||||
if (VarName.find(FuncName + ".auto.") != std::string::npos
|
||||
|| VarName.find(FuncName + ".arg.") != std::string::npos)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
inline static bool isLocalName (std::string &Name) {
|
||||
if (Name.find(".auto.") != std::string::npos
|
||||
|| Name.find(".arg.") != std::string::npos)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PIC16AsmPrinter::printMachineInstruction(const MachineInstr *MI) {
|
||||
printInstruction(MI);
|
||||
return true;
|
||||
|
@ -65,18 +49,20 @@ bool PIC16AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
|
|||
|
||||
// Emit the function variables.
|
||||
emitFunctionData(MF);
|
||||
std::string codeSection;
|
||||
codeSection = "code." + CurrentFnName + ".# " + "CODE";
|
||||
const Section *fCodeSection = TAI->getNamedSection(codeSection.c_str(),
|
||||
SectionFlags::Code);
|
||||
const char *codeSection = PAN::getCodeSectionName(CurrentFnName).c_str();
|
||||
|
||||
const Section *fCodeSection = TAI->getNamedSection(codeSection,
|
||||
SectionFlags::Code);
|
||||
O << "\n";
|
||||
// Start the Code Section.
|
||||
SwitchToSection (fCodeSection);
|
||||
|
||||
// Emit the frame address of the function at the beginning of code.
|
||||
O << " retlw low(" << FunctionLabelBegin<< CurrentFnName << ".frame.)\n";
|
||||
O << " retlw high(" << FunctionLabelBegin<< CurrentFnName << ".frame.)\n";
|
||||
O << CurrentFnName << ":\n";
|
||||
O << "\tretlw low(" << PAN::getFrameLabel(CurrentFnName) << ")\n";
|
||||
O << "\tretlw high(" << PAN::getFrameLabel(CurrentFnName) << ")\n";
|
||||
|
||||
// Emit function start label.
|
||||
O << CurrentFnName << ":\n";
|
||||
|
||||
// Print out code for the function.
|
||||
for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
|
||||
|
@ -136,19 +122,12 @@ void PIC16AsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
|
|||
return;
|
||||
|
||||
case MachineOperand::MO_GlobalAddress: {
|
||||
std::string Name = Mang->getValueName(MO.getGlobal());
|
||||
if (isLocalName(Name))
|
||||
O << FunctionLabelBegin << Mang->getValueName(MO.getGlobal());
|
||||
else
|
||||
O << Mang->getValueName(MO.getGlobal());
|
||||
O << Mang->getValueName(MO.getGlobal());
|
||||
break;
|
||||
}
|
||||
case MachineOperand::MO_ExternalSymbol: {
|
||||
std::string Name = MO.getSymbolName();
|
||||
if (Name.find("__intrinsics.") != std::string::npos)
|
||||
O << MO.getSymbolName();
|
||||
else
|
||||
O << FunctionLabelBegin << MO.getSymbolName();
|
||||
O << MO.getSymbolName();
|
||||
break;
|
||||
}
|
||||
case MachineOperand::MO_MachineBasicBlock:
|
||||
|
@ -189,41 +168,44 @@ void PIC16AsmPrinter::EmitExternsAndGlobals (Module &M) {
|
|||
O << "section.0" <<"\n";
|
||||
for (Module::iterator I = M.begin(), E = M.end(); I != E; I++) {
|
||||
std::string Name = Mang->getValueName(I);
|
||||
if (Name.compare("abort") == 0)
|
||||
if (Name.compare("@abort") == 0)
|
||||
continue;
|
||||
|
||||
// If it is llvm intrinsic call then don't emit
|
||||
if (Name.find("llvm.") != std::string::npos)
|
||||
continue;
|
||||
|
||||
if (I->isDeclaration()) {
|
||||
O << "\textern " <<Name << "\n";
|
||||
O << "\textern " << FunctionLabelBegin << Name << ".ret.\n";
|
||||
O << "\textern " << FunctionLabelBegin << Name << ".args.\n";
|
||||
}
|
||||
else if (I->hasExternalLinkage()) {
|
||||
O << "\tglobal " << Name << "\n";
|
||||
O << "\tglobal " << FunctionLabelBegin << Name << ".ret.\n";
|
||||
O << "\tglobal " << FunctionLabelBegin<< Name << ".args.\n";
|
||||
}
|
||||
assert ((I->isDeclaration() || I->hasExternalLinkage())
|
||||
&& "Not an extern function declaration or definition");
|
||||
|
||||
const char *directive = I->isDeclaration() ? TAI->getExternDirective() :
|
||||
TAI->getGlobalDirective();
|
||||
|
||||
O << directive << Name << "\n";
|
||||
O << directive << PAN::getRetvalLabel(Name) << "\n";
|
||||
O << directive << PAN::getArgsLabel(Name) << "\n";
|
||||
}
|
||||
|
||||
// Emit header file to include declaration of library functions
|
||||
// FIXME: find out libcall names.
|
||||
O << "\t#include C16IntrinsicCalls.INC\n";
|
||||
|
||||
// Emit declarations for external globals.
|
||||
// Emit declarations for external variable declarations and definitions.
|
||||
for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
|
||||
I != E; I++) {
|
||||
// Any variables reaching here with ".auto." in its name is a local scope
|
||||
// variable and should not be printed in global data section.
|
||||
std::string Name = Mang->getValueName(I);
|
||||
if (isLocalName (Name))
|
||||
if (PAN::isLocalName(Name))
|
||||
continue;
|
||||
|
||||
if (I->isDeclaration())
|
||||
O << "\textern "<< Name << "\n";
|
||||
else if (I->hasCommonLinkage() || I->hasExternalLinkage())
|
||||
O << "\tglobal "<< Name << "\n";
|
||||
if (!(I->isDeclaration() || I->hasExternalLinkage() ||
|
||||
I->hasCommonLinkage()))
|
||||
continue;
|
||||
|
||||
const char *directive = I->isDeclaration() ? TAI->getExternDirective() :
|
||||
TAI->getGlobalDirective();
|
||||
O << directive << Name << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -247,7 +229,7 @@ void PIC16AsmPrinter::EmitRomData (Module &M)
|
|||
// Any variables reaching here with "." in its name is a local scope
|
||||
// variable and should not be printed in global data section.
|
||||
std::string name = Mang->getValueName(I);
|
||||
if (name.find(".") != std::string::npos)
|
||||
if (PAN::isLocalName(name))
|
||||
continue;
|
||||
|
||||
I->setSection(TAI->getReadOnlySection()->getName());
|
||||
|
@ -273,15 +255,14 @@ void PIC16AsmPrinter::emitFunctionData(MachineFunction &MF) {
|
|||
unsigned FrameSize = 0;
|
||||
// Emit the data section name.
|
||||
O << "\n";
|
||||
std::string SectionName = "fpdata." + CurrentFnName + ".# " + "UDATA_OVR";
|
||||
const char *SectionName = PAN::getFrameSectionName(CurrentFnName).c_str();
|
||||
|
||||
const Section *fPDataSection = TAI->getNamedSection(SectionName.c_str(),
|
||||
const Section *fPDataSection = TAI->getNamedSection(SectionName,
|
||||
SectionFlags::Writeable);
|
||||
SwitchToSection(fPDataSection);
|
||||
|
||||
|
||||
// Emit function frame label
|
||||
O << FunctionLabelBegin << CurrentFnName << ".frame.:\n";
|
||||
O << PAN::getFrameLabel(CurrentFnName) << ":\n";
|
||||
|
||||
const Type *RetType = F->getReturnType();
|
||||
unsigned RetSize = 0;
|
||||
|
@ -289,11 +270,13 @@ void PIC16AsmPrinter::emitFunctionData(MachineFunction &MF) {
|
|||
RetSize = TD->getTypeAllocSize(RetType);
|
||||
|
||||
//Emit function return value space
|
||||
// FIXME: Do not emit RetvalLable when retsize is zero. To do this
|
||||
// we will need to avoid printing a global directive for Retval label
|
||||
// in emitExternandGloblas.
|
||||
if(RetSize > 0)
|
||||
O << FunctionLabelBegin << CurrentFnName << ".ret. RES " << RetSize
|
||||
<< "\n";
|
||||
O << PAN::getRetvalLabel(CurrentFnName) << " RES " << RetSize << "\n";
|
||||
else
|
||||
O << FunctionLabelBegin << CurrentFnName << ".ret.:\n";
|
||||
O << PAN::getRetvalLabel(CurrentFnName) << ": \n";
|
||||
|
||||
// Emit variable to hold the space for function arguments
|
||||
unsigned ArgSize = 0;
|
||||
|
@ -302,20 +285,19 @@ void PIC16AsmPrinter::emitFunctionData(MachineFunction &MF) {
|
|||
const Type *Ty = argi->getType();
|
||||
ArgSize += TD->getTypeAllocSize(Ty);
|
||||
}
|
||||
O << FunctionLabelBegin << CurrentFnName << ".args. RES " << ArgSize
|
||||
<< "\n";
|
||||
|
||||
O << PAN::getArgsLabel(CurrentFnName) << " RES " << ArgSize << "\n";
|
||||
|
||||
// Emit temporary space
|
||||
int TempSize = PTLI->GetTmpSize();
|
||||
if (TempSize > 0 )
|
||||
O << FunctionLabelBegin << CurrentFnName << ".temp. RES " << TempSize
|
||||
<<"\n";
|
||||
O << PAN::getTempdataLabel(CurrentFnName) << " RES " << TempSize <<"\n";
|
||||
|
||||
// Emit the section name for local variables.
|
||||
O << "\n";
|
||||
std::string SecNameLocals = "fadata." + CurrentFnName + ".# " + "UDATA_OVR";
|
||||
const char* SecNameLocals = PAN::getAutosSectionName(CurrentFnName).c_str() ;
|
||||
|
||||
const Section *fADataSection = TAI->getNamedSection(SecNameLocals.c_str(),
|
||||
const Section *fADataSection = TAI->getNamedSection(SecNameLocals,
|
||||
SectionFlags::Writeable);
|
||||
SwitchToSection(fADataSection);
|
||||
|
||||
|
@ -334,26 +316,32 @@ void PIC16AsmPrinter::emitFunctionData(MachineFunction &MF) {
|
|||
// Static local varilabes of a function does not have .auto. in their
|
||||
// name. They are not printed as part of function data but module
|
||||
// level global data.
|
||||
if (! isLocalToFunc(FuncName, VarName))
|
||||
if (! PAN::isLocalToFunc(FuncName, VarName))
|
||||
continue;
|
||||
|
||||
I->setSection("fadata." + CurrentFnName + ".#");
|
||||
I->setSection(TAI->SectionForGlobal(I)->getName());
|
||||
Constant *C = I->getInitializer();
|
||||
const Type *Ty = C->getType();
|
||||
unsigned Size = TD->getTypeAllocSize(Ty);
|
||||
FrameSize += Size;
|
||||
// Emit memory reserve directive.
|
||||
O << FunctionLabelBegin << VarName << " RES " << Size << "\n";
|
||||
O << VarName << " RES " << Size << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
void PIC16AsmPrinter::EmitGlobalData (Module &M)
|
||||
{
|
||||
// Set the section names for all globals.
|
||||
for (Module::global_iterator I = M.global_begin(), E = M.global_end();
|
||||
I != E; ++I) {
|
||||
I->setSection(TAI->SectionForGlobal(I)->getName());
|
||||
}
|
||||
|
||||
const PIC16TargetAsmInfo *PTAI = static_cast<const PIC16TargetAsmInfo *>(TAI);
|
||||
const_cast<PIC16TargetAsmInfo *>(PTAI)->SetSectionForGVs(M);
|
||||
const TargetData *TD = TM.getTargetData();
|
||||
|
||||
std::vector <PIC16Section *>IDATASections = PTAI->getIDATASections();
|
||||
// Now print all IDATA sections.
|
||||
std::vector <PIC16Section *>IDATASections = PTAI->IDATASections;
|
||||
for (unsigned i = 0; i < IDATASections.size(); i++) {
|
||||
SwitchToSection(IDATASections[i]->S_);
|
||||
std::vector<const GlobalVariable*> Items = IDATASections[i]->Items;
|
||||
|
@ -366,7 +354,8 @@ void PIC16AsmPrinter::EmitGlobalData (Module &M)
|
|||
}
|
||||
}
|
||||
|
||||
std::vector <PIC16Section *>BSSSections = PTAI->getBSSSections();
|
||||
// Now print all BSS sections.
|
||||
std::vector <PIC16Section *>BSSSections = PTAI->BSSSections;
|
||||
for (unsigned i = 0; i < BSSSections.size(); i++) {
|
||||
SwitchToSection(BSSSections[i]->S_);
|
||||
std::vector<const GlobalVariable*> Items = BSSSections[i]->Items;
|
||||
|
|
|
@ -23,12 +23,10 @@
|
|||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include <cstdio>
|
||||
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
|
||||
// PIC16TargetLowering Constructor.
|
||||
PIC16TargetLowering::PIC16TargetLowering(PIC16TargetMachine &TM)
|
||||
: TargetLowering(TM), TmpSize(0) {
|
||||
|
@ -41,24 +39,24 @@ PIC16TargetLowering::PIC16TargetLowering(PIC16TargetMachine &TM)
|
|||
setShiftAmountFlavor(Extend);
|
||||
|
||||
// SRA library call names
|
||||
setPIC16LibcallName(PIC16ISD::SRA_I8, "__intrinsics.sra.i8");
|
||||
setLibcallName(RTLIB::SRA_I16, "__intrinsics.sra.i16");
|
||||
setLibcallName(RTLIB::SRA_I32, "__intrinsics.sra.i32");
|
||||
setPIC16LibcallName(PIC16ISD::SRA_I8, "@__intrinsics.sra.i8");
|
||||
setLibcallName(RTLIB::SRA_I16, "@__intrinsics.sra.i16");
|
||||
setLibcallName(RTLIB::SRA_I32, "@__intrinsics.sra.i32");
|
||||
|
||||
// SHL library call names
|
||||
setPIC16LibcallName(PIC16ISD::SLL_I8, "__intrinsics.sll.i8");
|
||||
setLibcallName(RTLIB::SHL_I16, "__intrinsics.sll.i16");
|
||||
setLibcallName(RTLIB::SHL_I32, "__intrinsics.sll.i32");
|
||||
setPIC16LibcallName(PIC16ISD::SLL_I8, "@__intrinsics.sll.i8");
|
||||
setLibcallName(RTLIB::SHL_I16, "@__intrinsics.sll.i16");
|
||||
setLibcallName(RTLIB::SHL_I32, "@__intrinsics.sll.i32");
|
||||
|
||||
// SRL library call names
|
||||
setPIC16LibcallName(PIC16ISD::SRL_I8, "__intrinsics.srl.i8");
|
||||
setLibcallName(RTLIB::SRL_I16, "__intrinsics.srl.i16");
|
||||
setLibcallName(RTLIB::SRL_I32, "__intrinsics.srl.i32");
|
||||
setPIC16LibcallName(PIC16ISD::SRL_I8, "@__intrinsics.srl.i8");
|
||||
setLibcallName(RTLIB::SRL_I16, "@__intrinsics.srl.i16");
|
||||
setLibcallName(RTLIB::SRL_I32, "@__intrinsics.srl.i32");
|
||||
|
||||
// MUL Library call names
|
||||
setPIC16LibcallName(PIC16ISD::MUL_I8, "__intrinsics.mul.i8");
|
||||
setLibcallName(RTLIB::MUL_I16, "__intrinsics.mul.i16");
|
||||
setLibcallName(RTLIB::MUL_I32, "__intrinsics.mul.i32");
|
||||
setPIC16LibcallName(PIC16ISD::MUL_I8, "@__intrinsics.mul.i8");
|
||||
setLibcallName(RTLIB::MUL_I16, "@__intrinsics.mul.i16");
|
||||
setLibcallName(RTLIB::MUL_I32, "@__intrinsics.mul.i32");
|
||||
|
||||
setOperationAction(ISD::GlobalAddress, MVT::i16, Custom);
|
||||
setOperationAction(ISD::ExternalSymbol, MVT::i16, Custom);
|
||||
|
@ -529,9 +527,9 @@ PIC16TargetLowering::LegalizeFrameIndex(SDValue Op, SelectionDAG &DAG,
|
|||
// with, we need to traverse all the FrameIndices available earlier in
|
||||
// the list and add their requested size.
|
||||
unsigned FIndex = FR->getIndex();
|
||||
char *tmpName = new char [strlen(Name.c_str()) + 8];
|
||||
const char *tmpName;
|
||||
if (FIndex < ReservedFrameCount) {
|
||||
sprintf(tmpName, "%s.frame.", Name.c_str());
|
||||
tmpName = createESName(PAN::getFrameLabel(Name));
|
||||
ES = DAG.getTargetExternalSymbol(tmpName, MVT::i8);
|
||||
Offset = 0;
|
||||
for (unsigned i=0; i<FIndex ; ++i) {
|
||||
|
@ -539,7 +537,7 @@ PIC16TargetLowering::LegalizeFrameIndex(SDValue Op, SelectionDAG &DAG,
|
|||
}
|
||||
} else {
|
||||
// FrameIndex has been made for some temporary storage
|
||||
sprintf(tmpName, "%s.temp.", Name.c_str());
|
||||
tmpName = createESName(PAN::getTempdataLabel(Name));
|
||||
ES = DAG.getTargetExternalSymbol(tmpName, MVT::i8);
|
||||
Offset = GetTmpOffsetForFI(FIndex, MFI->getObjectSize(FIndex));
|
||||
}
|
||||
|
@ -845,12 +843,11 @@ SDValue PIC16TargetLowering::ConvertToMemOperand(SDValue Op,
|
|||
const Function *Func = MF.getFunction();
|
||||
const std::string FuncName = Func->getName();
|
||||
|
||||
char *tmpName = new char [strlen(FuncName.c_str()) + 8];
|
||||
|
||||
// Put the value on stack.
|
||||
// Get a stack slot index and convert to es.
|
||||
int FI = MF.getFrameInfo()->CreateStackObject(1, 1);
|
||||
sprintf(tmpName, "%s.temp.", FuncName.c_str());
|
||||
const char *tmpName = createESName(PAN::getTempdataLabel(FuncName));
|
||||
SDValue ES = DAG.getTargetExternalSymbol(tmpName, MVT::i8);
|
||||
|
||||
// Store the value to ES.
|
||||
|
@ -1064,8 +1061,7 @@ SDValue PIC16TargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG) {
|
|||
const Function *F = MF.getFunction();
|
||||
std::string FuncName = F->getName();
|
||||
|
||||
char *tmpName = new char [strlen(FuncName.c_str()) + 8];
|
||||
sprintf(tmpName, "%s.frame.", FuncName.c_str());
|
||||
const char *tmpName = createESName(PAN::getFrameLabel(FuncName));
|
||||
SDVTList VTs = DAG.getVTList (MVT::i8, MVT::Other);
|
||||
SDValue ES = DAG.getTargetExternalSymbol(tmpName, MVT::i8);
|
||||
SDValue BS = DAG.getConstant(1, MVT::i8);
|
||||
|
@ -1258,13 +1254,11 @@ SDValue PIC16TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) {
|
|||
}
|
||||
|
||||
// Label for argument passing
|
||||
char *argFrame = new char [strlen(Name.c_str()) + 8];
|
||||
sprintf(argFrame, "%s.args.", Name.c_str());
|
||||
const char *argFrame = createESName(PAN::getArgsLabel(Name));
|
||||
ArgLabel = DAG.getTargetExternalSymbol(argFrame, MVT::i8);
|
||||
|
||||
// Label for reading return value
|
||||
char *retName = new char [strlen(Name.c_str()) + 8];
|
||||
sprintf(retName, "%s.ret.", Name.c_str());
|
||||
const char *retName = createESName(PAN::getRetvalLabel(Name));
|
||||
RetLabel = DAG.getTargetExternalSymbol(retName, MVT::i8);
|
||||
} else {
|
||||
// if indirect call
|
||||
|
@ -1460,8 +1454,7 @@ SDValue PIC16TargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op,
|
|||
InitReservedFrameCount(F);
|
||||
|
||||
// Create the <fname>.args external symbol.
|
||||
char *tmpName = new char [strlen(FuncName.c_str()) + 8];
|
||||
sprintf(tmpName, "%s.args.", FuncName.c_str());
|
||||
const char *tmpName = createESName(PAN::getArgsLabel(FuncName));
|
||||
SDValue ES = DAG.getTargetExternalSymbol(tmpName, MVT::i8);
|
||||
|
||||
// Load arg values from the label + offset.
|
||||
|
|
|
@ -76,8 +76,7 @@ void PIC16InstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
|
|||
const Function *Func = MBB.getParent()->getFunction();
|
||||
const std::string FuncName = Func->getName();
|
||||
|
||||
char *tmpName = new char [strlen(FuncName.c_str()) + 10];
|
||||
sprintf(tmpName, "%s.temp.", FuncName.c_str());
|
||||
const char *tmpName = createESName(PAN::getTempdataLabel(FuncName));
|
||||
|
||||
// On the order of operands here: think "movwf SrcReg, tmp_slot, offset".
|
||||
if (RC == PIC16::GPRRegisterClass) {
|
||||
|
@ -119,8 +118,7 @@ void PIC16InstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
|
|||
const Function *Func = MBB.getParent()->getFunction();
|
||||
const std::string FuncName = Func->getName();
|
||||
|
||||
char *tmpName = new char [strlen(FuncName.c_str()) + 10];
|
||||
sprintf(tmpName, "%s.temp.", FuncName.c_str());
|
||||
const char *tmpName = createESName(PAN::getTempdataLabel(FuncName));
|
||||
|
||||
// On the order of operands here: think "movf FrameIndex, W".
|
||||
if (RC == PIC16::GPRRegisterClass) {
|
||||
|
|
|
@ -145,7 +145,7 @@ bool MemSelOpt::processInstruction(MachineInstr *MI) {
|
|||
// External Symbol is generated for temp data and arguments. They are
|
||||
// in fpdata.<functionname>.# section.
|
||||
std::string Sym = Op.getSymbolName();
|
||||
NewBank = PIC16ABINames::getSectionNameForSym(Sym);
|
||||
NewBank = PAN::getSectionNameForSym(Sym);
|
||||
}
|
||||
|
||||
// If the previous and new section names are same, we don't need to
|
||||
|
|
|
@ -23,6 +23,10 @@ PIC16TargetAsmInfo::
|
|||
PIC16TargetAsmInfo(const PIC16TargetMachine &TM)
|
||||
: TargetAsmInfo(TM) {
|
||||
CommentString = ";";
|
||||
GlobalPrefix = PAN::getTagName(PAN::PREFIX_SYMBOL);
|
||||
GlobalDirective = "\tglobal\t";
|
||||
ExternDirective = "\textern\t";
|
||||
|
||||
Data8bitsDirective = " db ";
|
||||
Data16bitsDirective = " dw ";
|
||||
Data32bitsDirective = " dl ";
|
||||
|
@ -86,9 +90,8 @@ PIC16TargetAsmInfo::getBSSSectionForGlobal(const GlobalVariable *GV) const {
|
|||
|
||||
// No BSS section spacious enough was found. Crate a new one.
|
||||
if (! FoundBSS) {
|
||||
char *name = new char[32];
|
||||
sprintf (name, "udata.%d.# UDATA", (int)BSSSections.size());
|
||||
const Section *NewSection = getNamedSection (name);
|
||||
std::string name = PAN::getUdataSectionName(BSSSections.size());
|
||||
const Section *NewSection = getNamedSection (name.c_str());
|
||||
|
||||
FoundBSS = new PIC16Section(NewSection);
|
||||
|
||||
|
@ -132,9 +135,8 @@ PIC16TargetAsmInfo::getIDATASectionForGlobal(const GlobalVariable *GV) const {
|
|||
|
||||
// No IDATA section spacious enough was found. Crate a new one.
|
||||
if (! FoundIDATA) {
|
||||
char *name = new char[32];
|
||||
sprintf (name, "idata.%d.# IDATA", (int)IDATASections.size());
|
||||
const Section *NewSection = getNamedSection (name);
|
||||
std::string name = PAN::getIdataSectionName(IDATASections.size());
|
||||
const Section *NewSection = getNamedSection (name.c_str());
|
||||
|
||||
FoundIDATA = new PIC16Section(NewSection);
|
||||
|
||||
|
@ -158,19 +160,20 @@ const Section*
|
|||
PIC16TargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV1) const {
|
||||
// We select the section based on the initializer here, so it really
|
||||
// has to be a GlobalVariable.
|
||||
if (!isa<GlobalVariable>(GV1))
|
||||
const GlobalVariable *GV = dyn_cast<GlobalVariable>(GV1);
|
||||
if (!GV1 || ! GV->hasInitializer())
|
||||
return TargetAsmInfo::SelectSectionForGlobal(GV1);
|
||||
|
||||
const GlobalVariable *GV = dyn_cast<GlobalVariable>(GV1);
|
||||
// We are only dealing with true globals here. So names with a "."
|
||||
// are local globals. Also declarations are not entertained.
|
||||
std::string name = GV->getName();
|
||||
if (name.find(".auto.") != std::string::npos
|
||||
|| name.find(".arg.") != std::string::npos || !GV->hasInitializer())
|
||||
return TargetAsmInfo::SelectSectionForGlobal(GV);
|
||||
// First, if this is an automatic variable for a function, get the section
|
||||
// name for it and return.
|
||||
const std::string name = GV->getName();
|
||||
if (PAN::isLocalName(name)) {
|
||||
const std::string Sec_Name = PAN::getSectionNameForSym(name);
|
||||
return getNamedSection(Sec_Name.c_str());
|
||||
}
|
||||
|
||||
const Constant *C = GV->getInitializer();
|
||||
// See if this is an uninitialized global.
|
||||
const Constant *C = GV->getInitializer();
|
||||
if (C->isNullValue())
|
||||
return getBSSSectionForGlobal(GV);
|
||||
|
||||
|
@ -178,30 +181,11 @@ PIC16TargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV1) const {
|
|||
if (GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE)
|
||||
return getIDATASectionForGlobal(GV);
|
||||
|
||||
|
||||
// Else let the default implementation take care of it.
|
||||
return TargetAsmInfo::SelectSectionForGlobal(GV);
|
||||
}
|
||||
|
||||
void PIC16TargetAsmInfo::SetSectionForGVs(Module &M) {
|
||||
for (Module::global_iterator I = M.global_begin(), E = M.global_end();
|
||||
I != E; ++I) {
|
||||
if (!I->hasInitializer()) // External global require no code.
|
||||
continue;
|
||||
|
||||
// Any variables reaching here with "." in its name is a local scope
|
||||
// variable and should not be printed in global data section.
|
||||
std::string name = I->getName();
|
||||
if (name.find(".auto.") != std::string::npos
|
||||
|| name.find(".args.") != std::string::npos)
|
||||
continue;
|
||||
int AddrSpace = I->getType()->getAddressSpace();
|
||||
|
||||
if (AddrSpace == PIC16ISD::RAM_SPACE)
|
||||
I->setSection(SectionForGlobal(I)->getName());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PIC16TargetAsmInfo::~PIC16TargetAsmInfo() {
|
||||
|
||||
for (unsigned i = 0; i < BSSSections.size(); i++) {
|
||||
|
|
|
@ -41,11 +41,11 @@ namespace llvm {
|
|||
struct PIC16TargetAsmInfo : public TargetAsmInfo {
|
||||
std::string getSectionNameForSym(const std::string &Sym) const;
|
||||
PIC16TargetAsmInfo(const PIC16TargetMachine &TM);
|
||||
virtual ~PIC16TargetAsmInfo();
|
||||
private:
|
||||
mutable std::vector<PIC16Section *> BSSSections;
|
||||
mutable std::vector<PIC16Section *> IDATASections;
|
||||
|
||||
virtual ~PIC16TargetAsmInfo();
|
||||
|
||||
private:
|
||||
const char *RomData8bitsDirective;
|
||||
const char *RomData16bitsDirective;
|
||||
const char *RomData32bitsDirective;
|
||||
|
|
Loading…
Reference in New Issue