| Benjamin Kramer | 74c35c1 | 2009-10-15 19:46:34 +0000 | [diff] [blame] | 1 | //===-- PIC16ABINames.h - PIC16 Naming conventios for ABI----- --*- C++ -*-===// | 
|  | 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 the functions to manage ABI Naming conventions for PIC16. | 
|  | 11 | // | 
|  | 12 | // | 
|  | 13 | //===----------------------------------------------------------------------===// | 
|  | 14 |  | 
|  | 15 | #ifndef LLVM_TARGET_PIC16ABINAMES_H | 
|  | 16 | #define LLVM_TARGET_PIC16ABINAMES_H | 
|  | 17 |  | 
|  | 18 | #include "llvm/Support/ErrorHandling.h" | 
|  | 19 | #include "llvm/Target/TargetMachine.h" | 
|  | 20 | #include <cassert> | 
|  | 21 | #include <sstream> | 
|  | 22 | #include <cstring> | 
|  | 23 | #include <string> | 
|  | 24 |  | 
|  | 25 | namespace llvm { | 
|  | 26 | class PIC16TargetMachine; | 
|  | 27 | class FunctionPass; | 
|  | 28 | class MachineCodeEmitter; | 
|  | 29 | class formatted_raw_ostream; | 
|  | 30 |  | 
|  | 31 | // A Central class to manage all ABI naming conventions. | 
|  | 32 | // PAN - [P]ic16 [A]BI [N]ames | 
|  | 33 | class PAN { | 
|  | 34 | public: | 
|  | 35 | // Map the name of the symbol to its section name. | 
|  | 36 | // Current ABI: | 
|  | 37 | // ----------------------------------------------------- | 
|  | 38 | // ALL Names are prefixed with the symobl '@'. | 
|  | 39 | // ------------------------------------------------------ | 
|  | 40 | // Global variables do not have any '.' in their names. | 
|  | 41 | // These are maily function names and global variable names. | 
|  | 42 | // Example - @foo,  @i | 
| Sanjiv Gupta | 89259d7 | 2009-10-16 08:58:34 +0000 | [diff] [blame] | 43 | // Static local variables - @<func>.<var> | 
| Benjamin Kramer | 74c35c1 | 2009-10-15 19:46:34 +0000 | [diff] [blame] | 44 | // ------------------------------------------------------- | 
|  | 45 | // Functions and auto variables. | 
|  | 46 | // Names are mangled as <prefix><funcname>.<tag>.<varname> | 
|  | 47 | // Where <prefix> is '@' and <tag> is any one of | 
|  | 48 | // the following | 
|  | 49 | // .auto. - an automatic var of a function. | 
|  | 50 | // .temp. - temproray data of a function. | 
|  | 51 | // .ret.  - return value label for a function. | 
|  | 52 | // .frame. - Frame label for a function where retval, args | 
|  | 53 | //           and temps are stored. | 
|  | 54 | // .args. - Label used to pass arguments to a direct call. | 
|  | 55 | // Example - Function name:   @foo | 
|  | 56 | //           Its frame:       @foo.frame. | 
|  | 57 | //           Its retval:      @foo.ret. | 
|  | 58 | //           Its local vars:  @foo.auto.a | 
|  | 59 | //           Its temp data:   @foo.temp. | 
|  | 60 | //           Its arg passing: @foo.args. | 
|  | 61 | //---------------------------------------------- | 
|  | 62 | // Libcall - compiler generated libcall names must start with .lib. | 
|  | 63 | //           This id will be used to emit extern decls for libcalls. | 
|  | 64 | // Example - libcall name:   @.lib.sra.i8 | 
|  | 65 | //           To pass args:   @.lib.sra.i8.args. | 
|  | 66 | //           To return val:  @.lib.sra.i8.ret. | 
|  | 67 | //---------------------------------------------- | 
|  | 68 | // SECTION Names | 
|  | 69 | // uninitialized globals - @udata.<num>.# | 
|  | 70 | // initialized globals - @idata.<num>.# | 
| Sanjiv Gupta | 89259d7 | 2009-10-16 08:58:34 +0000 | [diff] [blame] | 71 | // Program memory data - @romdata.# | 
|  | 72 | // Variables with user defined section name - <user_defined_section> | 
|  | 73 | // Variables with user defined address - @<var>.user_section.<address>.# | 
| Benjamin Kramer | 74c35c1 | 2009-10-15 19:46:34 +0000 | [diff] [blame] | 74 | // Function frame - @<func>.frame_section. | 
|  | 75 | // Function autos - @<func>.autos_section. | 
| Sanjiv Gupta | 89259d7 | 2009-10-16 08:58:34 +0000 | [diff] [blame] | 76 | // Overlay sections - @<color>.## | 
| Benjamin Kramer | 74c35c1 | 2009-10-15 19:46:34 +0000 | [diff] [blame] | 77 | // Declarations - Enclosed in comments. No section for them. | 
|  | 78 | //---------------------------------------------------------- | 
|  | 79 |  | 
|  | 80 | // Tags used to mangle different names. | 
|  | 81 | enum TAGS { | 
|  | 82 | PREFIX_SYMBOL, | 
|  | 83 | GLOBAL, | 
|  | 84 | STATIC_LOCAL, | 
|  | 85 | AUTOS_LABEL, | 
|  | 86 | FRAME_LABEL, | 
|  | 87 | RET_LABEL, | 
|  | 88 | ARGS_LABEL, | 
|  | 89 | TEMPS_LABEL, | 
|  | 90 |  | 
|  | 91 | LIBCALL, | 
|  | 92 |  | 
|  | 93 | FRAME_SECTION, | 
|  | 94 | AUTOS_SECTION, | 
|  | 95 | CODE_SECTION, | 
|  | 96 | USER_SECTION | 
|  | 97 | }; | 
|  | 98 |  | 
|  | 99 | // Textual names of the tags. | 
|  | 100 | inline static const char *getTagName(TAGS tag) { | 
|  | 101 | switch (tag) { | 
|  | 102 | default: return ""; | 
|  | 103 | case PREFIX_SYMBOL:    return "@"; | 
|  | 104 | case AUTOS_LABEL:       return ".auto."; | 
|  | 105 | case FRAME_LABEL:       return ".frame."; | 
|  | 106 | case TEMPS_LABEL:       return ".temp."; | 
|  | 107 | case ARGS_LABEL:       return ".args."; | 
|  | 108 | case RET_LABEL:       return ".ret."; | 
|  | 109 | case LIBCALL:       return ".lib."; | 
|  | 110 | case FRAME_SECTION:       return ".frame_section."; | 
|  | 111 | case AUTOS_SECTION:       return ".autos_section."; | 
|  | 112 | case CODE_SECTION:       return ".code_section."; | 
|  | 113 | case USER_SECTION:       return ".user_section."; | 
|  | 114 | } | 
|  | 115 | } | 
|  | 116 |  | 
|  | 117 | // Get tag type for the Symbol. | 
|  | 118 | inline static TAGS getSymbolTag(const std::string &Sym) { | 
|  | 119 | if (Sym.find(getTagName(TEMPS_LABEL)) != std::string::npos) | 
|  | 120 | return TEMPS_LABEL; | 
|  | 121 |  | 
|  | 122 | if (Sym.find(getTagName(FRAME_LABEL)) != std::string::npos) | 
|  | 123 | return FRAME_LABEL; | 
|  | 124 |  | 
|  | 125 | if (Sym.find(getTagName(RET_LABEL)) != std::string::npos) | 
|  | 126 | return RET_LABEL; | 
|  | 127 |  | 
|  | 128 | if (Sym.find(getTagName(ARGS_LABEL)) != std::string::npos) | 
|  | 129 | return ARGS_LABEL; | 
|  | 130 |  | 
|  | 131 | if (Sym.find(getTagName(AUTOS_LABEL)) != std::string::npos) | 
|  | 132 | return AUTOS_LABEL; | 
|  | 133 |  | 
|  | 134 | if (Sym.find(getTagName(LIBCALL)) != std::string::npos) | 
|  | 135 | return LIBCALL; | 
|  | 136 |  | 
|  | 137 | // It does not have any Tag. So its a true global or static local. | 
|  | 138 | if (Sym.find(".") == std::string::npos) | 
|  | 139 | return GLOBAL; | 
|  | 140 |  | 
|  | 141 | // If a . is there, then it may be static local. | 
|  | 142 | // We should mangle these as well in clang. | 
|  | 143 | if (Sym.find(".") != std::string::npos) | 
|  | 144 | return STATIC_LOCAL; | 
|  | 145 |  | 
|  | 146 | assert (0 && "Could not determine Symbol's tag"); | 
|  | 147 | return PREFIX_SYMBOL; // Silence warning when assertions are turned off. | 
|  | 148 | } | 
|  | 149 |  | 
|  | 150 | // addPrefix - add prefix symbol to a name if there isn't one already. | 
|  | 151 | inline static std::string addPrefix (const std::string &Name) { | 
|  | 152 | std::string prefix = getTagName (PREFIX_SYMBOL); | 
|  | 153 |  | 
|  | 154 | // If this name already has a prefix, nothing to do. | 
|  | 155 | if (Name.compare(0, prefix.size(), prefix) == 0) | 
|  | 156 | return Name; | 
|  | 157 |  | 
|  | 158 | return prefix + Name; | 
|  | 159 | } | 
|  | 160 |  | 
|  | 161 | // Get mangled func name from a mangled sym name. | 
|  | 162 | // In all cases func name is the first component before a '.'. | 
|  | 163 | static inline std::string getFuncNameForSym(const std::string &Sym1) { | 
|  | 164 | assert (getSymbolTag(Sym1) != GLOBAL && "not belongs to a function"); | 
|  | 165 |  | 
|  | 166 | std::string Sym = addPrefix(Sym1); | 
|  | 167 |  | 
|  | 168 | // Position of the . after func name. That's where func name ends. | 
|  | 169 | size_t func_name_end = Sym.find ('.'); | 
|  | 170 |  | 
|  | 171 | return Sym.substr (0, func_name_end); | 
|  | 172 | } | 
|  | 173 |  | 
|  | 174 | // Get Frame start label for a func. | 
|  | 175 | static std::string getFrameLabel(const std::string &Func) { | 
|  | 176 | std::string Func1 = addPrefix(Func); | 
|  | 177 | std::string tag = getTagName(FRAME_LABEL); | 
|  | 178 | return Func1 + tag; | 
|  | 179 | } | 
|  | 180 |  | 
|  | 181 | static std::string getRetvalLabel(const std::string &Func) { | 
|  | 182 | std::string Func1 = addPrefix(Func); | 
|  | 183 | std::string tag = getTagName(RET_LABEL); | 
|  | 184 | return Func1 + tag; | 
|  | 185 | } | 
|  | 186 |  | 
|  | 187 | static std::string getArgsLabel(const std::string &Func) { | 
|  | 188 | std::string Func1 = addPrefix(Func); | 
|  | 189 | std::string tag = getTagName(ARGS_LABEL); | 
|  | 190 | return Func1 + tag; | 
|  | 191 | } | 
|  | 192 |  | 
|  | 193 | static std::string getTempdataLabel(const std::string &Func) { | 
|  | 194 | std::string Func1 = addPrefix(Func); | 
|  | 195 | std::string tag = getTagName(TEMPS_LABEL); | 
|  | 196 | return Func1 + tag; | 
|  | 197 | } | 
|  | 198 |  | 
|  | 199 | static std::string getFrameSectionName(const std::string &Func) { | 
|  | 200 | std::string Func1 = addPrefix(Func); | 
|  | 201 | std::string tag = getTagName(FRAME_SECTION); | 
|  | 202 | return Func1 + tag + "#"; | 
|  | 203 | } | 
|  | 204 |  | 
|  | 205 | static std::string getAutosSectionName(const std::string &Func) { | 
|  | 206 | std::string Func1 = addPrefix(Func); | 
|  | 207 | std::string tag = getTagName(AUTOS_SECTION); | 
|  | 208 | return Func1 + tag + "#"; | 
|  | 209 | } | 
|  | 210 |  | 
|  | 211 | static std::string getCodeSectionName(const std::string &Func) { | 
|  | 212 | std::string Func1 = addPrefix(Func); | 
|  | 213 | std::string tag = getTagName(CODE_SECTION); | 
|  | 214 | return Func1 + tag + "#"; | 
|  | 215 | } | 
|  | 216 |  | 
|  | 217 | static std::string getUserSectionName(const std::string &Name) { | 
|  | 218 | std::string sname = addPrefix(Name);; | 
|  | 219 | std::string tag = getTagName(USER_SECTION); | 
|  | 220 | return sname + tag + "#"; | 
|  | 221 | } | 
|  | 222 |  | 
|  | 223 | // udata, romdata and idata section names are generated by a given number. | 
|  | 224 | // @udata.<num>.# | 
|  | 225 | static std::string getUdataSectionName(unsigned num, | 
|  | 226 | std::string prefix = "") { | 
|  | 227 | std::ostringstream o; | 
|  | 228 | o << getTagName(PREFIX_SYMBOL) << prefix << "udata." << num | 
|  | 229 | << ".#"; | 
|  | 230 | return o.str(); | 
|  | 231 | } | 
|  | 232 |  | 
|  | 233 | static std::string getRomdataSectionName() { | 
|  | 234 | return "romdata.#"; | 
|  | 235 | } | 
|  | 236 |  | 
| Sanjiv Gupta | b18a468 | 2009-10-25 08:14:11 +0000 | [diff] [blame^] | 237 | static std::string getSharedUDataSectionName() { | 
|  | 238 | std::ostringstream o; | 
|  | 239 | o << getTagName(PREFIX_SYMBOL)  << "udata_shr" << ".#"; | 
|  | 240 | return o.str(); | 
|  | 241 | } | 
|  | 242 |  | 
| Benjamin Kramer | 74c35c1 | 2009-10-15 19:46:34 +0000 | [diff] [blame] | 243 | static std::string getRomdataSectionName(unsigned num, | 
|  | 244 | std::string prefix = "") { | 
|  | 245 | std::ostringstream o; | 
|  | 246 | o << getTagName(PREFIX_SYMBOL) << prefix << "romdata." << num | 
|  | 247 | << ".#"; | 
|  | 248 | return o.str(); | 
|  | 249 | } | 
|  | 250 |  | 
|  | 251 | static std::string getIdataSectionName(unsigned num, | 
|  | 252 | std::string prefix = "") { | 
|  | 253 | std::ostringstream o; | 
|  | 254 | o << getTagName(PREFIX_SYMBOL) << prefix << "idata." << num | 
|  | 255 | << ".#"; | 
|  | 256 | return o.str(); | 
|  | 257 | } | 
|  | 258 |  | 
|  | 259 | inline static bool isLocalName (const std::string &Name) { | 
|  | 260 | if (getSymbolTag(Name) == AUTOS_LABEL) | 
|  | 261 | return true; | 
|  | 262 |  | 
|  | 263 | return false; | 
|  | 264 | } | 
|  | 265 |  | 
|  | 266 | inline static bool isMemIntrinsic (const std::string &Name) { | 
|  | 267 | if (Name.compare("@memcpy") == 0 || Name.compare("@memset") == 0 || | 
|  | 268 | Name.compare("@memmove") == 0) { | 
|  | 269 | return true; | 
|  | 270 | } | 
|  | 271 |  | 
|  | 272 | return false; | 
|  | 273 | } | 
|  | 274 |  | 
|  | 275 | inline static bool isLocalToFunc (std::string &Func, std::string &Var) { | 
|  | 276 | if (! isLocalName(Var)) return false; | 
|  | 277 |  | 
|  | 278 | std::string Func1 = addPrefix(Func); | 
|  | 279 | // Extract func name of the varilable. | 
|  | 280 | const std::string &fname = getFuncNameForSym(Var); | 
|  | 281 |  | 
|  | 282 | if (fname.compare(Func1) == 0) | 
|  | 283 | return true; | 
|  | 284 |  | 
|  | 285 | return false; | 
|  | 286 | } | 
|  | 287 |  | 
|  | 288 |  | 
|  | 289 | // Get the section for the given external symbol names. | 
|  | 290 | // This tries to find the type (Tag) of the symbol from its mangled name | 
|  | 291 | // and return appropriate section name for it. | 
|  | 292 | static inline std::string getSectionNameForSym(const std::string &Sym1) { | 
|  | 293 | std::string Sym = addPrefix(Sym1); | 
|  | 294 |  | 
|  | 295 | std::string SectionName; | 
|  | 296 |  | 
|  | 297 | std::string Fname = getFuncNameForSym (Sym); | 
|  | 298 | TAGS id = getSymbolTag (Sym); | 
|  | 299 |  | 
|  | 300 | switch (id) { | 
|  | 301 | default : assert (0 && "Could not determine external symbol type"); | 
|  | 302 | case FRAME_LABEL: | 
|  | 303 | case RET_LABEL: | 
|  | 304 | case TEMPS_LABEL: | 
|  | 305 | case ARGS_LABEL:  { | 
|  | 306 | return getFrameSectionName(Fname); | 
|  | 307 | } | 
|  | 308 | case AUTOS_LABEL: { | 
|  | 309 | return getAutosSectionName(Fname); | 
|  | 310 | } | 
|  | 311 | } | 
|  | 312 | } | 
| Sanjiv Gupta | 47ea743 | 2009-10-21 10:42:44 +0000 | [diff] [blame] | 313 |  | 
|  | 314 | /// Return Overlay Name for the section. | 
|  | 315 | /// The ABI Convention is: @<Color>.##.<section_tag> | 
|  | 316 | /// The section_tag is retrieved from the SectName parameter and | 
|  | 317 | /// and Color is passed in parameter. | 
|  | 318 | static inline std::string  getOverlayName(std::string SectName, int Color) { | 
|  | 319 | // FIXME: Only autos_section and frame_section are colored. | 
|  | 320 | // So check and assert if the passed SectName does not have AUTOS_SECTION | 
|  | 321 | // or FRAME_SECTION tag in it. | 
|  | 322 | std::ostringstream o; | 
|  | 323 | o << getTagName(PREFIX_SYMBOL) << Color << ".##" | 
|  | 324 | << SectName.substr(SectName.find(".")); | 
|  | 325 |  | 
|  | 326 | return o.str(); | 
|  | 327 | } | 
| Benjamin Kramer | 74c35c1 | 2009-10-15 19:46:34 +0000 | [diff] [blame] | 328 | }; // class PAN. | 
|  | 329 | } // end namespace llvm; | 
|  | 330 |  | 
|  | 331 | #endif |