lamina_codegen/
target_support.rs1use lamina_platform::{TargetArchitecture, TargetOperatingSystem};
8
9pub fn is_assembly_emission_supported(arch: TargetArchitecture, os: TargetOperatingSystem) -> bool {
17 match arch {
18 TargetArchitecture::Nvptx64 => os == TargetOperatingSystem::Cuda,
19 TargetArchitecture::Amdgcn => os == TargetOperatingSystem::AmdHsa,
20 TargetArchitecture::X86_64 => os_supported_for_x86_64(os),
21 TargetArchitecture::Aarch64 => os_supported_for_aarch64(os),
22 #[cfg(feature = "nightly")]
23 TargetArchitecture::Arx64 => os_supported_for_arx64(os),
24 TargetArchitecture::Riscv32 | TargetArchitecture::Riscv64 => os_supported_for_riscv(os),
25 TargetArchitecture::LoongArch64 => os == TargetOperatingSystem::Linux,
26 TargetArchitecture::S390x => os == TargetOperatingSystem::Linux,
27 TargetArchitecture::Mips64 | TargetArchitecture::Mips64El => {
28 os == TargetOperatingSystem::Linux
29 }
30 TargetArchitecture::I686 => os == TargetOperatingSystem::Linux,
31 TargetArchitecture::Wasm32 => {
33 matches!(
34 os,
35 TargetOperatingSystem::Unknown
36 | TargetOperatingSystem::Linux
37 | TargetOperatingSystem::Wasi
38 )
39 }
40 TargetArchitecture::Wasm64 => {
41 matches!(
42 os,
43 TargetOperatingSystem::Unknown | TargetOperatingSystem::Linux
44 )
45 }
46 TargetArchitecture::Armv7 => os == TargetOperatingSystem::Linux,
47 TargetArchitecture::Thumbv6m | TargetArchitecture::Thumbv7m => {
48 matches!(
49 os,
50 TargetOperatingSystem::Unknown | TargetOperatingSystem::Linux
51 )
52 }
53 TargetArchitecture::PowerPC64 => {
54 matches!(
55 os,
56 TargetOperatingSystem::Linux | TargetOperatingSystem::Unknown
57 )
58 }
59 TargetArchitecture::PowerPC64Be => os == TargetOperatingSystem::Linux,
60 TargetArchitecture::Arm32 => false,
61 #[cfg(feature = "nightly")]
62 TargetArchitecture::Riscv128 | TargetArchitecture::Lisa => false,
63 }
64}
65
66fn os_supported_for_x86_64(os: TargetOperatingSystem) -> bool {
68 matches!(
69 os,
70 TargetOperatingSystem::Linux
71 | TargetOperatingSystem::Android
72 | TargetOperatingSystem::MacOS
73 | TargetOperatingSystem::IOS
74 | TargetOperatingSystem::TvOS
75 | TargetOperatingSystem::WatchOS
76 | TargetOperatingSystem::VisionOS
77 | TargetOperatingSystem::Windows
78 | TargetOperatingSystem::FreeBSD
79 | TargetOperatingSystem::OpenBSD
80 | TargetOperatingSystem::NetBSD
81 | TargetOperatingSystem::DragonFly
82 | TargetOperatingSystem::Redox
83 | TargetOperatingSystem::Unknown
84 )
85}
86
87fn os_supported_for_aarch64(os: TargetOperatingSystem) -> bool {
89 matches!(
90 os,
91 TargetOperatingSystem::Linux
92 | TargetOperatingSystem::Android
93 | TargetOperatingSystem::MacOS
94 | TargetOperatingSystem::IOS
95 | TargetOperatingSystem::TvOS
96 | TargetOperatingSystem::WatchOS
97 | TargetOperatingSystem::VisionOS
98 | TargetOperatingSystem::Windows
99 | TargetOperatingSystem::FreeBSD
100 | TargetOperatingSystem::OpenBSD
101 | TargetOperatingSystem::NetBSD
102 | TargetOperatingSystem::DragonFly
103 | TargetOperatingSystem::Redox
104 | TargetOperatingSystem::Unknown
105 )
106}
107
108#[cfg(feature = "nightly")]
110fn os_supported_for_arx64(os: TargetOperatingSystem) -> bool {
111 matches!(os, TargetOperatingSystem::Unknown)
112}
113
114fn os_supported_for_riscv(os: TargetOperatingSystem) -> bool {
116 matches!(
117 os,
118 TargetOperatingSystem::Linux
119 | TargetOperatingSystem::FreeBSD
120 | TargetOperatingSystem::OpenBSD
121 | TargetOperatingSystem::NetBSD
122 | TargetOperatingSystem::DragonFly
123 | TargetOperatingSystem::Unknown
124 )
125}
126
127pub fn supported_assembly_targets_hint() -> &'static str {
129 "Supported: x86_64 and aarch64 on Linux, Android, macOS, iOS, Windows, BSD, Redox and bare metal; \n riscv32/riscv64 on Linux, BSD and bare metal; i686, armv7, ppc64le, ppc64, s390x, mips64, mips64el \n and loongarch64 on Linux; thumbv6m/thumbv7m on Linux and bare metal; wasm32 on Linux, WASI and \n bare metal, wasm64 on Linux and bare metal; nvptx64 on CUDA and amdgcn on AMDHSA. \n Use lamina_platform::Target for cross-compilation."
130}
131
132pub fn os_uses_elf(os: TargetOperatingSystem) -> bool {
134 matches!(
135 os,
136 TargetOperatingSystem::Linux
137 | TargetOperatingSystem::Android
138 | TargetOperatingSystem::FreeBSD
139 | TargetOperatingSystem::OpenBSD
140 | TargetOperatingSystem::NetBSD
141 | TargetOperatingSystem::DragonFly
142 | TargetOperatingSystem::Redox
143 | TargetOperatingSystem::Horizon
144 | TargetOperatingSystem::Orbis
145 | TargetOperatingSystem::Prospero
146 )
147}
148
149pub fn os_uses_macho(os: TargetOperatingSystem) -> bool {
151 matches!(
152 os,
153 TargetOperatingSystem::MacOS
154 | TargetOperatingSystem::IOS
155 | TargetOperatingSystem::TvOS
156 | TargetOperatingSystem::WatchOS
157 | TargetOperatingSystem::VisionOS
158 )
159}
160
161pub fn os_uses_coff(os: TargetOperatingSystem) -> bool {
163 os == TargetOperatingSystem::Windows
164}
165
166#[cfg(test)]
167mod tests {
168 use super::*;
169
170 #[test]
171 fn test_x86_64_cross_platform() {
172 assert!(is_assembly_emission_supported(
173 TargetArchitecture::X86_64,
174 TargetOperatingSystem::Linux
175 ));
176 assert!(is_assembly_emission_supported(
177 TargetArchitecture::X86_64,
178 TargetOperatingSystem::Windows
179 ));
180 assert!(is_assembly_emission_supported(
181 TargetArchitecture::X86_64,
182 TargetOperatingSystem::MacOS
183 ));
184 assert!(is_assembly_emission_supported(
185 TargetArchitecture::X86_64,
186 TargetOperatingSystem::FreeBSD
187 ));
188 }
189
190 #[test]
191 fn test_aarch64_cross_platform() {
192 assert!(is_assembly_emission_supported(
193 TargetArchitecture::Aarch64,
194 TargetOperatingSystem::Linux
195 ));
196 assert!(is_assembly_emission_supported(
197 TargetArchitecture::Aarch64,
198 TargetOperatingSystem::MacOS
199 ));
200 }
201
202 #[test]
203 fn test_riscv_elf_like_only() {
204 assert!(is_assembly_emission_supported(
205 TargetArchitecture::Riscv64,
206 TargetOperatingSystem::Linux
207 ));
208 assert!(!is_assembly_emission_supported(
209 TargetArchitecture::Riscv64,
210 TargetOperatingSystem::Windows
211 ));
212 }
213
214 #[test]
215 fn test_wasm_limited_os() {
216 assert!(is_assembly_emission_supported(
217 TargetArchitecture::Wasm32,
218 TargetOperatingSystem::Unknown
219 ));
220 assert!(is_assembly_emission_supported(
221 TargetArchitecture::Wasm32,
222 TargetOperatingSystem::Wasi
223 ));
224 assert!(!is_assembly_emission_supported(
225 TargetArchitecture::Wasm64,
226 TargetOperatingSystem::Wasi
227 ));
228 assert!(!is_assembly_emission_supported(
229 TargetArchitecture::X86_64,
230 TargetOperatingSystem::Wasi
231 ));
232 }
233
234 #[test]
235 fn test_unknown_os_fallback() {
236 assert!(is_assembly_emission_supported(
237 TargetArchitecture::X86_64,
238 TargetOperatingSystem::Unknown
239 ));
240 assert!(is_assembly_emission_supported(
241 TargetArchitecture::Aarch64,
242 TargetOperatingSystem::Unknown
243 ));
244 }
245
246 #[test]
247 fn test_apple_mobile_assembly_supported() {
248 for os in [
249 TargetOperatingSystem::IOS,
250 TargetOperatingSystem::TvOS,
251 TargetOperatingSystem::WatchOS,
252 TargetOperatingSystem::VisionOS,
253 ] {
254 assert!(
255 is_assembly_emission_supported(TargetArchitecture::X86_64, os),
256 "{os}"
257 );
258 assert!(
259 is_assembly_emission_supported(TargetArchitecture::Aarch64, os),
260 "{os}"
261 );
262 }
263 }
264
265 #[test]
266 fn test_android_is_elf_and_assembly_supported() {
267 assert!(is_assembly_emission_supported(
268 TargetArchitecture::X86_64,
269 TargetOperatingSystem::Android
270 ));
271 assert!(is_assembly_emission_supported(
272 TargetArchitecture::Aarch64,
273 TargetOperatingSystem::Android
274 ));
275 assert!(os_uses_elf(TargetOperatingSystem::Android));
276 }
277
278 #[test]
279 fn test_apple_mobile_oses_use_macho() {
280 for os in [
281 TargetOperatingSystem::IOS,
282 TargetOperatingSystem::TvOS,
283 TargetOperatingSystem::WatchOS,
284 TargetOperatingSystem::VisionOS,
285 ] {
286 assert!(os_uses_macho(os), "{os} should use Mach-O");
287 assert!(!os_uses_elf(os), "{os} should not use ELF");
288 }
289 }
290
291 #[test]
292 fn test_unsupported_arch() {
293 assert!(!is_assembly_emission_supported(
294 TargetArchitecture::Arm32,
295 TargetOperatingSystem::Linux
296 ));
297 }
298
299 #[test]
300 fn test_powerpc64_assembly_supported() {
301 assert!(is_assembly_emission_supported(
302 TargetArchitecture::PowerPC64,
303 TargetOperatingSystem::Linux
304 ));
305 assert!(is_assembly_emission_supported(
306 TargetArchitecture::PowerPC64,
307 TargetOperatingSystem::Unknown
308 ));
309 assert!(is_assembly_emission_supported(
310 TargetArchitecture::PowerPC64Be,
311 TargetOperatingSystem::Linux
312 ));
313 assert!(!is_assembly_emission_supported(
314 TargetArchitecture::PowerPC64Be,
315 TargetOperatingSystem::Windows
316 ));
317 }
318
319 #[test]
320 fn test_os_uses_elf() {
321 assert!(os_uses_elf(TargetOperatingSystem::Linux));
322 assert!(os_uses_elf(TargetOperatingSystem::FreeBSD));
323 assert!(os_uses_elf(TargetOperatingSystem::Redox));
324 assert!(os_uses_elf(TargetOperatingSystem::Horizon));
325 assert!(os_uses_elf(TargetOperatingSystem::Orbis));
326 assert!(os_uses_elf(TargetOperatingSystem::Prospero));
327 assert!(!os_uses_elf(TargetOperatingSystem::MacOS));
328 assert!(!os_uses_elf(TargetOperatingSystem::Windows));
329 }
330}