blob: 21e5b6e09e2baf5504cc736fab48a03dfeea6f71 [file] [log] [blame]
Quentin Colombetba2a0162016-02-16 19:26:02 +00001//===-- llvm/lib/Target/AArch64/AArch64CallLowering.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 "AArch64CallLowering.h"
17#include "AArch64ISelLowering.h"
18
19#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
20#include "llvm/CodeGen/MachineInstrBuilder.h"
21
22using namespace llvm;
23
24AArch64CallLowering::AArch64CallLowering(const AArch64TargetLowering &TLI)
25 : CallLowering(&TLI) {
26}
27
28#ifndef LLVM_BUILD_GLOBAL_ISEL
29bool AArch64CallLowering::LowerReturn(MachineIRBuilder &MIRBuilder,
30 const Value *Val, unsigned VReg) const {
31 return false;
32}
33
34bool AArch64CallLowering::LowerFormalArguments(
35 MachineIRBuilder &MIRBuilder, const Function::ArgumentListType &Args,
36 const SmallVectorImpl<unsigned> &VRegs) const {
37 return false;
38}
39#else
40bool AArch64CallLowering::LowerReturn(MachineIRBuilder &MIRBuilder,
41 const Value *Val, unsigned VReg) const {
42 MachineInstr *Return = MIRBuilder.buildInstr(AArch64::RET_ReallyLR);
43 assert(Return && "Unable to build a return instruction?!");
44
45 assert(((Val && VReg) || (!Val && !VReg)) && "Return value without a vreg");
46 if (VReg) {
47 assert(Val->getType()->isIntegerTy() && "Type not supported yet");
48 unsigned Size = Val->getType()->getPrimitiveSizeInBits();
49 assert((Size == 64 || Size == 32) && "Size not supported yet");
50 unsigned ResReg = (Size == 32) ? AArch64::W0 : AArch64::X0;
51 // Set the insertion point to be right before Return.
52 MIRBuilder.setInstr(*Return, /* Before */ true);
53 MachineInstr *Copy =
54 MIRBuilder.buildInstr(TargetOpcode::COPY, ResReg, VReg);
55 (void)Copy;
56 assert(Copy->getNextNode() == Return &&
57 "The insertion did not happen where we expected");
58 MachineInstrBuilder(MIRBuilder.getMF(), Return)
59 .addReg(ResReg, RegState::Implicit);
60 }
61 return true;
62}
63
64bool AArch64CallLowering::LowerFormalArguments(
65 MachineIRBuilder &MIRBuilder, const Function::ArgumentListType &Args,
66 const SmallVectorImpl<unsigned> &VRegs) const {
67 MachineFunction &MF = MIRBuilder.getMF();
68 const Function &F = *MF.getFunction();
69
70 SmallVector<CCValAssign, 16> ArgLocs;
71 CCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs, F.getContext());
72
73 unsigned NumArgs = Args.size();
74 Function::const_arg_iterator CurOrigArg = Args.begin();
75 const AArch64TargetLowering &TLI = *getTLI<AArch64TargetLowering>();
76 for (unsigned i = 0; i != NumArgs; ++i, ++CurOrigArg) {
77 MVT ValVT = MVT::getVT(CurOrigArg->getType());
78 CCAssignFn *AssignFn =
79 TLI.CCAssignFnForCall(F.getCallingConv(), /*IsVarArg=*/false);
80 bool Res =
81 AssignFn(i, ValVT, ValVT, CCValAssign::Full, ISD::ArgFlagsTy(), CCInfo);
82 assert(!Res && "Call operand has unhandled type");
83 (void)Res;
84 }
85 assert(ArgLocs.size() == Args.size() &&
86 "We have a different number of location and args?!");
87 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
88 CCValAssign &VA = ArgLocs[i];
89
90 assert(VA.isRegLoc() && "Not yet implemented");
91 // Transform the arguments in physical registers into virtual ones.
92 MIRBuilder.getMBB().addLiveIn(VA.getLocReg());
93 MIRBuilder.buildInstr(TargetOpcode::COPY, VRegs[i], VA.getLocReg());
94
95 switch (VA.getLocInfo()) {
96 default:
97 llvm_unreachable("Unknown loc info!");
98 case CCValAssign::Full:
99 break;
100 case CCValAssign::BCvt:
101 // We don't care about bitcast.
102 break;
103 case CCValAssign::AExt:
104 case CCValAssign::SExt:
105 case CCValAssign::ZExt:
106 // Zero/Sign extend the register.
107 assert(0 && "Not yet implemented");
108 break;
109 }
110 }
111 return true;
112}
113#endif