[llvm-commits] [llvm] r79562 - in /llvm/trunk/lib/Target/PIC16: AsmPrinter/PIC16AsmPrinter.cpp AsmPrinter/PIC16AsmPrinter.h Makefile PIC16.h PIC16ISelLowering.cpp PIC16ISelLowering.h PIC16InstrInfo.td PIC16PAN.h PIC16TargetObjectFile.cpp PIC16TargetObjectFile.h

Sanjiv Gupta sanjiv.gupta at microchip.com
Thu Aug 20 12:28:24 PDT 2009


Author: sgupta
Date: Thu Aug 20 14:28:24 2009
New Revision: 79562

URL: http://llvm.org/viewvc/llvm-project?rev=79562&view=rev
Log:
Implement support for ISRs. 
Clone functions that are shared between the Main thread and Interrupt thread.
CallSites are changed in AsmPrinter currently. A better solution would have been to modify the legalizer (SoftenFloat) to allow targets to change the name of libcalls for float operations. But that currently breaks other targets.
Also, cloing of automatic variables is done AsmPrinter, a better approach would
be to use the ValueMap in CloneFunction itself.

Added:
    llvm/trunk/lib/Target/PIC16/PIC16PAN.h
Modified:
    llvm/trunk/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.cpp
    llvm/trunk/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.h
    llvm/trunk/lib/Target/PIC16/Makefile
    llvm/trunk/lib/Target/PIC16/PIC16.h
    llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp
    llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.h
    llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.td
    llvm/trunk/lib/Target/PIC16/PIC16TargetObjectFile.cpp
    llvm/trunk/lib/Target/PIC16/PIC16TargetObjectFile.h

Modified: llvm/trunk/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.cpp?rev=79562&r1=79561&r2=79562&view=diff

==============================================================================
--- llvm/trunk/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.cpp (original)
+++ llvm/trunk/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.cpp Thu Aug 20 14:28:24 2009
@@ -39,6 +39,7 @@
   PTLI = static_cast<PIC16TargetLowering*>(TM.getTargetLowering());
   PTAI = static_cast<const PIC16TargetAsmInfo*>(T);
   PTOF = (PIC16TargetObjectFile*)&PTLI->getObjFileLowering();
+  CurrentFnPtr = NULL;
 }
 
 bool PIC16AsmPrinter::printMachineInstruction(const MachineInstr *MI) {
@@ -60,6 +61,11 @@
   // Get the mangled name.
   const Function *F = MF.getFunction();
   CurrentFnName = Mang->getMangledName(F);
+  CurrentFnPtr = F;
+
+  // Current function name was mangled in llvm-ld for both
+  // MainLine and InterruptLine and should be demangled here 
+  PAN::updateCallLineSymbol(CurrentFnName, CurrentFnPtr);
 
   // Emit the function frame (args and temps).
   EmitFunctionFrame(MF);
@@ -71,18 +77,23 @@
 
   // Now emit the instructions of function in its code section.
   const MCSection *fCodeSection = 
-    getObjFileLowering().getSectionForFunction(CurrentFnName);
+    getObjFileLowering().getSectionForFunction(CurrentFnName, 
+                                               PAN::isISR(F));
   // Start the Code Section.
   O <<  "\n";
   OutStreamer.SwitchSection(fCodeSection);
-
-  // Emit the frame address of the function at the beginning of code.
-  O << "\tretlw  low(" << PAN::getFrameLabel(CurrentFnName) << ")\n";
-  O << "\tretlw  high(" << PAN::getFrameLabel(CurrentFnName) << ")\n";
+  
+  // If it is not an interrupt function then emit the data address
+  // retrieval code in function code itself.
+  if (!(PAN::isISR(F))) {
+     // Emit the frame address of the function at the beginning of code.
+     O << "\tretlw  low(" << PAN::getFrameLabel(CurrentFnName) << ")\n";
+     O << "\tretlw  high(" << PAN::getFrameLabel(CurrentFnName) << ")\n";
+  }
 
   // Emit function start label.
   O << CurrentFnName << ":\n";
-
+  
   DebugLoc CurDL;
   O << "\n"; 
   // Print out code for the function.
@@ -142,7 +153,9 @@
       if (PAN::isMemIntrinsic(Sname)) {
         LibcallDecls.push_back(createESName(Sname));
       }
-
+      // All the call sites were mangled in llvm-ld pass hence the 
+      // operands for call instructions should be demangled here.
+      PAN::updateCallLineSymbol(Sname, CurrentFnPtr);
       O << Sname;
       break;
     }
@@ -151,7 +164,9 @@
 
       // If its a libcall name, record it to decls section.
       if (PAN::getSymbolTag(Sname) == PAN::LIBCALL) {
-        LibcallDecls.push_back(Sname);
+         // LibCallDecls for InterruptLine functions should have ".IL" suffix 
+         const char *NewName= PAN::getUpdatedLibCallDecl(Sname, CurrentFnPtr);
+         LibcallDecls.push_back(NewName);
       }
 
       // Record a call to intrinsic to print the extern declaration for it.
