From 940d6e907ffc5b1eeffeb80d5ad8c425c8af39a9 Mon Sep 17 00:00:00 2001 From: kai Date: Sun, 16 Sep 2012 19:50:21 +0200 Subject: [PATCH] Take advantage of Triple and TargetData. A lot of system specific knowledge is already present in LLVM. This is used to populate several fields in global.params instead of hard coded values in main(). Ensures that the frontend and LLVM have always the same values. --- dmd/mars.h | 36 ++++++++++-------- dmd2/mars.h | 36 ++++++++++-------- driver/linker.cpp | 4 +- driver/main.cpp | 96 +++++++++++++++++++---------------------------- gen/asmstmt.cpp | 2 +- gen/module.cpp | 2 +- gen/naked.cpp | 2 +- 7 files changed, 84 insertions(+), 94 deletions(-) diff --git a/dmd/mars.h b/dmd/mars.h index 343c3600..4afc4eb0 100644 --- a/dmd/mars.h +++ b/dmd/mars.h @@ -71,6 +71,10 @@ the target object file format: #include #include +#if IN_LLVM +#include "llvm/ADT/Triple.h" +#endif + #ifdef __DMC__ #ifdef DEBUG #undef assert @@ -140,14 +144,15 @@ struct OutBuffer; // LDC enum ARCH { - ARCHinvalid, - ARCHx86, - ARCHx86_64, - ARCHppc, - ARCHppc_64, - ARCHarm, - ARCHthumb + ARCHinvalid = llvm::Triple::UnknownArch, + ARCHx86 = llvm::Triple::x86, + ARCHx86_64 = llvm::Triple::x86_64, + ARCHppc = llvm::Triple::ppc, + ARCHppc_64 = llvm::Triple::ppc64, + ARCHarm = llvm::Triple::arm, + ARCHthumb = llvm::Triple::thumb, }; + enum OUTPUTFLAG { OUTPUTFLAGno, @@ -157,13 +162,13 @@ enum OUTPUTFLAG enum OS { - OSinvalid, - OSLinux, - OSHaiku, - OSWindows, - OSMacOSX, - OSFreeBSD, - OSSolaris, + OSinvalid = llvm::Triple::UnknownOS, + OSLinux = llvm::Triple::Linux, + OSHaiku = llvm::Triple::Haiku, + OSWindows = llvm::Triple::Win32, + OSMacOSX = llvm::Triple::MacOSX, + OSFreeBSD = llvm::Triple::FreeBSD, + OSSolaris = llvm::Triple::Solaris, }; typedef unsigned char ubyte; @@ -303,8 +308,7 @@ struct Param bool useAvailableExternally; // target stuff - const char* llvmArch; - const char *targetTriple; + llvm::Triple *targetTriple; // Codegen cl options bool singleObj; diff --git a/dmd2/mars.h b/dmd2/mars.h index bd602edf..64518649 100644 --- a/dmd2/mars.h +++ b/dmd2/mars.h @@ -71,6 +71,10 @@ the target object file format: #include #include +#if IN_LLVM +#include "llvm/ADT/Triple.h" +#endif + #ifdef __DMC__ #ifdef DEBUG #undef assert @@ -145,14 +149,15 @@ typedef ArrayBase Strings; #if IN_LLVM enum ARCH { - ARCHinvalid, - ARCHx86, - ARCHx86_64, - ARCHppc, - ARCHppc_64, - ARCHarm, - ARCHthumb + ARCHinvalid = llvm::Triple::UnknownArch, + ARCHx86 = llvm::Triple::x86, + ARCHx86_64 = llvm::Triple::x86_64, + ARCHppc = llvm::Triple::ppc, + ARCHppc_64 = llvm::Triple::ppc64, + ARCHarm = llvm::Triple::arm, + ARCHthumb = llvm::Triple::thumb, }; + enum OUTPUTFLAG { OUTPUTFLAGno, @@ -162,13 +167,13 @@ enum OUTPUTFLAG enum OS { - OSinvalid, - OSLinux, - OSHaiku, - OSWindows, - OSMacOSX, - OSFreeBSD, - OSSolaris, + OSinvalid = llvm::Triple::UnknownOS, + OSLinux = llvm::Triple::Linux, + OSHaiku = llvm::Triple::Haiku, + OSWindows = llvm::Triple::Win32, + OSMacOSX = llvm::Triple::MacOSX, + OSFreeBSD = llvm::Triple::FreeBSD, + OSSolaris = llvm::Triple::Solaris, }; typedef unsigned char ubyte; @@ -271,8 +276,7 @@ struct Param bool useAvailableExternally; // target stuff - const char* llvmArch; - const char *targetTriple; + llvm::Triple targetTriple; // Codegen cl options bool singleObj; diff --git a/driver/linker.cpp b/driver/linker.cpp index 54098a3f..afe58001 100644 --- a/driver/linker.cpp +++ b/driver/linker.cpp @@ -382,7 +382,7 @@ int linkObjToBinaryWin(bool sharedLib) int linkObjToBinary(bool sharedLib) { int status; - if (llvm::Triple(global.params.targetTriple).isOSWindows()) + if (global.params.targetTriple.getOS() == llvm::Triple::Win32) status = linkObjToBinaryWin(sharedLib); else status = linkObjToBinaryGcc(sharedLib); @@ -395,7 +395,7 @@ void createStaticLibrary() { Logger::println("*** Creating static library ***"); - const bool isTargetWindows = llvm::Triple(global.params.targetTriple).isOSWindows(); + const bool isTargetWindows = global.params.targetTriple.getOS() == llvm::Triple::Win32; // find archiver llvm::sys::Path tool = isTargetWindows ? getLib() : getArchiver(); diff --git a/driver/main.cpp b/driver/main.cpp index f7821c26..7246db8d 100644 --- a/driver/main.cpp +++ b/driver/main.cpp @@ -498,7 +498,7 @@ int main(int argc, char** argv) triple = llvm::Triple::normalize(mTargetTriple); } - global.params.targetTriple = triple.c_str(); + global.params.targetTriple = llvm::Triple(triple); // Allocate target machine. const llvm::Target *theTarget = NULL; @@ -566,54 +566,41 @@ int main(int argc, char** argv) gTargetData = target->getTargetData(); - global.params.llvmArch = theTarget->getName(); + global.params.isLE = gTargetData->isLittleEndian(); + // Starting with LLVM 3.1 we could also use global.params.targetTriple.isArch64Bit(); + global.params.is64bit = gTargetData->getPointerSizeInBits() == 64; + global.params.cpu = static_cast(global.params.targetTriple.getArch()); + global.params.os = static_cast(global.params.targetTriple.getOS()); - if (strcmp(global.params.llvmArch,"x86")==0) { - VersionCondition::addPredefinedGlobalIdent("X86"); - global.params.isLE = true; - global.params.is64bit = false; - global.params.cpu = ARCHx86; - if (global.params.useInlineAsm) { - VersionCondition::addPredefinedGlobalIdent("D_InlineAsm_X86"); - } - } - else if (strcmp(global.params.llvmArch,"x86-64")==0) { - VersionCondition::addPredefinedGlobalIdent("X86_64"); - global.params.isLE = true; - global.params.is64bit = true; - global.params.cpu = ARCHx86_64; - if (global.params.useInlineAsm) { - VersionCondition::addPredefinedGlobalIdent("D_InlineAsm_X86_64"); - } - } - else if (strcmp(global.params.llvmArch,"ppc32")==0) { - VersionCondition::addPredefinedGlobalIdent("PPC"); - global.params.isLE = false; - global.params.is64bit = false; - global.params.cpu = ARCHppc; - } - else if (strcmp(global.params.llvmArch,"ppc64")==0) { - VersionCondition::addPredefinedGlobalIdent("PPC64"); - global.params.isLE = false; - global.params.is64bit = true; - global.params.cpu = ARCHppc_64; - } - else if (strcmp(global.params.llvmArch,"arm")==0) { - VersionCondition::addPredefinedGlobalIdent("ARM"); - global.params.isLE = true; - global.params.is64bit = false; - global.params.cpu = ARCHarm; - } - else if (strcmp(global.params.llvmArch,"thumb")==0) { - VersionCondition::addPredefinedGlobalIdent("ARM"); - VersionCondition::addPredefinedGlobalIdent("Thumb"); - global.params.isLE = true; - global.params.is64bit = false; - global.params.cpu = ARCHthumb; - } - else { - error("invalid cpu architecture specified: %s", global.params.llvmArch); - fatal(); + switch (global.params.targetTriple.getArch()) + { + case llvm::Triple::x86: + VersionCondition::addPredefinedGlobalIdent("X86"); + if (global.params.useInlineAsm) { + VersionCondition::addPredefinedGlobalIdent("D_InlineAsm_X86"); + } + break; + case llvm::Triple::x86_64: + VersionCondition::addPredefinedGlobalIdent("X86_64"); + if (global.params.useInlineAsm) { + VersionCondition::addPredefinedGlobalIdent("D_InlineAsm_X86_64"); + } + break; + case llvm::Triple::ppc: + VersionCondition::addPredefinedGlobalIdent("PPC"); + break; + case llvm::Triple::ppc64: + VersionCondition::addPredefinedGlobalIdent("PPC64"); + break; + case llvm::Triple::arm: + VersionCondition::addPredefinedGlobalIdent("ARM"); + case llvm::Triple::thumb: + VersionCondition::addPredefinedGlobalIdent("ARM"); + VersionCondition::addPredefinedGlobalIdent("Thumb"); + break; + default: + error("invalid cpu architecture specified: %s", global.params.targetTriple.getArchName().str().c_str()); + fatal(); } // endianness @@ -638,10 +625,9 @@ int main(int argc, char** argv) // parse the OS out of the target triple // see http://gcc.gnu.org/install/specific.html for details // also llvm's different SubTargets have useful information - switch (llvm::Triple(triple).getOS()) + switch (global.params.targetTriple.getOS()) { case llvm::Triple::Win32: - global.params.os = OSWindows; VersionCondition::addPredefinedGlobalIdent("Windows"); VersionCondition::addPredefinedGlobalIdent("Win32"); if (global.params.is64bit) { @@ -649,7 +635,7 @@ int main(int argc, char** argv) } break; case llvm::Triple::MinGW32: - global.params.os = OSWindows; + global.params.os = OSWindows; // FIXME: Check source for uses of MinGW32 VersionCondition::addPredefinedGlobalIdent("Windows"); VersionCondition::addPredefinedGlobalIdent("Win32"); VersionCondition::addPredefinedGlobalIdent("mingw32"); @@ -663,35 +649,31 @@ int main(int argc, char** argv) fatal(); break; case llvm::Triple::Linux: - global.params.os = OSLinux; VersionCondition::addPredefinedGlobalIdent("linux"); VersionCondition::addPredefinedGlobalIdent("Posix"); break; case llvm::Triple::Haiku: - global.params.os = OSHaiku; VersionCondition::addPredefinedGlobalIdent("Haiku"); VersionCondition::addPredefinedGlobalIdent("Posix"); break; case llvm::Triple::Darwin: - global.params.os = OSMacOSX; + global.params.os = OSMacOSX; // FIXME: Do we need to distinguish between Darwin and MacOSX? VersionCondition::addPredefinedGlobalIdent("OSX"); VersionCondition::addPredefinedGlobalIdent("darwin"); VersionCondition::addPredefinedGlobalIdent("Posix"); break; case llvm::Triple::FreeBSD: - global.params.os = OSFreeBSD; VersionCondition::addPredefinedGlobalIdent("freebsd"); VersionCondition::addPredefinedGlobalIdent("FreeBSD"); VersionCondition::addPredefinedGlobalIdent("Posix"); break; case llvm::Triple::Solaris: - global.params.os = OSSolaris; VersionCondition::addPredefinedGlobalIdent("solaris"); VersionCondition::addPredefinedGlobalIdent("Solaris"); VersionCondition::addPredefinedGlobalIdent("Posix"); break; default: - error("target '%s' is not yet supported", global.params.targetTriple); + error("target '%s' is not yet supported", global.params.targetTriple.str().c_str()); fatal(); } diff --git a/gen/asmstmt.cpp b/gen/asmstmt.cpp index 5ae2656c..145942a5 100644 --- a/gen/asmstmt.cpp +++ b/gen/asmstmt.cpp @@ -149,7 +149,7 @@ Statement *AsmStatement::semantic(Scope *sc) bool err = false; if ((global.params.cpu != ARCHx86) && (global.params.cpu != ARCHx86_64)) { - error("inline asm is not supported for the \"%s\" architecture", global.params.llvmArch); + error("inline asm is not supported for the \"%s\" architecture", global.params.targetTriple.getArchName().str().c_str()); err = true; } if (!global.params.useInlineAsm) diff --git a/gen/module.cpp b/gen/module.cpp index 31c62bbd..e8b9c189 100644 --- a/gen/module.cpp +++ b/gen/module.cpp @@ -242,7 +242,7 @@ llvm::Module* Module::genLLVMModule(llvm::LLVMContext& context, Ir* sir) sir->setState(&ir); // set target triple - ir.module->setTargetTriple(global.params.targetTriple); + ir.module->setTargetTriple(global.params.targetTriple.str()); // set final data layout ir.module->setDataLayout(gTargetData->getStringRepresentation()); diff --git a/gen/naked.cpp b/gen/naked.cpp index b703f758..3863afc0 100644 --- a/gen/naked.cpp +++ b/gen/naked.cpp @@ -344,7 +344,7 @@ void emitABIReturnAsmStmt(IRAsmBlock* asmblock, Loc loc, FuncDeclaration* fdecl) // unsupported else { - error(loc, "this target (%s) does not implement inline asm falling off the end of the function", global.params.targetTriple); + error(loc, "this target (%s) does not implement inline asm falling off the end of the function", global.params.targetTriple.str().c_str()); fatal(); }