xref: /freebsd/contrib/llvm-project/llvm/lib/Target/VE/VECallingConv.td (revision e8d8bef961a50d4dc22501cde4fb9fb0be1b2532)
1480093f4SDimitry Andric//===-- VECallingConv.td - Calling Conventions VE ----------*- tablegen -*-===//
2480093f4SDimitry Andric//
3480093f4SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4480093f4SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
5480093f4SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6480093f4SDimitry Andric//
7480093f4SDimitry Andric//===----------------------------------------------------------------------===//
8480093f4SDimitry Andric//
9480093f4SDimitry Andric// This describes the calling conventions for the VE architectures.
10480093f4SDimitry Andric//
11480093f4SDimitry Andric//===----------------------------------------------------------------------===//
12480093f4SDimitry Andric
13480093f4SDimitry Andric//===----------------------------------------------------------------------===//
14480093f4SDimitry Andric// Aurora VE
15480093f4SDimitry Andric//===----------------------------------------------------------------------===//
165ffd83dbSDimitry Andricdef CC_VE_C_Stack: CallingConv<[
17*e8d8bef9SDimitry Andric  // F128 are assigned to the stack in 16-byte aligned units
18*e8d8bef9SDimitry Andric  CCIfType<[f128], CCAssignToStackWithShadow<16, 16, [SX7]>>,
195ffd83dbSDimitry Andric
205ffd83dbSDimitry Andric  // All of the rest are assigned to the stack in 8-byte aligned units.
215ffd83dbSDimitry Andric  CCAssignToStack<0, 8>
225ffd83dbSDimitry Andric]>;
235ffd83dbSDimitry Andric
24*e8d8bef9SDimitry Andric///// C Calling Convention (VE ABI v2.1) /////
25*e8d8bef9SDimitry Andric//
26*e8d8bef9SDimitry Andric// Reference: https://www.nec.com/en/global/prod/hpc/aurora/document/VE-ABI_v2.1.pdf
27*e8d8bef9SDimitry Andric//
28*e8d8bef9SDimitry Andricdef CC_VE_C : CallingConv<[
295ffd83dbSDimitry Andric  // All arguments get passed in generic registers if there is space.
305ffd83dbSDimitry Andric
31*e8d8bef9SDimitry Andric  // Promote i1/i8/i16/i32 arguments to i64.
32*e8d8bef9SDimitry Andric  CCIfType<[i1, i8, i16, i32], CCPromoteToType<i64>>,
335ffd83dbSDimitry Andric
34*e8d8bef9SDimitry Andric  // Convert float arguments to i64 with padding.
35*e8d8bef9SDimitry Andric  //     63     31   0
36*e8d8bef9SDimitry Andric  //    +------+------+
37*e8d8bef9SDimitry Andric  //    | float|   0  |
38*e8d8bef9SDimitry Andric  //    +------+------+
39*e8d8bef9SDimitry Andric  CCIfType<[f32], CCBitConvertToType<i64>>,
405ffd83dbSDimitry Andric
41*e8d8bef9SDimitry Andric  // bool, char, int, enum, long, long long, float, double
42*e8d8bef9SDimitry Andric  //     --> generic 64 bit registers
435ffd83dbSDimitry Andric  CCIfType<[i64, f64],
445ffd83dbSDimitry Andric           CCAssignToReg<[SX0, SX1, SX2, SX3, SX4, SX5, SX6, SX7]>>,
455ffd83dbSDimitry Andric
46*e8d8bef9SDimitry Andric  // long double --> pair of generic 64 bit registers
47*e8d8bef9SDimitry Andric  //
48*e8d8bef9SDimitry Andric  // NOTE: If Q1 is allocated while SX1 is free, llvm tries to allocate SX1 for
49*e8d8bef9SDimitry Andric  //       following operands, this masks SX1 to avoid such behavior.
50*e8d8bef9SDimitry Andric  CCIfType<[f128],
51*e8d8bef9SDimitry Andric           CCAssignToRegWithShadow<[Q0, Q1, Q2, Q3],
52*e8d8bef9SDimitry Andric                                   [SX0, SX1, SX3, SX5]>>,
53*e8d8bef9SDimitry Andric
545ffd83dbSDimitry Andric  // Alternatively, they are assigned to the stack in 8-byte aligned units.
555ffd83dbSDimitry Andric  CCDelegateTo<CC_VE_C_Stack>
565ffd83dbSDimitry Andric]>;
575ffd83dbSDimitry Andric
58*e8d8bef9SDimitry Andric///// Standard vararg C Calling Convention (VE ABI v2.1) /////
595ffd83dbSDimitry Andric// All arguments get passed in stack for varargs function or non-prototyped
605ffd83dbSDimitry Andric// function.
615ffd83dbSDimitry Andricdef CC_VE2 : CallingConv<[
62*e8d8bef9SDimitry Andric  // Promote i1/i8/i16/i32 arguments to i64.
63*e8d8bef9SDimitry Andric  CCIfType<[i1, i8, i16, i32], CCPromoteToType<i64>>,
64*e8d8bef9SDimitry Andric
65*e8d8bef9SDimitry Andric  // Convert float arguments to i64 with padding.
66*e8d8bef9SDimitry Andric  //     63     31   0
675ffd83dbSDimitry Andric  //    +------+------+
68*e8d8bef9SDimitry Andric  //    | float|   0  |
695ffd83dbSDimitry Andric  //    +------+------+
70*e8d8bef9SDimitry Andric  CCIfType<[f32], CCBitConvertToType<i64>>,
71*e8d8bef9SDimitry Andric
72*e8d8bef9SDimitry Andric  // F128 are assigned to the stack in 16-byte aligned units
73*e8d8bef9SDimitry Andric  CCIfType<[f128], CCAssignToStack<16, 16>>,
745ffd83dbSDimitry Andric
755ffd83dbSDimitry Andric  CCAssignToStack<0, 8>
765ffd83dbSDimitry Andric]>;
775ffd83dbSDimitry Andric
78*e8d8bef9SDimitry Andricdef RetCC_VE_C : CallingConv<[
79*e8d8bef9SDimitry Andric  // Promote i1/i8/i16/i32 return values to i64.
80*e8d8bef9SDimitry Andric  CCIfType<[i1, i8, i16, i32], CCPromoteToType<i64>>,
815ffd83dbSDimitry Andric
82*e8d8bef9SDimitry Andric  // Convert float return values to i64 with padding.
83*e8d8bef9SDimitry Andric  //     63     31   0
84*e8d8bef9SDimitry Andric  //    +------+------+
85*e8d8bef9SDimitry Andric  //    | float|   0  |
86*e8d8bef9SDimitry Andric  //    +------+------+
87*e8d8bef9SDimitry Andric  CCIfType<[f32], CCBitConvertToType<i64>>,
885ffd83dbSDimitry Andric
89*e8d8bef9SDimitry Andric  // bool, char, int, enum, long, long long, float, double
90*e8d8bef9SDimitry Andric  //     --> generic 64 bit registers
915ffd83dbSDimitry Andric  CCIfType<[i64, f64],
925ffd83dbSDimitry Andric           CCAssignToReg<[SX0, SX1, SX2, SX3, SX4, SX5, SX6, SX7]>>,
93*e8d8bef9SDimitry Andric
94*e8d8bef9SDimitry Andric  // long double --> pair of generic 64 bit registers
95*e8d8bef9SDimitry Andric  CCIfType<[f128],
96*e8d8bef9SDimitry Andric           CCAssignToRegWithShadow<[Q0, Q1, Q2, Q3],
97*e8d8bef9SDimitry Andric                                   [SX0, SX1, SX3, SX5]>>,
98*e8d8bef9SDimitry Andric]>;
99*e8d8bef9SDimitry Andric
100*e8d8bef9SDimitry Andric///// Custom fastcc /////
101*e8d8bef9SDimitry Andric//
102*e8d8bef9SDimitry Andric// This passes vector params and return values in registers.  Scalar values are
103*e8d8bef9SDimitry Andric// handled conforming to the standard cc.
104*e8d8bef9SDimitry Andricdef CC_VE_Fast : CallingConv<[
105*e8d8bef9SDimitry Andric  // vector --> generic vector registers
106*e8d8bef9SDimitry Andric  CCIfType<[v256i32, v256f32, v256i64, v256f64],
107*e8d8bef9SDimitry Andric           CCAssignToReg<[V0, V1, V2, V3, V4, V5, V6, V7]>>,
108*e8d8bef9SDimitry Andric  // TODO: make this conditional on packed mode
109*e8d8bef9SDimitry Andric  CCIfType<[v512i32, v512f32],
110*e8d8bef9SDimitry Andric           CCAssignToReg<[V0, V1, V2, V3, V4, V5, V6, V7]>>,
111*e8d8bef9SDimitry Andric
112*e8d8bef9SDimitry Andric  // vector mask --> generic vector mask registers
113*e8d8bef9SDimitry Andric  CCIfType<[v256i1],
114*e8d8bef9SDimitry Andric           CCAssignToReg<[VM1, VM2, VM3, VM4, VM5, VM6, VM7]>>,
115*e8d8bef9SDimitry Andric
116*e8d8bef9SDimitry Andric  // pair of vector mask --> generic vector mask registers
117*e8d8bef9SDimitry Andric  CCIfType<[v512i1],
118*e8d8bef9SDimitry Andric           CCAssignToRegWithShadow<[VMP1, VMP2, VMP3],
119*e8d8bef9SDimitry Andric                                   [VM1, VM3, VM5]>>,
120*e8d8bef9SDimitry Andric
121*e8d8bef9SDimitry Andric  // Follow the standard C CC for scalars.
122*e8d8bef9SDimitry Andric  CCDelegateTo<CC_VE_C>
123*e8d8bef9SDimitry Andric]>;
124*e8d8bef9SDimitry Andric
125*e8d8bef9SDimitry Andricdef RetCC_VE_Fast : CallingConv<[
126*e8d8bef9SDimitry Andric  // vector --> generic vector registers
127*e8d8bef9SDimitry Andric  CCIfType<[v256i32, v256f32, v256i64, v256f64],
128*e8d8bef9SDimitry Andric           CCAssignToReg<[V0, V1, V2, V3, V4, V5, V6, V7]>>,
129*e8d8bef9SDimitry Andric  // TODO: make this conditional on packed mode
130*e8d8bef9SDimitry Andric  CCIfType<[v512i32, v512f32],
131*e8d8bef9SDimitry Andric           CCAssignToReg<[V0, V1, V2, V3, V4, V5, V6, V7]>>,
132*e8d8bef9SDimitry Andric
133*e8d8bef9SDimitry Andric  // vector mask --> generic vector mask registers
134*e8d8bef9SDimitry Andric  CCIfType<[v256i1],
135*e8d8bef9SDimitry Andric           CCAssignToReg<[VM1, VM2, VM3, VM4, VM5, VM6, VM7]>>,
136*e8d8bef9SDimitry Andric
137*e8d8bef9SDimitry Andric  // pair of vector mask --> generic vector mask registers
138*e8d8bef9SDimitry Andric  CCIfType<[v512i1],
139*e8d8bef9SDimitry Andric           CCAssignToRegWithShadow<[VMP1, VMP2, VMP3],
140*e8d8bef9SDimitry Andric                                   [VM1, VM3, VM5]>>,
141*e8d8bef9SDimitry Andric
142*e8d8bef9SDimitry Andric  // Follow the standard C CC for scalars.
143*e8d8bef9SDimitry Andric  CCDelegateTo<RetCC_VE_C>
1445ffd83dbSDimitry Andric]>;
145480093f4SDimitry Andric
146480093f4SDimitry Andric// Callee-saved registers
147480093f4SDimitry Andricdef CSR : CalleeSavedRegs<(add (sequence "SX%u", 18, 33))>;
148480093f4SDimitry Andricdef CSR_NoRegs : CalleeSavedRegs<(add)>;
1495ffd83dbSDimitry Andric
1505ffd83dbSDimitry Andric// PreserveAll (clobbers s62,s63) - used for ve_grow_stack
151*e8d8bef9SDimitry Andricdef CSR_preserve_all : CalleeSavedRegs<(add (sequence "SX%u", 0, 61),
152*e8d8bef9SDimitry Andric                                            (sequence "V%u", 0, 63),
153*e8d8bef9SDimitry Andric                                            (sequence "VM%u", 1, 15))>;
154