[llvm-commits] CVS: llvm/lib/Target/X86/X86ATTAsmPrinter.cpp X86AsmPrinter.cpp X86AsmPrinter.h X86ISelLowering.cpp X86IntelAsmPrinter.cpp X86Subtarget.h

Anton Korobeynikov asl at math.spbu.ru
Thu Sep 14 11:24:05 PDT 2006



Changes in directory llvm/lib/Target/X86:

X86ATTAsmPrinter.cpp updated: 1.61 -> 1.62
X86AsmPrinter.cpp updated: 1.196 -> 1.197
X86AsmPrinter.h updated: 1.30 -> 1.31
X86ISelLowering.cpp updated: 1.258 -> 1.259
X86IntelAsmPrinter.cpp updated: 1.55 -> 1.56
X86Subtarget.h updated: 1.16 -> 1.17
---
Log message:

Adding dllimport, dllexport and external weak linkage types.
DLL* linkages got full (I hope) codegeneration support in C & both x86 
assembler backends.
External weak linkage added for future use, we don't provide any 
codegeneration, etc. support for it.


---
Diffs of the changes:  (+123 -9)

 X86ATTAsmPrinter.cpp   |   28 +++++++++++++++++++----
 X86AsmPrinter.cpp      |   24 +++++++++++++++++++
 X86AsmPrinter.h        |    3 ++
 X86ISelLowering.cpp    |   16 +++++++++++++
 X86IntelAsmPrinter.cpp |   59 +++++++++++++++++++++++++++++++++++++++++++++----
 X86Subtarget.h         |    2 +
 6 files changed, 123 insertions(+), 9 deletions(-)


Index: llvm/lib/Target/X86/X86ATTAsmPrinter.cpp
diff -u llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.61 llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.62
--- llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.61	Fri Sep  8 01:48:29 2006
+++ llvm/lib/Target/X86/X86ATTAsmPrinter.cpp	Thu Sep 14 13:23:27 2006
@@ -48,10 +48,13 @@
     SwitchToTextSection(TAI->getTextSection(), F);
     EmitAlignment(4, F);     // FIXME: This should be parameterized somewhere.
     break;
+  case Function::DLLExportLinkage:
+    DLLExportedFns.insert(Mang->makeNameProper(F->getName(), ""));
+    //FALLS THROUGH
   case Function::ExternalLinkage:
     SwitchToTextSection(TAI->getTextSection(), F);
     EmitAlignment(4, F);     // FIXME: This should be parameterized somewhere.
-    O << "\t.globl\t" << CurrentFnName << "\n";
+    O << "\t.globl\t" << CurrentFnName << "\n";    
     break;
   case Function::WeakLinkage:
   case Function::LinkOnceLinkage:
@@ -179,8 +182,9 @@
     bool isMemOp  = Modifier && !strcmp(Modifier, "mem");
     if (!isMemOp && !isCallOp) O << '$';
 
-    GlobalValue *GV = MO.getGlobal();
+    GlobalValue *GV = MO.getGlobal();    
     std::string Name = Mang->getValueName(GV);
+    
     bool isExt = (GV->isExternal() || GV->hasWeakLinkage() ||
                   GV->hasLinkOnceLinkage());
     if (X86PICStyle == PICStyle::Stub &&
@@ -196,13 +200,27 @@
           GVStubs.insert(Name);
           O << "L" << Name << "$non_lazy_ptr";
         }
-      } else
+      } else {
+        if (GV->hasDLLImportLinkage()) {
+          // FIXME: This should be fixed with full support of stdcall & fastcall
+          // CC's
+          O << "__imp_";          
+        } 
         O << Name;
+      }
+      
       if (!isCallOp && TM.getRelocationModel() == Reloc::PIC_)
         O << "-\"L" << getFunctionNumber() << "$pb\"";
-    } else
+    } else {
+      if (GV->hasDLLImportLinkage()) {
+        // FIXME: This should be fixed with full support of stdcall & fastcall
+        // CC's
+        O << "__imp_";          
+      }       
       O << Name;
-
+   
+    }
+    
     int Offset = MO.getOffset();
     if (Offset > 0)
       O << "+" << Offset;


Index: llvm/lib/Target/X86/X86AsmPrinter.cpp
diff -u llvm/lib/Target/X86/X86AsmPrinter.cpp:1.196 llvm/lib/Target/X86/X86AsmPrinter.cpp:1.197
--- llvm/lib/Target/X86/X86AsmPrinter.cpp:1.196	Fri Sep  8 01:48:29 2006
+++ llvm/lib/Target/X86/X86AsmPrinter.cpp	Thu Sep 14 13:23:27 2006
@@ -112,6 +112,9 @@
       case GlobalValue::AppendingLinkage:
         // FIXME: appending linkage variables should go into a section of
         // their name or something.  For now, just emit them as external.
