From: Daniel Sanders Date: Thu, 24 Apr 2014 16:05:26 +0000 (+0000) Subject: [mips] Support 128-bit int in N32 ABI by overriding TargetInfo::hasInt128Type() X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4ec7faa64f2613b0e71148036b5b48fbd11b11a7;p=clang [mips] Support 128-bit int in N32 ABI by overriding TargetInfo::hasInt128Type() Summary: The condition in the base class is rather strange. It says a target has the 128-bit integer type if the size of a pointer is >= 64-bits. N32 has 32-bit pointers but 64-bit integers. I'm a bit reluctant to change this for all targets so this patch makes the method virtual and overrides it for MIPS64. Reviewers: atanasyan Reviewed By: atanasyan Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D3472 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@207121 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h index 24a6fa612c..f9f7904cb3 100644 --- a/include/clang/Basic/TargetInfo.h +++ b/include/clang/Basic/TargetInfo.h @@ -283,7 +283,7 @@ public: unsigned getLongLongAlign() const { return LongLongAlign; } /// \brief Determine whether the __int128 type is supported on this target. - bool hasInt128Type() const { return getPointerWidth(0) >= 64; } // FIXME + virtual bool hasInt128Type() const { return getPointerWidth(0) >= 64; } // FIXME /// \brief Return the alignment that is suitable for storing any /// object with a fundamental alignment requirement. diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp index 59f5a018b0..f6ccbd17b9 100644 --- a/lib/Basic/Targets.cpp +++ b/lib/Basic/Targets.cpp @@ -5874,6 +5874,8 @@ public: Aliases = GCCRegAliases; NumAliases = llvm::array_lengthof(GCCRegAliases); } + + bool hasInt128Type() const override { return true; } }; class Mips64EBTargetInfo : public Mips64TargetInfoBase { diff --git a/test/CodeGen/mips-type-sizes-int128.c b/test/CodeGen/mips-type-sizes-int128.c new file mode 100644 index 0000000000..85ad73df9b --- /dev/null +++ b/test/CodeGen/mips-type-sizes-int128.c @@ -0,0 +1,13 @@ +// RUN: not %clang_cc1 -triple mips-none-linux-gnu -emit-llvm -w -o - %s 2> %t1 +// RUN: FileCheck --check-prefix=O32 %s < %t1 + +// RUN: %clang_cc1 -triple mips64-none-linux-gnu -emit-llvm -w -target-abi n32 -o - %s | FileCheck --check-prefix=NEW %s +// RUN: %clang_cc1 -triple mips64-none-linux-gnu -emit-llvm -w -o - %s | FileCheck --check-prefix=NEW %s + +// O32 does not support __int128 so it must be tested separately +// N32/N64 behave the same way so their tests have been combined into NEW + +int check_int128() { + return sizeof(__int128); // O32: :[[@LINE]]:17: error: __int128 is not supported on this target +// NEW: ret i32 16 +} diff --git a/test/CodeGen/mips-type-sizes.c b/test/CodeGen/mips-type-sizes.c new file mode 100644 index 0000000000..963b282c01 --- /dev/null +++ b/test/CodeGen/mips-type-sizes.c @@ -0,0 +1,92 @@ +// RUN: %clang_cc1 -triple mips-none-linux-gnu -emit-llvm -w -o - %s | FileCheck --check-prefix=ALL --check-prefix=O32 %s +// RUN: %clang_cc1 -triple mips64-none-linux-gnu -emit-llvm -w -target-abi n32 -o - %s | FileCheck --check-prefix=ALL --check-prefix=N32 %s +// RUN: %clang_cc1 -triple mips64-none-linux-gnu -emit-llvm -w -o - %s | FileCheck --check-prefix=ALL --check-prefix=N64 %s + +int check_char() { + return sizeof(char); +// ALL: ret i32 1 +} + +int check_short() { + return sizeof(short); +// ALL: ret i32 2 +} + +int check_int() { + return sizeof(int); +// ALL: ret i32 4 +} + +int check_long() { + return sizeof(long); +// O32: ret i32 4 +// N32: ret i32 4 +// N64: ret i32 8 +} + +int check_longlong() { + return sizeof(long long); +// ALL: ret i32 8 +} + +int check_fp16() { + return sizeof(__fp16); +// ALL: ret i32 2 +} + +int check_float() { + return sizeof(float); +// ALL: ret i32 4 +} + +int check_double() { + return sizeof(double); +// ALL: ret i32 8 +} + +int check_longdouble() { + return sizeof(long double); +// O32: ret i32 8 +// N32: ret i32 16 +// N64: ret i32 16 +} + +int check_floatComplex() { + return sizeof(float _Complex); +// ALL: ret i32 8 +} + +int check_doubleComplex() { + return sizeof(double _Complex); +// ALL: ret i32 16 +} + +int check_longdoubleComplex() { + return sizeof(long double _Complex); +// O32: ret i32 16 +// N32: ret i32 32 +// N64: ret i32 32 +} + +int check_bool() { + return sizeof(_Bool); +// ALL: ret i32 1 +} + +int check_wchar() { + return sizeof(__WCHAR_TYPE__); +// ALL: ret i32 4 +} + +int check_wchar_is_unsigned() { + return (__WCHAR_TYPE__)-1 > (__WCHAR_TYPE__)0; +// ALL: ret i32 0 +} + +int check_ptr() { + return sizeof(void *); +// O32: ret i32 4 +// N32: ret i32 4 +// N64: ret i32 8 +} +