blob: 0463596b8203d8f64dcf3aeab5723d1ff2e4d193 [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 Lattner621c44d2009-08-22 20:48:53 +000038 const MCAsmInfo *T, bool V)
Chris Lattner181c7cb2009-08-22 20:56:12 +000039: AsmPrinter(O, TM, T, V), DbgInfo(O, T) {
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +000040 PTLI = static_cast<PIC16TargetLowering*>(TM.getTargetLowering());
Chris Lattnera5ef4d32009-08-22 21:43:10 +000041 PMAI = static_cast<const PIC16MCAsmInfo*>(T);
Sanjiv Guptaac2620e2009-10-15 19:26:25 +000042 PTOF = (PIC16TargetObjectFile *)&PTLI->getObjFileLowering();
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +000043}
44
45bool PIC16AsmPrinter::printMachineInstruction(const MachineInstr *MI) {
Devang Patel5450fc12009-10-06 02:19:11 +000046 processDebugLoc(MI, true);
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +000047 printInstruction(MI);
David Greeneca9b04b2009-11-13 21:34:57 +000048 if (VerboseAsm)
Chris Lattner32d4cc72009-09-09 23:14:36 +000049 EmitComments(*MI);
50 O << '\n';
Devang Patel5450fc12009-10-06 02:19:11 +000051 processDebugLoc(MI, false);
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +000052 return true;
53}
54
Sanjiv Gupta00e8f5a2009-10-21 10:42:44 +000055static int getFunctionColor(const Function *F) {
56 if (F->hasSection()) {
57 std::string Sectn = F->getSection();
58 std::string StrToFind = "Overlay=";
Chris Lattner62b547a2009-10-22 03:42:27 +000059 std::string::size_type Pos = Sectn.find(StrToFind);
Sanjiv Gupta00e8f5a2009-10-21 10:42:44 +000060
61 // Retreive the color number if the key is found.
62 if (Pos != std::string::npos) {
63 Pos += StrToFind.length();
64 std::string Color = "";
65 char c = Sectn.at(Pos);
66 // A Color can only consist of digits.
67 while (c >= '0' && c<= '9') {
68 Color.append(1,c);
69 Pos++;
70 if (Pos >= Sectn.length())
71 break;
72 c = Sectn.at(Pos);
73 }
74 return atoi(Color.c_str());
75 }
76 }
77
78 // Color was not set for function, so return -1.
79 return -1;
80}
81
82// Color the Auto section of the given function.
83void PIC16AsmPrinter::ColorAutoSection(const Function *F) {
Chris Lattner0e9e07a2010-01-16 01:21:04 +000084 std::string SectionName = PAN::getAutosSectionName(CurrentFnSym->getName());
Sanjiv Gupta00e8f5a2009-10-21 10:42:44 +000085 PIC16Section* Section = PTOF->findPIC16Section(SectionName);
86 if (Section != NULL) {
87 int Color = getFunctionColor(F);
88 if (Color >= 0)
89 Section->setColor(Color);
90 }
91}
92
93
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +000094/// runOnMachineFunction - This emits the frame section, autos section and
95/// assembly for each instruction. Also takes care of function begin debug
96/// directive and file begin debug directive (if required) for the function.
97///
98bool PIC16AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
99 this->MF = &MF;
100
101 // This calls the base class function required to be called at beginning
102 // of runOnMachineFunction.
103 SetupMachineFunction(MF);
104
Sanjiv Gupta00e8f5a2009-10-21 10:42:44 +0000105 // Put the color information from function to its auto section.
Chris Lattner0e9e07a2010-01-16 01:21:04 +0000106 const Function *F = MF.getFunction();
Sanjiv Gupta00e8f5a2009-10-21 10:42:44 +0000107 ColorAutoSection(F);
108
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000109 // Emit the function frame (args and temps).
110 EmitFunctionFrame(MF);
111
112 DbgInfo.BeginFunction(MF);
113
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000114 // Now emit the instructions of function in its code section.
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000115 const MCSection *fCodeSection
Chris Lattner0e9e07a2010-01-16 01:21:04 +0000116 = getObjFileLowering().SectionForCode(CurrentFnSym->getName());
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000117
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000118 // Start the Code Section.
119 O << "\n";
Chris Lattner73266f92009-08-19 05:49:37 +0000120 OutStreamer.SwitchSection(fCodeSection);
Chris Lattner7f504882009-08-21 23:12:15 +0000121
122 // Emit the frame address of the function at the beginning of code.
Chris Lattner0e9e07a2010-01-16 01:21:04 +0000123 O << "\tretlw low(" << PAN::getFrameLabel(CurrentFnSym->getName()) << ")\n";
124 O << "\tretlw high(" << PAN::getFrameLabel(CurrentFnSym->getName()) << ")\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000125
126 // Emit function start label.
Chris Lattnerce409842010-01-17 21:43:43 +0000127 O << *CurrentFnSym << ":\n";
Chris Lattner7f504882009-08-21 23:12:15 +0000128
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000129 DebugLoc CurDL;
130 O << "\n";
131 // Print out code for the function.
132 for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
133 I != E; ++I) {
134
135 // Print a label for the basic block.
136 if (I != MF.begin()) {
Chris Lattnerda5fb6d2009-09-14 03:15:54 +0000137 EmitBasicBlockStart(I);
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000138 }
139
140 // Print a basic block.
141 for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
142 II != E; ++II) {
143
144 // Emit the line directive if source line changed.
145 const DebugLoc DL = II->getDebugLoc();
146 if (!DL.isUnknown() && DL != CurDL) {
147 DbgInfo.ChangeDebugLoc(MF, DL);
148 CurDL = DL;
149 }
150
151 // Print the assembly for the instruction.
152 printMachineInstruction(II);
153 }
154 }
155
156 // Emit function end debug directives.
157 DbgInfo.EndFunction(MF);
158
159 return false; // we didn't modify anything.
160}
161
162
163// printOperand - print operand of insn.
164void PIC16AsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
165 const MachineOperand &MO = MI->getOperand(opNum);
166
167 switch (MO.getType()) {
168 case MachineOperand::MO_Register:
Sanjiv Gupta20606ae2009-12-19 08:26:25 +0000169 {
170 // For indirect load/store insns, the fsr name is printed as INDF.
171 std::string RegName = getRegisterName(MO.getReg());
172 if ((MI->getOpcode() == PIC16::load_indirect) ||
173 (MI->getOpcode() == PIC16::store_indirect))
174 {
175 RegName.replace (0, 3, "INDF");
176 }
177 O << RegName;
178 }
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000179 return;
180
181 case MachineOperand::MO_Immediate:
182 O << (int)MO.getImm();
183 return;
184
185 case MachineOperand::MO_GlobalAddress: {
Chris Lattner86974d42010-01-16 01:40:07 +0000186 MCSymbol *Sym = GetGlobalValueSymbol(MO.getGlobal());
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000187 // FIXME: currently we do not have a memcpy def coming in the module
188 // by any chance, as we do not link in those as .bc lib. So these calls
189 // are always external and it is safe to emit an extern.
Chris Lattner86974d42010-01-16 01:40:07 +0000190 if (PAN::isMemIntrinsic(Sym->getName()))
191 LibcallDecls.push_back(createESName(Sym->getName()));
Chris Lattner7f504882009-08-21 23:12:15 +0000192
Chris Lattnerce409842010-01-17 21:43:43 +0000193 O << *Sym;
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000194 break;
195 }
196 case MachineOperand::MO_ExternalSymbol: {
197 const char *Sname = MO.getSymbolName();
198
199 // If its a libcall name, record it to decls section.
Chris Lattner86974d42010-01-16 01:40:07 +0000200 if (PAN::getSymbolTag(Sname) == PAN::LIBCALL)
Chris Lattner7f504882009-08-21 23:12:15 +0000201 LibcallDecls.push_back(Sname);
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000202
203 // Record a call to intrinsic to print the extern declaration for it.
204 std::string Sym = Sname;
205 if (PAN::isMemIntrinsic(Sym)) {
206 Sym = PAN::addPrefix(Sym);
207 LibcallDecls.push_back(createESName(Sym));
208 }
Chris Lattner7f504882009-08-21 23:12:15 +0000209
Chris Lattner86974d42010-01-16 01:40:07 +0000210 O << Sym;
Chris Lattner7f504882009-08-21 23:12:15 +0000211 break;
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000212 }
213 case MachineOperand::MO_MachineBasicBlock:
Chris Lattnerce409842010-01-17 21:43:43 +0000214 O << *GetMBBSymbol(MO.getMBB()->getNumber());
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000215 return;
216
217 default:
218 llvm_unreachable(" Operand type not supported.");
219 }
220}
221
222/// printCCOperand - Print the cond code operand.
223///
224void PIC16AsmPrinter::printCCOperand(const MachineInstr *MI, int opNum) {
225 int CC = (int)MI->getOperand(opNum).getImm();
226 O << PIC16CondCodeToString((PIC16CC::CondCodes)CC);
227}
228
229// This function is used to sort the decls list.
230// should return true if s1 should come before s2.
231static bool is_before(const char *s1, const char *s2) {
232 return strcmp(s1, s2) <= 0;
233}
234
235// This is used by list::unique below.
236// unique will filter out duplicates if it knows them.
237static bool is_duplicate(const char *s1, const char *s2) {
238 return !strcmp(s1, s2);
239}
240
241/// printLibcallDecls - print the extern declarations for compiler
242/// intrinsics.
243///
244void PIC16AsmPrinter::printLibcallDecls() {
245 // If no libcalls used, return.
246 if (LibcallDecls.empty()) return;
247
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000248 O << MAI->getCommentString() << "External decls for libcalls - BEGIN." <<"\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000249 // Remove duplicate entries.
250 LibcallDecls.sort(is_before);
251 LibcallDecls.unique(is_duplicate);
252
253 for (std::list<const char*>::const_iterator I = LibcallDecls.begin();
254 I != LibcallDecls.end(); I++) {
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000255 O << MAI->getExternDirective() << *I << "\n";
256 O << MAI->getExternDirective() << PAN::getArgsLabel(*I) << "\n";
257 O << MAI->getExternDirective() << PAN::getRetvalLabel(*I) << "\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000258 }
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000259 O << MAI->getCommentString() << "External decls for libcalls - END." <<"\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000260}
261
Bob Wilson4901f432009-09-30 21:44:42 +0000262/// doInitialization - Perform Module level initializations here.
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000263/// One task that we do here is to sectionize all global variables.
264/// The MemSelOptimizer pass depends on the sectionizing.
265///
266bool PIC16AsmPrinter::doInitialization(Module &M) {
267 bool Result = AsmPrinter::doInitialization(M);
268
Sanjiv Gupta20606ae2009-12-19 08:26:25 +0000269 // Every asmbly contains these std headers.
270 O << "\n#include p16f1xxx.inc";
271 O << "\n#include stdmacros.inc";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000272
273 // Set the section names for all globals.
274 for (Module::global_iterator I = M.global_begin(), E = M.global_end();
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000275 I != E; ++I) {
276
277 // Record External Var Decls.
278 if (I->isDeclaration()) {
279 ExternalVarDecls.push_back(I);
280 continue;
281 }
282
283 // Record Exteranl Var Defs.
284 if (I->hasExternalLinkage() || I->hasCommonLinkage()) {
285 ExternalVarDefs.push_back(I);
286 }
287
288 // Sectionify actual data.
289 if (!I->hasAvailableExternallyLinkage()) {
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000290 const MCSection *S = getObjFileLowering().SectionForGlobal(I, Mang, TM);
291
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000292 I->setSection(((const PIC16Section *)S)->getName());
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000293 }
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000294 }
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000295
296 DbgInfo.BeginModule(M);
297 EmitFunctionDecls(M);
298 EmitUndefinedVars(M);
299 EmitDefinedVars(M);
300 EmitIData(M);
301 EmitUData(M);
302 EmitRomData(M);
Sanjiv Gupta27e801c2009-10-25 08:14:11 +0000303 EmitSharedUdata(M);
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000304 EmitUserSections(M);
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000305 return Result;
306}
307
308/// Emit extern decls for functions imported from other modules, and emit
309/// global declarations for function defined in this module and which are
310/// available to other modules.
311///
312void PIC16AsmPrinter::EmitFunctionDecls(Module &M) {
313 // Emit declarations for external functions.
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000314 O <<"\n"<<MAI->getCommentString() << "Function Declarations - BEGIN." <<"\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000315 for (Module::iterator I = M.begin(), E = M.end(); I != E; I++) {
Chris Lattner86974d42010-01-16 01:40:07 +0000316 if (I->isIntrinsic() || I->getName() == "@abort")
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000317 continue;
318
319 if (!I->isDeclaration() && !I->hasExternalLinkage())
320 continue;
321
Chris Lattner86974d42010-01-16 01:40:07 +0000322 MCSymbol *Sym = GetGlobalValueSymbol(I);
323
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000324 // Do not emit memcpy, memset, and memmove here.
325 // Calls to these routines can be generated in two ways,
326 // 1. User calling the standard lib function
327 // 2. Codegen generating these calls for llvm intrinsics.
328 // In the first case a prototype is alread availale, while in
329 // second case the call is via and externalsym and the prototype is missing.
330 // So declarations for these are currently always getting printing by
331 // tracking both kind of references in printInstrunction.
Chris Lattner86974d42010-01-16 01:40:07 +0000332 if (I->isDeclaration() && PAN::isMemIntrinsic(Sym->getName())) continue;
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000333
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000334 const char *directive = I->isDeclaration() ? MAI->getExternDirective() :
335 MAI->getGlobalDirective();
Chris Lattner7f504882009-08-21 23:12:15 +0000336
Chris Lattner86974d42010-01-16 01:40:07 +0000337 O << directive << Sym->getName() << "\n";
338 O << directive << PAN::getRetvalLabel(Sym->getName()) << "\n";
339 O << directive << PAN::getArgsLabel(Sym->getName()) << "\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000340 }
341
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000342 O << MAI->getCommentString() << "Function Declarations - END." <<"\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000343}
344
345// Emit variables imported from other Modules.
346void PIC16AsmPrinter::EmitUndefinedVars(Module &M) {
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000347 std::vector<const GlobalVariable*> Items = ExternalVarDecls;
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000348 if (!Items.size()) return;
349
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000350 O << "\n" << MAI->getCommentString() << "Imported Variables - BEGIN" << "\n";
Chris Lattnerce409842010-01-17 21:43:43 +0000351 for (unsigned j = 0; j < Items.size(); j++)
352 O << MAI->getExternDirective() << *GetGlobalValueSymbol(Items[j]) << "\n";
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000353 O << MAI->getCommentString() << "Imported Variables - END" << "\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000354}
355
356// Emit variables defined in this module and are available to other modules.
357void PIC16AsmPrinter::EmitDefinedVars(Module &M) {
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000358 std::vector<const GlobalVariable*> Items = ExternalVarDefs;
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000359 if (!Items.size()) return;
360
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000361 O << "\n" << MAI->getCommentString() << "Exported Variables - BEGIN" << "\n";
Chris Lattnerce409842010-01-17 21:43:43 +0000362 for (unsigned j = 0; j < Items.size(); j++)
363 O << MAI->getGlobalDirective() << *GetGlobalValueSymbol(Items[j]) << "\n";
Chris Lattnera5ef4d32009-08-22 21:43:10 +0000364 O << MAI->getCommentString() << "Exported Variables - END" << "\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000365}
366
367// Emit initialized data placed in ROM.
368void PIC16AsmPrinter::EmitRomData(Module &M) {
Sanjiv Gupta018db662009-10-16 08:58:34 +0000369 EmitSingleSection(PTOF->ROMDATASection());
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000370}
371
Sanjiv Gupta27e801c2009-10-25 08:14:11 +0000372// Emit Shared section udata.
373void PIC16AsmPrinter::EmitSharedUdata(Module &M) {
374 EmitSingleSection(PTOF->SHAREDUDATASection());
375}
376
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000377bool PIC16AsmPrinter::doFinalization(Module &M) {
Sanjiv Gupta00e8f5a2009-10-21 10:42:44 +0000378 EmitAllAutos(M);
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000379 printLibcallDecls();
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000380 DbgInfo.EndModule(M);
381 O << "\n\t" << "END\n";
382 return AsmPrinter::doFinalization(M);
383}
384
385void PIC16AsmPrinter::EmitFunctionFrame(MachineFunction &MF) {
386 const Function *F = MF.getFunction();
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000387 const TargetData *TD = TM.getTargetData();
388 // Emit the data section name.
389 O << "\n";
Chris Lattner08e63732009-08-21 23:08:09 +0000390
Chris Lattnerc0c8d7d2010-01-16 01:17:26 +0000391 PIC16Section *fPDataSection =
392 const_cast<PIC16Section *>(getObjFileLowering().
Chris Lattner0e9e07a2010-01-16 01:21:04 +0000393 SectionForFrame(CurrentFnSym->getName()));
Sanjiv Gupta00e8f5a2009-10-21 10:42:44 +0000394
395 fPDataSection->setColor(getFunctionColor(F));
Chris Lattner73266f92009-08-19 05:49:37 +0000396 OutStreamer.SwitchSection(fPDataSection);
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000397
398 // Emit function frame label
Chris Lattner0e9e07a2010-01-16 01:21:04 +0000399 O << PAN::getFrameLabel(CurrentFnSym->getName()) << ":\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000400
401 const Type *RetType = F->getReturnType();
402 unsigned RetSize = 0;
403 if (RetType->getTypeID() != Type::VoidTyID)
404 RetSize = TD->getTypeAllocSize(RetType);
405
406 //Emit function return value space
407 // FIXME: Do not emit RetvalLable when retsize is zero. To do this
408 // we will need to avoid printing a global directive for Retval label
409 // in emitExternandGloblas.
410 if(RetSize > 0)
Chris Lattner0e9e07a2010-01-16 01:21:04 +0000411 O << PAN::getRetvalLabel(CurrentFnSym->getName())
412 << " RES " << RetSize << "\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000413 else
Chris Lattner0e9e07a2010-01-16 01:21:04 +0000414 O << PAN::getRetvalLabel(CurrentFnSym->getName()) << ": \n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000415
416 // Emit variable to hold the space for function arguments
417 unsigned ArgSize = 0;
418 for (Function::const_arg_iterator argi = F->arg_begin(),
419 arge = F->arg_end(); argi != arge ; ++argi) {
420 const Type *Ty = argi->getType();
421 ArgSize += TD->getTypeAllocSize(Ty);
422 }
423
Chris Lattner0e9e07a2010-01-16 01:21:04 +0000424 O << PAN::getArgsLabel(CurrentFnSym->getName()) << " RES " << ArgSize << "\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000425
426 // Emit temporary space
427 int TempSize = PTLI->GetTmpSize();
428 if (TempSize > 0)
Chris Lattner0e9e07a2010-01-16 01:21:04 +0000429 O << PAN::getTempdataLabel(CurrentFnSym->getName()) << " RES "
430 << TempSize << '\n';
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000431}
432
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000433
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000434void PIC16AsmPrinter::EmitInitializedDataSection(const PIC16Section *S) {
435 /// Emit Section header.
436 OutStreamer.SwitchSection(S);
437
438 std::vector<const GlobalVariable*> Items = S->Items;
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000439 for (unsigned j = 0; j < Items.size(); j++) {
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000440 Constant *C = Items[j]->getInitializer();
441 int AddrSpace = Items[j]->getType()->getAddressSpace();
Chris Lattnerce409842010-01-17 21:43:43 +0000442 O << *GetGlobalValueSymbol(Items[j]);
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000443 EmitGlobalConstant(C, AddrSpace);
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000444 }
Sanjiv Gupta1c138172009-10-15 10:10:43 +0000445}
446
Sanjiv Gupta018db662009-10-16 08:58:34 +0000447// Print all IDATA sections.
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000448void PIC16AsmPrinter::EmitIData(Module &M) {
Sanjiv Gupta018db662009-10-16 08:58:34 +0000449 EmitSectionList (M, PTOF->IDATASections());
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000450}
451
Sanjiv Gupta018db662009-10-16 08:58:34 +0000452void PIC16AsmPrinter::
453EmitUninitializedDataSection(const PIC16Section *S) {
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000454 const TargetData *TD = TM.getTargetData();
455 OutStreamer.SwitchSection(S);
456 std::vector<const GlobalVariable*> Items = S->Items;
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000457 for (unsigned j = 0; j < Items.size(); j++) {
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000458 Constant *C = Items[j]->getInitializer();
459 const Type *Ty = C->getType();
460 unsigned Size = TD->getTypeAllocSize(Ty);
Chris Lattnerce409842010-01-17 21:43:43 +0000461 O << *GetGlobalValueSymbol(Items[j]) << " RES " << Size << "\n";
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000462 }
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000463}
464
Sanjiv Gupta018db662009-10-16 08:58:34 +0000465// Print all UDATA sections.
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000466void PIC16AsmPrinter::EmitUData(Module &M) {
Sanjiv Gupta018db662009-10-16 08:58:34 +0000467 EmitSectionList (M, PTOF->UDATASections());
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000468}
469
Sanjiv Gupta018db662009-10-16 08:58:34 +0000470// Print all USER sections.
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000471void PIC16AsmPrinter::EmitUserSections(Module &M) {
Sanjiv Gupta018db662009-10-16 08:58:34 +0000472 EmitSectionList (M, PTOF->USERSections());
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000473}
474
Sanjiv Gupta018db662009-10-16 08:58:34 +0000475// Print all AUTO sections.
Sanjiv Guptaac2620e2009-10-15 19:26:25 +0000476void PIC16AsmPrinter::EmitAllAutos(Module &M) {
Sanjiv Gupta018db662009-10-16 08:58:34 +0000477 EmitSectionList (M, PTOF->AUTOSections());
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000478}
479
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000480extern "C" void LLVMInitializePIC16AsmPrinter() {
481 RegisterAsmPrinter<PIC16AsmPrinter> X(ThePIC16Target);
482}
483
Sanjiv Gupta018db662009-10-16 08:58:34 +0000484// Emit one data section using correct section emitter based on section type.
485void PIC16AsmPrinter::EmitSingleSection(const PIC16Section *S) {
486 if (S == NULL) return;
487
488 switch (S->getType()) {
489 default: llvm_unreachable ("unknow user section type");
490 case UDATA:
491 case UDATA_SHR:
492 case UDATA_OVR:
493 EmitUninitializedDataSection(S);
494 break;
495 case IDATA:
496 case ROMDATA:
497 EmitInitializedDataSection(S);
498 break;
499 }
500}
501
502// Emit a list of sections.
503void PIC16AsmPrinter::
504EmitSectionList(Module &M, const std::vector<PIC16Section *> &SList) {
505 for (unsigned i = 0; i < SList.size(); i++) {
506 // Exclude llvm specific metadata sections.
507 if (SList[i]->getName().find("llvm.") != std::string::npos)
508 continue;
509 O << "\n";
510 EmitSingleSection(SList[i]);
511 }
512}
Sanjiv Gupta8aae07e2009-08-13 16:37:05 +0000513