]> granicus.if.org Git - clang/commitdiff
[mips] Support 128-bit int in N32 ABI by overriding TargetInfo::hasInt128Type()
authorDaniel Sanders <daniel.sanders@imgtec.com>
Thu, 24 Apr 2014 16:05:26 +0000 (16:05 +0000)
committerDaniel Sanders <daniel.sanders@imgtec.com>
Thu, 24 Apr 2014 16:05:26 +0000 (16:05 +0000)
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

include/clang/Basic/TargetInfo.h
lib/Basic/Targets.cpp
test/CodeGen/mips-type-sizes-int128.c [new file with mode: 0644]
test/CodeGen/mips-type-sizes.c [new file with mode: 0644]

index 24a6fa612c0213a212a33fa03e39cec9b219a1f2..f9f7904cb3a06edbdd3fd2cbc3246253f30a66bd 100644 (file)
@@ -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.
index 59f5a018b0bfbdd6b04c311a892711f33789d644..f6ccbd17b9bdbcf1e062d49d93085ec37d7dce38 100644 (file)
@@ -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 (file)
index 0000000..85ad73d
--- /dev/null
@@ -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 (file)
index 0000000..963b282
--- /dev/null
@@ -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
+}
+