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