Merge pull request #7174 from alexthed1rk/impl-simd-arm-crc32

Impl simd arm crc32
This commit is contained in:
Jeroen van Rijn
2026-07-31 15:47:54 +02:00
committed by GitHub
2 changed files with 107 additions and 0 deletions

104
core/simd/arm/crc32.odin Normal file
View File

@@ -0,0 +1,104 @@
#+build arm64,arm32
package simd_arm
// CRC32 single round checksum for bytes (8 bits).
//
// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/__crc32b)
@(require_results, enable_target_feature = "crc")
__crc32b :: #force_inline proc "c" (crc: uint32_t, data: uint8_t) -> uint32_t {
return ___crc32b(crc, uint32_t(data))
}
// CRC32-C single round checksum for bytes (8 bits).
//
// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/__crc32cb)
@(require_results, enable_target_feature = "crc")
__crc32cb :: #force_inline proc "c" (crc: uint32_t, data: uint8_t) -> uint32_t {
return ___crc32cb(crc, uint32_t(data))
}
// CRC32 single round checksum for bytes (16 bits).
//
// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/__crc32h)
@(require_results, enable_target_feature = "crc")
__crc32h :: #force_inline proc "c" (crc: uint32_t, data: uint16_t) -> uint32_t {
return ___crc32h(crc, uint32_t(data))
}
// CRC32-C single round checksum for bytes (16 bits).
//
// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/__crc32ch)
@(require_results, enable_target_feature = "crc")
__crc32ch :: #force_inline proc "c" (crc: uint32_t, data: uint16_t) -> uint32_t {
return ___crc32ch(crc, uint32_t(data))
}
// CRC32 single round checksum for bytes (32 bits).
//
// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/__crc32w)
@(require_results, enable_target_feature = "crc")
__crc32w :: #force_inline proc "c" (crc: uint32_t, data: uint32_t) -> uint32_t {
return ___crc32w(crc, data)
}
// CRC32-C single round checksum for bytes (32 bits).
//
// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/__crc32cw)
@(require_results, enable_target_feature = "crc")
__crc32cw :: #force_inline proc "c" (crc: uint32_t, data: uint32_t) -> uint32_t {
return ___crc32cw(crc, data)
}
// CRC32 single round checksum for quad words (64 bits).
//
// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/__crc32d)
@(require_results, enable_target_feature = "crc")
__crc32d :: #force_inline proc "c" (crc: uint32_t, data: uint64_t) -> uint32_t {
when ODIN_ARCH == .arm64 {
return ___crc32d(crc, data)
} else {
b := uint32_t(data & 0xffffffff)
c := uint32_t(data >> 32)
return ___crc32w(___crc32w(crc, b), c)
}
}
// CRC32-C single round checksum for quad words (64 bits).
//
// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/__crc32cd)
@(require_results, enable_target_feature = "crc")
__crc32cd :: #force_inline proc "c" (crc: uint32_t, data: uint64_t) -> uint32_t {
when ODIN_ARCH == .arm64 {
return ___crc32cd(crc, data)
} else {
b := uint32_t(data & 0xffffffff)
c := uint32_t(data >> 32)
return ___crc32cw(___crc32cw(crc, b), c)
}
}
@(private, default_calling_convention = "none")
foreign _ {
@(link_name = "llvm.aarch64.crc32b" when ODIN_ARCH == .arm64 else "llvm.arm.crc32b")
___crc32b :: proc(crc: uint32_t, data: uint32_t) -> uint32_t ---
@(link_name = "llvm.aarch64.crc32h" when ODIN_ARCH == .arm64 else "llvm.arm.crc32h")
___crc32h :: proc(crc: uint32_t, data: uint32_t) -> uint32_t ---
@(link_name = "llvm.aarch64.crc32w" when ODIN_ARCH == .arm64 else "llvm.arm.crc32w")
___crc32w :: proc(crc: uint32_t, data: uint32_t) -> uint32_t ---
@(link_name = "llvm.aarch64.crc32cb" when ODIN_ARCH == .arm64 else "llvm.arm.crc32cb")
___crc32cb :: proc(crc: uint32_t, data: uint32_t) -> uint32_t ---
@(link_name = "llvm.aarch64.crc32ch" when ODIN_ARCH == .arm64 else "llvm.arm.crc32ch")
___crc32ch :: proc(crc: uint32_t, data: uint32_t) -> uint32_t ---
@(link_name = "llvm.aarch64.crc32cw" when ODIN_ARCH == .arm64 else "llvm.arm.crc32cw")
___crc32cw :: proc(crc: uint32_t, data: uint32_t) -> uint32_t ---
}
when ODIN_ARCH == .arm64 {
@(private, default_calling_convention = "none")
foreign _ {
@(link_name = "llvm.aarch64.crc32x")
___crc32d :: proc(crc: uint32_t, data: uint64_t) -> uint32_t ---
@(link_name = "llvm.aarch64.crc32cx")
___crc32cd :: proc(crc: uint32_t, data: uint64_t) -> uint32_t ---
}
}

View File

@@ -2,7 +2,10 @@
package simd_arm
// Type aliases to match `arm_neon.h`.
uint8_t :: u8
uint16_t :: u16
uint32_t :: u32
uint64_t :: u64
uint8x16_t :: #simd[16]u8
uint32x4_t :: #simd[4]u32