1 //===-- M68kCallLowering.cpp - Call lowering --------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 /// \file 10 /// This file implements the lowering of LLVM calls to machine code calls for 11 /// GlobalISel. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "M68kCallLowering.h" 16 #include "M68kISelLowering.h" 17 #include "M68kInstrInfo.h" 18 #include "M68kSubtarget.h" 19 #include "M68kTargetMachine.h" 20 #include "llvm/CodeGen/CallingConvLower.h" 21 #include "llvm/CodeGen/GlobalISel/CallLowering.h" 22 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" 23 #include "llvm/CodeGen/TargetCallingConv.h" 24 25 using namespace llvm; 26 27 M68kCallLowering::M68kCallLowering(const M68kTargetLowering &TLI) 28 : CallLowering(&TLI) {} 29 30 struct OutgoingArgHandler : public CallLowering::OutgoingValueHandler { 31 OutgoingArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI, 32 MachineInstrBuilder MIB) 33 : OutgoingValueHandler(MIRBuilder, MRI), MIB(MIB) {} 34 35 void assignValueToReg(Register ValVReg, Register PhysReg, 36 CCValAssign VA) override { 37 MIB.addUse(PhysReg, RegState::Implicit); 38 Register ExtReg = extendRegister(ValVReg, VA); 39 MIRBuilder.buildCopy(PhysReg, ExtReg); 40 } 41 42 void assignValueToAddress(Register ValVReg, Register Addr, LLT MemTy, 43 MachinePointerInfo &MPO, CCValAssign &VA) override { 44 llvm_unreachable("unimplemented"); 45 } 46 47 Register getStackAddress(uint64_t Size, int64_t Offset, 48 MachinePointerInfo &MPO, 49 ISD::ArgFlagsTy Flags) override { 50 llvm_unreachable("unimplemented"); 51 } 52 53 MachineInstrBuilder MIB; 54 }; 55 bool M68kCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder, 56 const Value *Val, ArrayRef<Register> VRegs, 57 FunctionLoweringInfo &FLI, 58 Register SwiftErrorVReg) const { 59 60 auto MIB = MIRBuilder.buildInstrNoInsert(M68k::RTS); 61 bool Success = true; 62 MachineFunction &MF = MIRBuilder.getMF(); 63 const Function &F = MF.getFunction(); 64 MachineRegisterInfo &MRI = MF.getRegInfo(); 65 const M68kTargetLowering &TLI = *getTLI<M68kTargetLowering>(); 66 CCAssignFn *AssignFn = 67 TLI.getCCAssignFn(F.getCallingConv(), true, F.isVarArg()); 68 auto &DL = F.getParent()->getDataLayout(); 69 if (!VRegs.empty()) { 70 SmallVector<ArgInfo, 8> SplitArgs; 71 ArgInfo OrigArg{VRegs, Val->getType(), 0}; 72 setArgFlags(OrigArg, AttributeList::ReturnIndex, DL, F); 73 splitToValueTypes(OrigArg, SplitArgs, DL, F.getCallingConv()); 74 OutgoingValueAssigner ArgAssigner(AssignFn); 75 OutgoingArgHandler ArgHandler(MIRBuilder, MRI, MIB); 76 Success = determineAndHandleAssignments(ArgHandler, ArgAssigner, SplitArgs, 77 MIRBuilder, F.getCallingConv(), 78 F.isVarArg()); 79 } 80 MIRBuilder.insertInstr(MIB); 81 return Success; 82 } 83 84 bool M68kCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder, 85 const Function &F, 86 ArrayRef<ArrayRef<Register>> VRegs, 87 FunctionLoweringInfo &FLI) const { 88 MachineFunction &MF = MIRBuilder.getMF(); 89 MachineRegisterInfo &MRI = MF.getRegInfo(); 90 const auto &DL = F.getParent()->getDataLayout(); 91 auto &TLI = *getTLI<M68kTargetLowering>(); 92 93 SmallVector<ArgInfo, 8> SplitArgs; 94 unsigned I = 0; 95 for (const auto &Arg : F.args()) { 96 ArgInfo OrigArg{VRegs[I], Arg.getType(), I}; 97 setArgFlags(OrigArg, I + AttributeList::FirstArgIndex, DL, F); 98 splitToValueTypes(OrigArg, SplitArgs, DL, F.getCallingConv()); 99 ++I; 100 } 101 102 CCAssignFn *AssignFn = 103 TLI.getCCAssignFn(F.getCallingConv(), false, F.isVarArg()); 104 IncomingValueAssigner ArgAssigner(AssignFn); 105 FormalArgHandler ArgHandler(MIRBuilder, MRI); 106 return determineAndHandleAssignments(ArgHandler, ArgAssigner, SplitArgs, 107 MIRBuilder, F.getCallingConv(), 108 F.isVarArg()); 109 } 110 111 void M68kIncomingValueHandler::assignValueToReg(Register ValVReg, 112 Register PhysReg, 113 CCValAssign VA) { 114 MIRBuilder.getMRI()->addLiveIn(PhysReg); 115 MIRBuilder.getMBB().addLiveIn(PhysReg); 116 IncomingValueHandler::assignValueToReg(ValVReg, PhysReg, VA); 117 } 118 119 void M68kIncomingValueHandler::assignValueToAddress(Register ValVReg, 120 Register Addr, 121 LLT MemTy, 122 MachinePointerInfo &MPO, 123 CCValAssign &VA) { 124 MachineFunction &MF = MIRBuilder.getMF(); 125 auto *MMO = MF.getMachineMemOperand(MPO, MachineMemOperand::MOLoad, MemTy, 126 inferAlignFromPtrInfo(MF, MPO)); 127 MIRBuilder.buildLoad(ValVReg, Addr, *MMO); 128 } 129 130 Register M68kIncomingValueHandler::getStackAddress(uint64_t Size, 131 int64_t Offset, 132 MachinePointerInfo &MPO, 133 ISD::ArgFlagsTy Flags) { 134 auto &MFI = MIRBuilder.getMF().getFrameInfo(); 135 const bool IsImmutable = !Flags.isByVal(); 136 int FI = MFI.CreateFixedObject(Size, Offset, IsImmutable); 137 MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI); 138 139 // Build Frame Index 140 llvm::LLT FramePtr = LLT::pointer( 141 0, MIRBuilder.getMF().getDataLayout().getPointerSizeInBits()); 142 MachineInstrBuilder AddrReg = MIRBuilder.buildFrameIndex(FramePtr, FI); 143 StackUsed = std::max(StackUsed, Size + Offset); 144 return AddrReg.getReg(0); 145 } 146 147 bool M68kCallLowering::lowerCall(MachineIRBuilder &MIRBuilder, 148 CallLoweringInfo &Info) const { 149 return false; 150 } 151 152 bool M68kCallLowering::enableBigEndian() const { return true; } 153