blob: 87f5aad02a63cdd5f6c20bb36de8573f3116ac11 [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.
131 O << CurrentFnName << ":\n";
Chris Lattner7f504882009-08-21 23:12:15 +0000132
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000133 DebugLoc CurDL;
134 O << "\n";
135 // Print out code for the function.
136 for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
137 I != E; ++I) {
138
139 // Print a label for the basic block.
140 if (I != MF.begin()) {
Chris Lattnerda5fb6d2009-09-14 03:15:54 +0000141 EmitBasicBlockStart(I);
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000142 }
143
144 // Print a basic block.
145 for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
146 II != E; ++II) {
147
148 // Emit the line directive if source line changed.
149 const DebugLoc DL = II->getDebugLoc();
150 if (!DL.isUnknown() && DL != CurDL) {
151 DbgInfo.ChangeDebugLoc(MF, DL);
152 CurDL = DL;
153 }
154
155 // Print the assembly for the instruction.
156 printMachineInstruction(II);
157 }
158 }
159
160 // Emit function end debug directives.
161 DbgInfo.EndFunction(MF);
162
163 return false; // we didn't modify anything.
164}
165
166
167// printOperand - print operand of insn.
168void PIC16AsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
169 const MachineOperand &MO = MI->getOperand(opNum);
170
171 switch (MO.getType()) {
172 case MachineOperand::MO_Register:
Sanjiv Gupta20606ae2009-12-19 08:26:25 +0000173 {
174 // For indirect load/store insns, the fsr name is printed as INDF.
175 std::string RegName = getRegisterName(MO.getReg());
176 if ((MI->getOpcode() == PIC16::load_indirect) ||
177 (MI->getOpcode() == PIC16::store_indirect))
178 {
179 RegName.replace (0, 3, "INDF");
180 }
181 O << RegName;
182 }
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000183 return;
184
185 case MachineOperand::MO_Immediate:
186 O << (int)MO.getImm();
187 return;
188
189 case MachineOperand::MO_GlobalAddress: {
190 std::string Sname = Mang->getMangledName(MO.getGlobal());
191 // FIXME: currently we do not have a memcpy def coming in the module
192 // by any chance, as we do not link in those as .bc lib. So these calls
193 // are always external and it is safe to emit an extern.
194 if (PAN::isMemIntrinsic(Sname)) {
195 LibcallDecls.push_back(createESName(Sname));
196 }
Chris Lattner7f504882009-08-21 23:12:15 +0000197
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000198 O << Sname;
199 break;
200 }
201 case MachineOperand::MO_ExternalSymbol: {
202 const char *Sname = MO.getSymbolName();
203
204 // If its a libcall name, record it to decls section.
205 if (PAN::getSymbolTag(Sname) == PAN::LIBCALL) {
Chris Lattner7f504882009-08-21 23:12:15 +0000206 LibcallDecls.push_back(Sname);
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000207 }
208
209 // Record a call to intrinsic to print the extern declaration for it.
210 std::string Sym = Sname;
211 if (PAN::isMemIntrinsic(Sym)) {
212 Sym = PAN::addPrefix(Sym);
213 LibcallDecls.push_back(createESName(Sym));
214 }
Chris Lattner7f504882009-08-21 23:12:15 +0000215
216 O << Sym;
217 break;
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000218 }
219 case MachineOperand::MO_MachineBasicBlock:
Chris Lattnerc6f802d2009-09-13 17:14:04 +0000220 GetMBBSymbol(MO.getMBB()->getNumber())->print(O, MAI);
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000221 return;
222
223 default:
224 llvm_unreachable(" Operand type not supported.");
225 }
226}
227
228/// printCCOperand - Print the cond code operand.
229///
230void PIC16AsmPrinter::printCCOperand(const MachineInstr *MI, int opNum) {
231 int CC = (int)MI->getOperand(opNum).getImm();
232 O << PIC16CondCodeToString((PIC16CC::CondCodes)CC);
233}
234
235// This function is used to sort the decls list.
236// should return true if s1 should come before s2.
237static bool is_before(const char *s1, const char *s2) {
238 return strcmp(s1, s2) <= 0;
239}
240
241// This is used by list::unique below.
242// unique will filter out duplicates if it knows them.
243static bool is_duplicate(const char *s1, const char *s2) {
244 return !strcmp(s1, s2);
245}
246
247/// printLibcallDecls - print the extern declarations for compiler
248/// intrinsics.
249///
250void PIC16AsmPrinter::printLibcallDecls() {
251 // If no libcalls used, return.
252 if (LibcallDecls.empty()) return;
253
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000254 O << MAI->getCommentString() << "External decls for libcalls - BEGIN." <<"\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000255 // Remove duplicate entries.
256 LibcallDecls.sort(is_before);
257 LibcallDecls.unique(is_duplicate);
258
259 for (std::list<const char*>::const_iterator I = LibcallDecls.begin();
260 I != LibcallDecls.end(); I++) {
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000261 O << MAI->getExternDirective() << *I << "\n";
262 O << MAI->getExternDirective() << PAN::getArgsLabel(*I) << "\n";
263 O << MAI->getExternDirective() << PAN::getRetvalLabel(*I) << "\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000264 }
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000265 O << MAI->getCommentString() << "External decls for libcalls - END." <<"\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000266}
267
Bob Wilson4901f432009-09-30 21:44:42 +0000268/// doInitialization - Perform Module level initializations here.
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000269/// One task that we do here is to sectionize all global variables.
270/// The MemSelOptimizer pass depends on the sectionizing.
271///
272bool PIC16AsmPrinter::doInitialization(Module &M) {
273 bool Result = AsmPrinter::doInitialization(M);
274
Sanjiv Gupta20606ae2009-12-19 08:26:25 +0000275 // Every asmbly contains these std headers.
276 O << "\n#include p16f1xxx.inc";
277 O << "\n#include stdmacros.inc";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000278
279 // Set the section names for all globals.
280 for (Module::global_iterator I = M.global_begin(), E = M.global_end();
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000281 I != E; ++I) {
282
283 // Record External Var Decls.
284 if (I->isDeclaration()) {
285 ExternalVarDecls.push_back(I);
286 continue;
287 }
288
289 // Record Exteranl Var Defs.
290 if (I->hasExternalLinkage() || I->hasCommonLinkage()) {
291 ExternalVarDefs.push_back(I);
292 }
293
294 // Sectionify actual data.
295 if (!I->hasAvailableExternallyLinkage()) {
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000296 const MCSection *S = getObjFileLowering().SectionForGlobal(I, Mang, TM);
297
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000298 I->setSection(((const PIC16Section *)S)->getName());
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000299 }
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000300 }
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000301
302 DbgInfo.BeginModule(M);
303 EmitFunctionDecls(M);
304 EmitUndefinedVars(M);
305 EmitDefinedVars(M);
306 EmitIData(M);
307 EmitUData(M);
308 EmitRomData(M);
Sanjiv Gupta27e801c2009-10-25 08:14:11 +0000309 EmitSharedUdata(M);
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000310 EmitUserSections(M);
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000311 return Result;
312}
313
314/// Emit extern decls for functions imported from other modules, and emit
315/// global declarations for function defined in this module and which are
316/// available to other modules.
317///
318void PIC16AsmPrinter::EmitFunctionDecls(Module &M) {
319 // Emit declarations for external functions.
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000320 O <<"\n"<<MAI->getCommentString() << "Function Declarations - BEGIN." <<"\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000321 for (Module::iterator I = M.begin(), E = M.end(); I != E; I++) {
322 if (I->isIntrinsic())
323 continue;
324
325 std::string Name = Mang->getMangledName(I);
326 if (Name.compare("@abort") == 0)
327 continue;
328
329 if (!I->isDeclaration() && !I->hasExternalLinkage())
330 continue;
331
332 // Do not emit memcpy, memset, and memmove here.
333 // Calls to these routines can be generated in two ways,
334 // 1. User calling the standard lib function
335 // 2. Codegen generating these calls for llvm intrinsics.
336 // In the first case a prototype is alread availale, while in
337 // second case the call is via and externalsym and the prototype is missing.
338 // So declarations for these are currently always getting printing by
339 // tracking both kind of references in printInstrunction.
340 if (I->isDeclaration() && PAN::isMemIntrinsic(Name)) continue;
341
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000342 const char *directive = I->isDeclaration() ? MAI->getExternDirective() :
343 MAI->getGlobalDirective();
Chris Lattner7f504882009-08-21 23:12:15 +0000344
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000345 O << directive << Name << "\n";
346 O << directive << PAN::getRetvalLabel(Name) << "\n";
347 O << directive << PAN::getArgsLabel(Name) << "\n";
348 }
349
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000350 O << MAI->getCommentString() << "Function Declarations - END." <<"\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000351}
352
353// Emit variables imported from other Modules.
354void PIC16AsmPrinter::EmitUndefinedVars(Module &M) {
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000355 std::vector<const GlobalVariable*> Items = ExternalVarDecls;
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000356 if (!Items.size()) return;
357
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000358 O << "\n" << MAI->getCommentString() << "Imported Variables - BEGIN" << "\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000359 for (unsigned j = 0; j < Items.size(); j++) {
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000360 O << MAI->getExternDirective() << Mang->getMangledName(Items[j]) << "\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000361 }
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000362 O << MAI->getCommentString() << "Imported Variables - END" << "\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000363}
364
365// Emit variables defined in this module and are available to other modules.
366void PIC16AsmPrinter::EmitDefinedVars(Module &M) {
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000367 std::vector<const GlobalVariable*> Items = ExternalVarDefs;
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000368 if (!Items.size()) return;
369
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000370 O << "\n" << MAI->getCommentString() << "Exported Variables - BEGIN" << "\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000371 for (unsigned j = 0; j < Items.size(); j++) {
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000372 O << MAI->getGlobalDirective() << Mang->getMangledName(Items[j]) << "\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000373 }
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000374 O << MAI->getCommentString() << "Exported Variables - END" << "\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000375}
376
377// Emit initialized data placed in ROM.
378void PIC16AsmPrinter::EmitRomData(Module &M) {
Sanjiv Gupta018db662009-10-16 08:58:34 +0000379 EmitSingleSection(PTOF->ROMDATASection());
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000380}
381
Sanjiv Gupta27e801c2009-10-25 08:14:11 +0000382// Emit Shared section udata.
383void PIC16AsmPrinter::EmitSharedUdata(Module &M) {
384 EmitSingleSection(PTOF->SHAREDUDATASection());
385}
386
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000387bool PIC16AsmPrinter::doFinalization(Module &M) {
Sanjiv Gupta00e8f5a2009-10-21 10:42:44 +0000388 EmitAllAutos(M);
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000389 printLibcallDecls();
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000390 DbgInfo.EndModule(M);
391 O << "\n\t" << "END\n";
392 return AsmPrinter::doFinalization(M);
393}
394
395void PIC16AsmPrinter::EmitFunctionFrame(MachineFunction &MF) {
396 const Function *F = MF.getFunction();
397 std::string FuncName = Mang->getMangledName(F);
398 const TargetData *TD = TM.getTargetData();
399 // Emit the data section name.
400 O << "\n";
Chris Lattner08e63732009-08-21 23:08:09 +0000401
Sanjiv Gupta00e8f5a2009-10-21 10:42:44 +0000402 PIC16Section *fPDataSection = const_cast<PIC16Section *>(getObjFileLowering().
403 SectionForFrame(CurrentFnName));
404
405 fPDataSection->setColor(getFunctionColor(F));
Chris Lattner73266f92009-08-19 05:49:37 +0000406 OutStreamer.SwitchSection(fPDataSection);
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000407
408 // Emit function frame label
409 O << PAN::getFrameLabel(CurrentFnName) << ":\n";
410
411 const Type *RetType = F->getReturnType();
412 unsigned RetSize = 0;
413 if (RetType->getTypeID() != Type::VoidTyID)
414 RetSize = TD->getTypeAllocSize(RetType);
415
416 //Emit function return value space
417 // FIXME: Do not emit RetvalLable when retsize is zero. To do this
418 // we will need to avoid printing a global directive for Retval label
419 // in emitExternandGloblas.
420 if(RetSize > 0)
421 O << PAN::getRetvalLabel(CurrentFnName) << " RES " << RetSize << "\n";
422 else
423 O << PAN::getRetvalLabel(CurrentFnName) << ": \n";
424
425 // Emit variable to hold the space for function arguments
426 unsigned ArgSize = 0;
427 for (Function::const_arg_iterator argi = F->arg_begin(),
428 arge = F->arg_end(); argi != arge ; ++argi) {
429 const Type *Ty = argi->getType();
430 ArgSize += TD->getTypeAllocSize(Ty);
431 }
432
433 O << PAN::getArgsLabel(CurrentFnName) << " RES " << ArgSize << "\n";
434
435 // Emit temporary space
436 int TempSize = PTLI->GetTmpSize();
437 if (TempSize > 0)
438 O << PAN::getTempdataLabel(CurrentFnName) << " RES " << TempSize << '\n';
439}
440
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000441
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000442void PIC16AsmPrinter::EmitInitializedDataSection(const PIC16Section *S) {
443 /// Emit Section header.
444 OutStreamer.SwitchSection(S);
445
446 std::vector<const GlobalVariable*> Items = S->Items;
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000447 for (unsigned j = 0; j < Items.size(); j++) {
448 std::string Name = Mang->getMangledName(Items[j]);
449 Constant *C = Items[j]->getInitializer();
450 int AddrSpace = Items[j]->getType()->getAddressSpace();
451 O << Name;
452 EmitGlobalConstant(C, AddrSpace);
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000453 }
Sanjiv Gupta1c138172009-10-15 10:10:43 +0000454}
455
Sanjiv Gupta018db662009-10-16 08:58:34 +0000456// Print all IDATA sections.
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000457void PIC16AsmPrinter::EmitIData(Module &M) {
Sanjiv Gupta018db662009-10-16 08:58:34 +0000458 EmitSectionList (M, PTOF->IDATASections());
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000459}
460
Sanjiv Gupta018db662009-10-16 08:58:34 +0000461void PIC16AsmPrinter::
462EmitUninitializedDataSection(const PIC16Section *S) {
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000463 const TargetData *TD = TM.getTargetData();
464 OutStreamer.SwitchSection(S);
465 std::vector<const GlobalVariable*> Items = S->Items;
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000466 for (unsigned j = 0; j < Items.size(); j++) {
467 std::string Name = Mang->getMangledName(Items[j]);
468 Constant *C = Items[j]->getInitializer();
469 const Type *Ty = C->getType();
470 unsigned Size = TD->getTypeAllocSize(Ty);
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000471 O << Name << " RES " << Size << "\n";
472 }
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000473}
474
Sanjiv Gupta018db662009-10-16 08:58:34 +0000475// Print all UDATA sections.
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000476void PIC16AsmPrinter::EmitUData(Module &M) {
Sanjiv Gupta018db662009-10-16 08:58:34 +0000477 EmitSectionList (M, PTOF->UDATASections());
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000478}
479
Sanjiv Gupta018db662009-10-16 08:58:34 +0000480// Print all USER sections.
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000481void PIC16AsmPrinter::EmitUserSections(Module &M) {
Sanjiv Gupta018db662009-10-16 08:58:34 +0000482 EmitSectionList (M, PTOF->USERSections());
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000483}
484
Sanjiv Gupta018db662009-10-16 08:58:34 +0000485// Print all AUTO sections.
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000486void PIC16AsmPrinter::EmitAllAutos(Module &M) {
Sanjiv Gupta018db662009-10-16 08:58:34 +0000487 EmitSectionList (M, PTOF->AUTOSections());
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000488}
489
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000490extern "C" void LLVMInitializePIC16AsmPrinter() {
491 RegisterAsmPrinter<PIC16AsmPrinter> X(ThePIC16Target);
492}
493
Sanjiv Gupta018db662009-10-16 08:58:34 +0000494// Emit one data section using correct section emitter based on section type.
495void PIC16AsmPrinter::EmitSingleSection(const PIC16Section *S) {
496 if (S == NULL) return;
497
498 switch (S->getType()) {
499 default: llvm_unreachable ("unknow user section type");
500 case UDATA:
501 case UDATA_SHR:
502 case UDATA_OVR:
503 EmitUninitializedDataSection(S);
504 break;
505 case IDATA:
506 case ROMDATA:
507 EmitInitializedDataSection(S);
508 break;
509 }
510}
511
512// Emit a list of sections.
513void PIC16AsmPrinter::
514EmitSectionList(Module &M, const std::vector<PIC16Section *> &SList) {
515 for (unsigned i = 0; i < SList.size(); i++) {
516 // Exclude llvm specific metadata sections.
517 if (SList[i]->getName().find("llvm.") != std::string::npos)
518 continue;
519 O << "\n";
520 EmitSingleSection(SList[i]);
521 }
522}
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000523