@@ -160,9 +175,13 @@
         Sym = PAN::addPrefix(Sym);
         LibcallDecls.push_back(createESName(Sym));
       }
-
-      O  << Sym;
-      break;
+      // Update the library call symbols. Library calls to InterruptLine
+      // functions are different. (They have ".IL" in their names)
+      // Also other symbols (frame and temp) for the cloned function
+      // should be updated here.
+      PAN::updateCallLineSymbol(Sym, CurrentFnPtr);
+      O << Sym; 
+     break;
     }
     case MachineOperand::MO_MachineBasicBlock:
       printBasicBlockLabel(MO.getMBB());
@@ -274,7 +293,11 @@
 
     const char *directive = I->isDeclaration() ? TAI->getExternDirective() :
                                                  TAI->getGlobalDirective();
-      
+   
+    // This is called in initialization. Hence information of the current
+    // function line is not available. Hence UnspecifiedLine. UnspecifiedLine
+    // will be treated as MainLine. 
+    PAN::updateCallLineSymbol(Name, PAN::UnspecifiedLine);
     O << directive << Name << "\n";
     O << directive << PAN::getRetvalLabel(Name) << "\n";
     O << directive << PAN::getArgsLabel(Name) << "\n";
@@ -423,6 +446,13 @@
 
   // Now print Autos section for this function.
   std::string SectionName = PAN::getAutosSectionName(FunctName);
+
+  // If this function is a cloned function then the name of auto section 
+  // will not be present in the list of existing section. Hence this section
+  // should be cloned. 
+  // This function will check and clone
+  PTOF->createClonedSectionForAutos(SectionName);
+
   const std::vector<PIC16Section*> &AutosSections = PTOF->AutosSections;
   for (unsigned i = 0; i < AutosSections.size(); i++) {
     O << "\n";
@@ -436,6 +466,8 @@
         Constant *C = Items[j]->getInitializer();
         const Type *Ty = C->getType();
         unsigned Size = TD->getTypeAllocSize(Ty);
+        // Auto variables should be cloned for the cloned function 
+        PAN::updateCallLineAutos(VarName, CurrentFnName);
         // Emit memory reserve directive.
         O << VarName << "  RES  " << Size << "\n";
       }

Modified: llvm/trunk/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.h?rev=79562&r1=79561&r2=79562&view=diff

==============================================================================
--- llvm/trunk/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.h (original)
+++ llvm/trunk/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.h Thu Aug 20 14:28:24 2009
@@ -73,6 +73,7 @@
     PIC16DbgInfo DbgInfo;
     const PIC16TargetAsmInfo *PTAI;
     std::list<const char *> LibcallDecls; // List of extern decls.
+    const Function *CurrentFnPtr;   // Hold the pointer to current Function 
   };
 } // end of namespace
 

Modified: llvm/trunk/lib/Target/PIC16/Makefile
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/Makefile?rev=79562&r1=79561&r2=79562&view=diff

==============================================================================
--- llvm/trunk/lib/Target/PIC16/Makefile (original)
+++ llvm/trunk/lib/Target/PIC16/Makefile Thu Aug 20 14:28:24 2009
@@ -17,7 +17,7 @@
 		PIC16GenDAGISel.inc PIC16GenCallingConv.inc \
 		PIC16GenSubtarget.inc
 
-DIRS = AsmPrinter TargetInfo
+DIRS = AsmPrinter TargetInfo PIC16Passes
 
 include $(LEVEL)/Makefile.common
 

Modified: llvm/trunk/lib/Target/PIC16/PIC16.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16.h?rev=79562&r1=79561&r2=79562&view=diff

==============================================================================
--- llvm/trunk/lib/Target/PIC16/PIC16.h (original)
+++ llvm/trunk/lib/Target/PIC16/PIC16.h Thu Aug 20 14:28:24 2009
@@ -22,6 +22,7 @@
 #include <sstream>
 #include <cstring>
 #include <string>
+#include "PIC16PAN.h"
 
 namespace llvm {
   class PIC16TargetMachine;
@@ -43,268 +44,6 @@
     UGE
   };
 }
