blob: 8c6dfbbfdf21bae287ef578bd17d53c90be101c6 [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.
419 if (!NoZerosInBSS && TAI->getBSSSection())
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000420 SwitchToDataSection(M.getModuleIdentifier().c_str(), I);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000421 else
422 SwitchToDataSection(TAI->getDataSection(), I);
423 if (TAI->getLCOMMDirective() != NULL) {
424 if (I->hasInternalLinkage()) {
425 O << TAI->getLCOMMDirective() << name << "," << Size;
426 } else
427 O << TAI->getCOMMDirective() << name << "," << Size;
428 } else {
429 if (I->hasInternalLinkage())
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000430 O << "\t.local\t" << name << "\n";
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000431
432 O << TAI->getCOMMDirective() <<"\t" << name << " " <<"RES"<< " "
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000433 << Size;
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000434 O << "\n\t\tGLOBAL" <<" "<< name;
435 if (TAI->getCOMMDirectiveTakesAlignment())
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000436 O << "," << (TAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000437 }
438 continue;
439 }
440 }
441
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000442 switch (I->getLinkage()) {
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000443 case GlobalValue::AppendingLinkage:
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000444 // FIXME: appending linkage variables should go into a section of
445 // their name or something. For now, just emit them as external.
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000446 // FALL THROUGH
447
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000448 case GlobalValue::ExternalLinkage:
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000449 O << "\t.globl " << name << "\n";
450 // FALL THROUGH
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000451
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000452 case GlobalValue::InternalLinkage:
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000453 if (I->isConstant()) {
454 const ConstantArray *CVA = dyn_cast<ConstantArray>(C);
455 if (TAI->getCStringSection() && CVA && CVA->isCString()) {
456 SwitchToDataSection(TAI->getCStringSection(), I);
457 break;
458 }
459 }
460 break;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000461
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000462 default:
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000463 assert(0 && "Unknown linkage type!");
464 break;
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000465 } // end switch.
466
467 EmitAlignment(Align, I);
468 O << name << ":\t\t\t\t" << TAI->getCommentString() << " " << I->getName()
469 << "\n";
470
471 // If the initializer is a extern weak symbol, remember to emit the weak
472 // reference!
473 if (const GlobalValue *GV = dyn_cast<GlobalValue>(C))
474 if (GV->hasExternalWeakLinkage())
475 ExtWeakSymbols.insert(GV);
476
477 EmitGlobalConstant(C);
478 O << '\n';
479 } // end for.
480
481 O << "\n "<< "END";
482 return AsmPrinter::doFinalization(M);
483}
484
485void PIC16AsmPrinter::
486SwitchToTextSection(const char *NewSection, const GlobalValue *GV)
487{
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000488 O << "\n";
489 if (NewSection && *NewSection) {
490 std::string codeSection = "code_";
491 codeSection += NewSection;
492 codeSection += " ";
493 codeSection += "CODE";
494 AsmPrinter::SwitchToTextSection(codeSection.c_str(), GV);
495 }
496 else
497 AsmPrinter::SwitchToTextSection(NewSection, GV);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000498}
499
500void PIC16AsmPrinter::
501SwitchToDataSection(const char *NewSection, const GlobalValue *GV)
502{
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000503 // Need to append index for page.
504 O << "\n";
505 if (NewSection && *NewSection) {
506 std::string dataSection = "udata_";
507 dataSection += NewSection;
508 if (dataSection.substr(dataSection.length() - 2).compare(".o") == 0) {
509 dataSection = dataSection.substr(0, dataSection.length() - 2);
510 }
511 dataSection += " ";
512 dataSection += "UDATA";
513 AsmPrinter::SwitchToDataSection(dataSection.c_str(), GV);
514 }
515 else
516 AsmPrinter::SwitchToDataSection(NewSection, GV);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000517}
518
519void PIC16AsmPrinter::
520SwitchToDataOvrSection(const char *NewSection, const GlobalValue *GV)
521{
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000522 O << "\n";
523 if (NewSection && *NewSection) {
524 std::string dataSection = "frame_";
525 dataSection += NewSection;
526 if (dataSection.substr(dataSection.length() - 2).compare(".o") == 0) {
527 dataSection = dataSection.substr(0, dataSection.length() - 2);
528 }
529 dataSection += "_";
530 dataSection += CurrentFnName;
531 dataSection += " ";
532 dataSection += "UDATA_OVR";
533 AsmPrinter::SwitchToDataSection(dataSection.c_str(), GV);
534 }
535 else
536 AsmPrinter::SwitchToDataSection(NewSection, GV);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000537}