+      case GlobalValue::DLLExportLinkage:
+        DLLExportedGVs.insert(Mang->makeNameProper(I->getName(),""));
+        // FALL THROUGH
       case GlobalValue::ExternalLinkage:
         // If external or appending, declare as a global symbol
         O << "\t.globl " << name << "\n";
@@ -134,6 +137,27 @@
     }
   }
   
+  // Output linker support code for dllexported globals
+  if (DLLExportedGVs.begin() != DLLExportedGVs.end()) {
+    SwitchToDataSection(".section .drectve", 0);    
+  }
+
+  for (std::set<std::string>::iterator i = DLLExportedGVs.begin(),
+         e = DLLExportedGVs.end();
+         i != e; ++i) {
+    O << "\t.ascii \" -export:" << *i << ",data\"\n";
+  }    
+
+  if (DLLExportedFns.begin() != DLLExportedFns.end()) {
+    SwitchToDataSection(".section .drectve", 0);    
+  }
+
+  for (std::set<std::string>::iterator i = DLLExportedFns.begin(),
+         e = DLLExportedFns.end();
+         i != e; ++i) {
+    O << "\t.ascii \" -export:" << *i << "\"\n";
+  }    
+ 
   if (Subtarget->isTargetDarwin()) {
     SwitchToDataSection("", 0);
 


Index: llvm/lib/Target/X86/X86AsmPrinter.h
diff -u llvm/lib/Target/X86/X86AsmPrinter.h:1.30 llvm/lib/Target/X86/X86AsmPrinter.h:1.31
--- llvm/lib/Target/X86/X86AsmPrinter.h:1.30	Fri Sep  8 01:48:29 2006
+++ llvm/lib/Target/X86/X86AsmPrinter.h	Thu Sep 14 13:23:27 2006
@@ -63,6 +63,9 @@
   // Necessary for Darwin to print out the apprioriate types of linker stubs
   std::set<std::string> FnStubs, GVStubs, LinkOnceStubs;
 
+  // Necessary for dllexport support
+  std::set<std::string> DLLExportedFns, DLLExportedGVs;
+  
   inline static bool isScale(const MachineOperand &MO) {
     return MO.isImmediate() &&
           (MO.getImmedValue() == 1 || MO.getImmedValue() == 2 ||


Index: llvm/lib/Target/X86/X86ISelLowering.cpp
diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.258 llvm/lib/Target/X86/X86ISelLowering.cpp:1.259
--- llvm/lib/Target/X86/X86ISelLowering.cpp:1.258	Wed Sep 13 12:04:54 2006
+++ llvm/lib/Target/X86/X86ISelLowering.cpp	Thu Sep 14 13:23:27 2006
@@ -1964,6 +1964,15 @@
           (GV->isExternal() && !GV->hasNotBeenReadFromBytecode()));
 }
 
+/// WinndowsGVRequiresExtraLoad - true if accessing the GV requires an extra
+/// load. For Windows, dllimported variables (not functions!) 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 or index register of the
+/// address, not the GV offset field.
+static bool WindowsGVRequiresExtraLoad(GlobalValue *GV) {
+  return (isa<GlobalVariable>((Value*)GV) && GV->hasDLLImportLinkage());  
+}
+
 /// isUndefOrInRange - Op is either an undef node or a ConstantSDNode.  Return
 /// true if Op is undef or if its value falls within the specified range (L, H].
 static bool isUndefOrInRange(SDOperand Op, unsigned Low, unsigned Hi) {
@@ -3376,7 +3385,14 @@
         DarwinGVRequiresExtraLoad(GV))
       Result = DAG.getLoad(getPointerTy(), DAG.getEntryNode(),
                            Result, DAG.getSrcValue(NULL));
+  } else if (Subtarget->isTargetCygwin() || Subtarget->isTargetWindows()) {
+    // FIXME: What's about PIC?
+    if (WindowsGVRequiresExtraLoad(GV)) {
+      Result = DAG.getLoad(getPointerTy(), DAG.getEntryNode(),
+                           Result, DAG.getSrcValue(NULL));      
+    }    
   }
+  
 
   return Result;
 }


Index: llvm/lib/Target/X86/X86IntelAsmPrinter.cpp
diff -u llvm/lib/Target/X86/X86IntelAsmPrinter.cpp:1.55 llvm/lib/Target/X86/X86IntelAsmPrinter.cpp:1.56
--- llvm/lib/Target/X86/X86IntelAsmPrinter.cpp:1.55	Fri Sep  8 01:48:29 2006
+++ llvm/lib/Target/X86/X86IntelAsmPrinter.cpp	Thu Sep 14 13:23:27 2006
@@ -35,10 +35,23 @@
   EmitConstantPool(MF.getConstantPool());
 
   // Print out labels for the function.
