arch_cfgs:
  - arch_name: aarch64
    target_feature: [neon]
    llvm_prefix: llvm.aarch64.neon
# Generate big endian shuffles
auto_big_endian: true

# Repeatedly used anchors 
# #[stable(feature = "neon_intrinsics", since = "1.59.0")]
neon-stable: &neon-stable
  FnCall: [stable, ['feature = "neon_intrinsics"', 'since = "1.59.0"']]

# #[stable(feature = "stdarch_neon_fp16", since = "1.94.0")]
neon-stable-fp16: &neon-stable-fp16
  FnCall: [stable, ['feature = "stdarch_neon_fp16"', 'since = "1.94.0"']]

# #[cfg_attr(target_arch = "arm", unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800"))]
neon-cfg-arm-unstable: &neon-cfg-arm-unstable
  FnCall: ['cfg_attr', ['target_arch = "arm"', {FnCall: ['unstable', ['feature = "stdarch_arm_neon_intrinsics"', 'issue = "111800"']]}]]

# #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
neon-arm-unstable: &neon-arm-unstable
  FnCall: ['unstable', ['feature = "stdarch_arm_neon_intrinsics"', 'issue = "111800"']]

# #[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
neon-v7: &neon-v7
  FnCall: [cfg_attr, ['target_arch = "arm"', { FnCall: [target_feature, [ 'enable = "v7"']]} ]]

# #[target_feature(enable = "neon,v7")]
enable-v7: &enable-v7
  FnCall: [target_feature, ['enable = "neon,v7"']]

# #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
neon-v8: &neon-v8
  FnCall: [cfg_attr, ['target_arch = "arm"', { FnCall: [target_feature, [ 'enable = "v8"']]} ]]

target-is-arm: &target-is-arm
  FnCall: [cfg, ['target_arch = "arm"']]

# #[cfg(not(target_arch = "arm"))]
target-not-arm: &target-not-arm
  FnCall: [cfg, [{ FnCall: [not, ['target_arch = "arm"']]}]]

# #[cfg(not(target_arch = "arm64ec"))]
target-not-arm64ec: &target-not-arm64ec
  FnCall: [cfg, [{ FnCall: [not, ['target_arch = "arm64ec"']]}]]

not-arm: &not-arm
  FnCall: [not, ['target_arch = "arm"']]

neon-target-aarch64-arm64ec: &neon-target-aarch64-arm64ec
  FnCall: [all, [test, {FnCall: [any, ['target_arch = "aarch64"', 'target_arch = "arm64ec"']]}]]

# #[cfg_attr(not(target_arch = "arm"), stable(feature = "neon_intrinsics", since = "1.59.0"))]
neon-not-arm-stable: &neon-not-arm-stable
  FnCall: [cfg_attr, [{ FnCall: [not, ['target_arch = "arm"']]}, {FnCall: [stable, ['feature = "neon_intrinsics"', 'since = "1.59.0"']]}]]

# #[cfg_attr(not(target_arch = "arm"), stable(feature = "stdarch_neon_fp16", since = "1.94.0"))]
neon-not-arm-stable-fp16: &neon-not-arm-stable-fp16
  FnCall: [cfg_attr, [{ FnCall: [not, ['target_arch = "arm"']]}, {FnCall: [stable, ['feature = "stdarch_neon_fp16"', 'since = "1.94.0"']]}]]

# #[cfg_attr(all(test, not(target_env = "msvc"))]
msvc-disabled: &msvc-disabled
  FnCall: [all, [test, {FnCall: [not, ['target_env = "msvc"']]}]]

# all(test, target_arch = "arm")
test-is-arm: &test-is-arm
  FnCall: [all, [test, 'target_arch = "arm"']]

# #[target_feature(enable = "neon,aes")]
neon-aes: &neon-aes
  FnCall: [target_feature, ['enable = "neon,aes"']]

# #[target_feature(enable = "neon,i8mm")]
neon-i8mm: &neon-i8mm
  FnCall: [target_feature, ['enable = "neon,i8mm"']]

# #[target_feature(enable = "neon,fp16")]
neon-fp16: &neon-fp16
  FnCall: [target_feature, ['enable = "neon,fp16"']]

# #[cfg_attr[target_arch = "arm", target_feature(enable = "neon,fp16")]
arm-fp16: &arm-fp16
  FnCall: [cfg_attr, ['target_arch = "arm"', {FnCall: [target_feature, ['enable = "fp16"']]}]]

enable-fcma: &enable-fcma
  FnCall: [cfg_attr, [{ FnCall: [not, ['target_arch = "arm"']]}, { FnCall: [target_feature, ['enable = "fcma"']] }]]

#[cfg_attr(not(target_arch = "arm"), unstable(feature = "stdarch_neon_i8mm", issue = "117223"))]
neon-unstable-i8mm: &neon-unstable-i8mm
  FnCall: [cfg_attr, [{ FnCall: [not, ['target_arch = "arm"']] }, { FnCall: [unstable, ['feature = "stdarch_neon_i8mm"', 'issue = "117223"']] } ]]

# #[unstable(feature = "stdarch_neon_fcma", issue = "117222")]
neon-unstable-fcma: &neon-unstable-fcma
  FnCall: [unstable, ['feature = "stdarch_neon_fcma"', 'issue = "117222"']]

arm-crc-unstable: &arm-crc-unstable
  FnCall: [cfg_attr, ['target_arch = "arm"', {FnCall: [unstable, ['feature = "stdarch_aarch32_crc32"', 'issue = "125085"']]}]]

aarch64-crc-stable: &aarch64-crc-stable
  FnCall: [cfg_attr, [{FnCall: [not, ['target_arch = "arm"']]}, {FnCall: [stable, ['feature = "stdarch_aarch64_crc32"', 'since = "1.80.0"']]}]]

# #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
neon-unstable-f16: &neon-unstable-f16
  FnCall: [unstable, ['feature = "stdarch_neon_f16"', 'issue = "136306"']]

intrinsics:
  - name: "vand{neon_type.no}"
    doc: Vector bitwise and
    arguments: ["a: {neon_type}", "b: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vand]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [and]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - int8x8_t
      - int8x16_t
      - int16x4_t
      - int16x8_t
      - int32x2_t
      - int32x4_t
      - uint8x8_t
      - uint8x16_t
      - uint16x4_t
      - uint16x8_t
      - uint32x2_t
      - uint32x4_t
      - int64x1_t
      - int64x2_t
      - uint64x1_t
      - uint64x2_t
    compose:
      - FnCall:
          - simd_and
          - - a
            - b

  - name: "vorr{neon_type.no}"
    doc: "Vector bitwise or (immediate, inclusive)"
    arguments: ["a: {neon_type}", "b: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vorr]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [orr]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - int8x8_t
      - int8x16_t
      - int16x4_t
      - int16x8_t
      - int32x2_t
      - int32x4_t
      - uint8x8_t
      - uint8x16_t
      - uint16x4_t
      - uint16x8_t
      - uint32x2_t
      - uint32x4_t
      - int64x1_t
      - int64x2_t
      - uint64x1_t
      - uint64x2_t
    compose:
      - FnCall:
          - simd_or
          - - a
            - b

  - name: "veor{neon_type.no}"
    doc: Vector bitwise exclusive or (vector)
    arguments: ["a: {neon_type}", "b: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [veor]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [eor]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - int8x8_t
      - int8x16_t
      - int16x4_t
      - int16x8_t
      - int32x2_t
      - int32x4_t
      - uint8x8_t
      - uint8x16_t
      - uint16x4_t
      - uint16x8_t
      - uint32x2_t
      - uint32x4_t
      - int64x1_t
      - int64x2_t
      - uint64x1_t
      - uint64x2_t
    compose:
      - FnCall:
          - simd_xor
          - - a
            - b

  - name: "vabd{neon_type.no}"
    doc: Absolute difference between the arguments
    arguments: ["a: {neon_type}", "b: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vabd.{neon_type}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [sabd]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - int8x8_t
      - int8x16_t
      - int16x4_t
      - int16x8_t
      - int32x2_t
      - int32x4_t
    compose:
      - LLVMLink:
          name: "sabd.{neon_type}"
          links:
            - link: "llvm.aarch64.neon.sabd.{neon_type}"
              arch: aarch64,arm64ec
            - link: "llvm.arm.neon.vabds.{neon_type}"
              arch: arm

  - name: "vabd{neon_type.no}"
    doc: Absolute difference between the arguments
    arguments: ["a: {neon_type}", "b: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vabd.{neon_type}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [uabd]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - uint8x8_t
      - uint8x16_t
      - uint16x4_t
      - uint16x8_t
      - uint32x2_t
      - uint32x4_t
    compose:
      - LLVMLink:
          name: "uabd.{neon_type}"
          links:
            - link: "llvm.aarch64.neon.uabd.{neon_type}"
              arch: aarch64,arm64ec
            - link: "llvm.arm.neon.vabdu.{neon_type}"
              arch: arm

  - name: "vabd{neon_type.no}"
    doc: Absolute difference between the arguments of Floating
    arguments: ["a: {neon_type}", "b: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vabd.f32"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fabd]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - float32x2_t
      - float32x4_t
    compose:
      - LLVMLink:
          name: "fabd.{neon_type}"
          links:
            - link: "llvm.arm.neon.vabds.{neon_type}"
              arch: arm
            - link: "llvm.aarch64.neon.fabd.{neon_type}"
              arch: aarch64,arm64ec

  - name: "vabd{neon_type.no}"
    doc: Absolute difference between the arguments of Floating
    arguments: ["a: {neon_type}", "b: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vabd.f16"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fabd]]}]]
      - *neon-fp16
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    safety: safe
    types:
      - float16x4_t
      - float16x8_t
    compose:
      - LLVMLink:
          name: "fabd.{neon_type}"
          links:
            - link: "llvm.arm.neon.vabds.{neon_type}"
              arch: arm
            - link: "llvm.aarch64.neon.fabd.{neon_type}"
              arch: aarch64,arm64ec

  - name: "vabdl{neon_type[0].noq}"
    doc: Signed Absolute difference Long
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall:
          - cfg_attr
          - - FnCall:
                - all
                - - test
                  - 'target_arch = "arm"'
            - FnCall:
                - assert_instr
                - - '"vabdl.{neon_type[0]}"'
      - FnCall:
          - cfg_attr
          - - FnCall:
                - all
                - - test
                  - FnCall:
                      - any
                      - - 'target_arch = "aarch64"'
                        - 'target_arch = "arm64ec"'
            - FnCall:
                - assert_instr
                - - sabdl
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [int8x8_t, int16x8_t, uint8x8_t]
      - [int16x4_t, int32x4_t, uint16x4_t]
      - [int32x2_t, int64x2_t, uint32x2_t]
    compose:
      - Let:
          - c
          - "{neon_type[2]}"
          - FnCall:
              - simd_cast
              - - FnCall:
                    - "vabd_{neon_type[0]}"
                    - - a
                      - b
      - FnCall:
          - simd_cast
          - - c

  - name: "vceq{neon_type[0].no}"
    doc: "Compare bitwise Equal (vector)"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vceq{type[2]}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [cmeq]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [uint8x8_t, uint8x8_t, ".i8"]
      - [uint8x16_t, uint8x16_t, ".i8"]
      - [int8x8_t, uint8x8_t, ".i8"]
      - [int8x16_t, uint8x16_t, ".i8"]
      - [poly8x8_t, uint8x8_t, ".i8"]
      - [poly8x16_t, uint8x16_t, ".i8"]
      - [uint16x4_t, uint16x4_t, ".i16"]
      - [uint16x8_t, uint16x8_t, ".i16"]
      - [int16x4_t, uint16x4_t, ".i16"]
      - [int16x8_t, uint16x8_t, ".i16"]
      - [uint32x2_t, uint32x2_t, ".i32"]
      - [uint32x4_t, uint32x4_t, ".i32"]
      - [int32x2_t, uint32x2_t, ".i32"]
      - [int32x4_t, uint32x4_t, ".i32"]
    compose:
      - FnCall: [simd_eq, [a, b]]

  - name: "vceq{neon_type[0].no}"
    doc: "Floating-point compare equal"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vceq.f32"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fcmeq]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [float32x2_t, uint32x2_t]
      - [float32x4_t, uint32x4_t]
    compose:
      - FnCall: [simd_eq, [a, b]]


  - name: "vceq{neon_type[0].no}"
    doc: "Floating-point compare equal"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vceq.f16"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fcmeq]]}]]
      - *neon-fp16
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    safety: safe
    types:
      - [float16x4_t, uint16x4_t]
      - [float16x8_t, uint16x8_t]
    compose:
      - FnCall: [simd_eq, [a, b]]

  - name: "vtst{neon_type[0].no}"
    doc: "Signed compare bitwise Test bits nonzero"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vtst]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [cmtst]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [int8x8_t, uint8x8_t, i8x8, 'i8x8::new(0, 0, 0, 0, 0, 0, 0, 0)']
      - [int8x16_t, uint8x16_t, i8x16, 'i8x16::new(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)']
      - [int16x4_t, uint16x4_t, i16x4, 'i16x4::new(0, 0, 0, 0)']
      - [int16x8_t, uint16x8_t, i16x8, 'i16x8::new(0, 0, 0, 0, 0, 0, 0, 0)']
      - [int32x2_t, uint32x2_t, i32x2, 'i32x2::new(0, 0)']
      - [int32x4_t, uint32x4_t, i32x4, 'i32x4::new(0, 0, 0, 0)']
      - [poly8x8_t, uint8x8_t, i8x8, 'i8x8::new(0, 0, 0, 0, 0, 0, 0, 0)']
      - [poly8x16_t, uint8x16_t, i8x16, 'i8x16::new(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)']
      - [poly16x4_t, uint16x4_t, i16x4, 'i16x4::new(0, 0, 0, 0)']
      - [poly16x8_t, uint16x8_t, i16x8, 'i16x8::new(0, 0, 0, 0, 0, 0, 0, 0)']
    compose:
      - Let: [c, "{neon_type[0]}", {FnCall: [simd_and, [a, b]]}]
      - Let: [d, "{type[2]}", "{type[3]}"]
      - FnCall: [simd_ne, [c, {FnCall: [transmute, [d]]}]]

  - name: "vabs{neon_type.no}"
    doc: "Floating-point absolute value"
    arguments: ["a: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vabs]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fabs]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - float32x2_t
      - float32x4_t
    compose:
      - FnCall: [simd_fabs, [a]]

  - name: "vabs{neon_type.no}"
    doc: "Floating-point absolute value"
    arguments: ["a: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vabs]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fabs]]}]]
      - *neon-fp16
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    safety: safe
    types:
      - float16x4_t
      - float16x8_t
    compose:
      - FnCall: [simd_fabs, [a]]

  - name: "vabs{type[0]}"
    doc: "Floating-point absolute value"
    arguments: ["a: {type[1]}"]
    return_type: "{type[1]}"
    attr:
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vabs]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fabs]]}]]
      - *neon-fp16
      - *neon-unstable-f16
      - *target-not-arm64ec
    safety: safe
    types:
      - ['h_f16', 'f16']
    compose:
      - FnCall:
          - simd_extract!
          - - FnCall:
                - "vabs_{type[1]}"
                - - FnCall: ["vdup_n_{type[1]}", [a]]
            - 0

  - name: "vcgt{neon_type[0].no}"
    doc: "Compare signed greater than"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vcgt.{type[2]}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [cmgt]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [int8x8_t, uint8x8_t, "s8"]
      - [int8x16_t, uint8x16_t, "s8"]
      - [int16x4_t, uint16x4_t, s16]
      - [int16x8_t, uint16x8_t, s16]
      - [int32x2_t, uint32x2_t, "s32"]
      - [int32x4_t, uint32x4_t, "s32"]
    compose:
      - FnCall: [simd_gt, [a, b]]

  - name: "vcgt{neon_type.no}"
    doc: "Compare unsigned greater than"
    arguments: ["a: {neon_type}", "b: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vcgt.{neon_type}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [cmhi]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - uint8x8_t
      - uint8x16_t
      - uint16x4_t
      - uint16x8_t
      - uint32x2_t
      - uint32x4_t
    compose:
      - FnCall: [simd_gt, [a, b]]

  - name: "vcgt{neon_type[0].no}"
    doc: "Floating-point compare greater than"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vcgt.f32"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fcmgt]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [float32x2_t, uint32x2_t]
      - [float32x4_t, uint32x4_t]
    compose:
      - FnCall: [simd_gt, [a, b]]


  - name: "vcgt{neon_type[0].no}"
    doc: "Floating-point compare greater than"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vcgt.f16"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fcmgt]]}]]
      - *neon-fp16
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    safety: safe
    types:
      - [float16x4_t, uint16x4_t]
      - [float16x8_t, uint16x8_t]
    compose:
      - FnCall: [simd_gt, [a, b]]


  - name: "vcgtz{neon_type[0].no}"
    doc: "Floating-point compare greater than zero"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vcgt.f16"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fcmgt]]}]]
      - *neon-fp16
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    safety: safe
    types:
      - [float16x4_t, uint16x4_t, f16x4, 'f16x4::new(0.0, 0.0, 0.0, 0.0)']
      - [float16x8_t, uint16x8_t, f16x8, 'f16x8::new(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)']
    compose:
      - Let: [b, "{type[2]}", "{type[3]}"]
      - FnCall: [simd_gt, [a, {FnCall: [transmute, [b]]}]]

  - name: "vclt{neon_type[0].no}"
    doc: "Compare signed less than"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vcgt.{neon_type[0]}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [cmgt]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [int8x8_t, uint8x8_t]
      - [int8x16_t, uint8x16_t]
      - [int16x4_t, uint16x4_t]
      - [int16x8_t, uint16x8_t]
      - [int32x2_t, uint32x2_t]
      - [int32x4_t, uint32x4_t]
    compose:
      - FnCall: [simd_lt, [a, b]]

  - name: "vcle{neon_type[0].no}"
    doc: "Compare signed less than or equal"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vcge.{neon_type[0]}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [cmge]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [int8x8_t, uint8x8_t]
      - [int8x16_t, uint8x16_t]
      - [int16x4_t, uint16x4_t]
      - [int16x8_t, uint16x8_t]
      - [int32x2_t, uint32x2_t]
      - [int32x4_t, uint32x4_t]
    compose:
      - FnCall: [simd_le, [a, b]]

  - name: "vcle{neon_type[0].no}"
    doc: "Floating-point compare less than or equal"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vcge.f32"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fcmge]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [float32x2_t, uint32x2_t]
      - [float32x4_t, uint32x4_t]
    compose:
      - FnCall: [simd_le, [a, b]]


  - name: "vcle{neon_type[0].no}"
    doc: "Floating-point compare less than or equal"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vcge.f16"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fcmge]]}]]
      - *neon-fp16
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    safety: safe
    types:
      - [float16x4_t, uint16x4_t]
      - [float16x8_t, uint16x8_t]
    compose:
      - FnCall: [simd_le, [a, b]]

  - name: "vclez{neon_type[0].no}"
    doc: "Floating-point compare less than or equal to zero"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vcle.f16"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fcmle]]}]]
      - *neon-fp16
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    safety: safe
    types:
      - [float16x4_t, uint16x4_t, f16x4, 'f16x4::new(0.0, 0.0, 0.0, 0.0)']
      - [float16x8_t, uint16x8_t, f16x8, 'f16x8::new(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)']
    compose:
      - Let: [b, "{type[2]}", "{type[3]}"]
      - FnCall:
          - simd_le
          - - a
            - FnCall: [transmute, [b]]

  - name: "vcge{neon_type[0].no}"
    doc: "Compare signed greater than or equal"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vcge.{neon_type[0]}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [cmge]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [int8x8_t, uint8x8_t]
      - [int8x16_t, uint8x16_t]
      - [int16x4_t, uint16x4_t]
      - [int16x8_t, uint16x8_t]
      - [int32x2_t, uint32x2_t]
      - [int32x4_t, uint32x4_t]
    compose:
      - FnCall: [simd_ge, [a, b]]

  - name: "vcls{neon_type.no}"
    doc: "Count leading sign bits"
    arguments: ["a: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vcls.{neon_type}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [cls]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - int8x8_t
      - int8x16_t
      - int16x4_t
      - int16x8_t
      - int32x2_t
      - int32x4_t
    compose:
      - LLVMLink:
          name: "vcls{neon_type.no}"
          links:
            - link: "llvm.arm.neon.vcls.{neon_type}"
              arch: arm
            - link: "llvm.aarch64.neon.cls.{neon_type}"
              arch: aarch64,arm64ec

  - name: "vcls{neon_type[0].no}"
    doc: "Count leading sign bits"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vcls]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [cls]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [uint8x8_t, int8x8_t]
      - [uint8x16_t, int8x16_t]
      - [uint16x4_t, int16x4_t]
      - [uint16x8_t, int16x8_t]
      - [uint32x2_t, int32x2_t]
      - [uint32x4_t, int32x4_t]
    compose:
      - FnCall:
          - "vcls{neon_type[1].no}"
          - - FnCall: [transmute, [a]]

  - name: "vclz{neon_type[0].no}"
    doc: "Count leading zero bits"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vclz.i8"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [clz]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [uint8x8_t, int8x8_t]
      - [uint8x16_t, int8x16_t]
    compose:
      - FnCall:
          - transmute
          - - FnCall:
                - "vclz{neon_type[1].no}"
                - - FnCall: [transmute, [a]]

  - name: "vclz{neon_type[0].no}"
    doc: "Count leading zero bits"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vclz{type[1]}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [clz]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [int8x8_t, '.i8']
      - [int8x16_t, '.i8']
      - [int16x4_t, '.i16']
      - [int16x8_t, '.i16']
      - [int32x2_t, '.i32']
      - [int32x4_t, '.i32']
    compose:
      - FnCall: [simd_ctlz, [a]]

  - name: "vclz{neon_type[0].no}"
    doc: "Count leading zero bits"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vclz{type[1]}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [clz]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [uint32x2_t, '.i32', int32x2_t]
      - [uint32x4_t, '.i32', int32x4_t]
      - [uint16x4_t, '.i16', int16x4_t]
      - [uint16x8_t, '.i16', int16x8_t]
    compose:
      - FnCall:
          - transmute
          - - FnCall:
                - "vclz{neon_type[2].no}"
                - - FnCall: [transmute, [a]]

  - name: "vcagt{neon_type[0].no}"
    doc: "Floating-point absolute compare greater than"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vacgt.f32"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [facgt]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [float32x2_t, uint32x2_t]
      - [float32x4_t, uint32x4_t]
    compose:
      - LLVMLink:
          name: "vcagt{neon_type[0].no}"
          links:
            - link: "llvm.arm.neon.vacgt.{neon_type[1]}.{neon_type[0]}"
              arch: arm
            - link: "llvm.aarch64.neon.facgt.{neon_type[1]}.{neon_type[0]}"
              arch: aarch64,arm64ec


  - name: "vcagt{neon_type[0].no}"
    doc: "Floating-point absolute compare greater than"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vacgt.f16"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [facgt]]}]]
      - *neon-fp16
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    safety: safe
    types:
      - [float16x4_t, uint16x4_t]
      - [float16x8_t, uint16x8_t]
    compose:
      - LLVMLink:
          name: "vcagt{neon_type[0].no}"
          links:
            - link: "llvm.arm.neon.vacgt.{neon_type[1]}.{neon_type[0]}"
              arch: arm
            - link: "llvm.aarch64.neon.facgt.{neon_type[1]}.{neon_type[0]}"
              arch: aarch64,arm64ec

  - name: "vcage{neon_type[0].no}"
    doc: "Floating-point absolute compare greater than or equal"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vacge.f32"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [facge]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [float32x2_t, uint32x2_t]
      - [float32x4_t, uint32x4_t]
    compose:
      - LLVMLink:
          name: "vcage{neon_type[0].no}"
          links:
            - link: "llvm.arm.neon.vacge.{neon_type[1]}.{neon_type[0]}"
              arch: arm
            - link: "llvm.aarch64.neon.facge.{neon_type[1]}.{neon_type[0]}"
              arch: aarch64,arm64ec

  - name: "vcage{neon_type[0].no}"
    doc: "Floating-point absolute compare greater than or equal"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vacge.f16"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [facge]]}]]
      - *neon-fp16
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    safety: safe
    types:
      - [float16x4_t, uint16x4_t]
      - [float16x8_t, uint16x8_t]
    compose:
      - LLVMLink:
          name: "vcage{neon_type[0].no}"
          links:
            - link: "llvm.arm.neon.vacge.{neon_type[1]}.{neon_type[0]}"
              arch: arm
            - link: "llvm.aarch64.neon.facge.{neon_type[1]}.{neon_type[0]}"
              arch: aarch64,arm64ec

  - name: "vcalt{neon_type[0].no}"
    doc: "Floating-point absolute compare less than"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vacgt.f32"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [facgt]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [float32x2_t, uint32x2_t]
      - [float32x4_t, uint32x4_t]
    compose:
      - FnCall: ["vcagt{neon_type[0].no}", [b, a]]

  - name: "vcalt{neon_type[0].no}"
    doc: "Floating-point absolute compare less than"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vacgt.f16"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [facgt]]}]]
      - *neon-fp16
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    safety: safe
    types:
      - [float16x4_t, uint16x4_t]
      - [float16x8_t, uint16x8_t]
    compose:
      - FnCall: ["vcagt{neon_type[0].no}", [b, a]]

  - name: "vcale{neon_type[0].no}"
    doc: "Floating-point absolute compare less than or equal"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vacge.f32"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [facge]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [float32x2_t, uint32x2_t]
      - [float32x4_t, uint32x4_t]
    compose:
      - FnCall: ["vcage{neon_type[0].no}", [b, a]]


  - name: "vcale{neon_type[0].no}"
    doc: "Floating-point absolute compare less than or equal"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vacge.f16"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [facge]]}]]
      - *neon-fp16
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    safety: safe
    types:
      - [float16x4_t, uint16x4_t]
      - [float16x8_t, uint16x8_t]
    compose:
      - FnCall: ["vcage{neon_type[0].no}", [b, a]]

  - name: "vcvt{neon_type[1].no}_{neon_type[0]}"
    doc: "Fixed-point convert to floating-point"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vcvt]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [scvtf]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [int32x2_t, float32x2_t]
      - [int32x4_t, float32x4_t]
    compose:
      - FnCall: [simd_cast, [a]]

  - name: "vcvt{neon_type[1].no}_{neon_type[0]}"
    doc: "Fixed-point convert to floating-point"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vcvt]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [scvtf]]}]]
      - *neon-fp16
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    safety: safe
    types:
      - [int16x4_t, float16x4_t]
      - [int16x8_t, float16x8_t]
    compose:
      - FnCall: [simd_cast, [a]]

  - name: "vcvt{neon_type[1].no}_{neon_type[0]}"
    doc: "Fixed-point convert to floating-point"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vcvt]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ucvtf]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [uint32x2_t, float32x2_t]
      - [uint32x4_t, float32x4_t]
    compose:
      - FnCall: [simd_cast, [a]]

  - name: "vcvt{neon_type[1].no}_{neon_type[0]}"
    doc: "Fixed-point convert to floating-point"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vcvt]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ucvtf]]}]]
      - *neon-fp16
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    safety: safe
    types:
      - [uint16x4_t, float16x4_t]
      - [uint16x8_t, float16x8_t]
    compose:
      - FnCall: [simd_cast, [a]]

  - name: "vcvt{neon_type[1].N}_{neon_type[0]}"
    doc: "Fixed-point convert to floating-point"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *target-is-arm
      - *enable-v7
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [vcvt, 'N = 2']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-arm-unstable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [uint32x2_t, float32x2_t]
      - [uint32x4_t, float32x4_t]
    compose:
      - FnCall: [static_assert!, ['N >= 1 && N <= 32']]
      - LLVMLink:
          name: "vcvt{neon_type[1].N}_{neon_type[0]}"
          arguments:
            - "a: {neon_type[0]}"
            - "n: i32"
          links:
            - link: "llvm.arm.neon.vcvtfxu2fp.{neon_type[1]}.{neon_type[0]}"
              arch: arm
      - FnCall: ["_vcvt{neon_type[1].N}_{neon_type[0]}", ["a", N], [], true]

  - name: "vcvt{neon_type[1].N}_{neon_type[0]}"
    doc: "Fixed-point convert to floating-point"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - FnCall: [cfg, [{FnCall: [not, ['target_arch = "arm"']]}]]
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [ucvtf, 'N = 2']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-stable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [uint32x2_t, float32x2_t]
      - [uint32x4_t, float32x4_t]
    compose:
      - FnCall: [static_assert!, ['N >= 1 && N <= 32']]
      - LLVMLink:
          name: "vcvt{neon_type[1].N}_{neon_type[0]}"
          arguments:
            - "a: {neon_type[0]}"
            - "n: i32"
          links:
            - link: "llvm.aarch64.neon.vcvtfxu2fp.{neon_type[1]}.{neon_type[0]}"
              arch: aarch64,arm64ec
      - FnCall: ["_vcvt{neon_type[1].N}_{neon_type[0]}", ["a", N], [], true]

  - name: "vcvt{neon_type[1].N}_{neon_type[0]}"
    doc: "Fixed-point convert to floating-point"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vcvt"', 'N = 1']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ucvtf, 'N = 1']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-fp16
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [uint16x4_t, float16x4_t]
      - [uint16x8_t, float16x8_t]
    compose:
      - FnCall: [static_assert!, ['N >= 1 && N <= 16']]
      - LLVMLink:
          name: "vcvt{neon_type[1].N}_{neon_type[0]}"
          arguments:
            - "a: {neon_type[0]}"
            - "n: i32"
          links:
            - link: "llvm.arm.neon.vcvtfxu2fp.{neon_type[1]}.{neon_type[0]}"
              arch: arm
            - link: "llvm.aarch64.neon.vcvtfxu2fp.{neon_type[1]}.{neon_type[0]}"
              arch: aarch64,arm64ec
      - FnCall: ["_vcvt{neon_type[1].N}_{neon_type[0]}", ["a", N], [], true]


  - name: "vcvt{neon_type[1].N}_{neon_type[0]}"
    doc: "Floating-point convert to signed fixed-point"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vcvt"', 'N = 1']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fcvtzs, 'N = 1']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-fp16
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [float16x4_t, int16x4_t]
      - [float16x8_t, int16x8_t]
    compose:
      - FnCall: [static_assert!, ['N >= 1 && N <= 16']]
      - LLVMLink:
          name: "vcvt{neon_type[1].N}_{neon_type[0]}"
          arguments:
            - "a: {neon_type[0]}"
            - "n: i32"
          links:
            - link: "llvm.arm.neon.vcvtfp2fxs.{neon_type[1]}.{neon_type[0]}"
              arch: arm
            - link: "llvm.aarch64.neon.vcvtfp2fxs.{neon_type[1]}.{neon_type[0]}"
              arch: aarch64,arm64ec
      - FnCall: ["_vcvt{neon_type[1].N}_{neon_type[0]}", [a, N], [], true]


  - name: "vcvt{neon_type[1].N}_{neon_type[0]}"
    doc: "Fixed-point convert to unsigned fixed-point, rounding toward zero"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vcvt"', 'N = 1']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fcvtzu, 'N = 1']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-fp16
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [float16x4_t, uint16x4_t]
      - [float16x8_t, uint16x8_t]
    compose:
      - FnCall: [static_assert!, ['N >= 1 && N <= 16']]
      - LLVMLink:
          name: "vcvt{neon_type[1].N}_{neon_type[0]}"
          arguments:
            - "a: {neon_type[0]}"
            - "n: i32"
          links:
            - link: "llvm.arm.neon.vcvtfp2fxu.{neon_type[1]}.{neon_type[0]}"
              arch: arm
            - link: "llvm.aarch64.neon.vcvtfp2fxu.{neon_type[1]}.{neon_type[0]}"
              arch: aarch64,arm64ec
      - FnCall: ["_vcvt{neon_type[1].N}_{neon_type[0]}", ["a", N], [], true]

  - name: "vcvt{neon_type[1].N}_{neon_type[0]}"
    doc: "Fixed-point convert to floating-point"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *target-is-arm
      - *enable-v7
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [vcvt, 'N = 2']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-arm-unstable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [int32x2_t, float32x2_t]
      - [int32x4_t, float32x4_t]
    compose:
      - FnCall: [static_assert!, ['N >= 1 && N <= 32']]
      - LLVMLink:
          name: "vcvt{neon_type[1].N}_{neon_type[0]}"
          arguments:
            - "a: {neon_type[0]}"
            - "n: i32"
          links:
            - link: "llvm.arm.neon.vcvtfxs2fp.{neon_type[1]}.{neon_type[0]}"
              arch: arm
      - FnCall: ["_vcvt{neon_type[1].N}_{neon_type[0]}", [a, N], [], true]


  - name: "vcvt{neon_type[1].N}_{neon_type[0]}"
    doc: "Fixed-point convert to floating-point"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vcvt"', 'N = 1']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [scvtf, 'N = 1']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-fp16
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [int16x4_t, float16x4_t]
      - [int16x8_t, float16x8_t]
    compose:
      - FnCall: [static_assert!, ['N >= 1 && N <= 16']]
      - LLVMLink:
          name: "vcvt{neon_type[1].N}_{neon_type[0]}"
          arguments:
            - "a: {neon_type[0]}"
            - "n: i32"
          links:
            - link: "llvm.arm.neon.vcvtfxs2fp.{neon_type[1]}.{neon_type[0]}"
              arch: arm
            - link: "llvm.aarch64.neon.vcvtfxs2fp.{neon_type[1]}.{neon_type[0]}"
              arch: aarch64,arm64ec
      - FnCall: ["_vcvt{neon_type[1].N}_{neon_type[0]}", [a, N], [], true]

  - name: "vcvt{neon_type[1].N}_{neon_type[0]}"
    doc: "Fixed-point convert to floating-point"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - FnCall: [cfg, [{FnCall: [not, ['target_arch = "arm"']]}]]
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [scvtf, 'N = 2']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-stable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [int32x2_t, float32x2_t]
      - [int32x4_t, float32x4_t]
    compose:
      - FnCall: [static_assert!, ['N >= 1 && N <= 32']]
      - LLVMLink:
          name: "vcvt{neon_type[1].N}_{neon_type[0]}"
          arguments:
            - "a: {neon_type[0]}"
            - "n: i32"
          links:
            - link: "llvm.aarch64.neon.vcvtfxs2fp.{neon_type[1]}.{neon_type[0]}"
              arch: aarch64,arm64ec
      - FnCall: ["_vcvt{neon_type[1].N}_{neon_type[0]}", [a, N], [], true]

  - name: "vcvt{type[2]}"
    doc: "Floating-point convert to fixed-point, rounding toward zero"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *target-is-arm
      - *enable-v7
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [vcvt, 'N = 2']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-arm-unstable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [float32x2_t, int32x2_t, _n_s32_f32]
      - [float32x4_t, int32x4_t, q_n_s32_f32]
    compose:
      - FnCall: [static_assert!, ['N >= 1 && N <= 32']]
      - LLVMLink:
          name: "vcvt{type[2]}"
          arguments: ["a: {type[0]}", "n: i32"]
          links:
            - link: "llvm.arm.neon.vcvtfp2fxs.{neon_type[1]}.{neon_type[0]}"
              arch: arm
      - FnCall: ["_vcvt{type[2]}", [a, N], [], true]

  - name: "vcvt{type[2]}"
    doc: "Floating-point convert to fixed-point, rounding toward zero"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *target-is-arm
      - *enable-v7
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [vcvt, 'N = 2']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-arm-unstable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [float32x2_t, uint32x2_t, _n_u32_f32]
      - [float32x4_t, uint32x4_t, q_n_u32_f32]
    compose:
      - FnCall: [static_assert!, ['N >= 1 && N <= 32']]
      - LLVMLink:
          name: "vcvt{type[2]}"
          arguments: ["a: {type[0]}", "n: i32"]
          links:
            - link: "llvm.arm.neon.vcvtfp2fxu.{neon_type[1]}.{neon_type[0]}"
              arch: arm
      - FnCall: ["_vcvt{type[2]}", [a, N], [], true]

  - name: "vcvt{type[2]}"
    doc: "Floating-point convert to fixed-point, rounding toward zero"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - FnCall: [cfg, [{FnCall: [not, ['target_arch = "arm"']]}]]
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [fcvtzs, 'N = 2']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-stable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [float32x2_t, int32x2_t, _n_s32_f32]
      - [float32x4_t, int32x4_t, q_n_s32_f32]
    compose:
      - FnCall: [static_assert!, ['N >= 1 && N <= 32']]
      - LLVMLink:
          name: "vcvt{type[2]}"
          arguments: ["a: {type[0]}", "n: i32"]
          links:
            - link: "llvm.aarch64.neon.vcvtfp2fxs.{neon_type[1]}.{neon_type[0]}"
              arch: aarch64,arm64ec
      - FnCall: ["_vcvt{type[2]}", [a, N], [], true]

  - name: "vcvt{type[2]}"
    doc: "Floating-point convert to fixed-point, rounding toward zero"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - FnCall: [cfg, [{FnCall: [not, ['target_arch = "arm"']]}]]
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [fcvtzu, 'N = 2']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-stable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [float32x2_t, uint32x2_t, _n_u32_f32]
      - [float32x4_t, uint32x4_t, q_n_u32_f32]
    compose:
      - FnCall: [static_assert!, ['N >= 1 && N <= 32']]
      - LLVMLink:
          name: "vcvt{type[2]}"
          arguments:
            - "a: {neon_type[0]}"
            - "n: i32"
          links:
            - link: "llvm.aarch64.neon.vcvtfp2fxu.{neon_type[1]}.{neon_type[0]}"
              arch: aarch64,arm64ec
      - FnCall: ["_vcvt{type[2]}", [a, N], [], true]

  - name: "vdup{type[0]}"
    doc: "Set all vector lanes to the same value"
    arguments: ["a: {neon_type[1]}"]
    return_type: "{neon_type[2]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vdup.8"', 'N = 4']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [dup, 'N = 4']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [_lane_s8, int8x8_t, int8x8_t, '3', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]']
      - [q_lane_s8, int8x8_t, int8x16_t, '3', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]']
      - [_lane_u8, uint8x8_t, uint8x8_t, '3', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]']
      - [q_lane_u8, uint8x8_t, uint8x16_t, '3', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]']
      - [_lane_p8, poly8x8_t, poly8x8_t, '3', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]']
      - [q_lane_p8, poly8x8_t, poly8x16_t, '3', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]']
    compose:
      - FnCall: [static_assert_uimm_bits!, [N, "{type[3]}"]]
      - FnCall: [simd_shuffle!, [a, a, "{type[4]}"]]

  - name: "vdup{type[0]}"
    doc: "Set all vector lanes to the same value"
    arguments: ["a: {neon_type[1]}"]
    return_type: "{neon_type[2]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vdup.8"', 'N = 8']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [dup, 'N = 8']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [q_laneq_s8, int8x16_t, int8x16_t, '4', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]']
      - [_laneq_s8, int8x16_t, int8x8_t, '4', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]']
      - [q_laneq_u8, uint8x16_t, uint8x16_t, '4', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]']
      - [_laneq_u8, uint8x16_t, uint8x8_t, '4', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]']
      - [q_laneq_p8, poly8x16_t, poly8x16_t, '4', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]']
      - [_laneq_p8, poly8x16_t, poly8x8_t, '4', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]']
    compose:
      - FnCall: [static_assert_uimm_bits!, [N, "{type[3]}"]]
      - FnCall: [simd_shuffle!, [a, a, "{type[4]}"]]

  - name: "vdup{type[0]}"
    doc: "Set all vector lanes to the same value"
    arguments: ["a: {neon_type[1]}"]
    return_type: "{neon_type[2]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vdup.16"', 'N = 2']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [dup, 'N = 2']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [_lane_s16, int16x4_t, int16x4_t, '2', '[N as u32, N as u32, N as u32, N as u32]']
      - [q_lane_s16, int16x4_t, int16x8_t, '2', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]']
      - [_lane_u16, uint16x4_t, uint16x4_t, '2', '[N as u32, N as u32, N as u32, N as u32]']
      - [q_lane_u16, uint16x4_t, uint16x8_t, '2', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]']
      - [_lane_p16, poly16x4_t, poly16x4_t, '2', '[N as u32, N as u32, N as u32, N as u32]']
      - [q_lane_p16, poly16x4_t, poly16x8_t, '2', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]']
    compose:
      - FnCall: [static_assert_uimm_bits!, [N, "{type[3]}"]]
      - FnCall: [simd_shuffle!, [a, a, "{type[4]}"]]

  - name: "vdup{type[0]}"
    doc: "Set all vector lanes to the same value"
    arguments: ["a: {neon_type[1]}"]
    return_type: "{neon_type[2]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vdup.16"', 'N = 4']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [dup, 'N = 4']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [q_laneq_s16, int16x8_t, int16x8_t, '3', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]']
      - [_laneq_s16, int16x8_t, int16x4_t, '3', '[N as u32, N as u32, N as u32, N as u32]']
      - [q_laneq_u16, uint16x8_t, uint16x8_t, '3', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]']
      - [_laneq_u16, uint16x8_t, uint16x4_t, '3', '[N as u32, N as u32, N as u32, N as u32]']
      - [q_laneq_p16, poly16x8_t, poly16x8_t, '3', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]']
      - [_laneq_p16, poly16x8_t, poly16x4_t, '3', '[N as u32, N as u32, N as u32, N as u32]']
    compose:
      - FnCall: [static_assert_uimm_bits!, [N, "{type[3]}"]]
      - FnCall: [simd_shuffle!, [a, a, "{type[4]}"]]


  - name: "vdup{type[0]}"
    doc: "Set all vector lanes to the same value"
    arguments: ["a: {neon_type[1]}"]
    return_type: "{neon_type[2]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vdup.16"', 'N = 4']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [dup, 'N = 4']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *arm-fp16
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [q_laneq_f16, float16x8_t, float16x8_t, '3', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]']
      - [_laneq_f16, float16x8_t, float16x4_t, '3', '[N as u32, N as u32, N as u32, N as u32]']
    compose:
      - FnCall: [static_assert_uimm_bits!, [N, "{type[3]}"]]
      - FnCall: [simd_shuffle!, [a, a, "{type[4]}"]]

  - name: "vdup{type[3]}{neon_type[0]}"
    doc: "Create a new vector with all lanes set to a value"
    arguments: ["a: {type[1]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vdup.16"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [dup]]}]]
      - *arm-fp16
      - *neon-unstable-f16
      - *target-not-arm64ec
    safety: safe
    types:
      - [float16x4_t, f16, 'float16x4', '_n_']
      - [float16x8_t, f16, 'float16x8', 'q_n_']
    compose:
      - "{type[2]}_t::splat(a)"

  - name: "vdup{type[0]}"
    doc: "Set all vector lanes to the same value"
    arguments: ["a: {neon_type[1]}"]
    return_type: "{neon_type[2]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vdup.16"', 'N = 2']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [dup, 'N = 2']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *arm-fp16
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [_lane_f16, float16x4_t, float16x4_t, '2', '[N as u32, N as u32, N as u32, N as u32]']
      - [q_lane_f16, float16x4_t, float16x8_t, '2', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]']
    compose:
      - FnCall: [static_assert_uimm_bits!, [N, "{type[3]}"]]
      - FnCall: [simd_shuffle!, [a, a, "{type[4]}"]]


  - name: "vdup{type[0]}"
    doc: "Set all vector lanes to the same value"
    arguments: ["a: {neon_type[1]}"]
    return_type: "{neon_type[2]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vdup.32"', 'N = 1']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [dup, 'N = 1']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [_lane_s32, int32x2_t, int32x2_t, '1', '[N as u32, N as u32]']
      - [q_lane_s32, int32x2_t, int32x4_t, '1', '[N as u32, N as u32, N as u32, N as u32]']
      - [_lane_u32, uint32x2_t, uint32x2_t, '1', '[N as u32, N as u32]']
      - [q_lane_u32, uint32x2_t, uint32x4_t, '1', '[N as u32, N as u32, N as u32, N as u32]']
      - [_lane_f32, float32x2_t, float32x2_t, '1', '[N as u32, N as u32]']
      - [q_lane_f32, float32x2_t, float32x4_t, '1', '[N as u32, N as u32, N as u32, N as u32]']
    compose:
      - FnCall: [static_assert_uimm_bits!, [N, "{type[3]}"]]
      - FnCall: [simd_shuffle!, [a, a, "{type[4]}"]]

  - name: "vdup{type[0]}"
    doc: "Set all vector lanes to the same value"
    arguments: ["a: {neon_type[1]}"]
    return_type: "{neon_type[2]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vdup.32"', 'N = 2']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [dup, 'N = 2']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [q_laneq_s32, int32x4_t, int32x4_t, '2', '[N as u32, N as u32, N as u32, N as u32]']
      - [_laneq_s32, int32x4_t, int32x2_t, '2', '[N as u32, N as u32]']
      - [q_laneq_u32, uint32x4_t, uint32x4_t, '2', '[N as u32, N as u32, N as u32, N as u32]']
      - [_laneq_u32, uint32x4_t, uint32x2_t, '2', '[N as u32, N as u32]']
      - [q_laneq_f32, float32x4_t, float32x4_t, '2', '[N as u32, N as u32, N as u32, N as u32]']
      - [_laneq_f32, float32x4_t, float32x2_t, '2', '[N as u32, N as u32]']
    compose:
      - FnCall: [static_assert_uimm_bits!, [N, "{type[3]}"]]
      - FnCall: [simd_shuffle!, [a, a, "{type[4]}"]]

  - name: "vdup{type[0]}"
    doc: "Set all vector lanes to the same value"
    arguments: ["a: {neon_type[1]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vmov, 'N = 1']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [dup, 'N = 1']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [q_laneq_s64, int64x2_t, '1', '[N as u32, N as u32]']
      - [q_laneq_u64, uint64x2_t, '1', '[N as u32, N as u32]']
    compose:
      - FnCall: [static_assert_uimm_bits!, [N, "{type[2]}"]]
      - FnCall: [simd_shuffle!, [a, a, "{type[3]}"]]

  - name: "vdup{type[0]}"
    doc: "Set all vector lanes to the same value"
    arguments: ["a: {neon_type[1]}"]
    return_type: "{neon_type[2]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vmov, 'N = 0']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [dup, 'N = 0']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [q_lane_s64, int64x1_t, int64x2_t]
      - [q_lane_u64, uint64x1_t, uint64x2_t]
    compose:
      - FnCall: [static_assert!, ['N == 0']]
      - FnCall: [simd_shuffle!, [a, a, '[N as u32, N as u32]']]

  - name: "vdup{type[0]}"
    doc: "Set all vector lanes to the same value"
    arguments: ["a: {neon_type[1]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [nop, 'N = 0']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [nop, 'N = 0']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [_lane_s64, int64x1_t]
      - [_lane_u64, uint64x1_t]
    compose:
      - FnCall: [static_assert!, ['N == 0']]
      - Identifier: [a, Symbol]

  - name: "vdup{type[0]}"
    doc: "Set all vector lanes to the same value"
    arguments: ["a: {neon_type[1]}"]
    return_type: "{neon_type[2]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vmov, 'N = 1']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [nop, 'N = 1']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [_laneq_s64, int64x2_t, int64x1_t, '::<i64, _>']
      - [_laneq_u64, uint64x2_t, uint64x1_t, '::<u64, _>']
    compose:
      - FnCall: [static_assert_uimm_bits!, [N, 1]]
      - FnCall:
          - "transmute{type[3]}"
          - - FnCall: [simd_extract!, [a, 'N as u32']]

  - name: "vext{neon_type[0].no}"
    doc: "Extract vector from pair of vectors"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vext.8"', 'N = 7']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ext, 'N = 7']]}]]
      - FnCall: [rustc_legacy_const_generics, ['2']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [int8x8_t, ' static_assert_uimm_bits!(N, 3);', 'unsafe { match N & 0b111 { 0 => simd_shuffle!(a, b, [0, 1, 2, 3, 4, 5, 6, 7]), 1 => simd_shuffle!(a, b, [1, 2, 3, 4, 5, 6, 7, 8]), 2 => simd_shuffle!(a, b, [2, 3, 4, 5, 6, 7, 8, 9]), 3 => simd_shuffle!(a, b, [3, 4, 5, 6, 7, 8, 9, 10]), 4 => simd_shuffle!(a, b, [4, 5, 6, 7, 8, 9, 10, 11]), 5 => simd_shuffle!(a, b, [5, 6, 7, 8, 9, 10, 11, 12]), 6 => simd_shuffle!(a, b, [6, 7, 8, 9, 10, 11, 12, 13]), 7 => simd_shuffle!(a, b, [7, 8, 9, 10, 11, 12, 13, 14]), _ => unreachable_unchecked(), } }']
      - [int16x8_t, ' static_assert_uimm_bits!(N, 3);', 'unsafe { match N & 0b111 { 0 => simd_shuffle!(a, b, [0, 1, 2, 3, 4, 5, 6, 7]), 1 => simd_shuffle!(a, b, [1, 2, 3, 4, 5, 6, 7, 8]), 2 => simd_shuffle!(a, b, [2, 3, 4, 5, 6, 7, 8, 9]), 3 => simd_shuffle!(a, b, [3, 4, 5, 6, 7, 8, 9, 10]), 4 => simd_shuffle!(a, b, [4, 5, 6, 7, 8, 9, 10, 11]), 5 => simd_shuffle!(a, b, [5, 6, 7, 8, 9, 10, 11, 12]), 6 => simd_shuffle!(a, b, [6, 7, 8, 9, 10, 11, 12, 13]), 7 => simd_shuffle!(a, b, [7, 8, 9, 10, 11, 12, 13, 14]), _ => unreachable_unchecked(), } }']
      - [uint8x8_t, ' static_assert_uimm_bits!(N, 3);', 'unsafe { match N & 0b111 { 0 => simd_shuffle!(a, b, [0, 1, 2, 3, 4, 5, 6, 7]), 1 => simd_shuffle!(a, b, [1, 2, 3, 4, 5, 6, 7, 8]), 2 => simd_shuffle!(a, b, [2, 3, 4, 5, 6, 7, 8, 9]), 3 => simd_shuffle!(a, b, [3, 4, 5, 6, 7, 8, 9, 10]), 4 => simd_shuffle!(a, b, [4, 5, 6, 7, 8, 9, 10, 11]), 5 => simd_shuffle!(a, b, [5, 6, 7, 8, 9, 10, 11, 12]), 6 => simd_shuffle!(a, b, [6, 7, 8, 9, 10, 11, 12, 13]), 7 => simd_shuffle!(a, b, [7, 8, 9, 10, 11, 12, 13, 14]), _ => unreachable_unchecked(), } }']
      - [uint16x8_t, ' static_assert_uimm_bits!(N, 3);', 'unsafe { match N & 0b111 { 0 => simd_shuffle!(a, b, [0, 1, 2, 3, 4, 5, 6, 7]), 1 => simd_shuffle!(a, b, [1, 2, 3, 4, 5, 6, 7, 8]), 2 => simd_shuffle!(a, b, [2, 3, 4, 5, 6, 7, 8, 9]), 3 => simd_shuffle!(a, b, [3, 4, 5, 6, 7, 8, 9, 10]), 4 => simd_shuffle!(a, b, [4, 5, 6, 7, 8, 9, 10, 11]), 5 => simd_shuffle!(a, b, [5, 6, 7, 8, 9, 10, 11, 12]), 6 => simd_shuffle!(a, b, [6, 7, 8, 9, 10, 11, 12, 13]), 7 => simd_shuffle!(a, b, [7, 8, 9, 10, 11, 12, 13, 14]), _ => unreachable_unchecked(), } }']
      - [poly8x8_t, ' static_assert_uimm_bits!(N, 3);', 'unsafe { match N & 0b111 { 0 => simd_shuffle!(a, b, [0, 1, 2, 3, 4, 5, 6, 7]), 1 => simd_shuffle!(a, b, [1, 2, 3, 4, 5, 6, 7, 8]), 2 => simd_shuffle!(a, b, [2, 3, 4, 5, 6, 7, 8, 9]), 3 => simd_shuffle!(a, b, [3, 4, 5, 6, 7, 8, 9, 10]), 4 => simd_shuffle!(a, b, [4, 5, 6, 7, 8, 9, 10, 11]), 5 => simd_shuffle!(a, b, [5, 6, 7, 8, 9, 10, 11, 12]), 6 => simd_shuffle!(a, b, [6, 7, 8, 9, 10, 11, 12, 13]), 7 => simd_shuffle!(a, b, [7, 8, 9, 10, 11, 12, 13, 14]), _ => unreachable_unchecked(), } }']
      - [poly16x8_t, ' static_assert_uimm_bits!(N, 3);', 'unsafe { match N & 0b111 { 0 => simd_shuffle!(a, b, [0, 1, 2, 3, 4, 5, 6, 7]), 1 => simd_shuffle!(a, b, [1, 2, 3, 4, 5, 6, 7, 8]), 2 => simd_shuffle!(a, b, [2, 3, 4, 5, 6, 7, 8, 9]), 3 => simd_shuffle!(a, b, [3, 4, 5, 6, 7, 8, 9, 10]), 4 => simd_shuffle!(a, b, [4, 5, 6, 7, 8, 9, 10, 11]), 5 => simd_shuffle!(a, b, [5, 6, 7, 8, 9, 10, 11, 12]), 6 => simd_shuffle!(a, b, [6, 7, 8, 9, 10, 11, 12, 13]), 7 => simd_shuffle!(a, b, [7, 8, 9, 10, 11, 12, 13, 14]), _ => unreachable_unchecked(), } }']
    compose:
      - Identifier: ["{type[1]}", Symbol]
      - Identifier: ["{type[2]}", Symbol]

  - name: "vext{neon_type[0].no}"
    doc: "Extract vector from pair of vectors"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vext.8"', 'N = 15']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ext, 'N = 15']]}]]
      - FnCall: [rustc_legacy_const_generics, ['2']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [int8x16_t, ' static_assert_uimm_bits!(N, 4);', 'unsafe { match N & 0b1111 { 0 => simd_shuffle!(a, b, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]), 1 => simd_shuffle!(a, b, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]), 2 => simd_shuffle!(a, b, [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17]), 3 => simd_shuffle!(a, b, [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]), 4 => simd_shuffle!(a, b, [4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]), 5 => simd_shuffle!(a, b, [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]), 6 => simd_shuffle!(a, b, [6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21]), 7 => simd_shuffle!(a, b, [7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22]), 8 => simd_shuffle!(a, b, [8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]), 9 => simd_shuffle!(a, b, [9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]), 10 => simd_shuffle!(a, b, [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]), 11 => simd_shuffle!(a, b, [11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26]), 12 => simd_shuffle!(a, b, [12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27]), 13 => simd_shuffle!(a, b, [13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28]), 14 => simd_shuffle!(a, b, [14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29]), 15 => simd_shuffle!(a, b, [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]), _ => unreachable_unchecked(), } }']
      - [uint8x16_t, ' static_assert_uimm_bits!(N, 4);', 'unsafe { match N & 0b1111 { 0 => simd_shuffle!(a, b, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]), 1 => simd_shuffle!(a, b, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]), 2 => simd_shuffle!(a, b, [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17]), 3 => simd_shuffle!(a, b, [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]), 4 => simd_shuffle!(a, b, [4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]), 5 => simd_shuffle!(a, b, [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]), 6 => simd_shuffle!(a, b, [6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21]), 7 => simd_shuffle!(a, b, [7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22]), 8 => simd_shuffle!(a, b, [8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]), 9 => simd_shuffle!(a, b, [9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]), 10 => simd_shuffle!(a, b, [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]), 11 => simd_shuffle!(a, b, [11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26]), 12 => simd_shuffle!(a, b, [12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27]), 13 => simd_shuffle!(a, b, [13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28]), 14 => simd_shuffle!(a, b, [14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29]), 15 => simd_shuffle!(a, b, [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]), _ => unreachable_unchecked(), } }']
      - [poly8x16_t, ' static_assert_uimm_bits!(N, 4);', 'unsafe { match N & 0b1111 { 0 => simd_shuffle!(a, b, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]), 1 => simd_shuffle!(a, b, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]), 2 => simd_shuffle!(a, b, [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17]), 3 => simd_shuffle!(a, b, [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]), 4 => simd_shuffle!(a, b, [4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]), 5 => simd_shuffle!(a, b, [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]), 6 => simd_shuffle!(a, b, [6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21]), 7 => simd_shuffle!(a, b, [7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22]), 8 => simd_shuffle!(a, b, [8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]), 9 => simd_shuffle!(a, b, [9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]), 10 => simd_shuffle!(a, b, [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]), 11 => simd_shuffle!(a, b, [11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26]), 12 => simd_shuffle!(a, b, [12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27]), 13 => simd_shuffle!(a, b, [13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28]), 14 => simd_shuffle!(a, b, [14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29]), 15 => simd_shuffle!(a, b, [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]), _ => unreachable_unchecked(), } }']
    compose:
      - Identifier: ["{type[1]}", Symbol]
      - Identifier: ["{type[2]}", Symbol]

  - name: "vext{neon_type[0].no}"
    doc: "Extract vector from pair of vectors"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vext.8"', 'N = 3']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ext, 'N = 3']]}]]
      - FnCall: [rustc_legacy_const_generics, ['2']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [int16x4_t, 'static_assert_uimm_bits!(N, 2);', 'unsafe { match N & 0b11 { 0 => simd_shuffle!(a, b, [0, 1, 2, 3]), 1 => simd_shuffle!(a, b, [1, 2, 3, 4]), 2 => simd_shuffle!(a, b, [2, 3, 4, 5]), 3 => simd_shuffle!(a, b, [3, 4, 5, 6]), _ => unreachable_unchecked(), } }']
      - [int32x4_t, ' static_assert_uimm_bits!(N, 2);', 'unsafe { match N & 0b11 { 0 => simd_shuffle!(a, b, [0, 1, 2, 3]), 1 => simd_shuffle!(a, b, [1, 2, 3, 4]), 2 => simd_shuffle!(a, b, [2, 3, 4, 5]), 3 => simd_shuffle!(a, b, [3, 4, 5, 6]), _ => unreachable_unchecked(), } }']
      - [uint16x4_t, ' static_assert_uimm_bits!(N, 2);', 'unsafe { match N & 0b11 { 0 => simd_shuffle!(a, b, [0, 1, 2, 3]), 1 => simd_shuffle!(a, b, [1, 2, 3, 4]), 2 => simd_shuffle!(a, b, [2, 3, 4, 5]), 3 => simd_shuffle!(a, b, [3, 4, 5, 6]), _ => unreachable_unchecked(), } }']
      - [uint32x4_t, ' static_assert_uimm_bits!(N, 2);', 'unsafe { match N & 0b11 { 0 => simd_shuffle!(a, b, [0, 1, 2, 3]), 1 => simd_shuffle!(a, b, [1, 2, 3, 4]), 2 => simd_shuffle!(a, b, [2, 3, 4, 5]), 3 => simd_shuffle!(a, b, [3, 4, 5, 6]), _ => unreachable_unchecked(), } }']
      - [poly16x4_t, ' static_assert_uimm_bits!(N, 2);', 'unsafe { match N & 0b11 { 0 => simd_shuffle!(a, b, [0, 1, 2, 3]), 1 => simd_shuffle!(a, b, [1, 2, 3, 4]), 2 => simd_shuffle!(a, b, [2, 3, 4, 5]), 3 => simd_shuffle!(a, b, [3, 4, 5, 6]), _ => unreachable_unchecked(), } }']
      - [float32x4_t, ' static_assert_uimm_bits!(N, 2);', 'unsafe { match N & 0b11 { 0 => simd_shuffle!(a, b, [0, 1, 2, 3]), 1 => simd_shuffle!(a, b, [1, 2, 3, 4]), 2 => simd_shuffle!(a, b, [2, 3, 4, 5]), 3 => simd_shuffle!(a, b, [3, 4, 5, 6]), _ => unreachable_unchecked(), } }']
    compose:
      - Identifier: ["{type[1]}", Symbol]
      - Identifier: ["{type[2]}", Symbol]


  - name: "vext{neon_type[0].no}"
    doc: "Extract vector from pair of vectors"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vext.8"', 'N = 3']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ext, 'N = 3']]}]]
      - FnCall: [rustc_legacy_const_generics, ['2']]
      - *neon-fp16
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [float16x4_t, ' static_assert_uimm_bits!(N, 2); unsafe { match N & 0b11 { 0 => simd_shuffle!(a, b, [0, 1, 2, 3]), 1 => simd_shuffle!(a, b, [1, 2, 3, 4]), 2 => simd_shuffle!(a, b, [2, 3, 4, 5]), 3 => simd_shuffle!(a, b, [3, 4, 5, 6]), _ => unreachable_unchecked(), } }']
    compose:
      - Identifier: ["{type[1]}", Symbol]

  - name: "vext{neon_type[0].no}"
    doc: "Extract vector from pair of vectors"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vext.8"', 'N = 7']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ext, 'N = 7']]}]]
      - FnCall: [rustc_legacy_const_generics, ['2']]
      - *neon-fp16
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [float16x8_t, ' static_assert_uimm_bits!(N, 3); unsafe { match N & 0b111 { 0 => simd_shuffle!(a, b, [0, 1, 2, 3, 4, 5, 6, 7]), 1 => simd_shuffle!(a, b, [1, 2, 3, 4, 5, 6, 7, 8]), 2 => simd_shuffle!(a, b, [2, 3, 4, 5, 6, 7, 8, 9]), 3 => simd_shuffle!(a, b, [3, 4, 5, 6, 7, 8, 9, 10]), 4 => simd_shuffle!(a, b, [4, 5, 6, 7, 8, 9, 10, 11]), 5 => simd_shuffle!(a, b, [5, 6, 7, 8, 9, 10, 11, 12]), 6 => simd_shuffle!(a, b, [6, 7, 8, 9, 10, 11, 12, 13]), 7 => simd_shuffle!(a, b, [7, 8, 9, 10, 11, 12, 13, 14]), _ => unreachable_unchecked(), } }']
    compose:
      - Identifier: ["{type[1]}", Symbol]



  - name: "vext{neon_type[0].no}"
    doc: "Extract vector from pair of vectors"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vext.8"', 'N = 1']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ext, 'N = 1']]}]]
      - FnCall: [rustc_legacy_const_generics, ['2']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [int32x2_t, ' static_assert_uimm_bits!(N, 1);', 'unsafe { match N & 0b1 { 0 => simd_shuffle!(a, b, [0, 1]), 1 => simd_shuffle!(a, b, [1, 2]), _ => unreachable_unchecked(), } }']
      - [uint32x2_t, ' static_assert_uimm_bits!(N, 1);', 'unsafe { match N & 0b1 { 0 => simd_shuffle!(a, b, [0, 1]), 1 => simd_shuffle!(a, b, [1, 2]), _ => unreachable_unchecked(), } }']
      - [float32x2_t, ' static_assert_uimm_bits!(N, 1);', 'unsafe { match N & 0b1 { 0 => simd_shuffle!(a, b, [0, 1]), 1 => simd_shuffle!(a, b, [1, 2]), _ => unreachable_unchecked(), } }']
    compose:
      - Identifier: ["{type[1]}", Symbol]
      - Identifier: ["{type[2]}", Symbol]

  - name: "vext{neon_type[0].no}"
    doc: "Extract vector from pair of vectors"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vmov, 'N = 1']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ext, 'N = 1']]}]]
      - FnCall: [rustc_legacy_const_generics, ['2']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [int64x2_t, 'static_assert_uimm_bits!(N, 1);', 'unsafe { match N & 0b1 { 0 => simd_shuffle!(a, b, [0, 1]), 1 => simd_shuffle!(a, b, [1, 2]), _ => unreachable_unchecked(), } }']
      - [uint64x2_t, 'static_assert_uimm_bits!(N, 1);', 'unsafe { match N & 0b1 { 0 => simd_shuffle!(a, b, [0, 1]), 1 => simd_shuffle!(a, b, [1, 2]), _ => unreachable_unchecked(), } }']
    compose:
      - Identifier: ["{type[1]}", Symbol]
      - Identifier: ["{type[2]}", Symbol]

  - name: "vmla{neon_type[0].no}"
    doc: "Multiply-add to accumulator"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}", "c: {neon_type[0]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vmla{type[1]}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [mla]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [int8x8_t, ".i8"]
      - [int8x16_t, ".i8"]
      - [uint8x8_t, ".i8"]
      - [uint8x16_t, ".i8"]
      - [int16x4_t, ".i16"]
      - [int16x8_t, ".i16"]
      - [uint16x4_t, ".i16"]
      - [uint16x8_t, ".i16"]
      - [int32x2_t, ".i32"]
      - [int32x4_t, ".i32"]
      - [uint32x2_t, ".i32"]
      - [uint32x4_t, ".i32"]
    compose:
      - FnCall: [simd_add, [a, {FnCall: [simd_mul, [b, c]]}]]

  - name: "vmla{neon_type.no}"
    doc: "Floating-point multiply-add to accumulator"
    arguments: ["a: {neon_type}", "b: {neon_type}", "c: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vmla.f32"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fmul]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - float32x2_t
      - float32x4_t
    compose:
      - FnCall: [simd_add, [a, {FnCall: [simd_mul, [b, c]]}]]

  - name: "vmlal{neon_type[1].no}"
    doc: "Signed multiply-add long"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}", "c: {neon_type[1]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vmlal.{type[2]}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [smlal]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [int16x8_t, int8x8_t, "s8"]
      - [int32x4_t, int16x4_t, "s16"]
      - [int64x2_t, int32x2_t, "s32"]
    compose:
      - FnCall: [simd_add, [a, {FnCall: ["vmull_{type[2]}", [b, c]]}]]

  - name: "vmlal_n_{type[4]}"
    doc: "Vector widening multiply accumulate with scalar"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}", "c: {type[2]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vmlal.{type[4]}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [smlal]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [int32x4_t, int16x4_t, "i16", int32x4_t, 's16']
      - [int64x2_t, int32x2_t, "i32", int64x2_t, 's32']
    compose:
      - FnCall:
          - "vmlal{neon_type[1].noq}"
          - - a
            - b
            - FnCall: ["vdup_n_{neon_type[1]}", [c]]

  - name: "vmlal_n_{type[2]}"
    doc: "Vector widening multiply accumulate with scalar"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}", "c: {type[2]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vmlal.{type[2]}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [umlal]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [uint32x4_t, uint16x4_t, "u16", uint32x4_t]
      - [uint64x2_t, uint32x2_t, "u32", uint64x2_t]
    compose:
      - FnCall:
          - "vmlal{neon_type[1].noq}"
          - - a
            - b
            - FnCall: ["vdup_n_{neon_type[1]}", [c]]

  - name: "vmlal_lane{neon_type[2].no}"
    doc: "Vector widening multiply accumulate with scalar"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}", "c: {neon_type[2]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vmlal.{neon_type[1]}"', 'LANE = 1']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [smlal, 'LANE = 1']]}]]
      - FnCall: [rustc_legacy_const_generics, ['3']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const LANE: i32']
    safety: safe
    types:
      - [int32x4_t, int16x4_t, int16x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
      - [int32x4_t, int16x4_t, int16x8_t, '3', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
      - [int64x2_t, int32x2_t, int32x2_t, '1', '[LANE as u32, LANE as u32]']
      - [int64x2_t, int32x2_t, int32x4_t, '2', '[LANE as u32, LANE as u32]']
    compose:
      - FnCall: [static_assert_uimm_bits!, [LANE, "{type[3]}"]]
      - FnCall:
          - "vmlal_{neon_type[1]}"
          - - a
            - b
            - FnCall: [simd_shuffle!, [c, c, '{type[4]}']]

  - name: "vmlal_lane{neon_type[2].no}"
    doc: "Vector widening multiply accumulate with scalar"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}", "c: {neon_type[2]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vmlal.{neon_type[1]}"', 'LANE = 1']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [umlal, 'LANE = 1']]}]]
      - FnCall: [rustc_legacy_const_generics, ['3']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const LANE: i32']
    safety: safe
    types:
      - [uint32x4_t, uint16x4_t, uint16x4_t, uint32x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
      - [uint32x4_t, uint16x4_t, uint16x8_t, uint32x4_t, '3', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
      - [uint64x2_t, uint32x2_t, uint32x2_t, uint64x2_t, '1', '[LANE as u32, LANE as u32]']
      - [uint64x2_t, uint32x2_t, uint32x4_t, uint64x2_t, '2', '[LANE as u32, LANE as u32]']
    compose:
      - FnCall: [static_assert_uimm_bits!, [LANE, "{type[4]}"]]
      - FnCall:
          - "vmlal_{neon_type[1]}"
          - - a
            - b
            - FnCall: [simd_shuffle!, [c, c, '{type[5]}']]

  - name: "vmlal_{neon_type[1]}"
    doc: "Unsigned multiply-add long"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}", "c: {neon_type[1]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vmlal.{neon_type[1]}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [umlal]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [uint16x8_t, uint8x8_t]
      - [uint32x4_t, uint16x4_t]
      - [uint64x2_t, uint32x2_t]
    compose:
      - FnCall:
          - simd_add
          - - a
            - FnCall: ["vmull_{neon_type[1]}", [b, c]]

  - name: "vmls{neon_type[0].no}"
    doc: "Multiply-subtract from accumulator"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}", "c: {neon_type[0]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vmls{type[1]}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [mls]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [int8x8_t, '.i8']
      - [int8x16_t, '.i8']
      - [uint8x8_t, '.i8']
      - [uint8x16_t, '.i8']
      - [int16x4_t, ".i16"]
      - [int16x8_t, ".i16"]
      - [uint16x4_t, ".i16"]
      - [uint16x8_t, ".i16"]
      - [int32x2_t, ".i32"]
      - [int32x4_t, ".i32"]
      - [uint32x2_t, ".i32"]
      - [uint32x4_t, ".i32"]
    compose:
      - FnCall:
          - simd_sub
          - - a
            - FnCall: [simd_mul, [b, c]]

  - name: "vmlsl_{neon_type[1]}"
    doc: "Signed multiply-subtract long"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}", "c: {neon_type[1]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vmlsl.{neon_type[1]}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [smlsl]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [int16x8_t, int8x8_t]
      - [int32x4_t, int16x4_t]
      - [int64x2_t, int32x2_t]
    compose:
      - FnCall: [simd_sub, [a, {FnCall: ["vmull_{neon_type[1]}", [b, c]]}]]

  - name: "vmlsl_n_{neon_type[1]}"
    doc: "Vector widening multiply subtract with scalar"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}", "c: {type[2]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vmlsl.{neon_type[1]}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [smlsl]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [int32x4_t, int16x4_t, "i16"]
      - [int64x2_t, int32x2_t, "i32"]
    compose:
      - FnCall: ["vmlsl_{neon_type[1]}", [a, b, {FnCall: ["vdup_n_{neon_type[1]}", [c]]}]]

  - name: "vmlsl_n_{neon_type[1]}"
    doc: "Vector widening multiply subtract with scalar"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}", "c: {type[2]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vmlsl.{neon_type[1]}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [umlsl]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [uint32x4_t, uint16x4_t, "u16"]
      - [uint64x2_t, uint32x2_t, "u32"]
    compose:
      - FnCall: ["vmlsl_{neon_type[1]}", [a, b, {FnCall: ["vdup_n_{neon_type[1]}", [c]]}]]

  - name: "vmlsl_lane{neon_type[2].no}"
    doc: "Vector widening multiply subtract with scalar"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}", "c: {neon_type[2]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vmlsl.{neon_type[1]}"', 'LANE = 1']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [smlsl, 'LANE = 1']]}]]
      - FnCall: [rustc_legacy_const_generics, ['3']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const LANE: i32']
    safety: safe
    types:
      - [int32x4_t, int16x4_t, int16x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
      - [int32x4_t, int16x4_t, int16x8_t, '3', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
    compose:
      - FnCall: [static_assert_uimm_bits!, [LANE, '{type[3]}']]
      - FnCall:
          - "vmlsl_{neon_type[1]}"
          - - a
            - b
            - FnCall: [simd_shuffle!, [c, c, "{type[4]}"]]

  - name: "vmlsl_lane{neon_type[2].no}"
    doc: "Vector widening multiply subtract with scalar"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}", "c: {neon_type[2]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vmlsl.{neon_type[1]}"', 'LANE = 1']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [smlsl, 'LANE = 1']]}]]
      - FnCall: [rustc_legacy_const_generics, ['3']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const LANE: i32']
    safety: safe
    types:
      - [int64x2_t, int32x2_t, int32x2_t, '[LANE as u32, LANE as u32]', '1']
      - [int64x2_t, int32x2_t, int32x4_t, '[LANE as u32, LANE as u32]', '2']
    compose:
      - FnCall: [static_assert_uimm_bits!, [LANE, "{type[4]}"]]
      - FnCall:
          - "vmlsl_{neon_type[1]}"
          - - a
            - b
            - FnCall: [simd_shuffle!, [c, c, "{type[3]}"]]

  - name: "vmlsl_lane{neon_type[2].no}"
    doc: "Vector widening multiply subtract with scalar"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}", "c: {neon_type[2]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vmlsl.{neon_type[1]}"', 'LANE = 1']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [umlsl, 'LANE = 1']]}]]
      - FnCall: [rustc_legacy_const_generics, ['3']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const LANE: i32']
    safety: safe
    types:
      - [uint32x4_t, uint16x4_t, uint16x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
      - [uint32x4_t, uint16x4_t, uint16x8_t, '3', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
      - [uint64x2_t, uint32x2_t, uint32x2_t, '1', '[LANE as u32, LANE as u32]']
      - [uint64x2_t, uint32x2_t, uint32x4_t, '2', '[LANE as u32, LANE as u32]']
    compose:
      - FnCall: [static_assert_uimm_bits!, [LANE, "{type[3]}"]]
      - FnCall:
          - "vmlsl_{neon_type[1]}"
          - - a
            - b
            - FnCall: [simd_shuffle!, [c, c, "{type[4]}"]]

  - name: "vmlsl_{neon_type[1]}"
    doc: "Unsigned multiply-subtract long"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}", "c: {neon_type[1]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vmlsl.{neon_type[1]}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [umlsl]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [uint16x8_t, uint8x8_t]
      - [uint32x4_t, uint16x4_t]
      - [uint64x2_t, uint32x2_t]
    compose:
      - FnCall: [simd_sub, [a, {FnCall: ["vmull_{neon_type[1]}", [b, c]]}]]

  - name: "vneg{neon_type[0].no}"
    doc: Negate
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vneg.{type[1]}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [neg]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [int8x8_t, 's8']
      - [int8x16_t, 's8']
      - [int16x4_t, 's16']
      - [int16x8_t, 's16']
      - [int32x2_t, 's32']
      - [int32x4_t, 's32']
    compose:
      - FnCall: [simd_neg, [a]]

  - name: "vneg{neon_type[0].no}"
    doc: Negate
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vneg.{type[1]}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fneg]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [float32x2_t, 'f32']
      - [float32x4_t, 'f32']
    compose:
      - FnCall: [simd_neg, [a]]

  - name: "vneg{neon_type[0].no}"
    doc: Negate
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vneg.{type[1]}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fneg]]}]]
      - *neon-fp16
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    safety: safe
    types:
      - [float16x4_t, 'f16']
      - [float16x8_t, 'f16']
    compose:
      - FnCall: [simd_neg, [a]]

  - name: "vqneg{neon_type[0].no}"
    doc: Signed saturating negate
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vqneg.{type[1]}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [sqneg]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [int8x8_t, 's8', 'i8']
      - [int8x16_t, 's8', 'i8']
      - [int16x4_t, 's16', 'i16']
      - [int16x8_t, 's16', 'i16']
      - [int32x2_t, 's32', 'i32']
      - [int32x4_t, 's32', 'i32']
    compose:
      - LLVMLink:
          name: "sqneg.{neon_type[0]}"
          links:
            - link: "llvm.aarch64.neon.sqneg.v{neon_type[0].lane}{type[2]}"
              arch: aarch64,arm64ec
            - link: "llvm.arm.neon.vqneg.v{neon_type[0].lane}{type[2]}"
              arch: arm

  - name: "vqsub{neon_type[0].no}"
    doc: Saturating subtract
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vqsub.{type[1]}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [uqsub]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [uint8x8_t, u8, i8]
      - [uint8x16_t, u8, i8]
      - [uint16x4_t, u16, i16]
      - [uint16x8_t, u16, i16]
      - [uint32x2_t, u32, i32]
      - [uint32x4_t, u32, i32]
      - [uint64x1_t, u64, i64]
      - [uint64x2_t, u64, i64]
    compose:
      - FnCall:
        - simd_saturating_sub
        - - a
          - b

  - name: "vqsub{neon_type[0].no}"
    doc: Saturating subtract
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vqsub.{type[1]}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [sqsub]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [int8x8_t, s8, i8]
      - [int8x16_t, s8, i8]
      - [int16x4_t, s16, i16]
      - [int16x8_t, s16, i16]
      - [int32x2_t, s32, i32]
      - [int32x4_t, s32, i32]
      - [int64x1_t, s64, i64]
      - [int64x2_t, s64, i64]
    compose:
      - FnCall:
        - simd_saturating_sub
        - - a
          - b

  - name: "vhadd{neon_type.no}"
    doc: Halving add
    arguments: ["a: {neon_type}", "b: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v7
      - FnCall:
          - cfg_attr
          - - FnCall:
                - all
                - - test
                  - 'target_arch = "arm"'
            - FnCall:
                - assert_instr
                - - '"vhadd.{neon_type}"'
      - FnCall:
          - cfg_attr
          - - FnCall:
                - all
                - - test
                  - FnCall:
                      - any
                      - - 'target_arch = "aarch64"'
                        - 'target_arch = "arm64ec"'
            - FnCall:
                - assert_instr
                - - uhadd
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - uint8x8_t
      - uint8x16_t
      - uint16x4_t
      - uint16x8_t
      - uint32x2_t
      - uint32x4_t
    compose:
      - LLVMLink:
          name: "uhadd.{neon_type}"
          links:
            - link: "llvm.aarch64.neon.uhadd.{neon_type}"
              arch: aarch64,arm64ec
            - link: "llvm.arm.neon.vhaddu.{neon_type}"
              arch: arm

  - name: "vhadd{neon_type.no}"
    doc: Halving add
    arguments: ["a: {neon_type}", "b: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v7
      - FnCall:
          - cfg_attr
          - - FnCall:
                - all
                - - test
                  - 'target_arch = "arm"'
            - FnCall:
                - assert_instr
                - - '"vhadd.{neon_type}"'
      - FnCall:
          - cfg_attr
          - - FnCall:
                - all
                - - test
                  - FnCall:
                      - any
                      - - 'target_arch = "aarch64"'
                        - 'target_arch = "arm64ec"'
            - FnCall:
                - assert_instr
                - - shadd
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - int8x8_t
      - int8x16_t
      - int16x4_t
      - int16x8_t
      - int32x2_t
      - int32x4_t
    compose:
      - LLVMLink:
          name: "shadd.{neon_type}"
          links:
            - link: "llvm.aarch64.neon.shadd.{neon_type}"
              arch: aarch64,arm64ec
            - link: "llvm.arm.neon.vhadds.{neon_type}"
              arch: arm

  - name: "vrhadd{neon_type.no}"
    doc: Rounding halving add
    arguments: ["a: {neon_type}", "b: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vrhadd.{neon_type}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [srhadd]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - int8x8_t
      - int8x16_t
      - int16x4_t
      - int16x8_t
      - int32x2_t
      - int32x4_t
    compose:
      - LLVMLink:
          name: "vrhadd.{neon_type}"
          links:
            - link: "llvm.aarch64.neon.srhadd.{neon_type}"
              arch: aarch64,arm64ec
            - link: "llvm.arm.neon.vrhadds.{neon_type}"
              arch: arm

  - name: "vrhadd{neon_type.no}"
    doc: Rounding halving add
    arguments: ["a: {neon_type}", "b: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vrhadd.{neon_type}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [urhadd]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - uint8x8_t
      - uint8x16_t
      - uint16x4_t
      - uint16x8_t
      - uint32x2_t
      - uint32x4_t
    compose:
      - LLVMLink:
          name: "vrhaddu.{neon_type}"
          links:
            - link: "llvm.aarch64.neon.urhadd.{neon_type}"
              arch: aarch64,arm64ec
            - link: "llvm.arm.neon.vrhaddu.{neon_type}"
              arch: arm

  - name: "vrndn{neon_type.no}"
    doc: "Floating-point round to integral, to nearest with ties to even"
    arguments: ["a: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - FnCall: [cfg_attr, ['target_arch = "arm"', {FnCall: [target_feature, ['enable = "fp-armv8,v8"']]}]]
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vrintn]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [frintn]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - float32x2_t
      - float32x4_t
    compose:
      - LLVMLink:
          name: "llvm.frinn.{neon_type}"
          links:
            - link: "llvm.roundeven.{neon_type}"
              arch: aarch64,arm64ec,arm

  - name: "vrndn{neon_type.no}"
    doc: "Floating-point round to integral, to nearest with ties to even"
    arguments: ["a: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - FnCall: [cfg_attr, ['target_arch = "arm"', {FnCall: [target_feature, ['enable = "fp-armv8,v8"']]}]]
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vrintn]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [frintn]]}]]
      - *neon-fp16
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    safety: safe
    types:
      - float16x4_t
      - float16x8_t
    compose:
      - LLVMLink:
          name: "llvm.frinn.{neon_type}"
          links:
            - link: "llvm.roundeven.{neon_type}"
              arch: aarch64,arm64ec,arm

  - name: "vqadd{neon_type.no}"
    doc: Saturating add
    arguments: ["a: {neon_type}", "b: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vqadd.{neon_type}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [uqadd]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - uint8x8_t
      - uint8x16_t
      - uint16x4_t
      - uint16x8_t
      - uint32x2_t
      - uint32x4_t
      - uint64x1_t
      - uint64x2_t
    compose:
      - FnCall:
        - simd_saturating_add
        - - a
          - b

  - name: "vqadd{neon_type.no}"
    doc: Saturating add
    arguments: ["a: {neon_type}", "b: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vqadd.{neon_type}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [sqadd]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - int8x8_t
      - int8x16_t
      - int16x4_t
      - int16x8_t
      - int32x2_t
      - int32x4_t
      - int64x1_t
      - int64x2_t
    compose:
      - FnCall:
        - simd_saturating_add
        - - a
          - b

  - name: "vld1{neon_type[1].no}"
    doc: "Load multiple single-element structures to one, two, three, or four registers"
    arguments: ["a: {type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vld]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ld]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety:
      unsafe: [neon]
    types:
      - ["*const f32", float32x2x2_t]
      - ["*const f32", float32x4x2_t]
      - ["*const f32", float32x2x3_t]
      - ["*const f32", float32x4x3_t]
      - ["*const f32", float32x2x4_t]
      - ["*const f32", float32x4x4_t]
    compose:
      - FnCall:
          - 'crate::ptr::read_unaligned'
          - - MethodCall:
                - a
                - cast
                - []

  - name: "vld1{neon_type[1].no}"
    doc: "Load multiple single-element structures to one, two, three, or four registers"
    arguments: ["a: {type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vld]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ld]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety:
      unsafe: [neon]
    types:
      - ["*const i8", int8x8x2_t]
      - ["*const i8", int8x16x2_t]
      - ["*const i8", int8x8x3_t]
      - ["*const i8", int8x16x3_t]
      - ["*const i8", int8x8x4_t]
      - ["*const i8", int8x16x4_t]
      - ["*const i16", int16x4x2_t]
      - ["*const i16", int16x8x2_t]
      - ["*const i16", int16x4x3_t]
      - ["*const i16", int16x8x3_t]
      - ["*const i16", int16x4x4_t]
      - ["*const i16", int16x8x4_t]
      - ["*const i32", int32x2x2_t]
      - ["*const i32", int32x4x2_t]
      - ["*const i32", int32x2x3_t]
      - ["*const i32", int32x4x3_t]
      - ["*const i32", int32x2x4_t]
      - ["*const i32", int32x4x4_t]
      - ["*const i64", int64x1x2_t]
      - ["*const i64", int64x1x3_t]
      - ["*const i64", int64x1x4_t]
      - ["*const i64", int64x2x2_t]
      - ["*const i64", int64x2x3_t]
      - ["*const i64", int64x2x4_t]
    compose:
      - FnCall:
          - 'crate::ptr::read_unaligned'
          - - MethodCall:
                - a
                - cast
                - []

  - name: "vld1{neon_type[1].no}"
    doc: "Load multiple single-element structures to one, two, three, or four registers"
    arguments: ["a: {type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vld]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ld]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    big_endian_inverse: false
    safety:
      unsafe: [neon]
    types:
      - ["*const u8", uint8x8x2_t, int8x8x2_t]
      - ["*const u8", uint8x16x2_t, int8x16x2_t]
      - ["*const u8", uint8x8x3_t, int8x8x3_t]
      - ["*const u8", uint8x16x3_t, int8x16x3_t]
      - ["*const u8", uint8x8x4_t, int8x8x4_t]
      - ["*const u8", uint8x16x4_t, int8x16x4_t]
      - ["*const u16", uint16x4x2_t, int16x4x2_t]
      - ["*const u16", uint16x8x2_t, int16x8x2_t]
      - ["*const u16", uint16x4x3_t, int16x4x3_t]
      - ["*const u16", uint16x8x3_t, int16x8x3_t]
      - ["*const u16", uint16x4x4_t, int16x4x4_t]
      - ["*const u16", uint16x8x4_t, int16x8x4_t]
      - ["*const u32", uint32x2x2_t, int32x2x2_t]
      - ["*const u32", uint32x4x2_t, int32x4x2_t]
      - ["*const u32", uint32x2x3_t, int32x2x3_t]
      - ["*const u32", uint32x4x3_t, int32x4x3_t]
      - ["*const u32", uint32x2x4_t, int32x2x4_t]
      - ["*const u32", uint32x4x4_t, int32x4x4_t]
      - ["*const u64", uint64x1x2_t, int64x1x2_t]
      - ["*const u64", uint64x1x3_t, int64x1x3_t]
      - ["*const u64", uint64x1x4_t, int64x1x4_t]
      - ["*const u64", uint64x2x2_t, int64x2x2_t]
      - ["*const u64", uint64x2x3_t, int64x2x3_t]
      - ["*const u64", uint64x2x4_t, int64x2x4_t]
      - ["*const p8", poly8x8x2_t, int8x8x2_t]
      - ["*const p8", poly8x8x3_t, int8x8x3_t]
      - ["*const p8", poly8x8x4_t, int8x8x4_t]
      - ["*const p8", poly8x16x2_t, int8x16x2_t]
      - ["*const p8", poly8x16x3_t, int8x16x3_t]
      - ["*const p8", poly8x16x4_t, int8x16x4_t]
      - ["*const p16", poly16x4x2_t, int16x4x2_t]
      - ["*const p16", poly16x4x3_t, int16x4x3_t]
      - ["*const p16", poly16x4x4_t, int16x4x4_t]
      - ["*const p16", poly16x8x2_t, int16x8x2_t]
      - ["*const p16", poly16x8x3_t, int16x8x3_t]
      - ["*const p16", poly16x8x4_t, int16x8x4_t]
    compose:
      - FnCall:
          - 'crate::ptr::read_unaligned'
          - - MethodCall:
                - a
                - cast
                - []

  - name: "vld1{neon_type[1].no}"
    doc: "Load multiple single-element structures to one, two, three, or four registers"
    arguments: ["a: {type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-aes
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [nop]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ld]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    big_endian_inverse: false
    safety:
      unsafe: [neon]
    types:
      - ["*const p64", poly64x1x3_t, int64x1x3_t]
      - ["*const p64", poly64x1x4_t, int64x1x4_t]
      - ["*const p64", poly64x2x2_t, int64x2x2_t]
      - ["*const p64", poly64x2x3_t, int64x2x3_t]
      - ["*const p64", poly64x2x4_t, int64x2x4_t]
    compose:
      - FnCall:
          - 'crate::ptr::read_unaligned'
          - - MethodCall:
                - a
                - cast
                - []

  - name: "vld1{neon_type[1].no}"
    doc: "Load multiple single-element structures to one, two, three, or four registers"
    arguments: ["a: {type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-aes
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vld]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ld]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety:
      unsafe: [neon]
    types:
      - ["*const p64", poly64x1x2_t, int64x1x2_t]
    compose:
      - FnCall:
          - 'crate::ptr::read_unaligned'
          - - MethodCall:
                - a
                - cast
                - []

  - name: "vld1{neon_type[1].no}"
    doc: "Load multiple single-element structures to one, two, three, or four registers"
    arguments: ["a: {type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vld1]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ld]]}]]
      - *arm-fp16
      - *neon-unstable-f16
      - *target-not-arm64ec
    safety:
      unsafe: [neon]
    types:
      - ["*const f16", float16x4x2_t]
      - ["*const f16", float16x8x2_t]
      - ["*const f16", float16x4x3_t]
      - ["*const f16", float16x8x3_t]
      - ["*const f16", float16x4x4_t]
      - ["*const f16", float16x8x4_t]
    compose:
      - FnCall:
          - 'crate::ptr::read_unaligned'
          - - MethodCall:
                - a
                - cast
                - []

  - name: "vld1{type[2]}_{neon_type[1]}"
    doc: "Load one single-element structure to one lane of one register"
    arguments: ["ptr: {type[0]}", "src: {neon_type[1]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7

      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vld1, 'LANE = 0']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ld1, 'LANE = 0']]}]]
      - FnCall: [rustc_legacy_const_generics, ["2"]]
      - *arm-fp16
      - *neon-unstable-f16
      - *target-not-arm64ec
    static_defs: ['const LANE: i32']
    safety:
      unsafe: [neon]
    types:
      - ["*const f16", float16x4_t, '_lane', '2']
      - ["*const f16", float16x8_t, 'q_lane', '3']
    compose:
      - FnCall: [static_assert_uimm_bits!, [LANE, '{type[3]}']]
      - FnCall: [simd_insert!, [src, "LANE as u32", "*ptr"]]

  - name: "vld1{type[2]}_{neon_type[1]}"
    doc: "Load one single-element structure and replicate to all lanes of one register"
    arguments: ["ptr: {type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ["vld1"]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ld1r]]}]]
      - *arm-fp16
      - *neon-unstable-f16
      - *target-not-arm64ec
    safety:
      unsafe: [neon]
    types:
      - ["*const f16", float16x4_t, '_dup', 'f16x4', "[0, 0, 0, 0]"]
      - ["*const f16", float16x8_t, 'q_dup', 'f16x8', "[0, 0, 0, 0, 0, 0, 0, 0]"]
    compose:
      - Let: [x, "{neon_type[1]}", "vld1{neon_type[1].lane_nox}::<0>(ptr, transmute({type[3]}::splat(0.0)))"]
      - FnCall: [simd_shuffle!, [x, x, "{type[4]}"]]


  - name: "vld2{neon_type[1].nox}"
    doc: Load multiple 2-element structures to two registers
    arguments: ["a: {type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *enable-v7
      - *target-is-arm
      - *neon-arm-unstable
    assert_instr: [vld2]
    safety:
      unsafe: [neon]
    types:
      - ["*const i8", int8x8x2_t, i8]
      - ["*const i16", int16x4x2_t, i16]
      - ["*const i32", int32x2x2_t, i32]
      - ["*const i8", int8x16x2_t, i8]
      - ["*const i16", int16x8x2_t, i16]
      - ["*const i32", int32x4x2_t, i32]
      - ["*const f32", float32x2x2_t, f32]
      - ["*const f32", float32x4x2_t, f32]
    compose:
      - LLVMLink:
          name: "vld2.{neon_type[1]}"
          arguments:
            - "ptr: *const i8"
            - "size: i32"
          links:
            - link: "llvm.arm.neon.vld2.v{neon_type[1].lane}{type[2]}"
              arch: arm
      - FnCall:
          - "_vld2{neon_type[1].nox}"
          - - "a as *const i8"
            - "{neon_type[1].base_byte_size}"

  - name: "vld2{neon_type[1].nox}"
    doc: Load multiple 2-element structures to two registers
    arguments: ["a: {type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *enable-v7
      - *target-is-arm
      - *neon-arm-unstable
    assert_instr: [nop]
    safety:
      unsafe: [neon]
    types:
      - ["*const i64", int64x1x2_t, i64]
    compose:
      - LLVMLink:
          name: "vld2.{neon_type[1]}"
          arguments:
            - "ptr: *const i8"
            - "size: i32"
          links:
            - link: "llvm.arm.neon.vld2.v{neon_type[1].lane}{type[2]}"
              arch: arm
      - FnCall:
          - "_vld2{neon_type[1].nox}"
          - - "a as *const i8"
            - "{neon_type[1].base_byte_size}"

  - name: "vld2{neon_type[1].nox}"
    doc: Load multiple 2-element structures to two registers
    arguments: ["a: {type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *target-not-arm
      - *neon-stable
    assert_instr: [ld2]
    safety:
      unsafe: [neon]
    types:
      - ["*const i8", int8x8x2_t, i8, int8x8_t]
      - ["*const i16", int16x4x2_t, i16, int16x4_t]
      - ["*const i32", int32x2x2_t, i32, int32x2_t]
      - ["*const i8", int8x16x2_t, i8, int8x16_t]
      - ["*const i16", int16x8x2_t, i16, int16x8_t]
      - ["*const i32", int32x4x2_t, i32, int32x4_t]
      - ["*const f32", float32x2x2_t, f32, float32x2_t]
      - ["*const f32", float32x4x2_t, f32, float32x4_t]
    compose:
      - LLVMLink:
          name: "vld2.{neon_type[1]}"
          arguments:
            - "ptr: *const {neon_type[3]}"
          links:
            - link: "llvm.aarch64.neon.ld2.v{neon_type[1].lane}{type[2]}.p0"
              arch: aarch64,arm64ec
      - FnCall:
          - "_vld2{neon_type[1].nox}"
          - - "a as _"

  - name: "vld2{neon_type[1].nox}"
    doc: Load multiple 2-element structures to two registers
    arguments: ["a: {type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *target-not-arm
      - *neon-stable
    assert_instr: [nop]
    safety:
      unsafe: [neon]
    types:
      - ["*const i64", int64x1x2_t, i64, int64x1_t]
    compose:
      - LLVMLink:
          name: "vld2.{neon_type[1]}"
          arguments:
            - "ptr: *const {neon_type[3]}"
          links:
            - link: "llvm.aarch64.neon.ld2.v{neon_type[1].lane}{type[2]}.p0"
              arch: aarch64,arm64ec
      - FnCall:
          - "_vld2{neon_type[1].nox}"
          - - "a as _"

  - name: "vld2{neon_type[1].nox}"
    doc: Load multiple 2-element structures to two registers
    arguments: ["a: {type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vld2]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ld2]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    big_endian_inverse: false
    safety:
      unsafe: [neon]
    types:
      - ["*const u8", uint8x8x2_t, int8x8x2_t]
      - ["*const u16", uint16x4x2_t, int16x4x2_t]
      - ["*const u32", uint32x2x2_t, int32x2x2_t]
      - ["*const u8", uint8x16x2_t, int8x16x2_t]
      - ["*const u16", uint16x8x2_t, int16x8x2_t]
      - ["*const u32", uint32x4x2_t, int32x4x2_t]
      - ["*const p8", poly8x8x2_t, int8x8x2_t]
      - ["*const p16", poly16x4x2_t, int16x4x2_t]
      - ["*const p8", poly8x16x2_t, int8x16x2_t]
      - ["*const p16", poly16x8x2_t, int16x8x2_t]
    compose:
      - FnCall:
          - transmute
          - - FnCall:
                - "vld2{neon_type[2].nox}"
                - - FnCall: [transmute, [a]]

  - name: "vld2{neon_type[1].nox}"
    doc: Load multiple 2-element structures to two registers
    arguments: ["a: {type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [nop]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [nop]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    big_endian_inverse: false
    safety:
      unsafe: [neon]
    types:
      - ["*const u64", uint64x1x2_t, int64x1x2_t]
    compose:
      - FnCall:
          - transmute
          - - FnCall:
                - "vld2{neon_type[2].nox}"
                - - FnCall: [transmute, [a]]

  - name: "vld2{neon_type[1].nox}"
    doc: Load multiple 2-element structures to two registers
    arguments: ["a: {type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-aes
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [nop]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [nop]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety:
      unsafe: [neon]
    types:
      - ["*const p64", poly64x1x2_t, int64x1x2_t]
    compose:
      - FnCall:
          - transmute
          - - FnCall:
                - "vld2{neon_type[2].nox}"
                - - FnCall: [transmute, [a]]

  - name: "vld2{neon_type[1].lane_nox}"
    doc: Load multiple 2-element structures to two registers
    arguments: ["a: {type[0]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *enable-v7
      - *target-is-arm
      - FnCall:
          - cfg_attr
          - - test
            - FnCall:
                - assert_instr
                - - vld2
                  - "LANE = 0"
      - FnCall:
          - rustc_legacy_const_generics
          - - "2"
      - *neon-arm-unstable
    static_defs:
      - "const LANE: i32"
    safety:
      unsafe: [neon]
    types:
      - ["*const i8", int8x8x2_t, i8, int8x8_t, "3"]
      - ["*const i16", int16x4x2_t, i16, int16x4_t, "2"]
      - ["*const i32", int32x2x2_t, i32, int32x2_t, "1"]
    compose:
      - FnCall:
          - "static_assert_uimm_bits!"
          - - LANE
            - "{type[4]}"
      - LLVMLink:
          name: "vld2.{neon_type[1]}"
          arguments:
            - "ptr: *const i8"
            - "a: {neon_type[3]}"
            - "b: {neon_type[3]}"
            - "n: i32"
            - "size: i32"
          links:
            - link: "llvm.arm.neon.vld2lane.v{neon_type[1].lane}{type[2]}.p0"
              arch: arm
      - FnCall:
          - "_vld2_lane{neon_type[1].nox}"
          - - "a as _"
            - "b.0"
            - "b.1"
            - "LANE"
            - "{neon_type[1].base_byte_size}"

  - name: "vld2{neon_type[1].lane_nox}"
    doc: Load multiple 2-element structures to two registers
    arguments: ["a: {type[0]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vld2, 'LANE = 0']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ld2, 'LANE = 0']]}]]
      - FnCall: [rustc_legacy_const_generics, ["2"]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs:
      - "const LANE: i32"
    big_endian_inverse: false
    safety:
      unsafe: [neon]
    types:
      - ["*const u8", uint8x8x2_t, int8x8_t, "3"]
      - ["*const u16", uint16x4x2_t, int16x4_t, "2"]
      - ["*const u32", uint32x2x2_t, int32x2_t, "1"]
      - ["*const u16", uint16x8x2_t, int16x8_t, "3"]
      - ["*const u32", uint32x4x2_t, int32x4_t, "2"]
      - ["*const p8", poly8x8x2_t, int8x8_t, "3"]
      - ["*const p16", poly16x4x2_t, int16x4_t, "2"]
      - ["*const p16", poly16x8x2_t, int16x8_t, "3"]
    compose:
      - FnCall:
          - "static_assert_uimm_bits!"
          - - LANE
            - "{type[3]}"
      - FnCall:
          - transmute
          - - FnCall:
                - "vld2{neon_type[2].lane_nox}::<LANE>"
                - - FnCall: [transmute, [a]]
                  - FnCall: [transmute, [b]]

  - name: "vld2{neon_type[1].lane_nox}"
    doc: Load multiple 2-element structures to two registers
    arguments: ["a: {type[0]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *target-not-arm
      - FnCall:
          - cfg_attr
          - - test
            - FnCall:
                - assert_instr
                - - ld2
                  - "LANE = 0"
      - FnCall: [rustc_legacy_const_generics, ["2"]]
      - *neon-stable
    static_defs:
      - "const LANE: i32"
    safety:
      unsafe: [neon]
    types:
      - ["*const i8", int8x8x2_t, i8, int8x8_t, "3"]
      - ["*const i16", int16x4x2_t, i16, int16x4_t, "2"]
      - ["*const i32", int32x2x2_t, i32, int32x2_t, "1"]
      - ["*const i16", int16x8x2_t, i16, int16x8_t, "3"]
      - ["*const i32", int32x4x2_t, i32, int32x4_t, "2"]
      - ["*const f32", float32x2x2_t, f32, float32x2_t, "2"]
      - ["*const f32", float32x4x2_t, f32, float32x4_t, "2"]
    compose:
      - FnCall:
          - "static_assert_uimm_bits!"
          - - LANE
            - "{type[4]}"
      - LLVMLink:
          name: "vld2.{neon_type[1]}"
          arguments:
            - "a: {neon_type[3]}"
            - "b: {neon_type[3]}"
            - "n: i64"
            - "ptr: *const i8"
          links:
            - link: "llvm.aarch64.neon.ld2lane.v{neon_type[1].lane}{type[2]}.p0"
              arch: aarch64,arm64ec
      - FnCall:
          - "_vld2{neon_type[1].lane_nox}"
          - - "b.0"
            - "b.1"
            - "LANE as i64"
            - "a as _"

  - name: "vld2{neon_type[1].lane_nox}"
    doc: Load multiple 2-element structures to two registers
    arguments: ["a: {type[0]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *enable-v7
      - *target-is-arm
      - FnCall:
          - cfg_attr
          - - test
            - FnCall:
                - assert_instr
                - - vld2
                  - "LANE = 0"
      - FnCall: [rustc_legacy_const_generics, ["2"]]
      - *neon-arm-unstable
    static_defs:
      - "const LANE: i32"
    safety:
      unsafe: [neon]
    types:
      - ["*const i16", int16x8x2_t, i16, int16x8_t, "3"]
      - ["*const i32", int32x4x2_t, i32, int32x4_t, "2"]
      - ["*const f32", float32x2x2_t, f32, float32x2_t, "1"]
      - ["*const f32", float32x4x2_t, f32, float32x4_t, "2"]
    compose:
      - FnCall:
          - "static_assert_uimm_bits!"
          - - LANE
            - "{type[4]}"
      - LLVMLink:
          name: "vld2.{neon_type[1]}"
          arguments:
            - "ptr: *const i8"
            - "a: {neon_type[3]}"
            - "b: {neon_type[3]}"
            - "n: i32"
            - "size: i32"
          links:
            - link: "llvm.arm.neon.vld2lane.v{neon_type[1].lane}{type[2]}.p0"
              arch: arm
      - FnCall:
          - "_vld2{neon_type[1].lane_nox}"
          - - "a as _"
            - "b.0"
            - "b.1"
            - "LANE"
            - "{neon_type[1].base_byte_size}"

  - name: "vld2{neon_type[1].dup_nox}"
    doc: Load single 2-element structure and replicate to all lanes of two registers
    arguments: ["a: {type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *enable-v7
      - *target-is-arm
      - *neon-arm-unstable
    assert_instr: [nop]
    safety:
      unsafe: [neon]
    types:
      - ["*const i64", int64x1x2_t, i64]
    compose:
      - LLVMLink:
          name: "vld2dup.{neon_type[1]}"
          arguments:
            - "ptr: *const i8"
            - "size: i32"
          links:
            - link: "llvm.arm.neon.vld2dup.v{neon_type[1].lane}{type[2]}.p0"
              arch: arm
      - FnCall:
          - "_vld2{neon_type[1].dup_nox}"
          - - "a as *const i8"
            - "{neon_type[1].base_byte_size}"

  - name: "vld2{neon_type[1].dup_nox}"
    doc: Load single 2-element structure and replicate to all lanes of two registers
    arguments: ["a: {type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *target-not-arm
      - *neon-stable
    assert_instr: [ld2r]
    safety:
      unsafe: [neon]
    types:
      - ["*const i64", int64x1x2_t, i64]
    compose:
      - LLVMLink:
          name: "vld2dup.{neon_type[1]}"
          arguments:
            - "ptr: *const i64"
          links:
            - link: "llvm.aarch64.neon.ld2r.v{neon_type[1].lane}{type[2]}.p0"
              arch: aarch64,arm64ec
      - FnCall:
          - "_vld2{neon_type[1].dup_nox}"
          - - "a as _"

  - name: "vld2{neon_type[1].dup_nox}"
    doc: Load single 2-element structure and replicate to all lanes of two registers
    arguments: ["a: {type[0]}"]
    return_type: "{type[1]}"
    attr:
      - *enable-v7
      - *target-is-arm
      - *neon-arm-unstable
    assert_instr: [vld2]
    safety:
      unsafe: [neon]
    types:
      - ["*const i8", int8x8x2_t, i8]
      - ["*const i16", int16x4x2_t, i16]
      - ["*const i32", int32x2x2_t, i32]
      - ["*const i8", int8x16x2_t, i8]
      - ["*const i16", int16x8x2_t, i16]
      - ["*const i32", int32x4x2_t, i32]
      - ["*const f32", float32x2x2_t, f32]
      - ["*const f32", float32x4x2_t, f32]
    compose:
      - LLVMLink:
          name: "vld2dup.{neon_type[1]}"
          arguments:
            - "ptr: *const i8"
            - "size: i32"
          links:
            - link: "llvm.arm.neon.vld2dup.v{neon_type[1].lane}{type[2]}.p0"
              arch: arm
      - FnCall:
          - "_vld2{neon_type[1].dup_nox}"
          - - "a as *const i8"
            - "{neon_type[1].base_byte_size}"

  - name: "vld2{neon_type[1].dup_nox}"
    doc: Load single 2-element structure and replicate to all lanes of two registers
    arguments: ["a: {type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vld2]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ld2r]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety:
      unsafe: [neon]
    types:
      - ["*const u8", uint8x8x2_t, int8x8x2_t]
      - ["*const u16", uint16x4x2_t, int16x4x2_t]
      - ["*const u32", uint32x2x2_t, int32x2x2_t]
      - ["*const u8", uint8x16x2_t, int8x16x2_t]
      - ["*const u16", uint16x8x2_t, int16x8x2_t]
      - ["*const u32", uint32x4x2_t, int32x4x2_t]
      - ["*const p8", poly8x8x2_t, int8x8x2_t]
      - ["*const p16", poly16x4x2_t, int16x4x2_t]
      - ["*const p8", poly8x16x2_t, int8x16x2_t]
      - ["*const p16", poly16x8x2_t, int16x8x2_t]
    compose:
      - FnCall:
          - transmute
          - - FnCall:
                - "vld2{neon_type[2].dup_nox}"
                - - FnCall:
                      - transmute
                      - - a

  - name: "vld2{neon_type[1].dup_nox}"
    doc: Load single 2-element structure and replicate to all lanes of two registers
    arguments: ["a: {type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [nop]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ld2r]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety:
      unsafe: [neon]
    types:
      - ["*const u64", uint64x1x2_t, int64x1x2_t]
    compose:
      - FnCall:
          - transmute
          - - FnCall:
                - "vld2{neon_type[2].dup_nox}"
                - - FnCall:
                      - transmute
                      - - a

  - name: "vld2{neon_type[1].dup_nox}"
    doc: Load single 2-element structure and replicate to all lanes of two registers
    arguments: ["a: {type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-aes
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [nop]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ld2r]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety:
      unsafe: [neon]
    types:
      - ["*const p64", poly64x1x2_t, int64x1x2_t]
    compose:
      - FnCall:
          - transmute
          - - FnCall:
                - "vld2{neon_type[2].dup_nox}"
                - - FnCall:
                      - transmute
                      - - a

  - name: "vld2{neon_type[1].dup_nox}"
    doc: Load single 2-element structure and replicate to all lanes of two registers
    arguments: ["a: {type[0]}"]
    return_type: "{type[1]}"
    attr:
      - FnCall:
          - cfg
          - - FnCall:
                - not
                - - 'target_arch = "arm"'
      - *neon-stable
    assert_instr: [ld2r]
    safety:
      unsafe: [neon]
    types:
      - ["*const i8", int8x8x2_t, i8]
      - ["*const i16", int16x4x2_t, i16]
      - ["*const i32", int32x2x2_t, i32]
      - ["*const i8", int8x16x2_t, i8]
      - ["*const i16", int16x8x2_t, i16]
      - ["*const i32", int32x4x2_t, i32]
      - ["*const f32", float32x2x2_t, f32]
      - ["*const f32", float32x4x2_t, f32]
    compose:
      - LLVMLink:
          name: "vld2dup.{neon_type[1]}"
          arguments:
            - "ptr: {type[0]}"
          links:
            - link: "llvm.aarch64.neon.ld2r.v{neon_type[1].lane}{type[2]}.p0"
              arch: aarch64,arm64ec
      - FnCall:
          - "_vld2{neon_type[1].dup_nox}"
          - - "a as _"

  - name: "vld2{neon_type[1].nox}"
    doc: Load single 2-element structure and replicate to all lanes of two registers
    arguments: ["a: {type[0]}"]
    return_type: "{type[1]}"
    attr:
      - *neon-v7
      - *target-is-arm
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vld2]]}]]
      - *arm-fp16
      - *neon-unstable-f16
      - *target-not-arm64ec
    safety:
      unsafe: [neon]
    types:
      - ["*const f16", float16x4x2_t, f16]
      - ["*const f16", float16x8x2_t, f16]
    compose:
      - LLVMLink:
          name: "vld2.{neon_type[1]}"
          arguments:
            - "ptr: {type[0]}"
            - "size: i32"
          links:
            - link: "llvm.arm.neon.vld2.v{neon_type[1].lane}{type[2]}.p0"
              arch: arm
      - FnCall:
          - "_vld2{neon_type[1].nox}"
          - - "a as _"
            - "2"

  - name: "vld2{neon_type[1].nox}"
    doc: Load single 2-element structure and replicate to all lanes of two registers
    arguments: ["a: {type[0]}"]
    return_type: "{type[1]}"
    attr:
      - *target-not-arm
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ld2]]}]]
      - *arm-fp16
      - *neon-unstable-f16
      - *target-not-arm64ec
    safety:
      unsafe: [neon]
    types:
      - ["*const f16", float16x4x2_t, f16]
      - ["*const f16", float16x8x2_t, f16]
    compose:
      - LLVMLink:
          name: "vld2.{neon_type[1]}"
          arguments:
            - "ptr: {type[0]}"
          links:
            - link: "llvm.aarch64.neon.ld2.v{neon_type[1].lane}{type[2]}.p0"
              arch: aarch64,arm64ec
      - FnCall:
          - "_vld2{neon_type[1].nox}"
          - - "a as _"

  - name: "vld2{neon_type[1].dup_nox}"
    doc: Load single 2-element structure and replicate to all lanes of two registers
    arguments: ["a: {type[0]}"]
    return_type: "{type[1]}"
    attr:
      - *neon-v7
      - *target-is-arm
      - *arm-fp16
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vld2]]}]]
      - *neon-unstable-f16
      - *target-not-arm64ec
    safety:
      unsafe: [neon]
    types:
      - ["*const f16", float16x4x2_t, f16]
      - ["*const f16", float16x8x2_t, f16]
    compose:
      - LLVMLink:
          name: "vld2dup.{neon_type[1]}"
          arguments:
            - "ptr: {type[0]}"
            - "size: i32"
          links:
            - link: "llvm.arm.neon.vld2dup.v{neon_type[1].lane}{type[2]}.p0"
              arch: arm
      - FnCall:
          - "_vld2{neon_type[1].dup_nox}"
          - - "a as _"
            - "2"


  - name: "vld2{neon_type[1].dup_nox}"
    doc: Load single 2-element structure and replicate to all lanes of two registers
    arguments: ["a: {type[0]}"]
    return_type: "{type[1]}"
    attr:
      - *target-not-arm
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ld2r]]}]]
      - *arm-fp16
      - *neon-unstable-f16
      - *target-not-arm64ec
    safety:
      unsafe: [neon]
    types:
      - ["*const f16", float16x4x2_t, f16]
      - ["*const f16", float16x8x2_t, f16]
    compose:
      - LLVMLink:
          name: "vld2dup.{neon_type[1]}"
          arguments:
            - "ptr: {type[0]}"
          links:
            - link: "llvm.aarch64.neon.ld2r.v{neon_type[1].lane}{type[2]}.p0"
              arch: aarch64,arm64ec
      - FnCall:
          - "_vld2{neon_type[1].dup_nox}"
          - - "a as _"


  - name: "vld2{neon_type[1].lane_nox}"
    doc: Load multiple 2-element structures to two registers
    arguments: ["a: {type[0]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *enable-v7
      - *target-is-arm
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['vld2', 'LANE = 0']]}]]
      - FnCall: [rustc_legacy_const_generics, ["2"]]
      - *arm-fp16
      - *neon-unstable-f16
      - *target-not-arm64ec
    static_defs:
      - "const LANE: i32"
    safety:
      unsafe: [neon]
    types:
      - ["*const f16", float16x4x2_t, f16, float16x4_t, "2"]
      - ["*const f16", float16x8x2_t, f16, float16x8_t, "3"]
    compose:
      - FnCall:
          - "static_assert_uimm_bits!"
          - - LANE
            - "{type[4]}"
      - LLVMLink:
          name: "vld2.{neon_type[1]}"
          arguments:
            - "ptr: *const f16"
            - "a: {neon_type[3]}"
            - "b: {neon_type[3]}"
            - "n: i32"
            - "size: i32"
          links:
            - link: "llvm.arm.neon.vld2lane.v{neon_type[1].lane}{type[2]}.p0"
              arch: arm
      - FnCall:
          - "_vld2{neon_type[1].lane_nox}"
          - - "a as _"
            - "b.0"
            - "b.1"
            - "LANE"
            - "2"


  - name: "vld2{neon_type[1].lane_nox}"
    doc: Load multiple 2-element structures to two registers
    arguments: ["a: {type[0]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *target-not-arm
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ld2, 'LANE = 0']]}]]
      - FnCall: [rustc_legacy_const_generics, ["2"]]
      - *arm-fp16
      - *neon-unstable-f16
      - *target-not-arm64ec
    static_defs:
      - "const LANE: i32"
    safety:
      unsafe: [neon]
    types:
      - ["*const f16", float16x4x2_t, f16, float16x4_t, "2"]
      - ["*const f16", float16x8x2_t, f16, float16x8_t, "3"]
    compose:
      - FnCall:
          - "static_assert_uimm_bits!"
          - - LANE
            - "{type[4]}"
      - LLVMLink:
          name: "vld2.{neon_type[1]}"
          arguments:
            - "a: {neon_type[3]}"
            - "b: {neon_type[3]}"
            - "n: i64"
            - "ptr: *const f16"
          links:
            - link: "llvm.aarch64.neon.ld2lane.v{neon_type[1].lane}{type[2]}.p0"
              arch: aarch64,arm64ec
      - FnCall:
          - "_vld2{neon_type[1].lane_nox}"
          - - "b.0"
            - "b.1"
            - "LANE as i64"
            - "a as _"


  - name: "vld3{neon_type[1].nox}"
    doc: Load single 3-element structure and replicate to all lanes of two registers
    arguments: ["a: {type[0]}"]
    return_type: "{type[1]}"
    attr:
      - *neon-v7
      - *target-is-arm
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vld3]]}]]
      - *arm-fp16
      - *neon-unstable-f16
      - *target-not-arm64ec
    safety:
      unsafe: [neon]
    types:
      - ["*const f16", float16x4x3_t, f16]
      - ["*const f16", float16x8x3_t, f16]
    compose:
      - LLVMLink:
          name: "vld3.{neon_type[1]}"
          arguments:
            - "ptr: {type[0]}"
            - "size: i32"
          links:
            - link: "llvm.arm.neon.vld3.v{neon_type[1].lane}{type[2]}.p0"
              arch: arm
      - FnCall:
          - "_vld3{neon_type[1].nox}"
          - - "a as _"
            - "2"

  - name: "vld3{neon_type[1].nox}"
    doc: Load single 3-element structure and replicate to all lanes of two registers
    arguments: ["a: {type[0]}"]
    return_type: "{type[1]}"
    attr:
      - *target-not-arm
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ld3]]}]]
      - *arm-fp16
      - *neon-unstable-f16
      - *target-not-arm64ec
    safety:
      unsafe: [neon]
    types:
      - ["*const f16", float16x4x3_t, f16, "4"]
      - ["*const f16", float16x8x3_t, f16, "8"]
    compose:
      - FnCall: ["crate::core_arch::macros::deinterleaving_load!", [{ Type: "{type[2]}" }, "{type[3]}", "3", a], [], true]


  - name: "vld3{neon_type[1].dup_nox}"
    doc: Load single 3-element structure and replicate to all lanes of two registers
    arguments: ["a: {type[0]}"]
    return_type: "{type[1]}"
    attr:
      - *neon-v7
      - *target-is-arm
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vld3]]}]]
      - *arm-fp16
      - *neon-unstable-f16
      - *target-not-arm64ec
    safety:
      unsafe: [neon]
    types:
      - ["*const f16", float16x4x3_t, f16]
      - ["*const f16", float16x8x3_t, f16]
    compose:
      - LLVMLink:
          name: "vld3dup.{neon_type[1]}"
          arguments:
            - "ptr: {type[0]}"
            - "size: i32"
          links:
            - link: "llvm.arm.neon.vld3dup.v{neon_type[1].lane}{type[2]}.p0"
              arch: arm
      - FnCall:
          - "_vld3{neon_type[1].dup_nox}"
          - - "a as _"
            - "2"


  - name: "vld3{neon_type[1].dup_nox}"
    doc: Load single 3-element structure and replicate to all lanes of two registers
    arguments: ["a: {type[0]}"]
    return_type: "{type[1]}"
    attr:
      - *target-not-arm
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ld3r]]}]]
      - *arm-fp16
      - *neon-unstable-f16
      - *target-not-arm64ec
    safety:
      unsafe: [neon]
    types:
      - ["*const f16", float16x4x3_t, f16]
      - ["*const f16", float16x8x3_t, f16]
    compose:
      - LLVMLink:
          name: "vld3dup.{neon_type[1]}"
          arguments:
            - "ptr: {type[0]}"
          links:
            - link: "llvm.aarch64.neon.ld3r.v{neon_type[1].lane}{type[2]}.p0"
              arch: aarch64,arm64ec
      - FnCall:
          - "_vld3{neon_type[1].dup_nox}"
          - - "a as _"


  - name: "vld3{neon_type[1].lane_nox}"
    doc: Load multiple 3-element structures to two registers
    arguments: ["a: {type[0]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *enable-v7
      - *target-is-arm
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['vld3', 'LANE = 0']]}]]
      - FnCall: [rustc_legacy_const_generics, ["2"]]
      - *arm-fp16
      - *neon-unstable-f16
      - *target-not-arm64ec
    static_defs:
      - "const LANE: i32"
    safety:
      unsafe: [neon]
    types:
      - ["*const f16", float16x4x3_t, f16, float16x4_t, "2"]
      - ["*const f16", float16x8x3_t, f16, float16x8_t, "3"]
    compose:
      - FnCall:
          - "static_assert_uimm_bits!"
          - - LANE
            - "{type[4]}"
      - LLVMLink:
          name: "vld3.{neon_type[1]}"
          arguments:
            - "ptr: *const f16"
            - "a: {neon_type[3]}"
            - "b: {neon_type[3]}"
            - "c: {neon_type[3]}"
            - "n: i32"
            - "size: i32"
          links:
            - link: "llvm.arm.neon.vld3lane.v{neon_type[1].lane}{type[2]}.p0"
              arch: arm
      - FnCall:
          - "_vld3{neon_type[1].lane_nox}"
          - - "a as _"
            - "b.0"
            - "b.1"
            - "b.2"
            - "LANE"
            - "2"


  - name: "vld3{neon_type[1].lane_nox}"
    doc: Load multiple 3-element structures to two registers
    arguments: ["a: {type[0]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *target-not-arm
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ld3, 'LANE = 0']]}]]
      - FnCall: [rustc_legacy_const_generics, ["2"]]
      - *arm-fp16
      - *neon-unstable-f16
      - *target-not-arm64ec
    static_defs:
      - "const LANE: i32"
    safety:
      unsafe: [neon]
    types:
      - ["*const f16", float16x4x3_t, f16, float16x4_t, "2"]
      - ["*const f16", float16x8x3_t, f16, float16x8_t, "3"]
    compose:
      - FnCall:
          - "static_assert_uimm_bits!"
          - - LANE
            - "{type[4]}"
      - LLVMLink:
          name: "vld3.{neon_type[1]}"
          arguments:
            - "a: {neon_type[3]}"
            - "b: {neon_type[3]}"
            - "c: {neon_type[3]}"
            - "n: i64"
            - "ptr: *const f16"
          links:
            - link: "llvm.aarch64.neon.ld3lane.v{neon_type[1].lane}{type[2]}.p0"
              arch: aarch64,arm64ec
      - FnCall:
          - "_vld3{neon_type[1].lane_nox}"
          - - "b.0"
            - "b.1"
            - "b.2"
            - "LANE as i64"
            - "a as _"

  - name: "vld3{neon_type[1].lane_nox}"
    doc: "Load multiple 3-element structures to two registers"
    arguments: ["a: {type[0]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *target-not-arm
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [ld3, 'LANE = 0']]}]]
      - FnCall: [rustc_legacy_const_generics, ["2"]]
      - *neon-stable
    static_defs:
      - "const LANE: i32"
    safety:
      unsafe: [neon]
    types:
      - ['*const i8', int8x8x3_t, int8x8_t, i8, '3']
      - ['*const i16', int16x8x3_t, int16x8_t, i16, '4']
      - ['*const i32', int32x4x3_t, int32x4_t, i32, '2']
      - ['*const i16', int16x4x3_t, int16x4_t, i16, '2']
      - ['*const i32', int32x2x3_t, int32x2_t, i32, '1']
    compose:
      - FnCall: [static_assert_uimm_bits!, [LANE, '{type[4]}']]
      - LLVMLink:
          name: 'ld3lane.{neon_type[2]}'
          arguments:
            - 'a: {type[2]}'
            - 'b: {type[2]}'
            - 'c: {type[2]}'
            - 'n: i64'
            - 'ptr: *const i8'
          links:
            - link: 'llvm.aarch64.neon.ld3lane.v{neon_type[1].lane}{type[3]}.p0'
              arch: aarch64,arm64ec
      - FnCall: ['_vld3{neon_type[1].lane_nox}', ['b.0', 'b.1', 'b.2', 'LANE as i64', 'a as _']]

  - name: "vld3{neon_type[1].nox}"
    doc: Load multiple 3-element structures to three registers
    arguments: ["a: {type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-stable
      - *target-not-arm
    assert_instr: [ld3]
    safety:
      unsafe: [neon]
    types:
      - ['*const i8', int8x8x3_t, i8, "8"]
      - ['*const i16', int16x4x3_t, i16, "4"]
      - ['*const i32', int32x2x3_t, i32, "2"]
      - ['*const i8', int8x16x3_t, i8, "16"]
      - ['*const i16', int16x8x3_t, i16, "8"]
      - ['*const i32', int32x4x3_t, i32, "4"]
      - ['*const f32', float32x2x3_t, f32, "2"]
      - ['*const f32', float32x4x3_t, f32, "4"]
    compose:
      - FnCall: ["crate::core_arch::macros::deinterleaving_load!", [{ Type: "{type[2]}" }, "{type[3]}", "3", a], [], true]


  - name: "vld3{neon_type[1].nox}"
    doc: Load multiple 3-element structures to three registers
    arguments: ["a: {type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-stable
      - *target-not-arm
    assert_instr: [nop]
    safety:
      unsafe: [neon]
    types:
      - ['*const i64', int64x1x3_t, '*const int64x1_t', i64]
    compose:
      - FnCall:
          - 'crate::ptr::read_unaligned'
          - - MethodCall:
                - a
                - cast
                - []

  - name: "vld3{neon_type[1].nox}"
    doc: Load multiple 3-element structures to three registers
    arguments: ["a: {type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *target-is-arm
      - *enable-v7
      - *neon-arm-unstable
    assert_instr: [vld3]
    safety:
      unsafe: [neon]
    types:
      - ['*const i8', int8x8x3_t, i8]
      - ['*const i16', int16x4x3_t, i16]
      - ['*const i32', int32x2x3_t, i32]
      - ['*const i8', int8x16x3_t, i8]
      - ['*const i16', int16x8x3_t, i16]
      - ['*const i32', int32x4x3_t, i32]
      - ['*const f32', float32x2x3_t, f32]
      - ['*const f32', float32x4x3_t, f32]
    compose:
      - LLVMLink:
          name: 'vld3{neon_type[1].nox}'
          arguments:
            - 'ptr: *const i8'
            - 'size: i32'
          links:
            - link: 'llvm.arm.neon.vld3.v{neon_type[1].lane}{type[2]}.p0'
              arch: arm
      - FnCall: ['_vld3{neon_type[1].nox}', ['a as *const i8', '{neon_type[1].base_byte_size}']]

  - name: "vld3{neon_type[1].nox}"
    doc: Load multiple 3-element structures to three registers
    arguments: ["a: {type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *target-is-arm
      - *enable-v7
      - *neon-arm-unstable
    assert_instr: [nop]
    safety:
      unsafe: [neon]
    types:
      - ['*const i64', int64x1x3_t, i64]
    compose:
      - LLVMLink:
          name: 'vld3{neon_type[1].nox}'
          arguments:
            - 'ptr: *const i8'
            - 'size: i32'
          links:
            - link: 'llvm.arm.neon.vld3.v{neon_type[1].lane}{type[2]}.p0'
              arch: arm
      - FnCall: ['_vld3{neon_type[1].nox}', ['a as *const i8', '{neon_type[1].base_byte_size}']]

  - name: "vld3{neon_type[1].lane_nox}"
    doc: Load multiple 3-element structures to three registers
    arguments: ["a: {type[0]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *target-not-arm
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [ld3, 'LANE = 0']]}]]
      - FnCall: [rustc_legacy_const_generics, ["2"]]
      - *neon-stable
    static_defs: ['const LANE: i32']
    safety:
      unsafe: [neon]
    types:
      - ['*const f32', float32x4x3_t, float32x4_t, f32, '2']
      - ['*const f32', float32x2x3_t, float32x2_t, f32, '1']
    compose:
      - FnCall: [static_assert_uimm_bits!, ['LANE', '{type[4]}']]
      - LLVMLink:
          name: 'vld3{neon_type[1].lane_nox}'
          arguments:
            - 'a: {type[2]}'
            - 'b: {type[2]}'
            - 'c: {type[2]}'
            - 'n: i64'
            - 'ptr: *const i8'
          links:
            - link: 'llvm.aarch64.neon.ld3lane.v{neon_type[1].lane}{type[3]}.p0'
              arch: aarch64,arm64ec
      - FnCall: ['_vld3{neon_type[1].lane_nox}', ['b.0', 'b.1', 'b.2', 'LANE as i64', 'a as _']]

  - name: "vld3{neon_type[2].lane_nox}"
    doc: "Load multiple 3-element structures to three registers"
    arguments: ["a: {type[0]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *target-is-arm
      - *enable-v7
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [vld3, 'LANE = 0']]}]]
      - FnCall: [rustc_legacy_const_generics, ["2"]]
      - *neon-arm-unstable
    static_defs: ['const LANE: i32']
    safety:
      unsafe: [neon]
    types:
      - ['*const f32', float32x2x3_t, float32x2_t, f32, '1', '4']
    compose:
      - FnCall: [static_assert_uimm_bits!, ['LANE', '{type[4]}']]
      - LLVMLink:
          name: 'vld3{neon_type[1].lane_nox}'
          arguments:
            - 'ptr: *const i8'
            - 'a: {type[2]}'
            - 'b: {type[2]}'
            - 'c: {type[2]}'
            - 'n: i32'
            - 'size: i32'
          links:
            - link: 'llvm.arm.neon.vld3lane.v{neon_type[1].lane}{type[3]}.p0'
              arch: arm
      - FnCall: ['_vld3{neon_type[1].lane_nox}', ['a as _', 'b.0', 'b.1', 'b.2', 'LANE', '{type[5]}']]

  - name: "vld3{neon_type[2].lane_nox}"
    doc: "Load multiple 3-element structures to two registers"
    arguments: ["a: {type[0]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *target-is-arm
      - *enable-v7
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [vld3, 'LANE = 0']]}]]
      - FnCall: [rustc_legacy_const_generics, ["2"]]
      - *neon-arm-unstable
    static_defs: ['const LANE: i32']
    safety:
      unsafe: [neon]
    types:
      - ['*const i8', int8x8x3_t, int8x8_t, i8, '3', '1']
      - ['*const i16', int16x4x3_t, int16x4_t, i16, '2', '2']
      - ['*const i32', int32x2x3_t, int32x2_t, i32, '1', '4']
      - ['*const i16', int16x8x3_t, int16x8_t, i16, '3', '2']
      - ['*const i32', int32x4x3_t, int32x4_t, i32, '2', '4']
    compose:
      - FnCall: [static_assert_uimm_bits!, ['LANE', '{type[4]}']]
      - LLVMLink:
          name: 'vld3{neon_type[1].lane_nox}'
          arguments:
            - 'ptr: *const i8'
            - 'a: {type[2]}'
            - 'b: {type[2]}'
            - 'c: {type[2]}'
            - 'n: i32'
            - 'size: i32'
          links:
            - link: 'llvm.arm.neon.vld3lane.v{neon_type[1].lane}{type[3]}.p0'
              arch: arm
      - FnCall: ['_vld3{neon_type[1].lane_nox}', ['a as _', 'b.0', 'b.1', 'b.2', 'LANE', '{type[5]}']]

  - name: "vld3{neon_type[2].lane_nox}"
    doc: "Load multiple 3-element structures to three registers"
    arguments: ["a: {type[0]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *target-is-arm
      - *enable-v7
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [vld3, 'LANE = 0']]}]]
      - FnCall: [rustc_legacy_const_generics, ["2"]]
      - *neon-arm-unstable
    static_defs: ['const LANE: i32']
    safety:
      unsafe: [neon]
    types:
      - ['*const f32', float32x4x3_t, float32x4_t, f32, '2', '4']
    compose:
      - FnCall: [static_assert_uimm_bits!, ['LANE', '{type[4]}']]
      - LLVMLink:
          name: 'vld3{neon_type[1].lane_nox}'
          arguments:
            - 'ptr: *const i8'
            - 'a: {type[2]}'
            - 'b: {type[2]}'
            - 'c: {type[2]}'
            - 'n: i32'
            - 'size: i32'
          links:
            - link: 'llvm.arm.neon.vld3lane.v{neon_type[1].lane}{type[3]}.p0'
              arch: arm
      - FnCall: ['_vld3{neon_type[1].lane_nox}', ['a as _', 'b.0', 'b.1', 'b.2', 'LANE', '{type[5]}']]

  - name: "vld3{neon_type[1].lane_nox}"
    doc: Load multiple 3-element structures to three registers
    arguments: ["a: {type[0]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vld3, 'LANE = 0']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ld3, 'LANE = 0']]}]]
      - FnCall: [rustc_legacy_const_generics, ["2"]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const LANE: i32']
    big_endian_inverse: false
    safety:
      unsafe: [neon]
    types:
      - ['*const u8', uint8x8x3_t, int8x8x3_t, '3']
      - ['*const u16', uint16x4x3_t, int16x4x3_t, '2']
      - ['*const u32', uint32x2x3_t, int32x2x3_t, '1']
      - ['*const p8', poly8x8x3_t, int8x8x3_t, '3']
      - ['*const u16', uint16x8x3_t, int16x8x3_t, '3']
      - ['*const p16', poly16x4x3_t, int16x4x3_t, '2']
      - ['*const p16', poly16x8x3_t, int16x8x3_t, '3']
      - ['*const u32', uint32x4x3_t, int32x4x3_t, '2']
    compose:
      - FnCall: [static_assert_uimm_bits!, [LANE, '{type[3]}']]
      - FnCall:
          - transmute
          - - FnCall:
                - 'vld3{neon_type[2].lane_nox}::<LANE>'
                - - FnCall: [transmute, [a]]
                  - FnCall: [transmute, [b]]

  - name: "vld3{neon_type[1].nox}"
    doc: Load multiple 3-element structures to three registers
    arguments: ["a: {type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vld3]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ld3]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    big_endian_inverse: false
    safety:
      unsafe: [neon]
    types:
      - ['*const u8', uint8x8x3_t, int8x8x3_t]
      - ['*const u8', uint8x16x3_t, int8x16x3_t]
      - ['*const u16', uint16x4x3_t, int16x4x3_t]
      - ['*const u32', uint32x2x3_t, int32x2x3_t]
      - ['*const u16', uint16x8x3_t, int16x8x3_t]
      - ['*const u32', uint32x4x3_t, int32x4x3_t]
      - ['*const p8', poly8x8x3_t, int8x8x3_t]
      - ['*const p8', poly8x16x3_t, int8x16x3_t]
      - ['*const p16', poly16x4x3_t, int16x4x3_t]
      - ['*const p16', poly16x8x3_t, int16x8x3_t]
    compose:
      - FnCall:
          - transmute
          - - FnCall:
                - 'vld3{neon_type[2].nox}'
                - - FnCall: [transmute, [a]]

  - name: "vld3{neon_type[1].nox}"
    doc: Load multiple 3-element structures to three registers
    arguments: ["a: {type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [nop]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [nop]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety:
      unsafe: [neon]
    types:
      - ['*const u64', uint64x1x3_t, int64x1x3_t]
    compose:
      - FnCall:
          - transmute
          - - FnCall:
                - 'vld3{neon_type[2].nox}'
                - - FnCall: [transmute, [a]]

  - name: "vld3{neon_type[1].nox}"
    doc: Load multiple 3-element structures to three registers
    arguments: ["a: {type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-aes
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [nop]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [nop]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety:
      unsafe: [neon]
    types:
      - ['*const p64', poly64x1x3_t, int64x1x3_t]
    compose:
      - FnCall:
          - transmute
          - - FnCall:
                - 'vld3{neon_type[2].nox}'
                - - FnCall:
                      - transmute
                      - - a

  - name: "vld3{neon_type[1].dup_nox}"
    doc: Load single 3-element structure and replicate to all lanes of three registers
    arguments: ["a: {type[0]}"]
    return_type: "{neon_type[1]}"
    attr: [*target-not-arm, *neon-stable]
    assert_instr: [ld3r]
    safety:
      unsafe: [neon]
    types:
      - ["*const i8", int8x8x3_t, i8]
      - ["*const i16", int16x4x3_t, i16]
      - ["*const i32", int32x2x3_t, i32]
      - ["*const i32", int32x4x3_t, i32]
      - ["*const i16", int16x8x3_t, i16]
      - ["*const i8", int8x16x3_t, i8]
      - ["*const i64", int64x1x3_t, i64]
      - ["*const f32", float32x4x3_t, f32]
      - ["*const f32", float32x2x3_t, f32]
    compose:
      - LLVMLink:
          name: 'ld3r{neon_type[1].dup_nox}'
          arguments:
            - 'ptr: {type[0]}'
          links:
            - link: 'llvm.aarch64.neon.ld3r.v{neon_type[1].lane}{type[2]}.p0'
              arch: aarch64,arm64ec
      - FnCall: ['_vld3{neon_type[1].dup_nox}', ['a as _']]

  - name: "vld3{neon_type[1].dup_nox}"
    doc: Load single 3-element structure and replicate to all lanes of three registers
    arguments: ["a: {type[0]}"]
    return_type: "{neon_type[1]}"
    attr: [*enable-v7, *target-is-arm, *neon-arm-unstable]
    assert_instr: [vld3]
    safety:
      unsafe: [neon]
    types:
      - ["*const i8", int8x8x3_t, i8, '1']
      - ["*const i16", int16x4x3_t, i16, '2']
      - ["*const i32", int32x2x3_t, i32, '4']
      - ["*const i8", int8x16x3_t, i8, '1']
      - ["*const i16", int16x8x3_t, i16, '2']
      - ["*const i32", int32x4x3_t, i32, '4']
      - ["*const f32", float32x4x3_t, f32, '4']
      - ["*const f32", float32x2x3_t, f32, '4']
    compose:
      - LLVMLink:
          name: 'vld3{neon_type[1].dup_nox}'
          arguments:
            - 'ptr: *const i8'
            - 'size: i32'
          links:
            - link: 'llvm.arm.neon.vld3dup.v{neon_type[1].lane}{type[2]}.p0'
              arch: arm
      - FnCall: ['_vld3{neon_type[1].dup_nox}', ['a as *const i8', '{type[3]}']]

  - name: "vld3{neon_type[1].dup_nox}"
    doc: Load single 3-element structure and replicate to all lanes of three registers
    arguments: ["a: {type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vld3]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ld3r]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety:
      unsafe: [neon]
    types:
      - ['*const u8', uint8x8x3_t, int8x8x3_t]
      - ['*const u16', uint16x4x3_t, int16x4x3_t]
      - ['*const u32', uint32x2x3_t, int32x2x3_t]
      - ['*const u8', uint8x16x3_t, int8x16x3_t]
      - ['*const u16', uint16x8x3_t, int16x8x3_t]
      - ['*const u32', uint32x4x3_t, int32x4x3_t]
      - ['*const p8', poly8x8x3_t, int8x8x3_t]
      - ['*const p16', poly16x4x3_t, int16x4x3_t]
      - ['*const p8', poly8x16x3_t, int8x16x3_t]
      - ['*const p16', poly16x8x3_t, int16x8x3_t]
    compose:
      - FnCall:
          - transmute
          - - FnCall:
                - 'vld3{neon_type[2].dup_nox}'
                - - FnCall:
                      - transmute
                      - - a

  - name: "vld3{neon_type[1].dup_nox}"
    doc: Load single 3-element structure and replicate to all lanes of three registers
    arguments: ["a: {type[0]}"]
    return_type: "{neon_type[1]}"
    attr: [*target-is-arm, *enable-v7, *neon-arm-unstable]
    assert_instr: [nop]
    safety:
      unsafe: [neon]
    types:
      - ["*const i64", int64x1x3_t, i64, '8']
    compose:
      - LLVMLink:
          name: 'vld3{neon_type[1].dup_nox}'
          arguments:
            - 'ptr: *const i8'
            - 'size: i32'
          links:
            - link: 'llvm.arm.neon.vld3dup.v{neon_type[1].lane}{type[2]}.p0'
              arch: arm
      - FnCall: ['_vld3{neon_type[1].dup_nox}', ['a as *const i8', '{type[3]}']]

  - name: "vld3{neon_type[1].dup_nox}"
    doc: Load single 3-element structure and replicate to all lanes of three registers
    arguments: ["a: {type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [nop]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ld3r]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety:
      unsafe: [neon]
    types:
      - ["*const u64", uint64x1x3_t, int64x1x3_t]
    compose:
      - FnCall:
          - transmute
          - - FnCall:
                - 'vld3{neon_type[2].dup_nox}'
                - - FnCall:
                      - transmute
                      - - a

  - name: "vld3{neon_type[1].dup_nox}"
    doc: Load single 3-element structure and replicate to all lanes of three registers
    arguments: ["a: {type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-aes
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [nop]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ld3r]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety:
      unsafe: [neon]
    types:
      - ["*const p64", poly64x1x3_t, int64x1x3_t]
    compose:
      - FnCall:
          - transmute
          - - FnCall:
                - 'vld3{neon_type[2].dup_nox}'
                - - FnCall:
                      - transmute
                      - - a

  - name: "vld4{neon_type[1].nox}"
    doc: Load multiple 4-element structures to four registers
    arguments: ["a: {type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *target-not-arm
      - *neon-stable
    assert_instr: [ld4]
    safety:
      unsafe: [neon]
    types:
      - ['*const i8', int8x8x4_t, i8, "8"]
      - ['*const i32', int32x4x4_t, i32, "4"]
      - ['*const i16', int16x4x4_t, i16, "4"]
      - ['*const i32', int32x2x4_t, i32, "2"]
      - ['*const i8', int8x16x4_t, i8, "16"]
      - ['*const i16', int16x8x4_t, i16, "8"]
      - ['*const f32', float32x2x4_t, f32, "2"]
      - ['*const f32', float32x4x4_t, f32, "4"]
    compose:
      - FnCall: ["crate::core_arch::macros::deinterleaving_load!", [{ Type: "{type[2]}" }, "{type[3]}", "4", a], [], true]

  - name: "vld4{neon_type[1].nox}"
    doc: Load multiple 4-element structures to four registers
    arguments: ["a: {type[0]}"]
    return_type: "{neon_type[1]}"
    attr: [*target-not-arm, *neon-stable]
    assert_instr: [nop]
    safety:
      unsafe: [neon]
    types:
      - ['*const i64', int64x1x4_t, i64, '*const int64x1_t']
    compose:
      - FnCall:
          - 'crate::ptr::read_unaligned'
          - - MethodCall:
                - a
                - cast
                - []

  - name: "vld4{neon_type[1].lane_nox}"
    doc: Load multiple 4-element structures to four registers
    arguments: ["a: {type[0]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *target-not-arm
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [ld4, 'LANE = 0']]}]]
      - FnCall: [rustc_legacy_const_generics, ["2"]]
      - *neon-stable
    static_defs:
      - "const LANE: i32"
    safety:
      unsafe: [neon]
    types:
      - ['*const i8', int8x8x4_t, int8x8_t, i8, '3']
      - ['*const i16', int16x4x4_t, int16x4_t, i16, '2']
      - ['*const i16', int16x8x4_t, int16x8_t, i16, '3']
      - ['*const i32', int32x2x4_t, int32x2_t, i32, '1']
      - ['*const i32', int32x4x4_t, int32x4_t, i32, '2']
      - ['*const f32', float32x2x4_t, float32x2_t, f32, '1']
      - ['*const f32', float32x4x4_t, float32x4_t, f32, '2']
    compose:
      - FnCall: [static_assert_uimm_bits!, [LANE, '{type[4]}']]
      - LLVMLink:
          name: 'ld4lane.{neon_type[2]}'
          arguments:
            - 'a: {type[2]}'
            - 'b: {type[2]}'
            - 'c: {type[2]}'
            - 'd: {type[2]}'
            - 'n: i64'
            - 'ptr: *const i8'
          links:
            - link: 'llvm.aarch64.neon.ld4lane.v{neon_type[1].lane}{type[3]}.p0'
              arch: aarch64,arm64ec
      - FnCall: ['_vld4{neon_type[1].lane_nox}', ['b.0', 'b.1', 'b.2', 'b.3', 'LANE as i64', 'a as _']]

  - name: "vld4{neon_type[1].nox}"
    doc: Load multiple 4-element structures to four registers
    arguments: ["a: {type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *enable-v7
      - *target-is-arm
      - *neon-arm-unstable
    assert_instr: [vld4]
    safety:
      unsafe: [neon]
    types:
      - ['*const i8', int8x8x4_t, i8, '1']
      - ['*const i16', int16x4x4_t, i16, '2']
      - ['*const i32', int32x2x4_t, i32, '4']
      - ['*const i8', int8x16x4_t, i8, '1']
      - ['*const i16', int16x8x4_t, i16, '2']
      - ['*const i32', int32x4x4_t, i32, '4']
      - ['*const f32', float32x4x4_t, f32, '4']
      - ['*const f32', float32x2x4_t, f32, '4']
    compose:
      - LLVMLink:
          name: 'vld4{neon_type[1].nox}'
          arguments:
            - 'ptr: *const i8'
            - 'size: i32'
          links:
            - link: 'llvm.arm.neon.vld4.v{neon_type[1].lane}{type[2]}.p0'
              arch: arm
      - FnCall: ['_vld4{neon_type[1].nox}', ['a as *const i8', '{type[3]}']]

  - name: "vld4{neon_type[1].nox}"
    doc: Load multiple 4-element structures to four registers
    arguments: ["a: {type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *enable-v7
      - *target-is-arm
      - *neon-arm-unstable
    assert_instr: [nop]
    safety:
      unsafe: [neon]
    types:
      - ['*const i64', int64x1x4_t, i64, '8']
    compose:
      - LLVMLink:
          name: 'vld4{neon_type[1].nox}'
          arguments:
            - 'ptr: *const i8'
            - 'size: i32'
          links:
            - link: 'llvm.arm.neon.vld4.v{neon_type[1].lane}{type[2]}.p0'
              arch: arm
      - FnCall: ['_vld4{neon_type[1].nox}', ['a as *const i8', '{type[3]}']]

  - name: "vld4{neon_type[1].nox}"
    doc: Load multiple 4-element structures to four registers
    arguments: ["a: {type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vld4]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ld4]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    big_endian_inverse: false
    safety:
      unsafe: [neon]
    types:
      - ['*const u8', uint8x8x4_t, int8x8x4_t]
      - ['*const u16', uint16x4x4_t, int16x4x4_t]
      - ['*const u32', uint32x2x4_t, int32x2x4_t]
      - ['*const u8', uint8x16x4_t, int8x16x4_t]
      - ['*const u16', uint16x8x4_t, int16x8x4_t]
      - ['*const u32', uint32x4x4_t, int32x4x4_t]
      - ['*const p8', poly8x8x4_t, int8x8x4_t]
      - ['*const p16', poly16x4x4_t, int16x4x4_t]
      - ['*const p8', poly8x16x4_t, int8x16x4_t]
      - ['*const p16', poly16x8x4_t, int16x8x4_t]
    compose:
      - FnCall:
          - transmute
          - - FnCall:
                - 'vld4{neon_type[2].nox}'
                - - FnCall:
                      - transmute
                      - - a

  - name: "vld4{neon_type[1].nox}"
    doc: Load multiple 4-element structures to four registers
    arguments: ["a: {type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [nop]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [nop]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety:
      unsafe: [neon]
    types:
      - ['*const u64', uint64x1x4_t, int64x1x4_t]
    compose:
      - FnCall:
          - transmute
          - - FnCall:
                - 'vld4{neon_type[2].nox}'
                - - FnCall:
                      - transmute
                      - - a

  - name: "vld4{neon_type[1].nox}"
    doc: Load multiple 4-element structures to four registers
    arguments: ["a: {type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v8
      - FnCall:
          - target_feature
          - - 'enable = "neon,aes"'
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [nop]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [nop]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety:
      unsafe: [neon]
    types:
      - ['*const p64', poly64x1x4_t, int64x1x4_t]
    compose:
      - FnCall:
          - transmute
          - - FnCall:
                - 'vld4{neon_type[2].nox}'
                - - FnCall:
                      - transmute
                      - - a

  - name: "vld4{neon_type[1].lane_nox}"
    doc: Load multiple 4-element structures to four registers
    arguments: ["a: {type[0]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *enable-v7
      - *target-is-arm
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [vld4, 'LANE = 0']]}]]
      - FnCall: [rustc_legacy_const_generics, ["2"]]
      - *neon-arm-unstable
    static_defs: ["const LANE: i32"]
    safety:
      unsafe: [neon]
    types:
      - ['*const i8', int8x8x4_t, int8x8_t, i8, '1', '3']
      - ['*const i16', int16x4x4_t, int16x4_t, i16, '2', '2']
      - ['*const i32', int32x2x4_t, int32x2_t, i32, '4', '1']
      - ['*const i16', int16x8x4_t, int16x8_t, i16, '2', '3']
      - ['*const i32', int32x4x4_t, int32x4_t, i32, '4', '2']
      - ['*const f32', float32x2x4_t, float32x2_t, f32, '4', '1']
      - ['*const f32', float32x4x4_t, float32x4_t, f32, '4', '2']
    compose:
      - FnCall: [static_assert_uimm_bits!, [LANE, '{type[5]}']]
      - LLVMLink:
          name: 'ld4lane.{neon_type[2]}'
          arguments:
            - 'ptr: *const i8'
            - 'a: {type[2]}'
            - 'b: {type[2]}'
            - 'c: {type[2]}'
            - 'd: {type[2]}'
            - 'n: i32'
            - 'size: i32'
          links:
            - link: 'llvm.arm.neon.vld4lane.v{neon_type[1].lane}{type[3]}.p0'
              arch: arm
      - FnCall: ['_vld4{neon_type[1].lane_nox}', ['a as _', 'b.0', 'b.1', 'b.2', 'b.3', LANE, '{type[4]}']]

  - name: "vld4{neon_type[1].lane_nox}"
    doc: Load multiple 4-element structures to four registers
    arguments: ["a: {type[0]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vld4, 'LANE = 0']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ld4, 'LANE = 0']]}]]
      - FnCall: [rustc_legacy_const_generics, ["2"]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ["const LANE: i32"]
    big_endian_inverse: false
    safety:
      unsafe: [neon]
    types:
      - ['*const u8', uint8x8x4_t, int8x8x4_t, '3']
      - ['*const u16', uint16x4x4_t, int16x4x4_t, '2']
      - ['*const u32', uint32x2x4_t, int32x2x4_t, '1']
      - ['*const u16', uint16x8x4_t, int16x8x4_t, '3']
      - ['*const u32', uint32x4x4_t, int32x4x4_t, '2']
      - ['*const p8', poly8x8x4_t, int8x8x4_t, '3']
      - ['*const p16', poly16x4x4_t, int16x4x4_t, '2']
      - ['*const p16', poly16x8x4_t, int16x8x4_t, '3']
    compose:
      - FnCall: [static_assert_uimm_bits!, ['LANE', '{type[3]}']]
      - FnCall:
          - transmute
          - - FnCall:
                - 'vld4{neon_type[2].lane_nox}::<LANE>'
                - - FnCall: [transmute, [a]]
                  - FnCall: [transmute, [b]]

  - name: "vst1{neon_type[1].lane_nox}"
    doc: "Store multiple single-element structures from one, two, three, or four registers"
    arguments: ["a: {type[0]}", "b: {neon_type[1]}"]
    static_defs: ["const LANE: i32"]
    safety:
      unsafe: [neon]
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [nop, 'LANE = 0']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [nop, 'LANE = 0']]}]]
      - FnCall: [rustc_legacy_const_generics, ["2"]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    types:
      - ['*mut i64', int64x1_t]
      - ['*mut u64', uint64x1_t]
    compose:
      - FnCall: [static_assert!, ['LANE == 0']]
      - Assign:
          - "*a"
          - FnCall: [simd_extract!, [b, 'LANE as u32']]
      - Identifier: [';', Symbol]

  - name: "vst1{neon_type[1].lane_nox}"
    doc: "Store multiple single-element structures from one, two, three, or four registers"
    arguments: ["a: {type[0]}", "b: {neon_type[1]}"]
    static_defs: ["const LANE: i32"]
    safety:
      unsafe: [neon]
    attr:
      - *neon-v8
      - FnCall:
          - target_feature
          - - 'enable = "neon,aes"'
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [nop, 'LANE = 0']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [nop, 'LANE = 0']]}]]
      - FnCall: [rustc_legacy_const_generics, ["2"]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    types:
      - ['*mut p64', poly64x1_t]
    compose:
      - FnCall: [static_assert!, ['LANE == 0']]
      - Assign:
          - "*a"
          - FnCall: [simd_extract!, [b, 'LANE as u32']]
      - Identifier: [';', Symbol]

  - name: "vst1{neon_type[1].lane_nox}"
    doc: "Store multiple single-element structures from one, two, three, or four registers"
    arguments: ["a: {type[0]}", "b: {neon_type[1]}"]
    static_defs: ["const LANE: i32"]
    safety:
      unsafe: [neon]
    attr:
      - *neon-v8
      - FnCall:
          - target_feature
          - - 'enable = "neon,aes"'
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [nop, 'LANE = 0']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [nop, 'LANE = 0']]}]]
      - FnCall: [rustc_legacy_const_generics, ["2"]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    types:
      - ['*mut p64', poly64x2_t]
    compose:
      - FnCall: [static_assert_uimm_bits!, [LANE, '1']]
      - Assign:
          - "*a"
          - FnCall: [simd_extract!, [b, 'LANE as u32']]
      - Identifier: [';', Symbol]

  - name: "vst1{neon_type[1].lane_nox}"
    doc: "Store multiple single-element structures from one, two, three, or four registers"
    arguments: ["a: {type[0]}", "b: {neon_type[1]}"]
    static_defs: ["const LANE: i32"]
    safety:
      unsafe: [neon]
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [nop, 'LANE = 0']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [nop, 'LANE = 0']]}]]
      - FnCall: [rustc_legacy_const_generics, ["2"]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    types:
      - ['*mut i8', int8x8_t, '3']
      - ['*mut i16', int16x4_t, '2']
      - ['*mut i32', int32x2_t, '1']
      - ['*mut i8', int8x16_t, '4']
      - ['*mut i16', int16x8_t, '3']
      - ['*mut i32', int32x4_t, '2']
      - ['*mut i64', int64x2_t, '1']
      - ['*mut u8', uint8x8_t, '3']
      - ['*mut u16', uint16x4_t, '2']
      - ['*mut u32', uint32x2_t, '1']
      - ['*mut u8', uint8x16_t, '4']
      - ['*mut u16', uint16x8_t, '3']
      - ['*mut u32', uint32x4_t, '2']
      - ['*mut u64', uint64x2_t, '1']
      - ['*mut p8', poly8x8_t, '3']
      - ['*mut p16', poly16x4_t, '2']
      - ['*mut p8', poly8x16_t, '4']
      - ['*mut p16', poly16x8_t, '3']
      - ['*mut f32', float32x2_t, '1']
      - ['*mut f32', float32x4_t, '2']
    compose:
      - FnCall: [static_assert_uimm_bits!, [LANE, "{type[2]}"]]
      - Assign:
          - "*a"
          - FnCall: [simd_extract!, [b, 'LANE as u32']]
      - Identifier: [';', Symbol]


  - name: "vst1{neon_type[1].lane_nox}"
    doc: "Store multiple single-element structures from one, two, three, or four registers"
    arguments: ["a: {type[0]}", "b: {neon_type[1]}"]
    static_defs: ["const LANE: i32"]
    safety:
      unsafe: [neon]
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [nop, 'LANE = 0']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [nop, 'LANE = 0']]}]]
      - FnCall: [rustc_legacy_const_generics, ["2"]]
      - *arm-fp16
      - *neon-unstable-f16
      - *target-not-arm64ec
    types:
      - ['*mut f16', float16x4_t, '2']
      - ['*mut f16', float16x8_t, '3']
    compose:
      - FnCall: [static_assert_uimm_bits!, [LANE, "{type[2]}"]]
      - Assign:
          - "*a"
          - FnCall: [simd_extract!, [b, 'LANE as u32']]
      - Identifier: [';', Symbol]


  - name: 'vst1{neon_type[1].no}'
    doc: "Store multiple single-element structures from one, two, three, or four registers"
    arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"]
    safety:
      unsafe: [neon]
    attr:
      - *target-not-arm
      - *neon-stable
    assert_instr: [st1]
    types:
      - [i8, int8x8x2_t, int8x8_t]
      - [i16, int16x4x2_t, int16x4_t]
      - [i32, int32x2x2_t, int32x2_t]
      - [i64, int64x1x2_t, int64x1_t]
      - [i8, int8x16x2_t, int8x16_t]
      - [i16, int16x8x2_t, int16x8_t]
      - [i32, int32x4x2_t, int32x4_t]
      - [i64, int64x2x2_t, int64x2_t]
    compose:
      - LLVMLink:
          name: 'st1x2.{neon_type[1]}'
          arguments:
            - 'a: {type[2]}'
            - 'b: {type[2]}'
            - 'ptr: *mut {type[0]}'
          links:
            - link: 'llvm.aarch64.neon.st1x2.v{neon_type[1].lane}{type[0]}.p0'
              arch: aarch64,arm64ec
      - FnCall: ['_vst1{neon_type[1].no}', ['b.0', 'b.1', 'a']]

  - name: 'vst1{neon_type[1].no}'
    doc: "Store multiple single-element structures from one, two, three, or four registers"
    arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"]
    safety:
      unsafe: [neon]
    attr:
      - *target-not-arm
      - *neon-stable
    assert_instr: [st1]
    types:
      - [i8, int8x8x3_t, int8x8_t]
      - [i16, int16x4x3_t, int16x4_t]
      - [i32, int32x2x3_t, int32x2_t]
      - [i64, int64x1x3_t, int64x1_t]
      - [i8, int8x16x3_t, int8x16_t]
      - [i16, int16x8x3_t, int16x8_t]
      - [i32, int32x4x3_t, int32x4_t]
      - [i64, int64x2x3_t, int64x2_t]
    compose:
      - LLVMLink:
          name: 'st1x3.{neon_type[1]}'
          arguments:
            - 'a: {type[2]}'
            - 'b: {type[2]}'
            - 'c: {type[2]}'
            - 'ptr: *mut {type[0]}'
          links:
            - link: 'llvm.aarch64.neon.st1x3.v{neon_type[1].lane}{type[0]}.p0'
              arch: aarch64,arm64ec
      - FnCall: ['_vst1{neon_type[1].no}', ['b.0', 'b.1', 'b.2', 'a']]

  - name: 'vst1{neon_type[1].no}'
    doc: "Store multiple single-element structures from one, two, three, or four registers"
    arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"]
    safety:
      unsafe: [neon]
    attr:
      - *target-not-arm
      - *neon-stable
    assert_instr: [st1]
    types:
      - [i8, int8x8x4_t, int8x8_t]
      - [i16, int16x4x4_t, int16x4_t]
      - [i32, int32x2x4_t, int32x2_t]
      - [i64, int64x1x4_t, int64x1_t]
      - [i8, int8x16x4_t, int8x16_t]
      - [i16, int16x8x4_t, int16x8_t]
      - [i32, int32x4x4_t, int32x4_t]
      - [i64, int64x2x4_t, int64x2_t]
    compose:
      - LLVMLink:
          name: 'st1x4.{neon_type[1]}'
          arguments:
            - 'a: {type[2]}'
            - 'b: {type[2]}'
            - 'c: {type[2]}'
            - 'd: {type[2]}'
            - 'ptr: *mut {type[0]}'
          links:
            - link: 'llvm.aarch64.neon.st1x4.v{neon_type[1].lane}{type[0]}.p0'
              arch: aarch64,arm64ec
      - FnCall: ['_vst1{neon_type[1].no}', ['b.0', 'b.1', 'b.2', 'b.3', 'a']]

  - name: 'vst1{neon_type[1].no}'
    doc: "Store multiple single-element structures from one, two, three, or four registers"
    arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"]
    safety:
      unsafe: [neon]
    attr:
      - *enable-v7
      - *target-is-arm
      - *neon-arm-unstable
    assert_instr: [vst1]
    types:
      - [i8, int8x8x2_t, int8x8_t]
      - [i16, int16x4x2_t, int16x4_t]
      - [i32, int32x2x2_t, int32x2_t]
      - [i64, int64x1x2_t, int64x1_t]
      - [i8, int8x16x2_t, int8x16_t]
      - [i16, int16x8x2_t, int16x8_t]
      - [i32, int32x4x2_t, int32x4_t]
      - [i64, int64x2x2_t, int64x2_t]
    compose:
      - LLVMLink:
          name: 'st1x2.{neon_type[1]}'
          arguments:
            - 'ptr: *mut {type[0]}'
            - 'a: {type[2]}'
            - 'b: {type[2]}'
          links:
            - link: 'llvm.arm.neon.vst1x2.v{neon_type[1].lane}{type[0]}.p0'
              arch: arm
      - FnCall: ['_vst1{neon_type[1].no}', ['a', 'b.0', 'b.1']]

  - name: 'vst1{neon_type[1].no}'
    doc: "Store multiple single-element structures from one, two, three, or four registers"
    arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"]
    safety:
      unsafe: [neon]
    attr:
      - *enable-v7
      - *target-is-arm
      - *neon-arm-unstable
    assert_instr: [vst1]
    types:
      - [i8, int8x8x3_t, int8x8_t]
      - [i16, int16x4x3_t, int16x4_t]
      - [i32, int32x2x3_t, int32x2_t]
      - [i64, int64x1x3_t, int64x1_t]
      - [i8, int8x16x3_t, int8x16_t]
      - [i16, int16x8x3_t, int16x8_t]
      - [i32, int32x4x3_t, int32x4_t]
      - [i64, int64x2x3_t, int64x2_t]
    compose:
      - LLVMLink:
          name: 'st1x3.{neon_type[1]}'
          arguments:
            - 'ptr: *mut {type[0]}'
            - 'a: {type[2]}'
            - 'b: {type[2]}'
            - 'c: {type[2]}'
          links:
            - link: 'llvm.arm.neon.vst1x3.p0.v{neon_type[1].lane}{type[0]}.p0'
              arch: arm
      - FnCall: ['_vst1{neon_type[1].no}', ['a', 'b.0', 'b.1', 'b.2']]

  - name: 'vst1{neon_type[1].no}'
    doc: "Store multiple single-element structures from one, two, three, or four registers"
    arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"]
    safety:
      unsafe: [neon]
    attr:
      - *target-is-arm
      - *enable-v7
      - *neon-arm-unstable
    assert_instr: [vst1]
    types:
      - [i8, int8x8x4_t, int8x8_t]
      - [i16, int16x4x4_t, int16x4_t]
      - [i32, int32x2x4_t, int32x2_t]
      - [i64, int64x1x4_t, int64x1_t]
      - [i8, int8x16x4_t, int8x16_t]
      - [i16, int16x8x4_t, int16x8_t]
      - [i32, int32x4x4_t, int32x4_t]
      - [i64, int64x2x4_t, int64x2_t]
    compose:
      - LLVMLink:
          name: 'st1x4.{neon_type[1]}'
          arguments:
            - 'ptr: *mut {type[0]}'
            - 'a: {type[2]}'
            - 'b: {type[2]}'
            - 'c: {type[2]}'
            - 'd: {type[2]}'
          links:
            - link: 'llvm.arm.neon.vst1x4.p0.v{neon_type[1].lane}{type[0]}.p0'
              arch: arm
      - FnCall: ['_vst1{neon_type[1].no}', ['a', 'b.0', 'b.1', 'b.2', 'b.3']]

  - name: 'vst1{neon_type[1].no}'
    doc: "Store multiple single-element structures to one, two, three, or four registers"
    arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"]
    safety:
      unsafe: [neon]
    attr:
      - *target-is-arm
      - *enable-v7
      - *neon-arm-unstable
    assert_instr: [vst1]
    types:
      - [f32, float32x2x4_t, float32x2_t]
      - [f32, float32x4x4_t, float32x4_t]
    compose:
      - LLVMLink:
          name: 'st1x4.{neon_type[1]}'
          arguments:
            - 'ptr: *mut {type[0]}'
            - 'a: {type[2]}'
            - 'b: {type[2]}'
            - 'c: {type[2]}'
            - 'd: {type[2]}'
          links:
            - link: 'llvm.arm.neon.vst1x4.p0.v{neon_type[1].lane}{type[0]}.p0'
              arch: arm
      - FnCall: ['_vst1{neon_type[1].no}', ['a', 'b.0', 'b.1', 'b.2', 'b.3']]

  - name: 'vst1{neon_type[1].no}'
    doc: "Store multiple single-element structures to one, two, three, or four registers"
    arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"]
    safety:
      unsafe: [neon]
    attr:
      - *target-is-arm
      - *neon-v7
      - *arm-fp16
      - *neon-unstable-f16
      - *target-not-arm64ec
    assert_instr: [vst1]
    types:
      - [f16, float16x4x4_t, float16x4_t]
      - [f16, float16x8x4_t, float16x8_t]
    compose:
      - LLVMLink:
          name: 'st1x4.{neon_type[1]}'
          arguments:
            - 'ptr: *mut {type[0]}'
            - 'a: {type[2]}'
            - 'b: {type[2]}'
            - 'c: {type[2]}'
            - 'd: {type[2]}'
          links:
            - link: 'llvm.arm.neon.vst1x4.p0.v{neon_type[1].lane}{type[0]}'
              arch: arm
      - FnCall: ['_vst1{neon_type[1].no}', ['a', 'b.0', 'b.1', 'b.2', 'b.3']]

  - name: "vst2{neon_type[1].nox}"
    doc: "Store multiple 2-element structures from two registers"
    arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"]
    attr:
      - *neon-v8
      - *neon-aes
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [nop]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [nop]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety:
      unsafe: [neon]
    types:
      - [p64, poly64x1x2_t, int64x1x2_t]
    compose:
      - FnCall:
          - "vst2{neon_type[2].nox}"
          - - FnCall: [transmute, [a]]
            - FnCall: [transmute, [b]]

  - name: "vst2{neon_type[1].nox}"
    doc: "Store multiple 2-element structures from two registers"
    arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"]
    attr:
      - *target-is-arm
      - *enable-v7
      - *neon-arm-unstable
    assert_instr: [nop]
    safety:
      unsafe: [neon]
    types:
      - [i64, int64x1x2_t, int64x1_t]
    compose:
      - LLVMLink:
          name: 'vst2.{neon_type[1]}'
          arguments:
            - 'ptr: *mut i8'
            - 'a: {type[2]}'
            - 'b: {type[2]}'
            - 'size: i32'
          links:
            - link: 'llvm.arm.neon.vst2.v{neon_type[1].lane}{type[0]}.p0'
              arch: arm
      - FnCall: ['_vst2{neon_type[1].nox}', ['a as _', 'b.0', 'b.1', '8']]

  - name: "vst2{neon_type[1].nox}"
    doc: "Store multiple 2-element structures from two registers"
    arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"]
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [nop]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [nop]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety:
      unsafe: [neon]
    types:
      - [u64, uint64x1x2_t, int64x1x2_t]
    compose:
      - FnCall:
          - "vst2{neon_type[2].nox}"
          - - FnCall: [transmute, [a]]
            - FnCall: [transmute, [b]]

  - name: "vst2{neon_type[1].nox}"
    doc: "Store multiple 2-element structures from two registers"
    arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"]
    attr:
      - *target-not-arm
      - *neon-stable
    assert_instr: [nop]
    safety:
      unsafe: [neon]
    types:
      - [i64, int64x1x2_t, int64x1_t]
    compose:
      - LLVMLink:
          name: 'st2.{neon_type[1]}'
          arguments:
            - 'a: {type[2]}'
            - 'b: {type[2]}'
            - 'ptr: *mut i8'
          links:
            - link: 'llvm.aarch64.neon.st2.v{neon_type[1].lane}{type[0]}.p0'
              arch: aarch64,arm64ec
      - FnCall: ['_vst2{neon_type[1].nox}', ['b.0', 'b.1', 'a as _']]

  - name: "vst2{neon_type[1].nox}"
    doc: "Store multiple 2-element structures from two registers"
    arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"]
    attr:
      - *target-not-arm
      - *neon-stable
    assert_instr: [st2]
    safety:
      unsafe: [neon]
    types:
      - [i8, int8x8x2_t, int8x8_t]
      - [i16, int16x4x2_t, int16x4_t]
      - [i32, int32x2x2_t, int32x2_t]
      - [i8, int8x16x2_t, int8x16_t]
      - [i16, int16x8x2_t, int16x8_t]
      - [i32, int32x4x2_t, int32x4_t]
      - [f32, float32x2x2_t, float32x2_t]
      - [f32, float32x4x2_t, float32x4_t]
    compose:
      - LLVMLink:
          name: 'st2.{neon_type[1]}'
          arguments:
            - 'a: {type[2]}'
            - 'b: {type[2]}'
            - 'ptr: *mut i8'
          links:
            - link: 'llvm.aarch64.neon.st2.v{neon_type[1].lane}{type[0]}.p0'
              arch: aarch64,arm64ec
      - FnCall: ['_vst2{neon_type[1].nox}', ['b.0', 'b.1', 'a as _']]


  - name: "vst2{neon_type[1].nox}"
    doc: "Store multiple 2-element structures from two registers"
    arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"]
    attr:
      - *target-not-arm
      - *arm-fp16
      - *neon-unstable-f16
      - *target-not-arm64ec
    assert_instr: [st2]
    safety:
      unsafe: [neon]
    types:
      - [f16, float16x4x2_t, float16x4_t]
      - [f16, float16x8x2_t, float16x8_t]
    compose:
      - LLVMLink:
          name: 'st2.{neon_type[1]}'
          arguments:
            - 'a: {type[2]}'
            - 'b: {type[2]}'
            - 'ptr: *mut i8'
          links:
            - link: 'llvm.aarch64.neon.st2.v{neon_type[1].lane}{type[0]}.p0'
              arch: aarch64,arm64ec
      - FnCall: ['_vst2{neon_type[1].nox}', ['b.0', 'b.1', 'a as _']]


  - name: "vst2{neon_type[1].nox}"
    doc: "Store multiple 2-element structures from two registers"
    arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"]
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vst2]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [st2]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety:
      unsafe: [neon]
    types:
      - [u8, uint8x8x2_t, int8x8x2_t]
      - [u16, uint16x4x2_t, int16x4x2_t]
      - [u32, uint32x2x2_t, int32x2x2_t]
      - [u8, uint8x16x2_t, int8x16x2_t]
      - [u16, uint16x8x2_t, int16x8x2_t]
      - [u32, uint32x4x2_t, int32x4x2_t]
      - [p8, poly8x8x2_t, int8x8x2_t]
      - [p16, poly16x4x2_t, int16x4x2_t]
      - [p8, poly8x16x2_t, int8x16x2_t]
      - [p16, poly16x8x2_t, int16x8x2_t]
    compose:
      - FnCall:
          - "vst2{neon_type[2].nox}"
          - - FnCall: [transmute, [a]]
            - FnCall: [transmute, [b]]

  - name: "vst2{neon_type[1].lane_nox}"
    doc: "Store multiple 2-element structures from two registers"
    arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"]
    attr:
      - *target-not-arm
      - FnCall: [rustc_legacy_const_generics, ['2']]
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [st2, 'LANE = 0']]}]]
      - *neon-stable
    static_defs: ['const LANE: i32']
    safety:
      unsafe: [neon]
    types:
      - [i8, int8x8x2_t, '3', int8x8_t]
      - [i16, int16x4x2_t, '2', int16x4_t]
      - [i32, int32x2x2_t, '1', int32x2_t]
      - [i16, int16x8x2_t, '3', int16x8_t]
      - [i32, int32x4x2_t, '2', int32x4_t]
      - [f32, float32x2x2_t, '1', float32x2_t]
      - [f32, float32x4x2_t, '2', float32x4_t]
    compose:
      - FnCall: [static_assert_uimm_bits!, [LANE, "{type[2]}"]]
      - LLVMLink:
          name: 'vst2.{neon_type[1].lane_nox}'
          arguments:
            - 'a: {type[3]}'
            - 'b: {type[3]}'
            - 'n: i64'
            - 'ptr: *mut i8'
          links:
            - link: 'llvm.aarch64.neon.st2lane.v{neon_type[1].lane}{type[0]}.p0'
              arch: aarch64,arm64ec
      - FnCall: ['_vst2{neon_type[1].lane_nox}', ['b.0', 'b.1', 'LANE as i64', 'a as _']]


  - name: "vst2{neon_type[1].lane_nox}"
    doc: "Store multiple 2-element structures from two registers"
    arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"]
    attr:
      - *target-not-arm
      - FnCall: [rustc_legacy_const_generics, ['2']]
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [st2, 'LANE = 0']]}]]
      - *arm-fp16
      - *neon-unstable-f16
      - *target-not-arm64ec
    static_defs: ['const LANE: i32']
    safety:
      unsafe: [neon]
    types:
      - [f16, float16x4x2_t, '2', float16x4_t]
      - [f16, float16x8x2_t, '3', float16x8_t]
    compose:
      - FnCall: [static_assert_uimm_bits!, [LANE, "{type[2]}"]]
      - LLVMLink:
          name: 'vst2.{neon_type[1].lane_nox}'
          arguments:
            - 'a: {type[3]}'
            - 'b: {type[3]}'
            - 'n: i64'
            - 'ptr: *mut i8'
          links:
            - link: 'llvm.aarch64.neon.st2lane.v{neon_type[1].lane}{type[0]}.p0'
              arch: aarch64,arm64ec
      - FnCall: ['_vst2{neon_type[1].lane_nox}', ['b.0', 'b.1', 'LANE as i64', 'a as _']]


  - name: "vst2{neon_type[1].lane_nox}"
    doc: "Store multiple 2-element structures from two registers"
    arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"]
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vst2, 'LANE = 0']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [st2, 'LANE = 0']]}]]
      - FnCall: [rustc_legacy_const_generics, ['2']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const LANE: i32']
    safety:
      unsafe: [neon]
    types:
      - [u8, uint8x8x2_t, int8x8x2_t, '3']
      - [u16, uint16x4x2_t, int16x4x2_t, '2']
      - [u32, uint32x2x2_t, int32x2x2_t, '1']
      - [u16, uint16x8x2_t, int16x8x2_t, '3']
      - [u32, uint32x4x2_t, int32x4x2_t, '2']
      - [p8, poly8x8x2_t, int8x8x2_t, '3']
      - [p16, poly16x4x2_t, int16x4x2_t, '2']
      - [p16, poly16x8x2_t, int16x8x2_t, '3']
    compose:
      - FnCall: [static_assert_uimm_bits!, [LANE, "{type[3]}"]]
      - FnCall:
          - "vst2{neon_type[2].lane_nox}::<LANE>"
          - - FnCall: [transmute, [a]]
            - FnCall: [transmute, [b]]

  - name: "vst2{neon_type[1].nox}"
    doc: "Store multiple 2-element structures from two registers"
    arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"]
    attr:
      - *target-is-arm
      - *enable-v7
      - *neon-arm-unstable
    assert_instr: [vst2]
    safety:
      unsafe: [neon]
    types:
      - [i8, int8x8x2_t, int8x8_t, '1']
      - [i16, int16x4x2_t, int16x4_t, '2']
      - [i32, int32x2x2_t, int32x2_t, '4']
      - [i8, int8x16x2_t, int8x16_t, '1']
      - [i16, int16x8x2_t, int16x8_t, '2']
      - [i32, int32x4x2_t, int32x4_t, '4']
      - [f32, float32x2x2_t, float32x2_t, '4']
      - [f32, float32x4x2_t, float32x4_t, '4']
    compose:
      - LLVMLink:
          name: 'vst2.{neon_type[1]}'
          arguments:
            - 'ptr: *mut i8'
            - 'a: {type[2]}'
            - 'b: {type[2]}'
            - 'size: i32'
          links:
            - link: 'llvm.arm.neon.vst2.v{neon_type[1].lane}{type[0]}.p0'
              arch: arm
      - FnCall: ['_vst2{neon_type[1].nox}', ['a as _', 'b.0', 'b.1', "{type[3]}"]]


  - name: "vst2{neon_type[1].nox}"
    doc: "Store multiple 2-element structures from two registers"
    arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"]
    attr:
      - *target-is-arm
      - *neon-v7
      - *arm-fp16
      - *neon-unstable-f16
      - *target-not-arm64ec
    assert_instr: [vst2]
    safety:
      unsafe: [neon]
    types:
      - [f16, float16x4x2_t, float16x4_t, '2']
      - [f16, float16x8x2_t, float16x8_t, '2']
    compose:
      - LLVMLink:
          name: 'vst2.{neon_type[1]}'
          arguments:
            - 'ptr: *mut i8'
            - 'a: {type[2]}'
            - 'b: {type[2]}'
            - 'size: i32'
          links:
            - link: 'llvm.arm.neon.vst2.p0.v{neon_type[1].lane}{type[0]}'
              arch: arm
      - FnCall: ['_vst2{neon_type[1].nox}', ['a as _', 'b.0', 'b.1', "{type[3]}"]]


  - name: "vst2{neon_type[1].lane_nox}"
    doc: "Store multiple 2-element structures from two registers"
    arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"]
    attr:
      - *target-is-arm
      - *enable-v7
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [vst2, 'LANE = 0']]}]]
      - FnCall: [rustc_legacy_const_generics, ['2']]
      - *neon-arm-unstable
    static_defs: ['const LANE: i32']
    safety:
      unsafe: [neon]
    types:
      - [i8, int8x8x2_t, '3', int8x8_t, '1']
      - [i16, int16x4x2_t, '2', int16x4_t, '2']
      - [i32, int32x2x2_t, '1', int32x2_t, '4']
      - [i16, int16x8x2_t, '3', int16x8_t, '2']
      - [i32, int32x4x2_t, '2', int32x4_t, '4']
      - [f32, float32x4x2_t, '2', float32x4_t, '4']
      - [f32, float32x2x2_t, '1', float32x2_t, '4']
    compose:
      - FnCall: [static_assert_uimm_bits!, [LANE, "{type[2]}"]]
      - LLVMLink:
          name: 'vst2lane.{neon_type[1]}'
          arguments:
            - 'ptr: *mut i8'
            - 'a: {type[3]}'
            - 'b: {type[3]}'
            - 'n: i32'
            - 'size: i32'
          links:
            - link: 'llvm.arm.neon.vst2lane.v{neon_type[1].lane}{type[0]}.p0'
              arch: arm
      - FnCall: ['_vst2{neon_type[1].lane_nox}', ['a as _', 'b.0', 'b.1', 'LANE', "{type[4]}"]]


  - name: "vst2{neon_type[1].lane_nox}"
    doc: "Store multiple 2-element structures from two registers"
    arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"]
    attr:
      - *target-is-arm
      - *neon-v7
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [vst2, 'LANE = 0']]}]]
      - FnCall: [rustc_legacy_const_generics, ['2']]
      - *arm-fp16
      - *neon-unstable-f16
      - *target-not-arm64ec
    static_defs: ['const LANE: i32']
    safety:
      unsafe: [neon]
    types:
      - [f16, float16x4x2_t, '2', float16x4_t, '2']
      - [f16, float16x8x2_t, '1', float16x8_t, '2']
    compose:
      - FnCall: [static_assert_uimm_bits!, [LANE, "{type[2]}"]]
      - LLVMLink:
          name: 'vst2lane.{neon_type[1]}'
          arguments:
            - 'ptr: *mut i8'
            - 'a: {type[3]}'
            - 'b: {type[3]}'
            - 'n: i32'
            - 'size: i32'
          links:
            - link: 'llvm.arm.neon.vst2lane.p0.v{neon_type[1].lane}{type[0]}'
              arch: arm
      - FnCall: ['_vst2{neon_type[1].lane_nox}', ['a as _', 'b.0', 'b.1', 'LANE', "{type[4]}"]]


  - name: "vst3{neon_type[1].nox}"
    doc: "Store multiple 3-element structures from three registers"
    arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"]
    attr:
      - *target-not-arm
      - *neon-stable
    assert_instr: [nop]
    safety:
      unsafe: [neon]
    types:
      - [i64, int64x1x3_t, int64x1_t]
    compose:
      - LLVMLink:
          name: 'st3.{neon_type[1].nox}'
          arguments:
            - 'a: {type[2]}'
            - 'b: {type[2]}'
            - 'c: {type[2]}'
            - 'ptr: *mut i8'
          links:
            - link: 'llvm.aarch64.neon.st3.v{neon_type[1].lane}{type[0]}.p0'
              arch: aarch64,arm64ec
      - FnCall: ['_vst3{neon_type[1].nox}', ['b.0', 'b.1', 'b.2', 'a as _']]

  - name: "vst3{neon_type[1].nox}"
    doc: "Store multiple 3-element structures from three registers"
    arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"]
    attr:
      - *neon-v8
      - *neon-aes
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [nop]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [nop]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety:
      unsafe: [neon]
    types:
      - [p64, poly64x1x3_t, int64x1x3_t]
    compose:
      - FnCall:
          - "vst3{neon_type[2].nox}"
          - - FnCall: [transmute, [a]]
            - FnCall: [transmute, [b]]

  - name: "vst3{neon_type[1].nox}"
    doc: "Store multiple 3-element structures from three registers"
    arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"]
    attr:
      - *target-is-arm
      - *enable-v7
      - *neon-arm-unstable
    assert_instr: [nop]
    safety:
      unsafe: [neon]
    types:
      - [i64, int64x1x3_t, int64x1_t]
    compose:
      - LLVMLink:
          name: 'vst3.{neon_type[1]}'
          arguments:
            - 'ptr: *mut i8'
            - 'a: {type[2]}'
            - 'b: {type[2]}'
            - 'c: {type[2]}'
            - 'size: i32'
          links:
            - link: 'llvm.arm.neon.vst3.p0.v{neon_type[1].lane}{type[0]}'
              arch: arm
      - FnCall: ['_vst3{neon_type[1].nox}', ['a as _', 'b.0', 'b.1', 'b.2', '8']]

  - name: "vst3{neon_type[1].nox}"
    doc: "Store multiple 3-element structures from three registers"
    arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"]
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [nop]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [nop]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety:
      unsafe: [neon]
    types:
      - [u64, uint64x1x3_t, int64x1x3_t]
    compose:
      - FnCall:
          - "vst3{neon_type[2].nox}"
          - - FnCall: [transmute, [a]]
            - FnCall: [transmute, [b]]

  - name: "vst3{neon_type[1].lane_nox}"
    doc: "Store multiple 3-element structures from three registers"
    arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"]
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vst3, 'LANE = 0']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [st3, 'LANE = 0']]}]]
      - FnCall: [rustc_legacy_const_generics, ['2']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ["const LANE: i32"]
    safety:
      unsafe: [neon]
    types:
      - [u8, uint8x8x3_t, int8x8x3_t, '3']
      - [u16, uint16x4x3_t, int16x4x3_t, '2']
      - [u32, uint32x2x3_t, int32x2x3_t, '1']
      - [u16, uint16x8x3_t, int16x8x3_t, '3']
      - [u32, uint32x4x3_t, int32x4x3_t, '2']
      - [p8, poly8x8x3_t, int8x8x3_t, '3']
      - [p16, poly16x4x3_t, int16x4x3_t, '2']
      - [p16, poly16x8x3_t, int16x8x3_t, '3']
    compose:
      - FnCall: [static_assert_uimm_bits!, [LANE, "{type[3]}"]]
      - FnCall:
          - "vst3{neon_type[2].lane_nox}::<LANE>"
          - - FnCall: [transmute, [a]]
            - FnCall: [transmute, [b]]

  - name: "vst3{neon_type[1].nox}"
    doc: "Store multiple 3-element structures from three registers"
    arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"]
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vst3]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [st3]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety:
      unsafe: [neon]
    types:
      - [u8, uint8x8x3_t, int8x8x3_t]
      - [u16, uint16x4x3_t, int16x4x3_t]
      - [u32, uint32x2x3_t, int32x2x3_t]
      - [u8, uint8x16x3_t, int8x16x3_t]
      - [u16, uint16x8x3_t, int16x8x3_t]
      - [u32, uint32x4x3_t, int32x4x3_t]
      - [p8, poly8x8x3_t, int8x8x3_t]
      - [p16, poly16x4x3_t, int16x4x3_t]
      - [p8, poly8x16x3_t, int8x16x3_t]
      - [p16, poly16x8x3_t, int16x8x3_t]
    compose:
      - FnCall:
          - "vst3{neon_type[2].nox}"
          - - FnCall: [transmute, [a]]
            - FnCall: [transmute, [b]]

  - name: "vst3{neon_type[1].nox}"
    doc: "Store multiple 3-element structures from three registers"
    arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"]
    attr:
      - *target-is-arm
      - *enable-v7
      - *neon-arm-unstable
    assert_instr: [vst3]
    safety:
      unsafe: [neon]
    types:
      - [i8, int8x8x3_t, int8x8_t, '1']
      - [i16, int16x4x3_t, int16x4_t, '2']
      - [i32, int32x2x3_t, int32x2_t, '4']
      - [i8, int8x16x3_t, int8x16_t, '1']
      - [i16, int16x8x3_t, int16x8_t, '2']
      - [i32, int32x4x3_t, int32x4_t, '4']
      - [f32, float32x2x3_t, float32x2_t, '4']
      - [f32, float32x4x3_t, float32x4_t, '4']
    compose:
      - LLVMLink:
          name: 'vst3.{neon_type[1]}'
          arguments:
            - 'ptr: *mut i8'
            - 'a: {type[2]}'
            - 'b: {type[2]}'
            - 'c: {type[2]}'
            - 'size: i32'
          links:
            - link: 'llvm.arm.neon.vst3.p0.v{neon_type[1].lane}{type[0]}'
              arch: arm
      - FnCall: ['_vst3{neon_type[1].nox}', ['a as _', 'b.0', 'b.1', 'b.2', "{type[3]}"]]


  - name: "vst3{neon_type[1].nox}"
    doc: "Store multiple 3-element structures from three registers"
    arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"]
    attr:
      - *target-is-arm
      - *neon-v7
      - *arm-fp16
      - *neon-unstable-f16
      - *target-not-arm64ec
    assert_instr: [vst3]
    safety:
      unsafe: [neon]
    types:
      - [f16, float16x4x3_t, float16x4_t, '2']
      - [f16, float16x8x3_t, float16x8_t, '2']
    compose:
      - LLVMLink:
          name: 'vst3.{neon_type[1]}'
          arguments:
            - 'ptr: *mut i8'
            - 'a: {type[2]}'
            - 'b: {type[2]}'
            - 'c: {type[2]}'
            - 'size: i32'
          links:
            - link: 'llvm.arm.neon.vst3.p0.v{neon_type[1].lane}{type[0]}'
              arch: arm
      - FnCall: ['_vst3{neon_type[1].nox}', ['a as _', 'b.0', 'b.1', 'b.2', "{type[3]}"]]


  - name: "vst3{neon_type[1].lane_nox}"
    doc: "Store multiple 3-element structures from three registers"
    arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"]
    attr:
      - *target-is-arm
      - *enable-v7
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [vst3, 'LANE = 0']]}]]
      - FnCall: [rustc_legacy_const_generics, ['2']]
      - *neon-arm-unstable
    static_defs: ['const LANE: i32']
    safety:
      unsafe: [neon]
    types:
      - [i8, int8x8x3_t, '3', int8x8_t, '1']
      - [i16, int16x4x3_t, '2', int16x4_t, '2']
      - [i32, int32x2x3_t, '1', int32x2_t, '4']
      - [i16, int16x8x3_t, '3', int16x8_t, '2']
      - [i32, int32x4x3_t, '2', int32x4_t, '4']
      - [f32, float32x2x3_t, '1', float32x2_t, '4']
      - [f32, float32x4x3_t, '2', float32x4_t, '4']
    compose:
      - FnCall: [static_assert_uimm_bits!, [LANE, "{type[2]}"]]
      - LLVMLink:
          name: 'vst3lane.{neon_type[1]}'
          arguments:
            - 'ptr: *mut i8'
            - 'a: {type[3]}'
            - 'b: {type[3]}'
            - 'c: {type[3]}'
            - 'n: i32'
            - 'size: i32'
          links:
            - link: 'llvm.arm.neon.vst3lane.p0.v{neon_type[1].lane}{type[0]}'
              arch: arm
      - FnCall: ['_vst3{neon_type[1].lane_nox}', ['a as _', 'b.0', 'b.1', 'b.2', 'LANE', "{type[4]}"]]


  - name: "vst3{neon_type[1].lane_nox}"
    doc: "Store multiple 3-element structures from three registers"
    arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"]
    attr:
      - *target-is-arm
      - *neon-v7
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [vst3, 'LANE = 0']]}]]
      - FnCall: [rustc_legacy_const_generics, ['2']]
      - *arm-fp16
      - *neon-unstable-f16
      - *target-not-arm64ec
    static_defs: ['const LANE: i32']
    safety:
      unsafe: [neon]
    types:
      - [f16, float16x4x3_t, '2', float16x4_t, '4']
      - [f16, float16x8x3_t, '3', float16x8_t, '4']
    compose:
      - FnCall: [static_assert_uimm_bits!, [LANE, "{type[2]}"]]
      - LLVMLink:
          name: 'vst3lane.{neon_type[1]}'
          arguments:
            - 'ptr: *mut i8'
            - 'a: {type[3]}'
            - 'b: {type[3]}'
            - 'c: {type[3]}'
            - 'n: i32'
            - 'size: i32'
          links:
            - link: 'llvm.arm.neon.vst3lane.p0.v{neon_type[1].lane}{type[0]}'
              arch: arm
      - FnCall: ['_vst3{neon_type[1].lane_nox}', ['a as _', 'b.0', 'b.1', 'b.2', 'LANE', "{type[4]}"]]


  - name: "vst3{neon_type[1].nox}"
    doc: "Store multiple 3-element structures from three registers"
    arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"]
    attr: [*target-not-arm, *neon-stable]
    assert_instr: [st3]
    safety:
      unsafe: [neon]
    types:
      - [i8, int8x8x3_t, int8x8_t]
      - [i16, int16x4x3_t, int16x4_t]
      - [i32, int32x2x3_t, int32x2_t]
      - [i8, int8x16x3_t, int8x16_t]
      - [i16, int16x8x3_t, int16x8_t]
      - [i32, int32x4x3_t, int32x4_t]
      - [f32, float32x2x3_t, float32x2_t]
      - [f32, float32x4x3_t, float32x4_t]
    compose:
      - LLVMLink:
          name: 'vst3.{neon_type[1]}'
          arguments:
            - 'a: {type[2]}'
            - 'b: {type[2]}'
            - 'c: {type[2]}'
            - 'ptr: *mut i8'
          links:
            - link: 'llvm.aarch64.neon.st3.v{neon_type[1].lane}{type[0]}.p0'
              arch: aarch64,arm64ec
      - FnCall: ['_vst3{neon_type[1].nox}', ['b.0', 'b.1', 'b.2', 'a as _']]


  - name: "vst3{neon_type[1].nox}"
    doc: "Store multiple 3-element structures from three registers"
    arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"]
    attr:
      - *target-not-arm
      - *arm-fp16
      - *neon-unstable-f16
      - *target-not-arm64ec
    assert_instr: [st3]
    safety:
      unsafe: [neon]
    types:
      - [f16, float16x4x3_t, float16x4_t]
      - [f16, float16x8x3_t, float16x8_t]
    compose:
      - LLVMLink:
          name: 'vst3.{neon_type[1]}'
          arguments:
            - 'a: {type[2]}'
            - 'b: {type[2]}'
            - 'c: {type[2]}'
            - 'ptr: *mut i8'
          links:
            - link: 'llvm.aarch64.neon.st3.v{neon_type[1].lane}{type[0]}.p0'
              arch: aarch64,arm64ec
      - FnCall: ['_vst3{neon_type[1].nox}', ['b.0', 'b.1', 'b.2', 'a as _']]


  - name: "vst3{neon_type[1].lane_nox}"
    doc: "Store multiple 3-element structures from three registers"
    arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"]
    attr:
      - *target-not-arm
      - FnCall: [rustc_legacy_const_generics, ['2']]
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [st3, 'LANE = 0']]}]]
      - *neon-stable
    static_defs: ['const LANE: i32']
    safety:
      unsafe: [neon]
    types:
      - [i8, int8x8x3_t, '3', int8x8_t]
      - [i16, int16x4x3_t, '2', int16x4_t]
      - [i32, int32x2x3_t, '1', int32x2_t]
      - [i16, int16x8x3_t, '3', int16x8_t]
      - [i32, int32x4x3_t, '2', int32x4_t]
      - [f32, float32x2x3_t, '1', float32x2_t]
      - [f32, float32x4x3_t, '2', float32x4_t]
    compose:
      - FnCall: [static_assert_uimm_bits!, [LANE, "{type[2]}"]]
      - LLVMLink:
          name: 'vst3.{neon_type[1].lane_nox}'
          arguments:
            - 'a: {type[3]}'
            - 'b: {type[3]}'
            - 'c: {type[3]}'
            - 'n: i64'
            - 'ptr: *mut i8'
          links:
            - link: 'llvm.aarch64.neon.st3lane.v{neon_type[1].lane}{type[0]}.p0'
              arch: aarch64,arm64ec
      - FnCall: ['_vst3{neon_type[1].lane_nox}', ['b.0', 'b.1', 'b.2', 'LANE as i64', 'a as _']]


  - name: "vst3{neon_type[1].lane_nox}"
    doc: "Store multiple 3-element structures from three registers"
    arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"]
    attr:
      - *target-not-arm
      - FnCall: [rustc_legacy_const_generics, ['2']]
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [st3, 'LANE = 0']]}]]
      - *arm-fp16
      - *neon-unstable-f16
      - *target-not-arm64ec
    static_defs: ['const LANE: i32']
    safety:
      unsafe: [neon]
    types:
      - [f16, float16x4x3_t, '2', float16x4_t]
      - [f16, float16x8x3_t, '3', float16x8_t]
    compose:
      - FnCall: [static_assert_uimm_bits!, [LANE, "{type[2]}"]]
      - LLVMLink:
          name: 'vst3.{neon_type[1].lane_nox}'
          arguments:
            - 'a: {type[3]}'
            - 'b: {type[3]}'
            - 'c: {type[3]}'
            - 'n: i64'
            - 'ptr: *mut i8'
          links:
            - link: 'llvm.aarch64.neon.st3lane.v{neon_type[1].lane}{type[0]}.p0'
              arch: aarch64,arm64ec
      - FnCall: ['_vst3{neon_type[1].lane_nox}', ['b.0', 'b.1', 'b.2', 'LANE as i64', 'a as _']]


  - name: "vst4{neon_type[1].nox}"
    doc: "Store multiple 4-element structures from four registers"
    arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"]
    attr:
      - *neon-v8
      - *neon-aes
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [nop]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [nop]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety:
      unsafe: [neon]
    types:
      - [p64, poly64x1x4_t, int64x1x4_t]
    compose:
      - FnCall:
          - "vst4{neon_type[2].nox}"
          - - FnCall: [transmute, [a]]
            - FnCall: [transmute, [b]]

  - name: "vst4{neon_type[1].nox}"
    doc: "Store multiple 4-element structures from four registers"
    arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"]
    attr:
      - *target-is-arm
      - *enable-v7
      - *neon-arm-unstable
    assert_instr: [nop]
    safety:
      unsafe: [neon]
    types:
      - [i64, int64x1x4_t, int64x1_t]
    compose:
      - LLVMLink:
          name: 'vst4.{neon_type[1]}'
          arguments:
            - 'ptr: *mut i8'
            - 'a: {type[2]}'
            - 'b: {type[2]}'
            - 'c: {type[2]}'
            - 'd: {type[2]}'
            - 'size: i32'
          links:
            - link: 'llvm.arm.neon.vst4.p0.v{neon_type[1].lane}{type[0]}'
              arch: arm
      - FnCall: ['_vst4{neon_type[1].nox}', ['a as _', 'b.0', 'b.1', 'b.2', 'b.3', '8']]

  - name: "vst4{neon_type[1].nox}"
    doc: "Store multiple 4-element structures from four registers"
    arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"]
    attr:
      - *target-not-arm
      - *neon-stable
    assert_instr: [nop]
    safety:
      unsafe: [neon]
    types:
      - [i64, int64x1x4_t, int64x1_t]
    compose:
      - LLVMLink:
          name: 'vst4.{neon_type[1]}'
          arguments:
            - 'a: {type[2]}'
            - 'b: {type[2]}'
            - 'c: {type[2]}'
            - 'd: {type[2]}'
            - 'ptr: *mut i8'
          links:
            - link: 'llvm.aarch64.neon.st4.{neon_type[2]}.p0'
              arch: aarch64,arm64ec
      - FnCall: ['_vst4{neon_type[1].nox}', ['b.0', 'b.1', 'b.2', 'b.3', 'a as _']]

  - name: "vst4{neon_type[1].nox}"
    doc: "Store multiple 4-element structures from four registers"
    arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"]
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [nop]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [nop]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety:
      unsafe: [neon]
    types:
      - [u64, uint64x1x4_t, int64x1x3_t]
    compose:
      - FnCall:
          - "vst4{neon_type[2].nox}"
          - - FnCall: [transmute, [a]]
            - FnCall: [transmute, [b]]

  - name: "vst4{neon_type[1].lane_nox}"
    doc: "Store multiple 4-element structures from four registers"
    arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"]
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vst4, 'LANE = 0']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [st4, 'LANE = 0']]}]]
      - FnCall: [rustc_legacy_const_generics, ['2']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ["const LANE: i32"]
    safety:
      unsafe: [neon]
    types:
      - [u8, uint8x8x4_t, int8x8x4_t, '3']
      - [u16, uint16x4x4_t, int16x4x4_t, '2']
      - [u32, uint32x2x4_t, int32x2x4_t, '1']
      - [u16, uint16x8x4_t, int16x8x4_t, '3']
      - [u32, uint32x4x4_t, int32x4x4_t, '2']
      - [p8, poly8x8x4_t, int8x8x4_t, '3']
      - [p16, poly16x4x4_t, int16x4x4_t, '2']
      - [p16, poly16x8x4_t, int16x8x4_t, '3']
    compose:
      - FnCall: [static_assert_uimm_bits!, [LANE, "{type[3]}"]]
      - FnCall:
          - "vst4{neon_type[2].lane_nox}::<LANE>"
          - - FnCall: [transmute, [a]]
            - FnCall: [transmute, [b]]

  - name: "vst4{neon_type[1].nox}"
    doc: "Store multiple 4-element structures from four registers"
    arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"]
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vst4]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [st4]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety:
      unsafe: [neon]
    types:
      - [u8, uint8x8x4_t, int8x8x4_t]
      - [u16, uint16x4x4_t, int16x4x4_t]
      - [u32, uint32x2x4_t, int32x2x4_t]
      - [u8, uint8x16x4_t, int8x16x4_t]
      - [u16, uint16x8x4_t, int16x8x4_t]
      - [u32, uint32x4x4_t, int32x4x4_t]
      - [p8, poly8x8x4_t, int8x8x4_t]
      - [p16, poly16x4x4_t, int16x4x4_t]
      - [p8, poly8x16x4_t, int8x16x4_t]
      - [p16, poly16x8x4_t, int16x8x4_t]
    compose:
      - FnCall:
          - "vst4{neon_type[2].nox}"
          - - FnCall: [transmute, [a]]
            - FnCall: [transmute, [b]]

  - name: "vst4{neon_type[1].nox}"
    doc: "Store multiple 4-element structures from four registers"
    arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"]
    attr:
      - *target-is-arm
      - *enable-v7
      - *neon-arm-unstable
    assert_instr: [vst4]
    safety:
      unsafe: [neon]
    types:
      - [i8, int8x8x4_t, int8x8_t, '1']
      - [i16, int16x4x4_t, int16x4_t, '2']
      - [i32, int32x2x4_t, int32x2_t, '4']
      - [i8, int8x16x4_t, int8x16_t, '1']
      - [i16, int16x8x4_t, int16x8_t, '2']
      - [i32, int32x4x4_t, int32x4_t, '4']
      - [f32, float32x2x4_t, float32x2_t, '4']
      - [f32, float32x4x4_t, float32x4_t, '4']
    compose:
      - LLVMLink:
          name: 'vst4.{neon_type[1]}'
          arguments:
            - 'ptr: *mut i8'
            - 'a: {type[2]}'
            - 'b: {type[2]}'
            - 'c: {type[2]}'
            - 'd: {type[2]}'
            - 'size: i32'
          links:
            - link: 'llvm.arm.neon.vst4.p0.v{neon_type[1].lane}{type[0]}'
              arch: arm
      - FnCall: ['_vst4{neon_type[1].nox}', ['a as _', 'b.0', 'b.1', 'b.2', 'b.3', "{type[3]}"]]


  - name: "vst4{neon_type[1].nox}"
    doc: "Store multiple 4-element structures from four registers"
    arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"]
    attr:
      - *target-is-arm
      - *neon-v7
      - *arm-fp16
      - *neon-unstable-f16
      - *target-not-arm64ec
    assert_instr: [vst4]
    safety:
      unsafe: [neon]
    types:
      - [f16, float16x4x4_t, float16x4_t, '2']
      - [f16, float16x8x4_t, float16x8_t, '2']
    compose:
      - LLVMLink:
          name: 'vst4.{neon_type[1]}'
          arguments:
            - 'ptr: *mut i8'
            - 'a: {type[2]}'
            - 'b: {type[2]}'
            - 'c: {type[2]}'
            - 'd: {type[2]}'
            - 'size: i32'
          links:
            - link: 'llvm.arm.neon.vst4.p0.v{neon_type[1].lane}{type[0]}'
              arch: arm
      - FnCall: ['_vst4{neon_type[1].nox}', ['a as _', 'b.0', 'b.1', 'b.2', 'b.3', "{type[3]}"]]


  - name: "vst4{neon_type[1].lane_nox}"
    doc: "Store multiple 4-element structures from four registers"
    arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"]
    attr:
      - *target-is-arm
      - *enable-v7
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [vst4, 'LANE = 0']]}]]
      - FnCall: [rustc_legacy_const_generics, ['2']]
      - *neon-arm-unstable
    static_defs: ['const LANE: i32']
    safety:
      unsafe: [neon]
    types:
      - [i8, int8x8x4_t, '3', int8x8_t, '1']
      - [i16, int16x4x4_t, '2', int16x4_t, '2']
      - [i32, int32x2x4_t, '1', int32x2_t, '4']
      - [i16, int16x8x4_t, '3', int16x8_t, '2']
      - [i32, int32x4x4_t, '2', int32x4_t, '4']
      - [f32, float32x2x4_t, '1', float32x2_t, '4']
      - [f32, float32x4x4_t, '2', float32x4_t, '4']
    compose:
      - FnCall: [static_assert_uimm_bits!, [LANE, "{type[2]}"]]
      - LLVMLink:
          name: 'vst4lane.{neon_type[1]}'
          arguments:
            - 'ptr: *mut i8'
            - 'a: {type[3]}'
            - 'b: {type[3]}'
            - 'c: {type[3]}'
            - 'd: {type[3]}'
            - 'n: i32'
            - 'size: i32'
          links:
            - link: 'llvm.arm.neon.vst4lane.p0.v{neon_type[1].lane}{type[0]}'
              arch: arm
      - FnCall: ['_vst4{neon_type[1].lane_nox}', ['a as _', 'b.0', 'b.1', 'b.2', 'b.3', 'LANE', "{type[4]}"]]

  - name: "vst4{neon_type[1].lane_nox}"
    doc: "Store multiple 4-element structures from four registers"
    arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"]
    attr:
      - *target-is-arm
      - *neon-v7
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [vst4, 'LANE = 0']]}]]
      - FnCall: [rustc_legacy_const_generics, ['2']]
      - *arm-fp16
      - *neon-unstable-f16
      - *target-not-arm64ec
    static_defs: ['const LANE: i32']
    safety:
      unsafe: [neon]
    types:
      - [f16, float16x4x4_t, '2', float16x4_t, '2']
      - [f16, float16x8x4_t, '3', float16x8_t, '2']
    compose:
      - FnCall: [static_assert_uimm_bits!, [LANE, "{type[2]}"]]
      - LLVMLink:
          name: 'vst4lane.{neon_type[1]}'
          arguments:
            - 'ptr: *mut i8'
            - 'a: {type[3]}'
            - 'b: {type[3]}'
            - 'c: {type[3]}'
            - 'd: {type[3]}'
            - 'n: i32'
            - 'size: i32'
          links:
            - link: 'llvm.arm.neon.vst4lane.p0.v{neon_type[1].lane}{type[0]}'
              arch: arm
      - FnCall: ['_vst4{neon_type[1].lane_nox}', ['a as _', 'b.0', 'b.1', 'b.2', 'b.3', 'LANE', "{type[4]}"]]


  - name: "vst4{neon_type[1].nox}"
    doc: "Store multiple 4-element structures from four registers"
    arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"]
    attr: [*target-not-arm, *neon-stable]
    assert_instr: [st4]
    safety:
      unsafe: [neon]
    types:
      - [i8, int8x8x4_t, int8x8_t]
      - [i16, int16x4x4_t, int16x4_t]
      - [i32, int32x2x4_t, int32x2_t]
      - [i8, int8x16x4_t, int8x16_t]
      - [i16, int16x8x4_t, int16x8_t]
      - [i32, int32x4x4_t, int32x4_t]
      - [f32, float32x2x4_t, float32x2_t]
      - [f32, float32x4x4_t, float32x4_t]
    compose:
      - LLVMLink:
          name: 'vst4.{neon_type[1]}'
          arguments:
            - 'a: {type[2]}'
            - 'b: {type[2]}'
            - 'c: {type[2]}'
            - 'd: {type[2]}'
            - 'ptr: *mut i8'
          links:
            - link: 'llvm.aarch64.neon.st4.v{neon_type[1].lane}{type[0]}.p0'
              arch: aarch64,arm64ec
      - FnCall: ['_vst4{neon_type[1].nox}', ['b.0', 'b.1', 'b.2', 'b.3', 'a as _']]


  - name: "vst4{neon_type[1].nox}"
    doc: "Store multiple 4-element structures from four registers"
    arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"]
    attr:
      - *target-not-arm
      - *arm-fp16
      - *neon-unstable-f16
      - *target-not-arm64ec
    assert_instr: [st4]
    safety:
      unsafe: [neon]
    types:
      - [f16, float16x4x4_t, float16x4_t]
      - [f16, float16x8x4_t, float16x8_t]
    compose:
      - LLVMLink:
          name: 'vst4.{neon_type[1]}'
          arguments:
            - 'a: {type[2]}'
            - 'b: {type[2]}'
            - 'c: {type[2]}'
            - 'd: {type[2]}'
            - 'ptr: *mut i8'
          links:
            - link: 'llvm.aarch64.neon.st4.v{neon_type[1].lane}{type[0]}.p0'
              arch: aarch64,arm64ec
      - FnCall: ['_vst4{neon_type[1].nox}', ['b.0', 'b.1', 'b.2', 'b.3', 'a as _']]


  - name: "vst4{neon_type[1].lane_nox}"
    doc: "Store multiple 4-element structures from four registers"
    arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"]
    attr:
      - *target-not-arm
      - FnCall: [rustc_legacy_const_generics, ['2']]
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [st4, 'LANE = 0']]}]]
      - *neon-stable
    static_defs: ['const LANE: i32']
    safety:
      unsafe: [neon]
    types:
      - [i8, int8x8x4_t, '3', int8x8_t]
      - [i16, int16x4x4_t, '2', int16x4_t]
      - [i32, int32x2x4_t, '1', int32x2_t]
      - [i16, int16x8x4_t, '3', int16x8_t]
      - [i32, int32x4x4_t, '2', int32x4_t]
      - [f32, float32x2x4_t, '1', float32x2_t]
      - [f32, float32x4x4_t, '2', float32x4_t]
    compose:
      - FnCall: [static_assert_uimm_bits!, [LANE, "{type[2]}"]]
      - LLVMLink:
          name: 'vst4.{neon_type[1].lane_nox}'
          arguments:
            - 'a: {type[3]}'
            - 'b: {type[3]}'
            - 'c: {type[3]}'
            - 'd: {type[3]}'
            - 'n: i64'
            - 'ptr: *mut i8'
          links:
            - link: 'llvm.aarch64.neon.st4lane.v{neon_type[1].lane}{type[0]}.p0'
              arch: aarch64,arm64ec
      - FnCall: ['_vst4{neon_type[1].lane_nox}', ['b.0', 'b.1', 'b.2', 'b.3', 'LANE as i64', 'a as _']]


  - name: "vst4{neon_type[1].lane_nox}"
    doc: "Store multiple 4-element structures from four registers"
    arguments: ["a: *mut {type[0]}", "b: {neon_type[1]}"]
    attr:
      - *target-not-arm
      - FnCall: [rustc_legacy_const_generics, ['2']]
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [st4, 'LANE = 0']]}]]
      - *arm-fp16
      - *neon-unstable-f16
      - *target-not-arm64ec
    static_defs: ['const LANE: i32']
    safety:
      unsafe: [neon]
    types:
      - [f16, float16x4x4_t, '2', float16x4_t]
      - [f16, float16x8x4_t, '3', float16x8_t]
    compose:
      - FnCall: [static_assert_uimm_bits!, [LANE, "{type[2]}"]]
      - LLVMLink:
          name: 'vst4.{neon_type[1].lane_nox}'
          arguments:
            - 'a: {type[3]}'
            - 'b: {type[3]}'
            - 'c: {type[3]}'
            - 'd: {type[3]}'
            - 'n: i64'
            - 'ptr: *mut i8'
          links:
            - link: 'llvm.aarch64.neon.st4lane.v{neon_type[1].lane}{type[0]}.p0'
              arch: aarch64,arm64ec
      - FnCall: ['_vst4{neon_type[1].lane_nox}', ['b.0', 'b.1', 'b.2', 'b.3', 'LANE as i64', 'a as _']]


  - name: "vusdot{neon_type[0].no}"
    doc: "Dot product vector form with unsigned and signed integers"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}", "c: {neon_type[2]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-i8mm
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vusdot]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [usdot]]}]]
      - *neon-unstable-i8mm
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [int32x2_t, uint8x8_t, int8x8_t]
      - [int32x4_t, uint8x16_t, int8x16_t]
    compose:
      - LLVMLink:
          name: "usdot.{neon_type[0]}"
          links:
            - link: "llvm.aarch64.neon.usdot.v{neon_type[0].lane}i32.v{neon_type[1].lane}i8"
              arch: aarch64,arm64ec
            - link: "llvm.arm.neon.usdot.v{neon_type[0].lane}i32.v{neon_type[1].lane}i8"
              arch: arm

  - name: "vusdot{type[0]}"
    doc: "Dot product index form with unsigned and signed integers"
    arguments: ["a: {neon_type[1]}", "b: {neon_type[2]}", "c: int8x8_t"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-i8mm
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vusdot, 'LANE = 0']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [usdot, 'LANE = 0']]}]]
      - FnCall: [rustc_legacy_const_generics, ['3']]
      - *neon-unstable-i8mm
      - *neon-cfg-arm-unstable
    static_defs: ["const LANE: i32"]
    big_endian_inverse: true # TODO: Remove this attribute, and replace transmute with vreinterpret when https://github.com/llvm/llvm-project/pull/169337 is merged, LLVM inlining issue causing assertion failure.
    safety: safe
    types:
      - ['_lane_s32', int32x2_t, uint8x8_t, '[LANE as u32, LANE as u32]','']
      - ['q_lane_s32', int32x4_t, uint8x16_t, '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]','q']
    compose:
      - FnCall: [static_assert_uimm_bits!, [LANE, '1']]
      - Let:
          - c
          - int32x2_t
          - FnCall: [transmute, [c]] #- FnCall: ['vreinterpret_s32_s8', [c]]
      - Let:
          - c
          - "{type[1]}"
          - FnCall: [simd_shuffle!, [c, c, "{type[3]}"]]
      - FnCall: ["vusdot{neon_type[1].no}", [a, b, {FnCall: [transmute, [c]]}]] #'vreinterpret{type[4]}_s8_s32'

  - name: "vsudot{neon_type[0].lane_nox}"
    doc: "Dot product index form with signed and unsigned integers"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}", "c: {neon_type[2]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-i8mm
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vsudot, 'LANE = 0']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [sudot, 'LANE = 0']]}]]
      - FnCall: [rustc_legacy_const_generics, ['3']]
      - *neon-unstable-i8mm
      - *neon-cfg-arm-unstable
    static_defs: ["const LANE: i32"]
    big_endian_inverse: true # TODO: Remove this attribute, and replace transmute with vreinterpret when https://github.com/llvm/llvm-project/pull/169337 is merged, LLVM inlining issue causing assertion failure.
    safety: safe
    types:
      - [int32x2_t, int8x8_t, uint8x8_t, '[LANE as u32, LANE as u32]', uint32x2_t,'']
      - [int32x4_t, int8x16_t, uint8x8_t, '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]', uint32x4_t,'q']
    compose:
      - FnCall: [static_assert_uimm_bits!, [LANE, '1']]
      - Let:
          - c
          - uint32x2_t
          - FnCall: [transmute, [c]] #- FnCall: ['vreinterpret_u32_u8', [c]]
      - Let:
          - c
          - "{type[4]}"
          - FnCall: [simd_shuffle!, [c, c, "{type[3]}"]]
      - FnCall: 
          - "vusdot{neon_type[0].no}"
          - - a
            - FnCall: [transmute, [c]] #- FnCall: ['vreinterpret{type[5]}_u8_u32', [c]]
            - b

  - name: "vmul{neon_type[1].no}"
    doc: Multiply
    arguments: ["a: {neon_type[1]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vmul{type[0]}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [mul]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - ['.i8', int8x8_t]
      - ['.i8', int8x16_t]
      - ['.i16', int16x4_t]
      - ['.i16', int16x8_t]
      - ['.i32', int32x2_t]
      - ['.i32', int32x4_t]
      - ['.i8', uint8x8_t]
      - ['.i8', uint8x16_t]
      - ['.i16', uint16x4_t]
      - ['.i16', uint16x8_t]
      - ['.i32', uint32x2_t]
      - ['.i32', uint32x4_t]
    compose:
      - FnCall: [simd_mul, [a, b]]

  - name: "vmul{neon_type[1].no}"
    doc: Multiply
    arguments: ["a: {neon_type[1]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vmul.{type[0]}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fmul]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [f32, float32x2_t]
      - [f32, float32x4_t]
    compose:
      - FnCall: [simd_mul, [a, b]]


  - name: "vmul{neon_type[1].no}"
    doc: Multiply
    arguments: ["a: {neon_type[1]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vmul.{type[0]}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fmul]]}]]
      - *neon-fp16
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    safety: safe
    types:
      - [f16, float16x4_t]
      - [f16, float16x8_t]
    compose:
      - FnCall: [simd_mul, [a, b]]


  - name: "vmul{neon_type[0].lane_nox}"
    doc: Multiply
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vmul, 'LANE = 1']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [mul, 'LANE = 1']]}]]
      - FnCall: [rustc_legacy_const_generics, ['2']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ["const LANE: i32"]
    safety: safe
    types:
      - [int16x4_t, int16x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
      - [int16x8_t, int16x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
      - [int32x2_t, int32x2_t, '1', '[LANE as u32, LANE as u32]']
      - [int32x4_t, int32x2_t, '1', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
      - [uint16x4_t, uint16x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
      - [uint16x8_t, uint16x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
      - [uint32x2_t, uint32x2_t, '1', '[LANE as u32, LANE as u32]']
      - [uint32x4_t, uint32x2_t, '1', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
    compose:
      - FnCall: ["static_assert_uimm_bits!", [LANE, "{type[2]}"]]
      - FnCall:
          - simd_mul
          - - a
            - FnCall: ["simd_shuffle!", [b, b, "{type[3]}"]]


  - name: "vmul{neon_type[0].lane_nox}"
    doc: Multiply
    arguments: ["a: {neon_type[0]}", "v: {neon_type[1]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vmul, 'LANE = 1']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fmul, 'LANE = 1']]}]]
      - FnCall: [rustc_legacy_const_generics, ['2']]
      - *neon-fp16
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    static_defs: ["const LANE: i32"]
    safety: safe
    types:
      - [float16x4_t, float16x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
      - [float16x8_t, float16x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
    compose:
      - FnCall: ["static_assert_uimm_bits!", [LANE, "{type[2]}"]]
      - FnCall:
          - simd_mul
          - - a
            - FnCall: ["simd_shuffle!", [v, v, "{type[3]}"]]


  - name: "vmul{neon_type[0].laneq_nox}"
    doc: Multiply
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vmul, 'LANE = 1']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [mul, 'LANE = 1']]}]]
      - FnCall: [rustc_legacy_const_generics, ['2']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ["const LANE: i32"]
    safety: safe
    types:
      - [int16x4_t, int16x8_t, '3', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
      - [int16x8_t, int16x8_t, '3', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
      - [int32x2_t, int32x4_t, '2', '[LANE as u32, LANE as u32]']
      - [int32x4_t, int32x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
      - [uint16x4_t, uint16x8_t, '3', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
      - [uint16x8_t, uint16x8_t, '3', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
      - [uint32x2_t, uint32x4_t, '2', '[LANE as u32, LANE as u32]']
      - [uint32x4_t, uint32x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
    compose:
      - FnCall: ["static_assert_uimm_bits!", [LANE, "{type[2]}"]]
      - FnCall:
          - simd_mul
          - - a
            - FnCall: ["simd_shuffle!", [b, b, "{type[3]}"]]

  - name: "vmull{neon_type[1].no}"
    doc: Signed multiply long
    arguments: ["a: {neon_type[1]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[2]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vmull.{type[0]}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [smull]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - ["s8", int8x8_t, int16x8_t]
      - ["s16", int16x4_t, int32x4_t]
      - ["s32", int32x2_t, int64x2_t]
    compose:
      - FnCall:
          - simd_mul
          - - FnCall: ['simd_cast', [a]]
            - FnCall: ['simd_cast', [b]]

  - name: "vmull{neon_type[1].no}"
    doc: "Unsigned multiply long"
    arguments: ["a: {neon_type[1]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[2]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vmull.{type[0]}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [umull]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - ["u8", uint8x8_t, uint16x8_t]
      - ["u16", uint16x4_t, uint32x4_t]
      - ["u32", uint32x2_t, uint64x2_t]
    compose:
      - FnCall:
          - simd_mul
          - - FnCall: ['simd_cast', [a]]
            - FnCall: ['simd_cast', [b]]

  - name: "vmull{neon_type[1].no}"
    doc: "Polynomial multiply long"
    arguments: ["a: {neon_type[1]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[2]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vmull.{type[0]}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [pmull]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - ["p8", poly8x8_t, poly16x8_t]
    compose:
      - LLVMLink:
          name: "pmull.{neon_type[1].no}"
          links:
            - link: "llvm.aarch64.neon.pmull.v8i16"
              arch: aarch64,arm64ec
            - link: "llvm.arm.neon.vmullp.v8i16"
              arch: arm

  - name: "vmull_n{neon_type[0].no}"
    doc: Vector long multiply with scalar
    arguments: ["a: {neon_type[0]}", "b: {type[1]}"]
    return_type: "{neon_type[2]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ["vmull"]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [smull]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [int16x4_t, "i16", int32x4_t]
      - [int32x2_t, "i32", int64x2_t]
    compose:
      - FnCall:
          - "vmull{neon_type[0].no}"
          - - a
            - FnCall:
                - "vdup_n{neon_type[0].no}"
                - - b

  - name: "vmull_n{neon_type[0].no}"
    doc: Vector long multiply with scalar
    arguments: ["a: {neon_type[0]}", "b: {type[1]}"]
    return_type: "{neon_type[2]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ["vmull"]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [umull]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [uint16x4_t, "u16", uint32x4_t]
      - [uint32x2_t, "u32", uint64x2_t]
    compose:
      - FnCall:
          - "vmull{neon_type[0].no}"
          - - a
            - FnCall:
                - "vdup_n{neon_type[0].no}"
                - - b

  - name: "vfma{neon_type.no}"
    doc: Floating-point fused Multiply-Add to accumulator(vector)
    arguments: ["a: {neon_type}", "b: {neon_type}", "c: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - FnCall: [cfg_attr, [target_arch = "arm", {FnCall: [target_feature, ['enable = "vfp4"']]}]]
      - FnCall:
          - cfg_attr
          - - FnCall:
                - all
                - - test
                  - 'target_arch = "arm"'
            - FnCall:
                - assert_instr
                - - vfma
      - FnCall:
          - cfg_attr
          - - FnCall:
                - all
                - - test
                  - FnCall:
                      - any
                      - - 'target_arch = "aarch64"'
                        - 'target_arch = "arm64ec"'
            - FnCall:
                - assert_instr
                - - fmla
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - float32x2_t
      - float32x4_t
    compose:
      - FnCall: [simd_fma, [b, c, a]]


  - name: "vfma{neon_type.no}"
    doc: Floating-point fused Multiply-Add to accumulator (vector)
    arguments: ["a: {neon_type}", "b: {neon_type}", "c: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - FnCall: [cfg_attr, [target_arch = "arm", {FnCall: [target_feature, ['enable = "vfp4"']]}]]
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vfma]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fmla]]}]]
      - *neon-fp16
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    safety: safe
    types:
      - float16x4_t
      - float16x8_t
    compose:
      - FnCall: [simd_fma, [b, c, a]]


  - name: "vfma{neon_type[0].N}"
    doc: Floating-point fused Multiply-Add to accumulator(vector)
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}", "c: {type[1]}"]
    return_type: "{neon_type[0]}"
    attr:
      - FnCall: [cfg_attr, [target_arch = "arm", {FnCall: [target_feature, ['enable = "vfp4"']]}]]
      - FnCall:
          - cfg_attr
          - - FnCall:
                - all
                - - test
                  - 'target_arch = "arm"'
            - FnCall:
                - assert_instr
                - - vfma
      - FnCall:
          - cfg_attr
          - - FnCall:
                - all
                - - test
                  - FnCall:
                      - any
                      - - 'target_arch = "aarch64"'
                        - 'target_arch = "arm64ec"'
            - FnCall:
                - assert_instr
                - - fmla
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [float32x2_t, f32]
      - [float32x4_t, f32]
    compose:
      - FnCall:
          - "vfma{neon_type[0].no}"
          - - a
            - b
            - FnCall:
                - "vdup{neon_type[0].N}_vfp4"
                - - c

  - name: "vsub{neon_type[1].no}"
    doc: "Subtract"
    arguments: ["a: {neon_type[1]}", "b: {neon_type[1]}"]
    return_type: "{type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vsub{type[0]}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [sub]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - ['.i8', int8x8_t]
      - ['.i8', int8x16_t]
      - ['.i16', int16x4_t]
      - ['.i16', int16x8_t]
      - ['.i32', int32x2_t]
      - ['.i32', int32x4_t]
      - ['.i8', uint8x8_t]
      - ['.i8', uint8x16_t]
      - ['.i16', uint16x4_t]
      - ['.i16', uint16x8_t]
      - ['.i32', uint32x2_t]
      - ['.i32', uint32x4_t]
      - ['.i64', int64x1_t]
      - ['.i64', int64x2_t]
      - ['.i64', uint64x1_t]
      - ['.i64', uint64x2_t]
    compose:
      - FnCall: [simd_sub, [a, b]]

  - name: "vsub{neon_type[1].no}"
    doc: "Subtract"
    arguments: ["a: {neon_type[1]}", "b: {neon_type[1]}"]
    return_type: "{type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vsub.{type[0]}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fsub]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - ['f32', float32x2_t]
      - ['f32', float32x4_t]
    compose:
      - FnCall: [simd_sub, [a, b]]


  - name: "vsub{neon_type[1].no}"
    doc: "Subtract"
    arguments: ["a: {neon_type[1]}", "b: {neon_type[1]}"]
    return_type: "{type[1]}"
    attr:
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vsub.{type[0]}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fsub]]}]]
      - *neon-fp16
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    safety: safe
    types:
      - ['f16', float16x4_t]
      - ['f16', float16x8_t]
    compose:
      - FnCall: [simd_sub, [a, b]]


  - name: "vadd{neon_type.no}"
    doc: Floating-point Add (vector).
    arguments: ["a: {neon_type}", "b: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vadd.f16"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fadd]]}]]
      - *neon-fp16
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    safety: safe
    types:
      - float16x4_t
      - float16x8_t
    compose:
      - FnCall:
          - simd_add
          - - a
            - b

  - name: "vadd{type[0]}"
    doc: Add
    arguments: ["a: {type[1]}", "b: {type[1]}"]
    return_type: "{type[1]}"
    attr:
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vadd.f16"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fadd]]}]]
      - *neon-fp16
      - *neon-unstable-f16
      - *target-not-arm64ec
    safety: safe
    types:
      - ['h_f16', 'f16']
    compose:
      - 'a + b'

  - name: "vadd{neon_type.no}"
    doc: Bitwise exclusive OR
    arguments: ["a: {neon_type}", "b: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v7
      - FnCall:
          - cfg_attr
          - - FnCall:
                - all
                - - test
                  - 'target_arch = "arm"'
            - FnCall:
                - assert_instr
                - - nop
      - FnCall:
          - cfg_attr
          - - FnCall:
                - all
                - - test
                  - FnCall:
                      - any
                      - - 'target_arch = "aarch64"'
                        - 'target_arch = "arm64ec"'
            - FnCall:
                - assert_instr
                - - nop
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - poly8x8_t
      - poly16x4_t
      - poly8x16_t
      - poly16x8_t
      - poly64x1_t
      - poly64x2_t
    compose:
      - FnCall:
          - simd_xor
          - - a
            - b

  - name: "vaddq_{type}"
    doc: Bitwise exclusive OR
    arguments: ["a: {type}", "b: {type}"]
    return_type: "{type}"
    attr:
      - *neon-v7
      - FnCall:
          - cfg_attr
          - - FnCall:
                - all
                - - test
                  - 'target_arch = "arm"'
            - FnCall:
                - assert_instr
                - - nop
      - FnCall:
          - cfg_attr
          - - FnCall:
                - all
                - - test
                  - FnCall:
                      - any
                      - - 'target_arch = "aarch64"'
                        - 'target_arch = "arm64ec"'
            - FnCall:
                - assert_instr
                - - nop
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - p128
    compose:
      - Xor:
          - a
          - b

  - name: "vsubhn{neon_type[0].noq}"
    doc: Subtract returning high narrow
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ["vsubhn"]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [subhn]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [int16x8_t, int8x8_t, 'i16x8', 'i16x8::new(8, 8, 8, 8, 8, 8, 8, 8)']
      - [int32x4_t, int16x4_t, 'i32x4', 'i32x4::new(16, 16, 16, 16)']
      - [int64x2_t, int32x2_t, 'i64x2', 'i64x2::new(32, 32)']
      - [uint16x8_t, uint8x8_t, 'u16x8', 'u16x8::new(8, 8, 8, 8, 8, 8, 8, 8)']
      - [uint32x4_t, uint16x4_t, 'u32x4', 'u32x4::new(16, 16, 16, 16)']
      - [uint64x2_t, uint32x2_t, 'u64x2', 'u64x2::new(32, 32)']
    compose:
      - Let: [c, "{type[2]}", "{type[3]}"]
      - FnCall:
          - simd_cast
          - - FnCall:
                - simd_shr
                - - FnCall: [simd_sub, [a, b]]
                  - FnCall: [transmute, [c]]

  - name: "vsubhn_high{neon_type[1].noq}"
    doc: Subtract returning high narrow
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}", "c: {neon_type[1]}"]
    return_type: "{neon_type[2]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ["vsubhn"]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [subhn2]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [int8x8_t, int16x8_t, int8x16_t, '[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]']
      - [int16x4_t, int32x4_t, int16x8_t, '[0, 1, 2, 3, 4, 5, 6, 7]']
      - [int32x2_t, int64x2_t, int32x4_t, '[0, 1, 2, 3]']
      - [uint8x8_t, uint16x8_t, uint8x16_t, '[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]']
      - [uint16x4_t, uint32x4_t, uint16x8_t, '[0, 1, 2, 3, 4, 5, 6, 7]']
      - [uint32x2_t, uint64x2_t, uint32x4_t, '[0, 1, 2, 3]']
    compose:
      - Let:
          - d
          - "{neon_type[0]}"
          - FnCall: ["vsubhn{neon_type[1].noq}", [b, c]]
      - FnCall: [simd_shuffle!, [a, d, "{type[3]}"]]

  - name: "vhsub{neon_type[1].no}"
    doc: "Signed halving subtract"
    arguments: ["a: {neon_type[1]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vhsub.{type[0]}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [uhsub]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - ['u8', uint8x8_t]
      - ['u8', uint8x16_t]
      - ['u16', uint16x4_t]
      - ['u16', uint16x8_t]
      - ['u32', uint32x2_t]
      - ['u32', uint32x4_t]
    compose:
      - LLVMLink:
          name: "uhsub.{neon_type[1].no}"
          links:
            - link: "llvm.aarch64.neon.uhsub.{neon_type[1]}"
              arch: aarch64,arm64ec
            - link: "llvm.arm.neon.vhsubu.{neon_type[1]}"
              arch: arm

  - name: "vhsub{neon_type[1].no}"
    doc: "Signed halving subtract"
    arguments: ["a: {neon_type[1]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vhsub.{type[0]}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [shsub]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - ['s8', int8x8_t]
      - ['s8', int8x16_t]
      - ['s16', int16x4_t]
      - ['s16', int16x8_t]
      - ['s32', int32x2_t]
      - ['s32', int32x4_t]
    compose:
      - LLVMLink:
          name: "shsub.{neon_type[1].no}"
          links:
            - link: "llvm.aarch64.neon.shsub.{neon_type[1]}"
              arch: aarch64,arm64ec
            - link: "llvm.arm.neon.vhsubs.{neon_type[1]}"
              arch: arm

  - name: "vsubw{neon_type[1].noq}"
    doc: Signed Subtract Wide
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vsubw]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ssubw]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [int16x8_t, int8x8_t]
      - [int32x4_t, int16x4_t]
      - [int64x2_t, int32x2_t]
    compose:
      - FnCall:
          - simd_sub
          - - a
            - FnCall: [simd_cast, [b]]

  - name: "vsubw{neon_type[1].noq}"
    doc: Unsigned Subtract Wide
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vsubw]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [usubw]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [uint16x8_t, uint8x8_t]
      - [uint32x4_t, uint16x4_t]
      - [uint64x2_t, uint32x2_t]
    compose:
      - FnCall:
          - simd_sub
          - - a
            - FnCall: [simd_cast, [b]]

  - name: "vsubl{neon_type[0].noq}"
    doc: "Signed Subtract Long"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vsubl]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ssubl]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [int8x8_t, int16x8_t]
      - [int16x4_t, int32x4_t]
      - [int32x2_t, int64x2_t]
    compose:
      - Let:
          - c
          - "{neon_type[1]}"
          - FnCall: [simd_cast, [a]]
      - Let:
          - d
          - "{neon_type[1]}"
          - FnCall: [simd_cast, [b]]
      - FnCall: [simd_sub, [c, d]]

  - name: "vsubl{neon_type[0].noq}"
    doc: "Unsigned Subtract Long"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vsubl]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [usubl]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [uint8x8_t, uint16x8_t]
      - [uint16x4_t, uint32x4_t]
      - [uint32x2_t, uint64x2_t]
    compose:
      - Let:
          - c
          - "{neon_type[1]}"
          - FnCall: [simd_cast, [a]]
      - Let:
          - d
          - "{neon_type[1]}"
          - FnCall: [simd_cast, [b]]
      - FnCall: [simd_sub, [c, d]]

  - name: "vusdot{neon_type[0].laneq_nox}"
    doc: "Dot product index form with unsigned and signed integers"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}", "c: {neon_type[2]}"]
    return_type: "{neon_type[0]}"
    big_endian_inverse: true # TODO: Remove this attribute, and replace transmute with vreinterpret when https://github.com/llvm/llvm-project/pull/169337 is merged, LLVM inlining issue causing assertion failure.
    attr:
      - *neon-v8
      - *neon-i8mm
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vusdot, 'LANE = 3']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [usdot, 'LANE = 3']]}]]
      - FnCall: [rustc_legacy_const_generics, ['3']]
      - FnCall: [unstable, ['feature = "stdarch_neon_i8mm"', 'issue = "117223"']]
    static_defs: ["const LANE: i32"]
    safety: safe
    types:
      - [int32x2_t, uint8x8_t, int8x16_t, '[LANE as u32, LANE as u32]','']
      - [int32x4_t, uint8x16_t, int8x16_t, '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]','q']
    compose:
      - FnCall: [static_assert_uimm_bits!, [LANE, '2']]
      - Let: [c, int32x4_t, {FnCall: [transmute, [c]]}]
      - Let: [c, "{neon_type[0]}", {FnCall: [simd_shuffle!, [c, c, "{type[3]}"]]}]
      - FnCall: ["vusdot{neon_type[0].no}", [a, b, {FnCall: [transmute, [c]]}]]
      #- FnCall: ["vusdot{neon_type[0].no}", [a, b, {FnCall: ['vreinterpret{type[4]}_s8_s32', [c]]}]] 

  - name: "vsudot{neon_type[0].laneq_nox}"
    doc: "Dot product index form with signed and unsigned integers"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}", "c: {neon_type[2]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v8
      - *neon-i8mm
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vsudot, 'LANE = 1']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [sudot, 'LANE = 3']]}]]
      - FnCall: [rustc_legacy_const_generics, ['3']]
      - FnCall: [unstable, ['feature = "stdarch_neon_i8mm"', 'issue = "117223"']]
    static_defs: ["const LANE: i32"]
    safety: safe
    types:
      - [int32x2_t, int8x8_t, uint8x16_t, '[LANE as u32, LANE as u32]', uint32x2_t]
      - [int32x4_t, int8x16_t, uint8x16_t, '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]', uint32x4_t]
    compose:
      - FnCall: [static_assert_uimm_bits!, [LANE, 2]]
      - Let:
          - c
          - uint32x4_t
          - FnCall: [transmute, [c]]
      - Let:
          - c
          - "{type[4]}"
          - FnCall: [simd_shuffle!, [c, c, "{type[3]}"]]
      - FnCall: 
          - "vusdot{neon_type[0].no}"
          - - a
            - FnCall: [transmute, [c]]
            - b

  - name: "vdot{neon_type[0].laneq_nox}"
    doc: Dot product arithmetic (indexed)
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}", "c: {neon_type[2]}"]
    return_type: "{neon_type[0]}"
    static_defs: ["const LANE: i32"]
    big_endian_inverse: true # TODO: Remove this attribute, and replace transmute with vreinterpret when https://github.com/llvm/llvm-project/pull/169337 is merged, LLVM inlining issue causing assertion failure.
    attr:
      - *neon-v8
      - FnCall: [target_feature, ['enable = "neon,dotprod"']]
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vsdot, 'LANE = 0']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [sdot, 'LANE = 0']]}]]
      - FnCall: [rustc_legacy_const_generics, ['3']]
      - FnCall: [unstable, ['feature = "stdarch_neon_dotprod"', 'issue = "117224"']]
    safety: safe
    types:
      - [int32x2_t, int8x8_t, int8x16_t, int32x4_t, '[LANE as u32, LANE as u32]', '']
      - [int32x4_t, int8x16_t, int8x16_t, int32x4_t, '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]','q']
    compose:
      - FnCall: [static_assert_uimm_bits!, [LANE, '2']]
      - Let:
          - c
          - "{neon_type[3]}"
          - FnCall: [transmute, [c]]
          #- FnCall: ['vreinterpretq_{neon_type[0]}_{neon_type[1]}', [c]]
      - Let:
          - c
          - "{neon_type[0]}"
          - FnCall: [simd_shuffle!, [c, c, '{type[4]}']]
      - FnCall:
          - "vdot{neon_type[0].no}"
          - - a
            - b
            - FnCall: [transmute, [c]]
            #- FnCall: ['vreinterpret{type[5]}_{neon_type[1]}_{neon_type[0]}', [c]]

  - name: "vdot{neon_type[0].laneq_nox}"
    doc: Dot product arithmetic (indexed)
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}", "c: {neon_type[2]}"]
    return_type: "{neon_type[0]}"
    static_defs: ["const LANE: i32"]
    big_endian_inverse: true # TODO: Remove this attribute, and replace transmute with vreinterpret when https://github.com/llvm/llvm-project/pull/169337 is merged, LLVM inlining issue causing assertion failure.
    attr:
      - *neon-v8
      - FnCall: [target_feature, ['enable = "neon,dotprod"']]
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vudot, 'LANE = 0']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [udot, 'LANE = 0']]}]]
      - FnCall: [rustc_legacy_const_generics, ['3']]
      - FnCall: [unstable, ['feature = "stdarch_neon_dotprod"', 'issue = "117224"']]
    safety: safe
    types:
      - [uint32x2_t, uint8x8_t, uint8x16_t, uint32x4_t, '[LANE as u32, LANE as u32]','']
      - [uint32x4_t, uint8x16_t, uint8x16_t, uint32x4_t, '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]','q']
    compose:
      - FnCall: [static_assert_uimm_bits!, [LANE, '2']]
      - Let:
          - c
          - "{neon_type[3]}"
          - FnCall: [transmute, [c]]
          #- FnCall: ['vreinterpretq_{neon_type[0]}_{neon_type[1]}', [c]]
      - Let:
          - c
          - "{neon_type[0]}"
          - FnCall: [simd_shuffle!, [c, c, '{type[4]}']]
      - FnCall:
          - "vdot{neon_type[0].no}"
          - - a
            - b
            - FnCall: [transmute, [c]]
            #- FnCall: ['vreinterpret{type[5]}_{neon_type[1]}_{neon_type[0]}', [c]]

  - name: "vdot{neon_type[0].no}"
    doc: Dot product arithmetic (vector)
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}", "c: {neon_type[1]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v8
      - FnCall: [target_feature, ['enable = "neon,dotprod"']]
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vsdot]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [sdot]]}]]
      - FnCall: [cfg_attr, [{FnCall: [not, ['target_arch = "arm"']]}, {FnCall: [unstable, ['feature = "stdarch_neon_dotprod"', 'issue = "117224"']]}]]
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [int32x2_t, int8x8_t]
      - [int32x4_t, int8x16_t]
    compose:
      - LLVMLink:
          name: "sdot.{neon_type[0]}.{neon_type[1]}"
          links:
            - link: "llvm.arm.neon.sdot.{neon_type[0]}.{neon_type[1]}"
              arch: arm
            - link: "llvm.aarch64.neon.sdot.{neon_type[0]}.{neon_type[1]}"
              arch: aarch64,arm64ec

  - name: "vdot{neon_type[0].no}"
    doc: Dot product arithmetic (vector)
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}", "c: {neon_type[1]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v8
      - FnCall: [target_feature, ['enable = "neon,dotprod"']]
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vudot]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [udot]]}]]
      - FnCall: [cfg_attr, [{FnCall: [not, ['target_arch = "arm"']]}, {FnCall: [unstable, ['feature = "stdarch_neon_dotprod"', 'issue = "117224"']]}]]
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [uint32x2_t, uint8x8_t]
      - [uint32x4_t, uint8x16_t]
    compose:
      - LLVMLink:
          name: "udot.{neon_type[0]}.{neon_type[1]}"
          links:
            - link: "llvm.arm.neon.udot.{neon_type[0]}.{neon_type[1]}"
              arch: arm
            - link: "llvm.aarch64.neon.udot.{neon_type[0]}.{neon_type[1]}"
              arch: aarch64,arm64ec

  - name: "vdot{neon_type[0].lane_nox}"
    doc: Dot product arithmetic (indexed)
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}", "c: {neon_type[2]}"]
    return_type: "{neon_type[0]}"
    static_defs: ["const LANE: i32"]
    attr:
      - *neon-v8
      - FnCall: [target_feature, ['enable = "neon,dotprod"']]
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vsdot, 'LANE = 0']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [sdot, 'LANE = 0']]}]]
      - FnCall: [rustc_legacy_const_generics, ['3']]
      - FnCall: [cfg_attr, [{FnCall: [not, ['target_arch = "arm"']]}, {FnCall: [unstable, ['feature = "stdarch_neon_dotprod"', 'issue = "117224"']]}]]
      - *neon-cfg-arm-unstable
    big_endian_inverse: true # TODO: Remove this attribute, and replace transmute with vreinterpret when https://github.com/llvm/llvm-project/pull/169337 is merged, LLVM inlining issue causing assertion failure.
    safety: safe
    types:
      - [int32x2_t, int8x8_t, int8x8_t, int32x2_t, '[LANE as u32, LANE as u32]','']
      - [int32x4_t, int8x16_t, int8x8_t, int32x2_t, '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]','q']
    compose:
      - FnCall: [static_assert_uimm_bits!, [LANE, '1']]
      - Let:
          - c
          - "{neon_type[3]}"
          - FnCall: [transmute, [c]]
      - Let:
          - c
          - "{neon_type[0]}"
          - FnCall: [simd_shuffle!, [c, c, '{type[4]}']]
      - FnCall:
          - "vdot{neon_type[0].no}"
          - - a
            - b
            - FnCall: [transmute, [c]]

  - name: "vdot{neon_type[0].lane_nox}"
    doc: Dot product arithmetic (indexed)
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}", "c: {neon_type[2]}"]
    return_type: "{neon_type[0]}"
    static_defs: ["const LANE: i32"]
    attr:
      - *neon-v8
      - FnCall: [target_feature, ['enable = "neon,dotprod"']]
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vudot, 'LANE = 0']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [udot, 'LANE = 0']]}]]
      - FnCall: [rustc_legacy_const_generics, ['3']]
      - FnCall: [cfg_attr, [{FnCall: [not, ['target_arch = "arm"']]}, {FnCall: [unstable, ['feature = "stdarch_neon_dotprod"', 'issue = "117224"']]}]]
      - *neon-cfg-arm-unstable
    safety: safe
    big_endian_inverse: true # TODO: Remove this attribute, and replace transmute with vreinterpret when https://github.com/llvm/llvm-project/pull/169337 is merged, LLVM inlining issue causing assertion failure.
    types:
      - [uint32x2_t, uint8x8_t, uint8x8_t, uint32x2_t, '[LANE as u32, LANE as u32]','']
      - [uint32x4_t, uint8x16_t, uint8x8_t, uint32x2_t, '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]','q']
    compose:
      - FnCall: [static_assert_uimm_bits!, [LANE, '1']]
      - Let:
          - c
          - "{neon_type[3]}"
          - FnCall: [transmute, [c]] #- FnCall: ['vreinterpret_{neon_type[0]}_{neon_type[1]}', [c]]
      - Let:
          - c
          - "{neon_type[0]}"
          - FnCall: [simd_shuffle!, [c, c, '{type[4]}']]
      - FnCall:
          - "vdot{neon_type[0].no}"
          - - a
            - b
            - FnCall: [transmute, [c]] #- FnCall: ['vreinterpret{type[5]}_{neon_type[1]}_{neon_type[0]}', [c]]

  - name: "vmax{neon_type.no}"
    doc: Maximum (vector)
    arguments: ["a: {neon_type}", "b: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vmax]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [smax]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - int8x8_t
      - int8x16_t
      - int16x4_t
      - int16x8_t
      - int32x2_t
      - int32x4_t
    compose:
      - Let: [mask, "{neon_type}", {FnCall: [simd_ge, [a, b]]}]
      - FnCall: [simd_select, [mask, a, b]]

  - name: "vmax{neon_type.no}"
    doc: Maximum (vector)
    arguments: ["a: {neon_type}", "b: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vmax]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [umax]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - uint8x8_t
      - uint8x16_t
      - uint16x4_t
      - uint16x8_t
      - uint32x2_t
      - uint32x4_t
    compose:
      - Let: [mask, "{neon_type}", {FnCall: [simd_ge, [a, b]]}]
      - FnCall: [simd_select, [mask, a, b]]

  - name: "vmax{neon_type.no}"
    doc: Maximum (vector)
    arguments: ["a: {neon_type}", "b: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vmax]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fmax]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - float32x2_t
      - float32x4_t
    compose:
      - LLVMLink:
          name: "smax.{neon_type}"
          links:
            - link: "llvm.arm.neon.vmaxs.{neon_type}"
              arch: arm
            - link: "llvm.aarch64.neon.fmax.{neon_type}"
              arch: aarch64,arm64ec


  - name: "vmax{neon_type.no}"
    doc: Maximum (vector)
    arguments: ["a: {neon_type}", "b: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vmax]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fmax]]}]]
      - *neon-fp16
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    safety: safe
    types:
      - float16x4_t
      - float16x8_t
    compose:
      - LLVMLink:
          name: "vmax.{neon_type}"
          links:
            - link: "llvm.arm.neon.vmaxs.{neon_type}"
              arch: arm
            - link: "llvm.aarch64.neon.fmax.{neon_type}"
              arch: aarch64,arm64ec


  - name: "vmaxnm{neon_type.no}"
    doc: Floating-point Maximum Number (vector)
    arguments: ["a: {neon_type}", "b: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - FnCall: [cfg_attr, ['target_arch = "arm"', {FnCall: [target_feature, ['enable = "fp-armv8,v8"']]}]]
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vmaxnm]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fmaxnm]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - float32x2_t
      - float32x4_t
    compose:
      - FnCall: [simd_fmax, [a, b]]


  - name: "vmaxnm{neon_type.no}"
    doc: Floating-point Maximum Number (vector)
    arguments: ["a: {neon_type}", "b: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - FnCall: [cfg_attr, ['target_arch = "arm"', {FnCall: [target_feature, ['enable = "fp-armv8,v8"']]}]]
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vmaxnm]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fmaxnm]]}]]
      - *neon-fp16
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    safety: safe
    types:
      - float16x4_t
      - float16x8_t
    compose:
      - FnCall: [simd_fmax, [a, b]]


  - name: "vminnm{neon_type.no}"
    doc: Floating-point Minimum Number (vector)
    arguments: ["a: {neon_type}", "b: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - FnCall: [cfg_attr, ['target_arch = "arm"', {FnCall: [target_feature, ['enable = "fp-armv8,v8"']]}]]
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vminnm]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fminnm]]}]]
      - *neon-fp16
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    safety: safe
    types:
      - float16x4_t
      - float16x8_t
    compose:
      - FnCall: [simd_fmin, [a, b]]


  - name: "vmin{neon_type.no}"
    doc: "Minimum (vector)"
    arguments: ["a: {neon_type}", "b: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vmin]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [smin]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - int8x8_t
      - int8x16_t
      - int16x4_t
      - int16x8_t
      - int32x2_t
      - int32x4_t
    compose:
      - Let: [mask, "{neon_type}", {FnCall: [simd_le, [a, b]]}]
      - FnCall: [simd_select, [mask, a, b]]

  - name: "vmin{neon_type.no}"
    doc: "Minimum (vector)"
    arguments: ["a: {neon_type}", "b: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vmin]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [umin]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - uint8x8_t
      - uint8x16_t
      - uint16x4_t
      - uint16x8_t
      - uint32x2_t
      - uint32x4_t
    compose:
      - Let: [mask, "{neon_type}", {FnCall: [simd_le, [a, b]]}]
      - FnCall: [simd_select, [mask, a, b]]

  - name: "vmin{neon_type.no}"
    doc: "Minimum (vector)"
    arguments: ["a: {neon_type}", "b: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vmin]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fmin]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - float32x2_t
      - float32x4_t
    compose:
      - LLVMLink:
          name: "fmin.{neon_type}"
          links:
            - link: "llvm.arm.neon.vmins.{neon_type}"
              arch: arm
            - link: "llvm.aarch64.neon.fmin.{neon_type}"
              arch: aarch64,arm64ec


  - name: "vmin{neon_type.no}"
    doc: Minimum (vector)
    arguments: ["a: {neon_type}", "b: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vmin]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fmin]]}]]
      - *neon-fp16
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    safety: safe
    types:
      - float16x4_t
      - float16x8_t
    compose:
      - LLVMLink:
          name: "vmin.{neon_type}"
          links:
            - link: "llvm.arm.neon.vmins.{neon_type}"
              arch: arm
            - link: "llvm.aarch64.neon.fmin.{neon_type}"
              arch: aarch64,arm64ec



  - name: "vminnm{neon_type.no}"
    doc: "Floating-point Minimum Number (vector)"
    arguments: ["a: {neon_type}", "b: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - FnCall: [cfg_attr, ['target_arch = "arm"', {FnCall: [target_feature, ['enable = "fp-armv8,v8"']]}]]
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vminnm]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fminnm]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - float32x2_t
      - float32x4_t
    compose:
      - FnCall: [simd_fmin, [a, b]]

  - name: "vpadd{neon_type.no}"
    doc: Floating-point add pairwise
    arguments: ["a: {neon_type}", "b: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vpadd]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [faddp]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - float32x2_t
    compose:
      - LLVMLink:
          name: "faddp.{neon_type}"
          links:
            - link: "llvm.arm.neon.vpadd.{neon_type}"
              arch: arm
            - link: "llvm.aarch64.neon.faddp.{neon_type}"
              arch: aarch64,arm64ec

  - name: "vpadd{neon_type.no}"
    doc: Floating-point add pairwise
    arguments: ["a: {neon_type}", "b: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vpadd]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [faddp]]}]]
      - *neon-fp16
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    safety: safe
    types:
      - float16x4_t
    compose:
      - LLVMLink:
          name: "faddp.{neon_type}"
          links:
            - link: "llvm.arm.neon.vpadd.{neon_type}"
              arch: arm
            - link: "llvm.aarch64.neon.faddp.{neon_type}"
              arch: aarch64,arm64ec


  - name: "vqdmull{neon_type[0].noq}"
    doc: "Signed saturating doubling multiply long"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vqdmull]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [sqdmull]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [int16x4_t, int32x4_t]
      - [int32x2_t, int64x2_t]
    compose:
      - LLVMLink:
          name: "vqdmull{neon_type[0].no}"
          links:
            - link: "llvm.arm.neon.vqdmull.{neon_type[1]}"
              arch: arm
            - link: "llvm.aarch64.neon.sqdmull.{neon_type[1]}"
              arch: aarch64,arm64ec

  - name: "vqdmull_n{neon_type[0].no}"
    doc: "Vector saturating doubling long multiply with scalar"
    arguments: ["a: {neon_type[0]}", "b: {type[1]}"]
    return_type: "{neon_type[2]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vqdmull]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [sqdmull]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [int16x4_t, "i16", int32x4_t]
      - [int32x2_t, "i32", int64x2_t]
    compose:
      - FnCall: ["vqdmull{neon_type[0].noq}", [a, {FnCall: ["vdup_n{neon_type[0].noq}", [b]]}]]

  - name: "vqdmull_lane_s16"
    doc: "Vector saturating doubling long multiply by scalar"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[2]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vqdmull, 'N = 2']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [sqdmull, 'N = 2']]}]]
      - FnCall: [rustc_legacy_const_generics, ['2']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [int16x4_t, int16x4_t, int32x4_t, '[N as u32, N as u32, N as u32, N as u32]']
    compose:
      - FnCall: [static_assert_uimm_bits!, [N, '2']]
      - Let: [b, "{neon_type[0]}", {FnCall: [simd_shuffle!, [b, b, "{type[3]}"]]}]
      - FnCall: [vqdmull_s16, [a, b]]

  - name: "vqdmull_lane_s32"
    doc: "Vector saturating doubling long multiply by scalar"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[2]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vqdmull, 'N = 1']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [sqdmull, 'N = 1']]}]]
      - FnCall: [rustc_legacy_const_generics, ['2']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [int32x2_t, int32x2_t, int64x2_t, '[N as u32, N as u32]']
    compose:
      - FnCall: [static_assert_uimm_bits!, [N, '1']]
      - Let: [b, "{neon_type[0]}", {FnCall: [simd_shuffle!, [b, b, "{type[3]}"]]}]
      - FnCall: [vqdmull_s32, [a, b]]

  - name: "vqdmlal{neon_type[1].noq}"
    doc: "Signed saturating doubling multiply-add long"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}", "c: {neon_type[1]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vqdmlal]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [sqdmlal]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [int32x4_t, int16x4_t, int16x4_t, int32x4_t]
      - [int64x2_t, int32x2_t, int32x2_t, int64x2_t]
    compose:
      - FnCall: ["vqadd{neon_type[0].no}", [a, {FnCall: ["vqdmull{neon_type[2].noq}", [b, c]]}]]

  - name: "vqdmlal_n{neon_type[1].noq}"
    doc: "Vector widening saturating doubling multiply accumulate with scalar"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}", "c: {type[2]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vqdmlal]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [sqdmlal]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [int32x4_t, int16x4_t, "i16", int32x4_t]
      - [int64x2_t, int32x2_t, "i32", int64x2_t]
    compose:
      - FnCall: ["vqadd{neon_type[0].no}", [a, {FnCall: ["vqdmull_n{neon_type[1].noq}", [b, c]]}]]

  - name: "vqdmlal_lane_s16"
    doc: "Vector widening saturating doubling multiply accumulate with scalar"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}", "c: {neon_type[1]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vqdmlal, N = 2]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [sqdmlal, 'N = 2']]}]]
      - FnCall: [rustc_legacy_const_generics, ['3']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [int32x4_t, int16x4_t, int16x4_t, int32x4_t]
    compose:
      - FnCall: [static_assert_uimm_bits!, [N, '2']]
      - FnCall: [vqaddq_s32, [a, {FnCall: ["vqdmull_lane_s16::<N>", [b, c]]}]]

  - name: "vqdmlal_lane_s32"
    doc: "Vector widening saturating doubling multiply accumulate with scalar"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}", "c: {neon_type[1]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vqdmlal, N = 1]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [sqdmlal, 'N = 1']]}]]
      - FnCall: [rustc_legacy_const_generics, ['3']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [int64x2_t, int32x2_t, int32x2_t, int64x2_t]
    compose:
      - FnCall: [static_assert_uimm_bits!, [N, '1']]
      - FnCall: [vqaddq_s64, [a, {FnCall: ["vqdmull_lane_s32::<N>", [b, c]]}]]

  - name: "vqdmlsl{neon_type[1].noq}"
    doc: "Signed saturating doubling multiply-subtract long"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}", "c: {neon_type[1]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vqdmlsl]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [sqdmlsl]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [int32x4_t, int16x4_t, int16x4_t, int32x4_t]
      - [int64x2_t, int32x2_t, int32x2_t, int64x2_t]
    compose:
      - FnCall: ["vqsub{neon_type[0].no}", [a, {FnCall: ["vqdmull{neon_type[1].noq}", [b, c]]}]]

  - name: "vqdmlsl{type[4]}"
    doc: "Vector widening saturating doubling multiply subtract with scalar"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}", "c: {type[2]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vqdmlsl]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [sqdmlsl]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [int32x4_t, int16x4_t, "i16", int32x4_t, '_n_s16']
      - [int64x2_t, int32x2_t, "i32", int64x2_t, '_n_s32']
    compose:
      - FnCall: ["vqsub{neon_type[0].no}", [a, {FnCall: ["vqdmull{type[4]}", [b, c]]}]]

  - name: "vqdmlsl_lane_s16"
    doc: "Vector widening saturating doubling multiply subtract with scalar"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}", "c: {neon_type[1]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vqdmlsl, N = 2]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [sqdmlsl, 'N = 2']]}]]
      - FnCall: [rustc_legacy_const_generics, ['3']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [int32x4_t, int16x4_t, int16x4_t, int32x4_t]
    compose:
      - FnCall: [static_assert_uimm_bits!, [N, '2']]
      - FnCall: [vqsubq_s32, [a, {FnCall: ["vqdmull_lane_s16::<N>", [b, c]]}]]

  - name: "vqdmlsl_lane_s32"
    doc: "Vector widening saturating doubling multiply subtract with scalar"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}", "c: {neon_type[1]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vqdmlsl, N = 1]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [sqdmlsl, 'N = 1']]}]]
      - FnCall: [rustc_legacy_const_generics, ['3']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [int64x2_t, int32x2_t, int32x2_t, int64x2_t]
    compose:
      - FnCall: [static_assert_uimm_bits!, [N, '1']]
      - FnCall: [vqsubq_s64, [a, {FnCall: ["vqdmull_lane_s32::<N>", [b, c]]}]]

  - name: "vqdmulh{neon_type[0].no}"
    doc: "Signed saturating doubling multiply returning high half"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vqdmulh]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [sqdmulh]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [int16x4_t, int16x4_t, int16x4_t]
      - [int16x8_t, int16x8_t, int16x8_t]
      - [int32x2_t, int32x2_t, int32x2_t]
      - [int32x4_t, int32x4_t, int32x4_t]
    compose:
      - LLVMLink:
          name: "vqdmulh{neon_type[0].no}"
          links:
            - link: "llvm.arm.neon.vqdmulh.{neon_type[0]}"
              arch: arm
            - link: "llvm.aarch64.neon.sqdmulh.{neon_type[0]}"
              arch: aarch64,arm64ec

  - name: "vqdmulh{type[3]}"
    doc: "Vector saturating doubling multiply high with scalar"
    arguments: ["a: {neon_type[0]}", "b: {type[1]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vqdmulh]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [sqdmulh]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [int16x4_t, "i16", int16x4_t, '_n_s16']
      - [int32x2_t, "i32", int32x2_t, '_n_s32']
      - [int16x8_t, "i16", int16x8_t, 'q_n_s16']
      - [int32x4_t, "i32", int32x4_t, 'q_n_s32']
    compose:
      - Let: [b, "{neon_type[0]}", {FnCall: ["vdup{type[3]}", [b]]}]
      - FnCall: ["vqdmulh{neon_type[0].no}", [a, b]]

  - name: "vqmovn{neon_type[0].noq}"
    doc: "Signed saturating extract narrow"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vqmovn]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [sqxtn]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [int16x8_t, int8x8_t]
      - [int32x4_t, int16x4_t]
      - [int64x2_t, int32x2_t]
    compose:
      - LLVMLink:
          name: "vqmovn{neon_type[0].noq}"
          links:
            - link: "llvm.arm.neon.vqmovns.{neon_type[1]}"
              arch: arm
            - link: "llvm.aarch64.neon.sqxtn.{neon_type[1]}"
              arch: aarch64,arm64ec

  - name: "vqmovun{neon_type[0].noq}"
    doc: "Signed saturating extract unsigned narrow"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vqmovun]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [sqxtun]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [int16x8_t, uint8x8_t]
      - [int32x4_t, uint16x4_t]
      - [int64x2_t, uint32x2_t]
    compose:
      - LLVMLink:
          name: "vqmovun{neon_type[0].noq}"
          links:
            - link: "llvm.arm.neon.vqmovnsu.{neon_type[1]}"
              arch: arm
            - link: "llvm.aarch64.neon.sqxtun.{neon_type[1]}"
              arch: aarch64,arm64ec

  - name: "vqrdmulh{neon_type[0].no}"
    doc: "Signed saturating rounding doubling multiply returning high half"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vqrdmulh]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [sqrdmulh]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [int16x4_t, int16x4_t, int16x4_t]
      - [int16x8_t, int16x8_t, int16x8_t]
      - [int32x2_t, int32x2_t, int32x2_t]
      - [int32x4_t, int32x4_t, int32x4_t]
    compose:
      - LLVMLink:
          name: "vqrdmulh{neon_type[0].no}"
          links:
            - link: "llvm.arm.neon.vqrdmulh.{neon_type[0]}"
              arch: arm
            - link: "llvm.aarch64.neon.sqrdmulh.{neon_type[0]}"
              arch: aarch64,arm64ec

  - name: "vqrshl{neon_type.no}"
    doc: "Signed saturating rounding shift left"
    arguments: ["a: {neon_type}", "b: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vqrshl]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [sqrshl]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - int8x8_t
      - int8x16_t
      - int16x4_t
      - int16x8_t
      - int32x2_t
      - int32x4_t
      - int64x1_t
      - int64x2_t
    compose:
      - LLVMLink:
          name: "vqrshl{neon_type}"
          links:
            - link: "llvm.arm.neon.vqrshifts.{neon_type}"
              arch: arm
            - link: "llvm.aarch64.neon.sqrshl.{neon_type}"
              arch: aarch64,arm64ec

  - name: "vqrshl{neon_type[0].no}"
    doc: "Unsigned signed saturating rounding shift left"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vqrshl]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [uqrshl]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [uint8x8_t, int8x8_t]
      - [uint8x16_t, int8x16_t]
      - [uint16x4_t, int16x4_t]
      - [uint16x8_t, int16x8_t]
      - [uint32x2_t, int32x2_t]
      - [uint32x4_t, int32x4_t]
      - [uint64x1_t, int64x1_t]
      - [uint64x2_t, int64x2_t]
    compose:
      - LLVMLink:
          name: "vqrshl{neon_type[0].no}"
          links:
            - link: "llvm.arm.neon.vqrshiftu.{neon_type[1]}"
              arch: arm
            - link: "llvm.aarch64.neon.uqrshl.{neon_type[1]}"
              arch: aarch64,arm64ec

  - name: "vqrshrn_n{neon_type[0].noq}"
    doc: "Signed saturating rounded shift right narrow"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *target-is-arm
      - *enable-v7
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [vqrshrn, 'N = 2']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-arm-unstable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [int16x8_t, int8x8_t, 'N >= 1 && N <= 8', 'const { int16x8_t([-N as i16; 8]) }']
      - [int32x4_t, int16x4_t, 'N >= 1 && N <= 16', 'const { int32x4_t([-N; 4]) }']
      - [int64x2_t, int32x2_t, 'N >= 1 && N <= 32', 'const { int64x2_t([-N as i64; 2]) }']
    compose:
      - FnCall: [static_assert!, ["{type[2]}"]]
      - LLVMLink:
          name: "vqrshrn{neon_type[0].noq}"
          arguments:
            - "a: {neon_type[0]}"
            - "n: {neon_type[0]}"
          links:
            - link: "llvm.arm.neon.vqrshiftns.{neon_type[1]}"
              arch: arm
      - FnCall: ["_vqrshrn_n{neon_type[0].noq}", [a, '{type[3]}'], [], true]

  - name: "vqrshrn_n{neon_type[0].noq}"
    doc: "Signed saturating rounded shift right narrow"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - FnCall: [cfg, [{FnCall: [not, ['target_arch = "arm"']]}]]
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [sqrshrn, 'N = 2']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-stable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [int16x8_t, int8x8_t, 'N >= 1 && N <= 8']
      - [int32x4_t, int16x4_t, 'N >= 1 && N <= 16']
      - [int64x2_t, int32x2_t, 'N >= 1 && N <= 32']
    compose:
      - FnCall: [static_assert!, ["{type[2]}"]]
      - LLVMLink:
          name: "vqrshrn{neon_type[0].no}"
          arguments:
            - "a: {neon_type[0]}"
            - "n: i32"
          links:
            - link: "llvm.aarch64.neon.sqrshrn.{neon_type[1]}"
              arch: aarch64,arm64ec
      - FnCall: ["_vqrshrn_n{neon_type[0].noq}", [a, N], [], true]

  - name: "vqrshrun_n{neon_type[0].noq}"
    doc: "Signed saturating rounded shift right unsigned narrow"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *target-is-arm
      - *enable-v7
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [vqrshrun, 'N = 2']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-arm-unstable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [int16x8_t, uint8x8_t, 'N >= 1 && N <= 8', 'const { int16x8_t([-N as i16; 8]) }']
      - [int32x4_t, uint16x4_t, 'N >= 1 && N <= 16', 'const { int32x4_t([-N; 4]) }']
      - [int64x2_t, uint32x2_t, 'N >= 1 && N <= 32', 'const { int64x2_t([-N as i64; 2]) }']
    compose:
      - FnCall: [static_assert!, ["{type[2]}"]]
      - LLVMLink:
          name: "vqrshrun_n{neon_type[0].noq}"
          arguments:
            - 'a: {neon_type[0]}'
            - 'n: {neon_type[0]}'
          links:
            - link: "llvm.arm.neon.vqrshiftnsu.{neon_type[1]}"
              arch: arm
      - FnCall:
          - "_vqrshrun_n{neon_type[0].noq}"
          - - a
            - "{type[3]}"
          - []
          - true

  - name: "vqrshrun_n{neon_type[0].noq}"
    doc: "Signed saturating rounded shift right unsigned narrow"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - FnCall: [cfg, [{FnCall: [not, ['target_arch = "arm"']]}]]
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [sqrshrun, 'N = 2']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-stable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [int16x8_t, uint8x8_t, 'N >= 1 && N <= 8']
      - [int32x4_t, uint16x4_t, 'N >= 1 && N <= 16']
      - [int64x2_t, uint32x2_t, 'N >= 1 && N <= 32']
    compose:
      - FnCall: [static_assert!, ["{type[2]}"]]
      - LLVMLink:
          name: "vqrshrun_n{neon_type[0].noq}"
          arguments:
            - 'a: {neon_type[0]}'
            - 'n: i32'
          links:
            - link: "llvm.aarch64.neon.sqrshrun.{neon_type[1]}"
              arch: aarch64,arm64ec
      - FnCall: ["_vqrshrun_n{neon_type[0].noq}", [a, N], [], true]

  - name: "vqshl{neon_type.no}"
    doc: "Signed saturating shift left"
    arguments: ["a: {neon_type}", "b: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vqshl]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [sqshl]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - int8x8_t
      - int8x16_t
      - int16x4_t
      - int16x8_t
      - int32x2_t
      - int32x4_t
      - int64x1_t
      - int64x2_t
    compose:
      - LLVMLink:
          name: "vqshl{neon_type}"
          links:
            - link: "llvm.arm.neon.vqshifts.{neon_type}"
              arch: arm
            - link: "llvm.aarch64.neon.sqshl.{neon_type}"
              arch: aarch64,arm64ec

  - name: "vqshl{neon_type[0].N}"
    doc: "Signed saturating shift left"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vqshl, 'N = 2']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [sqshl, 'N = 2']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [int8x8_t, '3']
      - [int8x16_t, '3']
      - [int16x4_t, '4']
      - [int16x8_t, '4']
      - [int32x2_t, '5']
      - [int32x4_t, '5']
      - [int64x1_t, '6']
      - [int64x2_t, '6']
    compose:
      - FnCall: [static_assert_uimm_bits!, [N, "{type[1]}"]]
      - FnCall:
          - "vqshl{neon_type[0].no}"
          - - a
            - FnCall: ["vdup{neon_type[0].N}", ['N as _']]

  - name: "vqshl{neon_type[0].no}"
    doc: "Unsigned saturating shift left"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vqshl]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [uqshl]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [uint8x8_t, int8x8_t]
      - [uint8x16_t, int8x16_t]
      - [uint16x4_t, int16x4_t]
      - [uint16x8_t, int16x8_t]
      - [uint32x2_t, int32x2_t]
      - [uint32x4_t, int32x4_t]
      - [uint64x1_t, int64x1_t]
      - [uint64x2_t, int64x2_t]
    compose:
      - LLVMLink:
          name: "vqshl{neon_type[0].no}"
          links:
            - link: "llvm.arm.neon.vqshiftu.{neon_type[1]}"
              arch: arm
            - link: "llvm.aarch64.neon.uqshl.{neon_type[1]}"
              arch: aarch64,arm64ec

  - name: "vqshl{neon_type[0].N}"
    doc: "Unsigned saturating shift left"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vqshl, N = 2]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [uqshl, 'N = 2']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [uint8x8_t, '3', int8x8_t]
      - [uint8x16_t, '3', int8x16_t]
      - [uint16x4_t, '4', int16x4_t]
      - [uint16x8_t, '4', int16x8_t]
      - [uint32x2_t, '5', int32x2_t]
      - [uint32x4_t, '5', int32x4_t]
      - [uint64x1_t, '6', int64x1_t]
      - [uint64x2_t, '6', int64x2_t]
    compose:
      - FnCall: [static_assert_uimm_bits!, [N, "{type[1]}"]]
      - FnCall:
          - "vqshl{neon_type[0].no}"
          - - a
            - FnCall: ["vdup{neon_type[2].N}", ['N as _']]

  - name: "vqshrn_n{neon_type[0].noq}"
    doc: "Signed saturating shift right narrow"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *target-is-arm
      - *enable-v7
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [vqshrn, 'N = 2']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-arm-unstable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [int16x8_t, int8x8_t, 'N >= 1 && N <= 8', 'const { int16x8_t([-N as i16; 8]) }']
      - [int32x4_t, int16x4_t, 'N >= 1 && N <= 16', 'const { int32x4_t([-N; 4]) }']
      - [int64x2_t, int32x2_t, 'N >= 1 && N <= 32', 'const { int64x2_t([-N as i64; 2]) }']
    compose:
      - FnCall: [static_assert!, ["{type[2]}"]]
      - LLVMLink:
          name: "vqshrn{neon_type[0].no}"
          arguments:
            - "a: {neon_type[0]}"
            - "n: {neon_type[0]}"
          links:
            - link: "llvm.arm.neon.vqshiftns.{neon_type[1]}"
              arch: arm
      - FnCall: ["_vqshrn_n{neon_type[0].noq}", [a, "{type[3]}"], [], true]

  - name: "vqshrn_n{neon_type[0].noq}"
    doc: "Signed saturating shift right narrow"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - FnCall: [cfg, [{FnCall: [not, ['target_arch = "arm"']]}]]
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [sqshrn, 'N = 2']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-stable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [int16x8_t, int8x8_t, 'N >= 1 && N <= 8']
      - [int32x4_t, int16x4_t, 'N >= 1 && N <= 16']
      - [int64x2_t, int32x2_t, 'N >= 1 && N <= 32']
    compose:
      - FnCall: [static_assert!, ["{type[2]}"]]
      - LLVMLink:
          name: "vqshrn_n{neon_type[0].noq}"
          arguments:
            - "a: {neon_type[0]}"
            - "n: i32"
          links:
            - link: "llvm.aarch64.neon.sqshrn.{neon_type[1]}"
              arch: aarch64,arm64ec
      - FnCall: ["_vqshrn_n{neon_type[0].noq}", [a, N], [], true]

  - name: "vqshrn_n_{neon_type[0]}"
    doc: "Unsigned saturating shift right narrow"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *target-is-arm
      - *enable-v7
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [vqshrn, 'N = 2']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-arm-unstable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [uint16x8_t, uint8x8_t, 'N >= 1 && N <= 8', 'const { uint16x8_t([-N as u16, -N as u16, -N as u16, -N as u16, -N as u16, -N as u16, -N as u16, -N as u16]) }']
      - [uint32x4_t, uint16x4_t, 'N >= 1 && N <= 16', 'const { uint32x4_t([-N as u32, -N as u32, -N as u32, -N as u32]) }']
      - [uint64x2_t, uint32x2_t, 'N >= 1 && N <= 32', 'const { uint64x2_t([-N as u64, -N as u64]) }']
    compose:
      - FnCall: [static_assert!, ["{type[2]}"]]
      - LLVMLink:
          name: "vqshrn_n_{neon_type[0]}"
          arguments:
            - "a: {neon_type[0]}"
            - "n: {neon_type[0]}"
          links:
            - link: "llvm.arm.neon.vqshiftnu.{neon_type[1]}"
              arch: arm
      - FnCall: ["_vqshrn_n_{neon_type[0]}", ["a", "{type[3]}"], [], true]

  - name: "vqshrn_n_{neon_type[0]}"
    doc: "Unsigned saturating shift right narrow"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - FnCall: [cfg, [{FnCall: [not, ['target_arch = "arm"']]}]]
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [uqshrn, 'N = 2']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-stable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [uint16x8_t, uint8x8_t, 'N >= 1 && N <= 8']
      - [uint32x4_t, uint16x4_t, 'N >= 1 && N <= 16']
      - [uint64x2_t, uint32x2_t, 'N >= 1 && N <= 32']
    compose:
      - FnCall: [static_assert!, ["{type[2]}"]]
      - LLVMLink:
          name: "vqshrn{neon_type[1].no}"
          arguments:
            - "a: {neon_type[0]}"
            - "n: i32"
          links:
            - link: "llvm.aarch64.neon.uqshrn.{neon_type[1]}"
              arch: aarch64,arm64ec
      - FnCall: ["_vqshrn_n_{neon_type[0]}", ["a", N], [], true]

  - name: "vqshrun_n_{neon_type[0]}"
    doc: "Signed saturating shift right unsigned narrow"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *target-is-arm
      - *enable-v7
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [vqshrun, 'N = 2']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-arm-unstable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [int16x8_t, uint8x8_t, 'N >= 1 && N <= 8', 'const { int16x8_t([-N as i16; 8]) }']
      - [int32x4_t, uint16x4_t, 'N >= 1 && N <= 16', 'const { int32x4_t([-N; 4]) }']
      - [int64x2_t, uint32x2_t, 'N >= 1 && N <= 32', 'const { int64x2_t([-N as i64; 2]) }']
    compose:
      - FnCall: [static_assert!, ["{type[2]}"]]
      - LLVMLink:
          name: "vqshrun_n_{neon_type[1]}"
          arguments:
            - "a: {neon_type[0]}"
            - "n: {neon_type[0]}"
          links:
            - link: "llvm.arm.neon.vqshiftnsu.{neon_type[1]}"
              arch: arm
      - FnCall: ["_vqshrun_n_{neon_type[0]}", [a, "{type[3]}"], [], true]

  - name: "vqshrun_n_{neon_type[0]}"
    doc: "Signed saturating shift right unsigned narrow"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - FnCall: [cfg, [{FnCall: [not, ['target_arch = "arm"']]}]]
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [sqshrun, 'N = 2']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-stable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [int16x8_t, uint8x8_t, 'N >= 1 && N <= 8']
      - [int32x4_t, uint16x4_t, 'N >= 1 && N <= 16']
      - [int64x2_t, uint32x2_t, 'N >= 1 && N <= 32']
    compose:
      - FnCall: [static_assert!, ["{type[2]}"]]
      - LLVMLink:
          name: "vqshrun_n_{neon_type[0]}"
          arguments:
            - "a: {neon_type[0]}"
            - "n: i32"
          links:
            - link: "llvm.aarch64.neon.sqshrun.{neon_type[1]}"
              arch: aarch64,arm64ec
      - FnCall: ["_vqshrun_n_{neon_type[0]}", [a, N], [], true]

  - name: "vrsqrts{neon_type.no}"
    doc: "Floating-point reciprocal square root step"
    arguments: ["a: {neon_type}", "b: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vrsqrts]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [frsqrts]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - float32x2_t
      - float32x4_t
    compose:
      - LLVMLink:
          name: "vrsqrts{neon_type.no}"
          links:
            - link: "llvm.arm.neon.vrsqrts.{neon_type}"
              arch: arm
            - link: "llvm.aarch64.neon.frsqrts.{neon_type}"
              arch: aarch64,arm64ec


  - name: "vrsqrts{neon_type.no}"
    doc: "Floating-point reciprocal square root step"
    arguments: ["a: {neon_type}", "b: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v8
      - *neon-fp16
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vrsqrts]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [frsqrts]]}]]
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    safety: safe
    types:
      - float16x4_t
      - float16x8_t
    compose:
      - LLVMLink:
          name: "vrsqrts{neon_type.no}"
          links:
            - link: "llvm.arm.neon.vrsqrts.{neon_type}"
              arch: arm
            - link: "llvm.aarch64.neon.frsqrts.{neon_type}"
              arch: aarch64,arm64ec


  - name: "vrecpe{neon_type.no}"
    doc: "Reciprocal estimate."
    arguments: ["a: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vrecpe]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [frecpe]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - float32x2_t
      - float32x4_t
    compose:
      - LLVMLink:
          name: "vrecpe{neon_type.no}"
          links:
            - link: "llvm.arm.neon.vrecpe.{neon_type}"
              arch: arm
            - link: "llvm.aarch64.neon.frecpe.{neon_type}"
              arch: aarch64,arm64ec


  - name: "vrecpe{neon_type.no}"
    doc: "Reciprocal estimate."
    arguments: ["a: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vrecpe]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [frecpe]]}]]
      - *neon-fp16
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    safety: safe
    types:
      - float16x4_t
      - float16x8_t
    compose:
      - LLVMLink:
          name: "vrecpe{neon_type.no}"
          links:
            - link: "llvm.arm.neon.vrecpe.{neon_type}"
              arch: arm
            - link: "llvm.aarch64.neon.frecpe.{neon_type}"
              arch: aarch64,arm64ec


  - name: "vrecps{neon_type.no}"
    doc: "Floating-point reciprocal step"
    arguments: ["a: {neon_type}", "b: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vrecps]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [frecps]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - float32x2_t
      - float32x4_t
    compose:
      - LLVMLink:
          name: "vrecps{neon_type.no}"
          links:
            - link: "llvm.arm.neon.vrecps.{neon_type}"
              arch: arm
            - link: "llvm.aarch64.neon.frecps.{neon_type}"
              arch: aarch64,arm64ec


  - name: "vrecps{neon_type.no}"
    doc: "Floating-point reciprocal step"
    arguments: ["a: {neon_type}", "b: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vrecps]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [frecps]]}]]
      - *neon-fp16
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    safety: safe
    types:
      - float16x4_t
      - float16x8_t
    compose:
      - LLVMLink:
          name: "vrecps{neon_type.no}"
          links:
            - link: "llvm.arm.neon.vrecps.{neon_type}"
              arch: arm
            - link: "llvm.aarch64.neon.frecps.{neon_type}"
              arch: aarch64,arm64ec


  - name: "vreinterpret{neon_type[1].no}{neon_type[0].noq}"
    doc: Vector reinterpret cast operation
    arguments: ["a: {type[0]}"]
    return_type: "{type[1]}"
    attr:
      - *neon-aes
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [nop]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [nop]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [poly64x1_t, int32x2_t]
      - [poly64x1_t, uint32x2_t]
      - [poly64x2_t, int32x4_t]
      - [poly64x2_t, uint32x4_t]
      - [p128, int64x2_t]
      - [p128, uint64x2_t]
      - [p128, poly64x2_t]
      - [poly8x16_t, p128]
      - [p128, int8x16_t]
      - [p128, uint8x16_t]
      - [p128, poly8x16_t]
      - [int32x2_t, poly64x1_t]
      - [uint32x2_t, poly64x1_t]
      - [int32x4_t, poly64x2_t]
      - [uint32x4_t, poly64x2_t]
      - [int64x2_t, p128]
      - [uint64x2_t, p128]
      - [poly64x2_t, p128]
      - [poly64x1_t, int16x4_t]
      - [poly64x1_t, uint16x4_t]
      - [poly64x1_t, poly16x4_t]
      - [poly64x2_t, int16x8_t]
      - [poly64x2_t, uint16x8_t]
      - [poly64x2_t, poly16x8_t]
      - [p128, int32x4_t]
      - [p128, uint32x4_t]
      - [poly16x4_t, poly64x1_t]
      - [int16x4_t, poly64x1_t]
      - [uint16x4_t, poly64x1_t]
      - [poly16x8_t, poly64x2_t]
      - [int16x8_t, poly64x2_t]
      - [uint16x8_t, poly64x2_t]
      - [int32x4_t, p128]
      - [uint32x4_t, p128]
      - [poly64x1_t, int8x8_t]
      - [poly64x1_t, uint8x8_t]
      - [poly64x1_t, poly8x8_t]
      - [poly64x2_t, int8x16_t]
      - [poly64x2_t, uint8x16_t]
      - [poly64x2_t, poly8x16_t]
      - [p128, int16x8_t]
      - [p128, uint16x8_t]
      - [p128, poly16x8_t]
      - [poly8x8_t, poly64x1_t]
      - [int8x8_t, poly64x1_t]
      - [uint8x8_t, poly64x1_t]
      - [poly8x16_t, poly64x2_t]
      - [int8x16_t, poly64x2_t]
      - [uint8x16_t, poly64x2_t]
      - [int16x8_t, p128]
      - [uint16x8_t, p128]
      - [poly16x8_t, p128]
      - [int8x16_t, p128]
      - [uint8x16_t, p128]
    compose:
      - FnCall: [transmute, [a]]

  - name: "vreinterpret{neon_type[1].no}{neon_type[0].noq}"
    doc: Vector reinterpret cast operation
    arguments: ["a: {type[0]}"]
    return_type: "{type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [nop]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [nop]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [uint8x8_t, int8x8_t]
      - [poly8x8_t, int8x8_t]
      - [poly16x4_t, int16x4_t]
      - [uint16x4_t, int16x4_t]
      - [uint32x2_t, int32x2_t]
      - [uint64x1_t, int64x1_t]
      - [uint8x16_t, int8x16_t]
      - [poly8x16_t, int8x16_t]
      - [poly16x8_t, int16x8_t]
      - [uint16x8_t, int16x8_t]
      - [uint32x4_t, int32x4_t]
      - [uint64x2_t, int64x2_t]
      - [poly8x8_t, uint8x8_t]
      - [int8x8_t, uint8x8_t]
      - [poly16x4_t, uint16x4_t]
      - [int16x4_t, uint16x4_t]
      - [int32x2_t, uint32x2_t]
      - [int64x1_t, uint64x1_t]
      - [poly8x16_t, uint8x16_t]
      - [int8x16_t, uint8x16_t]
      - [poly16x8_t, uint16x8_t]
      - [int16x8_t, uint16x8_t]
      - [int32x4_t, uint32x4_t]
      - [int64x2_t, uint64x2_t]
      - [int8x8_t, poly8x8_t]
      - [uint8x8_t, poly8x8_t]
      - [int16x4_t, poly16x4_t]
      - [uint16x4_t, poly16x4_t]
      - [int8x16_t, poly8x16_t]
      - [uint8x16_t, poly8x16_t]
      - [int16x8_t, poly16x8_t]
      - [uint16x8_t, poly16x8_t]
      - [int16x4_t, int8x8_t]
      - [uint16x4_t, int8x8_t]
      - [poly16x4_t, int8x8_t]
      - [int32x2_t, int16x4_t]
      - [uint32x2_t, int16x4_t]
      - [int64x1_t, int32x2_t]
      - [uint64x1_t, int32x2_t]
      - [int16x8_t, int8x16_t]
      - [uint16x8_t, int8x16_t]
      - [poly16x8_t, int8x16_t]
      - [int32x4_t, int16x8_t]
      - [uint32x4_t, int16x8_t]
      - [int64x2_t, int32x4_t]
      - [uint64x2_t, int32x4_t]
      - [poly16x4_t, uint8x8_t]
      - [int16x4_t, uint8x8_t]
      - [uint16x4_t, uint8x8_t]
      - [int32x2_t, uint16x4_t]
      - [uint32x2_t, uint16x4_t]
      - [int64x1_t, uint32x2_t]
      - [uint64x1_t, uint32x2_t]
      - [poly16x8_t, uint8x16_t]
      - [int16x8_t, uint8x16_t]
      - [uint16x8_t, uint8x16_t]
      - [int32x4_t, uint16x8_t]
      - [uint32x4_t, uint16x8_t]
      - [int64x2_t, uint32x4_t]
      - [uint64x2_t, uint32x4_t]
      - [poly16x4_t, poly8x8_t]
      - [int16x4_t, poly8x8_t]
      - [uint16x4_t, poly8x8_t]
      - [int32x2_t, poly16x4_t]
      - [uint32x2_t, poly16x4_t]
      - [poly16x8_t, poly8x16_t]
      - [int16x8_t, poly8x16_t]
      - [uint16x8_t, poly8x16_t]
      - [int32x4_t, poly16x8_t]
      - [uint32x4_t, poly16x8_t]
      - [poly8x8_t, int16x4_t]
      - [int8x8_t, int16x4_t]
      - [uint8x8_t, int16x4_t]
      - [poly16x4_t, int32x2_t]
      - [int16x4_t, int32x2_t]
      - [uint16x4_t, int32x2_t]
      - [int32x2_t, int64x1_t]
      - [uint32x2_t, int64x1_t]
      - [poly8x16_t, int16x8_t]
      - [int8x16_t, int16x8_t]
      - [uint8x16_t, int16x8_t]
      - [poly16x8_t, int32x4_t]
      - [int16x8_t, int32x4_t]
      - [uint16x8_t, int32x4_t]
      - [int32x4_t, int64x2_t]
      - [uint32x4_t, int64x2_t]
      - [poly8x8_t, uint16x4_t]
      - [int8x8_t, uint16x4_t]
      - [uint8x8_t, uint16x4_t]
      - [poly16x4_t, uint32x2_t]
      - [int16x4_t, uint32x2_t]
      - [uint16x4_t, uint32x2_t]
      - [int32x2_t, uint64x1_t]
      - [uint32x2_t, uint64x1_t]
      - [poly8x16_t, uint16x8_t]
      - [int8x16_t, uint16x8_t]
      - [uint8x16_t, uint16x8_t]
      - [poly16x8_t, uint32x4_t]
      - [int16x8_t, uint32x4_t]
      - [uint16x8_t, uint32x4_t]
      - [int32x4_t, uint64x2_t]
      - [uint32x4_t, uint64x2_t]
      - [poly8x8_t, poly16x4_t]
      - [int8x8_t, poly16x4_t]
      - [uint8x8_t, poly16x4_t]
      - [poly8x16_t, poly16x8_t]
      - [int8x16_t, poly16x8_t]
      - [uint8x16_t, poly16x8_t]
      - [int32x2_t, int8x8_t]
      - [uint32x2_t, int8x8_t]
      - [int64x1_t, int16x4_t]
      - [uint64x1_t, int16x4_t]
      - [int32x4_t, int8x16_t]
      - [uint32x4_t, int8x16_t]
      - [int64x2_t, int16x8_t]
      - [uint64x2_t, int16x8_t]
      - [int32x2_t, uint8x8_t]
      - [uint32x2_t, uint8x8_t]
      - [int64x1_t, uint16x4_t]
      - [uint64x1_t, uint16x4_t]
      - [int32x4_t, uint8x16_t]
      - [uint32x4_t, uint8x16_t]
      - [int64x2_t, uint16x8_t]
      - [uint64x2_t, uint16x8_t]
      - [int32x2_t, poly8x8_t]
      - [uint32x2_t, poly8x8_t]
      - [int64x1_t, poly16x4_t]
      - [uint64x1_t, poly16x4_t]
      - [int32x4_t, poly8x16_t]
      - [uint32x4_t, poly8x16_t]
      - [int64x2_t, poly16x8_t]
      - [uint64x2_t, poly16x8_t]
      - [poly8x8_t, int32x2_t]
      - [int8x8_t, int32x2_t]
      - [uint8x8_t, int32x2_t]
      - [poly16x4_t, int64x1_t]
      - [int16x4_t, int64x1_t]
      - [uint16x4_t, int64x1_t]
      - [poly8x16_t, int32x4_t]
      - [int8x16_t, int32x4_t]
      - [uint8x16_t, int32x4_t]
      - [poly16x8_t, int64x2_t]
      - [int16x8_t, int64x2_t]
      - [uint16x8_t, int64x2_t]
      - [poly8x8_t, uint32x2_t]
      - [int8x8_t, uint32x2_t]
      - [uint8x8_t, uint32x2_t]
      - [poly16x4_t, uint64x1_t]
      - [int16x4_t, uint64x1_t]
      - [uint16x4_t, uint64x1_t]
      - [poly8x16_t, uint32x4_t]
      - [int8x16_t, uint32x4_t]
      - [uint8x16_t, uint32x4_t]
      - [poly16x8_t, uint64x2_t]
      - [int16x8_t, uint64x2_t]
      - [uint16x8_t, uint64x2_t]
      - [int64x1_t, int8x8_t]
      - [uint64x1_t, int8x8_t]
      - [int64x1_t, uint8x8_t]
      - [uint64x1_t, uint8x8_t]
      - [int64x1_t, poly8x8_t]
      - [uint64x1_t, poly8x8_t]
      - [int64x2_t, int8x16_t]
      - [uint64x2_t, int8x16_t]
      - [int64x2_t, uint8x16_t]
      - [uint64x2_t, uint8x16_t]
      - [int64x2_t, poly8x16_t]
      - [uint64x2_t, poly8x16_t]
      - [poly8x8_t, int64x1_t]
      - [int8x8_t, int64x1_t]
      - [uint8x8_t, int64x1_t]
      - [poly8x8_t, uint64x1_t]
      - [int8x8_t, uint64x1_t]
      - [uint8x8_t, uint64x1_t]
      - [poly8x16_t, int64x2_t]
      - [int8x16_t, int64x2_t]
      - [uint8x16_t, int64x2_t]
      - [poly8x16_t, uint64x2_t]
      - [int8x16_t, uint64x2_t]
      - [uint8x16_t, uint64x2_t]
      - [float32x2_t, int8x8_t]
      - [float32x2_t, int16x4_t]
      - [float32x2_t, int32x2_t]
      - [float32x2_t, int64x1_t]
      - [float32x4_t, int8x16_t]
      - [float32x4_t, int16x8_t]
      - [float32x4_t, int32x4_t]
      - [float32x4_t, int64x2_t]
      - [float32x2_t, uint8x8_t]
      - [float32x2_t, uint16x4_t]
      - [float32x2_t, uint32x2_t]
      - [float32x2_t, uint64x1_t]
      - [float32x4_t, uint8x16_t]
      - [float32x4_t, uint16x8_t]
      - [float32x4_t, uint32x4_t]
      - [float32x4_t, uint64x2_t]
      - [float32x2_t, poly8x8_t]
      - [float32x2_t, poly16x4_t]
      - [float32x4_t, poly8x16_t]
      - [float32x4_t, poly16x8_t]
      - [float32x4_t, p128]
      - [int8x8_t, float32x2_t]
      - [int16x4_t, float32x2_t]
      - [int32x2_t, float32x2_t]
      - [int64x1_t, float32x2_t]
      - [int8x16_t, float32x4_t]
      - [int16x8_t, float32x4_t]
      - [int32x4_t, float32x4_t]
      - [int64x2_t, float32x4_t]
      - [uint8x8_t, float32x2_t]
      - [uint16x4_t, float32x2_t]
      - [uint32x2_t, float32x2_t]
      - [uint64x1_t, float32x2_t]
      - [uint8x16_t, float32x4_t]
      - [uint16x8_t, float32x4_t]
      - [uint32x4_t, float32x4_t]
      - [uint64x2_t, float32x4_t]
      - [poly8x8_t, float32x2_t]
      - [poly16x4_t, float32x2_t]
      - [poly8x16_t, float32x4_t]
      - [poly16x8_t, float32x4_t]
      - [p128, float32x4_t]
    compose:
      - FnCall: [transmute, [a]]


  - name: "vreinterpret{neon_type[1].no}{neon_type[0].noq}"
    doc: Vector reinterpret cast operation
    arguments: ["a: {type[0]}"]
    return_type: "{type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [nop]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [nop]]}]]
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    safety: safe
    types:
      # non-q
      - [float32x2_t, float16x4_t]
      - [poly16x4_t, float16x4_t]
      - [poly8x8_t, float16x4_t]
      - [int8x8_t, float16x4_t]
      - [int16x4_t, float16x4_t]
      - [int32x2_t, float16x4_t]
      - [int64x1_t, float16x4_t]
      - [uint8x8_t, float16x4_t]
      - [uint16x4_t, float16x4_t]
      - [uint32x2_t, float16x4_t]
      - [uint64x1_t, float16x4_t]
      - [float16x4_t, float32x2_t]
      - [float16x4_t, poly16x4_t]
      - [float16x4_t, poly8x8_t]
      - [float16x4_t, int8x8_t]
      - [float16x4_t, int16x4_t]
      - [float16x4_t, int32x2_t]
      - [float16x4_t, int64x1_t]
      - [float16x4_t, uint8x8_t]
      - [float16x4_t, uint16x4_t]
      - [float16x4_t, uint32x2_t]
      - [float16x4_t, uint64x1_t]
      # q
      - [float32x4_t, float16x8_t]
      - [poly16x8_t, float16x8_t]
      - [poly8x16_t, float16x8_t]
      - [int8x16_t, float16x8_t]
      - [int16x8_t, float16x8_t]
      - [int32x4_t, float16x8_t]
      - [int64x2_t, float16x8_t]
      - [uint8x16_t, float16x8_t]
      - [uint16x8_t, float16x8_t]
      - [uint32x4_t, float16x8_t]
      - [uint64x2_t, float16x8_t]
      - [float16x8_t, float32x4_t]
      - [float16x8_t, poly16x8_t]
      - [float16x8_t, poly8x16_t]
      - [float16x8_t, int8x16_t]
      - [float16x8_t, int16x8_t]
      - [float16x8_t, int32x4_t]
      - [float16x8_t, int64x2_t]
      - [float16x8_t, uint8x16_t]
      - [float16x8_t, uint16x8_t]
      - [float16x8_t, uint32x4_t]
      - [float16x8_t, uint64x2_t]
    compose:
      - FnCall: [transmute, [a]]


  - name: "vreinterpret{neon_type[1].no}{neon_type[0].noq}"
    doc: Vector reinterpret cast operation
    arguments: ["a: {type[0]}"]
    return_type: "{type[1]}"
    attr:
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [nop]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [nop]]}]]
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    safety: safe
    types:
      - [poly64x1_t, float16x4_t]
      - [float16x4_t, poly64x1_t]
      # q
      - [poly64x2_t, float16x8_t]
      - [poly128_t, float16x8_t]
      - [float16x8_t, poly128_t]
      - [float16x8_t, poly64x2_t]
    compose:
      - FnCall: [transmute, [a]]

  - name: "vrev64{neon_type[0].no}"
    doc: Reverse elements in 64-bit doublewords
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vrev64]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [rev64]]}]]
      - *neon-fp16
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    safety: safe
    types:
      - [float16x4_t, "[3, 2, 1, 0]"]
      - [float16x8_t, "[3, 2, 1, 0, 7, 6, 5, 4]"]
    compose:
      - FnCall: [simd_shuffle!, [a, a, "{type[1]}"]]

  - name: "vrshl{neon_type.no}"
    doc: "Signed rounding shift left"
    arguments: ["a: {neon_type}", "b: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vrshl]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [srshl]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - int8x8_t
      - int8x16_t
      - int16x4_t
      - int16x8_t
      - int32x2_t
      - int32x4_t
      - int64x1_t
      - int64x2_t
    compose:
      - LLVMLink:
          name: "vrshl{neon_type.no}"
          links:
            - link: "llvm.arm.neon.vrshifts.{neon_type}"
              arch: arm
            - link: "llvm.aarch64.neon.srshl.{neon_type}"
              arch: aarch64,arm64ec

  - name: "vrshl{neon_type[0].no}"
    doc: "Unsigned rounding shift left"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vrshl]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [urshl]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [uint8x8_t, int8x8_t]
      - [uint8x16_t, int8x16_t]
      - [uint16x4_t, int16x4_t]
      - [uint16x8_t, int16x8_t]
      - [uint32x2_t, int32x2_t]
      - [uint32x4_t, int32x4_t]
      - [uint64x1_t, int64x1_t]
      - [uint64x2_t, int64x2_t]
    compose:
      - LLVMLink:
          name: "vrshl{neon_type[0].no}"
          links:
            - link: "llvm.arm.neon.vrshiftu.{neon_type[0]}"
              arch: arm
            - link: "llvm.aarch64.neon.urshl.{neon_type[0]}"
              arch: aarch64,arm64ec

  - name: "vrshr{neon_type[0].N}"
    doc: "Signed rounding shift right"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vrshr, 'N = 2']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [srshr, 'N = 2']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [int8x8_t, 'N >= 1 && N <= 8']
      - [int8x16_t, 'N >= 1 && N <= 8']
      - [int16x4_t, 'N >= 1 && N <= 16']
      - [int16x8_t, 'N >= 1 && N <= 16']
      - [int32x2_t, 'N >= 1 && N <= 32']
      - [int32x4_t, 'N >= 1 && N <= 32']
      - [int64x1_t, 'N >= 1 && N <= 64']
      - [int64x2_t, 'N >= 1 && N <= 64']
    compose:
      - FnCall: [static_assert!, ["{type[1]}"]]
      - FnCall:
          - "vrshl{neon_type[0].no}"
          - - a
            - FnCall: ["vdup{neon_type[0].N}", ['-N as _']]

  - name: "vrshr{neon_type[0].N}"
    doc: "Unsigned rounding shift right"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vrshr, N = 2]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [urshr, 'N = 2']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [uint8x8_t, int8x8_t, 'N >= 1 && N <= 8']
      - [uint8x16_t, int8x16_t, 'N >= 1 && N <= 8']
      - [uint16x4_t, int16x4_t, 'N >= 1 && N <= 16']
      - [uint16x8_t, int16x8_t, 'N >= 1 && N <= 16']
      - [uint32x2_t, int32x2_t, 'N >= 1 && N <= 32']
      - [uint32x4_t, int32x4_t, 'N >= 1 && N <= 32']
      - [uint64x1_t, int64x1_t, 'N >= 1 && N <= 64']
      - [uint64x2_t, int64x2_t, 'N >= 1 && N <= 64']
    compose:
      - FnCall: [static_assert!, ["{type[2]}"]]
      - FnCall:
          - "vrshl{neon_type[0].no}"
          - - a
            - FnCall: ["vdup{neon_type[1].N}", ['-N as _']]

  - name: "vrshrn_n_{neon_type[0]}"
    doc: "Rounding shift right narrow"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *target-is-arm
      - *enable-v7
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [vrshrn, 'N = 2']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-arm-unstable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [int16x8_t, int8x8_t, 'N >= 1 && N <= 8', 'const { int16x8_t([-N as i16; 8]) }']
      - [int32x4_t, int16x4_t, 'N >= 1 && N <= 16', 'const { int32x4_t([-N; 4]) }']
      - [int64x2_t, int32x2_t, 'N >= 1 && N <= 32', 'const { int64x2_t([-N as i64; 2]) }']
    compose:
      - FnCall: [static_assert!, ["{type[2]}"]]
      - LLVMLink:
          name: "vrshrn_n_{neon_type[0]}"
          arguments:
            - "a: {neon_type[0]}"
            - "n: {neon_type[0]}"
          links:
            - link: "llvm.arm.neon.vrshiftn.{neon_type[1]}"
              arch: arm
      - FnCall: ["_vrshrn_n_{neon_type[0]}", [a, "{type[3]}"], [], true]

  - name: "vrshrn_n_{neon_type[0]}"
    doc: "Rounding shift right narrow"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - FnCall: [cfg, [{FnCall: [not, ['target_arch = "arm"']]}]]
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [rshrn, 'N = 2']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-stable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [int16x8_t, int8x8_t, 'N >= 1 && N <= 8']
      - [int32x4_t, int16x4_t, 'N >= 1 && N <= 16']
      - [int64x2_t, int32x2_t, 'N >= 1 && N <= 32']
    compose:
      - FnCall: [static_assert!, ["{type[2]}"]]
      - LLVMLink:
          name: "vrshrn_n_{neon_type[0]}"
          arguments:
            - "a: {neon_type[0]}"
            - "n: i32"
          links:
            - link: "llvm.aarch64.neon.rshrn.{neon_type[1]}"
              arch: aarch64,arm64ec
      - FnCall: ["_vrshrn_n_{neon_type[0]}", [a, N], [], true]

  - name: "vrshrn_n_{neon_type[0]}"
    doc: "Rounding shift right narrow"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vrshrn, N = 2]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [rshrn, 'N = 2']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [uint16x8_t, uint8x8_t, 'N >= 1 && N <= 8', s16]
      - [uint32x4_t, uint16x4_t, 'N >= 1 && N <= 16', s32]
      - [uint64x2_t, uint32x2_t, 'N >= 1 && N <= 32', s64]
    compose:
      - FnCall: [static_assert!, ["{type[2]}"]]
      - FnCall:
          - transmute
          - - FnCall:
                - "vrshrn_n_{type[3]}::<N>"
                - - FnCall: [transmute, [a]]

  - name: "vrsra{neon_type[0].N}"
    doc: "Signed rounding shift right and accumulate"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vrsra, 'N = 2']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [srsra, 'N = 2']]}]]
      - FnCall: [rustc_legacy_const_generics, ['2']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [int8x8_t, 'N >= 1 && N <= 8']
      - [int8x16_t, 'N >= 1 && N <= 8']
      - [int16x4_t, 'N >= 1 && N <= 16']
      - [int16x8_t, 'N >= 1 && N <= 16']
      - [int32x2_t, 'N >= 1 && N <= 32']
      - [int32x4_t, 'N >= 1 && N <= 32']
      - [int64x1_t, 'N >= 1 && N <= 64']
      - [int64x2_t, 'N >= 1 && N <= 64']
    compose:
      - FnCall: [static_assert!, ["{type[1]}"]]
      - FnCall:
          - simd_add
          - - a
            - FnCall: ["vrshr{neon_type[0].N}::<N>", [b]]

  - name: "vrsubhn_{neon_type[0]}"
    doc: "Rounding subtract returning high narrow"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[2]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vrsubhn]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [rsubhn]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [int16x8_t, int16x8_t, int8x8_t]
      - [int32x4_t, int32x4_t, int16x4_t]
      - [int64x2_t, int64x2_t, int32x2_t]
    compose:
      - LLVMLink:
          name: "vrsubhn_{neon_type[0]}"
          links:
            - link: "llvm.arm.neon.vrsubhn.{neon_type[2]}"
              arch: arm
            - link: "llvm.aarch64.neon.rsubhn.{neon_type[2]}"
              arch: aarch64,arm64ec

  - name: "vrsubhn_{neon_type[0]}"
    doc: "Rounding subtract returning high narrow"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[2]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vrsubhn]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [rsubhn]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [uint16x8_t, uint16x8_t, uint8x8_t, s16]
      - [uint32x4_t, uint32x4_t, uint16x4_t, s32]
      - [uint64x2_t, uint64x2_t, uint32x2_t, s64]
    compose:
      - FnCall:
          - transmute
          - - FnCall:
                - "vrsubhn_{type[3]}"
                - - FnCall: [transmute, [a]]
                  - FnCall: [transmute, [b]]

  - name: "vcreate_{neon_type[1]}"
    doc: "Insert vector element from another vector element"
    arguments: ["a: {type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [nop]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [nop]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - ["u64", int8x8_t]
      - ["u64", int16x4_t]
      - ["u64", int32x2_t]
      - ["u64", int64x1_t]
      - ["u64", uint8x8_t]
      - ["u64", uint16x4_t]
      - ["u64", uint32x2_t]
      - ["u64", uint64x1_t]
      - ["u64", poly8x8_t]
      - ["u64", poly16x4_t]
      - ["u64", float32x2_t]
    compose:
      - FnCall: [transmute, [a]]

  - name: "vcreate_{neon_type[1]}"
    doc: "Insert vector element from another vector element"
    arguments: ["a: {type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [nop]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [nop]]}]]
      - *arm-fp16
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    safety: safe
    types:
      - ["u64", float16x4_t]
    compose:
      - FnCall: [transmute, [a]]

  - name: "vcreate_p64"
    doc: "Insert vector element from another vector element"
    arguments: ["a: {type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-aes
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [nop]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [nop]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - ["u64", poly64x1_t]
    compose:
      - FnCall: [transmute, [a]]

  - name: "vset{neon_type[1].lane_nox}"
    doc: "Insert vector element from another vector element"
    arguments: ["a: {type[0]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [nop, LANE = 0]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [nop, 'LANE = 0']]}]]
      - FnCall: [rustc_legacy_const_generics, ['2']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const LANE: i32']
    safety: safe
    types:
      - ["i8", int8x8_t, '3']
      - ["i16", int16x4_t, '2']
      - ["i32", int32x2_t, '1']
      - ["u8", uint8x8_t, '3']
      - ["u16", uint16x4_t, '2']
      - ["u32", uint32x2_t, '1']
      - ["p8", poly8x8_t, '3']
      - ["p16", poly16x4_t, '2']
      - ["i8", int8x16_t, '4']
      - ["i16", int16x8_t, '3']
      - ["i32", int32x4_t, '2']
      - ["i64", int64x2_t, '1']
      - ["u8", uint8x16_t, '4']
      - ["u16", uint16x8_t, '3']
      - ["u32", uint32x4_t, '2']
      - ["u64", uint64x2_t, '1']
      - ["p8", poly8x16_t, '4']
      - ["p16", poly16x8_t, '3']
      - ["f32", float32x2_t, '1']
      - ["f32", float32x4_t, '2']
    compose:
      - FnCall: [static_assert_uimm_bits!, [LANE, "{type[2]}"]]
      - FnCall: [simd_insert!, [b, 'LANE as u32', a]]


  - name: "vset{neon_type[1].lane_nox}"
    doc: "Insert vector element from another vector element"
    arguments: ["a: {type[0]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [nop, LANE = 0]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [nop, 'LANE = 0']]}]]
      - FnCall: [rustc_legacy_const_generics, ['2']]
      - *neon-fp16
      - *neon-unstable-f16
      - *target-not-arm64ec
    static_defs: ['const LANE: i32']
    safety: safe
    types:
      - ["f16", float16x4_t, '2']
      - ["f16", float16x8_t, '3']
    compose:
      - FnCall: [static_assert_uimm_bits!, [LANE, "{type[2]}"]]
      - FnCall: [simd_insert!, [b, 'LANE as u32', a]]


  - name: "vset_lane_{neon_type[0]}"
    doc: "Insert vector element from another vector element"
    arguments: ["a: {type[0]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [nop, 'LANE = 0']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [nop, 'LANE = 0']]}]]
      - FnCall: [rustc_legacy_const_generics, ['2']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const LANE: i32']
    safety: safe
    types:
      - ["i64", int64x1_t, int64x1_t]
      - ["u64", uint64x1_t, uint64x1_t]
    compose:
      - FnCall: [static_assert!, ['LANE == 0']]
      - FnCall: [simd_insert!, [b, 'LANE as u32', a]]

  - name: "vset_lane_{neon_type[0]}"
    doc: "Insert vector element from another vector element"
    arguments: ["a: {type[0]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-aes
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [nop, 'LANE = 0']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [nop, 'LANE = 0']]}]]
      - FnCall: [rustc_legacy_const_generics, ['2']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const LANE: i32']
    safety: safe
    types:
      - ["p64", poly64x1_t, poly64x1_t]
    compose:
      - FnCall: [static_assert!, ['LANE == 0']]
      - FnCall: [simd_insert!, [b, 'LANE as u32', a]]

  - name: "vsetq_lane_p64"
    doc: "Insert vector element from another vector element"
    arguments: ["a: {type[0]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-aes
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [nop, 'LANE = 0']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [nop, 'LANE = 0']]}]]
      - FnCall: [rustc_legacy_const_generics, ['2']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const LANE: i32']
    safety: safe
    types:
      - ["p64", poly64x2_t, poly64x2_t]
    compose:
      - FnCall: [static_assert_uimm_bits!, [LANE, '1']]
      - FnCall: [simd_insert!, [b, 'LANE as u32', a]]

  - name: "vshl{neon_type.no}"
    doc: "Signed Shift left"
    arguments: ["a: {neon_type}", "b: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vshl]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [sshl]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - int8x8_t
      - int8x16_t
      - int16x4_t
      - int16x8_t
      - int32x2_t
      - int32x4_t
      - int64x1_t
      - int64x2_t
    compose:
      - LLVMLink:
          name: "vshl{neon_type.no}"
          links:
            - link: "llvm.arm.neon.vshifts.{neon_type}"
              arch: arm
            - link: "llvm.aarch64.neon.sshl.{neon_type}"
              arch: aarch64,arm64ec

  - name: "vshl{neon_type[0].no}"
    doc: "Unsigned Shift left"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vshl]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ushl]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [uint8x8_t, int8x8_t]
      - [uint8x16_t, int8x16_t]
      - [uint16x4_t, int16x4_t]
      - [uint16x8_t, int16x8_t]
      - [uint32x2_t, int32x2_t]
      - [uint32x4_t, int32x4_t]
      - [uint64x1_t, int64x1_t]
      - [uint64x2_t, int64x2_t]
    compose:
      - LLVMLink:
          name: "vshl{neon_type[0].no}"
          links:
            - link: "llvm.arm.neon.vshiftu.{neon_type[1]}"
              arch: arm
            - link: "llvm.aarch64.neon.ushl.{neon_type[1]}"
              arch: aarch64,arm64ec

  - name: "vshll_n_s8"
    doc: "Signed shift left long"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vshll.s8"', 'N = 2']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [sshll, 'N = 2']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [int8x8_t, int16x8_t, 'N >= 0 && N <= 8']
    compose:
      - FnCall: [static_assert!, ["{type[2]}"]]
      - FnCall:
          - simd_shl
          - - FnCall: [simd_cast, [a]]
            - FnCall: [vdupq_n_s16, ['N as _']]

  - name: "vshll_n_s16"
    doc: "Signed shift left long"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vshll.s16"', 'N = 2']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [sshll, 'N = 2']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [int16x4_t, int32x4_t]
    compose:
      - FnCall: [static_assert!, ["N >= 0 && N <= 16"]]
      - FnCall:
          - simd_shl
          - - FnCall: [simd_cast, [a]]
            - FnCall: [vdupq_n_s32, ['N as _']]

  - name: "vshll_n_s32"
    doc: "Signed shift left long"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vshll.s32"', 'N = 2']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [sshll, 'N = 2']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [int32x2_t, int64x2_t]
    compose:
      - FnCall: [static_assert!, ["N >= 0 && N <= 32"]]
      - FnCall:
          - simd_shl
          - - FnCall: [simd_cast, [a]]
            - FnCall: [vdupq_n_s64, ['N as _']]

  - name: "vshll_n_u8"
    doc: "Signed shift left long"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vshll.u8"', 'N = 2']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ushll, 'N = 2']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [uint8x8_t, uint16x8_t]
    compose:
      - FnCall: [static_assert!, ["N >= 0 && N <= 8"]]
      - FnCall:
          - simd_shl
          - - FnCall: [simd_cast, [a]]
            - FnCall: [vdupq_n_u16, ['N as _']]

  - name: "vshll_n_u16"
    doc: "Signed shift left long"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vshll.u16"', 'N = 2']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ushll, 'N = 2']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [uint16x4_t, uint32x4_t]
    compose:
      - FnCall: [static_assert!, ["N >= 0 && N <= 16"]]
      - FnCall:
          - simd_shl
          - - FnCall: [simd_cast, [a]]
            - FnCall: [vdupq_n_u32, ['N as _']]

  - name: "vshll_n_u32"
    doc: "Signed shift left long"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vshll.u32"', 'N = 2']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ushll, 'N = 2']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [uint32x2_t, uint64x2_t]
    compose:
      - FnCall: [static_assert!, ["N >= 0 && N <= 32"]]
      - FnCall:
          - simd_shl
          - - FnCall: [simd_cast, [a]]
            - FnCall: [vdupq_n_u64, ['N as _']]

  - name: "vshr{neon_type[0].N}"
    doc: "Shift right"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vshr.{neon_type[0]}"', 'N = 2']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [sshr, 'N = 2']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [int8x8_t, 'N >= 1 && N <= 8', 'let n: i32 = if N == 8 { 7 }', 'else { N };']
      - [int8x16_t, 'N >= 1 && N <= 8', 'let n: i32 = if N == 8 { 7 }', 'else { N };']
      - [int16x4_t, 'N >= 1 && N <= 16', 'let n: i32 = if N == 16 { 15 }', 'else { N };']
      - [int16x8_t, 'N >= 1 && N <= 16', 'let n: i32 = if N == 16 { 15 }', 'else { N };']
      - [int32x2_t, 'N >= 1 && N <= 32', 'let n: i32 = if N == 32 { 31 }', 'else { N };']
      - [int32x4_t, 'N >= 1 && N <= 32', 'let n: i32 = if N == 32 { 31 }', 'else { N };']
      - [int64x1_t, 'N >= 1 && N <= 64', 'let n: i32 = if N == 64 { 63 }', 'else { N };']
      - [int64x2_t, 'N >= 1 && N <= 64', 'let n: i32 = if N == 64 { 63 }', 'else { N };']
    compose:
      - FnCall: [static_assert!, ["{type[1]}"]]
      - Identifier: ["{type[2]}{type[3]}", Symbol]
      - FnCall:
          - simd_shr
          - - a
            - FnCall: ["vdup{neon_type[0].N}", ['n as _']]

  - name: "vshr{neon_type[0].N}"
    doc: "Shift right"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vshr.{neon_type[0]}"', 'N = 2']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ushr, 'N = 2']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [uint8x8_t, 'N >= 1 && N <= 8', 'let n: i32 = if N == 8 { return vdup_n_u8(0);    }', 'else { N };']
      - [uint8x16_t, 'N >= 1 && N <= 8', 'let n: i32 = if N == 8 { return vdupq_n_u8(0);   }', 'else { N };']
      - [uint16x4_t, 'N >= 1 && N <= 16', 'let n: i32 = if N == 16 { return vdup_n_u16(0);  }', 'else { N };']
      - [uint16x8_t, 'N >= 1 && N <= 16', 'let n: i32 = if N == 16 { return vdupq_n_u16(0); }', 'else { N };']
      - [uint32x2_t, 'N >= 1 && N <= 32', 'let n: i32 = if N == 32 { return vdup_n_u32(0);  }', 'else { N };']
      - [uint32x4_t, 'N >= 1 && N <= 32', 'let n: i32 = if N == 32 { return vdupq_n_u32(0); }', 'else { N };']
      - [uint64x1_t, 'N >= 1 && N <= 64', 'let n: i32 = if N == 64 { return vdup_n_u64(0);  }', 'else { N };']
      - [uint64x2_t, 'N >= 1 && N <= 64', 'let n: i32 = if N == 64 { return vdupq_n_u64(0); }', 'else { N };']
    compose:
      - FnCall: [static_assert!, ["{type[1]}"]]
      - Identifier: ['{type[2]}{type[3]}', Symbol]
      - FnCall:
          - simd_shr
          - - a
            - FnCall: ["vdup{neon_type[0].N}", ['n as _']]

  - name: "vshrn_n_{neon_type[0]}"
    doc: "Shift right narrow"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vshrn{type[2]}"', 'N = 2']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [shrn, 'N = 2']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [int16x8_t, int8x8_t, '.i16', 'N >= 1 && N <= 8']
      - [uint16x8_t, uint8x8_t, '.i16', 'N >= 1 && N <= 8']
      - [int32x4_t, int16x4_t, '.i32', 'N >= 1 && N <= 16']
      - [uint32x4_t, uint16x4_t, '.i32', 'N >= 1 && N <= 16']
      - [int64x2_t, int32x2_t, '.i64', 'N >= 1 && N <= 32']
      - [uint64x2_t, uint32x2_t, '.i64', 'N >= 1 && N <= 32']
    compose:
      - FnCall: [static_assert!, ["{type[3]}"]]
      - FnCall:
          - simd_cast
          - - FnCall:
                - simd_shr
                - - a
                  - FnCall: ["vdupq_n_{neon_type[0]}", ['N as _']]

  - name: "vsra{neon_type[0].N}"
    doc: "Signed shift right and accumulate"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vsra, 'N = 2']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ssra, 'N = 2']]}]]
      - FnCall: [rustc_legacy_const_generics, ['2']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [int8x8_t, 'N >= 1 && N <= 8']
      - [int8x16_t, 'N >= 1 && N <= 8']
      - [int16x4_t, 'N >= 1 && N <= 16']
      - [int16x8_t, 'N >= 1 && N <= 16']
      - [int32x2_t, 'N >= 1 && N <= 32']
      - [int32x4_t, 'N >= 1 && N <= 32']
      - [int64x1_t, 'N >= 1 && N <= 64']
      - [int64x2_t, 'N >= 1 && N <= 64']
    compose:
      - FnCall: [static_assert!, ["{type[1]}"]]
      - FnCall:
          - simd_add
          - - a
            - FnCall: ["vshr{neon_type[0].N}::<N>", [b]]

  - name: "vtrn{neon_type[0].no}"
    doc: "Transpose elements"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vtrn]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [trn1]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [trn2]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [int8x8_t, int8x8x2_t, '[0, 8, 2, 10, 4, 12, 6, 14]', '[1, 9, 3, 11, 5, 13, 7, 15]']
      - [int16x4_t, int16x4x2_t, '[0, 4, 2, 6]', '[1, 5, 3, 7]']
      - [int8x16_t, int8x16x2_t, '[0, 16, 2, 18, 4, 20, 6, 22, 8, 24, 10, 26, 12, 28, 14, 30]', '[1, 17, 3, 19, 5, 21, 7, 23, 9, 25, 11, 27, 13, 29, 15, 31]']
      - [int16x8_t, int16x8x2_t, '[0, 8, 2, 10, 4, 12, 6, 14]', '[1, 9, 3, 11, 5, 13, 7, 15]']
      - [int32x4_t, int32x4x2_t, '[0, 4, 2, 6]', '[1, 5, 3, 7]']
      - [uint8x8_t, uint8x8x2_t, '[0, 8, 2, 10, 4, 12, 6, 14]', '[1, 9, 3, 11, 5, 13, 7, 15]']
      - [uint16x4_t, uint16x4x2_t, '[0, 4, 2, 6]', '[1, 5, 3, 7]']
      - [uint8x16_t, uint8x16x2_t, '[0, 16, 2, 18, 4, 20, 6, 22, 8, 24, 10, 26, 12, 28, 14, 30]', '[1, 17, 3, 19, 5, 21, 7, 23, 9, 25, 11, 27, 13, 29, 15, 31]']
      - [uint16x8_t, uint16x8x2_t, '[0, 8, 2, 10, 4, 12, 6, 14]', '[1, 9, 3, 11, 5, 13, 7, 15]']
      - [uint32x4_t, uint32x4x2_t, '[0, 4, 2, 6]', '[1, 5, 3, 7]']
      - [poly8x8_t, poly8x8x2_t, '[0, 8, 2, 10, 4, 12, 6, 14]', '[1, 9, 3, 11, 5, 13, 7, 15]']
      - [poly16x4_t, poly16x4x2_t, '[0, 4, 2, 6]', '[1, 5, 3, 7]']
      - [poly8x16_t, poly8x16x2_t, '[0, 16, 2, 18, 4, 20, 6, 22, 8, 24, 10, 26, 12, 28, 14, 30]', '[1, 17, 3, 19, 5, 21, 7, 23, 9, 25, 11, 27, 13, 29, 15, 31]']
      - [poly16x8_t, poly16x8x2_t, '[0, 8, 2, 10, 4, 12, 6, 14]', '[1, 9, 3, 11, 5, 13, 7, 15]']
      - [float32x4_t, float32x4x2_t, '[0, 4, 2, 6]', '[1, 5, 3, 7]']
    compose:
      - Let:
          - a1
          - "{neon_type[0]}"
          - FnCall: [simd_shuffle!, [a, b, "{type[2]}"]]
      - Let:
          - b1
          - "{neon_type[0]}"
          - FnCall: [simd_shuffle!, [a, b, "{type[3]}"]]
      - FnCall:
          - transmute
          - - Identifier: ['(a1, b1)', Symbol]


  - name: "vtrn{neon_type[0].no}"
    doc: "Transpose elements"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vtrn]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [trn1]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [trn2]]}]]
      - *neon-fp16
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    safety: safe
    types:
      - [float16x4_t, float16x4x2_t, '[0, 4, 2, 6]', '[1, 5, 3, 7]']
      - [float16x8_t, float16x8x2_t, '[0, 8, 2, 10, 4, 12, 6, 14]', '[1, 9, 3, 11, 5, 13, 7, 15]']
    compose:
      - Let:
          - a1
          - "{neon_type[0]}"
          - FnCall: [simd_shuffle!, [a, b, "{type[2]}"]]
      - Let:
          - b1
          - "{neon_type[0]}"
          - FnCall: [simd_shuffle!, [a, b, "{type[3]}"]]
      - FnCall:
          - transmute
          - - Identifier: ['(a1, b1)', Symbol]


  - name: "vtrn{neon_type[0].no}"
    doc: "Transpose elements"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vtrn]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [zip1]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [zip2]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [int32x2_t, int32x2x2_t, '[0, 2]', '[1, 3]']
      - [uint32x2_t, uint32x2x2_t, '[0, 2]', '[1, 3]']
      - [float32x2_t, float32x2x2_t, '[0, 2]', '[1, 3]']
    compose:
      - Let:
          - a1
          - "{neon_type[0]}"
          - FnCall: [simd_shuffle!, [a, b, "{type[2]}"]]
      - Let:
          - b1
          - "{neon_type[0]}"
          - FnCall: [simd_shuffle!, [a, b, "{type[3]}"]]
      - FnCall:
          - transmute
          - - Identifier: ['(a1, b1)', Symbol]

  - name: "vzip{neon_type[0].no}"
    doc: Zip vectors
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vorr]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [zip1]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [zip2]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [int8x16_t, int8x16x2_t, '[0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23]', '[8, 24, 9, 25, 10, 26, 11, 27, 12, 28, 13, 29, 14, 30, 15, 31]']
      - [int16x8_t, int16x8x2_t, '[0, 8, 1, 9, 2, 10, 3, 11]', '[4, 12, 5, 13, 6, 14, 7, 15]']
      - [int32x4_t, int32x4x2_t, '[0, 4, 1, 5]', '[2, 6, 3, 7]']
      - [uint8x16_t, uint8x16x2_t, '[0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23]', '[8, 24, 9, 25, 10, 26, 11, 27, 12, 28, 13, 29, 14, 30, 15, 31]']
      - [uint16x8_t, uint16x8x2_t, '[0, 8, 1, 9, 2, 10, 3, 11]', '[4, 12, 5, 13, 6, 14, 7, 15]']
      - [uint32x4_t, uint32x4x2_t, '[0, 4, 1, 5]', '[2, 6, 3, 7]']
      - [poly8x16_t, poly8x16x2_t, '[0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23]', '[8, 24, 9, 25, 10, 26, 11, 27, 12, 28, 13, 29, 14, 30, 15, 31]']
      - [poly16x8_t, poly16x8x2_t, '[0, 8, 1, 9, 2, 10, 3, 11]', '[4, 12, 5, 13, 6, 14, 7, 15]']
      - [float32x4_t, float32x4x2_t, '[0, 4, 1, 5]', '[2, 6, 3, 7]']
    compose:
      - Let:
          - a0
          - "{neon_type[0]}"
          - FnCall: ["simd_shuffle!", [a, b, "{type[2]}"]]
      - Let:
          - b0
          - "{neon_type[0]}"
          - FnCall: ["simd_shuffle!", [a, b, "{type[3]}"]]
      - FnCall:
          - transmute
          - - '(a0, b0)'

  - name: "vzip{neon_type[0].no}"
    doc: Zip vectors
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vtrn]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [zip1]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [zip2]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [int32x2_t, int32x2x2_t, '[0, 2]', '[1, 3]']
      - [uint32x2_t, uint32x2x2_t, '[0, 2]', '[1, 3]']
      - [float32x2_t, float32x2x2_t, '[0, 2]', '[1, 3]']
    compose:
      - Let:
          - a0
          - "{neon_type[0]}"
          - FnCall: ["simd_shuffle!", [a, b, "{type[2]}"]]
      - Let:
          - b0
          - "{neon_type[0]}"
          - FnCall: ["simd_shuffle!", [a, b, "{type[3]}"]]
      - FnCall:
          - transmute
          - - '(a0, b0)'

  - name: "vzip{neon_type[0].no}"
    doc: Zip vectors
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vzip]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [zip1]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [zip2]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [int8x8_t, int8x8x2_t, '[0, 8, 1, 9, 2, 10, 3, 11]', '[4, 12, 5, 13, 6, 14, 7, 15]']
      - [int16x4_t, int16x4x2_t, '[0, 4, 1, 5]', '[2, 6, 3, 7]']
      - [uint8x8_t, uint8x8x2_t, '[0, 8, 1, 9, 2, 10, 3, 11]', '[4, 12, 5, 13, 6, 14, 7, 15]']
      - [uint16x4_t, uint16x4x2_t, '[0, 4, 1, 5]', '[2, 6, 3, 7]']
      - [poly8x8_t, poly8x8x2_t, '[0, 8, 1, 9, 2, 10, 3, 11]', '[4, 12, 5, 13, 6, 14, 7, 15]']
      - [poly16x4_t, poly16x4x2_t, '[0, 4, 1, 5]', '[2, 6, 3, 7]']
    compose:
      - Let:
          - a0
          - "{neon_type[0]}"
          - FnCall: ["simd_shuffle!", [a, b, "{type[2]}"]]
      - Let:
          - b0
          - "{neon_type[0]}"
          - FnCall: ["simd_shuffle!", [a, b, "{type[3]}"]]
      - FnCall:
          - transmute
          - - '(a0, b0)'


  - name: "vzip{neon_type[0].no}"
    doc: Zip vectors
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vzip.16"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [zip1]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [zip2]]}]]
      - *neon-fp16
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    safety: safe
    types:
      - [float16x4_t, float16x4x2_t, '[0, 4, 1, 5]', '[2, 6, 3, 7]']
      - [float16x8_t, float16x8x2_t, '[0, 8, 1, 9, 2, 10, 3, 11]', '[4, 12, 5, 13, 6, 14, 7, 15]']
    compose:
      - Let:
          - a0
          - "{neon_type[0]}"
          - FnCall: ["simd_shuffle!", [a, b, "{type[2]}"]]
      - Let:
          - b0
          - "{neon_type[0]}"
          - FnCall: ["simd_shuffle!", [a, b, "{type[3]}"]]
      - FnCall:
          - transmute
          - - '(a0, b0)'

  - name: "vuzp{neon_type[0].no}"
    doc: Unzip vectors
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vuzp]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [uzp1]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [uzp2]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [int8x8_t, int8x8x2_t, '[0, 2, 4, 6, 8, 10, 12, 14]', '[1, 3, 5, 7, 9, 11, 13, 15]']
      - [int16x4_t, int16x4x2_t, '[0, 2, 4, 6]', '[1, 3, 5, 7]']
      - [int8x16_t, int8x16x2_t, '[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30]', '[1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31]']
      - [int16x8_t, int16x8x2_t, '[0, 2, 4, 6, 8, 10, 12, 14]', '[1, 3, 5, 7, 9, 11, 13, 15]']
      - [int32x4_t, int32x4x2_t, '[0, 2, 4, 6]', '[1, 3, 5, 7]']
      - [uint8x8_t, uint8x8x2_t, '[0, 2, 4, 6, 8, 10, 12, 14]', '[1, 3, 5, 7, 9, 11, 13, 15]']
      - [uint16x4_t, uint16x4x2_t, '[0, 2, 4, 6]', '[1, 3, 5, 7]']
      - [uint8x16_t, uint8x16x2_t, '[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30]', '[1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31]']
      - [uint16x8_t, uint16x8x2_t, '[0, 2, 4, 6, 8, 10, 12, 14]', '[1, 3, 5, 7, 9, 11, 13, 15]']
      - [uint32x4_t, uint32x4x2_t, '[0, 2, 4, 6]', '[1, 3, 5, 7]']
      - [poly8x8_t, poly8x8x2_t, '[0, 2, 4, 6, 8, 10, 12, 14]', '[1, 3, 5, 7, 9, 11, 13, 15]']
      - [poly16x4_t, poly16x4x2_t, '[0, 2, 4, 6]', '[1, 3, 5, 7]']
      - [poly8x16_t, poly8x16x2_t, '[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30]', '[1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31]']
      - [poly16x8_t, poly16x8x2_t, '[0, 2, 4, 6, 8, 10, 12, 14]', '[1, 3, 5, 7, 9, 11, 13, 15]']
      - [float32x4_t, float32x4x2_t, '[0, 2, 4, 6]', '[1, 3, 5, 7]']
    compose:
      - Let:
          - a0
          - "{neon_type[0]}"
          - FnCall: ["simd_shuffle!", [a, b, "{type[2]}"]]
      - Let:
          - b0
          - "{neon_type[0]}"
          - FnCall: ["simd_shuffle!", [a, b, "{type[3]}"]]
      - FnCall:
          - transmute
          - - '(a0, b0)'


  - name: "vuzp{neon_type[0].no}"
    doc: Unzip vectors
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vuzp]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [uzp1]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [uzp2]]}]]
      - *neon-fp16
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    safety: safe
    types:
      - [float16x4_t, float16x4x2_t, '[0, 2, 4, 6]', '[1, 3, 5, 7]']
      - [float16x8_t, float16x8x2_t, '[0, 2, 4, 6, 8, 10, 12, 14]', '[1, 3, 5, 7, 9, 11, 13, 15]']
    compose:
      - Let:
          - a0
          - "{neon_type[0]}"
          - FnCall: ["simd_shuffle!", [a, b, "{type[2]}"]]
      - Let:
          - b0
          - "{neon_type[0]}"
          - FnCall: ["simd_shuffle!", [a, b, "{type[3]}"]]
      - FnCall:
          - transmute
          - - '(a0, b0)'


  - name: "vuzp{neon_type[0].no}"
    doc: Unzip vectors
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vtrn]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [zip1]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [zip2]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [float32x2_t, float32x2x2_t, '[0, 2]', '[1, 3]']
      - [int32x2_t, int32x2x2_t, '[0, 2]', '[1, 3]']
      - [uint32x2_t, uint32x2x2_t, '[0, 2]', '[1, 3]']
    compose:
      - Let:
          - a0
          - "{neon_type[0]}"
          - FnCall: ["simd_shuffle!", [a, b, "{type[2]}"]]
      - Let:
          - b0
          - "{neon_type[0]}"
          - FnCall: ["simd_shuffle!", [a, b, "{type[3]}"]]
      - FnCall:
          - transmute
          - - '(a0, b0)'

  - name: "vabal_{neon_type[1]}"
    doc: "Unsigned Absolute difference and Accumulate Long"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}", "c: {neon_type[1]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vabal.{type[2]}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [uabal]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [uint16x8_t, uint8x8_t, "u8"]
      - [uint32x4_t, uint16x4_t, "u16"]
      - [uint64x2_t, uint32x2_t, "u32"]
    compose:
      - Let: [d, "{neon_type[1]}", {FnCall: ["vabd_{type[2]}", [b, c]]}]
      - FnCall: [simd_add, [a, {FnCall: [simd_cast, [d]]}]]

  - name: "vabal_{neon_type[1]}"
    doc: "Signed Absolute difference and Accumulate Long"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}", "c: {neon_type[1]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vabal.{neon_type[1]}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [sabal]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [int16x8_t, int8x8_t, uint8x8_t]
      - [int32x4_t, int16x4_t, uint16x4_t]
      - [int64x2_t, int32x2_t, uint32x2_t]
    compose:
      - Let: [d, "{type[1]}", {FnCall: ["vabd_{neon_type[1]}", [b, c]]}]
      - Let: [e, "{type[2]}", {FnCall: ["simd_cast", [d]]}]
      - FnCall: [simd_add, [a, {FnCall: [simd_cast, [e]]}]]

  - name: "vqabs{neon_type.no}"
    doc: Signed saturating Absolute value
    arguments: ["a: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vqabs.{neon_type}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [sqabs]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - int8x8_t
      - int8x16_t
      - int16x4_t
      - int16x8_t
      - int32x2_t
      - int32x4_t
    compose:
      - LLVMLink:
          name: "sqabs.{neon_type}"
          links:
            - link: "llvm.aarch64.neon.sqabs.{neon_type}"
              arch: aarch64,arm64ec
            - link: "llvm.arm.neon.vqabs.{neon_type}"
              arch: arm

  - name: "vst1{neon_type[1].no}"
    doc: "Store multiple single-element structures to one, two, three, or four registers"
    arguments: ["a: {type[0]}", "b: {neon_type[1]}"]
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vst1]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [st1]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety:
      unsafe: [neon]
    types:
      - ["*mut u8", uint8x8x2_t, int8x8x2_t]
      - ["*mut u16", uint16x4x2_t, int16x4x2_t]
      - ["*mut u32", uint32x2x2_t, int32x2x2_t]
      - ["*mut u64", uint64x1x2_t, int64x1x2_t]
      - ["*mut u8", uint8x16x2_t, int8x16x2_t]
      - ["*mut u16", uint16x8x2_t, int16x8x2_t]
      - ["*mut u32", uint32x4x2_t, int32x4x2_t]
      - ["*mut u64", uint64x2x2_t, int64x2x2_t]
      - ["*mut u8", uint8x8x3_t, int8x8x3_t]
      - ["*mut u16", uint16x4x3_t, int16x4x3_t]
      - ["*mut u32", uint32x2x3_t, int32x2x3_t]
      - ["*mut u64", uint64x1x3_t, int64x1x3_t]
      - ["*mut u8", uint8x16x3_t, int8x16x3_t]
      - ["*mut u16", uint16x8x3_t, int16x8x3_t]
      - ["*mut u32", uint32x4x3_t, int32x4x3_t]
      - ["*mut u64", uint64x2x3_t, int64x2x3_t]
      - ["*mut u8", uint8x8x4_t, int8x8x4_t]
      - ["*mut u16", uint16x4x4_t, int16x4x4_t]
      - ["*mut u32", uint32x2x4_t, int32x2x4_t]
      - ["*mut u64", uint64x1x4_t, int64x1x4_t]
      - ["*mut u8", uint8x16x4_t, int8x16x4_t]
      - ["*mut u16", uint16x8x4_t, int16x8x4_t]
      - ["*mut u32", uint32x4x4_t, int32x4x4_t]
      - ["*mut u64", uint64x2x4_t, int64x2x4_t]
      - ["*mut p8", poly8x8x2_t, int8x8x2_t]
      - ["*mut p8", poly8x8x3_t, int8x8x3_t]
      - ["*mut p8", poly8x8x4_t, int8x8x4_t]
      - ["*mut p8", poly8x16x2_t, int8x16x2_t]
      - ["*mut p8", poly8x16x3_t, int8x16x3_t]
      - ["*mut p8", poly8x16x4_t, int8x16x4_t]
      - ["*mut p16", poly16x4x2_t, int16x4x2_t]
      - ["*mut p16", poly16x4x3_t, int16x4x3_t]
      - ["*mut p16", poly16x4x4_t, int16x4x4_t]
      - ["*mut p16", poly16x8x2_t, int16x8x2_t]
      - ["*mut p16", poly16x8x3_t, int16x8x3_t]
      - ["*mut p16", poly16x8x4_t, int16x8x4_t]
    compose:
      - FnCall:
          - "vst1{neon_type[2].no}"
          - - FnCall: [transmute, [a]]
            - FnCall: [transmute, [b]]

  - name: "vst1{neon_type[1].no}"
    doc: "Store multiple single-element structures to one, two, three, or four registers"
    arguments: ["a: {type[0]}", "b: {neon_type[1]}"]
    attr:
      - *neon-aes
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vst1]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [st1]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety:
      unsafe: [neon]
    types:
      - ["*mut p64", poly64x1x2_t, int64x1x2_t]
    compose:
      - FnCall:
          - "vst1{neon_type[2].no}"
          - - FnCall: [transmute, [a]]
            - FnCall: [transmute, [b]]

  - name: "vst1{neon_type[1].no}"
    doc: "Store multiple single-element structures to one, two, three, or four registers"
    arguments: ["a: {type[0]}", "b: {neon_type[1]}"]
    attr:
      - *neon-aes
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [nop]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [st1]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety:
      unsafe: [neon]
    types:
      - ["*mut p64", poly64x1x3_t, int64x1x3_t]
      - ["*mut p64", poly64x1x4_t, int64x1x4_t]
      - ["*mut p64", poly64x2x2_t, int64x2x2_t]
      - ["*mut p64", poly64x2x3_t, int64x2x3_t]
      - ["*mut p64", poly64x2x4_t, int64x2x4_t]
    compose:
      - FnCall:
          - "vst1{neon_type[2].no}"
          - - FnCall: [transmute, [a]]
            - FnCall: [transmute, [b]]

  - name: "vst1{neon_type[1].no}"
    doc: "Store multiple single-element structures to one, two, three, or four registers"
    arguments: ["a: {type[0]}", "b: {neon_type[1]}"]
    attr:
      - *target-is-arm
      - *enable-v7
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [vst1]]}]]
      - *neon-arm-unstable
    safety:
      unsafe: [neon]
    types:
      - ['*mut f32', float32x2x2_t, float32x2_t]
      - ['*mut f32', float32x4x2_t, float32x4_t]
    compose:
      - LLVMLink:
          name: "vst1{neon_type[1].no}"
          arguments:
            - "ptr: {type[0]}"
            - "a: {neon_type[2]}"
            - "b: {neon_type[2]}"
          links:
            - link: "llvm.arm.neon.vst1x{neon_type[1].tuple}.{neon_type[2]}.p0"
              arch: arm
      - FnCall: ["_vst1{neon_type[1].no}", ['a', 'b.0', 'b.1']]


    # vst1_f16_x2 - arm
  - name: "vst1{neon_type[1].no}"
    doc: "Store multiple single-element structures to one, two, three, or four registers"
    arguments: ["a: {type[0]}", "b: {neon_type[1]}"]
    attr:
      - *target-is-arm
      - *neon-v7
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [vst1]]}]]
      - *neon-fp16
      - *neon-unstable-f16
      - *target-not-arm64ec
    safety:
      unsafe: [neon]
    types:
      - ['*mut f16', float16x4x2_t, float16x4_t]
      - ['*mut f16', float16x8x2_t, float16x8_t]
    compose:
      - LLVMLink:
          name: "vst1{neon_type[1].no}"
          arguments:
            - "ptr: {type[0]}"
            - "a: {neon_type[2]}"
            - "b: {neon_type[2]}"
          links:
            - link: "llvm.arm.neon.vst1x{neon_type[1].tuple}.p0.{neon_type[2]}"
              arch: arm
      - FnCall: ["_vst1{neon_type[1].no}", ['a', 'b.0', 'b.1']]


    # vst1_f16_x2 - aarch64
  - name: "vst1{neon_type[1].no}"
    doc: "Store multiple single-element structures to one, two, three, or four registers"
    arguments: ["a: {type[0]}", "b: {neon_type[1]}"]
    attr:
      - FnCall: [cfg, [{FnCall: [not, ['target_arch = "arm"']]}]]
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [st1]]}]]
      - *neon-fp16
      - *neon-unstable-f16
      - *target-not-arm64ec
    safety:
      unsafe: [neon]
    types:
      - ["*mut f16", float16x4x2_t, float16x4_t]
      - ["*mut f16", float16x8x2_t, float16x8_t]
    compose:
      - LLVMLink:
          name: "vst1{neon_type[1].no}"
          arguments:
            - "a: {neon_type[2]}"
            - "b: {neon_type[2]}"
            - "ptr: {type[0]}"
          links:
            - link: "llvm.aarch64.neon.st1x2.{neon_type[2]}.p0"
              arch: aarch64,arm64ec
      - FnCall: ["_vst1{neon_type[1].no}", ['b.0', 'b.1', a]]

  - name: "vst1{neon_type[1].no}"
    doc: "Store multiple single-element structures to one, two, three, or four registers"
    arguments: ["a: {type[0]}", "b: {neon_type[1]}"]
    attr:
      - *target-is-arm
      - *neon-v7
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [vst1]]}]]
      - *neon-fp16
      - *neon-unstable-f16
      - *target-not-arm64ec
    safety:
      unsafe: [neon]
    types:
      - ['*mut f16', float16x4x3_t, float16x4_t]
      - ['*mut f16', float16x8x3_t, float16x8_t]
    compose:
      - LLVMLink:
          name: "vst1{neon_type[1].no}"
          arguments:
            - "ptr: {type[0]}"
            - "a: {neon_type[2]}"
            - "b: {neon_type[2]}"
            - "c: {neon_type[2]}"
          links:
            - link: "llvm.arm.neon.vst1x{neon_type[1].tuple}.p0.{neon_type[2]}"
              arch: arm
      - FnCall: ["_vst1{neon_type[1].no}", ['a', 'b.0', 'b.1', 'b.2']]

  - name: "vst1{neon_type[1].no}"
    doc: "Store multiple single-element structures to one, two, three, or four registers"
    arguments: ["a: {type[0]}", "b: {neon_type[1]}"]
    attr:
      - FnCall: [cfg, [{FnCall: [not, ['target_arch = "arm"']]}]]
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [st1]]}]]
      - *neon-stable
    safety:
      unsafe: [neon]
    types:
      - ["*mut f32", float32x2x2_t, float32x2_t]
      - ["*mut f32", float32x4x2_t, float32x4_t]
    compose:
      - LLVMLink:
          name: "vst1{neon_type[1].no}"
          arguments:
            - "a: {neon_type[2]}"
            - "b: {neon_type[2]}"
            - "ptr: {type[0]}"
          links:
            - link: "llvm.aarch64.neon.st1x2.{neon_type[2]}.p0"
              arch: aarch64,arm64ec
      - FnCall: ["_vst1{neon_type[1].no}", ['b.0', 'b.1', a]]

  - name: "vst1{neon_type[1].no}"
    doc: "Store multiple single-element structures to one, two, three, or four registers"
    arguments: ["a: {type[0]}", "b: {neon_type[1]}"]
    attr:
      - FnCall: [cfg, [{FnCall: [not, ['target_arch = "arm"']]}]]
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [st1]]}]]
      - *neon-stable
    safety:
      unsafe: [neon]
    types:
      - ["*mut f32", float32x2x3_t, float32x2_t]
      - ["*mut f32", float32x4x3_t, float32x4_t]
    compose:
      - LLVMLink:
          name: "vst1{neon_type[1].no}"
          arguments:
            - "a: {neon_type[2]}"
            - "b: {neon_type[2]}"
            - "c: {neon_type[2]}"
            - "ptr: {type[0]}"
          links:
            - link: "llvm.aarch64.neon.st1x3.{neon_type[2]}.p0"
              arch: aarch64,arm64ec
      - FnCall: ["_vst1{neon_type[1].no}", ['b.0', 'b.1', 'b.2', a]]


  - name: "vst1{neon_type[1].no}"
    doc: "Store multiple single-element structures to one, two, three, or four registers"
    arguments: ["a: {type[0]}", "b: {neon_type[1]}"]
    attr:
      - FnCall: [cfg, [{FnCall: [not, ['target_arch = "arm"']]}]]
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [st1]]}]]
      - *neon-fp16
      - *neon-unstable-f16
      - *target-not-arm64ec
    safety:
      unsafe: [neon]
    types:
      - ["*mut f16", float16x4x3_t, float16x4_t]
      - ["*mut f16", float16x8x3_t, float16x8_t]
    compose:
      - LLVMLink:
          name: "vst1{neon_type[1].no}"
          arguments:
            - "a: {neon_type[2]}"
            - "b: {neon_type[2]}"
            - "c: {neon_type[2]}"
            - "ptr: {type[0]}"
          links:
            - link: "llvm.aarch64.neon.st1x3.{neon_type[2]}.p0"
              arch: aarch64,arm64ec
      - FnCall: ["_vst1{neon_type[1].no}", ['b.0', 'b.1', 'b.2', a]]


  - name: "vst1{neon_type[1].no}"
    doc: "Store multiple single-element structures to one, two, three, or four registers"
    arguments: ["a: {type[0]}", "b: {neon_type[1]}"]
    attr:
      - FnCall: [cfg, [{FnCall: [not, ['target_arch = "arm"']]}]]
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [st1]]}]]
      - *neon-stable
    safety:
      unsafe: [neon]
    types:
      - ["*mut f32", float32x2x4_t, float32x2_t]
      - ["*mut f32", float32x4x4_t, float32x4_t]
    compose:
      - LLVMLink:
          name: "vst1{neon_type[1].no}"
          arguments:
            - "a: {neon_type[2]}"
            - "b: {neon_type[2]}"
            - "c: {neon_type[2]}"
            - "d: {neon_type[2]}"
            - "ptr: {type[0]}"
          links:
            - link: "llvm.aarch64.neon.st1x4.{neon_type[2]}.p0"
              arch: aarch64,arm64ec
      - FnCall: ["_vst1{neon_type[1].no}", ['b.0', 'b.1', 'b.2', 'b.3', a]]


  - name: "vst1{neon_type[1].no}"
    doc: "Store multiple single-element structures to one, two, three, or four registers"
    arguments: ["a: {type[0]}", "b: {neon_type[1]}"]
    attr:
      - FnCall: [cfg, [{FnCall: [not, ['target_arch = "arm"']]}]]
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [st1]]}]]
      - *neon-fp16
      - *neon-unstable-f16
      - *target-not-arm64ec
    safety:
      unsafe: [neon]
    types:
      - ["*mut f16", float16x4x4_t, float16x4_t]
      - ["*mut f16", float16x8x4_t, float16x8_t]
    compose:
      - LLVMLink:
          name: "vst1{neon_type[1].no}"
          arguments:
            - "a: {neon_type[2]}"
            - "b: {neon_type[2]}"
            - "c: {neon_type[2]}"
            - "d: {neon_type[2]}"
            - "ptr: {type[0]}"
          links:
            - link: "llvm.aarch64.neon.st1x4.{neon_type[2]}.p0"
              arch: aarch64,arm64ec
      - FnCall: ["_vst1{neon_type[1].no}", ['b.0', 'b.1', 'b.2', 'b.3', a]]


#  - name: "vst1{neon_type[1].no}"
#    doc: "Store a single-element structures to one register."
#    arguments: ["ptr: {type[0]}", "a: {neon_type[1]}"]
#    attr:
#      - *neon-v7
#      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vst1]]}]]
#      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [st1]]}]]
#      - *neon-fp16
#      - *neon-unstable-f16
#    safety:
#      unsafe: [neon]
#    types:
#      - ["*mut f16", float16x4_t]
#      - ["*mut f16", float16x8_t]
#    compose:
#      - FnCall: [core::ptr::write_unaligned, ['ptr.cast()', a]]

  - name: "vfms{neon_type.no}"
    doc: "Floating-point fused multiply-subtract from accumulator"
    arguments: ["a: {neon_type}", "b: {neon_type}", "c: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - FnCall: [cfg_attr, [target_arch = "arm", {FnCall: [target_feature, ['enable = "vfp4"']]}]]
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vfms]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fmls]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - float32x2_t
      - float32x4_t
    compose:
      - Let: [b, "{neon_type}", {FnCall: [simd_neg, [b]]}]
      - FnCall: ["vfma{neon_type.no}", [a, b, c]]

  - name: "vmul{neon_type[0].no}"
    doc: "Polynomial multiply"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vmul]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [pmul]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [poly8x8_t, int8x8_t]
      - [poly8x16_t, int8x16_t]
    compose:
      - LLVMLink:
          name: "vmul{neon_type[0].no}"
          links:
            - link: "llvm.arm.neon.vmulp.{neon_type[1]}"
              arch: arm
            - link: "llvm.aarch64.neon.pmul.{neon_type[1]}"
              arch: aarch64,arm64ec

  - name: "vmls{neon_type.no}"
    doc: "Floating-point multiply-subtract from accumulator"
    arguments: ["a: {neon_type}", "b: {neon_type}", "c: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vmls.f32"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fmul]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - float32x2_t
      - float32x4_t
    compose:
      - FnCall: [simd_sub, [a, {FnCall: [simd_mul, [b, c]]}]]

  - name: "vcge{neon_type.no}"
    doc: "Compare unsigned greater than or equal"
    arguments: ["a: {neon_type}", "b: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vcge.{neon_type}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [cmhs]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - uint8x8_t
      - uint8x16_t
      - uint16x4_t
      - uint16x8_t
      - uint32x2_t
      - uint32x4_t
    compose:
      - FnCall: [simd_ge, [a, b]]

  - name: "vcge{neon_type[0].no}"
    doc: "Floating-point compare greater than or equal"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vcge.f32"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fcmge]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [float32x2_t, uint32x2_t]
      - [float32x4_t, uint32x4_t]
    compose:
      - FnCall: [simd_ge, [a, b]]

  - name: "vcge{neon_type[0].no}"
    doc: "Floating-point compare greater than or equal"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vcge.f16"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fcmge]]}]]
      - *neon-fp16
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    safety: safe
    types:
      - [float16x4_t, uint16x4_t]
      - [float16x8_t, uint16x8_t]
    compose:
      - FnCall: [simd_ge, [a, b]]


  - name: "vcgez{neon_type[0].no}"
    doc: "Floating-point compare greater than or equal to zero"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vcge.f16"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fcmge]]}]]
      - *neon-fp16
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    safety: safe
    types:
      - [float16x4_t, uint16x4_t, f16x4, 'f16x4::new(0.0, 0.0, 0.0, 0.0)']
      - [float16x8_t, uint16x8_t, f16x8, 'f16x8::new(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)']
    compose:
      - Let: [b, "{type[2]}", "{type[3]}"]
      - FnCall:
          - simd_ge
          - - a
            - FnCall: [transmute, [b]]

  - name: "vclt{neon_type.no}"
    doc: "Compare unsigned less than"
    arguments: ["a: {neon_type}", "b: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vcgt.{neon_type}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [cmhi]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - uint8x8_t
      - uint8x16_t
      - uint16x4_t
      - uint16x8_t
      - uint32x2_t
      - uint32x4_t
    compose:
      - FnCall: [simd_lt, [a, b]]

  - name: "vtst{neon_type[0].no}"
    doc: "Unsigned compare bitwise Test bits nonzero"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vtst]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [cmtst]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [uint8x8_t, u8x8, 'u8x8::new(0, 0, 0, 0, 0, 0, 0, 0)']
      - [uint8x16_t, u8x16, 'u8x16::new(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)']
      - [uint16x4_t, u16x4, 'u16x4::new(0, 0, 0, 0)']
      - [uint16x8_t, u16x8, 'u16x8::new(0, 0, 0, 0, 0, 0, 0, 0)']
      - [uint32x2_t, u32x2, 'u32x2::new(0, 0)']
      - [uint32x4_t, u32x4, 'u32x4::new(0, 0, 0, 0)']
    compose:
      - Let: [c, "{neon_type[0]}", {FnCall: [simd_and, [a, b]]}]
      - Let: [d, "{type[1]}", "{type[2]}"]
      - FnCall: [simd_ne, [c, {FnCall: [transmute, [d]]}]]

  - name: "vshl{neon_type[0].N}"
    doc: "Shift left"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vshl, 'N = 2']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [shl, 'N = 2']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [int8x8_t, '3']
      - [int8x16_t, '3']
      - [int16x4_t, '4']
      - [int16x8_t, '4']
      - [int32x2_t, '5']
      - [int32x4_t, '5']
      - [uint8x8_t, '3']
      - [uint8x16_t, '3']
      - [uint16x4_t, '4']
      - [uint16x8_t, '4']
      - [uint32x2_t, '5']
      - [uint32x4_t, '5']
      - [int64x1_t, '6']
      - [int64x2_t, '6']
      - [uint64x1_t, '6']
      - [uint64x2_t, '6']
    compose:
      - FnCall: [static_assert_uimm_bits!, [N, "{type[1]}"]]
      - FnCall:
          - simd_shl
          - - a
            - FnCall: ["vdup{neon_type[0].N}", ['N as _']]

  - name: "vsra{neon_type[0].N}"
    doc: "Unsigned shift right and accumulate"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vsra, 'N = 2']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [usra, 'N = 2']]}]]
      - FnCall: [rustc_legacy_const_generics, ['2']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [uint8x8_t, '8']
      - [uint8x16_t, '8']
      - [uint16x4_t, '16']
      - [uint16x8_t, '16']
      - [uint32x2_t, '32']
      - [uint32x4_t, '32']
      - [uint64x1_t, '64']
      - [uint64x2_t, '64']
    compose:
      - FnCall: [static_assert!, ['N >= 1 && N <= {type[1]}']]
      - FnCall:
          - simd_add
          - - a
            - FnCall: ["vshr{neon_type[0].N}::<N>", [b]]

  - name: "vrsra{neon_type[0].N}"
    doc: "Unsigned rounding shift right and accumulate"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vrsra, 'N = 2']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ursra, 'N = 2']]}]]
      - FnCall: [rustc_legacy_const_generics, ['2']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [uint8x8_t, '8']
      - [uint8x16_t, '8']
      - [uint16x4_t, '16']
      - [uint16x8_t, '16']
      - [uint32x2_t, '32']
      - [uint32x4_t, '32']
      - [uint64x1_t, '64']
      - [uint64x2_t, '64']
    compose:
      - FnCall: [static_assert!, ['N >= 1 && N <= {type[1]}']]
      - FnCall:
          - simd_add
          - - a
            - FnCall: ["vrshr{neon_type[0].N}::<N>", [b]]

  - name: "vqrshrn_n_{neon_type[0]}"
    doc: "Unsigned signed saturating rounded shift right narrow"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *target-is-arm
      - *enable-v7
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [vqrshrn, 'N = 2']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-arm-unstable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [uint16x8_t, uint8x8_t, '8', 'const { uint16x8_t([-N as u16, -N as u16, -N as u16, -N as u16, -N as u16, -N as u16, -N as u16, -N as u16]) }']
      - [uint32x4_t, uint16x4_t, '16', 'const { uint32x4_t([-N as u32, -N as u32, -N as u32, -N as u32]) }']
      - [uint64x2_t, uint32x2_t, '32', 'const { uint64x2_t([-N as u64, -N as u64]) }']
    compose:
      - FnCall: [static_assert!, ['N >= 1 && N <= {type[2]}']]
      - LLVMLink:
          name: "vqrshrn{neon_type[0].N}"
          arguments:
            - "a: {neon_type[0]}"
            - "n: {neon_type[0]}"
          links:
            - link: "llvm.arm.neon.vqrshiftnu.{neon_type[1]}"
              arch: arm
      - FnCall: ["_vqrshrn_n{neon_type[0].noq}", ["a", "{type[3]}"], [], true]

  - name: "vqrshrn_n_{neon_type[0]}"
    doc: "Unsigned signed saturating rounded shift right narrow"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *target-not-arm
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [uqrshrn, 'N = 2']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-stable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [uint16x8_t, uint8x8_t, '8']
      - [uint32x4_t, uint16x4_t, '16']
      - [uint64x2_t, uint32x2_t, '32']
    compose:
      - FnCall: [static_assert!, ['N >= 1 && N <= {type[2]}']]
      - LLVMLink:
          name: "vqrshrn_n_{neon_type[0]}"
          arguments:
            - "a: {neon_type[0]}"
            - "n: i32"
          links:
            - link: "llvm.aarch64.neon.uqrshrn.{neon_type[1]}"
              arch: aarch64,arm64ec
      - FnCall: ["_vqrshrn_n_{neon_type[0]}", ["a", N], [], true]

  - name: "vcvt{neon_type[1].no}_{neon_type[0]}"
    doc: "Floating-point convert to unsigned fixed-point, rounding toward zero"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vcvt]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fcvtzu]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [float32x2_t, uint32x2_t]
      - [float32x4_t, uint32x4_t]
    compose:
      - LLVMLink:
          name: "vcvt{neon_type[1].no}_{neon_type[0]}"
          links:
            - link: "llvm.fptoui.sat.{neon_type[1]}.{neon_type[0]}"
              arch: arm
            - link: "llvm.fptoui.sat.{neon_type[1]}.{neon_type[0]}"
              arch: aarch64,arm64ec


  - name: "vcvt{neon_type[1].no}_{neon_type[0]}"
    doc: "Floating-point convert to unsigned fixed-point, rounding toward zero"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vcvt]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fcvtzu]]}]]
      - *neon-fp16
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    safety: safe
    types:
      - [float16x4_t, uint16x4_t]
      - [float16x8_t, uint16x8_t]
    compose:
      - FnCall:
          - simd_cast
          - - a

  - name: "vcvt_f16_{neon_type[0]}"
    doc: "Floating-point convert to lower precision narrow"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vcvt]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fcvtn]]}]]
      - *arm-fp16
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    safety: safe
    types:
      - [float32x4_t, float16x4_t]
    compose:
      - FnCall: [simd_cast, [a]]

  - name: "vcvt_f32_f16"
    doc: "Floating-point convert to higher precision long"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vcvt]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fcvtl]]}]]
      - *arm-fp16
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    safety: safe
    types:
      - [float16x4_t, float32x4_t]
    compose:
      - FnCall: [simd_cast, [a]]

  - name: "vmla{neon_type[0].N}"
    doc: "Vector multiply accumulate with scalar"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}", "c: {type[1]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vmla.i16"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [mla]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [int16x4_t, "i16", int16x4_t]
      - [int16x8_t, "i16", int16x8_t]
      - [uint16x4_t, "u16", uint16x4_t]
      - [uint16x8_t, "u16", uint16x8_t]
    compose:
      - FnCall:
          - "vmla{neon_type[0].no}"
          - - a
            - b
            - FnCall: ["vdup{neon_type[0].N}", [c]]

  - name: "vmla{neon_type[0].N}"
    doc: "Vector multiply accumulate with scalar"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}", "c: {type[1]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vmla.i32"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [mla]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [int32x2_t, "i32", int32x2_t]
      - [int32x4_t, "i32", int32x4_t]
      - [uint32x2_t, "u32", uint32x2_t]
      - [uint32x4_t, "u32", uint32x4_t]
    compose:
      - FnCall:
          - "vmla{neon_type[0].no}"
          - - a
            - b
            - FnCall: ["vdup{neon_type[0].N}", [c]]

  - name: "vmla{neon_type[0].N}"
    doc: "Vector multiply accumulate with scalar"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}", "c: {type[1]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vmla.f32"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fmul]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [float32x2_t, "f32", float32x2_t]
      - [float32x4_t, "f32", float32x4_t]
    compose:
      - FnCall: ["vmla{neon_type[0].no}", [a, b, {FnCall: ["vdup{neon_type[0].N}", [c]]}]]

  - name: "vmla{type[0]}"
    doc: "Vector multiply accumulate with scalar"
    arguments: ["a: {neon_type[1]}", "b: {neon_type[1]}", "c: {neon_type[2]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vmla.i16"', 'LANE = 1']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [mla, 'LANE = 1']]}]]
      - FnCall: [rustc_legacy_const_generics, ['3']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const LANE: i32']
    safety: safe
    types:
      - [_lane_s16, int16x4_t, int16x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
      - [_laneq_s16, int16x4_t, int16x8_t, '3', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
      - [q_lane_s16, int16x8_t, int16x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
      - [q_laneq_s16, int16x8_t, int16x8_t, '3', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
      - [_lane_u16, uint16x4_t, uint16x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
      - [_laneq_u16, uint16x4_t, uint16x8_t, '3', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
      - [q_lane_u16, uint16x8_t, uint16x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
      - [q_laneq_u16, uint16x8_t, uint16x8_t, '3', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
    compose:
      - FnCall: [static_assert_uimm_bits!, [LANE, '{type[3]}']]
      - FnCall:
          - "vmla{neon_type[1].no}"
          - - a
            - b
            - FnCall: [simd_shuffle!, [c, c, "{type[4]}"]]

  - name: "vmla{type[0]}"
    doc: "Vector multiply accumulate with scalar"
    arguments: ["a: {neon_type[1]}", "b: {neon_type[1]}", "c: {neon_type[2]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vmla.i32"', 'LANE = 1']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [mla, 'LANE = 1']]}]]
      - FnCall: [rustc_legacy_const_generics, ['3']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const LANE: i32']
    safety: safe
    types:
      - [_lane_s32, int32x2_t, int32x2_t, '1', '[LANE as u32, LANE as u32]']
      - [_laneq_s32, int32x2_t, int32x4_t, '2', '[LANE as u32, LANE as u32]']
      - [q_lane_s32, int32x4_t, int32x2_t, '1', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
      - [q_laneq_s32, int32x4_t, int32x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
      - [_lane_u32, uint32x2_t, uint32x2_t, '1', '[LANE as u32, LANE as u32]']
      - [_laneq_u32, uint32x2_t, uint32x4_t, '2', '[LANE as u32, LANE as u32]']
      - [q_lane_u32, uint32x4_t, uint32x2_t, '1', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
      - [q_laneq_u32, uint32x4_t, uint32x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
    compose:
      - FnCall: [static_assert_uimm_bits!, [LANE, '{type[3]}']]
      - FnCall:
          - "vmla{neon_type[1].no}"
          - - a
            - b
            - FnCall: [simd_shuffle!, [c, c, "{type[4]}"]]

  - name: "vmla{type[0]}"
    doc: "Vector multiply accumulate with scalar"
    arguments: ["a: {neon_type[1]}", "b: {neon_type[1]}", "c: {neon_type[2]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vmla.f32"', 'LANE = 1']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fmul, 'LANE = 1']]}]]
      - FnCall: [rustc_legacy_const_generics, ['3']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const LANE: i32']
    safety: safe
    types:
      - [_lane_f32, float32x2_t, float32x2_t, '1', '[LANE as u32, LANE as u32]']
      - [_laneq_f32, float32x2_t, float32x4_t, '2', '[LANE as u32, LANE as u32]']
      - [q_lane_f32, float32x4_t, float32x2_t, '1', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
      - [q_laneq_f32, float32x4_t, float32x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
    compose:
      - FnCall: [static_assert_uimm_bits!, [LANE, '{type[3]}']]
      - FnCall:
          - "vmla{neon_type[1].no}"
          - - a
            - b
            - FnCall: [simd_shuffle!, [c, c, "{type[4]}"]]

  - name: "vmls{neon_type[0].N}"
    doc: "Vector multiply subtract with scalar"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}", "c: {type[1]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vmls.i16"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [mls]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [int16x4_t, "i16", int16x4_t]
      - [int16x8_t, "i16", int16x8_t]
      - [uint16x4_t, "u16", uint16x4_t]
      - [uint16x8_t, "u16", uint16x8_t]
    compose:
      - FnCall:
          - "vmls{neon_type[0].no}"
          - - a
            - b
            - FnCall: ["vdup{neon_type[0].N}", [c]]

  - name: "vmls{neon_type[0].N}"
    doc: "Vector multiply subtract with scalar"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}", "c: {type[1]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vmls.i32"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [mls]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [int32x2_t, "i32", int32x2_t]
      - [int32x4_t, "i32", int32x4_t]
      - [uint32x2_t, "u32", uint32x2_t]
      - [uint32x4_t, "u32", uint32x4_t]
    compose:
      - FnCall:
          - "vmls{neon_type[0].no}"
          - - a
            - b
            - FnCall: ["vdup{neon_type[0].N}", [c]]

  - name: "vmls{neon_type[0].N}"
    doc: "Vector multiply subtract with scalar"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}", "c: {type[1]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vmls.f32"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fmul]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [float32x2_t, "f32", float32x2_t]
      - [float32x4_t, "f32", float32x4_t]
    compose:
      - FnCall: ["vmls{neon_type[0].no}", [a, b, {FnCall: ["vdup{neon_type[0].N}", [c]]}]]

  - name: "vmls{type[0]}"
    doc: "Vector multiply subtract with scalar"
    arguments: ["a: {neon_type[1]}", "b: {neon_type[1]}", "c: {neon_type[2]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vmls.i16"', 'LANE = 1']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [mls, 'LANE = 1']]}]]
      - FnCall: [rustc_legacy_const_generics, ['3']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const LANE: i32']
    safety: safe
    types:
      - [_lane_s16, int16x4_t, int16x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
      - [_laneq_s16, int16x4_t, int16x8_t, '3', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
      - [q_lane_s16, int16x8_t, int16x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
      - [q_laneq_s16, int16x8_t, int16x8_t, '3', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
      - [_lane_u16, uint16x4_t, uint16x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
      - [_laneq_u16, uint16x4_t, uint16x8_t, '3', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
      - [q_lane_u16, uint16x8_t, uint16x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
      - [q_laneq_u16, uint16x8_t, uint16x8_t, '3', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
    compose:
      - FnCall: [static_assert_uimm_bits!, [LANE, '{type[3]}']]
      - FnCall:
          - "vmls{neon_type[1].no}"
          - - a
            - b
            - FnCall: [simd_shuffle!, [c, c, "{type[4]}"]]

  - name: "vmls{type[0]}"
    doc: "Vector multiply subtract with scalar"
    arguments: ["a: {neon_type[1]}", "b: {neon_type[1]}", "c: {neon_type[2]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vmls.i32"', 'LANE = 1']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [mls, 'LANE = 1']]}]]
      - FnCall: [rustc_legacy_const_generics, ['3']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const LANE: i32']
    safety: safe
    types:
      - [_lane_s32, int32x2_t, int32x2_t, '1', '[LANE as u32, LANE as u32]']
      - [_laneq_s32, int32x2_t, int32x4_t, '2', '[LANE as u32, LANE as u32]']
      - [q_lane_s32, int32x4_t, int32x2_t, '1', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
      - [q_laneq_s32, int32x4_t, int32x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
      - [_lane_u32, uint32x2_t, uint32x2_t, '1', '[LANE as u32, LANE as u32]']
      - [_laneq_u32, uint32x2_t, uint32x4_t, '2', '[LANE as u32, LANE as u32]']
      - [q_lane_u32, uint32x4_t, uint32x2_t, '1', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
      - [q_laneq_u32, uint32x4_t, uint32x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
    compose:
      - FnCall: [static_assert_uimm_bits!, [LANE, '{type[3]}']]
      - FnCall:
          - "vmls{neon_type[1].no}"
          - - a
            - b
            - FnCall: [simd_shuffle!, [c, c, "{type[4]}"]]

  - name: "vmls{type[0]}"
    doc: "Vector multiply subtract with scalar"
    arguments: ["a: {neon_type[1]}", "b: {neon_type[1]}", "c: {neon_type[2]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vmls.f32"', 'LANE = 1']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fmul, 'LANE = 1']]}]]
      - FnCall: [rustc_legacy_const_generics, ['3']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const LANE: i32']
    safety: safe
    types:
      - [_lane_f32, float32x2_t, float32x2_t, '1', '[LANE as u32, LANE as u32]']
      - [_laneq_f32, float32x2_t, float32x4_t, '2', '[LANE as u32, LANE as u32]']
      - [q_lane_f32, float32x4_t, float32x2_t, '1', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
      - [q_laneq_f32, float32x4_t, float32x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
    compose:
      - FnCall: [static_assert_uimm_bits!, [LANE, '{type[3]}']]
      - FnCall:
          - "vmls{neon_type[1].no}"
          - - a
            - b
            - FnCall: [simd_shuffle!, [c, c, "{type[4]}"]]

  - name: "vmul{neon_type[0].N}"
    doc: "Vector multiply by scalar"
    arguments: ["a: {neon_type[0]}", "b: {type[1]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vmul]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [mul]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [int16x4_t, "i16"]
      - [int16x8_t, "i16"]
      - [int32x2_t, "i32"]
      - [int32x4_t, "i32"]
      - [uint16x4_t, "u16"]
      - [uint16x8_t, "u16"]
      - [uint32x2_t, "u32"]
      - [uint32x4_t, "u32"]
    compose:
      - FnCall:
          - simd_mul
          - - a
            - FnCall: ["vdup{neon_type[0].N}", [b]]

  - name: "vmul{neon_type[0].N}"
    doc: "Vector multiply by scalar"
    arguments: ["a: {neon_type[0]}", "b: {type[1]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vmul]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fmul]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [float32x2_t, "f32"]
      - [float32x4_t, "f32"]
    compose:
      - FnCall:
          - simd_mul
          - - a
            - FnCall: ["vdup{neon_type[0].N}", [b]]


  - name: "vmul{neon_type[0].N}"
    doc: "Vector multiply by scalar"
    arguments: ["a: {neon_type[0]}", "b: {type[1]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vmul]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fmul]]}]]
      - *neon-fp16
      - *neon-unstable-f16
      - *target-not-arm64ec
    safety: safe
    types:
      - [float16x4_t, "f16"]
      - [float16x8_t, "f16"]
    compose:
      - FnCall:
          - simd_mul
          - - a
            - FnCall: ["vdup{neon_type[0].N}", [b]]


  - name: "vmul{type[2]}"
    doc: "Floating-point multiply"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vmul, 'LANE = 0']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fmul, 'LANE = 0']]}]]
      - FnCall: [rustc_legacy_const_generics, ['2']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const LANE: i32']
    safety: safe
    types:
      - [float32x2_t, float32x2_t, '_lane_f32', '1', '[LANE as u32, LANE as u32]']
      - [float32x2_t, float32x4_t, '_laneq_f32', '2', '[LANE as u32, LANE as u32]']
      - [float32x4_t, float32x2_t, 'q_lane_f32', '1', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
      - [float32x4_t, float32x4_t, 'q_laneq_f32', '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
    compose:
      - FnCall: [static_assert_uimm_bits!, [LANE, '{type[3]}']]
      - FnCall:
          - simd_mul
          - - a
            - FnCall: [simd_shuffle!, [b, b, "{type[4]}"]]

  - name: "vqrdmulh{type[0]}"
    doc: "Vector rounding saturating doubling multiply high by scalar"
    arguments: ["a: {neon_type[1]}", "b: {neon_type[2]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vqrdmulh, 'LANE = 1']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [sqrdmulh, 'LANE = 1']]}]]
      - FnCall: [rustc_legacy_const_generics, ['2']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const LANE: i32']
    safety: safe
    types:
      - [_lane_s16, int16x4_t, int16x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
      - [_laneq_s16, int16x4_t, int16x8_t, '3', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
      - [q_lane_s16, int16x8_t, int16x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
      - [q_laneq_s16, int16x8_t, int16x8_t, '3', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
      - [_lane_s32, int32x2_t, int32x2_t, '1', '[LANE as u32, LANE as u32]']
      - [_laneq_s32, int32x2_t, int32x4_t, '2', '[LANE as u32, LANE as u32]']
      - [q_lane_s32, int32x4_t, int32x2_t, '1', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
      - [q_laneq_s32, int32x4_t, int32x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
    compose:
      - FnCall: [static_assert_uimm_bits!, [LANE, "{type[3]}"]]
      - Let: [b, "{neon_type[1]}", {FnCall: [simd_shuffle!, [b, b, '{type[4]}']]}]
      - FnCall: ["vqrdmulh{neon_type[1].no}", [a, b]]

  - name: "vqrdmulh{neon_type[0].N}"
    doc: "Vector saturating rounding doubling multiply high with scalar"
    arguments: ["a: {neon_type[0]}", "b: {type[1]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vqrdmulh]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [sqrdmulh]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [int16x4_t, "i16"]
      - [int16x8_t, "i16"]
      - [int32x2_t, "i32"]
      - [int32x4_t, "i32"]
    compose:
      - FnCall:
          - "vqrdmulh{neon_type[0].no}"
          - - a
            - FnCall: ["vdup{neon_type[0].N}", [b]]

  - name: "vclt{neon_type[0].no}"
    doc: "Floating-point compare less than"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vcgt.f32"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fcmgt]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [float32x2_t, uint32x2_t]
      - [float32x4_t, uint32x4_t]
    compose:
      - FnCall: [simd_lt, [a, b]]

  - name: "vclt{neon_type[0].no}"
    doc: "Floating-point compare less than"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vcgt.f16"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fcmgt]]}]]
      - *neon-fp16
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    safety: safe
    types:
      - [float16x4_t, uint16x4_t]
      - [float16x8_t, uint16x8_t]
    compose:
      - FnCall: [simd_lt, [a, b]]


  - name: "vcltz{neon_type[0].no}"
    doc: "Floating-point compare less than"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vclt.f16"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fcmlt]]}]]
      - *neon-fp16
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    safety: safe
    types:
      - [float16x4_t, uint16x4_t, f16x4, 'f16x4::new(0.0, 0.0, 0.0, 0.0)']
      - [float16x8_t, uint16x8_t, f16x8, 'f16x8::new(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)']
    compose:
      - Let: [b, "{type[2]}", "{type[3]}"]
      - FnCall:
          - simd_lt
          - - a
            - FnCall: [transmute, [b]]

  - name: "vabdl_{neon_type[0]}"
    doc: "Unsigned Absolute difference Long"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vabdl.{neon_type[0]}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [uabdl]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [uint8x8_t, uint16x8_t]
      - [uint16x4_t, uint32x4_t]
      - [uint32x2_t, uint64x2_t]
    compose:
      - FnCall: [simd_cast, [{FnCall: ["vabd_{neon_type[0]}", [a, b]]}]]

  - name: "vmull_lane{neon_type[1].no}"
    doc: "Vector long multiply by scalar"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[2]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vmull, 'LANE = 1']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [smull, 'LANE = 1']]}]]
      - FnCall: [rustc_legacy_const_generics, ['2']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const LANE: i32']
    safety: safe
    types:
      - [int16x4_t, int16x4_t, int32x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
      - [int16x4_t, int16x8_t, int32x4_t, '3', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
      - [int32x2_t, int32x2_t, int64x2_t, '1', '[LANE as u32, LANE as u32]']
      - [int32x2_t, int32x4_t, int64x2_t, '2', '[LANE as u32, LANE as u32]']
    compose:
      - FnCall: [static_assert_uimm_bits!, [LANE, "{type[3]}"]]
      - FnCall:
          - "vmull_{neon_type[0]}"
          - - a
            - FnCall: [simd_shuffle!, [b, b, "{type[4]}"]]

  - name: "vmull_lane{neon_type[1].no}"
    doc: "Vector long multiply by scalar"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[2]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vmull, 'LANE = 1']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [umull, 'LANE = 1']]}]]
      - FnCall: [rustc_legacy_const_generics, ['2']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const LANE: i32']
    safety: safe
    types:
      - [uint16x4_t, uint16x4_t, uint32x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
      - [uint16x4_t, uint16x8_t, uint32x4_t, '3', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]']
      - [uint32x2_t, uint32x2_t, uint64x2_t, '1', '[LANE as u32, LANE as u32]']
      - [uint32x2_t, uint32x4_t, uint64x2_t, '2', '[LANE as u32, LANE as u32]']
    compose:
      - FnCall: [static_assert_uimm_bits!, [LANE, "{type[3]}"]]
      - FnCall:
          - "vmull_{neon_type[0]}"
          - - a
            - FnCall: [simd_shuffle!, [b, b, "{type[4]}"]]

  - name: "vfms{neon_type[0].N}"
    doc: "Floating-point fused Multiply-subtract to accumulator(vector)"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}", "c: {type[1]}"]
    return_type: "{neon_type[0]}"
    attr:
      - FnCall: [cfg_attr, [target_arch = "arm", {FnCall: [target_feature, ['enable = "vfp4"']]}]]
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vfms]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fmls]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [float32x2_t, "f32"]
      - [float32x4_t, "f32"]
    compose:
      - FnCall:
          - "vfms{neon_type[0].no}"
          - - a
            - b
            - FnCall: ["vdup{neon_type[0].N}_vfp4", [c]]


  - name: "vfms{neon_type.no}"
    doc: "Floating-point fused multiply-subtract from accumulator"
    arguments: ["a: {neon_type}", "b: {neon_type}", "c: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v8
      - FnCall: [cfg_attr, [target_arch = "arm", {FnCall: [target_feature, ['enable = "vfp4"']]}]]
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [nop]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fmls]]}]]
      - *neon-fp16
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    safety: safe
    types:
      - float16x4_t
      - float16x8_t
    compose:
      - Let: [b, "{neon_type}", {FnCall: [simd_neg, [b]]}]
      - FnCall: ["vfma{neon_type.no}", [a, b, c]]

  - name: "vqdmulh{neon_type[0].laneq_nox}"
    doc: "Vector saturating doubling multiply high by scalar"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vqdmulh, 'LANE = 0']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [sqdmulh, 'LANE = 0']]}]]
      - FnCall: [rustc_legacy_const_generics, ['2']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const LANE: i32']
    safety: safe
    types:
      - [int16x8_t, int16x8_t, '3']
      - [int16x4_t, int16x8_t, '3']
      - [int32x4_t, int32x4_t, '2']
      - [int32x2_t, int32x4_t, '2']
    compose:
      - FnCall: [static_assert_uimm_bits!, [LANE, "{type[2]}"]]
      - FnCall:
          - "vqdmulh{neon_type[0].no}"
          - - a
            - FnCall:
                - "vdup{neon_type[0].N}"
                - - FnCall: [simd_extract!, [b, 'LANE as u32']]

  - name: "vrecpe{neon_type.no}"
    doc: "Unsigned reciprocal estimate"
    arguments: ["a: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vrecpe]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [urecpe]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - uint32x2_t
      - uint32x4_t
    compose:
      - LLVMLink:
          name: "vrecpe{neon_type.no}"
          links:
            - link: "llvm.arm.neon.vrecpe.{neon_type}"
              arch: arm
            - link: "llvm.aarch64.neon.urecpe.{neon_type}"
              arch: aarch64,arm64ec

  - name: "vrsqrte{neon_type.no}"
    doc: "Unsigned reciprocal square root estimate"
    arguments: ["a: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vrsqrte]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ursqrte]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - uint32x2_t
      - uint32x4_t
    compose:
      - LLVMLink:
          name: "vrsqrte{neon_type.no}"
          links:
            - link: "llvm.arm.neon.vrsqrte.{neon_type}"
              arch: arm
            - link: "llvm.aarch64.neon.ursqrte.{neon_type}"
              arch: aarch64,arm64ec

  - name: "vrsqrte{neon_type.no}"
    doc: "Reciprocal square-root estimate."
    arguments: ["a: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vrsqrte]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [frsqrte]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - float32x2_t
      - float32x4_t
    compose:
      - LLVMLink:
          name: "vrsqrte{neon_type.no}"
          links:
            - link: "llvm.arm.neon.vrsqrte.{neon_type}"
              arch: arm
            - link: "llvm.aarch64.neon.frsqrte.{neon_type}"
              arch: aarch64,arm64ec


  - name: "vrsqrte{neon_type.no}"
    doc: "Reciprocal square-root estimate."
    arguments: ["a: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v8
      - *neon-fp16
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vrsqrte]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [frsqrte]]}]]
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    safety: safe
    types:
      - float16x4_t
      - float16x8_t
    compose:
      - LLVMLink:
          name: "vrsqrte{neon_type.no}"
          links:
            - link: "llvm.arm.neon.vrsqrte.{neon_type}"
              arch: arm
            - link: "llvm.aarch64.neon.frsqrte.{neon_type}"
              arch: aarch64,arm64ec


  - name: "vqshlu{neon_type[0].N}"
    doc: "Signed saturating shift left unsigned"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *target-is-arm
      - *enable-v7
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [vqshlu, 'N = 2']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-arm-unstable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [int8x8_t, uint8x8_t, '3', 'const { int8x8_t([N as i8; 8]) }']
      - [int16x4_t, uint16x4_t, '4', 'const { int16x4_t([N as i16; 4]) }']
      - [int32x2_t, uint32x2_t, '5', 'const { int32x2_t([N; 2]) }']
      - [int64x1_t, uint64x1_t, '6', 'const { int64x1_t([N as i64]) }']
      - [int8x16_t, uint8x16_t, '3', 'const { int8x16_t([N as i8; 16]) }']
      - [int16x8_t, uint16x8_t, '4', 'const { int16x8_t([N as i16; 8]) }']
      - [int32x4_t, uint32x4_t, '5', 'const { int32x4_t([N; 4]) }']
      - [int64x2_t, uint64x2_t, '6', 'const { int64x2_t([N as i64; 2]) }']
    compose:
      - FnCall: [static_assert_uimm_bits!, [N, "{type[2]}"]]
      - LLVMLink:
          name: "vqshlu{neon_type[0].N}"
          arguments:
            - "a: {neon_type[0]}"
            - "n: {neon_type[0]}"
          links:
            - link: "llvm.arm.neon.vqshiftsu.{neon_type[0]}"
              arch: arm
      - FnCall: ["_vqshlu{neon_type[0].N}", [a, "{type[3]}"], [], true]

  - name: "vqshlu{neon_type[0].N}"
    doc: "Signed saturating shift left unsigned"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - FnCall: [cfg, [{FnCall: [not, ['target_arch = "arm"']]}]]
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [sqshlu, 'N = 2']]}]]
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *neon-stable
    static_defs: ['const N: i32']
    safety: safe
    types:
      - [int8x8_t, uint8x8_t, '3', 'const { int8x8_t([N as i8; 8]) }']
      - [int16x4_t, uint16x4_t, '4', 'const { int16x4_t([N as i16; 4]) }']
      - [int32x2_t, uint32x2_t, '5', 'const { int32x2_t([N; 2]) }']
      - [int64x1_t, uint64x1_t, '6', 'const { int64x1_t([N as i64]) }']
      - [int8x16_t, uint8x16_t, '3', 'const { int8x16_t([N as i8; 16]) }']
      - [int16x8_t, uint16x8_t, '4', 'const { int16x8_t([N as i16; 8]) }']
      - [int32x4_t, uint32x4_t, '5', 'const { int32x4_t([N; 4]) }']
      - [int64x2_t, uint64x2_t, '6', 'const { int64x2_t([N as i64; 2]) }']
    compose:
      - FnCall: [static_assert_uimm_bits!, [N, "{type[2]}"]]
      - LLVMLink:
          name: "vqshlu{neon_type[0].N}"
          arguments:
            - "a: {neon_type[0]}"
            - "n: {neon_type[0]}"
          links:
            - link: "llvm.aarch64.neon.sqshlu.{neon_type[0]}"
              arch: aarch64,arm64ec
      - FnCall: ["_vqshlu{neon_type[0].N}", [a, "{type[3]}"], [], true]

  - name: "vcvt{neon_type[1].no}_{neon_type[0]}"
    doc: "Floating-point convert to signed fixed-point, rounding toward zero"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vcvt]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fcvtzs]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [float32x2_t, int32x2_t]
      - [float32x4_t, int32x4_t]
    compose:
      - LLVMLink:
          name: "vcvt{neon_type[1].no}_{neon_type[0]}"
          links:
            - link: "llvm.fptosi.sat.{neon_type[1]}.{neon_type[0]}"
              arch: arm
            - link: "llvm.fptosi.sat.{neon_type[1]}.{neon_type[0]}"
              arch: aarch64,arm64ec


  - name: "vcvt{neon_type[1].no}_{neon_type[0]}"
    doc: "Floating-point convert to signed fixed-point, rounding toward zero"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vcvt]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fcvtzs]]}]]
      - *neon-fp16
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    safety: safe
    types:
      - [float16x4_t, int16x4_t]
      - [float16x8_t, int16x8_t]
    compose:
      - FnCall:
          - simd_cast
          - - a

  - name: "vqmovn_{neon_type[0]}"
    doc: "Unsigned saturating extract narrow"
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vqmovn]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [uqxtn]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [uint16x8_t, uint8x8_t]
      - [uint32x4_t, uint16x4_t]
      - [uint64x2_t, uint32x2_t]
    compose:
      - LLVMLink:
          name: "vqmovn_{neon_type[1]}"
          links:
            - link: "llvm.arm.neon.vqmovnu.{neon_type[1]}"
              arch: arm
            - link: "llvm.aarch64.neon.uqxtn.{neon_type[1]}"
              arch: aarch64,arm64ec

  - name: "vcle{neon_type.no}"
    doc: "Compare unsigned less than or equal"
    arguments: ["a: {neon_type}", "b: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vcge.{neon_type}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [cmhs]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - uint8x8_t
      - uint8x16_t
      - uint16x4_t
      - uint16x8_t
      - uint32x2_t
      - uint32x4_t
    compose:
      - FnCall: [simd_le, [a, b]]

  - name: "vld4{neon_type[1].dup_nox}"
    doc: "Load single 4-element structure and replicate to all lanes of four registers"
    arguments: ["a: {type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *target-is-arm
      - *enable-v7
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [vld4]]}]]
      - *neon-arm-unstable
    safety:
      unsafe: [neon]
    types:
      - ["*const i8", int8x8x4_t, int8x8_t, '1']
      - ["*const i16", int16x4x4_t, int16x4_t, '2']
      - ["*const i32", int32x2x4_t, int32x2_t, '4']
      - ["*const i8", int8x16x4_t, int8x16_t, '1']
      - ["*const i16", int16x8x4_t, int16x8_t, '2']
      - ["*const i32", int32x4x4_t, int32x4_t, '4']
      - ["*const f32", float32x2x4_t, float32x2_t, '4']
      - ["*const f32", float32x4x4_t, float32x4_t, '4']
    compose:
      - LLVMLink:
          name: "vld4{neon_type[1].dup_nox}"
          arguments:
            - "ptr: *const i8"
            - "size: i32"
          links:
            - link: "llvm.arm.neon.vld4dup.{neon_type[2]}.p0"
              arch: arm
      - FnCall: ["_vld4{neon_type[1].dup_nox}", ['a as *const i8', "{type[3]}"]]

  - name: "vld4{neon_type[1].dup_nox}"
    doc: "Load single 4-element structure and replicate to all lanes of four registers"
    arguments: ["a: {type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - FnCall: [cfg, [{FnCall: [not, ['target_arch = "arm"']]}]]
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [ld4r]]}]]
      - *neon-stable
    safety:
      unsafe: [neon]
    types:
      - ["*const i8", int8x8x4_t, int8x8_t]
      - ["*const i16", int16x4x4_t, int16x4_t]
      - ["*const i32", int32x2x4_t, int32x2_t]
      - ["*const i8", int8x16x4_t, int8x16_t]
      - ["*const i16", int16x8x4_t, int16x8_t]
      - ["*const i32", int32x4x4_t, int32x4_t]
      - ["*const i64", int64x1x4_t, int64x1_t]
      - ["*const f32", float32x2x4_t, float32x2_t]
      - ["*const f32", float32x4x4_t, float32x4_t]
    compose:
      - LLVMLink:
          name: "vld4{neon_type[1].dup_nox}"
          arguments:
            - "ptr: {type[0]}"
          links:
            - link: "llvm.aarch64.neon.ld4r.{neon_type[2]}.p0.p0"
              arch: aarch64,arm64ec
      - FnCall: ["_vld4{neon_type[1].dup_nox}", ['a as _']]

  - name: "vld4{neon_type[1].dup_nox}"
    doc: "Load single 4-element structure and replicate to all lanes of four registers"
    arguments: ["a: {type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *target-is-arm
      - *enable-v7
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [nop]]}]]
      - *neon-arm-unstable
    safety:
      unsafe: [neon]
    types:
      - ["*const i64", int64x1x4_t]
    compose:
      - LLVMLink:
          name: "vld4{neon_type[1].dup_nox}"
          arguments:
            - "ptr: *const i8"
            - "size: i32"
          links:
            - link: "llvm.arm.neon.vld4dup.v1i64.p0"
              arch: arm
      - FnCall: ["_vld4{neon_type[1].dup_nox}", ['a as *const i8', '8']]

  - name: "vld4{neon_type[1].dup_nox}"
    doc: "Load single 4-element structure and replicate to all lanes of four registers"
    arguments: ["a: {type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vld4]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ld4r]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety:
      unsafe: [neon]
    types:
      - ["*const u8", uint8x8x4_t, int8x8x4_t]
      - ["*const u16", uint16x4x4_t, int16x4x4_t]
      - ["*const u32", uint32x2x4_t, int32x2x4_t]
      - ["*const u8", uint8x16x4_t, int8x16x4_t]
      - ["*const u16", uint16x8x4_t, int16x8x4_t]
      - ["*const u32", uint32x4x4_t, int32x4x4_t]
      - ["*const p8", poly8x8x4_t, int8x8x4_t]
      - ["*const p16", poly16x4x4_t, int16x4x4_t]
      - ["*const p8", poly8x16x4_t, int8x16x4_t]
      - ["*const p16", poly16x8x4_t, int16x8x4_t]
    compose:
      - FnCall:
          - "transmute"
          - - FnCall: ["vld4{neon_type[2].dup_nox}", [{FnCall: [transmute, [a]]}]]

  - name: "vld4{neon_type[1].dup_nox}"
    doc: "Load single 4-element structure and replicate to all lanes of four registers"
    arguments: ["a: {type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [nop]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ld4r]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety:
      unsafe: [neon]
    types:
      - ["*const u64", uint64x1x4_t, int64x1x4_t]
    compose:
      - FnCall:
          - "transmute"
          - - FnCall: ["vld4{neon_type[2].dup_nox}", [{FnCall: [transmute, [a]]}]]

  - name: "vld4{neon_type[1].dup_nox}"
    doc: "Load single 4-element structure and replicate to all lanes of four registers"
    arguments: ["a: {type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-aes
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [nop]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ld4r]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety:
      unsafe: [neon]
    types:
      - ["*const p64", poly64x1x4_t, int64x1x4_t]
    compose:
      - FnCall:
          - "transmute"
          - - FnCall: ["vld4{neon_type[2].dup_nox}", [{FnCall: [transmute, [a]]}]]

  - name: "vld1{type[0]}"
    visibility: private
    arguments: ["a: {type[1]}"]
    static_defs: ["const ALIGN: i32"]
    return_type: "{neon_type[2]}"
    attr:
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - *target-is-arm
      - *enable-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vld1.8"', "ALIGN = 0"]]}]]
      - *neon-arm-unstable
    safety:
      unsafe: [neon]
    types:
      - ["_v8i8",   "*const i8", "int8x8_t"   ]
      - ["q_v16i8", "*const i8", "int8x16_t"  ]
      - ["_v4i16",  "*const i8", "int16x4_t"  ]
      - ["q_v8i16", "*const i8", "int16x8_t"  ]
      - ["_v2i32",  "*const i8", "int32x2_t"  ]
      - ["q_v4i32", "*const i8", "int32x4_t"  ]
      - ["_v1i64",  "*const i8", "int64x1_t"  ]
      - ["q_v2i64", "*const i8", "int64x2_t"  ]
      - ["_v2f32",  "*const i8", "float32x2_t"]
      - ["q_v4f32", "*const i8", "float32x4_t"]
    compose:
      - LLVMLink:
          name: "vld1.{type[0]}"
          arguments: ["a: {type[1]}", "b: i32"]
          links:
            - link: "llvm.arm.neon.vld1.{neon_type[2]}"
              arch: arm
      - FnCall: ["_vld1{type[0]}", [a, ALIGN]]

  - name: "vld1{type[0]}"
    visibility: private
    arguments: ["a: {type[1]}", "b: {type[2]}"]
    return_type: "{neon_type[3]}"
    attr:
      - *target-is-arm
      - *enable-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [nop]]}]]
      - *neon-fp16
      - *neon-arm-unstable
      - *target-not-arm64ec
    safety:
      unsafe: [neon]
    types:
      - ["_v4f16", "*const i8", "i32", "float16x4_t"]
      - ["q_v8f16", "*const i8", "i32", "float16x8_t"]
    compose:
      - LLVMLink:
          name: "vld1.{type[0]}"
          links:
            - link: "llvm.arm.neon.vld1.{neon_type[3]}"
              arch: arm
      - FnCall: ["_vld1{type[0]}", [a, b]]


  - name: "vld1{neon_type[1].no}"
    doc: "Load multiple single-element structures to one, two, three, or four registers."
    arguments: ["ptr: {type[0]}"]
    return_type: "{neon_type[1]}"
    safety:
      unsafe: [neon]
    attr:
      - *target-is-arm
      - *enable-v7
      - *neon-arm-unstable
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['{type[2]}']]}]]
    types:
      - ['*const i8',  int8x8_t,  '"vld1.8"',  'crate::mem::align_of::<i8>()',  '_v8i8'  ]
      - ['*const i8',  int8x16_t, '"vld1.8"',  'crate::mem::align_of::<i8>()',  'q_v16i8']
      - ['*const i16', int16x4_t, '"vld1.16"', 'crate::mem::align_of::<i16>()', '_v4i16' ]
      - ['*const i16', int16x8_t, '"vld1.16"', 'crate::mem::align_of::<i16>()', 'q_v8i16']
      - ['*const i32', int32x2_t, 'vldr',      'crate::mem::align_of::<i32>()', '_v2i32' ]
      - ['*const i32', int32x4_t, '"vld1.32"', 'crate::mem::align_of::<i32>()', 'q_v4i32']
      - ['*const i64', int64x1_t, 'vldr',      'crate::mem::align_of::<i64>()', '_v1i64' ]
      - ['*const i64', int64x2_t, '"vld1.64"', 'crate::mem::align_of::<i64>()', 'q_v2i64']
    compose:
      - Const:
          - ALIGN
          - "i32"
          - "{type[3]} as i32"
      - FnCall:
          - "vld1{type[4]}"
          - ['ptr as *const i8']
          - ['ALIGN']

  - name: "vld1{neon_type[1].no}"
    doc: "Load multiple single-element structures to one, two, three, or four registers."
    arguments: ["ptr: {type[0]}"]
    return_type: "{neon_type[1]}"
    safety:
      unsafe: [neon]
    attr:
      - *target-is-arm
      - FnCall: [target_feature, ['enable = "{type[3]}"']]
      - *neon-arm-unstable
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['{type[2]}']]}]]
    types:
      - ['*const u8',  uint8x8_t,   '"vld1.8"',  'neon,v7',  'crate::mem::align_of::<u8>()',  '_v8i8'  ]
      - ['*const u8',  uint8x16_t,  '"vld1.8"',  'neon,v7',  'crate::mem::align_of::<u8>()',  'q_v16i8']
      - ['*const u16', uint16x4_t,  '"vld1.16"', 'neon,v7',  'crate::mem::align_of::<u16>()', '_v4i16' ]
      - ['*const u16', uint16x8_t,  '"vld1.16"', 'neon,v7',  'crate::mem::align_of::<u16>()', 'q_v8i16']
      - ['*const u32', uint32x2_t,  'vldr',      'neon,v7',  'crate::mem::align_of::<u32>()', '_v2i32' ]
      - ['*const u32', uint32x4_t,  '"vld1.32"', 'neon,v7',  'crate::mem::align_of::<u32>()', 'q_v4i32']
      - ['*const u64', uint64x1_t,  'vldr',      'neon,v7',  'crate::mem::align_of::<u64>()', '_v1i64' ]
      - ['*const u64', uint64x2_t,  '"vld1.64"', 'neon,v7',  'crate::mem::align_of::<u64>()', 'q_v2i64']
      - ['*const p8',  poly8x8_t,   '"vld1.8"',  'neon,v7',  'crate::mem::align_of::<p8>()',  '_v8i8'  ]
      - ['*const p8',  poly8x16_t,  '"vld1.8"',  'neon,v7',  'crate::mem::align_of::<p8>()',  'q_v16i8']
      - ['*const p16', poly16x4_t,  '"vld1.16"', 'neon,v7',  'crate::mem::align_of::<p16>()', '_v4i16' ]
      - ['*const p16', poly16x8_t,  '"vld1.16"', 'neon,v7',  'crate::mem::align_of::<p16>()', 'q_v8i16']
      - ['*const p64', poly64x2_t,  '"vld1.64"', 'neon,aes', 'crate::mem::align_of::<p64>()', 'q_v2i64']
      - ['*const f32', float32x2_t, 'vldr',      'neon,v7',  'crate::mem::align_of::<f32>()', '_v2f32' ]
      - ['*const f32', float32x4_t, '"vld1.32"', 'neon,v7',  'crate::mem::align_of::<f32>()', 'q_v4f32']
    compose:
      - Const:
        - ALIGN
        - "i32"
        - "{type[4]} as i32"
      - FnCall:
        - transmute
        - - FnCall:
              - "vld1{type[5]}"
              - ['ptr as *const i8']
              - ['ALIGN']

  - name: "vld1{neon_type[1].no}"
    doc: "Load multiple single-element structures to one, two, three, or four registers."
    arguments: ["ptr: {type[0]}"]
    return_type: "{neon_type[1]}"
    safety:
      unsafe: [neon]
    attr:
      - *target-is-arm
      - FnCall: [target_feature, ['enable = "{type[3]}"']]
      - *neon-fp16
      - *neon-unstable-f16
      - *target-not-arm64ec
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['{type[2]}']]}]]
    types:
      - ['*const f16', float16x4_t, '"vld1.16"', 'neon,v7', 'crate::mem::align_of::<f16>() as i32', '_v4f16']
      - ['*const f16', float16x8_t, '"vld1.16"', 'neon,v7', 'crate::mem::align_of::<f16>() as i32', 'q_v8f16']
    compose:
      - FnCall:
        - transmute
        - - FnCall:
              - "vld1{type[5]}"
              - - 'ptr as *const i8'
                - '{type[4]}'

  - name: "vld1{neon_type[1].no}"
    doc: "Load multiple single-element structures to one, two, three, or four registers."
    arguments: ["ptr: {type[0]}"]
    return_type: "{neon_type[1]}"
    safety:
      unsafe: [neon]
    attr:
      - *target-is-arm
      - *neon-aes
      - *neon-arm-unstable
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['vldr']]}]]
    types:
      - ['*const p64', poly64x1_t]
    compose:
      # Inlining seems broken for 'fn vld1_v1i64', this "fixes" it
      - Let: [a, '*const i8', 'ptr as *const i8']
      - Let: [b, i32, 'crate::mem::align_of::<p64>() as i32']
      - 'unsafe extern "unadjusted" {{ #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vld1.v1i64")] fn _vld1_v1i64(a: *const i8, b: i32) -> int64x1_t; }} transmute(_vld1_v1i64(a, b))'

  - name: "vtbx1"
    visibility: private
    doc: "Extended table look-up"
    arguments: ["a: {neon_type}", "b: {neon_type}", "c: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *enable-v7
      - *target-is-arm
      - *neon-arm-unstable
    assert_instr: [vtbx]
    safety: safe
    types:
      - "int8x8_t"
    compose:
      - LLVMLink:
          name: "vtbx1"
          links:
            - link: "llvm.arm.neon.vtbx1"
              arch: arm

  - name: "vtbx1_s8"
    doc: "Extended table look-up"
    arguments: ["a: {neon_type}", "b: {neon_type}", "c: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *enable-v7
      - *target-is-arm
      - *neon-arm-unstable
    assert_instr: [vtbx]
    safety: safe
    types:
      - int8x8_t
    compose:
      - FnCall: [vtbx1, [a, b, c]]

  - name: "vtbx1{neon_type.no}"
    doc: "Extended table look-up"
    arguments: ["a: {neon_type}", "b: {neon_type}", "c: uint8x8_t"]
    return_type: "{neon_type}"
    attr:
      - *enable-v7
      - *target-is-arm
      - *neon-arm-unstable
    assert_instr: [vtbx]
    safety: safe
    types:
      - uint8x8_t
      - poly8x8_t
    compose:
      - FnCall: 
          - transmute
          - - FnCall: 
                - vtbx1
                - - FnCall: [transmute, [a]]
                  - FnCall: [transmute, [b]]
                  - FnCall: [transmute, [c]]

  - name: "vtbx2"
    visibility: private
    doc: "Extended table look-up"
    arguments: ["a: {neon_type}", "b: {neon_type}", "c: {neon_type}", "d: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *enable-v7
      - *target-is-arm
      - *neon-arm-unstable
    assert_instr: [vtbx]
    safety: safe
    types:
      - "int8x8_t"
    compose:
      - LLVMLink:
          name: "vtbx2"
          links:
            - link: "llvm.arm.neon.vtbx2"
              arch: arm

  - name: "vtbx2_s8"
    doc: "Extended table look-up"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}", "c: {neon_type[0]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *enable-v7
      - *target-is-arm
      - *neon-arm-unstable
    assert_instr: [vtbx]
    safety: safe
    types:
      - [int8x8_t, int8x8x2_t]
    compose:
      - FnCall: [vtbx2, [a, 'b.0', 'b.1', c]]

  - name: "vtbx2{neon_type[0].no}"
    doc: "Extended table look-up"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}", "c: {neon_type[2]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *enable-v7
      - *target-is-arm
      - *neon-arm-unstable
    assert_instr: [vtbx]
    safety: safe
    types:
      - [uint8x8_t, uint8x8x2_t, uint8x8_t]
      - [poly8x8_t, poly8x8x2_t, uint8x8_t]
    compose:
      - FnCall: 
          - transmute
          - - FnCall: 
                - vtbx2
                - - FnCall: [transmute, [a]]
                  - FnCall: [transmute, ['b.0']]
                  - FnCall: [transmute, ['b.1']]
                  - FnCall: [transmute, [c]]

  - name: "vtbx3"
    visibility: private
    doc: "Extended table look-up"
    arguments: ["a: {neon_type}", "b: {neon_type}", "c: {neon_type}", "d: {neon_type}", "e: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *enable-v7
      - *target-is-arm
      - *neon-arm-unstable
    assert_instr: [vtbx]
    safety: safe
    types:
      - "int8x8_t"
    compose:
      - LLVMLink:
          name: "vtbx3"
          links:
            - link: "llvm.arm.neon.vtbx3"
              arch: arm

  - name: "vtbx3_s8"
    doc: "Extended table look-up"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}", "c: {neon_type[0]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *enable-v7
      - *target-is-arm
      - *neon-arm-unstable
    assert_instr: [vtbx]
    safety: safe
    types:
      - [int8x8_t, int8x8x3_t]
    compose:
      - FnCall: [vtbx3, [a, 'b.0', 'b.1', 'b.2', c]]

  - name: "vtbx3{neon_type[0].no}"
    doc: "Extended table look-up"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}", "c: {neon_type[2]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *enable-v7
      - *target-is-arm
      - *neon-arm-unstable
    assert_instr: [vtbx]
    safety: safe
    types:
      - [uint8x8_t, uint8x8x3_t, uint8x8_t]
      - [poly8x8_t, poly8x8x3_t, uint8x8_t]
    compose:
      - FnCall: 
          - transmute
          - - FnCall: 
                - vtbx3
                - - FnCall: [transmute, [a]]
                  - FnCall: [transmute, ['b.0']]
                  - FnCall: [transmute, ['b.1']]
                  - FnCall: [transmute, ['b.2']]
                  - FnCall: [transmute, [c]]

  - name: "vtbx4"
    visibility: private
    doc: "Extended table look-up"
    arguments: ["a: {neon_type}", "b: {neon_type}", "c: {neon_type}", "d: {neon_type}", "e: {neon_type}", "f: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *enable-v7
      - *target-is-arm
      - *neon-arm-unstable
    assert_instr: [vtbx]
    safety: safe
    types:
      - "int8x8_t"
    compose:
      - LLVMLink:
          name: "vtbx4"
          links:
            - link: "llvm.arm.neon.vtbx4"
              arch: arm

  - name: "vtbx4{neon_type[0].noq}"
    doc: "Extended table look-up"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}", "c: {neon_type[2]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *enable-v7
      - *target-is-arm
      - *neon-arm-unstable
    assert_instr: [vtbx]
    safety: safe
    types:
      - ["uint8x8_t", "uint8x8x4_t", "uint8x8_t"]
      - ["poly8x8_t", "poly8x8x4_t", "uint8x8_t"]
    compose:
      - FnCall: 
          - "transmute"
          - - FnCall:
               - vtbx4
               - - FnCall: [transmute, [a]]
                 - FnCall: [transmute, ["b.0"]]
                 - FnCall: [transmute, ["b.1"]]
                 - FnCall: [transmute, ["b.2"]]
                 - FnCall: [transmute, ["b.3"]]
                 - FnCall: [transmute, [c]]

  - name: "vtbx4{neon_type[0].noq}"
    doc: "Extended table look-up"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}", "c: {neon_type[0]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *enable-v7
      - *target-is-arm
      - *neon-arm-unstable
    assert_instr: [vtbx]
    safety: safe
    types:
      - ["int8x8_t", "int8x8x4_t"]
    big_endian_inverse: true
    compose:
       - FnCall:
           - vtbx4
           - - a
             - FnCall: [transmute, ["b.0"]]
             - FnCall: [transmute, ["b.1"]]
             - FnCall: [transmute, ["b.2"]]
             - FnCall: [transmute, ["b.3"]]
             - c

  - name: "vld4{neon_type[1].nox}"
    doc: Load single 4-element structure and replicate to all lanes of two registers
    arguments: ["a: {type[0]}"]
    return_type: "{type[1]}"
    attr:
      - *neon-v7
      - *target-is-arm
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vld4]]}]]
      - *neon-fp16
      - *neon-unstable-f16
      - *target-not-arm64ec
    safety:
      unsafe: [neon]
    types:
      - ["*const f16", float16x4x4_t, f16]
      - ["*const f16", float16x8x4_t, f16]
    compose:
      - LLVMLink:
          name: "vld4.{neon_type[1]}"
          arguments:
            - "ptr: {type[0]}"
            - "size: i32"
          links:
            - link: "llvm.arm.neon.vld4.v{neon_type[1].lane}{type[2]}.p0"
              arch: arm
      - FnCall:
          - "_vld4{neon_type[1].nox}"
          - - "a as _"
            - "2"

  - name: "vld4{neon_type[1].nox}"
    doc: Load single 4-element structure and replicate to all lanes of two registers
    arguments: ["a: {type[0]}"]
    return_type: "{type[1]}"
    attr:
      - *target-not-arm
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ld4]]}]]
      - *neon-fp16
      - *neon-unstable-f16
      - *target-not-arm64ec
    safety:
      unsafe: [neon]
    types:
      - ["*const f16", float16x4x4_t, f16, "4"]
      - ["*const f16", float16x8x4_t, f16, "8"]
    compose:
      - FnCall: ["crate::core_arch::macros::deinterleaving_load!", [{ Type: "{type[2]}" }, "{type[3]}", "4", a], [], true]

  - name: "vld4{neon_type[1].dup_nox}"
    doc: Load single 4-element structure and replicate to all lanes of two registers
    arguments: ["a: {type[0]}"]
    return_type: "{type[1]}"
    attr:
      - *neon-v7
      - *target-is-arm
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vld4]]}]]
      - *neon-fp16
      - *neon-unstable-f16
      - *target-not-arm64ec
    safety:
      unsafe: [neon]
    types:
      - ["*const f16", float16x4x4_t, f16]
      - ["*const f16", float16x8x4_t, f16]
    compose:
      - LLVMLink:
          name: "vld4dup.{neon_type[1]}"
          arguments:
            - "ptr: {type[0]}"
            - "size: i32"
          links:
            - link: "llvm.arm.neon.vld4dup.v{neon_type[1].lane}{type[2]}.p0"
              arch: arm
      - FnCall:
          - "_vld4{neon_type[1].dup_nox}"
          - - "a as _"
            - "2"


  - name: "vld4{neon_type[1].dup_nox}"
    doc: Load single 4-element structure and replicate to all lanes of two registers
    arguments: ["a: {type[0]}"]
    return_type: "{type[1]}"
    attr:
      - *target-not-arm
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ld4r]]}]]
      - *neon-fp16
      - *neon-unstable-f16
      - *target-not-arm64ec
    safety:
      unsafe: [neon]
    types:
      - ["*const f16", float16x4x4_t, f16]
      - ["*const f16", float16x8x4_t, f16]
    compose:
      - LLVMLink:
          name: "vld4dup.{neon_type[1]}"
          arguments:
            - "ptr: {type[0]}"
          links:
            - link: "llvm.aarch64.neon.ld4r.v{neon_type[1].lane}{type[2]}.p0"
              arch: aarch64,arm64ec
      - FnCall:
          - "_vld4{neon_type[1].dup_nox}"
          - - "a as _"


  - name: "vld4{neon_type[1].lane_nox}"
    doc: Load multiple 4-element structures to two registers
    arguments: ["a: {type[0]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *enable-v7
      - *target-is-arm
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['vld4', 'LANE = 0']]}]]
      - FnCall: [rustc_legacy_const_generics, ["2"]]
      - *neon-fp16
      - *neon-unstable-f16
      - *target-not-arm64ec
    static_defs:
      - "const LANE: i32"
    safety:
      unsafe: [neon]
    types:
      - ["*const f16", float16x4x4_t, f16, float16x4_t, "2"]
      - ["*const f16", float16x8x4_t, f16, float16x8_t, "3"]
    compose:
      - FnCall:
          - "static_assert_uimm_bits!"
          - - LANE
            - "{type[4]}"
      - LLVMLink:
          name: "vld4.{neon_type[1]}"
          arguments:
            - "ptr: *const f16"
            - "a: {neon_type[3]}"
            - "b: {neon_type[3]}"
            - "c: {neon_type[3]}"
            - "d: {neon_type[3]}"
            - "n: i32"
            - "size: i32"
          links:
            - link: "llvm.arm.neon.vld4lane.v{neon_type[1].lane}{type[2]}.p0"
              arch: arm
      - FnCall:
          - "_vld4{neon_type[1].lane_nox}"
          - - "a as _"
            - "b.0"
            - "b.1"
            - "b.2"
            - "b.3"
            - "LANE"
            - "2"


  - name: "vld4{neon_type[1].lane_nox}"
    doc: Load multiple 4-element structures to two registers
    arguments: ["a: {type[0]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *target-not-arm
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ld4, 'LANE = 0']]}]]
      - FnCall: [rustc_legacy_const_generics, ["2"]]
      - *neon-fp16
      - *neon-unstable-f16
      - *target-not-arm64ec
    static_defs:
      - "const LANE: i32"
    safety:
      unsafe: [neon]
    types:
      - ["*const f16", float16x4x4_t, f16, float16x4_t, "2"]
      - ["*const f16", float16x8x4_t, f16, float16x8_t, "3"]
    compose:
      - FnCall:
          - "static_assert_uimm_bits!"
          - - LANE
            - "{type[4]}"
      - LLVMLink:
          name: "vld4.{neon_type[1]}"
          arguments:
            - "a: {neon_type[3]}"
            - "b: {neon_type[3]}"
            - "c: {neon_type[3]}"
            - "d: {neon_type[3]}"
            - "n: i64"
            - "ptr: *const f16"
          links:
            - link: "llvm.aarch64.neon.ld4lane.v{neon_type[1].lane}{type[2]}.p0"
              arch: aarch64,arm64ec
      - FnCall:
          - "_vld4{neon_type[1].lane_nox}"
          - - "b.0"
            - "b.1"
            - "b.2"
            - "b.3"
            - "LANE as i64"
            - "a as _"

  - name: "vcombine{neon_type[0].noq}"
    doc: Join two smaller vectors into a single larger vector
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [nop]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [float32x2_t, float32x4_t, '[0, 1, 2, 3]']
      - [poly8x8_t, poly8x16_t, '[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]']
      - [poly16x4_t, poly16x8_t, '[0, 1, 2, 3, 4, 5, 6, 7]']
      - [int8x8_t, int8x16_t, '[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]']
      - [int16x4_t, int16x8_t, '[0, 1, 2, 3, 4, 5, 6, 7]']
      - [int32x2_t, int32x4_t, '[0, 1, 2, 3]']
      - [int64x1_t, int64x2_t, '[0, 1]']
      - [uint8x8_t, uint8x16_t, '[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]']
      - [uint16x4_t, uint16x8_t, '[0, 1, 2, 3, 4, 5, 6, 7]']
      - [uint32x2_t, uint32x4_t, '[0, 1, 2, 3]']
      - [uint64x1_t, uint64x2_t, '[0, 1]']
      - [poly64x1_t, poly64x2_t, '[0, 1]']
    compose:
      - FnCall: [simd_shuffle!, [a, b, '{type[2]}']]

  - name: "vaeseq_u8"
    doc: "AES single round encryption."
    arguments: ["data: {neon_type}", "key: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - FnCall: [target_feature, ['enable = "aes"']]
      - *neon-v8
      - FnCall: [cfg_attr, [test, { FnCall: [assert_instr, [aese]] }]]
      - *neon-cfg-arm-unstable
      - FnCall: [cfg_attr, [*not-arm, { FnCall: [stable, ['feature = "aarch64_neon_crypto_intrinsics"', 'since = "1.72.0"']] }]]
    safety: safe
    types:
      - uint8x16_t
    compose:
      - LLVMLink:
          name: "vaeseq_u8"
          links:
            - link: "llvm.aarch64.crypto.aese"
              arch: aarch64,arm64ec
            - link: "llvm.arm.neon.aese"
              arch: arm

  - name: "vaesdq_u8"
    doc: "AES single round encryption."
    arguments: ["data: {neon_type}", "key: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - FnCall: [target_feature, ['enable = "aes"']]
      - *neon-v8
      - FnCall: [cfg_attr, [test, { FnCall: [assert_instr, [aesd]] }]]
      - *neon-cfg-arm-unstable
      - FnCall: [cfg_attr, [*not-arm, { FnCall: [stable, ['feature = "aarch64_neon_crypto_intrinsics"', 'since = "1.72.0"']] }]]
    safety: safe
    types:
      - uint8x16_t
    compose:
      - LLVMLink:
          name: "vaesdq_u8"
          links:
            - link: "llvm.aarch64.crypto.aesd"
              arch: aarch64,arm64ec
            - link: "llvm.arm.neon.aesd"
              arch: arm

  - name: "vaesmcq_u8"
    doc: "AES mix columns."
    arguments: ["data: {neon_type[0]}"]
    return_type: "{neon_type[0]}"
    attr:
      - FnCall: [target_feature, ['enable = "aes"']]
      - *neon-v8
      - FnCall: [cfg_attr, [test, { FnCall: [assert_instr, ["{type[1]}"]] }]]
      - *neon-cfg-arm-unstable
      - FnCall: [cfg_attr, [*not-arm, { FnCall: [stable, ['feature = "aarch64_neon_crypto_intrinsics"', 'since = "1.72.0"']] }]]
    safety: safe
    types:
      - [uint8x16_t, "aesmc"]
    compose:
      - LLVMLink:
          name: "vaesmcq_u8"
          links:
            - link: "llvm.aarch64.crypto.{type[1]}"
              arch: aarch64,arm64ec
            - link: "llvm.arm.neon.{type[1]}"
              arch: arm

  - name: "vaesimcq_u8"
    doc: "AES inverse mix columns."
    arguments: ["data: {neon_type[0]}"]
    return_type: "{neon_type[0]}"
    attr:
      - FnCall: [target_feature, ['enable = "aes"']]
      - *neon-v8
      - FnCall: [cfg_attr, [test, { FnCall: [assert_instr, ["{type[1]}"]] }]]
      - *neon-cfg-arm-unstable
      - FnCall: [cfg_attr, [*not-arm, { FnCall: [stable, ['feature = "aarch64_neon_crypto_intrinsics"', 'since = "1.72.0"']] }]]
    safety: safe
    types:
      - [uint8x16_t, "aesimc"]
    compose:
      - LLVMLink:
          name: "vaesimcq_u8"
          links:
            - link: "llvm.aarch64.crypto.{type[1]}"
              arch: aarch64,arm64ec
            - link: "llvm.arm.neon.{type[1]}"
              arch: arm

  - name: "vsha1h_u32"
    doc: "SHA1 fixed rotate."
    arguments: ["hash_e: {type[0]}"]
    return_type: "{type[0]}"
    attr:
      - FnCall: [target_feature, ['enable = "sha2"']]
      - *neon-v8
      - FnCall: [cfg_attr, [test, { FnCall: [assert_instr, ["{type[1]}"]] }]]
      - *neon-cfg-arm-unstable
      - FnCall: [cfg_attr, [*not-arm, { FnCall: [stable, ['feature = "aarch64_neon_crypto_intrinsics"', 'since = "1.72.0"']] }]]
    safety: safe
    types:
      - [u32, "sha1h"]
    compose:
      - LLVMLink:
          name: "vsha1h_u32"
          links:
            - link: "llvm.aarch64.crypto.{type[1]}"
              arch: aarch64,arm64ec
            - link: "llvm.arm.neon.{type[1]}"
              arch: arm

  - name: "vsha1cq_u32"
    doc: "SHA1 hash update accelerator, choose."
    arguments: ["hash_abcd: {neon_type[2]}", "hash_e: {type[0]}", "wk: {neon_type[2]}"]
    return_type: "{neon_type[2]}"
    attr:
      - FnCall: [target_feature, ['enable = "sha2"']]
      - *neon-v8
      - FnCall: [cfg_attr, [test, { FnCall: [assert_instr, ["{type[1]}"]] }]]
      - *neon-cfg-arm-unstable
      - FnCall: [cfg_attr, [*not-arm, { FnCall: [stable, ['feature = "aarch64_neon_crypto_intrinsics"', 'since = "1.72.0"']] }]]
    safety: safe
    types:
      - [u32, "sha1c", "uint32x4_t"]
    compose:
      - LLVMLink:
          name: "vsha1cq_u32"
          links:
            - link: "llvm.aarch64.crypto.{type[1]}"
              arch: aarch64,arm64ec
            - link: "llvm.arm.neon.{type[1]}"
              arch: arm

  - name: "vsha1mq_u32"
    doc: "SHA1 hash update accelerator, majority"
    arguments: ["hash_abcd: {neon_type[2]}", "hash_e: {type[0]}", "wk: {neon_type[2]}"]
    return_type: "{neon_type[2]}"
    attr:
      - FnCall: [target_feature, ['enable = "sha2"']]
      - *neon-v8
      - FnCall: [cfg_attr, [test, { FnCall: [assert_instr, ["{type[1]}"]] }]]
      - *neon-cfg-arm-unstable
      - FnCall: [cfg_attr, [*not-arm, { FnCall: [stable, ['feature = "aarch64_neon_crypto_intrinsics"', 'since = "1.72.0"']] }]]
    safety: safe
    types:
      - [u32, "sha1m", "uint32x4_t"]
    compose:
      - LLVMLink:
          name: "vsha1mq_u32"
          links:
            - link: "llvm.aarch64.crypto.{type[1]}"
              arch: aarch64,arm64ec
            - link: "llvm.arm.neon.{type[1]}"
              arch: arm

  - name: "vsha1pq_u32"
    doc: "SHA1 hash update accelerator, parity"
    arguments: ["hash_abcd: {neon_type[2]}", "hash_e: {type[0]}", "wk: {neon_type[2]}"]
    return_type: "{neon_type[2]}"
    attr:
      - FnCall: [target_feature, ['enable = "sha2"']]
      - *neon-v8
      - FnCall: [cfg_attr, [test, { FnCall: [assert_instr, ["{type[1]}"]] }]]
      - *neon-cfg-arm-unstable
      - FnCall: [cfg_attr, [*not-arm, { FnCall: [stable, ['feature = "aarch64_neon_crypto_intrinsics"', 'since = "1.72.0"']] }]]
    safety: safe
    types:
      - [u32, "sha1p", "uint32x4_t"]
    compose:
      - LLVMLink:
          name: "vsha1pq_u32"
          links:
            - link: "llvm.aarch64.crypto.{type[1]}"
              arch: aarch64,arm64ec
            - link: "llvm.arm.neon.{type[1]}"
              arch: arm

  - name: "vsha1su0q_u32"
    doc: "SHA1 schedule update accelerator, first part."
    arguments: ["w0_3: {neon_type[0]}", "w4_7: {neon_type[0]}", "w8_11: {neon_type[0]}"]
    return_type: "{neon_type[0]}"
    attr:
      - FnCall: [target_feature, ['enable = "sha2"']]
      - *neon-v8
      - FnCall: [cfg_attr, [test, { FnCall: [assert_instr, ["{type[1]}"]] }]]
      - *neon-cfg-arm-unstable
      - FnCall: [cfg_attr, [*not-arm, { FnCall: [stable, ['feature = "aarch64_neon_crypto_intrinsics"', 'since = "1.72.0"']] }]]
    safety: safe
    types:
      - [uint32x4_t, "sha1su0"]
    compose:
      - LLVMLink:
          name: "vsha1su0q_u32"
          links:
            - link: "llvm.aarch64.crypto.{type[1]}"
              arch: aarch64,arm64ec
            - link: "llvm.arm.neon.{type[1]}"
              arch: arm

  - name: "vsha1su1q_u32"
    doc: "SHA1 schedule update accelerator, second part."
    arguments: ["tw0_3: {neon_type[0]}", "w12_15: {neon_type[0]}"]
    return_type: "{neon_type[0]}"
    attr:
      - FnCall: [target_feature, ['enable = "sha2"']]
      - *neon-v8
      - FnCall: [cfg_attr, [test, { FnCall: [assert_instr, ["{type[1]}"]] }]]
      - *neon-cfg-arm-unstable
      - FnCall: [cfg_attr, [*not-arm, { FnCall: [stable, ['feature = "aarch64_neon_crypto_intrinsics"', 'since = "1.72.0"']] }]]
    safety: safe
    types:
      - [uint32x4_t, "sha1su1"]
    compose:
      - LLVMLink:
          name: "vsha1su0q_u32"
          links:
            - link: "llvm.aarch64.crypto.{type[1]}"
              arch: aarch64,arm64ec
            - link: "llvm.arm.neon.{type[1]}"
              arch: arm

  - name: "vsha256hq_u32"
    doc: "SHA1 schedule update accelerator, first part."
    arguments: ["hash_abcd: {neon_type[0]}", "hash_efgh: {neon_type[0]}", "wk: {neon_type[0]}"]
    return_type: "{neon_type[0]}"
    attr:
      - FnCall: [target_feature, ['enable = "sha2"']]
      - *neon-v8
      - FnCall: [cfg_attr, [test, { FnCall: [assert_instr, ["{type[1]}"]] }]]
      - *neon-cfg-arm-unstable
      - FnCall: [cfg_attr, [*not-arm, { FnCall: [stable, ['feature = "aarch64_neon_crypto_intrinsics"', 'since = "1.72.0"']] }]]
    safety: safe
    types:
      - [uint32x4_t, "sha256h"]
    compose:
      - LLVMLink:
          name: "vsha256hq_u32"
          links:
            - link: "llvm.aarch64.crypto.{type[1]}"
              arch: aarch64,arm64ec
            - link: "llvm.arm.neon.{type[1]}"
              arch: arm

  - name: "vsha256h2q_u32"
    doc: "SHA1 schedule update accelerator, upper part."
    arguments: ["hash_abcd: {neon_type[0]}", "hash_efgh: {neon_type[0]}", "wk: {neon_type[0]}"]
    return_type: "{neon_type[0]}"
    attr:
      - FnCall: [target_feature, ['enable = "sha2"']]
      - *neon-v8
      - FnCall: [cfg_attr, [test, { FnCall: [assert_instr, ["{type[1]}"]] }]]
      - *neon-cfg-arm-unstable
      - FnCall: [cfg_attr, [*not-arm, { FnCall: [stable, ['feature = "aarch64_neon_crypto_intrinsics"', 'since = "1.72.0"']] }]]
    safety: safe
    types:
      - [uint32x4_t, "sha256h2"]
    compose:
      - LLVMLink:
          name: "vsha256h2q_u32"
          links:
            - link: "llvm.aarch64.crypto.{type[1]}"
              arch: aarch64,arm64ec
            - link: "llvm.arm.neon.{type[1]}"
              arch: arm

  - name: "vsha256su0q_u32"
    doc: "SHA256 schedule update accelerator, first part."
    arguments: ["w0_3: {neon_type[0]}", "w4_7: {neon_type[0]}"]
    return_type: "{neon_type[0]}"
    attr:
      - FnCall: [target_feature, ['enable = "sha2"']]
      - *neon-v8
      - FnCall: [cfg_attr, [test, { FnCall: [assert_instr, ["{type[1]}"]] }]]
      - *neon-cfg-arm-unstable
      - FnCall: [cfg_attr, [*not-arm, { FnCall: [stable, ['feature = "aarch64_neon_crypto_intrinsics"', 'since = "1.72.0"']] }]]
    safety: safe
    types:
      - [uint32x4_t, "sha256su0"]
    compose:
      - LLVMLink:
          name: "vsha256su0q_u32"
          links:
            - link: "llvm.aarch64.crypto.{type[1]}"
              arch: aarch64,arm64ec
            - link: "llvm.arm.neon.{type[1]}"
              arch: arm

  - name: "vsha256su1q_u32"
    doc: "SHA256 schedule update accelerator, second part."
    arguments: ["tw0_3: {neon_type[0]}", "w8_11: {neon_type[0]}", "w12_15: {neon_type[0]}"]
    return_type: "{neon_type[0]}"
    attr:
      - FnCall: [target_feature, ['enable = "sha2"']]
      - *neon-v8
      - FnCall: [cfg_attr, [test, { FnCall: [assert_instr, ["{type[1]}"]] }]]
      - *neon-cfg-arm-unstable
      - FnCall: [cfg_attr, [*not-arm, { FnCall: [stable, ['feature = "aarch64_neon_crypto_intrinsics"', 'since = "1.72.0"']] }]]
    safety: safe
    types:
      - [uint32x4_t, "sha256su1"]
    compose:
      - LLVMLink:
          name: "vsha256su1q_u32"
          links:
            - link: "llvm.aarch64.crypto.{type[1]}"
              arch: aarch64,arm64ec
            - link: "llvm.arm.neon.{type[1]}"
              arch: arm

  - name: "__crc32b"
    doc: "CRC32 single round checksum for bytes (8 bits)."
    arguments: ["crc: {type[0]}", "data: {type[1]}"]
    return_type: "{type[0]}"
    attr:
      - FnCall: [target_feature, ['enable = "crc"']]
      - *neon-v8
      - FnCall: [cfg_attr, [test, { FnCall: [assert_instr, ["crc32b"]] }]]
      - *arm-crc-unstable
      - *aarch64-crc-stable
    safety: safe
    types:
      - [u32, u8]
    compose:
      - LLVMLink:
          name: "crc32b"
          arguments:
            - "crc: u32"
            - "data: u32"
          links:
            - link: "llvm.aarch64.crc32b"
              arch: aarch64,arm64ec
            - link: "llvm.arm.crc32b"
              arch: arm
      - FnCall: ["___crc32b", ["crc", "data as u32"], [], true]

  - name: "__crc32h"
    doc: "CRC32 single round checksum for bytes (16 bits)."
    arguments: ["crc: {type[0]}", "data: {type[1]}"]
    return_type: "{type[0]}"
    attr:
      - FnCall: [target_feature, ['enable = "crc"']]
      - *neon-v8
      - FnCall: [cfg_attr, [test, { FnCall: [assert_instr, ["crc32h"]] }]]
      - *arm-crc-unstable
      - *aarch64-crc-stable
    safety: safe
    types:
      - [u32, u16]
    compose:
      - LLVMLink:
          name: "crc32h"
          arguments:
            - "crc: u32"
            - "data: u32"
          links:
            - link: "llvm.aarch64.crc32h"
              arch: aarch64,arm64ec
            - link: "llvm.arm.crc32h"
              arch: arm
      - FnCall: ["___crc32h", ["crc", "data as u32"], [], true]

  - name: "__crc32w"
    doc: "CRC32 single round checksum for bytes (32 bits)."
    arguments: ["crc: {type}", "data: {type}"]
    return_type: "{type}"
    attr:
      - FnCall: [target_feature, ['enable = "crc"']]
      - *neon-v8
      - FnCall: [cfg_attr, [test, { FnCall: [assert_instr, ["crc32w"]] }]]
      - *arm-crc-unstable
      - *aarch64-crc-stable
    safety: safe
    types:
      - u32
    compose:
      - LLVMLink:
          name: "crc32w"
          links:
            - link: "llvm.aarch64.crc32w"
              arch: aarch64,arm64ec
            - link: "llvm.arm.crc32w"
              arch: arm

  - name: "__crc32cb"
    doc: "CRC32-C single round checksum for bytes (8 bits)."
    arguments: ["crc: {type[0]}", "data: {type[1]}"]
    return_type: "{type[0]}"
    attr:
      - FnCall: [target_feature, ['enable = "crc"']]
      - *neon-v8
      - FnCall: [cfg_attr, [test, { FnCall: [assert_instr, ["crc32cb"]] }]]
      - *arm-crc-unstable
      - *aarch64-crc-stable
    safety: safe
    types:
      - [u32, u8]
    compose:
      - LLVMLink:
          name: "crc32cb"
          arguments:
            - "crc: u32"
            - "data: u32"
          links:
            - link: "llvm.aarch64.crc32cb"
              arch: aarch64,arm64ec
            - link: "llvm.arm.crc32cb"
              arch: arm
      - FnCall: ["___crc32cb", ["crc", "data as u32"], [], true]

  - name: "__crc32ch"
    doc: "CRC32-C single round checksum for bytes (16 bits)."
    arguments: ["crc: {type[0]}", "data: {type[1]}"]
    return_type: "{type[0]}"
    attr:
      - FnCall: [target_feature, ['enable = "crc"']]
      - *neon-v8
      - FnCall: [cfg_attr, [test, { FnCall: [assert_instr, ["crc32ch"]] }]]
      - *arm-crc-unstable
      - *aarch64-crc-stable
    safety: safe
    types:
      - [u32, u16]
    compose:
      - LLVMLink:
          name: "crc32ch"
          arguments:
            - "crc: u32"
            - "data: u32"
          links:
            - link: "llvm.aarch64.crc32ch"
              arch: aarch64,arm64ec
            - link: "llvm.arm.crc32ch"
              arch: arm
      - FnCall: ["___crc32ch", ["crc", "data as u32"], [], true]

  - name: "__crc32cw"
    doc: "CRC32-C single round checksum for bytes (32 bits)."
    arguments: ["crc: {type}", "data: {type}"]
    return_type: "{type}"
    attr:
      - FnCall: [target_feature, ['enable = "crc"']]
      - *neon-v8
      - FnCall: [cfg_attr, [test, { FnCall: [assert_instr, ["crc32cw"]] }]]
      - *arm-crc-unstable
      - *aarch64-crc-stable
    safety: safe
    types:
      - u32
    compose:
      - LLVMLink:
          name: "crc32cw"
          links:
            - link: "llvm.aarch64.crc32cw"
              arch: aarch64,arm64ec
            - link: "llvm.arm.crc32cw"
              arch: arm

  - name: "__crc32d"
    doc: "CRC32 single round checksum for quad words (64 bits)."
    arguments: ["crc: {type[0]}", "data: {type[1]}"]
    return_type: "{type[0]}"
    attr:
      - FnCall: [target_feature, ['enable = "crc"']]
      - *target-is-arm
      - FnCall: [cfg_attr, [test, { FnCall: [assert_instr, ["crc32w"]] }]]
      - *arm-crc-unstable
    safety: safe
    types:
      - [u32, u64]
    compose:
      # As the call to `__crc32` does not get inlined, we define an LLVM binding
      # here, which is the same as above, and call it directly which results 
      # in the correct instructions being generated
      - Let: [b, u32, '(data & 0xFFFFFFFF) as u32']
      - Let: [c, u32, '(data >> 32) as u32']
      - 'unsafe extern "unadjusted" {{ #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.crc32w")] fn ___crc32w(crc: u32, data: u32) -> u32;}} unsafe {{ ___crc32w(___crc32w(crc, b), c) }}'

  - name: "__crc32cd"
    doc: "CRC32-C single round checksum for quad words (64 bits)."
    arguments: ["crc: {type[0]}", "data: {type[1]}"]
    return_type: "{type[0]}"
    attr:
      - FnCall: [target_feature, ['enable = "crc"']]
      - *target-is-arm
      - FnCall: [cfg_attr, [test, { FnCall: [assert_instr, ["crc32cw"]] }]]
      - *arm-crc-unstable
    safety: safe
    types:
      - [u32, u64]
    compose:
      - Let: [b, u32, '(data & 0xFFFFFFFF) as u32']
      - Let: [c, u32, '(data >> 32) as u32']
      - 'unsafe extern "unadjusted" {{ #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.crc32cw")] fn ___crc32cw(crc: u32, data: u32) -> u32;}} unsafe {{ ___crc32cw(___crc32cw(crc, b), c) }}'

  - name: "vabs{neon_type.no}"
    doc: "Absolute value (wrapping)."
    arguments: ["a: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vabs]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [abs]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - int8x8_t
      - int16x4_t
      - int32x2_t
      - int8x16_t
      - int16x8_t
      - int32x4_t
    compose:
      - Let:
          - neg
          - "{neon_type}"
          - FnCall: [simd_neg, [a]]
      - Let:
          - mask
          - "{neon_type}"
          - FnCall: [simd_ge, [a, neg]]
      - FnCall: [simd_select, [mask, a, neg]]


  - name: "vpmin{neon_type.no}"
    doc: "Folding minimum of adjacent pairs"
    arguments: ["a: {neon_type}", "b: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vpmin]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [sminp]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - int8x8_t
      - int16x4_t
      - int32x2_t
    compose:
      - LLVMLink:
          name: "vabs{neon_type.no}"
          links:
            - link: "llvm.aarch64.neon.sminp.{neon_type}"
              arch: aarch64,arm64ec
            - link: "llvm.arm.neon.vpmins.{neon_type}"
              arch: arm

  - name: "vpmin{neon_type.no}"
    doc: "Folding minimum of adjacent pairs"
    arguments: ["a: {neon_type}", "b: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vpmin]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [uminp]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - uint8x8_t
      - uint16x4_t
      - uint32x2_t
    compose:
      - LLVMLink:
          name: "vabs{neon_type.no}"
          links:
            - link: "llvm.aarch64.neon.uminp.{neon_type}"
              arch: aarch64,arm64ec
            - link: "llvm.arm.neon.vpminu.{neon_type}"
              arch: arm

  - name: "vpmin{neon_type.no}"
    doc: "Folding minimum of adjacent pairs"
    arguments: ["a: {neon_type}", "b: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vpmin]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fminp]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - float32x2_t
    compose:
      - LLVMLink:
          name: "vabs{neon_type.no}"
          links:
            - link: "llvm.aarch64.neon.fminp.{neon_type}"
              arch: aarch64,arm64ec
            - link: "llvm.arm.neon.vpmins.{neon_type}"
              arch: arm

  - name: "vpmax{neon_type.no}"
    doc: "Folding maximum of adjacent pairs"
    arguments: ["a: {neon_type}", "b: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vpmax]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [smaxp]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - int8x8_t
      - int16x4_t
      - int32x2_t
    compose:
      - LLVMLink:
          name: "vabs{neon_type.no}"
          links:
            - link: "llvm.aarch64.neon.smaxp.{neon_type}"
              arch: aarch64,arm64ec
            - link: "llvm.arm.neon.vpmaxs.{neon_type}"
              arch: arm

  - name: "vpmax{neon_type.no}"
    doc: "Folding maximum of adjacent pairs"
    arguments: ["a: {neon_type}", "b: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vpmax]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [umaxp]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - uint8x8_t
      - uint16x4_t
      - uint32x2_t
    compose:
      - LLVMLink:
          name: "vabs{neon_type.no}"
          links:
            - link: "llvm.aarch64.neon.umaxp.{neon_type}"
              arch: aarch64,arm64ec
            - link: "llvm.arm.neon.vpmaxu.{neon_type}"
              arch: arm

  - name: "vpmax{neon_type.no}"
    doc: "Folding maximum of adjacent pairs"
    arguments: ["a: {neon_type}", "b: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vpmax]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [fmaxp]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - float32x2_t
    compose:
      - LLVMLink:
          name: "vabs{neon_type.no}"
          links:
            - link: "llvm.aarch64.neon.fmaxp.{neon_type}"
              arch: aarch64,arm64ec
            - link: "llvm.arm.neon.vpmaxs.{neon_type}"
              arch: arm

  - name: "vraddhn{neon_type[0].noq}"
    doc: "Rounding Add returning High Narrow."
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"{type[2]}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [raddhn]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [int16x8_t, int8x8_t, 'vraddhn.i16'] 
      - [int32x4_t, int16x4_t, 'vraddhn.i32'] 
      - [int64x2_t, int32x2_t, 'vraddhn.i64'] 
    compose:
      - LLVMLink:
          name: "vraddhn{neon_type[0].noq}"
          links:
            - link: "llvm.aarch64.neon.raddhn.{neon_type[1]}"
              arch: aarch64,arm64ec
            - link: "llvm.arm.neon.vraddhn.{neon_type[1]}"
              arch: arm

  - name: "vraddhn{neon_type[0].noq}"
    doc: "Rounding Add returning High Narrow."
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"{type[2]}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [raddhn]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [uint16x8_t, uint8x8_t, 'vraddhn.i16', int16x8_t] 
      - [uint32x4_t, uint16x4_t, 'vraddhn.i32', int32x4_t]  
      - [uint64x2_t, uint32x2_t, 'vraddhn.i64', int64x2_t]  
    compose:
      - FnCall:
          - transmute
          - - FnCall:
                - "vraddhn{neon_type[3].noq}"
                - - FnCall: [transmute, [a]]
                  - FnCall: [transmute, [b]]

  - name: "vraddhn_high{neon_type[1].noq}"
    doc: "Rounding Add returning High Narrow (high half)."
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}", "c: {neon_type[1]}"]
    return_type: "{neon_type[2]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"{type[3]}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [raddhn2]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [uint8x8_t , uint16x8_t, uint8x16_t, 'vraddhn.i16', int16x8_t, '[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]']
      - [uint16x4_t, uint32x4_t, uint16x8_t, 'vraddhn.i32', int32x4_t, '[0, 1, 2, 3, 4, 5, 6, 7]']
      - [uint32x2_t, uint64x2_t, uint32x4_t, 'vraddhn.i64', int64x2_t, '[0, 1, 2, 3]']
    compose:
      - Let:
          - x
          - "{neon_type[0]}"
          - FnCall:
              - transmute
              - - FnCall:
                    - "vraddhn{neon_type[4].noq}"
                    - - FnCall: [transmute, [b]]
                      - FnCall: [transmute, [c]]
      - FnCall: ["simd_shuffle!", [a, x, '{type[5]}']]

  - name: "vraddhn_high{neon_type[1].noq}"
    doc: "Rounding Add returning High Narrow (high half)."
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}", "c: {neon_type[1]}"]
    return_type: "{neon_type[2]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"{type[3]}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [raddhn2]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [int8x8_t , int16x8_t, int8x16_t, 'vraddhn.i16', '[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]']
      - [int16x4_t, int32x4_t, int16x8_t, 'vraddhn.i32', '[0, 1, 2, 3, 4, 5, 6, 7]']
      - [int32x2_t, int64x2_t, int32x4_t, 'vraddhn.i64', '[0, 1, 2, 3]']
    compose:
      - Let:
          - x
          - FnCall:
              - "vraddhn{neon_type[1].noq}"
              - - b
                - c
      - FnCall: ["simd_shuffle!", [a, x, '{type[4]}']]

  - name: "vpadd{neon_type.no}"
    doc: "Add pairwise."
    arguments: ["a: {neon_type}", "b: {neon_type}"]
    return_type: "{neon_type}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vpadd]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [addp]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - int8x8_t
      - int16x4_t
      - int32x2_t
    compose:
      - LLVMLink:
          name: "vpadd{neon_type.no}"
          links:
            - link: "llvm.aarch64.neon.addp.{neon_type}"
              arch: aarch64,arm64ec
            - link: "llvm.arm.neon.vpadd.{neon_type}"
              arch: arm

  - name: "vpadd{neon_type[0].no}"
    doc: "Add pairwise."
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vpadd]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [addp]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - [uint8x8_t, int8x8_t]
      - [uint16x4_t, int16x4_t]
      - [uint32x2_t, int32x2_t]
    compose:
      - FnCall:
          - transmute
          - - FnCall:
                - "vpadd{neon_type[1].no}"
                - - FnCall: [transmute, [a]]
                  - FnCall: [transmute, [b]]

  # This was not publically exposed
  - name: "priv_vpadal{neon_type[1].no}"
    visibility: private 
    doc: "Signed Add and Accumulate Long Pairwise."
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[0]}"
    safety: safe
    attr:
      - *target-is-arm
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['{type[2]}']]}]]
      - *neon-cfg-arm-unstable
    types:
      - [int16x4_t, int8x8_t,  '"vpadal.s8"']
      - [int32x2_t, int16x4_t, '"vpadal.s16"']
      - [int64x1_t, int32x2_t, '"vpadal.s32"']
      - [int16x8_t, int8x16_t, '"vpadal.s8"']
      - [int32x4_t, int16x8_t, '"vpadal.s16"']
      - [int64x2_t, int32x4_t, '"vpadal.s32"']
    compose:
      - LLVMLink:
          name: "vpadal{neon_type[1].no}"
          links:
            - link: "llvm.arm.neon.vpadals.{neon_type[0]}.{neon_type[1]}"
              arch: arm

  # This was not publically exposed
  - name: "priv_vpadal{neon_type[1].no}"
    visibility: private 
    doc: "Signed Add and Accumulate Long Pairwise."
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[0]}"
    safety: safe
    attr:
      - *target-is-arm
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['{type[2]}']]}]]
      - *neon-cfg-arm-unstable
    types:
      - [uint16x4_t, uint8x8_t , '"vpadal.u8"']
      - [uint32x2_t, uint16x4_t, '"vpadal.u16"']
      - [uint64x1_t, uint32x2_t, '"vpadal.u32"']
      - [uint16x8_t, uint8x16_t, '"vpadal.u8"']
      - [uint32x4_t, uint16x8_t, '"vpadal.u16"']
      - [uint64x2_t, uint32x4_t, '"vpadal.u32"']
    compose:
      - LLVMLink:
          name: "vpadal{neon_type[1].no}"
          links:
            - link: "llvm.arm.neon.vpadalu.{neon_type[0]}.{neon_type[1]}"
              arch: arm

  - name: "vpaddl{neon_type[0].no}"
    doc: "Signed Add and Accumulate Long Pairwise."
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    safety: safe
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['{type[2]}']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [saddlp]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    types:
      - [int8x8_t, int16x4_t , '"vpaddl.s8"']
      - [int16x4_t, int32x2_t, '"vpaddl.s16"']
      - [int32x2_t, int64x1_t, '"vpaddl.s32"']
      - [int8x16_t, int16x8_t, '"vpaddl.s8"']
      - [int16x8_t, int32x4_t, '"vpaddl.s16"']
      - [int32x4_t, int64x2_t, '"vpaddl.s32"']
    compose:
      - LLVMLink:
          name: "vpaddl{neon_type[1].no}"
          links:
            - link: "llvm.aarch64.neon.saddlp.{neon_type[1]}.{neon_type[0]}"
              arch: aarch64,arm64ec
            - link: "llvm.arm.neon.vpaddls.{neon_type[1]}.{neon_type[0]}"
              arch: arm

  - name: "vpaddl{neon_type[0].no}"
    doc: "Unsigned Add and Accumulate Long Pairwise."
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    safety: safe
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['{type[2]}']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [uaddlp]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    types:
      - [uint8x8_t, uint16x4_t , '"vpaddl.u8"']
      - [uint16x4_t, uint32x2_t, '"vpaddl.u16"']
      - [uint32x2_t, uint64x1_t, '"vpaddl.u32"']
      - [uint8x16_t, uint16x8_t, '"vpaddl.u8"']
      - [uint16x8_t, uint32x4_t, '"vpaddl.u16"']
      - [uint32x4_t, uint64x2_t, '"vpaddl.u32"']
    compose:
      - LLVMLink:
          name: "vpaddl{neon_type[1].no}"
          links:
            - link: "llvm.aarch64.neon.uaddlp.{neon_type[1]}.{neon_type[0]}"
              arch: aarch64,arm64ec
            - link: "llvm.arm.neon.vpaddlu.{neon_type[1]}.{neon_type[0]}"
              arch: arm

  - name: "vpadal{neon_type[1].no}"
    doc: "Signed Add and Accumulate Long Pairwise."
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[0]}"
    safety: safe
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"{type[2]}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [sadalp]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    types:
      - [int16x4_t, int8x8_t, 'vpadal.s8', 'let x: int16x4_t; #[cfg(target_arch = "arm")]   { x = priv_vpadal_s8(a, b); } #[cfg(any(target_arch = "aarch64", target_arch = "arm64ec"))]   unsafe { x = simd_add(vpaddl_s8(b), a);}']
      - [int32x2_t, int16x4_t, 'vpadal.s16', 'let x: int32x2_t; #[cfg(target_arch = "arm")] { x = priv_vpadal_s16(a, b); } #[cfg(any(target_arch = "aarch64", target_arch = "arm64ec"))] unsafe { x = simd_add(vpaddl_s16(b), a);}']
      - [int64x1_t, int32x2_t, 'vpadal.s32', 'let x: int64x1_t; #[cfg(target_arch = "arm")] { x = priv_vpadal_s32(a, b); } #[cfg(any(target_arch = "aarch64", target_arch = "arm64ec"))] unsafe { x = simd_add(vpaddl_s32(b), a);}']
      - [int16x8_t, int8x16_t, 'vpadal.s8', 'let x: int16x8_t; #[cfg(target_arch = "arm")]  { x = priv_vpadalq_s8(a, b); } #[cfg(any(target_arch = "aarch64", target_arch = "arm64ec"))]   unsafe { x = simd_add(vpaddlq_s8(b), a);}']
      - [int32x4_t, int16x8_t, 'vpadal.s16', 'let x: int32x4_t; #[cfg(target_arch = "arm")] { x = priv_vpadalq_s16(a, b); } #[cfg(any(target_arch = "aarch64", target_arch = "arm64ec"))] unsafe { x = simd_add(vpaddlq_s16(b), a);}']
      - [int64x2_t, int32x4_t, 'vpadal.s32', 'let x: int64x2_t; #[cfg(target_arch = "arm")] { x = priv_vpadalq_s32(a, b); } #[cfg(any(target_arch = "aarch64", target_arch = "arm64ec"))] unsafe { x = simd_add(vpaddlq_s32(b), a);}']
    compose:
      - Identifier: ['{type[3]}', Symbol]
      - Identifier: [x, Symbol]

  - name: "vpadal{neon_type[1].no}"
    doc: "Unsigned Add and Accumulate Long Pairwise."
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[0]}"
    safety: safe
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"{type[2]}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [uadalp]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    types:
      - [uint16x4_t, uint8x8_t, 'vpadal.u8', 'let x: uint16x4_t; #[cfg(target_arch = "arm")]   { x = priv_vpadal_u8(a, b); } #[cfg(any(target_arch = "aarch64", target_arch = "arm64ec"))] unsafe { x = simd_add(vpaddl_u8(b), a);}']
      - [uint32x2_t, uint16x4_t, 'vpadal.u16', 'let x: uint32x2_t; #[cfg(target_arch = "arm")] { x = priv_vpadal_u16(a, b); } #[cfg(any(target_arch = "aarch64", target_arch = "arm64ec"))] unsafe { x = simd_add(vpaddl_u16(b), a);}']
      - [uint64x1_t, uint32x2_t, 'vpadal.u32', 'let x: uint64x1_t; #[cfg(target_arch = "arm")] { x = priv_vpadal_u32(a, b); } #[cfg(any(target_arch = "aarch64", target_arch = "arm64ec"))] unsafe { x = simd_add(vpaddl_u32(b), a);}']
      - [uint16x8_t, uint8x16_t, 'vpadal.u8', 'let x: uint16x8_t; #[cfg(target_arch = "arm")]  { x = priv_vpadalq_u8(a, b); } #[cfg(any(target_arch = "aarch64", target_arch = "arm64ec"))] unsafe { x = simd_add(vpaddlq_u8(b), a);}']
      - [uint32x4_t, uint16x8_t, 'vpadal.u16', 'let x: uint32x4_t; #[cfg(target_arch = "arm")] { x = priv_vpadalq_u16(a, b); } #[cfg(any(target_arch = "aarch64", target_arch = "arm64ec"))] unsafe { x = simd_add(vpaddlq_u16(b), a);}']
      - [uint64x2_t, uint32x4_t, 'vpadal.u32', 'let x: uint64x2_t; #[cfg(target_arch = "arm")] { x = priv_vpadalq_u32(a, b); } #[cfg(any(target_arch = "aarch64", target_arch = "arm64ec"))] unsafe { x = simd_add(vpaddlq_u32(b), a);}']
    compose:
      - Identifier: ['{type[3]}', Symbol]
      - Identifier: [x, Symbol]

  - name: "vcnt{neon_type.no}"
    doc: "Population count per byte."
    arguments: ["a: {neon_type}"]
    return_type: "{neon_type}"
    safety: safe
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vcnt]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [cnt]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    types:
      - int8x8_t
      - int8x16_t
    compose:
      - FnCall: [simd_ctpop, [a]]

  - name: "vcnt{neon_type[0].no}"
    doc: "Population count per byte."
    arguments: ["a: {neon_type[0]}"]
    return_type: "{neon_type[0]}"
    safety: safe
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [vcnt]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [cnt]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    types:
      - [uint8x8_t,  int8x8_t]
      - [uint8x16_t, int8x16_t]
      - [poly8x8_t,  int8x8_t]
      - [poly8x16_t, int8x16_t]
    compose:
      - FnCall:
          - transmute
          - - FnCall:
                - "vcnt{neon_type[1].no}"
                - - FnCall:
                      - transmute
                      - - a

  - name: "vmmla{neon_type[0].no}"
    doc: "8-bit integer matrix multiply-accumulate"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}", "c: {neon_type[1]}"]
    return_type: "{neon_type[0]}"
    safety: safe
    attr:
      - *neon-i8mm
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [nop]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [smmla]]}]]
      - *neon-unstable-i8mm
      - *neon-cfg-arm-unstable
    types:
      - [int32x4_t, int8x16_t]
    compose:
      - LLVMLink:
          name: "vmmla{neon_type[0].no}"
          links:
            - link: "llvm.aarch64.neon.smmla.{neon_type[0]}.{neon_type[1]}"
              arch: aarch64,arm64ec
            - link: "llvm.arm.neon.smmla.{neon_type[0]}.{neon_type[1]}"
              arch: arm

  - name: "vmmla{neon_type[0].no}"
    doc: "8-bit integer matrix multiply-accumulate"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}", "c: {neon_type[1]}"]
    return_type: "{neon_type[0]}"
    safety: safe
    attr:
      - *neon-i8mm
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [nop]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [ummla]]}]]
      - *neon-unstable-i8mm
      - *neon-cfg-arm-unstable
    types:
      - [uint32x4_t, uint8x16_t]
    compose:
      - LLVMLink:
          name: "vmmla{neon_type[0].no}"
          links:
            - link: "llvm.aarch64.neon.ummla.{neon_type[0]}.{neon_type[1]}"
              arch: aarch64,arm64ec
            - link: "llvm.arm.neon.ummla.{neon_type[0]}.{neon_type[1]}"
              arch: arm

  - name: "vusmmla{neon_type[0].no}"
    doc: "Unsigned and signed 8-bit integer matrix multiply-accumulate"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}", "c: {neon_type[2]}"]
    return_type: "{neon_type[0]}"
    safety: safe
    attr:
      - *neon-i8mm
      - *neon-v8
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [nop]]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [usmmla]]}]]
      - *neon-unstable-i8mm
      - *neon-cfg-arm-unstable
    types:
      - [int32x4_t, uint8x16_t, int8x16_t]
    compose:
      - LLVMLink:
          name: "vmmla{neon_type[0].no}"
          links:
            - link: "llvm.aarch64.neon.usmmla.{neon_type[0]}.{neon_type[1]}"
              arch: aarch64,arm64ec
            - link: "llvm.arm.neon.usmmla.{neon_type[0]}.{neon_type[1]}"
              arch: arm

  - name: "vtbl1"
    visibility: private
    doc: "Table look-up"
    arguments: ["a: {neon_type}", "b: {neon_type}"]
    return_type: "{neon_type}"
    safety: safe
    attr:
      - *target-is-arm
      - *neon-v7
      - *neon-arm-unstable
    assert_instr: [vtbl]
    types:
      - int8x8_t
    compose:
      - LLVMLink:
          name: "vtbl1"
          links:
            - link: "llvm.arm.neon.vtbl1"
              arch: arm
  
  - name: "vtbl1_s8"
    doc: "Table look-up"
    arguments: ["a: {neon_type}", "b: {neon_type}"]
    return_type: "{neon_type}"
    safety: safe
    attr:
      - *target-is-arm
      - *neon-v7
      - *neon-arm-unstable
    assert_instr: [vtbl]
    types:
      - int8x8_t
    compose:
      - FnCall: [vtbl1, [a, b]]

  - name: "vtbl1{neon_type[0].no}"
    doc: "Table look-up"
    arguments: ["a: {neon_type[0]}", "b: uint8x8_t"]
    return_type: "{neon_type[1]}"
    safety: safe
    attr:
      - *target-is-arm
      - *neon-v7
      - *neon-arm-unstable
    assert_instr: [vtbl]
    types:
      - [uint8x8_t, uint8x8_t]
      - [poly8x8_t, poly8x8_t]
    compose:
      - FnCall:
          - transmute
          - - FnCall:
                - vtbl1
                - - FnCall: [transmute, [a]]
                  - FnCall: [transmute, [b]]

  - name: "vtbl2"
    visibility: private
    doc: "Table look-up"
    arguments: ["a: {neon_type}", "b: {neon_type}", "c: {neon_type}"]
    return_type: "{neon_type}"
    safety: safe
    attr:
      - *target-is-arm
      - *neon-v7
      - *neon-arm-unstable
    assert_instr: [vtbl]
    types:
      - int8x8_t
    compose:
      - LLVMLink:
          name: "vtbl2"
          links:
            - link: "llvm.arm.neon.vtbl2"
              arch: arm

  - name: "vtbl2_s8"
    doc: "Table look-up"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[1]}"
    safety: safe
    attr:
      - *target-is-arm
      - *neon-v7
      - *neon-arm-unstable
    assert_instr: [vtbl]
    types:
      - [int8x8x2_t, int8x8_t]
    compose:
      - FnCall: [vtbl2, ['a.0', 'a.1', b]]

  - name: "vtbl2{neon_type[1].no}"
    doc: "Table look-up"
    arguments: ["a: {neon_type[0]}", "b: uint8x8_t"]
    return_type: "{neon_type[1]}"
    safety: safe
    attr:
      - *target-is-arm
      - *neon-v7
      - *neon-arm-unstable
    assert_instr: [vtbl]
    types:
      - [uint8x8x2_t, uint8x8_t]
      - [poly8x8x2_t, poly8x8_t]
    compose:
      - FnCall:
          - transmute
          - - FnCall:
                - vtbl2
                - - FnCall: [transmute, ['a.0']]
                  - FnCall: [transmute, ['a.1']]
                  - FnCall: [transmute, [b]]

  - name: "vtbl3"
    visibility: private
    doc: "Table look-up"
    arguments: ["a: {neon_type}", "b: {neon_type}", "c: {neon_type}", "d: {neon_type}"]
    return_type: "{neon_type}"
    safety: safe
    attr:
      - *target-is-arm
      - *neon-v7
      - *neon-arm-unstable
    assert_instr: [vtbl]
    types:
      - int8x8_t
    compose:
      - LLVMLink:
          name: "vtbl3"
          links:
            - link: "llvm.arm.neon.vtbl3"
              arch: arm

  - name: "vtbl3_s8"
    doc: "Table look-up"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[1]}"
    safety: safe
    attr:
      - *target-is-arm
      - *neon-v7
      - *neon-arm-unstable
    assert_instr: [vtbl]
    types:
      - [int8x8x3_t, int8x8_t]
    compose:
      - FnCall: [vtbl3, ['a.0', 'a.1', 'a.2', b]]

  - name: "vtbl3{neon_type[1].no}"
    doc: "Table look-up"
    arguments: ["a: {neon_type[0]}", "b: uint8x8_t"]
    return_type: "{neon_type[1]}"
    safety: safe
    attr:
      - *target-is-arm
      - *neon-v7
      - *neon-arm-unstable
    assert_instr: [vtbl]
    types:
      - [uint8x8x3_t, uint8x8_t]
      - [poly8x8x3_t, poly8x8_t]
    compose:
      - FnCall:
          - transmute
          - - FnCall:
                - vtbl3
                - - FnCall: [transmute, ['a.0']]
                  - FnCall: [transmute, ['a.1']]
                  - FnCall: [transmute, ['a.2']]
                  - FnCall: [transmute, [b]]

  - name: "vtbl4"
    visibility: private
    doc: "Table look-up"
    arguments: ["a: {neon_type}", "b: {neon_type}", "c: {neon_type}", "d: {neon_type}", "e: {neon_type}"]
    return_type: "{neon_type}"
    safety: safe
    attr:
      - *target-is-arm
      - *neon-v7
      - *neon-arm-unstable
    assert_instr: [vtbl]
    types:
      - int8x8_t
    compose:
      - LLVMLink:
          name: "vtbl4"
          links:
            - link: "llvm.arm.neon.vtbl4"
              arch: arm

  - name: "vtbl4_s8"
    doc: "Table look-up"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[1]}"
    safety: safe
    attr:
      - *target-is-arm
      - *neon-v7
      - *neon-arm-unstable
    assert_instr: [vtbl]
    types:
      - [int8x8x4_t, int8x8_t]
    compose:
      - FnCall: [vtbl4, ['a.0', 'a.1', 'a.2', 'a.3', b]]

  - name: "vtbl4{neon_type[1].no}"
    doc: "Table look-up"
    arguments: ["a: {neon_type[0]}", "b: uint8x8_t"]
    return_type: "{neon_type[1]}"
    safety: safe
    attr:
      - *target-is-arm
      - *neon-v7
      - *neon-arm-unstable
    assert_instr: [vtbl]
    types:
      - [uint8x8x4_t, uint8x8_t]
      - [poly8x8x4_t, poly8x8_t]
    compose:
      - FnCall:
          - transmute
          - - FnCall:
                - vtbl4
                - - FnCall: [transmute, ['a.0']]
                  - FnCall: [transmute, ['a.1']]
                  - FnCall: [transmute, ['a.2']]
                  - FnCall: [transmute, ['a.3']]
                  - FnCall: [transmute, [b]]

  - name: "vst1{type[0]}"
    visibility: private
    arguments: ["addr: {type[1]}", "val: {neon_type[2]}"]
    static_defs: ["const ALIGN: i32"]
    safety:
      unsafe: [neon]
    attr:
      - *target-is-arm
      - *neon-v7
      - *neon-arm-unstable
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vst1.{type[3]}"', "ALIGN = 0"]]}]]
      - FnCall: ["rustc_legacy_const_generics", ['2']]
    types:
      - ['_v8i8',   '* const i8', int8x8_t,    '8' ]
      - ['q_v16i8', '* const i8', int8x16_t,   '8' ]
      - ['_v4i16',  '* const i8', int16x4_t,   '16']
      - ['q_v8i16', '* const i8', int16x8_t,   '16']
      - ['_v2i32',  '* const i8', int32x2_t,   '32']
      - ['q_v4i32', '* const i8', int32x4_t,   '32']
      - ['_v1i64',  '* const i8', int64x1_t,   '64']
      - ['q_v2i64', '* const i8', int64x2_t,   '64']
      - ['_v2f32',  '* const i8', float32x2_t, '32']
      - ['q_v4f32', '* const i8', float32x4_t, '32']
    compose:
      - LLVMLink:
          name: "_vst1{type[0]}"
          arguments: ["addr: {type[1]}", "val: {neon_type[2]}", "align: i32"]
          links:
            - link: "llvm.arm.neon.vst1.{neon_type[2]}.p0"
              arch: arm
      - FnCall: ["_vst1{type[0]}",[addr, val, ALIGN]]

  - name: "vst1{type[0]}"
    visibility: private
    doc: "Store multiple single-element structures from one, two, three, or four registers."
    arguments: ["addr: {type[1]}", "val: {neon_type[2]}", "align: {type[3]}"]
    safety:
      unsafe: [neon]
    attr:
      - *target-is-arm
      - *neon-v7
      - *neon-fp16
      - *neon-arm-unstable
      - *target-not-arm64ec
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vst1.{type[4]}"']]}]]
    types:
      - ['_v4f16', '* const i8', float16x4_t, i32, '16']
      - ['q_v8f16', '* const i8', float16x8_t, i32, '16']
    compose:
      - LLVMLink:
          name: "_vst1{type[0]}"
          links:
            - link: "llvm.arm.neon.vst1.{neon_type[2]}.p0"
              arch: arm

  - name: "vst1{neon_type[1].no}"
    doc: "Store multiple single-element structures from one, two, three, or four registers."
    arguments: ["ptr: {type[0]}", "a: {neon_type[1]}"]
    safety:
      unsafe: [neon]
    attr:
      - *target-is-arm
      - *neon-v7
      - *neon-arm-unstable
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vst1.{type[2]}"']]}]]
    types:
      - ['*mut i8',  int8x8_t,    '8',  'a',            'crate::mem::align_of::<i8>()',  '_v8i8'  ]
      - ['*mut i8',  int8x16_t,   '8',  'a',            'crate::mem::align_of::<i8>()',  'q_v16i8']
      - ['*mut i16', int16x4_t,   '16', 'a',            'crate::mem::align_of::<i16>()', '_v4i16' ]
      - ['*mut i16', int16x8_t,   '16', 'a',            'crate::mem::align_of::<i16>()', 'q_v8i16']
      - ['*mut i32', int32x2_t,   '32', 'a',            'crate::mem::align_of::<i32>()', '_v2i32' ]
      - ['*mut i32', int32x4_t,   '32', 'a',            'crate::mem::align_of::<i32>()', 'q_v4i32']
      - ['*mut i64', int64x1_t,   '64', 'a',            'crate::mem::align_of::<i64>()', '_v1i64' ]
      - ['*mut i64', int64x2_t,   '64', 'a',            'crate::mem::align_of::<i64>()', 'q_v2i64']
      - ['*mut u8',  uint8x8_t,   '8',  'transmute(a)', 'crate::mem::align_of::<u8>()',  '_v8i8'  ]
      - ['*mut u8',  uint8x16_t,  '8',  'transmute(a)', 'crate::mem::align_of::<u8>()',  'q_v16i8']
      - ['*mut u16', uint16x4_t,  '16', 'transmute(a)', 'crate::mem::align_of::<u16>()', '_v4i16' ]
      - ['*mut u16', uint16x8_t,  '16', 'transmute(a)', 'crate::mem::align_of::<u16>()', 'q_v8i16']
      - ['*mut u32', uint32x2_t,  '32', 'transmute(a)', 'crate::mem::align_of::<u32>()', '_v2i32' ]
      - ['*mut u32', uint32x4_t,  '32', 'transmute(a)', 'crate::mem::align_of::<u32>()', 'q_v4i32']
      - ['*mut u64', uint64x1_t,  '64', 'transmute(a)', 'crate::mem::align_of::<u64>()', '_v1i64' ]
      - ['*mut u64', uint64x2_t,  '64', 'transmute(a)', 'crate::mem::align_of::<u64>()', 'q_v2i64']
      - ['*mut p8',  poly8x8_t,   '8',  'transmute(a)', 'crate::mem::align_of::<p8>()',  '_v8i8'  ]
      - ['*mut p8',  poly8x16_t,  '8',  'transmute(a)', 'crate::mem::align_of::<p8>()',  'q_v16i8']
      - ['*mut p16', poly16x4_t,  '16', 'transmute(a)', 'crate::mem::align_of::<p16>()', '_v4i16' ]
      - ['*mut p16', poly16x8_t,  '16', 'transmute(a)', 'crate::mem::align_of::<p16>()', 'q_v8i16']
      - ['*mut p64', poly64x1_t,  '64', 'transmute(a)', 'crate::mem::align_of::<p64>()', '_v1i64' ]
      - ['*mut p64', poly64x2_t,  '64', 'transmute(a)', 'crate::mem::align_of::<p64>()', 'q_v2i64']
      - ['*mut f32', float32x2_t, '32', 'transmute(a)', 'crate::mem::align_of::<f32>()', '_v2f32' ]
      - ['*mut f32', float32x4_t, '32', 'transmute(a)', 'crate::mem::align_of::<f32>()', 'q_v4f32']
    compose:
      - Const:
          - ALIGN
          - "i32"
          - "{type[4]} as i32"
      - FnCall:
          - "vst1{type[5]}"
          - ['ptr as *const i8','{type[3]}']
          - ['ALIGN']

  - name: "vst1{neon_type[1].no}"
    doc: "Store multiple single-element structures from one, two, three, or four registers."
    arguments: ["ptr: {type[0]}", "a: {neon_type[1]}"]
    safety:
      unsafe: [neon]
    attr:
      - *target-is-arm
      - *neon-v7
      - *neon-fp16
      - *neon-unstable-f16
      - *target-not-arm64ec
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vst1.{type[2]}"']]}]]
    types:
      - ['*mut f16', float16x4_t, '16', 'transmute(a)', 'crate::mem::align_of::<f16>() as i32', '_v4f16']
      - ['*mut f16', float16x8_t, '16', 'transmute(a)', 'crate::mem::align_of::<f16>() as i32', 'q_v8f16']
    compose:
      - FnCall:
          - "vst1{type[5]}"
          - - 'ptr as *const i8'
            - '{type[3]}'
            - '{type[4]}'

  - name: "vshiftlins{type[0]}"
    visibility: private
    arguments: ["a: {neon_type[1]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[1]}"
    safety: safe
    attr:
      - *target-is-arm
      - *neon-v7
      - *neon-arm-unstable
      - FnCall: [rustc_legacy_const_generics, ['2']]
    static_defs: ['const N: i32']
    types:
      - ['_v8i8',  'int8x8_t',  '8',  'int8x8_t([N as i8; 8 ])' ] 
      - ['_v16i8', 'int8x16_t', '8',  'int8x16_t([N as i8; 16])']
      - ['_v4i16', 'int16x4_t', '16', 'int16x4_t([N as i16; 4])']
      - ['_v8i16', 'int16x8_t', '16', 'int16x8_t([N as i16; 8])']
      - ['_v2i32', 'int32x2_t', '32', 'int32x2_t([N; 2])'       ]
      - ['_v4i32', 'int32x4_t', '32', 'int32x4_t([N; 4])'       ]
      - ['_v1i64', 'int64x1_t', '64', 'int64x1_t([N as i64; 1])']
      - ['_v2i64', 'int64x2_t', '64', 'int64x2_t([N as i64; 2])']
    compose:
      - LLVMLink:
          name: "_vshiftins{type[0]}"
          arguments: ["a: {type[1]}", "b: {type[1]}", "c: {type[1]}"]
          links:
            - link: "llvm.arm.neon.vshiftins.{neon_type[1]}"
              arch: arm
      - FnCall: ["_vshiftlins{type[0]}", [a,b, "const {{ {type[3]} }}"], [], true]

  - name: "vshiftrins{type[0]}"
    doc: "Shift Right and Insert (immediate)"
    visibility: private
    arguments: ["a: {neon_type[1]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[1]}"
    safety: safe
    attr:
      - *target-is-arm
      - *neon-v7
      - *neon-arm-unstable
      - FnCall: [rustc_legacy_const_generics, ['2']]
    static_defs: ['const N: i32']
    types:
      - ['_v8i8',  'int8x8_t',  '8',  'int8x8_t([-N as i8; 8 ])' ]
      - ['_v16i8', 'int8x16_t', '8',  'int8x16_t([-N as i8; 16])']
      - ['_v4i16', 'int16x4_t', '16', 'int16x4_t([-N as i16; 4])']
      - ['_v8i16', 'int16x8_t', '16', 'int16x8_t([-N as i16; 8])']
      - ['_v2i32', 'int32x2_t', '32', 'int32x2_t([-N; 2])'       ]
      - ['_v4i32', 'int32x4_t', '32', 'int32x4_t([-N; 4])'       ]
      - ['_v1i64', 'int64x1_t', '64', 'int64x1_t([-N as i64; 1])']
      - ['_v2i64', 'int64x2_t', '64', 'int64x2_t([-N as i64; 2])']
    compose:
      - LLVMLink:
          name: "_vshiftins{type[0]}"
          arguments: ["a: {type[1]}", "b: {type[1]}", "c: {type[1]}"]
          links:
            - link: "llvm.arm.neon.vshiftins.{neon_type[1]}"
              arch: arm
      - FnCall: ["_vshiftrins{type[0]}", [a,b, "const {{ {type[3]} }}"], [], true]

  - name: "vsri{neon_type[0].N}"
    doc: "Shift Right and Insert (immediate)"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[0]}"
    safety: safe
    attr:
      - *target-is-arm
      - FnCall: [target_feature, ['enable = "{type[1]}"']]
      - *neon-arm-unstable
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vsri.{type[2]}"', 'N = 1']]}]]
      - FnCall: [rustc_legacy_const_generics, ['2']]
    static_defs: ['const N: i32']
    types:
      - [uint8x8_t,  "neon,v7", '8',  '1 <= N && N <= 8',  'v8i8' ]
      - [uint8x16_t, "neon,v7", '8',  '1 <= N && N <= 8',  'v16i8']
      - [uint16x4_t, "neon,v7", '16', '1 <= N && N <= 16', 'v4i16']
      - [uint16x8_t, "neon,v7", '16', '1 <= N && N <= 16', 'v8i16']
      - [uint32x2_t, "neon,v7", '32', '1 <= N && N <= 32', 'v2i32']
      - [uint32x4_t, "neon,v7", '32', '1 <= N && N <= 32', 'v4i32']
      - [uint64x1_t, "neon,v7", '64', '1 <= N && N <= 64', 'v1i64']
      - [uint64x2_t, "neon,v7", '64', '1 <= N && N <= 64', 'v2i64']
      - [poly8x8_t,  "neon,v7",  '8', '1 <= N && N <= 8',  'v8i8' ]
      - [poly8x16_t, "neon,v7",  '8', '1 <= N && N <= 8',  'v16i8']
      - [poly16x4_t, "neon,v7", '16', '1 <= N && N <= 16', 'v4i16']
      - [poly16x8_t, "neon,v7", '16', '1 <= N && N <= 16', 'v8i16']
      ## These live in ./crates/core_arch/src/arm/neon.rs
      #- [poly64x1_t, "neon,v7,aes", '64', '1 <= N && N <= 64', 'v1i64', 'int64x1_t::splat', '-N as i64']
      #- [poly64x2_t, "neon,v7,aes", '64', '1 <= N && N <= 64', 'v2i64', 'int64x2_t::splat', '-N as i64']
    compose:
      - FnCall: ["static_assert!", ['{type[3]}']]
      - FnCall:
          - 'transmute'
          - - FnCall:
                - "vshiftrins_{type[4]}::<N>"
                - - FnCall: [transmute, [a]]
                  - FnCall: [transmute, [b]]

  - name: "vsri{neon_type[0].N}"
    doc: "Shift Right and Insert (immediate)"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[0]}"
    static_defs: ['const N: i32']
    attr:
      - *enable-v7
      - *target-is-arm
      - *neon-arm-unstable
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vsri.{type[1]}"', 'N = 1']]}]]
      - FnCall: [rustc_legacy_const_generics, ['2']]
    safety: safe
    types:
      - [int8x8_t,  '8',  '1 <= N && N <= 8',  'v8i8' ]
      - [int8x16_t, '8',  '1 <= N && N <= 8',  'v16i8']
      - [int16x4_t, '16', '1 <= N && N <= 16', 'v4i16']
      - [int16x8_t, '16', '1 <= N && N <= 16', 'v8i16']
      - [int32x2_t, '32', '1 <= N && N <= 32', 'v2i32']
      - [int32x4_t, '32', '1 <= N && N <= 32', 'v4i32']
      - [int64x1_t, '64', '1 <= N && N <= 64', 'v1i64']
      - [int64x2_t, '64', '1 <= N && N <= 64', 'v2i64']
    compose:
      - FnCall: ["static_assert!", ['{type[2]}']]
      - FnCall:
          - "vshiftrins_{type[3]}::<N>"
          - - a
            - b

  - name: "vsli{neon_type[0].N}"
    doc: "Shift Left and Insert (immediate)"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[0]}"
    safety: safe
    attr:
      - *target-is-arm
      - FnCall: [target_feature, ['enable = "{type[1]}"']]
      - *neon-arm-unstable
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vsli.{type[2]}"', 'N = 1']]}]]
      - FnCall: [rustc_legacy_const_generics, ['2']]
    static_defs: ['const N: i32']
    types:
      - [uint8x8_t,  "neon,v7", '8',  'static_assert_uimm_bits!', 'N, 3',     'v8i8']
      - [uint8x16_t, "neon,v7", '8',  'static_assert_uimm_bits!', 'N, 3',    'v16i8']
      - [uint16x4_t, "neon,v7", '16', 'static_assert_uimm_bits!', 'N, 4',    'v4i16']
      - [uint16x8_t, "neon,v7", '16', 'static_assert_uimm_bits!', 'N, 4',    'v8i16']
      - [uint32x2_t, "neon,v7", '32', 'static_assert!', 'N >= 0 && N <= 31', 'v2i32']
      - [uint32x4_t, "neon,v7", '32', 'static_assert!', 'N >= 0 && N <= 31', 'v4i32']
      - [uint64x1_t, "neon,v7", '64', 'static_assert!', 'N >= 0 && N <= 63', 'v1i64']
      - [uint64x2_t, "neon,v7", '64', 'static_assert!', 'N >= 0 && N <= 63', 'v2i64']
      - [poly8x8_t,  "neon,v7", '8',  'static_assert_uimm_bits!', 'N, 3',     'v8i8']
      - [poly8x16_t, "neon,v7", '8',  'static_assert_uimm_bits!', 'N, 3',    'v16i8']
      - [poly16x4_t, "neon,v7", '16', 'static_assert_uimm_bits!', 'N, 4',    'v4i16']
      - [poly16x8_t, "neon,v7", '16', 'static_assert_uimm_bits!', 'N, 4',    'v8i16']
      ## These live in ./crates/core_arch/src/arm/neon.rs
      #- [poly64x1_t, "neon,v7,aes", '"vsli.64"', 'static_assert!', '0 <= N && N <= 63', 'v1i64', 'int64x1_t::splat', 'N as i64']
      #- [poly64x2_t, "neon,v7,aes", '"vsli.64"', 'static_assert!', '0 <= N && N <= 63', 'v2i64', 'int64x2_t::splat', 'N as i64']
    compose:
      - FnCall: ["{type[3]}", ['{type[4]}']]
      - FnCall:
          - 'transmute'
          - - FnCall:
                - "vshiftlins_{type[5]}::<N>"
                - - FnCall: [transmute, [a]]
                  - FnCall: [transmute, [b]]
  
  - name: "vsli{neon_type[0].N}"
    doc: "Shift Left and Insert (immediate)"
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[0]}"
    safety: safe
    attr:
      - *target-is-arm
      - *enable-v7
      - *neon-arm-unstable
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vsli.{type[1]}"', 'N = 1']]}]]
      - FnCall: [rustc_legacy_const_generics, ['2']]
    static_defs: ['const N: i32']
    types:
      - [int8x8_t,  '8',  'static_assert_uimm_bits!', 'N, 3',              'v8i8' ]
      - [int8x16_t, '8',  'static_assert_uimm_bits!', 'N, 3',              'v16i8']
      - [int16x4_t, '16', 'static_assert_uimm_bits!', 'N, 4',              'v4i16']
      - [int16x8_t, '16', 'static_assert_uimm_bits!', 'N, 4',              'v8i16']
      - [int32x2_t, '32', 'static_assert!',           'N >= 0 && N <= 31', 'v2i32']
      - [int32x4_t, '32', 'static_assert!',           'N >= 0 && N <= 31', 'v4i32']
      - [int64x1_t, '64', 'static_assert!',           'N >= 0 && N <= 63', 'v1i64']
      - [int64x2_t, '64', 'static_assert!',           'N >= 0 && N <= 63', 'v2i64']
    compose:
      - FnCall: ["{type[2]}", ['{type[3]}']]
      - FnCall:
          - "vshiftlins_{type[4]}::<N>"
          - - a
            - b

  - name: "vcombine{neon_type[0].no}"
    doc: Join two smaller vectors into a single larger vector
    arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - *arm-fp16
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    assert_instr: [nop]
    safety: safe
    types:
      - [float16x4_t, float16x8_t]
    compose:
      - FnCall: [simd_shuffle!, [a, b, '[0, 1, 2, 3, 4, 5, 6, 7]']]

  - name: "vget_{type[2]}_{neon_type[0]}"
    doc: Duplicate vector element to vector
    arguments: ["a: {neon_type[1]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - *arm-fp16
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    assert_instr: [nop]
    safety: safe
    types:
      - [float16x4_t, float16x8_t, 'low', "[0, 1, 2, 3]"]
      - [float16x4_t, float16x8_t, 'high', "[4, 5, 6, 7]"]
    compose:
      - FnCall: [simd_shuffle!, [a, a, "{type[3]}"]]

  - name: "vget{type[2]}"
    doc: Duplicate vector element to scalar
    arguments: ["a: {neon_type[0]}"]
    return_type: "{type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, [nop, 'LANE = 0']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [nop, 'LANE = 0']]}]]
      - FnCall: [rustc_legacy_const_generics, ["1"]]
      - *arm-fp16
      - *neon-unstable-f16
      - *target-not-arm64ec
    static_defs: ['const LANE: i32']
    safety: safe
    types:
      - [float16x4_t, f16, '_lane_f16',  '2']
      - [float16x8_t, f16, 'q_lane_f16', '3']
    compose:
      - FnCall: [static_assert_uimm_bits!, [LANE, '{type[3]}']]
      - FnCall: [simd_extract!, [a, "LANE as u32"]]

  - name: "vmov{neon_type[0].N}"
    doc: "Duplicate element to vector"
    arguments: ["a: {type[1]}"]
    return_type: "{neon_type[0]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"vdup.16"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, [dup]]}]]
      - *arm-fp16
      - *neon-unstable-f16
      - *target-not-arm64ec
    safety: safe
    types:
      - [float16x4_t, f16]
      - [float16x8_t, f16]
    compose:
      - FnCall: ["vdup{neon_type[0].N}", [a]]

  - name: "{type[0]}"
    doc: "Load one single-element structure to one lane of one register."
    arguments: ["ptr: {type[1]}", "src: {neon_type[2]}"]
    return_type: "{neon_type[2]}"
    static_defs: ['const LANE: i32']
    attr:
      - *neon-v7
      - FnCall: [rustc_legacy_const_generics, ['2']]
      - FnCall: [cfg_attr, [*test-is-arm, { FnCall: [assert_instr, ["{type[3]}", 'LANE = {type[4]}']] }  ]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, { FnCall: [assert_instr, ['{type[5]}', 'LANE = {type[4]}']]}] ]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety:
      unsafe: [neon]
    types:
      - ['vld1_lane_s8', '*const i8', 'int8x8_t', '"vld1.8"', '7', 'ld1', 'static_assert_uimm_bits!', 'LANE, 3']
      - ['vld1_lane_u8', '*const u8', 'uint8x8_t', '"vld1.8"', '7', 'ld1', 'static_assert_uimm_bits!', 'LANE, 3']
      - ['vld1_lane_p8', '*const p8', 'poly8x8_t', '"vld1.8"', '7', 'ld1', 'static_assert_uimm_bits!', 'LANE, 3']
      - ['vld1q_lane_s8', '*const i8', 'int8x16_t', '"vld1.8"', '15', 'ld1', 'static_assert_uimm_bits!', 'LANE, 4']
      - ['vld1q_lane_u8', '*const u8', 'uint8x16_t', '"vld1.8"', '15', 'ld1', 'static_assert_uimm_bits!', 'LANE, 4']
      - ['vld1q_lane_p8', '*const p8', 'poly8x16_t', '"vld1.8"', '15', 'ld1', 'static_assert_uimm_bits!', 'LANE, 4']
      - ['vld1_lane_s16', '*const i16', 'int16x4_t', '"vld1.16"', '3', 'ld1', 'static_assert_uimm_bits!', 'LANE, 2']
      - ['vld1_lane_u16', '*const u16', 'uint16x4_t', '"vld1.16"', '3', 'ld1', 'static_assert_uimm_bits!', 'LANE, 2']
      - ['vld1_lane_p16', '*const p16', 'poly16x4_t', '"vld1.16"', '3', 'ld1', 'static_assert_uimm_bits!', 'LANE, 2']
      - ['vld1q_lane_s16', '*const i16', 'int16x8_t', '"vld1.16"', '7', 'ld1', 'static_assert_uimm_bits!', 'LANE, 3']
      - ['vld1q_lane_u16', '*const u16', 'uint16x8_t', '"vld1.16"', '7', 'ld1', 'static_assert_uimm_bits!', 'LANE, 3']
      - ['vld1q_lane_p16', '*const p16', 'poly16x8_t', '"vld1.16"', '7', 'ld1', 'static_assert_uimm_bits!', 'LANE, 3']
      - ['vld1_lane_s32', '*const i32', 'int32x2_t', '"vld1.32"', '1', 'ld1', 'static_assert_uimm_bits!', 'LANE, 1']
      - ['vld1_lane_u32', '*const u32', 'uint32x2_t', '"vld1.32"', '1', 'ld1', 'static_assert_uimm_bits!', 'LANE, 1']
      - ['vld1_lane_f32', '*const f32', 'float32x2_t', '"vld1.32"', '1', 'ld1', 'static_assert_uimm_bits!', 'LANE, 1']
      - ['vld1q_lane_s32', '*const i32', 'int32x4_t', '"vld1.32"', '3', 'ld1', 'static_assert_uimm_bits!', 'LANE, 2']
      - ['vld1q_lane_u32', '*const u32', 'uint32x4_t', '"vld1.32"', '3', 'ld1', 'static_assert_uimm_bits!', 'LANE, 2']
      - ['vld1q_lane_f32', '*const f32', 'float32x4_t', '"vld1.32"', '3', 'ld1', 'static_assert_uimm_bits!', 'LANE, 2']
      - ['vld1_lane_s64', '*const i64', 'int64x1_t', 'vldr', '0', 'ldr', 'static_assert!', 'LANE == 0']
      - ['vld1_lane_u64', '*const u64', 'uint64x1_t', 'vldr', '0', 'ldr', 'static_assert!', 'LANE == 0']
      - ['vld1q_lane_s64', '*const i64', 'int64x2_t', 'vldr', '1', 'ld1', 'static_assert_uimm_bits!', 'LANE, 1']
      - ['vld1q_lane_u64', '*const u64', 'uint64x2_t', 'vldr', '1', 'ld1', 'static_assert_uimm_bits!', 'LANE, 1']
    compose:
      - FnCall: ["{type[6]}", ["{type[7]}"]]
      - FnCall: [simd_insert!, [src, 'LANE as u32', '*ptr']]

  - name: "{type[0]}"
    doc: "Load one single-element structure to one lane of one register."
    arguments: ["ptr: {type[1]}", "src: {neon_type[2]}"]
    return_type: "{neon_type[2]}"
    attr:
      - *neon-aes
      - *neon-v7
      - FnCall: [rustc_legacy_const_generics, ['2']]
      - FnCall: [cfg_attr, [*test-is-arm, { FnCall: [assert_instr, ["{type[3]}", 'LANE = {type[4]}']] }  ]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, { FnCall: [assert_instr, ['{type[5]}', 'LANE = {type[4]}']]}] ]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const LANE: i32']
    safety:
      unsafe: [neon]
    types:
      - ['vld1_lane_p64', '*const p64', 'poly64x1_t', 'vldr', '0', 'ldr', 'static_assert!', 'LANE == 0']
      - ['vld1q_lane_p64', '*const p64', 'poly64x2_t', 'vldr', '1', 'ld1', 'static_assert_uimm_bits!', 'LANE, 1']
    compose:
      - FnCall: ["{type[6]}", ["{type[7]}"]]
      - FnCall: [simd_insert!, [src, 'LANE as u32', '*ptr']]

  - name: "{type[0]}"
    doc: "Load one single-element structure and Replicate to all lanes (of one register)."
    arguments: ["ptr: {type[1]}"]
    return_type: "{neon_type[2]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, { FnCall: [assert_instr, ["{type[3]}"]] }  ]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, { FnCall: [assert_instr, ['{type[4]}']]}] ]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety:
      unsafe: [neon]
    types:
      - ['vld1_dup_s64', '*const i64', 'int64x1_t', 'vldr', 'ldr', 'let x: int64x1_t; #[cfg(any(target_arch = "aarch64", target_arch = "arm64ec"))] { x = crate::core_arch::aarch64::vld1_s64(ptr); } #[cfg(target_arch = "arm")] { x = crate::core_arch::arm::vld1_s64(ptr); }']
      - ['vld1_dup_u64', '*const u64', 'uint64x1_t', 'vldr', 'ldr', 'let x: uint64x1_t; #[cfg(any(target_arch = "aarch64", target_arch = "arm64ec"))] { x = crate::core_arch::aarch64::vld1_u64(ptr); } #[cfg(target_arch = "arm")] { x = crate::core_arch::arm::vld1_u64(ptr); }']
    compose:
      - Identifier: ['{type[5]}', Symbol]
      - Identifier: [x, Symbol]

  - name: "{type[0]}"
    doc: "Load one single-element structure and Replicate to all lanes (of one register)."
    arguments: ["ptr: {type[1]}"]
    return_type: "{neon_type[2]}"
    attr:
      - *neon-aes
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, { FnCall: [assert_instr, ["{type[3]}"]] }  ]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, { FnCall: [assert_instr, ['{type[4]}']]}] ]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety:
      unsafe: [neon]
    types:
      - ['vld1_dup_p64', '*const p64', 'poly64x1_t', 'vldr', 'ldr', 'let x: poly64x1_t; #[cfg(any(target_arch = "aarch64", target_arch = "arm64ec"))] { x = crate::core_arch::aarch64::vld1_p64(ptr); } #[cfg(target_arch = "arm")] { x = crate::core_arch::arm::vld1_p64(ptr); }']
    compose:
      - Identifier: ['{type[5]}', Symbol]
      - Identifier: [x, Symbol]

  - name: "{type[0]}"
    doc: "Load one single-element structure and Replicate to all lanes (of one register)."
    arguments: ["ptr: {type[1]}"]
    return_type: "{neon_type[2]}"
    attr:
      - *neon-aes
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, { FnCall: [assert_instr, ["{type[3]}"]] }  ]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, { FnCall: [assert_instr, ['{type[4]}']]}] ]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety:
      unsafe: [neon]
    types:
      - ['vld1q_dup_p64', '*const p64', 'poly64x2_t', 'vldr', 'ld1r', 'vld1q_lane_p64::<0>', 'u64x2::splat(0)', '[0, 0]']
    compose:
      - Let:
        - x
        - FnCall:
            - '{type[5]}'
            - - ptr
              - FnCall: [transmute, ['{type[6]}']]
      - FnCall: ['simd_shuffle!', [x, x, '{type[7]}']]

  - name: "{type[0]}"
    doc: "Load one single-element structure and Replicate to all lanes (of one register)."
    arguments: ["ptr: {type[1]}"]
    return_type: "{neon_type[2]}"
    big_endian_inverse: false
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, { FnCall: [assert_instr, ['"{type[3]}"']] }  ]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, { FnCall: [assert_instr, ['{type[4]}']]}] ]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety:
      unsafe: [neon]
    types:
      - ['vld1_dup_s8', '*const i8', 'int8x8_t', 'vld1.8', 'ld1r', 'i8x8::splat']
      - ['vld1_dup_u8', '*const u8', 'uint8x8_t', 'vld1.8', 'ld1r', 'u8x8::splat']
      - ['vld1_dup_p8', '*const p8', 'poly8x8_t', 'vld1.8', 'ld1r', 'u8x8::splat']

      - ['vld1q_dup_s8', '*const i8', 'int8x16_t', 'vld1.8', 'ld1r', 'i8x16::splat']
      - ['vld1q_dup_u8', '*const u8', 'uint8x16_t', 'vld1.8', 'ld1r', 'u8x16::splat']
      - ['vld1q_dup_p8', '*const p8', 'poly8x16_t', 'vld1.8', 'ld1r', 'u8x16::splat']

      - ['vld1_dup_s16', '*const i16', 'int16x4_t', 'vld1.16', 'ld1r', 'i16x4::splat']
      - ['vld1_dup_u16', '*const u16', 'uint16x4_t', 'vld1.16', 'ld1r', 'u16x4::splat']
      - ['vld1_dup_p16', '*const p16', 'poly16x4_t', 'vld1.16', 'ld1r', 'u16x4::splat']

      - ['vld1q_dup_s16', '*const i16', 'int16x8_t', 'vld1.16', 'ld1r', 'i16x8::splat']
      - ['vld1q_dup_u16', '*const u16', 'uint16x8_t', 'vld1.16', 'ld1r', 'u16x8::splat']
      - ['vld1q_dup_p16', '*const p16', 'poly16x8_t', 'vld1.16', 'ld1r', 'u16x8::splat']

      - ['vld1_dup_s32', '*const i32', 'int32x2_t', 'vld1.32', 'ld1r', 'i32x2::splat']
      - ['vld1_dup_u32', '*const u32', 'uint32x2_t', 'vld1.32', 'ld1r', 'u32x2::splat']
      - ['vld1_dup_f32', '*const f32', 'float32x2_t', 'vld1.32', 'ld1r', 'f32x2::splat']

      - ['vld1q_dup_s32', '*const i32', 'int32x4_t', 'vld1.32', 'ld1r', 'i32x4::splat']
      - ['vld1q_dup_u32', '*const u32', 'uint32x4_t', 'vld1.32', 'ld1r', 'u32x4::splat']
      - ['vld1q_dup_f32', '*const f32', 'float32x4_t', 'vld1.32', 'ld1r', 'f32x4::splat']

      - ['vld1q_dup_s64', '*const i64', 'int64x2_t', 'vldr', 'ld1r', 'i64x2::splat']
      - ['vld1q_dup_u64', '*const u64', 'uint64x2_t', 'vldr', 'ld1r', 'u64x2::splat']
    compose:
      - FnCall:
          - transmute
          - - FnCall: ['{type[5]}', ["*ptr"]]

  - name: "{type[0]}"
    doc: "Absolute difference and accumulate (64-bit)"
    arguments: ['a: {neon_type[1]}', 'b: {neon_type[1]}', 'c: {neon_type[1]}']
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, { FnCall: [assert_instr, ['"{type[2]}"']] }  ]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, { FnCall: [assert_instr, ['{type[3]}']]}] ]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - ['vaba_s8', 'int8x8_t', 'vaba.s8', 'saba', 'vabd_s8']
      - ['vaba_u8', 'uint8x8_t', 'vaba.u8', 'uaba', 'vabd_u8']
      - ['vaba_s16', 'int16x4_t', 'vaba.s16', 'saba', 'vabd_s16']
      - ['vaba_u16', 'uint16x4_t', 'vaba.u16', 'uaba', 'vabd_u16']
      - ['vaba_s32', 'int32x2_t', 'vaba.s32', 'saba', 'vabd_s32']
      - ['vaba_u32', 'uint32x2_t', 'vaba.u32', 'uaba', 'vabd_u32']
    compose:
      - FnCall:
          - 'simd_add'
          - - a
            - FnCall: ['{type[4]}', [b, c]]

  - name: "{type[0]}"
    doc: "Absolute difference and accumulate (128-bit)"
    arguments: ['a: {neon_type[1]}', 'b: {neon_type[1]}', 'c: {neon_type[1]}']
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, { FnCall: [assert_instr, ['"{type[2]}"']] }  ]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, { FnCall: [assert_instr, ['{type[3]}']]}] ]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - ['vabaq_s8', 'int8x16_t', 'vaba.s8', 'saba', 'vabdq_s8']
      - ['vabaq_u8', 'uint8x16_t', 'vaba.u8', 'uaba', 'vabdq_u8']
      - ['vabaq_s16', 'int16x8_t', 'vaba.s16', 'saba', 'vabdq_s16']
      - ['vabaq_u16', 'uint16x8_t', 'vaba.u16', 'uaba', 'vabdq_u16']
      - ['vabaq_s32', 'int32x4_t', 'vaba.s32', 'saba', 'vabdq_s32']
      - ['vabaq_u32', 'uint32x4_t', 'vaba.u32', 'uaba', 'vabdq_u32']
    compose:
      - FnCall:
        - 'simd_add'
        - - a
          - FnCall: ['{type[4]}', [b, c]]

  - name: "{type[0]}"
    doc: "Vector add."
    arguments: ['a: {neon_type[1]}', 'b: {neon_type[1]}']
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, { FnCall: [assert_instr, ['{type[2]}']] }  ]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, { FnCall: [assert_instr, ['{type[3]}']]}] ]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - ['vadd_s8', 'int8x8_t', 'vadd', 'add']
      - ['vaddq_s8', 'int8x16_t', 'vadd', 'add']
      - ['vadd_s16', 'int16x4_t', 'vadd', 'add']
      - ['vaddq_s16', 'int16x8_t', 'vadd', 'add']
      - ['vadd_s32', 'int32x2_t', 'vadd', 'add']
      - ['vaddq_s32', 'int32x4_t', 'vadd', 'add']
      - ['vaddq_s64', 'int64x2_t', 'vadd', 'add']
      - ['vadd_f32', 'float32x2_t', 'vadd', 'fadd']
      - ['vaddq_f32', 'float32x4_t', 'vadd', 'fadd']
      - ['vadd_u8', 'uint8x8_t', 'vadd', 'add']
      - ['vaddq_u8', 'uint8x16_t', 'vadd', 'add']
      - ['vadd_u16', 'uint16x4_t', 'vadd', 'add']
      - ['vaddq_u16', 'uint16x8_t', 'vadd', 'add']
      - ['vadd_u32', 'uint32x2_t', 'vadd', 'add']
      - ['vaddq_u32', 'uint32x4_t', 'vadd', 'add']
      - ['vaddq_u64', 'uint64x2_t', 'vadd', 'add']
    compose:
      - FnCall: ['simd_add', [a, b]]

  - name: "{type[0]}"
    doc: "Add Long (vector)."
    arguments: ['a: {neon_type[1]}', 'b: {neon_type[1]}']
    return_type: "{neon_type[2]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, { FnCall: [assert_instr, ['{type[3]}']] }  ]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, { FnCall: [assert_instr, ['{type[4]}']]}] ]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - ['vaddl_s8', 'int8x8_t',  'int16x8_t', 'vaddl', 'saddl']
      - ['vaddl_s16', 'int16x4_t', 'int32x4_t', 'vaddl', 'saddl']
      - ['vaddl_s32', 'int32x2_t', 'int64x2_t', 'vaddl', 'saddl']
      - ['vaddl_u8', 'uint8x8_t', 'uint16x8_t', 'vaddl', 'uaddl']
      - ['vaddl_u16', 'uint16x4_t', 'uint32x4_t', 'vaddl', 'uaddl']
      - ['vaddl_u32', 'uint32x2_t', 'uint64x2_t', 'vaddl', 'uaddl']
    compose:
      - Let:
          - a
          - '{neon_type[2]}'
          - FnCall: [simd_cast, [a]]
      - Let:
          - b
          - '{neon_type[2]}'
          - FnCall: [simd_cast, [b]]
      - FnCall: ['simd_add', [a, b]]

  - name: "{type[0]}"
    doc: "Signed Add Long (vector, high half)."
    arguments: ['a: {neon_type[1]}', 'b: {neon_type[1]}']
    return_type: "{neon_type[2]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, { FnCall: [assert_instr, ['{type[3]}']] }  ]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, { FnCall: [assert_instr, ['{type[4]}']]}] ]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - ['vaddl_high_s8', 'int8x16_t', 'int16x8_t', 'vaddl', 'saddl2',  'int8x8_t', '[8, 9, 10, 11, 12, 13, 14, 15]']
      - ['vaddl_high_s16', 'int16x8_t', 'int32x4_t', 'vaddl', 'saddl2',  'int16x4_t', '[4, 5, 6, 7]']
      - ['vaddl_high_s32', 'int32x4_t', 'int64x2_t', 'vaddl', 'saddl2',  'int32x2_t', '[2, 3]']
      - ['vaddl_high_u8', 'uint8x16_t', 'uint16x8_t', 'vaddl', 'uaddl2',  'uint8x8_t', '[8, 9, 10, 11, 12, 13, 14, 15]']
      - ['vaddl_high_u16', 'uint16x8_t', 'uint32x4_t', 'vaddl', 'uaddl2',  'uint16x4_t', '[4, 5, 6, 7]']
      - ['vaddl_high_u32', 'uint32x4_t', 'uint64x2_t', 'vaddl', 'uaddl2',  'uint32x2_t', '[2, 3]']
    compose:
      - Let:
          - a
          - '{neon_type[5]}'
          - FnCall: ['simd_shuffle!', [a, a, '{type[6]}']]
      - Let:
          - b
          - '{neon_type[5]}'
          - FnCall: ['simd_shuffle!', [b, b, '{type[6]}']]
      - Let: [a, '{neon_type[2]}', {FnCall: [simd_cast, [a]]}]
      - Let: [b, '{neon_type[2]}', {FnCall: [simd_cast, [b]]}]
      - FnCall: [simd_add, [a, b]]

  - name: "{type[0]}"
    doc: "Add Wide"
    arguments: ['a: {neon_type[1]}', 'b: {neon_type[2]}']
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, { FnCall: [assert_instr, ['{type[3]}']] }  ]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, { FnCall: [assert_instr, ['{type[4]}']]}] ]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - ['vaddw_s8', 'int16x8_t', 'int8x8_t', 'vaddw', 'saddw']
      - ['vaddw_s16', 'int32x4_t', 'int16x4_t', 'vaddw', 'saddw']
      - ['vaddw_s32', 'int64x2_t', 'int32x2_t', 'vaddw', 'saddw']
      - ['vaddw_u8', 'uint16x8_t', 'uint8x8_t', 'vaddw', 'uaddw']
      - ['vaddw_u16', 'uint32x4_t', 'uint16x4_t', 'vaddw', 'uaddw']
      - ['vaddw_u32', 'uint64x2_t', 'uint32x2_t', 'vaddw', 'uaddw']
    compose:
      - Let:
          - b
          - '{neon_type[1]}'
          - FnCall: ['simd_cast', [b]]
      - FnCall: [simd_add, [a, b]]

  - name: "{type[0]}"
    doc: "Add Wide (high half)."
    arguments: ['a: {neon_type[1]}', 'b: {neon_type[2]}']
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, { FnCall: [assert_instr, ['{type[3]}']] }  ]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, { FnCall: [assert_instr, ['{type[4]}']]}] ]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - ['vaddw_high_s8', 'int16x8_t', 'int8x16_t', 'vaddw', 'saddw2', 'int8x8_t', '[8, 9, 10, 11, 12, 13, 14, 15]']
      - ['vaddw_high_s16', 'int32x4_t', 'int16x8_t', 'vaddw', 'saddw2', 'int16x4_t', '[4, 5, 6, 7]']
      - ['vaddw_high_s32', 'int64x2_t', 'int32x4_t', 'vaddw', 'saddw2', 'int32x2_t', '[2, 3]']
      - ['vaddw_high_u8', 'uint16x8_t', 'uint8x16_t', 'vaddw', 'uaddw2', 'uint8x8_t', '[8, 9, 10, 11, 12, 13, 14, 15]']
      - ['vaddw_high_u16', 'uint32x4_t', 'uint16x8_t', 'vaddw', 'uaddw2', 'uint16x4_t', '[4, 5, 6, 7]']
      - ['vaddw_high_u32', 'uint64x2_t', 'uint32x4_t', 'vaddw', 'uaddw2', 'uint32x2_t', '[2, 3]']
    compose:
      - Let:
          - b
          - '{neon_type[5]}'
          - FnCall: ['simd_shuffle!', [b, b, '{type[6]}']]
      - Let:
          - b
          - '{neon_type[1]}'
          - FnCall: ['simd_cast', [b]]
      - FnCall: [simd_add, [a, b]]

  - name: "{type[0]}"
    doc: "Add returning High Narrow."
    arguments: ['a: {neon_type[1]}', 'b: {neon_type[1]}']
    return_type: "{neon_type[2]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, { FnCall: [assert_instr, ['vaddhn']] }  ]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, { FnCall: [assert_instr, ['addhn']]}] ]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - ['vaddhn_s16', 'int16x8_t', 'int8x8_t', 'int16x8_t::splat(8)']
      - ['vaddhn_s32', 'int32x4_t', 'int16x4_t', 'int32x4_t::splat(16)']
      - ['vaddhn_s64', 'int64x2_t', 'int32x2_t', 'int64x2_t::splat(32)']
      - ['vaddhn_u16', 'uint16x8_t', 'uint8x8_t', 'uint16x8_t::splat(8)']
      - ['vaddhn_u32', 'uint32x4_t', 'uint16x4_t', 'uint32x4_t::splat(16)']
      - ['vaddhn_u64', 'uint64x2_t', 'uint32x2_t', 'uint64x2_t::splat(32)']
    compose:
      - FnCall:
        - simd_cast
        - - FnCall:
            - simd_shr
            - - FnCall:
                - simd_add
                - - a
                  - b
              - '{type[3]}'

  - name: "{type[0]}"
    doc: "Add returning High Narrow (high half)."
    arguments: ['r: {neon_type[1]}', 'a: {neon_type[2]}', 'b: {neon_type[2]}']
    return_type: "{neon_type[3]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, { FnCall: [assert_instr, ['vaddhn']] }  ]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, { FnCall: [assert_instr, ['addhn2']]}] ]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - ['vaddhn_high_s16', 'int8x8_t', 'int16x8_t', 'int8x16_t', 'int16x8_t::splat(8)', '[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]']
      - ['vaddhn_high_s32', 'int16x4_t', 'int32x4_t', 'int16x8_t', 'int32x4_t::splat(16)', '[0, 1, 2, 3, 4, 5, 6, 7]']
      - ['vaddhn_high_s64', 'int32x2_t', 'int64x2_t', 'int32x4_t', 'int64x2_t::splat(32)', '[0, 1, 2, 3]']
      - ['vaddhn_high_u16', 'uint8x8_t', 'uint16x8_t', 'uint8x16_t', 'uint16x8_t::splat(8)', '[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]']
      - ['vaddhn_high_u32', 'uint16x4_t', 'uint32x4_t', 'uint16x8_t', 'uint32x4_t::splat(16)', '[0, 1, 2, 3, 4, 5, 6, 7]']
      - ['vaddhn_high_u64', 'uint32x2_t', 'uint64x2_t', 'uint32x4_t', 'uint64x2_t::splat(32)', '[0, 1, 2, 3]']
    compose:
      - Let:
        - x
        - FnCall:
          - simd_cast
          - - FnCall:
              - simd_shr
              - - FnCall:
                  - simd_add
                  - - a
                    - b
                - '{type[4]}'
      - FnCall: ['simd_shuffle!', [r, x, '{type[5]}']]

  - name: "{type[0]}"
    doc: "Vector narrow integer."
    arguments: ['a: {neon_type[1]}']
    return_type: "{neon_type[2]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, { FnCall: [assert_instr, ['vmovn']] }  ]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, { FnCall: [assert_instr, ['xtn']]}] ]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - ['vmovn_s16', 'int16x8_t', 'int8x8_t']
      - ['vmovn_s32', 'int32x4_t', 'int16x4_t']
      - ['vmovn_s64', 'int64x2_t', 'int32x2_t']
      - ['vmovn_u16', 'uint16x8_t', 'uint8x8_t']
      - ['vmovn_u32', 'uint32x4_t', 'uint16x4_t']
      - ['vmovn_u64', 'uint64x2_t', 'uint32x2_t']
    compose:
      - FnCall: [simd_cast, [a]]

  - name: "{type[0]}"
    doc: "Vector long move." 
    arguments: ['a: {neon_type[1]}']
    return_type: "{neon_type[2]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, { FnCall: [assert_instr, ['vmovl']] }  ]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, { FnCall: [assert_instr, ['{type[3]}']]}] ]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - ['vmovl_s8', 'int8x8_t', 'int16x8_t', 'sxtl']
      - ['vmovl_s16', 'int16x4_t', 'int32x4_t', 'sxtl']
      - ['vmovl_s32', 'int32x2_t', 'int64x2_t', 'sxtl']
      - ['vmovl_u8', 'uint8x8_t', 'uint16x8_t', 'uxtl']
      - ['vmovl_u16', 'uint16x4_t', 'uint32x4_t', 'uxtl']
      - ['vmovl_u32', 'uint32x2_t', 'uint64x2_t', 'uxtl']
    compose:
      - FnCall: [simd_cast, [a]]

  - name: "{type[0]}"
    doc: "Vector bitwise not." 
    arguments: ['a: {neon_type[1]}']
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, { FnCall: [assert_instr, ['vmvn']] }  ]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, { FnCall: [assert_instr, ['mvn']]}] ]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - ['vmvn_s8', 'int8x8_t', 'int8x8_t::splat(-1)']
      - ['vmvnq_s8', 'int8x16_t', 'int8x16_t::splat(-1)']
      - ['vmvn_s16', 'int16x4_t', 'int16x4_t::splat(-1)']
      - ['vmvnq_s16', 'int16x8_t', 'int16x8_t::splat(-1)']
      - ['vmvn_s32', 'int32x2_t', 'int32x2_t::splat(-1)']
      - ['vmvnq_s32', 'int32x4_t', 'int32x4_t::splat(-1)']
      - ['vmvn_u8', 'uint8x8_t', 'uint8x8_t::splat(255)']
      - ['vmvnq_u8', 'uint8x16_t', 'uint8x16_t::splat(255)']
      - ['vmvn_u16', 'uint16x4_t', 'uint16x4_t::splat(65_535)']
      - ['vmvnq_u16', 'uint16x8_t', 'uint16x8_t::splat(65_535)']
      - ['vmvn_u32', 'uint32x2_t', 'uint32x2_t::splat(4_294_967_295)']
      - ['vmvnq_u32', 'uint32x4_t', 'uint32x4_t::splat(4_294_967_295)']
      - ['vmvn_p8', 'poly8x8_t', 'poly8x8_t::splat(255)']
      - ['vmvnq_p8', 'poly8x16_t', 'poly8x16_t::splat(255)']
    compose:
      - Let: [b, '{type[2]}']
      - FnCall: [simd_xor, [a, b]]

  - name: "{type[0]}"
    doc: "Vector bitwise bit clear." 
    arguments: ['a: {neon_type[1]}', 'b: {neon_type[1]}']
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, { FnCall: [assert_instr, ['vbic']] }  ]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, { FnCall: [assert_instr, ['bic']]}] ]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - ['vbic_s8', 'int8x8_t', 'int8x8_t::splat(-1)']
      - ['vbic_s16', 'int16x4_t', 'int16x4_t::splat(-1)']
      - ['vbic_s32', 'int32x2_t', 'int32x2_t::splat(-1)']
      - ['vbic_s64', 'int64x1_t', 'int64x1_t::splat(-1)']
      - ['vbicq_s8', 'int8x16_t', 'int8x16_t::splat(-1)']
      - ['vbicq_s16', 'int16x8_t', 'int16x8_t::splat(-1)']
      - ['vbicq_s32', 'int32x4_t', 'int32x4_t::splat(-1)']
      - ['vbicq_s64', 'int64x2_t', 'int64x2_t::splat(-1)']
    compose:
      - Let: [c, '{type[2]}']
      - FnCall:
        - simd_and
        - - FnCall: [simd_xor, [b, c]]
          - a

  - name: "{type[0]}"
    doc: "Vector bitwise bit clear." 
    arguments: ['a: {neon_type[1]}', 'b: {neon_type[1]}']
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, { FnCall: [assert_instr, ['vbic']] }  ]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, { FnCall: [assert_instr, ['bic']]}] ]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - ['vbic_u8', 'uint8x8_t', 'int8x8_t::splat(-1)']
      - ['vbic_u16', 'uint16x4_t', 'int16x4_t::splat(-1)']
      - ['vbic_u32', 'uint32x2_t', 'int32x2_t::splat(-1)']
      - ['vbic_u64', 'uint64x1_t', 'int64x1_t::splat(-1)']
      - ['vbicq_u8', 'uint8x16_t', 'int8x16_t::splat(-1)']
      - ['vbicq_u16', 'uint16x8_t', 'int16x8_t::splat(-1)']
      - ['vbicq_u32', 'uint32x4_t', 'int32x4_t::splat(-1)']
      - ['vbicq_u64', 'uint64x2_t', 'int64x2_t::splat(-1)']
    compose:
      - Let: [c, '{type[2]}']
      - FnCall:
        - simd_and
        - - FnCall:
            - simd_xor
            - - b
              - FnCall: [transmute, [c]]
          - a

  - name: "{type[0]}"
    doc: "Bitwise Select."
    arguments: ["a: {neon_type[1]}", "b: {neon_type[2]}", "c: {neon_type[2]}"]
    return_type: "{neon_type[2]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, { FnCall: [assert_instr, ['vbsl']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, ['bsl']]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - ['vbsl_s8', 'uint8x8_t', 'int8x8_t', 'int8x8_t::splat(-1)']
      - ['vbsl_s16', 'uint16x4_t', 'int16x4_t', 'int16x4_t::splat(-1)']
      - ['vbsl_s32', 'uint32x2_t', 'int32x2_t', 'int32x2_t::splat(-1)']
      - ['vbsl_s64', 'uint64x1_t', 'int64x1_t', 'int64x1_t::splat(-1)']
      - ['vbsl_f32', 'uint32x2_t', 'float32x2_t', 'int32x2_t::splat(-1)']
      - ['vbslq_f32', 'uint32x4_t', 'float32x4_t', 'int32x4_t::splat(-1)']
      - ['vbsl_p8', 'uint8x8_t', 'poly8x8_t', 'int8x8_t::splat(-1)']
      - ['vbsl_p16', 'uint16x4_t', 'poly16x4_t', 'int16x4_t::splat(-1)']
      - ['vbslq_s8', 'uint8x16_t', 'int8x16_t', 'int8x16_t::splat(-1)']
      - ['vbslq_s16', 'uint16x8_t', 'int16x8_t', 'int16x8_t::splat(-1)']
      - ['vbslq_s32', 'uint32x4_t', 'int32x4_t', 'int32x4_t::splat(-1)']
      - ['vbslq_s64', 'uint64x2_t', 'int64x2_t', 'int64x2_t::splat(-1)']
      - ['vbslq_p8', 'uint8x16_t', 'poly8x16_t', 'int8x16_t::splat(-1)']
      - ['vbslq_p16', 'uint16x8_t', 'poly16x8_t', 'int16x8_t::splat(-1)']
    compose:
      - Let: [not, '{type[3]}']
      - FnCall:
        - transmute
        - - FnCall:
            - simd_or
            - - FnCall:
                - simd_and
                - - a
                  - FnCall: [transmute, [b]]
              - FnCall:
                - simd_and
                - - FnCall:
                    - simd_xor
                    - - a
                      - FnCall: [transmute, [not]]
                  - FnCall: [transmute, [c]]

  - name: "{type[0]}"
    doc: "Bitwise Select."
    arguments: ["a: {neon_type[1]}", "b: {neon_type[2]}", "c: {neon_type[2]}"]
    return_type: "{neon_type[2]}"
    attr:
      - *neon-fp16
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, { FnCall: [assert_instr, ['vbsl']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, ['bsl']]}]]
      - *neon-not-arm-stable-fp16
      - *neon-cfg-arm-unstable
      - *target-not-arm64ec
    safety: safe
    types:
      - ['vbslq_f16', 'uint16x8_t', 'float16x8_t', 'int16x8_t::splat(-1)']
      - ['vbsl_f16', 'uint16x4_t', 'float16x4_t', 'int16x4_t::splat(-1)']
    compose:
      - Let: [not, '{type[3]}']
      - FnCall:
        - transmute
        - - FnCall:
            - simd_or
            - - FnCall:
                - simd_and
                - - a
                  - FnCall: [transmute, [b]]
              - FnCall:
                - simd_and
                - - FnCall:
                    - simd_xor
                    - - a
                      - FnCall: [transmute, [not]]
                  - FnCall: [transmute, [c]]

  - name: "{type[0]}"
    doc: "Bitwise Select."
    arguments: ["a: {neon_type[1]}", "b: {neon_type[1]}", "c: {neon_type[1]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, { FnCall: [assert_instr, ['vbsl']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, ['bsl']]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - ['vbslq_u8', 'uint8x16_t', 'int8x16_t::splat(-1)']
      - ['vbslq_u16', 'uint16x8_t', 'int16x8_t::splat(-1)']
      - ['vbslq_u32', 'uint32x4_t', 'int32x4_t::splat(-1)']
      - ['vbslq_u64', 'uint64x2_t', 'int64x2_t::splat(-1)']
      - ['vbsl_u8', 'uint8x8_t', 'int8x8_t::splat(-1)']
      - ['vbsl_u16', 'uint16x4_t', 'int16x4_t::splat(-1)']
      - ['vbsl_u32', 'uint32x2_t', 'int32x2_t::splat(-1)']
      - ['vbsl_u64', 'uint64x1_t', 'int64x1_t::splat(-1)']
    compose:
      - Let: [not, '{type[2]}']
      - FnCall:
        - transmute
        - - FnCall:
            - simd_or
            - - FnCall: [simd_and, [a, b]]
              - FnCall:
                - simd_and
                - - FnCall:
                    - simd_xor
                    - - a
                      - FnCall: [transmute, [not]]
                  - c

  - name: "{type[0]}"
    doc: "Vector bitwise inclusive OR NOT"
    arguments: ["a: {neon_type[1]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, { FnCall: [assert_instr, ['vorn']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, ['orn']]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - ['vorn_s8', 'int8x8_t', 'int8x8_t::splat(-1)']
      - ['vornq_s8', 'int8x16_t', 'int8x16_t::splat(-1)']
      - ['vorn_s16', 'int16x4_t', 'int16x4_t::splat(-1)']
      - ['vornq_s16', 'int16x8_t', 'int16x8_t::splat(-1)']
      - ['vorn_s32', 'int32x2_t', 'int32x2_t::splat(-1)']
      - ['vornq_s32', 'int32x4_t', 'int32x4_t::splat(-1)']
      - ['vorn_s64', 'int64x1_t', 'int64x1_t::splat(-1)']
      - ['vornq_s64', 'int64x2_t', 'int64x2_t::splat(-1)']
    compose:
      - Let: [c, '{type[2]}']
      - FnCall:
        - simd_or
        - - FnCall: [simd_xor, [b, c]]
          - a

  - name: "{type[0]}"
    doc: "Vector bitwise inclusive OR NOT"
    arguments: ["a: {neon_type[1]}", "b: {neon_type[1]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, { FnCall: [assert_instr, ['vorn']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, ['orn']]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - ['vorn_u8', 'uint8x8_t', 'int8x8_t::splat(-1)']
      - ['vornq_u8', 'uint8x16_t', 'int8x16_t::splat(-1)']
      - ['vorn_u16', 'uint16x4_t', 'int16x4_t::splat(-1)']
      - ['vornq_u16', 'uint16x8_t', 'int16x8_t::splat(-1)']
      - ['vorn_u32', 'uint32x2_t', 'int32x2_t::splat(-1)']
      - ['vornq_u32', 'uint32x4_t', 'int32x4_t::splat(-1)']
      - ['vorn_u64', 'uint64x1_t', 'int64x1_t::splat(-1)']
      - ['vornq_u64', 'uint64x2_t', 'int64x2_t::splat(-1)']
    compose:
      - Let: [c, '{type[2]}']
      - FnCall:
        - simd_or
        - - FnCall:
            - simd_xor
            - - b
              - FnCall: [transmute, [c]]
          - a

  - name: "{type[0]}"
    doc: "Move vector element to general-purpose register"
    arguments: ["v: {neon_type[1]}"]
    return_type: "{type[2]}"
    safety: safe
    static_defs: ['const IMM5: i32']
    attr:
      - *neon-v7
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [nop, 'IMM5 = {type[3]}']]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    types:
      - ['vget_lane_s8', 'int8x8_t', 'i8', '2', 'IMM5, 3', 'IMM5 as u32']
      - ['vget_lane_u8', 'uint8x8_t', 'u8', '2', 'IMM5, 3', 'IMM5 as u32']
      - ['vget_lane_p8', 'poly8x8_t', 'p8', '2', 'IMM5, 3', 'IMM5 as u32']
      - ['vgetq_lane_s8', 'int8x16_t', 'i8', '2', 'IMM5, 4', 'IMM5 as u32']
      - ['vgetq_lane_u8', 'uint8x16_t', 'u8', '2', 'IMM5, 4', 'IMM5 as u32']
      - ['vgetq_lane_p8', 'poly8x16_t', 'p8', '2', 'IMM5, 4', 'IMM5 as u32']
      - ['vget_lane_u16', 'uint16x4_t', 'u16', '2', 'IMM5, 2', 'IMM5 as u32']
      - ['vget_lane_s16', 'int16x4_t', 'i16', '2', 'IMM5, 2', 'IMM5 as u32']
      - ['vget_lane_p16', 'poly16x4_t', 'p16', '2', 'IMM5, 2', 'IMM5 as u32']
      - ['vgetq_lane_u16', 'uint16x8_t', 'u16', '2', 'IMM5, 3', 'IMM5 as u32']
      - ['vgetq_lane_s16', 'int16x8_t', 'i16', '2', 'IMM5, 3', 'IMM5 as u32']
      - ['vgetq_lane_p16', 'poly16x8_t', 'p16', '2', 'IMM5, 3', 'IMM5 as u32']
      - ['vget_lane_u32', 'uint32x2_t', 'u32', '1', 'IMM5, 1', 'IMM5 as u32']
      - ['vget_lane_s32', 'int32x2_t', 'i32', '1', 'IMM5, 1', 'IMM5 as u32']
      - ['vgetq_lane_u32', 'uint32x4_t', 'u32', '2', 'IMM5, 2', 'IMM5 as u32']
      - ['vgetq_lane_s32', 'int32x4_t', 'i32', '2', 'IMM5, 2', 'IMM5 as u32']
      - ['vget_lane_f32', 'float32x2_t', 'f32', '1', 'IMM5, 1', 'IMM5 as u32']
      - ['vgetq_lane_f32', 'float32x4_t', 'f32', '1', 'IMM5, 2', 'IMM5 as u32']
      - ['vgetq_lane_p64', 'poly64x2_t', 'p64', '1', 'IMM5, 1', 'IMM5 as u32']
      - ['vgetq_lane_s64', 'int64x2_t', 'i64', '1', 'IMM5, 1', 'IMM5 as u32']
      - ['vgetq_lane_u64', 'uint64x2_t', 'u64', '1', 'IMM5, 2', 'IMM5 as u32']
    compose:
      - FnCall: ['static_assert_uimm_bits!', ['{type[4]}']]
      - FnCall: ['simd_extract!', [v, '{type[5]}']]

  - name: "{type[0]}"
    doc: "Move vector element to general-purpose register"
    arguments: ["v: {neon_type[1]}"]
    return_type: "{type[2]}"
    safety: safe
    static_defs: ['const IMM5: i32']
    attr:
      - *neon-v7
      - FnCall: [rustc_legacy_const_generics, ['1']]
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [nop, 'IMM5 = 0']]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    types:
      - ['vget_lane_u64', 'uint64x1_t', 'u64', '0']
      - ['vget_lane_p64', 'poly64x1_t', 'p64', 'IMM5 as u32']
      - ['vget_lane_s64', 'int64x1_t', 'i64', 'IMM5 as u32']
    compose:
      - FnCall: ['static_assert!', ['IMM5 == 0']]
      - FnCall: ['simd_extract!', [v, '{type[3]}']]

    # Private vfp4 version used by FMA intriniscs because LLVM does
    # not inline the non-vfp4 version in vfp4 functions.
  - name: "{type[0]}"
    visibility: private
    doc: "Duplicate vector element to vector or scalar"
    arguments: ["value: {type[1]}"]
    return_type: "{neon_type[2]}"
    attr:
      - FnCall: [cfg_attr, [target_arch = "arm", {FnCall: [target_feature, ['enable = "vfp4"']]}]]
      - FnCall: [cfg_attr, [*test-is-arm, { FnCall: [assert_instr, ['"vdup.32"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, ['dup']]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - ['vdup_n_f32_vfp4', 'f32', 'float32x2_t', 'float32x2_t::splat(value)']
      - ['vdupq_n_f32_vfp4', 'f32', 'float32x4_t', 'float32x4_t::splat(value)']
    compose:
      - Identifier: ['{type[3]}', Symbol]

  - name: "{type[0]}"
    doc: "Duplicate vector element to vector or scalar"
    arguments: ["a: {type[1]}"]
    return_type: "{neon_type[2]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, { FnCall: [assert_instr, ['"{type[3]}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, ['{type[4]}']]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - ['vget_high_s64', 'int64x2_t', 'int64x1_t', 'vmov', 'ext', 'unsafe { int64x1_t([simd_extract!(a, 1)]) }']
      - ['vget_high_u64', 'uint64x2_t', 'uint64x1_t', 'vmov', 'ext', 'unsafe { uint64x1_t([simd_extract!(a, 1)]) }']
    compose:
      - Identifier: ['{type[5]}', Symbol]

  - name: "{type[0]}"
    doc: "Duplicate vector element to vector or scalar"
    arguments: ["a: {type[1]}"]
    return_type: "{neon_type[2]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [nop]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - ['vget_low_s64', 'int64x2_t', 'int64x1_t', 'unsafe { int64x1_t([simd_extract!(a, 0)]) }']
      - ['vget_low_u64', 'uint64x2_t', 'uint64x1_t', 'unsafe { uint64x1_t([simd_extract!(a, 0)]) }']
    compose:
      - Identifier: ['{type[3]}', Symbol]

  - name: "{type[0]}"
    doc: "Duplicate vector element to vector or scalar"
    arguments: ["a: {type[1]}"]
    return_type: "{neon_type[2]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, { FnCall: [assert_instr, ['"{type[3]}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, ['{type[4]}']]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - ['vget_high_s8', 'int8x16_t', 'int8x8_t', 'vmov', 'ext', '[8, 9, 10, 11, 12, 13, 14, 15]']
      - ['vget_high_u8', 'uint8x16_t', 'uint8x8_t', 'vmov', 'ext', '[8, 9, 10, 11, 12, 13, 14, 15]']
      - ['vget_high_p8', 'poly8x16_t', 'poly8x8_t', 'vmov', 'ext', '[8, 9, 10, 11, 12, 13, 14, 15]']
      - ['vget_high_s16', 'int16x8_t', 'int16x4_t', 'vmov', 'ext', '[4, 5, 6, 7]']
      - ['vget_high_u16', 'uint16x8_t', 'uint16x4_t', 'vmov', 'ext', '[4, 5, 6, 7]']
      - ['vget_high_p16', 'poly16x8_t', 'poly16x4_t', 'vmov', 'ext', '[4, 5, 6, 7]']
      - ['vget_high_s32', 'int32x4_t', 'int32x2_t', 'vmov', 'ext', '[2, 3]']
      - ['vget_high_u32', 'uint32x4_t', 'uint32x2_t', 'vmov', 'ext', '[2, 3]']
      - ['vget_high_f32', 'float32x4_t', 'float32x2_t', 'vmov', 'ext', '[2, 3]']
    compose:
      - FnCall: ['simd_shuffle!', [a, a, '{type[5]}']]

  - name: "{type[0]}"
    doc: "Duplicate vector element to vector or scalar"
    arguments: ["a: {type[1]}"]
    return_type: "{neon_type[2]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [nop]]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - ['vget_low_s8', 'int8x16_t', 'int8x8_t', '[0, 1, 2, 3, 4, 5, 6, 7]']
      - ['vget_low_u8', 'uint8x16_t', 'uint8x8_t','[0, 1, 2, 3, 4, 5, 6, 7]']
      - ['vget_low_p8', 'poly8x16_t', 'poly8x8_t','[0, 1, 2, 3, 4, 5, 6, 7]']
      - ['vget_low_s16', 'int16x8_t', 'int16x4_t', '[0, 1, 2, 3]']
      - ['vget_low_u16', 'uint16x8_t', 'uint16x4_t', '[0, 1, 2, 3]']
      - ['vget_low_p16', 'poly16x8_t', 'poly16x4_t', '[0, 1, 2, 3]']
      - ['vget_low_s32', 'int32x4_t', 'int32x2_t', '[0, 1]']
      - ['vget_low_f32', 'float32x4_t', 'float32x2_t', '[0, 1]']
      - ['vget_low_u32', 'uint32x4_t', 'uint32x2_t', '[0, 1]']
    compose:
      - FnCall: ['simd_shuffle!', [a, a, '{type[3]}']]

  - name: "{type[0]}"
    doc: "Duplicate vector element to vector or scalar"
    arguments: ["value: {type[1]}"]
    return_type: "{neon_type[2]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, { FnCall: [assert_instr, ['"{type[3]}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, ['{type[4]}']]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - ['vdupq_n_s8', 'i8', 'int8x16_t', 'vdup.8', 'dup', 'int8x16_t::splat(value)']
      - ['vdupq_n_s16', 'i16', 'int16x8_t', 'vdup.16', 'dup', 'int16x8_t::splat(value)']
      - ['vdupq_n_s32', 'i32', 'int32x4_t', 'vdup.32', 'dup', 'int32x4_t::splat(value)']
      - ['vdupq_n_s64', 'i64', 'int64x2_t', 'vmov', 'dup', 'int64x2_t::splat(value)']
      - ['vdupq_n_u8', 'u8', 'uint8x16_t', 'vdup.8', 'dup', 'uint8x16_t::splat(value)']
      - ['vdupq_n_u16', 'u16', 'uint16x8_t', 'vdup.16', 'dup', 'uint16x8_t::splat(value)']
      - ['vdupq_n_u32', 'u32', 'uint32x4_t', 'vdup.32', 'dup', 'uint32x4_t::splat(value)']
      - ['vdupq_n_f32', 'f32', 'float32x4_t', 'vdup.32', 'dup', 'float32x4_t::splat(value)']
      - ['vdupq_n_u64', 'u64', 'uint64x2_t', 'vmov', 'dup', 'uint64x2_t::splat(value)']
      - ['vdupq_n_p8', 'p8', 'poly8x16_t', 'vdup.8', 'dup', 'poly8x16_t::splat(value)']
      - ['vdupq_n_p16', 'p16', 'poly16x8_t', 'vdup.16', 'dup', 'poly16x8_t::splat(value)']
      - ['vdup_n_s8', 'i8', 'int8x8_t', 'vdup.8', 'dup', 'int8x8_t::splat(value)']
      - ['vdup_n_s16', 'i16', 'int16x4_t', 'vdup.16', 'dup', 'int16x4_t::splat(value)']
      - ['vdup_n_s32', 'i32', 'int32x2_t', 'vdup.32', 'dup', 'int32x2_t::splat(value)']
      - ['vdup_n_s64', 'i64', 'int64x1_t', 'vmov', 'fmov', 'int64x1_t::splat(value)']
      - ['vdup_n_u8', 'u8', 'uint8x8_t', 'vdup.8', 'dup', 'uint8x8_t::splat(value)']
      - ['vdup_n_u16', 'u16', 'uint16x4_t', 'vdup.16', 'dup', 'uint16x4_t::splat(value)']
      - ['vdup_n_u32', 'u32', 'uint32x2_t', 'vdup.32', 'dup', 'uint32x2_t::splat(value)']
      - ['vdup_n_f32', 'f32', 'float32x2_t', 'vdup.32', 'dup', 'float32x2_t::splat(value)']
      - ['vdup_n_u64', 'u64', 'uint64x1_t', 'vmov', 'fmov', 'uint64x1_t::splat(value)']
      - ['vdup_n_p8', 'p8', 'poly8x8_t', 'vdup.8', 'dup', 'poly8x8_t::splat(value)']
      - ['vdup_n_p16', 'p16', 'poly16x4_t', 'vdup.16', 'dup', 'poly16x4_t::splat(value)']
    compose:
      - Identifier: ['{type[5]}', Symbol]

  - name: "{type[0]}"
    doc: "Duplicate vector element to vector or scalar"
    arguments: ["value: {type[1]}"]
    return_type: "{neon_type[2]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, { FnCall: [assert_instr, ['"{type[3]}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, ['{type[4]}']]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - ['vmov_n_s8', 'i8', 'int8x8_t', 'vdup.8', 'dup', 'vdup_n_s8']
      - ['vmov_n_s16', 'i16', 'int16x4_t', 'vdup.16', 'dup', 'vdup_n_s16']
      - ['vmov_n_s32', 'i32', 'int32x2_t', 'vdup.32', 'dup', 'vdup_n_s32']
      - ['vmov_n_s64', 'i64', 'int64x1_t', 'vmov', 'fmov', 'vdup_n_s64']
      - ['vmov_n_u8', 'u8', 'uint8x8_t', 'vdup.8', 'dup', 'vdup_n_u8']
      - ['vmov_n_u16', 'u16', 'uint16x4_t', 'vdup.16', 'dup', 'vdup_n_u16']
      - ['vmov_n_u32', 'u32', 'uint32x2_t', 'vdup.32', 'dup', 'vdup_n_u32']
      - ['vmov_n_u64', 'u64', 'uint64x1_t', 'vmov', 'fmov', 'vdup_n_u64']
      - ['vmov_n_p8', 'p8', 'poly8x8_t', 'vdup.8', 'dup', 'vdup_n_p8']
      - ['vmov_n_p16', 'p16', 'poly16x4_t', 'vdup.16', 'dup', 'vdup_n_p16']
      - ['vmov_n_f32', 'f32', 'float32x2_t', 'vdup.32', 'dup', 'vdup_n_f32']
      - ['vmovq_n_s8', 'i8', 'int8x16_t', 'vdup.8', 'dup', 'vdupq_n_s8']
      - ['vmovq_n_s16', 'i16', 'int16x8_t', 'vdup.16', 'dup', 'vdupq_n_s16']
      - ['vmovq_n_s32', 'i32', 'int32x4_t', 'vdup.32', 'dup', 'vdupq_n_s32']
      - ['vmovq_n_s64', 'i64', 'int64x2_t', 'vmov', 'dup', 'vdupq_n_s64']
      - ['vmovq_n_u8', 'u8', 'uint8x16_t', 'vdup.8', 'dup', 'vdupq_n_u8']
      - ['vmovq_n_u16', 'u16', 'uint16x8_t', 'vdup.16', 'dup', 'vdupq_n_u16']
      - ['vmovq_n_u32', 'u32', 'uint32x4_t', 'vdup.32', 'dup', 'vdupq_n_u32']
      - ['vmovq_n_u64', 'u64', 'uint64x2_t', 'vmov', 'dup', 'vdupq_n_u64']
      - ['vmovq_n_p8', 'p8', 'poly8x16_t', 'vdup.8', 'dup', 'vdupq_n_p8']
      - ['vmovq_n_p16', 'p16', 'poly16x8_t', 'vdup.16', 'dup', 'vdupq_n_p16']
      - ['vmovq_n_f32', 'f32', 'float32x4_t', 'vdup.32', 'dup', 'vdupq_n_f32']
    compose:
      - FnCall: ['{type[5]}', [value]]

  - name: "{type[0]}"
    doc: "Store SIMD&FP register (immediate offset)"
    arguments: ["a: {type[1]}"]
    return_type: "{type[2]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['nop']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, ['nop']]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety:
      unsafe: [neon]
    types:
      - ['vldrq_p128', '* const p128', 'p128']
    compose:
      - Identifier: ['*a', Symbol]

  - name: "{type[0]}"
    doc: "Store SIMD&FP register (immediate offset)"
    arguments: ["a: {type[1]}", "b: {type[2]}"]
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['nop']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, ['nop']]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety:
      unsafe: [neon]
    types:
      - ['vstrq_p128', '* mut p128', 'p128']
    compose:
      - Identifier: ['*a = b', Symbol]

  - name: "{type[0]}"
    doc: "Extract vector from pair of vectors"
    arguments: ["a: {neon_type[1]}", "_b: {neon_type[1]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['nop', 'N = 0']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, ['nop', 'N = 0']]}]]
      - FnCall: [rustc_legacy_const_generics, ['2']]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    static_defs: ['const N: i32']
    safety:
      unsafe: [neon]
    types:
      - ['vext_s64', 'int64x1_t']
      - ['vext_u64', 'uint64x1_t']
    compose:
      - FnCall: ['static_assert!', ['N == 0']]
      - Identifier: ['a', Symbol]

  - name: "{type[0]}"
    doc: "Reversing vector elements (swap endianness)"
    arguments: ["a: {neon_type[1]}"]
    return_type: "{neon_type[1]}"
    attr:
      - *neon-v7
      - FnCall: [cfg_attr, [*test-is-arm, {FnCall: [assert_instr, ['"{type[2]}"']]}]]
      - FnCall: [cfg_attr, [*neon-target-aarch64-arm64ec, {FnCall: [assert_instr, ['{type[3]}']]}]]
      - *neon-not-arm-stable
      - *neon-cfg-arm-unstable
    safety: safe
    types:
      - ['vrev16_s8', 'int8x8_t', 'vrev16.8', 'rev16', '[1, 0, 3, 2, 5, 4, 7, 6]']
      - ['vrev16q_s8', 'int8x16_t', 'vrev16.8', 'rev16', '[1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14]']
      - ['vrev16_u8', 'uint8x8_t', 'vrev16.8', 'rev16', '[1, 0, 3, 2, 5, 4, 7, 6]']
      - ['vrev16q_u8', 'uint8x16_t', 'vrev16.8', 'rev16', '[1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14]']
      - ['vrev16_p8', 'poly8x8_t', 'vrev16.8', 'rev16', '[1, 0, 3, 2, 5, 4, 7, 6]']
      - ['vrev16q_p8', 'poly8x16_t', 'vrev16.8', 'rev16', '[1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14]']
      - ['vrev32_s8', 'int8x8_t', 'vrev32.8', 'rev32', '[3, 2, 1, 0, 7, 6, 5, 4]']
      - ['vrev32q_s8', 'int8x16_t', 'vrev32.8', 'rev32', '[3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12]']
      - ['vrev32_u8', 'uint8x8_t', 'vrev32.8', 'rev32', '[3, 2, 1, 0, 7, 6, 5, 4]']
      - ['vrev32q_u8', 'uint8x16_t', 'vrev32.8', 'rev32', '[3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12]']
      - ['vrev32_p8', 'poly8x8_t', 'vrev32.8', 'rev32', '[3, 2, 1, 0, 7, 6, 5, 4]']
      - ['vrev32q_p8', 'poly8x16_t', 'vrev32.8', 'rev32', '[3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12]']
      - ['vrev32_s16', 'int16x4_t', 'vrev32.16', 'rev32', '[1, 0, 3, 2]']
      - ['vrev32q_s16', 'int16x8_t', 'vrev32.16', 'rev32', '[1, 0, 3, 2, 5, 4, 7, 6]']
      - ['vrev32_u16', 'uint16x4_t', 'vrev32.16', 'rev32', '[1, 0, 3, 2]']
      - ['vrev32q_u16', 'uint16x8_t', 'vrev32.16', 'rev32', '[1, 0, 3, 2, 5, 4, 7, 6]']
      - ['vrev32_p16', 'poly16x4_t', 'vrev32.16', 'rev32', '[1, 0, 3, 2]']
      - ['vrev32q_p16', 'poly16x8_t', 'vrev32.16', 'rev32', '[1, 0, 3, 2, 5, 4, 7, 6]']
      - ['vrev64_s8', 'int8x8_t', 'vrev64.8', 'rev64', '[7, 6, 5, 4, 3, 2, 1, 0]']
      - ['vrev64q_s8', 'int8x16_t', 'vrev64.8', 'rev64', '[7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8]']
      - ['vrev64_u8', 'uint8x8_t', 'vrev64.8', 'rev64', '[7, 6, 5, 4, 3, 2, 1, 0]']
      - ['vrev64q_u8', 'uint8x16_t', 'vrev64.8', 'rev64', '[7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8]']
      - ['vrev64_p8', 'poly8x8_t', 'vrev64.8', 'rev64', '[7, 6, 5, 4, 3, 2, 1, 0]']
      - ['vrev64q_p8', 'poly8x16_t', 'vrev64.8', 'rev64', '[7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8]']
      - ['vrev64_s16', 'int16x4_t', 'vrev64.16', 'rev64', '[3, 2, 1, 0]']
      - ['vrev64q_s16', 'int16x8_t', 'vrev64.16', 'rev64', '[3, 2, 1, 0, 7, 6, 5, 4]']
      - ['vrev64_u16', 'uint16x4_t', 'vrev64.16', 'rev64', '[3, 2, 1, 0]']
      - ['vrev64q_u16', 'uint16x8_t', 'vrev64.16', 'rev64', '[3, 2, 1, 0, 7, 6, 5, 4]']
      - ['vrev64_p16', 'poly16x4_t', 'vrev64.16', 'rev64', '[3, 2, 1, 0]']
      - ['vrev64q_p16', 'poly16x8_t', 'vrev64.16', 'rev64', '[3, 2, 1, 0, 7, 6, 5, 4]']
      - ['vrev64_s32', 'int32x2_t', 'vrev64.32', 'rev64', '[1, 0]']
      - ['vrev64q_s32', 'int32x4_t', 'vrev64.32', 'rev64', '[1, 0, 3, 2]']
      - ['vrev64_u32', 'uint32x2_t', 'vrev64.32', 'rev64', '[1, 0]']
      - ['vrev64q_u32', 'uint32x4_t', 'vrev64.32', 'rev64', '[1, 0, 3, 2]']
      - ['vrev64_f32', 'float32x2_t', 'vrev64.32', 'rev64', '[1, 0]']
      - ['vrev64q_f32', 'float32x4_t', 'vrev64.32', 'rev64', '[1, 0, 3, 2]']
    compose:
      - FnCall: ['simd_shuffle!', [a, a, '{type[4]}']]