-  // A Central class to manage all ABI naming conventions.
-  // PAN - [P]ic16 [A]BI [N]ames
-  class PAN {
-    public:
-    // Map the name of the symbol to its section name.
-    // Current ABI:
-    // -----------------------------------------------------
-    // ALL Names are prefixed with the symobl '@'.
-    // ------------------------------------------------------
-    // Global variables do not have any '.' in their names.
-    // These are maily function names and global variable names.
-    // Example - @foo,  @i
-    // -------------------------------------------------------
-    // Functions and auto variables.
-    // Names are mangled as <prefix><funcname>.<tag>.<varname>
-    // Where <prefix> is '@' and <tag> is any one of
-    // the following
-    // .auto. - an automatic var of a function.
-    // .temp. - temproray data of a function.
-    // .ret.  - return value label for a function.
-    // .frame. - Frame label for a function where retval, args
-    //           and temps are stored.
-    // .args. - Label used to pass arguments to a direct call.
-    // Example - Function name:   @foo
-    //           Its frame:       @foo.frame.
-    //           Its retval:      @foo.ret.
-    //           Its local vars:  @foo.auto.a
-    //           Its temp data:   @foo.temp.
-    //           Its arg passing: @foo.args.
-    //----------------------------------------------
-    // Libcall - compiler generated libcall names must start with .lib.
-    //           This id will be used to emit extern decls for libcalls.
-    // Example - libcall name:   @.lib.sra.i8
-    //           To pass args:   @.lib.sra.i8.args.
-    //           To return val:  @.lib.sra.i8.ret.
-    //----------------------------------------------
-    // SECTION Names
-    // uninitialized globals - @udata.<num>.#
-    // initialized globals - @idata.<num>.#
-    // Function frame - @<func>.frame_section.
-    // Function autos - @<func>.autos_section.
-    // Declarations - Enclosed in comments. No section for them.
-    //----------------------------------------------------------
-    
-    // Tags used to mangle different names. 
-    enum TAGS {
-      PREFIX_SYMBOL,
-      GLOBAL,
-      STATIC_LOCAL,
-      AUTOS_LABEL,
-      FRAME_LABEL,
-      RET_LABEL,
-      ARGS_LABEL,
-      TEMPS_LABEL,
-      
-      LIBCALL,
-      
-      FRAME_SECTION,
-      AUTOS_SECTION,
-      CODE_SECTION
-    };
-
-    // Textual names of the tags.
-    inline static const char *getTagName(TAGS tag) {
-      switch (tag) {
-      default: return "";
-      case PREFIX_SYMBOL:    return "@";
-      case AUTOS_LABEL:       return ".auto.";
-      case FRAME_LABEL:       return ".frame.";
-      case TEMPS_LABEL:       return ".temp.";
-      case ARGS_LABEL:       return ".args.";
-      case RET_LABEL:       return ".ret.";
-      case LIBCALL:       return ".lib.";
-      case FRAME_SECTION:       return ".frame_section.";
-      case AUTOS_SECTION:       return ".autos_section.";
-      case CODE_SECTION:       return ".code_section.";
-      }
-    }
-
-    // Get tag type for the Symbol.
-    inline static TAGS getSymbolTag(const std::string &Sym) {
-      if (Sym.find(getTagName(TEMPS_LABEL)) != std::string::npos)
-        return TEMPS_LABEL;
-
-      if (Sym.find(getTagName(FRAME_LABEL)) != std::string::npos)
-        return FRAME_LABEL;
-
-      if (Sym.find(getTagName(RET_LABEL)) != std::string::npos)
-        return RET_LABEL;
-
-      if (Sym.find(getTagName(ARGS_LABEL)) != std::string::npos)
-        return ARGS_LABEL;
-
-      if (Sym.find(getTagName(AUTOS_LABEL)) != std::string::npos)
-        return AUTOS_LABEL;
-
-      if (Sym.find(getTagName(LIBCALL)) != std::string::npos)
-        return LIBCALL;
-
-      // It does not have any Tag. So its a true global or static local.
-      if (Sym.find(".") == std::string::npos) 
-        return GLOBAL;
-      
-      // If a . is there, then it may be static local.
-      // We should mangle these as well in clang.
-      if (Sym.find(".") != std::string::npos) 
-        return STATIC_LOCAL;
- 
-      assert (0 && "Could not determine Symbol's tag");
-      return PREFIX_SYMBOL; // Silence warning when assertions are turned off.
-    }
-
-    // addPrefix - add prefix symbol to a name if there isn't one already.
-    inline static std::string addPrefix (const std::string &Name) {
-      std::string prefix = getTagName (PREFIX_SYMBOL);
-
-      // If this name already has a prefix, nothing to do.
-      if (Name.compare(0, prefix.size(), prefix) == 0)
-        return Name;
-
-      return prefix + Name;
-    }
-
-    // Get mangled func name from a mangled sym name.
-    // In all cases func name is the first component before a '.'.
-    static inline std::string getFuncNameForSym(const std::string &Sym1) {
-      assert (getSymbolTag(Sym1) != GLOBAL && "not belongs to a function");
-
-      std::string Sym = addPrefix(Sym1);
-
-      // Position of the . after func name. That's where func name ends.
-      size_t func_name_end = Sym.find ('.');
-
-      return Sym.substr (0, func_name_end);
-    }
-
-    // Get Frame start label for a func.
-    static std::string getFrameLabel(const std::string &Func) {
-      std::string Func1 = addPrefix(Func);
-      std::string tag = getTagName(FRAME_LABEL);
-      return Func1 + tag;
-    }
-
-    static std::string getRetvalLabel(const std::string &Func) {
-      std::string Func1 = addPrefix(Func);
-      std::string tag = getTagName(RET_LABEL);
-      return Func1 + tag;
-    }
-
-    static std::string getArgsLabel(const std::string &Func) {
-      std::string Func1 = addPrefix(Func);
-      std::string tag = getTagName(ARGS_LABEL);
-      return Func1 + tag;
-    }
-
-    static std::string getTempdataLabel(const std::string &Func) {
-      std::string Func1 = addPrefix(Func);
-      std::string tag = getTagName(TEMPS_LABEL);
-      return Func1 + tag;
-    }
-
-    static std::string getFrameSectionName(const std::string &Func) {
-      std::string Func1 = addPrefix(Func);
-      std::string tag = getTagName(FRAME_SECTION);
-      return Func1 + tag + "# UDATA_OVR";
-    }
-
-    static std::string getAutosSectionName(const std::string &Func) {
-      std::string Func1 = addPrefix(Func);
-      std::string tag = getTagName(AUTOS_SECTION);
-      return Func1 + tag + "# UDATA_OVR";
-    }
-
-    static std::string getCodeSectionName(const std::string &Func) {
-      std::string Func1 = addPrefix(Func);
-      std::string tag = getTagName(CODE_SECTION);
-      return Func1 + tag + "# CODE";
-    }
-
-    // udata, romdata and idata section names are generated by a given number.
-    // @udata.<num>.# 
-    static std::string getUdataSectionName(unsigned num, 
-                                           std::string prefix = "") {
-       std::ostringstream o;
-       o << getTagName(PREFIX_SYMBOL) << prefix << "udata." << num 
-         << ".# UDATA"; 
-       return o.str(); 
-    }
-
-    static std::string getRomdataSectionName(unsigned num,
-                                             std::string prefix = "") {
-       std::ostringstream o;
-       o << getTagName(PREFIX_SYMBOL) << prefix << "romdata." << num 
-         << ".# ROMDATA";
-       return o.str();
-    }
-
-    static std::string getIdataSectionName(unsigned num,
-                                           std::string prefix = "") {
-       std::ostringstream o;
-       o << getTagName(PREFIX_SYMBOL) << prefix << "idata." << num 
-         << ".# IDATA"; 
-       return o.str(); 
-    }
-
-    inline static bool isLocalName (const std::string &Name) {
-      if (getSymbolTag(Name) == AUTOS_LABEL)
-        return true;
-
-      return false;
-    }
-
-    inline static bool isMemIntrinsic (const std::string &Name) {
-      if (Name.compare("@memcpy") == 0 || Name.compare("@memset") == 0 ||
-          Name.compare("@memmove") == 0) {
-        return true;
-      }
-      
-      return false;
-    }
-
-    inline static bool isLocalToFunc (std::string &Func, std::string &Var) {
-      if (! isLocalName(Var)) return false;
-
-      std::string Func1 = addPrefix(Func);
-      // Extract func name of the varilable.
-      const std::string &fname = getFuncNameForSym(Var);
-
-      if (fname.compare(Func1) == 0)
-        return true;
-
-      return false;
-    }
-
-
-    // Get the section for the given external symbol names.
-    // This tries to find the type (Tag) of the symbol from its mangled name
-    // and return appropriate section name for it.
-    static inline std::string getSectionNameForSym(const std::string &Sym1) {
-      std::string Sym = addPrefix(Sym1);
-
-      std::string SectionName;
- 
-      std::string Fname = getFuncNameForSym (Sym);
-      TAGS id = getSymbolTag (Sym);
-
-      switch (id) {
-        default : assert (0 && "Could not determine external symbol type");
-        case FRAME_LABEL:
-        case RET_LABEL:
-        case TEMPS_LABEL:
-        case ARGS_LABEL:  {
-          return getFrameSectionName(Fname);
-        }
-        case AUTOS_LABEL: {
-          return getAutosSectionName(Fname);
-        }
-      }
-    }
-  }; // class PAN.
-
-
   // External symbol names require memory to live till the program end.
   // So we have to allocate it and keep.
   inline static const char *createESName (const std::string &name) {

Modified: llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp?rev=79562&r1=79561&r2=79562&view=diff

==============================================================================
--- llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp Thu Aug 20 14:28:24 2009
@@ -443,6 +443,7 @@
   case PIC16ISD::SELECT_ICC:       return "PIC16ISD::SELECT_ICC";
   case PIC16ISD::BRCOND:           return "PIC16ISD::BRCOND";
   case PIC16ISD::RET:              return "PIC16ISD::RET";
+  case PIC16ISD::RETFIE:           return "PIC16ISD::RETFIE";
   case PIC16ISD::Dummy:            return "PIC16ISD::Dummy";
   }
 }
