[RISCV] Add custom CC_RISCV calling convention and improved call support

The TableGen-based calling convention definitions are inflexible, while
writing a function to implement the calling convention is very
straight-forward, and allows difficult cases to be handled more easily. With
this patch adds support for:
* Passing large scalars according to the RV32I calling convention
* Byval arguments
* Passing values on the stack when the argument registers are exhausted

The custom CC_RISCV calling convention is also used for returns.

This patch also documents the ABI lowering that a language frontend is 
expected to perform. I would like to work to simplify these requirements over 
time, but this will require further discussion within the LLVM community.

We add PendingArgFlags CCState, as a companion to PendingLocs.

The PendingLocs vector is used by a number of backends to handle arguments 
that are split during legalisation. However CCValAssign doesn't keep track of 
the original argument alignment. Therefore, add a PendingArgFlags vector which 
can be used to keep track of the ISD::ArgFlagsTy for every value added to 
PendingLocs.

Differential Revision: https://reviews.llvm.org/D39898

llvm-svn: 320359
diff --git a/llvm/test/CodeGen/RISCV/calls.ll b/llvm/test/CodeGen/RISCV/calls.ll
index 3fba88d..4299d46 100644
--- a/llvm/test/CodeGen/RISCV/calls.ll
+++ b/llvm/test/CodeGen/RISCV/calls.ll
@@ -52,7 +52,7 @@
 ; RV32I-NEXT:    lw ra, 12(sp)
 ; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    jalr zero, ra, 0
-  %1 = call i32 @defined_function(i32 %a) nounwind
+  %1 = call i32 @defined_function(i32 %a)
   ret i32 %1
 }
 
@@ -115,3 +115,83 @@
   %1 = call fastcc i32 @fastcc_function(i32 %a, i32 %b)
   ret i32 %a
 }
+
+declare i32 @external_many_args(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) nounwind
+
+define i32 @test_call_external_many_args(i32 %a) nounwind {
+; RV32I-LABEL: test_call_external_many_args:
+; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -32
+; RV32I-NEXT:    sw ra, 28(sp)
+; RV32I-NEXT:    sw s0, 24(sp)
+; RV32I-NEXT:    sw s1, 20(sp)
+; RV32I-NEXT:    addi s0, sp, 32
+; RV32I-NEXT:    addi s1, a0, 0
+; RV32I-NEXT:    sw s1, 4(sp)
+; RV32I-NEXT:    sw s1, 0(sp)
+; RV32I-NEXT:    lui a0, %hi(external_many_args)
+; RV32I-NEXT:    addi t0, a0, %lo(external_many_args)
+; RV32I-NEXT:    addi a0, s1, 0
+; RV32I-NEXT:    addi a1, s1, 0
+; RV32I-NEXT:    addi a2, s1, 0
+; RV32I-NEXT:    addi a3, s1, 0
+; RV32I-NEXT:    addi a4, s1, 0
+; RV32I-NEXT:    addi a5, s1, 0
+; RV32I-NEXT:    addi a6, s1, 0
+; RV32I-NEXT:    addi a7, s1, 0
+; RV32I-NEXT:    jalr ra, t0, 0
+; RV32I-NEXT:    addi a0, s1, 0
+; RV32I-NEXT:    lw s1, 20(sp)
+; RV32I-NEXT:    lw s0, 24(sp)
+; RV32I-NEXT:    lw ra, 28(sp)
+; RV32I-NEXT:    addi sp, sp, 32
+; RV32I-NEXT:    jalr zero, ra, 0
+  %1 = call i32 @external_many_args(i32 %a, i32 %a, i32 %a, i32 %a, i32 %a,
+                                    i32 %a, i32 %a, i32 %a, i32 %a, i32 %a)
+  ret i32 %a
+}
+
+define i32 @defined_many_args(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32 %j) nounwind {
+; RV32I-LABEL: defined_many_args:
+; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp)
+; RV32I-NEXT:    sw s0, 8(sp)
+; RV32I-NEXT:    addi s0, sp, 16
+; RV32I-NEXT:    lw a0, 4(s0)
+; RV32I-NEXT:    addi a0, a0, 1
+; RV32I-NEXT:    lw s0, 8(sp)
+; RV32I-NEXT:    lw ra, 12(sp)
+; RV32I-NEXT:    addi sp, sp, 16
+; RV32I-NEXT:    jalr zero, ra, 0
+  %added = add i32 %j, 1
+  ret i32 %added
+}
+
+define i32 @test_call_defined_many_args(i32 %a) nounwind {
+; RV32I-LABEL: test_call_defined_many_args:
+; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -32
+; RV32I-NEXT:    sw ra, 28(sp)
+; RV32I-NEXT:    sw s0, 24(sp)
+; RV32I-NEXT:    addi s0, sp, 32
+; RV32I-NEXT:    sw a0, 4(sp)
+; RV32I-NEXT:    sw a0, 0(sp)
+; RV32I-NEXT:    lui a1, %hi(defined_many_args)
+; RV32I-NEXT:    addi t0, a1, %lo(defined_many_args)
+; RV32I-NEXT:    addi a1, a0, 0
+; RV32I-NEXT:    addi a2, a0, 0
+; RV32I-NEXT:    addi a3, a0, 0
+; RV32I-NEXT:    addi a4, a0, 0
+; RV32I-NEXT:    addi a5, a0, 0
+; RV32I-NEXT:    addi a6, a0, 0
+; RV32I-NEXT:    addi a7, a0, 0
+; RV32I-NEXT:    jalr ra, t0, 0
+; RV32I-NEXT:    lw s0, 24(sp)
+; RV32I-NEXT:    lw ra, 28(sp)
+; RV32I-NEXT:    addi sp, sp, 32
+; RV32I-NEXT:    jalr zero, ra, 0
+  %1 = call i32 @defined_many_args(i32 %a, i32 %a, i32 %a, i32 %a, i32 %a,
+                                   i32 %a, i32 %a, i32 %a, i32 %a, i32 %a)
+  ret i32 %1
+}