1//===- HexagonCallingConv.td ----------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9class CCIfArgIsVarArg<CCAction A>
10  : CCIf<"State.isVarArg() && "
11         "ValNo >= static_cast<HexagonCCState&>(State)"
12         ".getNumNamedVarArgParams()", A>;
13
14def CC_HexagonStack: CallingConv<[
15  CCIfType<[i32,v2i16,v4i8],
16    CCAssignToStack<4,4>>,
17  CCIfType<[i64,v2i32,v4i16,v8i8],
18    CCAssignToStack<8,8>>
19]>;
20
21def CC_Hexagon_Legacy: CallingConv<[
22  CCIfType<[i1,i8,i16],
23    CCPromoteToType<i32>>,
24  CCIfType<[f32],
25    CCBitConvertToType<i32>>,
26  CCIfType<[f64],
27    CCBitConvertToType<i64>>,
28
29  CCIfByVal<
30    CCPassByVal<8,8>>,
31  CCIfArgIsVarArg<
32    CCDelegateTo<CC_HexagonStack>>,
33
34  // Pass split values in pairs, allocate odd register if necessary.
35  CCIfType<[i32],
36    CCIfSplit<
37      CCCustom<"CC_SkipOdd">>>,
38
39  CCIfType<[i32,v2i16,v4i8],
40    CCAssignToReg<[R0,R1,R2,R3,R4,R5]>>,
41  // Make sure to allocate any skipped 32-bit register, so it does not get
42  // allocated to a subsequent 32-bit value.
43  CCIfType<[i64,v2i32,v4i16,v8i8],
44    CCCustom<"CC_SkipOdd">>,
45  CCIfType<[i64,v2i32,v4i16,v8i8],
46    CCAssignToReg<[D0,D1,D2]>>,
47
48  CCDelegateTo<CC_HexagonStack>
49]>;
50
51def CC_Hexagon: CallingConv<[
52  CCIfType<[i1,i8,i16],
53    CCPromoteToType<i32>>,
54  CCIfType<[f32],
55    CCBitConvertToType<i32>>,
56  CCIfType<[f64],
57    CCBitConvertToType<i64>>,
58
59  CCIfByVal<
60    CCPassByVal<8,1>>,
61  CCIfArgIsVarArg<
62    CCDelegateTo<CC_HexagonStack>>,
63
64  // Pass split values in pairs, allocate odd register if necessary.
65  CCIfType<[i32],
66    CCIfSplit<
67      CCCustom<"CC_SkipOdd">>>,
68
69  CCIfType<[i32,v2i16,v4i8],
70    CCAssignToReg<[R0,R1,R2,R3,R4,R5]>>,
71  // Make sure to allocate any skipped 32-bit register, so it does not get
72  // allocated to a subsequent 32-bit value.
73  CCIfType<[i64,v2i32,v4i16,v8i8],
74    CCCustom<"CC_SkipOdd">>,
75  CCIfType<[i64,v2i32,v4i16,v8i8],
76    CCAssignToReg<[D0,D1,D2]>>,
77
78  CCDelegateTo<CC_HexagonStack>
79]>;
80
81def RetCC_Hexagon: CallingConv<[
82  CCIfType<[i1,i8,i16],
83    CCPromoteToType<i32>>,
84  CCIfType<[f32],
85    CCBitConvertToType<i32>>,
86  CCIfType<[f64],
87    CCBitConvertToType<i64>>,
88
89  // Small structures are returned in a pair of registers, (which is
90  // always r1:0). In such case, what is returned are two i32 values
91  // without any additional information (in ArgFlags) stating that
92  // they are parts of a structure. Because of that there is no way
93  // to differentiate that situation from an attempt to return two
94  // values, so always assign R0 and R1.
95  CCIfSplit<
96    CCAssignToReg<[R0,R1]>>,
97  CCIfType<[i32,v2i16,v4i8],
98    CCAssignToReg<[R0,R1]>>,
99  CCIfType<[i64,v2i32,v4i16,v8i8],
100    CCAssignToReg<[D0]>>
101]>;
102
103
104class CCIfHvx64<CCAction A>
105  : CCIf<"State.getMachineFunction().getSubtarget<HexagonSubtarget>()"
106         ".useHVX64BOps()", A>;
107
108class CCIfHvx128<CCAction A>
109  : CCIf<"State.getMachineFunction().getSubtarget<HexagonSubtarget>()"
110         ".useHVX128BOps()", A>;
111
112def CC_Hexagon_HVX: CallingConv<[
113  // HVX 64-byte mode
114  CCIfHvx64<
115    CCIfType<[v16i32,v32i16,v64i8],
116      CCAssignToReg<[V0,V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12,V13,V14,V15]>>>,
117  CCIfHvx64<
118    CCIfType<[v32i32,v64i16,v128i8],
119      CCAssignToReg<[W0,W1,W2,W3,W4,W5,W6,W7]>>>,
120  CCIfHvx64<
121    CCIfType<[v16i32,v32i16,v64i8],
122      CCAssignToStack<64,64>>>,
123  CCIfHvx64<
124    CCIfType<[v32i32,v64i16,v128i8],
125      CCAssignToStack<128,64>>>,
126
127  // HVX 128-byte mode
128  CCIfHvx128<
129    CCIfType<[v32i32,v64i16,v128i8],
130      CCAssignToReg<[V0,V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12,V13,V14,V15]>>>,
131  CCIfHvx128<
132    CCIfType<[v64i32,v128i16,v256i8],
133      CCAssignToReg<[W0,W1,W2,W3,W4,W5,W6,W7]>>>,
134  CCIfHvx128<
135    CCIfType<[v32i32,v64i16,v128i8],
136      CCAssignToStack<128,128>>>,
137  CCIfHvx128<
138    CCIfType<[v64i32,v128i16,v256i8],
139      CCAssignToStack<256,128>>>,
140
141  CCDelegateTo<CC_Hexagon>
142]>;
143
144def RetCC_Hexagon_HVX: CallingConv<[
145  // HVX 64-byte mode
146  CCIfHvx64<
147    CCIfType<[v16i32,v32i16,v64i8],
148      CCAssignToReg<[V0]>>>,
149  CCIfHvx64<
150    CCIfType<[v32i32,v64i16,v128i8],
151      CCAssignToReg<[W0]>>>,
152
153  // HVX 128-byte mode
154  CCIfHvx128<
155    CCIfType<[v32i32,v64i16,v128i8],
156      CCAssignToReg<[V0]>>>,
157  CCIfHvx128<
158    CCIfType<[v64i32,v128i16,v256i8],
159      CCAssignToReg<[W0]>>>,
160
161  CCDelegateTo<RetCC_Hexagon>
162]>;
163
164