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