1 //===-- llvm/lib/Target/ARM/ARMCallLowering.cpp - Call lowering -----------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 /// This file implements the lowering of LLVM calls to machine code calls for
14 //===----------------------------------------------------------------------===//
16 #include "ARMCallLowering.h"
18 #include "ARMBaseInstrInfo.h"
19 #include "ARMISelLowering.h"
21 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
22 #include "llvm/CodeGen/MachineRegisterInfo.h"
26 #ifndef LLVM_BUILD_GLOBAL_ISEL
27 #error "This shouldn't be built without GISel"
30 ARMCallLowering::ARMCallLowering(const ARMTargetLowering &TLI)
31 : CallLowering(&TLI) {}
33 static bool isSupportedType(const DataLayout DL, const ARMTargetLowering &TLI,
35 EVT VT = TLI.getValueType(DL, T);
36 if (!VT.isSimple() || !VT.isInteger() || VT.isVector())
39 unsigned VTSize = VT.getSimpleVT().getSizeInBits();
40 return VTSize == 8 || VTSize == 16 || VTSize == 32;
44 struct FuncReturnHandler : public CallLowering::ValueHandler {
45 FuncReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
46 MachineInstrBuilder &MIB)
47 : ValueHandler(MIRBuilder, MRI), MIB(MIB) {}
49 unsigned getStackAddress(uint64_t Size, int64_t Offset,
50 MachinePointerInfo &MPO) override {
51 llvm_unreachable("Don't know how to get a stack address yet");
54 void assignValueToReg(unsigned ValVReg, unsigned PhysReg,
55 CCValAssign &VA) override {
56 assert(VA.isRegLoc() && "Value shouldn't be assigned to reg");
57 assert(VA.getLocReg() == PhysReg && "Assigning to the wrong reg?");
59 assert(VA.getValVT().getSizeInBits() <= 32 && "Unsupported value size");
60 assert(VA.getLocVT().getSizeInBits() == 32 && "Unsupported location size");
62 assert(VA.getLocInfo() != CCValAssign::SExt &&
63 VA.getLocInfo() != CCValAssign::ZExt &&
64 "ABI extensions not supported yet");
66 MIRBuilder.buildCopy(PhysReg, ValVReg);
67 MIB.addUse(PhysReg, RegState::Implicit);
70 void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size,
71 MachinePointerInfo &MPO, CCValAssign &VA) override {
72 llvm_unreachable("Don't know how to assign a value to an address yet");
75 MachineInstrBuilder &MIB;
77 } // End anonymous namespace.
79 /// Lower the return value for the already existing \p Ret. This assumes that
80 /// \p MIRBuilder's insertion point is correct.
81 bool ARMCallLowering::lowerReturnVal(MachineIRBuilder &MIRBuilder,
82 const Value *Val, unsigned VReg,
83 MachineInstrBuilder &Ret) const {
85 // Nothing to do here.
88 auto &MF = MIRBuilder.getMF();
89 const auto &F = *MF.getFunction();
91 auto DL = MF.getDataLayout();
92 auto &TLI = *getTLI<ARMTargetLowering>();
93 if (!isSupportedType(DL, TLI, Val->getType()))
96 CCAssignFn *AssignFn =
97 TLI.CCAssignFnForReturn(F.getCallingConv(), F.isVarArg());
99 ArgInfo RetInfo(VReg, Val->getType());
100 setArgFlags(RetInfo, AttributeSet::ReturnIndex, DL, F);
102 FuncReturnHandler RetHandler(MIRBuilder, MF.getRegInfo(), Ret);
103 return handleAssignments(MIRBuilder, AssignFn, RetInfo, RetHandler);
106 bool ARMCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
107 const Value *Val, unsigned VReg) const {
108 assert(!Val == !VReg && "Return value without a vreg");
110 auto Ret = AddDefaultPred(MIRBuilder.buildInstrNoInsert(ARM::BX_RET));
112 if (!lowerReturnVal(MIRBuilder, Val, VReg, Ret))
115 MIRBuilder.insertInstr(Ret);
120 struct FormalArgHandler : public CallLowering::ValueHandler {
121 FormalArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI)
122 : ValueHandler(MIRBuilder, MRI) {}
124 unsigned getStackAddress(uint64_t Size, int64_t Offset,
125 MachinePointerInfo &MPO) override {
126 assert(Size == 4 && "Unsupported size");
128 auto &MFI = MIRBuilder.getMF().getFrameInfo();
130 int FI = MFI.CreateFixedObject(Size, Offset, true);
131 MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI);
134 MRI.createGenericVirtualRegister(LLT::pointer(MPO.getAddrSpace(), 32));
135 MIRBuilder.buildFrameIndex(AddrReg, FI);
140 void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size,
141 MachinePointerInfo &MPO, CCValAssign &VA) override {
142 assert(Size == 4 && "Unsupported size");
144 auto MMO = MIRBuilder.getMF().getMachineMemOperand(
145 MPO, MachineMemOperand::MOLoad, Size, /* Alignment */ 0);
146 MIRBuilder.buildLoad(ValVReg, Addr, *MMO);
149 void assignValueToReg(unsigned ValVReg, unsigned PhysReg,
150 CCValAssign &VA) override {
151 assert(VA.isRegLoc() && "Value shouldn't be assigned to reg");
152 assert(VA.getLocReg() == PhysReg && "Assigning to the wrong reg?");
154 assert(VA.getValVT().getSizeInBits() <= 32 && "Unsupported value size");
155 assert(VA.getLocVT().getSizeInBits() == 32 && "Unsupported location size");
157 MIRBuilder.getMBB().addLiveIn(PhysReg);
158 MIRBuilder.buildCopy(ValVReg, PhysReg);
161 } // End anonymous namespace
163 bool ARMCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
165 ArrayRef<unsigned> VRegs) const {
166 // Quick exit if there aren't any args
173 auto DL = MIRBuilder.getMF().getDataLayout();
174 auto &TLI = *getTLI<ARMTargetLowering>();
176 auto &Args = F.getArgumentList();
178 for (auto &Arg : Args) {
180 if (!isSupportedType(DL, TLI, Arg.getType()))
183 // FIXME: This check as well as ArgIdx are going away as soon as we support
184 // loading values < 32 bits.
185 if (ArgIdx > 4 && Arg.getType()->getIntegerBitWidth() != 32)
189 CCAssignFn *AssignFn =
190 TLI.CCAssignFnForCall(F.getCallingConv(), F.isVarArg());
192 SmallVector<ArgInfo, 8> ArgInfos;
194 for (auto &Arg : Args) {
195 ArgInfo AInfo(VRegs[Idx], Arg.getType());
196 setArgFlags(AInfo, Idx + 1, DL, F);
197 ArgInfos.push_back(AInfo);
201 FormalArgHandler ArgHandler(MIRBuilder, MIRBuilder.getMF().getRegInfo());
202 return handleAssignments(MIRBuilder, AssignFn, ArgInfos, ArgHandler);