]> granicus.if.org Git - clang/commitdiff
Add support for Android Vector calling convention for AArch64
authorNirav Dave <niravd@google.com>
Mon, 22 Feb 2016 16:48:42 +0000 (16:48 +0000)
committerNirav Dave <niravd@google.com>
Mon, 22 Feb 2016 16:48:42 +0000 (16:48 +0000)
This modification applies the following Android commit when we have an
Android environment. This is the sole non-renderscript in the Android repo

commit 9212d4fb30a3ca2f4ee966dd2748c35573d9682c
Author: Tim Murray <timmurray@google.com>
Date:   Fri Aug 15 16:00:15 2014 -0700

    Update vector calling convention for AArch64.

    bug 16846318

    Change-Id: I3cfd167758b4bd634d8480ee6ba6bb55d61f82a7

Reviewers: srhines, jyknight

Subscribers: mcrosier, aemerson, rengolin, tberghammer, danalbert, srhines

Differential Revision: http://reviews.llvm.org/D17448

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@261533 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/ABIInfo.h
lib/CodeGen/TargetInfo.cpp
test/CodeGen/arm64-abi-vector.c

index a65f2708561632f05fbdb18360d8ba27ebd85a5f..24410715df68e82d1a4f0558dbd8b3154b488ef5 100644 (file)
@@ -85,6 +85,8 @@ namespace clang {
                                        CodeGen::Address VAListAddr,
                                        QualType Ty) const = 0;
 
+    bool isAndroid() const;
+
     /// Emit the target dependent code to load a value of
     /// \arg Ty from the \c __builtin_ms_va_list pointed to by \arg VAListAddr.
     virtual CodeGen::Address EmitMSVAArg(CodeGen::CodeGenFunction &CGF,
index 8a5cc6c3df87bfd6468be8b2a30e58bc52ada485..7a122772a490488ebaa67c1fb3475d68a930196c 100644 (file)
@@ -117,6 +117,8 @@ const TargetInfo &ABIInfo::getTarget() const {
   return CGT.getTarget();
 }
 
+bool ABIInfo:: isAndroid() const { return getTarget().getTriple().isAndroid(); }
+
 bool ABIInfo::isHomogeneousAggregateBaseType(QualType Ty) const {
   return false;
 }
@@ -4319,6 +4321,11 @@ ABIArgInfo AArch64ABIInfo::classifyArgumentType(QualType Ty) const {
   // Handle illegal vector types here.
   if (isIllegalVectorType(Ty)) {
     uint64_t Size = getContext().getTypeSize(Ty);
+    // Android promotes <2 x i8> to i16, not i32
+    if(isAndroid() && (Size <= 16)) {
+      llvm::Type *ResType = llvm::Type::getInt16Ty(getVMContext());
+      return ABIArgInfo::getDirect(ResType);
+    }
     if (Size <= 32) {
       llvm::Type *ResType = llvm::Type::getInt32Ty(getVMContext());
       return ABIArgInfo::getDirect(ResType);
@@ -4803,11 +4810,6 @@ public:
     }
   }
 
-  bool isAndroid() const {
-    return (getTarget().getTriple().getEnvironment() ==
-            llvm::Triple::Android);
-  }
-
   ABIKind getABIKind() const { return Kind; }
 
 private:
index 29aeadb66da40edf3db9befe360489784a2302f7..fd828d99d28e12ca54ddd19425ac3ad0080edbc2 100644 (file)
@@ -1,7 +1,9 @@
 // RUN: %clang_cc1 -triple arm64-apple-ios7 -target-abi darwinpcs -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple aarch64-linux-android -emit-llvm -o - %s | FileCheck -check-prefix=ANDROID %s
 
 #include <stdarg.h>
 
+typedef __attribute__(( ext_vector_type(2) ))  char __char2;
 typedef __attribute__(( ext_vector_type(3) ))  char __char3;
 typedef __attribute__(( ext_vector_type(4) ))  char __char4;
 typedef __attribute__(( ext_vector_type(5) ))  char __char5;
@@ -13,6 +15,26 @@ typedef __attribute__(( ext_vector_type(3) ))  int __int3;
 typedef __attribute__(( ext_vector_type(5) ))  int __int5;
 typedef __attribute__(( ext_vector_type(3) ))  double __double3;
 
+// Passing legal vector types as varargs. Check that we've allocated the appropriate size
+double varargs_vec_2c(int fixed, ...) {
+// ANDROID: varargs_vec_2c
+// ANDROID: [[VAR:%.*]] = alloca <2 x i8>, align 2
+// ANDROID: [[AP_NEXT:%.*]] = getelementptr inbounds i8, i8* [[AP_CUR:%.*]], i64 8
+// ANDROID: bitcast i8* [[AP_CUR]] to <2 x i8>*
+  va_list ap;
+  double sum = fixed;
+  va_start(ap, fixed);
+  __char2 c3 = va_arg(ap, __char2);
+  sum = sum + c3.x + c3.y;
+  va_end(ap);
+  return sum;
+}
+
+double test_2c(__char2 *in) {
+// ANDROID: call double (i32, ...) @varargs_vec_2c(i32 3, i16 {{%.*}})
+  return varargs_vec_2c(3, *in);
+}
+
 double varargs_vec_3c(int fixed, ...) {
 // CHECK: varargs_vec_3c
 // CHECK: alloca <3 x i8>, align 4