* PIC codegen for X86/Linux has been implemented
* PIC-aware internal structures in X86 Codegen have been refactored
* Visibility (default/weak) has been added
* Docs fixes (external weak linkage, visibility, formatting)


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33136 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/docs/BytecodeFormat.html b/docs/BytecodeFormat.html
index cc0ae7c..e65ee0c 100644
--- a/docs/BytecodeFormat.html
+++ b/docs/BytecodeFormat.html
@@ -743,7 +743,6 @@
   <li>#3: LLVM 1.3</li>
   <li>#4: LLVM 1.3.x (not released)</li>
   <li>#5: LLVM 1.4 and newer</li>
-  </li>
 </ul>
 <p>Note that we plan to eventually expand the target description
 capabilities
@@ -1082,7 +1081,11 @@
       <td class="td_left">If this bit is set, a SectionID follows this vbr.</td>
     </tr>
     <tr>
-      <td><a href="#bit">bit(10-31)</a></td>
+      <td><a href="#bit">bit(10-12)</a></td>
+      <td class="td_left">Visibility style: 0=Default, 1=Hidden.</td>
+    </tr>
+    <tr>
+      <td><a href="#bit">bit(13-31)</a></td>
       <td class="td_left">Currently unassigned.</td>
     </tr>
   </tbody>
@@ -1337,7 +1340,7 @@
 </div>
 
 <!-- _______________________________________________________________________ -->
-<div class="doc_subsubsection">Undef Entries</a></div>
+<div class="doc_subsubsection">Undef Entries</div>
 
 <div class="doc_text">
 <p>When the number of operands to the constant is one, we have an 'undef' value
@@ -1345,7 +1348,7 @@
 </div>
 
 <!-- _______________________________________________________________________ -->
-<div class="doc_subsubsection">Inline Assembler Entries</a></div>
+<div class="doc_subsubsection">Inline Assembler Entries</div>
 
 <div class="doc_text">
 <p>Inline Assembler entries are stored in the constant pool, though they are not
@@ -1369,7 +1372,7 @@
     </tr>
     <tr>
       <td><a href="#uint32_vbr">uint32_vbr</a></td>
-      <td class="td_left">Flags</sup></td>
+      <td class="td_left">Flags</td>
     </tr>
   </tbody>
 </table>
@@ -1380,7 +1383,7 @@
 </div>
 
 <!-- _______________________________________________________________________ -->
-<div class="doc_subsubsection">Constant Expression Entries</a></div>
+<div class="doc_subsubsection">Constant Expression Entries</div>
 
 <div class="doc_text">
 
@@ -1436,8 +1439,8 @@
     </tr>
     <tr>
       <td><a href="#uint32_vbr">uint32_vbr</a></td>
-      <td class="td_left">The linkage type of the function: 0=External, 1=Weak,
-2=Appending, 3=Internal, 4=LinkOnce, 5=DllImport, 6=DllExport<sup>1</sup></td>
+      <td class="td_left"><a href="#funclinkage_and_visibility">The linkage and
+      visibility</a> style field</td>
     </tr>
     <tr>
       <td><a href="#block">block</a></td>
@@ -1470,7 +1473,34 @@
 be written. Compaction tables are only written if they will actually
 save bytecode space. If not, then a regular constant pool is written.</li>
 </ol>
+
+<!-- _______________________________________________________________________ -->
+<div class="doc_subsubsection"><a name="funclinkage_and_visibility">Linkage and
+    visibility word</a>
 </div>
+<div class="doc_text">
+
+<table>
+  <tbody>
+    <tr>
+      <th><b>Type</b></th>
+      <th class="td_left"><b>Field Description</b></th>
+    </tr>
+    <tr>
+      <td><a href="#bit">bit(0-15)</a></td>
+      <td class="td_left">The linkage type of the function: 0=External, 1=Weak,
+2=Appending, 3=Internal, 4=LinkOnce, 5=DllImport, 6=DllExport<sup>1</sup></td>
+    </tr>
+    <tr>
+      <td><a href="#bit">bit(16-31)</a></td>
+      <td class="td_left">Visibility style: 0=Default, 1=Hidden.</td>
+    </tr>
+  </tbody>
+</table>
+
+</div>
+</div>
+
 <!-- _______________________________________________________________________ -->
 <div class="doc_subsection"><a name="compactiontable">Compaction Table</a>
 </div>
diff --git a/docs/LangRef.html b/docs/LangRef.html
index e9daca0..2e40842 100644
--- a/docs/LangRef.html
+++ b/docs/LangRef.html
@@ -275,7 +275,7 @@
   For example, %foo, %DivisionByZero, %a.really.long.identifier.  The actual
   regular expression used is '<tt>%[a-zA-Z$._][a-zA-Z$._0-9]*</tt>'.
   Identifiers which require other characters in their names can be surrounded
-  with quotes.  In this way, anything except a <tt>"</tt> character can be used
+  with quotes.  In this way, anything except a <tt>&quot;</tt> character can be used
   in a name.</li>
 
   <li>Unnamed values are represented as an unsigned numeric value with a '%'
@@ -452,6 +452,13 @@
   "sections" with identical names when .o files are linked.
   </dd>
 
+  <dt><tt><b><a name="linkage_externweak">extern_weak</a></b></tt>: </dt>
+  <dd>The semantics of this linkage follow the ELF model: the symbol is weak
+    until linked, if not linked, the symbol becomes null instead of being an
+    undefined reference.
+  </dd>
+</dl>
+
   <dt><tt><b><a name="linkage_external">externally visible</a></b></tt>:</dt>
 
   <dd>If none of the above identifiers are used, the global is externally
@@ -459,17 +466,13 @@
   external symbol references.
   </dd>
 
-  <dt><tt><b><a name="linkage_externweak">extern_weak</a></b></tt>: </dt>
-
-  <dd>"<tt>extern_weak</tt>" TBD
-  </dd>
-
   <p>
   The next two types of linkage are targeted for Microsoft Windows platform
   only. They are designed to support importing (exporting) symbols from (to)
   DLLs.
   </p>
 
+  <dl>
   <dt><tt><b><a name="linkage_dllimport">dllimport</a></b></tt>: </dt>
 
   <dd>"<tt>dllimport</tt>" linkage causes the compiler to reference a function
@@ -489,7 +492,7 @@
 
 </dl>
 
-<p><a name="linkage_external">For example, since the "<tt>.LC0</tt>"
+<p><a name="linkage_external"></a>For example, since the "<tt>.LC0</tt>"
 variable is defined to be internal, if another module defined a "<tt>.LC0</tt>"
 variable and was linked with this one, one of the two would be renamed,
 preventing a collision.  Since "<tt>main</tt>" and "<tt>puts</tt>" are
@@ -497,7 +500,7 @@
 outside of the current module.</p>
 <p>It is illegal for a function <i>declaration</i>
 to have any linkage type other than "externally visible", <tt>dllimport</tt>,
-or <tt>extern_weak</tt>.</a></p>
+or <tt>extern_weak</tt>.</p>
 
 </div>
 
@@ -676,13 +679,13 @@
 
   <p>Parameter attributes consist of an at sign (@) followed by either a single
   keyword or a comma separate list of keywords enclosed in parentheses. For
-  example:<pre>
+  example:</p><pre>
     %someFunc = i16 @zext (i8 @(sext) %someParam)
     %someFunc = i16 @zext (i8 @zext %someParam)</pre>
-  Note that the two function types above are unique because the parameter
-  has a different attribute (@sext in the first one, @zext in the second).</p>
+  <p>Note that the two function types above are unique because the parameter has
+  a different attribute (@sext in the first one, @zext in the second).</p>
 
-  <p>Currently, only the following parameter attributes are defined:
+  <p>Currently, only the following parameter attributes are defined:</p>
   <dl>
     <dt><tt>@zext</tt></dt>
     <dd>This indicates that the parameter should be zero extended just before
@@ -690,7 +693,7 @@
     <dt><tt>@sext</tt></dt>
     <dd>This indicates that the parameter should be sign extended just before
     a call to this function.</dd>
-  </dl></p>
+  </dl>
 
   <p>The current motivation for parameter attributes is to enable the sign and
   zero extend information necessary for the C calling convention to be passed
@@ -3053,7 +3056,7 @@
 <h5>Arguments:</h5>
 <p>The '<tt>inttoptr</tt>' instruction takes an <a href="i_integer">integer</a>
 value to cast, and a type to cast it to, which must be a 
-<a href="#t_pointer">pointer</a> type. </tt>
+<a href="#t_pointer">pointer</a> type.
 
 <h5>Semantics:</h5>
 <p>The '<tt>inttoptr</tt>' instruction converts <tt>value</tt> to type
@@ -3172,7 +3175,6 @@
   <tt>true</tt> if <tt>var1</tt> is less than <tt>var2</tt>.</li>
   <li><tt>sle</tt>: interprets the operands as signed values and yields
   <tt>true</tt> if <tt>var1</tt> is less than or equal to <tt>var2</tt>.</li>
-  </li>
 </ol>
 <p>If the operands are <a href="#t_pointer">pointer</a> typed, the pointer
 values are treated as integers and then compared.</p>
diff --git a/include/llvm/Bytecode/BytecodeHandler.h b/include/llvm/Bytecode/BytecodeHandler.h
index c693380..1d95db5 100644
--- a/include/llvm/Bytecode/BytecodeHandler.h
+++ b/include/llvm/Bytecode/BytecodeHandler.h
@@ -112,6 +112,7 @@
     const Type* ElemType,     ///< The type of the global variable
     bool isConstant,          ///< Whether the GV is constant or not
     GlobalValue::LinkageTypes,///< The linkage type of the GV
+    GlobalValue::VisibilityTypes,///< The visibility style of the GV
     unsigned SlotNum,         ///< Slot number of GV
     unsigned initSlot         ///< Slot number of GV's initializer (0 if none)
   ) {}
diff --git a/include/llvm/GlobalValue.h b/include/llvm/GlobalValue.h
index c3b96f2..2fbbbc0 100644
--- a/include/llvm/GlobalValue.h
+++ b/include/llvm/GlobalValue.h
@@ -38,14 +38,19 @@
     ExternalWeakLinkage, /// ExternalWeak linkage description
     GhostLinkage         /// Stand-in functions for streaming fns from BC files    
   };
