Detect calls to compiler intrinsics and emit an extern declarations
only for those. These extern declarations to intrinsics are currently
being emitted at the bottom of generated .s file, which works fine with
gpasm(not sure about MPSAM though).
PIC16 linker generates errors for few cases (function-args/struct_args_5) if you do not include any
extern declarations (even if no intrinsics are being used), but that
needs to be fixed in the linker itself.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@71423 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/PIC16/PIC16AsmPrinter.cpp b/lib/Target/PIC16/PIC16AsmPrinter.cpp
index 1aebe09..f88d9e7 100644
--- a/lib/Target/PIC16/PIC16AsmPrinter.cpp
+++ b/lib/Target/PIC16/PIC16AsmPrinter.cpp
@@ -87,6 +87,7 @@
CurLine = line;
}
}
+
// Print the assembly for the instruction.
printMachineInstruction(II);
}
@@ -106,6 +107,8 @@
return new PIC16AsmPrinter(o, tm, tm.getTargetAsmInfo(), OptLevel, verbose);
}
+
+// printOperand - print operand of insn.
void PIC16AsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
const MachineOperand &MO = MI->getOperand(opNum);
@@ -126,8 +129,14 @@
break;
}
case MachineOperand::MO_ExternalSymbol: {
- std::string Name = MO.getSymbolName();
- O << MO.getSymbolName();
+ const char *Sname = MO.getSymbolName();
+
+ // If its a libcall name, record it to decls section.
+ if (PAN::getSymbolTag(Sname) == PAN::LIBCALL) {
+ Decls.push_back(Sname);
+ }
+
+ O << Sname;
break;
}
case MachineOperand::MO_MachineBasicBlock:
@@ -144,6 +153,23 @@
O << PIC16CondCodeToString((PIC16CC::CondCodes)CC);
}
+void PIC16AsmPrinter::printDecls(void) {
+ // If no libcalls used, return.
+ if (Decls.empty()) return;
+
+ const Section *S = TAI->getNamedSection(PAN::getDeclSectionName().c_str());
+ SwitchToSection(S);
+ // Remove duplicate entries.
+ Decls.sort();
+ Decls.unique();
+ for (std::list<const char*>::const_iterator I = Decls.begin();
+ I != Decls.end(); I++) {
+ O << TAI->getExternDirective() << *I << "\n";
+ // FIXME: Use PAN::getXXXLabel() funtions hrer.
+ O << TAI->getExternDirective() << *I << ".args." << "\n";
+ O << TAI->getExternDirective() << *I << ".ret." << "\n";
+ }
+}
bool PIC16AsmPrinter::doInitialization (Module &M) {
bool Result = AsmPrinter::doInitialization(M);
@@ -188,7 +214,7 @@
// Emit header file to include declaration of library functions
// FIXME: find out libcall names.
- O << "\t#include C16IntrinsicCalls.INC\n";
+ // O << "\t#include C16IntrinsicCalls.INC\n";
// Emit declarations for external variable declarations and definitions.
for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
@@ -212,7 +238,6 @@
void PIC16AsmPrinter::EmitRomData (Module &M)
{
SwitchToSection(TAI->getReadOnlySection());
- IsRomData = true;
for (Module::global_iterator I = M.global_begin(), E = M.global_end();
I != E; ++I) {
if (!I->hasInitializer()) // External global require no code.
@@ -238,10 +263,10 @@
O << "\n";
}
}
- IsRomData = false;
}
bool PIC16AsmPrinter::doFinalization(Module &M) {
+ printDecls();
O << "\t" << "END\n";
bool Result = AsmPrinter::doFinalization(M);
return Result;