diff --git a/base/runtime/internal.odin b/base/runtime/internal.odin index db17cb033..d74b7d1a8 100644 --- a/base/runtime/internal.odin +++ b/base/runtime/internal.odin @@ -17,12 +17,20 @@ RUNTIME_REQUIRE :: false // !ODIN_TILDE @(private) __float16 :: f16 when __ODIN_LLVM_F16_SUPPORTED else u16 -HAS_HARDWARE_SIMD :: false when (ODIN_ARCH == .amd64 || ODIN_ARCH == .i386) && !intrinsics.has_target_feature("sse2") else - false when (ODIN_ARCH == .arm64 || ODIN_ARCH == .arm32) && !intrinsics.has_target_feature("neon") else - false when (ODIN_ARCH == .wasm64p32 || ODIN_ARCH == .wasm32) && !intrinsics.has_target_feature("simd128") else - false when (ODIN_ARCH == .riscv64) && !intrinsics.has_target_feature("v") else - true +HAS_HARDWARE_SIMD :: NATIVE_SIMD_BIT_WIDTH != 0 +// Number of bits in the largest native SIMD register. +// 0 when target doesn't support hardware SIMD. +NATIVE_SIMD_BIT_WIDTH :: + 512 when (ODIN_ARCH == .amd64) && intrinsics.has_target_feature("avx512f") else + 256 when (ODIN_ARCH == .amd64) && (intrinsics.has_target_feature("avx2") || intrinsics.has_target_feature("avx")) else + 128 when (ODIN_ARCH == .amd64 || ODIN_ARCH == .i386) && intrinsics.has_target_feature("sse") else + // ARM: SVE can be larger, but NEON is always 128 + 128 when (ODIN_ARCH == .arm64 || ODIN_ARCH == .arm32) && intrinsics.has_target_feature("neon") else + // VLEN can be between 32 and thousands of bits. 128 is a safe bet. + 128 when (ODIN_ARCH == .riscv64) && intrinsics.has_target_feature("v") else + 128 when (ODIN_ARCH == .wasm64p32 || ODIN_ARCH == .wasm32) && intrinsics.has_target_feature("simd128") else + 0 @(private) byte_slice :: #force_inline proc "contextless" (data: rawptr, len: int) -> []byte #no_bounds_check {