jasonliu created this revision.
jasonliu added reviewers: Xiangling_L, sfertile, hubert.reinterpretcast, 
cebowleratibm, ZarkoCA.
Herald added subscribers: kbarton, nemanjai.
Herald added a project: clang.

Created AIXABIInfo and AIXTargetCodeGenInfo for AIX ABI.

Some investigation and FAQ on why we created AIXABIInfo:

Use or derive PPC32/PPC64 ABIInfo for AIX: 
There are a lot of subtle differences between PPC32 and PPC64 variation. For 
AIX we do not have a huge differences between 32 bit and 64 bit for the ABI 
rules. Which means if we decide to use PPC32 for 32 bit on AIX and PPC64 for 64 
bit on AIX, we will need to add in a lot of target check to make them 
symmetric. The code flow will be really hard to follow and verify for every 
target that is trying to use them. And it’s easy for us to take a lot of 
unwanted change that really is meant for SVR targets. 
Use one ABIInfo class for both 32 bit and 64 bit on AIX will make the code much 
clear and easier to follow through. And that was one of the reason for us to 
create LowerCall_AIX/LowerFormalArgument_AIX instead of just rename and use the 
existing SVR4/Darwin one.

Derive from DefaultABIInfo:
We are going to override most of the methods in DefaultABIInfo anyway if we 
look at the analysis below.

Derive from SwiftABIInfo:
I don't think we want to claim Swift support on AIX right now.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D79035

Files:
  clang/lib/CodeGen/TargetInfo.cpp
  clang/test/CodeGen/aix-complex.c
  clang/test/CodeGen/aix-return.c
  clang/test/CodeGen/aix-struct-arg.c
  clang/test/CodeGen/aix-vaargs.c
  clang/test/CodeGen/aix-vector.c
  clang/test/CodeGen/ppc32-and-aix-struct-return.c
  clang/test/CodeGen/ppc32-dwarf.c
  clang/test/CodeGen/ppc64-dwarf.c

