blob: a352974704a3d1a3dca87b20120e641459e4cb2a [file] [log] [blame]
// Copyright 2021 Google LLC
//
// This source code is licensed under the BSD-style license found in the
// LICENSE file in the root directory of this source tree.
$assert REQUANTIZATION in ["FP32", "RNDNU"]
$assert not CHANNELWISE or REQUANTIZATION == "FP32"
$assert DATATYPE in ["QC8", "QS8", "QU8"]
$assert DATATYPE != "QC8" or REQUANTIZATION == "FP32"
$assert DATATYPE != "QU8" or REQUANTIZATION == "RNDNU"
#include <xnnpack/assembly.h>
$PARAMS_UNION = "xnn_qs8_minmax_params" if CHANNELWISE else "xnn_qs8_conv_minmax_params"
$if DATATYPE == "QU8":
$REWIND_DECREMENT = 15
$else:
$REWIND_DECREMENT = 3 if CHANNELWISE else {"RNDNU": 15, "FP32": 7}[REQUANTIZATION]
$XMIN = "UMIN" if DATATYPE == "QU8" else "SMIN"
$XMAX = "UMAX" if DATATYPE == "QU8" else "SMAX"
$XXTL = "UXTL" if DATATYPE == "QU8" else "SXTL"
$SQXTXN = "SQXTUN" if DATATYPE == "QU8" else "SQXTN"
$SQXTXN2 = "SQXTUN2" if DATATYPE == "QU8" else "SQXTN2"
$XINT8_T = "uint8_t" if DATATYPE == "QU8" else "int8_t"
# void xnn_${DATATYPE.lower()}_igemm_minmax_${REQUANTIZATION.lower()}_ukernel_4x16__aarch64_neon_mlal_lane${"_prfm" if PREFETCH else ""}_cortex_a75(
# size_t mr, x0
# size_t nc, x1
# size_t kc, x2 / x0
# size_t ks, x3 / x9
# const ${XINT8_T}** restrict a, x4
# const ${XINT8_T}* restrict w, x5
# ${XINT8_T}* restrict c, x6
# size_t cm_stride, x7
# size_t cn_stride, [sp] -> x10
# size_t a_offset, [sp + 8] -> x8
# const ${XINT8_T}* zero, [sp + 16] -> x12
# const xnn_qs8_conv_minmax_params params [sp + 24] -> x11
$if REQUANTIZATION == "RNDNU" and DATATYPE == "QU8":
# params structure is 20 bytes
# struct {
# ${XINT8_T} kernel_zero_point;
# ${XINT8_T} padding[3];
# int32_t right_pre_shift;
# int32_t multiplier;
# int32_t right_post_shift;
# int16_t output_zero_point;
# ${XINT8_T} output_min;
# ${XINT8_T} output_max;
# } rndnu_neon;
#
# d8-d15, x19-x30 need to be preserved if used. x18 is reserved by the OS.
# Register usage
# A0 x13 v0
# A1 x14 v1
# A2 x15 v2
# A3 x20 v3
# B x5 v4 v5 v6
# C0 x6 v16 v20 v24 v28
# C1 x16 v17 v21 v25 v29
# C2 x17 v18 v22 v26 v30
# C3 x7 v19 v23 v27 v31
$if DATATYPE == "QU8":
# zero_point v7
# unused v8 v9 v10 v11 v12 v13 v14 v15
$else:
# unused v7 v8 v9 v10 v11 v12 v13 v14 v15
BEGIN_FUNCTION xnn_${DATATYPE.lower()}_igemm_minmax_${REQUANTIZATION.lower()}_ukernel_4x16__aarch64_neon_mlal_lane${"_prfm" if PREFETCH else ""}_cortex_a75
# Clamp C pointers
CMP x0, 2 // if mr < 2
LDP x10, x8, [sp] // Load cn_stride, a_offset
ADD x16, x6, x7 // c1 = c0 + cm_stride
CSEL x16, x6, x16, LO // c1 = c0
ADD x17, x16, x7 // c2 = c1 + cm_stride
LDP x12, x11, [sp, 16] // Load zero, params pointer
// if mr <= 2
CSEL x17, x16, x17, LS // c2 = c1
CMP x0, 4 // if mr < 4
STR x20, [sp, -16]! // Save x20 on stack
ADD x7, x17, x7 // c3 = c2 + cm_stride
CSEL x7, x17, x7, LO // c3 = c2
$if DATATYPE == "QU8":
LD1R {v7.4s}, [x11], 4 // kernel_zero_point
.p2align 3
0:
# Load initial bias from w into accumulators
LDP q16, q20, [x5], 32
MOV v17.16b, v16.16b
MOV v18.16b, v16.16b
LDP q24, q28, [x5], 32
MOV v19.16b, v16.16b
MOV v21.16b, v20.16b
MOV v22.16b, v20.16b
MOV v23.16b, v20.16b
MOV v25.16b, v24.16b
MOV v26.16b, v24.16b
MOV v27.16b, v24.16b
MOV v29.16b, v28.16b
MOV v30.16b, v28.16b
MOV v31.16b, v28.16b
MOV x9, x3 // p = ks
.p2align 3
1:
# Load next 4 A pointers
LDP x13, x14, [x4], 16
LDP x15, x20, [x4], 16
CMP x13, x12 // if a0 == zero
ADD x13, x13, x8 // a0 += a_offset
CSEL x13, x12, x13, EQ // a0 = zero, else += a0 + a_offset
CMP x14, x12 // if a1 == zero
ADD x14, x14, x8 // a1 += a_offset
CSEL x14, x12, x14, EQ // a1 = zero, else += a1 + a_offset
CMP x15, x12 // if a2 == zero
ADD x15, x15, x8 // a2 += a_offset
CSEL x15, x12, x15, EQ // a2 = zero, else += a2 + a_offset
CMP x20, x12 // if a3 == zero
ADD x20, x20, x8 // a3 += a_offset
CSEL x20, x12, x20, EQ // a3 = zero, else += a3 + a_offset
# Is there at least 8 bytes for epilogue?
SUBS x0, x2, 8 // k = kc - 8
B.LO 5f
# Prologue
LDR d0, [x13], 8
LDP d4, d6, [x5]
LDR d1, [x14], 8
LDR d2, [x15], 8
LDR d3, [x20], 8
${XXTL} v0.8h, v0.8b
$if DATATYPE == "QU8":
USUBL v4.8h, v4.8b, v7.8b
$else:
SXTL v4.8h, v4.8b
${XXTL} v1.8h, v1.8b
${XXTL} v2.8h, v2.8b
${XXTL} v3.8h, v3.8b
$if DATATYPE == "QU8":
USUBL v6.8h, v6.8b, v7.8b
$else:
SXTL v6.8h, v6.8b
SUBS x0, x0, 8 // k = k - 8
# Is there at least 8 bytes for main loop?
B.LO 3f
# Main loop - 8 bytes of A
.p2align 3
2:
SMLAL v16.4s, v4.4h, v0.h[0]
SMLAL2 v20.4s, v4.8h, v0.h[0]
$if PREFETCH:
PRFM PLDL1KEEP, [x13, 128]
SMLAL v17.4s, v4.4h, v1.h[0]
SMLAL2 v21.4s, v4.8h, v1.h[0]
$if PREFETCH:
PRFM PLDL1KEEP, [x14, 128]
SMLAL v18.4s, v4.4h, v2.h[0]
SMLAL2 v22.4s, v4.8h, v2.h[0]
$if PREFETCH:
PRFM PLDL1KEEP, [x15, 128]
SMLAL v19.4s, v4.4h, v3.h[0]
SMLAL2 v23.4s, v4.8h, v3.h[0]
$if PREFETCH:
PRFM PLDL1KEEP, [x20, 128]
LDR d5, [x5, 16]
SMLAL v24.4s, v6.4h, v0.h[0]
LDR d4, [x5, 24]
SMLAL2 v28.4s, v6.8h, v0.h[0]
$if PREFETCH:
PRFM PLDL1KEEP, [x5, 448]
SMLAL v25.4s, v6.4h, v1.h[0]
SMLAL2 v29.4s, v6.8h, v1.h[0]
$if PREFETCH:
PRFM PLDL1KEEP, [x5, 512]
$if DATATYPE == "QU8":
USUBL v5.8h, v5.8b, v7.8b
$else:
SXTL v5.8h, v5.8b
SMLAL v26.4s, v6.4h, v2.h[0]
SMLAL2 v30.4s, v6.8h, v2.h[0]
SMLAL v27.4s, v6.4h, v3.h[0]
SMLAL2 v31.4s, v6.8h, v3.h[0]
SMLAL v16.4s, v5.4h, v0.h[1]
SMLAL2 v20.4s, v5.8h, v0.h[1]
SMLAL v17.4s, v5.4h, v1.h[1]
SMLAL2 v21.4s, v5.8h, v1.h[1]
$if DATATYPE == "QU8":
USUBL v4.8h, v4.8b, v7.8b
$else:
SXTL v4.8h, v4.8b
SMLAL v18.4s, v5.4h, v2.h[1]
SMLAL2 v22.4s, v5.8h, v2.h[1]
SMLAL v19.4s, v5.4h, v3.h[1]
SMLAL2 v23.4s, v5.8h, v3.h[1]
LDR d6, [x5, 32]
SMLAL v24.4s, v4.4h, v0.h[1]
LDR d5, [x5, 40]
SMLAL2 v28.4s, v4.8h, v0.h[1]
SMLAL v25.4s, v4.4h, v1.h[1]
SMLAL2 v29.4s, v4.8h, v1.h[1]
$if DATATYPE == "QU8":
USUBL v6.8h, v6.8b, v7.8b
$else:
SXTL v6.8h, v6.8b
SMLAL v26.4s, v4.4h, v2.h[1]
SMLAL2 v30.4s, v4.8h, v2.h[1]
SMLAL v27.4s, v4.4h, v3.h[1]
SMLAL2 v31.4s, v4.8h, v3.h[1]
SMLAL v16.4s, v6.4h, v0.h[2]
SMLAL2 v20.4s, v6.8h, v0.h[2]
SMLAL v17.4s, v6.4h, v1.h[2]
$if DATATYPE == "QU8":
USUBL v5.8h, v5.8b, v7.8b
$else:
SXTL v5.8h, v5.8b
SMLAL2 v21.4s, v6.8h, v1.h[2]
SMLAL v18.4s, v6.4h, v2.h[2]
SMLAL2 v22.4s, v6.8h, v2.h[2]
SMLAL v19.4s, v6.4h, v3.h[2]
SMLAL2 v23.4s, v6.8h, v3.h[2]
LDR d4, [x5, 48]
SMLAL v24.4s, v5.4h, v0.h[2]
LDR d6, [x5, 56]
SMLAL2 v28.4s, v5.8h, v0.h[2]
SMLAL v25.4s, v5.4h, v1.h[2]
SMLAL2 v29.4s, v5.8h, v1.h[2]
$if DATATYPE == "QU8":
USUBL v4.8h, v4.8b, v7.8b
$else:
SXTL v4.8h, v4.8b
SMLAL v26.4s, v5.4h, v2.h[2]
SMLAL2 v30.4s, v5.8h, v2.h[2]
SMLAL v27.4s, v5.4h, v3.h[2]
SMLAL2 v31.4s, v5.8h, v3.h[2]
SMLAL v16.4s, v4.4h, v0.h[3]
SMLAL2 v20.4s, v4.8h, v0.h[3]
SMLAL v17.4s, v4.4h, v1.h[3]
SMLAL2 v21.4s, v4.8h, v1.h[3]
$if DATATYPE == "QU8":
USUBL v6.8h, v6.8b, v7.8b
$else:
SXTL v6.8h, v6.8b
SMLAL v18.4s, v4.4h, v2.h[3]
SMLAL2 v22.4s, v4.8h, v2.h[3]
SMLAL v19.4s, v4.4h, v3.h[3]
SMLAL2 v23.4s, v4.8h, v3.h[3]
LDR d5, [x5, 64]
SMLAL v24.4s, v6.4h, v0.h[3]
LDR d4, [x5, 72]
SMLAL2 v28.4s, v6.8h, v0.h[3]
$if DATATYPE == "QU8":
USUBL v5.8h, v5.8b, v7.8b
$else:
SXTL v5.8h, v5.8b
SMLAL v25.4s, v6.4h, v1.h[3]
SMLAL2 v29.4s, v6.8h, v1.h[3]
SMLAL v26.4s, v6.4h, v2.h[3]
SMLAL2 v30.4s, v6.8h, v2.h[3]
SMLAL v27.4s, v6.4h, v3.h[3]
SMLAL2 v31.4s, v6.8h, v3.h[3]
SMLAL v16.4s, v5.4h, v0.h[4]
SMLAL2 v20.4s, v5.8h, v0.h[4]
SMLAL v17.4s, v5.4h, v1.h[4]
SMLAL2 v21.4s, v5.8h, v1.h[4]
$if DATATYPE == "QU8":
USUBL v4.8h, v4.8b, v7.8b
$else:
SXTL v4.8h, v4.8b
SMLAL v18.4s, v5.4h, v2.h[4]
SMLAL2 v22.4s, v5.8h, v2.h[4]
SMLAL v19.4s, v5.4h, v3.h[4]
SMLAL2 v23.4s, v5.8h, v3.h[4]
LDR d6, [x5, 80]
SMLAL v24.4s, v4.4h, v0.h[4]
LDR d5, [x5, 88]
SMLAL2 v28.4s, v4.8h, v0.h[4]
SMLAL v25.4s, v4.4h, v1.h[4]
SMLAL2 v29.4s, v4.8h, v1.h[4]
$if DATATYPE == "QU8":
USUBL v6.8h, v6.8b, v7.8b
$else:
SXTL v6.8h, v6.8b
SMLAL v26.4s, v4.4h, v2.h[4]
SMLAL2 v30.4s, v4.8h, v2.h[4]
SMLAL v27.4s, v4.4h, v3.h[4]
SMLAL2 v31.4s, v4.8h, v3.h[4]
SMLAL v16.4s, v6.4h, v0.h[5]
SMLAL2 v20.4s, v6.8h, v0.h[5]
SMLAL v17.4s, v6.4h, v1.h[5]
SMLAL2 v21.4s, v6.8h, v1.h[5]
$if DATATYPE == "QU8":
USUBL v5.8h, v5.8b, v7.8b
$else:
SXTL v5.8h, v5.8b
SMLAL v18.4s, v6.4h, v2.h[5]
SMLAL2 v22.4s, v6.8h, v2.h[5]
SMLAL v19.4s, v6.4h, v3.h[5]
SMLAL2 v23.4s, v6.8h, v3.h[5]
LDR d4, [x5, 96]
SMLAL v24.4s, v5.4h, v0.h[5]
LDR d6, [x5, 104]
SMLAL2 v28.4s, v5.8h, v0.h[5]
SMLAL v25.4s, v5.4h, v1.h[5]
SMLAL2 v29.4s, v5.8h, v1.h[5]
$if DATATYPE == "QU8":
USUBL v4.8h, v4.8b, v7.8b
$else:
SXTL v4.8h, v4.8b
SMLAL v26.4s, v5.4h, v2.h[5]
SMLAL2 v30.4s, v5.8h, v2.h[5]
SMLAL v27.4s, v5.4h, v3.h[5]
SMLAL2 v31.4s, v5.8h, v3.h[5]
$if DATATYPE == "QU8":
USUBL v6.8h, v6.8b, v7.8b
$else:
SXTL v6.8h, v6.8b
SMLAL v16.4s, v4.4h, v0.h[6]
SMLAL2 v20.4s, v4.8h, v0.h[6]
SMLAL v17.4s, v4.4h, v1.h[6]
SMLAL2 v21.4s, v4.8h, v1.h[6]
SMLAL v18.4s, v4.4h, v2.h[6]
SMLAL2 v22.4s, v4.8h, v2.h[6]
SMLAL v19.4s, v4.4h, v3.h[6]
SMLAL2 v23.4s, v4.8h, v3.h[6]
LDR d4, [x5, 112]
SMLAL v24.4s, v6.4h, v0.h[6]
LDR d5, [x5, 120]
SMLAL2 v28.4s, v6.8h, v0.h[6]
SMLAL v25.4s, v6.4h, v1.h[6]
SMLAL2 v29.4s, v6.8h, v1.h[6]
$if DATATYPE == "QU8":
USUBL v4.8h, v4.8b, v7.8b
$else:
SXTL v4.8h, v4.8b
ADD x5, x5, 128
SMLAL v26.4s, v6.4h, v2.h[6]
SMLAL2 v30.4s, v6.8h, v2.h[6]
SMLAL v27.4s, v6.4h, v3.h[6]
SMLAL2 v31.4s, v6.8h, v3.h[6]
$if DATATYPE == "QU8":
USUBL v5.8h, v5.8b, v7.8b
$else:
SXTL v5.8h, v5.8b
SMLAL v16.4s, v4.4h, v0.h[7]
SMLAL2 v20.4s, v4.8h, v0.h[7]
SMLAL v17.4s, v4.4h, v1.h[7]
SMLAL2 v21.4s, v4.8h, v1.h[7]
SMLAL v18.4s, v4.4h, v2.h[7]
SMLAL2 v22.4s, v4.8h, v2.h[7]
SMLAL v19.4s, v4.4h, v3.h[7]
SMLAL2 v23.4s, v4.8h, v3.h[7]
LDR d4, [x5]
SMLAL v24.4s, v5.4h, v0.h[7]
LDR d6, [x5, 8]
SMLAL2 v28.4s, v5.8h, v0.h[7]
SMLAL v25.4s, v5.4h, v1.h[7]
SMLAL2 v29.4s, v5.8h, v1.h[7]
LDR d0, [x13], 8
SMLAL v26.4s, v5.4h, v2.h[7]
LDR d1, [x14], 8
SMLAL2 v30.4s, v5.8h, v2.h[7]
SMLAL v27.4s, v5.4h, v3.h[7]
SMLAL2 v31.4s, v5.8h, v3.h[7]
LDR d2, [x15], 8
${XXTL} v0.8h, v0.8b
LDR d3, [x20], 8
${XXTL} v1.8h, v1.8b
$if DATATYPE == "QU8":
USUBL v4.8h, v4.8b, v7.8b
$else:
SXTL v4.8h, v4.8b
${XXTL} v2.8h, v2.8b
SUBS x0, x0, 8
${XXTL} v3.8h, v3.8b
$if DATATYPE == "QU8":
USUBL v6.8h, v6.8b, v7.8b
$else:
SXTL v6.8h, v6.8b
B.HS 2b
# Epilogue. Same as main loop but no preloads in final group
.p2align 3
3:
SMLAL v16.4s, v4.4h, v0.h[0]
SMLAL2 v20.4s, v4.8h, v0.h[0]
SMLAL v17.4s, v4.4h, v1.h[0]
SMLAL2 v21.4s, v4.8h, v1.h[0]
SMLAL v18.4s, v4.4h, v2.h[0]
SMLAL2 v22.4s, v4.8h, v2.h[0]
SMLAL v19.4s, v4.4h, v3.h[0]
SMLAL2 v23.4s, v4.8h, v3.h[0]
LDR d5, [x5, 16]
SMLAL v24.4s, v6.4h, v0.h[0]
LDR d4, [x5, 24]
SMLAL2 v28.4s, v6.8h, v0.h[0]
SMLAL v25.4s, v6.4h, v1.h[0]
SMLAL2 v29.4s, v6.8h, v1.h[0]
$if DATATYPE == "QU8":
USUBL v5.8h, v5.8b, v7.8b
$else:
SXTL v5.8h, v5.8b
SMLAL v26.4s, v6.4h, v2.h[0]
SMLAL2 v30.4s, v6.8h, v2.h[0]
SMLAL v27.4s, v6.4h, v3.h[0]
SMLAL2 v31.4s, v6.8h, v3.h[0]
SMLAL v16.4s, v5.4h, v0.h[1]
SMLAL2 v20.4s, v5.8h, v0.h[1]
SMLAL v17.4s, v5.4h, v1.h[1]
SMLAL2 v21.4s, v5.8h, v1.h[1]
$if DATATYPE == "QU8":
USUBL v4.8h, v4.8b, v7.8b
$else:
SXTL v4.8h, v4.8b
SMLAL v18.4s, v5.4h, v2.h[1]
SMLAL2 v22.4s, v5.8h, v2.h[1]
SMLAL v19.4s, v5.4h, v3.h[1]
SMLAL2 v23.4s, v5.8h, v3.h[1]
LDR d6, [x5, 32]
SMLAL v24.4s, v4.4h, v0.h[1]
LDR d5, [x5, 40]
SMLAL2 v28.4s, v4.8h, v0.h[1]
SMLAL v25.4s, v4.4h, v1.h[1]
SMLAL2 v29.4s, v4.8h, v1.h[1]
$if DATATYPE == "QU8":
USUBL v6.8h, v6.8b, v7.8b
$else:
SXTL v6.8h, v6.8b
SMLAL v26.4s, v4.4h, v2.h[1]
SMLAL2 v30.4s, v4.8h, v2.h[1]
SMLAL v27.4s, v4.4h, v3.h[1]
SMLAL2 v31.4s, v4.8h, v3.h[1]
SMLAL v16.4s, v6.4h, v0.h[2]
SMLAL2 v20.4s, v6.8h, v0.h[2]
SMLAL v17.4s, v6.4h, v1.h[2]
$if DATATYPE == "QU8":
USUBL v5.8h, v5.8b, v7.8b
$else:
SXTL v5.8h, v5.8b
SMLAL2 v21.4s, v6.8h, v1.h[2]
SMLAL v18.4s, v6.4h, v2.h[2]
SMLAL2 v22.4s, v6.8h, v2.h[2]
SMLAL v19.4s, v6.4h, v3.h[2]
SMLAL2 v23.4s, v6.8h, v3.h[2]
LDR d4, [x5, 48]
SMLAL v24.4s, v5.4h, v0.h[2]
LDR d6, [x5, 56]
SMLAL2 v28.4s, v5.8h, v0.h[2]
SMLAL v25.4s, v5.4h, v1.h[2]
SMLAL2 v29.4s, v5.8h, v1.h[2]
$if DATATYPE == "QU8":
USUBL v4.8h, v4.8b, v7.8b
$else:
SXTL v4.8h, v4.8b
SMLAL v26.4s, v5.4h, v2.h[2]
SMLAL2 v30.4s, v5.8h, v2.h[2]
SMLAL v27.4s, v5.4h, v3.h[2]
SMLAL2 v31.4s, v5.8h, v3.h[2]
SMLAL v16.4s, v4.4h, v0.h[3]
SMLAL2 v20.4s, v4.8h, v0.h[3]
SMLAL v17.4s, v4.4h, v1.h[3]
SMLAL2 v21.4s, v4.8h, v1.h[3]
$if DATATYPE == "QU8":
USUBL v6.8h, v6.8b, v7.8b
$else:
SXTL v6.8h, v6.8b
SMLAL v18.4s, v4.4h, v2.h[3]
SMLAL2 v22.4s, v4.8h, v2.h[3]
SMLAL v19.4s, v4.4h, v3.h[3]
SMLAL2 v23.4s, v4.8h, v3.h[3]
LDR d5, [x5, 64]
SMLAL v24.4s, v6.4h, v0.h[3]
LDR d4, [x5, 72]
SMLAL2 v28.4s, v6.8h, v0.h[3]
$if DATATYPE == "QU8":
USUBL v5.8h, v5.8b, v7.8b
$else:
SXTL v5.8h, v5.8b
SMLAL v25.4s, v6.4h, v1.h[3]
SMLAL2 v29.4s, v6.8h, v1.h[3]
SMLAL v26.4s, v6.4h, v2.h[3]
SMLAL2 v30.4s, v6.8h, v2.h[3]
SMLAL v27.4s, v6.4h, v3.h[3]
SMLAL2 v31.4s, v6.8h, v3.h[3]
SMLAL v16.4s, v5.4h, v0.h[4]
SMLAL2 v20.4s, v5.8h, v0.h[4]
SMLAL v17.4s, v5.4h, v1.h[4]
SMLAL2 v21.4s, v5.8h, v1.h[4]
$if DATATYPE == "QU8":
USUBL v4.8h, v4.8b, v7.8b
$else:
SXTL v4.8h, v4.8b
SMLAL v18.4s, v5.4h, v2.h[4]
SMLAL2 v22.4s, v5.8h, v2.h[4]
SMLAL v19.4s, v5.4h, v3.h[4]
SMLAL2 v23.4s, v5.8h, v3.h[4]
LDR d6, [x5, 80]
SMLAL v24.4s, v4.4h, v0.h[4]
LDR d5, [x5, 88]
SMLAL2 v28.4s, v4.8h, v0.h[4]
SMLAL v25.4s, v4.4h, v1.h[4]
SMLAL2 v29.4s, v4.8h, v1.h[4]
$if DATATYPE == "QU8":
USUBL v6.8h, v6.8b, v7.8b
$else:
SXTL v6.8h, v6.8b
SMLAL v26.4s, v4.4h, v2.h[4]
SMLAL2 v30.4s, v4.8h, v2.h[4]
SMLAL v27.4s, v4.4h, v3.h[4]
SMLAL2 v31.4s, v4.8h, v3.h[4]
SMLAL v16.4s, v6.4h, v0.h[5]
SMLAL2 v20.4s, v6.8h, v0.h[5]
SMLAL v17.4s, v6.4h, v1.h[5]
SMLAL2 v21.4s, v6.8h, v1.h[5]
$if DATATYPE == "QU8":
USUBL v5.8h, v5.8b, v7.8b
$else:
SXTL v5.8h, v5.8b
SMLAL v18.4s, v6.4h, v2.h[5]
SMLAL2 v22.4s, v6.8h, v2.h[5]
SMLAL v19.4s, v6.4h, v3.h[5]
SMLAL2 v23.4s, v6.8h, v3.h[5]
LDR d4, [x5, 96]
SMLAL v24.4s, v5.4h, v0.h[5]
LDR d6, [x5, 104]
SMLAL2 v28.4s, v5.8h, v0.h[5]
SMLAL v25.4s, v5.4h, v1.h[5]
SMLAL2 v29.4s, v5.8h, v1.h[5]
$if DATATYPE == "QU8":
USUBL v4.8h, v4.8b, v7.8b
$else:
SXTL v4.8h, v4.8b
SMLAL v26.4s, v5.4h, v2.h[5]
SMLAL2 v30.4s, v5.8h, v2.h[5]
SMLAL v27.4s, v5.4h, v3.h[5]
SMLAL2 v31.4s, v5.8h, v3.h[5]
$if DATATYPE == "QU8":
USUBL v6.8h, v6.8b, v7.8b
$else:
SXTL v6.8h, v6.8b
SMLAL v16.4s, v4.4h, v0.h[6]
SMLAL2 v20.4s, v4.8h, v0.h[6]
SMLAL v17.4s, v4.4h, v1.h[6]
SMLAL2 v21.4s, v4.8h, v1.h[6]
SMLAL v18.4s, v4.4h, v2.h[6]
SMLAL2 v22.4s, v4.8h, v2.h[6]
SMLAL v19.4s, v4.4h, v3.h[6]
SMLAL2 v23.4s, v4.8h, v3.h[6]
SMLAL v24.4s, v6.4h, v0.h[6]
SMLAL2 v28.4s, v6.8h, v0.h[6]
SMLAL v25.4s, v6.4h, v1.h[6]
SMLAL2 v29.4s, v6.8h, v1.h[6]
LDR d4, [x5, 112]
$if DATATYPE == "QU8":
USUBL v4.8h, v4.8b, v7.8b
$else:
SXTL v4.8h, v4.8b
LDR d5, [x5, 120]
SMLAL v26.4s, v6.4h, v2.h[6]
SMLAL2 v30.4s, v6.8h, v2.h[6]
SMLAL v27.4s, v6.4h, v3.h[6]
SMLAL2 v31.4s, v6.8h, v3.h[6]
SMLAL v16.4s, v4.4h, v0.h[7]
SMLAL2 v20.4s, v4.8h, v0.h[7]
SMLAL v17.4s, v4.4h, v1.h[7]
SMLAL2 v21.4s, v4.8h, v1.h[7]
$if DATATYPE == "QU8":
USUBL v5.8h, v5.8b, v7.8b
$else:
SXTL v5.8h, v5.8b
SMLAL v18.4s, v4.4h, v2.h[7]
SMLAL2 v22.4s, v4.8h, v2.h[7]
SMLAL v19.4s, v4.4h, v3.h[7]
SMLAL2 v23.4s, v4.8h, v3.h[7]
ADD x5, x5, 128
SMLAL v24.4s, v5.4h, v0.h[7]
SMLAL2 v28.4s, v5.8h, v0.h[7]
SMLAL v25.4s, v5.4h, v1.h[7]
SMLAL2 v29.4s, v5.8h, v1.h[7]
AND x0, x2, 7 // kc remainder 0 to 7
SMLAL v26.4s, v5.4h, v2.h[7]
SMLAL2 v30.4s, v5.8h, v2.h[7]
SMLAL v27.4s, v5.4h, v3.h[7]
SMLAL2 v31.4s, v5.8h, v3.h[7]
# Is there a remainder?- 1 to 7 bytes of A
CBNZ x0, 5f
4:
# ks loop
SUBS x9, x9, 32 // ks -= MR * sizeof(${XINT8_T}*)
B.HI 1b
$if REQUANTIZATION == "RNDNU":
# Apply params - preshift, scale, postshift, bias and clamp
LD1R {v4.4s}, [x11], 4
SQSHL v16.4s, v16.4s, v4.4s // shift to upper bits
SQSHL v17.4s, v17.4s, v4.4s
SQSHL v18.4s, v18.4s, v4.4s
SQSHL v19.4s, v19.4s, v4.4s
SQSHL v20.4s, v20.4s, v4.4s
SQSHL v21.4s, v21.4s, v4.4s
SQSHL v22.4s, v22.4s, v4.4s
SQSHL v23.4s, v23.4s, v4.4s
LD1R {v5.4s}, [x11], 4
SQSHL v24.4s, v24.4s, v4.4s
SQSHL v25.4s, v25.4s, v4.4s
SQSHL v26.4s, v26.4s, v4.4s
SQSHL v27.4s, v27.4s, v4.4s
SQSHL v28.4s, v28.4s, v4.4s
SQSHL v29.4s, v29.4s, v4.4s
SQSHL v30.4s, v30.4s, v4.4s
SQSHL v31.4s, v31.4s, v4.4s
LD1R {v6.4s}, [x11], 4
SQDMULH v16.4s, v16.4s, v5.4s // scale without rounding
SQDMULH v17.4s, v17.4s, v5.4s
SQDMULH v18.4s, v18.4s, v5.4s
SQDMULH v19.4s, v19.4s, v5.4s
SQDMULH v20.4s, v20.4s, v5.4s
SQDMULH v21.4s, v21.4s, v5.4s
SQDMULH v22.4s, v22.4s, v5.4s
SQDMULH v23.4s, v23.4s, v5.4s
SQDMULH v24.4s, v24.4s, v5.4s
SQDMULH v25.4s, v25.4s, v5.4s
SQDMULH v26.4s, v26.4s, v5.4s
SQDMULH v27.4s, v27.4s, v5.4s
SQDMULH v28.4s, v28.4s, v5.4s
SQDMULH v29.4s, v29.4s, v5.4s
SQDMULH v30.4s, v30.4s, v5.4s
SQDMULH v31.4s, v31.4s, v5.4s
SRSHL v16.4s, v16.4s, v6.4s // signed rounding shift left
SRSHL v17.4s, v17.4s, v6.4s
SRSHL v18.4s, v18.4s, v6.4s
SRSHL v19.4s, v19.4s, v6.4s
SRSHL v20.4s, v20.4s, v6.4s
SRSHL v21.4s, v21.4s, v6.4s
SRSHL v22.4s, v22.4s, v6.4s
SRSHL v23.4s, v23.4s, v6.4s
SRSHL v24.4s, v24.4s, v6.4s
SRSHL v25.4s, v25.4s, v6.4s
SRSHL v26.4s, v26.4s, v6.4s
SRSHL v27.4s, v27.4s, v6.4s
SRSHL v28.4s, v28.4s, v6.4s
SRSHL v29.4s, v29.4s, v6.4s
SRSHL v30.4s, v30.4s, v6.4s
SRSHL v31.4s, v31.4s, v6.4s
$elif REQUANTIZATION == "FP32":
SCVTF v16.4s, v16.4s
SCVTF v17.4s, v17.4s
$if not CHANNELWISE:
# Apply params - scale, bias and clamp
LD1R {v4.4s}, [x11], 4
SCVTF v18.4s, v18.4s
SCVTF v19.4s, v19.4s
$else:
# Load per channel scale values from weights
LDR q4, [x5], 16
SCVTF v18.4s, v18.4s
SCVTF v19.4s, v19.4s
LDR q5, [x5], 16
SCVTF v20.4s, v20.4s
SCVTF v21.4s, v21.4s
SCVTF v22.4s, v22.4s
SCVTF v23.4s, v23.4s
SCVTF v24.4s, v24.4s
SCVTF v25.4s, v25.4s
SCVTF v26.4s, v26.4s
SCVTF v27.4s, v27.4s
SCVTF v28.4s, v28.4s
SCVTF v29.4s, v29.4s
SCVTF v30.4s, v30.4s
SCVTF v31.4s, v31.4s
$if CHANNELWISE:
LDR q6, [x5], 16
FMUL v16.4s, v16.4s, v4.4s
FMUL v17.4s, v17.4s, v4.4s
FMUL v18.4s, v18.4s, v4.4s
FMUL v19.4s, v19.4s, v4.4s
FMUL v20.4s, v20.4s, v5.4s
LDR q4, [x5], 16
FMUL v21.4s, v21.4s, v5.4s
FMUL v22.4s, v22.4s, v5.4s
FMUL v23.4s, v23.4s, v5.4s
FMUL v24.4s, v24.4s, v6.4s
FMUL v25.4s, v25.4s, v6.4s
FMUL v26.4s, v26.4s, v6.4s
FMUL v27.4s, v27.4s, v6.4s
FMUL v28.4s, v28.4s, v4.4s
FMUL v29.4s, v29.4s, v4.4s
FMUL v30.4s, v30.4s, v4.4s
FMUL v31.4s, v31.4s, v4.4s
$else:
FMUL v16.4s, v16.4s, v4.4s
FMUL v17.4s, v17.4s, v4.4s
FMUL v18.4s, v18.4s, v4.4s
FMUL v19.4s, v19.4s, v4.4s
FMUL v20.4s, v20.4s, v4.4s
FMUL v21.4s, v21.4s, v4.4s
FMUL v22.4s, v22.4s, v4.4s
FMUL v23.4s, v23.4s, v4.4s
FMUL v24.4s, v24.4s, v4.4s
FMUL v25.4s, v25.4s, v4.4s
FMUL v26.4s, v26.4s, v4.4s
FMUL v27.4s, v27.4s, v4.4s
FMUL v28.4s, v28.4s, v4.4s
FMUL v29.4s, v29.4s, v4.4s
FMUL v30.4s, v30.4s, v4.4s
FMUL v31.4s, v31.4s, v4.4s
FCVTNS v16.4s, v16.4s
FCVTNS v17.4s, v17.4s
FCVTNS v18.4s, v18.4s
FCVTNS v19.4s, v19.4s
FCVTNS v20.4s, v20.4s
FCVTNS v21.4s, v21.4s
FCVTNS v22.4s, v22.4s
FCVTNS v23.4s, v23.4s
FCVTNS v24.4s, v24.4s
FCVTNS v25.4s, v25.4s
FCVTNS v26.4s, v26.4s
FCVTNS v27.4s, v27.4s
FCVTNS v28.4s, v28.4s
FCVTNS v29.4s, v29.4s
FCVTNS v30.4s, v30.4s
FCVTNS v31.4s, v31.4s
SQXTN v16.4h, v16.4s
SQXTN v17.4h, v17.4s
SQXTN v18.4h, v18.4s
SQXTN v19.4h, v19.4s
SQXTN v24.4h, v24.4s
SQXTN v25.4h, v25.4s
SQXTN v26.4h, v26.4s
SQXTN v27.4h, v27.4s
LD1R {v6.8h}, [x11], 2 // add bias
SQXTN2 v16.8h, v20.4s
SQXTN2 v17.8h, v21.4s
SQXTN2 v18.8h, v22.4s
SQXTN2 v19.8h, v23.4s
SQXTN2 v24.8h, v28.4s
SQXTN2 v25.8h, v29.4s
SQXTN2 v26.8h, v30.4s
SQXTN2 v27.8h, v31.4s
SQADD v16.8h, v16.8h, v6.8h
SQADD v17.8h, v17.8h, v6.8h
SQADD v18.8h, v18.8h, v6.8h
SQADD v19.8h, v19.8h, v6.8h
SQADD v24.8h, v24.8h, v6.8h
SQADD v25.8h, v25.8h, v6.8h
SQADD v26.8h, v26.8h, v6.8h
SQADD v27.8h, v27.8h, v6.8h
LD1R {v4.16b}, [x11], 1 // clamp min value
${SQXTXN} v0.8b, v16.8h
${SQXTXN} v1.8b, v17.8h
${SQXTXN} v2.8b, v18.8h
${SQXTXN} v3.8b, v19.8h
LD1R {v5.16b}, [x11] // clamp max value
${SQXTXN2} v0.16b, v24.8h
${SQXTXN2} v1.16b, v25.8h
${SQXTXN2} v2.16b, v26.8h
${SQXTXN2} v3.16b, v27.8h
SUB x11, x11, ${REWIND_DECREMENT} // rewind params pointer
${XMAX} v0.16b, v0.16b, v4.16b
${XMAX} v1.16b, v1.16b, v4.16b
${XMAX} v2.16b, v2.16b, v4.16b
${XMAX} v3.16b, v3.16b, v4.16b
SUBS x1, x1, 16
${XMIN} v0.16b, v0.16b, v5.16b
${XMIN} v1.16b, v1.16b, v5.16b
${XMIN} v2.16b, v2.16b, v5.16b
${XMIN} v3.16b, v3.16b, v5.16b
B.LO 6f
# Store full 4 x 16
ST1 {v3.16b}, [x7], x10
ST1 {v2.16b}, [x17], x10
ST1 {v1.16b}, [x16], x10
ST1 {v0.16b}, [x6], x10
SUB x4, x4, x3 // a -= ks
# nc loop
B.HI 0b
# Restore x20 from stack
LDR x20, [sp], 16
RET
# Remainder- 1 to 7 bytes of A
.p2align 3
5:
AND x0, x2, 7 // kc remainder 1 to 7
LD1 {v0.8b}, [x13], x0
LDP d4, d5, [x5], 16
LD1 {v1.8b}, [x14], x0
LD1 {v2.8b}, [x15], x0
LD1 {v3.8b}, [x20], x0
${XXTL} v0.8h, v0.8b
$if DATATYPE == "QU8":
USUBL v4.8h, v4.8b, v7.8b
$else:
SXTL v4.8h, v4.8b
$if DATATYPE == "QU8":
USUBL v5.8h, v5.8b, v7.8b
$else:
SXTL v5.8h, v5.8b
${XXTL} v1.8h, v1.8b
${XXTL} v2.8h, v2.8b
${XXTL} v3.8h, v3.8b
SMLAL v16.4s, v4.4h, v0.h[0]
SMLAL2 v20.4s, v4.8h, v0.h[0]
SMLAL v24.4s, v5.4h, v0.h[0]
SMLAL2 v28.4s, v5.8h, v0.h[0]
SMLAL v17.4s, v4.4h, v1.h[0]
SMLAL2 v21.4s, v4.8h, v1.h[0]
SMLAL v25.4s, v5.4h, v1.h[0]
SMLAL2 v29.4s, v5.8h, v1.h[0]
SMLAL v18.4s, v4.4h, v2.h[0]
SMLAL2 v22.4s, v4.8h, v2.h[0]
SMLAL v26.4s, v5.4h, v2.h[0]
SMLAL2 v30.4s, v5.8h, v2.h[0]
SMLAL v19.4s, v4.4h, v3.h[0]
SMLAL2 v23.4s, v4.8h, v3.h[0]
SMLAL v27.4s, v5.4h, v3.h[0]
SMLAL2 v31.4s, v5.8h, v3.h[0]
CMP x0, 2
B.LO 4b
LDP d4, d5, [x5], 16
$if DATATYPE == "QU8":
USUBL v4.8h, v4.8b, v7.8b
$else:
SXTL v4.8h, v4.8b
$if DATATYPE == "QU8":
USUBL v5.8h, v5.8b, v7.8b
$else:
SXTL v5.8h, v5.8b
SMLAL v16.4s, v4.4h, v0.h[1]
SMLAL2 v20.4s, v4.8h, v0.h[1]
SMLAL v24.4s, v5.4h, v0.h[1]
SMLAL2 v28.4s, v5.8h, v0.h[1]
SMLAL v17.4s, v4.4h, v1.h[1]
SMLAL2 v21.4s, v4.8h, v1.h[1]
SMLAL v25.4s, v5.4h, v1.h[1]
SMLAL2 v29.4s, v5.8h, v1.h[1]
SMLAL v18.4s, v4.4h, v2.h[1]
SMLAL2 v22.4s, v4.8h, v2.h[1]
SMLAL v26.4s, v5.4h, v2.h[1]
SMLAL2 v30.4s, v5.8h, v2.h[1]
SMLAL v19.4s, v4.4h, v3.h[1]
SMLAL2 v23.4s, v4.8h, v3.h[1]
SMLAL v27.4s, v5.4h, v3.h[1]
SMLAL2 v31.4s, v5.8h, v3.h[1]
B.EQ 4b
LDP d4, d5, [x5], 16
$if DATATYPE == "QU8":
USUBL v4.8h, v4.8b, v7.8b
$else:
SXTL v4.8h, v4.8b
$if DATATYPE == "QU8":
USUBL v5.8h, v5.8b, v7.8b
$else:
SXTL v5.8h, v5.8b
SMLAL v16.4s, v4.4h, v0.h[2]
SMLAL2 v20.4s, v4.8h, v0.h[2]
SMLAL v24.4s, v5.4h, v0.h[2]
SMLAL2 v28.4s, v5.8h, v0.h[2]
SMLAL v17.4s, v4.4h, v1.h[2]
SMLAL2 v21.4s, v4.8h, v1.h[2]
SMLAL v25.4s, v5.4h, v1.h[2]
SMLAL2 v29.4s, v5.8h, v1.h[2]
SMLAL v18.4s, v4.4h, v2.h[2]
SMLAL2 v22.4s, v4.8h, v2.h[2]
SMLAL v26.4s, v5.4h, v2.h[2]
SMLAL2 v30.4s, v5.8h, v2.h[2]
SMLAL v19.4s, v4.4h, v3.h[2]
SMLAL2 v23.4s, v4.8h, v3.h[2]
SMLAL v27.4s, v5.4h, v3.h[2]
SMLAL2 v31.4s, v5.8h, v3.h[2]
CMP x0, 4
B.LO 4b
LDP d4, d5, [x5], 16
$if DATATYPE == "QU8":
USUBL v4.8h, v4.8b, v7.8b
$else:
SXTL v4.8h, v4.8b
$if DATATYPE == "QU8":
USUBL v5.8h, v5.8b, v7.8b
$else:
SXTL v5.8h, v5.8b
SMLAL v16.4s, v4.4h, v0.h[3]
SMLAL2 v20.4s, v4.8h, v0.h[3]
SMLAL v24.4s, v5.4h, v0.h[3]
SMLAL2 v28.4s, v5.8h, v0.h[3]
SMLAL v17.4s, v4.4h, v1.h[3]
SMLAL2 v21.4s, v4.8h, v1.h[3]
SMLAL v25.4s, v5.4h, v1.h[3]
SMLAL2 v29.4s, v5.8h, v1.h[3]
SMLAL v18.4s, v4.4h, v2.h[3]
SMLAL2 v22.4s, v4.8h, v2.h[3]
SMLAL v26.4s, v5.4h, v2.h[3]
SMLAL2 v30.4s, v5.8h, v2.h[3]
SMLAL v19.4s, v4.4h, v3.h[3]
SMLAL2 v23.4s, v4.8h, v3.h[3]
SMLAL v27.4s, v5.4h, v3.h[3]
SMLAL2 v31.4s, v5.8h, v3.h[3]
B.EQ 4b
LDP d4, d5, [x5], 16
$if DATATYPE == "QU8":
USUBL v4.8h, v4.8b, v7.8b
$else:
SXTL v4.8h, v4.8b
$if DATATYPE == "QU8":
USUBL v5.8h, v5.8b, v7.8b
$else:
SXTL v5.8h, v5.8b
SMLAL v16.4s, v4.4h, v0.h[4]
SMLAL2 v20.4s, v4.8h, v0.h[4]
SMLAL v24.4s, v5.4h, v0.h[4]
SMLAL2 v28.4s, v5.8h, v0.h[4]
SMLAL v17.4s, v4.4h, v1.h[4]
SMLAL2 v21.4s, v4.8h, v1.h[4]
SMLAL v25.4s, v5.4h, v1.h[4]
SMLAL2 v29.4s, v5.8h, v1.h[4]
SMLAL v18.4s, v4.4h, v2.h[4]
SMLAL2 v22.4s, v4.8h, v2.h[4]
SMLAL v26.4s, v5.4h, v2.h[4]
SMLAL2 v30.4s, v5.8h, v2.h[4]
SMLAL v19.4s, v4.4h, v3.h[4]
SMLAL2 v23.4s, v4.8h, v3.h[4]
SMLAL v27.4s, v5.4h, v3.h[4]
SMLAL2 v31.4s, v5.8h, v3.h[4]
CMP x0, 6
B.LO 4b
LDP d4, d5, [x5], 16
$if DATATYPE == "QU8":
USUBL v4.8h, v4.8b, v7.8b
$else:
SXTL v4.8h, v4.8b
$if DATATYPE == "QU8":
USUBL v5.8h, v5.8b, v7.8b
$else:
SXTL v5.8h, v5.8b
SMLAL v16.4s, v4.4h, v0.h[5]
SMLAL2 v20.4s, v4.8h, v0.h[5]
SMLAL v24.4s, v5.4h, v0.h[5]
SMLAL2 v28.4s, v5.8h, v0.h[5]
SMLAL v17.4s, v4.4h, v1.h[5]
SMLAL2 v21.4s, v4.8h, v1.h[5]
SMLAL v25.4s, v5.4h, v1.h[5]
SMLAL2 v29.4s, v5.8h, v1.h[5]
SMLAL v18.4s, v4.4h, v2.h[5]
SMLAL2 v22.4s, v4.8h, v2.h[5]
SMLAL v26.4s, v5.4h, v2.h[5]
SMLAL2 v30.4s, v5.8h, v2.h[5]
SMLAL v19.4s, v4.4h, v3.h[5]
SMLAL2 v23.4s, v4.8h, v3.h[5]
SMLAL v27.4s, v5.4h, v3.h[5]
SMLAL2 v31.4s, v5.8h, v3.h[5]
B.EQ 4b
LDP d4, d5, [x5], 16
$if DATATYPE == "QU8":
USUBL v4.8h, v4.8b, v7.8b
$else:
SXTL v4.8h, v4.8b
$if DATATYPE == "QU8":
USUBL v5.8h, v5.8b, v7.8b
$else:
SXTL v5.8h, v5.8b
SMLAL v16.4s, v4.4h, v0.h[6]
SMLAL2 v20.4s, v4.8h, v0.h[6]
SMLAL v24.4s, v5.4h, v0.h[6]
SMLAL2 v28.4s, v5.8h, v0.h[6]
SMLAL v17.4s, v4.4h, v1.h[6]
SMLAL2 v21.4s, v4.8h, v1.h[6]
SMLAL v25.4s, v5.4h, v1.h[6]
SMLAL2 v29.4s, v5.8h, v1.h[6]
SMLAL v18.4s, v4.4h, v2.h[6]
SMLAL2 v22.4s, v4.8h, v2.h[6]
SMLAL v26.4s, v5.4h, v2.h[6]
SMLAL2 v30.4s, v5.8h, v2.h[6]
SMLAL v19.4s, v4.4h, v3.h[6]
SMLAL2 v23.4s, v4.8h, v3.h[6]
SMLAL v27.4s, v5.4h, v3.h[6]
SMLAL2 v31.4s, v5.8h, v3.h[6]
B 4b
# Store odd width
.p2align 3
6:
TBZ x1, 3, 7f
STR d3, [x7], 8
STR d2, [x17], 8
DUP d3, v3.d[1]
DUP d2, v2.d[1]
STR d1, [x16], 8
STR d0, [x6], 8
DUP d1, v1.d[1]
DUP d0, v0.d[1]
7:
TBZ x1, 2, 8f
STR s3, [x7], 4
STR s2, [x17], 4
DUP s3, v3.s[1]
DUP s2, v2.s[1]
STR s1, [x16], 4
STR s0, [x6], 4
DUP s1, v1.s[1]
DUP s0, v0.s[1]
8:
TBZ x1, 1, 9f
STR h3, [x7], 2
STR h2, [x17], 2
DUP h3, v3.h[1]
DUP h2, v2.h[1]
STR h1, [x16], 2
STR h0, [x6], 2
DUP h1, v1.h[1]
DUP h0, v0.h[1]
9:
TBZ x1, 0, 10f
STR b3, [x7]
STR b2, [x17]
STR b1, [x16]
STR b0, [x6]
10:
# Restore x20 from stack
LDR x20, [sp], 16
RET
END_FUNCTION xnn_${DATATYPE.lower()}_igemm_minmax_${REQUANTIZATION.lower()}_ukernel_4x16__aarch64_neon_mlal_lane${"_prfm" if PREFETCH else ""}_cortex_a75
#ifdef __ELF__
.section ".note.GNU-stack","",%progbits
#endif