blob: 72f7c16c6374a6da577a0d7359c0317461468945 [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
Chris Lattnercec64dd2010-02-03 01:41:03 +000046void PIC16AsmPrinter::EmitInstruction(const MachineInstr *MI) {
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +000047 printInstruction(MI);
Chris Lattner726d3972010-02-10 00:36:00 +000048 OutStreamer.AddBlankLine();
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +000049}
50
Sanjiv Gupta00e8f5a2009-10-21 10:42:44 +000051static int getFunctionColor(const Function *F) {
52 if (F->hasSection()) {
53 std::string Sectn = F->getSection();
54 std::string StrToFind = "Overlay=";
Chris Lattner62b547a2009-10-22 03:42:27 +000055 std::string::size_type Pos = Sectn.find(StrToFind);
Sanjiv Gupta00e8f5a2009-10-21 10:42:44 +000056
57 // Retreive the color number if the key is found.
58 if (Pos != std::string::npos) {
59 Pos += StrToFind.length();
60 std::string Color = "";
61 char c = Sectn.at(Pos);
62 // A Color can only consist of digits.
63 while (c >= '0' && c<= '9') {
64 Color.append(1,c);
65 Pos++;
66 if (Pos >= Sectn.length())
67 break;
68 c = Sectn.at(Pos);
69 }
70 return atoi(Color.c_str());
71 }
72 }
73
74 // Color was not set for function, so return -1.
75 return -1;
76}
77
78// Color the Auto section of the given function.
79void PIC16AsmPrinter::ColorAutoSection(const Function *F) {
Chris Lattner0e9e07a2010-01-16 01:21:04 +000080 std::string SectionName = PAN::getAutosSectionName(CurrentFnSym->getName());
Sanjiv Gupta00e8f5a2009-10-21 10:42:44 +000081 PIC16Section* Section = PTOF->findPIC16Section(SectionName);
82 if (Section != NULL) {
83 int Color = getFunctionColor(F);
84 if (Color >= 0)
85 Section->setColor(Color);
86 }
87}
88
89
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +000090/// runOnMachineFunction - This emits the frame section, autos section and
91/// assembly for each instruction. Also takes care of function begin debug
92/// directive and file begin debug directive (if required) for the function.
93///
94bool PIC16AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +000095 // This calls the base class function required to be called at beginning
96 // of runOnMachineFunction.
97 SetupMachineFunction(MF);
98
Sanjiv Gupta00e8f5a2009-10-21 10:42:44 +000099 // Put the color information from function to its auto section.
Chris Lattner0e9e07a2010-01-16 01:21:04 +0000100 const Function *F = MF.getFunction();
Sanjiv Gupta00e8f5a2009-10-21 10:42:44 +0000101 ColorAutoSection(F);
102
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000103 // Emit the function frame (args and temps).
104 EmitFunctionFrame(MF);
105
106 DbgInfo.BeginFunction(MF);
107
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000108 // Now emit the instructions of function in its code section.
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000109 const MCSection *fCodeSection
Chris Lattner0e9e07a2010-01-16 01:21:04 +0000110 = getObjFileLowering().SectionForCode(CurrentFnSym->getName());
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000111
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000112 // Start the Code Section.
113 O << "\n";
Chris Lattner73266f92009-08-19 05:49:37 +0000114 OutStreamer.SwitchSection(fCodeSection);
Chris Lattner7f504882009-08-21 23:12:15 +0000115
116 // Emit the frame address of the function at the beginning of code.
Chris Lattner0e9e07a2010-01-16 01:21:04 +0000117 O << "\tretlw low(" << PAN::getFrameLabel(CurrentFnSym->getName()) << ")\n";
118 O << "\tretlw high(" << PAN::getFrameLabel(CurrentFnSym->getName()) << ")\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000119
120 // Emit function start label.
Chris Lattnerce409842010-01-17 21:43:43 +0000121 O << *CurrentFnSym << ":\n";
Chris Lattner7f504882009-08-21 23:12:15 +0000122
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000123 DebugLoc CurDL;
124 O << "\n";
125 // Print out code for the function.
126 for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
127 I != E; ++I) {
128
129 // Print a label for the basic block.
130 if (I != MF.begin()) {
Chris Lattnerda5fb6d2009-09-14 03:15:54 +0000131 EmitBasicBlockStart(I);
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000132 }
133
134 // Print a basic block.
135 for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
136 II != E; ++II) {
137
138 // Emit the line directive if source line changed.
139 const DebugLoc DL = II->getDebugLoc();
140 if (!DL.isUnknown() && DL != CurDL) {
141 DbgInfo.ChangeDebugLoc(MF, DL);
142 CurDL = DL;
143 }
144
145 // Print the assembly for the instruction.
Chris Lattnercec64dd2010-02-03 01:41:03 +0000146 EmitInstruction(II);
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000147 }
148 }
149
150 // Emit function end debug directives.
151 DbgInfo.EndFunction(MF);
152
153 return false; // we didn't modify anything.
154}
155
156
157// printOperand - print operand of insn.
158void PIC16AsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
159 const MachineOperand &MO = MI->getOperand(opNum);
160
161 switch (MO.getType()) {
162 case MachineOperand::MO_Register:
Sanjiv Gupta20606ae2009-12-19 08:26:25 +0000163 {
164 // For indirect load/store insns, the fsr name is printed as INDF.
165 std::string RegName = getRegisterName(MO.getReg());
166 if ((MI->getOpcode() == PIC16::load_indirect) ||
167 (MI->getOpcode() == PIC16::store_indirect))
168 {
169 RegName.replace (0, 3, "INDF");
170 }
171 O << RegName;
172 }
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000173 return;
174
175 case MachineOperand::MO_Immediate:
176 O << (int)MO.getImm();
177 return;
178
179 case MachineOperand::MO_GlobalAddress: {
Chris Lattner86974d42010-01-16 01:40:07 +0000180 MCSymbol *Sym = GetGlobalValueSymbol(MO.getGlobal());
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000181 // FIXME: currently we do not have a memcpy def coming in the module
182 // by any chance, as we do not link in those as .bc lib. So these calls
183 // are always external and it is safe to emit an extern.
Chris Lattner86974d42010-01-16 01:40:07 +0000184 if (PAN::isMemIntrinsic(Sym->getName()))
185 LibcallDecls.push_back(createESName(Sym->getName()));
Chris Lattner7f504882009-08-21 23:12:15 +0000186
Chris Lattnerce409842010-01-17 21:43:43 +0000187 O << *Sym;
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000188 break;
189 }
190 case MachineOperand::MO_ExternalSymbol: {
191 const char *Sname = MO.getSymbolName();
192
193 // If its a libcall name, record it to decls section.
Chris Lattner86974d42010-01-16 01:40:07 +0000194 if (PAN::getSymbolTag(Sname) == PAN::LIBCALL)
Chris Lattner7f504882009-08-21 23:12:15 +0000195 LibcallDecls.push_back(Sname);
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000196
197 // Record a call to intrinsic to print the extern declaration for it.
198 std::string Sym = Sname;
199 if (PAN::isMemIntrinsic(Sym)) {
200 Sym = PAN::addPrefix(Sym);
201 LibcallDecls.push_back(createESName(Sym));
202 }
Chris Lattner7f504882009-08-21 23:12:15 +0000203
Chris Lattner86974d42010-01-16 01:40:07 +0000204 O << Sym;
Chris Lattner7f504882009-08-21 23:12:15 +0000205 break;
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000206 }
207 case MachineOperand::MO_MachineBasicBlock:
Chris Lattner84d5ca92010-01-26 04:55:51 +0000208 O << *MO.getMBB()->getSymbol(OutContext);
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000209 return;
210
211 default:
212 llvm_unreachable(" Operand type not supported.");
213 }
214}
215
216/// printCCOperand - Print the cond code operand.
217///
218void PIC16AsmPrinter::printCCOperand(const MachineInstr *MI, int opNum) {
219 int CC = (int)MI->getOperand(opNum).getImm();
220 O << PIC16CondCodeToString((PIC16CC::CondCodes)CC);
221}
222
223// This function is used to sort the decls list.
224// should return true if s1 should come before s2.
225static bool is_before(const char *s1, const char *s2) {
226 return strcmp(s1, s2) <= 0;
227}
228
229// This is used by list::unique below.
230// unique will filter out duplicates if it knows them.
231static bool is_duplicate(const char *s1, const char *s2) {
232 return !strcmp(s1, s2);
233}
234
235/// printLibcallDecls - print the extern declarations for compiler
236/// intrinsics.
237///
238void PIC16AsmPrinter::printLibcallDecls() {
239 // If no libcalls used, return.
240 if (LibcallDecls.empty()) return;
241
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000242 O << MAI->getCommentString() << "External decls for libcalls - BEGIN." <<"\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000243 // Remove duplicate entries.
244 LibcallDecls.sort(is_before);
245 LibcallDecls.unique(is_duplicate);
246
247 for (std::list<const char*>::const_iterator I = LibcallDecls.begin();
248 I != LibcallDecls.end(); I++) {
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000249 O << MAI->getExternDirective() << *I << "\n";
250 O << MAI->getExternDirective() << PAN::getArgsLabel(*I) << "\n";
251 O << MAI->getExternDirective() << PAN::getRetvalLabel(*I) << "\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000252 }
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000253 O << MAI->getCommentString() << "External decls for libcalls - END." <<"\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000254}
255
Bob Wilson4901f432009-09-30 21:44:42 +0000256/// doInitialization - Perform Module level initializations here.
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000257/// One task that we do here is to sectionize all global variables.
258/// The MemSelOptimizer pass depends on the sectionizing.
259///
260bool PIC16AsmPrinter::doInitialization(Module &M) {
261 bool Result = AsmPrinter::doInitialization(M);
262
Sanjiv Gupta20606ae2009-12-19 08:26:25 +0000263 // Every asmbly contains these std headers.
264 O << "\n#include p16f1xxx.inc";
265 O << "\n#include stdmacros.inc";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000266
267 // Set the section names for all globals.
268 for (Module::global_iterator I = M.global_begin(), E = M.global_end();
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000269 I != E; ++I) {
270
271 // Record External Var Decls.
272 if (I->isDeclaration()) {
273 ExternalVarDecls.push_back(I);
274 continue;
275 }
276
277 // Record Exteranl Var Defs.
278 if (I->hasExternalLinkage() || I->hasCommonLinkage()) {
279 ExternalVarDefs.push_back(I);
280 }
281
282 // Sectionify actual data.
283 if (!I->hasAvailableExternallyLinkage()) {
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000284 const MCSection *S = getObjFileLowering().SectionForGlobal(I, Mang, TM);
285
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000286 I->setSection(((const PIC16Section *)S)->getName());
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000287 }
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000288 }
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000289
290 DbgInfo.BeginModule(M);
291 EmitFunctionDecls(M);
292 EmitUndefinedVars(M);
293 EmitDefinedVars(M);
294 EmitIData(M);
295 EmitUData(M);
296 EmitRomData(M);
Sanjiv Gupta27e801c2009-10-25 08:14:11 +0000297 EmitSharedUdata(M);
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000298 EmitUserSections(M);
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000299 return Result;
300}
301
302/// Emit extern decls for functions imported from other modules, and emit
303/// global declarations for function defined in this module and which are
304/// available to other modules.
305///
306void PIC16AsmPrinter::EmitFunctionDecls(Module &M) {
307 // Emit declarations for external functions.
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000308 O <<"\n"<<MAI->getCommentString() << "Function Declarations - BEGIN." <<"\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000309 for (Module::iterator I = M.begin(), E = M.end(); I != E; I++) {
Chris Lattner86974d42010-01-16 01:40:07 +0000310 if (I->isIntrinsic() || I->getName() == "@abort")
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000311 continue;
312
313 if (!I->isDeclaration() && !I->hasExternalLinkage())
314 continue;
315
Chris Lattner86974d42010-01-16 01:40:07 +0000316 MCSymbol *Sym = GetGlobalValueSymbol(I);
317
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000318 // Do not emit memcpy, memset, and memmove here.
319 // Calls to these routines can be generated in two ways,
320 // 1. User calling the standard lib function
321 // 2. Codegen generating these calls for llvm intrinsics.
322 // In the first case a prototype is alread availale, while in
323 // second case the call is via and externalsym and the prototype is missing.
324 // So declarations for these are currently always getting printing by
325 // tracking both kind of references in printInstrunction.
Chris Lattner86974d42010-01-16 01:40:07 +0000326 if (I->isDeclaration() && PAN::isMemIntrinsic(Sym->getName())) continue;
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000327
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000328 const char *directive = I->isDeclaration() ? MAI->getExternDirective() :
329 MAI->getGlobalDirective();
Chris Lattner7f504882009-08-21 23:12:15 +0000330
Chris Lattner86974d42010-01-16 01:40:07 +0000331 O << directive << Sym->getName() << "\n";
332 O << directive << PAN::getRetvalLabel(Sym->getName()) << "\n";
333 O << directive << PAN::getArgsLabel(Sym->getName()) << "\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000334 }
335
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000336 O << MAI->getCommentString() << "Function Declarations - END." <<"\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000337}
338
339// Emit variables imported from other Modules.
340void PIC16AsmPrinter::EmitUndefinedVars(Module &M) {
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000341 std::vector<const GlobalVariable*> Items = ExternalVarDecls;
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000342 if (!Items.size()) return;
343
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000344 O << "\n" << MAI->getCommentString() << "Imported Variables - BEGIN" << "\n";
Chris Lattnerce409842010-01-17 21:43:43 +0000345 for (unsigned j = 0; j < Items.size(); j++)
346 O << MAI->getExternDirective() << *GetGlobalValueSymbol(Items[j]) << "\n";
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000347 O << MAI->getCommentString() << "Imported Variables - END" << "\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000348}
349
350// Emit variables defined in this module and are available to other modules.
351void PIC16AsmPrinter::EmitDefinedVars(Module &M) {
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000352 std::vector<const GlobalVariable*> Items = ExternalVarDefs;
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000353 if (!Items.size()) return;
354
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000355 O << "\n" << MAI->getCommentString() << "Exported Variables - BEGIN" << "\n";
Chris Lattnerce409842010-01-17 21:43:43 +0000356 for (unsigned j = 0; j < Items.size(); j++)
357 O << MAI->getGlobalDirective() << *GetGlobalValueSymbol(Items[j]) << "\n";
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000358 O << MAI->getCommentString() << "Exported Variables - END" << "\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000359}
360
361// Emit initialized data placed in ROM.
362void PIC16AsmPrinter::EmitRomData(Module &M) {
Sanjiv Gupta018db662009-10-16 08:58:34 +0000363 EmitSingleSection(PTOF->ROMDATASection());
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000364}
365
Sanjiv Gupta27e801c2009-10-25 08:14:11 +0000366// Emit Shared section udata.
367void PIC16AsmPrinter::EmitSharedUdata(Module &M) {
368 EmitSingleSection(PTOF->SHAREDUDATASection());
369}
370
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000371bool PIC16AsmPrinter::doFinalization(Module &M) {
Sanjiv Gupta00e8f5a2009-10-21 10:42:44 +0000372 EmitAllAutos(M);
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000373 printLibcallDecls();
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000374 DbgInfo.EndModule(M);
375 O << "\n\t" << "END\n";
376 return AsmPrinter::doFinalization(M);
377}
378
379void PIC16AsmPrinter::EmitFunctionFrame(MachineFunction &MF) {
380 const Function *F = MF.getFunction();
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000381 const TargetData *TD = TM.getTargetData();
382 // Emit the data section name.
383 O << "\n";
Chris Lattner08e63732009-08-21 23:08:09 +0000384
Chris Lattnerc0c8d7d2010-01-16 01:17:26 +0000385 PIC16Section *fPDataSection =
386 const_cast<PIC16Section *>(getObjFileLowering().
Chris Lattner0e9e07a2010-01-16 01:21:04 +0000387 SectionForFrame(CurrentFnSym->getName()));
Sanjiv Gupta00e8f5a2009-10-21 10:42:44 +0000388
389 fPDataSection->setColor(getFunctionColor(F));
Chris Lattner73266f92009-08-19 05:49:37 +0000390 OutStreamer.SwitchSection(fPDataSection);
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000391
392 // Emit function frame label
Chris Lattner0e9e07a2010-01-16 01:21:04 +0000393 O << PAN::getFrameLabel(CurrentFnSym->getName()) << ":\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000394
395 const Type *RetType = F->getReturnType();
396 unsigned RetSize = 0;
397 if (RetType->getTypeID() != Type::VoidTyID)
398 RetSize = TD->getTypeAllocSize(RetType);
399
400 //Emit function return value space
401 // FIXME: Do not emit RetvalLable when retsize is zero. To do this
402 // we will need to avoid printing a global directive for Retval label
403 // in emitExternandGloblas.
404 if(RetSize > 0)
Chris Lattner0e9e07a2010-01-16 01:21:04 +0000405 O << PAN::getRetvalLabel(CurrentFnSym->getName())
406 << " RES " << RetSize << "\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000407 else
Chris Lattner0e9e07a2010-01-16 01:21:04 +0000408 O << PAN::getRetvalLabel(CurrentFnSym->getName()) << ": \n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000409
410 // Emit variable to hold the space for function arguments
411 unsigned ArgSize = 0;
412 for (Function::const_arg_iterator argi = F->arg_begin(),
413 arge = F->arg_end(); argi != arge ; ++argi) {
414 const Type *Ty = argi->getType();
415 ArgSize += TD->getTypeAllocSize(Ty);
416 }
417
Chris Lattner0e9e07a2010-01-16 01:21:04 +0000418 O << PAN::getArgsLabel(CurrentFnSym->getName()) << " RES " << ArgSize << "\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000419
420 // Emit temporary space
421 int TempSize = PTLI->GetTmpSize();
422 if (TempSize > 0)
Chris Lattner0e9e07a2010-01-16 01:21:04 +0000423 O << PAN::getTempdataLabel(CurrentFnSym->getName()) << " RES "
424 << TempSize << '\n';
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000425}
426
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000427
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000428void PIC16AsmPrinter::EmitInitializedDataSection(const PIC16Section *S) {
429 /// Emit Section header.
430 OutStreamer.SwitchSection(S);
431
432 std::vector<const GlobalVariable*> Items = S->Items;
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000433 for (unsigned j = 0; j < Items.size(); j++) {
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000434 Constant *C = Items[j]->getInitializer();
435 int AddrSpace = Items[j]->getType()->getAddressSpace();
Chris Lattnerce409842010-01-17 21:43:43 +0000436 O << *GetGlobalValueSymbol(Items[j]);
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000437 EmitGlobalConstant(C, AddrSpace);
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000438 }
Sanjiv Gupta1c138172009-10-15 10:10:43 +0000439}
440
Sanjiv Gupta018db662009-10-16 08:58:34 +0000441// Print all IDATA sections.
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000442void PIC16AsmPrinter::EmitIData(Module &M) {
Sanjiv Gupta018db662009-10-16 08:58:34 +0000443 EmitSectionList (M, PTOF->IDATASections());
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000444}
445
Sanjiv Gupta018db662009-10-16 08:58:34 +0000446void PIC16AsmPrinter::
447EmitUninitializedDataSection(const PIC16Section *S) {
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000448 const TargetData *TD = TM.getTargetData();
449 OutStreamer.SwitchSection(S);
450 std::vector<const GlobalVariable*> Items = S->Items;
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000451 for (unsigned j = 0; j < Items.size(); j++) {
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000452 Constant *C = Items[j]->getInitializer();
453 const Type *Ty = C->getType();
454 unsigned Size = TD->getTypeAllocSize(Ty);
Chris Lattnerce409842010-01-17 21:43:43 +0000455 O << *GetGlobalValueSymbol(Items[j]) << " RES " << Size << "\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000456 }
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000457}
458
Sanjiv Gupta018db662009-10-16 08:58:34 +0000459// Print all UDATA sections.
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000460void PIC16AsmPrinter::EmitUData(Module &M) {
Sanjiv Gupta018db662009-10-16 08:58:34 +0000461 EmitSectionList (M, PTOF->UDATASections());
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000462}
463
Sanjiv Gupta018db662009-10-16 08:58:34 +0000464// Print all USER sections.
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000465void PIC16AsmPrinter::EmitUserSections(Module &M) {
Sanjiv Gupta018db662009-10-16 08:58:34 +0000466 EmitSectionList (M, PTOF->USERSections());
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000467}
468
Sanjiv Gupta018db662009-10-16 08:58:34 +0000469// Print all AUTO sections.
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000470void PIC16AsmPrinter::EmitAllAutos(Module &M) {
Sanjiv Gupta018db662009-10-16 08:58:34 +0000471 EmitSectionList (M, PTOF->AUTOSections());
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000472}
473
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000474extern "C" void LLVMInitializePIC16AsmPrinter() {
475 RegisterAsmPrinter<PIC16AsmPrinter> X(ThePIC16Target);
476}
477
Sanjiv Gupta018db662009-10-16 08:58:34 +0000478// Emit one data section using correct section emitter based on section type.
479void PIC16AsmPrinter::EmitSingleSection(const PIC16Section *S) {
480 if (S == NULL) return;
481
482 switch (S->getType()) {
483 default: llvm_unreachable ("unknow user section type");
484 case UDATA:
485 case UDATA_SHR:
486 case UDATA_OVR:
487 EmitUninitializedDataSection(S);
488 break;
489 case IDATA:
490 case ROMDATA:
491 EmitInitializedDataSection(S);
492 break;
493 }
494}
495
496// Emit a list of sections.
497void PIC16AsmPrinter::
498EmitSectionList(Module &M, const std::vector<PIC16Section *> &SList) {
499 for (unsigned i = 0; i < SList.size(); i++) {
500 // Exclude llvm specific metadata sections.
501 if (SList[i]->getName().find("llvm.") != std::string::npos)
502 continue;
503 O << "\n";
504 EmitSingleSection(SList[i]);
505 }
506}
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000507