Index: clang/test/CodeGen/ppc64-dwarf.c
===================================================================
--- clang/test/CodeGen/ppc64-dwarf.c
+++ clang/test/CodeGen/ppc64-dwarf.c
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -triple powerpc64-unknown-unknown -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple powerpc64-unknown-aix -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple powerpc64-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,PPC64
 static unsigned char dwarf_reg_size_table[1024];
 
 int test() {
@@ -119,10 +120,10 @@
 // CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 108), align 1
 // CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 109), align 1
 // CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 110), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 111), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 112), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 113), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 114), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 115), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 116), align 1
+// PPC64-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 111), align 1
+// PPC64-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 112), align 1
+// PPC64-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 113), align 1
+// PPC64-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 114), align 1
+// PPC64-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 115), align 1
+// PPC64-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 116), align 1
 // CHECK-NEXT: ret i32 1
Index: clang/test/CodeGen/ppc32-dwarf.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/ppc32-dwarf.c
@@ -0,0 +1,126 @@
+// RUN: %clang_cc1 -triple powerpc-unknown-aix -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple powerpc-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,PPC32
+static unsigned char dwarf_reg_size_table[1024];
+
+int test() {
+  __builtin_init_dwarf_reg_size_table(dwarf_reg_size_table);
+
+  return __builtin_dwarf_sp_column();
+}
+
+// CHECK-LABEL: define i32 @test()
+// CHECK:         store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 0), align 1
+// CHECK-NEXT:    store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 1), align 1
+// CHECK-NEXT:    store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 2), align 1
+// CHECK-NEXT:    store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 3), align 1
+// CHECK-NEXT:    store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 4), align 1
+// CHECK-NEXT:    store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 5), align 1
+// CHECK-NEXT:    store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 6), align 1
+// CHECK-NEXT:    store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 7), align 1
+// CHECK-NEXT:    store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 8), align 1
+// CHECK-NEXT:    store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 9), align 1
+// CHECK-NEXT:    store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 10), align 1
+// CHECK-NEXT:    store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 11), align 1
+// CHECK-NEXT:    store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 12), align 1
+// CHECK-NEXT:    store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 13), align 1
+// CHECK-NEXT:    store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 14), align 1
+// CHECK-NEXT:    store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 15), align 1
+// CHECK-NEXT:    store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 16), align 1
+// CHECK-NEXT:    store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 17), align 1
+// CHECK-NEXT:    store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 18), align 1
+// CHECK-NEXT:    store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 19), align 1
+// CHECK-NEXT:    store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 20), align 1
+// CHECK-NEXT:    store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 21), align 1
+// CHECK-NEXT:    store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 22), align 1
+// CHECK-NEXT:    store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 23), align 1
+// CHECK-NEXT:    store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 24), align 1
+// CHECK-NEXT:    store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 25), align 1
+// CHECK-NEXT:    store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 26), align 1
+// CHECK-NEXT:    store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 27), align 1
+// CHECK-NEXT:    store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 28), align 1
+// CHECK-NEXT:    store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 29), align 1
+// CHECK-NEXT:    store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 30), align 1
+// CHECK-NEXT:    store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 31), align 1
+// CHECK-NEXT:    store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 32), align 1
+// CHECK-NEXT:    store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 33), align 1
+// CHECK-NEXT:    store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 34), align 1
+// CHECK-NEXT:    store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 35), align 1
+// CHECK-NEXT:    store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 36), align 1
+// CHECK-NEXT:    store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 37), align 1
+// CHECK-NEXT:    store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 38), align 1
+// CHECK-NEXT:    store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 39), align 1
+// CHECK-NEXT:    store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 40), align 1
+// CHECK-NEXT:    store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 41), align 1
+// CHECK-NEXT:    store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 42), align 1
+// CHECK-NEXT:    store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 43), align 1
+// CHECK-NEXT:    store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 44), align 1
+// CHECK-NEXT:    store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 45), align 1
+// CHECK-NEXT:    store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 46), align 1
+// CHECK-NEXT:    store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 47), align 1
+// CHECK-NEXT:    store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 48), align 1
+// CHECK-NEXT:    store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 49), align 1
+// CHECK-NEXT:    store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 50), align 1
+// CHECK-NEXT:    store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 51), align 1
+// CHECK-NEXT:    store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 52), align 1
+// CHECK-NEXT:    store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 53), align 1
+// CHECK-NEXT:    store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 54), align 1
+// CHECK-NEXT:    store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 55), align 1
+// CHECK-NEXT:    store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 56), align 1
+// CHECK-NEXT:    store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 57), align 1
+// CHECK-NEXT:    store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 58), align 1
+// CHECK-NEXT:    store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 59), align 1
+// CHECK-NEXT:    store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 60), align 1
+// CHECK-NEXT:    store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 61), align 1
+// CHECK-NEXT:    store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 62), align 1
+// CHECK-NEXT:    store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 63), align 1
+// CHECK-NEXT:    store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 64), align 1
+// CHECK-NEXT:    store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 65), align 1
+// CHECK-NEXT:    store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 66), align 1
+// CHECK-NEXT:    store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 67), align 1
+// CHECK-NEXT:    store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 68), align 1
+// CHECK-NEXT:    store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 69), align 1
+// CHECK-NEXT:    store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 70), align 1
+// CHECK-NEXT:    store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 71), align 1
+// CHECK-NEXT:    store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 72), align 1
+// CHECK-NEXT:    store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 73), align 1
+// CHECK-NEXT:    store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 74), align 1
+// CHECK-NEXT:    store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 75), align 1
+// CHECK-NEXT:    store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 76), align 1
+// CHECK-NEXT:    store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 77), align 1
+// CHECK-NEXT:    store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 78), align 1
+// CHECK-NEXT:    store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 79), align 1
+// CHECK-NEXT:    store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 80), align 1
+// CHECK-NEXT:    store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 81), align 1
+// CHECK-NEXT:    store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 82), align 1
+// CHECK-NEXT:    store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 83), align 1
+// CHECK-NEXT:    store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 84), align 1
+// CHECK-NEXT:    store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 85), align 1
+// CHECK-NEXT:    store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 86), align 1
+// CHECK-NEXT:    store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 87), align 1
+// CHECK-NEXT:    store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 88), align 1
+// CHECK-NEXT:    store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 89), align 1
+// CHECK-NEXT:    store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 90), align 1
+// CHECK-NEXT:    store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 91), align 1
+// CHECK-NEXT:    store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 92), align 1
+// CHECK-NEXT:    store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 93), align 1
+// CHECK-NEXT:    store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 94), align 1
+// CHECK-NEXT:    store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 95), align 1
+// CHECK-NEXT:    store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 96), align 1
+// CHECK-NEXT:    store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 97), align 1
+// CHECK-NEXT:    store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 98), align 1
+// CHECK-NEXT:    store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 99), align 1
+// CHECK-NEXT:    store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 100), align 1
+// CHECK-NEXT:    store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 101), align 1
+// CHECK-NEXT:    store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 102), align 1
+// CHECK-NEXT:    store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 103), align 1
+// CHECK-NEXT:    store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 104), align 1
+// CHECK-NEXT:    store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 105), align 1
+// CHECK-NEXT:    store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 106), align 1
+// CHECK-NEXT:    store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 107), align 1
+// CHECK-NEXT:    store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 108), align 1
+// CHECK-NEXT:    store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 109), align 1
+// CHECK-NEXT:    store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 110), align 1
+// PPC32-NEXT:    store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 111), align 1
+// PPC32-NEXT:    store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 112), align 1
+// PPC32-NEXT:    store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 113), align 1
+// PPC32-NEXT:    ret i32 1
Index: clang/test/CodeGen/ppc32-and-aix-struct-return.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/ppc32-and-aix-struct-return.c
@@ -0,0 +1,92 @@
+// REQUIRES: powerpc-registered-target
+// RUN: %clang_cc1 -triple powerpc-unknown-freebsd \
+// RUN:   -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-SVR4
+// RUN: %clang_cc1 -triple powerpc-unknown-aix \
+// RUN:   -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-AIX
+// RUN: %clang_cc1 -triple powerpc64-unknown-aix \
+// RUN:   -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-AIX
+// RUN: %clang_cc1 -triple powerpc-unknown-linux \
+// RUN:   -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-AIX
+// RUN: %clang_cc1 -triple powerpc-unknown-linux -maix-struct-return \
+// RUN:   -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-AIX
+// RUN: %clang_cc1 -triple powerpc-unknown-linux -msvr4-struct-return \
+// RUN:   -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-SVR4
+// RUN: %clang_cc1 -triple powerpc-unknown-netbsd \
+// RUN:   -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-SVR4
+// RUN: %clang_cc1 -triple powerpc-unknown-openbsd \
+// RUN:   -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-SVR4
+// RUN: %clang_cc1 -triple powerpc-unknown-openbsd -maix-struct-return \
+// RUN:   -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-AIX
+// RUN: %clang_cc1 -triple powerpc-unknown-openbsd -msvr4-struct-return \
+// RUN:   -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-SVR4
+
+typedef struct {
+} Zero;
+typedef struct {
+  char c;
+} One;
+typedef struct {
+  short s;
+} Two;
+typedef struct {
+  char c[3];
+} Three;
+typedef struct {
+  float f;
+} Four; // svr4 to return i32, not float
+typedef struct {
+  char c[5];
+} Five;
+typedef struct {
+  short s[3];
+} Six;
+typedef struct {
+  char c[7];
+} Seven;
+typedef struct {
+  int i;
+  char c;
+} Eight; // padded for alignment
+typedef struct {
+  char c[9];
+} Nine;
+
+// CHECK-AIX-LABEL: define void @ret0(%struct.Zero* noalias sret {{[^,]*}})
+// CHECK-SVR4-LABEL: define void @ret0()
+Zero ret0(void) { return (Zero){}; }
+
+// CHECK-AIX-LABEL: define void @ret1(%struct.One* noalias sret {{[^,]*}})
+// CHECK-SVR4-LABEL: define i8 @ret1()
+One ret1(void) { return (One){'a'}; }
+
+// CHECK-AIX-LABEL: define void @ret2(%struct.Two* noalias sret {{[^,]*}})
+// CHECK-SVR4-LABEL: define i16 @ret2()
+Two ret2(void) { return (Two){123}; }
+
+// CHECK-AIX-LABEL: define void @ret3(%struct.Three* noalias sret {{[^,]*}})
+// CHECK-SVR4-LABEL: define i24 @ret3()
+Three ret3(void) { return (Three){"abc"}; }
+
+// CHECK-AIX-LABEL: define void @ret4(%struct.Four* noalias sret {{[^,]*}})
+// CHECK-SVR4-LABEL: define i32 @ret4()
+Four ret4(void) { return (Four){0.4}; }
+
+// CHECK-AIX-LABEL: define void @ret5(%struct.Five* noalias sret {{[^,]*}})
+// CHECK-SVR4-LABEL: define i40 @ret5()
+Five ret5(void) { return (Five){"abcde"}; }
+
+// CHECK-AIX-LABEL: define void @ret6(%struct.Six* noalias sret {{[^,]*}})
+// CHECK-SVR4-LABEL: define i48 @ret6()
+Six ret6(void) { return (Six){12, 34, 56}; }
+
+// CHECK-AIX-LABEL: define void @ret7(%struct.Seven* noalias sret {{[^,]*}})
+// CHECK-SVR4-LABEL: define i56 @ret7()
+Seven ret7(void) { return (Seven){"abcdefg"}; }
+
+// CHECK-AIX-LABEL: define void @ret8(%struct.Eight* noalias sret {{[^,]*}})
+// CHECK-SVR4-LABEL: define i64 @ret8()
+Eight ret8(void) { return (Eight){123, 'a'}; }
+
+// CHECK-AIX-LABEL: define void @ret9(%struct.Nine* noalias sret {{[^,]*}})
+// CHECK-SVR4-LABEL: define void @ret9(%struct.Nine* noalias sret {{[^,]*}})
+Nine ret9(void) { return (Nine){"abcdefghi"}; }
Index: clang/test/CodeGen/aix-vector.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/aix-vector.c
@@ -0,0 +1,11 @@
+// REQUIRES: powerpc-registered-target
+// RUN: not %clang_cc1 -triple powerpc-unknown-aix  -target-feature +altivec \
+// RUN:   -emit-llvm -o - %s 2>&1 | FileCheck %s --check-prefixes=AIX-COM
+// RUN: not %clang_cc1 -triple powerpc64-unknown-aix  -target-feature +altivec \
+// RUN:   -emit-llvm -o - %s 2>&1 | FileCheck %s --check-prefixes=AIX-COM
+
+// AIX-COM: fatal error: error in backend: vector type is not supported on AIX yet
+vector signed int retVector(vector signed int x) {
+  return x;
+}
+
Index: clang/test/CodeGen/aix-vaargs.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/aix-vaargs.c
@@ -0,0 +1,85 @@
+// REQUIRES: powerpc-registered-target
+// REQUIRES: asserts
+// RUN: %clang_cc1 -triple powerpc-unknown-aix -emit-llvm -o - %s | FileCheck %s --check-prefixes=AIX-COM,AIX-M32
+// RUN: %clang_cc1 -triple powerpc64-unknown-aix -emit-llvm -o - %s | FileCheck %s --check-prefixes=AIX-COM,AIX-M64
+
+struct x {
+  double b;
+  long a;
+};
+
+void testva (int n, ...) {
+  __builtin_va_list ap;
+  __builtin_va_start(ap, n);
+  struct x t = __builtin_va_arg(ap, struct x);
+  __builtin_va_list ap2;
+  __builtin_va_copy(ap2, ap);
+  int v = __builtin_va_arg(ap2, int);
+  __builtin_va_end(ap2);
+  __builtin_va_end(ap);
+}
+
+// AIX-M32: define void @testva(i32 %n, ...)
+// AIX-M64: define void @testva(i32 signext %n, ...)
+
+// AIX-COM-NEXT: entry:
+// AIX-COM-NEXT:  %n.addr = alloca i32, align 4
+
+// AIX-M32-NEXT:  %ap = alloca i8*, align 4
+// AIX-M64-NEXT:  %ap = alloca i8*, align 8
+
+// AIX-COM-NEXT:  %t = alloca %struct.x, align 8
+
+// AIX-M32-NEXT:  %ap2 = alloca i8*, align 4
+// AIX-M64-NEXT:  %ap2 = alloca i8*, align 8
+
+// AIX-COM-NEXT:  %v = alloca i32, align 4
+// AIX-COM-NEXT:  store i32 %n, i32* %n.addr, align 4
+// AIX-COM-NEXT:  %ap1 = bitcast i8** %ap to i8*
+// AIX-COM-NEXT:  call void @llvm.va_start(i8* %ap1)
+
+// AIX-M32-NEXT:  %argp.cur = load i8*, i8** %ap, align 4
+// AIX-M32-NEXT:  %argp.next = getelementptr inbounds i8, i8* %argp.cur, i32 16
+// AIX-M32-NEXT:  store i8* %argp.next, i8** %ap, align 4
+// AIX-M64-NEXT:  %argp.cur = load i8*, i8** %ap, align 8
+// AIX-M64-NEXT:  %argp.next = getelementptr inbounds i8, i8* %argp.cur, i64 16
+// AIX-M64-NEXT:  store i8* %argp.next, i8** %ap, align 8
+
+// AIX-COM-NEXT:  %0 = bitcast i8* %argp.cur to %struct.x*
+// AIX-COM-NEXT:  %1 = bitcast %struct.x* %t to i8*
+// AIX-COM-NEXT:  %2 = bitcast %struct.x* %0 to i8*
+
+// AIX-M32-NEXT:  call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 8 %1, i8* align 4 %2, i32 16, i1 false)
+// AIX-M64-NEXT:  call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %1, i8* align 8 %2, i64 16, i1 false)
+
+// AIX-COM-NEXT:  %3 = bitcast i8** %ap2 to i8*
+// AIX-COM-NEXT:  %4 = bitcast i8** %ap to i8*
+// AIX-COM-NEXT:  call void @llvm.va_copy(i8* %3, i8* %4)
+
+// AIX-M32-NEXT:  %argp.cur2 = load i8*, i8** %ap2, align 4
+// AIX-M32-NEXT:  %argp.next3 = getelementptr inbounds i8, i8* %argp.cur2, i32 4
+// AIX-M32-NEXT:  store i8* %argp.next3, i8** %ap2, align 4
+// AIX-M32-NEXT:  %5 = bitcast i8* %argp.cur2 to i32*
+// AIX-M32-NEXT:  %6 = load i32, i32* %5, align 4
+// AIX-M32-NEXT:  store i32 %6, i32* %v, align 4
+// AIX-M64-NEXT:  %argp.cur2 = load i8*, i8** %ap2, align 8
+// AIX-M64-NEXT:  %argp.next3 = getelementptr inbounds i8, i8* %argp.cur2, i64 8
+// AIX-M64-NEXT:  store i8* %argp.next3, i8** %ap2, align 8
+// AIX-M64-NEXT:  %5 = getelementptr inbounds i8, i8* %argp.cur2, i64 4
+// AIX-M64-NEXT:  %6 = bitcast i8* %5 to i32*
+// AIX-M64-NEXT:  %7 = load i32, i32* %6, align 4
+// AIX-M64-NEXT:  store i32 %7, i32* %v, align 4
+
+// AIX-COM-NEXT:  %ap24 = bitcast i8** %ap2 to i8*
+// AIX-COM-NEXT:  call void @llvm.va_end(i8* %ap24)
+// AIX-COM-NEXT:  %ap5 = bitcast i8** %ap to i8*
+// AIX-COM-NEXT:  call void @llvm.va_end(i8* %ap5)
+// AIX-COM-NEXT:  ret void
+
+// AIX-COM: declare void @llvm.va_start(i8*)
+
+// AIX-M32: declare void @llvm.memcpy.p0i8.p0i8.i32(i8* noalias nocapture writeonly, i8* noalias nocapture readonly, i32, i1 immarg)
+// AIX-M64: declare void @llvm.memcpy.p0i8.p0i8.i64(i8* noalias nocapture writeonly, i8* noalias nocapture readonly, i64, i1 immarg)
+
+// AIX-COM: declare void @llvm.va_copy(i8*, i8*)
+// AIX-COM: declare void @llvm.va_end(i8*)
Index: clang/test/CodeGen/aix-struct-arg.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/aix-struct-arg.c
@@ -0,0 +1,66 @@
+// REQUIRES: powerpc-registered-target
+// RUN: %clang_cc1 -triple powerpc-unknown-aix \
+// RUN:   -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-AIX
+// RUN: %clang_cc1 -triple powerpc64-unknown-aix \
+// RUN:   -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-AIX
+
+typedef struct {
+} Zero;
+typedef struct {
+  char c;
+} One;
+typedef struct {
+  short s;
+} Two;
+typedef struct {
+  char c[3];
+} Three;
+typedef struct {
+  float f;
+} Four;
+typedef struct {
+  char c[5];
+} Five;
+typedef struct {
+  short s[3];
+} Six;
+typedef struct {
+  char c[7];
+} Seven;
+typedef struct {
+  int i;
+  char c;
+} Eight; // padded for alignment
+typedef struct {
+  char c[9];
+} Nine;
+
+// CHECK-AIX-LABEL: define void @arg0(%struct.Zero* byval(%struct.Zero) align 1 %x)
+void arg0(Zero x) {}
+
+// CHECK-AIX-LABEL: define void @arg1(%struct.One* byval(%struct.One) align 1 %x)
+void arg1(One x) {}
+
+// CHECK-AIX-LABEL: define void @arg2(%struct.Two* byval(%struct.Two) align 2 %x)
+void arg2(Two x) {}
+
+// CHECK-AIX-LABEL: define void @arg3(%struct.Three* byval(%struct.Three) align 1 %x)
+void arg3(Three x) {}
+
+// CHECK-AIX-LABEL: define void @arg4(%struct.Four* byval(%struct.Four) align 4 %x)
+void arg4(Four x) {}
+
+// CHECK-AIX-LABEL: define void @arg5(%struct.Five* byval(%struct.Five) align 1 %x)
+void arg5(Five x) {}
+
+// CHECK-AIX-LABEL: define void @arg6(%struct.Six* byval(%struct.Six) align 2 %x)
+void arg6(Six x) {}
+
+// CHECK-AIX-LABEL: define void @arg7(%struct.Seven* byval(%struct.Seven) align 1 %x)
+void arg7(Seven x) {}
+
+// CHECK-AIX-LABEL: define void @arg8(%struct.Eight* byval(%struct.Eight) align 4 %x)
+void arg8(Eight x) {}
+
+// CHECK-AIX-LABEL: define void @arg9(%struct.Nine* byval(%struct.Nine) align 1 %0)
+void arg9(Nine) {}
Index: clang/test/CodeGen/aix-return.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/aix-return.c
@@ -0,0 +1,34 @@
+// REQUIRES: powerpc-registered-target
+// RUN: %clang_cc1 -triple powerpc-unknown-aix \
+// RUN:   -emit-llvm -o - %s | FileCheck %s --check-prefixes=AIX-COM,AIX32
+// RUN: %clang_cc1 -triple powerpc64-unknown-aix \
+// RUN:   -emit-llvm -o - %s | FileCheck %s --check-prefixes=AIX-COM,AIX64
+
+// AIX-COM-LABEL: define void @retVoid()
+void retVoid(void) {}
+
+// AIX-COM-LABEL: define signext i8 @retChar(i8 signext %x)
+char retChar(char x) { return x; }
+
+// AIX-COM-LABEL: define signext i16 @retShort(i16 signext %x)
+short retShort(short x) { return x; }
+
+// AIX32-LABEL: define i32 @retInt(i32 %x)
+// AIX64-LABEL: define signext i32 @retInt(i32 signext %x)
+int retInt(int x) { return 1; }
+
+// AIX-COM-LABEL: define i64 @retLongLong(i64 %x)
+long long retLongLong(long long x) { return x; }
+
+// AIX-COM-LABEL: define signext i8 @retEnumChar(i8 signext %x)
+enum EnumChar : char { IsChar };
+enum EnumChar retEnumChar(enum EnumChar x) {
+  return x;
+}
+
+// AIX32-LABEL: define i32 @retEnumInt(i32 %x)
+// AIX64-LABEL: define signext i32 @retEnumInt(i32 signext %x)
+enum EnumInt : int { IsInt };
+enum EnumInt retEnumInt(enum EnumInt x) {
+  return x;
+}
Index: clang/test/CodeGen/aix-complex.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/aix-complex.c
@@ -0,0 +1,10 @@
+// REQUIRES: powerpc-registered-target
+// RUN: not %clang_cc1 -triple powerpc-unknown-aix \
+// RUN:   -emit-llvm -o - %s 2>&1 | FileCheck %s --check-prefix=AIX-COM
+// RUN: not %clang_cc1 -triple powerpc64-unknown-aix \
+// RUN:   -emit-llvm -o - %s 2>&1 | FileCheck %s --check-prefix=AIX-COM
+
+// AIX-COM: fatal error: error in backend: complex type is not supported on AIX yet
+_Complex float foo_float(_Complex float x) {
+  return x;
+}
Index: clang/lib/CodeGen/TargetInfo.cpp
===================================================================
--- clang/lib/CodeGen/TargetInfo.cpp
+++ clang/lib/CodeGen/TargetInfo.cpp
@@ -4172,6 +4172,208 @@
                           /*allowHigherAlign*/ false);
 }
 
