blob: 6b77bbe445932e99ed1740e89f1748ab0fdd0d18 [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) {
Chris Lattner0e9e07a2010-01-16 01:21:04 +000085 std::string SectionName = PAN::getAutosSectionName(CurrentFnSym->getName());
Sanjiv Gupta00e8f5a2009-10-21 10:42:44 +000086 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
Sanjiv Gupta00e8f5a2009-10-21 10:42:44 +0000106 // Put the color information from function to its auto section.
Chris Lattner0e9e07a2010-01-16 01:21:04 +0000107 const Function *F = MF.getFunction();
Sanjiv Gupta00e8f5a2009-10-21 10:42:44 +0000108 ColorAutoSection(F);
109
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000110 // Emit the function frame (args and temps).
111 EmitFunctionFrame(MF);
112
113 DbgInfo.BeginFunction(MF);
114
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000115 // Now emit the instructions of function in its code section.
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000116 const MCSection *fCodeSection
Chris Lattner0e9e07a2010-01-16 01:21:04 +0000117 = getObjFileLowering().SectionForCode(CurrentFnSym->getName());
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000118
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000119 // Start the Code Section.
120 O << "\n";
Chris Lattner73266f92009-08-19 05:49:37 +0000121 OutStreamer.SwitchSection(fCodeSection);
Chris Lattner7f504882009-08-21 23:12:15 +0000122
123 // Emit the frame address of the function at the beginning of code.
Chris Lattner0e9e07a2010-01-16 01:21:04 +0000124 O << "\tretlw low(" << PAN::getFrameLabel(CurrentFnSym->getName()) << ")\n";
125 O << "\tretlw high(" << PAN::getFrameLabel(CurrentFnSym->getName()) << ")\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000126
127 // Emit function start label.
Chris Lattnerc0c8d7d2010-01-16 01:17:26 +0000128 CurrentFnSym->print(O, MAI);
129 O << ":\n";
Chris Lattner7f504882009-08-21 23:12:15 +0000130
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000131 DebugLoc CurDL;
132 O << "\n";
133 // Print out code for the function.
134 for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
135 I != E; ++I) {
136
137 // Print a label for the basic block.
138 if (I != MF.begin()) {
Chris Lattnerda5fb6d2009-09-14 03:15:54 +0000139 EmitBasicBlockStart(I);
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000140 }
141
142 // Print a basic block.
143 for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
144 II != E; ++II) {
145
146 // Emit the line directive if source line changed.
147 const DebugLoc DL = II->getDebugLoc();
148 if (!DL.isUnknown() && DL != CurDL) {
149 DbgInfo.ChangeDebugLoc(MF, DL);
150 CurDL = DL;
151 }
152
153 // Print the assembly for the instruction.
154 printMachineInstruction(II);
155 }
156 }
157
158 // Emit function end debug directives.
159 DbgInfo.EndFunction(MF);
160
161 return false; // we didn't modify anything.
162}
163
164
165// printOperand - print operand of insn.
166void PIC16AsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
167 const MachineOperand &MO = MI->getOperand(opNum);
168
169 switch (MO.getType()) {
170 case MachineOperand::MO_Register:
Sanjiv Gupta20606ae2009-12-19 08:26:25 +0000171 {
172 // For indirect load/store insns, the fsr name is printed as INDF.
173 std::string RegName = getRegisterName(MO.getReg());
174 if ((MI->getOpcode() == PIC16::load_indirect) ||
175 (MI->getOpcode() == PIC16::store_indirect))
176 {
177 RegName.replace (0, 3, "INDF");
178 }
179 O << RegName;
180 }
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000181 return;
182
183 case MachineOperand::MO_Immediate:
184 O << (int)MO.getImm();
185 return;
186
187 case MachineOperand::MO_GlobalAddress: {
188 std::string Sname = Mang->getMangledName(MO.getGlobal());
189 // FIXME: currently we do not have a memcpy def coming in the module
190 // by any chance, as we do not link in those as .bc lib. So these calls
191 // are always external and it is safe to emit an extern.
192 if (PAN::isMemIntrinsic(Sname)) {
193 LibcallDecls.push_back(createESName(Sname));
194 }
Chris Lattner7f504882009-08-21 23:12:15 +0000195
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000196 O << Sname;
197 break;
198 }
199 case MachineOperand::MO_ExternalSymbol: {
200 const char *Sname = MO.getSymbolName();
201
202 // If its a libcall name, record it to decls section.
203 if (PAN::getSymbolTag(Sname) == PAN::LIBCALL) {
Chris Lattner7f504882009-08-21 23:12:15 +0000204 LibcallDecls.push_back(Sname);
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000205 }
206
207 // Record a call to intrinsic to print the extern declaration for it.
208 std::string Sym = Sname;
209 if (PAN::isMemIntrinsic(Sym)) {
210 Sym = PAN::addPrefix(Sym);
211 LibcallDecls.push_back(createESName(Sym));
212 }
Chris Lattner7f504882009-08-21 23:12:15 +0000213
214 O << Sym;
215 break;
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000216 }
217 case MachineOperand::MO_MachineBasicBlock:
Chris Lattnerc6f802d2009-09-13 17:14:04 +0000218 GetMBBSymbol(MO.getMBB()->getNumber())->print(O, MAI);
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000219 return;
220
221 default:
222 llvm_unreachable(" Operand type not supported.");
223 }
224}
225
226/// printCCOperand - Print the cond code operand.
227///
228void PIC16AsmPrinter::printCCOperand(const MachineInstr *MI, int opNum) {
229 int CC = (int)MI->getOperand(opNum).getImm();
230 O << PIC16CondCodeToString((PIC16CC::CondCodes)CC);
231}
232
233// This function is used to sort the decls list.
234// should return true if s1 should come before s2.
235static bool is_before(const char *s1, const char *s2) {
236 return strcmp(s1, s2) <= 0;
237}
238
239// This is used by list::unique below.
240// unique will filter out duplicates if it knows them.
241static bool is_duplicate(const char *s1, const char *s2) {
242 return !strcmp(s1, s2);
243}
244
245/// printLibcallDecls - print the extern declarations for compiler
246/// intrinsics.
247///
248void PIC16AsmPrinter::printLibcallDecls() {
249 // If no libcalls used, return.
250 if (LibcallDecls.empty()) return;
251
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000252 O << MAI->getCommentString() << "External decls for libcalls - BEGIN." <<"\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000253 // Remove duplicate entries.
254 LibcallDecls.sort(is_before);
255 LibcallDecls.unique(is_duplicate);
256
257 for (std::list<const char*>::const_iterator I = LibcallDecls.begin();
258 I != LibcallDecls.end(); I++) {
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000259 O << MAI->getExternDirective() << *I << "\n";
260 O << MAI->getExternDirective() << PAN::getArgsLabel(*I) << "\n";
261 O << MAI->getExternDirective() << PAN::getRetvalLabel(*I) << "\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000262 }
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000263 O << MAI->getCommentString() << "External decls for libcalls - END." <<"\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000264}
265
Bob Wilson4901f432009-09-30 21:44:42 +0000266/// doInitialization - Perform Module level initializations here.
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000267/// One task that we do here is to sectionize all global variables.
268/// The MemSelOptimizer pass depends on the sectionizing.
269///
270bool PIC16AsmPrinter::doInitialization(Module &M) {
271 bool Result = AsmPrinter::doInitialization(M);
272
Sanjiv Gupta20606ae2009-12-19 08:26:25 +0000273 // Every asmbly contains these std headers.
274 O << "\n#include p16f1xxx.inc";
275 O << "\n#include stdmacros.inc";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000276
277 // Set the section names for all globals.
278 for (Module::global_iterator I = M.global_begin(), E = M.global_end();
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000279 I != E; ++I) {
280
281 // Record External Var Decls.
282 if (I->isDeclaration()) {
283 ExternalVarDecls.push_back(I);
284 continue;
285 }
286
287 // Record Exteranl Var Defs.
288 if (I->hasExternalLinkage() || I->hasCommonLinkage()) {
289 ExternalVarDefs.push_back(I);
290 }
291
292 // Sectionify actual data.
293 if (!I->hasAvailableExternallyLinkage()) {
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000294 const MCSection *S = getObjFileLowering().SectionForGlobal(I, Mang, TM);
295
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000296 I->setSection(((const PIC16Section *)S)->getName());
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000297 }
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000298 }
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000299
300 DbgInfo.BeginModule(M);
301 EmitFunctionDecls(M);
302 EmitUndefinedVars(M);
303 EmitDefinedVars(M);
304 EmitIData(M);
305 EmitUData(M);
306 EmitRomData(M);
Sanjiv Gupta27e801c2009-10-25 08:14:11 +0000307 EmitSharedUdata(M);
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000308 EmitUserSections(M);
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000309 return Result;
310}
311
312/// Emit extern decls for functions imported from other modules, and emit
313/// global declarations for function defined in this module and which are
314/// available to other modules.
315///
316void PIC16AsmPrinter::EmitFunctionDecls(Module &M) {
317 // Emit declarations for external functions.
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000318 O <<"\n"<<MAI->getCommentString() << "Function Declarations - BEGIN." <<"\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000319 for (Module::iterator I = M.begin(), E = M.end(); I != E; I++) {
320 if (I->isIntrinsic())
321 continue;
322
323 std::string Name = Mang->getMangledName(I);
324 if (Name.compare("@abort") == 0)
325 continue;
326
327 if (!I->isDeclaration() && !I->hasExternalLinkage())
328 continue;
329
330 // Do not emit memcpy, memset, and memmove here.
331 // Calls to these routines can be generated in two ways,
332 // 1. User calling the standard lib function
333 // 2. Codegen generating these calls for llvm intrinsics.
334 // In the first case a prototype is alread availale, while in
335 // second case the call is via and externalsym and the prototype is missing.
336 // So declarations for these are currently always getting printing by
337 // tracking both kind of references in printInstrunction.
338 if (I->isDeclaration() && PAN::isMemIntrinsic(Name)) continue;
339
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000340 const char *directive = I->isDeclaration() ? MAI->getExternDirective() :
341 MAI->getGlobalDirective();
Chris Lattner7f504882009-08-21 23:12:15 +0000342
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000343 O << directive << Name << "\n";
344 O << directive << PAN::getRetvalLabel(Name) << "\n";
345 O << directive << PAN::getArgsLabel(Name) << "\n";
346 }
347
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000348 O << MAI->getCommentString() << "Function Declarations - END." <<"\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000349}
350
351// Emit variables imported from other Modules.
352void PIC16AsmPrinter::EmitUndefinedVars(Module &M) {
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000353 std::vector<const GlobalVariable*> Items = ExternalVarDecls;
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000354 if (!Items.size()) return;
355
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000356 O << "\n" << MAI->getCommentString() << "Imported Variables - BEGIN" << "\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000357 for (unsigned j = 0; j < Items.size(); j++) {
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000358 O << MAI->getExternDirective() << Mang->getMangledName(Items[j]) << "\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000359 }
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000360 O << MAI->getCommentString() << "Imported Variables - END" << "\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000361}
362
363// Emit variables defined in this module and are available to other modules.
364void PIC16AsmPrinter::EmitDefinedVars(Module &M) {
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000365 std::vector<const GlobalVariable*> Items = ExternalVarDefs;
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000366 if (!Items.size()) return;
367
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000368 O << "\n" << MAI->getCommentString() << "Exported Variables - BEGIN" << "\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000369 for (unsigned j = 0; j < Items.size(); j++) {
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000370 O << MAI->getGlobalDirective() << Mang->getMangledName(Items[j]) << "\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000371 }
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000372 O << MAI->getCommentString() << "Exported Variables - END" << "\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000373}
374
375// Emit initialized data placed in ROM.
376void PIC16AsmPrinter::EmitRomData(Module &M) {
Sanjiv Gupta018db662009-10-16 08:58:34 +0000377 EmitSingleSection(PTOF->ROMDATASection());
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000378}
379
Sanjiv Gupta27e801c2009-10-25 08:14:11 +0000380// Emit Shared section udata.
381void PIC16AsmPrinter::EmitSharedUdata(Module &M) {
382 EmitSingleSection(PTOF->SHAREDUDATASection());
383}
384
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000385bool PIC16AsmPrinter::doFinalization(Module &M) {
Sanjiv Gupta00e8f5a2009-10-21 10:42:44 +0000386 EmitAllAutos(M);
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000387 printLibcallDecls();
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000388 DbgInfo.EndModule(M);
389 O << "\n\t" << "END\n";
390 return AsmPrinter::doFinalization(M);
391}
392
393void PIC16AsmPrinter::EmitFunctionFrame(MachineFunction &MF) {
394 const Function *F = MF.getFunction();
395 std::string FuncName = Mang->getMangledName(F);
396 const TargetData *TD = TM.getTargetData();
397 // Emit the data section name.
398 O << "\n";
Chris Lattner08e63732009-08-21 23:08:09 +0000399
Chris Lattnerc0c8d7d2010-01-16 01:17:26 +0000400 PIC16Section *fPDataSection =
401 const_cast<PIC16Section *>(getObjFileLowering().
Chris Lattner0e9e07a2010-01-16 01:21:04 +0000402 SectionForFrame(CurrentFnSym->getName()));
Sanjiv Gupta00e8f5a2009-10-21 10:42:44 +0000403
404 fPDataSection->setColor(getFunctionColor(F));
Chris Lattner73266f92009-08-19 05:49:37 +0000405 OutStreamer.SwitchSection(fPDataSection);
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000406
407 // Emit function frame label
Chris Lattner0e9e07a2010-01-16 01:21:04 +0000408 O << PAN::getFrameLabel(CurrentFnSym->getName()) << ":\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000409
410 const Type *RetType = F->getReturnType();
411 unsigned RetSize = 0;
412 if (RetType->getTypeID() != Type::VoidTyID)
413 RetSize = TD->getTypeAllocSize(RetType);
414
415 //Emit function return value space
416 // FIXME: Do not emit RetvalLable when retsize is zero. To do this
417 // we will need to avoid printing a global directive for Retval label
418 // in emitExternandGloblas.
419 if(RetSize > 0)
Chris Lattner0e9e07a2010-01-16 01:21:04 +0000420 O << PAN::getRetvalLabel(CurrentFnSym->getName())
421 << " RES " << RetSize << "\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000422 else
Chris Lattner0e9e07a2010-01-16 01:21:04 +0000423 O << PAN::getRetvalLabel(CurrentFnSym->getName()) << ": \n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000424
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
Chris Lattner0e9e07a2010-01-16 01:21:04 +0000433 O << PAN::getArgsLabel(CurrentFnSym->getName()) << " RES " << ArgSize << "\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000434
435 // Emit temporary space
436 int TempSize = PTLI->GetTmpSize();
437 if (TempSize > 0)
Chris Lattner0e9e07a2010-01-16 01:21:04 +0000438 O << PAN::getTempdataLabel(CurrentFnSym->getName()) << " RES "
439 << TempSize << '\n';
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000440}
441
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000442
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000443void PIC16AsmPrinter::EmitInitializedDataSection(const PIC16Section *S) {
444 /// Emit Section header.
445 OutStreamer.SwitchSection(S);
446
447 std::vector<const GlobalVariable*> Items = S->Items;
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000448 for (unsigned j = 0; j < Items.size(); j++) {
449 std::string Name = Mang->getMangledName(Items[j]);
450 Constant *C = Items[j]->getInitializer();
451 int AddrSpace = Items[j]->getType()->getAddressSpace();
452 O << Name;
453 EmitGlobalConstant(C, AddrSpace);
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000454 }
Sanjiv Gupta1c138172009-10-15 10:10:43 +0000455}
456
Sanjiv Gupta018db662009-10-16 08:58:34 +0000457// Print all IDATA sections.
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000458void PIC16AsmPrinter::EmitIData(Module &M) {
Sanjiv Gupta018db662009-10-16 08:58:34 +0000459 EmitSectionList (M, PTOF->IDATASections());
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000460}
461
Sanjiv Gupta018db662009-10-16 08:58:34 +0000462void PIC16AsmPrinter::
463EmitUninitializedDataSection(const PIC16Section *S) {
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000464 const TargetData *TD = TM.getTargetData();
465 OutStreamer.SwitchSection(S);
466 std::vector<const GlobalVariable*> Items = S->Items;
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000467 for (unsigned j = 0; j < Items.size(); j++) {
468 std::string Name = Mang->getMangledName(Items[j]);
469 Constant *C = Items[j]->getInitializer();
470 const Type *Ty = C->getType();
471 unsigned Size = TD->getTypeAllocSize(Ty);
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000472 O << Name << " RES " << Size << "\n";
473 }
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000474}
475
Sanjiv Gupta018db662009-10-16 08:58:34 +0000476// Print all UDATA sections.
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000477void PIC16AsmPrinter::EmitUData(Module &M) {
Sanjiv Gupta018db662009-10-16 08:58:34 +0000478 EmitSectionList (M, PTOF->UDATASections());
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000479}
480
Sanjiv Gupta018db662009-10-16 08:58:34 +0000481// Print all USER sections.
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000482void PIC16AsmPrinter::EmitUserSections(Module &M) {
Sanjiv Gupta018db662009-10-16 08:58:34 +0000483 EmitSectionList (M, PTOF->USERSections());
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000484}
485
Sanjiv Gupta018db662009-10-16 08:58:34 +0000486// Print all AUTO sections.
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000487void PIC16AsmPrinter::EmitAllAutos(Module &M) {
Sanjiv Gupta018db662009-10-16 08:58:34 +0000488 EmitSectionList (M, PTOF->AUTOSections());
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000489}
490
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000491extern "C" void LLVMInitializePIC16AsmPrinter() {
492 RegisterAsmPrinter<PIC16AsmPrinter> X(ThePIC16Target);
493}
494
Sanjiv Gupta018db662009-10-16 08:58:34 +0000495// Emit one data section using correct section emitter based on section type.
496void PIC16AsmPrinter::EmitSingleSection(const PIC16Section *S) {
497 if (S == NULL) return;
498
499 switch (S->getType()) {
500 default: llvm_unreachable ("unknow user section type");
501 case UDATA:
502 case UDATA_SHR:
503 case UDATA_OVR:
504 EmitUninitializedDataSection(S);
505 break;
506 case IDATA:
507 case ROMDATA:
508 EmitInitializedDataSection(S);
509 break;
510 }
511}
512
513// Emit a list of sections.
514void PIC16AsmPrinter::
515EmitSectionList(Module &M, const std::vector<PIC16Section *> &SList) {
516 for (unsigned i = 0; i < SList.size(); i++) {
517 // Exclude llvm specific metadata sections.
518 if (SList[i]->getName().find("llvm.") != std::string::npos)
519 continue;
520 O << "\n";
521 EmitSingleSection(SList[i]);
522 }
523}
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000524