+  enum VisibilityTypes {
+    DefaultVisibility,
+    HiddenVisibility
+  };
 protected:
   GlobalValue(const Type *Ty, ValueTy vty, Use *Ops, unsigned NumOps,
               LinkageTypes linkage, const std::string &name = "")
-    : Constant(Ty, vty, Ops, NumOps, name), 
-      Parent(0), Linkage(linkage), Alignment(0) { }
+    : Constant(Ty, vty, Ops, NumOps, name), Parent(0),
+      Linkage(linkage), Visibility(DefaultVisibility), Alignment(0) { }
 
   Module *Parent;
   LinkageTypes Linkage;   // The linkage of this global
+  VisibilityTypes Visibility;  // The visibility style of this global
   unsigned Alignment;     // Alignment of this symbol, must be power of two
   std::string Section;    // Section to emit this into, empty mean default
 public:
@@ -58,6 +63,10 @@
     assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!");
     Alignment = Align;
   }
+
+  VisibilityTypes getVisibility() const { return Visibility; }
+  bool hasHiddenVisibility() const { return Visibility == HiddenVisibility; }
+  void setVisibility(VisibilityTypes V) { Visibility = V; }
   
   bool hasSection() const { return !Section.empty(); }
   const std::string &getSection() const { return Section; }
diff --git a/lib/AsmParser/Lexer.l b/lib/AsmParser/Lexer.l
index 5300b3d..22fe64b 100644
--- a/lib/AsmParser/Lexer.l
+++ b/lib/AsmParser/Lexer.l
@@ -203,6 +203,7 @@
 appending       { return APPENDING; }
 dllimport       { return DLLIMPORT; }
 dllexport       { return DLLEXPORT; }
+hidden          { return HIDDEN; }
 extern_weak     { return EXTERN_WEAK; }
 external        { return EXTERNAL; }
 implementation  { return IMPLEMENTATION; }
diff --git a/lib/AsmParser/Lexer.l.cvs b/lib/AsmParser/Lexer.l.cvs
index 5300b3d..22fe64b 100644
--- a/lib/AsmParser/Lexer.l.cvs
+++ b/lib/AsmParser/Lexer.l.cvs
@@ -203,6 +203,7 @@
 appending       { return APPENDING; }
 dllimport       { return DLLIMPORT; }
 dllexport       { return DLLEXPORT; }
+hidden          { return HIDDEN; }
 extern_weak     { return EXTERN_WEAK; }
 external        { return EXTERNAL; }
 implementation  { return IMPLEMENTATION; }
diff --git a/lib/AsmParser/llvmAsmParser.y b/lib/AsmParser/llvmAsmParser.y
index b84cf25..52d8847 100644
--- a/lib/AsmParser/llvmAsmParser.y
+++ b/lib/AsmParser/llvmAsmParser.y
@@ -210,6 +210,7 @@
   std::map<const Type*, ValueList> LateResolveValues;
   bool isDeclare;                    // Is this function a forward declararation?
   GlobalValue::LinkageTypes Linkage; // Linkage for forward declaration.
+  GlobalValue::VisibilityTypes Visibility;
 
   /// BBForwardRefs - When we see forward references to basic blocks, keep
   /// track of them here.
@@ -220,7 +221,8 @@
   inline PerFunctionInfo() {
     CurrentFunction = 0;
     isDeclare = false;
-    Linkage = GlobalValue::ExternalLinkage;    
+    Linkage = GlobalValue::ExternalLinkage;
+    Visibility = GlobalValue::DefaultVisibility;
   }
 
   inline void FunctionStart(Function *M) {
@@ -245,6 +247,7 @@
     CurrentFunction = 0;
     isDeclare = false;
     Linkage = GlobalValue::ExternalLinkage;
+    Visibility = GlobalValue::DefaultVisibility;
   }
 } CurFun;  // Info for the current function...
 
@@ -648,7 +651,9 @@
 /// ParseGlobalVariable - Handle parsing of a global.  If Initializer is null,
 /// this is a declaration, otherwise it is a definition.
 static GlobalVariable *
-ParseGlobalVariable(char *NameStr,GlobalValue::LinkageTypes Linkage,
+ParseGlobalVariable(char *NameStr,
+                    GlobalValue::LinkageTypes Linkage,
+                    GlobalValue::VisibilityTypes Visibility,
                     bool isConstantGlobal, const Type *Ty,
                     Constant *Initializer) {
   if (isa<FunctionType>(Ty)) {
@@ -681,6 +686,7 @@
     CurModule.CurrentModule->getGlobalList().push_back(GV);
     GV->setInitializer(Initializer);
     GV->setLinkage(Linkage);
+    GV->setVisibility(Visibility);
     GV->setConstant(isConstantGlobal);
     InsertValue(GV, CurModule.Values);
     return GV;
@@ -702,6 +708,7 @@
   GlobalVariable *GV =
     new GlobalVariable(Ty, isConstantGlobal, Linkage, Initializer, Name,
                        CurModule.CurrentModule);
+  GV->setVisibility(Visibility);
   InsertValue(GV, CurModule.Values);
   return GV;
 }
@@ -898,6 +905,7 @@
   std::vector<llvm::Constant*>           *ConstVector;
 
   llvm::GlobalValue::LinkageTypes         Linkage;
+  llvm::GlobalValue::VisibilityTypes      Visibility;
   llvm::FunctionType::ParameterAttributes ParamAttrs;
   int64_t                           SInt64Val;
   uint64_t                          UInt64Val;
@@ -940,6 +948,7 @@
 %type <BoolVal>       OptSideEffect               // 'sideeffect' or not.
 %type <Linkage>       GVInternalLinkage GVExternalLinkage
 %type <Linkage>       FunctionDefineLinkage FunctionDeclareLinkage
+%type <Visibility>    GVVisibilityStyle
 %type <Endianness>    BigOrLittle
 
 // ValueRef - Unresolved reference to a definition or BB
@@ -1011,6 +1020,9 @@
 // Function Attributes
 %token NORETURN
 
+// Visibility Styles
+%token DEFAULT HIDDEN
+
 %start Module
 %%
 
@@ -1081,6 +1093,11 @@
   | EXTERNAL    { $$ = GlobalValue::ExternalLinkage; }
   ;
 
+GVVisibilityStyle
+  : /*empty*/ { $$ = GlobalValue::DefaultVisibility; }
+  | HIDDEN    { $$ = GlobalValue::HiddenVisibility;  }
+  ;
+
 FunctionDeclareLinkage
   : /*empty*/   { $$ = GlobalValue::ExternalLinkage; }
   | DLLIMPORT   { $$ = GlobalValue::DLLImportLinkage; } 
@@ -1225,7 +1242,7 @@
     if (isVarArg) Params.pop_back();
 
     FunctionType *FT = FunctionType::get(*$1, Params, isVarArg, Attrs);
-    delete $3;      // Delete the argument list
+    delete $3;   // Delete the argument list
     delete $1;   // Delete the return type handle
     $$ = new PATypeHolder(HandleUpRefs(FT)); 
     CHECK_FOR_ERROR
@@ -1883,29 +1900,29 @@
     }
     CHECK_FOR_ERROR
   }
