diff --git a/Cargo.lock b/Cargo.lock index 48d99d608ae..af1a36a1a31 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3605,15 +3605,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" -[[package]] -name = "object" -version = "0.28.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e42c982f2d955fac81dd7e1d0e1426a7d702acd9c98d19ab01083a6a0328c424" -dependencies = [ - "memchr", -] - [[package]] name = "object" version = "0.29.0" @@ -7287,7 +7278,7 @@ dependencies = [ "itertools 0.10.5", "lazy_static", "libc", - "object 0.28.4", + "object 0.30.4", "rayon", "regex", "rustc_version 0.4.1", diff --git a/Makefile b/Makefile index 03d5f4bcdeb..e527f883c0e 100644 --- a/Makefile +++ b/Makefile @@ -18,15 +18,15 @@ SHELL=/usr/bin/env bash # # Here is what works and what doesn't: # -# * Cranelift works everywhere, +# * Cranelift works everywhere except */`loongarch64`, # # * LLVM works on Linux+Darwin/`amd64`, -# and linux+`aarch64`, linux+`riscv` +# and linux+`aarch64`, linux+`riscv`, linux+`loongarch64` # but it doesn't work on Darwin/`aarch64` or Windows/`aarch64`. # # * Singlepass works on Linux+Darwin+Windows/`amd64`, # and Linux+Darwin/`aarch64` -# it doesn't work on */`riscv`. +# it doesn't work on */`riscv` or */`loongarch64`. # # * Windows isn't tested on `aarch64`, that's why we consider it's not # working, but it might possibly be. @@ -48,6 +48,7 @@ IS_WINDOWS := 0 IS_AMD64 := 0 IS_AARCH64 := 0 IS_RISCV64 := 0 +IS_LOONGARCH64 := 0 # Test Windows apart because it doesn't support `uname -s`. ifeq ($(OS), Windows_NT) @@ -80,11 +81,13 @@ else IS_AARCH64 := 1 else ifneq (, $(filter $(uname), riscv64)) IS_RISCV64 := 1 + else ifneq (, $(filter $(uname), loongarch64)) + IS_LOONGARCH64 := 1 else # We use spaces instead of tabs to indent `$(error)` # otherwise it's considered as a command outside a # target and it will fail. - $(error Unrecognized architecture, expect `x86_64`, `aarch64`, `arm64`, 'riscv64') + $(error Unrecognized architecture, expect `x86_64`, `aarch64`, `arm64`, 'riscv64', 'loongarch64') endif # Libc @@ -241,6 +244,8 @@ ifeq ($(ENABLE_LLVM), 1) compilers_engines += llvm-universal else ifeq ($(IS_RISCV64), 1) compilers_engines += llvm-universal + else ifeq ($(IS_LOONGARCH64), 1) + compilers_engines += llvm-universal endif endif endif diff --git a/lib/cli/Cargo.toml b/lib/cli/Cargo.toml index 6736634fea8..47541ff02fa 100644 --- a/lib/cli/Cargo.toml +++ b/lib/cli/Cargo.toml @@ -252,7 +252,7 @@ clap = { version = "4.4.0", default-features = false, features = [ "env", ] } -[target.'cfg(not(target_arch = "riscv64"))'.dependencies] +[target.'cfg(not(any(target_arch = "riscv64", target_arch = "loongarch64")))'.dependencies] reqwest = { workspace = true, default-features = false, features = [ "rustls-tls", "json", @@ -260,13 +260,14 @@ reqwest = { workspace = true, default-features = false, features = [ "gzip", ] } -[target.'cfg(target_arch = "riscv64")'.dependencies] +[target.'cfg(any(target_arch = "riscv64", target_arch = "loongarch64"))'.dependencies] reqwest = { workspace = true, default-features = false, features = [ "native-tls", "json", "multipart", ] } + [build-dependencies] chrono = { version = "^0.4", default-features = false, features = [ "std", diff --git a/lib/compiler-llvm/Cargo.toml b/lib/compiler-llvm/Cargo.toml index 98a1e84ac48..c172303a0d4 100644 --- a/lib/compiler-llvm/Cargo.toml +++ b/lib/compiler-llvm/Cargo.toml @@ -21,7 +21,7 @@ wasmer-vm = { path = "../vm", version = "=5.0.0-rc.1" } wasmer-types = { path = "../types", version = "=5.0.0-rc.1" } target-lexicon = { version = "0.12.2", default-features = false } smallvec = "1.6" -object = { version = "0.28.3", default-features = false, features = ["read"] } +object = { version = "0.30.3", default-features = false, features = ["read"] } libc.workspace = true byteorder = "1" itertools = "0.10" @@ -31,7 +31,13 @@ rayon = "1.5" package = "inkwell" version = "0.5.0" default-features = false -features = ["llvm18-0-prefer-static", "target-x86", "target-aarch64", "target-riscv"] +features = [ + "llvm18-0-prefer-static", + "target-x86", + "target-aarch64", + "target-riscv", + "target-loongarch", +] [build-dependencies] cc = "1.0" diff --git a/lib/compiler-llvm/src/config.rs b/lib/compiler-llvm/src/config.rs index 9d00085a544..5d76872ec46 100644 --- a/lib/compiler-llvm/src/config.rs +++ b/lib/compiler-llvm/src/config.rs @@ -171,6 +171,16 @@ impl LLVM { info: true, machine_code: true, }), + Architecture::LoongArch64 => { + InkwellTarget::initialize_loongarch(&InitializationConfig { + asm_parser: true, + asm_printer: true, + base: true, + disassembler: true, + info: true, + machine_code: true, + }) + } // Architecture::Arm(_) => InkwellTarget::initialize_arm(&InitializationConfig { // asm_parser: true, // asm_printer: true, @@ -197,10 +207,12 @@ impl LLVM { &target_triple, match triple.architecture { Architecture::Riscv64(_) => "generic-rv64", + Architecture::LoongArch64 => "generic-la64", _ => "generic", }, match triple.architecture { Architecture::Riscv64(_) => "+m,+a,+c,+d,+f", + Architecture::LoongArch64 => "+f,+d", _ => &llvm_cpu_features, }, self.opt_level, diff --git a/lib/compiler-llvm/src/object_file.rs b/lib/compiler-llvm/src/object_file.rs index de8702b44c9..06b196326ed 100644 --- a/lib/compiler-llvm/src/object_file.rs +++ b/lib/compiler-llvm/src/object_file.rs @@ -231,6 +231,26 @@ where object::RelocationKind::Elf(object::elf::R_RISCV_PCREL_LO12_I), 0, ) => RelocationKind::RiscvPCRelLo12I, + ( + object::Architecture::LoongArch64, + object::RelocationKind::Elf(object::elf::R_LARCH_ABS_HI20), + 0, + ) => RelocationKind::LArchAbsHi20, + ( + object::Architecture::LoongArch64, + object::RelocationKind::Elf(object::elf::R_LARCH_ABS_LO12), + 0, + ) => RelocationKind::LArchAbsLo12, + ( + object::Architecture::LoongArch64, + object::RelocationKind::Elf(object::elf::R_LARCH_ABS64_HI12), + 0, + ) => RelocationKind::LArchAbs64Hi12, + ( + object::Architecture::LoongArch64, + object::RelocationKind::Elf(object::elf::R_LARCH_ABS64_LO20), + 0, + ) => RelocationKind::LArchAbs64Lo20, _ => { return Err(CompileError::Codegen(format!( "unknown relocation {:?}", diff --git a/lib/compiler/src/artifact_builders/trampoline.rs b/lib/compiler/src/artifact_builders/trampoline.rs index 387b62608a2..3fbfa245a9e 100644 --- a/lib/compiler/src/artifact_builders/trampoline.rs +++ b/lib/compiler/src/artifact_builders/trampoline.rs @@ -36,6 +36,15 @@ const RISCV64_TRAMPOLINE: [u8; 24] = [ 0, 0, 0, 0, ]; +// PCADDI r12, 0 0c 00 00 18 +// LD.D r12, r12, 16 8c 41 c0 28 +// JR r12 80 01 00 4c [00 00 00 00] +// JMPADDR 00 00 00 00 00 00 00 00 +const LOONGARCH64_TRAMPOLINE: [u8; 24] = [ + 0x0c, 0x00, 0x00, 0x0c, 0x8c, 0x41, 0xc0, 0x28, 0x80, 0x01, 0x00, 0x4c, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, +]; + fn make_trampoline( target: &Target, libcall: LibCall, @@ -70,6 +79,15 @@ fn make_trampoline( addend: 0, }); } + Architecture::LoongArch64 => { + code.extend(LOONGARCH64_TRAMPOLINE); + relocations.push(Relocation { + kind: RelocationKind::Abs8, + reloc_target: RelocationTarget::LibCall(libcall), + offset: code.len() as u32 - 8, + addend: 0, + }); + } arch => panic!("Unsupported architecture: {}", arch), }; } @@ -80,6 +98,7 @@ pub fn libcall_trampoline_len(target: &Target) -> usize { Architecture::Aarch64(_) => AARCH64_TRAMPOLINE.len(), Architecture::X86_64 => X86_64_TRAMPOLINE.len(), Architecture::Riscv64(_) => RISCV64_TRAMPOLINE.len(), + Architecture::LoongArch64 => LOONGARCH64_TRAMPOLINE.len(), arch => panic!("Unsupported architecture: {}", arch), } } diff --git a/lib/compiler/src/engine/link.rs b/lib/compiler/src/engine/link.rs index 92a0357be90..a3fc64dd2da 100644 --- a/lib/compiler/src/engine/link.rs +++ b/lib/compiler/src/engine/link.rs @@ -122,6 +122,30 @@ fn apply_relocation( | read_unaligned(reloc_address as *mut u64); write_unaligned(reloc_address as *mut u64, reloc_delta); }, + RelocationKind::LArchAbsHi20 => unsafe { + let (reloc_address, reloc_abs) = r.for_address(body, target_func_address as u64); + let reloc_abs = ((((reloc_abs >> 12) & 0xfffff) as u32) << 5) + | read_unaligned(reloc_address as *mut u32); + write_unaligned(reloc_address as *mut u32, reloc_abs); + }, + RelocationKind::LArchAbsLo12 => unsafe { + let (reloc_address, reloc_abs) = r.for_address(body, target_func_address as u64); + let reloc_abs = + (((reloc_abs & 0xfff) as u32) << 10) | read_unaligned(reloc_address as *mut u32); + write_unaligned(reloc_address as *mut u32, reloc_abs); + }, + RelocationKind::LArchAbs64Hi12 => unsafe { + let (reloc_address, reloc_abs) = r.for_address(body, target_func_address as u64); + let reloc_abs = ((((reloc_abs >> 52) & 0xfff) as u32) << 10) + | read_unaligned(reloc_address as *mut u32); + write_unaligned(reloc_address as *mut u32, reloc_abs); + }, + RelocationKind::LArchAbs64Lo20 => unsafe { + let (reloc_address, reloc_abs) = r.for_address(body, target_func_address as u64); + let reloc_abs = ((((reloc_abs >> 32) & 0xfffff) as u32) << 5) + | read_unaligned(reloc_address as *mut u32); + write_unaligned(reloc_address as *mut u32, reloc_abs); + }, kind => panic!( "Relocation kind unsupported in the current architecture {}", kind diff --git a/lib/object/src/module.rs b/lib/object/src/module.rs index 333980e30d5..af1017b13b7 100644 --- a/lib/object/src/module.rs +++ b/lib/object/src/module.rs @@ -47,6 +47,7 @@ pub fn get_object_for_target(triple: &Triple) -> Result { Architecture::X86_64 => object::Architecture::X86_64, Architecture::Aarch64(_) => object::Architecture::Aarch64, Architecture::Riscv64(_) => object::Architecture::Riscv64, + Architecture::LoongArch64 => object::Architecture::LoongArch64, architecture => { return Err(ObjectError::UnsupportedArchitecture(format!( "{}", diff --git a/lib/types/src/compilation/relocation.rs b/lib/types/src/compilation/relocation.rs index 58d91255da8..54060c9f6f2 100644 --- a/lib/types/src/compilation/relocation.rs +++ b/lib/types/src/compilation/relocation.rs @@ -64,6 +64,14 @@ pub enum RelocationKind { RiscvPCRelLo12I, /// RISC-V call target RiscvCall, + /// LoongArch absolute high 20bit + LArchAbsHi20, + /// LoongArch absolute low 12bit + LArchAbsLo12, + /// LoongArch absolute high 12bit + LArchAbs64Hi12, + /// LoongArch absolute low 20bit + LArchAbs64Lo20, /// Elf x86_64 32 bit signed PC relative offset to two GOT entries for GD symbol. ElfX86_64TlsGd, // /// Mach-O x86_64 32 bit signed PC relative offset to a `__thread_vars` entry. @@ -90,6 +98,10 @@ impl fmt::Display for RelocationKind { Self::ElfX86_64TlsGd => write!(f, "ElfX86_64TlsGd"), Self::RiscvPCRelHi20 => write!(f, "RiscvPCRelHi20"), Self::RiscvPCRelLo12I => write!(f, "RiscvPCRelLo12I"), + Self::LArchAbsHi20 => write!(f, "LArchAbsHi20"), + Self::LArchAbsLo12 => write!(f, "LArchAbsLo12"), + Self::LArchAbs64Hi12 => write!(f, "LArchAbs64Hi12"), + Self::LArchAbs64Lo20 => write!(f, "LArchAbs64Lo20"), // Self::MachOX86_64Tlv => write!(f, "MachOX86_64Tlv"), } } diff --git a/lib/vm/src/trap/traphandlers.rs b/lib/vm/src/trap/traphandlers.rs index fdb097f7564..43f0453733e 100644 --- a/lib/vm/src/trap/traphandlers.rs +++ b/lib/vm/src/trap/traphandlers.rs @@ -341,6 +341,9 @@ cfg_if::cfg_if! { } else if #[cfg(all(target_os = "freebsd", target_arch = "aarch64"))] { pc = context.uc_mcontext.mc_gpregs.gp_elr as usize; sp = context.uc_mcontext.mc_gpregs.gp_sp as usize; + } else if #[cfg(all(target_os = "linux", target_arch = "loongarch64"))] { + pc = context.uc_mcontext.__gregs[1] as usize; + sp = context.uc_mcontext.__gregs[3] as usize; } else { compile_error!("Unsupported platform"); } @@ -461,6 +464,14 @@ cfg_if::cfg_if! { context.uc_mcontext.mc_gpregs.gp_x[1] = x1 as libc::register_t; context.uc_mcontext.mc_gpregs.gp_x[29] = x29 as libc::register_t; context.uc_mcontext.mc_gpregs.gp_x[30] = lr as libc::register_t; + } else if #[cfg(all(target_os = "linux", target_arch = "loongarch64"))] { + let TrapHandlerRegs { pc, sp, a0, a1, fp, ra } = regs; + context.uc_mcontext.__pc = pc; + context.uc_mcontext.__gregs[1] = ra; + context.uc_mcontext.__gregs[3] = sp; + context.uc_mcontext.__gregs[4] = a0; + context.uc_mcontext.__gregs[5] = a1; + context.uc_mcontext.__gregs[22] = fp; } else { compile_error!("Unsupported platform"); } diff --git a/lib/wasix/Cargo.toml b/lib/wasix/Cargo.toml index c673407c275..f318344c2a4 100644 --- a/lib/wasix/Cargo.toml +++ b/lib/wasix/Cargo.toml @@ -41,7 +41,11 @@ getrandom = "0.2" typetag = { version = "0.1", optional = true } serde = { version = "1.0", default-features = false, features = ["derive"] } bincode = { version = "1.3" } -chrono = { version = "^0.4.31", default-features = false, features = [ "wasmbind", "std", "clock" ], optional = true } +chrono = { version = "^0.4.31", default-features = false, features = [ + "wasmbind", + "std", + "clock", +], optional = true } derivative = { version = "^2" } bytes = "1" anyhow = { version = "1.0.66" } @@ -51,12 +55,12 @@ waker-fn = { version = "1.1" } cooked-waker = "^5" rand = "0.8" tokio = { workspace = true, features = [ - "sync", - "macros", - "time", - "rt", + "sync", + "macros", + "time", + "rt", ], default-features = false } -tokio-stream = { version = "0.1", features = [ "sync" ] } +tokio-stream = { version = "0.1", features = ["sync"] } futures = { version = "0.3" } # used by feature='os' async-trait = { version = "^0.1" } @@ -76,10 +80,10 @@ num_enum = "0.5.7" wcgi = { version = "0.2.0", optional = true } wcgi-host = { version = "0.2.0", optional = true } tower-http = { version = "0.5.0", features = [ - "trace", - "util", - "catch-panic", - "cors", + "trace", + "util", + "catch-panic", + "cors", ], optional = true } tower = { version = "0.4.13", features = ["make", "util"], optional = true } url = "2.3.1" @@ -92,27 +96,33 @@ wasm-bindgen = { version = "0.2.87", optional = true } js-sys = { version = "0.3.64", optional = true } wasm-bindgen-futures = { version = "0.4.37", optional = true } web-sys = { version = "0.3.64", features = [ - "Request", - "RequestInit", - "Window", - "WorkerGlobalScope", - "RequestMode", - "Response", - "Headers", + "Request", + "RequestInit", + "Window", + "WorkerGlobalScope", + "RequestMode", + "Response", + "Headers", ], optional = true } ahash = "0.8.11" -hyper-util = { version = "0.1.5", features = ["server", "server-graceful", "tokio", "service", "client"], optional = true } -http-body-util = { version="0.1.1", optional = true } +hyper-util = { version = "0.1.5", features = [ + "server", + "server-graceful", + "tokio", + "service", + "client", +], optional = true } +http-body-util = { version = "0.1.1", optional = true } toml = "0.8" pin-utils = "0.1.0" -[target.'cfg(not(target_arch = "riscv64"))'.dependencies.reqwest] +[target.'cfg(not(any(target_arch = "riscv64", target_arch = "loongarch64")))'.dependencies.reqwest] workspace = true default-features = false features = ["rustls-tls", "json", "stream", "socks", "blocking"] optional = true -[target.'cfg(target_arch = "riscv64")'.dependencies.reqwest] +[target.'cfg(any(target_arch = "riscv64", target_arch = "loongarch64"))'.dependencies.reqwest] workspace = true default-features = false features = ["native-tls", "json", "stream", "socks", "blocking"] @@ -125,7 +135,9 @@ libc.workspace = true termios = { version = "0.3" } [target.'cfg(windows)'.dependencies] -windows-sys = { version = "0.59", features = ["Win32_System_SystemInformation"] } +windows-sys = { version = "0.59", features = [ + "Win32_System_SystemInformation", +] } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] terminal_size = { version = "0.3.0" } @@ -151,23 +163,38 @@ default = ["sys-default"] time = ["tokio/time"] ctrlc = ["tokio/signal"] -webc_runner_rt_wcgi = ["hyper", "hyper-util", "http-body-util", "wcgi", "wcgi-host", "tower", "tower-http"] +webc_runner_rt_wcgi = [ + "hyper", + "hyper-util", + "http-body-util", + "wcgi", + "wcgi-host", + "tower", + "tower-http", +] webc_runner_rt_dcgi = ["webc_runner_rt_wcgi", "journal"] -webc_runner_rt_dproxy = ["hyper", "hyper-util", "http-body-util", "tower", "tower-http", "journal"] +webc_runner_rt_dproxy = [ + "hyper", + "hyper-util", + "http-body-util", + "tower", + "tower-http", + "journal", +] webc_runner_rt_emscripten = ["wasmer-emscripten"] sys = ["webc/mmap", "time", "virtual-mio/sys"] sys-default = [ - "sys", - "logging", - "host-fs", - "journal", - "sys-poll", - "sys-thread", - "host-vnet", - "host-threads", - "host-reqwest", - "ctrlc" + "sys", + "logging", + "host-fs", + "journal", + "sys-poll", + "sys-thread", + "host-vnet", + "host-threads", + "host-reqwest", + "ctrlc", ] sys-poll = [] extra-logging = [] @@ -178,13 +205,13 @@ journal = ["tokio/fs", "wasmer-journal/log-file"] compiler = [] js = [ - "virtual-fs/no-time", - "getrandom/js", - "chrono", - "js-sys", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", + "virtual-fs/no-time", + "getrandom/js", + "chrono", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", ] js-default = ["js"] test-js = ["js", "wasmer/wat"] @@ -198,18 +225,18 @@ remote-vnet = ["virtual-net/remote"] logging = ["tracing/log"] disable-all-logging = ["tracing/release_max_level_off", "tracing/max_level_off"] enable-serde = [ - "typetag", - "virtual-fs/enable-serde", - "wasmer-wasix-types/enable-serde", + "typetag", + "virtual-fs/enable-serde", + "wasmer-wasix-types/enable-serde", ] [package.metadata.docs.rs] features = [ - "wasmer/sys", - "webc_runner_rt_wcgi", - "webc_runner_rt_dcgi", - "webc_runner_rt_dproxy", - "webc_runner_rt_emscripten", - "sys-default", + "wasmer/sys", + "webc_runner_rt_wcgi", + "webc_runner_rt_dcgi", + "webc_runner_rt_dproxy", + "webc_runner_rt_emscripten", + "sys-default", ] rustc-args = ["--cfg", "docsrs"] diff --git a/tests/ignores.txt b/tests/ignores.txt index d32e3e1eb56..0b8ea53081c 100644 --- a/tests/ignores.txt +++ b/tests/ignores.txt @@ -9,6 +9,7 @@ singlepass+aarch64+macos traps::test_trap_trace cranelift+aarch64+macos traps::test_trap_trace llvm+aarch64 traps::test_trap_trace llvm+riscv64 traps::test_trap_trace +llvm+loongarch64 traps::test_trap_trace singlepass+aarch64+macos traps::test_trap_stack_overflow # Need to investigate singlepass+aarch64+macos traps::trap_display_pretty llvm traps::trap_display_pretty @@ -29,6 +30,7 @@ cranelift+aarch64+macos traps::start_trap_pretty # https://github.com/wasmerio/wasmer/issues/2808 llvm+aarch64 spec::skip_stack_guard_page llvm+riscv64 spec::skip_stack_guard_page +llvm+loongarch64 spec::skip_stack_guard_page # riscv support is still early, function call ABI needs some work llvm+riscv64 static_function::llvm::universal @@ -56,6 +58,24 @@ cranelift+riscv64 spec::r#if::cranelift::universal # no SIMD on riscv, Cranelift will not handle them cranelift+riscv64 spec::simd +# loongarch64 support is still early, function call ABI needs some work +llvm+loongarch64 static_function::llvm::universal +llvm+loongarch64 static_function_with_env::llvm::universal +llvm+loongarch64 static_function_with_results::llvm::universal +llvm+loongarch64 spec::f32::llvm::universal +llvm+loongarch64 spec::f64::llvm::universal +llvm+loongarch64 spec::float_misc::llvm::universal +llvm+loongarch64 spec::memory_copy::llvm::universal +llvm+loongarch64 spec::memory_init::llvm::universal +llvm+loongarch64 spec::memory_trap::llvm::universal +llvm+loongarch64 spec::multi_value::binary::llvm::universal +llvm+loongarch64 spec::multi_value::block::llvm::universal +llvm+loongarch64 spec::simd::simd_align::llvm::universal +llvm+loongarch64 spec::simd::simd_f32x4_rounding::llvm::universal +llvm+loongarch64 spec::simd::simd_f64x2_rounding::llvm::universal +llvm+loongarch64 wasmer::nan_canonicalization::llvm::universal +llvm+loongarch64 wasmer::stack_overflow_sret::llvm::universal + # Windows doesn't overcommit and fails to allocate 4GB of memory windows wasmer::max_size_of_memory diff --git a/tests/lib/compiler-test-derive/src/ignores.rs b/tests/lib/compiler-test-derive/src/ignores.rs index 12364cf2191..268f11e4e41 100644 --- a/tests/lib/compiler-test-derive/src/ignores.rs +++ b/tests/lib/compiler-test-derive/src/ignores.rs @@ -111,7 +111,7 @@ impl Ignores { target_env = Some(alias.to_string()); } // Chipset architectures - "aarch64" | "x86" | "x64" | "riscv64" => { + "aarch64" | "x86" | "x64" | "riscv64" | "loongarch64" => { arch = Some(alias.to_string()); } // Engines