AArch64CallingConvention.h revision 341825
151673Smdodd//=== AArch64CallingConv.h - Custom Calling Convention Routines -*- C++ -*-===// 251673Smdodd// 351673Smdodd// The LLVM Compiler Infrastructure 451673Smdodd// 551673Smdodd// This file is distributed under the University of Illinois Open Source 651673Smdodd// License. See LICENSE.TXT for details. 751673Smdodd// 851673Smdodd//===----------------------------------------------------------------------===// 951673Smdodd// 1051673Smdodd// This file contains the custom routines for the AArch64 Calling Convention 1151673Smdodd// that aren't done by tablegen. 1251673Smdodd// 1351673Smdodd//===----------------------------------------------------------------------===// 1451673Smdodd 1551673Smdodd#ifndef LLVM_LIB_TARGET_AARCH64_AARCH64CALLINGCONVENTION_H 1651673Smdodd#define LLVM_LIB_TARGET_AARCH64_AARCH64CALLINGCONVENTION_H 1751673Smdodd 1851673Smdodd#include "AArch64.h" 1951673Smdodd#include "AArch64InstrInfo.h" 2051673Smdodd#include "AArch64Subtarget.h" 2151673Smdodd#include "llvm/CodeGen/CallingConvLower.h" 2251673Smdodd#include "llvm/CodeGen/TargetInstrInfo.h" 2351673Smdodd#include "llvm/IR/CallingConv.h" 2451673Smdodd 2551673Smdoddnamespace { 2651673Smdoddusing namespace llvm; 27117700Smarkm 28117700Smarkmstatic const MCPhysReg XRegList[] = {AArch64::X0, AArch64::X1, AArch64::X2, 29117700Smarkm AArch64::X3, AArch64::X4, AArch64::X5, 3051673Smdodd AArch64::X6, AArch64::X7}; 3151673Smdoddstatic const MCPhysReg HRegList[] = {AArch64::H0, AArch64::H1, AArch64::H2, 3251673Smdodd AArch64::H3, AArch64::H4, AArch64::H5, 3351673Smdodd AArch64::H6, AArch64::H7}; 3451673Smdoddstatic const MCPhysReg SRegList[] = {AArch64::S0, AArch64::S1, AArch64::S2, 3552549Smdodd AArch64::S3, AArch64::S4, AArch64::S5, 3651673Smdodd AArch64::S6, AArch64::S7}; 3751673Smdoddstatic const MCPhysReg DRegList[] = {AArch64::D0, AArch64::D1, AArch64::D2, 3851673Smdodd AArch64::D3, AArch64::D4, AArch64::D5, 39117700Smarkm AArch64::D6, AArch64::D7}; 40117700Smarkmstatic const MCPhysReg QRegList[] = {AArch64::Q0, AArch64::Q1, AArch64::Q2, 4152549Smdodd AArch64::Q3, AArch64::Q4, AArch64::Q5, 4252549Smdodd AArch64::Q6, AArch64::Q7}; 4351673Smdodd 4451673Smdoddstatic bool finishStackBlock(SmallVectorImpl<CCValAssign> &PendingMembers, 4551673Smdodd MVT LocVT, ISD::ArgFlagsTy &ArgFlags, 4651673Smdodd CCState &State, unsigned SlotAlign) { 4751673Smdodd unsigned Size = LocVT.getSizeInBits() / 8; 4851673Smdodd unsigned StackAlign = 4951673Smdodd State.getMachineFunction().getDataLayout().getStackAlignment(); 5051673Smdodd unsigned Align = std::min(ArgFlags.getOrigAlign(), StackAlign); 5151673Smdodd 5251673Smdodd for (auto &It : PendingMembers) { 5351673Smdodd It.convertToMem(State.AllocateStack(Size, std::max(Align, SlotAlign))); 5451673Smdodd State.addLoc(It); 5551673Smdodd SlotAlign = 1; 5651673Smdodd } 57117700Smarkm 58117700Smarkm // All pending members have now been allocated 5951673Smdodd PendingMembers.clear(); 6051673Smdodd return true; 6151673Smdodd} 62117700Smarkm 6351673Smdodd/// The Darwin variadic PCS places anonymous arguments in 8-byte stack slots. An 6451673Smdodd/// [N x Ty] type must still be contiguous in memory though. 6551673Smdoddstatic bool CC_AArch64_Custom_Stack_Block( 6651673Smdodd unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo, 6751673Smdodd ISD::ArgFlagsTy &ArgFlags, CCState &State) { 68117700Smarkm SmallVectorImpl<CCValAssign> &PendingMembers = State.getPendingLocs(); 69117700Smarkm 70117700Smarkm // Add the argument to the list to be allocated once we know the size of the 7151673Smdodd // block. 72117700Smarkm PendingMembers.push_back( 7351673Smdodd CCValAssign::getPending(ValNo, ValVT, LocVT, LocInfo)); 7451673Smdodd 7551673Smdodd if (!ArgFlags.isInConsecutiveRegsLast()) 7651673Smdodd return true; 7752549Smdodd 78140523Simp return finishStackBlock(PendingMembers, LocVT, ArgFlags, State, 8); 7951673Smdodd} 8051673Smdodd 8151673Smdodd/// Given an [N x Ty] block, it should be passed in a consecutive sequence of 8251673Smdodd/// registers. If no such sequence is available, mark the rest of the registers 8351673Smdodd/// of that type as used and place the argument on the stack. 8451673Smdoddstatic bool CC_AArch64_Custom_Block(unsigned &ValNo, MVT &ValVT, MVT &LocVT, 8551673Smdodd CCValAssign::LocInfo &LocInfo, 8651673Smdodd ISD::ArgFlagsTy &ArgFlags, CCState &State) { 8751673Smdodd // Try to allocate a contiguous block of registers, each of the correct 8851673Smdodd // size to hold one member. 8951673Smdodd ArrayRef<MCPhysReg> RegList; 90117700Smarkm if (LocVT.SimpleTy == MVT::i64) 9151673Smdodd RegList = XRegList; 92117700Smarkm else if (LocVT.SimpleTy == MVT::f16) 93140523Simp RegList = HRegList; 94140523Simp else if (LocVT.SimpleTy == MVT::f32 || LocVT.is32BitVector()) 95140523Simp RegList = SRegList; 9651673Smdodd else if (LocVT.SimpleTy == MVT::f64 || LocVT.is64BitVector()) 9751673Smdodd RegList = DRegList; 9851673Smdodd else if (LocVT.SimpleTy == MVT::f128 || LocVT.is128BitVector()) 9951673Smdodd RegList = QRegList; 10051673Smdodd else { 10151673Smdodd // Not an array we want to split up after all. 10251673Smdodd return false; 10351673Smdodd } 10451673Smdodd 10551673Smdodd SmallVectorImpl<CCValAssign> &PendingMembers = State.getPendingLocs(); 10651673Smdodd 10751673Smdodd // Add the argument to the list to be allocated once we know the size of the 10851673Smdodd // block. 10951673Smdodd PendingMembers.push_back( 11051673Smdodd CCValAssign::getPending(ValNo, ValVT, LocVT, LocInfo)); 11151673Smdodd 11251673Smdodd if (!ArgFlags.isInConsecutiveRegsLast()) 11351673Smdodd return true; 11451673Smdodd 115117700Smarkm unsigned RegResult = State.AllocateRegBlock(RegList, PendingMembers.size()); 11651673Smdodd if (RegResult) { 117117700Smarkm for (auto &It : PendingMembers) { 118117700Smarkm It.convertToReg(RegResult); 11951673Smdodd State.addLoc(It); 120147717Simp ++RegResult; 12151673Smdodd } 12252549Smdodd PendingMembers.clear(); 12351673Smdodd return true; 12452549Smdodd } 12552549Smdodd 126121588Simp // Mark all regs in the class as unavailable 127121241Sbms for (auto Reg : RegList) 12852549Smdodd State.AllocateReg(Reg); 129147717Simp 13051673Smdodd const AArch64Subtarget &Subtarget = static_cast<const AArch64Subtarget &>( 131166906Spiso State.getMachineFunction().getSubtarget()); 132117700Smarkm unsigned SlotAlign = Subtarget.isTargetDarwin() ? 1 : 8; 13352549Smdodd 13451673Smdodd return finishStackBlock(PendingMembers, LocVT, ArgFlags, State, SlotAlign); 13551673Smdodd} 13651673Smdodd 13751673Smdodd} 13852549Smdodd 13952549Smdodd#endif 14051673Smdodd