llvm/llvm/lib/Target/RISCV/RISCVCallingConv.cpp

//===-- RISCVCallingConv.cpp - RISC-V Custom CC Routines ------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file contains the custom routines for the RISC-V Calling Convention.
//
//===----------------------------------------------------------------------===//

#include "RISCVCallingConv.h"
#include "RISCVSubtarget.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/MC/MCRegister.h"

usingnamespacellvm;

// Calling Convention Implementation.
// The expectations for frontend ABI lowering vary from target to target.
// Ideally, an LLVM frontend would be able to avoid worrying about many ABI
// details, but this is a longer term goal. For now, we simply try to keep the
// role of the frontend as simple and well-defined as possible. The rules can
// be summarised as:
// * Never split up large scalar arguments. We handle them here.
// * If a hardfloat calling convention is being used, and the struct may be
// passed in a pair of registers (fp+fp, int+fp), and both registers are
// available, then pass as two separate arguments. If either the GPRs or FPRs
// are exhausted, then pass according to the rule below.
// * If a struct could never be passed in registers or directly in a stack
// slot (as it is larger than 2*XLEN and the floating point rules don't
// apply), then pass it using a pointer with the byval attribute.
// * If a struct is less than 2*XLEN, then coerce to either a two-element
// word-sized array or a 2*XLEN scalar (depending on alignment).
// * The frontend can determine whether a struct is returned by reference or
// not based on its size and fields. If it will be returned by reference, the
// frontend must modify the prototype so a pointer with the sret annotation is
// passed as the first argument. This is not necessary for large scalar
// returns.
// * Struct return values and varargs should be coerced to structs containing
// register-size fields in the same situations they would be for fixed
// arguments.

static const MCPhysReg ArgFPR16s[] =;
static const MCPhysReg ArgFPR32s[] =;
static const MCPhysReg ArgFPR64s[] =;
// This is an interim calling convention and it may be changed in the future.
static const MCPhysReg ArgVRs[] =;
static const MCPhysReg ArgVRM2s[] =;
static const MCPhysReg ArgVRM4s[] =;
static const MCPhysReg ArgVRM8s[] =;
static const MCPhysReg ArgVRN2M1s[] =;
static const MCPhysReg ArgVRN3M1s[] =;
static const MCPhysReg ArgVRN4M1s[] =;
static const MCPhysReg ArgVRN5M1s[] =;
static const MCPhysReg ArgVRN6M1s[] =;
static const MCPhysReg ArgVRN7M1s[] =;
static const MCPhysReg ArgVRN8M1s[] =;
static const MCPhysReg ArgVRN2M2s[] =;
static const MCPhysReg ArgVRN3M2s[] =;
static const MCPhysReg ArgVRN4M2s[] =;
static const MCPhysReg ArgVRN2M4s[] =;

ArrayRef<MCPhysReg> RISCV::getArgGPRs(const RISCVABI::ABI ABI) {}

static ArrayRef<MCPhysReg> getArgGPR16s(const RISCVABI::ABI ABI) {}

static ArrayRef<MCPhysReg> getArgGPR32s(const RISCVABI::ABI ABI) {}

static ArrayRef<MCPhysReg> getFastCCArgGPRs(const RISCVABI::ABI ABI) {}

static ArrayRef<MCPhysReg> getFastCCArgGPRF16s(const RISCVABI::ABI ABI) {}

static ArrayRef<MCPhysReg> getFastCCArgGPRF32s(const RISCVABI::ABI ABI) {}

// Pass a 2*XLEN argument that has been split into two XLEN values through
// registers or the stack as necessary.
static bool CC_RISCVAssign2XLen(unsigned XLen, CCState &State, CCValAssign VA1,
                                ISD::ArgFlagsTy ArgFlags1, unsigned ValNo2,
                                MVT ValVT2, MVT LocVT2,
                                ISD::ArgFlagsTy ArgFlags2, bool EABI) {}

static MCRegister allocateRVVReg(MVT ValVT, unsigned ValNo, CCState &State,
                                 const RISCVTargetLowering &TLI) {}

// Implements the RISC-V calling convention. Returns true upon failure.
bool llvm::CC_RISCV(unsigned ValNo, MVT ValVT, MVT LocVT,
                    CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags,
                    CCState &State, bool IsFixed, bool IsRet, Type *OrigTy) {}

// FastCC has less than 1% performance improvement for some particular
// benchmark. But theoretically, it may have benefit for some cases.
bool llvm::CC_RISCV_FastCC(unsigned ValNo, MVT ValVT, MVT LocVT,
                           CCValAssign::LocInfo LocInfo,
                           ISD::ArgFlagsTy ArgFlags, CCState &State,
                           bool IsFixed, bool IsRet, Type *OrigTy) {}

bool llvm::CC_RISCV_GHC(unsigned ValNo, MVT ValVT, MVT LocVT,
                        CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags,
                        CCState &State) {}