+static bool PPC_initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
+                                        llvm::Value *Address, bool Is64Bit,
+                                        bool IsAIX) {
+  // This is calculated from the LLVM and GCC tables and verified
+  // against gcc output.  AFAIK all ABIs use the same encoding.
+
+  CodeGen::CGBuilderTy &Builder = CGF.Builder;
+
+  llvm::IntegerType *i8 = CGF.Int8Ty;
+  llvm::Value *Four8 = llvm::ConstantInt::get(i8, 4);
+  llvm::Value *Eight8 = llvm::ConstantInt::get(i8, 8);
+  llvm::Value *Sixteen8 = llvm::ConstantInt::get(i8, 16);
+
+  // 0-31: r0-31, the 4-byte or 8-byte general-purpose registers
+  AssignToArrayRange(Builder, Address, Is64Bit ? Eight8 : Four8, 0, 31);
+
+  // 32-63: fp0-31, the 8-byte floating-point registers
+  AssignToArrayRange(Builder, Address, Eight8, 32, 63);
+
+  // 64-76 are various 4-byte or 8-byte special-purpose registers:
+  // 64: mq
+  // 65: lr
+  // 66: ctr
+  // 67: ap
+  AssignToArrayRange(Builder, Address, Is64Bit ? Eight8 : Four8, 64, 67);
+
+  // 68-76 are various 4-byte special-purpose registers:
+  // 68-75 cr0-7
+  // 76: xer
+  AssignToArrayRange(Builder, Address, Four8, 68, 76);
+
+  // 77-108: v0-31, the 16-byte vector registers
+  AssignToArrayRange(Builder, Address, Sixteen8, 77, 108);
+
+  // 109: vrsave
+  // 110: vscr
+  AssignToArrayRange(Builder, Address, Is64Bit ? Eight8 : Four8, 109, 110);
+
+  // AIX does not utilize the rest of the registers.
+  if (IsAIX)
+    return false;
+
+  // 111: spe_acc
+  // 112: spefscr
+  // 113: sfp
+  AssignToArrayRange(Builder, Address, Is64Bit ? Eight8 : Four8, 111, 113);
+
+  if (!Is64Bit)
+    return false;
+
+  // 64-bit only registers:
+  // 114: tfhar
+  // 115: tfiar
+  // 116: texasr
+  AssignToArrayRange(Builder, Address, Eight8, 114, 116);
+
+  return false;
+}
+
+// AIX
+namespace {
+/// AIXABIInfo - The AIX XCOFF ABI information.
+class AIXABIInfo : public ABIInfo {
+  const bool Is64Bit;
+  CharUnits getParamTypeAlignment(QualType Ty) const;
+
+public:
+  AIXABIInfo(CodeGen::CodeGenTypes &CGT, bool Is64Bit)
+      : ABIInfo(CGT), Is64Bit(Is64Bit) {}
+
+  bool isPromotableTypeForABI(QualType Ty) const;
+
+  ABIArgInfo classifyReturnType(QualType RetTy) const;
+  ABIArgInfo classifyArgumentType(QualType Ty) const;
+
+  void computeInfo(CGFunctionInfo &FI) const override {
+    if (!getCXXABI().classifyReturnType(FI))
+      FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
+
+    for (auto &I : FI.arguments())
+      I.info = classifyArgumentType(I.type);
+  }
+
+  Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+                    QualType Ty) const override;
+};
+
+class AIXTargetCodeGenInfo : public TargetCodeGenInfo {
+  const bool Is64Bit;
+
+public:
+  AIXTargetCodeGenInfo(CodeGen::CodeGenTypes &CGT, bool Is64Bit)
+      : TargetCodeGenInfo(new AIXABIInfo(CGT, Is64Bit)), Is64Bit(Is64Bit) {}
+  int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const override {
+    return 1; // r1 is the dedicated stack pointer
+  }
+
+  bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
+                               llvm::Value *Address) const override;
+};
+} // namespace
+
+// Return true if the ABI requires Ty to be passed sign- or zero-
+// extended to 32/64 bits.
+bool AIXABIInfo::isPromotableTypeForABI(QualType Ty) const {
+  // Treat an enum type as its underlying type.
+  if (const EnumType *EnumTy = Ty->getAs<EnumType>())
+    Ty = EnumTy->getDecl()->getIntegerType();
+
+  // Promotable integer types are required to be promoted by the ABI.
+  if (Ty->isPromotableIntegerType())
+    return true;
+
+  if (!Is64Bit)
+    return false;
+
+  // For 64 bit mode, in addition to the usual promotable integer types, we also
+  // need to extend all 32-bit types, since the ABI requires promotion to 64
+  // bits.
+  if (const BuiltinType *BT = Ty->getAs<BuiltinType>())
+    switch (BT->getKind()) {
+    case BuiltinType::Int:
+    case BuiltinType::UInt:
+      return true;
+    default:
+      break;
+    }
+
+  return false;
+}
+
+ABIArgInfo AIXABIInfo::classifyReturnType(QualType RetTy) const {
+  if (RetTy->isAnyComplexType())
+    llvm::report_fatal_error("complex type is not supported on AIX yet");
+
+  if (RetTy->isVectorType())
+    llvm::report_fatal_error("vector type is not supported on AIX yet");
+
+  if (RetTy->isVoidType())
+    return ABIArgInfo::getIgnore();
+
+  if (isAggregateTypeForABI(RetTy))
+    return getNaturalAlignIndirect(RetTy);
+
+  return (isPromotableTypeForABI(RetTy) ? ABIArgInfo::getExtend(RetTy)
+                                        : ABIArgInfo::getDirect());
+}
+
+ABIArgInfo AIXABIInfo::classifyArgumentType(QualType Ty) const {
+  if (Ty->isAnyComplexType())
+    llvm::report_fatal_error("complex type is not supported on AIX yet");
+
+  if (Ty->isVectorType())
+    llvm::report_fatal_error("vector type is not supported on AIX yet");
+
+  Ty = useFirstFieldIfTransparentUnion(Ty);
+
+  if (isAggregateTypeForABI(Ty)) {
+    // Records with non-trivial destructors/copy-constructors should not be
+    // passed by value.
+    if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI()))
+      return getNaturalAlignIndirect(Ty, RAA == CGCXXABI::RAA_DirectInMemory);
+
+    return getNaturalAlignIndirect(Ty);
+  }
+
+  return (isPromotableTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty)
+                                     : ABIArgInfo::getDirect());
+}
+
+CharUnits AIXABIInfo::getParamTypeAlignment(QualType Ty) const {
+  if (Ty->isAnyComplexType())
+    llvm::report_fatal_error("complex type is not supported on AIX yet");
+
+  if (Ty->isVectorType())
+    llvm::report_fatal_error("vector type is not supported on AIX yet");
+
+  return CharUnits::fromQuantity(Is64Bit ? 8 : 4);
+}
+
+Address AIXABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
+                              QualType Ty) const {
+  if (Ty->isAnyComplexType())
+    llvm::report_fatal_error("complex type is not supported on AIX yet");
+
+  if (Ty->isVectorType())
+    llvm::report_fatal_error("vector type is not supported on AIX yet");
+
+  auto TypeInfo = getContext().getTypeInfoInChars(Ty);
+  TypeInfo.second = getParamTypeAlignment(Ty);
+
+  CharUnits SlotSize = CharUnits::fromQuantity(Is64Bit ? 8 : 4);
+
+  return emitVoidPtrVAArg(CGF, VAListAddr, Ty, /*Indirect*/ false, TypeInfo,
+                          SlotSize, /*AllowHigher*/ true);
+}
+
+bool AIXTargetCodeGenInfo::initDwarfEHRegSizeTable(
+    CodeGen::CodeGenFunction &CGF, llvm::Value *Address) const {
+  return PPC_initDwarfEHRegSizeTable(CGF, Address, Is64Bit, /*IsAIX*/ true);
+}
+
 // PowerPC-32
 namespace {
 /// PPC32_SVR4_ABIInfo - The 32-bit PowerPC ELF (SVR4) ABI information.
@@ -4449,42 +4651,8 @@
 bool
 PPC32TargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
                                                 llvm::Value *Address) const {
-  // This is calculated from the LLVM and GCC tables and verified
-  // against gcc output.  AFAIK all ABIs use the same encoding.
-
-  CodeGen::CGBuilderTy &Builder = CGF.Builder;
-
-  llvm::IntegerType *i8 = CGF.Int8Ty;
-  llvm::Value *Four8 = llvm::ConstantInt::get(i8, 4);
-  llvm::Value *Eight8 = llvm::ConstantInt::get(i8, 8);
-  llvm::Value *Sixteen8 = llvm::ConstantInt::get(i8, 16);
-
-  // 0-31: r0-31, the 4-byte general-purpose registers
-  AssignToArrayRange(Builder, Address, Four8, 0, 31);
-
-  // 32-63: fp0-31, the 8-byte floating-point registers
-  AssignToArrayRange(Builder, Address, Eight8, 32, 63);
-
-  // 64-76 are various 4-byte special-purpose registers:
-  // 64: mq
-  // 65: lr
-  // 66: ctr
-  // 67: ap
-  // 68-75 cr0-7
-  // 76: xer
-  AssignToArrayRange(Builder, Address, Four8, 64, 76);
-
-  // 77-108: v0-31, the 16-byte vector registers
-  AssignToArrayRange(Builder, Address, Sixteen8, 77, 108);
-
-  // 109: vrsave
-  // 110: vscr
-  // 111: spe_acc
-  // 112: spefscr
-  // 113: sfp
-  AssignToArrayRange(Builder, Address, Four8, 109, 113);
-
-  return false;
+  return PPC_initDwarfEHRegSizeTable(CGF, Address, /* Is64Bit*/ false,
+                                     /*IsAIX*/ false);
 }
 
 // PowerPC-64
