1 //===-- llvm/lib/Target/X86/X86CallLowering.cpp - Call lowering -----------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 /// 10 /// \file 11 /// This file implements the lowering of LLVM calls to machine code calls for 12 /// GlobalISel. 13 /// 14 //===----------------------------------------------------------------------===// 15 16 #include "X86CallLowering.h" 17 #include "X86ISelLowering.h" 18 #include "X86InstrInfo.h" 19 #include "X86TargetMachine.h" 20 #include "X86CallingConv.h" 21 22 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" 23 #include "llvm/CodeGen/MachineValueType.h" 24 #include "llvm/CodeGen/MachineRegisterInfo.h" 25 #include "llvm/Target/TargetSubtargetInfo.h" 26 27 using namespace llvm; 28 29 #include "X86GenCallingConv.inc" 30 31 #ifndef LLVM_BUILD_GLOBAL_ISEL 32 #error "This shouldn't be built without GISel" 33 #endif 34 35 X86CallLowering::X86CallLowering(const X86TargetLowering &TLI) 36 : CallLowering(&TLI) {} 37 38 bool X86CallLowering::lowerReturn(MachineIRBuilder &MIRBuilder, 39 const Value *Val, unsigned VReg) const { 40 // TODO: handle functions returning non-void values. 41 if (Val) 42 return false; 43 44 // silence unused-function warning, remove after the function implementation. 45 (void)RetCC_X86; 46 47 MIRBuilder.buildInstr(X86::RET).addImm(0); 48 49 return true; 50 } 51 52 namespace { 53 struct FormalArgHandler : public CallLowering::ValueHandler { 54 FormalArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI, 55 CCAssignFn *AssignFn, const DataLayout &DL) 56 : ValueHandler(MIRBuilder, MRI, AssignFn), DL(DL) {} 57 58 unsigned getStackAddress(uint64_t Size, int64_t Offset, 59 MachinePointerInfo &MPO) override { 60 61 auto &MFI = MIRBuilder.getMF().getFrameInfo(); 62 int FI = MFI.CreateFixedObject(Size, Offset, true); 63 MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI); 64 65 unsigned AddrReg = 66 MRI.createGenericVirtualRegister(LLT::pointer(0, 67 DL.getPointerSizeInBits(0))); 68 MIRBuilder.buildFrameIndex(AddrReg, FI); 69 return AddrReg; 70 } 71 72 void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size, 73 MachinePointerInfo &MPO, CCValAssign &VA) override { 74 75 auto MMO = MIRBuilder.getMF().getMachineMemOperand( 76 MPO, MachineMemOperand::MOLoad | MachineMemOperand::MOInvariant, Size, 77 0); 78 MIRBuilder.buildLoad(ValVReg, Addr, *MMO); 79 } 80 81 void assignValueToReg(unsigned ValVReg, unsigned PhysReg, 82 CCValAssign &VA) override { 83 MIRBuilder.getMBB().addLiveIn(PhysReg); 84 MIRBuilder.buildCopy(ValVReg, PhysReg); 85 } 86 87 const DataLayout &DL; 88 }; 89 } 90 91 bool X86CallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder, 92 const Function &F, 93 ArrayRef<unsigned> VRegs) const { 94 if (F.arg_empty()) 95 return true; 96 97 //TODO: handle variadic function 98 if (F.isVarArg()) 99 return false; 100 101 auto DL = MIRBuilder.getMF().getDataLayout(); 102 103 SmallVector<ArgInfo, 8> ArgInfos; 104 unsigned Idx = 0; 105 for (auto &Arg : F.getArgumentList()) { 106 ArgInfo AInfo(VRegs[Idx], Arg.getType()); 107 setArgFlags(AInfo, Idx + 1, DL, F); 108 ArgInfos.push_back(AInfo); 109 Idx++; 110 } 111 112 FormalArgHandler ArgHandler(MIRBuilder, MIRBuilder.getMF().getRegInfo(), 113 CC_X86, DL); 114 return handleAssignments(MIRBuilder, ArgInfos, ArgHandler); 115 } 116