changeset 735:eee9efe5b51f

Attempt at getting LLVM to provide a proper target data layout. Should assert now if things are borked. Added untested support for Thumb target.
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Mon, 27 Oct 2008 17:37:34 +0100
parents 6dcab994ddc3
children e4e50f4b58cd
files dmd/constfold.c dmd/mars.c dmd/mars.h gen/toobj.cpp
diffstat 4 files changed, 28 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/dmd/constfold.c	Mon Oct 27 16:36:59 2008 +0100
+++ b/dmd/constfold.c	Mon Oct 27 17:37:34 2008 +0100
@@ -487,7 +487,7 @@
 	    c = fmodl(e1->toReal(), r2) + fmodl(e1->toImaginary(), r2) * I;
 #elif defined(IN_GCC)
 	    c = complex_t(e1->toReal() % r2, e1->toImaginary() % r2);
-#elif (defined(__FreeBSD__) && __FreeBSD_version < 800000) || defined(__arm__)
+#elif (defined(__FreeBSD__) && __FreeBSD_version < 800000) || defined(__arm__) || defined(__thumb__)
 	// freebsd is kinda messed up. the STABLE branch doesn't support C99's fmodl !?!
 	// arm also doesn't like fmodl
 	    c = complex_t(fmod(e1->toReal(), r2), fmod(e1->toImaginary(), r2));
@@ -502,7 +502,7 @@
 	    c = fmodl(e1->toReal(), i2) + fmodl(e1->toImaginary(), i2) * I;
 #elif defined(IN_GCC)
 	    c = complex_t(e1->toReal() % i2, e1->toImaginary() % i2);
-#elif (defined(__FreeBSD__) && __FreeBSD_version < 800000) || defined(__arm__)
+#elif (defined(__FreeBSD__) && __FreeBSD_version < 800000) || defined(__arm__) || defined(__thumb__)
         // freebsd is kinda messed up. the STABLE branch doesn't support C99's fmodl !?!
 	// arm also doesn't like fmodl
 	    c = complex_t(fmod(e1->toReal(), i2), fmod(e1->toImaginary(), i2));
--- a/dmd/mars.c	Mon Oct 27 16:36:59 2008 +0100
+++ b/dmd/mars.c	Mon Oct 27 17:37:34 2008 +0100
@@ -186,7 +186,7 @@
 \n\
 Codegen control:\n\
   -m<arch>       emit code specific to <arch> being one of:\n\
-                 x86 x86-64 ppc32 ppc64\n\
+                 x86 x86-64 ppc32 ppc64 arm thumb\n\
   -t<os>         emit code specific to <os> being one of:\n\
                  Linux, Windows, MacOSX, FreeBSD\n\
 \n\
@@ -830,6 +830,8 @@
             global.params.llvmArch = "ppc32";
     #elif defined(__arm__)
         global.params.llvmArch = "arm";
+    #elif defined(__thumb__)
+        global.params.llvmArch = "thumb";
     #else
     #error
     #endif
@@ -840,7 +842,6 @@
         global.params.isLE = true;
         global.params.is64bit = false;
         global.params.cpu = ARCHx86;
-        //global.params.data_layout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-f80:32:32-v64:64:64-v128:128:128-a0:0:64";
         if (global.params.useInlineAsm) {
             VersionCondition::addPredefinedGlobalIdent("LLVM_InlineAsm_X86");
         }
@@ -850,21 +851,18 @@
         global.params.isLE = true;
         global.params.is64bit = true;
         global.params.cpu = ARCHx86_64;
-        //global.params.data_layout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64";
     }
     else if (strcmp(global.params.llvmArch,"ppc32")==0) {
         VersionCondition::addPredefinedGlobalIdent("PPC");
         global.params.isLE = false;
         global.params.is64bit = false;
         global.params.cpu = ARCHppc;
-        //global.params.data_layout = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64";
     }
     else if (strcmp(global.params.llvmArch,"ppc64")==0) {
         VersionCondition::addPredefinedGlobalIdent("PPC64");
         global.params.isLE = false;
         global.params.is64bit = true;
         global.params.cpu = ARCHppc_64;
-        //global.params.data_layout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64";
     }
     else if (strcmp(global.params.llvmArch,"arm")==0) {
         VersionCondition::addPredefinedGlobalIdent("ARM");
@@ -872,6 +870,12 @@
         global.params.is64bit = false;
         global.params.cpu = ARCHarm;
     }
+    else if (strcmp(global.params.llvmArch,"thumb")==0) {
+        VersionCondition::addPredefinedGlobalIdent("Thumb");
+        global.params.isLE = true;
+        global.params.is64bit = false;
+        global.params.cpu = ARCHthumb;
+    }
     else {
         assert(0 && "Invalid arch");
     }
@@ -927,6 +931,12 @@
 
     Logger::println("Target triple: %s", global.params.targetTriple);
 
+    // build a minimal data layout so llvm can find the target
+    global.params.dataLayout = global.params.isLE
+        ? (char*)(global.params.is64bit ? "e-p:64:64" : "e-p:32:32")
+        : (char*)(global.params.is64bit ? "E-p:64:64" : "E-p:32:32");
+    Logger::println("Layout: %s", global.params.dataLayout);
+
     // Initialization
     Type::init();
     Id::initialize();
--- a/dmd/mars.h	Mon Oct 27 16:36:59 2008 +0100
+++ b/dmd/mars.h	Mon Oct 27 17:37:34 2008 +0100
@@ -45,7 +45,8 @@
     ARCHx86_64,
     ARCHppc,
     ARCHppc_64,
-    ARCHarm
+    ARCHarm,
+    ARCHthumb
 };
 enum OUTPUTFLAG
 {
@@ -161,6 +162,7 @@
 
     // target stuff
     char *targetTriple;
+    char *dataLayout;
 };
 
 struct Global
--- a/gen/toobj.cpp	Mon Oct 27 16:36:59 2008 +0100
+++ b/gen/toobj.cpp	Mon Oct 27 17:37:34 2008 +0100
@@ -104,6 +104,7 @@
     // set target stuff
 
     ir.module->setTargetTriple(global.params.targetTriple);
+    ir.module->setDataLayout(global.params.dataLayout);
 
     // get the target machine
     const llvm::TargetMachineRegistry::entry* MArch;
@@ -131,7 +132,13 @@
     llvm::TargetMachine &Target = *target.get();
 
     gTargetData = Target.getTargetData();
-    ir.module->setDataLayout(gTargetData->getStringRepresentation());
+
+    // set final data layout
+    std::string datalayout = gTargetData->getStringRepresentation();
+    ir.module->setDataLayout(datalayout);
+    if (Logger::enabled())
+        Logger::cout() << "Final data layout: " << datalayout << '\n';
+    assert(memcmp(global.params.dataLayout, datalayout.c_str(), 9) == 0); // "E-p:xx:xx"
 
     // debug info
     if (global.params.symdebug) {