aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Target/PIC16/Makefile21
-rw-r--r--lib/Target/PIC16/PIC16.h38
-rw-r--r--lib/Target/PIC16/PIC16.td46
-rw-r--r--lib/Target/PIC16/PIC16AsmPrinter.cpp569
-rw-r--r--lib/Target/PIC16/PIC16CallingConv.td17
-rw-r--r--lib/Target/PIC16/PIC16ConstantPoolValue.cpp88
-rw-r--r--lib/Target/PIC16/PIC16ConstantPoolValue.h75
-rw-r--r--lib/Target/PIC16/PIC16ISelDAGToDAG.cpp291
-rw-r--r--lib/Target/PIC16/PIC16ISelLowering.cpp801
-rw-r--r--lib/Target/PIC16/PIC16ISelLowering.h92
-rw-r--r--lib/Target/PIC16/PIC16InstrFormats.td112
-rw-r--r--lib/Target/PIC16/PIC16InstrInfo.cpp143
-rw-r--r--lib/Target/PIC16/PIC16InstrInfo.h78
-rw-r--r--lib/Target/PIC16/PIC16InstrInfo.td302
-rw-r--r--lib/Target/PIC16/PIC16RegisterInfo.cpp223
-rw-r--r--lib/Target/PIC16/PIC16RegisterInfo.h86
-rw-r--r--lib/Target/PIC16/PIC16RegisterInfo.td84
-rw-r--r--lib/Target/PIC16/PIC16Subtarget.cpp27
-rw-r--r--lib/Target/PIC16/PIC16Subtarget.h41
-rw-r--r--lib/Target/PIC16/PIC16TargetAsmInfo.cpp26
-rw-r--r--lib/Target/PIC16/PIC16TargetAsmInfo.h30
-rw-r--r--lib/Target/PIC16/PIC16TargetMachine.cpp72
-rw-r--r--lib/Target/PIC16/PIC16TargetMachine.h61
23 files changed, 3323 insertions, 0 deletions
diff --git a/lib/Target/PIC16/Makefile b/lib/Target/PIC16/Makefile
new file mode 100644
index 0000000000..c429324cc2
--- /dev/null
+++ b/lib/Target/PIC16/Makefile
@@ -0,0 +1,21 @@
+##===- lib/Target/PIC16/Makefile ---------------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+LEVEL = ../../..
+LIBRARYNAME = LLVMPIC16
+TARGET = PIC16
+
+# Make sure that tblgen is run, first thing.
+BUILT_SOURCES = PIC16GenRegisterInfo.h.inc PIC16GenRegisterNames.inc \
+ PIC16GenRegisterInfo.inc PIC16GenInstrNames.inc \
+ PIC16GenInstrInfo.inc PIC16GenAsmWriter.inc \
+ PIC16GenDAGISel.inc PIC16GenCallingConv.inc \
+ PIC16GenSubtarget.inc
+
+include $(LEVEL)/Makefile.common
+
diff --git a/lib/Target/PIC16/PIC16.h b/lib/Target/PIC16/PIC16.h
new file mode 100644
index 0000000000..5c2a4cce82
--- /dev/null
+++ b/lib/Target/PIC16/PIC16.h
@@ -0,0 +1,38 @@
+//===-- PIC16.h - Top-level interface for PIC16 representation --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Bruno Cardoso Lopes and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the entry points for global functions defined in
+// the LLVM PIC16 back-end.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TARGET_PIC16_H
+#define TARGET_PIC16_H
+
+#include <iosfwd>
+
+namespace llvm {
+ class PIC16TargetMachine;
+ class FunctionPassManager;
+ class FunctionPass;
+ class MachineCodeEmitter;
+
+ FunctionPass *createPIC16ISelDag(PIC16TargetMachine &TM);
+ FunctionPass *createPIC16CodePrinterPass(std::ostream &OS,
+ PIC16TargetMachine &TM);
+} // end namespace llvm;
+
+// Defines symbolic names for PIC16 registers. This defines a mapping from
+// register name to register number.
+#include "PIC16GenRegisterNames.inc"
+
+// Defines symbolic names for the PIC16 instructions.
+#include "PIC16GenInstrNames.inc"
+
+#endif
diff --git a/lib/Target/PIC16/PIC16.td b/lib/Target/PIC16/PIC16.td
new file mode 100644
index 0000000000..0ab4a3444f
--- /dev/null
+++ b/lib/Target/PIC16/PIC16.td
@@ -0,0 +1,46 @@
+//===- PIC16.td - Describe the PIC16 Target Machine -----------*- tblgen -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// This is the top level entry point for the PIC16 target.
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Target-independent interfaces
+//===----------------------------------------------------------------------===//
+
+include "../Target.td"
+
+//===----------------------------------------------------------------------===//
+// Descriptions
+//===----------------------------------------------------------------------===//
+
+include "PIC16RegisterInfo.td"
+include "PIC16CallingConv.td"
+include "PIC16InstrInfo.td"
+
+def PIC16InstrInfo : InstrInfo {
+ let TSFlagsFields = [];
+ let TSFlagsShifts = [];
+}
+
+
+
+// Not currently supported, but work as SubtargetFeature placeholder.
+def FeaturePIC16Old : SubtargetFeature<"pic16old", "IsPIC16Old", "true",
+ "PIC16 Old ISA Support">;
+
+//===----------------------------------------------------------------------===//
+// PIC16 processors supported.
+//===----------------------------------------------------------------------===//
+
+def : Processor<"generic", NoItineraries, []>;
+
+def PIC16 : Target {
+ let InstructionSet = PIC16InstrInfo;
+}
+
diff --git a/lib/Target/PIC16/PIC16AsmPrinter.cpp b/lib/Target/PIC16/PIC16AsmPrinter.cpp
new file mode 100644
index 0000000000..151fafc4c5
--- /dev/null
+++ b/lib/Target/PIC16/PIC16AsmPrinter.cpp
@@ -0,0 +1,569 @@
+//===-- PIC16AsmPrinter.cpp - PIC16 LLVM assembly writer ------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains a printer that converts from our internal representation
+// of machine-dependent LLVM code to PIC16 assembly language.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "asm-printer"
+#include "PIC16.h"
+#include "PIC16TargetMachine.h"
+#include "PIC16ConstantPoolValue.h"
+#include "PIC16InstrInfo.h"
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Module.h"
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/CodeGen/AsmPrinter.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineConstantPool.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/Mangler.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Target/TargetAsmInfo.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetOptions.h"
+#include <cctype>
+
+using namespace llvm;
+
+STATISTIC(EmittedInsts, "Number of machine instrs printed");
+
+namespace {
+ struct VISIBILITY_HIDDEN PIC16AsmPrinter : public AsmPrinter {
+ PIC16AsmPrinter(std::ostream &O, TargetMachine &TM, const TargetAsmInfo *T)
+ : AsmPrinter(O, TM, T) {
+ }
+
+
+ /// We name each basic block in a Function with a unique number, so
+ /// that we can consistently refer to them later. This is cleared
+ /// at the beginning of each call to runOnMachineFunction().
+ ///
+ typedef std::map<const Value *, unsigned> ValueMapTy;
+ ValueMapTy NumberForBB;
+
+ /// Keeps the set of GlobalValues that require non-lazy-pointers for
+ /// indirect access.
+ std::set<std::string> GVNonLazyPtrs;
+
+ /// Keeps the set of external function GlobalAddresses that the asm
+ /// printer should generate stubs for.
+ std::set<std::string> FnStubs;
+
+ /// True if asm printer is printing a series of CONSTPOOL_ENTRY.
+ bool InCPMode;
+
+ virtual const char *getPassName() const {
+ return "PIC16 Assembly Printer";
+ }
+
+ void printOperand(const MachineInstr *MI, int opNum,
+ const char *Modifier = 0);
+
+ void printSOImmOperand(const MachineInstr *MI, int opNum);
+
+ void printAddrModeOperand(const MachineInstr *MI, int OpNo);
+
+ void printRegisterList(const MachineInstr *MI, int opNum);
+ void printCPInstOperand(const MachineInstr *MI, int opNum,
+ const char *Modifier);
+
+
+ bool printInstruction(const MachineInstr *MI); // autogenerated.
+ void emitFunctionStart(MachineFunction &F);
+ bool runOnMachineFunction(MachineFunction &F);
+ bool doInitialization(Module &M);
+ bool doFinalization(Module &M);
+
+ virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV);
+
+ void getAnalysisUsage(AnalysisUsage &AU) const;
+
+ public:
+ void SwitchToTextSection(const char *NewSection,
+ const GlobalValue *GV = NULL);
+ void SwitchToDataSection(const char *NewSection,
+ const GlobalValue *GV = NULL);
+ void SwitchToDataOvrSection(const char *NewSection,
+ const GlobalValue *GV = NULL);
+ };
+} // end of anonymous namespace
+
+#include "PIC16GenAsmWriter.inc"
+
+/// createPIC16CodePrinterPass - Returns a pass that prints the PIC16
+/// assembly code for a MachineFunction to the given output stream,
+/// using the given target machine description. This should work
+/// regardless of whether the function is in SSA form.
+///
+FunctionPass *llvm::createPIC16CodePrinterPass(std::ostream &o,
+ PIC16TargetMachine &tm) {
+ return new PIC16AsmPrinter(o, tm, tm.getTargetAsmInfo());
+}
+
+void PIC16AsmPrinter::getAnalysisUsage(AnalysisUsage &AU) const
+{
+ // Currently unimplemented.
+}
+
+
+void PIC16AsmPrinter ::
+EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV)
+{
+ printDataDirective(MCPV->getType());
+
+ PIC16ConstantPoolValue *ACPV = (PIC16ConstantPoolValue*)MCPV;
+ GlobalValue *GV = ACPV->getGV();
+ std::string Name = GV ? Mang->getValueName(GV) : TAI->getGlobalPrefix();
+ if (!GV)
+ Name += ACPV->getSymbol();
+ if (ACPV->isNonLazyPointer()) {
+ GVNonLazyPtrs.insert(Name);
+ O << TAI->getPrivateGlobalPrefix() << Name << "$non_lazy_ptr";
+ } else if (ACPV->isStub()) {
+ FnStubs.insert(Name);
+ O << TAI->getPrivateGlobalPrefix() << Name << "$stub";
+ } else
+ O << Name;
+ if (ACPV->hasModifier()) O << "(" << ACPV->getModifier() << ")";
+
+ if (ACPV->getPCAdjustment() != 0) {
+ O << "-(" << TAI->getPrivateGlobalPrefix() << "PC"
+ << utostr(ACPV->getLabelId())
+ << "+" << (unsigned)ACPV->getPCAdjustment();
+
+ if (ACPV->mustAddCurrentAddress())
+ O << "-.";
+
+ O << ")";
+ }
+ O << "\n";
+
+ // If the constant pool value is a extern weak symbol, remember to emit
+ // the weak reference.
+ if (GV && GV->hasExternalWeakLinkage())
+ ExtWeakSymbols.insert(GV);
+}
+
+/// Emit the directives used by ASM on the start of functions
+void PIC16AsmPrinter:: emitFunctionStart(MachineFunction &MF)
+{
+ // Print out the label for the function.
+ const Function *F = MF.getFunction();
+ MachineFrameInfo *FrameInfo = MF.getFrameInfo();
+ if (FrameInfo->hasStackObjects()) {
+ int indexBegin = FrameInfo->getObjectIndexBegin();
+ int indexEnd = FrameInfo->getObjectIndexEnd();
+ while (indexBegin<indexEnd) {
+ if (indexBegin ==0)
+ SwitchToDataOvrSection(F->getParent()->getModuleIdentifier().c_str(),
+ F);
+
+ O << "\t\t" << CurrentFnName << "_" << indexBegin << " " << "RES"
+ << " " << FrameInfo->getObjectSize(indexBegin) << "\n" ;
+ indexBegin++;
+ }
+ }
+ SwitchToTextSection(CurrentFnName.c_str(), F);
+ O << "_" << CurrentFnName << ":" ;
+ O << "\n";
+}
+
+
+/// runOnMachineFunction - This uses the printInstruction()
+/// method to print assembly for each instruction.
+///
+bool PIC16AsmPrinter::
+runOnMachineFunction(MachineFunction &MF)
+{
+
+ // DW.SetModuleInfo(&getAnalysis<MachineModuleInfo>());
+ SetupMachineFunction(MF);
+ O << "\n";
+
+ // NOTE: we don't print out constant pools here, they are handled as
+ // instructions.
+ O << "\n";
+
+ // What's my mangled name?
+ CurrentFnName = Mang->getValueName(MF.getFunction());
+
+ // Emit the function start directives
+ emitFunctionStart(MF);
+
+ // Emit pre-function debug information.
+ // DW.BeginFunction(&MF);
+
+ // Print out code for the function.
+ for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
+ I != E; ++I) {
+ // Print a label for the basic block.
+ if (I != MF.begin()) {
+ printBasicBlockLabel(I, true);
+ O << '\n';
+ }
+ for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
+ II != E; ++II) {
+ // Print the assembly for the instruction.
+ O << '\t';
+ printInstruction(II);
+ ++EmittedInsts;
+ }
+ }
+
+ // Emit post-function debug information.
+ // DW.EndFunction();
+
+ // We didn't modify anything.
+ return false;
+}
+
+void PIC16AsmPrinter::
+printOperand(const MachineInstr *MI, int opNum, const char *Modifier)
+{
+ const MachineOperand &MO = MI->getOperand(opNum);
+ const TargetRegisterInfo &RI = *TM.getRegisterInfo();
+
+ switch (MO.getType())
+ {
+ case MachineOperand::MO_Register:
+ {
+ if (TargetRegisterInfo::isPhysicalRegister(MO.getReg()))
+ O << RI.get(MO.getReg()).Name;
+ else
+ assert(0 && "not implemented");
+ break;
+ }
+ case MachineOperand::MO_Immediate:
+ {
+ if (!Modifier || strcmp(Modifier, "no_hash") != 0)
+ O << "#";
+ O << (int)MO.getImm();
+ break;
+ }
+ case MachineOperand::MO_MachineBasicBlock:
+ {
+ printBasicBlockLabel(MO.getMBB());
+ return;
+ }
+ case MachineOperand::MO_GlobalAddress:
+ {
+ O << Mang->getValueName(MO.getGlobal())<<'+'<<MO.getOffset();
+ break;
+ }
+ case MachineOperand::MO_ExternalSymbol:
+ {
+ O << MO.getSymbolName();
+ break;
+ }
+ case MachineOperand::MO_ConstantPoolIndex:
+ {
+ O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
+ << '_' << MO.getIndex();
+ break;
+ }
+ case MachineOperand::MO_FrameIndex:
+ {
+ O << "_" << CurrentFnName
+ << '+' << MO.getIndex();
+ break;
+ }
+ case MachineOperand::MO_JumpTableIndex:
+ {
+ O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
+ << '_' << MO.getIndex();
+ break;
+ }
+ default:
+ {
+ O << "<unknown operand type>"; abort ();
+ break;
+ }
+ } // end switch.
+}
+
+static void
+printSOImm(std::ostream &O, int64_t V, const TargetAsmInfo *TAI)
+{
+ assert(V < (1 << 12) && "Not a valid so_imm value!");
+ unsigned Imm = V;
+
+ O << Imm;
+}
+
+/// printSOImmOperand - SOImm is 4-bit rotate amount in bits 8-11 with 8-bit
+/// immediate in bits 0-7.
+void PIC16AsmPrinter::
+printSOImmOperand(const MachineInstr *MI, int OpNum)
+{
+ const MachineOperand &MO = MI->getOperand(OpNum);
+ assert(MO.isImmediate() && "Not a valid so_imm value!");
+ printSOImm(O, MO.getImm(), TAI);
+}
+
+
+void PIC16AsmPrinter:: printAddrModeOperand(const MachineInstr *MI, int Op)
+{
+ const MachineOperand &MO1 = MI->getOperand(Op);
+ const MachineOperand &MO2 = MI->getOperand(Op+1);
+
+ if (MO2.isFrameIndex ()) {
+ printOperand(MI, Op+1);
+ return;
+ }
+
+ if (!MO1.isRegister()) { // FIXME: This is for CP entries, but isn't right.
+ printOperand(MI, Op);
+ return;
+ }
+
+ // If this is Stack Slot
+ if (MO1.isRegister()) {
+ if(strcmp(TM.getRegisterInfo()->get(MO1.getReg()).Name, "SP")==0)
+ {
+ O << CurrentFnName <<"_"<< MO2.getImm();
+ return;
+ }
+ O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).Name;
+ O << "+";
+ O << MO2.getImm();
+ O << "]";
+ return;
+ }
+
+ O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).Name;
+ O << "]";
+}
+
+
+void PIC16AsmPrinter:: printRegisterList(const MachineInstr *MI, int opNum)
+{
+ O << "{";
+ for (unsigned i = opNum, e = MI->getNumOperands(); i != e; ++i) {
+ printOperand(MI, i);
+ if (i != e-1) O << ", ";
+ }
+ O << "}";
+}
+
+void PIC16AsmPrinter::
+printCPInstOperand(const MachineInstr *MI, int OpNo, const char *Modifier)
+{
+ assert(Modifier && "This operand only works with a modifier!");
+
+ // There are two aspects to a CONSTANTPOOL_ENTRY operand, the label and the
+ // data itself.
+ if (!strcmp(Modifier, "label")) {
+ unsigned ID = MI->getOperand(OpNo).getImm();
+ O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
+ << '_' << ID << ":\n";
+ } else {
+ assert(!strcmp(Modifier, "cpentry") && "Unknown modifier for CPE");
+ unsigned CPI = MI->getOperand(OpNo).getIndex();
+
+ const MachineConstantPoolEntry &MCPE = // Chasing pointers is fun?
+ MI->getParent()->getParent()->getConstantPool()->getConstants()[CPI];
+
+ if (MCPE.isMachineConstantPoolEntry())
+ EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal);
+ else {
+ EmitGlobalConstant(MCPE.Val.ConstVal);
+ // remember to emit the weak reference
+ if (const GlobalValue *GV = dyn_cast<GlobalValue>(MCPE.Val.ConstVal))
+ if (GV->hasExternalWeakLinkage())
+ ExtWeakSymbols.insert(GV);
+ }
+ }
+}
+
+
+bool PIC16AsmPrinter:: doInitialization(Module &M)
+{
+ // Emit initial debug information.
+ // DW.BeginModule(&M);
+
+ bool Result = AsmPrinter::doInitialization(M);
+ return Result;
+}
+
+bool PIC16AsmPrinter:: doFinalization(Module &M)
+{
+ const TargetData *TD = TM.getTargetData();
+
+ for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
+ I != E; ++I) {
+ if (!I->hasInitializer()) // External global require no code
+ continue;
+
+ if (EmitSpecialLLVMGlobal(I)) {
+ continue;
+ }
+
+ std::string name = Mang->getValueName(I);
+ Constant *C = I->getInitializer();
+ const Type *Type = C->getType();
+ unsigned Size = TD->getABITypeSize(Type);
+ unsigned Align = TD->getPreferredAlignmentLog(I);
+
+ const char *VisibilityDirective = NULL;
+ if (I->hasHiddenVisibility())
+ VisibilityDirective = TAI->getHiddenDirective();
+ else if (I->hasProtectedVisibility())
+ VisibilityDirective = TAI->getProtectedDirective();
+
+ if (VisibilityDirective)
+ O << VisibilityDirective << name << "\n";
+
+ if (C->isNullValue()) {
+ if (I->hasExternalLinkage()) {
+ if (const char *Directive = TAI->getZeroFillDirective()) {
+ O << "\t.globl\t" << name << "\n";
+ O << Directive << "__DATA__, __common, " << name << ", "
+ << Size << ", " << Align << "\n";
+ continue;
+ }
+ }
+
+ if (!I->hasSection() &&
+ (I->hasInternalLinkage() || I->hasWeakLinkage() ||
+ I->hasLinkOnceLinkage())) {
+ if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
+ if (!NoZerosInBSS && TAI->getBSSSection())
+ SwitchToDataSection(M.getModuleIdentifier().c_str(), I);
+ else
+ SwitchToDataSection(TAI->getDataSection(), I);
+ if (TAI->getLCOMMDirective() != NULL) {
+ if (I->hasInternalLinkage()) {
+ O << TAI->getLCOMMDirective() << name << "," << Size;
+ } else
+ O << TAI->getCOMMDirective() << name << "," << Size;
+ } else {
+ if (I->hasInternalLinkage())
+ O << "\t.local\t" << name << "\n";
+
+ O << TAI->getCOMMDirective() <<"\t" << name << " " <<"RES"<< " "
+ << Size;
+ O << "\n\t\tGLOBAL" <<" "<< name;
+ if (TAI->getCOMMDirectiveTakesAlignment())
+ O << "," << (TAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
+ }
+ continue;
+ }
+ }
+
+ switch (I->getLinkage())
+ {
+ case GlobalValue::AppendingLinkage:
+ {
+ // FIXME: appending linkage variables should go into a section of
+ // their name or something. For now, just emit them as external.
+ // Fall through
+ }
+ case GlobalValue::ExternalLinkage:
+ {
+ O << "\t.globl " << name << "\n";
+ // FALL THROUGH
+ }
+ case GlobalValue::InternalLinkage:
+ {
+ if (I->isConstant()) {
+ const ConstantArray *CVA = dyn_cast<ConstantArray>(C);
+ if (TAI->getCStringSection() && CVA && CVA->isCString()) {
+ SwitchToDataSection(TAI->getCStringSection(), I);
+ break;
+ }
+ }
+ break;
+ }
+ default:
+ {
+ assert(0 && "Unknown linkage type!");
+ break;
+ }
+ } // end switch.
+
+ EmitAlignment(Align, I);
+ O << name << ":\t\t\t\t" << TAI->getCommentString() << " " << I->getName()
+ << "\n";
+
+ // If the initializer is a extern weak symbol, remember to emit the weak
+ // reference!
+ if (const GlobalValue *GV = dyn_cast<GlobalValue>(C))
+ if (GV->hasExternalWeakLinkage())
+ ExtWeakSymbols.insert(GV);
+
+ EmitGlobalConstant(C);
+ O << '\n';
+ } // end for.
+
+ O << "\n "<< "END";
+ return AsmPrinter::doFinalization(M);
+}
+
+void PIC16AsmPrinter::
+SwitchToTextSection(const char *NewSection, const GlobalValue *GV)
+{
+ O << "\n";
+ if (NewSection && *NewSection) {
+ std::string codeSection = "code_";
+ codeSection += NewSection;
+ codeSection += " ";
+ codeSection += "CODE";
+ AsmPrinter::SwitchToTextSection(codeSection.c_str(),GV);
+ }
+ else
+ AsmPrinter::SwitchToTextSection(NewSection,GV);
+}
+
+void PIC16AsmPrinter::
+SwitchToDataSection(const char *NewSection, const GlobalValue *GV)
+{
+ //Need to append index for page
+ O << "\n";
+ if (NewSection && *NewSection) {
+ std::string dataSection ="udata_";
+ dataSection+=NewSection;
+ if (dataSection.substr(dataSection.length()-2).compare(".o") == 0) {
+ dataSection = dataSection.substr(0,dataSection.length()-2);
+ }
+ dataSection += " ";
+ dataSection += "UDATA";
+ AsmPrinter::SwitchToDataSection(dataSection.c_str(),GV);
+ }
+ else
+ AsmPrinter::SwitchToDataSection(NewSection,GV);
+}
+
+void PIC16AsmPrinter::
+SwitchToDataOvrSection(const char *NewSection, const GlobalValue *GV)
+{
+ O << "\n";
+ if (NewSection && *NewSection) {
+ std::string dataSection = "frame_";
+ dataSection += NewSection;
+ if (dataSection.substr(dataSection.length()-2).compare(".o") == 0) {
+ dataSection = dataSection.substr(0,dataSection.length()-2);
+ }
+ dataSection += "_";
+ dataSection += CurrentFnName;
+ dataSection += " ";
+ dataSection += "UDATA_OVR";
+ AsmPrinter::SwitchToDataSection(dataSection.c_str(),GV);
+ }
+ else
+ AsmPrinter::SwitchToDataSection(NewSection,GV);
+}
diff --git a/lib/Target/PIC16/PIC16CallingConv.td b/lib/Target/PIC16/PIC16CallingConv.td
new file mode 100644
index 0000000000..bcd5f7c83d
--- /dev/null
+++ b/lib/Target/PIC16/PIC16CallingConv.td
@@ -0,0 +1,17 @@
+//===- PIC16CallingConv.td - Calling Conventions Sparc -----*- tablegen -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This describes the calling conventions for the PIC16 architectures.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Return Value Calling Conventions
+//===----------------------------------------------------------------------===//
+
diff --git a/lib/Target/PIC16/PIC16ConstantPoolValue.cpp b/lib/Target/PIC16/PIC16ConstantPoolValue.cpp
new file mode 100644
index 0000000000..6e324f9e4d
--- /dev/null
+++ b/lib/Target/PIC16/PIC16ConstantPoolValue.cpp
@@ -0,0 +1,88 @@
+//===- PIC16ConstantPoolValue.cpp - PIC16 constantpool value --------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the PIC16 specific constantpool value class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "PIC16ConstantPoolValue.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/GlobalValue.h"
+#include "llvm/Type.h"
+using namespace llvm;
+
+PIC16ConstantPoolValue::PIC16ConstantPoolValue(GlobalValue *gv, unsigned id,
+ PIC16CP::PIC16CPKind k,
+ unsigned char PCAdj,
+ const char *Modif, bool AddCA)
+ : MachineConstantPoolValue((const Type*)gv->getType()),
+ GV(gv), S(NULL), LabelId(id), Kind(k), PCAdjust(PCAdj),
+ Modifier(Modif), AddCurrentAddress(AddCA) {}
+
+PIC16ConstantPoolValue::PIC16ConstantPoolValue(const char *s, unsigned id,
+ PIC16CP::PIC16CPKind k,
+ unsigned char PCAdj,
+ const char *Modif, bool AddCA)
+ : MachineConstantPoolValue((const Type*)Type::Int32Ty),
+ GV(NULL), S(s), LabelId(id), Kind(k), PCAdjust(PCAdj),
+ Modifier(Modif), AddCurrentAddress(AddCA) {}
+
+PIC16ConstantPoolValue::PIC16ConstantPoolValue(GlobalValue *gv,
+ PIC16CP::PIC16CPKind k,
+ const char *Modif)
+ : MachineConstantPoolValue((const Type*)Type::Int32Ty),
+ GV(gv), S(NULL), LabelId(0), Kind(k), PCAdjust(0),
+ Modifier(Modif) {}
+
+int PIC16ConstantPoolValue::getExistingMachineCPValue(MachineConstantPool *CP,
+ unsigned Alignment) {
+ unsigned AlignMask = (1 << Alignment)-1;
+ const std::vector<MachineConstantPoolEntry> Constants = CP->getConstants();
+ for (unsigned i = 0, e = Constants.size(); i != e; ++i) {
+ if (Constants[i].isMachineConstantPoolEntry() &&
+ (Constants[i].Offset & AlignMask) == 0) {
+ PIC16ConstantPoolValue *CPV =
+ (PIC16ConstantPoolValue *)Constants[i].Val.MachineCPVal;
+ if (CPV->GV == GV &&
+ CPV->S == S &&
+ CPV->LabelId == LabelId &&
+ CPV->Kind == Kind &&
+ CPV->PCAdjust == PCAdjust)
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+void
+PIC16ConstantPoolValue::AddSelectionDAGCSEId(FoldingSetNodeID &ID) {
+ ID.AddPointer(GV);
+ ID.AddPointer(S);
+ ID.AddInteger(LabelId);
+ ID.AddInteger((unsigned)Kind);
+ ID.AddInteger(PCAdjust);
+}
+
+void PIC16ConstantPoolValue::print(std::ostream &O) const {
+ if (GV)
+ O << GV->getName();
+ else
+ O << S;
+ if (isNonLazyPointer()) O << "$non_lazy_ptr";
+ else if (isStub()) O << "$stub";
+ if (Modifier) O << "(" << Modifier << ")";
+ if (PCAdjust != 0) {
+ O << "-(LPIC" << LabelId << "+"
+ << (unsigned)PCAdjust;
+ if (AddCurrentAddress)
+ O << "-.";
+ O << ")";
+ }
+}
diff --git a/lib/Target/PIC16/PIC16ConstantPoolValue.h b/lib/Target/PIC16/PIC16ConstantPoolValue.h
new file mode 100644
index 0000000000..04d4a17e68
--- /dev/null
+++ b/lib/Target/PIC16/PIC16ConstantPoolValue.h
@@ -0,0 +1,75 @@
+//===- PIC16ConstantPoolValue.h - PIC16 constantpool value ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the PIC16 specific constantpool value class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_PIC16_CONSTANTPOOLVALUE_H
+#define LLVM_TARGET_PIC16_CONSTANTPOOLVALUE_H
+
+#include "llvm/CodeGen/MachineConstantPool.h"
+
+namespace llvm {
+
+namespace PIC16CP {
+ enum PIC16CPKind {
+ CPValue,
+ CPNonLazyPtr,
+ CPStub
+ };
+}
+
+/// PIC16ConstantPoolValue - PIC16 specific constantpool value. This is used to
+/// represent PC relative displacement between the address of the load
+/// instruction and the global value being loaded, i.e. (&GV-(LPIC+8)).
+class PIC16ConstantPoolValue : public MachineConstantPoolValue {
+ GlobalValue *GV; // GlobalValue being loaded.
+ const char *S; // ExtSymbol being loaded.
+ unsigned LabelId; // Label id of the load.
+ PIC16CP::PIC16CPKind Kind; // non_lazy_ptr or stub?
+ unsigned char PCAdjust; // Extra adjustment if constantpool is pc relative.
+ // 8 for PIC16
+ const char *Modifier; // GV modifier i.e. (&GV(modifier)-(LPIC+8))
+ bool AddCurrentAddress;
+
+public:
+ PIC16ConstantPoolValue(GlobalValue *gv, unsigned id,
+ PIC16CP::PIC16CPKind Kind = PIC16CP::CPValue,
+ unsigned char PCAdj = 0, const char *Modifier = NULL,
+ bool AddCurrentAddress = false);
+ PIC16ConstantPoolValue(const char *s, unsigned id,
+ PIC16CP::PIC16CPKind Kind = PIC16CP::CPValue,<