@@ -5019,66 +5187,19 @@
                           TypeInfo, SlotSize, /*AllowHigher*/ true);
 }
 
-static bool
-PPC64_initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
-                              llvm::Value *Address) {
-  // This is calculated from the LLVM and GCC tables and verified
-  // against gcc output.  AFAIK all ABIs use the same encoding.
-
-  CodeGen::CGBuilderTy &Builder = CGF.Builder;
-
-  llvm::IntegerType *i8 = CGF.Int8Ty;
-  llvm::Value *Four8 = llvm::ConstantInt::get(i8, 4);
-  llvm::Value *Eight8 = llvm::ConstantInt::get(i8, 8);
-  llvm::Value *Sixteen8 = llvm::ConstantInt::get(i8, 16);
-
-  // 0-31: r0-31, the 8-byte general-purpose registers
-  AssignToArrayRange(Builder, Address, Eight8, 0, 31);
-
-  // 32-63: fp0-31, the 8-byte floating-point registers
-  AssignToArrayRange(Builder, Address, Eight8, 32, 63);
-
-  // 64-67 are various 8-byte special-purpose registers:
-  // 64: mq
-  // 65: lr
-  // 66: ctr
-  // 67: ap
-  AssignToArrayRange(Builder, Address, Eight8, 64, 67);
-
-  // 68-76 are various 4-byte special-purpose registers:
-  // 68-75 cr0-7
-  // 76: xer
-  AssignToArrayRange(Builder, Address, Four8, 68, 76);
-
-  // 77-108: v0-31, the 16-byte vector registers
-  AssignToArrayRange(Builder, Address, Sixteen8, 77, 108);
-
-  // 109: vrsave
-  // 110: vscr
-  // 111: spe_acc
-  // 112: spefscr
-  // 113: sfp
-  // 114: tfhar
-  // 115: tfiar
-  // 116: texasr
-  AssignToArrayRange(Builder, Address, Eight8, 109, 116);
-
-  return false;
-}
-
 bool
 PPC64_SVR4_TargetCodeGenInfo::initDwarfEHRegSizeTable(
   CodeGen::CodeGenFunction &CGF,
   llvm::Value *Address) const {
-
-  return PPC64_initDwarfEHRegSizeTable(CGF, Address);
+  return PPC_initDwarfEHRegSizeTable(CGF, Address, /* Is64Bit*/ true,
+                                     /*IsAIX*/ false);
 }
 
 bool
 PPC64TargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
                                                 llvm::Value *Address) const {
-
-  return PPC64_initDwarfEHRegSizeTable(CGF, Address);
+  return PPC_initDwarfEHRegSizeTable(CGF, Address, /* Is64Bit*/ true,
+                                     /*IsAIX*/ false);
 }
 
 //===----------------------------------------------------------------------===//
