blob: ac4776e657ffb1ca532011ed74d8d1e9371bc195 [file] [log] [blame]
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +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
Sanjiv Guptaac2620e2009-10-15 19:26:25 +000015#include "PIC16ABINames.h"
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +000016#include "PIC16AsmPrinter.h"
Sanjiv Guptaac2620e2009-10-15 19:26:25 +000017#include "PIC16Section.h"
Chris Lattner621c44d2009-08-22 20:48:53 +000018#include "PIC16MCAsmInfo.h"
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +000019#include "llvm/DerivedTypes.h"
20#include "llvm/Function.h"
21#include "llvm/Module.h"
22#include "llvm/CodeGen/DwarfWriter.h"
23#include "llvm/CodeGen/MachineFrameInfo.h"
24#include "llvm/CodeGen/DwarfWriter.h"
25#include "llvm/CodeGen/MachineModuleInfo.h"
Chris Lattner73266f92009-08-19 05:49:37 +000026#include "llvm/MC/MCStreamer.h"
Chris Lattnerc6f802d2009-09-13 17:14:04 +000027#include "llvm/MC/MCSymbol.h"
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +000028#include "llvm/Target/TargetRegistry.h"
29#include "llvm/Target/TargetLoweringObjectFile.h"
30#include "llvm/Support/ErrorHandling.h"
31#include "llvm/Support/FormattedStream.h"
32#include "llvm/Support/Mangler.h"
33#include <cstring>
34using namespace llvm;
35
36#include "PIC16GenAsmWriter.inc"
37
38PIC16AsmPrinter::PIC16AsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
Chris Lattner621c44d2009-08-22 20:48:53 +000039 const MCAsmInfo *T, bool V)
Chris Lattner181c7cb2009-08-22 20:56:12 +000040: AsmPrinter(O, TM, T, V), DbgInfo(O, T) {
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +000041 PTLI = static_cast<PIC16TargetLowering*>(TM.getTargetLowering());
Chris Lattnera5ef4d32009-08-22 21:43:10 +000042 PMAI = static_cast<const PIC16MCAsmInfo*>(T);
Sanjiv Guptaac2620e2009-10-15 19:26:25 +000043 PTOF = (PIC16TargetObjectFile *)&PTLI->getObjFileLowering();
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +000044}
45
46bool PIC16AsmPrinter::printMachineInstruction(const MachineInstr *MI) {
Devang Patel5450fc12009-10-06 02:19:11 +000047 processDebugLoc(MI, true);
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +000048 printInstruction(MI);
David Greeneca9b04b2009-11-13 21:34:57 +000049 if (VerboseAsm)
Chris Lattner32d4cc72009-09-09 23:14:36 +000050 EmitComments(*MI);
51 O << '\n';
Devang Patel5450fc12009-10-06 02:19:11 +000052 processDebugLoc(MI, false);
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +000053 return true;
54}
55
Sanjiv Gupta00e8f5a2009-10-21 10:42:44 +000056static int getFunctionColor(const Function *F) {
57 if (F->hasSection()) {
58 std::string Sectn = F->getSection();
59 std::string StrToFind = "Overlay=";
Chris Lattner62b547a2009-10-22 03:42:27 +000060 std::string::size_type Pos = Sectn.find(StrToFind);
Sanjiv Gupta00e8f5a2009-10-21 10:42:44 +000061
62 // Retreive the color number if the key is found.
63 if (Pos != std::string::npos) {
64 Pos += StrToFind.length();
65 std::string Color = "";
66 char c = Sectn.at(Pos);
67 // A Color can only consist of digits.
68 while (c >= '0' && c<= '9') {
69 Color.append(1,c);
70 Pos++;
71 if (Pos >= Sectn.length())
72 break;
73 c = Sectn.at(Pos);
74 }
75 return atoi(Color.c_str());
76 }
77 }
78
79 // Color was not set for function, so return -1.
80 return -1;
81}
82
83// Color the Auto section of the given function.
84void PIC16AsmPrinter::ColorAutoSection(const Function *F) {
85 std::string SectionName = PAN::getAutosSectionName(CurrentFnName);
86 PIC16Section* Section = PTOF->findPIC16Section(SectionName);
87 if (Section != NULL) {
88 int Color = getFunctionColor(F);
89 if (Color >= 0)
90 Section->setColor(Color);
91 }
92}
93
94
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +000095/// runOnMachineFunction - This emits the frame section, autos section and
96/// assembly for each instruction. Also takes care of function begin debug
97/// directive and file begin debug directive (if required) for the function.
98///
99bool PIC16AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
100 this->MF = &MF;
101
102 // This calls the base class function required to be called at beginning
103 // of runOnMachineFunction.
104 SetupMachineFunction(MF);
105
106 // Get the mangled name.
107 const Function *F = MF.getFunction();
108 CurrentFnName = Mang->getMangledName(F);
109
Sanjiv Gupta00e8f5a2009-10-21 10:42:44 +0000110 // Put the color information from function to its auto section.
111 ColorAutoSection(F);
112
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000113 // Emit the function frame (args and temps).
114 EmitFunctionFrame(MF);
115
116 DbgInfo.BeginFunction(MF);
117
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000118 // Now emit the instructions of function in its code section.
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000119 const MCSection *fCodeSection
120 = getObjFileLowering().SectionForCode(CurrentFnName);
121
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000122 // Start the Code Section.
123 O << "\n";
Chris Lattner73266f92009-08-19 05:49:37 +0000124 OutStreamer.SwitchSection(fCodeSection);
Chris Lattner7f504882009-08-21 23:12:15 +0000125
126 // Emit the frame address of the function at the beginning of code.
127 O << "\tretlw low(" << PAN::getFrameLabel(CurrentFnName) << ")\n";
128 O << "\tretlw high(" << PAN::getFrameLabel(CurrentFnName) << ")\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000129
130 // Emit function start label.
Chris Lattnerc0c8d7d2010-01-16 01:17:26 +0000131 CurrentFnSym->print(O, MAI);
132 O << ":\n";
Chris Lattner7f504882009-08-21 23:12:15 +0000133
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000134 DebugLoc CurDL;
135 O << "\n";
136 // Print out code for the function.
137 for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
138 I != E; ++I) {
139
140 // Print a label for the basic block.
141 if (I != MF.begin()) {
Chris Lattnerda5fb6d2009-09-14 03:15:54 +0000142 EmitBasicBlockStart(I);
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000143 }
144
145 // Print a basic block.
146 for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
147 II != E; ++II) {
148
149 // Emit the line directive if source line changed.
150 const DebugLoc DL = II->getDebugLoc();
151 if (!DL.isUnknown() && DL != CurDL) {
152 DbgInfo.ChangeDebugLoc(MF, DL);
153 CurDL = DL;
154 }
155
156 // Print the assembly for the instruction.
157 printMachineInstruction(II);
158 }
159 }
160
161 // Emit function end debug directives.
162 DbgInfo.EndFunction(MF);
163
164 return false; // we didn't modify anything.
165}
166
167
168// printOperand - print operand of insn.
169void PIC16AsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
170 const MachineOperand &MO = MI->getOperand(opNum);
171
172 switch (MO.getType()) {
173 case MachineOperand::MO_Register:
Sanjiv Gupta20606ae2009-12-19 08:26:25 +0000174 {
175 // For indirect load/store insns, the fsr name is printed as INDF.
176 std::string RegName = getRegisterName(MO.getReg());
177 if ((MI->getOpcode() == PIC16::load_indirect) ||
178 (MI->getOpcode() == PIC16::store_indirect))
179 {
180 RegName.replace (0, 3, "INDF");
181 }
182 O << RegName;
183 }
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000184 return;
185
186 case MachineOperand::MO_Immediate:
187 O << (int)MO.getImm();
188 return;
189
190 case MachineOperand::MO_GlobalAddress: {
191 std::string Sname = Mang->getMangledName(MO.getGlobal());
192 // FIXME: currently we do not have a memcpy def coming in the module
193 // by any chance, as we do not link in those as .bc lib. So these calls
194 // are always external and it is safe to emit an extern.
195 if (PAN::isMemIntrinsic(Sname)) {
196 LibcallDecls.push_back(createESName(Sname));
197 }
Chris Lattner7f504882009-08-21 23:12:15 +0000198
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000199 O << Sname;
200 break;
201 }
202 case MachineOperand::MO_ExternalSymbol: {
203 const char *Sname = MO.getSymbolName();
204
205 // If its a libcall name, record it to decls section.
206 if (PAN::getSymbolTag(Sname) == PAN::LIBCALL) {
Chris Lattner7f504882009-08-21 23:12:15 +0000207 LibcallDecls.push_back(Sname);
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000208 }
209
210 // Record a call to intrinsic to print the extern declaration for it.
211 std::string Sym = Sname;
212 if (PAN::isMemIntrinsic(Sym)) {
213 Sym = PAN::addPrefix(Sym);
214 LibcallDecls.push_back(createESName(Sym));
215 }
Chris Lattner7f504882009-08-21 23:12:15 +0000216
217 O << Sym;
218 break;
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000219 }
220 case MachineOperand::MO_MachineBasicBlock:
Chris Lattnerc6f802d2009-09-13 17:14:04 +0000221 GetMBBSymbol(MO.getMBB()->getNumber())->print(O, MAI);
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000222 return;
223
224 default:
225 llvm_unreachable(" Operand type not supported.");
226 }
227}
228
229/// printCCOperand - Print the cond code operand.
230///
231void PIC16AsmPrinter::printCCOperand(const MachineInstr *MI, int opNum) {
232 int CC = (int)MI->getOperand(opNum).getImm();
233 O << PIC16CondCodeToString((PIC16CC::CondCodes)CC);
234}
235
236// This function is used to sort the decls list.
237// should return true if s1 should come before s2.
238static bool is_before(const char *s1, const char *s2) {
239 return strcmp(s1, s2) <= 0;
240}
241
242// This is used by list::unique below.
243// unique will filter out duplicates if it knows them.
244static bool is_duplicate(const char *s1, const char *s2) {
245 return !strcmp(s1, s2);
246}
247
248/// printLibcallDecls - print the extern declarations for compiler
249/// intrinsics.
250///
251void PIC16AsmPrinter::printLibcallDecls() {
252 // If no libcalls used, return.
253 if (LibcallDecls.empty()) return;
254
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000255 O << MAI->getCommentString() << "External decls for libcalls - BEGIN." <<"\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000256 // Remove duplicate entries.
257 LibcallDecls.sort(is_before);
258 LibcallDecls.unique(is_duplicate);
259
260 for (std::list<const char*>::const_iterator I = LibcallDecls.begin();
261 I != LibcallDecls.end(); I++) {
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000262 O << MAI->getExternDirective() << *I << "\n";
263 O << MAI->getExternDirective() << PAN::getArgsLabel(*I) << "\n";
264 O << MAI->getExternDirective() << PAN::getRetvalLabel(*I) << "\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000265 }
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000266 O << MAI->getCommentString() << "External decls for libcalls - END." <<"\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000267}
268
Bob Wilson4901f432009-09-30 21:44:42 +0000269/// doInitialization - Perform Module level initializations here.
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000270/// One task that we do here is to sectionize all global variables.
271/// The MemSelOptimizer pass depends on the sectionizing.
272///
273bool PIC16AsmPrinter::doInitialization(Module &M) {
274 bool Result = AsmPrinter::doInitialization(M);
275
Sanjiv Gupta20606ae2009-12-19 08:26:25 +0000276 // Every asmbly contains these std headers.
277 O << "\n#include p16f1xxx.inc";
278 O << "\n#include stdmacros.inc";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000279
280 // Set the section names for all globals.
281 for (Module::global_iterator I = M.global_begin(), E = M.global_end();
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000282 I != E; ++I) {
283
284 // Record External Var Decls.
285 if (I->isDeclaration()) {
286 ExternalVarDecls.push_back(I);
287 continue;
288 }
289
290 // Record Exteranl Var Defs.
291 if (I->hasExternalLinkage() || I->hasCommonLinkage()) {
292 ExternalVarDefs.push_back(I);
293 }
294
295 // Sectionify actual data.
296 if (!I->hasAvailableExternallyLinkage()) {
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000297 const MCSection *S = getObjFileLowering().SectionForGlobal(I, Mang, TM);
298
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000299 I->setSection(((const PIC16Section *)S)->getName());
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000300 }
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000301 }
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000302
303 DbgInfo.BeginModule(M);
304 EmitFunctionDecls(M);
305 EmitUndefinedVars(M);
306 EmitDefinedVars(M);
307 EmitIData(M);
308 EmitUData(M);
309 EmitRomData(M);
Sanjiv Gupta27e801c2009-10-25 08:14:11 +0000310 EmitSharedUdata(M);
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000311 EmitUserSections(M);
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000312 return Result;
313}
314
315/// Emit extern decls for functions imported from other modules, and emit
316/// global declarations for function defined in this module and which are
317/// available to other modules.
318///
319void PIC16AsmPrinter::EmitFunctionDecls(Module &M) {
320 // Emit declarations for external functions.
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000321 O <<"\n"<<MAI->getCommentString() << "Function Declarations - BEGIN." <<"\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000322 for (Module::iterator I = M.begin(), E = M.end(); I != E; I++) {
323 if (I->isIntrinsic())
324 continue;
325
326 std::string Name = Mang->getMangledName(I);
327 if (Name.compare("@abort") == 0)
328 continue;
329
330 if (!I->isDeclaration() && !I->hasExternalLinkage())
331 continue;
332
333 // Do not emit memcpy, memset, and memmove here.
334 // Calls to these routines can be generated in two ways,
335 // 1. User calling the standard lib function
336 // 2. Codegen generating these calls for llvm intrinsics.
337 // In the first case a prototype is alread availale, while in
338 // second case the call is via and externalsym and the prototype is missing.
339 // So declarations for these are currently always getting printing by
340 // tracking both kind of references in printInstrunction.
341 if (I->isDeclaration() && PAN::isMemIntrinsic(Name)) continue;
342
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000343 const char *directive = I->isDeclaration() ? MAI->getExternDirective() :
344 MAI->getGlobalDirective();
Chris Lattner7f504882009-08-21 23:12:15 +0000345
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000346 O << directive << Name << "\n";
347 O << directive << PAN::getRetvalLabel(Name) << "\n";
348 O << directive << PAN::getArgsLabel(Name) << "\n";
349 }
350
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000351 O << MAI->getCommentString() << "Function Declarations - END." <<"\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000352}
353
354// Emit variables imported from other Modules.
355void PIC16AsmPrinter::EmitUndefinedVars(Module &M) {
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000356 std::vector<const GlobalVariable*> Items = ExternalVarDecls;
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000357 if (!Items.size()) return;
358
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000359 O << "\n" << MAI->getCommentString() << "Imported Variables - BEGIN" << "\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000360 for (unsigned j = 0; j < Items.size(); j++) {
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000361 O << MAI->getExternDirective() << Mang->getMangledName(Items[j]) << "\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000362 }
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000363 O << MAI->getCommentString() << "Imported Variables - END" << "\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000364}
365
366// Emit variables defined in this module and are available to other modules.
367void PIC16AsmPrinter::EmitDefinedVars(Module &M) {
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000368 std::vector<const GlobalVariable*> Items = ExternalVarDefs;
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000369 if (!Items.size()) return;
370
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000371 O << "\n" << MAI->getCommentString() << "Exported Variables - BEGIN" << "\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000372 for (unsigned j = 0; j < Items.size(); j++) {
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000373 O << MAI->getGlobalDirective() << Mang->getMangledName(Items[j]) << "\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000374 }
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000375 O << MAI->getCommentString() << "Exported Variables - END" << "\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000376}
377
378// Emit initialized data placed in ROM.
379void PIC16AsmPrinter::EmitRomData(Module &M) {
Sanjiv Gupta018db662009-10-16 08:58:34 +0000380 EmitSingleSection(PTOF->ROMDATASection());
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000381}
382
Sanjiv Gupta27e801c2009-10-25 08:14:11 +0000383// Emit Shared section udata.
384void PIC16AsmPrinter::EmitSharedUdata(Module &M) {
385 EmitSingleSection(PTOF->SHAREDUDATASection());
386}
387
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000388bool PIC16AsmPrinter::doFinalization(Module &M) {
Sanjiv Gupta00e8f5a2009-10-21 10:42:44 +0000389 EmitAllAutos(M);
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000390 printLibcallDecls();
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000391 DbgInfo.EndModule(M);
392 O << "\n\t" << "END\n";
393 return AsmPrinter::doFinalization(M);
394}
395
396void PIC16AsmPrinter::EmitFunctionFrame(MachineFunction &MF) {
397 const Function *F = MF.getFunction();
398 std::string FuncName = Mang->getMangledName(F);
399 const TargetData *TD = TM.getTargetData();
400 // Emit the data section name.
401 O << "\n";
Chris Lattner08e63732009-08-21 23:08:09 +0000402
Chris Lattnerc0c8d7d2010-01-16 01:17:26 +0000403 PIC16Section *fPDataSection =
404 const_cast<PIC16Section *>(getObjFileLowering().
Sanjiv Gupta00e8f5a2009-10-21 10:42:44 +0000405 SectionForFrame(CurrentFnName));
406
407 fPDataSection->setColor(getFunctionColor(F));
Chris Lattner73266f92009-08-19 05:49:37 +0000408 OutStreamer.SwitchSection(fPDataSection);
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000409
410 // Emit function frame label
411 O << PAN::getFrameLabel(CurrentFnName) << ":\n";
412
413 const Type *RetType = F->getReturnType();
414 unsigned RetSize = 0;
415 if (RetType->getTypeID() != Type::VoidTyID)
416 RetSize = TD->getTypeAllocSize(RetType);
417
418 //Emit function return value space
419 // FIXME: Do not emit RetvalLable when retsize is zero. To do this
420 // we will need to avoid printing a global directive for Retval label
421 // in emitExternandGloblas.
422 if(RetSize > 0)
423 O << PAN::getRetvalLabel(CurrentFnName) << " RES " << RetSize << "\n";
424 else
425 O << PAN::getRetvalLabel(CurrentFnName) << ": \n";
426
427 // Emit variable to hold the space for function arguments
428 unsigned ArgSize = 0;
429 for (Function::const_arg_iterator argi = F->arg_begin(),
430 arge = F->arg_end(); argi != arge ; ++argi) {
431 const Type *Ty = argi->getType();
432 ArgSize += TD->getTypeAllocSize(Ty);
433 }
434
435 O << PAN::getArgsLabel(CurrentFnName) << " RES " << ArgSize << "\n";
436
437 // Emit temporary space
438 int TempSize = PTLI->GetTmpSize();
439 if (TempSize > 0)
440 O << PAN::getTempdataLabel(CurrentFnName) << " RES " << TempSize << '\n';
441}
442
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000443
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000444void PIC16AsmPrinter::EmitInitializedDataSection(const PIC16Section *S) {
445 /// Emit Section header.
446 OutStreamer.SwitchSection(S);
447
448 std::vector<const GlobalVariable*> Items = S->Items;
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000449 for (unsigned j = 0; j < Items.size(); j++) {
450 std::string Name = Mang->getMangledName(Items[j]);
451 Constant *C = Items[j]->getInitializer();
452 int AddrSpace = Items[j]->getType()->getAddressSpace();
453 O << Name;
454 EmitGlobalConstant(C, AddrSpace);
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000455 }
Sanjiv Gupta1c138172009-10-15 10:10:43 +0000456}
457
Sanjiv Gupta018db662009-10-16 08:58:34 +0000458// Print all IDATA sections.
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000459void PIC16AsmPrinter::EmitIData(Module &M) {
Sanjiv Gupta018db662009-10-16 08:58:34 +0000460 EmitSectionList (M, PTOF->IDATASections());
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000461}
462
Sanjiv Gupta018db662009-10-16 08:58:34 +0000463void PIC16AsmPrinter::
464EmitUninitializedDataSection(const PIC16Section *S) {
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000465 const TargetData *TD = TM.getTargetData();
466 OutStreamer.SwitchSection(S);
467 std::vector<const GlobalVariable*> Items = S->Items;
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000468 for (unsigned j = 0; j < Items.size(); j++) {
469 std::string Name = Mang->getMangledName(Items[j]);
470 Constant *C = Items[j]->getInitializer();
471 const Type *Ty = C->getType();
472 unsigned Size = TD->getTypeAllocSize(Ty);
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000473 O << Name << " RES " << Size << "\n";
474 }
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000475}
476
Sanjiv Gupta018db662009-10-16 08:58:34 +0000477// Print all UDATA sections.
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000478void PIC16AsmPrinter::EmitUData(Module &M) {
Sanjiv Gupta018db662009-10-16 08:58:34 +0000479 EmitSectionList (M, PTOF->UDATASections());
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000480}
481
Sanjiv Gupta018db662009-10-16 08:58:34 +0000482// Print all USER sections.
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000483void PIC16AsmPrinter::EmitUserSections(Module &M) {
Sanjiv Gupta018db662009-10-16 08:58:34 +0000484 EmitSectionList (M, PTOF->USERSections());
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000485}
486
Sanjiv Gupta018db662009-10-16 08:58:34 +0000487// Print all AUTO sections.
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000488void PIC16AsmPrinter::EmitAllAutos(Module &M) {
Sanjiv Gupta018db662009-10-16 08:58:34 +0000489 EmitSectionList (M, PTOF->AUTOSections());
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000490}
491
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000492extern "C" void LLVMInitializePIC16AsmPrinter() {
493 RegisterAsmPrinter<PIC16AsmPrinter> X(ThePIC16Target);
494}
495
Sanjiv Gupta018db662009-10-16 08:58:34 +0000496// Emit one data section using correct section emitter based on section type.
497void PIC16AsmPrinter::EmitSingleSection(const PIC16Section *S) {
498 if (S == NULL) return;
499
500 switch (S->getType()) {
501 default: llvm_unreachable ("unknow user section type");
502 case UDATA:
503 case UDATA_SHR:
504 case UDATA_OVR:
505 EmitUninitializedDataSection(S);
506 break;
507 case IDATA:
508 case ROMDATA:
509 EmitInitializedDataSection(S);
510 break;
511 }
512}
513
514// Emit a list of sections.
515void PIC16AsmPrinter::
516EmitSectionList(Module &M, const std::vector<PIC16Section *> &SList) {
517 for (unsigned i = 0; i < SList.size(); i++) {
518 // Exclude llvm specific metadata sections.
519 if (SList[i]->getName().find("llvm.") != std::string::npos)
520 continue;
521 O << "\n";
522 EmitSingleSection(SList[i]);
523 }
524}
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000525