Allow symbols to start from the digit if target requests it. This allows, e.g. pinning
variables to specified absolute address. Make use of this feature for MSP430.
This unbreaks PR4776.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@82227 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h
index 98e43a3..fb69630 100644
--- a/include/llvm/MC/MCAsmInfo.h
+++ b/include/llvm/MC/MCAsmInfo.h
@@ -95,6 +95,10 @@
     /// AllowQuotesInName - This is true if the assembler allows for complex
     /// symbol names to be surrounded in quotes.  This defaults to false.
     bool AllowQuotesInName;
+
+    /// AllowNameToStartWithDigit - This is true if the assembler allows symbol
+    /// names to start with a digit (e.g., "0x0021").  This defaults to false.
+    bool AllowNameToStartWithDigit;
     
     //===--- Data Emission Directives -------------------------------------===//
 
@@ -354,6 +358,9 @@
     bool doesAllowQuotesInName() const {
       return AllowQuotesInName;
     }
+    bool doesAllowNameToStartWithDigit() const {
+      return AllowNameToStartWithDigit;
+    }
     const char *getZeroDirective() const {
       return ZeroDirective;
     }
diff --git a/include/llvm/Support/Mangler.h b/include/llvm/Support/Mangler.h
index 23ea377..03c5648 100644
--- a/include/llvm/Support/Mangler.h
+++ b/include/llvm/Support/Mangler.h
@@ -51,6 +51,10 @@
   /// the space character.  By default, this is false.
   bool UseQuotes;
 
+  /// SymbolsCanStartWithDigit - If this is set, the target allows symbols to
+  /// start with digits (e.g., "0x0021").  By default, this is false.
+  bool SymbolsCanStartWithDigit;
+
   /// AnonGlobalIDs - We need to give global values the same name every time
   /// they are mangled.  This keeps track of the number we give to anonymous
   /// ones.
@@ -75,9 +79,13 @@
   /// strings for assembler labels.
   void setUseQuotes(bool Val) { UseQuotes = Val; }
 
+  /// setSymbolsCanStartWithDigit - If SymbolsCanStartWithDigit is set to true,
+  /// this target allows symbols to start with digits.
+  void setSymbolsCanStartWithDigit(bool Val) { SymbolsCanStartWithDigit = Val; }
+
   /// Acceptable Characters - This allows the target to specify which characters
   /// are acceptable to the assembler without being mangled.  By default we
-  /// allow letters, numbers, '_', '$', and '.', which is what GAS accepts.
+  /// allow letters, numbers, '_', '$', '.', which is what GAS accepts, and '@'.
   void markCharAcceptable(unsigned char X) {
     AcceptableChars[X/32] |= 1 << (X&31);
   }
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 6a94287..e29bff5 100644
--- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -106,6 +106,9 @@
   
   if (MAI->doesAllowQuotesInName())
     Mang->setUseQuotes(true);
+
+  if (MAI->doesAllowNameToStartWithDigit())
+    Mang->setSymbolsCanStartWithDigit(true);
   
   GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>();
   assert(MI && "AsmPrinter didn't require GCModuleInfo?");
diff --git a/lib/MC/MCAsmInfo.cpp b/lib/MC/MCAsmInfo.cpp
index 1bba6a3..74fb930 100644
--- a/lib/MC/MCAsmInfo.cpp
+++ b/lib/MC/MCAsmInfo.cpp
@@ -34,6 +34,7 @@
   InlineAsmEnd = "NO_APP";
   AssemblerDialect = 0;
   AllowQuotesInName = false;
+  AllowNameToStartWithDigit = false;
   ZeroDirective = "\t.zero\t";
   ZeroDirectiveSuffix = 0;
   AsciiDirective = "\t.ascii\t";
diff --git a/lib/MC/MCSymbol.cpp b/lib/MC/MCSymbol.cpp
index 832f8fb..86ff3f3 100644
--- a/lib/MC/MCSymbol.cpp
+++ b/lib/MC/MCSymbol.cpp
@@ -38,8 +38,9 @@
 static bool NameNeedsEscaping(const StringRef &Str, const MCAsmInfo &MAI) {
   assert(!Str.empty() && "Cannot create an empty MCSymbol");
   
-  // If the first character is a number, we need quotes.
-  if (Str[0] >= '0' && Str[0] <= '9')
+  // If the first character is a number and the target does not allow this, we
+  // need quotes.
+  if (!MAI.doesAllowNameToStartWithDigit() && Str[0] >= '0' && Str[0] <= '9')
     return true;
 
   // If any of the characters in the string is an unacceptable character, force
@@ -50,9 +51,11 @@
   return false;
 }
 
