1*fe6060f1SDimitry Andric //===-- M68kCallingConv.h - M68k Custom CC Routines ---------*- C++ -*-===// 2*fe6060f1SDimitry Andric // 3*fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*fe6060f1SDimitry Andric // 7*fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 8*fe6060f1SDimitry Andric /// 9*fe6060f1SDimitry Andric /// \file 10*fe6060f1SDimitry Andric /// This file contains the custom routines for the M68k Calling Convention 11*fe6060f1SDimitry Andric /// that aren't done by tablegen. 12*fe6060f1SDimitry Andric /// 13*fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 14*fe6060f1SDimitry Andric 15*fe6060f1SDimitry Andric #ifndef LLVM_LIB_TARGET_M68K_M68KCALLINGCONV_H 16*fe6060f1SDimitry Andric #define LLVM_LIB_TARGET_M68K_M68KCALLINGCONV_H 17*fe6060f1SDimitry Andric 18*fe6060f1SDimitry Andric #include "MCTargetDesc/M68kMCTargetDesc.h" 19*fe6060f1SDimitry Andric 20*fe6060f1SDimitry Andric #include "llvm/CodeGen/CallingConvLower.h" 21*fe6060f1SDimitry Andric #include "llvm/IR/CallingConv.h" 22*fe6060f1SDimitry Andric #include "llvm/IR/Function.h" 23*fe6060f1SDimitry Andric 24*fe6060f1SDimitry Andric namespace llvm { 25*fe6060f1SDimitry Andric 26*fe6060f1SDimitry Andric /// Custom state to propagate llvm type info to register CC assigner 27*fe6060f1SDimitry Andric class M68kCCState : public CCState { 28*fe6060f1SDimitry Andric public: 29*fe6060f1SDimitry Andric const llvm::Function &F; 30*fe6060f1SDimitry Andric 31*fe6060f1SDimitry Andric M68kCCState(const llvm::Function &F, CallingConv::ID CC, bool IsVarArg, 32*fe6060f1SDimitry Andric MachineFunction &MF, SmallVectorImpl<CCValAssign> &Locs, 33*fe6060f1SDimitry Andric LLVMContext &C) 34*fe6060f1SDimitry Andric : CCState(CC, IsVarArg, MF, Locs, C), F(F) {} 35*fe6060f1SDimitry Andric }; 36*fe6060f1SDimitry Andric 37*fe6060f1SDimitry Andric /// NOTE this function is used to select registers for formal arguments and call 38*fe6060f1SDimitry Andric /// FIXME: Handling on pointer arguments is not complete 39*fe6060f1SDimitry Andric inline bool CC_M68k_Any_AssignToReg(unsigned &ValNo, MVT &ValVT, MVT &LocVT, 40*fe6060f1SDimitry Andric CCValAssign::LocInfo &LocInfo, 41*fe6060f1SDimitry Andric ISD::ArgFlagsTy &ArgFlags, CCState &State) { 42*fe6060f1SDimitry Andric M68kCCState CCInfo = static_cast<M68kCCState &>(State); 43*fe6060f1SDimitry Andric 44*fe6060f1SDimitry Andric static const MCPhysReg DataRegList[] = {M68k::D0, M68k::D1, M68k::A0, 45*fe6060f1SDimitry Andric M68k::A1}; 46*fe6060f1SDimitry Andric 47*fe6060f1SDimitry Andric // Address registers have %a register priority 48*fe6060f1SDimitry Andric static const MCPhysReg AddrRegList[] = { 49*fe6060f1SDimitry Andric M68k::A0, 50*fe6060f1SDimitry Andric M68k::A1, 51*fe6060f1SDimitry Andric M68k::D0, 52*fe6060f1SDimitry Andric M68k::D1, 53*fe6060f1SDimitry Andric }; 54*fe6060f1SDimitry Andric 55*fe6060f1SDimitry Andric auto I = CCInfo.F.arg_begin(); 56*fe6060f1SDimitry Andric int No = ValNo; 57*fe6060f1SDimitry Andric while (No > 0) { 58*fe6060f1SDimitry Andric No -= I->getType()->isIntegerTy(64) ? 2 : 1; 59*fe6060f1SDimitry Andric I++; 60*fe6060f1SDimitry Andric } 61*fe6060f1SDimitry Andric 62*fe6060f1SDimitry Andric bool IsPtr = I != CCInfo.F.arg_end() && I->getType()->isPointerTy(); 63*fe6060f1SDimitry Andric 64*fe6060f1SDimitry Andric unsigned Reg = 65*fe6060f1SDimitry Andric IsPtr ? State.AllocateReg(AddrRegList) : State.AllocateReg(DataRegList); 66*fe6060f1SDimitry Andric 67*fe6060f1SDimitry Andric if (Reg) { 68*fe6060f1SDimitry Andric State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo)); 69*fe6060f1SDimitry Andric return true; 70*fe6060f1SDimitry Andric } 71*fe6060f1SDimitry Andric 72*fe6060f1SDimitry Andric return false; 73*fe6060f1SDimitry Andric } 74*fe6060f1SDimitry Andric 75*fe6060f1SDimitry Andric } // namespace llvm 76*fe6060f1SDimitry Andric 77*fe6060f1SDimitry Andric #endif 78