diff options
Diffstat (limited to 'lib/Target/PIC16/PIC16AsmPrinter.cpp')
-rw-r--r-- | lib/Target/PIC16/PIC16AsmPrinter.cpp | 696 |
1 files changed, 285 insertions, 411 deletions
diff --git a/lib/Target/PIC16/PIC16AsmPrinter.cpp b/lib/Target/PIC16/PIC16AsmPrinter.cpp index d765d75..21f1902 100644 --- a/lib/Target/PIC16/PIC16AsmPrinter.cpp +++ b/lib/Target/PIC16/PIC16AsmPrinter.cpp @@ -12,194 +12,70 @@ // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "asm-printer" -#include "PIC16.h" -#include "PIC16TargetMachine.h" -#include "PIC16ConstantPoolValue.h" -#include "PIC16InstrInfo.h" -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" +#include "PIC16AsmPrinter.h" +#include "PIC16TargetAsmInfo.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/Mangler.h" +#include "llvm/Function.h" #include "llvm/Module.h" -#include "llvm/ADT/Statistic.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/CodeGen/AsmPrinter.h" -#include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/CodeGen/MachineConstantPool.h" #include "llvm/CodeGen/MachineFrameInfo.h" -#include "llvm/CodeGen/MachineInstr.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/Mangler.h" -#include "llvm/Support/MathExtras.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Target/TargetAsmInfo.h" -#include "llvm/Target/TargetData.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetOptions.h" -#include <cctype> +#include "llvm/DerivedTypes.h" using namespace llvm; -STATISTIC(EmittedInsts, "Number of machine instrs printed"); - -namespace { - struct VISIBILITY_HIDDEN PIC16AsmPrinter : public AsmPrinter { - PIC16AsmPrinter(raw_ostream &O, TargetMachine &TM, const TargetAsmInfo *T) - : AsmPrinter(O, TM, T) { - } - - - /// We name each basic block in a Function with a unique number, so - /// that we can consistently refer to them later. This is cleared - /// at the beginning of each call to runOnMachineFunction(). - /// - typedef std::map<const Value *, unsigned> ValueMapTy; - ValueMapTy NumberForBB; - - /// Keeps the set of GlobalValues that require non-lazy-pointers for - /// indirect access. - std::set<std::string> GVNonLazyPtrs; - - /// Keeps the set of external function GlobalAddresses that the asm - /// printer should generate stubs for. - std::set<std::string> FnStubs; - - /// True if asm printer is printing a series of CONSTPOOL_ENTRY. - bool InCPMode; - - virtual const char *getPassName() const { - return "PIC16 Assembly Printer"; - } - - void printOperand(const MachineInstr *MI, int opNum, - const char *Modifier = 0); - - void printSOImmOperand(const MachineInstr *MI, int opNum); - - void printAddrModeOperand(const MachineInstr *MI, int OpNo); - - void printRegisterList(const MachineInstr *MI, int opNum); - void printCPInstOperand(const MachineInstr *MI, int opNum, - const char *Modifier); - - - bool printInstruction(const MachineInstr *MI); // autogenerated. - void emitFunctionStart(MachineFunction &F); - bool runOnMachineFunction(MachineFunction &F); - bool doInitialization(Module &M); - bool doFinalization(Module &M); - - virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV); - - void getAnalysisUsage(AnalysisUsage &AU) const; - - public: - void SwitchToTextSection(const char *NewSection, - const GlobalValue *GV = NULL); - void SwitchToDataSection(const char *NewSection, - const GlobalValue *GV = NULL); - void SwitchToDataOvrSection(const char *NewSection, - const GlobalValue *GV = NULL); - }; -} // end of anonymous namespace - #include "PIC16GenAsmWriter.inc" -/// createPIC16CodePrinterPass - Returns a pass that prints the PIC16 -/// assembly code for a MachineFunction to the given output stream, -/// using the given target machine description. This should work -/// regardless of whether the function is in SSA form. -/// -FunctionPass *llvm::createPIC16CodePrinterPass(raw_ostream &o, - PIC16TargetMachine &tm) { - return new PIC16AsmPrinter(o, tm, tm.getTargetAsmInfo()); -} - -void PIC16AsmPrinter::getAnalysisUsage(AnalysisUsage &AU) const -{ - // FIXME: Currently unimplemented. -} - - -void PIC16AsmPrinter :: -EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) -{ - printDataDirective(MCPV->getType()); - - PIC16ConstantPoolValue *ACPV = (PIC16ConstantPoolValue*)MCPV; - GlobalValue *GV = ACPV->getGV(); - std::string Name = GV ? Mang->getValueName(GV) : TAI->getGlobalPrefix(); - if (!GV) - Name += ACPV->getSymbol(); - if (ACPV->isNonLazyPointer()) { - GVNonLazyPtrs.insert(Name); - O << TAI->getPrivateGlobalPrefix() << Name << "$non_lazy_ptr"; - } else if (ACPV->isStub()) { - FnStubs.insert(Name); - O << TAI->getPrivateGlobalPrefix() << Name << "$stub"; - } else { - O << Name; - } - - if (ACPV->hasModifier()) O << "(" << ACPV->getModifier() << ")"; - - if (ACPV->getPCAdjustment() != 0) { - O << "-(" << TAI->getPrivateGlobalPrefix() << "PC" - << utostr(ACPV->getLabelId()) - << "+" << (unsigned)ACPV->getPCAdjustment(); - - if (ACPV->mustAddCurrentAddress()) - O << "-."; - - O << ")"; - } - O << "\n"; - - // If the constant pool value is a extern weak symbol, remember to emit - // the weak reference. - if (GV && GV->hasExternalWeakLinkage()) - ExtWeakSymbols.insert(GV); -} - -/// emitFunctionStart - Emit the directives used by ASM on the start of -/// functions. -void PIC16AsmPrinter::emitFunctionStart(MachineFunction &MF) -{ - // Print out the label for the function. - const Function *F = MF.getFunction(); - MachineFrameInfo *FrameInfo = MF.getFrameInfo(); - if (FrameInfo->hasStackObjects()) { - int indexBegin = FrameInfo->getObjectIndexBegin(); - int indexEnd = FrameInfo->getObjectIndexEnd(); - while (indexBegin < indexEnd) { - if (indexBegin == 0) - SwitchToDataOvrSection(F->getParent()->getModuleIdentifier().c_str(), - F); - - O << "\t\t" << CurrentFnName << "_" << indexBegin << " " << "RES" - << " " << FrameInfo->getObjectSize(indexBegin) << "\n" ; - indexBegin++; +bool PIC16AsmPrinter::printMachineInstruction(const MachineInstr *MI) { + std::string NewBankselLabel; + unsigned Operands = MI->getNumOperands(); + if (Operands > 1) { + // Global address or external symbol should be second operand from last + // if we want to print banksel for it. + const MachineOperand &Op = MI->getOperand(Operands-2); + unsigned OpType = Op.getType(); + if (OpType == MachineOperand::MO_GlobalAddress || + OpType == MachineOperand::MO_ExternalSymbol) { + if (OpType == MachineOperand::MO_GlobalAddress ) + NewBankselLabel = Mang->getValueName(Op.getGlobal()); + else + NewBankselLabel = Op.getSymbolName(); + + // Operand after global address or external symbol should be banksel. + // Value 1 for this operand means we need to generate banksel else do not + // generate banksel. + const MachineOperand &BS = MI->getOperand(Operands-1); + if (((int)BS.getImm() == 1) && + (strcmp (CurrentBankselLabelInBasicBlock.c_str(), + NewBankselLabel.c_str()))) { + CurrentBankselLabelInBasicBlock = NewBankselLabel; + O << "\tbanksel "; + printOperand(MI, Operands-2); + O << "\n"; + } } } - SwitchToTextSection(CurrentFnName.c_str(), F); - O << "_" << CurrentFnName << ":" ; - O << "\n"; + printInstruction(MI); + return true; } - /// runOnMachineFunction - This uses the printInstruction() /// method to print assembly for each instruction. /// -bool PIC16AsmPrinter::runOnMachineFunction(MachineFunction &MF) -{ +bool PIC16AsmPrinter::runOnMachineFunction(MachineFunction &MF) { + // This calls the base class function required to be called at beginning + // of runOnMachineFunction. SetupMachineFunction(MF); - O << "\n"; - // What's my mangled name? - CurrentFnName = Mang->getValueName(MF.getFunction()); + // Get the mangled name. + const Function *F = MF.getFunction(); + CurrentFnName = Mang->getValueName(F); - // Emit the function start directives - emitFunctionStart(MF); + // Emit the function variables. + emitFunctionData(MF); + std::string codeSection; + codeSection = "code." + CurrentFnName + ".#"; + O << "\n"; + SwitchToTextSection (codeSection.c_str(),F); // Print out code for the function. for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); @@ -209,319 +85,317 @@ bool PIC16AsmPrinter::runOnMachineFunction(MachineFunction &MF) printBasicBlockLabel(I, true); O << '\n'; } + else + O << "_" << CurrentFnName << ":\n"; + CurrentBankselLabelInBasicBlock = ""; for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); II != E; ++II) { // Print the assembly for the instruction. - O << '\t'; - printInstruction(II); - ++EmittedInsts; + printMachineInstruction(II); } } + return false; // we didn't modify anything. +} - // We didn't modify anything. - return false; +/// createPIC16CodePrinterPass - Returns a pass that prints the PIC16 +/// assembly code for a MachineFunction to the given output stream, +/// using the given target machine description. This should work +/// regardless of whether the function is in SSA form. +/// +FunctionPass *llvm::createPIC16CodePrinterPass(raw_ostream &o, + PIC16TargetMachine &tm) { + return new PIC16AsmPrinter(o, tm, tm.getTargetAsmInfo()); } -void PIC16AsmPrinter:: -printOperand(const MachineInstr *MI, int opNum, const char *Modifier) -{ +void PIC16AsmPrinter::printOperand(const MachineInstr *MI, int opNum) { const MachineOperand &MO = MI->getOperand(opNum); - const TargetRegisterInfo &RI = *TM.getRegisterInfo(); switch (MO.getType()) { case MachineOperand::MO_Register: if (TargetRegisterInfo::isPhysicalRegister(MO.getReg())) - O << RI.get(MO.getReg()).Name; + O << TM.getRegisterInfo()->get(MO.getReg()).AsmName; else assert(0 && "not implemented"); - break; + return; - case MachineOperand::MO_Immediate: - if (!Modifier || strcmp(Modifier, "no_hash") != 0) - O << "#"; + case MachineOperand::MO_Immediate: O << (int)MO.getImm(); - break; - - case MachineOperand::MO_MachineBasicBlock: - printBasicBlockLabel(MO.getMBB()); return; - case MachineOperand::MO_GlobalAddress: - O << Mang->getValueName(MO.getGlobal())<<'+'<<MO.getOffset(); + case MachineOperand::MO_GlobalAddress: + O << Mang->getValueName(MO.getGlobal()); break; - case MachineOperand::MO_ExternalSymbol: + case MachineOperand::MO_ExternalSymbol: O << MO.getSymbolName(); break; - case MachineOperand::MO_ConstantPoolIndex: - O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() - << '_' << MO.getIndex(); - break; - - case MachineOperand::MO_FrameIndex: - O << "_" << CurrentFnName - << '+' << MO.getIndex(); - break; - - case MachineOperand::MO_JumpTableIndex: - O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() - << '_' << MO.getIndex(); - break; - default: - O << "<unknown operand type>"; abort (); - break; - } // end switch. + assert(0 && " Operand type not supported."); + } } -static void -printSOImm(raw_ostream &O, int64_t V, const TargetAsmInfo *TAI) -{ - assert(V < (1 << 12) && "Not a valid so_imm value!"); - - O << (unsigned) V; +bool PIC16AsmPrinter::doInitialization (Module &M) { + bool Result = AsmPrinter::doInitialization(M); + // FIXME:: This is temporary solution to generate the include file. + // The processor should be passed to llc as in input and the header file + // should be generated accordingly. + O << "\t#include P16F1937.INC\n"; + + EmitInitData (M); + EmitUnInitData(M); + EmitRomData(M); + return Result; } -/// printSOImmOperand - SOImm is 4-bit rotated amount in bits 8-11 with 8-bit -/// immediate in bits 0-7. -void PIC16AsmPrinter::printSOImmOperand(const MachineInstr *MI, int OpNum) +void PIC16AsmPrinter::EmitInitData (Module &M) { - const MachineOperand &MO = MI->getOperand(OpNum); - assert(MO.isImm() && "Not a valid so_imm value!"); - printSOImm(O, MO.getImm(), TAI); -} + std::string iDataSection = "idata.#"; + SwitchToDataSection(iDataSection.c_str()); + for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); + I != E; ++I) { + if (!I->hasInitializer()) // External global require no code. + continue; + Constant *C = I->getInitializer(); + const PointerType *PtrTy = I->getType(); + int AddrSpace = PtrTy->getAddressSpace(); -void PIC16AsmPrinter::printAddrModeOperand(const MachineInstr *MI, int Op) -{ - const MachineOperand &MO1 = MI->getOperand(Op); - const MachineOperand &MO2 = MI->getOperand(Op+1); + if ((!C->isNullValue()) && (AddrSpace == PIC16ISD::RAM_SPACE)) { + + if (EmitSpecialLLVMGlobal(I)) + continue; - if (MO2.isFI()) { - printOperand(MI, Op+1); - return; - } + // Any variables reaching here with "." in its name is a local scope + // variable and should not be printed in global data section. + std::string name = Mang->getValueName(I); + if (name.find(".") != std::string::npos) + continue; - if (!MO1.isReg()) { - // FIXME: This is for CP entries, but isn't right. - printOperand(MI, Op); - return; + O << name; + EmitGlobalConstant(C); + } } +} - // If this is Stack Slot - if (MO1.isReg()) { - if (strcmp(TM.getRegisterInfo()->get(MO1.getReg()).Name, "SP") == 0) { - O << CurrentFnName <<"_"<< MO2.getImm(); - return; +void PIC16AsmPrinter::EmitConstantValueOnly(const Constant* CV) { + if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) { + unsigned BitWidth = CI->getBitWidth(); + int Val = CI->getZExtValue(); + if (BitWidth == 8) { + // Expecting db directive here. In case of romdata we need to pad the + // word with zeros. + if (IsRomData) + O << 0 <<", "; + O << Val; + } + else if (BitWidth == 16) { + unsigned Element1, Element2; + Element1 = 0x00ff & Val; + Element2 = 0x00ff & (Val >> 8); + if (IsRomData) + O << 0 <<", "<<Element1 <<", "<< 0 <<", "<< Element2; + else + O << Element1 <<", "<< Element2; + } + else if (BitWidth == 32) { + unsigned Element1, Element2, Element3, Element4; + Element1 = 0x00ff & Val; + Element2 = 0x00ff & (Val >> 8); + Element3 = 0x00ff & (Val >> 16); + Element4 = 0x00ff & (Val >> 24); + if (IsRomData) + O << 0 <<", "<< Element1 <<", "<< 0 <<", "<< Element2 <<", "<< 0 + <<", "<< Element3 <<", "<< 0 <<", "<< Element4; + else + O << Element1 <<", "<< Element2 <<", "<< Element3 <<", "<< Element4; } - O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).Name; - O << "+"; - O << MO2.getImm(); - O << "]"; return; } - - O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).Name; - O << "]"; + AsmPrinter::EmitConstantValueOnly(CV); } - -void PIC16AsmPrinter::printRegisterList(const MachineInstr *MI, int opNum) +void PIC16AsmPrinter::EmitRomData (Module &M) { - O << "{"; - for (unsigned i = opNum, e = MI->getNumOperands(); i != e; ++i) { - printOperand(MI, i); - if (i != e-1) O << ", "; - } - O << "}"; -} + std::string romDataSection = "romdata.#"; + SwitchToRomDataSection(romDataSection.c_str()); + IsRomData = true; + for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); + I != E; ++I) { + if (!I->hasInitializer()) // External global require no code. + continue; -void PIC16AsmPrinter:: -printCPInstOperand(const MachineInstr *MI, int OpNo, const char *Modifier) -{ - assert(Modifier && "This operand only works with a modifier!"); - - // There are two aspects to a CONSTANTPOOL_ENTRY operand, the label and the - // data itself. - if (!strcmp(Modifier, "label")) { - unsigned ID = MI->getOperand(OpNo).getImm(); - O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() - << '_' << ID << ":\n"; - } else { - assert(!strcmp(Modifier, "cpentry") && "Unknown modifier for CPE"); - unsigned CPI = MI->getOperand(OpNo).getIndex(); - - const MachineConstantPoolEntry &MCPE = // Chasing pointers is fun? - MI->getParent()->getParent()->getConstantPool()->getConstants()[CPI]; - - if (MCPE.isMachineConstantPoolEntry()) - EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal); - else { - EmitGlobalConstant(MCPE.Val.ConstVal); - // remember to emit the weak reference - if (const GlobalValue *GV = dyn_cast<GlobalValue>(MCPE.Val.ConstVal)) - if (GV->hasExternalWeakLinkage()) - ExtWeakSymbols.insert(GV); + Constant *C = I->getInitializer(); + const PointerType *PtrTy = I->getType(); + int AddrSpace = PtrTy->getAddressSpace(); + if ((!C->isNullValue()) && (AddrSpace == PIC16ISD::ROM_SPACE)) { + + if (EmitSpecialLLVMGlobal(I)) + continue; + + // Any variables reaching here with "." in its name is a local scope + // variable and should not be printed in global data section. + std::string name = Mang->getValueName(I); + if (name.find(".") != std::string::npos) + continue; + + O << name; + EmitGlobalConstant(C); + O << "\n"; } } + IsRomData = false; } -bool PIC16AsmPrinter::doInitialization(Module &M) -{ - bool Result = AsmPrinter::doInitialization(M); - return Result; -} - -bool PIC16AsmPrinter::doFinalization(Module &M) +void PIC16AsmPrinter::EmitUnInitData (Module &M) { + std::string uDataSection = "udata.#"; + SwitchToUDataSection(uDataSection.c_str()); const TargetData *TD = TM.getTargetData(); for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) { - if (!I->hasInitializer()) // External global require no code + if (!I->hasInitializer()) // External global require no code. continue; - if (EmitSpecialLLVMGlobal(I)) { - continue; + Constant *C = I->getInitializer(); + if (C->isNullValue()) { + + if (EmitSpecialLLVMGlobal(I)) + continue; + + // Any variables reaching here with "." in its name is a local scope + // variable and should not be printed in global data section. + std::string name = Mang->getValueName(I); + if (name.find(".") != std::string::npos) + continue; + + const Type *Ty = C->getType(); + unsigned Size = TD->getABITypeSize(Ty); + O << name << " " <<"RES"<< " " << Size ; + O << "\n"; } + } +} - std::string name = Mang->getValueName(I); +bool PIC16AsmPrinter::doFinalization(Module &M) { + O << "\t" << "END\n"; + bool Result = AsmPrinter::doFinalization(M); + return Result; +} + +void PIC16AsmPrinter::emitFunctionData(MachineFunction &MF) { + const Function *F = MF.getFunction(); + std::string FuncName = Mang->getValueName(F); + const Module *M = F->getParent(); + const TargetData *TD = TM.getTargetData(); + + // Emit the data section name. + O << "\n"; + std::string fDataSection = "fdata." + CurrentFnName + ".#"; + SwitchToUDataSection(fDataSection.c_str(), F); + // Emit the label for data section of current function. + O << "_frame_" << CurrentFnName << ":" ; + O << "\n"; + + // Emit the function variables. + + if (F->hasExternalLinkage()) { + O << "\t" << "GLOBAL _frame_" << CurrentFnName << "\n"; + O << "\t" << "GLOBAL _" << CurrentFnName << "\n"; + } + // In PIC16 all the function arguments and local variables are global. + // Therefore to get the variable belonging to this function entire + // global list will be traversed and variables belonging to this function + // will be emitted in the current data section. + for (Module::const_global_iterator I = M->global_begin(), E = M->global_end(); + I != E; ++I) { + std::string VarName = Mang->getValueName(I); + + // The variables of a function are of form FuncName.* . If this variable + // does not belong to this function then continue. + if (!(VarName.find(FuncName + ".") == 0 ? true : false)) + continue; + Constant *C = I->getInitializer(); const Type *Ty = C->getType(); unsigned Size = TD->getABITypeSize(Ty); - unsigned Align = TD->getPreferredAlignmentLog(I); + // Emit memory reserve directive. + O << VarName << " RES " << Size << "\n"; + } + emitFunctionTempData(MF); +} - const char *VisibilityDirective = NULL; - if (I->hasHiddenVisibility()) - VisibilityDirective = TAI->getHiddenDirective(); - else if (I->hasProtectedVisibility()) - VisibilityDirective = TAI->getProtectedDirective(); +void PIC16AsmPrinter::emitFunctionTempData(MachineFunction &MF) { + // Emit temporary variables. + MachineFrameInfo *FrameInfo = MF.getFrameInfo(); + if (FrameInfo->hasStackObjects()) { + int indexBegin = FrameInfo->getObjectIndexBegin(); + int indexEnd = FrameInfo->getObjectIndexEnd(); - if (VisibilityDirective) - O << VisibilityDirective << name << "\n"; + if (indexBegin < indexEnd) + O << CurrentFnName << ".tmp RES"<< " " + <<indexEnd - indexBegin <<"\n"; + /* + while (indexBegin < indexEnd) { + O << CurrentFnName << "_tmp_" << indexBegin << " " << "RES"<< " " + << 1 << "\n" ; + indexBegin++; + } + */ + } +} - if (C->isNullValue()) { - if (I->hasExternalLinkage()) { - if (const char *Directive = TAI->getZeroFillDirective()) { - O << "\t.globl\t" << name << "\n"; - O << Directive << "__DATA__, __common, " << name << ", " - << Size << ", " << Align << "\n"; - continue; - } - } +/// The function is same as AsmPrinter::SwitchtoDataSection except the call +/// to getUDataSectionStartSuffix. +void PIC16AsmPrinter::SwitchToUDataSection(const char *NewSection, + const GlobalValue *GV) { + std::string NS; + if (GV && GV->hasSection()) + NS = TAI->getSwitchToSectionDirective() + GV->getSection(); + else + NS = NewSection; - if (!I->hasSection() && - (I->hasInternalLinkage() || I->hasWeakLinkage() || - I->hasLinkOnceLinkage() || I->hasCommonLinkage())) { - if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. - SwitchToDataSection(M.getModuleIdentifier().c_str(), I); - if (TAI->getLCOMMDirective() != NULL) { - if (I->hasInternalLinkage()) { - O << TAI->getLCOMMDirective() << name << "," << Size; - } else - O << TAI->getCOMMDirective() << name << "," << Size; - } else { - if (I->hasInternalLinkage()) - O << "\t.local\t" << name << "\n"; - - O << TAI->getCOMMDirective() <<"\t" << name << " " <<"RES"<< " " - << Size; - O << "\n\t\tGLOBAL" <<" "<< name; - if (TAI->getCOMMDirectiveTakesAlignment()) - O << "," << (TAI->getAlignmentIsInBytes() ? (1 << Align) : Align); - } - continue; - } - } + // If we're already in this section, we're done. + if (CurrentSection == NS) return; - switch (I->getLinkage()) { - case GlobalValue::AppendingLinkage: - // FIXME: appending linkage variables should go into a section of - // their name or something. For now, just emit them as external. - // FALL THROUGH + // Close the current section, if applicable. + if (TAI->getSectionEndDirectiveSuffix() && !CurrentSection.empty()) + O << CurrentSection << TAI->getSectionEndDirectiveSuffix() << '\n'; - case GlobalValue::ExternalLinkage: - O << "\t.globl " << name << "\n"; - // FALL THROUGH + CurrentSection = NS; - case GlobalValue::InternalLinkage: - break; + if (!CurrentSection.empty()){} + O << CurrentSection << (static_cast<const PIC16TargetAsmInfo *>(TAI))-> + getUDataSectionStartSuffix() << '\n'; - default: - assert(0 && "Unknown linkage type!"); - break; - } // end switch. + IsInTextSection = false; +} - EmitAlignment(Align, I); - O << name << ":\t\t\t\t" << TAI->getCommentString() << " " << I->getName() - << "\n"; +/// The function is same as AsmPrinter::SwitchtoDataSection except the call +/// to getRomDataSectionStartSuffix. +void PIC16AsmPrinter::SwitchToRomDataSection(const char *NewSection, + const GlobalValue *GV) { + std::string NS; + if (GV && GV->hasSection()) + NS = TAI->getSwitchToSectionDirective() + GV->getSection(); + else + NS = NewSection; - // If the initializer is a extern weak symbol, remember to emit the weak - // reference! - if (const GlobalValue *GV = dyn_cast<GlobalValue>(C)) - if (GV->hasExternalWeakLinkage()) - ExtWeakSymbols.insert(GV); + // If we're already in this section, we're done. + if (CurrentSection == NS) return; - EmitGlobalConstant(C); - O << '\n'; - } // end for. + // Close the current section, if applicable. + if (TAI->getSectionEndDirectiveSuffix() && !CurrentSection.empty()) + O << CurrentSection << TAI->getSectionEndDirectiveSuffix() << '\n'; - O << "\n "<< "END"; - return AsmPrinter::doFinalization(M); -} + CurrentSection = NS; -void PIC16AsmPrinter:: -SwitchToTextSection(const char *NewSection, const GlobalValue *GV) -{ - O << "\n"; - if (NewSection && *NewSection) { - std::string codeSection = "code_"; - codeSection += NewSection; - codeSection += " "; - codeSection += "CODE"; - AsmPrinter::SwitchToTextSection(codeSection.c_str(), GV); - } - else - AsmPrinter::SwitchToTextSection(NewSection, GV); -} + if (!CurrentSection.empty()) {} + O << CurrentSection << (static_cast< const PIC16TargetAsmInfo *>(TAI))-> + getRomDataSectionStartSuffix() << '\n'; -void PIC16AsmPrinter:: -SwitchToDataSection(const char *NewSection, const GlobalValue *GV) -{ - // Need to append index for page. - O << "\n"; - if (NewSection && *NewSection) { - std::string dataSection = "udata_"; - dataSection += NewSection; - if (dataSection.substr(dataSection.length() - 2).compare(".o") == 0) { - dataSection = dataSection.substr(0, dataSection.length() - 2); - } - dataSection += " "; - dataSection += "UDATA"; - AsmPrinter::SwitchToDataSection(dataSection.c_str(), GV); - } - else - AsmPrinter::SwitchToDataSection(NewSection, GV); + IsInTextSection = false; } -void PIC16AsmPrinter:: -SwitchToDataOvrSection(const char *NewSection, const GlobalValue *GV) -{ - O << "\n"; - if (NewSection && *NewSection) { - std::string dataSection = "frame_"; - dataSection += NewSection; - if (dataSection.substr(dataSection.length() - 2).compare(".o") == 0) { - dataSection = dataSection.substr(0, dataSection.length() - 2); - } - dataSection += "_"; - dataSection += CurrentFnName; - dataSection += " "; - dataSection += "UDATA_OVR"; - AsmPrinter::SwitchToDataSection(dataSection.c_str(), GV); - } - else - AsmPrinter::SwitchToDataSection(NewSection, GV); -} |