253 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8//9/// \file10/// This file implements the lowering of LLVM calls to machine code calls for11/// 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/MachineFrameInfo.h"24#include "llvm/CodeGen/TargetCallingConv.h"25 26using namespace llvm;27 28namespace {29 30struct M68kFormalArgHandler : public M68kIncomingValueHandler {31 M68kFormalArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI)32 : M68kIncomingValueHandler(MIRBuilder, MRI) {}33};34 35struct CallReturnHandler : public M68kIncomingValueHandler {36 CallReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,37 MachineInstrBuilder &MIB)38 : M68kIncomingValueHandler(MIRBuilder, MRI), MIB(MIB) {}39 40private:41 void assignValueToReg(Register ValVReg, Register PhysReg,42 const CCValAssign &VA) override;43 44 MachineInstrBuilder &MIB;45};46 47} // end anonymous namespace48 49M68kCallLowering::M68kCallLowering(const M68kTargetLowering &TLI)50 : CallLowering(&TLI) {}51 52struct M68kOutgoingArgHandler : public CallLowering::OutgoingValueHandler {53 M68kOutgoingArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,54 MachineInstrBuilder MIB)55 : OutgoingValueHandler(MIRBuilder, MRI), MIB(MIB),56 DL(MIRBuilder.getMF().getDataLayout()),57 STI(MIRBuilder.getMF().getSubtarget<M68kSubtarget>()) {}58 59 void assignValueToReg(Register ValVReg, Register PhysReg,60 const CCValAssign &VA) override {61 MIB.addUse(PhysReg, RegState::Implicit);62 Register ExtReg = extendRegister(ValVReg, VA);63 MIRBuilder.buildCopy(PhysReg, ExtReg);64 }65 66 void assignValueToAddress(Register ValVReg, Register Addr, LLT MemTy,67 const MachinePointerInfo &MPO,68 const CCValAssign &VA) override {69 MachineFunction &MF = MIRBuilder.getMF();70 Register ExtReg = extendRegister(ValVReg, VA);71 72 auto *MMO = MF.getMachineMemOperand(MPO, MachineMemOperand::MOStore, MemTy,73 inferAlignFromPtrInfo(MF, MPO));74 MIRBuilder.buildStore(ExtReg, Addr, *MMO);75 }76 77 Register getStackAddress(uint64_t Size, int64_t Offset,78 MachinePointerInfo &MPO,79 ISD::ArgFlagsTy Flags) override {80 LLT p0 = LLT::pointer(0, DL.getPointerSizeInBits(0));81 LLT SType = LLT::scalar(DL.getPointerSizeInBits(0));82 Register StackReg = STI.getRegisterInfo()->getStackRegister();83 auto SPReg = MIRBuilder.buildCopy(p0, StackReg).getReg(0);84 auto OffsetReg = MIRBuilder.buildConstant(SType, Offset);85 auto AddrReg = MIRBuilder.buildPtrAdd(p0, SPReg, OffsetReg);86 MPO = MachinePointerInfo::getStack(MIRBuilder.getMF(), Offset);87 return AddrReg.getReg(0);88 }89 MachineInstrBuilder MIB;90 const DataLayout &DL;91 const M68kSubtarget &STI;92};93bool M68kCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,94 const Value *Val, ArrayRef<Register> VRegs,95 FunctionLoweringInfo &FLI,96 Register SwiftErrorVReg) const {97 98 auto MIB = MIRBuilder.buildInstrNoInsert(M68k::RTS);99 bool Success = true;100 MachineFunction &MF = MIRBuilder.getMF();101 const Function &F = MF.getFunction();102 MachineRegisterInfo &MRI = MF.getRegInfo();103 const M68kTargetLowering &TLI = *getTLI<M68kTargetLowering>();104 CCAssignFn *AssignFn =105 TLI.getCCAssignFn(F.getCallingConv(), true, F.isVarArg());106 auto &DL = F.getDataLayout();107 if (!VRegs.empty()) {108 SmallVector<ArgInfo, 8> SplitArgs;109 ArgInfo OrigArg{VRegs, Val->getType(), 0};110 setArgFlags(OrigArg, AttributeList::ReturnIndex, DL, F);111 splitToValueTypes(OrigArg, SplitArgs, DL, F.getCallingConv());112 OutgoingValueAssigner ArgAssigner(AssignFn);113 M68kOutgoingArgHandler ArgHandler(MIRBuilder, MRI, MIB);114 Success = determineAndHandleAssignments(ArgHandler, ArgAssigner, SplitArgs,115 MIRBuilder, F.getCallingConv(),116 F.isVarArg());117 }118 MIRBuilder.insertInstr(MIB);119 return Success;120}121 122bool M68kCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,123 const Function &F,124 ArrayRef<ArrayRef<Register>> VRegs,125 FunctionLoweringInfo &FLI) const {126 MachineFunction &MF = MIRBuilder.getMF();127 MachineRegisterInfo &MRI = MF.getRegInfo();128 const auto &DL = F.getDataLayout();129 auto &TLI = *getTLI<M68kTargetLowering>();130 131 SmallVector<ArgInfo, 8> SplitArgs;132 unsigned I = 0;133 for (const auto &Arg : F.args()) {134 ArgInfo OrigArg{VRegs[I], Arg.getType(), I};135 setArgFlags(OrigArg, I + AttributeList::FirstArgIndex, DL, F);136 splitToValueTypes(OrigArg, SplitArgs, DL, F.getCallingConv());137 ++I;138 }139 140 CCAssignFn *AssignFn =141 TLI.getCCAssignFn(F.getCallingConv(), false, F.isVarArg());142 IncomingValueAssigner ArgAssigner(AssignFn);143 M68kFormalArgHandler ArgHandler(MIRBuilder, MRI);144 return determineAndHandleAssignments(ArgHandler, ArgAssigner, SplitArgs,145 MIRBuilder, F.getCallingConv(),146 F.isVarArg());147}148 149void M68kIncomingValueHandler::assignValueToReg(Register ValVReg,150 Register PhysReg,151 const CCValAssign &VA) {152 MIRBuilder.getMRI()->addLiveIn(PhysReg);153 MIRBuilder.getMBB().addLiveIn(PhysReg);154 IncomingValueHandler::assignValueToReg(ValVReg, PhysReg, VA);155}156 157void M68kIncomingValueHandler::assignValueToAddress(158 Register ValVReg, Register Addr, LLT MemTy, const MachinePointerInfo &MPO,159 const CCValAssign &VA) {160 MachineFunction &MF = MIRBuilder.getMF();161 auto *MMO = MF.getMachineMemOperand(MPO, MachineMemOperand::MOLoad, MemTy,162 inferAlignFromPtrInfo(MF, MPO));163 MIRBuilder.buildLoad(ValVReg, Addr, *MMO);164}165 166Register M68kIncomingValueHandler::getStackAddress(uint64_t Size,167 int64_t Offset,168 MachinePointerInfo &MPO,169 ISD::ArgFlagsTy Flags) {170 auto &MFI = MIRBuilder.getMF().getFrameInfo();171 const bool IsImmutable = !Flags.isByVal();172 int FI = MFI.CreateFixedObject(Size, Offset, IsImmutable);173 MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI);174 175 // Build Frame Index176 llvm::LLT FramePtr = LLT::pointer(177 0, MIRBuilder.getMF().getDataLayout().getPointerSizeInBits());178 MachineInstrBuilder AddrReg = MIRBuilder.buildFrameIndex(FramePtr, FI);179 StackUsed = std::max(StackUsed, Size + Offset);180 return AddrReg.getReg(0);181}182 183void CallReturnHandler::assignValueToReg(Register ValVReg, Register PhysReg,184 const CCValAssign &VA) {185 MIB.addDef(PhysReg, RegState::Implicit);186 MIRBuilder.buildCopy(ValVReg, PhysReg);187}188 189bool M68kCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,190 CallLoweringInfo &Info) const {191 MachineFunction &MF = MIRBuilder.getMF();192 Function &F = MF.getFunction();193 MachineRegisterInfo &MRI = MF.getRegInfo();194 auto &DL = F.getDataLayout();195 const M68kTargetLowering &TLI = *getTLI<M68kTargetLowering>();196 const M68kSubtarget &STI = MF.getSubtarget<M68kSubtarget>();197 const TargetInstrInfo &TII = *STI.getInstrInfo();198 const M68kRegisterInfo *TRI = STI.getRegisterInfo();199 200 SmallVector<ArgInfo, 8> OutArgs;201 for (auto &OrigArg : Info.OrigArgs)202 splitToValueTypes(OrigArg, OutArgs, DL, Info.CallConv);203 204 SmallVector<ArgInfo, 8> InArgs;205 if (!Info.OrigRet.Ty->isVoidTy())206 splitToValueTypes(Info.OrigRet, InArgs, DL, Info.CallConv);207 208 unsigned AdjStackDown = TII.getCallFrameSetupOpcode();209 auto CallSeqStart = MIRBuilder.buildInstr(AdjStackDown);210 211 unsigned Opc = TLI.getTargetMachine().isPositionIndependent() ? M68k::CALLq212 : Info.Callee.isReg() ? M68k::CALLj213 : M68k::CALLb;214 215 auto MIB = MIRBuilder.buildInstrNoInsert(Opc)216 .add(Info.Callee)217 .addRegMask(TRI->getCallPreservedMask(MF, Info.CallConv));218 219 CCAssignFn *AssignFn = TLI.getCCAssignFn(Info.CallConv, false, Info.IsVarArg);220 OutgoingValueAssigner Assigner(AssignFn);221 M68kOutgoingArgHandler Handler(MIRBuilder, MRI, MIB);222 if (!determineAndHandleAssignments(Handler, Assigner, OutArgs, MIRBuilder,223 Info.CallConv, Info.IsVarArg))224 return false;225 226 if (Info.Callee.isReg())227 constrainOperandRegClass(MF, *TRI, MRI, *STI.getInstrInfo(),228 *STI.getRegBankInfo(), *MIB, MIB->getDesc(),229 Info.Callee, 0);230 231 MIRBuilder.insertInstr(MIB);232 233 if (!Info.OrigRet.Ty->isVoidTy()) {234 CCAssignFn *RetAssignFn =235 TLI.getCCAssignFn(Info.CallConv, true, Info.IsVarArg);236 237 OutgoingValueAssigner Assigner(RetAssignFn, RetAssignFn);238 CallReturnHandler Handler(MIRBuilder, MRI, MIB);239 if (!determineAndHandleAssignments(Handler, Assigner, InArgs, MIRBuilder,240 Info.CallConv, Info.IsVarArg))241 return false;242 }243 244 CallSeqStart.addImm(Assigner.StackSize).addImm(0);245 246 unsigned AdjStackUp = TII.getCallFrameDestroyOpcode();247 MIRBuilder.buildInstr(AdjStackUp).addImm(Assigner.StackSize).addImm(0);248 249 return true;250}251 252bool M68kCallLowering::enableBigEndian() const { return true; }253