LCOV - code coverage report
Current view: top level - lib/Target/AArch64 - AArch64CallingConvention.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 40 40 100.0 %
Date: 2017-09-14 15:23:50 Functions: 3 3 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //=== AArch64CallingConv.h - Custom Calling Convention Routines -*- C++ -*-===//
       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             : // This file contains the custom routines for the AArch64 Calling Convention
      11             : // that aren't done by tablegen.
      12             : //
      13             : //===----------------------------------------------------------------------===//
      14             : 
      15             : #ifndef LLVM_LIB_TARGET_AARCH64_AARCH64CALLINGCONVENTION_H
      16             : #define LLVM_LIB_TARGET_AARCH64_AARCH64CALLINGCONVENTION_H
      17             : 
      18             : #include "AArch64.h"
      19             : #include "AArch64InstrInfo.h"
      20             : #include "AArch64Subtarget.h"
      21             : #include "llvm/CodeGen/CallingConvLower.h"
      22             : #include "llvm/IR/CallingConv.h"
      23             : #include "llvm/Target/TargetInstrInfo.h"
      24             : 
      25             : namespace {
      26             : using namespace llvm;
      27             : 
      28             : static const MCPhysReg XRegList[] = {AArch64::X0, AArch64::X1, AArch64::X2,
      29             :                                      AArch64::X3, AArch64::X4, AArch64::X5,
      30             :                                      AArch64::X6, AArch64::X7};
      31             : static const MCPhysReg HRegList[] = {AArch64::H0, AArch64::H1, AArch64::H2,
      32             :                                      AArch64::H3, AArch64::H4, AArch64::H5,
      33             :                                      AArch64::H6, AArch64::H7};
      34             : static const MCPhysReg SRegList[] = {AArch64::S0, AArch64::S1, AArch64::S2,
      35             :                                      AArch64::S3, AArch64::S4, AArch64::S5,
      36             :                                      AArch64::S6, AArch64::S7};
      37             : static const MCPhysReg DRegList[] = {AArch64::D0, AArch64::D1, AArch64::D2,
      38             :                                      AArch64::D3, AArch64::D4, AArch64::D5,
      39             :                                      AArch64::D6, AArch64::D7};
      40             : static const MCPhysReg QRegList[] = {AArch64::Q0, AArch64::Q1, AArch64::Q2,
      41             :                                      AArch64::Q3, AArch64::Q4, AArch64::Q5,
      42             :                                      AArch64::Q6, AArch64::Q7};
      43             : 
      44          63 : static bool finishStackBlock(SmallVectorImpl<CCValAssign> &PendingMembers,
      45             :                              MVT LocVT, ISD::ArgFlagsTy &ArgFlags,
      46             :                              CCState &State, unsigned SlotAlign) {
      47          63 :   unsigned Size = LocVT.getSizeInBits() / 8;
      48             :   unsigned StackAlign =
      49          63 :       State.getMachineFunction().getDataLayout().getStackAlignment();
      50         126 :   unsigned Align = std::min(ArgFlags.getOrigAlign(), StackAlign);
      51             : 
      52         310 :   for (auto &It : PendingMembers) {
      53         242 :     It.convertToMem(State.AllocateStack(Size, std::max(Align, SlotAlign)));
      54         242 :     State.addLoc(It);
      55         121 :     SlotAlign = 1;
      56             :   }
      57             : 
      58             :   // All pending members have now been allocated
      59          63 :   PendingMembers.clear();
      60          63 :   return true;
      61             : }
      62             : 
      63             : /// The Darwin variadic PCS places anonymous arguments in 8-byte stack slots. An
      64             : /// [N x Ty] type must still be contiguous in memory though.
      65           5 : static bool CC_AArch64_Custom_Stack_Block(
      66             :       unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo,
      67             :       ISD::ArgFlagsTy &ArgFlags, CCState &State) {
      68           5 :   SmallVectorImpl<CCValAssign> &PendingMembers = State.getPendingLocs();
      69             : 
      70             :   // Add the argument to the list to be allocated once we know the size of the
      71             :   // block.
      72          10 :   PendingMembers.push_back(
      73          15 :       CCValAssign::getPending(ValNo, ValVT, LocVT, LocInfo));
      74             : 
      75           5 :   if (!ArgFlags.isInConsecutiveRegsLast())
      76             :     return true;
      77             : 
      78           2 :   return finishStackBlock(PendingMembers, LocVT, ArgFlags, State, 8);
      79             : }
      80             : 
      81             : /// Given an [N x Ty] block, it should be passed in a consecutive sequence of
      82             : /// registers. If no such sequence is available, mark the rest of the registers
      83             : /// of that type as used and place the argument on the stack.
      84        1142 : static bool CC_AArch64_Custom_Block(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
      85             :                                     CCValAssign::LocInfo &LocInfo,
      86             :                                     ISD::ArgFlagsTy &ArgFlags, CCState &State) {
      87             :   // Try to allocate a contiguous block of registers, each of the correct
      88             :   // size to hold one member.
      89        1142 :   ArrayRef<MCPhysReg> RegList;
      90        1142 :   if (LocVT.SimpleTy == MVT::i64)
      91             :     RegList = XRegList;
      92         970 :   else if (LocVT.SimpleTy == MVT::f16)
      93             :     RegList = HRegList;
      94        1780 :   else if (LocVT.SimpleTy == MVT::f32 || LocVT.is32BitVector())
      95             :     RegList = SRegList;
      96         814 :   else if (LocVT.SimpleTy == MVT::f64 || LocVT.is64BitVector())
      97             :     RegList = DRegList;
      98         572 :   else if (LocVT.SimpleTy == MVT::f128 || LocVT.is128BitVector())
      99             :     RegList = QRegList;
     100             :   else {
     101             :     // Not an array we want to split up after all.
     102             :     return false;
     103             :   }
     104             : 
     105         622 :   SmallVectorImpl<CCValAssign> &PendingMembers = State.getPendingLocs();
     106             : 
     107             :   // Add the argument to the list to be allocated once we know the size of the
     108             :   // block.
     109        1244 :   PendingMembers.push_back(
     110        1866 :       CCValAssign::getPending(ValNo, ValVT, LocVT, LocInfo));
     111             : 
     112         622 :   if (!ArgFlags.isInConsecutiveRegsLast())
     113             :     return true;
     114             : 
     115         306 :   unsigned RegResult = State.AllocateRegBlock(RegList, PendingMembers.size());
     116         153 :   if (RegResult) {
     117         782 :     for (auto &It : PendingMembers) {
     118         506 :       It.convertToReg(RegResult);
     119        1012 :       State.addLoc(It);
     120         506 :       ++RegResult;
     121             :     }
     122          92 :     PendingMembers.clear();
     123          92 :     return true;
     124             :   }
     125             : 
     126             :   // Mark all regs in the class as unavailable
     127         610 :   for (auto Reg : RegList)
     128         488 :     State.AllocateReg(Reg);
     129             : 
     130             :   const AArch64Subtarget &Subtarget = static_cast<const AArch64Subtarget &>(
     131          61 :       State.getMachineFunction().getSubtarget());
     132          29 :   unsigned SlotAlign = Subtarget.isTargetDarwin() ? 1 : 8;
     133             : 
     134          61 :   return finishStackBlock(PendingMembers, LocVT, ArgFlags, State, SlotAlign);
     135             : }
     136             : 
     137             : }
     138             : 
     139             : #endif

Generated by: LCOV version 1.13