diff --git a/neon_intrinsics/advsimd.md b/neon_intrinsics/advsimd.md index b44f4769..ab9b4318 100644 --- a/neon_intrinsics/advsimd.md +++ b/neon_intrinsics/advsimd.md @@ -118,6 +118,7 @@ See [Changelog for year 2026](#changelog-for-year-2026). ### Changelog for year 2026 +* Added proposed support for LDNP/STNP intrinsics. * Added support for FEAT_F16F32DOT * Added support for FEAT_F16F32MM and FEAT_F16MM * Renamed vmmlaq_f16_f16 to vmmlaq_f16 @@ -3829,6 +3830,25 @@ The intrinsics in this section are guarded by the macro ``__ARM_NEON``. ### Load +#### Non-temporal pair + + +| Intrinsic | Argument preparation | AArch64 Instruction | Result | Supported architectures | +|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------|---------------------------------------------------------------------------------------------------------------------|---------------------------| +| int8x16x2_t vldnq_s8_x2(
     int8_t const *ptr)
| `ptr -> Xn` | `LDNP Qt1,Qt2,[Xn]` | `Qt1/Qt2 -> result.val[0]/result.val[1]` | `A64` | +| int16x8x2_t vldnq_s16_x2(
     int16_t const *ptr)
| `ptr -> Xn` | `LDNP Qt1,Qt2,[Xn]` | `Qt1/Qt2 -> result.val[0]/result.val[1]` | `A64` | +| int32x4x2_t vldnq_s32_x2(
     int32_t const *ptr)
| `ptr -> Xn` | `LDNP Qt1,Qt2,[Xn]` | `Qt1/Qt2 -> result.val[0]/result.val[1]` | `A64` | +| int64x2x2_t vldnq_s64_x2(
     int64_t const *ptr)
| `ptr -> Xn` | `LDNP Qt1,Qt2,[Xn]` | `Qt1/Qt2 -> result.val[0]/result.val[1]` | `A64` | +| uint8x16x2_t vldnq_u8_x2(
     uint8_t const *ptr)
| `ptr -> Xn` | `LDNP Qt1,Qt2,[Xn]` | `Qt1/Qt2 -> result.val[0]/result.val[1]` | `A64` | +| uint16x8x2_t vldnq_u16_x2(
     uint16_t const *ptr)
| `ptr -> Xn` | `LDNP Qt1,Qt2,[Xn]` | `Qt1/Qt2 -> result.val[0]/result.val[1]` | `A64` | +| uint32x4x2_t vldnq_u32_x2(
     uint32_t const *ptr)
| `ptr -> Xn` | `LDNP Qt1,Qt2,[Xn]` | `Qt1/Qt2 -> result.val[0]/result.val[1]` | `A64` | +| uint64x2x2_t vldnq_u64_x2(
     uint64_t const *ptr)
| `ptr -> Xn` | `LDNP Qt1,Qt2,[Xn]` | `Qt1/Qt2 -> result.val[0]/result.val[1]` | `A64` | +| float16x8x2_t vldnq_f16_x2(
     float16_t const *ptr)
| `ptr -> Xn` | `LDNP Qt1,Qt2,[Xn]` | `Qt1/Qt2 -> result.val[0]/result.val[1]` | `A64` | +| bfloat16x8x2_t vldnq_bf16_x2(
     bfloat16_t const *ptr)
| `ptr -> Xn` | `LDNP Qt1,Qt2,[Xn]` | `Qt1/Qt2 -> result.val[0]/result.val[1]` | `A64` | +| float32x4x2_t vldnq_f32_x2(
     float32_t const *ptr)
| `ptr -> Xn` | `LDNP Qt1,Qt2,[Xn]` | `Qt1/Qt2 -> result.val[0]/result.val[1]` | `A64` | +| float64x2x2_t vldnq_f64_x2(
     float64_t const *ptr)
| `ptr -> Xn` | `LDNP Qt1,Qt2,[Xn]` | `Qt1/Qt2 -> result.val[0]/result.val[1]` | `A64` | +| mfloat8x16x2_t vldnq_mf8_x2(
     mfloat8_t const *ptr)
