aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/Target/PIC16/PIC16AsmPrinter.cpp99
-rw-r--r--lib/Target/PIC16/PIC16AsmPrinter.h8
-rw-r--r--lib/Target/PIC16/PIC16DebugInfo.cpp132
-rw-r--r--lib/Target/PIC16/PIC16DebugInfo.h23
-rw-r--r--lib/Target/PIC16/PIC16TargetAsmInfo.cpp3
5 files changed, 195 insertions, 70 deletions
diff --git a/lib/Target/PIC16/PIC16AsmPrinter.cpp b/lib/Target/PIC16/PIC16AsmPrinter.cpp
index 738723b..ef3bc4b 100644
--- a/lib/Target/PIC16/PIC16AsmPrinter.cpp
+++ b/lib/Target/PIC16/PIC16AsmPrinter.cpp
@@ -48,7 +48,12 @@ bool PIC16AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
CurrentFnName = Mang->getValueName(F);
// Emit the function variables.
- emitFunctionData(MF);
+ EmitFunctionFrame(MF);
+
+ // Emit function begin debug directives
+ DbgInfo.EmitFunctBeginDI(F);
+
+ EmitAutos(CurrentFnName);
const char *codeSection = PAN::getCodeSectionName(CurrentFnName).c_str();
const Section *fCodeSection = TAI->getNamedSection(codeSection,
@@ -64,6 +69,10 @@ bool PIC16AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
// Emit function start label.
O << CurrentFnName << ":\n";
+ // For emitting line directives, we need to keep track of the current
+ // source line. When it changes then only emit the line directive.
+ unsigned CurLine = 0;
+ O << "\n";
// Print out code for the function.
for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
I != E; ++I) {
@@ -73,9 +82,6 @@ bool PIC16AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
O << '\n';
}
- // For emitting line directives, we need to keep track of the current
- // source line. When it changes then only emit the line directive.
- unsigned CurLine = 0;
for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
II != E; ++II) {
// Emit the line directive if source line changed.
@@ -92,6 +98,9 @@ bool PIC16AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
printMachineInstruction(II);
}
}
+
+ // Emit function end debug directives.
+ DbgInfo.EmitFunctEndDI(F, CurLine);
return false; // we didn't modify anything.
}
@@ -172,10 +181,12 @@ void PIC16AsmPrinter::printLibcallDecls(void) {
bool PIC16AsmPrinter::doInitialization (Module &M) {
bool Result = AsmPrinter::doInitialization(M);
+ DbgInfo.EmitFileDirective(M);
+
// FIXME:: This is temporary solution to generate the include file.
// The processor should be passed to llc as in input and the header file
// should be generated accordingly.
- O << "\t#include P16F1937.INC\n";
+ O << "\n\t#include P16F1937.INC\n";
MachineModuleInfo *MMI = getAnalysisIfAvailable<MachineModuleInfo>();
assert(MMI);
DwarfWriter *DW = getAnalysisIfAvailable<DwarfWriter>();
@@ -194,7 +205,7 @@ bool PIC16AsmPrinter::doInitialization (Module &M) {
EmitIData(M);
EmitUData(M);
EmitRomData(M);
- EmitAutos(M);
+ DbgInfo.PopulateFunctsDI(M);
return Result;
}
@@ -273,14 +284,14 @@ void PIC16AsmPrinter::EmitRomData (Module &M)
bool PIC16AsmPrinter::doFinalization(Module &M) {
printLibcallDecls();
- EmitVarDebugInfo(M);
- O << "\t" << ".EOF\n";
- O << "\t" << "END\n";
+ DbgInfo.EmitVarDebugInfo(M);
+ O << "\n\t" << ".EOF";
+ O << "\n\t" << "END\n";
bool Result = AsmPrinter::doFinalization(M);
return Result;
}
-void PIC16AsmPrinter::emitFunctionData(MachineFunction &MF) {
+void PIC16AsmPrinter::EmitFunctionFrame(MachineFunction &MF) {
const Function *F = MF.getFunction();
std::string FuncName = Mang->getValueName(F);
const TargetData *TD = TM.getTargetData();
@@ -364,70 +375,30 @@ void PIC16AsmPrinter::EmitUData (Module &M) {
}
}
-void PIC16AsmPrinter::EmitAutos (Module &M)
+void PIC16AsmPrinter::EmitAutos (std::string FunctName)
{
// Section names for all globals are already set.
const TargetData *TD = TM.getTargetData();
- // Now print all Autos sections.
+ // Now print Autos section for this function.
+ std::string SectionName = PAN::getAutosSectionName(FunctName);
std::vector <PIC16Section *>AutosSections = PTAI->AutosSections;
for (unsigned i = 0; i < AutosSections.size(); i++) {
O << "\n";
- SwitchToSection(AutosSections[i]->S_);
- std::vector<const GlobalVariable*> Items = AutosSections[i]->Items;
- for (unsigned j = 0; j < Items.size(); j++) {
- std::string VarName = Mang->getValueName(Items[j]);
- Constant *C = Items[j]->getInitializer();
- const Type *Ty = C->getType();
- unsigned Size = TD->getTypeAllocSize(Ty);
- // Emit memory reserve directive.
- O << VarName << " RES " << Size << "\n";
- }
- }
-}
-
-void PIC16AsmPrinter::EmitVarDebugInfo(Module &M) {
- GlobalVariable *Root = M.getGlobalVariable("llvm.dbg.global_variables");
- if (!Root)
- return;
-
- O << TAI->getCommentString() << " Debug Information:";
- Constant *RootC = cast<Constant>(*Root->use_begin());
- for (Value::use_iterator UI = RootC->use_begin(), UE = Root->use_end();
- UI != UE; ++UI) {
- for (Value::use_iterator UUI = UI->use_begin(), UUE = UI->use_end();
- UUI != UUE; ++UUI) {
- DIGlobalVariable DIGV(cast<GlobalVariable>(*UUI));
- DIType Ty = DIGV.getType();
- unsigned short TypeNo = 0;
- bool HasAux = false;
- int Aux[20] = { 0 };
- std::string TypeName = "";
- std::string VarName = TAI->getGlobalPrefix()+DIGV.getGlobal()->getName();
- DbgInfo.PopulateDebugInfo(Ty, TypeNo, HasAux, Aux, TypeName);
- // Emit debug info only if type information is availaible.
- if (TypeNo != PIC16Dbg::T_NULL) {
- O << "\n\t.type " << VarName << ", " << TypeNo;
- short ClassNo = DbgInfo.getClass(DIGV);
- O << "\n\t.class " << VarName << ", " << ClassNo;
- if (HasAux) {
- if (TypeName != "") {
- // Emit debug info for structure and union objects after
- // .dim directive supports structure/union tag name in aux entry.
- /* O << "\n\t.dim " << VarName << ", 1," << TypeName;
- for (int i = 0; i<20; i++)
- O << "," << Aux[i];*/
- }
- else {
- O << "\n\t.dim " << VarName << ", 1" ;
- for (int i = 0; i<20; i++)
- O << "," << Aux[i];
- }
- }
+ if (AutosSections[i]->S_->getName() == SectionName) {
+ SwitchToSection(AutosSections[i]->S_);
+ std::vector<const GlobalVariable*> Items = AutosSections[i]->Items;
+ for (unsigned j = 0; j < Items.size(); j++) {
+ std::string VarName = Mang->getValueName(Items[j]);
+ Constant *C = Items[j]->getInitializer();
+ const Type *Ty = C->getType();
+ unsigned Size = TD->getTypeAllocSize(Ty);
+ // Emit memory reserve directive.
+ O << VarName << " RES " << Size << "\n";
}
+ break;
}
}
- O << "\n";
}
diff --git a/lib/Target/PIC16/PIC16AsmPrinter.h b/lib/Target/PIC16/PIC16AsmPrinter.h
index adcd64d..2545dfd 100644
--- a/lib/Target/PIC16/PIC16AsmPrinter.h
+++ b/lib/Target/PIC16/PIC16AsmPrinter.h
@@ -32,7 +32,7 @@ namespace llvm {
explicit PIC16AsmPrinter(raw_ostream &O, PIC16TargetMachine &TM,
const TargetAsmInfo *T, CodeGenOpt::Level OL,
bool V)
- : AsmPrinter(O, TM, T, OL, V) {
+ : AsmPrinter(O, TM, T, OL, V), DbgInfo(O,T) {
PTLI = TM.getTargetLowering();
PTAI = static_cast<const PIC16TargetAsmInfo *> (T);
}
@@ -51,12 +51,10 @@ namespace llvm {
void EmitDefinedVars (Module &M);
void EmitIData (Module &M);
void EmitUData (Module &M);
- void EmitAutos (Module &M);
+ void EmitAutos (std::string FunctName);
void EmitRomData (Module &M);
- void emitFunctionData(MachineFunction &MF);
+ void EmitFunctionFrame(MachineFunction &MF);
void printLibcallDecls(void);
- void EmitVarDebugInfo (Module &M);
-
protected:
bool doInitialization(Module &M);
bool doFinalization(Module &M);
diff --git a/lib/Target/PIC16/PIC16DebugInfo.cpp b/lib/Target/PIC16/PIC16DebugInfo.cpp
index 166d96e..4d43811 100644
--- a/lib/Target/PIC16/PIC16DebugInfo.cpp
+++ b/lib/Target/PIC16/PIC16DebugInfo.cpp
@@ -14,9 +14,17 @@
#include "PIC16.h"
#include "PIC16DebugInfo.h"
#include "llvm/GlobalVariable.h"
+#include "llvm/Support/raw_ostream.h"
using namespace llvm;
+PIC16DbgInfo::~PIC16DbgInfo() {
+ for(std::map<std::string, DISubprogram *>::iterator i = FunctNameMap.begin();
+ i!=FunctNameMap.end(); i++)
+ delete i->second;
+ FunctNameMap.clear();
+}
+
void PIC16DbgInfo::PopulateDebugInfo(DIType Ty, unsigned short &TypeNo,
bool &HasAux, int Aux[],
std::string &TypeName) {
@@ -136,3 +144,127 @@ short PIC16DbgInfo::getClass(DIGlobalVariable DIGV) {
ClassNo = PIC16Dbg::C_EXT;
return ClassNo;
}
+
+void PIC16DbgInfo::PopulateFunctsDI(Module &M) {
+ GlobalVariable *Root = M.getGlobalVariable("llvm.dbg.subprograms");
+ if (!Root)
+ return;
+ Constant *RootC = cast<Constant>(*Root->use_begin());
+
+ for (Value::use_iterator UI = RootC->use_begin(), UE = Root->use_end();
+ UI != UE; ++UI)
+ for (Value::use_iterator UUI = UI->use_begin(), UUE = UI->use_end();
+ UUI != UUE; ++UUI) {
+ GlobalVariable *GVSP = cast<GlobalVariable>(*UUI);
+ DISubprogram *SP = new DISubprogram(GVSP);
+ std::string Name;
+ SP->getLinkageName(Name);
+ FunctNameMap[Name] = SP;
+ }
+ return;
+}
+
+DISubprogram* PIC16DbgInfo::getFunctDI(std::string FunctName) {
+ return FunctNameMap[FunctName];
+}
+
+void PIC16DbgInfo::EmitFunctBeginDI(const Function *F) {
+ std::string FunctName = F->getName();
+ DISubprogram *SP = getFunctDI(FunctName);
+ if (SP) {
+ std::string FunctBeginSym = ".bf." + FunctName;
+ std::string BlockBeginSym = ".bb." + FunctName;
+
+ int FunctBeginLine = SP->getLineNumber();
+ int BFAux[PIC16Dbg::AuxSize] = {0};
+ BFAux[4] = FunctBeginLine;
+ BFAux[5] = FunctBeginLine >> 8;
+ // Emit debug directives for beginning of function.
+ EmitSymbol(FunctBeginSym, PIC16Dbg::C_FCN);
+ EmitAuxEntry(FunctBeginSym, BFAux, PIC16Dbg::AuxSize);
+ EmitSymbol(BlockBeginSym, PIC16Dbg::C_BLOCK);
+ EmitAuxEntry(BlockBeginSym, BFAux, PIC16Dbg::AuxSize);
+ }
+}
+
+void PIC16DbgInfo::EmitFunctEndDI(const Function *F, unsigned Line) {
+ std::string FunctName = F->getName();
+ DISubprogram *SP = getFunctDI(FunctName);
+ if (SP) {
+ std::string FunctEndSym = ".ef." + FunctName;
+ std::string BlockEndSym = ".eb." + FunctName;
+
+ // Emit debug directives for end of function.
+ EmitSymbol(BlockEndSym, PIC16Dbg::C_BLOCK);
+ int EFAux[PIC16Dbg::AuxSize] = {0};
+ // 5th and 6th byte stand for line number.
+ EFAux[4] = Line;
+ EFAux[5] = Line >> 8;
+ EmitAuxEntry(BlockEndSym, EFAux, PIC16Dbg::AuxSize);
+ EmitSymbol(FunctEndSym, PIC16Dbg::C_FCN);
+ EmitAuxEntry(FunctEndSym, EFAux, PIC16Dbg::AuxSize);
+ }
+}
+
+/// EmitAuxEntry - Emit Auxiliary debug information.
+///
+void PIC16DbgInfo::EmitAuxEntry(const std::string VarName, int Aux[], int num) {
+ O << "\n\t.dim " << VarName << ", 1" ;
+ for (int i = 0; i<num; i++)
+ O << "," << Aux[i];
+}
+
+void PIC16DbgInfo::EmitSymbol(std::string Name, int Class) {
+ O << "\n\t" << ".def "<< Name << ", debug, class = " << Class;
+}
+
+void PIC16DbgInfo::EmitVarDebugInfo(Module &M) {
+ GlobalVariable *Root = M.getGlobalVariable("llvm.dbg.global_variables");
+ if (!Root)
+ return;
+
+ Constant *RootC = cast<Constant>(*Root->use_begin());
+ for (Value::use_iterator UI = RootC->use_begin(), UE = Root->use_end();
+ UI != UE; ++UI) {
+ for (Value::use_iterator UUI = UI->use_begin(), UUE = UI->use_end();
+ UUI != UUE; ++UUI) {
+ DIGlobalVariable DIGV(cast<GlobalVariable>(*UUI));
+ DIType Ty = DIGV.getType();
+ unsigned short TypeNo = 0;
+ bool HasAux = false;
+ int Aux[PIC16Dbg::AuxSize] = { 0 };
+ std::string TypeName = "";
+ std::string VarName = TAI->getGlobalPrefix()+DIGV.getGlobal()->getName();
+ PopulateDebugInfo(Ty, TypeNo, HasAux, Aux, TypeName);
+ // Emit debug info only if type information is availaible.
+ if (TypeNo != PIC16Dbg::T_NULL) {
+ O << "\n\t.type " << VarName << ", " << TypeNo;
+ short ClassNo = getClass(DIGV);
+ O << "\n\t.class " << VarName << ", " << ClassNo;
+ if (HasAux) {
+ if (TypeName != "") {
+ // Emit debug info for structure and union objects after
+ // .dim directive supports structure/union tag name in aux entry.
+ /* O << "\n\t.dim " << VarName << ", 1," << TypeName;
+ for (int i = 0; i<PIC16Dbg::AuxSize; i++)
+ O << "," << Aux[i];*/
+ }
+ else {
+ EmitAuxEntry(VarName, Aux, PIC16Dbg::AuxSize);
+ }
+ }
+ }
+ }
+ }
+ O << "\n";
+}
+
+void PIC16DbgInfo::EmitFileDirective(Module &M) {
+ GlobalVariable *CU = M.getNamedGlobal("llvm.dbg.compile_unit");
+ if (CU) {
+ DICompileUnit DIUnit(CU);
+ std::string Dir, FN;
+ O << "\n\t.file\t\"" << DIUnit.getDirectory(Dir) <<"/"
+ << DIUnit.getFilename(FN) << "\"" ;
+ }
+}
diff --git a/lib/Target/PIC16/PIC16DebugInfo.h b/lib/Target/PIC16/PIC16DebugInfo.h
index 582d821..96b23da 100644
--- a/lib/Target/PIC16/PIC16DebugInfo.h
+++ b/lib/Target/PIC16/PIC16DebugInfo.h
@@ -14,7 +14,10 @@
#ifndef PIC16DBG_H
#define PIC16DBG_H
-#include "llvm/Analysis/DebugInfo.h"
+#include "llvm/Analysis/DebugInfo.h"
+#include "llvm/Module.h"
+#include "llvm/Target/TargetAsmInfo.h"
+#include <map>
namespace llvm {
namespace PIC16Dbg {
@@ -80,14 +83,32 @@ namespace llvm {
C_SECTION,
C_EFCN = 255
};
+ enum SymbolSize {
+ AuxSize =20
+ };
}
+ class raw_ostream;
+
class PIC16DbgInfo {
+ std::map <std::string, DISubprogram *> FunctNameMap;
+ raw_ostream &O;
+ const TargetAsmInfo *TAI;
public:
+ PIC16DbgInfo(raw_ostream &o, const TargetAsmInfo *T) : O(o), TAI(T) {}
+ ~PIC16DbgInfo();
void PopulateDebugInfo(DIType Ty, unsigned short &TypeNo, bool &HasAux,
int Aux[], std::string &TypeName);
unsigned GetTypeDebugNumber(std::string &type);
short getClass(DIGlobalVariable DIGV);
+ void PopulateFunctsDI(Module &M);
+ DISubprogram *getFunctDI(std::string FunctName);
+ void EmitFunctBeginDI(const Function *F);
+ void EmitFunctEndDI(const Function *F, unsigned Line);
+ void EmitAuxEntry(const std::string VarName, int Aux[], int num);
+ inline void EmitSymbol(std::string Name, int Class);
+ void EmitVarDebugInfo(Module &M);
+ void EmitFileDirective(Module &M);
};
} // end namespace llvm;
#endif
diff --git a/lib/Target/PIC16/PIC16TargetAsmInfo.cpp b/lib/Target/PIC16/PIC16TargetAsmInfo.cpp
index 9d7592a..d2657f0 100644
--- a/lib/Target/PIC16/PIC16TargetAsmInfo.cpp
+++ b/lib/Target/PIC16/PIC16TargetAsmInfo.cpp
@@ -47,6 +47,9 @@ PIC16TargetAsmInfo(const PIC16TargetMachine &TM)
ROSection = new PIC16Section(getReadOnlySection());
ExternalVarDecls = new PIC16Section(getNamedSection("ExternalVarDecls"));
ExternalVarDefs = new PIC16Section(getNamedSection("ExternalVarDefs"));
+ // Set it to false because we weed to generate c file name and not bc file
+ // name.
+ HasSingleParameterDotFile = false;
}
const char *PIC16TargetAsmInfo::getRomDirective(unsigned size) const