1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-18 18:42:46 +02:00
llvm-mirror/lib/Target/AArch64/AArch64CallingConvention.cpp
Reid Kleckner 18f71dad93 [AArch64] Include AArch64GenCallingConv.inc once
Summary:
Avoids duplicating generated static helpers for calling convention
analysis.

This also means you can modify AArch64CallingConv.td without recompiling
the AArch64ISelLowering.cpp monolith, so it provides faster incremental
rebuilds.

Saves 12K in llc.exe, but adds a new object file, which is large.

Reviewers: efriedma, t.p.northover

Subscribers: mgorny, javed.absar, kristof.beyls, hiraditya, llvm-commits

Differential Revision: https://reviews.llvm.org/D56948

llvm-svn: 352430
2019-01-28 21:28:40 +00:00

135 lines
5.3 KiB
C++

//=== AArch64CallingConvention.cpp - AArch64 CC impl ------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file contains the table-generated and custom routines for the AArch64
// Calling Convention.
//
//===----------------------------------------------------------------------===//
#include "AArch64CallingConvention.h"
#include "AArch64.h"
#include "AArch64InstrInfo.h"
#include "AArch64Subtarget.h"
#include "llvm/CodeGen/CallingConvLower.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/IR/CallingConv.h"
using namespace llvm;
static const MCPhysReg XRegList[] = {AArch64::X0, AArch64::X1, AArch64::X2,
AArch64::X3, AArch64::X4, AArch64::X5,
AArch64::X6, AArch64::X7};
static const MCPhysReg HRegList[] = {AArch64::H0, AArch64::H1, AArch64::H2,
AArch64::H3, AArch64::H4, AArch64::H5,
AArch64::H6, AArch64::H7};
static const MCPhysReg SRegList[] = {AArch64::S0, AArch64::S1, AArch64::S2,
AArch64::S3, AArch64::S4, AArch64::S5,
AArch64::S6, AArch64::S7};
static const MCPhysReg DRegList[] = {AArch64::D0, AArch64::D1, AArch64::D2,
AArch64::D3, AArch64::D4, AArch64::D5,
AArch64::D6, AArch64::D7};
static const MCPhysReg QRegList[] = {AArch64::Q0, AArch64::Q1, AArch64::Q2,
AArch64::Q3, AArch64::Q4, AArch64::Q5,
AArch64::Q6, AArch64::Q7};
static bool finishStackBlock(SmallVectorImpl<CCValAssign> &PendingMembers,
MVT LocVT, ISD::ArgFlagsTy &ArgFlags,
CCState &State, unsigned SlotAlign) {
unsigned Size = LocVT.getSizeInBits() / 8;
unsigned StackAlign =
State.getMachineFunction().getDataLayout().getStackAlignment();
unsigned Align = std::min(ArgFlags.getOrigAlign(), StackAlign);
for (auto &It : PendingMembers) {
It.convertToMem(State.AllocateStack(Size, std::max(Align, SlotAlign)));
State.addLoc(It);
SlotAlign = 1;
}
// All pending members have now been allocated
PendingMembers.clear();
return true;
}
/// The Darwin variadic PCS places anonymous arguments in 8-byte stack slots. An
/// [N x Ty] type must still be contiguous in memory though.
static bool CC_AArch64_Custom_Stack_Block(
unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo,
ISD::ArgFlagsTy &ArgFlags, CCState &State) {
SmallVectorImpl<CCValAssign> &PendingMembers = State.getPendingLocs();
// Add the argument to the list to be allocated once we know the size of the
// block.
PendingMembers.push_back(
CCValAssign::getPending(ValNo, ValVT, LocVT, LocInfo));
if (!ArgFlags.isInConsecutiveRegsLast())
return true;
return finishStackBlock(PendingMembers, LocVT, ArgFlags, State, 8);
}
/// Given an [N x Ty] block, it should be passed in a consecutive sequence of
/// registers. If no such sequence is available, mark the rest of the registers
/// of that type as used and place the argument on the stack.
static bool CC_AArch64_Custom_Block(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
CCValAssign::LocInfo &LocInfo,
ISD::ArgFlagsTy &ArgFlags, CCState &State) {
// Try to allocate a contiguous block of registers, each of the correct
// size to hold one member.
ArrayRef<MCPhysReg> RegList;
if (LocVT.SimpleTy == MVT::i64)
RegList = XRegList;
else if (LocVT.SimpleTy == MVT::f16)
RegList = HRegList;
else if (LocVT.SimpleTy == MVT::f32 || LocVT.is32BitVector())
RegList = SRegList;
else if (LocVT.SimpleTy == MVT::f64 || LocVT.is64BitVector())
RegList = DRegList;
else if (LocVT.SimpleTy == MVT::f128 || LocVT.is128BitVector())
RegList = QRegList;
else {
// Not an array we want to split up after all.
return false;
}
SmallVectorImpl<CCValAssign> &PendingMembers = State.getPendingLocs();
// Add the argument to the list to be allocated once we know the size of the
// block.
PendingMembers.push_back(
CCValAssign::getPending(ValNo, ValVT, LocVT, LocInfo));
if (!ArgFlags.isInConsecutiveRegsLast())
return true;
unsigned RegResult = State.AllocateRegBlock(RegList, PendingMembers.size());
if (RegResult) {
for (auto &It : PendingMembers) {
It.convertToReg(RegResult);
State.addLoc(It);
++RegResult;
}
PendingMembers.clear();
return true;
}
// Mark all regs in the class as unavailable
for (auto Reg : RegList)
State.AllocateReg(Reg);
const AArch64Subtarget &Subtarget = static_cast<const AArch64Subtarget &>(
State.getMachineFunction().getSubtarget());
unsigned SlotAlign = Subtarget.isTargetDarwin() ? 1 : 8;
return finishStackBlock(PendingMembers, LocVT, ArgFlags, State, SlotAlign);
}
// TableGen provides definitions of the calling convention analysis entry
// points.
#include "AArch64GenCallingConv.inc"