From 64a5887f831833be334833c146351f15c27275fa Mon Sep 17 00:00:00 2001 From: Alexander Zhura Date: Fri, 14 Aug 2026 22:01:59 +0300 Subject: [PATCH] Impl simd arm neon logical --- core/simd/arm/neon.odin | 962 ++++++++++++++++++++++++++++++++++++++- core/simd/arm/pmull.odin | 34 ++ 2 files changed, 980 insertions(+), 16 deletions(-) diff --git a/core/simd/arm/neon.odin b/core/simd/arm/neon.odin index 33713d128..17f0f2fa9 100644 --- a/core/simd/arm/neon.odin +++ b/core/simd/arm/neon.odin @@ -211,14 +211,6 @@ vcnt_u8 :: #force_inline proc "c" (a: uint8x8_t) -> uint8x8_t { return transmute(uint8x8_t)vcnt_s8(transmute(int8x8_t)a) } -// Population count per byte. -// -// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcnt_p8) -@(require_results, enable_target_feature = "neon") -vcnt_p8 :: #force_inline proc "c" (a: poly8x8_t) -> poly8x8_t { - return transmute(poly8x8_t)vcnt_s8(transmute(int8x8_t)a) -} - // Population count per byte. // // [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcntq_s8) @@ -235,14 +227,6 @@ vcntq_u8 :: #force_inline proc "c" (a: uint8x16_t) -> uint8x16_t { return transmute(uint8x16_t)vcntq_s8(transmute(int8x16_t)a) } -// Population count per byte. -// -// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcntq_p8) -@(require_results, enable_target_feature = "neon") -vcntq_p8 :: #force_inline proc "c" (a: poly8x16_t) -> poly8x16_t { - return transmute(poly8x16_t)vcntq_s8(transmute(int8x16_t)a) -} - // Vector bitwise bit clear. // // [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vbic_s8) @@ -988,6 +972,864 @@ vtbx4_u8 :: #force_inline proc "c" (v: uint8x8_t, t: uint8x8x4_t, idx: uint8x8_t } } +// Duplicate vector element to vector or scalar +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_n_s8) +@(require_results, enable_target_feature = "neon") +vdup_n_s8 :: #force_inline proc "c" (value: int8_t) -> int8x8_t { + return int8x8_t(value) +} + +// Duplicate vector element to vector or scalar +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_n_s16) +@(require_results, enable_target_feature = "neon") +vdup_n_s16 :: #force_inline proc "c" (value: int16_t) -> int16x4_t { + return int16x4_t(value) +} + +// Duplicate vector element to vector or scalar +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_n_s32) +@(require_results, enable_target_feature = "neon") +vdup_n_s32 :: #force_inline proc "c" (value: int32_t) -> int32x2_t { + return int32x2_t(value) +} + +// Duplicate vector element to vector or scalar +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_n_s64) +@(require_results, enable_target_feature = "neon") +vdup_n_s64 :: #force_inline proc "c" (value: int64_t) -> int64x1_t { + return int64x1_t(value) +} + +// Move vector element to general-purpose register +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vget_lane_s8) +@(require_results, enable_target_feature = "neon") +vget_lane_s8 :: #force_inline proc "c" (v: int8x8_t, $LANE: int32_t) -> int8_t where 0 <= LANE, LANE < 8 { + when ODIN_ENDIAN == .Little { + return simd.extract(v, LANE) + } else { + v := simd.shuffle(v, v, 7, 6, 5, 4, 3, 2, 1, 0) + return simd.extract(v, LANE) + } +} + +// Move vector element to general-purpose register +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vget_lane_u8) +@(require_results, enable_target_feature = "neon") +vget_lane_u8 :: #force_inline proc "c" (v: uint8x8_t, $LANE: int32_t) -> uint8_t where 0 <= LANE, LANE < 8 { + when ODIN_ENDIAN == .Little { + return simd.extract(v, LANE) + } else { + v := simd.shuffle(v, v, 7, 6, 5, 4, 3, 2, 1, 0) + return simd.extract(v, LANE) + } +} + +// Move vector element to general-purpose register +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vget_lane_s16) +@(require_results, enable_target_feature = "neon") +vget_lane_s16 :: #force_inline proc "c" (v: int16x4_t, $LANE: int32_t) -> int16_t where 0 <= LANE, LANE < 4 { + when ODIN_ENDIAN == .Little { + return simd.extract(v, LANE) + } else { + v := simd.shuffle(v, v, 3, 2, 1, 0) + return simd.extract(v, LANE) + } +} + +// Move vector element to general-purpose register +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vget_lane_u16) +@(require_results, enable_target_feature = "neon") +vget_lane_u16 :: #force_inline proc "c" (v: uint16x4_t, $LANE: int32_t) -> uint16_t where 0 <= LANE, LANE < 4 { + when ODIN_ENDIAN == .Little { + return simd.extract(v, LANE) + } else { + v := simd.shuffle(v, v, 3, 2, 1, 0) + return simd.extract(v, LANE) + } +} + +// Move vector element to general-purpose register +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vget_lane_s32) +@(require_results, enable_target_feature = "neon") +vget_lane_s32 :: #force_inline proc "c" (v: int32x2_t, $LANE: int32_t) -> int32_t where 0 <= LANE, LANE < 2 { + when ODIN_ENDIAN == .Little { + return simd.extract(v, LANE) + } else { + v := simd.shuffle(v, v, 1, 0) + return simd.extract(v, LANE) + } +} + +// Move vector element to general-purpose register +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vget_lane_u32) +@(require_results, enable_target_feature = "neon") +vget_lane_u32 :: #force_inline proc "c" (v: uint32x2_t, $LANE: int32_t) -> uint32_t where 0 <= LANE, LANE < 2 { + when ODIN_ENDIAN == .Little { + return simd.extract(v, LANE) + } else { + v := simd.shuffle(v, v, 1, 0) + return simd.extract(v, LANE) + } +} + +// Move vector element to general-purpose register +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vget_lane_s64) +@(require_results, enable_target_feature = "neon") +vget_lane_s64 :: #force_inline proc "c" (v: int64x1_t, $LANE: int32_t) -> int64_t where LANE == 0 { + return simd.extract(v, LANE) +} + +// Move vector element to general-purpose register +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vget_lane_u64) +@(require_results, enable_target_feature = "neon") +vget_lane_u64 :: #force_inline proc "c" (v: uint64x1_t, $LANE: int32_t) -> uint64_t where LANE == 0 { + return simd.extract(v, LANE) +} + +// Negate. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vneg_s8) +@(require_results, enable_target_feature = "neon") +vneg_s8 :: #force_inline proc "c" (a: int8x8_t) -> int8x8_t { + return simd.neg(a) +} + +// Negate. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vnegq_s8) +@(require_results, enable_target_feature = "neon") +vnegq_s8 :: #force_inline proc "c" (a: int8x16_t) -> int8x16_t { + return simd.neg(a) +} + +// Negate. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vneg_s16) +@(require_results, enable_target_feature = "neon") +vneg_s16 :: #force_inline proc "c" (a: int16x4_t) -> int16x4_t { + return simd.neg(a) +} + +// Negate. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vnegq_s16) +@(require_results, enable_target_feature = "neon") +vnegq_s16 :: #force_inline proc "c" (a: int16x8_t) -> int16x8_t { + return simd.neg(a) +} + +// Negate. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vneg_s32) +@(require_results, enable_target_feature = "neon") +vneg_s32 :: #force_inline proc "c" (a: int32x2_t) -> int32x2_t { + return simd.neg(a) +} + +// Negate. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vnegq_s32) +@(require_results, enable_target_feature = "neon") +vnegq_s32 :: #force_inline proc "c" (a: int32x4_t) -> int32x4_t { + return simd.neg(a) +} + +// Signed saturating Negate. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqneg_s8) +@(require_results, enable_target_feature = "neon") +vqneg_s8 :: #force_inline proc "c" (a: int8x8_t) -> int8x8_t { + return _vqneg_s8(a) +} + +// Signed saturating Negate. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqneg_s16) +@(require_results, enable_target_feature = "neon") +vqneg_s16 :: #force_inline proc "c" (a: int16x4_t) -> int16x4_t { + return _vqneg_s16(a) +} + +// Signed saturating Negate. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqneg_s32) +@(require_results, enable_target_feature = "neon") +vqneg_s32 :: #force_inline proc "c" (a: int32x2_t) -> int32x2_t { + return _vqneg_s32(a) +} + +// Signed saturating Negate. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqnegq_s8) +@(require_results, enable_target_feature = "neon") +vqnegq_s8 :: #force_inline proc "c" (a: int8x16_t) -> int8x16_t { + return _vqnegq_s8(a) +} + +// Signed saturating Negate. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqnegq_s16) +@(require_results, enable_target_feature = "neon") +vqnegq_s16 :: #force_inline proc "c" (a: int16x8_t) -> int16x8_t { + return _vqnegq_s16(a) +} + +// Signed saturating Negate. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqnegq_s32) +@(require_results, enable_target_feature = "neon") +vqnegq_s32 :: #force_inline proc "c" (a: int32x4_t) -> int32x4_t { + return _vqnegq_s32(a) +} + +// Bitwise Not. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmvn_s8) +@(require_results, enable_target_feature = "neon") +vmvn_s8 :: #force_inline proc "c" (a: int8x8_t) -> int8x8_t { + b := int8x8_t(-1) + return simd.bit_xor(a, b) +} + +// Bitwise Not. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmvn_u8) +@(require_results, enable_target_feature = "neon") +vmvn_u8 :: #force_inline proc "c" (a: uint8x8_t) -> uint8x8_t { + b := uint8x8_t(max(uint8_t)) + return simd.bit_xor(a, b) +} + +// Bitwise Not. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmvn_s16) +@(require_results, enable_target_feature = "neon") +vmvn_s16 :: #force_inline proc "c" (a: int16x4_t) -> int16x4_t { + b := int16x4_t(-1) + return simd.bit_xor(a, b) +} + +// Bitwise Not. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmvn_u16) +@(require_results, enable_target_feature = "neon") +vmvn_u16 :: #force_inline proc "c" (a: uint16x4_t) -> uint16x4_t { + b := uint16x4_t(max(uint16_t)) + return simd.bit_xor(a, b) +} + +// Bitwise Not. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmvn_s32) +@(require_results, enable_target_feature = "neon") +vmvn_s32 :: #force_inline proc "c" (a: int32x2_t) -> int32x2_t { + b := int32x2_t(-1) + return simd.bit_xor(a, b) +} + +// Bitwise Not. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmvn_u32) +@(require_results, enable_target_feature = "neon") +vmvn_u32 :: #force_inline proc "c" (a: uint32x2_t) -> uint32x2_t { + b := uint32x2_t(max(uint32_t)) + return simd.bit_xor(a, b) +} + +// Bitwise Not. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmvnq_s8) +@(require_results, enable_target_feature = "neon") +vmvnq_s8 :: #force_inline proc "c" (a: int8x16_t) -> int8x16_t { + b := int8x16_t(-1) + return simd.bit_xor(a, b) +} + +// Bitwise Not. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmvnq_u8) +@(require_results, enable_target_feature = "neon") +vmvnq_u8 :: #force_inline proc "c" (a: uint8x16_t) -> uint8x16_t { + b := uint8x16_t(max(uint8_t)) + return simd.bit_xor(a, b) +} + +// Bitwise Not. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmvnq_s16) +@(require_results, enable_target_feature = "neon") +vmvnq_s16 :: #force_inline proc "c" (a: int16x8_t) -> int16x8_t { + b := int16x8_t(-1) + return simd.bit_xor(a, b) +} + +// Bitwise Not. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmvnq_u16) +@(require_results, enable_target_feature = "neon") +vmvnq_u16 :: #force_inline proc "c" (a: uint16x8_t) -> uint16x8_t { + b := uint16x8_t(max(uint16_t)) + return simd.bit_xor(a, b) +} + +// Bitwise Not. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmvnq_s32) +@(require_results, enable_target_feature = "neon") +vmvnq_s32 :: #force_inline proc "c" (a: int32x4_t) -> int32x4_t { + b := int32x4_t(-1) + return simd.bit_xor(a, b) +} + +// Bitwise Not. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmvnq_u32) +@(require_results, enable_target_feature = "neon") +vmvnq_u32 :: #force_inline proc "c" (a: uint32x4_t) -> uint32x4_t { + b := uint32x4_t(max(uint32_t)) + return simd.bit_xor(a, b) +} + +// Bitwise And. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vand_s8) +@(require_results, enable_target_feature = "neon") +vand_s8 :: #force_inline proc "c" (a, b: int8x8_t) -> int8x8_t { + return simd.bit_and(a, b) +} + +// Bitwise And. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vand_u8) +@(require_results, enable_target_feature = "neon") +vand_u8 :: #force_inline proc "c" (a, b: uint8x8_t) -> uint8x8_t { + return simd.bit_and(a, b) +} + +// Bitwise And. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vand_s16) +@(require_results, enable_target_feature = "neon") +vand_s16 :: #force_inline proc "c" (a, b: int16x4_t) -> int16x4_t { + return simd.bit_and(a, b) +} + +// Bitwise And. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vand_u16) +@(require_results, enable_target_feature = "neon") +vand_u16 :: #force_inline proc "c" (a, b: uint16x4_t) -> uint16x4_t { + return simd.bit_and(a, b) +} + +// Bitwise And. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vand_s32) +@(require_results, enable_target_feature = "neon") +vand_s32 :: #force_inline proc "c" (a, b: int32x2_t) -> int32x2_t { + return simd.bit_and(a, b) +} + +// Bitwise And. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vand_u32) +@(require_results, enable_target_feature = "neon") +vand_u32 :: #force_inline proc "c" (a, b: uint32x2_t) -> uint32x2_t { + return simd.bit_and(a, b) +} + +// Bitwise And. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vand_s64) +@(require_results, enable_target_feature = "neon") +vand_s64 :: #force_inline proc "c" (a, b: int64x1_t) -> int64x1_t { + return simd.bit_and(a, b) +} + +// Bitwise And. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vand_u64) +@(require_results, enable_target_feature = "neon") +vand_u64 :: #force_inline proc "c" (a, b: uint64x1_t) -> uint64x1_t { + return simd.bit_and(a, b) +} + +// Bitwise And. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vandq_s8) +@(require_results, enable_target_feature = "neon") +vandq_s8 :: #force_inline proc "c" (a, b: int8x16_t) -> int8x16_t { + return simd.bit_and(a, b) +} + +// Bitwise And. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vandq_u8) +@(require_results, enable_target_feature = "neon") +vandq_u8 :: #force_inline proc "c" (a, b: uint8x16_t) -> uint8x16_t { + return simd.bit_and(a, b) +} + +// Bitwise And. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vandq_s16) +@(require_results, enable_target_feature = "neon") +vandq_s16 :: #force_inline proc "c" (a, b: int16x8_t) -> int16x8_t { + return simd.bit_and(a, b) +} + +// Bitwise And. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vandq_u16) +@(require_results, enable_target_feature = "neon") +vandq_u16 :: #force_inline proc "c" (a, b: uint16x8_t) -> uint16x8_t { + return simd.bit_and(a, b) +} + +// Bitwise And. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vandq_s32) +@(require_results, enable_target_feature = "neon") +vandq_s32 :: #force_inline proc "c" (a, b: int32x4_t) -> int32x4_t { + return simd.bit_and(a, b) +} + +// Bitwise And. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vandq_u32) +@(require_results, enable_target_feature = "neon") +vandq_u32 :: #force_inline proc "c" (a, b: uint32x4_t) -> uint32x4_t { + return simd.bit_and(a, b) +} + +// Bitwise And. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vandq_s64) +@(require_results, enable_target_feature = "neon") +vandq_s64 :: #force_inline proc "c" (a, b: int64x2_t) -> int64x2_t { + return simd.bit_and(a, b) +} + +// Bitwise And. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vandq_u64) +@(require_results, enable_target_feature = "neon") +vandq_u64 :: #force_inline proc "c" (a, b: uint64x2_t) -> uint64x2_t { + return simd.bit_and(a, b) +} + +// Bitwise Inclusive Or. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorr_s8) +@(require_results, enable_target_feature = "neon") +vorr_s8 :: #force_inline proc "c" (a, b: int8x8_t) -> int8x8_t { + return simd.bit_or(a, b) +} + +// Bitwise Inclusive Or. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorr_u8) +@(require_results, enable_target_feature = "neon") +vorr_u8 :: #force_inline proc "c" (a, b: uint8x8_t) -> uint8x8_t { + return simd.bit_or(a, b) +} + +// Bitwise Inclusive Or. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorr_s16) +@(require_results, enable_target_feature = "neon") +vorr_s16 :: #force_inline proc "c" (a, b: int16x4_t) -> int16x4_t { + return simd.bit_or(a, b) +} + +// Bitwise Inclusive Or. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorr_u16) +@(require_results, enable_target_feature = "neon") +vorr_u16 :: #force_inline proc "c" (a, b: uint16x4_t) -> uint16x4_t { + return simd.bit_or(a, b) +} + +// Bitwise Inclusive Or. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorr_s32) +@(require_results, enable_target_feature = "neon") +vorr_s32 :: #force_inline proc "c" (a, b: int32x2_t) -> int32x2_t { + return simd.bit_or(a, b) +} + +// Bitwise Inclusive Or. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorr_u32) +@(require_results, enable_target_feature = "neon") +vorr_u32 :: #force_inline proc "c" (a, b: uint32x2_t) -> uint32x2_t { + return simd.bit_or(a, b) +} + +// Bitwise Inclusive Or. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorr_s64) +@(require_results, enable_target_feature = "neon") +vorr_s64 :: #force_inline proc "c" (a, b: int64x1_t) -> int64x1_t { + return simd.bit_or(a, b) +} + +// Bitwise Inclusive Or. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorr_u64) +@(require_results, enable_target_feature = "neon") +vorr_u64 :: #force_inline proc "c" (a, b: uint64x1_t) -> uint64x1_t { + return simd.bit_or(a, b) +} + +// Bitwise Inclusive Or. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorrq_s8) +@(require_results, enable_target_feature = "neon") +vorrq_s8 :: #force_inline proc "c" (a, b: int8x16_t) -> int8x16_t { + return simd.bit_or(a, b) +} + +// Bitwise Inclusive Or. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorrq_u8) +@(require_results, enable_target_feature = "neon") +vorrq_u8 :: #force_inline proc "c" (a, b: uint8x16_t) -> uint8x16_t { + return simd.bit_or(a, b) +} + +// Bitwise Inclusive Or. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorrq_s16) +@(require_results, enable_target_feature = "neon") +vorrq_s16 :: #force_inline proc "c" (a, b: int16x8_t) -> int16x8_t { + return simd.bit_or(a, b) +} + +// Bitwise Inclusive Or. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorrq_u16) +@(require_results, enable_target_feature = "neon") +vorrq_u16 :: #force_inline proc "c" (a, b: uint16x8_t) -> uint16x8_t { + return simd.bit_or(a, b) +} + +// Bitwise Inclusive Or. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorrq_s32) +@(require_results, enable_target_feature = "neon") +vorrq_s32 :: #force_inline proc "c" (a, b: int32x4_t) -> int32x4_t { + return simd.bit_or(a, b) +} + +// Bitwise Inclusive Or. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorrq_u32) +@(require_results, enable_target_feature = "neon") +vorrq_u32 :: #force_inline proc "c" (a, b: uint32x4_t) -> uint32x4_t { + return simd.bit_or(a, b) +} + +// Bitwise Inclusive Or. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorrq_s64) +@(require_results, enable_target_feature = "neon") +vorrq_s64 :: #force_inline proc "c" (a, b: int64x2_t) -> int64x2_t { + return simd.bit_or(a, b) +} + +// Bitwise Inclusive Or. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorrq_u64) +@(require_results, enable_target_feature = "neon") +vorrq_u64 :: #force_inline proc "c" (a, b: uint64x2_t) -> uint64x2_t { + return simd.bit_or(a, b) +} + +// Bitwise Exclusive Or. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veor_s8) +@(require_results, enable_target_feature = "neon") +veor_s8 :: #force_inline proc "c" (a, b: int8x8_t) -> int8x8_t { + return simd.bit_xor(a, b) +} + +// Bitwise Exclusive Or. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veor_u8) +@(require_results, enable_target_feature = "neon") +veor_u8 :: #force_inline proc "c" (a, b: uint8x8_t) -> uint8x8_t { + return simd.bit_xor(a, b) +} + +// Bitwise Exclusive Or. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veor_s16) +@(require_results, enable_target_feature = "neon") +veor_s16 :: #force_inline proc "c" (a, b: int16x4_t) -> int16x4_t { + return simd.bit_xor(a, b) +} + +// Bitwise Exclusive Or. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veor_u16) +@(require_results, enable_target_feature = "neon") +veor_u16 :: #force_inline proc "c" (a, b: uint16x4_t) -> uint16x4_t { + return simd.bit_xor(a, b) +} + +// Bitwise Exclusive Or. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veor_s32) +@(require_results, enable_target_feature = "neon") +veor_s32 :: #force_inline proc "c" (a, b: int32x2_t) -> int32x2_t { + return simd.bit_xor(a, b) +} + +// Bitwise Exclusive Or. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veor_u32) +@(require_results, enable_target_feature = "neon") +veor_u32 :: #force_inline proc "c" (a, b: uint32x2_t) -> uint32x2_t { + return simd.bit_xor(a, b) +} + +// Bitwise Exclusive Or. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veor_s64) +@(require_results, enable_target_feature = "neon") +veor_s64 :: #force_inline proc "c" (a, b: int64x1_t) -> int64x1_t { + return simd.bit_xor(a, b) +} + +// Bitwise Exclusive Or. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veor_u64) +@(require_results, enable_target_feature = "neon") +veor_u64 :: #force_inline proc "c" (a, b: uint64x1_t) -> uint64x1_t { + return simd.bit_xor(a, b) +} + +// Bitwise Exclusive Or. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veorq_s8) +@(require_results, enable_target_feature = "neon") +veorq_s8 :: #force_inline proc "c" (a, b: int8x16_t) -> int8x16_t { + return simd.bit_xor(a, b) +} + +// Bitwise Exclusive Or. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veorq_u8) +@(require_results, enable_target_feature = "neon") +veorq_u8 :: #force_inline proc "c" (a, b: uint8x16_t) -> uint8x16_t { + return simd.bit_xor(a, b) +} + +// Bitwise Exclusive Or. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veorq_s16) +@(require_results, enable_target_feature = "neon") +veorq_s16 :: #force_inline proc "c" (a, b: int16x8_t) -> int16x8_t { + return simd.bit_xor(a, b) +} + +// Bitwise Exclusive Or. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veorq_u16) +@(require_results, enable_target_feature = "neon") +veorq_u16 :: #force_inline proc "c" (a, b: uint16x8_t) -> uint16x8_t { + return simd.bit_xor(a, b) +} + +// Bitwise Exclusive Or. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veorq_s32) +@(require_results, enable_target_feature = "neon") +veorq_s32 :: #force_inline proc "c" (a, b: int32x4_t) -> int32x4_t { + return simd.bit_xor(a, b) +} + +// Bitwise Exclusive Or. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veorq_u32) +@(require_results, enable_target_feature = "neon") +veorq_u32 :: #force_inline proc "c" (a, b: uint32x4_t) -> uint32x4_t { + return simd.bit_xor(a, b) +} + +// Bitwise Exclusive Or. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veorq_s64) +@(require_results, enable_target_feature = "neon") +veorq_s64 :: #force_inline proc "c" (a, b: int64x2_t) -> int64x2_t { + return simd.bit_xor(a, b) +} + +// Bitwise Exclusive Or. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/veorq_u64) +@(require_results, enable_target_feature = "neon") +veorq_u64 :: #force_inline proc "c" (a, b: uint64x2_t) -> uint64x2_t { + return simd.bit_xor(a, b) +} + +// Bitwise Inclusive Or Not. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorn_s8) +@(require_results, enable_target_feature = "neon") +vorn_s8 :: #force_inline proc "c" (a, b: int8x8_t) -> int8x8_t { + c := int8x8_t(-1) + return simd.bit_or(simd.bit_xor(b, c), a) +} + +// Bitwise Inclusive Or Not. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorn_u8) +@(require_results, enable_target_feature = "neon") +vorn_u8 :: #force_inline proc "c" (a, b: uint8x8_t) -> uint8x8_t { + c := uint8x8_t(max(uint8_t)) + return simd.bit_or(simd.bit_xor(b, c), a) +} + +// Bitwise Inclusive Or Not. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorn_s16) +@(require_results, enable_target_feature = "neon") +vorn_s16 :: #force_inline proc "c" (a, b: int16x4_t) -> int16x4_t { + c := int16x4_t(-1) + return simd.bit_or(simd.bit_xor(b, c), a) +} + +// Bitwise Inclusive Or Not. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorn_u16) +@(require_results, enable_target_feature = "neon") +vorn_u16 :: #force_inline proc "c" (a, b: uint16x4_t) -> uint16x4_t { + c := uint16x4_t(max(uint16_t)) + return simd.bit_or(simd.bit_xor(b, c), a) +} + +// Bitwise Inclusive Or Not. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorn_s32) +@(require_results, enable_target_feature = "neon") +vorn_s32 :: #force_inline proc "c" (a, b: int32x2_t) -> int32x2_t { + c := int32x2_t(-1) + return simd.bit_or(simd.bit_xor(b, c), a) +} + +// Bitwise Inclusive Or Not. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorn_u32) +@(require_results, enable_target_feature = "neon") +vorn_u32 :: #force_inline proc "c" (a, b: uint32x2_t) -> uint32x2_t { + c := uint32x2_t(max(uint32_t)) + return simd.bit_or(simd.bit_xor(b, c), a) +} + +// Bitwise Inclusive Or Not. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorn_s64) +@(require_results, enable_target_feature = "neon") +vorn_s64 :: #force_inline proc "c" (a, b: int64x1_t) -> int64x1_t { + c := int64x1_t(-1) + return simd.bit_or(simd.bit_xor(b, c), a) +} + +// Bitwise Inclusive Or Not. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vorn_u64) +@(require_results, enable_target_feature = "neon") +vorn_u64 :: #force_inline proc "c" (a, b: uint64x1_t) -> uint64x1_t { + c := uint64x1_t(max(uint64_t)) + return simd.bit_or(simd.bit_xor(b, c), a) +} + +// Bitwise Inclusive Or Not. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vornq_s8) +@(require_results, enable_target_feature = "neon") +vornq_s8 :: #force_inline proc "c" (a, b: int8x16_t) -> int8x16_t { + c := int8x16_t(-1) + return simd.bit_or(simd.bit_xor(b, c), a) +} + +// Bitwise Inclusive Or Not. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vornq_u8) +@(require_results, enable_target_feature = "neon") +vornq_u8 :: #force_inline proc "c" (a, b: uint8x16_t) -> uint8x16_t { + c := uint8x16_t(max(uint8_t)) + return simd.bit_or(simd.bit_xor(b, c), a) +} + +// Bitwise Inclusive Or Not. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vornq_s16) +@(require_results, enable_target_feature = "neon") +vornq_s16 :: #force_inline proc "c" (a, b: int16x8_t) -> int16x8_t { + c := int16x8_t(-1) + return simd.bit_or(simd.bit_xor(b, c), a) +} + +// Bitwise Inclusive Or Not. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vornq_u16) +@(require_results, enable_target_feature = "neon") +vornq_u16 :: #force_inline proc "c" (a, b: uint16x8_t) -> uint16x8_t { + c := uint16x8_t(max(uint16_t)) + return simd.bit_or(simd.bit_xor(b, c), a) +} + +// Bitwise Inclusive Or Not. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vornq_s32) +@(require_results, enable_target_feature = "neon") +vornq_s32 :: #force_inline proc "c" (a, b: int32x4_t) -> int32x4_t { + c := int32x4_t(-1) + return simd.bit_or(simd.bit_xor(b, c), a) +} + +// Bitwise Inclusive Or Not. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vornq_u32) +@(require_results, enable_target_feature = "neon") +vornq_u32 :: #force_inline proc "c" (a, b: uint32x4_t) -> uint32x4_t { + c := uint32x4_t(max(uint32_t)) + return simd.bit_or(simd.bit_xor(b, c), a) +} + +// Bitwise Inclusive Or Not. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vornq_s64) +@(require_results, enable_target_feature = "neon") +vornq_s64 :: #force_inline proc "c" (a, b: int64x2_t) -> int64x2_t { + c := int64x2_t(-1) + return simd.bit_or(simd.bit_xor(b, c), a) +} + +// Bitwise Inclusive Or Not. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vornq_u64) +@(require_results, enable_target_feature = "neon") +vornq_u64 :: #force_inline proc "c" (a, b: uint64x2_t) -> uint64x2_t { + c := uint64x2_t(max(uint64_t)) + return simd.bit_or(simd.bit_xor(b, c), a) +} + when ODIN_ARCH == .arm64 { // Table Lookup. // @@ -1728,6 +2570,78 @@ when ODIN_ARCH == .arm64 { return simd.shuffle(c, c, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) } } + + // Negate. + // + // [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vneg_s64) + @(require_results, enable_target_feature = "neon") + vneg_s64 :: #force_inline proc "c" (a: int64x1_t) -> int64x1_t { + return simd.neg(a) + } + + // Negate. + // + // [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vnegd_s64) + @(require_results, enable_target_feature = "neon") + vnegd_s64 :: #force_inline proc "c" (a: int64_t) -> int64_t { + return -a + } + + // Negate. + // + // [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vnegq_s64) + @(require_results, enable_target_feature = "neon") + vnegq_s64 :: #force_inline proc "c" (a: int64x2_t) -> int64x2_t { + return simd.neg(a) + } + + // Signed saturating Negate. + // + // [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqneg_s64) + @(require_results, enable_target_feature = "neon") + vqneg_s64 :: #force_inline proc "c" (a: int64x1_t) -> int64x1_t { + return _vqneg_s64(a) + } + + // Signed saturating Negate. + // + // [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqnegq_s64) + @(require_results, enable_target_feature = "neon") + vqnegq_s64 :: #force_inline proc "c" (a: int64x2_t) -> int64x2_t { + return _vqnegq_s64(a) + } + + // Signed saturating Negate. + // + // [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqnegb_s8) + @(require_results, enable_target_feature = "neon") + vqnegb_s8 :: #force_inline proc "c" (a: int8_t) -> int8_t { + return vget_lane_s8(vqneg_s8(vdup_n_s8(a)), 0) + } + + // Signed saturating Negate. + // + // [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqnegh_s16) + @(require_results, enable_target_feature = "neon") + vqnegh_s16 :: #force_inline proc "c" (a: int16_t) -> int16_t { + return vget_lane_s16(vqneg_s16(vdup_n_s16(a)), 0) + } + + // Signed saturating Negate. + // + // [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqnegs_s32) + @(require_results, enable_target_feature = "neon") + vqnegs_s32 :: #force_inline proc "c" (a: int32_t) -> int32_t { + return vget_lane_s32(vqneg_s32(vdup_n_s32(a)), 0) + } + + // Signed saturating Negate. + // + // [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqnegd_s64) + @(require_results, enable_target_feature = "neon") + vqnegd_s64 :: #force_inline proc "c" (a: int64_t) -> int64_t { + return vget_lane_s64(vqneg_s64(vdup_n_s64(a)), 0) + } } @(private, default_calling_convention = "none") @@ -1744,6 +2658,18 @@ foreign _ { _vclsq_s16 :: proc(a: int16x8_t) -> int16x8_t --- @(link_name = "llvm.aarch64.neon.cls.v4i32" when ODIN_ARCH == .arm64 else "llvm.arm.neon.vcls.v4i32") _vclsq_s32 :: proc(a: int32x4_t) -> int32x4_t --- + @(link_name = "llvm.aarch64.neon.sqneg.v8i8" when ODIN_ARCH == .arm64 else "llvm.arm.neon.vqneg.v8i8") + _vqneg_s8 :: proc(a: int8x8_t) -> int8x8_t --- + @(link_name = "llvm.aarch64.neon.sqneg.v4i16" when ODIN_ARCH == .arm64 else "llvm.arm.neon.vqneg.v4i16") + _vqneg_s16 :: proc(a: int16x4_t) -> int16x4_t --- + @(link_name = "llvm.aarch64.neon.sqneg.v2i32" when ODIN_ARCH == .arm64 else "llvm.arm.neon.vqneg.v2i32") + _vqneg_s32 :: proc(a: int32x2_t) -> int32x2_t --- + @(link_name = "llvm.aarch64.neon.sqneg.v16i8" when ODIN_ARCH == .arm64 else "llvm.arm.neon.vqneg.v16i8") + _vqnegq_s8 :: proc(a: int8x16_t) -> int8x16_t --- + @(link_name = "llvm.aarch64.neon.sqneg.v8i16" when ODIN_ARCH == .arm64 else "llvm.arm.neon.vqneg.v8i16") + _vqnegq_s16 :: proc(a: int16x8_t) -> int16x8_t --- + @(link_name = "llvm.aarch64.neon.sqneg.v4i32" when ODIN_ARCH == .arm64 else "llvm.arm.neon.vqneg.v4i32") + _vqnegq_s32 :: proc(a: int32x4_t) -> int32x4_t --- } when ODIN_ARCH == .arm32 { @@ -1771,6 +2697,10 @@ when ODIN_ARCH == .arm32 { when ODIN_ARCH == .arm64 { @(private, default_calling_convention = "none") foreign _ { + @(link_name = "llvm.aarch64.neon.sqneg.v1i64") + _vqneg_s64 :: proc(a: int64x1_t) -> int64x1_t --- + @(link_name = "llvm.aarch64.neon.sqneg.v2i64") + _vqnegq_s64 :: proc(a: int64x2_t) -> int64x2_t --- @(link_name = "llvm.aarch64.neon.tbl1.v8i8") _vqtbl1 :: proc(t: int8x16_t, idx: uint8x8_t) -> int8x8_t --- @(link_name = "llvm.aarch64.neon.tbl1.v16i8") diff --git a/core/simd/arm/pmull.odin b/core/simd/arm/pmull.odin index b2baa85db..cb2940b2d 100644 --- a/core/simd/arm/pmull.odin +++ b/core/simd/arm/pmull.odin @@ -596,6 +596,40 @@ vtbx4_p8 :: #force_inline proc "c" (v: poly8x8_t, t: poly8x8x4_t, idx: uint8x8_t } } +// Population count per byte. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcnt_p8) +@(require_results, enable_target_feature = "neon") +vcnt_p8 :: #force_inline proc "c" (a: poly8x8_t) -> poly8x8_t { + return transmute(poly8x8_t)vcnt_s8(transmute(int8x8_t)a) +} + +// Population count per byte. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcntq_p8) +@(require_results, enable_target_feature = "neon") +vcntq_p8 :: #force_inline proc "c" (a: poly8x16_t) -> poly8x16_t { + return transmute(poly8x16_t)vcntq_s8(transmute(int8x16_t)a) +} + +// Bitwise Not. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmvn_p8) +@(require_results, enable_target_feature = "neon") +vmvn_p8 :: #force_inline proc "c" (a: poly8x8_t) -> poly8x8_t { + b := poly8x8_t(max(poly8_t)) + return simd.bit_xor(a, b) +} + +// Bitwise Not. +// +// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmvnq_p8) +@(require_results, enable_target_feature = "neon") +vmvnq_p8 :: #force_inline proc "c" (a: poly8x16_t) -> poly8x16_t { + b := poly8x16_t(max(poly8_t)) + return simd.bit_xor(a, b) +} + when ODIN_ARCH == .arm64 { // Polynomial multiply long //