-  SwitchToTextSection("_text", MF.getFunction());
-  EmitAlignment(4);
-  if (MF.getFunction()->getLinkage() == GlobalValue::ExternalLinkage)
+  const Function* F = MF.getFunction();
+  switch (F->getLinkage()) {
+  default: assert(0 && "Unsupported linkage type!");
+  case Function::InternalLinkage:
+    SwitchToTextSection("_text", F);
+    EmitAlignment(4);
+    break;    
+  case Function::DLLExportLinkage:
+    DLLExportedFns.insert(CurrentFnName);
+    //FALLS THROUGH
+  case Function::ExternalLinkage:
     O << "\tpublic " << CurrentFnName << "\n";
+    SwitchToTextSection("_text", F);
+    EmitAlignment(4);
+    break;    
+  }
+  
   O << CurrentFnName << "\tproc near\n";
   
   // Print out code for the function.
@@ -118,8 +131,15 @@
   case MachineOperand::MO_GlobalAddress: {
     bool isCallOp = Modifier && !strcmp(Modifier, "call");
     bool isMemOp  = Modifier && !strcmp(Modifier, "mem");
+    GlobalValue *GV = MO.getGlobal();    
+
     if (!isMemOp && !isCallOp) O << "OFFSET ";
-    O << Mang->getValueName(MO.getGlobal());
+    if (GV->hasDLLImportLinkage()) {
+      // FIXME: This should be fixed with full support of stdcall & fastcall
+      // CC's
+      O << "__imp_";          
+    } 
+    O << Mang->getValueName(GV);
     int Offset = MO.getOffset();
     if (Offset > 0)
       O << " + " << Offset;
@@ -350,6 +370,9 @@
       // FIXME: the default alignment is 16 bytes, but 1, 2, 4, and 256
       // are also available.
       break;
+    case GlobalValue::DLLExportLinkage:
+      DLLExportedGVs.insert(name);
+      // FALL THROUGH
     case GlobalValue::ExternalLinkage:
       O << "\tpublic " << name << "\n";
       // FALL THROUGH
@@ -371,6 +394,34 @@
     if (bCustomSegment)
       O << name << "?\tends\n";
   }
+
+    // Output linker support code for dllexported globals
+  if ((DLLExportedGVs.begin() != DLLExportedGVs.end()) ||
+      (DLLExportedFns.begin() != DLLExportedFns.end())) {
+    SwitchToDataSection("", 0);
+    O << "; WARNING: The following code is valid only with MASM v8.x and (possible) higher\n"
+      << "; This version of MASM is usually shipped with Microsoft Visual Studio 2005\n"
+      << "; or (possible) further versions. Unfortunately, there is no way to support\n"
+      << "; dllexported symbols in the earlier versions of MASM in fully automatic way\n\n";
+    O << "_drectve\t segment info alias('.drectve')\n";
+  }
+
+  for (std::set<std::string>::iterator i = DLLExportedGVs.begin(),
+         e = DLLExportedGVs.end();
+         i != e; ++i) {
+    O << "\t db ' /EXPORT:" << *i << ",data'\n";
+  }    
+
+  for (std::set<std::string>::iterator i = DLLExportedFns.begin(),
+         e = DLLExportedFns.end();
+         i != e; ++i) {
+    O << "\t db ' /EXPORT:" << *i << "'\n";
+  }    
+
+  if ((DLLExportedGVs.begin() != DLLExportedGVs.end()) ||
+      (DLLExportedFns.begin() != DLLExportedFns.end())) {
+    O << "_drectve\t ends\n";    
+  }
   
   // Bypass X86SharedAsmPrinter::doFinalization().
   AsmPrinter::doFinalization(M);


Index: llvm/lib/Target/X86/X86Subtarget.h
diff -u llvm/lib/Target/X86/X86Subtarget.h:1.16 llvm/lib/Target/X86/X86Subtarget.h:1.17
--- llvm/lib/Target/X86/X86Subtarget.h:1.16	Fri Sep  8 01:48:29 2006
+++ llvm/lib/Target/X86/X86Subtarget.h	Thu Sep 14 13:23:27 2006
@@ -99,6 +99,8 @@
 
   bool isTargetDarwin() const { return TargetType == isDarwin; }
   bool isTargetELF() const { return TargetType == isELF; }
+  bool isTargetWindows() const { return TargetType == isWindows; }
+  bool isTargetCygwin() const { return TargetType == isCygwin; }  
 };
 } // End llvm namespace
 






More information about the llvm-commits mailing list