| `ptr -> Xn` | `LDNP Qt1,Qt2,[Xn]` | `Qt1/Qt2 -> result.val[0]/result.val[1]` | `A64` | + #### Stride | Intrinsic | Argument preparation | AArch64 Instruction | Result | Supported architectures | @@ -4308,6 +4328,25 @@ The intrinsics in this section are guarded by the macro ``__ARM_NEON``. ### Store +#### Non-temporal pair + +| Intrinsic | Argument preparation | AArch64 Instruction | Result | Supported architectures | +|-----------|----------------------|---------------------|--------|-------------------------| +| void vstnq_s8_x2(
     int8_t *ptr,
     int8x16x2_t val)
| `val.val[0]/val.val[1] -> Qt1/Qt2`
`ptr -> Xn` | `STNP Qt1,Qt2,[Xn]` | | `A64` | +| void vstnq_s16_x2(
     int16_t *ptr,
     int16x8x2_t val)
| `val.val[0]/val.val[1] -> Qt1/Qt2`
`ptr -> Xn` | `STNP Qt1,Qt2,[Xn]` | | `A64` | +| void vstnq_s32_x2(
     int32_t *ptr,
     int32x4x2_t val)
| `val.val[0]/val.val[1] -> Qt1/Qt2`
`ptr -> Xn` | `STNP Qt1,Qt2,[Xn]` | | `A64` | +| void vstnq_s64_x2(
     int64_t *ptr,
     int64x2x2_t val)
| `val.val[0]/val.val[1] -> Qt1/Qt2`
`ptr -> Xn` | `STNP Qt1,Qt2,[Xn]` | | `A64` | +| void vstnq_u8_x2(
     uint8_t *ptr,
     uint8x16x2_t val)
| `val.val[0]/val.val[1] -> Qt1/Qt2`
`ptr -> Xn` | `STNP Qt1,Qt2,[Xn]` | | `A64` | +| void vstnq_u16_x2(
     uint16_t *ptr,
     uint16x8x2_t val)
| `val.val[0]/val.val[1] -> Qt1/Qt2`
`ptr -> Xn` | `STNP Qt1,Qt2,[Xn]` | | `A64` | +| void vstnq_u32_x2(
     uint32_t *ptr,
     uint32x4x2_t val)
| `val.val[0]/val.val[1] -> Qt1/Qt2`
`ptr -> Xn` | `STNP Qt1,Qt2,[Xn]` | | `A64` | +| void vstnq_u64_x2(
     uint64_t *ptr,
     uint64x2x2_t val)
| `val.val[0]/val.val[1] -> Qt1/Qt2`
`ptr -> Xn` | `STNP Qt1,Qt2,[Xn]` | | `A64` | +| void vstnq_f16_x2(
     float16_t *ptr,
     float16x8x2_t val)
| `val.val[0]/val.val[1] -> Qt1/Qt2`
`ptr -> Xn` | `STNP Qt1,Qt2,[Xn]` | | `A64` | +| void vstnq_bf16_x2(
     bfloat16_t *ptr,
     bfloat16x8x2_t val)
| `val.val[0]/val.val[1] -> Qt1/Qt2`
`ptr -> Xn` | `STNP Qt1,Qt2,[Xn]` | | `A64` | +| void vstnq_f32_x2(
     float32_t *ptr,
     float32x4x2_t val)
| `val.val[0]/val.val[1] -> Qt1/Qt2`
`ptr -> Xn` | `STNP Qt1,Qt2,[Xn]` | | `A64` | +| void vstnq_f64_x2(
     float64_t *ptr,
     float64x2x2_t val)
| `val.val[0]/val.val[1] -> Qt1/Qt2`
`ptr -> Xn` | `STNP Qt1,Qt2,[Xn]` | | `A64` | +| void vstnq_mf8_x2(
     mfloat8_t *ptr,
     mfloat8x16x2_t val)
