Skip to content

Commit

Permalink
[RISCV] Add custom CC_RISCV calling convention and improved call support
Browse files Browse the repository at this point in the history
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
  • Loading branch information
asb committed Dec 11, 2017
1 parent bfb00d4 commit dc31c61
Show file tree
Hide file tree
Showing 10 changed files with 1,871 additions and 49 deletions.
6 changes: 6 additions & 0 deletions llvm/include/llvm/CodeGen/CallingConvLower.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ class CCState {
unsigned MaxStackArgAlign;
SmallVector<uint32_t, 16> UsedRegs;
SmallVector<CCValAssign, 4> PendingLocs;
SmallVector<ISD::ArgFlagsTy, 4> PendingArgFlags;

// ByValInfo and SmallVector<ByValInfo, 4> ByValRegs:
//
Expand Down Expand Up @@ -508,6 +509,11 @@ class CCState {
return PendingLocs;
}

// Get a list of argflags for pending assignments.
SmallVectorImpl<ISD::ArgFlagsTy> &getPendingArgFlags() {
return PendingArgFlags;
}

/// Compute the remaining unused register parameters that would be used for
/// the given value type. This is useful when varargs are passed in the
/// registers that normal prototyped parameters would be passed in, or for
Expand Down
1 change: 0 additions & 1 deletion llvm/lib/Target/RISCV/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ tablegen(LLVM RISCVGenMCCodeEmitter.inc -gen-emitter)
tablegen(LLVM RISCVGenMCPseudoLowering.inc -gen-pseudo-lowering)
tablegen(LLVM RISCVGenAsmMatcher.inc -gen-asm-matcher)
tablegen(LLVM RISCVGenAsmWriter.inc -gen-asm-writer)
tablegen(LLVM RISCVGenCallingConv.inc -gen-callingconv)
tablegen(LLVM RISCVGenDAGISel.inc -gen-dag-isel)
tablegen(LLVM RISCVGenSubtargetInfo.inc -gen-subtarget)
tablegen(LLVM RISCVGenDisassemblerTables.inc -gen-disassembler)
Expand Down
16 changes: 2 additions & 14 deletions llvm/lib/Target/RISCV/RISCVCallingConv.td
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,8 @@
//
//===----------------------------------------------------------------------===//

// RISCV 32-bit C return-value convention.
def RetCC_RISCV32 : CallingConv<[CCIfType<[i32], CCAssignToReg<[X10, X11]>>]>;

// RISCV 32-bit C Calling convention.
def CC_RISCV32 : CallingConv<[
// Promote i8/i16 args to i32
CCIfType<[ i8, i16 ], CCPromoteToType<i32>>,

// All arguments get passed in integer registers if there is space.
CCIfType<[i32], CCAssignToReg<[ X10, X11, X12, X13, X14, X15, X16, X17]>>,

// Could be assigned to the stack in 8-byte aligned units, but unsupported
CCAssignToStack<8, 8>
]>;
// The RISC-V calling convention is handled with custom code in
// RISCVISelLowering.cpp (CC_RISCV).

def CSR : CalleeSavedRegs<(add X1, X3, X4, X8, X9, (sequence "X%u", 18, 27))>;

Expand Down
Loading

0 comments on commit dc31c61

Please sign in to comment.