@@ -1272,7 +1273,10 @@
                         DAG.getConstant (i, MVT::i8));
       
   }
-  return DAG.getNode(PIC16ISD::RET, dl, MVT::Other, Chain);
+  if (PAN::isISR(F))
+     return DAG.getNode(PIC16ISD::RETFIE, dl, MVT::Other, Chain);
+  else
+     return DAG.getNode(PIC16ISD::RET, dl, MVT::Other, Chain);
 }
 
 void PIC16TargetLowering::

Modified: llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.h?rev=79562&r1=79561&r2=79562&view=diff

==============================================================================
--- llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.h (original)
+++ llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.h Thu Aug 20 14:28:24 2009
@@ -53,6 +53,7 @@
       SELECT_ICC,    // Psuedo to be caught in schedular and expanded to brcond.
       BRCOND,        // Conditional branch.
       RET,           // Return.
+      RETFIE,        // Return from interrupt
       Dummy
     };
 

Modified: llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.td?rev=79562&r1=79561&r2=79562&view=diff

==============================================================================
--- llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.td (original)
+++ llvm/trunk/lib/Target/PIC16/PIC16InstrInfo.td Thu Aug 20 14:28:24 2009
@@ -117,6 +117,7 @@
 
 def PIC16ret       : SDNode<"PIC16ISD::RET", SDTNone, [SDNPHasChain]>;
 
