diff options
| author | Saleem Abdulrasool <compnerd@compnerd.org> | 2014-04-04 20:31:19 +0000 | 
|---|---|---|
| committer | Saleem Abdulrasool <compnerd@compnerd.org> | 2014-04-04 20:31:19 +0000 | 
| commit | f4c9e49f94494154f23f20f84a79552c9f1a03fb (patch) | |
| tree | 2ff0cce22fe31ab23f5d0510f5782caf879e228e | |
| parent | cf6f688a403f046ec9f81dfbfd04621ff7777072 (diff) | |
| download | bcm5719-llvm-f4c9e49f94494154f23f20f84a79552c9f1a03fb.tar.gz bcm5719-llvm-f4c9e49f94494154f23f20f84a79552c9f1a03fb.zip  | |
Driver: add target definition for Windows on ARM
This introduces the definitions needed for the Windows on ARM target.  Add
target definitions for both the MSVC environment and the MSVC + Itanium C++ ABI
environment.  The Visual Studio definitions correspond to the definitions
provided by Visual Studio 2012.
llvm-svn: 205650
| -rw-r--r-- | clang/include/clang/Basic/DiagnosticDriverKinds.td | 3 | ||||
| -rw-r--r-- | clang/lib/Basic/Targets.cpp | 101 | ||||
| -rw-r--r-- | clang/lib/Driver/ToolChain.cpp | 3 | ||||
| -rw-r--r-- | clang/lib/Driver/Tools.cpp | 31 | ||||
| -rw-r--r-- | clang/test/Driver/windows-arm-minimal-arch.c | 5 | ||||
| -rw-r--r-- | clang/test/Parser/arm-windows-calling-convention-handling.c | 10 | ||||
| -rw-r--r-- | clang/test/Preprocessor/woa-defaults.c | 33 | 
7 files changed, 180 insertions, 6 deletions
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td index 71080ba552f..a64b1ae63ce 100644 --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -82,6 +82,9 @@ def err_drv_invalid_libcxx_deployment : Error<  def err_drv_malformed_sanitizer_blacklist : Error<    "malformed sanitizer blacklist: '%0'">; +def err_target_unsupported_arch +  : Error<"the target architecture '%0' is not supported by the target '%1'">; +  def err_drv_I_dash_not_supported : Error<    "'%0' not supported, please use -iquote instead">;  def err_drv_unknown_argument : Error<"unknown argument: '%0'">; diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp index 44b92674c85..a6272ef64a0 100644 --- a/clang/lib/Basic/Targets.cpp +++ b/clang/lib/Basic/Targets.cpp @@ -3708,6 +3708,9 @@ class ARMTargetInfo : public TargetInfo {    static const Builtin::Info BuiltinInfo[];    static bool shouldUseInlineAtomic(const llvm::Triple &T) { +    if (T.isOSWindows()) +      return true; +      // On linux, binaries targeting old cpus call functions in libgcc to      // perform atomic operations. The implementation in libgcc then calls into      // the kernel which on armv6 and newer uses ldrex and strex. The net result @@ -3774,19 +3777,30 @@ class ARMTargetInfo : public TargetInfo {      if (IsThumb) {        // Thumb1 add sp, #imm requires the immediate value be multiple of 4,        // so set preferred for small types to 32. -      if (T.isOSBinFormatMachO()) +      if (T.isOSBinFormatMachO()) {          DescriptionString = BigEndian ?                                "E-m:o-p:32:32-i1:8:32-i8:8:32-i16:16:32-i64:64-"                                "v128:64:128-a:0:32-n32-S64" :                                "e-m:o-p:32:32-i1:8:32-i8:8:32-i16:16:32-i64:64-"                                "v128:64:128-a:0:32-n32-S64"; -      else +      } else if (T.isOSWindows()) { +        // FIXME: this is invalid for WindowsCE +        assert(!BigEndian && "Windows on ARM does not support big endian"); +        DescriptionString = "e" +                            "-m:e" +                            "-p:32:32" +                            "-i1:8:32-i8:8:32-i16:16:32-i64:64" +                            "-v128:64:128" +                            "-a:0:32" +                            "-n32" +                            "-S64"; +      } else {          DescriptionString = BigEndian ?                                "E-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-i64:64-"                                "v128:64:128-a:0:32-n32-S64" :                                "e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-i64:64-"                                "v128:64:128-a:0:32-n32-S64"; - +      }      } else {        if (T.isOSBinFormatMachO())          DescriptionString = BigEndian ? @@ -4093,12 +4107,14 @@ public:      // FIXME: It's more complicated than this and we don't really support      // interworking. -    if (5 <= CPUArchVer && CPUArchVer <= 8) +    // Windows on ARM does not "support" interworking +    if (5 <= CPUArchVer && CPUArchVer <= 8 && !getTriple().isOSWindows())        Builder.defineMacro("__THUMB_INTERWORK__");      if (ABI == "aapcs" || ABI == "aapcs-linux" || ABI == "aapcs-vfp") {        // Embedded targets on Darwin follow AAPCS, but not EABI. -      if (!getTriple().isOSDarwin()) +      // Windows on ARM follows AAPCS VFP, but does not conform to EABI. +      if (!getTriple().isOSDarwin() && !getTriple().isOSWindows())          Builder.defineMacro("__ARM_EABI__");        Builder.defineMacro("__ARM_PCS", "1"); @@ -4371,6 +4387,72 @@ public:  } // end anonymous namespace.  namespace { +class WindowsARMTargetInfo : public WindowsTargetInfo<ARMleTargetInfo> { +  const llvm::Triple Triple; +public: +  WindowsARMTargetInfo(const llvm::Triple &Triple) +    : WindowsTargetInfo<ARMleTargetInfo>(Triple), Triple(Triple) { +    TLSSupported = false; +    WCharType = UnsignedShort; +    SizeType = UnsignedInt; +    UserLabelPrefix = ""; +  } +  void getVisualStudioDefines(const LangOptions &Opts, +                              MacroBuilder &Builder) const { +    WindowsTargetInfo<ARMleTargetInfo>::getVisualStudioDefines(Opts, Builder); + +    // FIXME: this is invalid for WindowsCE +    Builder.defineMacro("_M_ARM_NT", "1"); +    Builder.defineMacro("_M_ARMT", "_M_ARM"); +    Builder.defineMacro("_M_THUMB", "_M_ARM"); + +    assert((Triple.getArch() == llvm::Triple::arm || +            Triple.getArch() == llvm::Triple::thumb) && +           "invalid architecture for Windows ARM target info"); +    unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 4 : 6; +    Builder.defineMacro("_M_ARM", Triple.getArchName().substr(Offset)); + +    // TODO map the complete set of values +    // 31: VFPv3 40: VFPv4 +    Builder.defineMacro("_M_ARM_FP", "31"); +  } +}; + +// Windows ARM + Itanium C++ ABI Target +class ItaniumWindowsARMleTargetInfo : public WindowsARMTargetInfo { +public: +  ItaniumWindowsARMleTargetInfo(const llvm::Triple &Triple) +    : WindowsARMTargetInfo(Triple) { +    TheCXXABI.set(TargetCXXABI::GenericARM); +  } + +  void getTargetDefines(const LangOptions &Opts, +                        MacroBuilder &Builder) const override { +    WindowsARMTargetInfo::getTargetDefines(Opts, Builder); + +    if (Opts.MSVCCompat) +      WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder); +  } +}; + +// Windows ARM, MS (C++) ABI +class MicrosoftARMleTargetInfo : public WindowsARMTargetInfo { +public: +  MicrosoftARMleTargetInfo(const llvm::Triple &Triple) +    : WindowsARMTargetInfo(Triple) { +    TheCXXABI.set(TargetCXXABI::Microsoft); +  } + +  void getTargetDefines(const LangOptions &Opts, +                        MacroBuilder &Builder) const override { +    WindowsARMTargetInfo::getTargetDefines(Opts, Builder); +    WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder); +  } +}; +} + + +namespace {  class DarwinARMTargetInfo :    public DarwinTargetInfo<ARMleTargetInfo> {  protected: @@ -6058,6 +6140,15 @@ static TargetInfo *AllocateTarget(const llvm::Triple &Triple) {        return new RTEMSTargetInfo<ARMleTargetInfo>(Triple);      case llvm::Triple::NaCl:        return new NaClTargetInfo<ARMleTargetInfo>(Triple); +    case llvm::Triple::Win32: +      switch (Triple.getEnvironment()) { +      default: +        return new ARMleTargetInfo(Triple); +      case llvm::Triple::Itanium: +        return new ItaniumWindowsARMleTargetInfo(Triple); +      case llvm::Triple::MSVC: +        return new MicrosoftARMleTargetInfo(Triple); +      }      default:        return new ARMleTargetInfo(Triple);      } diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index d164edd7347..dd2a2bc64fd 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -214,6 +214,9 @@ std::string ToolChain::ComputeLLVMTriple(const ArgList &Args,      bool ThumbDefault = Suffix.startswith("v6m") || Suffix.startswith("v7m") ||        Suffix.startswith("v7em") ||        (Suffix.startswith("v7") && getTriple().isOSBinFormatMachO()); +    // FIXME: this is invalid for WindowsCE +    if (getTriple().isOSWindows()) +      ThumbDefault = true;      std::string ArchName;      if (IsBigEndian)        ArchName = "armeb"; diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp index 6acc3d5f58a..cd369d72eb5 100644 --- a/clang/lib/Driver/Tools.cpp +++ b/clang/lib/Driver/Tools.cpp @@ -475,6 +475,10 @@ static bool isSignedCharDefault(const llvm::Triple &Triple) {    case llvm::Triple::arm64:    case llvm::Triple::arm:    case llvm::Triple::armeb: +    if (Triple.isOSDarwin() || Triple.isOSWindows()) +      return true; +    return false; +    case llvm::Triple::ppc:    case llvm::Triple::ppc64:      if (Triple.isOSDarwin()) @@ -645,6 +649,11 @@ StringRef tools::arm::getARMFloatABI(const Driver &D, const ArgList &Args,        break;      } +    // FIXME: this is invalid for WindowsCE +    case llvm::Triple::Win32: +      FloatABI = "hard"; +      break; +      case llvm::Triple::FreeBSD:        switch(Triple.getEnvironment()) {        case llvm::Triple::GNUEABIHF: @@ -772,6 +781,9 @@ void Clang::AddARMTargetArgs(const ArgList &Args,      } else {        ABIName = "apcs-gnu";      } +  } else if (Triple.isOSWindows()) { +    // FIXME: this is invalid for WindowsCE +    ABIName = "aapcs";    } else {      // Select the default based on the platform.      switch(Triple.getEnvironment()) { @@ -2198,6 +2210,16 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,    std::string TripleStr = getToolChain().ComputeEffectiveClangTriple(Args);    CmdArgs.push_back(Args.MakeArgString(TripleStr)); +  const llvm::Triple TT(TripleStr); +  if (TT.isOSWindows() && (TT.getArch() == llvm::Triple::arm || +                           TT.getArch() == llvm::Triple::thumb)) { +    unsigned Offset = TT.getArch() == llvm::Triple::arm ? 4 : 6; +    unsigned Version; +    TT.getArchName().substr(Offset).getAsInteger(10, Version); +    if (Version < 7) +      D.Diag(diag::err_target_unsupported_arch) << TT.getArchName() << TripleStr; +  } +    // Push all default warning arguments that are specific to    // the given target.  These come before user provided warning options    // are provided. @@ -4835,9 +4857,16 @@ const char *arm::getARMCPUForMArch(const ArgList &Args,      }    } -  if (Triple.getOS() == llvm::Triple::NetBSD) { +  switch (Triple.getOS()) { +  case llvm::Triple::NetBSD:      if (MArch == "armv6")        return "arm1176jzf-s"; +    break; +  case llvm::Triple::Win32: +    // FIXME: this is invalid for WindowsCE +    return "cortex-a9"; +  default: +    break;    }    const char *result = llvm::StringSwitch<const char *>(MArch) diff --git a/clang/test/Driver/windows-arm-minimal-arch.c b/clang/test/Driver/windows-arm-minimal-arch.c new file mode 100644 index 00000000000..cf55b8f99d0 --- /dev/null +++ b/clang/test/Driver/windows-arm-minimal-arch.c @@ -0,0 +1,5 @@ +// RUN: not %clang -target thumbv5-windows -mcpu=arm10tdmi %s -o /dev/null 2>&1 \ +// RUN:   | FileCheck %s + +// CHECK: error: the target architecture 'thumbv5' is not supported by the target 'thumbv5--windows-msvc' + diff --git a/clang/test/Parser/arm-windows-calling-convention-handling.c b/clang/test/Parser/arm-windows-calling-convention-handling.c new file mode 100644 index 00000000000..7717aada53a --- /dev/null +++ b/clang/test/Parser/arm-windows-calling-convention-handling.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -triple thumbv7-windows -fms-compatibility -fsyntax-only -verify %s + +int __cdecl cdecl(int a, int b, int c, int d) { // expected-warning {{calling convention '__cdecl' ignored for this target}} +  return a + b + c + d; +} + +float __stdcall stdcall(float a, float b, float c, float d) { // expected-warning {{calling convention '__stdcall' ignored for this target}} +  return a + b + c + d; +} + diff --git a/clang/test/Preprocessor/woa-defaults.c b/clang/test/Preprocessor/woa-defaults.c new file mode 100644 index 00000000000..6eab3b96f41 --- /dev/null +++ b/clang/test/Preprocessor/woa-defaults.c @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 -dM -triple armv7-windows -E %s | FileCheck %s +// RUN: %clang_cc1 -dM -fno-signed-char -triple armv7-windows -E %s \ +// RUN:   | FileCheck %s -check-prefix CHECK-UNSIGNED-CHAR + +// CHECK: #define _INTEGRAL_MAX_BITS 64 +// CHECK: #define _M_ARM 7 +// CHECK: #define _M_ARMT _M_ARM +// CHECK: #define _M_ARM_FP 31 +// CHECK: #define _M_ARM_NT 1 +// CHECK: #define _M_THUMB _M_ARM +// CHECK: #define _WIN32 1 + +// CHECK: #define __ARM_PCS 1 +// CHECK: #define __ARM_PCS_VFP 1 +// CHECK: #define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ +// CHECK: #define __SIZEOF_DOUBLE__ 8 +// CHECK: #define __SIZEOF_FLOAT__ 4 +// CHECK: #define __SIZEOF_INT__ 4 +// CHECK: #define __SIZEOF_LONG_DOUBLE__ 8 +// CHECK: #define __SIZEOF_LONG_LONG__ 8 +// CHECK: #define __SIZEOF_LONG__ 4 +// CHECK: #define __SIZEOF_POINTER__ 4 +// CHECK: #define __SIZEOF_PTRDIFF_T__ 4 +// CHECK: #define __SIZEOF_SHORT__ 2 +// CHECK: #define __SIZEOF_SIZE_T__ 4 +// CHECK: #define __SIZEOF_WCHAR_T__ 2 +// CHECK: #define __SIZEOF_WINT_T__ 4 + +// CHECK-NOT: __THUMB_INTERWORK__ +// CHECK-NOT: __ARM_EABI__ +// CHECK-NOT: _CHAR_UNSIGNED + +// CHECK-UNSIGNED-CHAR: #define _CHAR_UNSIGNED 1  | 

