2012-02-18 20:03:15 +08:00
|
|
|
//===-- ARMCallingConv.td - Calling Conventions for ARM ----*- tablegen -*-===//
|
2009-04-18 04:35:10 +08:00
|
|
|
//
|
2019-01-19 16:50:56 +08:00
|
|
|
// 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
|
2009-04-18 04:35:10 +08:00
|
|
|
//
|
2009-04-18 03:07:39 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// This describes the calling conventions for ARM architecture.
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
/// CCIfAlign - Match of the original alignment of the arg
|
|
|
|
class CCIfAlign<string Align, CCAction A>:
|
2020-06-25 21:21:07 +08:00
|
|
|
CCIf<!strconcat("ArgFlags.getNonZeroOrigAlign() == ", Align), A>;
|
2009-04-18 03:07:39 +08:00
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// ARM APCS Calling Convention
|
|
|
|
//===----------------------------------------------------------------------===//
|
2019-01-29 05:28:43 +08:00
|
|
|
let Entry = 1 in
|
2009-04-18 03:07:39 +08:00
|
|
|
def CC_ARM_APCS : CallingConv<[
|
|
|
|
|
2011-03-01 01:17:53 +08:00
|
|
|
// Handles byval parameters.
|
2011-04-21 00:47:52 +08:00
|
|
|
CCIfByVal<CCPassByVal<4, 4>>,
|
2019-11-04 18:41:32 +08:00
|
|
|
|
2011-11-05 08:02:56 +08:00
|
|
|
CCIfType<[i1, i8, i16], CCPromoteToType<i32>>,
|
2009-04-18 03:07:39 +08:00
|
|
|
|
2016-04-14 05:43:25 +08:00
|
|
|
// Pass SwiftSelf in a callee saved register.
|
|
|
|
CCIfSwiftSelf<CCIfType<[i32], CCAssignToReg<[R10]>>>,
|
2016-03-30 01:37:21 +08:00
|
|
|
|
2017-02-09 09:52:17 +08:00
|
|
|
// A SwiftError is passed in R8.
|
|
|
|
CCIfSwiftError<CCIfType<[i32], CCAssignToReg<[R8]>>>,
|
2016-04-12 05:08:06 +08:00
|
|
|
|
2009-06-23 07:27:02 +08:00
|
|
|
// Handle all vector types as either f64 or v2f64.
|
2020-06-18 22:40:23 +08:00
|
|
|
CCIfType<[v1i64, v2i32, v4i16, v4f16, v4bf16, v8i8, v2f32], CCBitConvertToType<f64>>,
|
|
|
|
CCIfType<[v2i64, v4i32, v8i16, v8f16, v8bf16, v16i8, v4f32], CCBitConvertToType<v2f64>>,
|
2009-06-23 07:27:02 +08:00
|
|
|
|
|
|
|
// f64 and v2f64 are passed in adjacent GPRs, possibly split onto the stack
|
|
|
|
CCIfType<[f64, v2f64], CCCustom<"CC_ARM_APCS_Custom_f64">>,
|
2009-04-18 03:07:39 +08:00
|
|
|
|
|
|
|
CCIfType<[f32], CCBitConvertToType<i32>>,
|
2009-04-25 00:55:25 +08:00
|
|
|
CCIfType<[i32], CCAssignToReg<[R0, R1, R2, R3]>>,
|
2009-04-18 03:07:39 +08:00
|
|
|
|
2009-04-25 00:55:25 +08:00
|
|
|
CCIfType<[i32], CCAssignToStack<4, 4>>,
|
2009-06-23 07:27:02 +08:00
|
|
|
CCIfType<[f64], CCAssignToStack<8, 4>>,
|
|
|
|
CCIfType<[v2f64], CCAssignToStack<16, 4>>
|
2009-04-18 03:07:39 +08:00
|
|
|
]>;
|
|
|
|
|
2019-01-29 05:28:43 +08:00
|
|
|
let Entry = 1 in
|
2009-04-18 03:07:39 +08:00
|
|
|
def RetCC_ARM_APCS : CallingConv<[
|
2011-11-08 08:03:32 +08:00
|
|
|
CCIfType<[i1, i8, i16], CCPromoteToType<i32>>,
|
2009-04-18 03:07:39 +08:00
|
|
|
CCIfType<[f32], CCBitConvertToType<i32>>,
|
2009-06-23 07:27:02 +08:00
|
|
|
|
2016-04-14 05:43:25 +08:00
|
|
|
// Pass SwiftSelf in a callee saved register.
|
|
|
|
CCIfSwiftSelf<CCIfType<[i32], CCAssignToReg<[R10]>>>,
|
|
|
|
|
2017-02-09 09:52:17 +08:00
|
|
|
// A SwiftError is returned in R8.
|
|
|
|
CCIfSwiftError<CCIfType<[i32], CCAssignToReg<[R8]>>>,
|
2016-04-12 05:08:06 +08:00
|
|
|
|
2009-06-23 07:27:02 +08:00
|
|
|
// Handle all vector types as either f64 or v2f64.
|
2020-06-18 22:40:23 +08:00
|
|
|
CCIfType<[v1i64, v2i32, v4i16, v4f16, v4bf16, v8i8, v2f32], CCBitConvertToType<f64>>,
|
|
|
|
CCIfType<[v2i64, v4i32, v8i16, v8f16, v8bf16, v16i8, v4f32], CCBitConvertToType<v2f64>>,
|
2009-06-23 07:27:02 +08:00
|
|
|
|
|
|
|
CCIfType<[f64, v2f64], CCCustom<"RetCC_ARM_APCS_Custom_f64">>,
|
2009-04-18 03:07:39 +08:00
|
|
|
|
|
|
|
CCIfType<[i32], CCAssignToReg<[R0, R1, R2, R3]>>,
|
|
|
|
CCIfType<[i64], CCAssignToRegWithShadow<[R0, R2], [R1, R3]>>
|
|
|
|
]>;
|
|
|
|
|
2010-10-23 02:23:05 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// ARM APCS Calling Convention for FastCC (when VFP2 or later is available)
|
|
|
|
//===----------------------------------------------------------------------===//
|
2019-01-29 05:28:43 +08:00
|
|
|
let Entry = 1 in
|
2010-10-23 02:23:05 +08:00
|
|
|
def FastCC_ARM_APCS : CallingConv<[
|
|
|
|
// Handle all vector types as either f64 or v2f64.
|
2020-06-18 22:40:23 +08:00
|
|
|
CCIfType<[v1i64, v2i32, v4i16, v4f16, v4bf16, v8i8, v2f32], CCBitConvertToType<f64>>,
|
|
|
|
CCIfType<[v2i64, v4i32, v8i16, v8f16, v8bf16, v16i8, v4f32], CCBitConvertToType<v2f64>>,
|
2010-10-23 02:23:05 +08:00
|
|
|
|
|
|
|
CCIfType<[v2f64], CCAssignToReg<[Q0, Q1, Q2, Q3]>>,
|
|
|
|
CCIfType<[f64], CCAssignToReg<[D0, D1, D2, D3, D4, D5, D6, D7]>>,
|
|
|
|
CCIfType<[f32], CCAssignToReg<[S0, S1, S2, S3, S4, S5, S6, S7, S8,
|
|
|
|
S9, S10, S11, S12, S13, S14, S15]>>,
|
2014-02-12 07:49:31 +08:00
|
|
|
|
2014-03-05 06:56:57 +08:00
|
|
|
// CPRCs may be allocated to co-processor registers or the stack - they
|
2019-11-04 18:41:32 +08:00
|
|
|
// may never be allocated to core registers.
|
2014-02-12 07:49:31 +08:00
|
|
|
CCIfType<[f32], CCAssignToStackWithShadow<4, 4, [Q0, Q1, Q2, Q3]>>,
|
|
|
|
CCIfType<[f64], CCAssignToStackWithShadow<8, 4, [Q0, Q1, Q2, Q3]>>,
|
|
|
|
CCIfType<[v2f64], CCAssignToStackWithShadow<16, 4, [Q0, Q1, Q2, Q3]>>,
|
|
|
|
|
2010-10-23 02:23:05 +08:00
|
|
|
CCDelegateTo<CC_ARM_APCS>
|
|
|
|
]>;
|
|
|
|
|
2019-01-29 05:28:43 +08:00
|
|
|
let Entry = 1 in
|
2010-10-23 02:23:05 +08:00
|
|
|
def RetFastCC_ARM_APCS : CallingConv<[
|
|
|
|
// Handle all vector types as either f64 or v2f64.
|
2020-06-18 22:40:23 +08:00
|
|
|
CCIfType<[v1i64, v2i32, v4i16, v4f16, v4bf16, v8i8, v2f32], CCBitConvertToType<f64>>,
|
|
|
|
CCIfType<[v2i64, v4i32, v8i16, v8f16, v8bf16, v16i8, v4f32], CCBitConvertToType<v2f64>>,
|
2010-10-23 02:23:05 +08:00
|
|
|
|
|
|
|
CCIfType<[v2f64], CCAssignToReg<[Q0, Q1, Q2, Q3]>>,
|
|
|
|
CCIfType<[f64], CCAssignToReg<[D0, D1, D2, D3, D4, D5, D6, D7]>>,
|
|
|
|
CCIfType<[f32], CCAssignToReg<[S0, S1, S2, S3, S4, S5, S6, S7, S8,
|
|
|
|
S9, S10, S11, S12, S13, S14, S15]>>,
|
|
|
|
CCDelegateTo<RetCC_ARM_APCS>
|
|
|
|
]>;
|
|
|
|
|
2012-08-03 08:05:53 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// ARM APCS Calling Convention for GHC
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2019-01-29 05:28:43 +08:00
|
|
|
let Entry = 1 in
|
2012-08-03 08:05:53 +08:00
|
|
|
def CC_ARM_APCS_GHC : CallingConv<[
|
|
|
|
// Handle all vector types as either f64 or v2f64.
|
2020-06-18 22:40:23 +08:00
|
|
|
CCIfType<[v1i64, v2i32, v4i16, v4f16, v4bf16, v8i8, v2f32], CCBitConvertToType<f64>>,
|
|
|
|
CCIfType<[v2i64, v4i32, v8i16, v8f16, v8bf16, v16i8, v4f32], CCBitConvertToType<v2f64>>,
|
2012-08-03 08:05:53 +08:00
|
|
|
|
|
|
|
CCIfType<[v2f64], CCAssignToReg<[Q4, Q5]>>,
|
|
|
|
CCIfType<[f64], CCAssignToReg<[D8, D9, D10, D11]>>,
|
|
|
|
CCIfType<[f32], CCAssignToReg<[S16, S17, S18, S19, S20, S21, S22, S23]>>,
|
|
|
|
|
|
|
|
// Promote i8/i16 arguments to i32.
|
|
|
|
CCIfType<[i8, i16], CCPromoteToType<i32>>,
|
|
|
|
|
|
|
|
// Pass in STG registers: Base, Sp, Hp, R1, R2, R3, R4, SpLim
|
|
|
|
CCIfType<[i32], CCAssignToReg<[R4, R5, R6, R7, R8, R9, R10, R11]>>
|
|
|
|
]>;
|
2010-10-23 02:23:05 +08:00
|
|
|
|
2009-04-18 03:07:39 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
2009-06-09 06:53:56 +08:00
|
|
|
// ARM AAPCS (EABI) Calling Convention, common parts
|
2009-04-18 03:07:39 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
2009-06-09 06:53:56 +08:00
|
|
|
|
|
|
|
def CC_ARM_AAPCS_Common : CallingConv<[
|
2009-04-18 03:07:39 +08:00
|
|
|
|
2011-11-08 05:43:40 +08:00
|
|
|
CCIfType<[i1, i8, i16], CCPromoteToType<i32>>,
|
2009-04-18 03:07:39 +08:00
|
|
|
|
|
|
|
// i64/f64 is passed in even pairs of GPRs
|
|
|
|
// i64 is 8-aligned i32 here, so we may need to eat R1 as a pad register
|
2009-05-19 18:02:36 +08:00
|
|
|
// (and the same is true for f64 if VFP is not enabled)
|
2009-04-18 03:07:39 +08:00
|
|
|
CCIfType<[i32], CCIfAlign<"8", CCAssignToRegWithShadow<[R0, R2], [R0, R1]>>>,
|
2020-06-25 21:21:07 +08:00
|
|
|
CCIfType<[i32], CCIf<"ArgFlags.getNonZeroOrigAlign() != Align(8)",
|
2009-05-19 18:02:36 +08:00
|
|
|
CCAssignToReg<[R0, R1, R2, R3]>>>,
|
2009-04-18 03:07:39 +08:00
|
|
|
|
2014-02-07 19:19:53 +08:00
|
|
|
CCIfType<[i32], CCIfAlign<"8", CCAssignToStackWithShadow<4, 8, [R0, R1, R2, R3]>>>,
|
|
|
|
CCIfType<[i32], CCAssignToStackWithShadow<4, 4, [R0, R1, R2, R3]>>,
|
2020-06-18 22:40:23 +08:00
|
|
|
CCIfType<[f16, bf16, f32], CCAssignToStackWithShadow<4, 4, [Q0, Q1, Q2, Q3]>>,
|
2014-02-07 19:19:53 +08:00
|
|
|
CCIfType<[f64], CCAssignToStackWithShadow<8, 8, [Q0, Q1, Q2, Q3]>>,
|
2015-10-29 06:46:43 +08:00
|
|
|
CCIfType<[v2f64], CCIfAlign<"16",
|
|
|
|
CCAssignToStackWithShadow<16, 16, [Q0, Q1, Q2, Q3]>>>,
|
2014-02-07 19:19:53 +08:00
|
|
|
CCIfType<[v2f64], CCAssignToStackWithShadow<16, 8, [Q0, Q1, Q2, Q3]>>
|
2009-04-18 03:07:39 +08:00
|
|
|
]>;
|
|
|
|
|
2009-06-09 06:53:56 +08:00
|
|
|
def RetCC_ARM_AAPCS_Common : CallingConv<[
|
2011-11-08 08:03:32 +08:00
|
|
|
CCIfType<[i1, i8, i16], CCPromoteToType<i32>>,
|
2009-06-09 06:59:50 +08:00
|
|
|
CCIfType<[i32], CCAssignToReg<[R0, R1, R2, R3]>>,
|
2009-06-09 06:53:56 +08:00
|
|
|
CCIfType<[i64], CCAssignToRegWithShadow<[R0, R2], [R1, R3]>>
|
|
|
|
]>;
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// ARM AAPCS (EABI) Calling Convention
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2019-01-29 05:28:43 +08:00
|
|
|
let Entry = 1 in
|
2009-06-09 06:53:56 +08:00
|
|
|
def CC_ARM_AAPCS : CallingConv<[
|
2012-08-11 04:39:38 +08:00
|
|
|
// Handles byval parameters.
|
|
|
|
CCIfByVal<CCPassByVal<4, 4>>,
|
|
|
|
|
2015-07-13 02:16:40 +08:00
|
|
|
// The 'nest' parameter, if any, is passed in R12.
|
|
|
|
CCIfNest<CCAssignToReg<[R12]>>,
|
|
|
|
|
2009-06-23 07:27:02 +08:00
|
|
|
// Handle all vector types as either f64 or v2f64.
|
2020-06-18 22:40:23 +08:00
|
|
|
CCIfType<[v1i64, v2i32, v4i16, v4f16, v4bf16, v8i8, v2f32], CCBitConvertToType<f64>>,
|
|
|
|
CCIfType<[v2i64, v4i32, v8i16, v8f16, v8bf16, v16i8, v4f32], CCBitConvertToType<v2f64>>,
|
2009-06-23 07:27:02 +08:00
|
|
|
|
2016-04-14 05:43:25 +08:00
|
|
|
// Pass SwiftSelf in a callee saved register.
|
|
|
|
CCIfSwiftSelf<CCIfType<[i32], CCAssignToReg<[R10]>>>,
|
2016-03-30 01:37:21 +08:00
|
|
|
|
2017-02-09 09:52:17 +08:00
|
|
|
// A SwiftError is passed in R8.
|
|
|
|
CCIfSwiftError<CCIfType<[i32], CCAssignToReg<[R8]>>>,
|
2016-04-12 05:08:06 +08:00
|
|
|
|
2009-06-23 07:27:02 +08:00
|
|
|
CCIfType<[f64, v2f64], CCCustom<"CC_ARM_AAPCS_Custom_f64">>,
|
2009-04-18 03:07:39 +08:00
|
|
|
CCIfType<[f32], CCBitConvertToType<i32>>,
|
2020-06-18 22:40:23 +08:00
|
|
|
CCIfType<[f16, bf16], CCCustom<"CC_ARM_AAPCS_Custom_f16">>,
|
2009-06-09 06:53:56 +08:00
|
|
|
CCDelegateTo<CC_ARM_AAPCS_Common>
|
|
|
|
]>;
|
|
|
|
|
2019-01-29 05:28:43 +08:00
|
|
|
let Entry = 1 in
|
2009-06-09 06:53:56 +08:00
|
|
|
def RetCC_ARM_AAPCS : CallingConv<[
|
2009-06-23 07:27:02 +08:00
|
|
|
// Handle all vector types as either f64 or v2f64.
|
2020-06-18 22:40:23 +08:00
|
|
|
CCIfType<[v1i64, v2i32, v4i16, v4f16, v4bf16, v8i8, v2f32], CCBitConvertToType<f64>>,
|
|
|
|
CCIfType<[v2i64, v4i32, v8i16, v8f16, v8bf16, v16i8, v4f32], CCBitConvertToType<v2f64>>,
|
2009-06-23 07:27:02 +08:00
|
|
|
|
2016-04-14 05:43:25 +08:00
|
|
|
// Pass SwiftSelf in a callee saved register.
|
|
|
|
CCIfSwiftSelf<CCIfType<[i32], CCAssignToReg<[R10]>>>,
|
|
|
|
|
2017-02-09 09:52:17 +08:00
|
|
|
// A SwiftError is returned in R8.
|
|
|
|
CCIfSwiftError<CCIfType<[i32], CCAssignToReg<[R8]>>>,
|
2016-04-12 05:08:06 +08:00
|
|
|
|
2009-06-23 07:27:02 +08:00
|
|
|
CCIfType<[f64, v2f64], CCCustom<"RetCC_ARM_AAPCS_Custom_f64">>,
|
2009-06-09 06:53:56 +08:00
|
|
|
CCIfType<[f32], CCBitConvertToType<i32>>,
|
2020-06-18 22:40:23 +08:00
|
|
|
CCIfType<[f16, bf16], CCCustom<"CC_ARM_AAPCS_Custom_f16">>,
|
[ARM] Armv8.2-A FP16 code generation (part 1/3)
This is the groundwork for Armv8.2-A FP16 code generation .
Clang passes and returns _Float16 values as floats, together with the required
bitconverts and truncs etc. to implement correct AAPCS behaviour, see D42318.
We will implement half-precision argument passing/returning lowering in the ARM
backend soon, but for now this means that this:
_Float16 sub(_Float16 a, _Float16 b) {
return a + b;
}
gets lowered to this:
define float @sub(float %a.coerce, float %b.coerce) {
entry:
%0 = bitcast float %a.coerce to i32
%tmp.0.extract.trunc = trunc i32 %0 to i16
%1 = bitcast i16 %tmp.0.extract.trunc to half
<SNIP>
%add = fadd half %1, %3
<SNIP>
}
When FullFP16 is *not* supported, we don't make f16 a legal type, and we get
legalization for "free", i.e. nothing changes and everything works as before.
And also f16 argument passing/returning is handled.
When FullFP16 is supported, we do make f16 a legal type, and have 2 places that
we need to patch up: f16 argument passing and returning, which involves minor
tweaks to avoid unnecessary code generation for some bitcasts.
As a "demonstrator" that this works for the different FP16, FullFP16, softfp
modes, etc., I've added match rules to the VSUB instruction description showing
that we can codegen this instruction from IR, but more importantly, also to
some conversion instructions. These conversions were causing issue before in
the FP16 and FullFP16 cases.
I've also added match rules to the VLDRH and VSTRH desriptions, so that we can
actually compile the entire half-precision sub code example above. This showed
that these loads and stores had the wrong addressing mode specified: AddrMode5
instead of AddrMode5FP16, which turned out not be implemented at all, so that
has also been added.
This is the minimal patch that shows all the different moving parts. In patch
2/3 I will add some efficient lowering of bitcasts, and in 2/3 I will add the
remaining Armv8.2-A FP16 instruction descriptions.
Thanks to Sam Parker and Oliver Stannard for their help and reviews!
Differential Revision: https://reviews.llvm.org/D38315
llvm-svn: 323512
2018-01-26 17:26:40 +08:00
|
|
|
|
2009-06-09 06:53:56 +08:00
|
|
|
CCDelegateTo<RetCC_ARM_AAPCS_Common>
|
|
|
|
]>;
|
2009-04-18 03:07:39 +08:00
|
|
|
|
2009-06-09 06:53:56 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// ARM AAPCS-VFP (EABI) Calling Convention
|
2010-10-23 02:23:05 +08:00
|
|
|
// Also used for FastCC (when VFP2 or later is available)
|
2009-06-09 06:53:56 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2019-01-29 05:28:43 +08:00
|
|
|
let Entry = 1 in
|
2009-06-09 06:53:56 +08:00
|
|
|
def CC_ARM_AAPCS_VFP : CallingConv<[
|
2012-08-14 05:22:50 +08:00
|
|
|
// Handles byval parameters.
|
|
|
|
CCIfByVal<CCPassByVal<4, 4>>,
|
|
|
|
|
2009-06-23 07:27:02 +08:00
|
|
|
// Handle all vector types as either f64 or v2f64.
|
2020-06-18 22:40:23 +08:00
|
|
|
CCIfType<[v1i64, v2i32, v4i16, v4f16, v4bf16, v8i8, v2f32], CCBitConvertToType<f64>>,
|
|
|
|
CCIfType<[v2i64, v4i32, v8i16, v8f16, v8bf16, v16i8, v4f32], CCBitConvertToType<v2f64>>,
|
2009-06-23 07:27:02 +08:00
|
|
|
|
2016-04-14 05:43:25 +08:00
|
|
|
// Pass SwiftSelf in a callee saved register.
|
|
|
|
CCIfSwiftSelf<CCIfType<[i32], CCAssignToReg<[R10]>>>,
|
2016-03-30 01:37:21 +08:00
|
|
|
|
2017-02-09 09:52:17 +08:00
|
|
|
// A SwiftError is passed in R8.
|
|
|
|
CCIfSwiftError<CCIfType<[i32], CCAssignToReg<[R8]>>>,
|
2016-04-12 05:08:06 +08:00
|
|
|
|
2014-05-09 22:01:47 +08:00
|
|
|
// HFAs are passed in a contiguous block of registers, or on the stack
|
2015-02-25 01:22:34 +08:00
|
|
|
CCIfConsecutiveRegs<CCCustom<"CC_ARM_AAPCS_Custom_Aggregate">>,
|
2014-05-09 22:01:47 +08:00
|
|
|
|
2009-08-06 03:04:42 +08:00
|
|
|
CCIfType<[v2f64], CCAssignToReg<[Q0, Q1, Q2, Q3]>>,
|
2009-06-09 06:53:56 +08:00
|
|
|
CCIfType<[f64], CCAssignToReg<[D0, D1, D2, D3, D4, D5, D6, D7]>>,
|
|
|
|
CCIfType<[f32], CCAssignToReg<[S0, S1, S2, S3, S4, S5, S6, S7, S8,
|
|
|
|
S9, S10, S11, S12, S13, S14, S15]>>,
|
2020-06-18 22:40:23 +08:00
|
|
|
CCIfType<[f16, bf16], CCCustom<"CC_ARM_AAPCS_VFP_Custom_f16">>,
|
2009-06-09 06:53:56 +08:00
|
|
|
CCDelegateTo<CC_ARM_AAPCS_Common>
|
|
|
|
]>;
|
|
|
|
|
2019-01-29 05:28:43 +08:00
|
|
|
let Entry = 1 in
|
2009-06-09 06:53:56 +08:00
|
|
|
def RetCC_ARM_AAPCS_VFP : CallingConv<[
|
2009-06-23 07:27:02 +08:00
|
|
|
// Handle all vector types as either f64 or v2f64.
|
2020-06-18 22:40:23 +08:00
|
|
|
CCIfType<[v1i64, v2i32, v4i16, v4f16, v4bf16, v8i8, v2f32], CCBitConvertToType<f64>>,
|
|
|
|
CCIfType<[v2i64, v4i32, v8i16, v8f16, v8bf16, v16i8, v4f32], CCBitConvertToType<v2f64>>,
|
2009-06-23 07:27:02 +08:00
|
|
|
|
2016-04-14 05:43:25 +08:00
|
|
|
// Pass SwiftSelf in a callee saved register.
|
|
|
|
CCIfSwiftSelf<CCIfType<[i32], CCAssignToReg<[R10]>>>,
|
|
|
|
|
2017-02-09 09:52:17 +08:00
|
|
|
// A SwiftError is returned in R8.
|
|
|
|
CCIfSwiftError<CCIfType<[i32], CCAssignToReg<[R8]>>>,
|
2016-04-12 05:08:06 +08:00
|
|
|
|
2009-08-06 03:04:42 +08:00
|
|
|
CCIfType<[v2f64], CCAssignToReg<[Q0, Q1, Q2, Q3]>>,
|
2009-06-09 06:53:56 +08:00
|
|
|
CCIfType<[f64], CCAssignToReg<[D0, D1, D2, D3, D4, D5, D6, D7]>>,
|
|
|
|
CCIfType<[f32], CCAssignToReg<[S0, S1, S2, S3, S4, S5, S6, S7, S8,
|
[ARM] Supporting lowering of half-precision FP arguments and returns in AArch32's backend
Summary:
Half-precision floating point arguments and returns are currently
promoted to either float or int32 in clang's CodeGen and there's
no existing support for the lowering of `half` arguments and returns
from IR in AArch32's backend.
Such frontend coercions, implemented as coercion through memory
in clang, can cause a series of issues in argument lowering, as causing
arguments to be stored on the wrong bits on big-endian architectures
and incurring in missing overflow detections in the return of certain
functions.
This patch introduces the handling of half-precision arguments and returns in
the backend using the actual "half" type on the IR. Using the "half"
type the backend is able to properly enforce the AAPCS' directions for
those arguments, making sure they are stored on the proper bits of the
registers and performing the necessary floating point convertions.
Reviewers: rjmccall, olista01, asl, efriedma, ostannard, SjoerdMeijer
Reviewed By: ostannard
Subscribers: stuij, hiraditya, dmgreen, llvm-commits, chill, dnsampaio, danielkiss, kristof.beyls, cfe-commits
Tags: #clang, #llvm
Differential Revision: https://reviews.llvm.org/D75169
2020-06-09 16:45:47 +08:00
|
|
|
S9, S10, S11, S12, S13, S14, S15]>>,
|
2020-06-18 22:40:23 +08:00
|
|
|
CCIfType<[f16, bf16], CCCustom<"CC_ARM_AAPCS_VFP_Custom_f16">>,
|
2009-06-09 06:53:56 +08:00
|
|
|
CCDelegateTo<RetCC_ARM_AAPCS_Common>
|
2009-04-18 03:07:39 +08:00
|
|
|
]>;
|
2012-01-18 07:09:00 +08:00
|
|
|
|
Add Windows Control Flow Guard checks (/guard:cf).
Summary:
A new function pass (Transforms/CFGuard/CFGuard.cpp) inserts CFGuard checks on
indirect function calls, using either the check mechanism (X86, ARM, AArch64) or
or the dispatch mechanism (X86-64). The check mechanism requires a new calling
convention for the supported targets. The dispatch mechanism adds the target as
an operand bundle, which is processed by SelectionDAG. Another pass
(CodeGen/CFGuardLongjmp.cpp) identifies and emits valid longjmp targets, as
required by /guard:cf. This feature is enabled using the `cfguard` CC1 option.
Reviewers: thakis, rnk, theraven, pcc
Subscribers: ychen, hans, metalcanine, dmajor, tomrittervg, alex, mehdi_amini, mgorny, javed.absar, kristof.beyls, hiraditya, steven_wu, dexonsmith, cfe-commits, llvm-commits
Tags: #clang, #llvm
Differential Revision: https://reviews.llvm.org/D65761
2019-10-28 21:22:19 +08:00
|
|
|
|
|
|
|
// Windows Control Flow Guard checks take a single argument (the target function
|
|
|
|
// address) and have no return value.
|
|
|
|
let Entry = 1 in
|
|
|
|
def CC_ARM_Win32_CFGuard_Check : CallingConv<[
|
|
|
|
CCIfType<[i32], CCAssignToReg<[R0]>>
|
|
|
|
]>;
|
|
|
|
|
|
|
|
|
|
|
|
|
2012-01-18 07:09:00 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Callee-saved register lists.
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2012-11-07 07:05:24 +08:00
|
|
|
def CSR_NoRegs : CalleeSavedRegs<(add)>;
|
2016-10-11 18:06:59 +08:00
|
|
|
def CSR_FPRegs : CalleeSavedRegs<(add (sequence "D%u", 0, 31))>;
|
2012-11-07 07:05:24 +08:00
|
|
|
|
2012-01-18 07:09:00 +08:00
|
|
|
def CSR_AAPCS : CalleeSavedRegs<(add LR, R11, R10, R9, R8, R7, R6, R5, R4,
|
|
|
|
(sequence "D%u", 15, 8))>;
|
|
|
|
|
Add Windows Control Flow Guard checks (/guard:cf).
Summary:
A new function pass (Transforms/CFGuard/CFGuard.cpp) inserts CFGuard checks on
indirect function calls, using either the check mechanism (X86, ARM, AArch64) or
or the dispatch mechanism (X86-64). The check mechanism requires a new calling
convention for the supported targets. The dispatch mechanism adds the target as
an operand bundle, which is processed by SelectionDAG. Another pass
(CodeGen/CFGuardLongjmp.cpp) identifies and emits valid longjmp targets, as
required by /guard:cf. This feature is enabled using the `cfguard` CC1 option.
Reviewers: thakis, rnk, theraven, pcc
Subscribers: ychen, hans, metalcanine, dmajor, tomrittervg, alex, mehdi_amini, mgorny, javed.absar, kristof.beyls, hiraditya, steven_wu, dexonsmith, cfe-commits, llvm-commits
Tags: #clang, #llvm
Differential Revision: https://reviews.llvm.org/D65761
2019-10-28 21:22:19 +08:00
|
|
|
// The Windows Control Flow Guard Check function preserves the same registers as
|
|
|
|
// AAPCS, and also preserves all floating point registers.
|
|
|
|
def CSR_Win_AAPCS_CFGuard_Check : CalleeSavedRegs<(add LR, R11, R10, R9, R8, R7,
|
|
|
|
R6, R5, R4, (sequence "D%u", 15, 0))>;
|
|
|
|
|
2017-09-26 01:19:50 +08:00
|
|
|
// R8 is used to pass swifterror, remove it from CSR.
|
|
|
|
def CSR_AAPCS_SwiftError : CalleeSavedRegs<(sub CSR_AAPCS, R8)>;
|
|
|
|
|
2021-02-01 18:08:40 +08:00
|
|
|
// R10 is used to pass swiftself, remove it from CSR.
|
|
|
|
def CSR_AAPCS_SwiftTail : CalleeSavedRegs<(sub CSR_AAPCS, R10)>;
|
|
|
|
|
2016-05-14 03:16:14 +08:00
|
|
|
// The order of callee-saved registers needs to match the order we actually push
|
|
|
|
// them in FrameLowering, because this order is what's used by
|
|
|
|
// PrologEpilogInserter to allocate frame index slots. So when R7 is the frame
|
|
|
|
// pointer, we use this AAPCS alternative.
|
|
|
|
def CSR_AAPCS_SplitPush : CalleeSavedRegs<(add LR, R7, R6, R5, R4,
|
|
|
|
R11, R10, R9, R8,
|
|
|
|
(sequence "D%u", 15, 8))>;
|
|
|
|
|
2017-09-26 01:51:33 +08:00
|
|
|
// R8 is used to pass swifterror, remove it from CSR.
|
|
|
|
def CSR_AAPCS_SplitPush_SwiftError : CalleeSavedRegs<(sub CSR_AAPCS_SplitPush,
|
|
|
|
R8)>;
|
|
|
|
|
2021-02-01 18:08:40 +08:00
|
|
|
// R10 is used to pass swifterror, remove it from CSR.
|
|
|
|
def CSR_AAPCS_SplitPush_SwiftTail : CalleeSavedRegs<(sub CSR_AAPCS_SplitPush,
|
|
|
|
R10)>;
|
|
|
|
|
2013-04-20 13:14:40 +08:00
|
|
|
// Constructors and destructors return 'this' in the ARM C++ ABI; since 'this'
|
|
|
|
// and the pointer return value are both passed in R0 in these cases, this can
|
|
|
|
// be partially modelled by treating R0 as a callee-saved register
|
|
|
|
// Only the resulting RegMask is used; the SaveList is ignored
|
|
|
|
def CSR_AAPCS_ThisReturn : CalleeSavedRegs<(add LR, R11, R10, R9, R8, R7, R6,
|
|
|
|
R5, R4, (sequence "D%u", 15, 8),
|
|
|
|
R0)>;
|
|
|
|
|
2012-01-18 07:09:00 +08:00
|
|
|
// iOS ABI deviates from ARM standard ABI. R9 is not a callee-saved register.
|
|
|
|
// Also save R7-R4 first to match the stack frame fixed spill areas.
|
|
|
|
def CSR_iOS : CalleeSavedRegs<(add LR, R7, R6, R5, R4, (sub CSR_AAPCS, R9))>;
|
2012-08-03 08:05:53 +08:00
|
|
|
|
2017-02-09 09:52:17 +08:00
|
|
|
// R8 is used to pass swifterror, remove it from CSR.
|
|
|
|
def CSR_iOS_SwiftError : CalleeSavedRegs<(sub CSR_iOS, R8)>;
|
2016-04-12 05:08:06 +08:00
|
|
|
|
2021-02-01 18:08:40 +08:00
|
|
|
// R10 is used to pass swiftself, remove it from CSR.
|
|
|
|
def CSR_iOS_SwiftTail : CalleeSavedRegs<(sub CSR_iOS, R10)>;
|
|
|
|
|
2013-04-20 13:14:40 +08:00
|
|
|
def CSR_iOS_ThisReturn : CalleeSavedRegs<(add LR, R7, R6, R5, R4,
|
2013-10-01 22:33:28 +08:00
|
|
|
(sub CSR_AAPCS_ThisReturn, R9))>;
|
|
|
|
|
2017-04-20 02:07:54 +08:00
|
|
|
def CSR_iOS_TLSCall
|
|
|
|
: CalleeSavedRegs<(add LR, SP, (sub(sequence "R%u", 12, 1), R9, R12),
|
|
|
|
(sequence "D%u", 31, 0))>;
|
2016-01-12 07:50:43 +08:00
|
|
|
|
|
|
|
// C++ TLS access function saves all registers except SP. Try to match
|
|
|
|
// the order of CSRs in CSR_iOS.
|
|
|
|
def CSR_iOS_CXX_TLS : CalleeSavedRegs<(add CSR_iOS, (sequence "R%u", 12, 1),
|
|
|
|
(sequence "D%u", 31, 0))>;
|
2016-01-07 17:03:03 +08:00
|
|
|
|
2016-01-12 08:47:18 +08:00
|
|
|
// CSRs that are handled by prologue, epilogue.
|
2016-03-19 07:44:37 +08:00
|
|
|
def CSR_iOS_CXX_TLS_PE : CalleeSavedRegs<(add LR, R12, R11, R7, R5, R4)>;
|
2016-01-12 08:47:18 +08:00
|
|
|
|
|
|
|
// CSRs that are handled explicitly via copies.
|
2016-03-19 07:44:37 +08:00
|
|
|
def CSR_iOS_CXX_TLS_ViaCopy : CalleeSavedRegs<(sub CSR_iOS_CXX_TLS,
|
|
|
|
CSR_iOS_CXX_TLS_PE)>;
|
2016-01-12 08:47:18 +08:00
|
|
|
|
2013-10-01 22:33:28 +08:00
|
|
|
// The "interrupt" attribute is used to generate code that is acceptable in
|
|
|
|
// exception-handlers of various kinds. It makes us use a different return
|
|
|
|
// instruction (handled elsewhere) and affects which registers we must return to
|
|
|
|
// our "caller" in the same state as we receive them.
|
|
|
|
|
|
|
|
// For most interrupts, all registers except SP and LR are shared with
|
|
|
|
// user-space. We mark LR to be saved anyway, since this is what the ARM backend
|
|
|
|
// generally does rather than tracking its liveness as a normal register.
|
|
|
|
def CSR_GenericInt : CalleeSavedRegs<(add LR, (sequence "R%u", 12, 0))>;
|
|
|
|
|
|
|
|
// The fast interrupt handlers have more private state and get their own copies
|
|
|
|
// of R8-R12, in addition to SP and LR. As before, mark LR for saving too.
|
|
|
|
|
|
|
|
// FIXME: we mark R11 as callee-saved since it's often the frame-pointer, and
|
|
|
|
// current frame lowering expects to encounter it while processing callee-saved
|
|
|
|
// registers.
|
|
|
|
def CSR_FIQ : CalleeSavedRegs<(add LR, R11, (sequence "R%u", 7, 0))>;
|
|
|
|
|
|
|
|
|