@@ -10329,6 +10450,9 @@
   }
 
   case llvm::Triple::ppc: {
+    if (Triple.isOSAIX())
+      return SetCGInfo(new AIXTargetCodeGenInfo(Types, /* Is64Bit */ false));
+
     bool IsSoftFloat =
         CodeGenOpts.FloatABI == "soft" || getTarget().hasFeature("spe");
     bool RetSmallStructInRegABI =
@@ -10337,6 +10461,9 @@
         new PPC32TargetCodeGenInfo(Types, IsSoftFloat, RetSmallStructInRegABI));
   }
   case llvm::Triple::ppc64:
+    if (Triple.isOSAIX())
+      return SetCGInfo(new AIXTargetCodeGenInfo(Types, /* Is64Bit */ true));
+
     if (Triple.isOSBinFormatELF()) {
       PPC64_SVR4_ABIInfo::ABIKind Kind = PPC64_SVR4_ABIInfo::ELFv1;
       if (getTarget().getABI() == "elfv2")
@@ -10346,8 +10473,8 @@
 
       return SetCGInfo(new PPC64_SVR4_TargetCodeGenInfo(Types, Kind, HasQPX,
                                                         IsSoftFloat));
-    } else
-      return SetCGInfo(new PPC64TargetCodeGenInfo(Types));
+    }
+    return SetCGInfo(new PPC64TargetCodeGenInfo(Types));
   case llvm::Triple::ppc64le: {
     assert(Triple.isOSBinFormatELF() && "PPC64 LE non-ELF not supported!");
     PPC64_SVR4_ABIInfo::ABIKind Kind = PPC64_SVR4_ABIInfo::ELFv2;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to