+def PIC16Retfie : SDNode<"PIC16ISD::RETFIE", SDTNone, [SDNPHasChain]>;
 //===----------------------------------------------------------------------===//
 // PIC16 Operand Definitions.
 //===----------------------------------------------------------------------===//
@@ -497,6 +498,10 @@
 def Return : 
   ControlFormat<0, (outs), (ins), "return", [(PIC16ret)]>;
 
+//Return instruction to return from ISR
+let isTerminator = 1, isBarrier = 1, isReturn = 1 in
+def Retfie : 
+  ControlFormat<0, (outs), (ins), "retfie", [(PIC16Retfie)]>;
 //===----------------------------------------------------------------------===//
 // PIC16 Replacment Patterns.
 //===----------------------------------------------------------------------===//

Added: llvm/trunk/lib/Target/PIC16/PIC16PAN.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16PAN.h?rev=79562&view=auto

==============================================================================
--- llvm/trunk/lib/Target/PIC16/PIC16PAN.h (added)
+++ llvm/trunk/lib/Target/PIC16/PIC16PAN.h Thu Aug 20 14:28:24 2009
@@ -0,0 +1,421 @@
+//===-- PIC16PAN.h - PIC16 ABI Naming conventions --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source 
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the entry points for global functions defined in 
+// the LLVM PIC16 back-end.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_PIC16PAN_H
+#define LLVM_TARGET_PIC16PAN_H
+
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Function.h"
+#include <iosfwd>
+#include <cassert>
+#include <cstring>
+#include <string>
+
+namespace llvm {
+  // A Central class to manage all ABI naming conventions.
+  // PAN - [P]ic16 [A]BI [N]ames
+  class PAN {
+    public:
+    // Map the name of the symbol to its section name.
+    // Current ABI:
+    // -----------------------------------------------------
+    // ALL Names are prefixed with the symobl '@'.
+    // ------------------------------------------------------
+    // Global variables do not have any '.' in their names.
+    // These are maily function names and global variable names.
+    // Example - @foo,  @i
+    // -------------------------------------------------------
+    // Functions and auto variables.
+    // Names are mangled as <prefix><funcname>.<tag>.<varname>
+    // Where <prefix> is '@' and <tag> is any one of
+    // the following
+    // .auto. - an automatic var of a function.
+    // .temp. - temproray data of a function.
+    // .ret.  - return value label for a function.
+    // .frame. - Frame label for a function where retval, args
+    //           and temps are stored.
+    // .args. - Label used to pass arguments to a direct call.
+    // Example - Function name:   @foo
+    //           Its frame:       @foo.frame.
+    //           Its retval:      @foo.ret.
+    //           Its local vars:  @foo.auto.a
+    //           Its temp data:   @foo.temp.
+    //           Its arg passing: @foo.args.
+    //----------------------------------------------
+    // Libcall - compiler generated libcall names must start with .lib.
+    //           This id will be used to emit extern decls for libcalls.
+    // Example - libcall name:   @.lib.sra.i8
+    //           To pass args:   @.lib.sra.i8.args.
+    //           To return val:  @.lib.sra.i8.ret.
+    //----------------------------------------------
+    // SECTION Names
+    // uninitialized globals - @udata.<num>.#
+    // initialized globals - @idata.<num>.#
+    // Function frame - @<func>.frame_section.
+    // Function autos - @<func>.autos_section.
+    // Declarations - Enclosed in comments. No section for them.
+    //----------------------------------------------------------
+    
+    // Tags used to mangle different names. 
+    enum TAGS {
+      PREFIX_SYMBOL,
+      GLOBAL,
+      STATIC_LOCAL,
+      AUTOS_LABEL,
+      FRAME_LABEL,
+      RET_LABEL,
+      ARGS_LABEL,
+      TEMPS_LABEL,
+      
+      LIBCALL,
+      
+      FRAME_SECTION,
+      AUTOS_SECTION,
+      CODE_SECTION
+    };
+    enum CallLine {
+      MainLine,
+      InterruptLine,
+      SharedLine,
+      UnspecifiedLine
+    };
+
+    // Textual names of the tags.
+    inline static const char *getTagName(TAGS tag) {
+      switch (tag) {
+      default: return "";
+      case PREFIX_SYMBOL:    return "@";
+      case AUTOS_LABEL:       return ".auto.";
+      case FRAME_LABEL:       return ".frame.";
+      case TEMPS_LABEL:       return ".temp.";
+      case ARGS_LABEL:       return ".args.";
+      case RET_LABEL:       return ".ret.";
+      case LIBCALL:       return ".lib.";
+      case FRAME_SECTION:       return ".frame_section.";
+      case AUTOS_SECTION:       return ".autos_section.";
+      case CODE_SECTION:       return ".code_section.";
+      }
+    }
+
+    inline static bool isISR(const Function *F) {
+       if (F->getSection().find("interrupt") != std::string::npos)
+         return true; 
+
+       return false;
+    } 
+    inline static bool isInterruptLineFunction(const Function *F) {
+       if (isISR(F)) return true;
+       if (F->getSection().find("IL") != std::string::npos)
+         return true; 
+
+       return false;
+    }
+    inline static bool isMainLineFunction(const Function *F) {
+       if (F->getSection().find("ML") != std::string::npos)
+         return true; 
+
+       return false;
+    }
+    inline static bool isSharedLineFunction(const Function *F) {
+       if (F->getSection().find("SL") != std::string::npos)
+         return true; 
+
+       return false;
+    }
+
+    inline static const char *getUpdatedLibCallDecl(const char *Name, 
+                                              const Function *F) {
+       // If the current function is not an interrupt line function then 
+       // there is no need to change the name.
+       if (!isInterruptLineFunction(F))
+          return Name;
+
+
+       // CAUTION::This code may cause some memory leak and at times
+       // use more memory than required.
+       // (We will try to clean it sometime later)
+
+       // InterruptLine functions should hold ".IL" suffix and
+       char *NewName = (char *)malloc(strlen(Name) + 3 + 1);
+       strcpy(NewName, Name);
+       strcat(NewName, ".IL");
+       return NewName;
+    }
+
+    inline static void updateCallLineAutos(std::string &Sym, std::string FuncName) {
+      // If the function has ".IL" in its name then it must be
+      // a cloned function and autos for such a function should also
+      // have ".IL" in their name. So update them here.
+      if (FuncName.find(".IL") != std::string::npos)
+          Sym.replace(Sym.find(".auto"), 5, ".IL.auto");
+    }
+
+    // Insert ".IL" at proper location in the ARGS and RET symbols
+    inline static void updateCallLineLibcall(std::string &Sym) {
+       std::string SubStr;
+       std::size_t pos;
+       std::string Suffix;
+       if (getSymbolTag(Sym) == ARGS_LABEL) {
+          Suffix = getTagName(ARGS_LABEL);
+          pos = Sym.find(Suffix);
+          SubStr = Sym.substr(0,pos);
+       } else if (getSymbolTag(Sym) == RET_LABEL) {
+          Suffix = getTagName(RET_LABEL);
+          pos = Sym.find(Suffix);
+          SubStr = Sym.substr(0,pos);
+       } else {
+          SubStr = Sym;
+          Suffix = "";
+       }
+       Sym = SubStr + ".IL" + Suffix;
+    }
+
+    inline static void updateCallLineSymbol(std::string &Sym, CallLine CLine) {
+      if (isLIBCALLSymbol(Sym) && CLine == InterruptLine) {
+         updateCallLineLibcall(Sym);
+         return;
+      }
+         
+       // UnMangle the function name - mangled in llvm-ld
+       // For MainLine function the shared string should be removed
+       // and for InterruptLine function the shared string should be 
+       // replaced with ".IL"
+       std::string ReplaceString="";
+       if (CLine == MainLine || CLine == UnspecifiedLine)
+         ReplaceString = "";
+       else if (CLine == InterruptLine)
+         ReplaceString = ".IL";
+       std::string FindString = ".shared";
+       if (Sym.find(FindString) != std::string::npos) {
+         Sym.replace(Sym.find(FindString), FindString.length(), ReplaceString);
+         return;
+       }
+    } 
+
+    inline static void updateCallLineSymbol(std::string &Sym, 
+                                            const Function *F) {
+       // If it is an auto symbol then it should be updated accordingly
+       if (Sym.find(".auto") != std::string::npos) {
+         updateCallLineAutos(Sym, F->getName().str());
+         return;
+       } 
+
+       if (isMainLineFunction(F))
+         updateCallLineSymbol(Sym, MainLine);
+       else if (isInterruptLineFunction(F))
+         updateCallLineSymbol(Sym, InterruptLine);
+       else
+         updateCallLineSymbol(Sym, UnspecifiedLine);
+    }
+
+    inline static bool isLIBCALLSymbol(const std::string &Sym) {
+      if (Sym.find(getTagName(LIBCALL)) != std::string::npos)
+        return true;
+     
+      return false;
+    }
+
+    // Get tag type for the Symbol.
+    inline static TAGS getSymbolTag(const std::string &Sym) {
+      if (Sym.find(getTagName(TEMPS_LABEL)) != std::string::npos)
+        return TEMPS_LABEL;
+
+      if (Sym.find(getTagName(FRAME_LABEL)) != std::string::npos)
+        return FRAME_LABEL;
+
+      if (Sym.find(getTagName(RET_LABEL)) != std::string::npos)
+        return RET_LABEL;
+
+      if (Sym.find(getTagName(ARGS_LABEL)) != std::string::npos)
+        return ARGS_LABEL;
+
+      if (Sym.find(getTagName(AUTOS_LABEL)) != std::string::npos)
+        return AUTOS_LABEL;
+
+      if (Sym.find(getTagName(LIBCALL)) != std::string::npos)
+        return LIBCALL;
+
+      // It does not have any Tag. So its a true global or static local.
+      if (Sym.find(".") == std::string::npos) 
+        return GLOBAL;
+      
+      // If a . is there, then it may be static local.
+      // We should mangle these as well in clang.
+      if (Sym.find(".") != std::string::npos) 
+        return STATIC_LOCAL;
+ 
+      assert (0 && "Could not determine Symbol's tag");
+      return PREFIX_SYMBOL; // Silence warning when assertions are turned off.
+    }
+
+    // addPrefix - add prefix symbol to a name if there isn't one already.
+    inline static std::string addPrefix (const std::string &Name) {
+      std::string prefix = getTagName (PREFIX_SYMBOL);
+
+      // If this name already has a prefix, nothing to do.
+      if (Name.compare(0, prefix.size(), prefix) == 0)
+        return Name;
+
+      return prefix + Name;
+    }
+
+    // Get mangled func name from a mangled sym name.
+    // In all cases func name is the first component before a '.'.
+    static inline std::string getFuncNameForSym(const std::string &Sym1) {
+      assert (getSymbolTag(Sym1) != GLOBAL && "not belongs to a function");
+
+      std::string Sym = addPrefix(Sym1);
+
+      // Position of the . after func name. That's where func name ends.
+      size_t func_name_end = Sym.find ('.');
+
+      return Sym.substr (0, func_name_end);
+    }
+
+    // Get Frame start label for a func.
+    static std::string getFrameLabel(const std::string &Func) {
+      std::string Func1 = addPrefix(Func);
+      std::string tag = getTagName(FRAME_LABEL);
+      return Func1 + tag;
+    }
+
+    static std::string getRetvalLabel(const std::string &Func) {
+      std::string Func1 = addPrefix(Func);
+      std::string tag = getTagName(RET_LABEL);
+      return Func1 + tag;
+    }
+
+    static std::string getArgsLabel(const std::string &Func) {
+      std::string Func1 = addPrefix(Func);
+      std::string tag = getTagName(ARGS_LABEL);
+      return Func1 + tag;
+    }
+
+    static std::string getTempdataLabel(const std::string &Func) {
+      std::string Func1 = addPrefix(Func);
+      std::string tag = getTagName(TEMPS_LABEL);
+      return Func1 + tag;
+    }
+
+    static std::string getFrameSectionName(const std::string &Func) {
+      std::string Func1 = addPrefix(Func);
+      std::string tag = getTagName(FRAME_SECTION);
+      return Func1 + tag + "# UDATA_OVR";
+    }
+
+    static std::string getAutosSectionName(const std::string &Func) {
+      std::string Func1 = addPrefix(Func);
+      std::string tag = getTagName(AUTOS_SECTION);
+      return Func1 + tag + "# UDATA_OVR";
+    }
+
+    static std::string getCodeSectionName(const std::string &Func, bool isInterrupt) {
+      std::string Func1 = addPrefix(Func);
+      std::string tag = getTagName(CODE_SECTION);
+      std::string Name = Func1 + tag + "# CODE";
+
+      // If this is an interrupt function then the code section should
+      // be placed at address 0x4 (hard)
+      if (isInterrupt)
+         Name += "    0x4";
+
+      return Name;
+    }
+
+    // udata, romdata and idata section names are generated by a given number.
+    // @udata.<num>.# 
+    static std::string getUdataSectionName(unsigned num, 
+                                           std::string prefix = "") {
+       std::ostringstream o;
+       o << getTagName(PREFIX_SYMBOL) << prefix << "udata." << num 
+         << ".# UDATA"; 
+       return o.str(); 
+    }
+
+    static std::string getRomdataSectionName(unsigned num,
+                                             std::string prefix = "") {
+       std::ostringstream o;
+       o << getTagName(PREFIX_SYMBOL) << prefix << "romdata." << num 
+         << ".# ROMDATA";
+       return o.str();
+    }
+
+    static std::string getIdataSectionName(unsigned num,
+                                           std::string prefix = "") {
+       std::ostringstream o;
+       o << getTagName(PREFIX_SYMBOL) << prefix << "idata." << num 
+         << ".# IDATA"; 
+       return o.str(); 
+    }
+
+    inline static bool isLocalName (const std::string &Name) {
+      if (getSymbolTag(Name) == AUTOS_LABEL)
+        return true;
+
+      return false;
+    }
+
+    inline static bool isMemIntrinsic (const std::string &Name) {
+      if (Name.compare("@memcpy") == 0 || Name.compare("@memset") == 0 ||
+          Name.compare("@memmove") == 0) {
+        return true;
+      }
+      
+      return false;
+    }
+
+    inline static bool isLocalToFunc (std::string &Func, std::string &Var) {
+      if (! isLocalName(Var)) return false;
+
+      std::string Func1 = addPrefix(Func);
+      // Extract func name of the varilable.
+      const std::string &fname = getFuncNameForSym(Var);
+
+      if (fname.compare(Func1) == 0)
+        return true;
+
+      return false;
+    }
+
+
+    // Get the section for the given external symbol names.
+    // This tries to find the type (Tag) of the symbol from its mangled name
+    // and return appropriate section name for it.
+    static inline std::string getSectionNameForSym(const std::string &Sym1) {
+      std::string Sym = addPrefix(Sym1);
+
+      std::string SectionName;
+ 
+      std::string Fname = getFuncNameForSym (Sym);
+      TAGS id = getSymbolTag (Sym);
+
+      switch (id) {
+        default : assert (0 && "Could not determine external symbol type");
+        case FRAME_LABEL:
+        case RET_LABEL:
+        case TEMPS_LABEL:
+        case ARGS_LABEL:  {
+          return getFrameSectionName(Fname);
+        }
+        case AUTOS_LABEL: {
+          return getAutosSectionName(Fname);
+        }
+      }
+    }
+  }; // class PAN.
+
+} // end namespace llvm;
+
+#endif

