diff options
author | Tim Northover <Tim.Northover@arm.com> | 2013-01-31 12:13:10 +0000 |
---|---|---|
committer | Tim Northover <Tim.Northover@arm.com> | 2013-01-31 12:13:10 +0000 |
commit | c264e16a42b3f6c36521857a29ea0949d9781c22 (patch) | |
tree | c65f59d74e94b2ef6efa080c8f72e82f71fed848 /test/CodeGenCXX/aarch64-cxxabi.cpp | |
parent | 903ef044e5fe8efe5d06f63945f903ae81a262fd (diff) |
Add support for AArch64 target.
In cooperation with the LLVM patch, this should implement all scalar front-end
parts of the C and C++ ABIs for AArch64.
This patch excludes the NEON support also reviewed due to an outbreak of
batshit insanity in our legal department. That will be committed soon bringing
the changes to precisely what has been approved.
Further reviews would be gratefully received.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@174055 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CodeGenCXX/aarch64-cxxabi.cpp')
-rw-r--r-- | test/CodeGenCXX/aarch64-cxxabi.cpp | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/test/CodeGenCXX/aarch64-cxxabi.cpp b/test/CodeGenCXX/aarch64-cxxabi.cpp new file mode 100644 index 0000000000..04d9493ae6 --- /dev/null +++ b/test/CodeGenCXX/aarch64-cxxabi.cpp @@ -0,0 +1,96 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -emit-llvm -w -o - %s | FileCheck %s + +// Check differences between the generic Itanium ABI, the AArch32 version and +// the AArch64 version. + +//////////////////////////////////////////////////////////////////////////////// + +// The ABI says that the key function is the "textually first, non-inline, +// non-pure, virtual member function". The generic version decides this after +// the completion of the class definition; the AArch32 version decides this at +// the end of the translation unit. + +// We construct a class which needs a VTable here under generic ABI, but not +// AArch32. + +// (see next section for explanation of guard) +// CHECK: @_ZGVZ15guard_variablesiE4mine = internal global i64 0 + +// CHECK: @_ZTV16CheckKeyFunction = +struct CheckKeyFunction { + virtual void foo(); +}; + +// This is not inline when CheckKeyFunction is completed, so +// CheckKeyFunction::foo is the key function. VTables should be emitted. +inline void CheckKeyFunction::foo() { +} + +//////////////////////////////////////////////////////////////////////////////// + +// Guard variables only specify and use the low bit to determine status, rather +// than the low byte as in the generic Itanium ABI. However, unlike 32-bit ARM, +// they *are* 64-bits wide so check that in case confusion has occurred. + +class Guarded { +public: + Guarded(int i); + ~Guarded(); +}; + +void guard_variables(int a) { + static Guarded mine(a); +// CHECK: [[GUARDBIT:%[0-9]+]] = and i64 {{%[0-9]+}}, 1 +// CHECK: icmp eq i64 [[GUARDBIT]], 0 + + // As guards are 64-bit, these helpers should take 64-bit pointers. +// CHECK: call i32 @__cxa_guard_acquire(i64* +// CHECK: call void @__cxa_guard_release(i64* +} + +//////////////////////////////////////////////////////////////////////////////// + +// Member function pointers use the adj field to distinguish between virtual and +// nonvirtual members. As a result the adjustment is shifted (if ptr was used, a +// mask would be expected instead). + +class C { + int a(); + virtual int b(); +}; + + +int member_pointer(C &c, int (C::*func)()) { +// CHECK: ashr i64 %[[MEMPTRADJ:[0-9a-z.]+]], 1 +// CHECK: %[[ISVIRTUAL:[0-9]+]] = and i64 %[[MEMPTRADJ]], 1 +// CHECK: icmp ne i64 %[[ISVIRTUAL]], 0 + return (c.*func)(); +} + +//////////////////////////////////////////////////////////////////////////////// + +// AArch64 PCS says that va_list type is based on "struct __va_list ..." in the +// std namespace, which means it should mangle as "St9__va_list". + +// CHECK: @_Z7va_funcSt9__va_list +void va_func(__builtin_va_list l) { +} + +//////////////////////////////////////////////////////////////////////////////// + +// AArch64 constructors (like generic Itanium, but unlike AArch32) do not return +// "this". + +void test_constructor() { + Guarded g(42); +// CHECK: call void @_ZN7GuardedC1Ei +} + +//////////////////////////////////////////////////////////////////////////////// + +// In principle the AArch32 ABI allows this to be accomplished via a call to +// __aeabi_atexit instead of __cxa_atexit. Clang doesn't make use of this at the +// moment, but it's definitely not allowed for AArch64. + +// CHECK: call i32 @__cxa_atexit +Guarded g(42); |