-  | OptAssign GlobalType ConstVal { /* "Externally Visible" Linkage */
-    if ($3 == 0) 
-      GEN_ERROR("Global value initializer is not a constant!");
-    CurGV = ParseGlobalVariable($1, GlobalValue::ExternalLinkage, $2, 
-                                $3->getType(), $3);
-    CHECK_FOR_ERROR
-  } GlobalVarAttributes {
-    CurGV = 0;
-  }
-  | OptAssign GVInternalLinkage GlobalType ConstVal {
+  | OptAssign GVVisibilityStyle GlobalType ConstVal { /* "Externally Visible" Linkage */
     if ($4 == 0) 
       GEN_ERROR("Global value initializer is not a constant!");
-    CurGV = ParseGlobalVariable($1, $2, $3, $4->getType(), $4);
+    CurGV = ParseGlobalVariable($1, GlobalValue::ExternalLinkage,
+                                $2, $3, $4->getType(), $4);
     CHECK_FOR_ERROR
   } GlobalVarAttributes {
     CurGV = 0;
   }
-  | OptAssign GVExternalLinkage GlobalType Types {
-    if (!UpRefs.empty())
-      GEN_ERROR("Invalid upreference in type: " + (*$4)->getDescription());
-    CurGV = ParseGlobalVariable($1, $2, $3, *$4, 0);
+  | OptAssign GVInternalLinkage GVVisibilityStyle GlobalType ConstVal {
+    if ($5 == 0) 
+      GEN_ERROR("Global value initializer is not a constant!");
+    CurGV = ParseGlobalVariable($1, $2, $3, $4, $5->getType(), $5);
     CHECK_FOR_ERROR
-    delete $4;
+  } GlobalVarAttributes {
+    CurGV = 0;
+  }
+  | OptAssign GVExternalLinkage GVVisibilityStyle GlobalType Types {
+    if (!UpRefs.empty())
+      GEN_ERROR("Invalid upreference in type: " + (*$5)->getDescription());
+    CurGV = ParseGlobalVariable($1, $2, $3, $4, *$5, 0);
+    CHECK_FOR_ERROR
+    delete $5;
   } GlobalVarAttributes {
     CurGV = 0;
     CHECK_FOR_ERROR
@@ -2103,6 +2120,7 @@
     // correctly handle cases, when pointer to function is passed as argument to
     // another function.
     Fn->setLinkage(CurFun.Linkage);
+    Fn->setVisibility(CurFun.Visibility);
   }
   Fn->setCallingConv($1);
   Fn->setAlignment($9);
@@ -2136,12 +2154,13 @@
 
 BEGIN : BEGINTOK | '{';                // Allow BEGIN or '{' to start a function
 
-FunctionHeader : FunctionDefineLinkage FunctionHeaderH BEGIN {
+FunctionHeader : FunctionDefineLinkage GVVisibilityStyle FunctionHeaderH BEGIN {
   $$ = CurFun.CurrentFunction;
 
   // Make sure that we keep track of the linkage type even if there was a
   // previous "declare".
   $$->setLinkage($1);
+  $$->setVisibility($2);
 };
 
 END : ENDTOK | '}';                    // Allow end of '}' to end a function
@@ -2151,8 +2170,9 @@
   CHECK_FOR_ERROR
 };
 
-FunctionProto : FunctionDeclareLinkage FunctionHeaderH {
+FunctionProto : FunctionDeclareLinkage GVVisibilityStyle FunctionHeaderH {
     CurFun.CurrentFunction->setLinkage($1);
+    CurFun.CurrentFunction->setVisibility($2);
     $$ = CurFun.CurrentFunction;
     CurFun.FunctionDone();
     CHECK_FOR_ERROR
diff --git a/lib/AsmParser/llvmAsmParser.y.cvs b/lib/AsmParser/llvmAsmParser.y.cvs
index b84cf25..52d8847 100644
--- a/lib/AsmParser/llvmAsmParser.y.cvs
+++ b/lib/AsmParser/llvmAsmParser.y.cvs
@@ -210,6 +210,7 @@
   std::map<const Type*, ValueList> LateResolveValues;
   bool isDeclare;                    // Is this function a forward declararation?
   GlobalValue::LinkageTypes Linkage; // Linkage for forward declaration.
+  GlobalValue::VisibilityTypes Visibility;
 
   /// BBForwardRefs - When we see forward references to basic blocks, keep
   /// track of them here.
@@ -220,7 +221,8 @@
   inline PerFunctionInfo() {
     CurrentFunction = 0;
     isDeclare = false;
-    Linkage = GlobalValue::ExternalLinkage;    
+    Linkage = GlobalValue::ExternalLinkage;
+    Visibility = GlobalValue::DefaultVisibility;
   }
 
   inline void FunctionStart(Function *M) {
@@ -245,6 +247,7 @@
     CurrentFunction = 0;
     isDeclare = false;
     Linkage = GlobalValue::ExternalLinkage;
+    Visibility = GlobalValue::DefaultVisibility;
   }
 } CurFun;  // Info for the current function...
 
@@ -648,7 +651,9 @@
 /// ParseGlobalVariable - Handle parsing of a global.  If Initializer is null,
 /// this is a declaration, otherwise it is a definition.
 static GlobalVariable *
-ParseGlobalVariable(char *NameStr,GlobalValue::LinkageTypes Linkage,
+ParseGlobalVariable(char *NameStr,
+                    GlobalValue::LinkageTypes Linkage,
+                    GlobalValue::VisibilityTypes Visibility,
                     bool isConstantGlobal, const Type *Ty,
                     Constant *Initializer) {
   if (isa<FunctionType>(Ty)) {
@@ -681,6 +686,7 @@
     CurModule.CurrentModule->getGlobalList().push_back(GV);
     GV->setInitializer(Initializer);
     GV->setLinkage(Linkage);
+    GV->setVisibility(Visibility);
     GV->setConstant(isConstantGlobal);
     InsertValue(GV, CurModule.Values);
     return GV;
@@ -702,6 +708,7 @@
   GlobalVariable *GV =
     new GlobalVariable(Ty, isConstantGlobal, Linkage, Initializer, Name,
                        CurModule.CurrentModule);
+  GV->setVisibility(Visibility);
   InsertValue(GV, CurModule.Values);
   return GV;
 }
@@ -898,6 +905,7 @@
   std::vector<llvm::Constant*>           *ConstVector;
 
   llvm::GlobalValue::LinkageTypes         Linkage;
+  llvm::GlobalValue::VisibilityTypes      Visibility;
   llvm::FunctionType::ParameterAttributes ParamAttrs;
   int64_t                           SInt64Val;
   uint64_t                          UInt64Val;
@@ -940,6 +948,7 @@
 %type <BoolVal>       OptSideEffect               // 'sideeffect' or not.
 %type <Linkage>       GVInternalLinkage GVExternalLinkage
 %type <Linkage>       FunctionDefineLinkage FunctionDeclareLinkage
+%type <Visibility>    GVVisibilityStyle
 %type <Endianness>    BigOrLittle
 
 // ValueRef - Unresolved reference to a definition or BB
@@ -1011,6 +1020,9 @@
 // Function Attributes
 %token NORETURN
 
+// Visibility Styles
+%token DEFAULT HIDDEN
+
 %start Module
 %%
 
@@ -1081,6 +1093,11 @@
   | EXTERNAL    { $$ = GlobalValue::ExternalLinkage; }
   ;
 
+GVVisibilityStyle
+  : /*empty*/ { $$ = GlobalValue::DefaultVisibility; }
+  | HIDDEN    { $$ = GlobalValue::HiddenVisibility;  }
+  ;
+
 FunctionDeclareLinkage
   : /*empty*/   { $$ = GlobalValue::ExternalLinkage; }
   | DLLIMPORT   { $$ = GlobalValue::DLLImportLinkage; } 
@@ -1225,7 +1242,7 @@
     if (isVarArg) Params.pop_back();
 
     FunctionType *FT = FunctionType::get(*$1, Params, isVarArg, Attrs);
-    delete $3;      // Delete the argument list
+    delete $3;   // Delete the argument list
     delete $1;   // Delete the return type handle
     $$ = new PATypeHolder(HandleUpRefs(FT)); 
     CHECK_FOR_ERROR
@@ -1883,29 +1900,29 @@
     }
     CHECK_FOR_ERROR
   }
-  | OptAssign GlobalType ConstVal { /* "Externally Visible" Linkage */
-    if ($3 == 0) 
-      GEN_ERROR("Global value initializer is not a constant!");
-    CurGV = ParseGlobalVariable($1, GlobalValue::ExternalLinkage, $2, 
-                                $3->getType(), $3);
-    CHECK_FOR_ERROR
-  } GlobalVarAttributes {
-    CurGV = 0;
-  }
-  | OptAssign GVInternalLinkage GlobalType ConstVal {
+  | OptAssign GVVisibilityStyle GlobalType ConstVal { /* "Externally Visible" Linkage */
     if ($4 == 0) 
       GEN_ERROR("Global value initializer is not a constant!");
-    CurGV = ParseGlobalVariable($1, $2, $3, $4->getType(), $4);
+    CurGV = ParseGlobalVariable($1, GlobalValue::ExternalLinkage,
+                                $2, $3, $4->getType(), $4);
     CHECK_FOR_ERROR
   } GlobalVarAttributes {
     CurGV = 0;
   }
-  | OptAssign GVExternalLinkage GlobalType Types {
-    if (!UpRefs.empty())
-      GEN_ERROR("Invalid upreference in type: " + (*$4)->getDescription());
-    CurGV = ParseGlobalVariable($1, $2, $3, *$4, 0);
+  | OptAssign GVInternalLinkage GVVisibilityStyle GlobalType ConstVal {
+    if ($5 == 0) 
+      GEN_ERROR("Global value initializer is not a constant!");
+    CurGV = ParseGlobalVariable($1, $2, $3, $4, $5->getType(), $5);
     CHECK_FOR_ERROR
-    delete $4;
+  } GlobalVarAttributes {
+    CurGV = 0;
+  }
+  | OptAssign GVExternalLinkage GVVisibilityStyle GlobalType Types {
+    if (!UpRefs.empty())
+      GEN_ERROR("Invalid upreference in type: " + (*$5)->getDescription());
+    CurGV = ParseGlobalVariable($1, $2, $3, $4, *$5, 0);
+    CHECK_FOR_ERROR
+    delete $5;
   } GlobalVarAttributes {
     CurGV = 0;
     CHECK_FOR_ERROR
@@ -2103,6 +2120,7 @@
     // correctly handle cases, when pointer to function is passed as argument to
     // another function.
     Fn->setLinkage(CurFun.Linkage);
+    Fn->setVisibility(CurFun.Visibility);
   }
   Fn->setCallingConv($1);
   Fn->setAlignment($9);
@@ -2136,12 +2154,13 @@
 
 BEGIN : BEGINTOK | '{';                // Allow BEGIN or '{' to start a function
 
-FunctionHeader : FunctionDefineLinkage FunctionHeaderH BEGIN {
+FunctionHeader : FunctionDefineLinkage GVVisibilityStyle FunctionHeaderH BEGIN {
   $$ = CurFun.CurrentFunction;
 
   // Make sure that we keep track of the linkage type even if there was a
   // previous "declare".
   $$->setLinkage($1);
+  $$->setVisibility($2);
 };
 
 END : ENDTOK | '}';                    // Allow end of '}' to end a function
@@ -2151,8 +2170,9 @@
   CHECK_FOR_ERROR
 };
 
-FunctionProto : FunctionDeclareLinkage FunctionHeaderH {
+FunctionProto : FunctionDeclareLinkage GVVisibilityStyle FunctionHeaderH {
     CurFun.CurrentFunction->setLinkage($1);
+    CurFun.CurrentFunction->setVisibility($2);
     $$ = CurFun.CurrentFunction;
     CurFun.FunctionDone();
     CHECK_FOR_ERROR
diff --git a/lib/Bytecode/Reader/Analyzer.cpp b/lib/Bytecode/Reader/Analyzer.cpp
index 899a534..465e3b0 100644
--- a/lib/Bytecode/Reader/Analyzer.cpp
+++ b/lib/Bytecode/Reader/Analyzer.cpp
@@ -162,6 +162,7 @@
     const Type* ElemType,
     bool isConstant,
     GlobalValue::LinkageTypes Linkage,
+    GlobalValue::VisibilityTypes Visibility,
     unsigned SlotNum,
     unsigned initSlot
   ) {
@@ -169,7 +170,9 @@
       *os << "      GV: "
           << ( initSlot == 0 ? "Uni" : "I" ) << "nitialized, "
           << ( isConstant? "Constant, " : "Variable, ")
-          << " Linkage=" << Linkage << " Type=";
+          << " Linkage=" << Linkage
+          << " Visibility="<< Visibility
+          << " Type=";
       WriteTypeSymbolic(*os, ElemType, M);
       *os << " Slot=" << SlotNum << " InitSlot=" << initSlot
           << "\n";
@@ -206,6 +209,7 @@
       *os << "      Function Decl: ";
       WriteTypeSymbolic(*os,Func->getType(),M);
       *os <<", Linkage=" << Func->getLinkage();
+      *os <<", Visibility=" << Func->getVisibility();
       *os << "\n";
     }
   }
@@ -311,6 +315,7 @@
     if (os) {
       *os << "    BLOCK: Function {\n"
           << "      Linkage: " << Func->getLinkage() << "\n"
+          << "      Visibility: " << Func->getVisibility() << "\n"
           << "      Type: ";
       WriteTypeSymbolic(*os,Func->getType(),M);
       *os << "\n";
diff --git a/lib/Bytecode/Reader/Reader.cpp b/lib/Bytecode/Reader/Reader.cpp
index ce3826c..b91604a 100644
--- a/lib/Bytecode/Reader/Reader.cpp
+++ b/lib/Bytecode/Reader/Reader.cpp
@@ -1628,9 +1628,12 @@
 
   unsigned FuncSize = BlockEnd - At;
   GlobalValue::LinkageTypes Linkage = GlobalValue::ExternalLinkage;
+  GlobalValue::VisibilityTypes Visibility = GlobalValue::DefaultVisibility;
 
-  unsigned LinkageType = read_vbr_uint();
-  switch (LinkageType) {
+  unsigned rWord = read_vbr_uint();
+  unsigned LinkageID =  rWord & 65535;
+  unsigned VisibilityID = rWord >> 16;
+  switch (LinkageID) {
   case 0: Linkage = GlobalValue::ExternalLinkage; break;
   case 1: Linkage = GlobalValue::WeakLinkage; break;
   case 2: Linkage = GlobalValue::AppendingLinkage; break;
@@ -1644,8 +1647,17 @@
     Linkage = GlobalValue::InternalLinkage;
     break;
   }
+  switch (VisibilityID) {
+  case 0: Visibility = GlobalValue::DefaultVisibility; break;
+  case 1: Visibility = GlobalValue::HiddenVisibility; break;
+  default:
+   error("Unknown visibility type: " + utostr(VisibilityID));
+   Visibility = GlobalValue::DefaultVisibility;
+   break;
+  }
 
   F->setLinkage(Linkage);
+  F->setVisibility(Visibility);
   if (Handler) Handler->handleFunctionBegin(F,FuncSize);
 
   // Keep track of how many basic blocks we have read in...
@@ -1844,6 +1856,7 @@
     // Linkage, bit4+ = slot#
     unsigned SlotNo = VarType >> 5;
     unsigned LinkageID = (VarType >> 2) & 7;
+    unsigned VisibilityID = 0;
     bool isConstant = VarType & 1;
     bool hasInitializer = (VarType & 2) != 0;
     unsigned Alignment = 0;
@@ -1853,10 +1866,12 @@
     if (LinkageID == 3 && !hasInitializer) {
       unsigned ExtWord = read_vbr_uint();
       // The extension word has this format: bit 0 = has initializer, bit 1-3 =
-      // linkage, bit 4-8 = alignment (log2), bits 10+ = future use.
+      // linkage, bit 4-8 = alignment (log2), bit 9 = has section,
+      // bits 10-12 = visibility, bits 13+ = future use.
       hasInitializer = ExtWord & 1;
       LinkageID = (ExtWord >> 1) & 7;
       Alignment = (1 << ((ExtWord >> 4) & 31)) >> 1;
+      VisibilityID = (ExtWord >> 10) & 7;
       
       if (ExtWord & (1 << 9))  // Has a section ID.
         GlobalSectionID = read_vbr_uint();
@@ -1877,7 +1892,16 @@
       Linkage = GlobalValue::InternalLinkage;
       break;
     }
-
+    GlobalValue::VisibilityTypes Visibility;
+    switch (VisibilityID) {
+    case 0: Visibility = GlobalValue::DefaultVisibility; break;
+    case 1: Visibility = GlobalValue::HiddenVisibility; break;
+    default:
+      error("Unknown visibility type: " + utostr(VisibilityID));
+      Visibility = GlobalValue::DefaultVisibility;
+      break;
+    }
+    
     const Type *Ty = getType(SlotNo);
     if (!Ty)
       error("Global has no type! SlotNo=" + utostr(SlotNo));
@@ -1891,6 +1915,7 @@
     GlobalVariable *GV = new GlobalVariable(ElTy, isConstant, Linkage,
                                             0, "", TheModule);
     GV->setAlignment(Alignment);
+    GV->setVisibility(Visibility);
     insertValue(GV, SlotNo, ModuleValues);
 
     if (GlobalSectionID != 0)
@@ -1904,7 +1929,8 @@
 
     // Notify handler about the global value.
     if (Handler)
-      Handler->handleGlobalVariable(ElTy, isConstant, Linkage, SlotNo,initSlot);
+      Handler->handleGlobalVariable(ElTy, isConstant, Linkage, Visibility,
+                                    SlotNo, initSlot);
 
     // Get next item
     VarType = read_vbr_uint();
diff --git a/lib/Bytecode/Writer/Writer.cpp b/lib/Bytecode/Writer/Writer.cpp
index c7003cd..10a151d 100644
--- a/lib/Bytecode/Writer/Writer.cpp
+++ b/lib/Bytecode/Writer/Writer.cpp
@@ -960,6 +960,14 @@
   }
 }
 
+static unsigned getEncodedVisibility(const GlobalValue *GV) {
+  switch (GV->getVisibility()) {
+  default: assert(0 && "Invalid visibility!");
+  case GlobalValue::DefaultVisibility: return 0;
+  case GlobalValue::HiddenVisibility:  return 1;
+  }
+}
+
 void BytecodeWriter::outputModuleInfoBlock(const Module *M) {
   BytecodeBlock ModuleInfoBlock(BytecodeFormat::ModuleGlobalInfoBlockID, *this);
 
@@ -979,7 +987,9 @@
     
     // Fields: bit0 = isConstant, bit1 = hasInitializer, bit2-4=Linkage,
     // bit5+ = Slot # for type.
-    bool HasExtensionWord = (I->getAlignment() != 0) || I->hasSection();
+    bool HasExtensionWord = (I->getAlignment() != 0) ||
+                            I->hasSection() ||
+      (I->getVisibility() != GlobalValue::DefaultVisibility);
     
     // If we need to use the extension byte, set linkage=3(internal) and
     // initializer = 0 (impossible!).
@@ -993,12 +1003,13 @@
       output_vbr(oSlot);
       
       // The extension word has this format: bit 0 = has initializer, bit 1-3 =
-      // linkage, bit 4-8 = alignment (log2), bit 9 = has SectionID, 
-      // bits 10+ = future use.
+      // linkage, bit 4-8 = alignment (log2), bit 9 = has SectionID,
+      // bits 10-12 = visibility, bits 13+ = future use.
       unsigned ExtWord = (unsigned)I->hasInitializer() |
                          (getEncodedLinkage(I) << 1) |
                          ((Log2_32(I->getAlignment())+1) << 4) |
-                         ((unsigned)I->hasSection() << 9);
+                         ((unsigned)I->hasSection() << 9) |
+                         (getEncodedVisibility(I) << 10);
       output_vbr(ExtWord);
       if (I->hasSection()) {
         // Give section names unique ID's.
@@ -1102,7 +1113,8 @@
   if (F->isExternal()) return;
 
   BytecodeBlock FunctionBlock(BytecodeFormat::FunctionBlockID, *this);
-  output_vbr(getEncodedLinkage(F));
+  unsigned rWord = (getEncodedVisibility(F) << 16) | getEncodedLinkage(F);
+  output_vbr(rWord);
 
   // Get slot information about the function...
   Table.incorporateFunction(F);
diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp
index a0b4ceb..1346acb 100644
--- a/lib/Target/CBackend/CBackend.cpp
+++ b/lib/Target/CBackend/CBackend.cpp
@@ -1290,6 +1290,11 @@
       << "#define __ATTRIBUTE_WEAK__\n"
       << "#endif\n\n";
 
+  // Add hidden visibility support. FIXME: APPLE_CC?
+  Out << "#if defined(__GNUC__)\n"
+      << "#define __HIDDEN__ __attribute__((visibility(\"hidden\")))\n"
+      << "#endif\n\n";
+    
   // Define NaN and Inf as GCC builtins if using GCC, as 0 otherwise
   // From the GCC documentation:
   //
@@ -1500,6 +1505,8 @@
         Out << " __ATTRIBUTE_CTOR__";
       if (StaticDtors.count(I))
         Out << " __ATTRIBUTE_DTOR__";
+      if (I->hasHiddenVisibility())
+        Out << " __HIDDEN__";
       
       if (I->hasName() && I->getName()[0] == 1)
         Out << " LLVM_ASM(\"" << I->getName().c_str()+1 << "\")";
@@ -1531,6 +1538,8 @@
           Out << " __ATTRIBUTE_WEAK__";
         else if (I->hasExternalWeakLinkage())
           Out << " __EXTERNAL_WEAK__";
+        if (I->hasHiddenVisibility())
+          Out << " __HIDDEN__";
         Out << ";\n";
       }
   }
@@ -1559,6 +1568,9 @@
         else if (I->hasWeakLinkage())
           Out << " __ATTRIBUTE_WEAK__";
 
+        if (I->hasHiddenVisibility())
+          Out << " __HIDDEN__";
+        
         // If the initializer is not null, emit the initializer.  If it is null,
         // we try to avoid emitting large amounts of zeros.  The problem with
         // this, however, occurs when the variable has weak linkage.  In this
diff --git a/lib/Target/X86/README.txt b/lib/Target/X86/README.txt
index c871a76..7e36520 100644
--- a/lib/Target/X86/README.txt
+++ b/lib/Target/X86/README.txt
@@ -534,10 +534,6 @@
 
 //===---------------------------------------------------------------------===//
 
-We should handle __attribute__ ((__visibility__ ("hidden"))).
-
-//===---------------------------------------------------------------------===//
-
 int %foo(int* %a, int %t) {
 entry:
         br label %cond_true
diff --git a/lib/Target/X86/X86ATTAsmPrinter.cpp b/lib/Target/X86/X86ATTAsmPrinter.cpp
index ccc2965..7edea6f 100755
--- a/lib/Target/X86/X86ATTAsmPrinter.cpp
+++ b/lib/Target/X86/X86ATTAsmPrinter.cpp
@@ -19,6 +19,7 @@
 #include "X86MachineFunctionInfo.h"
 #include "X86TargetMachine.h"
 #include "X86TargetAsmInfo.h"
+#include "llvm/ADT/StringExtras.h"
 #include "llvm/CallingConv.h"
 #include "llvm/Module.h"
 #include "llvm/Support/Mangler.h"
@@ -29,6 +30,21 @@
 
 STATISTIC(EmittedInsts, "Number of machine instrs printed");
 
+static std::string computePICLabel(unsigned fnNumber,
+                                   const X86Subtarget* Subtarget) 
+{
+  std::string label;
+
+  if (Subtarget->isTargetDarwin()) {
+    label =  "\"L" + utostr_32(fnNumber) + "$pb\"";
+  } else if (Subtarget->isTargetELF()) {
+    label = ".Lllvm$" + utostr_32(fnNumber) + "$piclabel";
+  } else
+    assert(0 && "Don't know how to print PIC label!\n");
+
+  return label;
+}
+
 /// getSectionForFunction - Return the section that we should emit the
 /// specified function body into.
 std::string X86ATTAsmPrinter::getSectionForFunction(const Function &F) const {
@@ -109,12 +125,15 @@
     }
     break;
   }
+  if (F->hasHiddenVisibility())
+    O << "\t.hidden " << CurrentFnName << "\n";
+  
   O << CurrentFnName << ":\n";
   // Add some workaround for linkonce linkage on Cygwin\MinGW
   if (Subtarget->isTargetCygMing() &&
       (F->getLinkage() == Function::LinkOnceLinkage ||
        F->getLinkage() == Function::WeakLinkage))
-    O << "_llvm$workaround$fake$stub_" << CurrentFnName << ":\n";
+    O << "Lllvm$workaround$fake$stub$" << CurrentFnName << ":\n";
 
   if (Subtarget->isTargetDarwin() ||
       Subtarget->isTargetELF() ||
@@ -193,9 +212,14 @@
     if (!isMemOp) O << '$';
     O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() << "_"
       << MO.getJumpTableIndex();
-    if (X86PICStyle == PICStyle::Stub &&
-        TM.getRelocationModel() == Reloc::PIC_)
-      O << "-\"L" << getFunctionNumber() << "$pb\"";
+
+    if (TM.getRelocationModel() == Reloc::PIC_) {
+      if (Subtarget->isPICStyleStub())
+        O << "-\"L" << getFunctionNumber() << "$pb\"";
+      else if (Subtarget->isPICStyleGOT())
+        O << "@GOTOFF";
+    }
+    
     if (isMemOp && Subtarget->is64Bit() && !NotRIPRel)
       O << "(%rip)";
     return;
@@ -205,9 +229,14 @@
     if (!isMemOp) O << '$';
     O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << "_"
       << MO.getConstantPoolIndex();
-    if (X86PICStyle == PICStyle::Stub &&
-        TM.getRelocationModel() == Reloc::PIC_)
-      O << "-\"L" << getFunctionNumber() << "$pb\"";
+
+    if (TM.getRelocationModel() == Reloc::PIC_) {
+      if (Subtarget->isPICStyleStub())
+        O << "-\"L" << getFunctionNumber() << "$pb\"";
+      if (Subtarget->isPICStyleGOT())
+        O << "@GOTOFF";
+    }
+    
     int Offset = MO.getOffset();
     if (Offset > 0)
       O << "+" << Offset;
@@ -228,11 +257,11 @@
     
     bool isExt = (GV->isExternal() || GV->hasWeakLinkage() ||
                   GV->hasLinkOnceLinkage());
+    bool isHidden = GV->hasHiddenVisibility();
     
     X86SharedAsmPrinter::decorateName(Name, GV);
     
-    if (X86PICStyle == PICStyle::Stub &&
-        TM.getRelocationModel() != Reloc::Static) {
+    if (Subtarget->isPICStyleStub()) {
       // Link-once, External, or Weakly-linked global variables need
       // non-lazily-resolved stubs
       if (isExt) {
@@ -258,6 +287,12 @@
         O << "__imp_";          
       }       
       O << Name;
+
+      if (Subtarget->isPICStyleGOT() && isCallOp && isa<Function>(GV)) {
+        // Assemble call via PLT for non-local symbols
+        if (!isHidden || isExt)
+          O << "@PLT";
+      }
     }
 
     if (GV->hasExternalWeakLinkage())
@@ -269,31 +304,55 @@
     else if (Offset < 0)
       O << Offset;
 
-    if (isMemOp && Subtarget->is64Bit()) {
-      if (isExt && TM.getRelocationModel() != Reloc::Static)
-        O << "@GOTPCREL(%rip)";
-      else if (!NotRIPRel)
-        // Use rip when possible to reduce code size, except when index or
-        // base register are also part of the address. e.g.
-        // foo(%rip)(%rcx,%rax,4) is not legal
-        O << "(%rip)";        
+    if (isMemOp) {
+      if (isExt) {
+        if (Subtarget->isPICStyleGOT()) {
+          O << "@GOT";
+        } else if (Subtarget->isPICStyleRIPRel()) {
+          O << "@GOTPCREL(%rip)";
+        } if (Subtarget->is64Bit() && !NotRIPRel)
+            // Use rip when possible to reduce code size, except when
+            // index or base register are also part of the address. e.g.
+            // foo(%rip)(%rcx,%rax,4) is not legal
+            O << "(%rip)";
+      } else {
+        if (Subtarget->is64Bit() && !NotRIPRel)
+          O << "(%rip)";
+        else if (Subtarget->isPICStyleGOT())
+          O << "@GOTOFF";
+      }
     }
 
     return;
   }
   case MachineOperand::MO_ExternalSymbol: {
     bool isCallOp = Modifier && !strcmp(Modifier, "call");
-    if (isCallOp && 
-        X86PICStyle == PICStyle::Stub &&
-        TM.getRelocationModel() != Reloc::Static) {
-      std::string Name(TAI->getGlobalPrefix());
-      Name += MO.getSymbolName();
+    std::string Name(TAI->getGlobalPrefix());
+    Name += MO.getSymbolName();
+    if (isCallOp && Subtarget->isPICStyleStub()) {
       FnStubs.insert(Name);
       O << "L" << Name << "$stub";
       return;
     }
     if (!isCallOp) O << '$';
-    O << TAI->getGlobalPrefix() << MO.getSymbolName();
+    O << Name;
+
+    if (Subtarget->isPICStyleGOT()) {
+      std::string GOTName(TAI->getGlobalPrefix());
+      GOTName+="_GLOBAL_OFFSET_TABLE_";
+      if (Name == GOTName)
+        // Really hack! Emit extra offset to PC during printing GOT offset to
+        // compensate size of popl instruction. The resulting code should look
+        // like:
+        //   call .piclabel
+        // piclabel:
+        //   popl %some_register
+        //   addl $_GLOBAL_ADDRESS_TABLE_ + [.-piclabel], %some_register
+        O << " + [.-" << computePICLabel(getFunctionNumber(), Subtarget) << "]";
+    }
+
+    if (isCallOp && Subtarget->isPICStyleGOT())
+      O << "@PLT";
 
     if (!isCallOp && Subtarget->is64Bit())
       O << "(%rip)";
@@ -366,8 +425,8 @@
 }
 
 void X86ATTAsmPrinter::printPICLabel(const MachineInstr *MI, unsigned Op) {
-  O << "\"L" << getFunctionNumber() << "$pb\"\n";
-  O << "\"L" << getFunctionNumber() << "$pb\":";
+  std::string label = computePICLabel(getFunctionNumber(), Subtarget);
+  O << label << "\n" << label << ":";
 }
 
 
diff --git a/lib/Target/X86/X86AsmPrinter.cpp b/lib/Target/X86/X86AsmPrinter.cpp
index 4f55f42a..a896068 100644
--- a/lib/Target/X86/X86AsmPrinter.cpp
+++ b/lib/Target/X86/X86AsmPrinter.cpp
@@ -105,13 +105,9 @@
 
 /// doInitialization
 bool X86SharedAsmPrinter::doInitialization(Module &M) {
-  if (Subtarget->isTargetDarwin()) {
-    if (!Subtarget->is64Bit())
-      X86PICStyle = PICStyle::Stub;
-
-    // Emit initial debug information.
-    DW.BeginModule(&M);
-  } else if (Subtarget->isTargetELF() || Subtarget->isTargetCygMing()) {
+  if (Subtarget->isTargetELF() ||
+      Subtarget->isTargetCygMing() ||
+      Subtarget->isTargetDarwin()) {
     // Emit initial debug information.
     DW.BeginModule(&M);
   }
@@ -241,7 +237,6 @@
         << "\n";
       if (TAI->hasDotTypeDotSizeDirective())
         O << "\t.size " << name << ", " << Size << "\n";
-
       // If the initializer is a extern weak symbol, remember to emit the weak
       // reference!
       if (const GlobalValue *GV = dyn_cast<GlobalValue>(C))
@@ -251,6 +246,8 @@
       EmitGlobalConstant(C);
       O << '\n';
     }
+    if (I->hasHiddenVisibility())
+      O << "\t.hidden " << name << "\n";
   }
   
   // Output linker support code for dllexported globals
diff --git a/lib/Target/X86/X86AsmPrinter.h b/lib/Target/X86/X86AsmPrinter.h
index ab885fd..87f1852 100755
--- a/lib/Target/X86/X86AsmPrinter.h
+++ b/lib/Target/X86/X86AsmPrinter.h
@@ -28,19 +28,12 @@
 
 namespace llvm {
 
-// FIXME: Move this to CodeGen/AsmPrinter.h
-namespace PICStyle {
-  enum X86AsmPICStyle {
-    Stub, GOT
-  };
-}
-
 struct VISIBILITY_HIDDEN X86SharedAsmPrinter : public AsmPrinter {
   DwarfWriter DW;
 
   X86SharedAsmPrinter(std::ostream &O, X86TargetMachine &TM,
                       const TargetAsmInfo *T)
-    : AsmPrinter(O, TM, T), DW(O, this, T), X86PICStyle(PICStyle::GOT) {
+    : AsmPrinter(O, TM, T), DW(O, this, T) {
     Subtarget = &TM.getSubtarget<X86Subtarget>();
   }
 
@@ -73,8 +66,6 @@
     MachineFunctionPass::getAnalysisUsage(AU);
   }
 
-  PICStyle::X86AsmPICStyle X86PICStyle;
-  
   const X86Subtarget *Subtarget;
 
   // Necessary for Darwin to print out the apprioriate types of linker stubs
diff --git a/lib/Target/X86/X86ISelDAGToDAG.cpp b/lib/Target/X86/X86ISelDAGToDAG.cpp
index 5c80f23..f36456e 100644
--- a/lib/Target/X86/X86ISelDAGToDAG.cpp
+++ b/lib/Target/X86/X86ISelDAGToDAG.cpp
@@ -938,10 +938,23 @@
     MachineBasicBlock &FirstMBB = BB->getParent()->front();
     MachineBasicBlock::iterator MBBI = FirstMBB.begin();
     SSARegMap *RegMap = BB->getParent()->getSSARegMap();
-    GlobalBaseReg = RegMap->createVirtualRegister(X86::GR32RegisterClass);
+    unsigned PC = RegMap->createVirtualRegister(X86::GR32RegisterClass);
+    
     const TargetInstrInfo *TII = TM.getInstrInfo();
     BuildMI(FirstMBB, MBBI, TII->get(X86::MovePCtoStack));
-    BuildMI(FirstMBB, MBBI, TII->get(X86::POP32r), GlobalBaseReg);
+    BuildMI(FirstMBB, MBBI, TII->get(X86::POP32r), PC);
+    
+    // If we're using vanilla 'GOT' PIC style, we should use relative addressing
+    // not to pc, but to _GLOBAL_ADDRESS_TABLE_ external
+    if (Subtarget->isPICStyleGOT()) {
+      GlobalBaseReg = RegMap->createVirtualRegister(X86::GR32RegisterClass);
+      BuildMI(FirstMBB, MBBI, TII->get(X86::ADD32ri), GlobalBaseReg).
+        addReg(PC).
+        addExternalSymbol("_GLOBAL_OFFSET_TABLE_");
+    } else {
+      GlobalBaseReg = PC;
+    }
+    
   }
   return CurDAG->getRegister(GlobalBaseReg, TLI.getPointerTy()).Val;
 }
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index 44d094a..350f575 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -664,6 +664,13 @@
     InFlag = Chain.getValue(1);
   }
 
+  if (Subtarget->isPICStyleGOT()) {
+    Chain = DAG.getCopyToReg(Chain, X86::EBX,
+                             DAG.getNode(X86ISD::GlobalBaseReg, getPointerTy()),
+                             InFlag);
+    InFlag = Chain.getValue(1);
+  }
+  
   // If the callee is a GlobalAddress node (quite common, every direct call is)
   // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
   if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
@@ -687,7 +694,7 @@
   for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
     Ops.push_back(DAG.getRegister(RegsToPass[i].first,
                                   RegsToPass[i].second.getValueType()));
-
+  
   if (InFlag.Val)
     Ops.push_back(InFlag);
 
@@ -3856,12 +3863,12 @@
                                                getPointerTy(),
                                                CP->getAlignment());
   Result = DAG.getNode(X86ISD::Wrapper, getPointerTy(), Result);
-  if (Subtarget->isTargetDarwin()) {
-    // With PIC, the address is actually $g + Offset.
-    if (!Subtarget->is64Bit() &&
-        getTargetMachine().getRelocationModel() == Reloc::PIC_)
-      Result = DAG.getNode(ISD::ADD, getPointerTy(),
-                    DAG.getNode(X86ISD::GlobalBaseReg, getPointerTy()), Result);
+  // With PIC, the address is actually $g + Offset.
+  if (getTargetMachine().getRelocationModel() == Reloc::PIC_ &&
+      !Subtarget->isPICStyleRIPRel()) {
+    Result = DAG.getNode(ISD::ADD, getPointerTy(),
+                         DAG.getNode(X86ISD::GlobalBaseReg, getPointerTy()),
+                         Result);
   }
 
   return Result;
@@ -3872,19 +3879,19 @@
   GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
   SDOperand Result = DAG.getTargetGlobalAddress(GV, getPointerTy());
   Result = DAG.getNode(X86ISD::Wrapper, getPointerTy(), Result);
-  if (Subtarget->isTargetDarwin()) {
-    // With PIC, the address is actually $g + Offset.
-    if (!Subtarget->is64Bit() &&
-        getTargetMachine().getRelocationModel() == Reloc::PIC_)
-      Result = DAG.getNode(ISD::ADD, getPointerTy(),
-                           DAG.getNode(X86ISD::GlobalBaseReg, getPointerTy()),
-                           Result);
+  // With PIC, the address is actually $g + Offset.
+  if (getTargetMachine().getRelocationModel() == Reloc::PIC_ &&
+      !Subtarget->isPICStyleRIPRel()) {
+    Result = DAG.getNode(ISD::ADD, getPointerTy(),
+                         DAG.getNode(X86ISD::GlobalBaseReg, getPointerTy()),
+                         Result);
   }
   
   // For Darwin & Mingw32, external and weak symbols are indirect, so we want to
   // load the value at address GV, not the value of GV itself. This means that
   // the GlobalAddress must be in the base or index register of the address, not
   // the GV offset field. Platform check is inside GVRequiresExtraLoad() call
+  // The same applies for external symbols during PIC codegen
   if (Subtarget->GVRequiresExtraLoad(GV, getTargetMachine(), false))
     Result = DAG.getLoad(getPointerTy(), DAG.getEntryNode(), Result, NULL, 0);
 
@@ -3896,13 +3903,27 @@
   const char *Sym = cast<ExternalSymbolSDNode>(Op)->getSymbol();
   SDOperand Result = DAG.getTargetExternalSymbol(Sym, getPointerTy());
   Result = DAG.getNode(X86ISD::Wrapper, getPointerTy(), Result);
-  if (Subtarget->isTargetDarwin()) {
-    // With PIC, the address is actually $g + Offset.
-    if (!Subtarget->is64Bit() &&
-        getTargetMachine().getRelocationModel() == Reloc::PIC_)
-      Result = DAG.getNode(ISD::ADD, getPointerTy(),
-                           DAG.getNode(X86ISD::GlobalBaseReg, getPointerTy()),
-                           Result);
+  // With PIC, the address is actually $g + Offset.
+  if (getTargetMachine().getRelocationModel() == Reloc::PIC_ &&
+      !Subtarget->isPICStyleRIPRel()) {
+    Result = DAG.getNode(ISD::ADD, getPointerTy(),
+                         DAG.getNode(X86ISD::GlobalBaseReg, getPointerTy()),
+                         Result);
+  }
+
+  return Result;
+}
+
+SDOperand X86TargetLowering::LowerJumpTable(SDOperand Op, SelectionDAG &DAG) {
+  JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
+  SDOperand Result = DAG.getTargetJumpTable(JT->getIndex(), getPointerTy());
+  Result = DAG.getNode(X86ISD::Wrapper, getPointerTy(), Result);
+  // With PIC, the address is actually $g + Offset.
+  if (getTargetMachine().getRelocationModel() == Reloc::PIC_ &&
+      !Subtarget->isPICStyleRIPRel()) {
+    Result = DAG.getNode(ISD::ADD, getPointerTy(),
+                         DAG.getNode(X86ISD::GlobalBaseReg, getPointerTy()),
+                         Result);
   }
 
   return Result;
@@ -4334,22 +4355,6 @@
                      Cond, Op.getOperand(2), CC, Cond.getValue(1));
 }
 
-SDOperand X86TargetLowering::LowerJumpTable(SDOperand Op, SelectionDAG &DAG) {
-  JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
-  SDOperand Result = DAG.getTargetJumpTable(JT->getIndex(), getPointerTy());
-  Result = DAG.getNode(X86ISD::Wrapper, getPointerTy(), Result);
-  if (Subtarget->isTargetDarwin()) {
-    // With PIC, the address is actually $g + Offset.
-    if (!Subtarget->is64Bit() &&
-        getTargetMachine().getRelocationModel() == Reloc::PIC_)
-      Result = DAG.getNode(ISD::ADD, getPointerTy(),
-                           DAG.getNode(X86ISD::GlobalBaseReg, getPointerTy()),
-                           Result);
-  }
-
-  return Result;
-}
-
 SDOperand X86TargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) {
   unsigned CallingConv= cast<ConstantSDNode>(Op.getOperand(1))->getValue();
 
diff --git a/lib/Target/X86/X86RegisterInfo.cpp b/lib/Target/X86/X86RegisterInfo.cpp
index eff7972..6f9f3b6 100644
--- a/lib/Target/X86/X86RegisterInfo.cpp
+++ b/lib/Target/X86/X86RegisterInfo.cpp
@@ -178,6 +178,8 @@
       MIB = MIB.addGlobalAddress(MO.getGlobal(), MO.getOffset());
     else if (MO.isJumpTableIndex())
       MIB = MIB.addJumpTableIndex(MO.getJumpTableIndex());
+    else if (MO.isExternalSymbol())
+      MIB = MIB.addExternalSymbol(MO.getSymbolName());
     else
       assert(0 && "Unknown operand type!");
   }
@@ -202,6 +204,8 @@
       MIB = MIB.addGlobalAddress(MO.getGlobal(), MO.getOffset());
     else if (MO.isJumpTableIndex())
       MIB = MIB.addJumpTableIndex(MO.getJumpTableIndex());
+    else if (MO.isExternalSymbol())
+      MIB = MIB.addExternalSymbol(MO.getSymbolName());
     else
       assert(0 && "Unknown operand for FuseInst!");
   }
diff --git a/lib/Target/X86/X86Subtarget.cpp b/lib/Target/X86/X86Subtarget.cpp
index 6feb0af..5f2342f 100644
--- a/lib/Target/X86/X86Subtarget.cpp
+++ b/lib/Target/X86/X86Subtarget.cpp
@@ -19,11 +19,11 @@
 using namespace llvm;
 
 cl::opt<X86Subtarget::AsmWriterFlavorTy>
-AsmWriterFlavor("x86-asm-syntax", cl::init(X86Subtarget::unset),
+AsmWriterFlavor("x86-asm-syntax", cl::init(X86Subtarget::Unset),
   cl::desc("Choose style of code to emit from X86 backend:"),
   cl::values(
-    clEnumValN(X86Subtarget::att,   "att",   "  Emit AT&T-style assembly"),
-    clEnumValN(X86Subtarget::intel, "intel", "  Emit Intel-style assembly"),
+    clEnumValN(X86Subtarget::ATT,   "att",   "  Emit AT&T-style assembly"),
+    clEnumValN(X86Subtarget::Intel, "intel", "  Emit Intel-style assembly"),
     clEnumValEnd));
 
 
@@ -36,7 +36,7 @@
                                        bool isDirectCall) const
 {
   if (TM.getRelocationModel() != Reloc::Static)
-    if (isTargetDarwin()) {
+    if (isTargetDarwin() || isPICStyleGOT()) {
       return (!isDirectCall &&
               (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() ||
                (GV->isExternal() && !GV->hasNotBeenReadFromBytecode())));
@@ -212,6 +212,7 @@
 
 X86Subtarget::X86Subtarget(const Module &M, const std::string &FS, bool is64Bit)
   : AsmFlavor(AsmWriterFlavor)
+  , PICStyle(PICStyle::None)
   , X86SSELevel(NoMMXSSE)
   , HasX86_64(false)
   , stackAlignment(8)
@@ -270,11 +271,11 @@
 
   // If the asm syntax hasn't been overridden on the command line, use whatever
   // the target wants.
-  if (AsmFlavor == X86Subtarget::unset) {
+  if (AsmFlavor == X86Subtarget::Unset) {
     if (TargetType == isWindows) {
-      AsmFlavor = X86Subtarget::intel;
+      AsmFlavor = X86Subtarget::Intel;
     } else {
-      AsmFlavor = X86Subtarget::att;
+      AsmFlavor = X86Subtarget::ATT;
     }
   }
 
diff --git a/lib/Target/X86/X86Subtarget.h b/lib/Target/X86/X86Subtarget.h
index 863e1af..43e8508 100644
--- a/lib/Target/X86/X86Subtarget.h
+++ b/lib/Target/X86/X86Subtarget.h
@@ -22,13 +22,18 @@
 class Module;
 class GlobalValue;
 class TargetMachine;
+  
+namespace PICStyle {
+enum Style {
+  Stub, GOT, RIPRel, WinPIC, None
+};
+}
 
 class X86Subtarget : public TargetSubtarget {
 public:
   enum AsmWriterFlavorTy {
-    att, intel, unset
+    ATT, Intel, Unset
   };
-
 protected:
   enum X86SSEEnum {
     NoMMXSSE, MMX, SSE1, SSE2, SSE3
@@ -41,6 +46,9 @@
   /// AsmFlavor - Which x86 asm dialect to use.
   AsmWriterFlavorTy AsmFlavor;
 
+  /// PICStyle - Which PIC style to use
+  PICStyle::Style PICStyle;
+  
   /// X86SSELevel - MMX, SSE1, SSE2, SSE3, or none supported.
   X86SSEEnum X86SSELevel;
 
@@ -93,6 +101,9 @@
 
   bool is64Bit() const { return Is64Bit; }
 
+  PICStyle::Style getPICStyle() const { return PICStyle; }
+  void setPICStyle(PICStyle::Style Style)  { PICStyle = Style; }
+
   bool hasMMX() const { return X86SSELevel >= MMX; }
   bool hasSSE1() const { return X86SSELevel >= SSE1; }
   bool hasSSE2() const { return X86SSELevel >= SSE2; }
@@ -100,8 +111,8 @@
   bool has3DNow() const { return X863DNowLevel >= ThreeDNow; }
   bool has3DNowA() const { return X863DNowLevel >= ThreeDNowA; }
 
-  bool isFlavorAtt() const { return AsmFlavor == att; }
-  bool isFlavorIntel() const { return AsmFlavor == intel; }
+  bool isFlavorAtt() const { return AsmFlavor == ATT; }
+  bool isFlavorIntel() const { return AsmFlavor == Intel; }
 
   bool isTargetDarwin() const { return TargetType == isDarwin; }
   bool isTargetELF() const { return TargetType == isELF; }
@@ -111,6 +122,12 @@
                                          TargetType == isCygwin); }
   bool isTargetCygwin() const { return TargetType == isCygwin; }
 
+  bool isPICStyleSet() const { return PICStyle != PICStyle::None; }
+  bool isPICStyleGOT() const { return PICStyle == PICStyle::GOT; }
+  bool isPICStyleStub() const { return PICStyle == PICStyle::Stub; }
+  bool isPICStyleRIPRel() const { return PICStyle == PICStyle::RIPRel; }
+  bool isPICStyleWinPIC() const { return PICStyle == PICStyle:: WinPIC; }
+    
   /// True if accessing the GV requires an extra load. For Windows, dllimported
   /// symbols are indirect, loading the value at address GV rather then the
   /// value of GV itself. This means that the GlobalAddress must be in the base
diff --git a/lib/Target/X86/X86TargetMachine.cpp b/lib/Target/X86/X86TargetMachine.cpp
index d92ae49..8bcda9a 100644
--- a/lib/Target/X86/X86TargetMachine.cpp
+++ b/lib/Target/X86/X86TargetMachine.cpp
@@ -127,6 +127,25 @@
     if (getCodeModel() == CodeModel::Default)
       setCodeModel(CodeModel::Small);
   }
+
+  if (getRelocationModel() == Reloc::PIC_) {
+    if (Subtarget.isTargetDarwin()) {
+      if (Subtarget.is64Bit())
+        Subtarget.setPICStyle(PICStyle::RIPRel);
+      else
+        Subtarget.setPICStyle(PICStyle::Stub);
+    } else if (Subtarget.isTargetELF())
+      Subtarget.setPICStyle(PICStyle::GOT);
+    else
+      assert(0 && "Don't know how to generate PIC code for this target!");
+  } else if (getRelocationModel() == Reloc::DynamicNoPIC) {
+    if (Subtarget.isTargetDarwin())
+      Subtarget.setPICStyle(PICStyle::Stub);
+    else if (Subtarget.isTargetCygMing())
+      Subtarget.setPICStyle(PICStyle::WinPIC);
+    else
+      assert(0 && "Don't know how to generate PIC code for this target!");
+  }
 }
 
 //===----------------------------------------------------------------------===//
@@ -163,6 +182,8 @@
                                       MachineCodeEmitter &MCE) {
   // FIXME: Move this to TargetJITInfo!
   setRelocationModel(Reloc::Static);
+  Subtarget.setPICStyle(PICStyle::None);
+  
   // JIT cannot ensure globals are placed in the lower 4G of address.
   if (Subtarget.is64Bit())
     setCodeModel(CodeModel::Large);
diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp
index 89240fc..3b0f0d6 100644
--- a/lib/VMCore/AsmWriter.cpp
+++ b/lib/VMCore/AsmWriter.cpp
@@ -858,8 +858,7 @@
      case GlobalValue::DLLImportLinkage:   Out << "dllimport "; break;
      case GlobalValue::ExternalWeakLinkage: Out << "extern_weak "; break;
      default: Out << "external "; break;
-    }
-  else
+    } else {
     switch (GV->getLinkage()) {
     case GlobalValue::InternalLinkage:     Out << "internal "; break;
     case GlobalValue::LinkOnceLinkage:     Out << "linkonce "; break;
@@ -873,7 +872,15 @@
       cerr << "GhostLinkage not allowed in AsmWriter!\n";
       abort();
     }
-
+    switch (GV->getVisibility()) {
+    case GlobalValue::DefaultVisibility: break;
+    case GlobalValue::HiddenVisibility: Out << "hidden "; break;
+    default:
+     cerr << "Invalid visibility style!\n";
+     abort();
+    }
+  }
+  
   Out << (GV->isConstant() ? "constant " : "global ");
   printType(GV->getType()->getElementType());
 
@@ -974,6 +981,13 @@
       cerr << "GhostLinkage not allowed in AsmWriter!\n";
       abort();
     }
+    switch (F->getVisibility()) {
+    case GlobalValue::DefaultVisibility: break;
+    case GlobalValue::HiddenVisibility: Out << "hidden "; break;
+    default:
+     cerr << "Invalid visibility style!\n";
+     abort();
+    }
   }
 
   // Print the calling convention.
diff --git a/test/CodeGen/X86/test-hidden.ll b/test/CodeGen/X86/test-hidden.ll
new file mode 100644
index 0000000..f3a3d9c
--- /dev/null
+++ b/test/CodeGen/X86/test-hidden.ll
@@ -0,0 +1,19 @@
+; RUN: llvm-as < %s | llc -mtriple=i686-pc-linux-gnu &&
+; RUN: llvm-as < %s | llc -mtriple=i686-pc-linux-gnu | grep ".hidden" | wc -l | grep 2 
+
+%struct.Person = type { i32 }
+%a = hidden global i32 0
+%b = external global i32
+
+implementation   ; Functions:
+
+define weak hidden void %_ZN6Person13privateMethodEv(%struct.Person* %this) {
+  ret void
+}
+
+declare void %function(i32)
+
+define weak void %_ZN6PersonC1Ei(%struct.Person* %this, i32 %_c) {
+  ret void
+}
+
diff --git a/test/CodeGen/X86/test-pic-1.ll b/test/CodeGen/X86/test-pic-1.ll
new file mode 100644
index 0000000..a12e742
--- /dev/null
+++ b/test/CodeGen/X86/test-pic-1.ll
@@ -0,0 +1,18 @@
+; RUN: llvm-as < %s | llc -mtriple=i686-pc-linux-gnu -relocation-model=pic &&
+; RUN: llvm-as < %s | llc -mtriple=i686-pc-linux-gnu -relocation-model=pic | grep _GLOBAL_OFFSET_TABLE_ &&
+; RUN: llvm-as < %s | llc -mtriple=i686-pc-linux-gnu -relocation-model=pic | grep piclabel | wc -l | grep 3 &&
+; RUN: llvm-as < %s | llc -mtriple=i686-pc-linux-gnu -relocation-model=pic | grep GOT | wc -l | grep 3 &&
+; RUN: llvm-as < %s | llc -mtriple=i686-pc-linux-gnu -relocation-model=pic | grep GOTOFF | wc -l | grep 0
+
+%ptr = external global i32* 
+%dst = external global i32 
+%src = external global i32 
+
+define void %foo() {
+entry:
+    store i32* %dst, i32** %ptr
+    %tmp.s = load i32* %src
+    store i32 %tmp.s, i32* %dst
+    ret void
+}
+
diff --git a/test/CodeGen/X86/test-pic-2.ll b/test/CodeGen/X86/test-pic-2.ll
new file mode 100644
index 0000000..04fdbda
--- /dev/null
+++ b/test/CodeGen/X86/test-pic-2.ll
@@ -0,0 +1,17 @@
+; RUN: llvm-as < %s | llc -mtriple=i686-pc-linux-gnu -relocation-model=pic &&
+; RUN: llvm-as < %s | llc -mtriple=i686-pc-linux-gnu -relocation-model=pic | grep _GLOBAL_OFFSET_TABLE_ &&
+; RUN: llvm-as < %s | llc -mtriple=i686-pc-linux-gnu -relocation-model=pic | grep piclabel | wc -l | grep 3 &&
+; RUN: llvm-as < %s | llc -mtriple=i686-pc-linux-gnu -relocation-model=pic | grep GOTOFF | wc -l | grep 4
+
+%ptr = internal global i32* null
+%dst = internal global i32 0
+%src = internal global i32 0
+
+define void %foo() {
+entry:
+    store i32* %dst, i32** %ptr
+    %tmp.s = load i32* %src
+    store i32 %tmp.s, i32* %dst
+    ret void
+}
+
diff --git a/test/CodeGen/X86/test-pic-3.ll b/test/CodeGen/X86/test-pic-3.ll
new file mode 100644
index 0000000..726a53b
--- /dev/null
+++ b/test/CodeGen/X86/test-pic-3.ll
@@ -0,0 +1,14 @@
+; RUN: llvm-as < %s | llc -mtriple=i686-pc-linux-gnu -relocation-model=pic &&
+; RUN: llvm-as < %s | llc -mtriple=i686-pc-linux-gnu -relocation-model=pic | grep _GLOBAL_OFFSET_TABLE_ &&
+; RUN: llvm-as < %s | llc -mtriple=i686-pc-linux-gnu -relocation-model=pic | grep piclabel | wc -l | grep 3 &&
+; RUN: llvm-as < %s | llc -mtriple=i686-pc-linux-gnu -relocation-model=pic | grep PLT | wc -l | grep 1
+
+define void %bar() {
+entry:
+    call void(...)* %foo()
+    br label %return
+return:
+    ret void
+}
+
+declare void %foo(...)
diff --git a/test/CodeGen/X86/test-pic-4.ll b/test/CodeGen/X86/test-pic-4.ll
new file mode 100644
index 0000000..13abb2e
--- /dev/null
+++ b/test/CodeGen/X86/test-pic-4.ll
@@ -0,0 +1,21 @@
+; RUN: llvm-as < %s | llc -mtriple=i686-pc-linux-gnu -relocation-model=pic &&
+; RUN: llvm-as < %s | llc -mtriple=i686-pc-linux-gnu -relocation-model=pic | grep _GLOBAL_OFFSET_TABLE_ &&
+; RUN: llvm-as < %s | llc -mtriple=i686-pc-linux-gnu -relocation-model=pic | grep piclabel | wc -l | grep 3 &&
+; RUN: llvm-as < %s | llc -mtriple=i686-pc-linux-gnu -relocation-model=pic | grep PLT | wc -l | grep 1 &&
+; RUN: llvm-as < %s | llc -mtriple=i686-pc-linux-gnu -relocation-model=pic | grep "GOT" | wc -l | grep 1 &&
+; RUN: llvm-as < %s | llc -mtriple=i686-pc-linux-gnu -relocation-model=pic | grep "GOTOFF" | wc -l | grep 0
+
+%pfoo = external global void(...)* 
+
+define void %bar() {
+entry:
+    %tmp = call void(...)*(...)* %afoo()
+    store void(...)* %tmp, void(...)** %pfoo
+    %tmp1 = load void(...)** %pfoo
+    call void(...)* %tmp1()
+    br label %return
+return:
+    ret void
+}
+
+declare void(...)* %afoo(...)
diff --git a/test/CodeGen/X86/test-pic-5.ll b/test/CodeGen/X86/test-pic-5.ll
new file mode 100644
index 0000000..4517e09
--- /dev/null
+++ b/test/CodeGen/X86/test-pic-5.ll
@@ -0,0 +1,13 @@
+; RUN: llvm-as < %s | llc -mtriple=i686-pc-linux-gnu -relocation-model=pic &&
+; RUN: llvm-as < %s | llc -mtriple=i686-pc-linux-gnu -relocation-model=pic | grep _GLOBAL_OFFSET_TABLE_ &&
+; RUN: llvm-as < %s | llc -mtriple=i686-pc-linux-gnu -relocation-model=pic | grep piclabel | wc -l | grep 3 &&
+; RUN: llvm-as < %s | llc -mtriple=i686-pc-linux-gnu -relocation-model=pic | grep PLT | wc -l | grep 1
+
+%ptr = external global i32* 
+
+define void %foo() {
+entry:
+    %ptr = malloc i32, i32 10
+    ret void
+}
+
diff --git a/test/CodeGen/X86/test-pic-cpool.ll b/test/CodeGen/X86/test-pic-cpool.ll
new file mode 100644
index 0000000..7a9df53
--- /dev/null
+++ b/test/CodeGen/X86/test-pic-cpool.ll
@@ -0,0 +1,13 @@
+; RUN: llvm-as < %s | llc -mtriple=i686-pc-linux-gnu -relocation-model=pic &&
+; RUN: llvm-as < %s | llc -mtriple=i686-pc-linux-gnu -relocation-model=pic | grep _GLOBAL_OFFSET_TABLE_ &&
+; RUN: llvm-as < %s | llc -mtriple=i686-pc-linux-gnu -relocation-model=pic | grep piclabel | wc -l | grep 3 &&
+; RUN: llvm-as < %s | llc -mtriple=i686-pc-linux-gnu -relocation-model=pic | grep GOTOFF | wc -l | grep 2 &&
+; RUN: llvm-as < %s | llc -mtriple=i686-pc-linux-gnu -relocation-model=pic | grep CPI | wc -l | grep 4
+
+define double %foo(i32 %a.u) {
+entry:
+    %tmp = icmp eq i32 %a.u,0
+    %retval = select bool %tmp, double 4.561230e+02, double 1.234560e+02
+    ret double %retval
+}
+
diff --git a/test/CodeGen/X86/test-pic-jtbl.ll b/test/CodeGen/X86/test-pic-jtbl.ll
new file mode 100644
index 0000000..ff3c4d6
--- /dev/null
+++ b/test/CodeGen/X86/test-pic-jtbl.ll
@@ -0,0 +1,57 @@
+; RUN: llvm-as < %s | llc -mtriple=i686-pc-linux-gnu -relocation-model=pic &&
+; RUN: llvm-as < %s | llc -mtriple=i686-pc-linux-gnu -relocation-model=pic | grep _GLOBAL_OFFSET_TABLE_ &&
+; RUN: llvm-as < %s | llc -mtriple=i686-pc-linux-gnu -relocation-model=pic | grep piclabel | wc -l | grep 3 &&
+; RUN: llvm-as < %s | llc -mtriple=i686-pc-linux-gnu -relocation-model=pic | grep PLT | wc -l | grep 13 &&
+; RUN: llvm-as < %s | llc -mtriple=i686-pc-linux-gnu -relocation-model=pic | grep GOTOFF | wc -l | grep 1 &&
+; RUN: llvm-as < %s | llc -mtriple=i686-pc-linux-gnu -relocation-model=pic | grep JTI | wc -l | grep 15
+
+define void %bar(i32 %n.u) {
+entry:
+    switch i32 %n.u, label %bb12 [i32 1, label %bb i32 2, label %bb6 i32 4, label %bb7 i32 5, label %bb8 i32 6, label %bb10 i32 7, label %bb1 i32 8, label %bb3 i32 9, label %bb4 i32 10, label %bb9 i32 11, label %bb2 i32 12, label %bb5 i32 13, label %bb11 ]
+bb:
+    tail call void(...)* %foo1()
+    ret void
+bb1:
+    tail call void(...)* %foo2()
+    ret void
+bb2:
+    tail call void(...)* %foo6()
+    ret void
+bb3:
+    tail call void(...)* %foo3()
+    ret void
+bb4:
+    tail call void(...)* %foo4()
+    ret void
+bb5:
+    tail call void(...)* %foo5()
+    ret void
+bb6:
+    tail call void(...)* %foo1()
+    ret void
+bb7:
+    tail call void(...)* %foo2()
+    ret void
+bb8:
+    tail call void(...)* %foo6()
+    ret void
+bb9:
+    tail call void(...)* %foo3()
+    ret void
+bb10:
+    tail call void(...)* %foo4()
+    ret void
+bb11:
+    tail call void(...)* %foo5()
+    ret void
+bb12:
+    tail call void(...)* %foo6()
+    ret void
+}
+
+declare void %foo1(...)
+declare void %foo2(...)
+declare void %foo6(...)
+declare void %foo3(...)
+declare void %foo4(...)
+declare void %foo5(...)