| `val.val[0]/val.val[1] -> Qt1/Qt2`
`ptr -> Xn` | `STNP Qt1,Qt2,[Xn]` | | `A64` | + + #### Stride | Intrinsic | Argument preparation | AArch64 Instruction | Result | Supported architectures | diff --git a/neon_intrinsics/advsimd.template.md b/neon_intrinsics/advsimd.template.md index 45fee375..5df0afbb 100644 --- a/neon_intrinsics/advsimd.template.md +++ b/neon_intrinsics/advsimd.template.md @@ -118,6 +118,7 @@ See [Changelog for year 2026](#changelog-for-year-2026). ### Changelog for year 2026 +* Added proposed support for LDNP/STNP intrinsics. * Added support for FEAT_F16F32DOT * Added support for FEAT_F16F32MM and FEAT_F16MM * Renamed vmmlaq_f16_f16 to vmmlaq_f16 diff --git a/tools/intrinsic_db/advsimd.csv b/tools/intrinsic_db/advsimd.csv index d5bac768..25aa0df3 100644 --- a/tools/intrinsic_db/advsimd.csv +++ b/tools/intrinsic_db/advsimd.csv @@ -4863,3 +4863,30 @@ float32x4_t vmmlaq_f32_f16(float32x4_t r, float16x8_t a, float16x8_t b) r -> Vd.
Non-widening half-precision matrix multiply instruction. Requires the +f16mm architecture extension. float16x8_t vmmlaq_f16(float16x8_t r, float16x8_t a, float16x8_t b) r -> Vd.8H;a -> Vn.8H;b -> Vm.8H FMMLA Vd.8H, Vn.8H, Vm.8H Vd.8H -> result A64 +
Non-temporal pair load and store intrinsics +int8x16x2_t vldnq_s8_x2(int8_t const *ptr) ptr -> Xn LDNP Qt1,Qt2,[Xn] Qt2 -> result.val[1];Qt1 -> result.val[0] A64 +int16x8x2_t vldnq_s16_x2(int16_t const *ptr) ptr -> Xn LDNP Qt1,Qt2,[Xn] Qt2 -> result.val[1];Qt1 -> result.val[0] A64 +int32x4x2_t vldnq_s32_x2(int32_t const *ptr) ptr -> Xn LDNP Qt1,Qt2,[Xn] Qt2 -> result.val[1];Qt1 -> result.val[0] A64 +int64x2x2_t vldnq_s64_x2(int64_t const *ptr) ptr -> Xn LDNP Qt1,Qt2,[Xn] Qt2 -> result.val[1];Qt1 -> result.val[0] A64 +uint8x16x2_t vldnq_u8_x2(uint8_t const *ptr) ptr -> Xn LDNP Qt1,Qt2,[Xn] Qt2 -> result.val[1];Qt1 -> result.val[0] A64 +uint16x8x2_t vldnq_u16_x2(uint16_t const *ptr) ptr -> Xn LDNP Qt1,Qt2,[Xn] Qt2 -> result.val[1];Qt1 -> result.val[0] A64 +uint32x4x2_t vldnq_u32_x2(uint32_t const *ptr) ptr -> Xn LDNP Qt1,Qt2,[Xn] Qt2 -> result.val[1];Qt1 -> result.val[0] A64 +uint64x2x2_t vldnq_u64_x2(uint64_t const *ptr) ptr -> Xn LDNP Qt1,Qt2,[Xn] Qt2 -> result.val[1];Qt1 -> result.val[0] A64 +float16x8x2_t vldnq_f16_x2(float16_t const *ptr) ptr -> Xn LDNP Qt1,Qt2,[Xn] Qt2 -> result.val[1];Qt1 -> result.val[0] A64 +bfloat16x8x2_t vldnq_bf16_x2(bfloat16_t const *ptr) ptr -> Xn LDNP Qt1,Qt2,[Xn] Qt2 -> result.val[1];Qt1 -> result.val[0] A64 +float32x4x2_t vldnq_f32_x2(float32_t const *ptr) ptr -> Xn LDNP Qt1,Qt2,[Xn] Qt2 -> result.val[1];Qt1 -> result.val[0] A64 +float64x2x2_t vldnq_f64_x2(float64_t const *ptr) ptr -> Xn LDNP Qt1,Qt2,[Xn] Qt2 -> result.val[1];Qt1 -> result.val[0] A64 +mfloat8x16x2_t vldnq_mf8_x2(mfloat8_t const *ptr) ptr -> Xn LDNP Qt1,Qt2,[Xn] Qt2 -> result.val[1];Qt1 -> result.val[0] A64 +void vstnq_s8_x2(int8_t *ptr, int8x16x2_t val) val.val[1] -> Qt2;val.val[0] -> Qt1;ptr -> Xn STNP Qt1,Qt2,[Xn] A64 +void vstnq_s16_x2(int16_t *ptr, int16x8x2_t val) val.val[1] -> Qt2;val.val[0] -> Qt1;ptr -> Xn STNP Qt1,Qt2,[Xn] A64 +void vstnq_s32_x2(int32_t *ptr, int32x4x2_t val) val.val[1] -> Qt2;val.val[0] -> Qt1;ptr -> Xn STNP Qt1,Qt2,[Xn] A64 +void vstnq_s64_x2(int64_t *ptr, int64x2x2_t val) val.val[1] -> Qt2;val.val[0] -> Qt1;ptr -> Xn STNP Qt1,Qt2,[Xn] A64 +void vstnq_u8_x2(uint8_t *ptr, uint8x16x2_t val) val.val[1] -> Qt2;val.val[0] -> Qt1;ptr -> Xn STNP Qt1,Qt2,[Xn] A64 +void vstnq_u16_x2(uint16_t *ptr, uint16x8x2_t val) val.val[1] -> Qt2;val.val[0] -> Qt1;ptr -> Xn STNP Qt1,Qt2,[Xn] A64 +void vstnq_u32_x2(uint32_t *ptr, uint32x4x2_t val) val.val[1] -> Qt2;val.val[0] -> Qt1;ptr -> Xn STNP Qt1,Qt2,[Xn] A64 +void vstnq_u64_x2(uint64_t *ptr, uint64x2x2_t val) val.val[1] -> Qt2;val.val[0] -> Qt1;ptr -> Xn STNP Qt1,Qt2,[Xn] A64 +void vstnq_f16_x2(float16_t *ptr, float16x8x2_t val) val.val[1] -> Qt2;val.val[0] -> Qt1;ptr -> Xn STNP Qt1,Qt2,[Xn] A64 +void vstnq_bf16_x2(bfloat16_t *ptr, bfloat16x8x2_t val) val.val[1] -> Qt2;val.val[0] -> Qt1;ptr -> Xn STNP Qt1,Qt2,[Xn] A64 +void vstnq_f32_x2(float32_t *ptr, float32x4x2_t val) val.val[1] -> Qt2;val.val[0] -> Qt1;ptr -> Xn STNP Qt1,Qt2,[Xn] A64 +void vstnq_f64_x2(float64_t *ptr, float64x2x2_t val) val.val[1] -> Qt2;val.val[0] -> Qt1;ptr -> Xn STNP Qt1,Qt2,[Xn] A64 +void vstnq_mf8_x2(mfloat8_t *ptr, mfloat8x16x2_t val) val.val[1] -> Qt2;val.val[0] -> Qt1;ptr -> Xn STNP Qt1,Qt2,[Xn] A64 diff --git a/tools/intrinsic_db/advsimd_classification.csv b/tools/intrinsic_db/advsimd_classification.csv index 312f9b05..9e4d0731 100644 --- a/tools/intrinsic_db/advsimd_classification.csv +++ b/tools/intrinsic_db/advsimd_classification.csv @@ -4745,3 +4745,29 @@ vdot_laneq_f32_f16 Vector arithmetic|Dot product vdotq_lane_f32_f16 Vector arithmetic|Dot product vmmlaq_f32_f16 Vector arithmetic|Matrix multiply vmmlaq_f16 Vector arithmetic|Matrix multiply +vldnq_s8_x2 Load|Stride +vldnq_s16_x2 Load|Stride +vldnq_s32_x2 Load|Stride +vldnq_s64_x2 Load|Stride +vldnq_u8_x2 Load|Stride +vldnq_u16_x2 Load|Stride +vldnq_u32_x2 Load|Stride +vldnq_u64_x2 Load|Stride +vldnq_f16_x2 Load|Stride +vldnq_bf16_x2 Load|Stride +vldnq_f32_x2 Load|Stride +vldnq_f64_x2 Load|Stride +vldnq_mf8_x2 Load|Stride +vstnq_s8_x2 Store|Stride +vstnq_s16_x2 Store|Stride +vstnq_s32_x2 Store|Stride +vstnq_s64_x2 Store|Stride +vstnq_u8_x2 Store|Stride +vstnq_u16_x2 Store|Stride +vstnq_u32_x2 Store|Stride +vstnq_u64_x2 Store|Stride +vstnq_f16_x2 Store|Stride +vstnq_bf16_x2 Store|Stride +vstnq_f32_x2 Store|Stride +vstnq_f64_x2 Store|Stride +vstnq_mf8_x2 Store|Stride