blob: c6b2ace6f664db4e7c65296142b3ef7ea3a71ed3 [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"
34#include "llvm/Target/TargetAsmInfo.h"
35#include "llvm/Target/TargetData.h"
36#include "llvm/Target/TargetMachine.h"
37#include "llvm/Target/TargetOptions.h"
38#include <cctype>
39
40using namespace llvm;
41
42STATISTIC(EmittedInsts, "Number of machine instrs printed");
43
44namespace {
45 struct VISIBILITY_HIDDEN PIC16AsmPrinter : public AsmPrinter {
46 PIC16AsmPrinter(std::ostream &O, TargetMachine &TM, const TargetAsmInfo *T)
47 : AsmPrinter(O, TM, T) {
48 }
49
50
51 /// We name each basic block in a Function with a unique number, so
52 /// that we can consistently refer to them later. This is cleared
53 /// at the beginning of each call to runOnMachineFunction().
54 ///
55 typedef std::map<const Value *, unsigned> ValueMapTy;
56 ValueMapTy NumberForBB;
57
58 /// Keeps the set of GlobalValues that require non-lazy-pointers for
59 /// indirect access.
60 std::set<std::string> GVNonLazyPtrs;
61
62 /// Keeps the set of external function GlobalAddresses that the asm
63 /// printer should generate stubs for.
64 std::set<std::string> FnStubs;
65
66 /// True if asm printer is printing a series of CONSTPOOL_ENTRY.
67 bool InCPMode;
68
69 virtual const char *getPassName() const {
70 return "PIC16 Assembly Printer";
71 }
72
73 void printOperand(const MachineInstr *MI, int opNum,
74 const char *Modifier = 0);
75
76 void printSOImmOperand(const MachineInstr *MI, int opNum);
77
78 void printAddrModeOperand(const MachineInstr *MI, int OpNo);
79
80 void printRegisterList(const MachineInstr *MI, int opNum);
81 void printCPInstOperand(const MachineInstr *MI, int opNum,
82 const char *Modifier);
83
84
85 bool printInstruction(const MachineInstr *MI); // autogenerated.
86 void emitFunctionStart(MachineFunction &F);
87 bool runOnMachineFunction(MachineFunction &F);
88 bool doInitialization(Module &M);
89 bool doFinalization(Module &M);
90
91 virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV);
92
93 void getAnalysisUsage(AnalysisUsage &AU) const;
94
95 public:
96 void SwitchToTextSection(const char *NewSection,
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +000097 const GlobalValue *GV = NULL);
Sanjiv Gupta0e687712008-05-13 09:02:57 +000098 void SwitchToDataSection(const char *NewSection,
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +000099 const GlobalValue *GV = NULL);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000100 void SwitchToDataOvrSection(const char *NewSection,
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000101 const GlobalValue *GV = NULL);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000102 };
103} // end of anonymous namespace
104
105#include "PIC16GenAsmWriter.inc"
106
107/// createPIC16CodePrinterPass - Returns a pass that prints the PIC16
108/// assembly code for a MachineFunction to the given output stream,
109/// using the given target machine description. This should work
110/// regardless of whether the function is in SSA form.
111///
112FunctionPass *llvm::createPIC16CodePrinterPass(std::ostream &o,
113 PIC16TargetMachine &tm) {
114 return new PIC16AsmPrinter(o, tm, tm.getTargetAsmInfo());
115}
116
117void PIC16AsmPrinter::getAnalysisUsage(AnalysisUsage &AU) const
118{
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000119 // FIXME: Currently unimplemented.
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000120}
121
122
123void PIC16AsmPrinter ::
124EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV)
125{
126 printDataDirective(MCPV->getType());
127
128 PIC16ConstantPoolValue *ACPV = (PIC16ConstantPoolValue*)MCPV;
129 GlobalValue *GV = ACPV->getGV();
130 std::string Name = GV ? Mang->getValueName(GV) : TAI->getGlobalPrefix();
131 if (!GV)
132 Name += ACPV->getSymbol();
133 if (ACPV->isNonLazyPointer()) {
134 GVNonLazyPtrs.insert(Name);
135 O << TAI->getPrivateGlobalPrefix() << Name << "$non_lazy_ptr";
136 } else if (ACPV->isStub()) {
137 FnStubs.insert(Name);
138 O << TAI->getPrivateGlobalPrefix() << Name << "$stub";
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000139 } else {
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000140 O << Name;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000141 }
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000142
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000143 if (ACPV->hasModifier()) O << "(" << ACPV->getModifier() << ")";
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000144
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000145 if (ACPV->getPCAdjustment() != 0) {
146 O << "-(" << TAI->getPrivateGlobalPrefix() << "PC"
147 << utostr(ACPV->getLabelId())
148 << "+" << (unsigned)ACPV->getPCAdjustment();
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000149
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000150 if (ACPV->mustAddCurrentAddress())
151 O << "-.";
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000152
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000153 O << ")";
154 }
155 O << "\n";
156
157 // If the constant pool value is a extern weak symbol, remember to emit
158 // the weak reference.
159 if (GV && GV->hasExternalWeakLinkage())
160 ExtWeakSymbols.insert(GV);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000161}
162
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000163/// emitFunctionStart - Emit the directives used by ASM on the start of
164/// functions.
165void PIC16AsmPrinter::emitFunctionStart(MachineFunction &MF)
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000166{
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000167 // Print out the label for the function.
168 const Function *F = MF.getFunction();
169 MachineFrameInfo *FrameInfo = MF.getFrameInfo();
170 if (FrameInfo->hasStackObjects()) {
171 int indexBegin = FrameInfo->getObjectIndexBegin();
172 int indexEnd = FrameInfo->getObjectIndexEnd();
173 while (indexBegin < indexEnd) {
174 if (indexBegin == 0)
175 SwitchToDataOvrSection(F->getParent()->getModuleIdentifier().c_str(),
176 F);
177
178 O << "\t\t" << CurrentFnName << "_" << indexBegin << " " << "RES"
179 << " " << FrameInfo->getObjectSize(indexBegin) << "\n" ;
180 indexBegin++;
181 }
182 }
183 SwitchToTextSection(CurrentFnName.c_str(), F);
184 O << "_" << CurrentFnName << ":" ;
185 O << "\n";
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000186}
187
188
189/// runOnMachineFunction - This uses the printInstruction()
190/// method to print assembly for each instruction.
191///
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000192bool PIC16AsmPrinter::runOnMachineFunction(MachineFunction &MF)
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000193{
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000194 SetupMachineFunction(MF);
195 O << "\n";
196
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000197 // What's my mangled name?
198 CurrentFnName = Mang->getValueName(MF.getFunction());
199
200 // Emit the function start directives
201 emitFunctionStart(MF);
202
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000203 // Print out code for the function.
204 for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
205 I != E; ++I) {
206 // Print a label for the basic block.
207 if (I != MF.begin()) {
208 printBasicBlockLabel(I, true);
209 O << '\n';
210 }
211 for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
212 II != E; ++II) {
213 // Print the assembly for the instruction.
214 O << '\t';
215 printInstruction(II);
216 ++EmittedInsts;
217 }
218 }
219
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000220 // We didn't modify anything.
221 return false;
222}
223
224void PIC16AsmPrinter::
225printOperand(const MachineInstr *MI, int opNum, const char *Modifier)
226{
227 const MachineOperand &MO = MI->getOperand(opNum);
228 const TargetRegisterInfo &RI = *TM.getRegisterInfo();
229
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000230 switch (MO.getType()) {
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000231 case MachineOperand::MO_Register:
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000232 if (TargetRegisterInfo::isPhysicalRegister(MO.getReg()))
233 O << RI.get(MO.getReg()).Name;
234 else
235 assert(0 && "not implemented");
236 break;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000237
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000238 case MachineOperand::MO_Immediate:
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000239 if (!Modifier || strcmp(Modifier, "no_hash") != 0)
240 O << "#";
241 O << (int)MO.getImm();
242 break;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000243
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000244 case MachineOperand::MO_MachineBasicBlock:
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000245 printBasicBlockLabel(MO.getMBB());
246 return;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000247
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000248 case MachineOperand::MO_GlobalAddress:
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000249 O << Mang->getValueName(MO.getGlobal())<<'+'<<MO.getOffset();
250 break;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000251
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000252 case MachineOperand::MO_ExternalSymbol:
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000253 O << MO.getSymbolName();
254 break;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000255
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000256 case MachineOperand::MO_ConstantPoolIndex:
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000257 O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
258 << '_' << MO.getIndex();
259 break;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000260
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000261 case MachineOperand::MO_FrameIndex:
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000262 O << "_" << CurrentFnName
263 << '+' << MO.getIndex();
264 break;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000265
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000266 case MachineOperand::MO_JumpTableIndex:
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000267 O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
268 << '_' << MO.getIndex();
269 break;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000270
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000271 default:
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000272 O << "<unknown operand type>"; abort ();
273 break;
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000274 } // end switch.
275}
276
277static void
278printSOImm(std::ostream &O, int64_t V, const TargetAsmInfo *TAI)
279{
280 assert(V < (1 << 12) && "Not a valid so_imm value!");
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000281
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000282 O << (unsigned) V;
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000283}
284
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000285/// printSOImmOperand - SOImm is 4-bit rotated amount in bits 8-11 with 8-bit
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000286/// immediate in bits 0-7.
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000287void PIC16AsmPrinter::printSOImmOperand(const MachineInstr *MI, int OpNum)
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000288{
289 const MachineOperand &MO = MI->getOperand(OpNum);
290 assert(MO.isImmediate() && "Not a valid so_imm value!");
291 printSOImm(O, MO.getImm(), TAI);
292}
293
294
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000295void PIC16AsmPrinter::printAddrModeOperand(const MachineInstr *MI, int Op)
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000296{
297 const MachineOperand &MO1 = MI->getOperand(Op);
298 const MachineOperand &MO2 = MI->getOperand(Op+1);
299
300 if (MO2.isFrameIndex ()) {
301 printOperand(MI, Op+1);
302 return;
303 }
304
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000305 if (!MO1.isRegister()) {
306 // FIXME: This is for CP entries, but isn't right.
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000307 printOperand(MI, Op);
308 return;
309 }
310
311 // If this is Stack Slot
312 if (MO1.isRegister()) {
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000313 if (strcmp(TM.getRegisterInfo()->get(MO1.getReg()).Name, "SP") == 0) {
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000314 O << CurrentFnName <<"_"<< MO2.getImm();
315 return;
316 }
317 O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).Name;
318 O << "+";
319 O << MO2.getImm();
320 O << "]";
321 return;
322 }
323
324 O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).Name;
325 O << "]";
326}
327
328
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000329void PIC16AsmPrinter::printRegisterList(const MachineInstr *MI, int opNum)
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000330{
331 O << "{";
332 for (unsigned i = opNum, e = MI->getNumOperands(); i != e; ++i) {
333 printOperand(MI, i);
334 if (i != e-1) O << ", ";
335 }
336 O << "}";
337}
338
339void PIC16AsmPrinter::
340printCPInstOperand(const MachineInstr *MI, int OpNo, const char *Modifier)
341{
342 assert(Modifier && "This operand only works with a modifier!");
343
344 // There are two aspects to a CONSTANTPOOL_ENTRY operand, the label and the
345 // data itself.
346 if (!strcmp(Modifier, "label")) {
347 unsigned ID = MI->getOperand(OpNo).getImm();
348 O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
349 << '_' << ID << ":\n";
350 } else {
351 assert(!strcmp(Modifier, "cpentry") && "Unknown modifier for CPE");
352 unsigned CPI = MI->getOperand(OpNo).getIndex();
353
354 const MachineConstantPoolEntry &MCPE = // Chasing pointers is fun?
355 MI->getParent()->getParent()->getConstantPool()->getConstants()[CPI];
356
357 if (MCPE.isMachineConstantPoolEntry())
358 EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal);
359 else {
360 EmitGlobalConstant(MCPE.Val.ConstVal);
361 // remember to emit the weak reference
362 if (const GlobalValue *GV = dyn_cast<GlobalValue>(MCPE.Val.ConstVal))
363 if (GV->hasExternalWeakLinkage())
364 ExtWeakSymbols.insert(GV);
365 }
366 }
367}
368
369
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000370bool PIC16AsmPrinter::doInitialization(Module &M)
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000371{
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000372 bool Result = AsmPrinter::doInitialization(M);
373 return Result;
374}
375
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000376bool PIC16AsmPrinter::doFinalization(Module &M)
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000377{
378 const TargetData *TD = TM.getTargetData();
379
380 for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
381 I != E; ++I) {
382 if (!I->hasInitializer()) // External global require no code
383 continue;
384
385 if (EmitSpecialLLVMGlobal(I)) {
386 continue;
387 }
388
389 std::string name = Mang->getValueName(I);
390 Constant *C = I->getInitializer();
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000391 const Type *Ty = C->getType();
392 unsigned Size = TD->getABITypeSize(Ty);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000393 unsigned Align = TD->getPreferredAlignmentLog(I);
394
395 const char *VisibilityDirective = NULL;
396 if (I->hasHiddenVisibility())
397 VisibilityDirective = TAI->getHiddenDirective();
398 else if (I->hasProtectedVisibility())
399 VisibilityDirective = TAI->getProtectedDirective();
400
401 if (VisibilityDirective)
402 O << VisibilityDirective << name << "\n";
403
404 if (C->isNullValue()) {
405 if (I->hasExternalLinkage()) {
406 if (const char *Directive = TAI->getZeroFillDirective()) {
407 O << "\t.globl\t" << name << "\n";
408 O << Directive << "__DATA__, __common, " << name << ", "
409 << Size << ", " << Align << "\n";
410 continue;
411 }
412 }
413
414 if (!I->hasSection() &&
415 (I->hasInternalLinkage() || I->hasWeakLinkage() ||
Dale Johannesenaafce772008-05-14 20:12:51 +0000416 I->hasLinkOnceLinkage() || I->hasCommonLinkage())) {
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000417 if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
418 if (!NoZerosInBSS && TAI->getBSSSection())
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000419 SwitchToDataSection(M.getModuleIdentifier().c_str(), I);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000420 else
421 SwitchToDataSection(TAI->getDataSection(), I);
422 if (TAI->getLCOMMDirective() != NULL) {
423 if (I->hasInternalLinkage()) {
424 O << TAI->getLCOMMDirective() << name << "," << Size;
425 } else
426 O << TAI->getCOMMDirective() << name << "," << Size;
427 } else {
428 if (I->hasInternalLinkage())
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000429 O << "\t.local\t" << name << "\n";
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000430
431 O << TAI->getCOMMDirective() <<"\t" << name << " " <<"RES"<< " "
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000432 << Size;
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000433 O << "\n\t\tGLOBAL" <<" "<< name;
434 if (TAI->getCOMMDirectiveTakesAlignment())
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000435 O << "," << (TAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000436 }
437 continue;
438 }
439 }
440
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000441 switch (I->getLinkage()) {
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000442 case GlobalValue::AppendingLinkage:
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000443 // FIXME: appending linkage variables should go into a section of
444 // their name or something. For now, just emit them as external.
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000445 // FALL THROUGH
446
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000447 case GlobalValue::ExternalLinkage:
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000448 O << "\t.globl " << name << "\n";
449 // FALL THROUGH
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000450
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000451 case GlobalValue::InternalLinkage:
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000452 if (I->isConstant()) {
453 const ConstantArray *CVA = dyn_cast<ConstantArray>(C);
454 if (TAI->getCStringSection() && CVA && CVA->isCString()) {
455 SwitchToDataSection(TAI->getCStringSection(), I);
456 break;
457 }
458 }
459 break;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000460
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000461 default:
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000462 assert(0 && "Unknown linkage type!");
463 break;
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000464 } // end switch.
465
466 EmitAlignment(Align, I);
467 O << name << ":\t\t\t\t" << TAI->getCommentString() << " " << I->getName()
468 << "\n";
469
470 // If the initializer is a extern weak symbol, remember to emit the weak
471 // reference!
472 if (const GlobalValue *GV = dyn_cast<GlobalValue>(C))
473 if (GV->hasExternalWeakLinkage())
474 ExtWeakSymbols.insert(GV);
475
476 EmitGlobalConstant(C);
477 O << '\n';
478 } // end for.
479
480 O << "\n "<< "END";
481 return AsmPrinter::doFinalization(M);
482}
483
484void PIC16AsmPrinter::
485SwitchToTextSection(const char *NewSection, const GlobalValue *GV)
486{
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000487 O << "\n";
488 if (NewSection && *NewSection) {
489 std::string codeSection = "code_";
490 codeSection += NewSection;
491 codeSection += " ";
492 codeSection += "CODE";
493 AsmPrinter::SwitchToTextSection(codeSection.c_str(), GV);
494 }
495 else
496 AsmPrinter::SwitchToTextSection(NewSection, GV);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000497}
498
499void PIC16AsmPrinter::
500SwitchToDataSection(const char *NewSection, const GlobalValue *GV)
501{
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000502 // Need to append index for page.
503 O << "\n";
504 if (NewSection && *NewSection) {
505 std::string dataSection = "udata_";
506 dataSection += NewSection;
507 if (dataSection.substr(dataSection.length() - 2).compare(".o") == 0) {
508 dataSection = dataSection.substr(0, dataSection.length() - 2);
509 }
510 dataSection += " ";
511 dataSection += "UDATA";
512 AsmPrinter::SwitchToDataSection(dataSection.c_str(), GV);
513 }
514 else
515 AsmPrinter::SwitchToDataSection(NewSection, GV);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000516}
517
518void PIC16AsmPrinter::
519SwitchToDataOvrSection(const char *NewSection, const GlobalValue *GV)
520{
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000521 O << "\n";
522 if (NewSection && *NewSection) {
523 std::string dataSection = "frame_";
524 dataSection += NewSection;
525 if (dataSection.substr(dataSection.length() - 2).compare(".o") == 0) {
526 dataSection = dataSection.substr(0, dataSection.length() - 2);
527 }
528 dataSection += "_";
529 dataSection += CurrentFnName;
530 dataSection += " ";
531 dataSection += "UDATA_OVR";
532 AsmPrinter::SwitchToDataSection(dataSection.c_str(), GV);
533 }
534 else
535 AsmPrinter::SwitchToDataSection(NewSection, GV);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000536}