-static void PrintMangledName(raw_ostream &OS, StringRef Str) {
-  // The first character is not allowed to be a number.
-  if (Str[0] >= '0' && Str[0] <= '9') {
+static void PrintMangledName(raw_ostream &OS, StringRef Str,
+                             const MCAsmInfo &MAI) {
+  // The first character is not allowed to be a number unless the target
+  // explicitly allows it.
+  if (!MAI.doesAllowNameToStartWithDigit() && Str[0] >= '0' && Str[0] <= '9') {
     MangleLetter(OS, Str[0]);
     Str = Str.substr(1);
   }
@@ -91,7 +94,7 @@
 
   // On systems that do not allow quoted names, print with mangling.
   if (!MAI->doesAllowQuotesInName())
-    return PrintMangledName(OS, getName());
+    return PrintMangledName(OS, getName(), *MAI);
 
   // If the string contains a double quote or newline, we still have to mangle
   // it.
diff --git a/lib/Target/MSP430/MSP430MCAsmInfo.cpp b/lib/Target/MSP430/MSP430MCAsmInfo.cpp
index 2309a5f..069313e 100644
--- a/lib/Target/MSP430/MSP430MCAsmInfo.cpp
+++ b/lib/Target/MSP430/MSP430MCAsmInfo.cpp
@@ -16,4 +16,5 @@
 
 MSP430MCAsmInfo::MSP430MCAsmInfo(const Target &T, const StringRef &TT) {
   AlignmentIsInBytes = false;
+  AllowNameToStartWithDigit = true;
 }
diff --git a/lib/VMCore/Mangler.cpp b/lib/VMCore/Mangler.cpp
index e0e2248..a5fbf26 100644
--- a/lib/VMCore/Mangler.cpp
+++ b/lib/VMCore/Mangler.cpp
@@ -47,8 +47,9 @@
       ++I;  // Skip over the marker.
     }
     
-    // Mangle the first letter specially, don't allow numbers.
-    if (*I >= '0' && *I <= '9')
+    // Mangle the first letter specially, don't allow numbers unless the target
+    // explicitly allows them.
+    if (!SymbolsCanStartWithDigit && *I >= '0' && *I <= '9')
       Result += MangleLetter(*I++);
 
     for (std::string::const_iterator E = X.end(); I != E; ++I) {
diff --git a/test/CodeGen/MSP430/2009-09-18-AbsoluteAddr.ll b/test/CodeGen/MSP430/2009-09-18-AbsoluteAddr.ll
new file mode 100644
index 0000000..cc574c7
--- /dev/null
+++ b/test/CodeGen/MSP430/2009-09-18-AbsoluteAddr.ll
@@ -0,0 +1,22 @@
+; RUN: llc < %s | grep 0x0021 | count 2
+; PR4776
+target datalayout = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8"
+target triple = "msp430-unknown-unknown"
+
+@"\010x0021" = common global i8 0, align 1        ; <i8*> [#uses=2]
+
+define zeroext i8 @foo(i8 zeroext %x) nounwind {
+entry:
+  %retval = alloca i8                             ; <i8*> [#uses=2]
+  %x.addr = alloca i8                             ; <i8*> [#uses=2]
+  %tmp = alloca i8, align 1                       ; <i8*> [#uses=2]
+  store i8 %x, i8* %x.addr
+  %tmp1 = volatile load i8* @"\010x0021"          ; <i8> [#uses=1]
+  store i8 %tmp1, i8* %tmp
+  %tmp2 = load i8* %x.addr                        ; <i8> [#uses=1]
+  volatile store i8 %tmp2, i8* @"\010x0021"
+  %tmp3 = load i8* %tmp                           ; <i8> [#uses=1]
+  store i8 %tmp3, i8* %retval
+  %0 = load i8* %retval                           ; <i8> [#uses=1]
+  ret i8 %0
+}