Modified: llvm/trunk/lib/Target/PIC16/PIC16TargetObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16TargetObjectFile.cpp?rev=79562&r1=79561&r2=79562&view=diff

==============================================================================
--- llvm/trunk/lib/Target/PIC16/PIC16TargetObjectFile.cpp (original)
+++ llvm/trunk/lib/Target/PIC16/PIC16TargetObjectFile.cpp Thu Aug 20 14:28:24 2009
@@ -70,8 +70,8 @@
 }
 
 const MCSection *PIC16TargetObjectFile::
-getSectionForFunction(const std::string &FnName) const {
-  std::string T = PAN::getCodeSectionName(FnName);
+getSectionForFunction(const std::string &FnName, bool isInterrupt) const {
+  std::string T = PAN::getCodeSectionName(FnName, isInterrupt);
   return getPIC16Section(T.c_str(), SectionKind::getText());
 }
 
@@ -196,6 +196,48 @@
   return FoundAutoSec->S_;
 }
 
+void PIC16TargetObjectFile::createClonedSectionForAutos(const std::string &SecName) {
+
+  // If the function is cloned then it will have ".IL" in its name
+  // If this function is not cloned then return;
+  if (SecName.find(".IL") == std::string::npos) 
+      return;
+
+  // Come here if the function is cloned.
+  // Get the name of the original section from which it has been cloned.
+  std::string OrigName = SecName;
+  OrigName.replace(SecName.find(".IL"),3,"");
+
+  // Find original section
+  PIC16Section *FoundAutoSec = NULL;
+  for (unsigned i = 0; i < AutosSections.size(); i++) {
+    if (AutosSections[i]->S_->getName() == OrigName) {
+      FoundAutoSec = AutosSections[i];
+      break; 
+    }
+  }
+
+  // No auto section exists for the original function.
+  if (!FoundAutoSec)
+    return;
+
+  // Create new section for the cloned function 
+  const MCSectionPIC16 *NewSection =
+      getPIC16Section(SecName.c_str(), SectionKind::getMetadata());
+  
+  PIC16Section *NewAutoSec = new PIC16Section(NewSection);
+  // Add this newly created autos section to the list of AutosSections.
+  AutosSections.push_back(NewAutoSec);
+
+  // Add the items from the original section to the new section
+  // Donot mangle them here. Because mangling them here will distort 
+  // the original names. 
+  // These names will be mangled them at the time of printing only
+  const std::vector<const GlobalVariable*> &Items = FoundAutoSec->Items;
+  for (unsigned j = 0; j < Items.size(); j++) {
+    NewAutoSec->Items.push_back(Items[j]); 
+  }
+}
 
 // Override default implementation to put the true globals into
 // multiple data sections if required.

Modified: llvm/trunk/lib/Target/PIC16/PIC16TargetObjectFile.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16TargetObjectFile.h?rev=79562&r1=79561&r2=79562&view=diff

==============================================================================
--- llvm/trunk/lib/Target/PIC16/PIC16TargetObjectFile.h (original)
+++ llvm/trunk/lib/Target/PIC16/PIC16TargetObjectFile.h Thu Aug 20 14:28:24 2009
@@ -77,10 +77,13 @@
                                                     Mangler *Mang,
                                                     const TargetMachine&) const;
 
-    const MCSection *getSectionForFunction(const std::string &FnName) const;
+    const MCSection *getSectionForFunction(const std::string &FnName, 
+                                           bool isInterrupt=false) const;
     const MCSection *getSectionForFunctionFrame(const std::string &FnName)const;
     
-    
+    // If the current function is cloned then create the new autos section
+    // also. 
+    void createClonedSectionForAutos(const std::string &SecName);
   private:
     std::string getSectionNameForSym(const std::string &Sym) const;
 





More information about the llvm-commits mailing list