@@ -18,6 +18,164 @@ class CCIfSubtarget<string F, CCAction A>
18
18
"(State.getMachineFunction().getSubtarget()).", F),
19
19
A>;
20
20
21
+ // Register classes for RegCall
22
+ class RC_X86_RegCall {
23
+ list<Register> GPR_8 = [];
24
+ list<Register> GPR_16 = [];
25
+ list<Register> GPR_32 = [];
26
+ list<Register> GPR_64 = [];
27
+ list<Register> XMM = [];
28
+ list<Register> YMM = [];
29
+ list<Register> ZMM = [];
30
+ }
31
+
32
+ // RegCall register classes for 32 bits
33
+ def RC_X86_32_RegCall : RC_X86_RegCall {
34
+ let GPR_8 = [AL, CL, DL, DIL, SIL];
35
+ let GPR_16 = [AX, CX, DX, DI, SI];
36
+ let GPR_32 = [EAX, ECX, EDX, EDI, ESI];
37
+ let GPR_64 = [RAX]; ///< Not actually used, but AssignToReg can't handle []
38
+ ///< \todo Fix AssignToReg to enable empty lists
39
+ let XMM = [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7];
40
+ let YMM = [YMM0, YMM1, YMM2, YMM3, YMM4, YMM5, YMM6, YMM7];
41
+ let ZMM = [ZMM0, ZMM1, ZMM2, ZMM3, ZMM4, ZMM5, ZMM6, ZMM7];
42
+ }
43
+
44
+ class RC_X86_64_RegCall : RC_X86_RegCall {
45
+ let XMM = [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
46
+ XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15];
47
+ let YMM = [YMM0, YMM1, YMM2, YMM3, YMM4, YMM5, YMM6, YMM7,
48
+ YMM8, YMM9, YMM10, YMM11, YMM12, YMM13, YMM14, YMM15];
49
+ let ZMM = [ZMM0, ZMM1, ZMM2, ZMM3, ZMM4, ZMM5, ZMM6, ZMM7,
50
+ ZMM8, ZMM9, ZMM10, ZMM11, ZMM12, ZMM13, ZMM14, ZMM15];
51
+ }
52
+
53
+ def RC_X86_64_RegCall_Win : RC_X86_64_RegCall {
54
+ let GPR_8 = [AL, CL, DL, DIL, SIL, R8B, R9B, R10B, R11B, R12B, R14B, R15B];
55
+ let GPR_16 = [AX, CX, DX, DI, SI, R8W, R9W, R10W, R11W, R12W, R14W, R15W];
56
+ let GPR_32 = [EAX, ECX, EDX, EDI, ESI, R8D, R9D, R10D, R11D, R12D, R14D, R15D];
57
+ let GPR_64 = [RAX, RCX, RDX, RDI, RSI, R8, R9, R10, R11, R12, R14, R15];
58
+ }
59
+
60
+ def RC_X86_64_RegCall_SysV : RC_X86_64_RegCall {
61
+ let GPR_8 = [AL, CL, DL, DIL, SIL, R8B, R9B, R12B, R13B, R14B, R15B];
62
+ let GPR_16 = [AX, CX, DX, DI, SI, R8W, R9W, R12W, R13W, R14W, R15W];
63
+ let GPR_32 = [EAX, ECX, EDX, EDI, ESI, R8D, R9D, R12D, R13D, R14D, R15D];
64
+ let GPR_64 = [RAX, RCX, RDX, RDI, RSI, R8, R9, R12, R13, R14, R15];
65
+ }
66
+
67
+ // X86-64 Intel regcall calling convention.
68
+ multiclass X86_RegCall_base<RC_X86_RegCall RC> {
69
+ def CC_#NAME : CallingConv<[
70
+ // Handles byval parameters.
71
+ CCIfSubtarget<"is64Bit()", CCIfByVal<CCPassByVal<8, 8>>>,
72
+ CCIfByVal<CCPassByVal<4, 4>>,
73
+
74
+ // Promote i1/i8/i16 arguments to i32.
75
+ CCIfType<[i1, i8, i16], CCPromoteToType<i32>>,
76
+
77
+ // bool, char, int, enum, long, pointer --> GPR
78
+ CCIfType<[i32], CCAssignToReg<RC.GPR_32>>,
79
+
80
+ // TODO: Handle the case of mask types (v*i1)
81
+ // TODO: Handle the case of 32 bit machine with v64i1 argument
82
+ // (split to 2 registers)
83
+ CCIfType<[v8i1, v16i1, v32i1, v64i1], CCCustom<"CC_X86_RegCall_Error">>,
84
+
85
+ // long long, __int64 --> GPR
86
+ CCIfType<[i64], CCAssignToReg<RC.GPR_64>>,
87
+
88
+ // TODO: Handle the case of long double (f80)
89
+ CCIfType<[f80], CCCustom<"CC_X86_RegCall_Error">>,
90
+
91
+ // float, double, float128 --> XMM
92
+ // In the case of SSE disabled --> save to stack
93
+ CCIfType<[f32, f64, f128],
94
+ CCIfSubtarget<"hasSSE1()", CCAssignToReg<RC.XMM>>>,
95
+
96
+ // __m128, __m128i, __m128d --> XMM
97
+ // In the case of SSE disabled --> save to stack
98
+ CCIfType<[v16i8, v8i16, v4i32, v2i64, v4f32, v2f64],
99
+ CCIfSubtarget<"hasSSE1()", CCAssignToReg<RC.XMM>>>,
100
+
101
+ // __m256, __m256i, __m256d --> YMM
102
+ // In the case of SSE disabled --> save to stack
103
+ CCIfType<[v32i8, v16i16, v8i32, v4i64, v8f32, v4f64],
104
+ CCIfSubtarget<"hasAVX()", CCAssignToReg<RC.YMM>>>,
105
+
106
+ // __m512, __m512i, __m512d --> ZMM
107
+ // In the case of SSE disabled --> save to stack
108
+ CCIfType<[v64i8, v32i16, v16i32, v8i64, v16f32, v8f64],
109
+ CCIfSubtarget<"hasAVX512()",CCAssignToReg<RC.ZMM>>>,
110
+
111
+ // If no register was found -> assign to stack
112
+
113
+ // In 64 bit, assign 64/32 bit values to 8 byte stack
114
+ CCIfSubtarget<"is64Bit()", CCIfType<[i32, i64, f32, f64],
115
+ CCAssignToStack<8, 8>>>,
116
+
117
+ // In 32 bit, assign 64/32 bit values to 8/4 byte stack
118
+ CCIfType<[i32, f32], CCAssignToStack<4, 4>>,
119
+ CCIfType<[f64], CCAssignToStack<8, 4>>,
120
+
121
+ // MMX type gets 8 byte slot in stack , while alignment depends on target
122
+ CCIfSubtarget<"is64Bit()", CCIfType<[x86mmx], CCAssignToStack<8, 8>>>,
123
+ CCIfType<[x86mmx], CCAssignToStack<8, 4>>,
124
+
125
+ // float 128 get stack slots whose size and alignment depends
126
+ // on the subtarget.
127
+ CCIfType<[f128], CCAssignToStack<0, 0>>,
128
+
129
+ // Vectors get 16-byte stack slots that are 16-byte aligned.
130
+ CCIfType<[v16i8, v8i16, v4i32, v2i64, v4f32, v2f64],
131
+ CCAssignToStack<16, 16>>,
132
+
133
+ // 256-bit vectors get 32-byte stack slots that are 32-byte aligned.
134
+ CCIfType<[v32i8, v16i16, v8i32, v4i64, v8f32, v4f64],
135
+ CCAssignToStack<32, 32>>,
136
+
137
+ // 512-bit vectors get 64-byte stack slots that are 64-byte aligned.
138
+ CCIfType<[v16i32, v8i64, v16f32, v8f64], CCAssignToStack<64, 64>>
139
+ ]>;
140
+
141
+ def RetCC_#NAME : CallingConv<[
142
+ // Promote i1 arguments to i8.
143
+ CCIfType<[i1], CCPromoteToType<i8>>,
144
+
145
+ // bool, char, int, enum, long, pointer --> GPR
146
+ CCIfType<[i8], CCAssignToReg<RC.GPR_8>>,
147
+ CCIfType<[i16], CCAssignToReg<RC.GPR_16>>,
148
+ CCIfType<[i32], CCAssignToReg<RC.GPR_32>>,
149
+
150
+ // TODO: Handle the case of mask types (v*i1)
151
+ // TODO: Handle the case of 32 bit machine with v64i1 argument
152
+ // (split to 2 registers)
153
+ CCIfType<[v8i1, v16i1, v32i1, v64i1], CCCustom<"CC_X86_RegCall_Error">>,
154
+
155
+ // long long, __int64 --> GPR
156
+ CCIfType<[i64], CCAssignToReg<RC.GPR_64>>,
157
+
158
+ // long double --> FP
159
+ CCIfType<[f80], CCAssignToReg<[FP0]>>,
160
+
161
+ // float, double, float128 --> XMM
162
+ CCIfType<[f32, f64, f128],
163
+ CCIfSubtarget<"hasSSE1()", CCAssignToReg<RC.XMM>>>,
164
+
165
+ // __m128, __m128i, __m128d --> XMM
166
+ CCIfType<[v16i8, v8i16, v4i32, v2i64, v4f32, v2f64],
167
+ CCIfSubtarget<"hasSSE1()", CCAssignToReg<RC.XMM>>>,
168
+
169
+ // __m256, __m256i, __m256d --> YMM
170
+ CCIfType<[v32i8, v16i16, v8i32, v4i64, v8f32, v4f64],
171
+ CCIfSubtarget<"hasAVX()", CCAssignToReg<RC.YMM>>>,
172
+
173
+ // __m512, __m512i, __m512d --> ZMM
174
+ CCIfType<[v64i8, v32i16, v16i32, v8i64, v16f32, v8f64],
175
+ CCIfSubtarget<"hasAVX512()", CCAssignToReg<RC.ZMM>>>
176
+ ]>;
177
+ }
178
+
21
179
//===----------------------------------------------------------------------===//
22
180
// Return Value Calling Conventions
23
181
//===----------------------------------------------------------------------===//
@@ -237,13 +395,22 @@ def RetCC_X86_64_HHVM: CallingConv<[
237
395
RAX, R10, R11, R13, R14, R15]>>
238
396
]>;
239
397
398
+
399
+ defm X86_32_RegCall :
400
+ X86_RegCall_base<RC_X86_32_RegCall>;
401
+ defm X86_Win64_RegCall :
402
+ X86_RegCall_base<RC_X86_64_RegCall_Win>;
403
+ defm X86_SysV64_RegCall :
404
+ X86_RegCall_base<RC_X86_64_RegCall_SysV>;
405
+
240
406
// This is the root return-value convention for the X86-32 backend.
241
407
def RetCC_X86_32 : CallingConv<[
242
408
// If FastCC, use RetCC_X86_32_Fast.
243
409
CCIfCC<"CallingConv::Fast", CCDelegateTo<RetCC_X86_32_Fast>>,
244
410
// If HiPE, use RetCC_X86_32_HiPE.
245
411
CCIfCC<"CallingConv::HiPE", CCDelegateTo<RetCC_X86_32_HiPE>>,
246
412
CCIfCC<"CallingConv::X86_VectorCall", CCDelegateTo<RetCC_X86_32_VectorCall>>,
413
+ CCIfCC<"CallingConv::X86_RegCall", CCDelegateTo<RetCC_X86_32_RegCall>>,
247
414
248
415
// Otherwise, use RetCC_X86_32_C.
249
416
CCDelegateTo<RetCC_X86_32_C>
@@ -268,6 +435,11 @@ def RetCC_X86_64 : CallingConv<[
268
435
// Handle HHVM calls.
269
436
CCIfCC<"CallingConv::HHVM", CCDelegateTo<RetCC_X86_64_HHVM>>,
270
437
438
+ CCIfCC<"CallingConv::X86_RegCall",
439
+ CCIfSubtarget<"isTargetWin64()",
440
+ CCDelegateTo<RetCC_X86_Win64_RegCall>>>,
441
+ CCIfCC<"CallingConv::X86_RegCall", CCDelegateTo<RetCC_X86_SysV64_RegCall>>,
442
+
271
443
// Mingw64 and native Win64 use Win64 CC
272
444
CCIfSubtarget<"isTargetWin64()", CCDelegateTo<RetCC_X86_Win64_C>>,
273
445
@@ -817,6 +989,7 @@ def CC_X86_32 : CallingConv<[
817
989
CCIfCC<"CallingConv::Fast", CCDelegateTo<CC_X86_32_FastCC>>,
818
990
CCIfCC<"CallingConv::GHC", CCDelegateTo<CC_X86_32_GHC>>,
819
991
CCIfCC<"CallingConv::HiPE", CCDelegateTo<CC_X86_32_HiPE>>,
992
+ CCIfCC<"CallingConv::X86_RegCall", CCDelegateTo<CC_X86_32_RegCall>>,
820
993
821
994
// Otherwise, drop to normal X86-32 CC
822
995
CCDelegateTo<CC_X86_32_C>
@@ -833,6 +1006,9 @@ def CC_X86_64 : CallingConv<[
833
1006
CCIfCC<"CallingConv::X86_VectorCall", CCDelegateTo<CC_X86_Win64_VectorCall>>,
834
1007
CCIfCC<"CallingConv::HHVM", CCDelegateTo<CC_X86_64_HHVM>>,
835
1008
CCIfCC<"CallingConv::HHVM_C", CCDelegateTo<CC_X86_64_HHVM_C>>,
1009
+ CCIfCC<"CallingConv::X86_RegCall",
1010
+ CCIfSubtarget<"isTargetWin64()", CCDelegateTo<CC_X86_Win64_RegCall>>>,
1011
+ CCIfCC<"CallingConv::X86_RegCall", CCDelegateTo<CC_X86_SysV64_RegCall>>,
836
1012
CCIfCC<"CallingConv::X86_INTR", CCDelegateTo<CC_X86_64_Intr>>,
837
1013
838
1014
// Mingw64 and native Win64 use Win64 CC
@@ -936,3 +1112,17 @@ def CSR_64_Intel_OCL_BI_AVX512 : CalleeSavedRegs<(add RBX, RDI, RSI, R14, R15,
936
1112
937
1113
// Only R12 is preserved for PHP calls in HHVM.
938
1114
def CSR_64_HHVM : CalleeSavedRegs<(add R12)>;
1115
+
1116
+ // Register calling convention preserves few GPR and XMM8-15
1117
+ def CSR_32_RegCall_NoSSE : CalleeSavedRegs<(add ESI, EDI, EBX, EBP, ESP)>;
1118
+ def CSR_32_RegCall : CalleeSavedRegs<(add CSR_32_RegCall_NoSSE,
1119
+ (sequence "XMM%u", 4, 7))>;
1120
+ def CSR_Win64_RegCall_NoSSE : CalleeSavedRegs<(add RBX, RBP, RSP,
1121
+ (sequence "R%u", 10, 15))>;
1122
+ def CSR_Win64_RegCall : CalleeSavedRegs<(add CSR_Win64_RegCall_NoSSE,
1123
+ (sequence "XMM%u", 8, 15))>;
1124
+ def CSR_SysV64_RegCall_NoSSE : CalleeSavedRegs<(add RBX, RBP, RSP,
1125
+ (sequence "R%u", 12, 15))>;
1126
+ def CSR_SysV64_RegCall : CalleeSavedRegs<(add CSR_SysV64_RegCall_NoSSE,
1127
+ (sequence "XMM%u", 8, 15))>;
1128
+
0 commit comments