blob: 3670efcc22c6c73e8f92a2c34d0d4da20ae0ca92 [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"
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +000032#include <cstring>
33using namespace llvm;
34
35#include "PIC16GenAsmWriter.inc"
36
37PIC16AsmPrinter::PIC16AsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
Chris Lattner8d2970b2010-02-02 23:37:42 +000038 MCContext &Ctx, MCStreamer &Streamer,
39 const MCAsmInfo *T)
40: AsmPrinter(O, TM, Ctx, Streamer, T), 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) {
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000100 // This calls the base class function required to be called at beginning
101 // of runOnMachineFunction.
102 SetupMachineFunction(MF);
103
Sanjiv Gupta00e8f5a2009-10-21 10:42:44 +0000104 // Put the color information from function to its auto section.
Chris Lattner0e9e07a2010-01-16 01:21:04 +0000105 const Function *F = MF.getFunction();
Sanjiv Gupta00e8f5a2009-10-21 10:42:44 +0000106 ColorAutoSection(F);
107
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000108 // Emit the function frame (args and temps).
109 EmitFunctionFrame(MF);
110
111 DbgInfo.BeginFunction(MF);
112
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000113 // Now emit the instructions of function in its code section.
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000114 const MCSection *fCodeSection
Chris Lattner0e9e07a2010-01-16 01:21:04 +0000115 = getObjFileLowering().SectionForCode(CurrentFnSym->getName());
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000116
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000117 // Start the Code Section.
118 O << "\n";
Chris Lattner73266f92009-08-19 05:49:37 +0000119 OutStreamer.SwitchSection(fCodeSection);
Chris Lattner7f504882009-08-21 23:12:15 +0000120
121 // Emit the frame address of the function at the beginning of code.
Chris Lattner0e9e07a2010-01-16 01:21:04 +0000122 O << "\tretlw low(" << PAN::getFrameLabel(CurrentFnSym->getName()) << ")\n";
123 O << "\tretlw high(" << PAN::getFrameLabel(CurrentFnSym->getName()) << ")\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000124
125 // Emit function start label.
Chris Lattnerce409842010-01-17 21:43:43 +0000126 O << *CurrentFnSym << ":\n";
Chris Lattner7f504882009-08-21 23:12:15 +0000127
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000128 DebugLoc CurDL;
129 O << "\n";
130 // Print out code for the function.
131 for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
132 I != E; ++I) {
133
134 // Print a label for the basic block.
135 if (I != MF.begin()) {
Chris Lattnerda5fb6d2009-09-14 03:15:54 +0000136 EmitBasicBlockStart(I);
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000137 }
138
139 // Print a basic block.
140 for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
141 II != E; ++II) {
142
143 // Emit the line directive if source line changed.
144 const DebugLoc DL = II->getDebugLoc();
145 if (!DL.isUnknown() && DL != CurDL) {
146 DbgInfo.ChangeDebugLoc(MF, DL);
147 CurDL = DL;
148 }
149
150 // Print the assembly for the instruction.
151 printMachineInstruction(II);
152 }
153 }
154
155 // Emit function end debug directives.
156 DbgInfo.EndFunction(MF);
157
158 return false; // we didn't modify anything.
159}
160
161
162// printOperand - print operand of insn.
163void PIC16AsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
164 const MachineOperand &MO = MI->getOperand(opNum);
165
166 switch (MO.getType()) {
167 case MachineOperand::MO_Register:
Sanjiv Gupta20606ae2009-12-19 08:26:25 +0000168 {
169 // For indirect load/store insns, the fsr name is printed as INDF.
170 std::string RegName = getRegisterName(MO.getReg());
171 if ((MI->getOpcode() == PIC16::load_indirect) ||
172 (MI->getOpcode() == PIC16::store_indirect))
173 {
174 RegName.replace (0, 3, "INDF");
175 }
176 O << RegName;
177 }
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000178 return;
179
180 case MachineOperand::MO_Immediate:
181 O << (int)MO.getImm();
182 return;
183
184 case MachineOperand::MO_GlobalAddress: {
Chris Lattner86974d42010-01-16 01:40:07 +0000185 MCSymbol *Sym = GetGlobalValueSymbol(MO.getGlobal());
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000186 // FIXME: currently we do not have a memcpy def coming in the module
187 // by any chance, as we do not link in those as .bc lib. So these calls
188 // are always external and it is safe to emit an extern.
Chris Lattner86974d42010-01-16 01:40:07 +0000189 if (PAN::isMemIntrinsic(Sym->getName()))
190 LibcallDecls.push_back(createESName(Sym->getName()));
Chris Lattner7f504882009-08-21 23:12:15 +0000191
Chris Lattnerce409842010-01-17 21:43:43 +0000192 O << *Sym;
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000193 break;
194 }
195 case MachineOperand::MO_ExternalSymbol: {
196 const char *Sname = MO.getSymbolName();
197
198 // If its a libcall name, record it to decls section.
Chris Lattner86974d42010-01-16 01:40:07 +0000199 if (PAN::getSymbolTag(Sname) == PAN::LIBCALL)
Chris Lattner7f504882009-08-21 23:12:15 +0000200 LibcallDecls.push_back(Sname);
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000201
202 // Record a call to intrinsic to print the extern declaration for it.
203 std::string Sym = Sname;
204 if (PAN::isMemIntrinsic(Sym)) {
205 Sym = PAN::addPrefix(Sym);
206 LibcallDecls.push_back(createESName(Sym));
207 }
Chris Lattner7f504882009-08-21 23:12:15 +0000208
Chris Lattner86974d42010-01-16 01:40:07 +0000209 O << Sym;
Chris Lattner7f504882009-08-21 23:12:15 +0000210 break;
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000211 }
212 case MachineOperand::MO_MachineBasicBlock:
Chris Lattner84d5ca92010-01-26 04:55:51 +0000213 O << *MO.getMBB()->getSymbol(OutContext);
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000214 return;
215
216 default:
217 llvm_unreachable(" Operand type not supported.");
218 }
219}
220
221/// printCCOperand - Print the cond code operand.
222///
223void PIC16AsmPrinter::printCCOperand(const MachineInstr *MI, int opNum) {
224 int CC = (int)MI->getOperand(opNum).getImm();
225 O << PIC16CondCodeToString((PIC16CC::CondCodes)CC);
226}
227
228// This function is used to sort the decls list.
229// should return true if s1 should come before s2.
230static bool is_before(const char *s1, const char *s2) {
231 return strcmp(s1, s2) <= 0;
232}
233
234// This is used by list::unique below.
235// unique will filter out duplicates if it knows them.
236static bool is_duplicate(const char *s1, const char *s2) {
237 return !strcmp(s1, s2);
238}
239
240/// printLibcallDecls - print the extern declarations for compiler
241/// intrinsics.
242///
243void PIC16AsmPrinter::printLibcallDecls() {
244 // If no libcalls used, return.
245 if (LibcallDecls.empty()) return;
246
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000247 O << MAI->getCommentString() << "External decls for libcalls - BEGIN." <<"\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000248 // Remove duplicate entries.
249 LibcallDecls.sort(is_before);
250 LibcallDecls.unique(is_duplicate);
251
252 for (std::list<const char*>::const_iterator I = LibcallDecls.begin();
253 I != LibcallDecls.end(); I++) {
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000254 O << MAI->getExternDirective() << *I << "\n";
255 O << MAI->getExternDirective() << PAN::getArgsLabel(*I) << "\n";
256 O << MAI->getExternDirective() << PAN::getRetvalLabel(*I) << "\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000257 }
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000258 O << MAI->getCommentString() << "External decls for libcalls - END." <<"\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000259}
260
Bob Wilson4901f432009-09-30 21:44:42 +0000261/// doInitialization - Perform Module level initializations here.
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000262/// One task that we do here is to sectionize all global variables.
263/// The MemSelOptimizer pass depends on the sectionizing.
264///
265bool PIC16AsmPrinter::doInitialization(Module &M) {
266 bool Result = AsmPrinter::doInitialization(M);
267
Sanjiv Gupta20606ae2009-12-19 08:26:25 +0000268 // Every asmbly contains these std headers.
269 O << "\n#include p16f1xxx.inc";
270 O << "\n#include stdmacros.inc";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000271
272 // Set the section names for all globals.
273 for (Module::global_iterator I = M.global_begin(), E = M.global_end();
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000274 I != E; ++I) {
275
276 // Record External Var Decls.
277 if (I->isDeclaration()) {
278 ExternalVarDecls.push_back(I);
279 continue;
280 }
281
282 // Record Exteranl Var Defs.
283 if (I->hasExternalLinkage() || I->hasCommonLinkage()) {
284 ExternalVarDefs.push_back(I);
285 }
286
287 // Sectionify actual data.
288 if (!I->hasAvailableExternallyLinkage()) {
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000289 const MCSection *S = getObjFileLowering().SectionForGlobal(I, Mang, TM);
290
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000291 I->setSection(((const PIC16Section *)S)->getName());
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000292 }
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000293 }
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000294
295 DbgInfo.BeginModule(M);
296 EmitFunctionDecls(M);
297 EmitUndefinedVars(M);
298 EmitDefinedVars(M);
299 EmitIData(M);
300 EmitUData(M);
301 EmitRomData(M);
Sanjiv Gupta27e801c2009-10-25 08:14:11 +0000302 EmitSharedUdata(M);
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000303 EmitUserSections(M);
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000304 return Result;
305}
306
307/// Emit extern decls for functions imported from other modules, and emit
308/// global declarations for function defined in this module and which are
309/// available to other modules.
310///
311void PIC16AsmPrinter::EmitFunctionDecls(Module &M) {
312 // Emit declarations for external functions.
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000313 O <<"\n"<<MAI->getCommentString() << "Function Declarations - BEGIN." <<"\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000314 for (Module::iterator I = M.begin(), E = M.end(); I != E; I++) {
Chris Lattner86974d42010-01-16 01:40:07 +0000315 if (I->isIntrinsic() || I->getName() == "@abort")
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000316 continue;
317
318 if (!I->isDeclaration() && !I->hasExternalLinkage())
319 continue;
320
Chris Lattner86974d42010-01-16 01:40:07 +0000321 MCSymbol *Sym = GetGlobalValueSymbol(I);
322
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000323 // Do not emit memcpy, memset, and memmove here.
324 // Calls to these routines can be generated in two ways,
325 // 1. User calling the standard lib function
326 // 2. Codegen generating these calls for llvm intrinsics.
327 // In the first case a prototype is alread availale, while in
328 // second case the call is via and externalsym and the prototype is missing.
329 // So declarations for these are currently always getting printing by
330 // tracking both kind of references in printInstrunction.
Chris Lattner86974d42010-01-16 01:40:07 +0000331 if (I->isDeclaration() && PAN::isMemIntrinsic(Sym->getName())) continue;
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000332
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000333 const char *directive = I->isDeclaration() ? MAI->getExternDirective() :
334 MAI->getGlobalDirective();
Chris Lattner7f504882009-08-21 23:12:15 +0000335
Chris Lattner86974d42010-01-16 01:40:07 +0000336 O << directive << Sym->getName() << "\n";
337 O << directive << PAN::getRetvalLabel(Sym->getName()) << "\n";
338 O << directive << PAN::getArgsLabel(Sym->getName()) << "\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000339 }
340
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000341 O << MAI->getCommentString() << "Function Declarations - END." <<"\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000342}
343
344// Emit variables imported from other Modules.
345void PIC16AsmPrinter::EmitUndefinedVars(Module &M) {
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000346 std::vector<const GlobalVariable*> Items = ExternalVarDecls;
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000347 if (!Items.size()) return;
348
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000349 O << "\n" << MAI->getCommentString() << "Imported Variables - BEGIN" << "\n";
Chris Lattnerce409842010-01-17 21:43:43 +0000350 for (unsigned j = 0; j < Items.size(); j++)
351 O << MAI->getExternDirective() << *GetGlobalValueSymbol(Items[j]) << "\n";
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000352 O << MAI->getCommentString() << "Imported Variables - END" << "\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000353}
354
355// Emit variables defined in this module and are available to other modules.
356void PIC16AsmPrinter::EmitDefinedVars(Module &M) {
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000357 std::vector<const GlobalVariable*> Items = ExternalVarDefs;
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000358 if (!Items.size()) return;
359
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000360 O << "\n" << MAI->getCommentString() << "Exported Variables - BEGIN" << "\n";
Chris Lattnerce409842010-01-17 21:43:43 +0000361 for (unsigned j = 0; j < Items.size(); j++)
362 O << MAI->getGlobalDirective() << *GetGlobalValueSymbol(Items[j]) << "\n";
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000363 O << MAI->getCommentString() << "Exported Variables - END" << "\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000364}
365
366// Emit initialized data placed in ROM.
367void PIC16AsmPrinter::EmitRomData(Module &M) {
Sanjiv Gupta018db662009-10-16 08:58:34 +0000368 EmitSingleSection(PTOF->ROMDATASection());
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000369}
370
Sanjiv Gupta27e801c2009-10-25 08:14:11 +0000371// Emit Shared section udata.
372void PIC16AsmPrinter::EmitSharedUdata(Module &M) {
373 EmitSingleSection(PTOF->SHAREDUDATASection());
374}
375
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000376bool PIC16AsmPrinter::doFinalization(Module &M) {
Sanjiv Gupta00e8f5a2009-10-21 10:42:44 +0000377 EmitAllAutos(M);
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000378 printLibcallDecls();
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000379 DbgInfo.EndModule(M);
380 O << "\n\t" << "END\n";
381 return AsmPrinter::doFinalization(M);
382}
383
384void PIC16AsmPrinter::EmitFunctionFrame(MachineFunction &MF) {
385 const Function *F = MF.getFunction();
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000386 const TargetData *TD = TM.getTargetData();
387 // Emit the data section name.
388 O << "\n";
Chris Lattner08e63732009-08-21 23:08:09 +0000389
Chris Lattnerc0c8d7d2010-01-16 01:17:26 +0000390 PIC16Section *fPDataSection =
391 const_cast<PIC16Section *>(getObjFileLowering().
Chris Lattner0e9e07a2010-01-16 01:21:04 +0000392 SectionForFrame(CurrentFnSym->getName()));
Sanjiv Gupta00e8f5a2009-10-21 10:42:44 +0000393
394 fPDataSection->setColor(getFunctionColor(F));
Chris Lattner73266f92009-08-19 05:49:37 +0000395 OutStreamer.SwitchSection(fPDataSection);
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000396
397 // Emit function frame label
Chris Lattner0e9e07a2010-01-16 01:21:04 +0000398 O << PAN::getFrameLabel(CurrentFnSym->getName()) << ":\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000399
400 const Type *RetType = F->getReturnType();
401 unsigned RetSize = 0;
402 if (RetType->getTypeID() != Type::VoidTyID)
403 RetSize = TD->getTypeAllocSize(RetType);
404
405 //Emit function return value space
406 // FIXME: Do not emit RetvalLable when retsize is zero. To do this
407 // we will need to avoid printing a global directive for Retval label
408 // in emitExternandGloblas.
409 if(RetSize > 0)
Chris Lattner0e9e07a2010-01-16 01:21:04 +0000410 O << PAN::getRetvalLabel(CurrentFnSym->getName())
411 << " RES " << RetSize << "\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000412 else
Chris Lattner0e9e07a2010-01-16 01:21:04 +0000413 O << PAN::getRetvalLabel(CurrentFnSym->getName()) << ": \n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000414
415 // Emit variable to hold the space for function arguments
416 unsigned ArgSize = 0;
417 for (Function::const_arg_iterator argi = F->arg_begin(),
418 arge = F->arg_end(); argi != arge ; ++argi) {
419 const Type *Ty = argi->getType();
420 ArgSize += TD->getTypeAllocSize(Ty);
421 }
422
Chris Lattner0e9e07a2010-01-16 01:21:04 +0000423 O << PAN::getArgsLabel(CurrentFnSym->getName()) << " RES " << ArgSize << "\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000424
425 // Emit temporary space
426 int TempSize = PTLI->GetTmpSize();
427 if (TempSize > 0)
Chris Lattner0e9e07a2010-01-16 01:21:04 +0000428 O << PAN::getTempdataLabel(CurrentFnSym->getName()) << " RES "
429 << TempSize << '\n';
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000430}
431
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000432
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000433void PIC16AsmPrinter::EmitInitializedDataSection(const PIC16Section *S) {
434 /// Emit Section header.
435 OutStreamer.SwitchSection(S);
436
437 std::vector<const GlobalVariable*> Items = S->Items;
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000438 for (unsigned j = 0; j < Items.size(); j++) {
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000439 Constant *C = Items[j]->getInitializer();
440 int AddrSpace = Items[j]->getType()->getAddressSpace();
Chris Lattnerce409842010-01-17 21:43:43 +0000441 O << *GetGlobalValueSymbol(Items[j]);
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000442 EmitGlobalConstant(C, AddrSpace);
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000443 }
Sanjiv Gupta1c138172009-10-15 10:10:43 +0000444}
445
Sanjiv Gupta018db662009-10-16 08:58:34 +0000446// Print all IDATA sections.
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000447void PIC16AsmPrinter::EmitIData(Module &M) {
Sanjiv Gupta018db662009-10-16 08:58:34 +0000448 EmitSectionList (M, PTOF->IDATASections());
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000449}
450
Sanjiv Gupta018db662009-10-16 08:58:34 +0000451void PIC16AsmPrinter::
452EmitUninitializedDataSection(const PIC16Section *S) {
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000453 const TargetData *TD = TM.getTargetData();
454 OutStreamer.SwitchSection(S);
455 std::vector<const GlobalVariable*> Items = S->Items;
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000456 for (unsigned j = 0; j < Items.size(); j++) {
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000457 Constant *C = Items[j]->getInitializer();
458 const Type *Ty = C->getType();
459 unsigned Size = TD->getTypeAllocSize(Ty);
Chris Lattnerce409842010-01-17 21:43:43 +0000460 O << *GetGlobalValueSymbol(Items[j]) << " RES " << Size << "\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000461 }
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000462}
463
Sanjiv Gupta018db662009-10-16 08:58:34 +0000464// Print all UDATA sections.
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000465void PIC16AsmPrinter::EmitUData(Module &M) {
Sanjiv Gupta018db662009-10-16 08:58:34 +0000466 EmitSectionList (M, PTOF->UDATASections());
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000467}
468
Sanjiv Gupta018db662009-10-16 08:58:34 +0000469// Print all USER sections.
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000470void PIC16AsmPrinter::EmitUserSections(Module &M) {
Sanjiv Gupta018db662009-10-16 08:58:34 +0000471 EmitSectionList (M, PTOF->USERSections());
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000472}
473
Sanjiv Gupta018db662009-10-16 08:58:34 +0000474// Print all AUTO sections.
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000475void PIC16AsmPrinter::EmitAllAutos(Module &M) {
Sanjiv Gupta018db662009-10-16 08:58:34 +0000476 EmitSectionList (M, PTOF->AUTOSections());
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000477}
478
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000479extern "C" void LLVMInitializePIC16AsmPrinter() {
480 RegisterAsmPrinter<PIC16AsmPrinter> X(ThePIC16Target);
481}
482
Sanjiv Gupta018db662009-10-16 08:58:34 +0000483// Emit one data section using correct section emitter based on section type.
484void PIC16AsmPrinter::EmitSingleSection(const PIC16Section *S) {
485 if (S == NULL) return;
486
487 switch (S->getType()) {
488 default: llvm_unreachable ("unknow user section type");
489 case UDATA:
490 case UDATA_SHR:
491 case UDATA_OVR:
492 EmitUninitializedDataSection(S);
493 break;
494 case IDATA:
495 case ROMDATA:
496 EmitInitializedDataSection(S);
497 break;
498 }
499}
500
501// Emit a list of sections.
502void PIC16AsmPrinter::
503EmitSectionList(Module &M, const std::vector<PIC16Section *> &SList) {
504 for (unsigned i = 0; i < SList.size(); i++) {
505 // Exclude llvm specific metadata sections.
506 if (SList[i]->getName().find("llvm.") != std::string::npos)
507 continue;
508 O << "\n";
509 EmitSingleSection(SList[i]);
510 }
511}
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000512