109 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			109 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			C++
		
	
	
	
//===-- PPCCallingConv.h - --------------------------------------*- C++ -*-===//
 | 
						|
//
 | 
						|
// 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
 | 
						|
//
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
 | 
						|
#include "PPCRegisterInfo.h"
 | 
						|
#include "PPCCallingConv.h"
 | 
						|
#include "PPCSubtarget.h"
 | 
						|
#include "PPCCCState.h"
 | 
						|
using namespace llvm;
 | 
						|
 | 
						|
inline bool CC_PPC_AnyReg_Error(unsigned &, MVT &, MVT &,
 | 
						|
                                CCValAssign::LocInfo &, ISD::ArgFlagsTy &,
 | 
						|
                                CCState &) {
 | 
						|
  llvm_unreachable("The AnyReg calling convention is only supported by the " \
 | 
						|
                   "stackmap and patchpoint intrinsics.");
 | 
						|
  // gracefully fallback to PPC C calling convention on Release builds.
 | 
						|
  return false;
 | 
						|
}
 | 
						|
 | 
						|
static bool CC_PPC32_SVR4_Custom_Dummy(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
 | 
						|
                                       CCValAssign::LocInfo &LocInfo,
 | 
						|
                                       ISD::ArgFlagsTy &ArgFlags,
 | 
						|
                                       CCState &State) {
 | 
						|
  return true;
 | 
						|
}
 | 
						|
 | 
						|
static bool CC_PPC32_SVR4_Custom_AlignArgRegs(unsigned &ValNo, MVT &ValVT,
 | 
						|
                                              MVT &LocVT,
 | 
						|
                                              CCValAssign::LocInfo &LocInfo,
 | 
						|
                                              ISD::ArgFlagsTy &ArgFlags,
 | 
						|
                                              CCState &State) {
 | 
						|
  static const MCPhysReg ArgRegs[] = {
 | 
						|
    PPC::R3, PPC::R4, PPC::R5, PPC::R6,
 | 
						|
    PPC::R7, PPC::R8, PPC::R9, PPC::R10,
 | 
						|
  };
 | 
						|
  const unsigned NumArgRegs = array_lengthof(ArgRegs);
 | 
						|
 | 
						|
  unsigned RegNum = State.getFirstUnallocated(ArgRegs);
 | 
						|
 | 
						|
  // Skip one register if the first unallocated register has an even register
 | 
						|
  // number and there are still argument registers available which have not been
 | 
						|
  // allocated yet. RegNum is actually an index into ArgRegs, which means we
 | 
						|
  // need to skip a register if RegNum is odd.
 | 
						|
  if (RegNum != NumArgRegs && RegNum % 2 == 1) {
 | 
						|
    State.AllocateReg(ArgRegs[RegNum]);
 | 
						|
  }
 | 
						|
 | 
						|
  // Always return false here, as this function only makes sure that the first
 | 
						|
  // unallocated register has an odd register number and does not actually
 | 
						|
  // allocate a register for the current argument.
 | 
						|
  return false;
 | 
						|
}
 | 
						|
 | 
						|
static bool CC_PPC32_SVR4_Custom_SkipLastArgRegsPPCF128(
 | 
						|
    unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo,
 | 
						|
    ISD::ArgFlagsTy &ArgFlags, CCState &State) {
 | 
						|
  static const MCPhysReg ArgRegs[] = {
 | 
						|
    PPC::R3, PPC::R4, PPC::R5, PPC::R6,
 | 
						|
    PPC::R7, PPC::R8, PPC::R9, PPC::R10,
 | 
						|
  };
 | 
						|
  const unsigned NumArgRegs = array_lengthof(ArgRegs);
 | 
						|
 | 
						|
  unsigned RegNum = State.getFirstUnallocated(ArgRegs);
 | 
						|
  int RegsLeft = NumArgRegs - RegNum;
 | 
						|
 | 
						|
  // Skip if there is not enough registers left for long double type (4 gpr regs
 | 
						|
  // in soft float mode) and put long double argument on the stack.
 | 
						|
  if (RegNum != NumArgRegs && RegsLeft < 4) {
 | 
						|
    for (int i = 0; i < RegsLeft; i++) {
 | 
						|
      State.AllocateReg(ArgRegs[RegNum + i]);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return false;
 | 
						|
}
 | 
						|
 | 
						|
static bool CC_PPC32_SVR4_Custom_AlignFPArgRegs(unsigned &ValNo, MVT &ValVT,
 | 
						|
                                                MVT &LocVT,
 | 
						|
                                                CCValAssign::LocInfo &LocInfo,
 | 
						|
                                                ISD::ArgFlagsTy &ArgFlags,
 | 
						|
                                                CCState &State) {
 | 
						|
  static const MCPhysReg ArgRegs[] = {
 | 
						|
    PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
 | 
						|
    PPC::F8
 | 
						|
  };
 | 
						|
 | 
						|
  const unsigned NumArgRegs = array_lengthof(ArgRegs);
 | 
						|
 | 
						|
  unsigned RegNum = State.getFirstUnallocated(ArgRegs);
 | 
						|
 | 
						|
  // If there is only one Floating-point register left we need to put both f64
 | 
						|
  // values of a split ppc_fp128 value on the stack.
 | 
						|
  if (RegNum != NumArgRegs && ArgRegs[RegNum] == PPC::F8) {
 | 
						|
    State.AllocateReg(ArgRegs[RegNum]);
 | 
						|
  }
 | 
						|
 | 
						|
  // Always return false here, as this function only makes sure that the two f64
 | 
						|
  // values a ppc_fp128 value is split into are both passed in registers or both
 | 
						|
  // passed on the stack and does not actually allocate a register for the
 | 
						|
  // current argument.
 | 
						|
  return false;
 | 
						|
}
 | 
						|
 | 
						|
#include "PPCGenCallingConv.inc"
 |