From 6b9e85df485c5f702b840d8e159c40b9fb5a9b3c Mon Sep 17 00:00:00 2001 From: Tomas Lindquist Olsen Date: Mon, 27 Oct 2008 17:37:34 +0100 Subject: [PATCH] Attempt at getting LLVM to provide a proper target data layout. Should assert now if things are borked. Added untested support for Thumb target. --- dmd/constfold.c | 4 ++-- dmd/mars.c | 20 +++++++++++++++----- dmd/mars.h | 4 +++- gen/toobj.cpp | 9 ++++++++- 4 files changed, 28 insertions(+), 9 deletions(-) diff --git a/dmd/constfold.c b/dmd/constfold.c index d2707c27..7dc1a266 100644 --- a/dmd/constfold.c +++ b/dmd/constfold.c @@ -487,7 +487,7 @@ Expression *Mod(Type *type, Expression *e1, Expression *e2) 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 @@ Expression *Mod(Type *type, Expression *e1, Expression *e2) 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)); diff --git a/dmd/mars.c b/dmd/mars.c index 0f02ec5f..86966189 100644 --- a/dmd/mars.c +++ b/dmd/mars.c @@ -186,7 +186,7 @@ Usage:\n\ \n\ Codegen control:\n\ -m emit code specific to being one of:\n\ - x86 x86-64 ppc32 ppc64\n\ + x86 x86-64 ppc32 ppc64 arm thumb\n\ -t emit code specific to being one of:\n\ Linux, Windows, MacOSX, FreeBSD\n\ \n\ @@ -830,6 +830,8 @@ int main(int argc, char *argv[], char** envp) 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 @@ int main(int argc, char *argv[], char** envp) 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 @@ int main(int argc, char *argv[], char** envp) 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 @@ int main(int argc, char *argv[], char** envp) 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 @@ int main(int argc, char *argv[], char** envp) 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(); diff --git a/dmd/mars.h b/dmd/mars.h index c026b11e..b7891935 100644 --- a/dmd/mars.h +++ b/dmd/mars.h @@ -45,7 +45,8 @@ enum ARCH ARCHx86_64, ARCHppc, ARCHppc_64, - ARCHarm + ARCHarm, + ARCHthumb }; enum OUTPUTFLAG { @@ -161,6 +162,7 @@ struct Param // target stuff char *targetTriple; + char *dataLayout; }; struct Global diff --git a/gen/toobj.cpp b/gen/toobj.cpp index bf65204a..c27b79fb 100644 --- a/gen/toobj.cpp +++ b/gen/toobj.cpp @@ -104,6 +104,7 @@ void Module::genobjfile(int multiobj, char** envp) // 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 @@ void Module::genobjfile(int multiobj, char** envp) 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) {