diff options
Diffstat (limited to 'lib/Target/PIC16')
44 files changed, 0 insertions, 7482 deletions
diff --git a/lib/Target/PIC16/AsmPrinter/CMakeLists.txt b/lib/Target/PIC16/AsmPrinter/CMakeLists.txt deleted file mode 100644 index d36bb8e..0000000 --- a/lib/Target/PIC16/AsmPrinter/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -include_directories( - ${CMAKE_CURRENT_BINARY_DIR}/.. - ${CMAKE_CURRENT_SOURCE_DIR}/.. - ) - -add_llvm_library(LLVMPIC16AsmPrinter - PIC16AsmPrinter.cpp - ) -add_dependencies(LLVMPIC16AsmPrinter PIC16CodeGenTable_gen) diff --git a/lib/Target/PIC16/AsmPrinter/Makefile b/lib/Target/PIC16/AsmPrinter/Makefile deleted file mode 100644 index e3c0684..0000000 --- a/lib/Target/PIC16/AsmPrinter/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -##===- lib/Target/PIC16/AsmPrinter/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 = LLVMPIC16AsmPrinter - -# Hack: we need to include 'main' pic16 target directory to grab private headers -CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/.. - -include $(LEVEL)/Makefile.common diff --git a/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.cpp b/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.cpp deleted file mode 100644 index b665817..0000000 --- a/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.cpp +++ /dev/null @@ -1,512 +0,0 @@ -//===-- 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. -// -//===----------------------------------------------------------------------===// - -#include "PIC16ABINames.h" -#include "PIC16AsmPrinter.h" -#include "PIC16Section.h" -#include "PIC16MCAsmInfo.h" -#include "PIC16MachineFunctionInfo.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Function.h" -#include "llvm/Module.h" -#include "llvm/CodeGen/MachineFrameInfo.h" -#include "llvm/CodeGen/MachineModuleInfo.h" -#include "llvm/MC/MCStreamer.h" -#include "llvm/MC/MCSymbol.h" -#include "llvm/Target/Mangler.h" -#include "llvm/Target/TargetRegistry.h" -#include "llvm/Target/TargetLoweringObjectFile.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/ADT/SmallString.h" -#include <cstring> -using namespace llvm; - -#include "PIC16GenAsmWriter.inc" - -PIC16AsmPrinter::PIC16AsmPrinter(TargetMachine &TM, MCStreamer &Streamer) -: AsmPrinter(TM, Streamer), DbgInfo(Streamer, TM.getMCAsmInfo()) { - PMAI = static_cast<const PIC16MCAsmInfo*>(TM.getMCAsmInfo()); - PTOF = &getObjFileLowering(); -} - -void PIC16AsmPrinter::EmitInstruction(const MachineInstr *MI) { - SmallString<128> Str; - raw_svector_ostream OS(Str); - printInstruction(MI, OS); - - OutStreamer.EmitRawText(OS.str()); -} - -static int getFunctionColor(const Function *F) { - if (F->hasSection()) { - std::string Sectn = F->getSection(); - std::string StrToFind = "Overlay="; - std::string::size_type Pos = Sectn.find(StrToFind); - - // Retreive the color number if the key is found. - if (Pos != std::string::npos) { - Pos += StrToFind.length(); - std::string Color = ""; - char c = Sectn.at(Pos); - // A Color can only consist of digits. - while (c >= '0' && c<= '9') { - Color.append(1,c); - Pos++; - if (Pos >= Sectn.length()) - break; - c = Sectn.at(Pos); - } - return atoi(Color.c_str()); - } - } - - // Color was not set for function, so return -1. - return -1; -} - -// Color the Auto section of the given function. -void PIC16AsmPrinter::ColorAutoSection(const Function *F) { - std::string SectionName = PAN::getAutosSectionName(CurrentFnSym->getName()); - PIC16Section* Section = PTOF->findPIC16Section(SectionName); - if (Section != NULL) { - int Color = getFunctionColor(F); - if (Color >= 0) - Section->setColor(Color); - } -} - - -/// runOnMachineFunction - This emits the frame section, autos section and -/// assembly for each instruction. Also takes care of function begin debug -/// directive and file begin debug directive (if required) for the function. -/// -bool PIC16AsmPrinter::runOnMachineFunction(MachineFunction &MF) { - // This calls the base class function required to be called at beginning - // of runOnMachineFunction. - SetupMachineFunction(MF); - - // Put the color information from function to its auto section. - const Function *F = MF.getFunction(); - ColorAutoSection(F); - - // Emit the function frame (args and temps). - EmitFunctionFrame(MF); - - DbgInfo.BeginFunction(MF); - - // Now emit the instructions of function in its code section. - const MCSection *fCodeSection = - getObjFileLowering().SectionForCode(CurrentFnSym->getName(), - PAN::isISR(F->getSection())); - - // Start the Code Section. - OutStreamer.SwitchSection(fCodeSection); - - // Emit the frame address of the function at the beginning of code. - OutStreamer.EmitRawText("\tretlw low(" + - Twine(PAN::getFrameLabel(CurrentFnSym->getName())) + - ")"); - OutStreamer.EmitRawText("\tretlw high(" + - Twine(PAN::getFrameLabel(CurrentFnSym->getName())) + - ")"); - - // Emit function start label. - OutStreamer.EmitLabel(CurrentFnSym); - - DebugLoc CurDL; - // 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()) - EmitBasicBlockStart(I); - - // Print a basic block. - for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); - II != E; ++II) { - // Emit the line directive if source line changed. - DebugLoc DL = II->getDebugLoc(); - if (!DL.isUnknown() && DL != CurDL) { - DbgInfo.ChangeDebugLoc(MF, DL); - CurDL = DL; - } - - // Print the assembly for the instruction. - EmitInstruction(II); - } - } - - // Emit function end debug directives. - DbgInfo.EndFunction(MF); - - return false; // we didn't modify anything. -} - - -// printOperand - print operand of insn. -void PIC16AsmPrinter::printOperand(const MachineInstr *MI, int opNum, - raw_ostream &O) { - const MachineOperand &MO = MI->getOperand(opNum); - const Function *F = MI->getParent()->getParent()->getFunction(); - - switch (MO.getType()) { - case MachineOperand::MO_Register: - { - // For indirect load/store insns, the fsr name is printed as INDF. - std::string RegName = getRegisterName(MO.getReg()); - if ((MI->getOpcode() == PIC16::load_indirect) || - (MI->getOpcode() == PIC16::store_indirect)) - RegName.replace (0, 3, "INDF"); - O << RegName; - } - return; - - case MachineOperand::MO_Immediate: - O << (int)MO.getImm(); - return; - - case MachineOperand::MO_GlobalAddress: { - MCSymbol *Sym = Mang->getSymbol(MO.getGlobal()); - // FIXME: currently we do not have a memcpy def coming in the module - // by any chance, as we do not link in those as .bc lib. So these calls - // are always external and it is safe to emit an extern. - if (PAN::isMemIntrinsic(Sym->getName())) - LibcallDecls.insert(Sym->getName()); - - O << *Sym; - break; - } - case MachineOperand::MO_ExternalSymbol: { - const char *Sname = MO.getSymbolName(); - std::string Printname = Sname; - - // Intrinsic stuff needs to be renamed if we are printing IL fn. - if (PAN::isIntrinsicStuff(Printname)) { - if (PAN::isISR(F->getSection())) { - Printname = PAN::Rename(Sname); - } - // Record these decls, we need to print them in asm as extern. - LibcallDecls.insert(Printname); - } - - O << Printname; - break; - } - case MachineOperand::MO_MachineBasicBlock: - O << *MO.getMBB()->getSymbol(); - return; - - default: - llvm_unreachable(" Operand type not supported."); - } -} - -/// printCCOperand - Print the cond code operand. -/// -void PIC16AsmPrinter::printCCOperand(const MachineInstr *MI, int opNum, - raw_ostream &O) { - int CC = (int)MI->getOperand(opNum).getImm(); - O << PIC16CondCodeToString((PIC16CC::CondCodes)CC); -} - -/// printLibcallDecls - print the extern declarations for compiler -/// intrinsics. -/// -void PIC16AsmPrinter::printLibcallDecls() { - // If no libcalls used, return. - if (LibcallDecls.empty()) return; - - OutStreamer.AddComment("External decls for libcalls - BEGIN"); - OutStreamer.AddBlankLine(); - - for (std::set<std::string>::const_iterator I = LibcallDecls.begin(), - E = LibcallDecls.end(); I != E; I++) - OutStreamer.EmitRawText(MAI->getExternDirective() + Twine(*I)); - - OutStreamer.AddComment("External decls for libcalls - END"); - OutStreamer.AddBlankLine(); -} - -/// doInitialization - Perform Module level initializations here. -/// One task that we do here is to sectionize all global variables. -/// The MemSelOptimizer pass depends on the sectionizing. -/// -bool PIC16AsmPrinter::doInitialization(Module &M) { - bool Result = AsmPrinter::doInitialization(M); - - // Every asmbly contains these std headers. - OutStreamer.EmitRawText(StringRef("\n#include p16f1xxx.inc")); - OutStreamer.EmitRawText(StringRef("#include stdmacros.inc")); - - // Set the section names for all globals. - for (Module::global_iterator I = M.global_begin(), E = M.global_end(); - I != E; ++I) { - - // Record External Var Decls. - if (I->isDeclaration()) { - ExternalVarDecls.push_back(I); - continue; - } - - // Record Exteranl Var Defs. - if (I->hasExternalLinkage() || I->hasCommonLinkage()) { - ExternalVarDefs.push_back(I); - } - - // Sectionify actual data. - if (!I->hasAvailableExternallyLinkage()) { - const MCSection *S = getObjFileLowering().SectionForGlobal(I, Mang, TM); - - I->setSection(((const PIC16Section *)S)->getName()); - } - } - - DbgInfo.BeginModule(M); - EmitFunctionDecls(M); - EmitUndefinedVars(M); - EmitDefinedVars(M); - EmitIData(M); - EmitUData(M); - EmitRomData(M); - EmitSharedUdata(M); - EmitUserSections(M); - return Result; -} - -/// Emit extern decls for functions imported from other modules, and emit -/// global declarations for function defined in this module and which are -/// available to other modules. -/// -void PIC16AsmPrinter::EmitFunctionDecls(Module &M) { - // Emit declarations for external functions. - OutStreamer.AddComment("Function Declarations - BEGIN"); - OutStreamer.AddBlankLine(); - for (Module::iterator I = M.begin(), E = M.end(); I != E; I++) { - if (I->isIntrinsic() || I->getName() == "@abort") - continue; - - if (!I->isDeclaration() && !I->hasExternalLinkage()) - continue; - - MCSymbol *Sym = Mang->getSymbol(I); - - // Do not emit memcpy, memset, and memmove here. - // Calls to these routines can be generated in two ways, - // 1. User calling the standard lib function - // 2. Codegen generating these calls for llvm intrinsics. - // In the first case a prototype is alread availale, while in - // second case the call is via and externalsym and the prototype is missing. - // So declarations for these are currently always getting printing by - // tracking both kind of references in printInstrunction. - if (I->isDeclaration() && PAN::isMemIntrinsic(Sym->getName())) continue; - - const char *directive = I->isDeclaration() ? MAI->getExternDirective() : - MAI->getGlobalDirective(); - - OutStreamer.EmitRawText(directive + Twine(Sym->getName())); - OutStreamer.EmitRawText(directive + - Twine(PAN::getRetvalLabel(Sym->getName()))); - OutStreamer.EmitRawText(directive + - Twine(PAN::getArgsLabel(Sym->getName()))); - } - - OutStreamer.AddComment("Function Declarations - END"); - OutStreamer.AddBlankLine(); - -} - -// Emit variables imported from other Modules. -void PIC16AsmPrinter::EmitUndefinedVars(Module &M) { - std::vector<const GlobalVariable*> Items = ExternalVarDecls; - if (!Items.size()) return; - - OutStreamer.AddComment("Imported Variables - BEGIN"); - OutStreamer.AddBlankLine(); - for (unsigned j = 0; j < Items.size(); j++) - OutStreamer.EmitRawText(MAI->getExternDirective() + - Twine(Mang->getSymbol(Items[j])->getName())); - - OutStreamer.AddComment("Imported Variables - END"); - OutStreamer.AddBlankLine(); -} - -// Emit variables defined in this module and are available to other modules. -void PIC16AsmPrinter::EmitDefinedVars(Module &M) { - std::vector<const GlobalVariable*> Items = ExternalVarDefs; - if (!Items.size()) return; - - OutStreamer.AddComment("Exported Variables - BEGIN"); - OutStreamer.AddBlankLine(); - - for (unsigned j = 0; j < Items.size(); j++) - OutStreamer.EmitRawText(MAI->getGlobalDirective() + - Twine(Mang->getSymbol(Items[j])->getName())); - OutStreamer.AddComment("Exported Variables - END"); - OutStreamer.AddBlankLine(); -} - -// Emit initialized data placed in ROM. -void PIC16AsmPrinter::EmitRomData(Module &M) { - EmitSingleSection(PTOF->ROMDATASection()); -} - -// Emit Shared section udata. -void PIC16AsmPrinter::EmitSharedUdata(Module &M) { - EmitSingleSection(PTOF->SHAREDUDATASection()); -} - -bool PIC16AsmPrinter::doFinalization(Module &M) { - EmitAllAutos(M); - printLibcallDecls(); - DbgInfo.EndModule(M); - OutStreamer.EmitRawText(StringRef("\tEND")); - return AsmPrinter::doFinalization(M); -} - -void PIC16AsmPrinter::EmitFunctionFrame(MachineFunction &MF) { - const Function *F = MF.getFunction(); - const TargetData *TD = TM.getTargetData(); - PIC16MachineFunctionInfo *FuncInfo = MF.getInfo<PIC16MachineFunctionInfo>(); - - // Emit the data section name. - - PIC16Section *fPDataSection = - const_cast<PIC16Section *>(getObjFileLowering(). - SectionForFrame(CurrentFnSym->getName())); - - fPDataSection->setColor(getFunctionColor(F)); - OutStreamer.SwitchSection(fPDataSection); - - // Emit function frame label - OutStreamer.EmitRawText(PAN::getFrameLabel(CurrentFnSym->getName()) + - Twine(":")); - - const Type *RetType = F->getReturnType(); - unsigned RetSize = 0; - if (RetType->getTypeID() != Type::VoidTyID) - 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) - OutStreamer.EmitRawText(PAN::getRetvalLabel(CurrentFnSym->getName()) + - Twine(" RES ") + Twine(RetSize)); - else - OutStreamer.EmitRawText(PAN::getRetvalLabel(CurrentFnSym->getName()) + - Twine(":")); - - // Emit variable to hold the space for function arguments - unsigned ArgSize = 0; - for (Function::const_arg_iterator argi = F->arg_begin(), - arge = F->arg_end(); argi != arge ; ++argi) { - const Type *Ty = argi->getType(); - ArgSize += TD->getTypeAllocSize(Ty); - } - - OutStreamer.EmitRawText(PAN::getArgsLabel(CurrentFnSym->getName()) + - Twine(" RES ") + Twine(ArgSize)); - - // Emit temporary space - int TempSize = FuncInfo->getTmpSize(); - if (TempSize > 0) - OutStreamer.EmitRawText(PAN::getTempdataLabel(CurrentFnSym->getName()) + - Twine(" RES ") + Twine(TempSize)); -} - - -void PIC16AsmPrinter::EmitInitializedDataSection(const PIC16Section *S) { - /// Emit Section header. - OutStreamer.SwitchSection(S); - - std::vector<const GlobalVariable*> Items = S->Items; - for (unsigned j = 0; j < Items.size(); j++) { - Constant *C = Items[j]->getInitializer(); - int AddrSpace = Items[j]->getType()->getAddressSpace(); - OutStreamer.EmitRawText(Mang->getSymbol(Items[j])->getName()); - EmitGlobalConstant(C, AddrSpace); - } -} - -// Print all IDATA sections. -void PIC16AsmPrinter::EmitIData(Module &M) { - EmitSectionList (M, PTOF->IDATASections()); -} - -void PIC16AsmPrinter:: -EmitUninitializedDataSection(const PIC16Section *S) { - const TargetData *TD = TM.getTargetData(); - OutStreamer.SwitchSection(S); - std::vector<const GlobalVariable*> Items = S->Items; - for (unsigned j = 0; j < Items.size(); j++) { - Constant *C = Items[j]->getInitializer(); - const Type *Ty = C->getType(); - unsigned Size = TD->getTypeAllocSize(Ty); - OutStreamer.EmitRawText(Mang->getSymbol(Items[j])->getName() + - Twine(" RES ") + Twine(Size)); - } -} - -// Print all UDATA sections. -void PIC16AsmPrinter::EmitUData(Module &M) { - EmitSectionList (M, PTOF->UDATASections()); -} - -// Print all USER sections. -void PIC16AsmPrinter::EmitUserSections(Module &M) { - EmitSectionList (M, PTOF->USERSections()); -} - -// Print all AUTO sections. -void PIC16AsmPrinter::EmitAllAutos(Module &M) { - EmitSectionList (M, PTOF->AUTOSections()); -} - -extern "C" void LLVMInitializePIC16AsmPrinter() { - RegisterAsmPrinter<PIC16AsmPrinter> X(ThePIC16Target); -} - -// Emit one data section using correct section emitter based on section type. -void PIC16AsmPrinter::EmitSingleSection(const PIC16Section *S) { - if (S == NULL) return; - - switch (S->getType()) { - default: llvm_unreachable ("unknow user section type"); - case UDATA: - case UDATA_SHR: - case UDATA_OVR: - EmitUninitializedDataSection(S); - break; - case IDATA: - case ROMDATA: - EmitInitializedDataSection(S); - break; - } -} - -// Emit a list of sections. -void PIC16AsmPrinter:: -EmitSectionList(Module &M, const std::vector<PIC16Section *> &SList) { - for (unsigned i = 0; i < SList.size(); i++) { - // Exclude llvm specific metadata sections. - if (SList[i]->getName().find("llvm.") != std::string::npos) - continue; - OutStreamer.AddBlankLine(); - EmitSingleSection(SList[i]); - } -} - diff --git a/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.h b/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.h deleted file mode 100644 index aa2e1f4..0000000 --- a/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.h +++ /dev/null @@ -1,88 +0,0 @@ -//===-- PIC16AsmPrinter.h - PIC16 LLVM assembly writer ----------*- C++ -*-===// -// -// 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. -// -//===----------------------------------------------------------------------===// - -#ifndef PIC16ASMPRINTER_H -#define PIC16ASMPRINTER_H - -#include "PIC16.h" -#include "PIC16TargetMachine.h" -#include "PIC16DebugInfo.h" -#include "PIC16MCAsmInfo.h" -#include "PIC16TargetObjectFile.h" -#include "llvm/Analysis/DebugInfo.h" -#include "llvm/CodeGen/AsmPrinter.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Target/TargetMachine.h" -#include <list> -#include <set> -#include <string> - -namespace llvm { - class LLVM_LIBRARY_VISIBILITY PIC16AsmPrinter : public AsmPrinter { - public: - explicit PIC16AsmPrinter(TargetMachine &TM, MCStreamer &Streamer); - private: - virtual const char *getPassName() const { - return "PIC16 Assembly Printer"; - } - - const PIC16TargetObjectFile &getObjFileLowering() const { - return (const PIC16TargetObjectFile &)AsmPrinter::getObjFileLowering(); - } - - bool runOnMachineFunction(MachineFunction &F); - void printOperand(const MachineInstr *MI, int opNum, raw_ostream &O); - void printCCOperand(const MachineInstr *MI, int opNum, raw_ostream &O); - void printInstruction(const MachineInstr *MI, raw_ostream &O); - static const char *getRegisterName(unsigned RegNo); - - void EmitInstruction(const MachineInstr *MI); - void EmitFunctionDecls (Module &M); - void EmitUndefinedVars (Module &M); - void EmitDefinedVars (Module &M); - void EmitIData (Module &M); - void EmitUData (Module &M); - void EmitAllAutos (Module &M); - void EmitRomData (Module &M); - void EmitSharedUdata(Module &M); - void EmitUserSections (Module &M); - void EmitFunctionFrame(MachineFunction &MF); - void printLibcallDecls(); - void EmitUninitializedDataSection(const PIC16Section *S); - void EmitInitializedDataSection(const PIC16Section *S); - void EmitSingleSection(const PIC16Section *S); - void EmitSectionList(Module &M, - const std::vector< PIC16Section *> &SList); - void ColorAutoSection(const Function *F); - protected: - bool doInitialization(Module &M); - bool doFinalization(Module &M); - - /// EmitGlobalVariable - Emit the specified global variable and its - /// initializer to the output stream. - virtual void EmitGlobalVariable(const GlobalVariable *GV) { - // PIC16 doesn't use normal hooks for this. - } - - private: - const PIC16TargetObjectFile *PTOF; - PIC16DbgInfo DbgInfo; - const PIC16MCAsmInfo *PMAI; - std::set<std::string> LibcallDecls; // Sorted & uniqued set of extern decls. - std::vector<const GlobalVariable *> ExternalVarDecls; - std::vector<const GlobalVariable *> ExternalVarDefs; - }; -} // end of namespace - -#endif diff --git a/lib/Target/PIC16/CMakeLists.txt b/lib/Target/PIC16/CMakeLists.txt deleted file mode 100644 index 2b6cb9e..0000000 --- a/lib/Target/PIC16/CMakeLists.txt +++ /dev/null @@ -1,26 +0,0 @@ -set(LLVM_TARGET_DEFINITIONS PIC16.td) - -tablegen(PIC16GenRegisterInfo.h.inc -gen-register-desc-header) -tablegen(PIC16GenRegisterNames.inc -gen-register-enums) -tablegen(PIC16GenRegisterInfo.inc -gen-register-desc) -tablegen(PIC16GenInstrNames.inc -gen-instr-enums) -tablegen(PIC16GenInstrInfo.inc -gen-instr-desc) -tablegen(PIC16GenAsmWriter.inc -gen-asm-writer) -tablegen(PIC16GenDAGISel.inc -gen-dag-isel) -tablegen(PIC16GenCallingConv.inc -gen-callingconv) -tablegen(PIC16GenSubtarget.inc -gen-subtarget) - -add_llvm_target(PIC16CodeGen - PIC16DebugInfo.cpp - PIC16InstrInfo.cpp - PIC16ISelDAGToDAG.cpp - PIC16ISelLowering.cpp - PIC16MemSelOpt.cpp - PIC16MCAsmInfo.cpp - PIC16RegisterInfo.cpp - PIC16Section.cpp - PIC16Subtarget.cpp - PIC16TargetMachine.cpp - PIC16TargetObjectFile.cpp - PIC16SelectionDAGInfo.cpp - ) diff --git a/lib/Target/PIC16/Makefile b/lib/Target/PIC16/Makefile deleted file mode 100644 index 9e784d1..0000000 --- a/lib/Target/PIC16/Makefile +++ /dev/null @@ -1,24 +0,0 @@ -##===- 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 = LLVMPIC16CodeGen -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 - -DIRS = AsmPrinter TargetInfo PIC16Passes - -include $(LEVEL)/Makefile.common - diff --git a/lib/Target/PIC16/PIC16.h b/lib/Target/PIC16/PIC16.h deleted file mode 100644 index 08bb3e6..0000000 --- a/lib/Target/PIC16/PIC16.h +++ /dev/null @@ -1,134 +0,0 @@ -//===-- PIC16.h - Top-level interface for PIC16 representation --*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file 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 LLVM_TARGET_PIC16_H -#define LLVM_TARGET_PIC16_H - -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Target/TargetMachine.h" -#include <cassert> -#include <sstream> -#include <cstring> -#include <string> -#include <vector> - -namespace llvm { - class PIC16TargetMachine; - class FunctionPass; - class MachineCodeEmitter; - class formatted_raw_ostream; - -namespace PIC16CC { - enum CondCodes { - EQ, - NE, - LT, - LE, - GT, - GE, - ULT, - UGT, - ULE, - UGE - }; -} - - enum PIC16SectionType { - CODE, - UDATA, - IDATA, - ROMDATA, - UDATA_OVR, - UDATA_SHR - }; - - class ESNames { - std::vector<char*> stk; - ESNames() {} - public: - ~ESNames() { - while (!stk.empty()) - { - char* p = stk.back(); - delete [] p; - stk.pop_back(); - } - } - - // External symbol names require memory to live till the program end. - // So we have to allocate it and keep. Push all such allocations into a - // vector so that they get freed up on termination. - inline static const char *createESName (const std::string &name) { - static ESNames esn; - char *tmpName = new char[name.size() + 1]; - memcpy(tmpName, name.c_str(), name.size() + 1); - esn.stk.push_back(tmpName); - return tmpName; - } - - }; - - inline static const char *PIC16CondCodeToString(PIC16CC::CondCodes CC) { - switch (CC) { - default: llvm_unreachable("Unknown condition code"); - case PIC16CC::NE: return "ne"; - case PIC16CC::EQ: return "eq"; - case PIC16CC::LT: return "lt"; - case PIC16CC::ULT: return "lt"; - case PIC16CC::LE: return "le"; - case PIC16CC::ULE: return "le"; - case PIC16CC::GT: return "gt"; - case PIC16CC::UGT: return "gt"; - case PIC16CC::GE: return "ge"; - case PIC16CC::UGE: return "ge"; - } - } - - inline static bool isSignedComparison(PIC16CC::CondCodes CC) { - switch (CC) { - default: llvm_unreachable("Unknown condition code"); - case PIC16CC::NE: - case PIC16CC::EQ: - case PIC16CC::LT: - case PIC16CC::LE: - case PIC16CC::GE: - case PIC16CC::GT: - return true; - case PIC16CC::ULT: - case PIC16CC::UGT: - case PIC16CC::ULE: - case PIC16CC::UGE: - return false; // condition codes for unsigned comparison. - } - } - - - - FunctionPass *createPIC16ISelDag(PIC16TargetMachine &TM); - // Banksel optimizer pass. - FunctionPass *createPIC16MemSelOptimizerPass(); - - extern Target ThePIC16Target; - extern Target TheCooperTarget; - -} // 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 deleted file mode 100644 index b2b9b1c..0000000 --- a/lib/Target/PIC16/PIC16.td +++ /dev/null @@ -1,40 +0,0 @@ -//===- 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 "llvm/Target/Target.td" - -include "PIC16RegisterInfo.td" -include "PIC16InstrInfo.td" - -//===----------------------------------------------------------------------===// -// Subtarget Features. -//===----------------------------------------------------------------------===// -def FeatureCooper : SubtargetFeature<"cooper", "IsCooper", "true", - "PIC16 Cooper ISA Support">; - -//===----------------------------------------------------------------------===// -// PIC16 supported processors. -//===----------------------------------------------------------------------===// - -def : Processor<"generic", NoItineraries, []>; -def : Processor<"cooper", NoItineraries, [FeatureCooper]>; - - -def PIC16InstrInfo : InstrInfo {} - -def PIC16 : Target { - let InstructionSet = PIC16InstrInfo; -} - diff --git a/lib/Target/PIC16/PIC16ABINames.h b/lib/Target/PIC16/PIC16ABINames.h deleted file mode 100644 index 4c1a8da..0000000 --- a/lib/Target/PIC16/PIC16ABINames.h +++ /dev/null @@ -1,399 +0,0 @@ -//===-- PIC16ABINames.h - PIC16 Naming conventios for ABI----- --*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains the functions to manage ABI Naming conventions for PIC16. -// -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_TARGET_PIC16ABINAMES_H -#define LLVM_TARGET_PIC16ABINAMES_H - -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Target/TargetMachine.h" -#include <cassert> -#include <sstream> -#include <cstring> -#include <string> - -namespace llvm { - class PIC16TargetMachine; - class FunctionPass; - class MachineCodeEmitter; - class formatted_raw_ostream; - - // 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. - // These are maily function names and global variable names. - // Example - @foo, @i - // Static local variables - @<func>.<var> - // ------------------------------------------------------- - // Functions and auto variables. - // 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. - // .ret. - return value label for a function. - // .frame. - Frame label for a function where retval, args - // and temps are stored. - // .args. - Label used to pass arguments to a direct call. - // Example - Function name: @foo - // Its frame: @foo.frame. - // Its retval: @foo.ret. - // Its local vars: @foo.auto.a - // Its temp data: @foo.temp. - // Its arg passing: @foo.args. - //---------------------------------------------- - // Libcall - compiler generated libcall names must start with .lib. - // This id will be used to emit extern decls for libcalls. - // Example - libcall name: @.lib.sra.i8 - // To pass args: @.lib.sra.i8.args. - // To return val: @.lib.sra.i8.ret. - //---------------------------------------------- - // SECTION Names - // uninitialized globals - @udata.<num>.# - // initialized globals - @idata.<num>.# - // Program memory data - @romdata.# - // Variables with user defined section name - <user_defined_section> - // Variables with user defined address - @<var>.user_section.<address>.# - // Function frame - @<func>.frame_section. - // Function autos - @<func>.autos_section. - // Overlay sections - @<color>.## - // Declarations - Enclosed in comments. No section for them. - //---------------------------------------------------------- - - // Tags used to mangle different names. - enum TAGS { - PREFIX_SYMBOL, - GLOBAL, - STATIC_LOCAL, - AUTOS_LABEL, - FRAME_LABEL, - RET_LABEL, - ARGS_LABEL, - TEMPS_LABEL, - - LIBCALL, - - FRAME_SECTION, - AUTOS_SECTION, - CODE_SECTION, - USER_SECTION - }; - - // Textual names of the tags. - inline static const char *getTagName(TAGS tag) { - switch (tag) { - default: return ""; - case PREFIX_SYMBOL: return "@"; - 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 ".frame_section."; - case AUTOS_SECTION: return ".autos_section."; - case CODE_SECTION: return ".code_section."; - case USER_SECTION: return ".user_section."; - } - } - - // 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(getTagName(FRAME_LABEL)) != std::string::npos) - return FRAME_LABEL; - - if (Sym.find(getTagName(RET_LABEL)) != std::string::npos) - return RET_LABEL; - - if (Sym.find(getTagName(ARGS_LABEL)) != std::string::npos) - return ARGS_LABEL; - - if (Sym.find(getTagName(AUTOS_LABEL)) != std::string::npos) - return AUTOS_LABEL; - - if (Sym.find(getTagName(LIBCALL)) != std::string::npos) - return LIBCALL; - - // 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"); - return PREFIX_SYMBOL; // Silence warning when assertions are turned off. - } - - // 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 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 ('.'); - - return Sym.substr (0, func_name_end); - } - - // 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; - } - - // Get the retval label for the given function. - static std::string getRetvalLabel(const std::string &Func) { - std::string Func1 = addPrefix(Func); - std::string tag = getTagName(RET_LABEL); - return Func1 + tag; - } - - // Get the argument label for the given function. - static std::string getArgsLabel(const std::string &Func) { - std::string Func1 = addPrefix(Func); - std::string tag = getTagName(ARGS_LABEL); - return Func1 + tag; - } - - // Get the tempdata label for the given function. - 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 + "#"; - } - - static std::string getAutosSectionName(const std::string &Func) { - std::string Func1 = addPrefix(Func); - std::string tag = getTagName(AUTOS_SECTION); - return Func1 + tag + "#"; - } - - static std::string getCodeSectionName(const std::string &Func) { - std::string Func1 = addPrefix(Func); - std::string tag = getTagName(CODE_SECTION); - return Func1 + tag + "#"; - } - - static std::string getUserSectionName(const std::string &Name) { - std::string sname = addPrefix(Name);; - std::string tag = getTagName(USER_SECTION); - return sname + tag + "#"; - } - - // udata, romdata and idata section names are generated by a given number. - // @udata.<num>.# - static std::string getUdataSectionName(unsigned num, - std::string prefix = "") { - std::ostringstream o; - o << getTagName(PREFIX_SYMBOL) << prefix << "udata." << num - << ".#"; - return o.str(); - } - - static std::string getRomdataSectionName() { - return "romdata.#"; - } - - static std::string getSharedUDataSectionName() { - std::ostringstream o; - o << getTagName(PREFIX_SYMBOL) << "udata_shr" << ".#"; - return o.str(); - } - - static std::string getRomdataSectionName(unsigned num, - std::string prefix = "") { - std::ostringstream o; - o << getTagName(PREFIX_SYMBOL) << prefix << "romdata." << num - << ".#"; - return o.str(); - } - - static std::string getIdataSectionName(unsigned num, - std::string prefix = "") { - std::ostringstream o; - o << getTagName(PREFIX_SYMBOL) << prefix << "idata." << num - << ".#"; - return o.str(); - } - - inline static bool isLocalName (const std::string &Name) { - if (getSymbolTag(Name) == AUTOS_LABEL) - return true; - - return false; - } - - - inline static bool isMemIntrinsic (const std::string &Name) { - if (Name.compare("@memcpy") == 0 || Name.compare("@memset") == 0 || - Name.compare("@memmove") == 0) { - return true; - } - - return false; - } - - // Currently names of libcalls are assigned during TargetLowering - // object construction. There is no provision to change the when the - // code for a function IL function being generated. - // So we have to change these names while printing assembly. - // We need to do that mainly for names related to intrinsics. This - // function returns true if a name needs to be cloned. - inline static bool isIntrinsicStuff(const std::string &Name) { - // Return true if the name contains LIBCALL marker, or a MemIntrinisc. - // these are mainly ARGS_LABEL, RET_LABEL, and the LIBCALL name itself. - if ((Name.find(getTagName(LIBCALL)) != std::string::npos) - || isMemIntrinsic(Name)) - return true; - - return false; - } - - // Rename the name for IL. - inline static std::string Rename(const std::string &Name) { - std::string Newname; - // If its a label (LIBCALL+Func+LABEL), change it to - // (LIBCALL+Func+IL+LABEL). - TAGS id = getSymbolTag(Name); - if (id == ARGS_LABEL || id == RET_LABEL) { - std::size_t pos = Name.find(getTagName(id)); - Newname = Name.substr(0, pos) + ".IL" + getTagName(id); - return Newname; - } - - // Else, just append IL to name. - return Name + ".IL"; - } - - - - - 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 (Tag) of the symbol from its mangled name - // and return appropriate section name for it. - static inline std::string getSectionNameForSym(const std::string &Sym1) { - std::string Sym = addPrefix(Sym1); - - std::string SectionName; - - std::string Fname = getFuncNameForSym (Sym); - TAGS id = getSymbolTag (Sym); - - switch (id) { - default : assert (0 && "Could not determine external symbol type"); - case FRAME_LABEL: - case RET_LABEL: - case TEMPS_LABEL: - case ARGS_LABEL: { - return getFrameSectionName(Fname); - } - case AUTOS_LABEL: { - return getAutosSectionName(Fname); - } - } - } - - /// Return Overlay Name for the section. - /// The ABI Convention is: @<Color>.##.<section_tag> - /// The section_tag is retrieved from the SectName parameter and - /// and Color is passed in parameter. - static inline std::string getOverlayName(std::string SectName, int Color) { - // FIXME: Only autos_section and frame_section are colored. - // So check and assert if the passed SectName does not have AUTOS_SECTION - // or FRAME_SECTION tag in it. - std::ostringstream o; - o << getTagName(PREFIX_SYMBOL) << Color << ".##" - << SectName.substr(SectName.find(".")); - - return o.str(); - } - - // Return true if the current function is an ISR - inline static bool isISR(const std::string SectName) { - if (SectName.find("interrupt") != std::string::npos) - return true; - - return false; - } - - // Return the address for ISR starts in rom. - inline static std::string getISRAddr(void) { - return "0x4"; - } - - // Returns the name of clone of a function. - static std::string getCloneFnName(const std::string &Func) { - return (Func + ".IL"); - } - - // Returns the name of clone of a variable. - static std::string getCloneVarName(const std::string &Fn, - const std::string &Var) { - std::string cloneVarName = Var; - // These vars are named like fun.auto.var. - // Just replace the function name, with clone function name. - std::string cloneFnName = getCloneFnName(Fn); - cloneVarName.replace(cloneVarName.find(Fn), Fn.length(), cloneFnName); - return cloneVarName; - } - }; // class PAN. -} // end namespace llvm; - -#endif diff --git a/lib/Target/PIC16/PIC16DebugInfo.cpp b/lib/Target/PIC16/PIC16DebugInfo.cpp deleted file mode 100644 index 7a948de..0000000 --- a/lib/Target/PIC16/PIC16DebugInfo.cpp +++ /dev/null @@ -1,490 +0,0 @@ - -//===-- PIC16DebugInfo.cpp - Implementation for PIC16 Debug Information ======// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains the helper functions for representing debug information. -// -//===----------------------------------------------------------------------===// - -#include "PIC16.h" -#include "PIC16ABINames.h" -#include "PIC16DebugInfo.h" -#include "llvm/GlobalVariable.h" -#include "llvm/CodeGen/MachineFunction.h" -#include "llvm/MC/MCAsmInfo.h" -#include "llvm/MC/MCStreamer.h" -#include "llvm/Support/DebugLoc.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/ADT/StringExtras.h" -using namespace llvm; - -/// PopulateDebugInfo - Populate the TypeNo, Aux[] and TagName from Ty. -/// -void PIC16DbgInfo::PopulateDebugInfo (DIType Ty, unsigned short &TypeNo, - bool &HasAux, int Aux[], - std::string &TagName) { - if (Ty.isBasicType()) - PopulateBasicTypeInfo (Ty, TypeNo); - else if (Ty.isCompositeType()) - PopulateCompositeTypeInfo (Ty, TypeNo, HasAux, Aux, TagName); - else if (Ty.isDerivedType()) - PopulateDerivedTypeInfo (Ty, TypeNo, HasAux, Aux, TagName); - else { - TypeNo = PIC16Dbg::T_NULL; - HasAux = false; - } - return; -} - -/// PopulateBasicTypeInfo- Populate TypeNo for basic type from Ty. -/// -void PIC16DbgInfo::PopulateBasicTypeInfo (DIType Ty, unsigned short &TypeNo) { - std::string Name = Ty.getName(); - unsigned short BaseTy = GetTypeDebugNumber(Name); - TypeNo = TypeNo << PIC16Dbg::S_BASIC; - TypeNo = TypeNo | (0xffff & BaseTy); -} - -/// PopulateDerivedTypeInfo - Populate TypeNo, Aux[], TagName for derived type -/// from Ty. Derived types are mostly pointers. -/// -void PIC16DbgInfo::PopulateDerivedTypeInfo (DIType Ty, unsigned short &TypeNo, - bool &HasAux, int Aux[], - std::string &TagName) { - - switch(Ty.getTag()) - { - case dwarf::DW_TAG_pointer_type: - TypeNo = TypeNo << PIC16Dbg::S_DERIVED; - TypeNo = TypeNo | PIC16Dbg::DT_PTR; - break; - default: - TypeNo = TypeNo << PIC16Dbg::S_DERIVED; - } - - // We also need to encode the information about the base type of - // pointer in TypeNo. - DIType BaseType = DIDerivedType(Ty).getTypeDerivedFrom(); - PopulateDebugInfo(BaseType, TypeNo, HasAux, Aux, TagName); -} - -/// PopulateArrayTypeInfo - Populate TypeNo, Aux[] for array from Ty. -void PIC16DbgInfo::PopulateArrayTypeInfo (DIType Ty, unsigned short &TypeNo, - bool &HasAux, int Aux[], - std::string &TagName) { - - DICompositeType CTy = DICompositeType(Ty); - DIArray Elements = CTy.getTypeArray(); - unsigned short size = 1; - unsigned short Dimension[4]={0,0,0,0}; - for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) { - DIDescriptor Element = Elements.getElement(i); - if (Element.getTag() == dwarf::DW_TAG_subrange_type) { - TypeNo = TypeNo << PIC16Dbg::S_DERIVED; - TypeNo = TypeNo | PIC16Dbg::DT_ARY; - DISubrange SubRange = DISubrange(Element); - Dimension[i] = SubRange.getHi() - SubRange.getLo() + 1; - // Each dimension is represented by 2 bytes starting at byte 9. - Aux[8+i*2+0] = Dimension[i]; - Aux[8+i*2+1] = Dimension[i] >> 8; - size = size * Dimension[i]; - } - } - HasAux = true; - // In auxillary entry for array, 7th and 8th byte represent array size. - Aux[6] = size & 0xff; - Aux[7] = size >> 8; - DIType BaseType = CTy.getTypeDerivedFrom(); - PopulateDebugInfo(BaseType, TypeNo, HasAux, Aux, TagName); -} - -/// PopulateStructOrUnionTypeInfo - Populate TypeNo, Aux[] , TagName for -/// structure or union. -/// -void PIC16DbgInfo::PopulateStructOrUnionTypeInfo (DIType Ty, - unsigned short &TypeNo, - bool &HasAux, int Aux[], - std::string &TagName) { - DICompositeType CTy = DICompositeType(Ty); - TypeNo = TypeNo << PIC16Dbg::S_BASIC; - if (Ty.getTag() == dwarf::DW_TAG_structure_type) - TypeNo = TypeNo | PIC16Dbg::T_STRUCT; - else - TypeNo = TypeNo | PIC16Dbg::T_UNION; - TagName = CTy.getName(); - // UniqueSuffix is .number where number is obtained from - // llvm.dbg.composite<number>. - // FIXME: This will break when composite type is not represented by - // llvm.dbg.composite* global variable. Since we need to revisit - // PIC16DebugInfo implementation anyways after the MDNodes based - // framework is done, let us continue with the way it is. - std::string UniqueSuffix = "." + Ty->getNameStr().substr(18); - TagName += UniqueSuffix; - unsigned short size = CTy.getSizeInBits()/8; - // 7th and 8th byte represent size. - HasAux = true; - Aux[6] = size & 0xff; - Aux[7] = size >> 8; -} - -/// PopulateEnumTypeInfo - Populate TypeNo for enum from Ty. -void PIC16DbgInfo::PopulateEnumTypeInfo (DIType Ty, unsigned short &TypeNo) { - TypeNo = TypeNo << PIC16Dbg::S_BASIC; - TypeNo = TypeNo | PIC16Dbg::T_ENUM; -} - -/// PopulateCompositeTypeInfo - Populate TypeNo, Aux[] and TagName for -/// composite types from Ty. -/// -void PIC16DbgInfo::PopulateCompositeTypeInfo (DIType Ty, unsigned short &TypeNo, - bool &HasAux, int Aux[], - std::string &TagName) { - switch (Ty.getTag()) { - case dwarf::DW_TAG_array_type: { - PopulateArrayTypeInfo (Ty, TypeNo, HasAux, Aux, TagName); - break; - } - case dwarf:: DW_TAG_union_type: - case dwarf::DW_TAG_structure_type: { - PopulateStructOrUnionTypeInfo (Ty, TypeNo, HasAux, Aux, TagName); - break; - } - case dwarf::DW_TAG_enumeration_type: { - PopulateEnumTypeInfo (Ty, TypeNo); - break; - } - default: - TypeNo = TypeNo << PIC16Dbg::S_DERIVED; - } -} - -/// GetTypeDebugNumber - Get debug type number for given type. -/// -unsigned PIC16DbgInfo::GetTypeDebugNumber(std::string &type) { - if (type == "char") - return PIC16Dbg::T_CHAR; - else if (type == "short") - return PIC16Dbg::T_SHORT; - else if (type == "int") - return PIC16Dbg::T_INT; - else if (type == "long") - return PIC16Dbg::T_LONG; - else if (type == "unsigned char") - return PIC16Dbg::T_UCHAR; - else if (type == "unsigned short") - return PIC16Dbg::T_USHORT; - else if (type == "unsigned int") - return PIC16Dbg::T_UINT; - else if (type == "unsigned long") - return PIC16Dbg::T_ULONG; - else - return 0; -} - -/// GetStorageClass - Get storage class for give debug variable. -/// -short PIC16DbgInfo::getStorageClass(DIGlobalVariable DIGV) { - short ClassNo; - if (PAN::isLocalName(DIGV.getName())) { - // Generating C_AUTO here fails due to error in linker. Change it once - // linker is fixed. - ClassNo = PIC16Dbg::C_STAT; - } - else if (DIGV.isLocalToUnit()) - ClassNo = PIC16Dbg::C_STAT; - else - ClassNo = PIC16Dbg::C_EXT; - return ClassNo; -} - -/// BeginModule - Emit necessary debug info to start a Module and do other -/// required initializations. -void PIC16DbgInfo::BeginModule(Module &M) { - // Emit file directive for module. - DebugInfoFinder DbgFinder; - DbgFinder.processModule(M); - if (DbgFinder.compile_unit_count() != 0) { - // FIXME : What if more then one CUs are present in a module ? - MDNode *CU = *DbgFinder.compile_unit_begin(); - EmitDebugDirectives = true; - SwitchToCU(CU); - } - // Emit debug info for decls of composite types. - EmitCompositeTypeDecls(M); -} - -/// Helper to find first valid debug loc for a function. -/// -static const DebugLoc GetDebugLocForFunction(const MachineFunction &MF) { - DebugLoc DL; - for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); - I != E; ++I) { - for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); - II != E; ++II) { - DL = II->getDebugLoc(); - if (!DL.isUnknown()) - return DL; - } - } - return DL; -} - -/// BeginFunction - Emit necessary debug info to start a function. -/// -void PIC16DbgInfo::BeginFunction(const MachineFunction &MF) { - if (! EmitDebugDirectives) return; - - // Retreive the first valid debug Loc and process it. - const DebugLoc &DL = GetDebugLocForFunction(MF); - // Emit debug info only if valid debug info is available. - if (!DL.isUnknown()) { - ChangeDebugLoc(MF, DL, true); - EmitFunctBeginDI(MF.getFunction()); - } - // Set current line to 0 so that.line directive is genearted after .bf. - CurLine = 0; -} - -/// ChangeDebugLoc - Take necessary steps when DebugLoc changes. -/// CurFile and CurLine may change as a result of this. -/// -void PIC16DbgInfo::ChangeDebugLoc(const MachineFunction &MF, - const DebugLoc &DL, bool IsInBeginFunction) { - if (!EmitDebugDirectives) return; - assert(!DL.isUnknown() && "can't change to invalid debug loc"); - - SwitchToCU(DL.getScope(MF.getFunction()->getContext())); - SwitchToLine(DL.getLine(), IsInBeginFunction); -} - -/// SwitchToLine - Emit line directive for a new line. -/// -void PIC16DbgInfo::SwitchToLine(unsigned Line, bool IsInBeginFunction) { - if (CurLine == Line) return; - if (!IsInBeginFunction) - OS.EmitRawText("\n\t.line " + Twine(Line)); - CurLine = Line; -} - -/// EndFunction - Emit .ef for end of function. -/// -void PIC16DbgInfo::EndFunction(const MachineFunction &MF) { - if (! EmitDebugDirectives) return; - const DebugLoc &DL = GetDebugLocForFunction(MF); - // Emit debug info only if valid debug info is available. - if (!DL.isUnknown()) - EmitFunctEndDI(MF.getFunction(), CurLine); -} - -/// EndModule - Emit .eof for end of module. -/// -void PIC16DbgInfo::EndModule(Module &M) { - if (! EmitDebugDirectives) return; - EmitVarDebugInfo(M); - if (CurFile != "") OS.EmitRawText(StringRef("\n\t.eof")); -} - -/// EmitCompositeTypeElements - Emit debug information for members of a -/// composite type. -/// -void PIC16DbgInfo::EmitCompositeTypeElements (DICompositeType CTy, - std::string SuffixNo) { - unsigned long Value = 0; - DIArray Elements = CTy.getTypeArray(); - for (unsigned i = 0, N = Elements.getNumElements(); i < N; i++) { - DIDescriptor Element = Elements.getElement(i); - unsigned short TypeNo = 0; - bool HasAux = false; - int ElementAux[PIC16Dbg::AuxSize] = { 0 }; - std::string TagName = ""; - DIDerivedType DITy(Element); - unsigned short ElementSize = DITy.getSizeInBits()/8; - // Get mangleddd name for this structure/union element. - std::string MangMemName = DITy.getName().str() + SuffixNo; - PopulateDebugInfo(DITy, TypeNo, HasAux, ElementAux, TagName); - short Class = 0; - if( CTy.getTag() == dwarf::DW_TAG_union_type) - Class = PIC16Dbg::C_MOU; - else if (CTy.getTag() == dwarf::DW_TAG_structure_type) - Class = PIC16Dbg::C_MOS; - EmitSymbol(MangMemName.c_str(), Class, TypeNo, Value); - if (CTy.getTag() == dwarf::DW_TAG_structure_type) - Value += ElementSize; - if (HasAux) - EmitAuxEntry(MangMemName.c_str(), ElementAux, PIC16Dbg::AuxSize, TagName); - } -} - -/// EmitCompositeTypeDecls - Emit composite type declarations like structure -/// and union declarations. -/// -void PIC16DbgInfo::EmitCompositeTypeDecls(Module &M) { - DebugInfoFinder DbgFinder; - DbgFinder.processModule(M); - for (DebugInfoFinder::iterator I = DbgFinder.type_begin(), - E = DbgFinder.type_end(); I != E; ++I) { - DICompositeType CTy(*I); - if (!CTy.Verify()) - continue; - if (CTy.getTag() == dwarf::DW_TAG_union_type || - CTy.getTag() == dwarf::DW_TAG_structure_type ) { - // Get the number after llvm.dbg.composite and make UniqueSuffix from - // it. - std::string DIVar = CTy->getNameStr(); - std::string UniqueSuffix = "." + DIVar.substr(18); - std::string MangledCTyName = CTy.getName().str() + UniqueSuffix; - unsigned short size = CTy.getSizeInBits()/8; - int Aux[PIC16Dbg::AuxSize] = {0}; - // 7th and 8th byte represent size of structure/union. - Aux[6] = size & 0xff; - Aux[7] = size >> 8; - // Emit .def for structure/union tag. - if( CTy.getTag() == dwarf::DW_TAG_union_type) - EmitSymbol(MangledCTyName.c_str(), PIC16Dbg::C_UNTAG); - else if (CTy.getTag() == dwarf::DW_TAG_structure_type) - EmitSymbol(MangledCTyName.c_str(), PIC16Dbg::C_STRTAG); - - // Emit auxiliary debug information for structure/union tag. - EmitAuxEntry(MangledCTyName.c_str(), Aux, PIC16Dbg::AuxSize); - - // Emit members. - EmitCompositeTypeElements (CTy, UniqueSuffix); - - // Emit mangled Symbol for end of structure/union. - std::string EOSSymbol = ".eos" + UniqueSuffix; - EmitSymbol(EOSSymbol.c_str(), PIC16Dbg::C_EOS); - EmitAuxEntry(EOSSymbol.c_str(), Aux, PIC16Dbg::AuxSize, - MangledCTyName.c_str()); - } - } -} - - -/// EmitFunctBeginDI - Emit .bf for function. -/// -void PIC16DbgInfo::EmitFunctBeginDI(const Function *F) { - std::string FunctName = F->getName(); - if (EmitDebugDirectives) { - std::string FunctBeginSym = ".bf." + FunctName; - std::string BlockBeginSym = ".bb." + FunctName; - - int BFAux[PIC16Dbg::AuxSize] = {0}; - BFAux[4] = CurLine; - BFAux[5] = CurLine >> 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); - } -} - -/// EmitFunctEndDI - Emit .ef for function end. -/// -void PIC16DbgInfo::EmitFunctEndDI(const Function *F, unsigned Line) { - std::string FunctName = F->getName(); - if (EmitDebugDirectives) { - 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] = CurLine; - EFAux[5] = CurLine >> 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, - std::string TagName) { - std::string Tmp; - // TagName is emitted in case of structure/union objects. - if (!TagName.empty()) Tmp += ", " + TagName; - - for (int i = 0; i<Num; i++) - Tmp += "," + utostr(Aux[i] & 0xff); - - OS.EmitRawText("\n\t.dim " + Twine(VarName) + ", 1" + Tmp); -} - -/// EmitSymbol - Emit .def for a symbol. Value is offset for the member. -/// -void PIC16DbgInfo::EmitSymbol(std::string Name, short Class, - unsigned short Type, unsigned long Value) { - std::string Tmp; - if (Value > 0) - Tmp = ", value = " + utostr(Value); - - OS.EmitRawText("\n\t.def " + Twine(Name) + ", type = " + utostr(Type) + - ", class = " + utostr(Class) + Tmp); -} - -/// EmitVarDebugInfo - Emit debug information for all variables. -/// -void PIC16DbgInfo::EmitVarDebugInfo(Module &M) { - DebugInfoFinder DbgFinder; - DbgFinder.processModule(M); - - for (DebugInfoFinder::iterator I = DbgFinder.global_variable_begin(), - E = DbgFinder.global_variable_end(); I != E; ++I) { - DIGlobalVariable DIGV(*I); - DIType Ty = DIGV.getType(); - unsigned short TypeNo = 0; - bool HasAux = false; - int Aux[PIC16Dbg::AuxSize] = { 0 }; - std::string TagName = ""; - std::string VarName = DIGV.getName(); - VarName = MAI->getGlobalPrefix() + VarName; - PopulateDebugInfo(Ty, TypeNo, HasAux, Aux, TagName); - // Emit debug info only if type information is availaible. - if (TypeNo != PIC16Dbg::T_NULL) { - OS.EmitRawText("\t.type " + Twine(VarName) + ", " + Twine(TypeNo)); - short ClassNo = getStorageClass(DIGV); - OS.EmitRawText("\t.class " + Twine(VarName) + ", " + Twine(ClassNo)); - if (HasAux) - EmitAuxEntry(VarName, Aux, PIC16Dbg::AuxSize, TagName); - } - } -} - -/// SwitchToCU - Switch to a new compilation unit. -/// -void PIC16DbgInfo::SwitchToCU(MDNode *CU) { - // Get the file path from CU. - DICompileUnit cu(CU); - std::string DirName = cu.getDirectory(); - std::string FileName = cu.getFilename(); - std::string FilePath = DirName + "/" + FileName; - - // Nothing to do if source file is still same. - if ( FilePath == CurFile ) return; - - // Else, close the current one and start a new. - if (CurFile != "") - OS.EmitRawText(StringRef("\t.eof")); - OS.EmitRawText("\n\t.file\t\"" + Twine(FilePath) + "\""); - CurFile = FilePath; - CurLine = 0; -} - -/// EmitEOF - Emit .eof for end of file. -/// -void PIC16DbgInfo::EmitEOF() { - if (CurFile != "") - OS.EmitRawText(StringRef("\t.EOF")); -} - diff --git a/lib/Target/PIC16/PIC16DebugInfo.h b/lib/Target/PIC16/PIC16DebugInfo.h deleted file mode 100644 index 031dcf0..0000000 --- a/lib/Target/PIC16/PIC16DebugInfo.h +++ /dev/null @@ -1,156 +0,0 @@ -//===-- PIC16DebugInfo.h - Interfaces for PIC16 Debug Information ============// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains the helper functions for representing debug information. -// -//===----------------------------------------------------------------------===// - -#ifndef PIC16DBG_H -#define PIC16DBG_H - -#include "llvm/Analysis/DebugInfo.h" -#include "llvm/Module.h" - -namespace llvm { - class MachineFunction; - class DebugLoc; - class MCStreamer; - - namespace PIC16Dbg { - enum VarType { - T_NULL, - T_VOID, - T_CHAR, - T_SHORT, - T_INT, - T_LONG, - T_FLOAT, - T_DOUBLE, - T_STRUCT, - T_UNION, - T_ENUM, - T_MOE, - T_UCHAR, - T_USHORT, - T_UINT, - T_ULONG - }; - enum DerivedType { - DT_NONE, - DT_PTR, - DT_FCN, - DT_ARY - }; - enum TypeSize { - S_BASIC = 5, - S_DERIVED = 3 - }; - enum DbgClass { - C_NULL, - C_AUTO, - C_EXT, - C_STAT, - C_REG, - C_EXTDEF, - C_LABEL, - C_ULABEL, - C_MOS, - C_ARG, - C_STRTAG, - C_MOU, - C_UNTAG, - C_TPDEF, - C_USTATIC, - C_ENTAG, - C_MOE, - C_REGPARM, - C_FIELD, - C_AUTOARG, - C_LASTENT, - C_BLOCK = 100, - C_FCN, - C_EOS, - C_FILE, - C_LINE, - C_ALIAS, - C_HIDDEN, - C_EOF, - C_LIST, - C_SECTION, - C_EFCN = 255 - }; - enum SymbolSize { - AuxSize =20 - }; - } - - class PIC16DbgInfo { - MCStreamer &OS; - const MCAsmInfo *MAI; - std::string CurFile; - unsigned CurLine; - - // EmitDebugDirectives is set if debug information is available. Default - // value for it is false. - bool EmitDebugDirectives; - - public: - PIC16DbgInfo(MCStreamer &os, const MCAsmInfo *T) : OS(os), MAI(T) { - CurFile = ""; - CurLine = 0; - EmitDebugDirectives = false; - } - - void BeginModule (Module &M); - void BeginFunction (const MachineFunction &MF); - void ChangeDebugLoc (const MachineFunction &MF, const DebugLoc &DL, - bool IsInBeginFunction = false); - void EndFunction (const MachineFunction &MF); - void EndModule (Module &M); - - - private: - void SwitchToCU (MDNode *CU); - void SwitchToLine (unsigned Line, bool IsInBeginFunction = false); - - void PopulateDebugInfo (DIType Ty, unsigned short &TypeNo, bool &HasAux, - int Aux[], std::string &TypeName); - void PopulateBasicTypeInfo (DIType Ty, unsigned short &TypeNo); - void PopulateDerivedTypeInfo (DIType Ty, unsigned short &TypeNo, - bool &HasAux, int Aux[], - std::string &TypeName); - - void PopulateCompositeTypeInfo (DIType Ty, unsigned short &TypeNo, - bool &HasAux, int Aux[], - std::string &TypeName); - void PopulateArrayTypeInfo (DIType Ty, unsigned short &TypeNo, - bool &HasAux, int Aux[], - std::string &TypeName); - - void PopulateStructOrUnionTypeInfo (DIType Ty, unsigned short &TypeNo, - bool &HasAux, int Aux[], - std::string &TypeName); - void PopulateEnumTypeInfo (DIType Ty, unsigned short &TypeNo); - - unsigned GetTypeDebugNumber(std::string &Type); - short getStorageClass(DIGlobalVariable DIGV); - void EmitFunctBeginDI(const Function *F); - void EmitCompositeTypeDecls(Module &M); - void EmitCompositeTypeElements (DICompositeType CTy, std::string Suffix); - void EmitFunctEndDI(const Function *F, unsigned Line); - void EmitAuxEntry(const std::string VarName, int Aux[], - int num = PIC16Dbg::AuxSize, std::string TagName = ""); - inline void EmitSymbol(std::string Name, short Class, - unsigned short Type = PIC16Dbg::T_NULL, - unsigned long Value = 0); - void EmitVarDebugInfo(Module &M); - void EmitEOF(); - }; -} // end namespace llvm; -#endif diff --git a/lib/Target/PIC16/PIC16ISelDAGToDAG.cpp b/lib/Target/PIC16/PIC16ISelDAGToDAG.cpp deleted file mode 100644 index 6cbd002..0000000 --- a/lib/Target/PIC16/PIC16ISelDAGToDAG.cpp +++ /dev/null @@ -1,50 +0,0 @@ -//===-- PIC16ISelDAGToDAG.cpp - A dag to dag inst selector for PIC16 ------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines an instruction selector for the PIC16 target. -// -//===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "pic16-isel" - -#include "llvm/Support/ErrorHandling.h" -#include "PIC16ISelDAGToDAG.h" -using namespace llvm; - -/// createPIC16ISelDag - This pass converts a legalized DAG into a -/// PIC16-specific DAG, ready for instruction scheduling. -FunctionPass *llvm::createPIC16ISelDag(PIC16TargetMachine &TM) { - return new PIC16DAGToDAGISel(TM); -} - - -/// Select - Select instructions not customized! Used for -/// expanded, promoted and normal instructions. -SDNode* PIC16DAGToDAGISel::Select(SDNode *N) { - - // Select the default instruction. - SDNode *ResNode = SelectCode(N); - - return ResNode; -} - - -// SelectDirectAddr - Match a direct address for DAG. -// A direct address could be a globaladdress or externalsymbol. -bool PIC16DAGToDAGISel::SelectDirectAddr(SDNode *Op, SDValue N, - SDValue &Address) { - // Return true if TGA or ES. - if (N.getOpcode() == ISD::TargetGlobalAddress - || N.getOpcode() == ISD::TargetExternalSymbol) { - Address = N; - return true; - } - - return false; -} diff --git a/lib/Target/PIC16/PIC16ISelDAGToDAG.h b/lib/Target/PIC16/PIC16ISelDAGToDAG.h deleted file mode 100644 index ecaddd3..0000000 --- a/lib/Target/PIC16/PIC16ISelDAGToDAG.h +++ /dev/null @@ -1,60 +0,0 @@ -//===-- PIC16ISelDAGToDAG.cpp - A dag to dag inst selector for PIC16 ------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines an instruction selector for the PIC16 target. -// -//===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "pic16-isel" - -#include "PIC16.h" -#include "PIC16RegisterInfo.h" -#include "PIC16TargetMachine.h" -#include "PIC16MachineFunctionInfo.h" -#include "llvm/CodeGen/SelectionDAGISel.h" -#include "llvm/Support/Compiler.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Support/Debug.h" -#include "llvm/Intrinsics.h" -using namespace llvm; - -namespace { - -class LLVM_LIBRARY_VISIBILITY PIC16DAGToDAGISel : public SelectionDAGISel { - - /// TM - Keep a reference to PIC16TargetMachine. - const PIC16TargetMachine &TM; - - /// PIC16Lowering - This object fully describes how to lower LLVM code to an - /// PIC16-specific SelectionDAG. - const PIC16TargetLowering &PIC16Lowering; - -public: - explicit PIC16DAGToDAGISel(PIC16TargetMachine &tm) : - SelectionDAGISel(tm), - TM(tm), PIC16Lowering(*TM.getTargetLowering()) {} - - // Pass Name - virtual const char *getPassName() const { - return "PIC16 DAG->DAG Pattern Instruction Selection"; - } - -private: - // Include the pieces autogenerated from the target description. -#include "PIC16GenDAGISel.inc" - - SDNode *Select(SDNode *N); - - // Match direct address complex pattern. - bool SelectDirectAddr(SDNode *Op, SDValue N, SDValue &Address); - -}; - -} - diff --git a/lib/Target/PIC16/PIC16ISelLowering.cpp b/lib/Target/PIC16/PIC16ISelLowering.cpp deleted file mode 100644 index 527b31d..0000000 --- a/lib/Target/PIC16/PIC16ISelLowering.cpp +++ /dev/null @@ -1,2000 +0,0 @@ -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the interfaces that PIC16 uses to lower LLVM code into a -// selection DAG. -// -//===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "pic16-lower" -#include "PIC16ABINames.h" -#include "PIC16ISelLowering.h" -#include "PIC16TargetObjectFile.h" -#include "PIC16TargetMachine.h" -#include "PIC16MachineFunctionInfo.h" -#include "llvm/DerivedTypes.h" -#include "llvm/GlobalValue.h" -#include "llvm/Function.h" -#include "llvm/CallingConv.h" -#include "llvm/CodeGen/MachineFrameInfo.h" -#include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/MachineInstrBuilder.h" -#include "llvm/CodeGen/MachineRegisterInfo.h" -#include "llvm/CodeGen/SelectionDAGISel.h" -#include "llvm/Support/ErrorHandling.h" - - -using namespace llvm; - -static const char *getIntrinsicName(unsigned opcode) { - std::string Basename; - switch(opcode) { - default: llvm_unreachable("do not know intrinsic name"); - // Arithmetic Right shift for integer types. - case PIC16ISD::SRA_I8: Basename = "sra.i8"; break; - case RTLIB::SRA_I16: Basename = "sra.i16"; break; - case RTLIB::SRA_I32: Basename = "sra.i32"; break; - - // Left shift for integer types. - case PIC16ISD::SLL_I8: Basename = "sll.i8"; break; - case RTLIB::SHL_I16: Basename = "sll.i16"; break; - case RTLIB::SHL_I32: Basename = "sll.i32"; break; - - // Logical Right Shift for integer types. - case PIC16ISD::SRL_I8: Basename = "srl.i8"; break; - case RTLIB::SRL_I16: Basename = "srl.i16"; break; - case RTLIB::SRL_I32: Basename = "srl.i32"; break; - - // Multiply for integer types. - case PIC16ISD::MUL_I8: Basename = "mul.i8"; break; - case RTLIB::MUL_I16: Basename = "mul.i16"; break; - case RTLIB::MUL_I32: Basename = "mul.i32"; break; - - // Signed division for integers. - case RTLIB::SDIV_I16: Basename = "sdiv.i16"; break; - case RTLIB::SDIV_I32: Basename = "sdiv.i32"; break; - - // Unsigned division for integers. - case RTLIB::UDIV_I16: Basename = "udiv.i16"; break; - case RTLIB::UDIV_I32: Basename = "udiv.i32"; break; - - // Signed Modulas for integers. - case RTLIB::SREM_I16: Basename = "srem.i16"; break; - case RTLIB::SREM_I32: Basename = "srem.i32"; break; - - // Unsigned Modulas for integers. - case RTLIB::UREM_I16: Basename = "urem.i16"; break; - case RTLIB::UREM_I32: Basename = "urem.i32"; break; - - ////////////////////// - // LIBCALLS FOR FLOATS - ////////////////////// - - // Float to signed integrals - case RTLIB::FPTOSINT_F32_I8: Basename = "f32_to_si32"; break; - case RTLIB::FPTOSINT_F32_I16: Basename = "f32_to_si32"; break; - case RTLIB::FPTOSINT_F32_I32: Basename = "f32_to_si32"; break; - - // Signed integrals to float. char and int are first sign extended to i32 - // before being converted to float, so an I8_F32 or I16_F32 isn't required. - case RTLIB::SINTTOFP_I32_F32: Basename = "si32_to_f32"; break; - - // Float to Unsigned conversions. - // Signed conversion can be used for unsigned conversion as well. - // In signed and unsigned versions only the interpretation of the - // MSB is different. Bit representation remains the same. - case RTLIB::FPTOUINT_F32_I8: Basename = "f32_to_si32"; break; - case RTLIB::FPTOUINT_F32_I16: Basename = "f32_to_si32"; break; - case RTLIB::FPTOUINT_F32_I32: Basename = "f32_to_si32"; break; - - // Unsigned to Float conversions. char and int are first zero extended - // before being converted to float. - case RTLIB::UINTTOFP_I32_F32: Basename = "ui32_to_f32"; break; - - // Floating point add, sub, mul, div. - case RTLIB::ADD_F32: Basename = "add.f32"; break; - case RTLIB::SUB_F32: Basename = "sub.f32"; break; - case RTLIB::MUL_F32: Basename = "mul.f32"; break; - case RTLIB::DIV_F32: Basename = "div.f32"; break; - - // Floating point comparison - case RTLIB::O_F32: Basename = "unordered.f32"; break; - case RTLIB::UO_F32: Basename = "unordered.f32"; break; - case RTLIB::OLE_F32: Basename = "le.f32"; break; - case RTLIB::OGE_F32: Basename = "ge.f32"; break; - case RTLIB::OLT_F32: Basename = "lt.f32"; break; - case RTLIB::OGT_F32: Basename = "gt.f32"; break; - case RTLIB::OEQ_F32: Basename = "eq.f32"; break; - case RTLIB::UNE_F32: Basename = "neq.f32"; break; - } - - std::string prefix = PAN::getTagName(PAN::PREFIX_SYMBOL); - std::string tagname = PAN::getTagName(PAN::LIBCALL); - std::string Fullname = prefix + tagname + Basename; - - // The name has to live through program life. - return ESNames::createESName(Fullname); -} - -// getStdLibCallName - Get the name for the standard library function. -static const char *getStdLibCallName(unsigned opcode) { - std::string BaseName; - switch(opcode) { - case RTLIB::COS_F32: BaseName = "cos"; - break; - case RTLIB::SIN_F32: BaseName = "sin"; - break; - case RTLIB::MEMCPY: BaseName = "memcpy"; - break; - case RTLIB::MEMSET: BaseName = "memset"; - break; - case RTLIB::MEMMOVE: BaseName = "memmove"; - break; - default: llvm_unreachable("do not know std lib call name"); - } - std::string prefix = PAN::getTagName(PAN::PREFIX_SYMBOL); - std::string LibCallName = prefix + BaseName; - - // The name has to live through program life. - return ESNames::createESName(LibCallName); -} - -// PIC16TargetLowering Constructor. -PIC16TargetLowering::PIC16TargetLowering(PIC16TargetMachine &TM) - : TargetLowering(TM, new PIC16TargetObjectFile()) { - - Subtarget = &TM.getSubtarget<PIC16Subtarget>(); - - addRegisterClass(MVT::i8, PIC16::GPRRegisterClass); - - setShiftAmountType(MVT::i8); - - // Std lib call names - setLibcallName(RTLIB::COS_F32, getStdLibCallName(RTLIB::COS_F32)); - setLibcallName(RTLIB::SIN_F32, getStdLibCallName(RTLIB::SIN_F32)); - setLibcallName(RTLIB::MEMCPY, getStdLibCallName(RTLIB::MEMCPY)); - setLibcallName(RTLIB::MEMSET, getStdLibCallName(RTLIB::MEMSET)); - setLibcallName(RTLIB::MEMMOVE, getStdLibCallName(RTLIB::MEMMOVE)); - - // SRA library call names - setPIC16LibcallName(PIC16ISD::SRA_I8, getIntrinsicName(PIC16ISD::SRA_I8)); - setLibcallName(RTLIB::SRA_I16, getIntrinsicName(RTLIB::SRA_I16)); - setLibcallName(RTLIB::SRA_I32, getIntrinsicName(RTLIB::SRA_I32)); - - // SHL library call names - setPIC16LibcallName(PIC16ISD::SLL_I8, getIntrinsicName(PIC16ISD::SLL_I8)); - setLibcallName(RTLIB::SHL_I16, getIntrinsicName(RTLIB::SHL_I16)); - setLibcallName(RTLIB::SHL_I32, getIntrinsicName(RTLIB::SHL_I32)); - - // SRL library call names - setPIC16LibcallName(PIC16ISD::SRL_I8, getIntrinsicName(PIC16ISD::SRL_I8)); - setLibcallName(RTLIB::SRL_I16, getIntrinsicName(RTLIB::SRL_I16)); - setLibcallName(RTLIB::SRL_I32, getIntrinsicName(RTLIB::SRL_I32)); - - // MUL Library call names - setPIC16LibcallName(PIC16ISD::MUL_I8, getIntrinsicName(PIC16ISD::MUL_I8)); - setLibcallName(RTLIB::MUL_I16, getIntrinsicName(RTLIB::MUL_I16)); - setLibcallName(RTLIB::MUL_I32, getIntrinsicName(RTLIB::MUL_I32)); - - // Signed division lib call names - setLibcallName(RTLIB::SDIV_I16, getIntrinsicName(RTLIB::SDIV_I16)); - setLibcallName(RTLIB::SDIV_I32, getIntrinsicName(RTLIB::SDIV_I32)); - - // Unsigned division lib call names - setLibcallName(RTLIB::UDIV_I16, getIntrinsicName(RTLIB::UDIV_I16)); - setLibcallName(RTLIB::UDIV_I32, getIntrinsicName(RTLIB::UDIV_I32)); - - // Signed remainder lib call names - setLibcallName(RTLIB::SREM_I16, getIntrinsicName(RTLIB::SREM_I16)); - setLibcallName(RTLIB::SREM_I32, getIntrinsicName(RTLIB::SREM_I32)); - - // Unsigned remainder lib call names - setLibcallName(RTLIB::UREM_I16, getIntrinsicName(RTLIB::UREM_I16)); - setLibcallName(RTLIB::UREM_I32, getIntrinsicName(RTLIB::UREM_I32)); - - // Floating point to signed int conversions. - setLibcallName(RTLIB::FPTOSINT_F32_I8, - getIntrinsicName(RTLIB::FPTOSINT_F32_I8)); - setLibcallName(RTLIB::FPTOSINT_F32_I16, - getIntrinsicName(RTLIB::FPTOSINT_F32_I16)); - setLibcallName(RTLIB::FPTOSINT_F32_I32, - getIntrinsicName(RTLIB::FPTOSINT_F32_I32)); - - // Signed int to floats. - setLibcallName(RTLIB::SINTTOFP_I32_F32, - getIntrinsicName(RTLIB::SINTTOFP_I32_F32)); - - // Floating points to unsigned ints. - setLibcallName(RTLIB::FPTOUINT_F32_I8, - getIntrinsicName(RTLIB::FPTOUINT_F32_I8)); - setLibcallName(RTLIB::FPTOUINT_F32_I16, - getIntrinsicName(RTLIB::FPTOUINT_F32_I16)); - setLibcallName(RTLIB::FPTOUINT_F32_I32, - getIntrinsicName(RTLIB::FPTOUINT_F32_I32)); - - // Unsigned int to floats. - setLibcallName(RTLIB::UINTTOFP_I32_F32, - getIntrinsicName(RTLIB::UINTTOFP_I32_F32)); - - // Floating point add, sub, mul ,div. - setLibcallName(RTLIB::ADD_F32, getIntrinsicName(RTLIB::ADD_F32)); - setLibcallName(RTLIB::SUB_F32, getIntrinsicName(RTLIB::SUB_F32)); - setLibcallName(RTLIB::MUL_F32, getIntrinsicName(RTLIB::MUL_F32)); - setLibcallName(RTLIB::DIV_F32, getIntrinsicName(RTLIB::DIV_F32)); - - // Floationg point comparison - setLibcallName(RTLIB::O_F32, getIntrinsicName(RTLIB::O_F32)); - setLibcallName(RTLIB::UO_F32, getIntrinsicName(RTLIB::UO_F32)); - setLibcallName(RTLIB::OLE_F32, getIntrinsicName(RTLIB::OLE_F32)); - setLibcallName(RTLIB::OGE_F32, getIntrinsicName(RTLIB::OGE_F32)); - setLibcallName(RTLIB::OLT_F32, getIntrinsicName(RTLIB::OLT_F32)); - setLibcallName(RTLIB::OGT_F32, getIntrinsicName(RTLIB::OGT_F32)); - setLibcallName(RTLIB::OEQ_F32, getIntrinsicName(RTLIB::OEQ_F32)); - setLibcallName(RTLIB::UNE_F32, getIntrinsicName(RTLIB::UNE_F32)); - - // Return value comparisons of floating point calls. - setCmpLibcallCC(RTLIB::OEQ_F32, ISD::SETNE); - setCmpLibcallCC(RTLIB::UNE_F32, ISD::SETNE); - setCmpLibcallCC(RTLIB::OLT_F32, ISD::SETNE); - setCmpLibcallCC(RTLIB::OLE_F32, ISD::SETNE); - setCmpLibcallCC(RTLIB::OGE_F32, ISD::SETNE); - setCmpLibcallCC(RTLIB::OGT_F32, ISD::SETNE); - setCmpLibcallCC(RTLIB::UO_F32, ISD::SETNE); - setCmpLibcallCC(RTLIB::O_F32, ISD::SETEQ); - - setOperationAction(ISD::GlobalAddress, MVT::i16, Custom); - setOperationAction(ISD::ExternalSymbol, MVT::i16, Custom); - - setOperationAction(ISD::LOAD, MVT::i8, Legal); - setOperationAction(ISD::LOAD, MVT::i16, Custom); - setOperationAction(ISD::LOAD, MVT::i32, Custom); - - setOperationAction(ISD::STORE, MVT::i8, Legal); - setOperationAction(ISD::STORE, MVT::i16, Custom); - setOperationAction(ISD::STORE, MVT::i32, Custom); - setOperationAction(ISD::STORE, MVT::i64, Custom); - - setOperationAction(ISD::ADDE, MVT::i8, Custom); - setOperationAction(ISD::ADDC, MVT::i8, Custom); - setOperationAction(ISD::SUBE, MVT::i8, Custom); - setOperationAction(ISD::SUBC, MVT::i8, Custom); - setOperationAction(ISD::SUB, MVT::i8, Custom); - setOperationAction(ISD::ADD, MVT::i8, Custom); - setOperationAction(ISD::ADD, MVT::i16, Custom); - - setOperationAction(ISD::OR, MVT::i8, Custom); - setOperationAction(ISD::AND, MVT::i8, Custom); - setOperationAction(ISD::XOR, MVT::i8, Custom); - - setOperationAction(ISD::FrameIndex, MVT::i16, Custom); - - setOperationAction(ISD::MUL, MVT::i8, Custom); - - setOperationAction(ISD::SMUL_LOHI, MVT::i8, Expand); - setOperationAction(ISD::UMUL_LOHI, MVT::i8, Expand); - setOperationAction(ISD::MULHU, MVT::i8, Expand); - setOperationAction(ISD::MULHS, MVT::i8, Expand); - - setOperationAction(ISD::SRA, MVT::i8, Custom); - setOperationAction(ISD::SHL, MVT::i8, Custom); - setOperationAction(ISD::SRL, MVT::i8, Custom); - - setOperationAction(ISD::ROTL, MVT::i8, Expand); - setOperationAction(ISD::ROTR, MVT::i8, Expand); - - setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand); - - // PIC16 does not support shift parts - setOperationAction(ISD::SRA_PARTS, MVT::i8, Expand); - setOperationAction(ISD::SHL_PARTS, MVT::i8, Expand); - setOperationAction(ISD::SRL_PARTS, MVT::i8, Expand); - - - // PIC16 does not have a SETCC, expand it to SELECT_CC. - setOperationAction(ISD::SETCC, MVT::i8, Expand); - setOperationAction(ISD::SELECT, MVT::i8, Expand); - setOperationAction(ISD::BRCOND, MVT::Other, Expand); - setOperationAction(ISD::BRIND, MVT::Other, Expand); - - setOperationAction(ISD::SELECT_CC, MVT::i8, Custom); - setOperationAction(ISD::BR_CC, MVT::i8, Custom); - - //setOperationAction(ISD::TRUNCATE, MVT::i16, Custom); - setTruncStoreAction(MVT::i16, MVT::i8, Custom); - - // Now deduce the information based on the above mentioned - // actions - computeRegisterProperties(); -} - -std::pair<const TargetRegisterClass*, uint8_t> -PIC16TargetLowering::findRepresentativeClass(EVT VT) const { - switch (VT.getSimpleVT().SimpleTy) { - default: - return TargetLowering::findRepresentativeClass(VT); - case MVT::i16: - return std::make_pair(PIC16::FSR16RegisterClass, 1); - } -} - -// getOutFlag - Extract the flag result if the Op has it. -static SDValue getOutFlag(SDValue &Op) { - // Flag is the last value of the node. - SDValue Flag = Op.getValue(Op.getNode()->getNumValues() - 1); - - assert (Flag.getValueType() == MVT::Flag - && "Node does not have an out Flag"); - - return Flag; -} -// Get the TmpOffset for FrameIndex -unsigned PIC16TargetLowering::GetTmpOffsetForFI(unsigned FI, unsigned size, - MachineFunction &MF) const { - PIC16MachineFunctionInfo *FuncInfo = MF.getInfo<PIC16MachineFunctionInfo>(); - std::map<unsigned, unsigned> &FiTmpOffsetMap = FuncInfo->getFiTmpOffsetMap(); - - std::map<unsigned, unsigned>::iterator - MapIt = FiTmpOffsetMap.find(FI); - if (MapIt != FiTmpOffsetMap.end()) - return MapIt->second; - - // This FI (FrameIndex) is not yet mapped, so map it - FiTmpOffsetMap[FI] = FuncInfo->getTmpSize(); - FuncInfo->setTmpSize(FuncInfo->getTmpSize() + size); - return FiTmpOffsetMap[FI]; -} - -void PIC16TargetLowering::ResetTmpOffsetMap(SelectionDAG &DAG) const { - MachineFunction &MF = DAG.getMachineFunction(); - PIC16MachineFunctionInfo *FuncInfo = MF.getInfo<PIC16MachineFunctionInfo>(); - FuncInfo->getFiTmpOffsetMap().clear(); - FuncInfo->setTmpSize(0); -} - -// To extract chain value from the SDValue Nodes -// This function will help to maintain the chain extracting -// code at one place. In case of any change in future it will -// help maintain the code. -static SDValue getChain(SDValue &Op) { - SDValue Chain = Op.getValue(Op.getNode()->getNumValues() - 1); - - // If the last value returned in Flag then the chain is - // second last value returned. - if (Chain.getValueType() == MVT::Flag) - Chain = Op.getValue(Op.getNode()->getNumValues() - 2); - - // All nodes may not produce a chain. Therefore following assert - // verifies that the node is returning a chain only. - assert (Chain.getValueType() == MVT::Other - && "Node does not have a chain"); - - return Chain; -} - -/// PopulateResults - Helper function to LowerOperation. -/// If a node wants to return multiple results after lowering, -/// it stuffs them into an array of SDValue called Results. - -static void PopulateResults(SDValue N, SmallVectorImpl<SDValue>&Results) { - if (N.getOpcode() == ISD::MERGE_VALUES) { - int NumResults = N.getNumOperands(); - for( int i = 0; i < NumResults; i++) - Results.push_back(N.getOperand(i)); - } - else - Results.push_back(N); -} - -MVT::SimpleValueType -PIC16TargetLowering::getSetCCResultType(EVT ValType) const { - return MVT::i8; -} - -MVT::SimpleValueType -PIC16TargetLowering::getCmpLibcallReturnType() const { - return MVT::i8; -} - -/// The type legalizer framework of generating legalizer can generate libcalls -/// only when the operand/result types are illegal. -/// PIC16 needs to generate libcalls even for the legal types (i8) for some ops. -/// For example an arithmetic right shift. These functions are used to lower -/// such operations that generate libcall for legal types. - -void -PIC16TargetLowering::setPIC16LibcallName(PIC16ISD::PIC16Libcall Call, - const char *Name) { - PIC16LibcallNames[Call] = Name; -} - -const char * -PIC16TargetLowering::getPIC16LibcallName(PIC16ISD::PIC16Libcall Call) const { - return PIC16LibcallNames[Call]; -} - -SDValue -PIC16TargetLowering::MakePIC16Libcall(PIC16ISD::PIC16Libcall Call, - EVT RetVT, const SDValue *Ops, - unsigned NumOps, bool isSigned, - SelectionDAG &DAG, DebugLoc dl) const { - - TargetLowering::ArgListTy Args; - Args.reserve(NumOps); - - TargetLowering::ArgListEntry Entry; - for (unsigned i = 0; i != NumOps; ++i) { - Entry.Node = Ops[i]; - Entry.Ty = Entry.Node.getValueType().getTypeForEVT(*DAG.getContext()); - Entry.isSExt = isSigned; - Entry.isZExt = !isSigned; - Args.push_back(Entry); - } - - SDValue Callee = DAG.getExternalSymbol(getPIC16LibcallName(Call), MVT::i16); - - const Type *RetTy = RetVT.getTypeForEVT(*DAG.getContext()); - std::pair<SDValue,SDValue> CallInfo = - LowerCallTo(DAG.getEntryNode(), RetTy, isSigned, !isSigned, false, - false, 0, CallingConv::C, false, - /*isReturnValueUsed=*/true, - Callee, Args, DAG, dl); - - return CallInfo.first; -} - -const char *PIC16TargetLowering::getTargetNodeName(unsigned Opcode) const { - switch (Opcode) { - default: return NULL; - case PIC16ISD::Lo: return "PIC16ISD::Lo"; - case PIC16ISD::Hi: return "PIC16ISD::Hi"; - case PIC16ISD::MTLO: return "PIC16ISD::MTLO"; - case PIC16ISD::MTHI: return "PIC16ISD::MTHI"; - case PIC16ISD::MTPCLATH: return "PIC16ISD::MTPCLATH"; - case PIC16ISD::PIC16Connect: return "PIC16ISD::PIC16Connect"; - case PIC16ISD::Banksel: return "PIC16ISD::Banksel"; - case PIC16ISD::PIC16Load: return "PIC16ISD::PIC16Load"; - case PIC16ISD::PIC16LdArg: return "PIC16ISD::PIC16LdArg"; - case PIC16ISD::PIC16LdWF: return "PIC16ISD::PIC16LdWF"; - case PIC16ISD::PIC16Store: return "PIC16ISD::PIC16Store"; - case PIC16ISD::PIC16StWF: return "PIC16ISD::PIC16StWF"; - case PIC16ISD::BCF: return "PIC16ISD::BCF"; - case PIC16ISD::LSLF: return "PIC16ISD::LSLF"; - case PIC16ISD::LRLF: return "PIC16ISD::LRLF"; - case PIC16ISD::RLF: return "PIC16ISD::RLF"; - case PIC16ISD::RRF: return "PIC16ISD::RRF"; - case PIC16ISD::CALL: return "PIC16ISD::CALL"; - case PIC16ISD::CALLW: return "PIC16ISD::CALLW"; - case PIC16ISD::SUBCC: return "PIC16ISD::SUBCC"; - case PIC16ISD::SELECT_ICC: return "PIC16ISD::SELECT_ICC"; - case PIC16ISD::BRCOND: return "PIC16ISD::BRCOND"; - case PIC16ISD::RET: return "PIC16ISD::RET"; - case PIC16ISD::Dummy: return "PIC16ISD::Dummy"; - } -} - -void PIC16TargetLowering::ReplaceNodeResults(SDNode *N, - SmallVectorImpl<SDValue>&Results, - SelectionDAG &DAG) const { - - switch (N->getOpcode()) { - case ISD::GlobalAddress: - Results.push_back(ExpandGlobalAddress(N, DAG)); - return; - case ISD::ExternalSymbol: - Results.push_back(ExpandExternalSymbol(N, DAG)); - return; - case ISD::STORE: - Results.push_back(ExpandStore(N, DAG)); - return; - case ISD::LOAD: - PopulateResults(ExpandLoad(N, DAG), Results); - return; - case ISD::ADD: - // Results.push_back(ExpandAdd(N, DAG)); - return; - case ISD::FrameIndex: - Results.push_back(ExpandFrameIndex(N, DAG)); - return; - default: - assert (0 && "not implemented"); - return; - } -} - -SDValue PIC16TargetLowering::ExpandFrameIndex(SDNode *N, - SelectionDAG &DAG) const { - - // Currently handling FrameIndex of size MVT::i16 only - // One example of this scenario is when return value is written on - // FrameIndex#0 - - if (N->getValueType(0) != MVT::i16) - return SDValue(); - - // Expand the FrameIndex into ExternalSymbol and a Constant node - // The constant will represent the frame index number - // Get the current function frame - MachineFunction &MF = DAG.getMachineFunction(); - const Function *Func = MF.getFunction(); - const std::string Name = Func->getName(); - - FrameIndexSDNode *FR = dyn_cast<FrameIndexSDNode>(SDValue(N,0)); - // FIXME there isn't really debug info here - DebugLoc dl = FR->getDebugLoc(); - - // Expand FrameIndex like GlobalAddress and ExternalSymbol - // Also use Offset field for lo and hi parts. The default - // offset is zero. - - SDValue ES; - int FrameOffset; - SDValue FI = SDValue(N,0); - LegalizeFrameIndex(FI, DAG, ES, FrameOffset); - SDValue Offset = DAG.getConstant(FrameOffset, MVT::i8); - SDValue Lo = DAG.getNode(PIC16ISD::Lo, dl, MVT::i8, ES, Offset); - SDValue Hi = DAG.getNode(PIC16ISD::Hi, dl, MVT::i8, ES, Offset); - return DAG.getNode(ISD::BUILD_PAIR, dl, N->getValueType(0), Lo, Hi); -} - - -SDValue PIC16TargetLowering::ExpandStore(SDNode *N, SelectionDAG &DAG) const { - StoreSDNode *St = cast<StoreSDNode>(N); - SDValue Chain = St->getChain(); - SDValue Src = St->getValue(); - SDValue Ptr = St->getBasePtr(); - EVT ValueType = Src.getValueType(); - unsigned StoreOffset = 0; - DebugLoc dl = N->getDebugLoc(); - - SDValue PtrLo, PtrHi; - LegalizeAddress(Ptr, DAG, PtrLo, PtrHi, StoreOffset, dl); - - if (ValueType == MVT::i8) { - return DAG.getNode (PIC16ISD::PIC16Store, dl, MVT::Other, Chain, Src, - PtrLo, PtrHi, - DAG.getConstant (0 + StoreOffset, MVT::i8)); - } - else if (ValueType == MVT::i16) { - // Get the Lo and Hi parts from MERGE_VALUE or BUILD_PAIR. - SDValue SrcLo, SrcHi; - GetExpandedParts(Src, DAG, SrcLo, SrcHi); - SDValue ChainLo = Chain, ChainHi = Chain; - // FIXME: This makes unsafe assumptions. The Chain may be a TokenFactor - // created for an unrelated purpose, in which case it may not have - // exactly two operands. Also, even if it does have two operands, they - // may not be the low and high parts of an aligned load that was split. - if (Chain.getOpcode() == ISD::TokenFactor) { - ChainLo = Chain.getOperand(0); - ChainHi = Chain.getOperand(1); - } - SDValue Store1 = DAG.getNode(PIC16ISD::PIC16Store, dl, MVT::Other, - ChainLo, - SrcLo, PtrLo, PtrHi, - DAG.getConstant (0 + StoreOffset, MVT::i8)); - - SDValue Store2 = DAG.getNode(PIC16ISD::PIC16Store, dl, MVT::Other, ChainHi, - SrcHi, PtrLo, PtrHi, - DAG.getConstant (1 + StoreOffset, MVT::i8)); - - return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, getChain(Store1), - getChain(Store2)); - } - else if (ValueType == MVT::i32) { - // Get the Lo and Hi parts from MERGE_VALUE or BUILD_PAIR. - SDValue SrcLo, SrcHi; - GetExpandedParts(Src, DAG, SrcLo, SrcHi); - - // Get the expanded parts of each of SrcLo and SrcHi. - SDValue SrcLo1, SrcLo2, SrcHi1, SrcHi2; - GetExpandedParts(SrcLo, DAG, SrcLo1, SrcLo2); - GetExpandedParts(SrcHi, DAG, SrcHi1, SrcHi2); - - SDValue ChainLo = Chain, ChainHi = Chain; - // FIXME: This makes unsafe assumptions; see the FIXME above. - if (Chain.getOpcode() == ISD::TokenFactor) { - ChainLo = Chain.getOperand(0); - ChainHi = Chain.getOperand(1); - } - SDValue ChainLo1 = ChainLo, ChainLo2 = ChainLo, ChainHi1 = ChainHi, - ChainHi2 = ChainHi; - // FIXME: This makes unsafe assumptions; see the FIXME above. - if (ChainLo.getOpcode() == ISD::TokenFactor) { - ChainLo1 = ChainLo.getOperand(0); - ChainLo2 = ChainLo.getOperand(1); - } - // FIXME: This makes unsafe assumptions; see the FIXME above. - if (ChainHi.getOpcode() == ISD::TokenFactor) { - ChainHi1 = ChainHi.getOperand(0); - ChainHi2 = ChainHi.getOperand(1); - } - SDValue Store1 = DAG.getNode(PIC16ISD::PIC16Store, dl, MVT::Other, - ChainLo1, - SrcLo1, PtrLo, PtrHi, - DAG.getConstant (0 + StoreOffset, MVT::i8)); - - SDValue Store2 = DAG.getNode(PIC16ISD::PIC16Store, dl, MVT::Other, ChainLo2, - SrcLo2, PtrLo, PtrHi, - DAG.getConstant (1 + StoreOffset, MVT::i8)); - - SDValue Store3 = DAG.getNode(PIC16ISD::PIC16Store, dl, MVT::Other, ChainHi1, - SrcHi1, PtrLo, PtrHi, - DAG.getConstant (2 + StoreOffset, MVT::i8)); - - SDValue Store4 = DAG.getNode(PIC16ISD::PIC16Store, dl, MVT::Other, ChainHi2, - SrcHi2, PtrLo, PtrHi, - DAG.getConstant (3 + StoreOffset, MVT::i8)); - - SDValue RetLo = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, - getChain(Store1), getChain(Store2)); - SDValue RetHi = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, - getChain(Store3), getChain(Store4)); - return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, RetLo, RetHi); - - } else if (ValueType == MVT::i64) { - SDValue SrcLo, SrcHi; - GetExpandedParts(Src, DAG, SrcLo, SrcHi); - SDValue ChainLo = Chain, ChainHi = Chain; - // FIXME: This makes unsafe assumptions; see the FIXME above. - if (Chain.getOpcode() == ISD::TokenFactor) { - ChainLo = Chain.getOperand(0); - ChainHi = Chain.getOperand(1); - } - SDValue Store1 = DAG.getStore(ChainLo, dl, SrcLo, Ptr, NULL, - 0 + StoreOffset, false, false, 0); - - Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, - DAG.getConstant(4, Ptr.getValueType())); - SDValue Store2 = DAG.getStore(ChainHi, dl, SrcHi, Ptr, NULL, - 1 + StoreOffset, false, false, 0); - - return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Store1, - Store2); - } else { - assert (0 && "value type not supported"); - return SDValue(); - } -} - -SDValue PIC16TargetLowering::ExpandExternalSymbol(SDNode *N, - SelectionDAG &DAG) - const { - ExternalSymbolSDNode *ES = dyn_cast<ExternalSymbolSDNode>(SDValue(N, 0)); - // FIXME there isn't really debug info here - DebugLoc dl = ES->getDebugLoc(); - - SDValue TES = DAG.getTargetExternalSymbol(ES->getSymbol(), MVT::i8); - SDValue Offset = DAG.getConstant(0, MVT::i8); - SDValue Lo = DAG.getNode(PIC16ISD::Lo, dl, MVT::i8, TES, Offset); - SDValue Hi = DAG.getNode(PIC16ISD::Hi, dl, MVT::i8, TES, Offset); - - return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i16, Lo, Hi); -} - -// ExpandGlobalAddress - -SDValue PIC16TargetLowering::ExpandGlobalAddress(SDNode *N, - SelectionDAG &DAG) const { - GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(SDValue(N, 0)); - // FIXME there isn't really debug info here - DebugLoc dl = G->getDebugLoc(); - - SDValue TGA = DAG.getTargetGlobalAddress(G->getGlobal(), N->getDebugLoc(), - MVT::i8, - G->getOffset()); - - SDValue Offset = DAG.getConstant(0, MVT::i8); - SDValue Lo = DAG.getNode(PIC16ISD::Lo, dl, MVT::i8, TGA, Offset); - SDValue Hi = DAG.getNode(PIC16ISD::Hi, dl, MVT::i8, TGA, Offset); - - return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i16, Lo, Hi); -} - -bool PIC16TargetLowering::isDirectAddress(const SDValue &Op) const { - assert (Op.getNode() != NULL && "Can't operate on NULL SDNode!!"); - - if (Op.getOpcode() == ISD::BUILD_PAIR) { - if (Op.getOperand(0).getOpcode() == PIC16ISD::Lo) - return true; - } - return false; -} - -// Return true if DirectAddress is in ROM_SPACE -bool PIC16TargetLowering::isRomAddress(const SDValue &Op) const { - - // RomAddress is a GlobalAddress in ROM_SPACE_ - // If the Op is not a GlobalAddress return NULL without checking - // anything further. - if (!isDirectAddress(Op)) - return false; - - // Its a GlobalAddress. - // It is BUILD_PAIR((PIC16Lo TGA), (PIC16Hi TGA)) and Op is BUILD_PAIR - SDValue TGA = Op.getOperand(0).getOperand(0); - GlobalAddressSDNode *GSDN = dyn_cast<GlobalAddressSDNode>(TGA); - - if (GSDN->getAddressSpace() == PIC16ISD::ROM_SPACE) - return true; - - // Any other address space return it false - return false; -} - - -// GetExpandedParts - This function is on the similiar lines as -// the GetExpandedInteger in type legalizer is. This returns expanded -// parts of Op in Lo and Hi. - -void PIC16TargetLowering::GetExpandedParts(SDValue Op, SelectionDAG &DAG, - SDValue &Lo, SDValue &Hi) const { - SDNode *N = Op.getNode(); - DebugLoc dl = N->getDebugLoc(); - EVT NewVT = getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); - - // Extract the lo component. - Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, NewVT, Op, - DAG.getConstant(0, MVT::i8)); - - // extract the hi component - Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, NewVT, Op, - DAG.getConstant(1, MVT::i8)); -} - -// Legalize FrameIndex into ExternalSymbol and offset. -void -PIC16TargetLowering::LegalizeFrameIndex(SDValue Op, SelectionDAG &DAG, - SDValue &ES, int &Offset) const { - - MachineFunction &MF = DAG.getMachineFunction(); - const Function *Func = MF.getFunction(); - MachineFrameInfo *MFI = MF.getFrameInfo(); - PIC16MachineFunctionInfo *FuncInfo = MF.getInfo<PIC16MachineFunctionInfo>(); - const std::string Name = Func->getName(); - - FrameIndexSDNode *FR = dyn_cast<FrameIndexSDNode>(Op); - - // FrameIndices are not stack offsets. But they represent the request - // for space on stack. That space requested may be more than one byte. - // Therefore, to calculate the stack offset that a FrameIndex aligns - // with, we need to traverse all the FrameIndices available earlier in - // the list and add their requested size. - unsigned FIndex = FR->getIndex(); - const char *tmpName; - if (FIndex < FuncInfo->getReservedFrameCount()) { - tmpName = ESNames::createESName(PAN::getFrameLabel(Name)); - ES = DAG.getTargetExternalSymbol(tmpName, MVT::i8); - Offset = 0; - for (unsigned i=0; i<FIndex ; ++i) { - Offset += MFI->getObjectSize(i); - } - } else { - // FrameIndex has been made for some temporary storage - tmpName = ESNames::createESName(PAN::getTempdataLabel(Name)); - ES = DAG.getTargetExternalSymbol(tmpName, MVT::i8); - Offset = GetTmpOffsetForFI(FIndex, MFI->getObjectSize(FIndex), MF); - } - - return; -} - -// This function legalizes the PIC16 Addresses. If the Pointer is -// -- Direct address variable residing -// --> then a Banksel for that variable will be created. -// -- Rom variable -// --> then it will be treated as an indirect address. -// -- Indirect address -// --> then the address will be loaded into FSR -// -- ADD with constant operand -// --> then constant operand of ADD will be returned as Offset -// and non-constant operand of ADD will be treated as pointer. -// Returns the high and lo part of the address, and the offset(in case of ADD). - -void PIC16TargetLowering::LegalizeAddress(SDValue Ptr, SelectionDAG &DAG, - SDValue &Lo, SDValue &Hi, - unsigned &Offset, DebugLoc dl) const { - - // Offset, by default, should be 0 - Offset = 0; - - // If the pointer is ADD with constant, - // return the constant value as the offset - if (Ptr.getOpcode() == ISD::ADD) { - SDValue OperLeft = Ptr.getOperand(0); - SDValue OperRight = Ptr.getOperand(1); - if ((OperLeft.getOpcode() == ISD::Constant) && - (dyn_cast<ConstantSDNode>(OperLeft)->getZExtValue() < 32 )) { - Offset = dyn_cast<ConstantSDNode>(OperLeft)->getZExtValue(); - Ptr = OperRight; - } else if ((OperRight.getOpcode() == ISD::Constant) && - (dyn_cast<ConstantSDNode>(OperRight)->getZExtValue() < 32 )){ - Offset = dyn_cast<ConstantSDNode>(OperRight)->getZExtValue(); - Ptr = OperLeft; - } - } - - // If the pointer is Type i8 and an external symbol - // then treat it as direct address. - // One example for such case is storing and loading - // from function frame during a call - if (Ptr.getValueType() == MVT::i8) { - switch (Ptr.getOpcode()) { - case ISD::TargetExternalSymbol: - Lo = Ptr; - Hi = DAG.getConstant(1, MVT::i8); - return; - } - } - - // Expansion of FrameIndex has Lo/Hi parts - if (isDirectAddress(Ptr)) { - SDValue TFI = Ptr.getOperand(0).getOperand(0); - int FrameOffset; - if (TFI.getOpcode() == ISD::TargetFrameIndex) { - LegalizeFrameIndex(TFI, DAG, Lo, FrameOffset); - Hi = DAG.getConstant(1, MVT::i8); - Offset += FrameOffset; - return; - } else if (TFI.getOpcode() == ISD::TargetExternalSymbol) { - // FrameIndex has already been expanded. - // Now just make use of its expansion - Lo = TFI; - Hi = DAG.getConstant(1, MVT::i8); - SDValue FOffset = Ptr.getOperand(0).getOperand(1); - assert (FOffset.getOpcode() == ISD::Constant && - "Invalid operand of PIC16ISD::Lo"); - Offset += dyn_cast<ConstantSDNode>(FOffset)->getZExtValue(); - return; - } - } - - if (isDirectAddress(Ptr) && !isRomAddress(Ptr)) { - // Direct addressing case for RAM variables. The Hi part is constant - // and the Lo part is the TGA itself. - Lo = Ptr.getOperand(0).getOperand(0); - - // For direct addresses Hi is a constant. Value 1 for the constant - // signifies that banksel needs to generated for it. Value 0 for - // the constant signifies that banksel does not need to be generated - // for it. Mark it as 1 now and optimize later. - Hi = DAG.getConstant(1, MVT::i8); - return; - } - - // Indirect addresses. Get the hi and lo parts of ptr. - GetExpandedParts(Ptr, DAG, Lo, Hi); - - // Put the hi and lo parts into FSR. - Lo = DAG.getNode(PIC16ISD::MTLO, dl, MVT::i8, Lo); - Hi = DAG.getNode(PIC16ISD::MTHI, dl, MVT::i8, Hi); - - return; -} - -SDValue PIC16TargetLowering::ExpandLoad(SDNode *N, SelectionDAG &DAG) const { - LoadSDNode *LD = dyn_cast<LoadSDNode>(SDValue(N, 0)); - SDValue Chain = LD->getChain(); - SDValue Ptr = LD->getBasePtr(); - DebugLoc dl = LD->getDebugLoc(); - - SDValue Load, Offset; - SDVTList Tys; - EVT VT, NewVT; - SDValue PtrLo, PtrHi; - unsigned LoadOffset; - - // Legalize direct/indirect addresses. This will give the lo and hi parts - // of the address and the offset. - LegalizeAddress(Ptr, DAG, PtrLo, PtrHi, LoadOffset, dl); - - // Load from the pointer (direct address or FSR) - VT = N->getValueType(0); - unsigned NumLoads = VT.getSizeInBits() / 8; - std::vector<SDValue> PICLoads; - unsigned iter; - EVT MemVT = LD->getMemoryVT(); - if(ISD::isNON_EXTLoad(N)) { - for (iter=0; iter<NumLoads ; ++iter) { - // Add the pointer offset if any - Offset = DAG.getConstant(iter + LoadOffset, MVT::i8); - Tys = DAG.getVTList(MVT::i8, MVT::Other); - Load = DAG.getNode(PIC16ISD::PIC16Load, dl, Tys, Chain, PtrLo, PtrHi, - Offset); - PICLoads.push_back(Load); - } - } else { - // If it is extended load then use PIC16Load for Memory Bytes - // and for all extended bytes perform action based on type of - // extention - i.e. SignExtendedLoad or ZeroExtendedLoad - - - // For extended loads this is the memory value type - // i.e. without any extension - EVT MemVT = LD->getMemoryVT(); - unsigned MemBytes = MemVT.getSizeInBits() / 8; - // if MVT::i1 is extended to MVT::i8 then MemBytes will be zero - // So set it to one - if (MemBytes == 0) MemBytes = 1; - - unsigned ExtdBytes = VT.getSizeInBits() / 8; - Offset = DAG.getConstant(LoadOffset, MVT::i8); - - Tys = DAG.getVTList(MVT::i8, MVT::Other); - // For MemBytes generate PIC16Load with proper offset - for (iter=0; iter < MemBytes; ++iter) { - // Add the pointer offset if any - Offset = DAG.getConstant(iter + LoadOffset, MVT::i8); - Load = DAG.getNode(PIC16ISD::PIC16Load, dl, Tys, Chain, PtrLo, PtrHi, - Offset); - PICLoads.push_back(Load); - } - - // For SignExtendedLoad - if (ISD::isSEXTLoad(N)) { - // For all ExtdBytes use the Right Shifted(Arithmetic) Value of the - // highest MemByte - SDValue SRA = DAG.getNode(ISD::SRA, dl, MVT::i8, Load, - DAG.getConstant(7, MVT::i8)); - for (iter=MemBytes; iter<ExtdBytes; ++iter) { - PICLoads.push_back(SRA); - } - } else if (ISD::isZEXTLoad(N) || ISD::isEXTLoad(N)) { - //} else if (ISD::isZEXTLoad(N)) { - // ZeroExtendedLoad -- For all ExtdBytes use constant 0 - SDValue ConstZero = DAG.getConstant(0, MVT::i8); - for (iter=MemBytes; iter<ExtdBytes; ++iter) { - PICLoads.push_back(ConstZero); - } - } - } - SDValue BP; - - if (VT == MVT::i8) { - // Operand of Load is illegal -- Load itself is legal - return PICLoads[0]; - } - else if (VT == MVT::i16) { - BP = DAG.getNode(ISD::BUILD_PAIR, dl, VT, PICLoads[0], PICLoads[1]); - if ((MemVT == MVT::i8) || (MemVT == MVT::i1)) - Chain = getChain(PICLoads[0]); - else - Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, - getChain(PICLoads[0]), getChain(PICLoads[1])); - } else if (VT == MVT::i32) { - SDValue BPs[2]; - BPs[0] = DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i16, - PICLoads[0], PICLoads[1]); - BPs[1] = DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i16, - PICLoads[2], PICLoads[3]); - BP = DAG.getNode(ISD::BUILD_PAIR, dl, VT, BPs[0], BPs[1]); - if ((MemVT == MVT::i8) || (MemVT == MVT::i1)) - Chain = getChain(PICLoads[0]); - else if (MemVT == MVT::i16) - Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, - getChain(PICLoads[0]), getChain(PICLoads[1])); - else { - SDValue Chains[2]; - Chains[0] = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, - getChain(PICLoads[0]), getChain(PICLoads[1])); - Chains[1] = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, - getChain(PICLoads[2]), getChain(PICLoads[3])); - Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, - Chains[0], Chains[1]); - } - } - Tys = DAG.getVTList(VT, MVT::Other); - return DAG.getNode(ISD::MERGE_VALUES, dl, Tys, BP, Chain); -} - -SDValue PIC16TargetLowering::LowerShift(SDValue Op, SelectionDAG &DAG) const { - // We should have handled larger operands in type legalizer itself. - assert (Op.getValueType() == MVT::i8 && "illegal shift to lower"); - - SDNode *N = Op.getNode(); - SDValue Value = N->getOperand(0); - SDValue Amt = N->getOperand(1); - PIC16ISD::PIC16Libcall CallCode; - switch (N->getOpcode()) { - case ISD::SRA: - CallCode = PIC16ISD::SRA_I8; - break; - case ISD::SHL: - CallCode = PIC16ISD::SLL_I8; - break; - case ISD::SRL: - CallCode = PIC16ISD::SRL_I8; - break; - default: - assert ( 0 && "This shift is not implemented yet."); - return SDValue(); - } - SmallVector<SDValue, 2> Ops(2); - Ops[0] = Value; - Ops[1] = Amt; - SDValue Call = MakePIC16Libcall(CallCode, N->getValueType(0), &Ops[0], 2, - true, DAG, N->getDebugLoc()); - return Call; -} - -SDValue PIC16TargetLowering::LowerMUL(SDValue Op, SelectionDAG &DAG) const { - // We should have handled larger operands in type legalizer itself. - assert (Op.getValueType() == MVT::i8 && "illegal multiply to lower"); - - SDNode *N = Op.getNode(); - SmallVector<SDValue, 2> Ops(2); - Ops[0] = N->getOperand(0); - Ops[1] = N->getOperand(1); - SDValue Call = MakePIC16Libcall(PIC16ISD::MUL_I8, N->getValueType(0), - &Ops[0], 2, true, DAG, N->getDebugLoc()); - return Call; -} - -void -PIC16TargetLowering::LowerOperationWrapper(SDNode *N, - SmallVectorImpl<SDValue>&Results, - SelectionDAG &DAG) const { - SDValue Op = SDValue(N, 0); - SDValue Res; - unsigned i; - switch (Op.getOpcode()) { - case ISD::LOAD: - Res = ExpandLoad(Op.getNode(), DAG); break; - default: { - // All other operations are handled in LowerOperation. - Res = LowerOperation(Op, DAG); - if (Res.getNode()) - Results.push_back(Res); - - return; - } - } - - N = Res.getNode(); - unsigned NumValues = N->getNumValues(); - for (i = 0; i < NumValues ; i++) { - Results.push_back(SDValue(N, i)); - } -} - -SDValue PIC16TargetLowering::LowerOperation(SDValue Op, - SelectionDAG &DAG) const { - switch (Op.getOpcode()) { - case ISD::ADD: - case ISD::ADDC: - case ISD::ADDE: - return LowerADD(Op, DAG); - case ISD::SUB: - case ISD::SUBC: - case ISD::SUBE: - return LowerSUB(Op, DAG); - case ISD::LOAD: - return ExpandLoad(Op.getNode(), DAG); - case ISD::STORE: - return ExpandStore(Op.getNode(), DAG); - case ISD::MUL: - return LowerMUL(Op, DAG); - case ISD::SHL: - case ISD::SRA: - case ISD::SRL: - return LowerShift(Op, DAG); - case ISD::OR: - case ISD::AND: - case ISD::XOR: - return LowerBinOp(Op, DAG); - case ISD::BR_CC: - return LowerBR_CC(Op, DAG); - case ISD::SELECT_CC: - return LowerSELECT_CC(Op, DAG); - } - return SDValue(); -} - -SDValue PIC16TargetLowering::ConvertToMemOperand(SDValue Op, - SelectionDAG &DAG, - DebugLoc dl) const { - assert (Op.getValueType() == MVT::i8 - && "illegal value type to store on stack."); - - MachineFunction &MF = DAG.getMachineFunction(); - const Function *Func = MF.getFunction(); - const std::string FuncName = Func->getName(); - - - // Put the value on stack. - // Get a stack slot index and convert to es. - int FI = MF.getFrameInfo()->CreateStackObject(1, 1, false); - const char *tmpName = ESNames::createESName(PAN::getTempdataLabel(FuncName)); - SDValue ES = DAG.getTargetExternalSymbol(tmpName, MVT::i8); - - // Store the value to ES. - SDValue Store = DAG.getNode (PIC16ISD::PIC16Store, dl, MVT::Other, - DAG.getEntryNode(), - Op, ES, - DAG.getConstant (1, MVT::i8), // Banksel. - DAG.getConstant (GetTmpOffsetForFI(FI, 1, MF), - MVT::i8)); - - // Load the value from ES. - SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Other); - SDValue Load = DAG.getNode(PIC16ISD::PIC16Load, dl, Tys, Store, - ES, DAG.getConstant (1, MVT::i8), - DAG.getConstant (GetTmpOffsetForFI(FI, 1, MF), - MVT::i8)); - - return Load.getValue(0); -} - -SDValue PIC16TargetLowering:: -LowerIndirectCallArguments(SDValue Chain, SDValue InFlag, - SDValue DataAddr_Lo, SDValue DataAddr_Hi, - const SmallVectorImpl<ISD::OutputArg> &Outs, - const SmallVectorImpl<SDValue> &OutVals, - const SmallVectorImpl<ISD::InputArg> &Ins, - DebugLoc dl, SelectionDAG &DAG) const { - unsigned NumOps = Outs.size(); - - // If call has no arguments then do nothing and return. - if (NumOps == 0) - return Chain; - - std::vector<SDValue> Ops; - SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Flag); - SDValue Arg, StoreRet; - - // For PIC16 ABI the arguments come after the return value. - unsigned RetVals = Ins.size(); - for (unsigned i = 0, ArgOffset = RetVals; i < NumOps; i++) { - // Get the arguments - Arg = OutVals[i]; - - Ops.clear(); - Ops.push_back(Chain); - Ops.push_back(Arg); - Ops.push_back(DataAddr_Lo); - Ops.push_back(DataAddr_Hi); - Ops.push_back(DAG.getConstant(ArgOffset, MVT::i8)); - Ops.push_back(InFlag); - - StoreRet = DAG.getNode (PIC16ISD::PIC16StWF, dl, Tys, &Ops[0], Ops.size()); - - Chain = getChain(StoreRet); - InFlag = getOutFlag(StoreRet); - ArgOffset++; - } - return Chain; -} - -SDValue PIC16TargetLowering:: -LowerDirectCallArguments(SDValue ArgLabel, SDValue Chain, SDValue InFlag, - const SmallVectorImpl<ISD::OutputArg> &Outs, - const SmallVectorImpl<SDValue> &OutVals, - DebugLoc dl, SelectionDAG &DAG) const { - unsigned NumOps = Outs.size(); - std::string Name; - SDValue Arg, StoreAt; - EVT ArgVT; - unsigned Size=0; - - // If call has no arguments then do nothing and return. - if (NumOps == 0) - return Chain; - - // FIXME: This portion of code currently assumes only - // primitive types being passed as arguments. - - // Legalize the address before use - SDValue PtrLo, PtrHi; - unsigned AddressOffset; - int StoreOffset = 0; - LegalizeAddress(ArgLabel, DAG, PtrLo, PtrHi, AddressOffset, dl); - SDValue StoreRet; - - std::vector<SDValue> Ops; - SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Flag); - for (unsigned i=0, Offset = 0; i<NumOps; i++) { - // Get the argument - Arg = OutVals[i]; - StoreOffset = (Offset + AddressOffset); - - // Store the argument on frame - - Ops.clear(); - Ops.push_back(Chain); - Ops.push_back(Arg); - Ops.push_back(PtrLo); - Ops.push_back(PtrHi); - Ops.push_back(DAG.getConstant(StoreOffset, MVT::i8)); - Ops.push_back(InFlag); - - StoreRet = DAG.getNode (PIC16ISD::PIC16StWF, dl, Tys, &Ops[0], Ops.size()); - - Chain = getChain(StoreRet); - InFlag = getOutFlag(StoreRet); - - // Update the frame offset to be used for next argument - ArgVT = Arg.getValueType(); - Size = ArgVT.getSizeInBits(); - Size = Size/8; // Calculate size in bytes - Offset += Size; // Increase the frame offset - } - return Chain; -} - -SDValue PIC16TargetLowering:: -LowerIndirectCallReturn(SDValue Chain, SDValue InFlag, - SDValue DataAddr_Lo, SDValue DataAddr_Hi, - const SmallVectorImpl<ISD::InputArg> &Ins, - DebugLoc dl, SelectionDAG &DAG, - SmallVectorImpl<SDValue> &InVals) const { - unsigned RetVals = Ins.size(); - - // If call does not have anything to return - // then do nothing and go back. - if (RetVals == 0) - return Chain; - - // Call has something to return - SDValue LoadRet; - - SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Other, MVT::Flag); - for(unsigned i=0;i<RetVals;i++) { - LoadRet = DAG.getNode(PIC16ISD::PIC16LdWF, dl, Tys, Chain, DataAddr_Lo, - DataAddr_Hi, DAG.getConstant(i, MVT::i8), - InFlag); - InFlag = getOutFlag(LoadRet); - Chain = getChain(LoadRet); - InVals.push_back(LoadRet); - } - return Chain; -} - -SDValue PIC16TargetLowering:: -LowerDirectCallReturn(SDValue RetLabel, SDValue Chain, SDValue InFlag, - const SmallVectorImpl<ISD::InputArg> &Ins, - DebugLoc dl, SelectionDAG &DAG, - SmallVectorImpl<SDValue> &InVals) const { - - // Currently handling primitive types only. They will come in - // i8 parts - unsigned RetVals = Ins.size(); - - // Return immediately if the return type is void - if (RetVals == 0) - return Chain; - - // Call has something to return - - // Legalize the address before use - SDValue LdLo, LdHi; - unsigned LdOffset; - LegalizeAddress(RetLabel, DAG, LdLo, LdHi, LdOffset, dl); - - SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Other, MVT::Flag); - SDValue LoadRet; - - for(unsigned i=0, Offset=0;i<RetVals;i++) { - - LoadRet = DAG.getNode(PIC16ISD::PIC16LdWF, dl, Tys, Chain, LdLo, LdHi, - DAG.getConstant(LdOffset + Offset, MVT::i8), - InFlag); - - InFlag = getOutFlag(LoadRet); - - Chain = getChain(LoadRet); - Offset++; - InVals.push_back(LoadRet); - } - - return Chain; -} - -SDValue -PIC16TargetLowering::LowerReturn(SDValue Chain, - CallingConv::ID CallConv, bool isVarArg, - const SmallVectorImpl<ISD::OutputArg> &Outs, - const SmallVectorImpl<SDValue> &OutVals, - DebugLoc dl, SelectionDAG &DAG) const { - - // Number of values to return - unsigned NumRet = Outs.size(); - - // Function returns value always on stack with the offset starting - // from 0 - MachineFunction &MF = DAG.getMachineFunction(); - const Function *F = MF.getFunction(); - std::string FuncName = F->getName(); - - const char *tmpName = ESNames::createESName(PAN::getFrameLabel(FuncName)); - SDValue ES = DAG.getTargetExternalSymbol(tmpName, MVT::i8); - SDValue BS = DAG.getConstant(1, MVT::i8); - SDValue RetVal; - for(unsigned i=0;i<NumRet; ++i) { - RetVal = OutVals[i]; - Chain = DAG.getNode (PIC16ISD::PIC16Store, dl, MVT::Other, Chain, RetVal, - ES, BS, - DAG.getConstant (i, MVT::i8)); - - } - return DAG.getNode(PIC16ISD::RET, dl, MVT::Other, Chain); -} - -void PIC16TargetLowering:: -GetDataAddress(DebugLoc dl, SDValue Callee, SDValue &Chain, - SDValue &DataAddr_Lo, SDValue &DataAddr_Hi, - SelectionDAG &DAG) const { - assert (Callee.getOpcode() == PIC16ISD::PIC16Connect - && "Don't know what to do of such callee!!"); - SDValue ZeroOperand = DAG.getConstant(0, MVT::i8); - SDValue SeqStart = DAG.getCALLSEQ_START(Chain, ZeroOperand); - Chain = getChain(SeqStart); - SDValue OperFlag = getOutFlag(SeqStart); // To manage the data dependency - - // Get the Lo and Hi part of code address - SDValue Lo = Callee.getOperand(0); - SDValue Hi = Callee.getOperand(1); - - SDValue Data_Lo, Data_Hi; - SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Other, MVT::Flag); - // Subtract 2 from Address to get the Lower part of DataAddress. - SDVTList VTList = DAG.getVTList(MVT::i8, MVT::Flag); - Data_Lo = DAG.getNode(ISD::SUBC, dl, VTList, Lo, - DAG.getConstant(2, MVT::i8)); - SDValue Ops[3] = { Hi, DAG.getConstant(0, MVT::i8), Data_Lo.getValue(1)}; - Data_Hi = DAG.getNode(ISD::SUBE, dl, VTList, Ops, 3); - SDValue PCLATH = DAG.getNode(PIC16ISD::MTPCLATH, dl, MVT::i8, Data_Hi); - Callee = DAG.getNode(PIC16ISD::PIC16Connect, dl, MVT::i8, Data_Lo, PCLATH); - SDValue Call = DAG.getNode(PIC16ISD::CALLW, dl, Tys, Chain, Callee, - OperFlag); - Chain = getChain(Call); - OperFlag = getOutFlag(Call); - SDValue SeqEnd = DAG.getCALLSEQ_END(Chain, ZeroOperand, ZeroOperand, - OperFlag); - Chain = getChain(SeqEnd); - OperFlag = getOutFlag(SeqEnd); - - // Low part of Data Address - DataAddr_Lo = DAG.getNode(PIC16ISD::MTLO, dl, MVT::i8, Call, OperFlag); - - // Make the second call. - SeqStart = DAG.getCALLSEQ_START(Chain, ZeroOperand); - Chain = getChain(SeqStart); - OperFlag = getOutFlag(SeqStart); // To manage the data dependency - - // Subtract 1 from Address to get high part of data address. - Data_Lo = DAG.getNode(ISD::SUBC, dl, VTList, Lo, - DAG.getConstant(1, MVT::i8)); - SDValue HiOps[3] = { Hi, DAG.getConstant(0, MVT::i8), Data_Lo.getValue(1)}; - Data_Hi = DAG.getNode(ISD::SUBE, dl, VTList, HiOps, 3); - PCLATH = DAG.getNode(PIC16ISD::MTPCLATH, dl, MVT::i8, Data_Hi); - - // Use new Lo to make another CALLW - Callee = DAG.getNode(PIC16ISD::PIC16Connect, dl, MVT::i8, Data_Lo, PCLATH); - Call = DAG.getNode(PIC16ISD::CALLW, dl, Tys, Chain, Callee, OperFlag); - Chain = getChain(Call); - OperFlag = getOutFlag(Call); - SeqEnd = DAG.getCALLSEQ_END(Chain, ZeroOperand, ZeroOperand, - OperFlag); - Chain = getChain(SeqEnd); - OperFlag = getOutFlag(SeqEnd); - // Hi part of Data Address - DataAddr_Hi = DAG.getNode(PIC16ISD::MTHI, dl, MVT::i8, Call, OperFlag); -} - -SDValue -PIC16TargetLowering::LowerCall(SDValue Chain, SDValue Callee, - CallingConv::ID CallConv, bool isVarArg, - bool &isTailCall, - const SmallVectorImpl<ISD::OutputArg> &Outs, - const SmallVectorImpl<SDValue> &OutVals, - const SmallVectorImpl<ISD::InputArg> &Ins, - DebugLoc dl, SelectionDAG &DAG, - SmallVectorImpl<SDValue> &InVals) const { - // PIC16 target does not yet support tail call optimization. - isTailCall = false; - - assert(Callee.getValueType() == MVT::i16 && - "Don't know how to legalize this call node!!!"); - - // The flag to track if this is a direct or indirect call. - bool IsDirectCall = true; - unsigned RetVals = Ins.size(); - unsigned NumArgs = Outs.size(); - - SDValue DataAddr_Lo, DataAddr_Hi; - if (!isa<GlobalAddressSDNode>(Callee) && - !isa<ExternalSymbolSDNode>(Callee)) { - IsDirectCall = false; // This is indirect call - - // If this is an indirect call then to pass the arguments - // and read the return value back, we need the data address - // of the function being called. - // To get the data address two more calls need to be made. - - // Come here for indirect calls - SDValue Lo, Hi; - // Indirect addresses. Get the hi and lo parts of ptr. - GetExpandedParts(Callee, DAG, Lo, Hi); - // Connect Lo and Hi parts of the callee with the PIC16Connect - Callee = DAG.getNode(PIC16ISD::PIC16Connect, dl, MVT::i8, Lo, Hi); - - // Read DataAddress only if we have to pass arguments or - // read return value. - if ((RetVals > 0) || (NumArgs > 0)) - GetDataAddress(dl, Callee, Chain, DataAddr_Lo, DataAddr_Hi, DAG); - } - - SDValue ZeroOperand = DAG.getConstant(0, MVT::i8); - - // Start the call sequence. - // Carring the Constant 0 along the CALLSEQSTART - // because there is nothing else to carry. - SDValue SeqStart = DAG.getCALLSEQ_START(Chain, ZeroOperand); - Chain = getChain(SeqStart); - SDValue OperFlag = getOutFlag(SeqStart); // To manage the data dependency - std::string Name; - - // For any direct call - callee will be GlobalAddressNode or - // ExternalSymbol - SDValue ArgLabel, RetLabel; - if (IsDirectCall) { - // Considering the GlobalAddressNode case here. - if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) { - const GlobalValue *GV = G->getGlobal(); - Callee = DAG.getTargetGlobalAddress(GV, dl, MVT::i8); - Name = G->getGlobal()->getName(); - } else {// Considering the ExternalSymbol case here - ExternalSymbolSDNode *ES = dyn_cast<ExternalSymbolSDNode>(Callee); - Callee = DAG.getTargetExternalSymbol(ES->getSymbol(), MVT::i8); - Name = ES->getSymbol(); - } - - // Label for argument passing - const char *argFrame = ESNames::createESName(PAN::getArgsLabel(Name)); - ArgLabel = DAG.getTargetExternalSymbol(argFrame, MVT::i8); - - // Label for reading return value - const char *retName = ESNames::createESName(PAN::getRetvalLabel(Name)); - RetLabel = DAG.getTargetExternalSymbol(retName, MVT::i8); - } else { - // if indirect call - SDValue CodeAddr_Lo = Callee.getOperand(0); - SDValue CodeAddr_Hi = Callee.getOperand(1); - - /*CodeAddr_Lo = DAG.getNode(ISD::ADD, dl, MVT::i8, CodeAddr_Lo, - DAG.getConstant(2, MVT::i8));*/ - - // move Hi part in PCLATH - CodeAddr_Hi = DAG.getNode(PIC16ISD::MTPCLATH, dl, MVT::i8, CodeAddr_Hi); - Callee = DAG.getNode(PIC16ISD::PIC16Connect, dl, MVT::i8, CodeAddr_Lo, - CodeAddr_Hi); - } - - // Pass the argument to function before making the call. - SDValue CallArgs; - if (IsDirectCall) { - CallArgs = LowerDirectCallArguments(ArgLabel, Chain, OperFlag, - Outs, OutVals, dl, DAG); - Chain = getChain(CallArgs); - OperFlag = getOutFlag(CallArgs); - } else { - CallArgs = LowerIndirectCallArguments(Chain, OperFlag, DataAddr_Lo, - DataAddr_Hi, Outs, OutVals, Ins, - dl, DAG); - Chain = getChain(CallArgs); - OperFlag = getOutFlag(CallArgs); - } - - SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Flag); - SDValue PICCall = DAG.getNode(PIC16ISD::CALL, dl, Tys, Chain, Callee, - OperFlag); - Chain = getChain(PICCall); - OperFlag = getOutFlag(PICCall); - - - // Carrying the Constant 0 along the CALLSEQSTART - // because there is nothing else to carry. - SDValue SeqEnd = DAG.getCALLSEQ_END(Chain, ZeroOperand, ZeroOperand, - OperFlag); - Chain = getChain(SeqEnd); - OperFlag = getOutFlag(SeqEnd); - - // Lower the return value reading after the call. - if (IsDirectCall) - return LowerDirectCallReturn(RetLabel, Chain, OperFlag, - Ins, dl, DAG, InVals); - else - return LowerIndirectCallReturn(Chain, OperFlag, DataAddr_Lo, - DataAddr_Hi, Ins, dl, DAG, InVals); -} - -bool PIC16TargetLowering::isDirectLoad(const SDValue Op) const { - if (Op.getOpcode() == PIC16ISD::PIC16Load) - if (Op.getOperand(1).getOpcode() == ISD::TargetGlobalAddress - || Op.getOperand(1).getOpcode() == ISD::TargetExternalSymbol) - return true; - return false; -} - -// NeedToConvertToMemOp - Returns true if one of the operands of the -// operation 'Op' needs to be put into memory. Also returns the -// operand no. of the operand to be converted in 'MemOp'. Remember, PIC16 has -// no instruction that can operation on two registers. Most insns take -// one register and one memory operand (addwf) / Constant (addlw). -bool PIC16TargetLowering::NeedToConvertToMemOp(SDValue Op, unsigned &MemOp, - SelectionDAG &DAG) const { - // If one of the operand is a constant, return false. - if (Op.getOperand(0).getOpcode() == ISD::Constant || - Op.getOperand(1).getOpcode() == ISD::Constant) - return false; - - // Return false if one of the operands is already a direct - // load and that operand has only one use. - if (isDirectLoad(Op.getOperand(0))) { - if (Op.getOperand(0).hasOneUse()) { - // Legal and profitable folding check uses the NodeId of DAG nodes. - // This NodeId is assigned by topological order. Therefore first - // assign topological order then perform legal and profitable check. - // Note:- Though this ordering is done before begining with legalization, - // newly added node during legalization process have NodeId=-1 (NewNode) - // therefore before performing any check proper ordering of the node is - // required. - DAG.AssignTopologicalOrder(); - - // Direct load operands are folded in binary operations. But before folding - // verify if this folding is legal. Fold only if it is legal otherwise - // convert this direct load to a separate memory operation. - if (SelectionDAGISel::IsLegalToFold(Op.getOperand(0), - Op.getNode(), Op.getNode(), - CodeGenOpt::Default)) - return false; - else - MemOp = 0; - } - } - - // For operations that are non-cummutative there is no need to check - // for right operand because folding right operand may result in - // incorrect operation. - if (! SelectionDAG::isCommutativeBinOp(Op.getOpcode())) - return true; - - if (isDirectLoad(Op.getOperand(1))) { - if (Op.getOperand(1).hasOneUse()) { - // Legal and profitable folding check uses the NodeId of DAG nodes. - // This NodeId is assigned by topological order. Therefore first - // assign topological order then perform legal and profitable check. - // Note:- Though this ordering is done before begining with legalization, - // newly added node during legalization process have NodeId=-1 (NewNode) - // therefore before performing any check proper ordering of the node is - // required. - DAG.AssignTopologicalOrder(); - - // Direct load operands are folded in binary operations. But before folding - // verify if this folding is legal. Fold only if it is legal otherwise - // convert this direct load to a separate memory operation. - if (SelectionDAGISel::IsLegalToFold(Op.getOperand(1), - Op.getNode(), Op.getNode(), - CodeGenOpt::Default)) - return false; - else - MemOp = 1; - } - } - return true; -} - -// LowerBinOp - Lower a commutative binary operation that does not -// affect status flag carry. -SDValue PIC16TargetLowering::LowerBinOp(SDValue Op, SelectionDAG &DAG) const { - DebugLoc dl = Op.getDebugLoc(); - - // We should have handled larger operands in type legalizer itself. - assert (Op.getValueType() == MVT::i8 && "illegal Op to lower"); - - unsigned MemOp = 1; - if (NeedToConvertToMemOp(Op, MemOp, DAG)) { - // Put one value on stack. - SDValue NewVal = ConvertToMemOperand (Op.getOperand(MemOp), DAG, dl); - - return DAG.getNode(Op.getOpcode(), dl, MVT::i8, Op.getOperand(MemOp ^ 1), - NewVal); - } - else { - return Op; - } -} - -// LowerADD - Lower all types of ADD operations including the ones -// that affects carry. -SDValue PIC16TargetLowering::LowerADD(SDValue Op, SelectionDAG &DAG) const { - // We should have handled larger operands in type legalizer itself. - assert (Op.getValueType() == MVT::i8 && "illegal add to lower"); - DebugLoc dl = Op.getDebugLoc(); - unsigned MemOp = 1; - if (NeedToConvertToMemOp(Op, MemOp, DAG)) { - // Put one value on stack. - SDValue NewVal = ConvertToMemOperand (Op.getOperand(MemOp), DAG, dl); - - // ADDC and ADDE produce two results. - SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Flag); - - // ADDE has three operands, the last one is the carry bit. - if (Op.getOpcode() == ISD::ADDE) - return DAG.getNode(Op.getOpcode(), dl, Tys, Op.getOperand(MemOp ^ 1), - NewVal, Op.getOperand(2)); - // ADDC has two operands. - else if (Op.getOpcode() == ISD::ADDC) - return DAG.getNode(Op.getOpcode(), dl, Tys, Op.getOperand(MemOp ^ 1), - NewVal); - // ADD it is. It produces only one result. - else - return DAG.getNode(Op.getOpcode(), dl, MVT::i8, Op.getOperand(MemOp ^ 1), - NewVal); - } - else - return Op; -} - -SDValue PIC16TargetLowering::LowerSUB(SDValue Op, SelectionDAG &DAG) const { - DebugLoc dl = Op.getDebugLoc(); - // We should have handled larger operands in type legalizer itself. - assert (Op.getValueType() == MVT::i8 && "illegal sub to lower"); - unsigned MemOp = 1; - SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Flag); - - // Since we don't have an instruction for X - c , - // we can change it to X + (-c) - ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op.getOperand(1)); - if (C && (Op.getOpcode() == ISD::SUB)) - { - return DAG.getNode(ISD::ADD, - dl, MVT::i8, Op.getOperand(0), - DAG.getConstant(0-(C->getZExtValue()), MVT::i8)); - } - - if (NeedToConvertToMemOp(Op, MemOp, DAG) || - (isDirectLoad(Op.getOperand(1)) && - (!isDirectLoad(Op.getOperand(0))) && - (Op.getOperand(0).getOpcode() != ISD::Constant))) - { - // Put first operand on stack. - SDValue NewVal = ConvertToMemOperand (Op.getOperand(0), DAG, dl); - - switch (Op.getOpcode()) { - default: - assert (0 && "Opcode unknown."); - case ISD::SUBE: - return DAG.getNode(Op.getOpcode(), - dl, Tys, NewVal, Op.getOperand(1), - Op.getOperand(2)); - break; - case ISD::SUBC: - return DAG.getNode(Op.getOpcode(), - dl, Tys, NewVal, Op.getOperand(1)); - break; - case ISD::SUB: - return DAG.getNode(Op.getOpcode(), - dl, MVT::i8, NewVal, Op.getOperand(1)); - break; - } - } - else - return Op; -} - -void PIC16TargetLowering::InitReservedFrameCount(const Function *F, - SelectionDAG &DAG) const { - MachineFunction &MF = DAG.getMachineFunction(); - PIC16MachineFunctionInfo *FuncInfo = MF.getInfo<PIC16MachineFunctionInfo>(); - - unsigned NumArgs = F->arg_size(); - - bool isVoidFunc = (F->getReturnType()->getTypeID() == Type::VoidTyID); - - if (isVoidFunc) - FuncInfo->setReservedFrameCount(NumArgs); - else - FuncInfo->setReservedFrameCount(NumArgs + 1); -} - -// LowerFormalArguments - Argument values are loaded from the -// <fname>.args + offset. All arguments are already broken to leaglized -// types, so the offset just runs from 0 to NumArgVals - 1. - -SDValue -PIC16TargetLowering::LowerFormalArguments(SDValue Chain, - CallingConv::ID CallConv, - bool isVarArg, - const SmallVectorImpl<ISD::InputArg> &Ins, - DebugLoc dl, - SelectionDAG &DAG, - SmallVectorImpl<SDValue> &InVals) - const { - unsigned NumArgVals = Ins.size(); - - // Get the callee's name to create the <fname>.args label to pass args. - MachineFunction &MF = DAG.getMachineFunction(); - const Function *F = MF.getFunction(); - std::string FuncName = F->getName(); - - // Reset the map of FI and TmpOffset - ResetTmpOffsetMap(DAG); - // Initialize the ReserveFrameCount - InitReservedFrameCount(F, DAG); - - // Create the <fname>.args external symbol. - const char *tmpName = ESNames::createESName(PAN::getArgsLabel(FuncName)); - SDValue ES = DAG.getTargetExternalSymbol(tmpName, MVT::i8); - - // Load arg values from the label + offset. - SDVTList VTs = DAG.getVTList (MVT::i8, MVT::Other); - SDValue BS = DAG.getConstant(1, MVT::i8); - for (unsigned i = 0; i < NumArgVals ; ++i) { - SDValue Offset = DAG.getConstant(i, MVT::i8); - SDValue PICLoad = DAG.getNode(PIC16ISD::PIC16LdArg, dl, VTs, Chain, ES, BS, - Offset); - Chain = getChain(PICLoad); - InVals.push_back(PICLoad); - } - - return Chain; -} - -// Perform DAGCombine of PIC16Load. -// FIXME - Need a more elaborate comment here. -SDValue PIC16TargetLowering:: -PerformPIC16LoadCombine(SDNode *N, DAGCombinerInfo &DCI) const { - SelectionDAG &DAG = DCI.DAG; - SDValue Chain = N->getOperand(0); - if (N->hasNUsesOfValue(0, 0)) { - DAG.ReplaceAllUsesOfValueWith(SDValue(N,1), Chain); - } - return SDValue(); -} - -// For all the functions with arguments some STORE nodes are generated -// that store the argument on the frameindex. However in PIC16 the arguments -// are passed on stack only. Therefore these STORE nodes are redundant. -// To remove these STORE nodes will be removed in PerformStoreCombine -// -// Currently this function is doint nothing and will be updated for removing -// unwanted store operations -SDValue PIC16TargetLowering:: -PerformStoreCombine(SDNode *N, DAGCombinerInfo &DCI) const { - return SDValue(N, 0); - /* - // Storing an undef value is of no use, so remove it - if (isStoringUndef(N, Chain, DAG)) { - return Chain; // remove the store and return the chain - } - //else everything is ok. - return SDValue(N, 0); - */ -} - -SDValue PIC16TargetLowering::PerformDAGCombine(SDNode *N, - DAGCombinerInfo &DCI) const { - switch (N->getOpcode()) { - case ISD::STORE: - return PerformStoreCombine(N, DCI); - case PIC16ISD::PIC16Load: - return PerformPIC16LoadCombine(N, DCI); - } - return SDValue(); -} - -static PIC16CC::CondCodes IntCCToPIC16CC(ISD::CondCode CC) { - switch (CC) { - default: llvm_unreachable("Unknown condition code!"); - case ISD::SETNE: return PIC16CC::NE; - case ISD::SETEQ: return PIC16CC::EQ; - case ISD::SETGT: return PIC16CC::GT; - case ISD::SETGE: return PIC16CC::GE; - case ISD::SETLT: return PIC16CC::LT; - case ISD::SETLE: return PIC16CC::LE; - case ISD::SETULT: return PIC16CC::ULT; - case ISD::SETULE: return PIC16CC::ULE; - case ISD::SETUGE: return PIC16CC::UGE; - case ISD::SETUGT: return PIC16CC::UGT; - } -} - -// Look at LHS/RHS/CC and see if they are a lowered setcc instruction. If so -// set LHS/RHS and SPCC to the LHS/RHS of the setcc and SPCC to the condition. -static void LookThroughSetCC(SDValue &LHS, SDValue &RHS, - ISD::CondCode CC, unsigned &SPCC) { - if (isa<ConstantSDNode>(RHS) && - cast<ConstantSDNode>(RHS)->isNullValue() && - CC == ISD::SETNE && - (LHS.getOpcode() == PIC16ISD::SELECT_ICC && - LHS.getOperand(3).getOpcode() == PIC16ISD::SUBCC) && - isa<ConstantSDNode>(LHS.getOperand(0)) && - isa<ConstantSDNode>(LHS.getOperand(1)) && - cast<ConstantSDNode>(LHS.getOperand(0))->isOne() && - cast<ConstantSDNode>(LHS.getOperand(1))->isNullValue()) { - SDValue CMPCC = LHS.getOperand(3); - SPCC = cast<ConstantSDNode>(LHS.getOperand(2))->getZExtValue(); - LHS = CMPCC.getOperand(0); - RHS = CMPCC.getOperand(1); - } -} - -// Returns appropriate CMP insn and corresponding condition code in PIC16CC -SDValue PIC16TargetLowering::getPIC16Cmp(SDValue LHS, SDValue RHS, - unsigned CC, SDValue &PIC16CC, - SelectionDAG &DAG, DebugLoc dl) const { - PIC16CC::CondCodes CondCode = (PIC16CC::CondCodes) CC; - - // PIC16 sub is literal - W. So Swap the operands and condition if needed. - // i.e. a < 12 can be rewritten as 12 > a. - if (RHS.getOpcode() == ISD::Constant) { - - SDValue Tmp = LHS; - LHS = RHS; - RHS = Tmp; - - switch (CondCode) { - default: break; - case PIC16CC::LT: - CondCode = PIC16CC::GT; - break; - case PIC16CC::GT: - CondCode = PIC16CC::LT; - break; - case PIC16CC::ULT: - CondCode = PIC16CC::UGT; - break; - case PIC16CC::UGT: - CondCode = PIC16CC::ULT; - break; - case PIC16CC::GE: - CondCode = PIC16CC::LE; - break; - case PIC16CC::LE: - CondCode = PIC16CC::GE; - break; - case PIC16CC::ULE: - CondCode = PIC16CC::UGE; - break; - case PIC16CC::UGE: - CondCode = PIC16CC::ULE; - break; - } - } - - PIC16CC = DAG.getConstant(CondCode, MVT::i8); - - // These are signed comparisons. - SDValue Mask = DAG.getConstant(128, MVT::i8); - if (isSignedComparison(CondCode)) { - LHS = DAG.getNode (ISD::XOR, dl, MVT::i8, LHS, Mask); - RHS = DAG.getNode (ISD::XOR, dl, MVT::i8, RHS, Mask); - } - - SDVTList VTs = DAG.getVTList (MVT::i8, MVT::Flag); - // We can use a subtract operation to set the condition codes. But - // we need to put one operand in memory if required. - // Nothing to do if the first operand is already a valid type (direct load - // for subwf and literal for sublw) and it is used by this operation only. - if ((LHS.getOpcode() == ISD::Constant || isDirectLoad(LHS)) - && LHS.hasOneUse()) - return DAG.getNode(PIC16ISD::SUBCC, dl, VTs, LHS, RHS); - - // else convert the first operand to mem. - LHS = ConvertToMemOperand (LHS, DAG, dl); - return DAG.getNode(PIC16ISD::SUBCC, dl, VTs, LHS, RHS); -} - - -SDValue PIC16TargetLowering::LowerSELECT_CC(SDValue Op, - SelectionDAG &DAG) const { - SDValue LHS = Op.getOperand(0); - SDValue RHS = Op.getOperand(1); - ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get(); - SDValue TrueVal = Op.getOperand(2); - SDValue FalseVal = Op.getOperand(3); - unsigned ORIGCC = ~0; - DebugLoc dl = Op.getDebugLoc(); - - // If this is a select_cc of a "setcc", and if the setcc got lowered into - // an CMP[IF]CC/SELECT_[IF]CC pair, find the original compared values. - // i.e. - // A setcc: lhs, rhs, cc is expanded by llvm to - // select_cc: result of setcc, 0, 1, 0, setne - // We can think of it as: - // select_cc: lhs, rhs, 1, 0, cc - LookThroughSetCC(LHS, RHS, CC, ORIGCC); - if (ORIGCC == ~0U) ORIGCC = IntCCToPIC16CC (CC); - - SDValue PIC16CC; - SDValue Cmp = getPIC16Cmp(LHS, RHS, ORIGCC, PIC16CC, DAG, dl); - - return DAG.getNode (PIC16ISD::SELECT_ICC, dl, TrueVal.getValueType(), TrueVal, - FalseVal, PIC16CC, Cmp.getValue(1)); -} - -MachineBasicBlock * -PIC16TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, - MachineBasicBlock *BB) const { - const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo(); - unsigned CC = (PIC16CC::CondCodes)MI->getOperand(3).getImm(); - DebugLoc dl = MI->getDebugLoc(); - - // To "insert" a SELECT_CC instruction, we actually have to insert the diamond - // control-flow pattern. The incoming instruction knows the destination vreg - // to set, the condition code register to branch on, the true/false values to - // select between, and a branch opcode to use. - const BasicBlock *LLVM_BB = BB->getBasicBlock(); - MachineFunction::iterator It = BB; - ++It; - - // thisMBB: - // ... - // TrueVal = ... - // [f]bCC copy1MBB - // fallthrough --> copy0MBB - MachineBasicBlock *thisMBB = BB; - MachineFunction *F = BB->getParent(); - MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB); - MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB); - BuildMI(BB, dl, TII.get(PIC16::pic16brcond)).addMBB(sinkMBB).addImm(CC); - F->insert(It, copy0MBB); - F->insert(It, sinkMBB); - - // Transfer the remainder of BB and its successor edges to sinkMBB. - sinkMBB->splice(sinkMBB->begin(), BB, - llvm::next(MachineBasicBlock::iterator(MI)), - BB->end()); - sinkMBB->transferSuccessorsAndUpdatePHIs(BB); - - // Next, add the true and fallthrough blocks as its successors. - BB->addSuccessor(copy0MBB); - BB->addSuccessor(sinkMBB); - - // copy0MBB: - // %FalseValue = ... - // # fallthrough to sinkMBB - BB = copy0MBB; - - // Update machine-CFG edges - BB->addSuccessor(sinkMBB); - - // sinkMBB: - // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ] - // ... - BB = sinkMBB; - BuildMI(*BB, BB->begin(), dl, - TII.get(PIC16::PHI), MI->getOperand(0).getReg()) - .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB) - .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB); - - MI->eraseFromParent(); // The pseudo instruction is gone now. - return BB; -} - - -SDValue PIC16TargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const { - SDValue Chain = Op.getOperand(0); - ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get(); - SDValue LHS = Op.getOperand(2); // LHS of the condition. - SDValue RHS = Op.getOperand(3); // RHS of the condition. - SDValue Dest = Op.getOperand(4); // BB to jump to - unsigned ORIGCC = ~0; - DebugLoc dl = Op.getDebugLoc(); - - // If this is a br_cc of a "setcc", and if the setcc got lowered into - // an CMP[IF]CC/SELECT_[IF]CC pair, find the original compared values. - LookThroughSetCC(LHS, RHS, CC, ORIGCC); - if (ORIGCC == ~0U) ORIGCC = IntCCToPIC16CC (CC); - - // Get the Compare insn and condition code. - SDValue PIC16CC; - SDValue Cmp = getPIC16Cmp(LHS, RHS, ORIGCC, PIC16CC, DAG, dl); - - return DAG.getNode(PIC16ISD::BRCOND, dl, MVT::Other, Chain, Dest, PIC16CC, - Cmp.getValue(1)); -} - diff --git a/lib/Target/PIC16/PIC16ISelLowering.h b/lib/Target/PIC16/PIC16ISelLowering.h deleted file mode 100644 index d942af4..0000000 --- a/lib/Target/PIC16/PIC16ISelLowering.h +++ /dev/null @@ -1,253 +0,0 @@ -//===-- PIC16ISelLowering.h - PIC16 DAG Lowering Interface ------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the interfaces that PIC16 uses to lower LLVM code into a -// selection DAG. -// -//===----------------------------------------------------------------------===// - -#ifndef PIC16ISELLOWERING_H -#define PIC16ISELLOWERING_H - -#include "PIC16.h" -#include "PIC16Subtarget.h" -#include "llvm/CodeGen/SelectionDAG.h" -#include "llvm/Target/TargetLowering.h" -#include <map> - -namespace llvm { - namespace PIC16ISD { - enum NodeType { - // Start the numbering from where ISD NodeType finishes. - FIRST_NUMBER = ISD::BUILTIN_OP_END, - - Lo, // Low 8-bits of GlobalAddress. - Hi, // High 8-bits of GlobalAddress. - PIC16Load, - PIC16LdArg, // This is replica of PIC16Load but used to load function - // arguments and is being used for facilitating for some - // store removal optimizations. - - PIC16LdWF, - PIC16Store, - PIC16StWF, - Banksel, - MTLO, // Move to low part of FSR - MTHI, // Move to high part of FSR - MTPCLATH, // Move to PCLATCH - PIC16Connect, // General connector for PIC16 nodes - BCF, - LSLF, // PIC16 Logical shift left - LRLF, // PIC16 Logical shift right - RLF, // Rotate left through carry - RRF, // Rotate right through carry - CALL, // PIC16 Call instruction - CALLW, // PIC16 CALLW instruction - SUBCC, // Compare for equality or inequality. - SELECT_ICC, // Pseudo to be caught in scheduler and expanded to brcond. - BRCOND, // Conditional branch. - RET, // Return. - Dummy - }; - - // Keep track of different address spaces. - enum AddressSpace { - RAM_SPACE = 0, // RAM address space - ROM_SPACE = 1 // ROM address space number is 1 - }; - enum PIC16Libcall { - MUL_I8 = RTLIB::UNKNOWN_LIBCALL + 1, - SRA_I8, - SLL_I8, - SRL_I8, - PIC16UnknownCall - }; - } - - - //===--------------------------------------------------------------------===// - // TargetLowering Implementation - //===--------------------------------------------------------------------===// - class PIC16TargetLowering : public TargetLowering { - public: - explicit PIC16TargetLowering(PIC16TargetMachine &TM); - - /// getTargetNodeName - This method returns the name of a target specific - /// DAG node. - virtual const char *getTargetNodeName(unsigned Opcode) const; - /// getSetCCResultType - Return the ISD::SETCC ValueType - virtual MVT::SimpleValueType getSetCCResultType(EVT ValType) const; - virtual MVT::SimpleValueType getCmpLibcallReturnType() const; - SDValue LowerShift(SDValue Op, SelectionDAG &DAG) const; - SDValue LowerMUL(SDValue Op, SelectionDAG &DAG) const; - SDValue LowerADD(SDValue Op, SelectionDAG &DAG) const; - SDValue LowerSUB(SDValue Op, SelectionDAG &DAG) const; - SDValue LowerBinOp(SDValue Op, SelectionDAG &DAG) const; - // Call returns - SDValue - LowerDirectCallReturn(SDValue RetLabel, SDValue Chain, SDValue InFlag, - const SmallVectorImpl<ISD::InputArg> &Ins, - DebugLoc dl, SelectionDAG &DAG, - SmallVectorImpl<SDValue> &InVals) const; - SDValue - LowerIndirectCallReturn(SDValue Chain, SDValue InFlag, - SDValue DataAddr_Lo, SDValue DataAddr_Hi, - const SmallVectorImpl<ISD::InputArg> &Ins, - DebugLoc dl, SelectionDAG &DAG, - SmallVectorImpl<SDValue> &InVals) const; - - // Call arguments - SDValue - LowerDirectCallArguments(SDValue ArgLabel, SDValue Chain, SDValue InFlag, - const SmallVectorImpl<ISD::OutputArg> &Outs, - const SmallVectorImpl<SDValue> &OutVals, - DebugLoc dl, SelectionDAG &DAG) const; - - SDValue - LowerIndirectCallArguments(SDValue Chain, SDValue InFlag, - SDValue DataAddr_Lo, SDValue DataAddr_Hi, - const SmallVectorImpl<ISD::OutputArg> &Outs, - const SmallVectorImpl<SDValue> &OutVals, - const SmallVectorImpl<ISD::InputArg> &Ins, - DebugLoc dl, SelectionDAG &DAG) const; - - SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG) const; - SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const; - SDValue getPIC16Cmp(SDValue LHS, SDValue RHS, unsigned OrigCC, SDValue &CC, - SelectionDAG &DAG, DebugLoc dl) const; - virtual MachineBasicBlock * - EmitInstrWithCustomInserter(MachineInstr *MI, - MachineBasicBlock *MBB) const; - - virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const; - virtual void ReplaceNodeResults(SDNode *N, - SmallVectorImpl<SDValue> &Results, - SelectionDAG &DAG) const; - virtual void LowerOperationWrapper(SDNode *N, - SmallVectorImpl<SDValue> &Results, - SelectionDAG &DAG) const; - - virtual SDValue - LowerFormalArguments(SDValue Chain, - CallingConv::ID CallConv, - bool isVarArg, - const SmallVectorImpl<ISD::InputArg> &Ins, - DebugLoc dl, SelectionDAG &DAG, - SmallVectorImpl<SDValue> &InVals) const; - - virtual SDValue - LowerCall(SDValue Chain, SDValue Callee, - CallingConv::ID CallConv, bool isVarArg, bool &isTailCall, - const SmallVectorImpl<ISD::OutputArg> &Outs, - const SmallVectorImpl<SDValue> &OutVals, - const SmallVectorImpl<ISD::InputArg> &Ins, - DebugLoc dl, SelectionDAG &DAG, - SmallVectorImpl<SDValue> &InVals) const; - - virtual SDValue - LowerReturn(SDValue Chain, - CallingConv::ID CallConv, bool isVarArg, - const SmallVectorImpl<ISD::OutputArg> &Outs, - const SmallVectorImpl<SDValue> &OutVals, - DebugLoc dl, SelectionDAG &DAG) const; - - SDValue ExpandStore(SDNode *N, SelectionDAG &DAG) const; - SDValue ExpandLoad(SDNode *N, SelectionDAG &DAG) const; - SDValue ExpandGlobalAddress(SDNode *N, SelectionDAG &DAG) const; - SDValue ExpandExternalSymbol(SDNode *N, SelectionDAG &DAG) const; - SDValue ExpandFrameIndex(SDNode *N, SelectionDAG &DAG) const; - - SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const; - SDValue PerformPIC16LoadCombine(SDNode *N, DAGCombinerInfo &DCI) const; - SDValue PerformStoreCombine(SDNode *N, DAGCombinerInfo &DCI) const; - - // This function returns the Tmp Offset for FrameIndex. If any TmpOffset - // already exists for the FI then it returns the same else it creates the - // new offset and returns. - unsigned GetTmpOffsetForFI(unsigned FI, unsigned slot_size, - MachineFunction &MF) const; - void ResetTmpOffsetMap(SelectionDAG &DAG) const; - void InitReservedFrameCount(const Function *F, - SelectionDAG &DAG) const; - - /// getFunctionAlignment - Return the Log2 alignment of this function. - virtual unsigned getFunctionAlignment(const Function *) const { - // FIXME: The function never seems to be aligned. - return 1; - } - protected: - std::pair<const TargetRegisterClass*, uint8_t> - findRepresentativeClass(EVT VT) const; - private: - // If the Node is a BUILD_PAIR representing a direct Address, - // then this function will return true. - bool isDirectAddress(const SDValue &Op) const; - - // If the Node is a DirectAddress in ROM_SPACE then this - // function will return true - bool isRomAddress(const SDValue &Op) const; - - // Extract the Lo and Hi component of Op. - void GetExpandedParts(SDValue Op, SelectionDAG &DAG, SDValue &Lo, - SDValue &Hi) const; - - - // Load pointer can be a direct or indirect address. In PIC16 direct - // addresses need Banksel and Indirect addresses need to be loaded to - // FSR first. Handle address specific cases here. - void LegalizeAddress(SDValue Ptr, SelectionDAG &DAG, SDValue &Chain, - SDValue &NewPtr, unsigned &Offset, DebugLoc dl) const; - - // FrameIndex should be broken down into ExternalSymbol and FrameOffset. - void LegalizeFrameIndex(SDValue Op, SelectionDAG &DAG, SDValue &ES, - int &Offset) const; - - // For indirect calls data address of the callee frame need to be - // extracted. This function fills the arguments DataAddr_Lo and - // DataAddr_Hi with the address of the callee frame. - void GetDataAddress(DebugLoc dl, SDValue Callee, SDValue &Chain, - SDValue &DataAddr_Lo, SDValue &DataAddr_Hi, - SelectionDAG &DAG) const; - - // We can not have both operands of a binary operation in W. - // This function is used to put one operand on stack and generate a load. - SDValue ConvertToMemOperand(SDValue Op, SelectionDAG &DAG, - DebugLoc dl) const; - - // This function checks if we need to put an operand of an operation on - // stack and generate a load or not. - // DAG parameter is required to access DAG information during - // analysis. - bool NeedToConvertToMemOp(SDValue Op, unsigned &MemOp, - SelectionDAG &DAG) const; - - /// Subtarget - Keep a pointer to the PIC16Subtarget around so that we can - /// make the right decision when generating code for different targets. - const PIC16Subtarget *Subtarget; - - - // Extending the LIB Call framework of LLVM - // to hold the names of PIC16Libcalls. - const char *PIC16LibcallNames[PIC16ISD::PIC16UnknownCall]; - - // To set and retrieve the lib call names. - void setPIC16LibcallName(PIC16ISD::PIC16Libcall Call, const char *Name); - const char *getPIC16LibcallName(PIC16ISD::PIC16Libcall Call) const; - - // Make PIC16 Libcall. - SDValue MakePIC16Libcall(PIC16ISD::PIC16Libcall Call, EVT RetVT, - const SDValue *Ops, unsigned NumOps, bool isSigned, - SelectionDAG &DAG, DebugLoc dl) const; - - // Check if operation has a direct load operand. - inline bool isDirectLoad(const SDValue Op) const; - }; -} // namespace llvm - -#endif // PIC16ISELLOWERING_H diff --git a/lib/Target/PIC16/PIC16InstrFormats.td b/lib/Target/PIC16/PIC16InstrFormats.td deleted file mode 100644 index e213ea8..0000000 --- a/lib/Target/PIC16/PIC16InstrFormats.td +++ /dev/null @@ -1,117 +0,0 @@ -//===- PIC16InstrFormats.td - PIC16 Instruction Formats-------*- tblgen -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -//===----------------------------------------------------------------------===// -// Describe PIC16 instructions format -// -// All the possible PIC16 fields are: -// -// opcode - operation code. -// f - 7-bit register file address. -// d - 1-bit direction specifier -// k - 8/11 bit literals -// b - 3 bits bit num specifier -// -//===----------------------------------------------------------------------===// - -// Generic PIC16 Format -// PIC16 Instructions are 14-bit wide. - -// FIXME: Add Cooper Specific Formats if any. - -class PIC16Inst<dag outs, dag ins, string asmstr, list<dag> pattern> - : Instruction { - field bits<14> Inst; - - let Namespace = "PIC16"; - dag OutOperandList = outs; - dag InOperandList = ins; - let AsmString = asmstr; - let Pattern = pattern; -} - - -//===----------------------------------------------------------------------===// -// Byte Oriented instruction class in PIC16 : <|opcode|d|f|> -// opcode = 6 bits. -// d = direction = 1 bit. -// f = file register address = 7 bits. -//===----------------------------------------------------------------------===// - -class ByteFormat<bits<6> opcode, dag outs, dag ins, string asmstr, - list<dag> pattern> - :PIC16Inst<outs, ins, asmstr, pattern> { - bits<1> d; - bits<7> f; - - let Inst{13-8} = opcode; - - let Inst{7} = d; - let Inst{6-0} = f; -} - -//===----------------------------------------------------------------------===// -// Bit Oriented instruction class in PIC16 : <|opcode|b|f|> -// opcode = 4 bits. -// b = bit specifier = 3 bits. -// f = file register address = 7 bits. -//===----------------------------------------------------------------------===// - -class BitFormat<bits<4> opcode, dag outs, dag ins, string asmstr, - list<dag> pattern> - : PIC16Inst<outs, ins, asmstr, pattern> { - bits<3> b; - bits<7> f; - - let Inst{13-10} = opcode; - - let Inst{9-7} = b; - let Inst{6-0} = f; -} - -//===----------------------------------------------------------------------===// -// Literal Format instruction class in PIC16 : <|opcode|k|> -// opcode = 6 bits -// k = literal = 8 bits -//===----------------------------------------------------------------------===// - -class LiteralFormat<bits<6> opcode, dag outs, dag ins, string asmstr, - list<dag> pattern> - : PIC16Inst<outs, ins, asmstr, pattern> { - bits<8> k; - - let Inst{13-8} = opcode; - - let Inst{7-0} = k; -} - -//===----------------------------------------------------------------------===// -// Control Format instruction class in PIC16 : <|opcode|k|> -// opcode = 3 bits. -// k = jump address = 11 bits. -//===----------------------------------------------------------------------===// - -class ControlFormat<bits<3> opcode, dag outs, dag ins, string asmstr, - list<dag> pattern> - : PIC16Inst<outs, ins, asmstr, pattern> { - bits<11> k; - - let Inst{13-11} = opcode; - - let Inst{10-0} = k; -} - -//===----------------------------------------------------------------------===// -// Pseudo instruction class in PIC16 -//===----------------------------------------------------------------------===// - -class Pseudo<dag outs, dag ins, string asmstr, list<dag> pattern> - : PIC16Inst<outs, ins, asmstr, pattern> { - let Inst{13-6} = 0; -} diff --git a/lib/Target/PIC16/PIC16InstrInfo.cpp b/lib/Target/PIC16/PIC16InstrInfo.cpp deleted file mode 100644 index 81257f3..0000000 --- a/lib/Target/PIC16/PIC16InstrInfo.cpp +++ /dev/null @@ -1,224 +0,0 @@ -//===- PIC16InstrInfo.cpp - PIC16 Instruction Information -----------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains the PIC16 implementation of the TargetInstrInfo class. -// -//===----------------------------------------------------------------------===// - -#include "PIC16.h" -#include "PIC16ABINames.h" -#include "PIC16InstrInfo.h" -#include "PIC16TargetMachine.h" -#include "PIC16GenInstrInfo.inc" -#include "llvm/Function.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/MachineInstrBuilder.h" -#include "llvm/CodeGen/MachineRegisterInfo.h" -#include "llvm/Support/ErrorHandling.h" -#include <cstdio> - - -using namespace llvm; - -// FIXME: Add the subtarget support on this constructor. -PIC16InstrInfo::PIC16InstrInfo(PIC16TargetMachine &tm) - : TargetInstrInfoImpl(PIC16Insts, array_lengthof(PIC16Insts)), - TM(tm), - RegInfo(*this, *TM.getSubtargetImpl()) {} - - -/// isStoreToStackSlot - If the specified machine instruction is a direct -/// store to a stack slot, return the virtual or physical register number of -/// the source reg along with the FrameIndex of the loaded stack slot. -/// If not, return 0. This predicate must return 0 if the instruction has -/// any side effects other than storing to the stack slot. -unsigned PIC16InstrInfo::isStoreToStackSlot(const MachineInstr *MI, - int &FrameIndex) const { - if (MI->getOpcode() == PIC16::movwf - && MI->getOperand(0).isReg() - && MI->getOperand(1).isSymbol()) { - FrameIndex = MI->getOperand(1).getIndex(); - return MI->getOperand(0).getReg(); - } - return 0; -} - -/// isLoadFromStackSlot - If the specified machine instruction is a direct -/// load from a stack slot, return the virtual or physical register number of -/// the dest reg along with the FrameIndex of the stack slot. -/// If not, return 0. This predicate must return 0 if the instruction has -/// any side effects other than storing to the stack slot. -unsigned PIC16InstrInfo::isLoadFromStackSlot(const MachineInstr *MI, - int &FrameIndex) const { - if (MI->getOpcode() == PIC16::movf - && MI->getOperand(0).isReg() - && MI->getOperand(1).isSymbol()) { - FrameIndex = MI->getOperand(1).getIndex(); - return MI->getOperand(0).getReg(); - } - return 0; -} - - -void PIC16InstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, - MachineBasicBlock::iterator I, - unsigned SrcReg, bool isKill, int FI, - const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const { - const PIC16TargetLowering *PTLI = TM.getTargetLowering(); - DebugLoc DL; - if (I != MBB.end()) DL = I->getDebugLoc(); - - const Function *Func = MBB.getParent()->getFunction(); - const std::string FuncName = Func->getName(); - - const char *tmpName = ESNames::createESName(PAN::getTempdataLabel(FuncName)); - - // On the order of operands here: think "movwf SrcReg, tmp_slot, offset". - if (RC == PIC16::GPRRegisterClass) { - //MachineFunction &MF = *MBB.getParent(); - //MachineRegisterInfo &RI = MF.getRegInfo(); - BuildMI(MBB, I, DL, get(PIC16::movwf)) - .addReg(SrcReg, getKillRegState(isKill)) - .addImm(PTLI->GetTmpOffsetForFI(FI, 1, *MBB.getParent())) - .addExternalSymbol(tmpName) - .addImm(1); // Emit banksel for it. - } - else if (RC == PIC16::FSR16RegisterClass) { - // This is a 16-bit register and the frameindex given by llvm is of - // size two here. Break this index N into two zero based indexes and - // put one into the map. The second one is always obtained by adding 1 - // to the first zero based index. In fact it is going to use 3 slots - // as saving FSRs corrupts W also and hence we need to save/restore W also. - - unsigned opcode = (SrcReg == PIC16::FSR0) ? PIC16::save_fsr0 - : PIC16::save_fsr1; - BuildMI(MBB, I, DL, get(opcode)) - .addReg(SrcReg, getKillRegState(isKill)) - .addImm(PTLI->GetTmpOffsetForFI(FI, 3, *MBB.getParent())) - .addExternalSymbol(tmpName) - .addImm(1); // Emit banksel for it. - } - else - llvm_unreachable("Can't store this register to stack slot"); -} - -void PIC16InstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, - MachineBasicBlock::iterator I, - unsigned DestReg, int FI, - const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const { - const PIC16TargetLowering *PTLI = TM.getTargetLowering(); - DebugLoc DL; - if (I != MBB.end()) DL = I->getDebugLoc(); - - const Function *Func = MBB.getParent()->getFunction(); - const std::string FuncName = Func->getName(); - - const char *tmpName = ESNames::createESName(PAN::getTempdataLabel(FuncName)); - - // On the order of operands here: think "movf FrameIndex, W". - if (RC == PIC16::GPRRegisterClass) { - //MachineFunction &MF = *MBB.getParent(); - //MachineRegisterInfo &RI = MF.getRegInfo(); - BuildMI(MBB, I, DL, get(PIC16::movf), DestReg) - .addImm(PTLI->GetTmpOffsetForFI(FI, 1, *MBB.getParent())) - .addExternalSymbol(tmpName) - .addImm(1); // Emit banksel for it. - } - else if (RC == PIC16::FSR16RegisterClass) { - // This is a 16-bit register and the frameindex given by llvm is of - // size two here. Break this index N into two zero based indexes and - // put one into the map. The second one is always obtained by adding 1 - // to the first zero based index. In fact it is going to use 3 slots - // as saving FSRs corrupts W also and hence we need to save/restore W also. - - unsigned opcode = (DestReg == PIC16::FSR0) ? PIC16::restore_fsr0 - : PIC16::restore_fsr1; - BuildMI(MBB, I, DL, get(opcode), DestReg) - .addImm(PTLI->GetTmpOffsetForFI(FI, 3, *MBB.getParent())) - .addExternalSymbol(tmpName) - .addImm(1); // Emit banksel for it. - } - else - llvm_unreachable("Can't load this register from stack slot"); -} - -void PIC16InstrInfo::copyPhysReg(MachineBasicBlock &MBB, - MachineBasicBlock::iterator I, DebugLoc DL, - unsigned DestReg, unsigned SrcReg, - bool KillSrc) const { - unsigned Opc; - if (PIC16::FSR16RegClass.contains(DestReg, SrcReg)) - Opc = PIC16::copy_fsr; - else if (PIC16::GPRRegClass.contains(DestReg, SrcReg)) - Opc = PIC16::copy_w; - else - llvm_unreachable("Impossible reg-to-reg copy"); - - BuildMI(MBB, I, DL, get(Opc), DestReg) - .addReg(SrcReg, getKillRegState(KillSrc)); -} - -/// InsertBranch - Insert a branch into the end of the specified -/// MachineBasicBlock. This operands to this method are the same as those -/// returned by AnalyzeBranch. This is invoked in cases where AnalyzeBranch -/// returns success and when an unconditional branch (TBB is non-null, FBB is -/// null, Cond is empty) needs to be inserted. It returns the number of -/// instructions inserted. -unsigned PIC16InstrInfo:: -InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, - MachineBasicBlock *FBB, - const SmallVectorImpl<MachineOperand> &Cond, - DebugLoc DL) const { - // Shouldn't be a fall through. - assert(TBB && "InsertBranch must not be told to insert a fallthrough"); - - if (FBB == 0) { // One way branch. - if (Cond.empty()) { - // Unconditional branch? - BuildMI(&MBB, DL, get(PIC16::br_uncond)).addMBB(TBB); - } - return 1; - } - - // FIXME: If the there are some conditions specified then conditional branch - // should be generated. - // For the time being no instruction is being generated therefore - // returning NULL. - return 0; -} - -bool PIC16InstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, - MachineBasicBlock *&TBB, - MachineBasicBlock *&FBB, - SmallVectorImpl<MachineOperand> &Cond, - bool AllowModify) const { - MachineBasicBlock::iterator I = MBB.end(); - if (I == MBB.begin()) - return true; - - // Get the terminator instruction. - --I; - while (I->isDebugValue()) { - if (I == MBB.begin()) - return true; - --I; - } - // Handle unconditional branches. If the unconditional branch's target is - // successor basic block then remove the unconditional branch. - if (I->getOpcode() == PIC16::br_uncond && AllowModify) { - if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) { - TBB = 0; - I->eraseFromParent(); - } - } - return true; -} diff --git a/lib/Target/PIC16/PIC16InstrInfo.h b/lib/Target/PIC16/PIC16InstrInfo.h deleted file mode 100644 index 661b335..0000000 --- a/lib/Target/PIC16/PIC16InstrInfo.h +++ /dev/null @@ -1,76 +0,0 @@ -//===- PIC16InstrInfo.h - PIC16 Instruction Information----------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the niversity of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains the PIC16 implementation of the TargetInstrInfo class. -// -//===----------------------------------------------------------------------===// - -#ifndef PIC16INSTRUCTIONINFO_H -#define PIC16INSTRUCTIONINFO_H - -#include "PIC16.h" -#include "PIC16RegisterInfo.h" -#include "llvm/Target/TargetInstrInfo.h" - -namespace llvm { - - -class PIC16InstrInfo : public TargetInstrInfoImpl -{ - PIC16TargetMachine &TM; - const PIC16RegisterInfo RegInfo; -public: - explicit PIC16InstrInfo(PIC16TargetMachine &TM); - - virtual const PIC16RegisterInfo &getRegisterInfo() const { return RegInfo; } - - /// isLoadFromStackSlot - If the specified machine instruction is a direct - /// load from a stack slot, return the virtual or physical register number of - /// the destination along with the FrameIndex of the loaded stack slot. If - /// not, return 0. This predicate must return 0 if the instruction has - /// any side effects other than loading from the stack slot. - virtual unsigned isLoadFromStackSlot(const MachineInstr *MI, - int &FrameIndex) const; - - /// isStoreToStackSlot - If the specified machine instruction is a direct - /// store to a stack slot, return the virtual or physical register number of - /// the source reg along with the FrameIndex of the loaded stack slot. If - /// not, return 0. This predicate must return 0 if the instruction has - /// any side effects other than storing to the stack slot. - virtual unsigned isStoreToStackSlot(const MachineInstr *MI, - int &FrameIndex) const; - - virtual void storeRegToStackSlot(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MBBI, - unsigned SrcReg, bool isKill, int FrameIndex, - const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const; - - virtual void loadRegFromStackSlot(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MBBI, - unsigned DestReg, int FrameIndex, - const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const; - virtual void copyPhysReg(MachineBasicBlock &MBB, - MachineBasicBlock::iterator I, DebugLoc DL, - unsigned DestReg, unsigned SrcReg, - bool KillSrc) const; - virtual - unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, - MachineBasicBlock *FBB, - const SmallVectorImpl<MachineOperand> &Cond, - DebugLoc DL) const; - virtual bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, - MachineBasicBlock *&FBB, - SmallVectorImpl<MachineOperand> &Cond, - bool AllowModify) const; - }; -} // namespace llvm - -#endif diff --git a/lib/Target/PIC16/PIC16InstrInfo.td b/lib/Target/PIC16/PIC16InstrInfo.td deleted file mode 100644 index 86d36cb..0000000 --- a/lib/Target/PIC16/PIC16InstrInfo.td +++ /dev/null @@ -1,540 +0,0 @@ -//===- PIC16InstrInfo.td - PIC16 Instruction defs -------------*- tblgen-*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file describes the PIC16 instructions in TableGen format. -// -//===----------------------------------------------------------------------===// - -//===----------------------------------------------------------------------===// -// PIC16 Specific Type Constraints. -//===----------------------------------------------------------------------===// -class SDTCisI8<int OpNum> : SDTCisVT<OpNum, i8>; -class SDTCisI16<int OpNum> : SDTCisVT<OpNum, i16>; - -//===----------------------------------------------------------------------===// -// PIC16 Specific Type Profiles. -//===----------------------------------------------------------------------===// - -// Generic type profiles for i8/i16 unary/binary operations. -// Taking one i8 or i16 and producing void. -def SDTI8VoidOp : SDTypeProfile<0, 1, [SDTCisI8<0>]>; -def SDTI16VoidOp : SDTypeProfile<0, 1, [SDTCisI16<0>]>; - -// Taking one value and producing an output of same type. -def SDTI8UnaryOp : SDTypeProfile<1, 1, [SDTCisI8<0>, SDTCisI8<1>]>; -def SDTI16UnaryOp : SDTypeProfile<1, 1, [SDTCisI16<0>, SDTCisI16<1>]>; - -// Taking two values and producing an output of same type. -def SDTI8BinOp : SDTypeProfile<1, 2, [SDTCisI8<0>, SDTCisI8<1>, SDTCisI8<2>]>; -def SDTI16BinOp : SDTypeProfile<1, 2, [SDTCisI16<0>, SDTCisI16<1>, - SDTCisI16<2>]>; - -// Node specific type profiles. -def SDT_PIC16Load : SDTypeProfile<1, 3, [SDTCisI8<0>, SDTCisI8<1>, - SDTCisI8<2>, SDTCisI8<3>]>; - -def SDT_PIC16Store : SDTypeProfile<0, 4, [SDTCisI8<0>, SDTCisI8<1>, - SDTCisI8<2>, SDTCisI8<3>]>; - -def SDT_PIC16Connect : SDTypeProfile<1, 2, [SDTCisI8<0>, SDTCisI8<1>, - SDTCisI8<2>]>; - -// PIC16ISD::CALL type prorile -def SDT_PIC16call : SDTypeProfile<0, -1, [SDTCisInt<0>]>; -def SDT_PIC16callw : SDTypeProfile<1, -1, [SDTCisInt<0>]>; - -// PIC16ISD::BRCOND -def SDT_PIC16Brcond: SDTypeProfile<0, 2, - [SDTCisVT<0, OtherVT>, SDTCisI8<1>]>; - -// PIC16ISD::BRCOND -def SDT_PIC16Selecticc: SDTypeProfile<1, 3, - [SDTCisI8<0>, SDTCisI8<1>, SDTCisI8<2>, - SDTCisI8<3>]>; - -//===----------------------------------------------------------------------===// -// PIC16 addressing modes matching via DAG. -//===----------------------------------------------------------------------===// -def diraddr : ComplexPattern<i8, 1, "SelectDirectAddr", [], []>; - -//===----------------------------------------------------------------------===// -// PIC16 Specific Node Definitions. -//===----------------------------------------------------------------------===// -def PIC16callseq_start : SDNode<"ISD::CALLSEQ_START", SDTI8VoidOp, - [SDNPHasChain, SDNPOutFlag]>; -def PIC16callseq_end : SDNode<"ISD::CALLSEQ_END", SDTI8VoidOp, - [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; - -// Low 8-bits of GlobalAddress. -def PIC16Lo : SDNode<"PIC16ISD::Lo", SDTI8BinOp>; - -// High 8-bits of GlobalAddress. -def PIC16Hi : SDNode<"PIC16ISD::Hi", SDTI8BinOp>; - -// The MTHI and MTLO nodes are used only to match them in the incoming -// DAG for replacement by corresponding set_fsrhi, set_fsrlo insntructions. -// These nodes are not used for defining any instructions. -def MTLO : SDNode<"PIC16ISD::MTLO", SDTI8UnaryOp>; -def MTHI : SDNode<"PIC16ISD::MTHI", SDTI8UnaryOp>; -def MTPCLATH : SDNode<"PIC16ISD::MTPCLATH", SDTI8UnaryOp>; - -// Node to generate Bank Select for a GlobalAddress. -def Banksel : SDNode<"PIC16ISD::Banksel", SDTI8UnaryOp>; - -// Node to match a direct store operation. -def PIC16Store : SDNode<"PIC16ISD::PIC16Store", SDT_PIC16Store, [SDNPHasChain]>; -def PIC16StWF : SDNode<"PIC16ISD::PIC16StWF", SDT_PIC16Store, - [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>; - -// Node to match a direct load operation. -def PIC16Load : SDNode<"PIC16ISD::PIC16Load", SDT_PIC16Load, [SDNPHasChain]>; -def PIC16LdArg : SDNode<"PIC16ISD::PIC16LdArg", SDT_PIC16Load, [SDNPHasChain]>; -def PIC16LdWF : SDNode<"PIC16ISD::PIC16LdWF", SDT_PIC16Load, - [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>; -def PIC16Connect: SDNode<"PIC16ISD::PIC16Connect", SDT_PIC16Connect, []>; - -// Node to match PIC16 call -def PIC16call : SDNode<"PIC16ISD::CALL", SDT_PIC16call, - [SDNPHasChain , SDNPOptInFlag, SDNPOutFlag]>; -def PIC16callw : SDNode<"PIC16ISD::CALLW", SDT_PIC16callw, - [SDNPHasChain , SDNPOptInFlag, SDNPOutFlag]>; - -// Node to match a comparison instruction. -def PIC16Subcc : SDNode<"PIC16ISD::SUBCC", SDTI8BinOp, [SDNPOutFlag]>; - -// Node to match a conditional branch. -def PIC16Brcond : SDNode<"PIC16ISD::BRCOND", SDT_PIC16Brcond, - [SDNPHasChain, SDNPInFlag]>; - -def PIC16Selecticc : SDNode<"PIC16ISD::SELECT_ICC", SDT_PIC16Selecticc, - [SDNPInFlag]>; - -def PIC16ret : SDNode<"PIC16ISD::RET", SDTNone, [SDNPHasChain]>; - -//===----------------------------------------------------------------------===// -// PIC16 Operand Definitions. -//===----------------------------------------------------------------------===// -def i8mem : Operand<i8>; -def brtarget: Operand<OtherVT>; - -// Operand for printing out a condition code. -let PrintMethod = "printCCOperand" in - def CCOp : Operand<i8>; - -include "PIC16InstrFormats.td" - -//===----------------------------------------------------------------------===// -// PIC16 Common Classes. -//===----------------------------------------------------------------------===// - -// W = W Op F : Load the value from F and do Op to W. -let Constraints = "$src = $dst", mayLoad = 1 in -class BinOpFW<bits<6> OpCode, string OpcStr, SDNode OpNode>: - ByteFormat<OpCode, (outs GPR:$dst), - (ins GPR:$src, i8imm:$offset, i8mem:$ptrlo, i8imm:$ptrhi), - !strconcat(OpcStr, " $ptrlo + $offset, W"), - [(set GPR:$dst, (OpNode GPR:$src, (PIC16Load diraddr:$ptrlo, - (i8 imm:$ptrhi), - (i8 imm:$offset))))]>; - -// F = F Op W : Load the value from F, do op with W and store in F. -// This insn class is not marked as TwoAddress because the reg is -// being used as a source operand only. (Remember a TwoAddress insn -// needs a copy.) -let mayStore = 1 in -class BinOpWF<bits<6> OpCode, string OpcStr, SDNode OpNode>: - ByteFormat<OpCode, (outs), - (ins GPR:$src, i8imm:$offset, i8mem:$ptrlo, i8imm:$ptrhi), - !strconcat(OpcStr, " $ptrlo + $offset, F"), - [(PIC16Store (OpNode GPR:$src, (PIC16Load diraddr:$ptrlo, - (i8 imm:$ptrhi), - (i8 imm:$offset))), - diraddr:$ptrlo, - (i8 imm:$ptrhi), (i8 imm:$offset) - )]>; - -// W = W Op L : Do Op of L with W and place result in W. -let Constraints = "$src = $dst" in -class BinOpWL<bits<6> opcode, string OpcStr, SDNode OpNode> : - LiteralFormat<opcode, (outs GPR:$dst), - (ins GPR:$src, i8imm:$literal), - !strconcat(OpcStr, " $literal"), - [(set GPR:$dst, (OpNode GPR:$src, (i8 imm:$literal)))]>; - -//===----------------------------------------------------------------------===// -// PIC16 Instructions. -//===----------------------------------------------------------------------===// - -// Pseudo-instructions. -def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i8imm:$amt), - "!ADJCALLSTACKDOWN $amt", - [(PIC16callseq_start imm:$amt)]>; - -def ADJCALLSTACKUP : Pseudo<(outs), (ins i8imm:$amt), - "!ADJCALLSTACKUP $amt", - [(PIC16callseq_end imm:$amt)]>; - -//----------------------------------- -// Vaious movlw insn patterns. -//----------------------------------- -let isReMaterializable = 1 in { -// Move 8-bit literal to W. -def movlw : BitFormat<12, (outs GPR:$dst), (ins i8imm:$src), - "movlw $src", - [(set GPR:$dst, (i8 imm:$src))]>; - -// Move a Lo(TGA) to W. -def movlw_lo_1 : BitFormat<12, (outs GPR:$dst), (ins i8imm:$src, i8imm:$src2), - "movlw LOW(${src} + ${src2})", - [(set GPR:$dst, (PIC16Lo tglobaladdr:$src, imm:$src2 ))]>; - -// Move a Lo(TES) to W. -def movlw_lo_2 : BitFormat<12, (outs GPR:$dst), (ins i8imm:$src, i8imm:$src2), - "movlw LOW(${src} + ${src2})", - [(set GPR:$dst, (PIC16Lo texternalsym:$src, imm:$src2 ))]>; - -// Move a Hi(TGA) to W. -def movlw_hi_1 : BitFormat<12, (outs GPR:$dst), (ins i8imm:$src, i8imm:$src2), - "movlw HIGH(${src} + ${src2})", - [(set GPR:$dst, (PIC16Hi tglobaladdr:$src, imm:$src2))]>; - -// Move a Hi(TES) to W. -def movlw_hi_2 : BitFormat<12, (outs GPR:$dst), (ins i8imm:$src, i8imm:$src2), - "movlw HIGH(${src} + ${src2})", - [(set GPR:$dst, (PIC16Hi texternalsym:$src, imm:$src2))]>; -} - -//------------------- -// FSR setting insns. -//------------------- -// These insns are matched via a DAG replacement pattern. -def set_fsrlo: - ByteFormat<0, (outs FSR16:$fsr), - (ins GPR:$val), - "movwf ${fsr}L", - []>; - -let Constraints = "$src = $dst" in -def set_fsrhi: - ByteFormat<0, (outs FSR16:$dst), - (ins FSR16:$src, GPR:$val), - "movwf ${dst}H", - []>; - -def set_pclath: - ByteFormat<0, (outs PCLATHR:$dst), - (ins GPR:$val), - "movwf ${dst}", - [(set PCLATHR:$dst , (MTPCLATH GPR:$val))]>; - -//---------------------------- -// copyPhysReg -// copyPhysReg insns. These are dummy. They should always be deleted -// by the optimizer and never be present in the final generated code. -// if they are, then we have to write correct macros for these insns. -//---------------------------- -def copy_fsr: - Pseudo<(outs FSR16:$dst), (ins FSR16:$src), "copy_fsr $dst, $src", []>; - -def copy_w: - Pseudo<(outs GPR:$dst), (ins GPR:$src), "copy_w $dst, $src", []>; - -class SAVE_FSR<string OpcStr>: - Pseudo<(outs), - (ins FSR16:$src, i8imm:$offset, i8mem:$ptrlo, i8imm:$ptrhi), - !strconcat(OpcStr, " $ptrlo, $offset"), - []>; - -def save_fsr0: SAVE_FSR<"save_fsr0">; -def save_fsr1: SAVE_FSR<"save_fsr1">; - -class RESTORE_FSR<string OpcStr>: - Pseudo<(outs FSR16:$dst), - (ins i8imm:$offset, i8mem:$ptrlo, i8imm:$ptrhi), - !strconcat(OpcStr, " $ptrlo, $offset"), - []>; - -def restore_fsr0: RESTORE_FSR<"restore_fsr0">; -def restore_fsr1: RESTORE_FSR<"restore_fsr1">; - -//-------------------------- -// Store to memory -//------------------------- - -// Direct store. -// Input operands are: val = W, ptrlo = GA, offset = offset, ptrhi = banksel. -let mayStore = 1 in -class MOVWF_INSN<bits<6> OpCode, SDNode OpNodeDest, SDNode Op>: - ByteFormat<0, (outs), - (ins GPR:$val, i8imm:$offset, i8mem:$ptrlo, i8imm:$ptrhi), - "movwf ${ptrlo} + ${offset}", - [(Op GPR:$val, OpNodeDest:$ptrlo, (i8 imm:$ptrhi), - (i8 imm:$offset))]>; - -// Store W to a Global Address. -def movwf : MOVWF_INSN<0, tglobaladdr, PIC16Store>; - -// Store W to an External Symobol. -def movwf_1 : MOVWF_INSN<0, texternalsym, PIC16Store>; - -// Store with InFlag and OutFlag -// This is same as movwf_1 but has a flag. A flag is required to -// order the stores while passing the params to function. -def movwf_2 : MOVWF_INSN<0, texternalsym, PIC16StWF>; - -// Indirect store. Matched via a DAG replacement pattern. -def store_indirect : - ByteFormat<0, (outs), - (ins GPR:$val, FSR16:$fsr, i8imm:$offset), - "movwi $offset[$fsr]", - []>; - -//---------------------------- -// Load from memory -//---------------------------- -// Direct load. -// Input Operands are: ptrlo = GA, offset = offset, ptrhi = banksel. -// Output: dst = W -let Defs = [STATUS], mayLoad = 1 in -class MOVF_INSN<bits<6> OpCode, SDNode OpNodeSrc, SDNode Op>: - ByteFormat<0, (outs GPR:$dst), - (ins i8imm:$offset, i8mem:$ptrlo, i8imm:$ptrhi), - "movf ${ptrlo} + ${offset}, W", - [(set GPR:$dst, - (Op OpNodeSrc:$ptrlo, (i8 imm:$ptrhi), - (i8 imm:$offset)))]>; - -// Load from a GA. -def movf : MOVF_INSN<0, tglobaladdr, PIC16Load>; - -// Load from an ES. -def movf_1 : MOVF_INSN<0, texternalsym, PIC16Load>; -def movf_1_1 : MOVF_INSN<0, texternalsym, PIC16LdArg>; - -// Load with InFlag and OutFlag -// This is same as movf_1 but has a flag. A flag is required to -// order the loads while copying the return value of a function. -def movf_2 : MOVF_INSN<0, texternalsym, PIC16LdWF>; - -// Indirect load. Matched via a DAG replacement pattern. -def load_indirect : - ByteFormat<0, (outs GPR:$dst), - (ins FSR16:$fsr, i8imm:$offset), - "moviw $offset[$fsr]", - []>; - -//------------------------- -// Bitwise operations patterns -//-------------------------- -// W = W op [F] -let Defs = [STATUS] in { -def OrFW : BinOpFW<0, "iorwf", or>; -def XOrFW : BinOpFW<0, "xorwf", xor>; -def AndFW : BinOpFW<0, "andwf", and>; - -// F = W op [F] -def OrWF : BinOpWF<0, "iorwf", or>; -def XOrWF : BinOpWF<0, "xorwf", xor>; -def AndWF : BinOpWF<0, "andwf", and>; - -//------------------------- -// Various add/sub patterns. -//------------------------- - -// W = W + [F] -def addfw_1: BinOpFW<0, "addwf", add>; -def addfw_2: BinOpFW<0, "addwf", addc>; - -let Uses = [STATUS] in -def addfwc: BinOpFW<0, "addwfc", adde>; // With Carry. - -// F = W + [F] -def addwf_1: BinOpWF<0, "addwf", add>; -def addwf_2: BinOpWF<0, "addwf", addc>; -let Uses = [STATUS] in -def addwfc: BinOpWF<0, "addwfc", adde>; // With Carry. -} - -// W -= [F] ; load from F and sub the value from W. -let Constraints = "$src = $dst", mayLoad = 1 in -class SUBFW<bits<6> OpCode, string OpcStr, SDNode OpNode>: - ByteFormat<OpCode, (outs GPR:$dst), - (ins GPR:$src, i8imm:$offset, i8mem:$ptrlo, i8imm:$ptrhi), - !strconcat(OpcStr, " $ptrlo + $offset, W"), - [(set GPR:$dst, (OpNode (PIC16Load diraddr:$ptrlo, - (i8 imm:$ptrhi), (i8 imm:$offset)), - GPR:$src))]>; -let Defs = [STATUS] in { -def subfw_1: SUBFW<0, "subwf", sub>; -def subfw_2: SUBFW<0, "subwf", subc>; - -let Uses = [STATUS] in -def subfwb: SUBFW<0, "subwfb", sube>; // With Borrow. - -} -let Defs = [STATUS], isTerminator = 1 in -def subfw_cc: SUBFW<0, "subwf", PIC16Subcc>; - -// [F] -= W ; -let mayStore = 1 in -class SUBWF<bits<6> OpCode, string OpcStr, SDNode OpNode>: - ByteFormat<OpCode, (outs), - (ins GPR:$src, i8imm:$offset, i8mem:$ptrlo, i8imm:$ptrhi), - !strconcat(OpcStr, " $ptrlo + $offset"), - [(PIC16Store (OpNode (PIC16Load diraddr:$ptrlo, - (i8 imm:$ptrhi), (i8 imm:$offset)), - GPR:$src), diraddr:$ptrlo, - (i8 imm:$ptrhi), (i8 imm:$offset))]>; - -let Defs = [STATUS] in { -def subwf_1: SUBWF<0, "subwf", sub>; -def subwf_2: SUBWF<0, "subwf", subc>; - -let Uses = [STATUS] in - def subwfb: SUBWF<0, "subwfb", sube>; // With Borrow. - -def subwf_cc: SUBWF<0, "subwf", PIC16Subcc>; -} - -// addlw -let Defs = [STATUS] in { -def addlw_1 : BinOpWL<0, "addlw", add>; -def addlw_2 : BinOpWL<0, "addlw", addc>; - -let Uses = [STATUS] in -def addlwc : BinOpWL<0, "addlwc", adde>; // With Carry. (Assembler macro). - -// bitwise operations involving a literal and w. -def andlw : BinOpWL<0, "andlw", and>; -def xorlw : BinOpWL<0, "xorlw", xor>; -def orlw : BinOpWL<0, "iorlw", or>; -} - -// sublw -// W = C - W ; sub W from literal. (Without borrow). -let Constraints = "$src = $dst" in -class SUBLW<bits<6> opcode, string OpcStr, SDNode OpNode> : - LiteralFormat<opcode, (outs GPR:$dst), - (ins GPR:$src, i8imm:$literal), - !strconcat(OpcStr, " $literal"), - [(set GPR:$dst, (OpNode (i8 imm:$literal), GPR:$src))]>; -// subwl -// W = W - C ; sub literal from W (Without borrow). -let Constraints = "$src = $dst" in -class SUBWL<bits<6> opcode, string OpcStr, SDNode OpNode> : - LiteralFormat<opcode, (outs GPR:$dst), - (ins GPR:$src, i8imm:$literal), - !strconcat(OpcStr, " $literal"), - [(set GPR:$dst, (OpNode GPR:$src, (i8 imm:$literal)))]>; - -let Defs = [STATUS] in { -def sublw_1 : SUBLW<0, "sublw", sub>; -def sublw_2 : SUBLW<0, "sublw", subc>; -def sublw_3 : SUBLW<0, "sublwb", sube>; // With borrow (Assembler macro). - -def sublw_4 : SUBWL<0, "subwl", sub>; // Assembler macro replace with addlw -def sublw_5 : SUBWL<0, "subwl", subc>; // Assembler macro replace with addlw -def sublw_6 : SUBWL<0, "subwlb", sube>; // With borrow (Assembler macro). -} -let Defs = [STATUS], isTerminator = 1 in -def sublw_cc : SUBLW<0, "sublw", PIC16Subcc>; - -// Call instruction. -let isCall = 1, - Defs = [W, FSR0, FSR1] in { - def CALL: LiteralFormat<0x1, (outs), (ins i8imm:$func), - //"call ${func} + 2", - "call ${func}", - [(PIC16call diraddr:$func)]>; -} - -let isCall = 1, - Defs = [W, FSR0, FSR1] in { - def CALL_1: LiteralFormat<0x1, (outs), (ins GPR:$func, PCLATHR:$pc), - "callw", - [(PIC16call (PIC16Connect GPR:$func, PCLATHR:$pc))]>; -} - -let isCall = 1, - Defs = [FSR0, FSR1] in { - def CALLW: LiteralFormat<0x1, (outs GPR:$dest), - (ins GPR:$func, PCLATHR:$pc), - "callw", - [(set GPR:$dest, (PIC16callw (PIC16Connect GPR:$func, PCLATHR:$pc)))]>; -} - -let Uses = [STATUS], isBranch = 1, isTerminator = 1, hasDelaySlot = 0 in -def pic16brcond: ControlFormat<0x0, (outs), (ins brtarget:$dst, CCOp:$cc), - "b$cc $dst", - [(PIC16Brcond bb:$dst, imm:$cc)]>; - -// Unconditional branch. -let isBranch = 1, isTerminator = 1, hasDelaySlot = 0 in -def br_uncond: ControlFormat<0x0, (outs), (ins brtarget:$dst), - "goto $dst", - [(br bb:$dst)]>; - -// SELECT_CC_* - Used to implement the SELECT_CC DAG operation. Expanded after -// instruction selection into a branch sequence. -let usesCustomInserter = 1 in { // Expanded after instruction selection. - def SELECT_CC_Int_ICC - : Pseudo<(outs GPR:$dst), (ins GPR:$T, GPR:$F, i8imm:$Cond), - "; SELECT_CC_Int_ICC PSEUDO!", - [(set GPR:$dst, (PIC16Selecticc GPR:$T, GPR:$F, - imm:$Cond))]>; -} - - -// Banksel. -def banksel : - Pseudo<(outs), - (ins i8mem:$ptr), - "banksel $ptr", - []>; - -def pagesel : - Pseudo<(outs), - (ins i8mem:$ptr), - "movlp $ptr", - []>; - - -// Return insn. -let isTerminator = 1, isBarrier = 1, isReturn = 1 in -def Return : - ControlFormat<0, (outs), (ins), "return", [(PIC16ret)]>; - -//===----------------------------------------------------------------------===// -// PIC16 Replacment Patterns. -//===----------------------------------------------------------------------===// - -// Identify an indirect store and select insns for it. -def : Pat<(PIC16Store GPR:$val, (MTLO GPR:$loaddr), (MTHI GPR:$hiaddr), - imm:$offset), - (store_indirect GPR:$val, - (set_fsrhi (set_fsrlo GPR:$loaddr), GPR:$hiaddr), - imm:$offset)>; - -def : Pat<(PIC16StWF GPR:$val, (MTLO GPR:$loaddr), (MTHI GPR:$hiaddr), - imm:$offset), - (store_indirect GPR:$val, - (set_fsrhi (set_fsrlo GPR:$loaddr), GPR:$hiaddr), - imm:$offset)>; - -// Identify an indirect load and select insns for it. -def : Pat<(PIC16Load (MTLO GPR:$loaddr), (MTHI GPR:$hiaddr), - imm:$offset), - (load_indirect (set_fsrhi (set_fsrlo GPR:$loaddr), GPR:$hiaddr), - imm:$offset)>; - -def : Pat<(PIC16LdWF (MTLO GPR:$loaddr), (MTHI GPR:$hiaddr), - imm:$offset), - (load_indirect (set_fsrhi (set_fsrlo GPR:$loaddr), GPR:$hiaddr), - imm:$offset)>; - diff --git a/lib/Target/PIC16/PIC16MCAsmInfo.cpp b/lib/Target/PIC16/PIC16MCAsmInfo.cpp deleted file mode 100644 index 1bcc497..0000000 --- a/lib/Target/PIC16/PIC16MCAsmInfo.cpp +++ /dev/null @@ -1,59 +0,0 @@ -//===-- PIC16MCAsmInfo.cpp - PIC16 asm properties -------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains the declarations of the PIC16MCAsmInfo properties. -// -//===----------------------------------------------------------------------===// - -#include "PIC16MCAsmInfo.h" - -// FIXME: Layering violation to get enums and static function, should be moved -// to separate headers. -#include "PIC16.h" -#include "PIC16ABINames.h" -#include "PIC16ISelLowering.h" -using namespace llvm; - -PIC16MCAsmInfo::PIC16MCAsmInfo(const Target &T, StringRef TT) { - CommentString = ";"; - GlobalPrefix = PAN::getTagName(PAN::PREFIX_SYMBOL); - GlobalDirective = "\tglobal\t"; - ExternDirective = "\textern\t"; - - Data8bitsDirective = " db "; - Data16bitsDirective = " dw "; - Data32bitsDirective = " dl "; - Data64bitsDirective = NULL; - ZeroDirective = NULL; - AsciiDirective = " dt "; - AscizDirective = NULL; - - RomData8bitsDirective = " dw "; - RomData16bitsDirective = " rom_di "; - RomData32bitsDirective = " rom_dl "; - HasSetDirective = false; - - // Set it to false because we weed to generate c file name and not bc file - // name. - HasSingleParameterDotFile = false; -} - -const char *PIC16MCAsmInfo::getDataASDirective(unsigned Size, - unsigned AS) const { - if (AS != PIC16ISD::ROM_SPACE) - return 0; - - switch (Size) { - case 8: return RomData8bitsDirective; - case 16: return RomData16bitsDirective; - case 32: return RomData32bitsDirective; - default: return NULL; - } -} - diff --git a/lib/Target/PIC16/PIC16MCAsmInfo.h b/lib/Target/PIC16/PIC16MCAsmInfo.h deleted file mode 100644 index 6e1c111..0000000 --- a/lib/Target/PIC16/PIC16MCAsmInfo.h +++ /dev/null @@ -1,35 +0,0 @@ -//=====-- PIC16MCAsmInfo.h - PIC16 asm properties -------------*- C++ -*--====// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains the declaration of the PIC16MCAsmInfo class. -// -//===----------------------------------------------------------------------===// - -#ifndef PIC16TARGETASMINFO_H -#define PIC16TARGETASMINFO_H - -#include "llvm/MC/MCAsmInfo.h" - -namespace llvm { - class Target; - class StringRef; - - class PIC16MCAsmInfo : public MCAsmInfo { - const char *RomData8bitsDirective; - const char *RomData16bitsDirective; - const char *RomData32bitsDirective; - public: - PIC16MCAsmInfo(const Target &T, StringRef TT); - - virtual const char *getDataASDirective(unsigned size, unsigned AS) const; - }; - -} // namespace llvm - -#endif diff --git a/lib/Target/PIC16/PIC16MachineFunctionInfo.h b/lib/Target/PIC16/PIC16MachineFunctionInfo.h deleted file mode 100644 index bdf5086..0000000 --- a/lib/Target/PIC16/PIC16MachineFunctionInfo.h +++ /dev/null @@ -1,52 +0,0 @@ -//====- PIC16MachineFuctionInfo.h - PIC16 machine function info -*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file declares PIC16-specific per-machine-function information. -// -//===----------------------------------------------------------------------===// - -#ifndef PIC16MACHINEFUNCTIONINFO_H -#define PIC16MACHINEFUNCTIONINFO_H - -#include "llvm/CodeGen/MachineFunction.h" - -namespace llvm { - -/// PIC16MachineFunctionInfo - This class is derived from MachineFunction -/// private PIC16 target-specific information for each MachineFunction. -class PIC16MachineFunctionInfo : public MachineFunctionInfo { - // The frameindexes generated for spill/reload are stack based. - // This maps maintain zero based indexes for these FIs. - std::map<unsigned, unsigned> FiTmpOffsetMap; - unsigned TmpSize; - - // These are the frames for return value and argument passing - // These FrameIndices will be expanded to foo.frame external symbol - // and all others will be expanded to foo.tmp external symbol. - unsigned ReservedFrameCount; - -public: - PIC16MachineFunctionInfo() - : TmpSize(0), ReservedFrameCount(0) {} - - explicit PIC16MachineFunctionInfo(MachineFunction &MF) - : TmpSize(0), ReservedFrameCount(0) {} - - std::map<unsigned, unsigned> &getFiTmpOffsetMap() { return FiTmpOffsetMap; } - - unsigned getTmpSize() const { return TmpSize; } - void setTmpSize(unsigned Size) { TmpSize = Size; } - - unsigned getReservedFrameCount() const { return ReservedFrameCount; } - void setReservedFrameCount(unsigned Count) { ReservedFrameCount = Count; } -}; - -} // End llvm namespace - -#endif diff --git a/lib/Target/PIC16/PIC16MemSelOpt.cpp b/lib/Target/PIC16/PIC16MemSelOpt.cpp deleted file mode 100644 index b6aa38f..0000000 --- a/lib/Target/PIC16/PIC16MemSelOpt.cpp +++ /dev/null @@ -1,254 +0,0 @@ -//===-- PIC16MemSelOpt.cpp - PIC16 banksel optimizer --------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the pass which optimizes the emitting of banksel -// instructions before accessing data memory. This currently works within -// a basic block only and keep tracks of the last accessed memory bank. -// If memory access continues to be in the same bank it just makes banksel -// immediate, which is a part of the insn accessing the data memory, from 1 -// to zero. The asm printer emits a banksel only if that immediate is 1. -// -// FIXME: this is not implemented yet. The banksel pass only works on local -// basic blocks. -// -//===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "pic16-codegen" -#include "PIC16.h" -#include "PIC16ABINames.h" -#include "PIC16InstrInfo.h" -#include "PIC16MCAsmInfo.h" -#include "PIC16TargetMachine.h" -#include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/CodeGen/MachineInstrBuilder.h" -#include "llvm/CodeGen/Passes.h" -#include "llvm/Target/TargetInstrInfo.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/GlobalValue.h" -#include "llvm/DerivedTypes.h" - -using namespace llvm; - -namespace { - struct MemSelOpt : public MachineFunctionPass { - static char ID; - MemSelOpt() : MachineFunctionPass(ID) {} - - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.addPreservedID(MachineLoopInfoID); - AU.addPreservedID(MachineDominatorsID); - MachineFunctionPass::getAnalysisUsage(AU); - } - - virtual bool runOnMachineFunction(MachineFunction &MF); - - virtual const char *getPassName() const { - return "PIC16 Memsel Optimizer"; - } - - bool processBasicBlock(MachineFunction &MF, MachineBasicBlock &MBB); - bool processInstruction(MachineInstr *MI); - - private: - const TargetInstrInfo *TII; // Machine instruction info. - MachineBasicBlock *MBB; // Current basic block - std::string CurBank; - int PageChanged; - - }; - char MemSelOpt::ID = 0; -} - -FunctionPass *llvm::createPIC16MemSelOptimizerPass() { - return new MemSelOpt(); -} - - -/// runOnMachineFunction - Loop over all of the basic blocks, transforming FP -/// register references into FP stack references. -/// -bool MemSelOpt::runOnMachineFunction(MachineFunction &MF) { - TII = MF.getTarget().getInstrInfo(); - bool Changed = false; - for (MachineFunction::iterator I = MF.begin(), E = MF.end(); - I != E; ++I) { - Changed |= processBasicBlock(MF, *I); - } - - return Changed; -} - -/// processBasicBlock - Loop over all of the instructions in the basic block, -/// transforming FP instructions into their stack form. -/// -bool MemSelOpt::processBasicBlock(MachineFunction &MF, MachineBasicBlock &BB) { - bool Changed = false; - MBB = &BB; - - // Let us assume that when entering a basic block now bank is selected. - // Ideally we should look at the predecessors for this information. - CurBank=""; - PageChanged=0; - - MachineBasicBlock::iterator I; - for (I = BB.begin(); I != BB.end(); ++I) { - Changed |= processInstruction(I); - - // if the page has changed insert a page sel before - // any instruction that needs one - if (PageChanged == 1) - { - // Restore the page if it was changed, before leaving the basic block, - // because it may be required by the goto terminator or the fall thru - // basic blcok. - // If the terminator is return, we don't need to restore since there - // is no goto or fall thru basic block. - if ((I->getOpcode() == PIC16::sublw_3) || //macro has goto - (I->getOpcode() == PIC16::sublw_6) || //macro has goto - (I->getOpcode() == PIC16::addlwc) || //macro has goto - (TII->get(I->getOpcode()).isBranch())) - { - DebugLoc dl = I->getDebugLoc(); - BuildMI(*MBB, I, dl, TII->get(PIC16::pagesel)).addExternalSymbol("$"); - Changed = true; - PageChanged = 0; - } - } - } - - // The basic block is over, but if we did not find any goto yet, - // we haven't restored the page. - // Restore the page if it was changed, before leaving the basic block, - // because it may be required by fall thru basic blcok. - // If the terminator is return, we don't need to restore since there - // is fall thru basic block. - if (PageChanged == 1) { - // save the end pointer before we move back to last insn. - MachineBasicBlock::iterator J = I; - I--; - const TargetInstrDesc &TID = TII->get(I->getOpcode()); - if (! TID.isReturn()) - { - DebugLoc dl = I->getDebugLoc(); - BuildMI(*MBB, J, dl, - TII->get(PIC16::pagesel)).addExternalSymbol("$"); - Changed = true; - PageChanged = 0; - } - } - - - return Changed; -} - -bool MemSelOpt::processInstruction(MachineInstr *MI) { - bool Changed = false; - - unsigned NumOperands = MI->getNumOperands(); - if (NumOperands == 0) return false; - - - // If this insn is not going to access any memory, return. - const TargetInstrDesc &TID = TII->get(MI->getOpcode()); - if (!(TID.isBranch() || TID.isCall() || TID.mayLoad() || TID.mayStore())) - return false; - - // The first thing we should do is that record if banksel/pagesel are - // changed in an unknown way. This can happend via any type of call. - // We do it here first before scanning of MemOp / BBOp as the indirect - // call insns do not have any operands, but they still may change bank/page. - if (TID.isCall()) { - // Record that we have changed the page, so that we can restore it - // before basic block ends. - // We require to signal that a page anc bank change happened even for - // indirect calls. - PageChanged = 1; - - // When a call is made, there may be banksel for variables in callee. - // Hence the banksel in caller needs to be reset. - CurBank = ""; - } - - // Scan for the memory address operand. - // FIXME: Should we use standard interfaces like memoperands_iterator, - // hasMemOperand() etc ? - int MemOpPos = -1; - int BBOpPos = -1; - for (unsigned i = 0; i < NumOperands; i++) { - MachineOperand Op = MI->getOperand(i); - if (Op.getType() == MachineOperand::MO_GlobalAddress || - Op.getType() == MachineOperand::MO_ExternalSymbol) { - // We found one mem operand. Next one may be BS. - MemOpPos = i; - } - if (Op.getType() == MachineOperand::MO_MachineBasicBlock) { - // We found one BB operand. Next one may be pagesel. - BBOpPos = i; - } - } - - // If we did not find an insn accessing memory. Continue. - if ((MemOpPos == -1) && - (BBOpPos == -1)) - return false; - assert ((BBOpPos != MemOpPos) && "operand can only be of one type"); - - - // If this is a pagesel material, handle it first. - // CALL and br_ucond insns use MemOp (GA or ES) and not BBOp. - // Pagesel is required only for a direct call. - if ((MI->getOpcode() == PIC16::CALL)) { - // Get the BBOp. - MachineOperand &MemOp = MI->getOperand(MemOpPos); - DebugLoc dl = MI->getDebugLoc(); - BuildMI(*MBB, MI, dl, TII->get(PIC16::pagesel)).addOperand(MemOp); - - // CALL and br_ucond needs only pagesel. so we are done. - return true; - } - - // Pagesel is handled. Now, add a Banksel if needed. - if (MemOpPos == -1) return Changed; - // Get the MemOp. - MachineOperand &Op = MI->getOperand(MemOpPos); - - // Get the section name(NewBank) for MemOp. - // This assumes that the section names for globals are already set by - // AsmPrinter->doInitialization. - std::string NewBank = CurBank; - bool hasExternalLinkage = false; - if (Op.getType() == MachineOperand::MO_GlobalAddress && - Op.getGlobal()->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE) { - if (Op.getGlobal()->hasExternalLinkage()) - hasExternalLinkage= true; - NewBank = Op.getGlobal()->getSection(); - } else if (Op.getType() == MachineOperand::MO_ExternalSymbol) { - // External Symbol is generated for temp data and arguments. They are - // in fpdata.<functionname>.# section. - std::string Sym = Op.getSymbolName(); - NewBank = PAN::getSectionNameForSym(Sym); - } - - // If the section is shared section, do not emit banksel. - if (NewBank == PAN::getSharedUDataSectionName()) - return Changed; - - // If the previous and new section names are same, we don't need to - // emit banksel. - if (NewBank.compare(CurBank) != 0 || hasExternalLinkage) { - DebugLoc dl = MI->getDebugLoc(); - BuildMI(*MBB, MI, dl, TII->get(PIC16::banksel)). - addOperand(Op); - Changed = true; - CurBank = NewBank; - } - - return Changed; -} - diff --git a/lib/Target/PIC16/PIC16Passes/Makefile b/lib/Target/PIC16/PIC16Passes/Makefile deleted file mode 100644 index 9684b8d..0000000 --- a/lib/Target/PIC16/PIC16Passes/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -##===- lib/Target/PIC16/PIC16Passes/Makefile -----------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## -LEVEL = ../../../.. -TARGET = PIC16 -LIBRARYNAME = LLVMpic16passes -BUILD_ARCHIVE = 1 - -include $(LEVEL)/Makefile.common - diff --git a/lib/Target/PIC16/PIC16Passes/PIC16Cloner.cpp b/lib/Target/PIC16/PIC16Passes/PIC16Cloner.cpp deleted file mode 100644 index 56f0211..0000000 --- a/lib/Target/PIC16/PIC16Passes/PIC16Cloner.cpp +++ /dev/null @@ -1,299 +0,0 @@ -//===-- PIC16Cloner.cpp - PIC16 LLVM Cloner for shared functions -*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains code to clone all functions that are shared between -// the main line code (ML) and interrupt line code (IL). It clones all such -// shared functions and their automatic global vars by adding the .IL suffix. -// -// This pass is supposed to be run on the linked .bc module. -// It traveses the module call graph twice. Once starting from the main function -// and marking each reached function as "ML". Again, starting from the ISR -// and cloning any reachable function that was marked as "ML". After cloning -// the function, it remaps all the call sites in IL functions to call the -// cloned functions. -//===----------------------------------------------------------------------===// - -#include "llvm/Analysis/CallGraph.h" -#include "llvm/Pass.h" -#include "llvm/Module.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Transforms/Utils/Cloning.h" -#include "PIC16Cloner.h" -#include "../PIC16ABINames.h" -#include <vector> - -using namespace llvm; -using std::vector; -using std::string; -using std::map; - -namespace llvm { - char PIC16Cloner::ID = 0; - - ModulePass *createPIC16ClonerPass() { return new PIC16Cloner(); } -} - -// We currently intend to run these passes in opt, which does not have any -// diagnostic support. So use these functions for now. In future -// we will probably write our own driver tool. -// -void PIC16Cloner::reportError(string ErrorString) { - errs() << "ERROR : " << ErrorString << "\n"; - exit(1); -} - -void PIC16Cloner:: -reportError (string ErrorString, vector<string> &Values) { - unsigned ValCount = Values.size(); - string TargetString; - for (unsigned i=0; i<ValCount; ++i) { - TargetString = "%"; - TargetString += ((char)i + '0'); - ErrorString.replace(ErrorString.find(TargetString), TargetString.length(), - Values[i]); - } - errs() << "ERROR : " << ErrorString << "\n"; - exit(1); -} - - -// Entry point -// -bool PIC16Cloner::runOnModule(Module &M) { - CallGraph &CG = getAnalysis<CallGraph>(); - - // Search for the "main" and "ISR" functions. - CallGraphNode *mainCGN = NULL, *isrCGN = NULL; - for (CallGraph::iterator it = CG.begin() ; it != CG.end(); it++) - { - // External calling node doesn't have any function associated with it. - if (! it->first) - continue; - - if (it->first->getName().str() == "main") { - mainCGN = it->second; - } - - if (PAN::isISR(it->first->getSection())) { - isrCGN = it->second; - } - - // Don't search further if we've found both. - if (mainCGN && isrCGN) - break; - } - - // We have nothing to do if any of the main or ISR is missing. - if (! mainCGN || ! isrCGN) return false; - - // Time for some diagnostics. - // See if the main itself is interrupt function then report an error. - if (PAN::isISR(mainCGN->getFunction()->getSection())) { - reportError("Function 'main' can't be interrupt function"); - } - - - // Mark all reachable functions from main as ML. - markCallGraph(mainCGN, "ML"); - - // And then all the functions reachable from ISR will be cloned. - cloneSharedFunctions(isrCGN); - - return true; -} - -// Mark all reachable functions from the given node, with the given mark. -// -void PIC16Cloner::markCallGraph(CallGraphNode *CGN, string StringMark) { - // Mark the top node first. - Function *thisF = CGN->getFunction(); - - thisF->setSection(StringMark); - - // Mark all the called functions - for(CallGraphNode::iterator cgn_it = CGN->begin(); - cgn_it != CGN->end(); ++cgn_it) { - Function *CalledF = cgn_it->second->getFunction(); - - // If calling an external function then CallGraphNode - // will not be associated with any function. - if (! CalledF) - continue; - - // Issue diagnostic if interrupt function is being called. - if (PAN::isISR(CalledF->getSection())) { - vector<string> Values; - Values.push_back(CalledF->getName().str()); - reportError("Interrupt function (%0) can't be called", Values); - } - - // Has already been mark - if (CalledF->getSection().find(StringMark) != string::npos) { - // Should we do anything here? - } else { - // Mark now - CalledF->setSection(StringMark); - } - - // Before going any further mark all the called function by current - // function. - markCallGraph(cgn_it->second ,StringMark); - } // end of loop of all called functions. -} - - -// For PIC16, automatic variables of a function are emitted as globals. -// Clone the auto variables of a function and put them in VMap, -// this VMap will be used while -// Cloning the code of function itself. -// -void PIC16Cloner::CloneAutos(Function *F) { - // We'll need to update module's globals list as well. So keep a reference - // handy. - Module *M = F->getParent(); - Module::GlobalListType &Globals = M->getGlobalList(); - - // Clear the leftovers in VMap by any previous cloning. - VMap.clear(); - - // Find the auto globls for this function and clone them, and put them - // in VMap. - std::string FnName = F->getName().str(); - std::string VarName, ClonedVarName; - for (Module::global_iterator I = M->global_begin(), E = M->global_end(); - I != E; ++I) { - VarName = I->getName().str(); - if (PAN::isLocalToFunc(FnName, VarName)) { - // Auto variable for current function found. Clone it. - const GlobalVariable *GV = I; - - const Type *InitTy = GV->getInitializer()->getType(); - GlobalVariable *ClonedGV = - new GlobalVariable(InitTy, false, GV->getLinkage(), - GV->getInitializer()); - ClonedGV->setName(PAN::getCloneVarName(FnName, VarName)); - // Add these new globals to module's globals list. - Globals.push_back(ClonedGV); - - // Update VMap. - VMap[GV] = ClonedGV; - } - } -} - - -// Clone all functions that are reachable from ISR and are already -// marked as ML. -// -void PIC16Cloner::cloneSharedFunctions(CallGraphNode *CGN) { - - // Check all the called functions from ISR. - for(CallGraphNode::iterator cgn_it = CGN->begin(); - cgn_it != CGN->end(); ++cgn_it) { - Function *CalledF = cgn_it->second->getFunction(); - - // If calling an external function then CallGraphNode - // will not be associated with any function. - if (!CalledF) - continue; - - // Issue diagnostic if interrupt function is being called. - if (PAN::isISR(CalledF->getSection())) { - vector<string> Values; - Values.push_back(CalledF->getName().str()); - reportError("Interrupt function (%0) can't be called", Values); - } - - if (CalledF->getSection().find("ML") != string::npos) { - // Function is alternatively marked. It should be a shared one. - // Create IL copy. Passing called function as first argument - // and the caller as the second argument. - - // Before making IL copy, first ensure that this function has a - // body. If the function does have a body. It can't be cloned. - // Such a case may occur when the function has been declarated - // in the C source code but its body exists in assembly file. - if (!CalledF->isDeclaration()) { - Function *cf = cloneFunction(CalledF); - remapAllSites(CGN->getFunction(), CalledF, cf); - } else { - // It is called only from ISR. Still mark it as we need this info - // in code gen while calling intrinsics.Function is not marked. - CalledF->setSection("IL"); - } - } - // Before going any further clone all the shared function reachaable - // by current function. - cloneSharedFunctions(cgn_it->second); - } // end of loop of all called functions. -} - -// Clone the given function and return it. -// Note: it uses the VMap member of the class, which is already populated -// by cloneAutos by the time we reach here. -// FIXME: Should we just pass VMap's ref as a parameter here? rather -// than keeping the VMap as a member. -Function * -PIC16Cloner::cloneFunction(Function *OrgF) { - Function *ClonedF; - - // See if we already cloned it. Return that. - cloned_map_iterator cm_it = ClonedFunctionMap.find(OrgF); - if(cm_it != ClonedFunctionMap.end()) { - ClonedF = cm_it->second; - return ClonedF; - } - - // Clone does not exist. - // First clone the autos, and populate VMap. - CloneAutos(OrgF); - - // Now create the clone. - ClonedF = CloneFunction(OrgF, VMap, /*ModuleLevelChanges=*/false); - - // The new function should be for interrupt line. Therefore should have - // the name suffixed with IL and section attribute marked with IL. - ClonedF->setName(PAN::getCloneFnName(OrgF->getName())); - ClonedF->setSection("IL"); - - // Add the newly created function to the module. - OrgF->getParent()->getFunctionList().push_back(ClonedF); - - // Update the ClonedFunctionMap to record this cloning activity. - ClonedFunctionMap[OrgF] = ClonedF; - - return ClonedF; -} - - -// Remap the call sites of shared functions, that are in IL. -// Change the IL call site of a shared function to its clone. -// -void PIC16Cloner:: -remapAllSites(Function *Caller, Function *OrgF, Function *Clone) { - // First find the caller to update. If the caller itself is cloned - // then use the cloned caller. Otherwise use it. - cloned_map_iterator cm_it = ClonedFunctionMap.find(Caller); - if (cm_it != ClonedFunctionMap.end()) - Caller = cm_it->second; - - // For the lack of a better call site finding mechanism, iterate over - // all insns to find the uses of original fn. - for (Function::iterator BI = Caller->begin(); BI != Caller->end(); ++BI) { - BasicBlock &BB = *BI; - for (BasicBlock::iterator II = BB.begin(); II != BB.end(); ++II) { - if (II->getNumOperands() > 0 && II->getOperand(0) == OrgF) - II->setOperand(0, Clone); - } - } -} - - - diff --git a/lib/Target/PIC16/PIC16Passes/PIC16Cloner.h b/lib/Target/PIC16/PIC16Passes/PIC16Cloner.h deleted file mode 100644 index e7d67ce..0000000 --- a/lib/Target/PIC16/PIC16Passes/PIC16Cloner.h +++ /dev/null @@ -1,83 +0,0 @@ -//===-- PIC16Cloner.h - PIC16 LLVM Cloner for shared functions --*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains declaration of a cloner class clone all functions that -// are shared between the main line code (ML) and interrupt line code (IL). -// -//===----------------------------------------------------------------------===// - -#ifndef PIC16CLONER_H -#define PIC16CLONER_H - -#include "llvm/ADT/ValueMap.h" - -using namespace llvm; -using std::vector; -using std::string; -using std::map; - -namespace llvm { - // forward classes. - class Value; - class Function; - class Module; - class ModulePass; - class CallGraph; - class CallGraphNode; - class AnalysisUsage; - - class PIC16Cloner : public ModulePass { - public: - static char ID; // Class identification - PIC16Cloner() : ModulePass(ID) {} - - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequired<CallGraph>(); - } - virtual bool runOnModule(Module &M); - - private: // Functions - // Mark reachable functions for the MainLine or InterruptLine. - void markCallGraph(CallGraphNode *CGN, string StringMark); - - // Clone auto variables of function specified. - void CloneAutos(Function *F); - - // Clone the body of a function. - Function *cloneFunction(Function *F); - - // Clone all shared functions. - void cloneSharedFunctions(CallGraphNode *isrCGN); - - // Remap all call sites to the shared function. - void remapAllSites(Function *Caller, Function *OrgF, Function *Clone); - - // Error reporting for PIC16Pass - void reportError(string ErrorString, vector<string> &Values); - void reportError(string ErrorString); - - private: //data - // Records if the interrupt function has already been found. - // If more than one interrupt function is found then an error - // should be thrown. - bool foundISR; - - // This ValueMap maps the auto variables of the original functions with - // the corresponding cloned auto variable of the cloned function. - // This value map is passed during the function cloning so that all the - // uses of auto variables be updated properly. - ValueMap<const Value*, Value*> VMap; - - // Map of a already cloned functions. - map<Function *, Function *> ClonedFunctionMap; - typedef map<Function *, Function *>::iterator cloned_map_iterator; - }; -} // End of anonymous namespace - -#endif diff --git a/lib/Target/PIC16/PIC16Passes/PIC16Overlay.cpp b/lib/Target/PIC16/PIC16Passes/PIC16Overlay.cpp deleted file mode 100644 index 0f8928a..0000000 --- a/lib/Target/PIC16/PIC16Passes/PIC16Overlay.cpp +++ /dev/null @@ -1,182 +0,0 @@ -//===-- PIC16Overlay.cpp - Implementation for PIC16 Frame Overlay===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains the PIC16 Frame Overlay implementation. -// -//===----------------------------------------------------------------------===// - - -#include "llvm/Analysis/CallGraph.h" -#include "llvm/Pass.h" -#include "llvm/Module.h" -#include "llvm/Instructions.h" -#include "llvm/Value.h" -#include "PIC16Overlay.h" -#include "llvm/Function.h" -#include <cstdlib> -#include <sstream> -using namespace llvm; - -namespace llvm { - char PIC16Overlay::ID = 0; - ModulePass *createPIC16OverlayPass() { return new PIC16Overlay(); } -} - -void PIC16Overlay::getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesAll(); - AU.addRequired<CallGraph>(); -} - -void PIC16Overlay::DFSTraverse(CallGraphNode *CGN, unsigned Depth) { - // Do not set any color for external calling node. - if (Depth != 0 && CGN->getFunction()) { - unsigned Color = getColor(CGN->getFunction()); - - // Handle indirectly called functions - if (Color >= PIC16OVERLAY::StartIndirectCallColor || - Depth >= PIC16OVERLAY::StartIndirectCallColor) { - // All functions called from an indirectly called function are given - // an unique color. - if (Color < PIC16OVERLAY::StartIndirectCallColor && - Depth >= PIC16OVERLAY::StartIndirectCallColor) - setColor(CGN->getFunction(), Depth); - - for (unsigned int i = 0; i < CGN->size(); i++) - DFSTraverse((*CGN)[i], ++IndirectCallColor); - return; - } - // Just return if the node already has a color greater than the current - // depth. A node must be colored with the maximum depth that it has. - if (Color >= Depth) - return; - - Depth = ModifyDepthForInterrupt(CGN, Depth); - setColor(CGN->getFunction(), Depth); - } - - // Color all children of this node with color depth+1. - for (unsigned int i = 0; i < CGN->size(); i++) - DFSTraverse((*CGN)[i], Depth+1); -} - -unsigned PIC16Overlay::ModifyDepthForInterrupt(CallGraphNode *CGN, - unsigned Depth) { - Function *Fn = CGN->getFunction(); - - // Return original Depth if function or section for function do not exist. - if (!Fn || !Fn->hasSection()) - return Depth; - - // Return original Depth if this function is not marked as interrupt. - if (Fn->getSection().find("interrupt") == string::npos) - return Depth; - - Depth = Depth + InterruptDepth; - return Depth; -} - -void PIC16Overlay::setColor(Function *Fn, unsigned Color) { - std::string Section = ""; - if (Fn->hasSection()) - Section = Fn->getSection(); - - size_t Pos = Section.find(OverlayStr); - - // Convert Color to string. - std::stringstream ss; - ss << Color; - std::string ColorString = ss.str(); - - // If color is already set then reset it with the new value. Else append - // the Color string to section. - if (Pos != std::string::npos) { - Pos += OverlayStr.length(); - char c = Section.at(Pos); - unsigned OldColorLength = 0; - while (c >= '0' && c<= '9') { - OldColorLength++; - if (Pos < Section.length() - 1) - Pos++; - else - break; - c = Section.at(Pos); - } - // Replace old color with new one. - Section.replace(Pos-OldColorLength +1, OldColorLength, ColorString); - } - else { - // Append Color information to section string. - if (Fn->hasSection()) - Section.append(" "); - Section.append(OverlayStr + ColorString); - } - Fn->setSection(Section); -} - -unsigned PIC16Overlay::getColor(Function *Fn) { - int Color = 0; - if (!Fn->hasSection()) - return 0; - - std::string Section = Fn->getSection(); - size_t Pos = Section.find(OverlayStr); - - // Return 0 if Color is not set. - if (Pos == std::string::npos) - return 0; - - // Set Pos to after "Overlay=". - Pos += OverlayStr.length(); - char c = Section.at(Pos); - std::string ColorString = ""; - - // Find the string representing Color. A Color can only consist of digits. - while (c >= '0' && c<= '9') { - ColorString.append(1,c); - if (Pos < Section.length() - 1) - Pos++; - else - break; - c = Section.at(Pos); - } - Color = atoi(ColorString.c_str()); - - return Color; -} - -bool PIC16Overlay::runOnModule(Module &M) { - CallGraph &CG = getAnalysis<CallGraph>(); - CallGraphNode *ECN = CG.getExternalCallingNode(); - - MarkIndirectlyCalledFunctions(M); - // Since External Calling Node is the base function, do a depth first - // traversal of CallGraph with ECN as root. Each node with be marked with - // a color that is max(color(callers)) + 1. - if(ECN) { - DFSTraverse(ECN, 0); - } - return false; -} - -void PIC16Overlay::MarkIndirectlyCalledFunctions(Module &M) { - // If the use of a function is not a call instruction then this - // function might be called indirectly. In that case give it - // an unique color. - for (Module::iterator MI = M.begin(), E = M.end(); MI != E; ++MI) { - for (Value::use_iterator I = MI->use_begin(), E = MI->use_end(); I != E; - ++I) { - User *U = *I; - if ((!isa<CallInst>(U) && !isa<InvokeInst>(U)) - || !CallSite(cast<Instruction>(U)).isCallee(I)) { - setColor(MI, ++IndirectCallColor); - break; - } - } - } -} diff --git a/lib/Target/PIC16/PIC16Passes/PIC16Overlay.h b/lib/Target/PIC16/PIC16Passes/PIC16Overlay.h deleted file mode 100644 index 2f611e6..0000000 --- a/lib/Target/PIC16/PIC16Passes/PIC16Overlay.h +++ /dev/null @@ -1,60 +0,0 @@ -//===-- PIC16Overlay.h - Interface for PIC16 Frame Overlay -*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains the PIC16 Overlay infrastructure. -// -//===----------------------------------------------------------------------===// - -#ifndef PIC16FRAMEOVERLAY_H -#define PIC16FRAMEOVERLAY_H - - -using std::string; -using namespace llvm; - -namespace llvm { - // Forward declarations. - class Function; - class Module; - class ModulePass; - class AnalysisUsage; - class CallGraphNode; - class CallGraph; - - namespace PIC16OVERLAY { - enum OverlayConsts { - StartInterruptColor = 200, - StartIndirectCallColor = 300 - }; - } - class PIC16Overlay : public ModulePass { - std::string OverlayStr; - unsigned InterruptDepth; - unsigned IndirectCallColor; - public: - static char ID; // Class identification - PIC16Overlay() : ModulePass(ID) { - OverlayStr = "Overlay="; - InterruptDepth = PIC16OVERLAY::StartInterruptColor; - IndirectCallColor = PIC16OVERLAY::StartIndirectCallColor; - } - - virtual void getAnalysisUsage(AnalysisUsage &AU) const; - virtual bool runOnModule(Module &M); - - private: - unsigned getColor(Function *Fn); - void setColor(Function *Fn, unsigned Color); - unsigned ModifyDepthForInterrupt(CallGraphNode *CGN, unsigned Depth); - void MarkIndirectlyCalledFunctions(Module &M); - void DFSTraverse(CallGraphNode *CGN, unsigned Depth); - }; -} // End of namespace - -#endif diff --git a/lib/Target/PIC16/PIC16RegisterInfo.cpp b/lib/Target/PIC16/PIC16RegisterInfo.cpp deleted file mode 100644 index 76de47f..0000000 --- a/lib/Target/PIC16/PIC16RegisterInfo.cpp +++ /dev/null @@ -1,84 +0,0 @@ -//===- PIC16RegisterInfo.cpp - PIC16 Register Information -----------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains the PIC16 implementation of the TargetRegisterInfo class. -// -//===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "pic16-reg-info" - -#include "PIC16.h" -#include "PIC16RegisterInfo.h" -#include "llvm/ADT/BitVector.h" -#include "llvm/Support/ErrorHandling.h" - -using namespace llvm; - -PIC16RegisterInfo::PIC16RegisterInfo(const TargetInstrInfo &tii, - const PIC16Subtarget &st) - : PIC16GenRegisterInfo(PIC16::ADJCALLSTACKDOWN, PIC16::ADJCALLSTACKUP), - TII(tii), - ST(st) {} - -#include "PIC16GenRegisterInfo.inc" - -/// PIC16 Callee Saved Registers -const unsigned* PIC16RegisterInfo:: -getCalleeSavedRegs(const MachineFunction *MF) const { - static const unsigned CalleeSavedRegs[] = { 0 }; - return CalleeSavedRegs; -} - -BitVector PIC16RegisterInfo::getReservedRegs(const MachineFunction &MF) const { - BitVector Reserved(getNumRegs()); - return Reserved; -} - -bool PIC16RegisterInfo::hasFP(const MachineFunction &MF) const { - return false; -} - -void PIC16RegisterInfo:: -eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj, - RegScavenger *RS) const -{ /* NOT YET IMPLEMENTED */ } - -void PIC16RegisterInfo::emitPrologue(MachineFunction &MF) const -{ /* NOT YET IMPLEMENTED */ } - -void PIC16RegisterInfo:: -emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const -{ /* NOT YET IMPLEMENTED */ } - -int PIC16RegisterInfo:: -getDwarfRegNum(unsigned RegNum, bool isEH) const { - llvm_unreachable("Not keeping track of debug information yet!!"); - return -1; -} - -unsigned PIC16RegisterInfo::getFrameRegister(const MachineFunction &MF) const { - llvm_unreachable("PIC16 Does not have any frame register"); - return 0; -} - -unsigned PIC16RegisterInfo::getRARegister() const { - llvm_unreachable("PIC16 Does not have any return address register"); - return 0; -} - -// This function eliminates ADJCALLSTACKDOWN, -// ADJCALLSTACKUP pseudo instructions -void PIC16RegisterInfo:: -eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, - MachineBasicBlock::iterator I) const { - // Simply discard ADJCALLSTACKDOWN, - // ADJCALLSTACKUP instructions. - MBB.erase(I); -} - diff --git a/lib/Target/PIC16/PIC16RegisterInfo.h b/lib/Target/PIC16/PIC16RegisterInfo.h deleted file mode 100644 index 20052b0..0000000 --- a/lib/Target/PIC16/PIC16RegisterInfo.h +++ /dev/null @@ -1,64 +0,0 @@ -//===- PIC16RegisterInfo.h - PIC16 Register Information Impl ----*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains the PIC16 implementation of the TargetRegisterInfo class. -// -//===----------------------------------------------------------------------===// - -#ifndef PIC16REGISTERINFO_H -#define PIC16REGISTERINFO_H - -#include "PIC16GenRegisterInfo.h.inc" -#include "llvm/Target/TargetRegisterInfo.h" - -namespace llvm { - -// Forward Declarations. - class PIC16Subtarget; - class TargetInstrInfo; - -class PIC16RegisterInfo : public PIC16GenRegisterInfo { - private: - const TargetInstrInfo &TII; - const PIC16Subtarget &ST; - - public: - PIC16RegisterInfo(const TargetInstrInfo &tii, - const PIC16Subtarget &st); - - - //------------------------------------------------------ - // Pure virtual functions from TargetRegisterInfo - //------------------------------------------------------ - - // PIC16 callee saved registers - virtual const unsigned* - getCalleeSavedRegs(const MachineFunction *MF = 0) const; - - virtual BitVector getReservedRegs(const MachineFunction &MF) const; - virtual bool hasFP(const MachineFunction &MF) const; - - virtual void eliminateFrameIndex(MachineBasicBlock::iterator MI, - int SPAdj, RegScavenger *RS=NULL) const; - - void eliminateCallFramePseudoInstr(MachineFunction &MF, - MachineBasicBlock &MBB, - MachineBasicBlock::iterator I) const; - - virtual void emitPrologue(MachineFunction &MF) const; - virtual void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const; - virtual int getDwarfRegNum(unsigned RegNum, bool isEH) const; - virtual unsigned getFrameRegister(const MachineFunction &MF) const; - virtual unsigned getRARegister() const; - -}; - -} // end namespace llvm - -#endif diff --git a/lib/Target/PIC16/PIC16RegisterInfo.td b/lib/Target/PIC16/PIC16RegisterInfo.td deleted file mode 100644 index 2959d91..0000000 --- a/lib/Target/PIC16/PIC16RegisterInfo.td +++ /dev/null @@ -1,33 +0,0 @@ -//===- PIC16RegisterInfo.td - PIC16 Register defs ------------*- tblgen -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -//===----------------------------------------------------------------------===// -// Declarations that describe the PIC16 register file -//===----------------------------------------------------------------------===// - -class PIC16Reg<string n> : Register<n> { - let Namespace = "PIC16"; -} - -// PIC16 Registers. -def W : PIC16Reg<"W">; -def FSR0 : PIC16Reg<"FSR0">; -def FSR1 : PIC16Reg<"FSR1">; -def BS : PIC16Reg<"BS">; -def PCLATH : PIC16Reg<"PCLATH">; - -def STATUS : PIC16Reg<"STATUS">; - -// PIC16 Register classes. -def GPR : RegisterClass<"PIC16", [i8], 8, [W]>; -def FSR16 : RegisterClass<"PIC16", [i16], 8, [FSR0, FSR1]>; -def BSR : RegisterClass<"PIC16", [i8], 8, [BS]>; -def PCLATHR : RegisterClass<"PIC16", [i8], 8, [PCLATH]>; -def STATUSR : RegisterClass<"PIC16", [i8], 8, [STATUS]>; - diff --git a/lib/Target/PIC16/PIC16Section.cpp b/lib/Target/PIC16/PIC16Section.cpp deleted file mode 100644 index 2505b11..0000000 --- a/lib/Target/PIC16/PIC16Section.cpp +++ /dev/null @@ -1,104 +0,0 @@ -//===-- PIC16Section.cpp - PIC16 Section ----------- --------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "PIC16.h" -#include "PIC16ABINames.h" -#include "PIC16Section.h" -#include "llvm/MC/MCContext.h" -#include "llvm/Support/raw_ostream.h" -using namespace llvm; - - -// This is the only way to create a PIC16Section. Sections created here -// do not need to be explicitly deleted as they are managed by auto_ptrs. -PIC16Section *PIC16Section::Create(StringRef Name, PIC16SectionType Ty, - StringRef Address, int Color, - MCContext &Ctx) { - - /// Determine the internal SectionKind info. - /// Users of PIC16Section class should not need to know the internal - /// SectionKind. They should work only with PIC16SectionType. - /// - /// PIC16 Terminology for section kinds is as below. - /// UDATA - BSS - /// IDATA - initialized data (equiv to Metadata) - /// ROMDATA - ReadOnly. - /// UDATA_OVR - Sections that can be overlaid. Section of such type is - /// used to contain function autos an frame. We can think of - /// it as equiv to llvm ThreadBSS) - /// UDATA_SHR - Shared RAM. Memory area that is mapped to all banks. - - SectionKind K; - switch (Ty) { - default: llvm_unreachable ("can not create unknown section type"); - case UDATA_OVR: { - K = SectionKind::getThreadBSS(); - break; - } - case UDATA_SHR: - case UDATA: { - K = SectionKind::getBSS(); - break; - } - case ROMDATA: - case IDATA: { - K = SectionKind::getMetadata(); - break; - } - case CODE: { - K = SectionKind::getText(); - break; - } - - } - - // Copy strings into context allocated memory so they get free'd when the - // context is destroyed. - char *NameCopy = static_cast<char*>(Ctx.Allocate(Name.size(), 1)); - memcpy(NameCopy, Name.data(), Name.size()); - char *AddressCopy = static_cast<char*>(Ctx.Allocate(Address.size(), 1)); - memcpy(AddressCopy, Address.data(), Address.size()); - - // Create the Section. - PIC16Section *S = - new (Ctx) PIC16Section(StringRef(NameCopy, Name.size()), K, - StringRef(AddressCopy, Address.size()), Color); - S->T = Ty; - return S; -} - -// A generic way to print all types of sections. -void PIC16Section::PrintSwitchToSection(const MCAsmInfo &MAI, - raw_ostream &OS) const { - - // If the section is overlaid(i.e. it has a color), print overlay name for - // it. Otherwise print its normal name. - if (Color != -1) - OS << PAN::getOverlayName(getName(), Color) << '\t'; - else - OS << getName() << '\t'; - - // Print type. - switch (getType()) { - default : llvm_unreachable ("unknown section type"); - case UDATA: OS << "UDATA"; break; - case IDATA: OS << "IDATA"; break; - case ROMDATA: OS << "ROMDATA"; break; - case UDATA_SHR: OS << "UDATA_SHR"; break; - case UDATA_OVR: OS << "UDATA_OVR"; break; - case CODE: OS << "CODE"; break; - } - - OS << '\t'; - - // Print Address. - OS << Address; - - OS << '\n'; -} diff --git a/lib/Target/PIC16/PIC16Section.h b/lib/Target/PIC16/PIC16Section.h deleted file mode 100644 index 5b33b51..0000000 --- a/lib/Target/PIC16/PIC16Section.h +++ /dev/null @@ -1,99 +0,0 @@ -//===- PIC16Section.h - PIC16-specific section representation -*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file declares the PIC16Section class. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_PIC16SECTION_H -#define LLVM_PIC16SECTION_H - -#include "llvm/MC/MCSection.h" -#include "llvm/GlobalVariable.h" -#include <vector> - -namespace llvm { - /// PIC16Section - Represents a physical section in PIC16 COFF. - /// Contains data objects. - /// - class PIC16Section : public MCSection { - /// PIC16 Sections does not really use the SectionKind class to - /// to distinguish between various types of sections. PIC16 maintain - /// its own Section Type info. See the PIC16SectionType enum in PIC16.h - /// for various section types. - PIC16SectionType T; - - /// Name of the section to uniquely identify it. - StringRef Name; - - /// User can specify an address at which a section should be placed. - /// Negative value here means user hasn't specified any. - StringRef Address; - - /// Overlay information - Sections with same color can be overlaid on - /// one another. - int Color; - - /// Total size of all data objects contained here. - unsigned Size; - - PIC16Section(StringRef name, SectionKind K, StringRef addr, int color) - : MCSection(SV_PIC16, K), Name(name), Address(addr), - Color(color), Size(0) { - } - - public: - /// Return the name of the section. - StringRef getName() const { return Name; } - - /// Return the Address of the section. - StringRef getAddress() const { return Address; } - - /// Return the Color of the section. - int getColor() const { return Color; } - void setColor(int color) { Color = color; } - - /// Return the size of the section. - unsigned getSize() const { return Size; } - void setSize(unsigned size) { Size = size; } - - /// Conatined data objects. - // FIXME: This vector is leaked because sections are allocated with a - // BumpPtrAllocator. - std::vector<const GlobalVariable *>Items; - - /// Check section type. - bool isUDATA_Type() const { return T == UDATA; } - bool isIDATA_Type() const { return T == IDATA; } - bool isROMDATA_Type() const { return T == ROMDATA; } - bool isUDATA_OVR_Type() const { return T == UDATA_OVR; } - bool isUDATA_SHR_Type() const { return T == UDATA_SHR; } - bool isCODE_Type() const { return T == CODE; } - - PIC16SectionType getType() const { return T; } - - /// This would be the only way to create a section. - static PIC16Section *Create(StringRef Name, PIC16SectionType Ty, - StringRef Address, int Color, - MCContext &Ctx); - - /// Override this as PIC16 has its own way of printing switching - /// to a section. - virtual void PrintSwitchToSection(const MCAsmInfo &MAI, - raw_ostream &OS) const; - - static bool classof(const MCSection *S) { - return S->getVariant() == SV_PIC16; - } - static bool classof(const PIC16Section *) { return true; } - }; - -} // end namespace llvm - -#endif diff --git a/lib/Target/PIC16/PIC16SelectionDAGInfo.cpp b/lib/Target/PIC16/PIC16SelectionDAGInfo.cpp deleted file mode 100644 index 995955a..0000000 --- a/lib/Target/PIC16/PIC16SelectionDAGInfo.cpp +++ /dev/null @@ -1,23 +0,0 @@ -//===-- PIC16SelectionDAGInfo.cpp - PIC16 SelectionDAG Info ---------------===// -// -// 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 PIC16SelectionDAGInfo class. -// -//===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "pic16-selectiondag-info" -#include "PIC16TargetMachine.h" -using namespace llvm; - -PIC16SelectionDAGInfo::PIC16SelectionDAGInfo(const PIC16TargetMachine &TM) - : TargetSelectionDAGInfo(TM) { -} - -PIC16SelectionDAGInfo::~PIC16SelectionDAGInfo() { -} diff --git a/lib/Target/PIC16/PIC16SelectionDAGInfo.h b/lib/Target/PIC16/PIC16SelectionDAGInfo.h deleted file mode 100644 index c67fd8b..0000000 --- a/lib/Target/PIC16/PIC16SelectionDAGInfo.h +++ /dev/null @@ -1,31 +0,0 @@ -//===-- PIC16SelectionDAGInfo.h - PIC16 SelectionDAG Info -------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the PIC16 subclass for TargetSelectionDAGInfo. -// -//===----------------------------------------------------------------------===// - -#ifndef PIC16SELECTIONDAGINFO_H -#define PIC16SELECTIONDAGINFO_H - -#include "llvm/Target/TargetSelectionDAGInfo.h" - -namespace llvm { - -class PIC16TargetMachine; - -class PIC16SelectionDAGInfo : public TargetSelectionDAGInfo { -public: - explicit PIC16SelectionDAGInfo(const PIC16TargetMachine &TM); - ~PIC16SelectionDAGInfo(); -}; - -} - -#endif diff --git a/lib/Target/PIC16/PIC16Subtarget.cpp b/lib/Target/PIC16/PIC16Subtarget.cpp deleted file mode 100644 index 33fc3fb..0000000 --- a/lib/Target/PIC16/PIC16Subtarget.cpp +++ /dev/null @@ -1,27 +0,0 @@ -//===- PIC16Subtarget.cpp - PIC16 Subtarget Information -------------------===// -// -// 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 subclass of TargetSubtarget. -// -//===----------------------------------------------------------------------===// - -#include "PIC16Subtarget.h" -#include "PIC16GenSubtarget.inc" - -using namespace llvm; - -PIC16Subtarget::PIC16Subtarget(const std::string &TT, const std::string &FS, - bool Cooper) - :IsCooper(Cooper) -{ - std::string CPU = "generic"; - - // Parse features string. - ParseSubtargetFeatures(FS, CPU); -} diff --git a/lib/Target/PIC16/PIC16Subtarget.h b/lib/Target/PIC16/PIC16Subtarget.h deleted file mode 100644 index 81e3783..0000000 --- a/lib/Target/PIC16/PIC16Subtarget.h +++ /dev/null @@ -1,44 +0,0 @@ -//=====-- PIC16Subtarget.h - Define Subtarget for the PIC16 ---*- C++ -*--====// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file declares the PIC16 specific subclass of TargetSubtarget. -// -//===----------------------------------------------------------------------===// - -#ifndef PIC16SUBTARGET_H -#define PIC16SUBTARGET_H - -#include "llvm/Target/TargetSubtarget.h" - -#include <string> - -namespace llvm { - -class PIC16Subtarget : public TargetSubtarget { - - // IsCooper - Target ISA is Cooper. - bool IsCooper; - -public: - /// This constructor initializes the data members to match that - /// of the specified triple. - /// - PIC16Subtarget(const std::string &TT, const std::string &FS, bool Cooper); - - /// isCooper - Returns true if the target ISA is Cooper. - bool isCooper() const { return IsCooper; } - - /// ParseSubtargetFeatures - Parses features string setting specified - /// subtarget options. Definition of function is auto generated by tblgen. - std::string ParseSubtargetFeatures(const std::string &FS, - const std::string &CPU); -}; -} // End llvm namespace - -#endif // PIC16SUBTARGET_H diff --git a/lib/Target/PIC16/PIC16TargetMachine.cpp b/lib/Target/PIC16/PIC16TargetMachine.cpp deleted file mode 100644 index 82b69be..0000000 --- a/lib/Target/PIC16/PIC16TargetMachine.cpp +++ /dev/null @@ -1,55 +0,0 @@ -//===-- PIC16TargetMachine.cpp - Define TargetMachine for PIC16 -----------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Top-level implementation for the PIC16 target. -// -//===----------------------------------------------------------------------===// - -#include "PIC16.h" -#include "PIC16MCAsmInfo.h" -#include "PIC16TargetMachine.h" -#include "llvm/PassManager.h" -#include "llvm/CodeGen/Passes.h" -#include "llvm/Target/TargetRegistry.h" - -using namespace llvm; - -extern "C" void LLVMInitializePIC16Target() { - // Register the target. Curretnly the codegen works for - // enhanced pic16 mid-range. - RegisterTargetMachine<PIC16TargetMachine> X(ThePIC16Target); - RegisterAsmInfo<PIC16MCAsmInfo> A(ThePIC16Target); -} - - -// PIC16TargetMachine - Enhanced PIC16 mid-range Machine. May also represent -// a Traditional Machine if 'Trad' is true. -PIC16TargetMachine::PIC16TargetMachine(const Target &T, const std::string &TT, - const std::string &FS, bool Trad) -: LLVMTargetMachine(T, TT), - Subtarget(TT, FS, Trad), - DataLayout("e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8-n8"), - InstrInfo(*this), TLInfo(*this), TSInfo(*this), - FrameInfo(TargetFrameInfo::StackGrowsUp, 8, 0) { } - - -bool PIC16TargetMachine::addInstSelector(PassManagerBase &PM, - CodeGenOpt::Level OptLevel) { - // Install an instruction selector. - PM.add(createPIC16ISelDag(*this)); - return false; -} - -bool PIC16TargetMachine::addPreEmitPass(PassManagerBase &PM, - CodeGenOpt::Level OptLevel) { - PM.add(createPIC16MemSelOptimizerPass()); - return true; // -print-machineinstr should print after this. -} - - diff --git a/lib/Target/PIC16/PIC16TargetMachine.h b/lib/Target/PIC16/PIC16TargetMachine.h deleted file mode 100644 index dae5d31..0000000 --- a/lib/Target/PIC16/PIC16TargetMachine.h +++ /dev/null @@ -1,70 +0,0 @@ -//===-- PIC16TargetMachine.h - Define TargetMachine for PIC16 ---*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file declares the PIC16 specific subclass of TargetMachine. -// -//===----------------------------------------------------------------------===// - - -#ifndef PIC16_TARGETMACHINE_H -#define PIC16_TARGETMACHINE_H - -#include "PIC16InstrInfo.h" -#include "PIC16ISelLowering.h" -#include "PIC16SelectionDAGInfo.h" -#include "PIC16RegisterInfo.h" -#include "PIC16Subtarget.h" -#include "llvm/Target/TargetData.h" -#include "llvm/Target/TargetFrameInfo.h" -#include "llvm/Target/TargetMachine.h" - -namespace llvm { - -/// PIC16TargetMachine -/// -class PIC16TargetMachine : public LLVMTargetMachine { - PIC16Subtarget Subtarget; - const TargetData DataLayout; // Calculates type size & alignment - PIC16InstrInfo InstrInfo; - PIC16TargetLowering TLInfo; - PIC16SelectionDAGInfo TSInfo; - - // PIC16 does not have any call stack frame, therefore not having - // any PIC16 specific FrameInfo class. - TargetFrameInfo FrameInfo; - -public: - PIC16TargetMachine(const Target &T, const std::string &TT, - const std::string &FS, bool Cooper = false); - - virtual const TargetFrameInfo *getFrameInfo() const { return &FrameInfo; } - virtual const PIC16InstrInfo *getInstrInfo() const { return &InstrInfo; } - virtual const TargetData *getTargetData() const { return &DataLayout;} - virtual const PIC16Subtarget *getSubtargetImpl() const { return &Subtarget; } - - virtual const PIC16RegisterInfo *getRegisterInfo() const { - return &(InstrInfo.getRegisterInfo()); - } - - virtual const PIC16TargetLowering *getTargetLowering() const { - return &TLInfo; - } - - virtual const PIC16SelectionDAGInfo* getSelectionDAGInfo() const { - return &TSInfo; - } - - virtual bool addInstSelector(PassManagerBase &PM, - CodeGenOpt::Level OptLevel); - virtual bool addPreEmitPass(PassManagerBase &PM, CodeGenOpt::Level OptLevel); -}; // PIC16TargetMachine. - -} // end namespace llvm - -#endif diff --git a/lib/Target/PIC16/PIC16TargetObjectFile.cpp b/lib/Target/PIC16/PIC16TargetObjectFile.cpp deleted file mode 100644 index ff0f971..0000000 --- a/lib/Target/PIC16/PIC16TargetObjectFile.cpp +++ /dev/null @@ -1,384 +0,0 @@ -//===-- PIC16TargetObjectFile.cpp - PIC16 object files --------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "PIC16TargetObjectFile.h" -#include "PIC16TargetMachine.h" -#include "PIC16Section.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Module.h" -#include "llvm/MC/MCSection.h" -#include "llvm/MC/MCContext.h" -#include "llvm/Support/raw_ostream.h" -using namespace llvm; - - -PIC16TargetObjectFile::PIC16TargetObjectFile() { -} - -PIC16TargetObjectFile::~PIC16TargetObjectFile() { -} - -/// Find a pic16 section. Return null if not found. Do not create one. -PIC16Section *PIC16TargetObjectFile:: -findPIC16Section(const std::string &Name) const { - /// Return if we have an already existing one. - PIC16Section *Entry = SectionsByName[Name]; - if (Entry) - return Entry; - - return NULL; -} - - -/// Find a pic16 section. If not found, create one. -PIC16Section *PIC16TargetObjectFile:: -getPIC16Section(const std::string &Name, PIC16SectionType Ty, - const std::string &Address, int Color) const { - - /// Return if we have an already existing one. - PIC16Section *&Entry = SectionsByName[Name]; - if (Entry) - return Entry; - - - Entry = PIC16Section::Create(Name, Ty, Address, Color, getContext()); - return Entry; -} - -/// Find a standard pic16 data section. If not found, create one and keep -/// track of it by adding it to appropriate std section list. -PIC16Section *PIC16TargetObjectFile:: -getPIC16DataSection(const std::string &Name, PIC16SectionType Ty, - const std::string &Address, int Color) const { - - /// Return if we have an already existing one. - PIC16Section *&Entry = SectionsByName[Name]; - if (Entry) - return Entry; - - - /// Else create a new one and add it to appropriate section list. - Entry = PIC16Section::Create(Name, Ty, Address, Color, getContext()); - - switch (Ty) { - default: llvm_unreachable ("unknow standard section type."); - case UDATA: UDATASections_.push_back(Entry); break; - case IDATA: IDATASections_.push_back(Entry); break; - case ROMDATA: ROMDATASection_ = Entry; break; - case UDATA_SHR: SHAREDUDATASection_ = Entry; break; - } - - return Entry; -} - - -/// Find a standard pic16 autos section. If not found, create one and keep -/// track of it by adding it to appropriate std section list. -PIC16Section *PIC16TargetObjectFile:: -getPIC16AutoSection(const std::string &Name, PIC16SectionType Ty, - const std::string &Address, int Color) const { - - /// Return if we have an already existing one. - PIC16Section *&Entry = SectionsByName[Name]; - if (Entry) - return Entry; - - - /// Else create a new one and add it to appropriate section list. - Entry = PIC16Section::Create(Name, Ty, Address, Color, getContext()); - - assert (Ty == UDATA_OVR && "incorrect section type for autos"); - AUTOSections_.push_back(Entry); - - return Entry; -} - -/// Find a pic16 user section. If not found, create one and keep -/// track of it by adding it to appropriate std section list. -PIC16Section *PIC16TargetObjectFile:: -getPIC16UserSection(const std::string &Name, PIC16SectionType Ty, - const std::string &Address, int Color) const { - - /// Return if we have an already existing one. - PIC16Section *&Entry = SectionsByName[Name]; - if (Entry) - return Entry; - - - /// Else create a new one and add it to appropriate section list. - Entry = PIC16Section::Create(Name, Ty, Address, Color, getContext()); - - USERSections_.push_back(Entry); - - return Entry; -} - -/// Do some standard initialization. -void PIC16TargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &tm){ - TargetLoweringObjectFile::Initialize(Ctx, tm); - TM = &tm; - - ROMDATASection_ = NULL; - SHAREDUDATASection_ = NULL; -} - -/// allocateUDATA - Allocate a un-initialized global to an existing or new UDATA -/// section and return that section. -const MCSection * -PIC16TargetObjectFile::allocateUDATA(const GlobalVariable *GV) const { - assert(GV->hasInitializer() && "This global doesn't need space"); - const Constant *C = GV->getInitializer(); - assert(C->isNullValue() && "Unitialized globals has non-zero initializer"); - - // Find how much space this global needs. - const TargetData *TD = TM->getTargetData(); - const Type *Ty = C->getType(); - unsigned ValSize = TD->getTypeAllocSize(Ty); - - // Go through all UDATA Sections and assign this variable - // to the first available section having enough space. - PIC16Section *Found = NULL; - for (unsigned i = 0; i < UDATASections_.size(); i++) { - if (DataBankSize - UDATASections_[i]->getSize() >= ValSize) { - Found = UDATASections_[i]; - break; - } - } - - // No UDATA section spacious enough was found. Crate a new one. - if (!Found) { - std::string name = PAN::getUdataSectionName(UDATASections_.size()); - Found = getPIC16DataSection(name.c_str(), UDATA); - } - - // Insert the GV into this UDATA section. - Found->Items.push_back(GV); - Found->setSize(Found->getSize() + ValSize); - return Found; -} - -/// allocateIDATA - allocate an initialized global into an existing -/// or new section and return that section. -const MCSection * -PIC16TargetObjectFile::allocateIDATA(const GlobalVariable *GV) const{ - assert(GV->hasInitializer() && "This global doesn't need space"); - const Constant *C = GV->getInitializer(); - assert(!C->isNullValue() && "initialized globals has zero initializer"); - assert(GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE && - "can allocate initialized RAM data only"); - - // Find how much space this global needs. - const TargetData *TD = TM->getTargetData(); - const Type *Ty = C->getType(); - unsigned ValSize = TD->getTypeAllocSize(Ty); - - // Go through all IDATA Sections and assign this variable - // to the first available section having enough space. - PIC16Section *Found = NULL; - for (unsigned i = 0; i < IDATASections_.size(); i++) { - if (DataBankSize - IDATASections_[i]->getSize() >= ValSize) { - Found = IDATASections_[i]; - break; - } - } - - // No IDATA section spacious enough was found. Crate a new one. - if (!Found) { - std::string name = PAN::getIdataSectionName(IDATASections_.size()); - Found = getPIC16DataSection(name.c_str(), IDATA); - } - - // Insert the GV into this IDATA. - Found->Items.push_back(GV); - Found->setSize(Found->getSize() + ValSize); - return Found; -} - -// Allocate a program memory variable into ROMDATA section. -const MCSection * -PIC16TargetObjectFile::allocateROMDATA(const GlobalVariable *GV) const { - - std::string name = PAN::getRomdataSectionName(); - PIC16Section *S = getPIC16DataSection(name.c_str(), ROMDATA); - - S->Items.push_back(GV); - return S; -} - -// Get the section for an automatic variable of a function. -// For PIC16 they are globals only with mangled names. -const MCSection * -PIC16TargetObjectFile::allocateAUTO(const GlobalVariable *GV) const { - - const std::string name = PAN::getSectionNameForSym(GV->getName()); - PIC16Section *S = getPIC16AutoSection(name.c_str()); - - S->Items.push_back(GV); - return S; -} - - -// Override default implementation to put the true globals into -// multiple data sections if required. -const MCSection * -PIC16TargetObjectFile::SelectSectionForGlobal(const GlobalValue *GV1, - SectionKind Kind, - Mangler *Mang, - const TargetMachine &TM) const { - // We select the section based on the initializer here, so it really - // has to be a GlobalVariable. - const GlobalVariable *GV = dyn_cast<GlobalVariable>(GV1); - if (!GV) - return TargetLoweringObjectFile::SelectSectionForGlobal(GV1, Kind, Mang,TM); - - assert(GV->hasInitializer() && "A def without initializer?"); - - // First, if this is an automatic variable for a function, get the section - // name for it and return. - std::string name = GV->getName(); - if (PAN::isLocalName(name)) - return allocateAUTO(GV); - - // See if this is an uninitialized global. - const Constant *C = GV->getInitializer(); - if (C->isNullValue()) - return allocateUDATA(GV); - - // If this is initialized data in RAM. Put it in the correct IDATA section. - if (GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE) - return allocateIDATA(GV); - - // This is initialized data in rom, put it in the readonly section. - if (GV->getType()->getAddressSpace() == PIC16ISD::ROM_SPACE) - return allocateROMDATA(GV); - - // Else let the default implementation take care of it. - return TargetLoweringObjectFile::SelectSectionForGlobal(GV, Kind, Mang,TM); -} - - - - -/// getExplicitSectionGlobal - Allow the target to completely override -/// section assignment of a global. -const MCSection *PIC16TargetObjectFile:: -getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind, - Mangler *Mang, const TargetMachine &TM) const { - assert(GV->hasSection()); - - if (const GlobalVariable *GVar = cast<GlobalVariable>(GV)) { - std::string SectName = GVar->getSection(); - // If address for a variable is specified, get the address and create - // section. - // FIXME: move this attribute checking in PAN. - std::string AddrStr = "Address="; - if (SectName.compare(0, AddrStr.length(), AddrStr) == 0) { - std::string SectAddr = SectName.substr(AddrStr.length()); - if (SectAddr.compare("NEAR") == 0) - return allocateSHARED(GVar, Mang); - else - return allocateAtGivenAddress(GVar, SectAddr); - } - - // Create the section specified with section attribute. - return allocateInGivenSection(GVar); - } - - return getPIC16DataSection(GV->getSection().c_str(), UDATA); -} - -const MCSection * -PIC16TargetObjectFile::allocateSHARED(const GlobalVariable *GV, - Mangler *Mang) const { - // Make sure that this is an uninitialized global. - assert(GV->hasInitializer() && "This global doesn't need space"); - if (!GV->getInitializer()->isNullValue()) { - // FIXME: Generate a warning in this case that near qualifier will be - // ignored. - return SelectSectionForGlobal(GV, SectionKind::getDataRel(), Mang, *TM); - } - std::string Name = PAN::getSharedUDataSectionName(); - - PIC16Section *SharedUDataSect = getPIC16DataSection(Name.c_str(), UDATA_SHR); - // Insert the GV into shared section. - SharedUDataSect->Items.push_back(GV); - return SharedUDataSect; -} - - -// Interface used by AsmPrinter to get a code section for a function. -const PIC16Section * -PIC16TargetObjectFile::SectionForCode(const std::string &FnName, - bool isISR) const { - const std::string &sec_name = PAN::getCodeSectionName(FnName); - // If it is ISR, its code section starts at a specific address. - if (isISR) - return getPIC16Section(sec_name, CODE, PAN::getISRAddr()); - return getPIC16Section(sec_name, CODE); -} - -// Interface used by AsmPrinter to get a frame section for a function. -const PIC16Section * -PIC16TargetObjectFile::SectionForFrame(const std::string &FnName) const { - const std::string &sec_name = PAN::getFrameSectionName(FnName); - return getPIC16Section(sec_name, UDATA_OVR); -} - -// Allocate a global var in existing or new section of given name. -const MCSection * -PIC16TargetObjectFile::allocateInGivenSection(const GlobalVariable *GV) const { - // Determine the type of section that we need to create. - PIC16SectionType SecTy; - - // See if this is an uninitialized global. - const Constant *C = GV->getInitializer(); - if (C->isNullValue()) - SecTy = UDATA; - // If this is initialized data in RAM. Put it in the correct IDATA section. - else if (GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE) - SecTy = IDATA; - // This is initialized data in rom, put it in the readonly section. - else if (GV->getType()->getAddressSpace() == PIC16ISD::ROM_SPACE) - SecTy = ROMDATA; - else - llvm_unreachable ("Could not determine section type for global"); - - PIC16Section *S = getPIC16UserSection(GV->getSection().c_str(), SecTy); - S->Items.push_back(GV); - return S; -} - -// Allocate a global var in a new absolute sections at given address. -const MCSection * -PIC16TargetObjectFile::allocateAtGivenAddress(const GlobalVariable *GV, - const std::string &Addr) const { - // Determine the type of section that we need to create. - PIC16SectionType SecTy; - - // See if this is an uninitialized global. - const Constant *C = GV->getInitializer(); - if (C->isNullValue()) - SecTy = UDATA; - // If this is initialized data in RAM. Put it in the correct IDATA section. - else if (GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE) - SecTy = IDATA; - // This is initialized data in rom, put it in the readonly section. - else if (GV->getType()->getAddressSpace() == PIC16ISD::ROM_SPACE) - SecTy = ROMDATA; - else - llvm_unreachable ("Could not determine section type for global"); - - std::string Prefix = GV->getNameStr() + "." + Addr + "."; - std::string SName = PAN::getUserSectionName(Prefix); - PIC16Section *S = getPIC16UserSection(SName.c_str(), SecTy, Addr.c_str()); - S->Items.push_back(GV); - return S; -} - - diff --git a/lib/Target/PIC16/PIC16TargetObjectFile.h b/lib/Target/PIC16/PIC16TargetObjectFile.h deleted file mode 100644 index b1eb9f9..0000000 --- a/lib/Target/PIC16/PIC16TargetObjectFile.h +++ /dev/null @@ -1,168 +0,0 @@ -//===-- PIC16TargetObjectFile.h - PIC16 Object Info -------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_TARGET_PIC16_TARGETOBJECTFILE_H -#define LLVM_TARGET_PIC16_TARGETOBJECTFILE_H - -#include "PIC16.h" -#include "PIC16ABINames.h" -#include "llvm/Target/TargetLoweringObjectFile.h" -#include "llvm/ADT/StringMap.h" -#include <vector> -#include <string> - -namespace llvm { - class GlobalVariable; - class Module; - class PIC16TargetMachine; - class PIC16Section; - - enum { DataBankSize = 80 }; - - /// PIC16 Splits the global data into mulitple udata and idata sections. - /// Each udata and idata section needs to contain a list of globals that - /// they contain, in order to avoid scanning over all the global values - /// again and printing only those that match the current section. - /// Keeping values inside the sections make printing a section much easier. - /// - /// FIXME: MOVE ALL THIS STUFF TO PIC16Section. - /// - - /// PIC16TargetObjectFile - PIC16 Object file. Contains data and code - /// sections. - // PIC16 Object File has two types of sections. - // 1. Standard Sections - // 1.1 un-initialized global data - // 1.2 initialized global data - // 1.3 program memory data - // 1.4 local variables of functions. - // 2. User defined sections - // 2.1 Objects placed in a specific section. (By _Section() macro) - // 2.2 Objects placed at a specific address. (By _Address() macro) - class PIC16TargetObjectFile : public TargetLoweringObjectFile { - /// SectionsByName - Bindings of names to allocated sections. - mutable StringMap<PIC16Section*> SectionsByName; - - const TargetMachine *TM; - - /// Lists of sections. - /// Standard Data Sections. - mutable std::vector<PIC16Section *> UDATASections_; - mutable std::vector<PIC16Section *> IDATASections_; - mutable PIC16Section * ROMDATASection_; - mutable PIC16Section * SHAREDUDATASection_; - - /// Standard Auto Sections. - mutable std::vector<PIC16Section *> AUTOSections_; - - /// User specified sections. - mutable std::vector<PIC16Section *> USERSections_; - - - /// Find or Create a PIC16 Section, without adding it to any - /// section list. - PIC16Section *getPIC16Section(const std::string &Name, - PIC16SectionType Ty, - const std::string &Address = "", - int Color = -1) const; - - /// Convenience functions. These wrappers also take care of adding - /// the newly created section to the appropriate sections list. - - /// Find or Create PIC16 Standard Data Section. - PIC16Section *getPIC16DataSection(const std::string &Name, - PIC16SectionType Ty, - const std::string &Address = "", - int Color = -1) const; - - /// Find or Create PIC16 Standard Auto Section. - PIC16Section *getPIC16AutoSection(const std::string &Name, - PIC16SectionType Ty = UDATA_OVR, - const std::string &Address = "", - int Color = -1) const; - - /// Find or Create PIC16 Standard Auto Section. - PIC16Section *getPIC16UserSection(const std::string &Name, - PIC16SectionType Ty, - const std::string &Address = "", - int Color = -1) const; - - /// Allocate Un-initialized data to a standard UDATA section. - const MCSection *allocateUDATA(const GlobalVariable *GV) const; - - /// Allocate Initialized data to a standard IDATA section. - const MCSection *allocateIDATA(const GlobalVariable *GV) const; - - /// Allocate ROM data to the standard ROMDATA section. - const MCSection *allocateROMDATA(const GlobalVariable *GV) const; - - /// Allocate an AUTO variable to an AUTO section. - const MCSection *allocateAUTO(const GlobalVariable *GV) const; - - /// Allocate DATA in user specified section. - const MCSection *allocateInGivenSection(const GlobalVariable *GV) const; - - /// Allocate DATA at user specified address. - const MCSection *allocateAtGivenAddress(const GlobalVariable *GV, - const std::string &Addr) const; - - /// Allocate a shared variable to SHARED section. - const MCSection *allocateSHARED(const GlobalVariable *GV, - Mangler *Mang) const; - - public: - PIC16TargetObjectFile(); - ~PIC16TargetObjectFile(); - void Initialize(MCContext &Ctx, const TargetMachine &TM); - - /// Return the section with the given Name. Null if not found. - PIC16Section *findPIC16Section(const std::string &Name) const; - - /// Override section allocations for user specified sections. - virtual const MCSection * - getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind, - Mangler *Mang, const TargetMachine &TM) const; - - /// Select sections for Data and Auto variables(globals). - virtual const MCSection *SelectSectionForGlobal(const GlobalValue *GV, - SectionKind Kind, - Mangler *Mang, - const TargetMachine&) const; - - - /// Return a code section for a function. - const PIC16Section *SectionForCode (const std::string &FnName, - bool isISR) const; - - /// Return a frame section for a function. - const PIC16Section *SectionForFrame (const std::string &FnName) const; - - /// Accessors for various section lists. - const std::vector<PIC16Section *> &UDATASections() const { - return UDATASections_; - } - const std::vector<PIC16Section *> &IDATASections() const { - return IDATASections_; - } - const PIC16Section *ROMDATASection() const { - return ROMDATASection_; - } - const PIC16Section *SHAREDUDATASection() const { - return SHAREDUDATASection_; - } - const std::vector<PIC16Section *> &AUTOSections() const { - return AUTOSections_; - } - const std::vector<PIC16Section *> &USERSections() const { - return USERSections_; - } - }; -} // end namespace llvm - -#endif diff --git a/lib/Target/PIC16/TargetInfo/CMakeLists.txt b/lib/Target/PIC16/TargetInfo/CMakeLists.txt deleted file mode 100644 index bfc6ff4..0000000 --- a/lib/Target/PIC16/TargetInfo/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -include_directories( ${CMAKE_CURRENT_BINARY_DIR}/.. ${CMAKE_CURRENT_SOURCE_DIR}/.. ) - -add_llvm_library(LLVMPIC16Info - PIC16TargetInfo.cpp - ) - -add_dependencies(LLVMPIC16Info PIC16Table_gen) diff --git a/lib/Target/PIC16/TargetInfo/Makefile b/lib/Target/PIC16/TargetInfo/Makefile deleted file mode 100644 index 76609f6..0000000 --- a/lib/Target/PIC16/TargetInfo/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -##===- lib/Target/PIC16/TargetInfo/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 = LLVMPIC16Info - -# Hack: we need to include 'main' target directory to grab private headers -CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/.. - -include $(LEVEL)/Makefile.common diff --git a/lib/Target/PIC16/TargetInfo/PIC16TargetInfo.cpp b/lib/Target/PIC16/TargetInfo/PIC16TargetInfo.cpp deleted file mode 100644 index f1bdb12..0000000 --- a/lib/Target/PIC16/TargetInfo/PIC16TargetInfo.cpp +++ /dev/null @@ -1,22 +0,0 @@ -//===-- PIC16TargetInfo.cpp - PIC16 Target Implementation -----------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "PIC16.h" -#include "llvm/Module.h" -#include "llvm/Target/TargetRegistry.h" -using namespace llvm; - -Target llvm::ThePIC16Target, llvm::TheCooperTarget; - -extern "C" void LLVMInitializePIC16TargetInfo() { - RegisterTarget<Triple::pic16> X(ThePIC16Target, "pic16", - "PIC16 14-bit [experimental]"); - - RegisterTarget<> Y(TheCooperTarget, "cooper", "PIC16 Cooper [experimental]"); -} |