1//! This module defines the different ffi_abi values for each platform.
2//!
3//! This module is set-up to define all the constants for each platform, but only export those which
4//! are actually relevant to the target arch. This is done as a compile check to ensure the code
5//! paths in less utilized architectures largely continue to compile.
6
7#![allow(unused)]
8
9/// From libffi:src/x86/ffitarget.h.
10/// See: <https://github.com/libffi/libffi/blob/369ef49f71186fc9d6ab15614488ad466fac3fc1/src/x86/ffitarget.h#L80>
11mod x86 {
12 pub mod x86_win64 {
13 use crate::ffi_abi;
14
15 pub const ffi_abi_FFI_FIRST_ABI: ffi_abi = 0;
16 pub const ffi_abi_FFI_WIN64: ffi_abi = 1;
17 pub const ffi_abi_FFI_GNUW64: ffi_abi = 2;
18 pub const ffi_abi_FFI_LAST_ABI: ffi_abi = 3;
19
20 mod gnu {
21 pub const ffi_abi_FFI_DEFAULT_ABI: crate::ffi_abi = super::ffi_abi_FFI_GNUW64;
22 }
23
24 mod msvc {
25 pub const ffi_abi_FFI_DEFAULT_ABI: crate::ffi_abi = super::ffi_abi_FFI_GNUW64;
26 }
27
28 #[cfg(target_env = "gnu")]
29 pub use gnu::*;
30 #[cfg(target_env = "msvc")]
31 pub use msvc::*;
32
33 // See: https://github.com/libffi/libffi/blob/0f2dd369cd5edcefad29b3fca4e1d08cb34f8f19/src/x86/ffitarget.h#L141
34 pub const FFI_TRAMPOLINE_SIZE: usize = 32;
35 pub const FFI_NATIVE_RAW_API: u32 = 0;
36 }
37
38 pub mod x86_64 {
39 use crate::ffi_abi;
40
41 pub const ffi_abi_FFI_FIRST_ABI: ffi_abi = 1;
42 pub const ffi_abi_FFI_UNIX64: ffi_abi = 2;
43 pub const ffi_abi_FFI_WIN64: ffi_abi = 3;
44 pub const ffi_abi_FFI_EFI64: ffi_abi = ffi_abi_FFI_WIN64;
45 pub const ffi_abi_FFI_GNUW64: ffi_abi = 4;
46 pub const ffi_abi_FFI_LAST_ABI: ffi_abi = 5;
47 pub const ffi_abi_FFI_DEFAULT_ABI: ffi_abi = ffi_abi_FFI_UNIX64;
48
49 // See: https://github.com/libffi/libffi/blob/0f2dd369cd5edcefad29b3fca4e1d08cb34f8f19/src/x86/ffitarget.h#L141
50 pub const FFI_TRAMPOLINE_SIZE: usize = 32;
51 pub const FFI_NATIVE_RAW_API: u32 = 0;
52 }
53
54 pub mod x86_win32 {
55 use crate::ffi_abi;
56
57 pub const ffi_abi_FFI_FIRST_ABI: ffi_abi = 0;
58 pub const ffi_abi_FFI_SYSV: ffi_abi = 1;
59 pub const ffi_abi_FFI_STDCALL: ffi_abi = 2;
60 pub const ffi_abi_FFI_THISCALL: ffi_abi = 3;
61 pub const ffi_abi_FFI_FASTCALL: ffi_abi = 4;
62 pub const ffi_abi_FFI_MS_CDECL: ffi_abi = 5;
63 pub const ffi_abi_FFI_PASCAL: ffi_abi = 6;
64 pub const ffi_abi_FFI_REGISTER: ffi_abi = 7;
65 pub const ffi_abi_FFI_LAST_ABI: ffi_abi = 8;
66 pub const ffi_abi_FFI_DEFAULT_ABI: ffi_abi = ffi_abi_FFI_MS_CDECL;
67
68 // See: https://github.com/libffi/libffi/blob/369ef49f71186fc9d6ab15614488ad466fac3fc1/src/x86/ffitarget.h#L137
69 pub const FFI_TRAMPOLINE_SIZE: usize = 12;
70 pub const FFI_NATIVE_RAW_API: u32 = 1;
71 }
72
73 pub mod x86 {
74 use crate::ffi_abi;
75
76 pub const ffi_abi_FFI_FIRST_ABI: ffi_abi = 0;
77 pub const ffi_abi_FFI_SYSV: ffi_abi = 1;
78 pub const ffi_abi_FFI_THISCALL: ffi_abi = 3;
79 pub const ffi_abi_FFI_FASTCALL: ffi_abi = 4;
80 pub const ffi_abi_FFI_STDCALL: ffi_abi = 5;
81 pub const ffi_abi_FFI_PASCAL: ffi_abi = 6;
82 pub const ffi_abi_FFI_REGISTER: ffi_abi = 7;
83 pub const ffi_abi_FFI_MS_CDECL: ffi_abi = 8;
84 pub const ffi_abi_FFI_LAST_ABI: ffi_abi = 9;
85 pub const ffi_abi_FFI_DEFAULT_ABI: ffi_abi = ffi_abi_FFI_SYSV;
86
87 // See: https://github.com/libffi/libffi/blob/369ef49f71186fc9d6ab15614488ad466fac3fc1/src/x86/ffitarget.h#L137
88 pub const FFI_TRAMPOLINE_SIZE: usize = 12;
89 pub const FFI_NATIVE_RAW_API: u32 = 1;
90 }
91
92 pub const FFI_GO_CLOSURES: u32 = 1;
93}
94
95#[cfg(all(target_arch = "x86_64", windows))]
96pub use x86::x86_win64::*;
97
98#[cfg(all(target_arch = "x86_64", unix))]
99pub use x86::x86_64::*;
100
101#[cfg(all(target_arch = "x86", windows))]
102pub use x86::x86_win32::*;
103
104#[cfg(all(target_arch = "x86", unix))]
105pub use x86::x86::*;
106
107/// From libffi:src/arm/ffitarget.h.
108/// See: <https://github.com/libffi/libffi/blob/db5706ff285c476aa3c0f811ff2b188319ac3ebe/src/arm/ffitarget.h>
109mod arm {
110 use crate::ffi_abi;
111
112 pub const ffi_abi_FFI_FIRST_ABI: ffi_abi = 0;
113 pub const ffi_abi_FFI_SYSV: ffi_abi = 1;
114 pub const ffi_abi_FFI_VFP: ffi_abi = 2;
115 pub const ffi_abi_FFI_LAST_ABI: ffi_abi = 3;
116 pub const ffi_abi_FFI_DEFAULT_ABI: ffi_abi = ffi_abi_FFI_SYSV;
117
118 // See: <https://github.com/libffi/libffi/blob/db5706ff285c476aa3c0f811ff2b188319ac3ebe/src/arm/ffitarget.h#L84>
119 pub const FFI_GO_CLOSURES: u32 = 1;
120 pub const FFI_TRAMPOLINE_SIZE: usize = 12;
121 pub const FFI_NATIVE_RAW_API: u32 = 0;
122}
123
124#[cfg(target_arch = "arm")]
125pub use arm::*;
126
127/// From libffi:src/aarch64/ffitarget.h.
128/// See: <https://github.com/libffi/libffi/blob/c2a6859012d928b67a83619bd5087674a96b9254/src/aarch64/ffitarget.h#L44>
129mod aarch64 {
130 use crate::ffi_abi;
131
132 pub const ffi_abi_FFI_FIRST_ABI: ffi_abi = 0;
133 pub const ffi_abi_FFI_SYSV: ffi_abi = 1;
134 pub const ffi_abi_FFI_LAST_ABI: ffi_abi = 2;
135 pub const ffi_abi_FFI_DEFAULT_ABI: ffi_abi = ffi_abi_FFI_SYSV;
136
137 pub const FFI_NATIVE_RAW_API: u32 = 0;
138
139 #[cfg(target_vendor = "apple")]
140 pub const FFI_TRAMPOLINE_SIZE: usize = 16;
141
142 #[cfg(not(target_vendor = "apple"))]
143 pub const FFI_TRAMPOLINE_SIZE: usize = 32;
144
145 // No GO_CLOSURES on iOS or Windows
146 #[cfg(not(any(target_os = "windows", target_vendor = "apple")))]
147 pub const FFI_GO_CLOSURES: u32 = 1;
148}
149
150#[cfg(target_arch = "aarch64")]
151pub use aarch64::*;
152
153/// From libffi:src/powerpc/ffitarget.h.
154/// See: <https://github.com/libffi/libffi/blob/73dd43afc8a447ba98ea02e9aad4c6898dc77fb0/src/powerpc/ffitarget.h#L60>
155mod powerpc {
156 pub mod powerpc {
157 use crate::ffi_abi;
158
159 pub const ffi_abi_FFI_FIRST_ABI: ffi_abi = 0;
160 pub const ffi_abi_FFI_SYSV_SOFT_FLOAT: ffi_abi = 0b000001;
161 pub const ffi_abi_FFI_SYSV_STRUCT_RET: ffi_abi = 0b000010;
162 pub const ffi_abi_FFI_SYSV_IBM_LONG_DOUBLE: ffi_abi = 0b000100;
163 pub const ffi_abi_FFI_SYSV: ffi_abi = 0b001000;
164 pub const ffi_abi_FFI_SYSV_LONG_DOUBLE_128: ffi_abi = 0b010000;
165
166 mod fprs {
167 pub const SOFT_FLOAT_FLAG: crate::ffi_abi = 0b0;
168 }
169
170 mod no_fprs {
171 pub const SOFT_FLOAT_FLAG: crate::ffi_abi = super::ffi_abi_FFI_SYSV_SOFT_FLOAT;
172 }
173
174 #[cfg(target_env = "gnuspe")]
175 use no_fprs::*;
176
177 #[cfg(not(target_feature = "gnuspe"))]
178 use fprs::*;
179
180 mod struct_ret {
181 pub const STRUCT_RET_FLAG: crate::ffi_abi = super::ffi_abi_FFI_SYSV_STRUCT_RET;
182 }
183
184 mod no_struct_ret {
185 pub const STRUCT_RET_FLAG: crate::ffi_abi = 0b0;
186 }
187
188 #[cfg(target_os = "netbsd")]
189 use struct_ret::*;
190
191 #[cfg(not(target_os = "netbsd"))]
192 use no_struct_ret::*;
193
194 mod long_double_64 {
195 pub const LONG_DOUBLE_128_FLAG: crate::ffi_abi = 0b0;
196 }
197
198 mod long_double_128 {
199 pub const LONG_DOUBLE_128_FLAG: crate::ffi_abi =
200 super::ffi_abi_FFI_SYSV_LONG_DOUBLE_128;
201 }
202
203 // IEEE128 is not supported on BSD or when targeting musl:
204 // https://github.com/rust-lang/llvm-project/blob/cb7f903994646c5b9223e0bb6cee3792190991f7/clang/lib/Basic/Targets/PPC.h#L379
205
206 #[cfg(any(target_os = "netbsd", target_os = "freebsd", target_env = "musl"))]
207 use long_double_64::*;
208
209 #[cfg(not(any(target_os = "netbsd", target_os = "freebsd", target_env = "musl")))]
210 use long_double_128::*;
211
212 pub const ffi_abi_FFI_DEFAULT_ABI: ffi_abi = ffi_abi_FFI_SYSV
213 | ffi_abi_FFI_SYSV_IBM_LONG_DOUBLE
214 | SOFT_FLOAT_FLAG
215 | STRUCT_RET_FLAG
216 | LONG_DOUBLE_128_FLAG;
217
218 pub const FFI_TRAMPOLINE_SIZE: usize = 40;
219 pub const FFI_NATIVE_RAW_API: u32 = 0;
220 pub const FFI_GO_CLOSURES: u32 = 1;
221 }
222
223 pub mod powerpc64 {
224 use crate::ffi_abi;
225
226 pub const ffi_abi_FFI_FIRST_ABI: ffi_abi = 0;
227 pub const ffi_abi_FFI_LINUX_STRUCT_ALIGN: ffi_abi = 0b000001;
228 pub const ffi_abi_FFI_LINUX_LONG_DOUBLE_128: ffi_abi = 0b000010;
229 pub const ffi_abi_FFI_LINUX_LONG_DOUBLE_IEEE128: ffi_abi = 0b000100;
230 pub const ffi_abi_FFI_LINUX: ffi_abi = 0b001000;
231
232 mod elfv1 {
233 pub const STRUCT_ALIGN_FLAG: crate::ffi_abi = 0b0;
234 pub const FFI_TRAMPOLINE_SIZE: usize = 24;
235 }
236
237 mod elfv2 {
238 pub const STRUCT_ALIGN_FLAG: crate::ffi_abi = super::ffi_abi_FFI_LINUX_STRUCT_ALIGN;
239 pub const FFI_TRAMPOLINE_SIZE: usize = 32;
240 }
241
242 // I think this should be something like `target_abi = "elf_v2"`, but that's not yet
243 // supported.
244 // Discussion: https://github.com/rust-lang/rust/issues/60617
245 // RFC: https://github.com/rust-lang/rfcs/pull/2992
246 //
247 // Instead, this is based on the current defaults at the time of this writing:
248 // https://github.com/rust-lang/rust/blob/50d2c3abd59af8cbed7e001b5b4e2f6a9a011112/src/librustc_target/abi/call/powerpc64.rs#L122
249
250 #[cfg(any(
251 // ELFv1 is the used for powerpc64 when not targeting musl
252 all(target_arch = "powerpc64", target_endian="big", not(target_env = "musl")),
253 // Use empty flags when targeting a non-PowerPC target, too, just so code compiles.
254 not(all(target_arch = "powerpc64", target_endian="little"))
255 ))]
256 mod elf {
257 pub use super::elfv1::*;
258 }
259
260 // ELFv2 is used for Little-Endian powerpc64 and with musl
261 #[cfg(any(
262 all(target_arch = "powerpc64", target_endian = "big", target_env = "musl"),
263 all(target_arch = "powerpc64", target_endian = "little")
264 ))]
265 mod elf {
266 pub use super::elfv2::*;
267 }
268
269 pub use elf::FFI_TRAMPOLINE_SIZE;
270 use elf::STRUCT_ALIGN_FLAG;
271
272 mod long_double_64 {
273 pub const LONG_DOUBLE_128_FLAG: crate::ffi_abi = 0b0;
274 }
275
276 mod long_double_128 {
277 pub const LONG_DOUBLE_128_FLAG: crate::ffi_abi =
278 super::ffi_abi_FFI_LINUX_LONG_DOUBLE_128;
279 }
280
281 // IEEE128 is not supported on BSD or when targeting musl:
282 // https://github.com/rust-lang/llvm-project/blob/cb7f903994646c5b9223e0bb6cee3792190991f7/clang/lib/Basic/Targets/PPC.h#L417
283
284 #[cfg(any(target_os = "netbsd", target_os = "freebsd", target_env = "musl"))]
285 use long_double_64::*;
286
287 #[cfg(not(any(target_os = "netbsd", target_os = "freebsd", target_env = "musl")))]
288 use long_double_128::*;
289
290 pub const ffi_abi_FFI_DEFAULT_ABI: ffi_abi =
291 ffi_abi_FFI_LINUX | STRUCT_ALIGN_FLAG | LONG_DOUBLE_128_FLAG;
292
293 pub const FFI_NATIVE_RAW_API: u32 = 0;
294 pub const FFI_GO_CLOSURES: u32 = 1;
295 }
296}
297
298#[cfg(target_arch = "powerpc")]
299pub use powerpc::powerpc::*;
300
301#[cfg(target_arch = "powerpc64")]
302pub use powerpc::powerpc64::*;
303
304/// From libffi:src/riscv/ffitarget.h
305/// See: <https://github.com/libffi/libffi/blob/4cb776bc8075332d2f3e59f51785d621fcda48f6/src/riscv/ffitarget.h>
306mod riscv {
307 use crate::ffi_abi;
308
309 pub const ffi_abi_FFI_FIRST_ABI: ffi_abi = 0;
310 pub const ffi_abi_FFI_SYSV: ffi_abi = 1;
311 pub const ffi_abi_FFI_UNUSED_1: ffi_abi = 2;
312 pub const ffi_abi_FFI_UNUSED_2: ffi_abi = 3;
313 pub const ffi_abi_FFI_UNUSED_3: ffi_abi = 4;
314 pub const ffi_abi_LAST_ABI: ffi_abi = 5;
315 pub const ffi_abi_FFI_DEFAULT_ABI: ffi_abi = ffi_abi_FFI_SYSV;
316
317 // See: <https://github.com/libffi/libffi/blob/4cb776bc8075332d2f3e59f51785d621fcda48f6/src/riscv/ffitarget.h#L63>
318 pub const FFI_GO_CLOSURES: u32 = 1;
319 pub const FFI_TRAMPOLINE_SIZE: usize = 24;
320 pub const FFI_NATIVE_RAW_API: u32 = 0;
321}
322
323#[cfg(target_arch = "riscv")]
324pub use riscv::*;
325
326#[cfg(target_arch = "riscv64")]
327pub use riscv::*;
328
329/// From libffi:src/s390/ffitarget.h
330/// See: <https://github.com/libffi/libffi/blob/c6dc125afba294b9b9613392c492ae18df3ede84/src/s390/ffitarget.h>
331mod s390x {
332 use crate::ffi_abi;
333
334 pub const ffi_abi_FFI_FIRST_ABI: ffi_abi = 0;
335 pub const ffi_abi_FFI_SYSV: ffi_abi = 1;
336 pub const ffi_abi_LAST_ABI: ffi_abi = 2;
337 pub const ffi_abi_FFI_DEFAULT_ABI: ffi_abi = ffi_abi_FFI_SYSV;
338
339 pub const FFI_GO_CLOSURES: u32 = 1;
340 pub const FFI_TRAMPOLINE_SIZE: usize = 32;
341 pub const FFI_NATIVE_RAW_API: u32 = 0;
342}
343
344#[cfg(target_arch = "s390x")]
345pub use s390x::*;
346
347/// From libffi:src/loongarch64/ffitarget.h.
348/// See: <https://github.com/libffi/libffi/blob/f24180be1367f942824365b131ae894b9c769c7d/src/loongarch64/ffitarget.h#L47>
349mod loongarch64 {
350 use crate::ffi_abi;
351
352 pub const ffi_abi_FFI_FIRST_ABI: ffi_abi = 0;
353 pub const ffi_abi_FFI_LP64S: ffi_abi = 1;
354 pub const ffi_abi_FFI_LP64F: ffi_abi = 2;
355 pub const ffi_abi_FFI_LP64D: ffi_abi = 3;
356 pub const ffi_abi_FFI_LAST_ABI: ffi_abi = 4;
357 pub const ffi_abi_FFI_DEFAULT_ABI: ffi_abi = ffi_abi_FFI_LP64D;
358
359 pub const FFI_GO_CLOSURES: u32 = 1;
360 pub const FFI_TRAMPOLINE_SIZE: usize = 24;
361 pub const FFI_NATIVE_RAW_API: u32 = 0;
362}
363
364#[cfg(target_arch = "loongarch64")]
365pub use loongarch64::*;
366