llvm.org GIT mirror llvm / 35a27c8
revert r79562 + r79563 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@79690 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Lattner 10 years ago
10 changed file(s) with 280 addition(s) and 533 deletion(s). Raw diff Collapse all Expand all
3838 PTLI = static_cast(TM.getTargetLowering());
3939 PTAI = static_cast(T);
4040 PTOF = (PIC16TargetObjectFile*)&PTLI->getObjFileLowering();
41 CurrentFnPtr = NULL;
4241 }
4342
4443 bool PIC16AsmPrinter::printMachineInstruction(const MachineInstr *MI) {
6059 // Get the mangled name.
6160 const Function *F = MF.getFunction();
6261 CurrentFnName = Mang->getMangledName(F);
63 CurrentFnPtr = F;
64
65 // Current function name was mangled in llvm-ld for both
66 // MainLine and InterruptLine and should be demangled here
67 PAN::updateCallLineSymbol(CurrentFnName, CurrentFnPtr);
6862
6963 // Emit the function frame (args and temps).
7064 EmitFunctionFrame(MF);
7670
7771 // Now emit the instructions of function in its code section.
7872 const MCSection *fCodeSection =
79 getObjFileLowering().getSectionForFunction(CurrentFnName,
80 PAN::isISR(F));
73 getObjFileLowering().getSectionForFunction(CurrentFnName);
8174 // Start the Code Section.
8275 O << "\n";
8376 OutStreamer.SwitchSection(fCodeSection);
84
85 // If it is not an interrupt function then emit the data address
86 // retrieval code in function code itself.
87 if (!(PAN::isISR(F))) {
88 // Emit the frame address of the function at the beginning of code.
89 O << "\tretlw low(" << PAN::getFrameLabel(CurrentFnName) << ")\n";
90 O << "\tretlw high(" << PAN::getFrameLabel(CurrentFnName) << ")\n";
91 }
77
78 // Emit the frame address of the function at the beginning of code.
79 O << "\tretlw low(" << PAN::getFrameLabel(CurrentFnName) << ")\n";
80 O << "\tretlw high(" << PAN::getFrameLabel(CurrentFnName) << ")\n";
9281
9382 // Emit function start label.
9483 O << CurrentFnName << ":\n";
95
84
9685 DebugLoc CurDL;
9786 O << "\n";
9887 // Print out code for the function.
152141 if (PAN::isMemIntrinsic(Sname)) {
153142 LibcallDecls.push_back(createESName(Sname));
154143 }
155 // All the call sites were mangled in llvm-ld pass hence the
156 // operands for call instructions should be demangled here.
157 PAN::updateCallLineSymbol(Sname, CurrentFnPtr);
144
158145 O << Sname;
159146 break;
160147 }
163150
164151 // If its a libcall name, record it to decls section.
165152 if (PAN::getSymbolTag(Sname) == PAN::LIBCALL) {
166 // LibCallDecls for InterruptLine functions should have ".IL" suffix
167 const char *NewName= PAN::getUpdatedLibCallDecl(Sname, CurrentFnPtr);
168 LibcallDecls.push_back(NewName);
153 LibcallDecls.push_back(Sname);
169154 }
170155
171156 // Record a call to intrinsic to print the extern declaration for it.
174159 Sym = PAN::addPrefix(Sym);
175160 LibcallDecls.push_back(createESName(Sym));
176161 }
177 // Update the library call symbols. Library calls to InterruptLine
178 // functions are different. (They have ".IL" in their names)
179 // Also other symbols (frame and temp) for the cloned function
180 // should be updated here.
181 PAN::updateCallLineSymbol(Sym, CurrentFnPtr);
182 O << Sym;
183 break;
162
163 O << Sym;
164 break;
184165 }
185166 case MachineOperand::MO_MachineBasicBlock:
186167 printBasicBlockLabel(MO.getMBB());
292273
293274 const char *directive = I->isDeclaration() ? TAI->getExternDirective() :
294275 TAI->getGlobalDirective();
295
296 // This is called in initialization. Hence information of the current
297 // function line is not available. Hence UnspecifiedLine. UnspecifiedLine
298 // will be treated as MainLine.
299 PAN::updateCallLineSymbol(Name, PAN::UnspecifiedLine);
276
300277 O << directive << Name << "\n";
301278 O << directive << PAN::getRetvalLabel(Name) << "\n";
302279 O << directive << PAN::getArgsLabel(Name) << "\n";
445422
446423 // Now print Autos section for this function.
447424 std::string SectionName = PAN::getAutosSectionName(FunctName);
448
449 // If this function is a cloned function then the name of auto section
450 // will not be present in the list of existing section. Hence this section
451 // should be cloned.
452 // This function will check and clone
453 PTOF->createClonedSectionForAutos(SectionName);
454
455425 const std::vector &AutosSections = PTOF->AutosSections;
456426 for (unsigned i = 0; i < AutosSections.size(); i++) {
457427 O << "\n";
465435 Constant *C = Items[j]->getInitializer();
466436 const Type *Ty = C->getType();
467437 unsigned Size = TD->getTypeAllocSize(Ty);
468 // Auto variables should be cloned for the cloned function
469 PAN::updateCallLineAutos(VarName, CurrentFnName);
470438 // Emit memory reserve directive.
471439 O << VarName << " RES " << Size << "\n";
472440 }
7272 PIC16DbgInfo DbgInfo;
7373 const PIC16TargetAsmInfo *PTAI;
7474 std::list LibcallDecls; // List of extern decls.
75 const Function *CurrentFnPtr; // Hold the pointer to current Function
7675 };
7776 } // end of namespace
7877
1616 PIC16GenDAGISel.inc PIC16GenCallingConv.inc \
1717 PIC16GenSubtarget.inc
1818
19 DIRS = AsmPrinter TargetInfo PIC16Passes
19 DIRS = AsmPrinter TargetInfo
2020
2121 include $(LEVEL)/Makefile.common
2222
2121 #include
2222 #include
2323 #include
24 #include "PIC16PAN.h"
2524
2625 namespace llvm {
2726 class PIC16TargetMachine;
4342 UGE
4443 };
4544 }
45 // A Central class to manage all ABI naming conventions.
46 // PAN - [P]ic16 [A]BI [N]ames
47 class PAN {
48 public:
49 // Map the name of the symbol to its section name.
50 // Current ABI:
51 // -----------------------------------------------------
52 // ALL Names are prefixed with the symobl '@'.
53 // ------------------------------------------------------
54 // Global variables do not have any '.' in their names.
55 // These are maily function names and global variable names.
56 // Example - @foo, @i
57 // -------------------------------------------------------
58 // Functions and auto variables.
59 // Names are mangled as ..
60 // Where is '@' and is any one of
61 // the following
62 // .auto. - an automatic var of a function.
63 // .temp. - temproray data of a function.
64 // .ret. - return value label for a function.
65 // .frame. - Frame label for a function where retval, args
66 // and temps are stored.
67 // .args. - Label used to pass arguments to a direct call.
68 // Example - Function name: @foo
69 // Its frame: @foo.frame.
70 // Its retval: @foo.ret.
71 // Its local vars: @foo.auto.a
72 // Its temp data: @foo.temp.
73 // Its arg passing: @foo.args.
74 //----------------------------------------------
75 // Libcall - compiler generated libcall names must start with .lib.
76 // This id will be used to emit extern decls for libcalls.
77 // Example - libcall name: @.lib.sra.i8
78 // To pass args: @.lib.sra.i8.args.
79 // To return val: @.lib.sra.i8.ret.
80 //----------------------------------------------
81 // SECTION Names
82 // uninitialized globals - @udata..#
83 // initialized globals - @idata..#
84 // Function frame - @.frame_section.
85 // Function autos - @.autos_section.
86 // Declarations - Enclosed in comments. No section for them.
87 //----------------------------------------------------------
88
89 // Tags used to mangle different names.
90 enum TAGS {
91 PREFIX_SYMBOL,
92 GLOBAL,
93 STATIC_LOCAL,
94 AUTOS_LABEL,
95 FRAME_LABEL,
96 RET_LABEL,
97 ARGS_LABEL,
98 TEMPS_LABEL,
99
100 LIBCALL,
101
102 FRAME_SECTION,
103 AUTOS_SECTION,
104 CODE_SECTION
105 };
106
107 // Textual names of the tags.
108 inline static const char *getTagName(TAGS tag) {
109 switch (tag) {
110 default: return "";
111 case PREFIX_SYMBOL: return "@";
112 case AUTOS_LABEL: return ".auto.";
113 case FRAME_LABEL: return ".frame.";
114 case TEMPS_LABEL: return ".temp.";
115 case ARGS_LABEL: return ".args.";
116 case RET_LABEL: return ".ret.";
117 case LIBCALL: return ".lib.";
118 case FRAME_SECTION: return ".frame_section.";
119 case AUTOS_SECTION: return ".autos_section.";
120 case CODE_SECTION: return ".code_section.";
121 }
122 }
123
124 // Get tag type for the Symbol.
125 inline static TAGS getSymbolTag(const std::string &Sym) {
126 if (Sym.find(getTagName(TEMPS_LABEL)) != std::string::npos)
127 return TEMPS_LABEL;
128
129 if (Sym.find(getTagName(FRAME_LABEL)) != std::string::npos)
130 return FRAME_LABEL;
131
132 if (Sym.find(getTagName(RET_LABEL)) != std::string::npos)
133 return RET_LABEL;
134
135 if (Sym.find(getTagName(ARGS_LABEL)) != std::string::npos)
136 return ARGS_LABEL;
137
138 if (Sym.find(getTagName(AUTOS_LABEL)) != std::string::npos)
139 return AUTOS_LABEL;
140
141 if (Sym.find(getTagName(LIBCALL)) != std::string::npos)
142 return LIBCALL;
143
144 // It does not have any Tag. So its a true global or static local.
145 if (Sym.find(".") == std::string::npos)
146 return GLOBAL;
147
148 // If a . is there, then it may be static local.
149 // We should mangle these as well in clang.
150 if (Sym.find(".") != std::string::npos)
151 return STATIC_LOCAL;
152
153 assert (0 && "Could not determine Symbol's tag");
154 return PREFIX_SYMBOL; // Silence warning when assertions are turned off.
155 }
156
157 // addPrefix - add prefix symbol to a name if there isn't one already.
158 inline static std::string addPrefix (const std::string &Name) {
159 std::string prefix = getTagName (PREFIX_SYMBOL);
160
161 // If this name already has a prefix, nothing to do.
162 if (Name.compare(0, prefix.size(), prefix) == 0)
163 return Name;
164
165 return prefix + Name;
166 }
167
168 // Get mangled func name from a mangled sym name.
169 // In all cases func name is the first component before a '.'.
170 static inline std::string getFuncNameForSym(const std::string &Sym1) {
171 assert (getSymbolTag(Sym1) != GLOBAL && "not belongs to a function");
172
173 std::string Sym = addPrefix(Sym1);
174
175 // Position of the . after func name. That's where func name ends.
176 size_t func_name_end = Sym.find ('.');
177
178 return Sym.substr (0, func_name_end);
179 }
180
181 // Get Frame start label for a func.
182 static std::string getFrameLabel(const std::string &Func) {
183 std::string Func1 = addPrefix(Func);
184 std::string tag = getTagName(FRAME_LABEL);
185 return Func1 + tag;
186 }
187
188 static std::string getRetvalLabel(const std::string &Func) {
189 std::string Func1 = addPrefix(Func);
190 std::string tag = getTagName(RET_LABEL);
191 return Func1 + tag;
192 }
193
194 static std::string getArgsLabel(const std::string &Func) {
195 std::string Func1 = addPrefix(Func);
196 std::string tag = getTagName(ARGS_LABEL);
197 return Func1 + tag;
198 }
199
200 static std::string getTempdataLabel(const std::string &Func) {
201 std::string Func1 = addPrefix(Func);
202 std::string tag = getTagName(TEMPS_LABEL);
203 return Func1 + tag;
204 }
205
206 static std::string getFrameSectionName(const std::string &Func) {
207 std::string Func1 = addPrefix(Func);
208 std::string tag = getTagName(FRAME_SECTION);
209 return Func1 + tag + "# UDATA_OVR";
210 }
211
212 static std::string getAutosSectionName(const std::string &Func) {
213 std::string Func1 = addPrefix(Func);
214 std::string tag = getTagName(AUTOS_SECTION);
215 return Func1 + tag + "# UDATA_OVR";
216 }
217
218 static std::string getCodeSectionName(const std::string &Func) {
219 std::string Func1 = addPrefix(Func);
220 std::string tag = getTagName(CODE_SECTION);
221 return Func1 + tag + "# CODE";
222 }
223
224 // udata, romdata and idata section names are generated by a given number.
225 // @udata..#
226 static std::string getUdataSectionName(unsigned num,
227 std::string prefix = "") {
228 std::ostringstream o;
229 o << getTagName(PREFIX_SYMBOL) << prefix << "udata." << num
230 << ".# UDATA";
231 return o.str();
232 }
233
234 static std::string getRomdataSectionName(unsigned num,
235 std::string prefix = "") {
236 std::ostringstream o;
237 o << getTagName(PREFIX_SYMBOL) << prefix << "romdata." << num
238 << ".# ROMDATA";
239 return o.str();
240 }
241
242 static std::string getIdataSectionName(unsigned num,
243 std::string prefix = "") {
244 std::ostringstream o;
245 o << getTagName(PREFIX_SYMBOL) << prefix << "idata." << num
246 << ".# IDATA";
247 return o.str();
248 }
249
250 inline static bool isLocalName (const std::string &Name) {
251 if (getSymbolTag(Name) == AUTOS_LABEL)
252 return true;
253
254 return false;
255 }
256
257 inline static bool isMemIntrinsic (const std::string &Name) {
258 if (Name.compare("@memcpy") == 0 || Name.compare("@memset") == 0 ||
259 Name.compare("@memmove") == 0) {
260 return true;
261 }
262
263 return false;
264 }
265
266 inline static bool isLocalToFunc (std::string &Func, std::string &Var) {
267 if (! isLocalName(Var)) return false;
268
269 std::string Func1 = addPrefix(Func);
270 // Extract func name of the varilable.
271 const std::string &fname = getFuncNameForSym(Var);
272
273 if (fname.compare(Func1) == 0)
274 return true;
275
276 return false;
277 }
278
279
280 // Get the section for the given external symbol names.
281 // This tries to find the type (Tag) of the symbol from its mangled name
282 // and return appropriate section name for it.
283 static inline std::string getSectionNameForSym(const std::string &Sym1) {
284 std::string Sym = addPrefix(Sym1);
285
286 std::string SectionName;
287
288 std::string Fname = getFuncNameForSym (Sym);
289 TAGS id = getSymbolTag (Sym);
290
291 switch (id) {
292 default : assert (0 && "Could not determine external symbol type");
293 case FRAME_LABEL:
294 case RET_LABEL:
295 case TEMPS_LABEL:
296 case ARGS_LABEL: {
297 return getFrameSectionName(Fname);
298 }
299 case AUTOS_LABEL: {
300 return getAutosSectionName(Fname);
301 }
302 }
303 }
304 }; // class PAN.
305
306
46307 // External symbol names require memory to live till the program end.
47308 // So we have to allocate it and keep.
48309 inline static const char *createESName (const std::string &name) {
442442 case PIC16ISD::SELECT_ICC: return "PIC16ISD::SELECT_ICC";
443443 case PIC16ISD::BRCOND: return "PIC16ISD::BRCOND";
444444 case PIC16ISD::RET: return "PIC16ISD::RET";
445 case PIC16ISD::RETFIE: return "PIC16ISD::RETFIE";
446445 case PIC16ISD::Dummy: return "PIC16ISD::Dummy";
447446 }
448447 }
12721271 DAG.getConstant (i, MVT::i8));
12731272
12741273 }
1275 if (PAN::isISR(F))
1276 return DAG.getNode(PIC16ISD::RETFIE, dl, MVT::Other, Chain);
1277 else
1278 return DAG.getNode(PIC16ISD::RET, dl, MVT::Other, Chain);
1274 return DAG.getNode(PIC16ISD::RET, dl, MVT::Other, Chain);
12791275 }
12801276
12811277 void PIC16TargetLowering::
5252 SELECT_ICC, // Psuedo to be caught in schedular and expanded to brcond.
5353 BRCOND, // Conditional branch.
5454 RET, // Return.
55 RETFIE, // Return from interrupt
5655 Dummy
5756 };
5857
116116
117117 def PIC16ret : SDNode<"PIC16ISD::RET", SDTNone, [SDNPHasChain]>;
118118
119 def PIC16Retfie : SDNode<"PIC16ISD::RETFIE", SDTNone, [SDNPHasChain]>;
120119 //===----------------------------------------------------------------------===//
121120 // PIC16 Operand Definitions.
122121 //===----------------------------------------------------------------------===//
497496 def Return :
498497 ControlFormat<0, (outs), (ins), "return", [(PIC16ret)]>;
499498
500 //Return instruction to return from ISR
501 let isTerminator = 1, isBarrier = 1, isReturn = 1 in
502 def Retfie :
503 ControlFormat<0, (outs), (ins), "retfie", [(PIC16Retfie)]>;
504499 //===----------------------------------------------------------------------===//
505500 // PIC16 Replacment Patterns.
506501 //===----------------------------------------------------------------------===//
+0
-426
lib/Target/PIC16/PIC16PAN.h less more
None //===-- PIC16PAN.h - PIC16 ABI Naming conventions --*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains the entry points for global functions defined in
10 // the LLVM PIC16 back-end.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_TARGET_PIC16PAN_H
15 #define LLVM_TARGET_PIC16PAN_H
16
17 #include "llvm/Support/ErrorHandling.h"
18 #include "llvm/Target/TargetMachine.h"
19 #include "llvm/Function.h"
20 #include
21 #include
22 #include
23 #include
24
25 namespace llvm {
26 // A Central class to manage all ABI naming conventions.
27 // PAN - [P]ic16 [A]BI [N]ames
28 class PAN {
29 public:
30 // Map the name of the symbol to its section name.
31 // Current ABI:
32 // -----------------------------------------------------
33 // ALL Names are prefixed with the symobl '@'.
34 // ------------------------------------------------------
35 // Global variables do not have any '.' in their names.
36 // These are maily function names and global variable names.
37 // Example - @foo, @i
38 // -------------------------------------------------------
39 // Functions and auto variables.
40 // Names are mangled as ..
41 // Where is '@' and is any one of
42 // the following
43 // .auto. - an automatic var of a function.
44 // .temp. - temproray data of a function.
45 // .ret. - return value label for a function.
46 // .frame. - Frame label for a function where retval, args
47 // and temps are stored.
48 // .args. - Label used to pass arguments to a direct call.
49 // Example - Function name: @foo
50 // Its frame: @foo.frame.
51 // Its retval: @foo.ret.
52 // Its local vars: @foo.auto.a
53 // Its temp data: @foo.temp.
54 // Its arg passing: @foo.args.
55 //----------------------------------------------
56 // Libcall - compiler generated libcall names must start with .lib.
57 // This id will be used to emit extern decls for libcalls.
58 // Example - libcall name: @.lib.sra.i8
59 // To pass args: @.lib.sra.i8.args.
60 // To return val: @.lib.sra.i8.ret.
61 //----------------------------------------------
62 // SECTION Names
63 // uninitialized globals - @udata..#
64 // initialized globals - @idata..#
65 // Function frame - @.frame_section.
66 // Function autos - @.autos_section.
67 // Declarations - Enclosed in comments. No section for them.
68 //----------------------------------------------------------
69
70 // Tags used to mangle different names.
71 enum TAGS {
72 PREFIX_SYMBOL,
73 GLOBAL,
74 STATIC_LOCAL,
75 AUTOS_LABEL,
76 FRAME_LABEL,
77 RET_LABEL,
78 ARGS_LABEL,
79 TEMPS_LABEL,
80
81 LIBCALL,
82
83 FRAME_SECTION,
84 AUTOS_SECTION,
85 CODE_SECTION
86 };
87 enum CallLine {
88 MainLine,
89 InterruptLine,
90 SharedLine,
91 UnspecifiedLine
92 };
93
94 // Textual names of the tags.
95 inline static const char *getTagName(TAGS tag) {
96 switch (tag) {
97 default: return "";
98 case PREFIX_SYMBOL: return "@";
99 case AUTOS_LABEL: return ".auto.";
100 case FRAME_LABEL: return ".frame.";
101 case TEMPS_LABEL: return ".temp.";
102 case ARGS_LABEL: return ".args.";
103 case RET_LABEL: return ".ret.";
104 case LIBCALL: return ".lib.";
105 case FRAME_SECTION: return ".frame_section.";
106 case AUTOS_SECTION: return ".autos_section.";
107 case CODE_SECTION: return ".code_section.";
108 }
109 }
110
111 inline static bool isISR(const Function *F) {
112 if (F->getSection().find("interrupt") != std::string::npos)
113 return true;
114
115 return false;
116 }
117 inline static bool isInterruptLineFunction(const Function *F) {
118 if (isISR(F)) return true;
119 if (F->getSection().find("IL") != std::string::npos)
120 return true;
121
122 return false;
123 }
124 inline static bool isMainLineFunction(const Function *F) {
125 if (F->getSection().find("ML") != std::string::npos)
126 return true;
127
128 return false;
129 }
130 inline static bool isSharedLineFunction(const Function *F) {
131 if (F->getSection().find("SL") != std::string::npos)
132 return true;
133
134 return false;
135 }
136
137 inline static const char *getUpdatedLibCallDecl(const char *Name,
138 const Function *F) {
139 // If the current function is not an interrupt line function then
140 // there is no need to change the name.
141 if (!isInterruptLineFunction(F))
142 return Name;
143
144
145 // CAUTION::This code may cause some memory leak and at times
146 // use more memory than required.
147 // (We will try to clean it sometime later)
148
149 // InterruptLine functions should hold ".IL" suffix and
150 char *NewName = (char *)malloc(strlen(Name) + 3 + 1);
151 strcpy(NewName, Name);
152 strcat(NewName, ".IL");
153 return NewName;
154 }
155
156 inline static void updateCallLineAutos(std::string &Sym, std::string FuncName) {
157 // If the function has ".IL" in its name then it must be
158 // a cloned function and autos for such a function should also
159 // have ".IL" in their name. So update them here.
160 if (FuncName.find(".IL") != std::string::npos)
161 Sym.replace(Sym.find(".auto"), 5, ".IL.auto");
162 }
163
164 // Insert ".IL" at proper location in the ARGS and RET symbols
165 inline static void updateCallLineLibcall(std::string &Sym) {
166 std::string SubStr;
167 std::size_t pos;
168 std::string Suffix;
169 if (getSymbolTag(Sym) == ARGS_LABEL) {
170 Suffix = getTagName(ARGS_LABEL);
171 pos = Sym.find(Suffix);
172 SubStr = Sym.substr(0,pos);
173 } else if (getSymbolTag(Sym) == RET_LABEL) {
174 Suffix = getTagName(RET_LABEL);
175 pos = Sym.find(Suffix);
176 SubStr = Sym.substr(0,pos);
177 } else {
178 SubStr = Sym;
179 Suffix = "";
180 }
181 Sym = SubStr + ".IL" + Suffix;
182 }
183
184 inline static void updateCallLineSymbol(std::string &Sym, CallLine CLine) {
185 if (isLIBCALLSymbol(Sym) && CLine == InterruptLine) {
186 updateCallLineLibcall(Sym);
187 return;
188 }
189
190 // UnMangle the function name - mangled in llvm-ld
191 // For MainLine function the shared string should be removed
192 // and for InterruptLine function the shared string should be
193 // replaced with ".IL"
194 std::string ReplaceString="";
195 if (CLine == MainLine || CLine == UnspecifiedLine)
196 ReplaceString = "";
197 else if (CLine == InterruptLine)
198 ReplaceString = ".IL";
199 std::string FindString = ".shared";
200 if (Sym.find(FindString) != std::string::npos) {
201 Sym.replace(Sym.find(FindString), FindString.length(), ReplaceString);
202 return;
203 }
204 }
205
206 inline static void updateCallLineSymbol(std::string &Sym,
207 const Function *F) {
208 // If it is an auto symbol then it should be updated accordingly
209 if (Sym.find(".auto") != std::string::npos) {
210 updateCallLineAutos(Sym, F->getName().str());
211 return;
212 }
213
214 if (isMainLineFunction(F))
215 updateCallLineSymbol(Sym, MainLine);
216 else if (isInterruptLineFunction(F))
217 updateCallLineSymbol(Sym, InterruptLine);
218 else
219 updateCallLineSymbol(Sym, UnspecifiedLine);
220 }
221
222 inline static bool isLIBCALLSymbol(const std::string &Sym) {
223 if (Sym.find(getTagName(LIBCALL)) != std::string::npos)
224 return true;
225
226 return false;
227 }
228
229 // Get tag type for the Symbol.
230 inline static TAGS getSymbolTag(const std::string &Sym) {
231 if (Sym.find(getTagName(TEMPS_LABEL)) != std::string::npos)
232 return TEMPS_LABEL;
233
234 if (Sym.find(getTagName(FRAME_LABEL)) != std::string::npos)
235 return FRAME_LABEL;
236
237 if (Sym.find(getTagName(RET_LABEL)) != std::string::npos)
238 return RET_LABEL;
239
240 if (Sym.find(getTagName(ARGS_LABEL)) != std::string::npos)
241 return ARGS_LABEL;
242
243 if (Sym.find(getTagName(AUTOS_LABEL)) != std::string::npos)
244 return AUTOS_LABEL;
245
246 if (Sym.find(getTagName(LIBCALL)) != std::string::npos)
247 return LIBCALL;
248
249 // It does not have any Tag. So its a true global or static local.
250 if (Sym.find(".") == std::string::npos)
251 return GLOBAL;
252
253 // If a . is there, then it may be static local.
254 // We should mangle these as well in clang.
255 if (Sym.find(".") != std::string::npos)
256 return STATIC_LOCAL;
257
258 assert (0 && "Could not determine Symbol's tag");
259 return PREFIX_SYMBOL; // Silence warning when assertions are turned off.
260 }
261
262 // addPrefix - add prefix symbol to a name if there isn't one already.
263 inline static std::string addPrefix (const std::string &Name) {
264 std::string prefix = getTagName (PREFIX_SYMBOL);
265
266 // If this name already has a prefix, nothing to do.
267 if (Name.compare(0, prefix.size(), prefix) == 0)
268 return Name;
269
270 return prefix + Name;
271 }
272
273 // Get mangled func name from a mangled sym name.
274 // In all cases func name is the first component before a '.'.
275 static inline std::string getFuncNameForSym(const std::string &Sym1) {
276 assert (getSymbolTag(Sym1) != GLOBAL && "not belongs to a function");
277
278 std::string Sym = addPrefix(Sym1);
279
280 // Position of the . after func name. That's where func name ends.
281 size_t func_name_end = Sym.find ('.');
282
283 return Sym.substr (0, func_name_end);
284 }
285
286 // Get Frame start label for a func.
287 static std::string getFrameLabel(const std::string &Func) {
288 std::string Func1 = addPrefix(Func);
289 std::string tag = getTagName(FRAME_LABEL);
290 return Func1 + tag;
291 }
292
293 static std::string getRetvalLabel(const std::string &Func) {
294 std::string Func1 = addPrefix(Func);
295 std::string tag = getTagName(RET_LABEL);
296 return Func1 + tag;
297 }
298
299 static std::string getArgsLabel(const std::string &Func) {
300 std::string Func1 = addPrefix(Func);
301 std::string tag = getTagName(ARGS_LABEL);
302 return Func1 + tag;
303 }
304
305 static std::string getTempdataLabel(const std::string &Func) {
306 std::string Func1 = addPrefix(Func);
307 std::string tag = getTagName(TEMPS_LABEL);
308 return Func1 + tag;
309 }
310
311 static std::string getFrameSectionName(const std::string &Func) {
312 std::string Func1 = addPrefix(Func);
313 std::string tag = getTagName(FRAME_SECTION);
314 return Func1 + tag + "# UDATA_OVR";
315 }
316
317 static std::string getAutosSectionName(const std::string &Func) {
318 std::string Func1 = addPrefix(Func);
319 std::string tag = getTagName(AUTOS_SECTION);
320 return Func1 + tag + "# UDATA_OVR";
321 }
322
323 static std::string getCodeSectionName(const std::string &Func, bool isInterrupt) {
324 std::string Func1 = addPrefix(Func);
325 std::string tag = getTagName(CODE_SECTION);
326 std::string Name = Func1 + tag + "# CODE";
327
328 // If this is an interrupt function then the code section should
329 // be placed at address 0x4 (hard)
330 if (isInterrupt)
331 Name += " 0x4";
332
333 return Name;
334 }
335
336 // udata, romdata and idata section names are generated by a given number.
337 // @udata..#
338 static std::string getUdataSectionName(unsigned num,
339 std::string prefix = "") {
340 std::ostringstream o;
341 o << getTagName(PREFIX_SYMBOL) << prefix << "udata." << num
342 << ".# UDATA";
343 return o.str();
344 }
345
346 static std::string getRomdataSectionName(unsigned num,
347 std::string prefix = "") {
348 std::ostringstream o;
349 o << getTagName(PREFIX_SYMBOL) << prefix << "romdata." << num
350 << ".# ROMDATA";
351 return o.str();
352 }
353
354 static std::string getIdataSectionName(unsigned num,
355 std::string prefix = "") {
356 std::ostringstream o;
357 o << getTagName(PREFIX_SYMBOL) << prefix << "idata." << num
358 << ".# IDATA";
359 return o.str();
360 }
361
362 inline static bool isLocalName (const std::string &Name) {
363 if (getSymbolTag(Name) == AUTOS_LABEL)
364 return true;
365
366 return false;
367 }
368
369 inline static bool isMemIntrinsic (const std::string &Name) {
370 if (Name.compare("@memcpy") == 0 || Name.compare("@memset") == 0 ||
371 Name.compare("@memmove") == 0) {
372 return true;
373 }
374
375 return false;
376 }
377
378 inline static bool isLocalToFunc (std::string &Func, std::string &Var) {
379 if (! isLocalName(Var)) return false;
380
381 std::string Func1 = addPrefix(Func);
382 // Extract func name of the varilable.
383 const std::string &fname = getFuncNameForSym(Var);
384
385 if (fname.compare(Func1) == 0)
386 return true;
387
388 return false;
389 }
390
391
392 // Get the section for the given external symbol names.
393 // This tries to find the type (Tag) of the symbol from its mangled name
394 // and return appropriate section name for it.
395 static inline std::string getSectionNameForSym(const std::string &Sym1) {
396 std::string Sym = addPrefix(Sym1);
397
398 std::string SectionName;
399
400 std::string Fname = getFuncNameForSym (Sym);
401 TAGS id = getSymbolTag (Sym);
402
403 switch (id) {
404 default : assert (0 && "Could not determine external symbol type");
405 case FRAME_LABEL:
406 case RET_LABEL:
407 case TEMPS_LABEL:
408 case ARGS_LABEL: {
409 return getFrameSectionName(Fname);
410 }
411 case AUTOS_LABEL: {
412 return getAutosSectionName(Fname);
413 }
414 }
415 }
416
417 inline static std::string getAutosSectionForColor(std::string Color) {
418 return Color.append("_AUTOS");
419 }
420
421 }; // class PAN.
422
423 } // end namespace llvm;
424
425 #endif
6969 }
7070
7171 const MCSection *PIC16TargetObjectFile::
72 getSectionForFunction(const std::string &FnName, bool isInterrupt) const {
73 std::string T = PAN::getCodeSectionName(FnName, isInterrupt);
72 getSectionForFunction(const std::string &FnName) const {
73 std::string T = PAN::getCodeSectionName(FnName);
7474 return getPIC16Section(T.c_str(), SectionKind::getText());
7575 }
7676
195195 return FoundAutoSec->S_;
196196 }
197197
198 void PIC16TargetObjectFile::createClonedSectionForAutos(const std::string &SecName) {
199
200 // If the function is cloned then it will have ".IL" in its name
201 // If this function is not cloned then return;
202 if (SecName.find(".IL") == std::string::npos)
203 return;
204
205 // Come here if the function is cloned.
206 // Get the name of the original section from which it has been cloned.
207 std::string OrigName = SecName;
208 OrigName.replace(SecName.find(".IL"),3,"");
209
210 // Find original section
211 PIC16Section *FoundAutoSec = NULL;
212 for (unsigned i = 0; i < AutosSections.size(); i++) {
213 if (AutosSections[i]->S_->getName() == OrigName) {
214 FoundAutoSec = AutosSections[i];
215 break;
216 }
217 }
218
219 // No auto section exists for the original function.
220 if (!FoundAutoSec)
221 return;
222
223 // Create new section for the cloned function
224 const MCSectionPIC16 *NewSection =
225 getPIC16Section(SecName.c_str(), SectionKind::getMetadata());
226
227 PIC16Section *NewAutoSec = new PIC16Section(NewSection);
228 // Add this newly created autos section to the list of AutosSections.
229 AutosSections.push_back(NewAutoSec);
230
231 // Add the items from the original section to the new section
232 // Donot mangle them here. Because mangling them here will distort
233 // the original names.
234 // These names will be mangled them at the time of printing only
235 const std::vector &Items = FoundAutoSec->Items;
236 for (unsigned j = 0; j < Items.size(); j++) {
237 NewAutoSec->Items.push_back(Items[j]);
238 }
239 }
240198
241199 // Override default implementation to put the true globals into
242200 // multiple data sections if required.
7676 Mangler *Mang,
7777 const TargetMachine&) const;
7878
79 const MCSection *getSectionForFunction(const std::string &FnName,
80 bool isInterrupt=false) const;
79 const MCSection *getSectionForFunction(const std::string &FnName) const;
8180 const MCSection *getSectionForFunctionFrame(const std::string &FnName)const;
8281
83 // If the current function is cloned then create the new autos section
84 // also.
85 void createClonedSectionForAutos(const std::string &SecName);
82
8683 private:
8784 std::string getSectionNameForSym(const std::string &Sym) const;
8885