diff options
author | Derek Schuff <dschuff@google.com> | 2012-10-11 16:55:58 +0000 |
---|---|---|
committer | Derek Schuff <dschuff@google.com> | 2012-10-11 16:55:58 +0000 |
commit | 7da46f949f6ec63d7c7dcda5f49588261c669ffb (patch) | |
tree | c62983f49fd6a6948a7edb2f9814dd403eefd3f4 | |
parent | 0142f0cf0859c1622f66edaaaafddcdfb8918376 (diff) |
Properly factor Native Client defines to support NaCl as an OS
with x86/ARM architecture
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@165722 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Basic/Targets.cpp | 53 | ||||
-rw-r--r-- | lib/CodeGen/TargetInfo.cpp | 10 | ||||
-rw-r--r-- | test/CodeGen/arm-aapcs-vfp.c | 6 | ||||
-rw-r--r-- | test/CodeGen/long-double-x86-nacl.c | 7 | ||||
-rw-r--r-- | test/CodeGen/x86_64-arguments-nacl.c | 92 | ||||
-rw-r--r-- | test/Driver/x86_64-nacl-defines.cpp | 45 | ||||
-rw-r--r-- | test/Driver/x86_64-nacl-types.cpp | 36 |
7 files changed, 238 insertions, 11 deletions
diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp index 4948ba45b6..d421b058eb 100644 --- a/lib/Basic/Targets.cpp +++ b/lib/Basic/Targets.cpp @@ -590,6 +590,43 @@ public: : OSTargetInfo<Target>(triple) {} }; +template <typename Target> +class NaClTargetInfo : public OSTargetInfo<Target> { + protected: + virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, + MacroBuilder &Builder) const { + if (Opts.POSIXThreads) + Builder.defineMacro("_REENTRANT"); + if (Opts.CPlusPlus) + Builder.defineMacro("_GNU_SOURCE"); + + DefineStd(Builder, "unix", Opts); + Builder.defineMacro("__ELF__"); + Builder.defineMacro("__native_client__"); + } + public: + NaClTargetInfo(const std::string &triple) + : OSTargetInfo<Target>(triple) { + this->UserLabelPrefix = ""; + this->LongAlign = 32; + this->LongWidth = 32; + this->PointerAlign = 32; + this->PointerWidth = 32; + this->IntMaxType = TargetInfo::SignedLongLong; + this->UIntMaxType = TargetInfo::UnsignedLongLong; + this->Int64Type = TargetInfo::SignedLongLong; + this->DoubleAlign = 64; + this->LongDoubleWidth = 64; + this->LongDoubleAlign = 64; + this->SizeType = TargetInfo::UnsignedInt; + this->PtrDiffType = TargetInfo::SignedInt; + this->IntPtrType = TargetInfo::SignedInt; + this->RegParmMax = 2; + this->LongDoubleFormat = &llvm::APFloat::IEEEdouble; + this->DescriptionString = "e-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-" + "f32:32:32-f64:64:64-p:32:32:32-v128:32:32"; + } +}; } // end anonymous namespace. //===----------------------------------------------------------------------===// @@ -4197,15 +4234,7 @@ public: } virtual void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { - DefineStd(Builder, "unix", Opts); - Builder.defineMacro("__ELF__"); - if (Opts.POSIXThreads) - Builder.defineMacro("_REENTRANT"); - if (Opts.CPlusPlus) - Builder.defineMacro("_GNU_SOURCE"); - Builder.defineMacro("__LITTLE_ENDIAN__"); - Builder.defineMacro("__native_client__"); getArchDefines(Opts, Builder); } virtual bool hasFeature(StringRef Feature) const { @@ -4278,6 +4307,8 @@ static TargetInfo *AllocateTarget(const std::string &T) { return new BitrigTargetInfo<ARMTargetInfo>(T); case llvm::Triple::RTEMS: return new RTEMSTargetInfo<ARMTargetInfo>(T); + case llvm::Triple::NativeClient: + return new NaClTargetInfo<ARMTargetInfo>(T); default: return new ARMTargetInfo(T); } @@ -4348,7 +4379,7 @@ static TargetInfo *AllocateTarget(const std::string &T) { case llvm::Triple::le32: switch (os) { case llvm::Triple::NativeClient: - return new PNaClTargetInfo(T); + return new NaClTargetInfo<PNaClTargetInfo>(T); default: return NULL; } @@ -4453,6 +4484,8 @@ static TargetInfo *AllocateTarget(const std::string &T) { return new HaikuX86_32TargetInfo(T); case llvm::Triple::RTEMS: return new RTEMSX86_32TargetInfo(T); + case llvm::Triple::NativeClient: + return new NaClTargetInfo<X86_32TargetInfo>(T); default: return new X86_32TargetInfo(T); } @@ -4482,6 +4515,8 @@ static TargetInfo *AllocateTarget(const std::string &T) { return new MinGWX86_64TargetInfo(T); case llvm::Triple::Win32: // This is what Triple.h supports now. return new VisualStudioWindowsX86_64TargetInfo(T); + case llvm::Triple::NativeClient: + return new NaClTargetInfo<X86_64TargetInfo>(T); default: return new X86_64TargetInfo(T); } diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp index 3136245a9a..887ca890bc 100644 --- a/lib/CodeGen/TargetInfo.cpp +++ b/lib/CodeGen/TargetInfo.cpp @@ -1333,7 +1333,10 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase, Hi = Integer; } else if (k >= BuiltinType::Bool && k <= BuiltinType::LongLong) { Current = Integer; - } else if (k == BuiltinType::Float || k == BuiltinType::Double) { + } else if ((k == BuiltinType::Float || k == BuiltinType::Double) || + (k == BuiltinType::LongDouble && + getContext().getTargetInfo().getTriple().getOS() == + llvm::Triple::NativeClient)) { Current = SSE; } else if (k == BuiltinType::LongDouble) { Lo = X87; @@ -1419,7 +1422,10 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase, Lo = Hi = Integer; } else if (ET == getContext().FloatTy) Current = SSE; - else if (ET == getContext().DoubleTy) + else if (ET == getContext().DoubleTy || + (ET == getContext().LongDoubleTy && + getContext().getTargetInfo().getTriple().getOS() == + llvm::Triple::NativeClient)) Lo = Hi = SSE; else if (ET == getContext().LongDoubleTy) Current = ComplexX87; diff --git a/test/CodeGen/arm-aapcs-vfp.c b/test/CodeGen/arm-aapcs-vfp.c index 614b52dad5..7210229f37 100644 --- a/test/CodeGen/arm-aapcs-vfp.c +++ b/test/CodeGen/arm-aapcs-vfp.c @@ -6,6 +6,12 @@ // RUN: -ffreestanding \ // RUN: -emit-llvm -w -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple armv7-unknown-nacl-gnueabi \ +// RUN: -target-cpu cortex-a8 \ +// RUN: -mfloat-abi hard \ +// RUN: -ffreestanding \ +// RUN: -emit-llvm -w -o - %s | FileCheck %s + #include <arm_neon.h> struct homogeneous_struct { diff --git a/test/CodeGen/long-double-x86-nacl.c b/test/CodeGen/long-double-x86-nacl.c new file mode 100644 index 0000000000..175129cb6a --- /dev/null +++ b/test/CodeGen/long-double-x86-nacl.c @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - -triple=i686-unknown-nacl | FileCheck %s + +long double x = 0; +int checksize[sizeof(x) == 8 ? 1 : -1]; + +// CHECK: define void @s1(double %a) +void s1(long double a) {} diff --git a/test/CodeGen/x86_64-arguments-nacl.c b/test/CodeGen/x86_64-arguments-nacl.c new file mode 100644 index 0000000000..d864a7511b --- /dev/null +++ b/test/CodeGen/x86_64-arguments-nacl.c @@ -0,0 +1,92 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-nacl -emit-llvm -o - %s| FileCheck %s +#include <stdarg.h> +// Test for x86-64 structure representation (instead of pnacl representation), +// in particular for unions. Also crib a few tests from x86 Linux. + +union PP_VarValue { + int as_int; + double as_double; + long long as_i64; +}; + +struct PP_Var { + int type; + int padding; + union PP_VarValue value; +}; + +// CHECK: define { i64, i64 } @f0() +struct PP_Var f0() { + struct PP_Var result = { 0, 0, 0 }; + return result; +} + +// CHECK: define void @f1(i64 %p1.coerce0, i64 %p1.coerce1) +void f1(struct PP_Var p1) { while(1) {} } + +// long doubles are 64 bits on NaCl +// CHECK: define double @f5() +long double f5(void) { + return 0; +} + +// CHECK: define void @f6(i8 signext %a0, i16 signext %a1, i32 %a2, i64 %a3, i8* %a4) +void f6(char a0, short a1, int a2, long long a3, void *a4) { +} + +// CHECK: define i64 @f8_1() +// CHECK: define void @f8_2(i64 %a0.coerce) +union u8 { + long double a; + int b; +}; +union u8 f8_1() { while (1) {} } +void f8_2(union u8 a0) {} + +// CHECK: define i64 @f9() +struct s9 { int a; int b; int : 0; } f9(void) { while (1) {} } + +// CHECK: define void @f10(i64 %a0.coerce) +struct s10 { int a; int b; int : 0; }; +void f10(struct s10 a0) {} + +// CHECK: define double @f11() +union { long double a; float b; } f11() { while (1) {} } + +// CHECK: define i32 @f12_0() +// CHECK: define void @f12_1(i32 %a0.coerce) +struct s12 { int a __attribute__((aligned(16))); }; +struct s12 f12_0(void) { while (1) {} } +void f12_1(struct s12 a0) {} + +// Check that sret parameter is accounted for when checking available integer +// registers. +// CHECK: define void @f13(%struct.s13_0* noalias sret %agg.result, i32 %a, i32 %b, i32 %c, i32 %d, {{.*}}* byval align 8 %e, i32 %f) + +struct s13_0 { long long f0[3]; }; +struct s13_1 { long long f0[2]; }; +struct s13_0 f13(int a, int b, int c, int d, + struct s13_1 e, int f) { while (1) {} } + +// CHECK: define void @f20(%struct.s20* byval align 32 %x) +struct __attribute__((aligned(32))) s20 { + int x; + int y; +}; +void f20(struct s20 x) {} + + +// CHECK: declare void @func(i64) +typedef struct _str { + union { + long double a; + long c; + }; +} str; + +void func(str s); +str ss; +void f9122143() +{ + func(ss); +} diff --git a/test/Driver/x86_64-nacl-defines.cpp b/test/Driver/x86_64-nacl-defines.cpp new file mode 100644 index 0000000000..caa9a74d2d --- /dev/null +++ b/test/Driver/x86_64-nacl-defines.cpp @@ -0,0 +1,45 @@ +// RUN: %clang -target x86_64-unknown-nacl -ccc-echo %s -emit-llvm-only -c 2>&1 | FileCheck %s -check-prefix=ECHO +// RUN: %clang -target x86_64-unknown-nacl %s -emit-llvm -S -c -o - | FileCheck %s +// RUN: %clang -target x86_64-unknown-nacl %s -emit-llvm -S -c -pthread -o - | FileCheck %s -check-prefix=THREADS + +// ECHO: {{.*}} -cc1 {{.*}}x86_64-nacl-defines.c + +// Check platform defines + +// CHECK: __LITTLE_ENDIAN__defined +#ifdef __LITTLE_ENDIAN__ +void __LITTLE_ENDIAN__defined() {} +#endif + +// CHECK: __native_client__defined +#ifdef __native_client__ +void __native_client__defined() {} +#endif + +// CHECK: __x86_64__defined +#ifdef __x86_64__ +void __x86_64__defined() {} +#endif + +// CHECK: unixdefined +#ifdef unix +void unixdefined() {} +#endif + +// CHECK: __ELF__defined +#ifdef __ELF__ +void __ELF__defined() {} +#endif + +// CHECK: _GNU_SOURCEdefined +#ifdef _GNU_SOURCE +void _GNU_SOURCEdefined() {} +#endif + +// THREADS: _REENTRANTdefined +// CHECK: _REENTRANTundefined +#ifdef _REENTRANT +void _REENTRANTdefined() {} +#else +void _REENTRANTundefined() {} +#endif diff --git a/test/Driver/x86_64-nacl-types.cpp b/test/Driver/x86_64-nacl-types.cpp new file mode 100644 index 0000000000..2cdc26ddca --- /dev/null +++ b/test/Driver/x86_64-nacl-types.cpp @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-nacl -std=c++11 -verify %s + +#include <stddef.h> +#include <stdarg.h> + +static_assert(alignof(char) == 1, "alignof char is wrong"); + +static_assert(alignof(short) == 2, "sizeof short is wrong"); +static_assert(alignof(short) == 2, "alignof short is wrong"); + +static_assert(alignof(int) == 4, "sizeof int is wrong"); +static_assert(alignof(int) == 4, "alignof int is wrong"); + +static_assert(sizeof(long) == 4, "sizeof long is wrong"); +static_assert(sizeof(long) == 4, "alignof long is wrong"); + +static_assert(sizeof(long long) == 8, "sizeof long long is wrong wrong"); +static_assert(alignof(long long) == 8, "alignof long long is wrong wrong"); + +static_assert(sizeof(void*) == 4, "sizeof void * is wrong"); +static_assert(alignof(void*) == 4, "alignof void * is wrong"); + +static_assert(sizeof(float) == 4, "sizeof float is wrong"); +static_assert(alignof(float) == 4, "alignof float is wrong"); + +static_assert(sizeof(double) == 8, "sizeof double is wrong"); +static_assert(alignof(double) == 8, "alignof double is wrong"); + +static_assert(sizeof(long double) == 8, "sizeof long double is wrong"); +static_assert(alignof(long double) == 8, "alignof long double is wrong"); + +static_assert(sizeof(va_list) == 16, "sizeof va_list is wrong"); +static_assert(alignof(va_list) == 4, "alignof va_list is wrong"); + +static_assert(sizeof(size_t) == 4, "sizeof size_t is wrong"); +static_assert(alignof(size_t) == 4, "alignof size_t is wrong"); |