forked from OSchip/llvm-project
Properly factor Native Client defines to support NaCl as an OS
with x86/ARM architecture llvm-svn: 165722
This commit is contained in:
parent
d0d7860f40
commit
57b7e8f63f
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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) {}
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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");
|
Loading…
Reference in New Issue