mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-23 02:29:18 +00:00
ARM: Allow __fp16 as a function arg or return type for AArch64
ACLE 2.0 allows __fp16 to be used as a function argument or return type. This enables this for AArch64. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@212812 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
c58b079d23
commit
cb047f2a74
@ -270,7 +270,7 @@ SelectionDAGLegalize::ExpandConstantFP(ConstantFPSDNode *CFP, bool UseCP) {
|
|||||||
|
|
||||||
EVT OrigVT = VT;
|
EVT OrigVT = VT;
|
||||||
EVT SVT = VT;
|
EVT SVT = VT;
|
||||||
while (SVT != MVT::f32) {
|
while (SVT != MVT::f32 && SVT != MVT::f16) {
|
||||||
SVT = (MVT::SimpleValueType)(SVT.getSimpleVT().SimpleTy - 1);
|
SVT = (MVT::SimpleValueType)(SVT.getSimpleVT().SimpleTy - 1);
|
||||||
if (ConstantFPSDNode::isValueValidForType(SVT, CFP->getValueAPF()) &&
|
if (ConstantFPSDNode::isValueValidForType(SVT, CFP->getValueAPF()) &&
|
||||||
// Only do this if the target has a native EXTLOAD instruction from
|
// Only do this if the target has a native EXTLOAD instruction from
|
||||||
|
@ -54,6 +54,8 @@ def CC_AArch64_AAPCS : CallingConv<[
|
|||||||
|
|
||||||
CCIfType<[i64], CCAssignToRegWithShadow<[X0, X1, X2, X3, X4, X5, X6, X7],
|
CCIfType<[i64], CCAssignToRegWithShadow<[X0, X1, X2, X3, X4, X5, X6, X7],
|
||||||
[W0, W1, W2, W3, W4, W5, W6, W7]>>,
|
[W0, W1, W2, W3, W4, W5, W6, W7]>>,
|
||||||
|
CCIfType<[f16], CCAssignToRegWithShadow<[H0, H1, H2, H3, H4, H5, H6, H7],
|
||||||
|
[Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7]>>,
|
||||||
CCIfType<[f32], CCAssignToRegWithShadow<[S0, S1, S2, S3, S4, S5, S6, S7],
|
CCIfType<[f32], CCAssignToRegWithShadow<[S0, S1, S2, S3, S4, S5, S6, S7],
|
||||||
[Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7]>>,
|
[Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7]>>,
|
||||||
CCIfType<[f64], CCAssignToRegWithShadow<[D0, D1, D2, D3, D4, D5, D6, D7],
|
CCIfType<[f64], CCAssignToRegWithShadow<[D0, D1, D2, D3, D4, D5, D6, D7],
|
||||||
@ -65,7 +67,7 @@ def CC_AArch64_AAPCS : CallingConv<[
|
|||||||
CCAssignToReg<[Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7]>>,
|
CCAssignToReg<[Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7]>>,
|
||||||
|
|
||||||
// If more than will fit in registers, pass them on the stack instead.
|
// If more than will fit in registers, pass them on the stack instead.
|
||||||
CCIfType<[i1, i8, i16], CCAssignToStack<8, 8>>,
|
CCIfType<[i1, i8, i16, f16], CCAssignToStack<8, 8>>,
|
||||||
CCIfType<[i32, f32], CCAssignToStack<8, 8>>,
|
CCIfType<[i32, f32], CCAssignToStack<8, 8>>,
|
||||||
CCIfType<[i64, f64, v1f64, v2f32, v1i64, v2i32, v4i16, v8i8],
|
CCIfType<[i64, f64, v1f64, v2f32, v1i64, v2i32, v4i16, v8i8],
|
||||||
CCAssignToStack<8, 8>>,
|
CCAssignToStack<8, 8>>,
|
||||||
@ -88,6 +90,8 @@ def RetCC_AArch64_AAPCS : CallingConv<[
|
|||||||
[X0, X1, X2, X3, X4, X5, X6, X7]>>,
|
[X0, X1, X2, X3, X4, X5, X6, X7]>>,
|
||||||
CCIfType<[i64], CCAssignToRegWithShadow<[X0, X1, X2, X3, X4, X5, X6, X7],
|
CCIfType<[i64], CCAssignToRegWithShadow<[X0, X1, X2, X3, X4, X5, X6, X7],
|
||||||
[W0, W1, W2, W3, W4, W5, W6, W7]>>,
|
[W0, W1, W2, W3, W4, W5, W6, W7]>>,
|
||||||
|
CCIfType<[f16], CCAssignToRegWithShadow<[H0, H1, H2, H3, H4, H5, H6, H7],
|
||||||
|
[Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7]>>,
|
||||||
CCIfType<[f32], CCAssignToRegWithShadow<[S0, S1, S2, S3, S4, S5, S6, S7],
|
CCIfType<[f32], CCAssignToRegWithShadow<[S0, S1, S2, S3, S4, S5, S6, S7],
|
||||||
[Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7]>>,
|
[Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7]>>,
|
||||||
CCIfType<[f64], CCAssignToRegWithShadow<[D0, D1, D2, D3, D4, D5, D6, D7],
|
CCIfType<[f64], CCAssignToRegWithShadow<[D0, D1, D2, D3, D4, D5, D6, D7],
|
||||||
@ -129,6 +133,8 @@ def CC_AArch64_DarwinPCS : CallingConv<[
|
|||||||
|
|
||||||
CCIfType<[i64], CCAssignToRegWithShadow<[X0, X1, X2, X3, X4, X5, X6, X7],
|
CCIfType<[i64], CCAssignToRegWithShadow<[X0, X1, X2, X3, X4, X5, X6, X7],
|
||||||
[W0, W1, W2, W3, W4, W5, W6, W7]>>,
|
[W0, W1, W2, W3, W4, W5, W6, W7]>>,
|
||||||
|
CCIfType<[f16], CCAssignToRegWithShadow<[H0, H1, H2, H3, H4, H5, H6, H7],
|
||||||
|
[Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7]>>,
|
||||||
CCIfType<[f32], CCAssignToRegWithShadow<[S0, S1, S2, S3, S4, S5, S6, S7],
|
CCIfType<[f32], CCAssignToRegWithShadow<[S0, S1, S2, S3, S4, S5, S6, S7],
|
||||||
[Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7]>>,
|
[Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7]>>,
|
||||||
CCIfType<[f64], CCAssignToRegWithShadow<[D0, D1, D2, D3, D4, D5, D6, D7],
|
CCIfType<[f64], CCAssignToRegWithShadow<[D0, D1, D2, D3, D4, D5, D6, D7],
|
||||||
@ -141,7 +147,7 @@ def CC_AArch64_DarwinPCS : CallingConv<[
|
|||||||
|
|
||||||
// If more than will fit in registers, pass them on the stack instead.
|
// If more than will fit in registers, pass them on the stack instead.
|
||||||
CCIf<"ValVT == MVT::i1 || ValVT == MVT::i8", CCAssignToStack<1, 1>>,
|
CCIf<"ValVT == MVT::i1 || ValVT == MVT::i8", CCAssignToStack<1, 1>>,
|
||||||
CCIf<"ValVT == MVT::i16", CCAssignToStack<2, 2>>,
|
CCIf<"ValVT == MVT::i16 || ValVT == MVT::f16", CCAssignToStack<2, 2>>,
|
||||||
CCIfType<[i32, f32], CCAssignToStack<4, 4>>,
|
CCIfType<[i32, f32], CCAssignToStack<4, 4>>,
|
||||||
CCIfType<[i64, f64, v1f64, v2f32, v1i64, v2i32, v4i16, v8i8],
|
CCIfType<[i64, f64, v1f64, v2f32, v1i64, v2i32, v4i16, v8i8],
|
||||||
CCAssignToStack<8, 8>>,
|
CCAssignToStack<8, 8>>,
|
||||||
@ -154,7 +160,7 @@ def CC_AArch64_DarwinPCS_VarArg : CallingConv<[
|
|||||||
|
|
||||||
// Handle all scalar types as either i64 or f64.
|
// Handle all scalar types as either i64 or f64.
|
||||||
CCIfType<[i8, i16, i32], CCPromoteToType<i64>>,
|
CCIfType<[i8, i16, i32], CCPromoteToType<i64>>,
|
||||||
CCIfType<[f32], CCPromoteToType<f64>>,
|
CCIfType<[f16, f32], CCPromoteToType<f64>>,
|
||||||
|
|
||||||
// Everything is on the stack.
|
// Everything is on the stack.
|
||||||
// i128 is split to two i64s, and its stack alignment is 16 bytes.
|
// i128 is split to two i64s, and its stack alignment is 16 bytes.
|
||||||
|
@ -1711,6 +1711,8 @@ SDValue AArch64TargetLowering::LowerFormalArguments(
|
|||||||
RC = &AArch64::GPR32RegClass;
|
RC = &AArch64::GPR32RegClass;
|
||||||
else if (RegVT == MVT::i64)
|
else if (RegVT == MVT::i64)
|
||||||
RC = &AArch64::GPR64RegClass;
|
RC = &AArch64::GPR64RegClass;
|
||||||
|
else if (RegVT == MVT::f16)
|
||||||
|
RC = &AArch64::FPR16RegClass;
|
||||||
else if (RegVT == MVT::f32)
|
else if (RegVT == MVT::f32)
|
||||||
RC = &AArch64::FPR32RegClass;
|
RC = &AArch64::FPR32RegClass;
|
||||||
else if (RegVT == MVT::f64 || RegVT.is64BitVector())
|
else if (RegVT == MVT::f64 || RegVT.is64BitVector())
|
||||||
|
@ -109,3 +109,17 @@ entry:
|
|||||||
; CHECK: ldr {{q[0-9]+}}, [sp]
|
; CHECK: ldr {{q[0-9]+}}, [sp]
|
||||||
ret <2 x double> %varg_stack;
|
ret <2 x double> %varg_stack;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
; Check that f16 can be passed and returned (ACLE 2.0 extension)
|
||||||
|
define half @test_half(float, half %arg) {
|
||||||
|
; CHECK-LABEL: test_half:
|
||||||
|
; CHECK: mov v0.16b, v{{[0-9]+}}.16b
|
||||||
|
ret half %arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
; Check that f16 constants are materialized correctly
|
||||||
|
define half @test_half_const() {
|
||||||
|
; CHECK-LABEL: test_half_const:
|
||||||
|
; CHECK: ldr h0, [x{{[0-9]+}}, :lo12:{{.*}}]
|
||||||
|
ret half 0xH4248
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user