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.

llvm-svn: 71423
This commit is contained in:
Sanjiv Gupta 2009-05-11 06:01:38 +00:00
parent aeec9d53ce
commit 9d175c15e7
4 changed files with 43 additions and 10 deletions

View File

@ -114,7 +114,7 @@ namespace PIC16CC {
case TEMPS_LABEL: return ".temp."; case TEMPS_LABEL: return ".temp.";
case ARGS_LABEL: return ".args."; case ARGS_LABEL: return ".args.";
case RET_LABEL: return ".ret."; case RET_LABEL: return ".ret.";
case LIBCALL: return ".lib."; case LIBCALL: return "__intrinsics";
case FRAME_SECTION: return ".fpdata."; case FRAME_SECTION: return ".fpdata.";
case AUTOS_SECTION: return ".fadata."; case AUTOS_SECTION: return ".fadata.";
case CODE_SECTION: return "code"; case CODE_SECTION: return "code";
@ -234,6 +234,12 @@ namespace PIC16CC {
return o.str(); return o.str();
} }
static std::string getDeclSectionName(void) {
std::string dsname = "decl_section.1";
dsname = addPrefix(dsname);
return dsname;
}
inline static bool isLocalName (const std::string &Name) { inline static bool isLocalName (const std::string &Name) {
if (getSymbolTag(Name) == AUTOS_LABEL) if (getSymbolTag(Name) == AUTOS_LABEL)
return true; return true;

View File

@ -87,6 +87,7 @@ bool PIC16AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
CurLine = line; CurLine = line;
} }
} }
// Print the assembly for the instruction. // Print the assembly for the instruction.
printMachineInstruction(II); printMachineInstruction(II);
} }
@ -106,6 +107,8 @@ FunctionPass *llvm::createPIC16CodePrinterPass(raw_ostream &o,
return new PIC16AsmPrinter(o, tm, tm.getTargetAsmInfo(), OptLevel, verbose); return new PIC16AsmPrinter(o, tm, tm.getTargetAsmInfo(), OptLevel, verbose);
} }
// printOperand - print operand of insn.
void PIC16AsmPrinter::printOperand(const MachineInstr *MI, int opNum) { void PIC16AsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
const MachineOperand &MO = MI->getOperand(opNum); const MachineOperand &MO = MI->getOperand(opNum);
@ -126,8 +129,14 @@ void PIC16AsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
break; break;
} }
case MachineOperand::MO_ExternalSymbol: { case MachineOperand::MO_ExternalSymbol: {
std::string Name = MO.getSymbolName(); const char *Sname = MO.getSymbolName();
O << 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; break;
} }
case MachineOperand::MO_MachineBasicBlock: case MachineOperand::MO_MachineBasicBlock:
@ -144,6 +153,23 @@ void PIC16AsmPrinter::printCCOperand(const MachineInstr *MI, int opNum) {
O << PIC16CondCodeToString((PIC16CC::CondCodes)CC); 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 PIC16AsmPrinter::doInitialization (Module &M) {
bool Result = AsmPrinter::doInitialization(M); bool Result = AsmPrinter::doInitialization(M);
@ -188,7 +214,7 @@ void PIC16AsmPrinter::EmitExternsAndGlobals (Module &M) {
// Emit header file to include declaration of library functions // Emit header file to include declaration of library functions
// FIXME: find out libcall names. // 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. // Emit declarations for external variable declarations and definitions.
for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
@ -212,7 +238,6 @@ void PIC16AsmPrinter::EmitExternsAndGlobals (Module &M) {
void PIC16AsmPrinter::EmitRomData (Module &M) void PIC16AsmPrinter::EmitRomData (Module &M)
{ {
SwitchToSection(TAI->getReadOnlySection()); SwitchToSection(TAI->getReadOnlySection());
IsRomData = true;
for (Module::global_iterator I = M.global_begin(), E = M.global_end(); for (Module::global_iterator I = M.global_begin(), E = M.global_end();
I != E; ++I) { I != E; ++I) {
if (!I->hasInitializer()) // External global require no code. if (!I->hasInitializer()) // External global require no code.
@ -238,10 +263,10 @@ void PIC16AsmPrinter::EmitRomData (Module &M)
O << "\n"; O << "\n";
} }
} }
IsRomData = false;
} }
bool PIC16AsmPrinter::doFinalization(Module &M) { bool PIC16AsmPrinter::doFinalization(Module &M) {
printDecls();
O << "\t" << "END\n"; O << "\t" << "END\n";
bool Result = AsmPrinter::doFinalization(M); bool Result = AsmPrinter::doFinalization(M);
return Result; return Result;

View File

@ -21,6 +21,8 @@
#include "llvm/Support/CommandLine.h" #include "llvm/Support/CommandLine.h"
#include "llvm/Target/TargetAsmInfo.h" #include "llvm/Target/TargetAsmInfo.h"
#include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetMachine.h"
#include <list>
#include <string>
namespace llvm { namespace llvm {
struct VISIBILITY_HIDDEN PIC16AsmPrinter : public AsmPrinter { struct VISIBILITY_HIDDEN PIC16AsmPrinter : public AsmPrinter {
@ -28,8 +30,6 @@ namespace llvm {
const TargetAsmInfo *T, CodeGenOpt::Level OL, const TargetAsmInfo *T, CodeGenOpt::Level OL,
bool V) bool V)
: AsmPrinter(O, TM, T, OL, V) { : AsmPrinter(O, TM, T, OL, V) {
FunctionLabelBegin = '@';
IsRomData = false;
PTLI = TM.getTargetLowering(); PTLI = TM.getTargetLowering();
} }
private : private :
@ -46,6 +46,7 @@ namespace llvm {
void EmitGlobalData (Module &M); void EmitGlobalData (Module &M);
void EmitRomData (Module &M); void EmitRomData (Module &M);
void emitFunctionData(MachineFunction &MF); void emitFunctionData(MachineFunction &MF);
void printDecls(void);
protected: protected:
bool doInitialization(Module &M); bool doInitialization(Module &M);
@ -53,8 +54,7 @@ namespace llvm {
private: private:
PIC16TargetLowering *PTLI; PIC16TargetLowering *PTLI;
bool IsRomData; std::list<const char *> Decls; // List of extern decls.
char FunctionLabelBegin;
}; };
} // end of namespace } // end of namespace

View File

@ -137,6 +137,8 @@ bool MemSelOpt::processInstruction(MachineInstr *MI) {
} }
// Get the section name(NewBank) for MemOp. // Get the section name(NewBank) for MemOp.
// This assumes that the section names for globals are laready set by
// AsmPrinter->doInitialization.
std::string NewBank = CurBank; std::string NewBank = CurBank;
if (Op.getType() == MachineOperand::MO_GlobalAddress && if (Op.getType() == MachineOperand::MO_GlobalAddress &&
Op.getGlobal()->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE) { Op.getGlobal()->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE) {