blob: 5102e7a241f039da1298b8269812dd72df562a74 [file] [log] [blame]
Sanjiv Gupta0e687712008-05-13 09:02:57 +00001//===-- PIC16AsmPrinter.cpp - PIC16 LLVM assembly writer ------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file contains a printer that converts from our internal representation
11// of machine-dependent LLVM code to PIC16 assembly language.
12//
13//===----------------------------------------------------------------------===//
14
15#define DEBUG_TYPE "asm-printer"
16#include "PIC16.h"
17#include "PIC16TargetMachine.h"
18#include "PIC16ConstantPoolValue.h"
19#include "PIC16InstrInfo.h"
20#include "llvm/Constants.h"
21#include "llvm/DerivedTypes.h"
22#include "llvm/Module.h"
Sanjiv Gupta0e687712008-05-13 09:02:57 +000023#include "llvm/ADT/Statistic.h"
24#include "llvm/ADT/StringExtras.h"
25#include "llvm/CodeGen/AsmPrinter.h"
26#include "llvm/CodeGen/MachineFunctionPass.h"
27#include "llvm/CodeGen/MachineConstantPool.h"
28#include "llvm/CodeGen/MachineFrameInfo.h"
29#include "llvm/CodeGen/MachineInstr.h"
30#include "llvm/Support/CommandLine.h"
31#include "llvm/Support/Debug.h"
32#include "llvm/Support/Mangler.h"
33#include "llvm/Support/MathExtras.h"
Owen Andersoncb371882008-08-21 00:14:44 +000034#include "llvm/Support/raw_ostream.h"
Sanjiv Gupta0e687712008-05-13 09:02:57 +000035#include "llvm/Target/TargetAsmInfo.h"
36#include "llvm/Target/TargetData.h"
37#include "llvm/Target/TargetMachine.h"
38#include "llvm/Target/TargetOptions.h"
39#include <cctype>
40
41using namespace llvm;
42
43STATISTIC(EmittedInsts, "Number of machine instrs printed");
44
45namespace {
46 struct VISIBILITY_HIDDEN PIC16AsmPrinter : public AsmPrinter {
Owen Andersoncb371882008-08-21 00:14:44 +000047 PIC16AsmPrinter(raw_ostream &O, TargetMachine &TM, const TargetAsmInfo *T)
Sanjiv Gupta0e687712008-05-13 09:02:57 +000048 : AsmPrinter(O, TM, T) {
49 }
50
51
52 /// We name each basic block in a Function with a unique number, so
53 /// that we can consistently refer to them later. This is cleared
54 /// at the beginning of each call to runOnMachineFunction().
55 ///
56 typedef std::map<const Value *, unsigned> ValueMapTy;
57 ValueMapTy NumberForBB;
58
59 /// Keeps the set of GlobalValues that require non-lazy-pointers for
60 /// indirect access.
61 std::set<std::string> GVNonLazyPtrs;
62
63 /// Keeps the set of external function GlobalAddresses that the asm
64 /// printer should generate stubs for.
65 std::set<std::string> FnStubs;
66
67 /// True if asm printer is printing a series of CONSTPOOL_ENTRY.
68 bool InCPMode;
69
70 virtual const char *getPassName() const {
71 return "PIC16 Assembly Printer";
72 }
73
74 void printOperand(const MachineInstr *MI, int opNum,
75 const char *Modifier = 0);
76
77 void printSOImmOperand(const MachineInstr *MI, int opNum);
78
79 void printAddrModeOperand(const MachineInstr *MI, int OpNo);
80
81 void printRegisterList(const MachineInstr *MI, int opNum);
82 void printCPInstOperand(const MachineInstr *MI, int opNum,
83 const char *Modifier);
84
85
86 bool printInstruction(const MachineInstr *MI); // autogenerated.
87 void emitFunctionStart(MachineFunction &F);
88 bool runOnMachineFunction(MachineFunction &F);
89 bool doInitialization(Module &M);
90 bool doFinalization(Module &M);
91
92 virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV);
93
94 void getAnalysisUsage(AnalysisUsage &AU) const;
95
96 public:
97 void SwitchToTextSection(const char *NewSection,
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +000098 const GlobalValue *GV = NULL);
Sanjiv Gupta0e687712008-05-13 09:02:57 +000099 void SwitchToDataSection(const char *NewSection,
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000100 const GlobalValue *GV = NULL);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000101 void SwitchToDataOvrSection(const char *NewSection,
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000102 const GlobalValue *GV = NULL);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000103 };
104} // end of anonymous namespace
105
106#include "PIC16GenAsmWriter.inc"
107
108/// createPIC16CodePrinterPass - Returns a pass that prints the PIC16
109/// assembly code for a MachineFunction to the given output stream,
110/// using the given target machine description. This should work
111/// regardless of whether the function is in SSA form.
112///
Owen Andersoncb371882008-08-21 00:14:44 +0000113FunctionPass *llvm::createPIC16CodePrinterPass(raw_ostream &o,
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000114 PIC16TargetMachine &tm) {
115 return new PIC16AsmPrinter(o, tm, tm.getTargetAsmInfo());
116}
117
118void PIC16AsmPrinter::getAnalysisUsage(AnalysisUsage &AU) const
119{
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000120 // FIXME: Currently unimplemented.
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000121}
122
123
124void PIC16AsmPrinter ::
125EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV)
126{
127 printDataDirective(MCPV->getType());
128
129 PIC16ConstantPoolValue *ACPV = (PIC16ConstantPoolValue*)MCPV;
130 GlobalValue *GV = ACPV->getGV();
131 std::string Name = GV ? Mang->getValueName(GV) : TAI->getGlobalPrefix();
132 if (!GV)
133 Name += ACPV->getSymbol();
134 if (ACPV->isNonLazyPointer()) {
135 GVNonLazyPtrs.insert(Name);
136 O << TAI->getPrivateGlobalPrefix() << Name << "$non_lazy_ptr";
137 } else if (ACPV->isStub()) {
138 FnStubs.insert(Name);
139 O << TAI->getPrivateGlobalPrefix() << Name << "$stub";
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000140 } else {
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000141 O << Name;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000142 }
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000143
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000144 if (ACPV->hasModifier()) O << "(" << ACPV->getModifier() << ")";
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000145
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000146 if (ACPV->getPCAdjustment() != 0) {
147 O << "-(" << TAI->getPrivateGlobalPrefix() << "PC"
148 << utostr(ACPV->getLabelId())
149 << "+" << (unsigned)ACPV->getPCAdjustment();
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000150
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000151 if (ACPV->mustAddCurrentAddress())
152 O << "-.";
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000153
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000154 O << ")";
155 }
156 O << "\n";
157
158 // If the constant pool value is a extern weak symbol, remember to emit
159 // the weak reference.
160 if (GV && GV->hasExternalWeakLinkage())
161 ExtWeakSymbols.insert(GV);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000162}
163
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000164/// emitFunctionStart - Emit the directives used by ASM on the start of
165/// functions.
166void PIC16AsmPrinter::emitFunctionStart(MachineFunction &MF)
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000167{
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000168 // Print out the label for the function.
169 const Function *F = MF.getFunction();
170 MachineFrameInfo *FrameInfo = MF.getFrameInfo();
171 if (FrameInfo->hasStackObjects()) {
172 int indexBegin = FrameInfo->getObjectIndexBegin();
173 int indexEnd = FrameInfo->getObjectIndexEnd();
174 while (indexBegin < indexEnd) {
175 if (indexBegin == 0)
176 SwitchToDataOvrSection(F->getParent()->getModuleIdentifier().c_str(),
177 F);
178
179 O << "\t\t" << CurrentFnName << "_" << indexBegin << " " << "RES"
180 << " " << FrameInfo->getObjectSize(indexBegin) << "\n" ;
181 indexBegin++;
182 }
183 }
184 SwitchToTextSection(CurrentFnName.c_str(), F);
185 O << "_" << CurrentFnName << ":" ;
186 O << "\n";
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000187}
188
189
190/// runOnMachineFunction - This uses the printInstruction()
191/// method to print assembly for each instruction.
192///
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000193bool PIC16AsmPrinter::runOnMachineFunction(MachineFunction &MF)
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000194{
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000195 SetupMachineFunction(MF);
196 O << "\n";
197
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000198 // What's my mangled name?
199 CurrentFnName = Mang->getValueName(MF.getFunction());
200
201 // Emit the function start directives
202 emitFunctionStart(MF);
203
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000204 // Print out code for the function.
205 for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
206 I != E; ++I) {
207 // Print a label for the basic block.
208 if (I != MF.begin()) {
209 printBasicBlockLabel(I, true);
210 O << '\n';
211 }
212 for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
213 II != E; ++II) {
214 // Print the assembly for the instruction.
215 O << '\t';
216 printInstruction(II);
217 ++EmittedInsts;
218 }
219 }
220
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000221 // We didn't modify anything.
222 return false;
223}
224
225void PIC16AsmPrinter::
226printOperand(const MachineInstr *MI, int opNum, const char *Modifier)
227{
228 const MachineOperand &MO = MI->getOperand(opNum);
229 const TargetRegisterInfo &RI = *TM.getRegisterInfo();
230
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000231 switch (MO.getType()) {
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000232 case MachineOperand::MO_Register:
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000233 if (TargetRegisterInfo::isPhysicalRegister(MO.getReg()))
234 O << RI.get(MO.getReg()).Name;
235 else
236 assert(0 && "not implemented");
237 break;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000238
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000239 case MachineOperand::MO_Immediate:
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000240 if (!Modifier || strcmp(Modifier, "no_hash") != 0)
241 O << "#";
242 O << (int)MO.getImm();
243 break;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000244
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000245 case MachineOperand::MO_MachineBasicBlock:
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000246 printBasicBlockLabel(MO.getMBB());
247 return;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000248
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000249 case MachineOperand::MO_GlobalAddress:
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000250 O << Mang->getValueName(MO.getGlobal())<<'+'<<MO.getOffset();
251 break;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000252
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000253 case MachineOperand::MO_ExternalSymbol:
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000254 O << MO.getSymbolName();
255 break;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000256
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000257 case MachineOperand::MO_ConstantPoolIndex:
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000258 O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
259 << '_' << MO.getIndex();
260 break;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000261
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000262 case MachineOperand::MO_FrameIndex:
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000263 O << "_" << CurrentFnName
264 << '+' << MO.getIndex();
265 break;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000266
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000267 case MachineOperand::MO_JumpTableIndex:
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000268 O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
269 << '_' << MO.getIndex();
270 break;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000271
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000272 default:
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000273 O << "<unknown operand type>"; abort ();
274 break;
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000275 } // end switch.
276}
277
278static void
Owen Andersoncb371882008-08-21 00:14:44 +0000279printSOImm(raw_ostream &O, int64_t V, const TargetAsmInfo *TAI)
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000280{
281 assert(V < (1 << 12) && "Not a valid so_imm value!");
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000282
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000283 O << (unsigned) V;
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000284}
285
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000286/// printSOImmOperand - SOImm is 4-bit rotated amount in bits 8-11 with 8-bit
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000287/// immediate in bits 0-7.
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000288void PIC16AsmPrinter::printSOImmOperand(const MachineInstr *MI, int OpNum)
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000289{
290 const MachineOperand &MO = MI->getOperand(OpNum);
291 assert(MO.isImmediate() && "Not a valid so_imm value!");
292 printSOImm(O, MO.getImm(), TAI);
293}
294
295
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000296void PIC16AsmPrinter::printAddrModeOperand(const MachineInstr *MI, int Op)
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000297{
298 const MachineOperand &MO1 = MI->getOperand(Op);
299 const MachineOperand &MO2 = MI->getOperand(Op+1);
300
301 if (MO2.isFrameIndex ()) {
302 printOperand(MI, Op+1);
303 return;
304 }
305
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000306 if (!MO1.isRegister()) {
307 // FIXME: This is for CP entries, but isn't right.
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000308 printOperand(MI, Op);
309 return;
310 }
311
312 // If this is Stack Slot
313 if (MO1.isRegister()) {
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000314 if (strcmp(TM.getRegisterInfo()->get(MO1.getReg()).Name, "SP") == 0) {
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000315 O << CurrentFnName <<"_"<< MO2.getImm();
316 return;
317 }
318 O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).Name;
319 O << "+";
320 O << MO2.getImm();
321 O << "]";
322 return;
323 }
324
325 O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).Name;
326 O << "]";
327}
328
329
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000330void PIC16AsmPrinter::printRegisterList(const MachineInstr *MI, int opNum)
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000331{
332 O << "{";
333 for (unsigned i = opNum, e = MI->getNumOperands(); i != e; ++i) {
334 printOperand(MI, i);
335 if (i != e-1) O << ", ";
336 }
337 O << "}";
338}
339
340void PIC16AsmPrinter::
341printCPInstOperand(const MachineInstr *MI, int OpNo, const char *Modifier)
342{
343 assert(Modifier && "This operand only works with a modifier!");
344
345 // There are two aspects to a CONSTANTPOOL_ENTRY operand, the label and the
346 // data itself.
347 if (!strcmp(Modifier, "label")) {
348 unsigned ID = MI->getOperand(OpNo).getImm();
349 O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
350 << '_' << ID << ":\n";
351 } else {
352 assert(!strcmp(Modifier, "cpentry") && "Unknown modifier for CPE");
353 unsigned CPI = MI->getOperand(OpNo).getIndex();
354
355 const MachineConstantPoolEntry &MCPE = // Chasing pointers is fun?
356 MI->getParent()->getParent()->getConstantPool()->getConstants()[CPI];
357
358 if (MCPE.isMachineConstantPoolEntry())
359 EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal);
360 else {
361 EmitGlobalConstant(MCPE.Val.ConstVal);
362 // remember to emit the weak reference
363 if (const GlobalValue *GV = dyn_cast<GlobalValue>(MCPE.Val.ConstVal))
364 if (GV->hasExternalWeakLinkage())
365 ExtWeakSymbols.insert(GV);
366 }
367 }
368}
369
370
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000371bool PIC16AsmPrinter::doInitialization(Module &M)
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000372{
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000373 bool Result = AsmPrinter::doInitialization(M);
374 return Result;
375}
376
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000377bool PIC16AsmPrinter::doFinalization(Module &M)
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000378{
379 const TargetData *TD = TM.getTargetData();
380
381 for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
382 I != E; ++I) {
383 if (!I->hasInitializer()) // External global require no code
384 continue;
385
386 if (EmitSpecialLLVMGlobal(I)) {
387 continue;
388 }
389
390 std::string name = Mang->getValueName(I);
391 Constant *C = I->getInitializer();
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000392 const Type *Ty = C->getType();
393 unsigned Size = TD->getABITypeSize(Ty);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000394 unsigned Align = TD->getPreferredAlignmentLog(I);
395
396 const char *VisibilityDirective = NULL;
397 if (I->hasHiddenVisibility())
398 VisibilityDirective = TAI->getHiddenDirective();
399 else if (I->hasProtectedVisibility())
400 VisibilityDirective = TAI->getProtectedDirective();
401
402 if (VisibilityDirective)
403 O << VisibilityDirective << name << "\n";
404
405 if (C->isNullValue()) {
406 if (I->hasExternalLinkage()) {
407 if (const char *Directive = TAI->getZeroFillDirective()) {
408 O << "\t.globl\t" << name << "\n";
409 O << Directive << "__DATA__, __common, " << name << ", "
410 << Size << ", " << Align << "\n";
411 continue;
412 }
413 }
414
415 if (!I->hasSection() &&
416 (I->hasInternalLinkage() || I->hasWeakLinkage() ||
Dale Johannesenaafce772008-05-14 20:12:51 +0000417 I->hasLinkOnceLinkage() || I->hasCommonLinkage())) {
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000418 if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
Anton Korobeynikov6ec7cf02008-09-24 22:11:26 +0000419 SwitchToDataSection(M.getModuleIdentifier().c_str(), I);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000420 if (TAI->getLCOMMDirective() != NULL) {
421 if (I->hasInternalLinkage()) {
422 O << TAI->getLCOMMDirective() << name << "," << Size;
423 } else
424 O << TAI->getCOMMDirective() << name << "," << Size;
425 } else {
426 if (I->hasInternalLinkage())
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000427 O << "\t.local\t" << name << "\n";
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000428
429 O << TAI->getCOMMDirective() <<"\t" << name << " " <<"RES"<< " "
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000430 << Size;
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000431 O << "\n\t\tGLOBAL" <<" "<< name;
432 if (TAI->getCOMMDirectiveTakesAlignment())
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000433 O << "," << (TAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000434 }
435 continue;
436 }
437 }
438
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000439 switch (I->getLinkage()) {
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000440 case GlobalValue::AppendingLinkage:
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000441 // FIXME: appending linkage variables should go into a section of
442 // their name or something. For now, just emit them as external.
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000443 // FALL THROUGH
444
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000445 case GlobalValue::ExternalLinkage:
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000446 O << "\t.globl " << name << "\n";
447 // FALL THROUGH
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000448
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000449 case GlobalValue::InternalLinkage:
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000450 break;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000451
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000452 default:
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000453 assert(0 && "Unknown linkage type!");
454 break;
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000455 } // end switch.
456
457 EmitAlignment(Align, I);
458 O << name << ":\t\t\t\t" << TAI->getCommentString() << " " << I->getName()
459 << "\n";
460
461 // If the initializer is a extern weak symbol, remember to emit the weak
462 // reference!
463 if (const GlobalValue *GV = dyn_cast<GlobalValue>(C))
464 if (GV->hasExternalWeakLinkage())
465 ExtWeakSymbols.insert(GV);
466
467 EmitGlobalConstant(C);
468 O << '\n';
469 } // end for.
470
471 O << "\n "<< "END";
472 return AsmPrinter::doFinalization(M);
473}
474
475void PIC16AsmPrinter::
476SwitchToTextSection(const char *NewSection, const GlobalValue *GV)
477{
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000478 O << "\n";
479 if (NewSection && *NewSection) {
480 std::string codeSection = "code_";
481 codeSection += NewSection;
482 codeSection += " ";
483 codeSection += "CODE";
484 AsmPrinter::SwitchToTextSection(codeSection.c_str(), GV);
485 }
486 else
487 AsmPrinter::SwitchToTextSection(NewSection, GV);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000488}
489
490void PIC16AsmPrinter::
491SwitchToDataSection(const char *NewSection, const GlobalValue *GV)
492{
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000493 // Need to append index for page.
494 O << "\n";
495 if (NewSection && *NewSection) {
496 std::string dataSection = "udata_";
497 dataSection += NewSection;
498 if (dataSection.substr(dataSection.length() - 2).compare(".o") == 0) {
499 dataSection = dataSection.substr(0, dataSection.length() - 2);
500 }
501 dataSection += " ";
502 dataSection += "UDATA";
503 AsmPrinter::SwitchToDataSection(dataSection.c_str(), GV);
504 }
505 else
506 AsmPrinter::SwitchToDataSection(NewSection, GV);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000507}
508
509void PIC16AsmPrinter::
510SwitchToDataOvrSection(const char *NewSection, const GlobalValue *GV)
511{
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000512 O << "\n";
513 if (NewSection && *NewSection) {
514 std::string dataSection = "frame_";
515 dataSection += NewSection;
516 if (dataSection.substr(dataSection.length() - 2).compare(".o") == 0) {
517 dataSection = dataSection.substr(0, dataSection.length() - 2);
518 }
519 dataSection += "_";
520 dataSection += CurrentFnName;
521 dataSection += " ";
522 dataSection += "UDATA_OVR";
523 AsmPrinter::SwitchToDataSection(dataSection.c_str(), GV);
524 }
525 else
526 AsmPrinter::SwitchToDataSection(NewSection, GV);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000527}