changeset 923:9bab304ed531

Added support for naked asm on OSX. (hopefully!)
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Tue, 03 Feb 2009 18:14:30 +0100
parents 0749c0757a43
children 0ea8bdfe4405
files gen/naked.cpp
diffstat 1 files changed, 43 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/gen/naked.cpp	Tue Feb 03 18:11:39 2009 +0100
+++ b/gen/naked.cpp	Tue Feb 03 18:14:30 2009 +0100
@@ -104,34 +104,60 @@
 
     // build function header
 
-    // REALLY FIXME: this is most likely extremely platform dependent
+    // FIXME: could we perhaps use llvm asmwriter to give us these details ?
 
     const char* mangle = fd->mangle();
-    const char* linkage = "globl";
-    std::string section = "text";
-    unsigned align = 16;
-
     std::ostringstream tmpstr;
 
-    if (DtoIsTemplateInstance(fd))
+    // osx is different
+    // also mangling has an extra underscore prefixed
+    if (global.params.os == OSMacOSX)
     {
-        linkage = "weak";
-        tmpstr << "section\t.gnu.linkonce.t." << mangle << ",\"ax\",@progbits";
-        section = tmpstr.str();
+        std::string section = "text";
+        bool weak = false;
+        if (DtoIsTemplateInstance(fd))
+        {
+            tmpstr << "section\t__TEXT,__textcoal_nt,coalesced,pure_instructions";
+            section = tmpstr.str();
+            weak = true;
+        }
+        asmstr << "\t." << section << std::endl;
+        asmstr << "\t.align\t4,0x90" << std::endl;
+        asmstr << "\t.globl\t_" << mangle << std::endl;
+        if (weak)
+        {
+            asmstr << "\t.weak_definition\t_" << mangle << std::endl;
+        }
+        asmstr << "_" << mangle << ":" << std::endl;
     }
-
-    asmstr << "\t." << section << std::endl;
-    asmstr << "\t.align\t" << align << std::endl;
-    asmstr << "\t." << linkage << "\t" << mangle << std::endl;
-    asmstr << "\t.type\t" << mangle << ",@function" << std::endl;
-    asmstr << mangle << ":" << std::endl;
+    // this works on linux x86 32 and 64 bit
+    // assume it works everywhere else as well for now
+    else
+    {
+        const char* linkage = "globl";
+        std::string section = "text";
+        if (DtoIsTemplateInstance(fd))
+        {
+            linkage = "weak";
+            tmpstr << "section\t.gnu.linkonce.t." << mangle << ",\"ax\",@progbits";
+            section = tmpstr.str();
+        }
+        asmstr << "\t." << section << std::endl;
+        asmstr << "\t.align\t16" << std::endl;
+        asmstr << "\t." << linkage << "\t" << mangle << std::endl;
+        asmstr << "\t.type\t" << mangle << ",@function" << std::endl;
+        asmstr << mangle << ":" << std::endl;
+    }
 
     // emit body
     fd->fbody->toNakedIR(gIR);
 
     // emit size after body
-    // why? dunno, llvm seems to do it by default ..
-    asmstr << "\t.size\t" << mangle << ", .-" << mangle << std::endl << std::endl;
+    // llvm does this on linux, but not on osx
+    if (global.params.os != OSMacOSX)
+    {
+        asmstr << "\t.size\t" << mangle << ", .-" << mangle << std::endl << std::endl;
+    }
 
     gIR->module->appendModuleInlineAsm(asmstr.str());
     asmstr.str("");