Files
alibaba--mnn/source/backend/cpu/arm/arm64/MNNGemmInt8AddBiasScale_ARMV86_Unit.S
2026-07-13 13:33:03 +08:00

1724 lines
54 KiB
ArmAsm

//
// MNNGemmInt8AddBiasScale_ARMV86_Unit.S
// MNN
//
// Created by MNN on 2022/09/26.
// Copyright © 2018, Alibaba Group Holding Limited
//
#if defined(__aarch64__)
#include "MNNAsmGlobal.h"
.text
.align 5
.macro SET_0_5 d0, d1, d2, d3, d4
movi \d0\().16b, #0
movi \d1\().16b, #0
movi \d2\().16b, #0
movi \d3\().16b, #0
movi \d4\().16b, #0
.endm
.macro SET_0_4 d0, d1, d2, d3
movi \d0\().16b, #0
movi \d1\().16b, #0
movi \d2\().16b, #0
movi \d3\().16b, #0
.endm
.macro ADD_BIAS_FLOAT d0, d1, d2, d3, z0
fadd \d0\().4s, \d0\().4s, \z0\().4s
fadd \d1\().4s, \d1\().4s, \z0\().4s
fadd \d2\().4s, \d2\().4s, \z0\().4s
fadd \d3\().4s, \d3\().4s, \z0\().4s
.endm
.macro ADD_FLOAT d0, d1, d2, d3, s0, s1, s2, s3
fadd \d0\().4s, \d0\().4s, \s0\().4s
fadd \d1\().4s, \d1\().4s, \s1\().4s
fadd \d2\().4s, \d2\().4s, \s2\().4s
fadd \d3\().4s, \d3\().4s, \s3\().4s
.endm
.macro Int32ToFloat z0, z1, z2, z3
scvtf \z0\().4s, \z0\().4s
scvtf \z1\().4s, \z1\().4s
scvtf \z2\().4s, \z2\().4s
scvtf \z3\().4s, \z3\().4s
.endm
.macro MUL_SCALE s, d0, d1, d2, d3
fmul \d0\().4s, \d0\().4s, \s\().4s
fmul \d1\().4s, \d1\().4s, \s\().4s
fmul \d2\().4s, \d2\().4s, \s\().4s
fmul \d3\().4s, \d3\().4s, \s\().4s
.endm
.macro MUL_INPUT_SCALE s, d0, d1, d2, d3
fmul \d0\().4s, \d0\().4s, \s\().s[0]
fmul \d1\().4s, \d1\().4s, \s\().s[1]
fmul \d2\().4s, \d2\().4s, \s\().s[2]
fmul \d3\().4s, \d3\().4s, \s\().s[3]
.endm
.macro FloatToInt32 z0, z1, z2, z3
fcvtas \z0\().4s, \z0\().4s
fcvtas \z1\().4s, \z1\().4s
fcvtas \z2\().4s, \z2\().4s
fcvtas \z3\().4s, \z3\().4s
.endm
.macro Int32ToInt16 s0, s1, s2, s3, d0, d1
sqxtn \d0\().4h, \s0\().4s
sqxtn2 \d0\().8h, \s1\().4s
sqxtn \d1\().4h, \s2\().4s
sqxtn2 \d1\().8h, \s3\().4s
.endm
.macro Int16ToInt8_ONE s0, s1, d0
sqxtn \d0\().8b, \s0\().8h
sqxtn2 \d0\().16b, \s1\().8h
.endm
.macro Int16ToInt8 s0, s1, s2, s3, d0, d1
Int16ToInt8_ONE \s0, \s1, \d0
Int16ToInt8_ONE \s2, \s3, \d1
.endm
.macro MLA_WEIGHTZERO d0, s0, s1, idx // idx for xKernelSum
fmla \d0\().4s, \s1\().4s, \s0\().s[\idx]
.endm
.macro ReLU_FP32 s0, s1, s2, s3, z0, z1 // z0:min z1:max
fmin \s0\().4s, \s0\().4s, \z1\().4s
fmin \s1\().4s, \s1\().4s, \z1\().4s
fmin \s2\().4s, \s2\().4s, \z1\().4s
fmin \s3\().4s, \s3\().4s, \z1\().4s
fmax \s0\().4s, \s0\().4s, \z0\().4s
fmax \s1\().4s, \s1\().4s, \z0\().4s
fmax \s2\().4s, \s2\().4s, \z0\().4s
fmax \s3\().4s, \s3\().4s, \z0\().4s
.endm
.macro ReLU_FP32_2 s0, s1, z0, z1 // z0:min z1:max
fmin \s0\().4s, \s0\().4s, \z1\().4s
fmin \s1\().4s, \s1\().4s, \z1\().4s
fmax \s0\().4s, \s0\().4s, \z0\().4s
fmax \s1\().4s, \s1\().4s, \z0\().4s
.endm
.macro REVERT_INPUT_DEQUANT_BIAS rg0, rg1, rg2, rg3
mul \rg1, \rg2, \rg3
sub \rg0, \rg0, \rg1
.endm
.macro REVERT_WEIGHT_KERNEL_SUM rg0, rg1, rg2, rg3
// y=UP_DIV(ocDiv4,(hp/pack))
add \rg1, \rg3, #1
lsr \rg1, \rg1, #1
// blockNum * y * (hp * sizeof(float))
mul \rg1, \rg2, \rg1
sub \rg0, \rg0, \rg1, LSL #5 // revert weight kernel sum
.endm
asm_function MNNGemmInt8AddBiasScale_ARMV86_Unit
/*
struct QuanPostTreatParameters {
const float* scale;
const float* biasFloat;
int32_t maxValue;
int32_t minValue;
int32_t useInt8 = 1; // Save result as int8_t dataType; otherwise float32.
float roundValuePos = 0.5f;
float roundValueNeg = -0.5f;
float* srcKernelSum;
float* weightQuanBias;
float* fp32minmax;
ssize_t blockNum = 1;
const int32_t* bias;
const float* extraScale = nullptr;
};
*/
//void MNNGemmInt8AddBiasScale_ARMV86_Unit(int8_t* dst, const int8_t* src,
// const int8_t* weight, size_t src_depth_quad, size_t dst_step, size_t dst_depth_quad,
// const QuanPostTreatParameters* parameters, size_t realDstCount);
//Auto: x0:dst, x1:src, x2:weight, x3:src_depth_quad, x4:dst_step
//x5:dst_depth_quad, x6: parameters, x7: realDstCount
//Load from x6: x9: bias, x8: srcKernelSum
ldr x9, [x6, #8]
stp d14, d15, [sp, #(-16 * 10)]!
stp d12, d13, [sp, #(16 * 1)]
stp d10, d11, [sp, #(16 * 2)]
stp d8, d9, [sp, #(16 * 3)]
stp x21, x22, [sp, #(16 * 4)]
stp x19, x20, [sp, #(16 * 5)]
stp x23, x24, [sp, #(16 * 6)]
stp x25, x26, [sp, #(16 * 7)]
stp x27, x28, [sp, #(16 * 8)]
ldr x8, [x6, #40] // srcKernelSum
ldr x28, [x6, #48] // weightKernelSum
ldr x26, [x6, #64] // blockNum
lsl x22, x7, #3 // eDest * GEMM_INT8_SRC_UNIT
ldr x23, [x6, #80] // input scale
ldr x27, [x6, #88] // input bias
ldr x10, [x6, #96] // accumBuffer
add x14, x6, #16 // int8 max ptr
cbz x28, Start
ldr x14, [x6, #56] // float32 maxmin ptr
Start:
mov x15, x8 // input kernel sum
mov x21, x23 // input dequant scale
mov x24, #-32 // inputBlockNum=1
cbz x27, TILE_10
mov x24, #8 // inputBlockNum>1
TILE_10:
cmp x7, #10
blt TILE_8
mov x20, x9 // bias
sub x4, x4, #32 // For int8 output, x4-32
mov x6, x27 // input bias
mov x12, #-256
cbz x28, LoopDz8_TILE_10
sub x4, x4, #96 // For int8 output, x4-32-96
LoopDz8_TILE_10:
cmp x5, #2
mov x11, x1 // src
mov x19, #0
blt LoopDz4_TILE_10
L8_TILE10_BLOCKNUM:
mov x13, x3 // src_depth_quad
SET_0_5 v12, v16, v20, v24, v28 // oc:0,1,0,1
SET_0_5 v13, v17, v21, v25, v29 // oc:2,3,2,3
SET_0_5 v14, v18, v22, v26, v30 // oc:4,5,4,5
SET_0_5 v15, v19, v23, v27, v31 // oc:6,7,6,7
LoopSz_TILE_10:
ld1 {v8.16b, v9.16b, v10.16b, v11.16b}, [x2], #64 // weight
ld1 {v3.16b, v4.16b, v5.16b, v6.16b}, [x11], #64 // src: E0-E9
ld1 {v7.16b}, [x11], #16
subs x13, x13, #1
.inst 0x4e88a46c // smmla v12.4s, v3.16b, v8.16b // tile0-oc0, tile0-oc1, tile1-oc0, tile1-oc1
.inst 0x4e89a46d // smmla v13.4s, v3.16b, v9.16b // tile0-oc2, tile0-oc3, tile1-oc2, tile1-oc3
.inst 0x4e8aa46e // smmla v14.4s, v3.16b, v10.16b // tile0-oc4, tile0-oc5, tile1-oc4, tile1-oc5
.inst 0x4e8ba46f // smmla v15.4s, v3.16b, v11.16b // tile0-oc6, tile0-oc7, tile1-oc6, tile1-oc7
.inst 0x4e88a490 // smmla v16.4s, v4.16b, v8.16b // tile2-oc0, tile2-oc1, tile3-oc0, tile3-oc1
.inst 0x4e89a491 // smmla v17.4s, v4.16b, v9.16b // tile2-oc2, tile2-oc3, tile3-oc2, tile3-oc3
.inst 0x4e8aa492 // smmla v18.4s, v4.16b, v10.16b // tile2-oc4, tile2-oc5, tile3-oc4, tile3-oc5
.inst 0x4e8ba493 // smmla v19.4s, v4.16b, v11.16b // tile2-oc6, tile2-oc7, tile3-oc6, tile3-oc7
.inst 0x4e88a4b4 // smmla v20.4s, v5.16b, v8.16b // tile4-oc0, tile4-oc1, tile5-oc0, tile5-oc1
.inst 0x4e89a4b5 // smmla v21.4s, v5.16b, v9.16b // tile4-oc2, tile4-oc3, tile5-oc2, tile5-oc3
.inst 0x4e8aa4b6 // smmla v22.4s, v5.16b, v10.16b // tile4-oc4, tile4-oc5, tile5-oc4, tile5-oc5
.inst 0x4e8ba4b7 // smmla v23.4s, v5.16b, v11.16b // tile4-oc6, tile4-oc7, tile5-oc6, tile5-oc7
.inst 0x4e88a4d8 // smmla v24.4s, v6.16b, v8.16b // tile6-oc0, tile6-oc1, tile7-oc0, tile7-oc1
.inst 0x4e89a4d9 // smmla v25.4s, v6.16b, v9.16b // tile6-oc2, tile6-oc3, tile7-oc2, tile7-oc3
.inst 0x4e8aa4da // smmla v26.4s, v6.16b, v10.16b // tile6-oc4, tile6-oc5, tile7-oc4, tile7-oc5
.inst 0x4e8ba4db // smmla v27.4s, v6.16b, v11.16b // tile6-oc6, tile6-oc7, tile7-oc6, tile7-oc7
.inst 0x4e88a4fc // smmla v28.4s, v7.16b, v8.16b // tile8-oc0, tile8-oc1, tile9-oc0, tile9-oc1
.inst 0x4e89a4fd // smmla v29.4s, v7.16b, v9.16b // tile8-oc2, tile8-oc3, tile9-oc2, tile9-oc3
.inst 0x4e8aa4fe // smmla v30.4s, v7.16b, v10.16b // tile8-oc4, tile8-oc5, tile9-oc4, tile9-oc5
.inst 0x4e8ba4ff // smmla v31.4s, v7.16b, v11.16b // tile8-oc6, tile8-oc7, tile9-oc6, tile9-oc7
bne LoopSz_TILE_10
LoopSzEnd_TILE_10:
// transpose
uzp1 v0.2d, v12.2d, v13.2d // E0: oc:0-3
uzp2 v1.2d, v12.2d, v13.2d // E1: oc:0-3
uzp1 v2.2d, v16.2d, v17.2d
uzp2 v3.2d, v16.2d, v17.2d
uzp1 v4.2d, v20.2d, v21.2d
uzp2 v5.2d, v20.2d, v21.2d
uzp1 v6.2d, v24.2d, v25.2d
uzp2 v7.2d, v24.2d, v25.2d
uzp1 v8.2d, v28.2d, v29.2d
uzp2 v9.2d, v28.2d, v29.2d
uzp1 v10.2d, v14.2d, v15.2d // E0: oc:4-7
uzp2 v11.2d, v14.2d, v15.2d // E1: oc:4-7
uzp1 v12.2d, v18.2d, v19.2d
uzp2 v13.2d, v18.2d, v19.2d
uzp1 v14.2d, v22.2d, v23.2d
uzp2 v15.2d, v22.2d, v23.2d
uzp1 v16.2d, v26.2d, v27.2d
uzp2 v17.2d, v26.2d, v27.2d
uzp1 v18.2d, v30.2d, v31.2d
uzp2 v19.2d, v30.2d, v31.2d
Int32ToFloat v0, v1, v2, v3
Int32ToFloat v4, v5, v6, v7
Int32ToFloat v8, v9, v10, v11
Int32ToFloat v12, v13, v14, v15
Int32ToFloat v16, v17, v18, v19
Tile10Quan:
ld1 {v20.4s, v21.4s}, [x2], #32 // weight scale
ld1 {v22.4s, v23.4s}, [x8], #32 // input kernel sum
ld1 {v24.d}[0], [x8], #8
ld1 {v25.4s, v26.4s}, [x2], #32 // weight quan zeropoint
MUL_SCALE v20, v0, v1, v2, v3
MUL_SCALE v20, v4, v5, v6, v7
MUL_SCALE v21, v10, v11, v12, v13
MUL_SCALE v21, v14, v15, v16, v17
fmul v8.4s, v8.4s, v20.4s
fmul v9.4s, v9.4s, v20.4s
fmul v18.4s, v18.4s, v21.4s
fmul v19.4s, v19.4s, v21.4s
cbz x21, TILE10_MLA
ld1 {v27.4s, v28.4s}, [x23], #32 // input scale
ld1 {v29.d}[0], [x23], x24
MUL_INPUT_SCALE v27, v0, v1, v2, v3
MUL_INPUT_SCALE v28, v4, v5, v6, v7
MUL_INPUT_SCALE v27, v10, v11, v12, v13
MUL_INPUT_SCALE v28, v14, v15, v16, v17
fmul v8.4s, v8.4s, v29.s[0]
fmul v9.4s, v9.4s, v29.s[1]
fmul v18.4s, v18.4s, v29.s[0]
fmul v19.4s, v19.4s, v29.s[1]
TILE10_MLA:
MLA_WEIGHTZERO v0, v22, v25, 0 // tile:0, oc:0-3
MLA_WEIGHTZERO v1, v22, v25, 1 // tile:1, oc:0-3
MLA_WEIGHTZERO v10, v22, v26, 0 // tile:0, oc:4-7
MLA_WEIGHTZERO v11, v22, v26, 1 // tile:1, oc:4-7
MLA_WEIGHTZERO v2, v22, v25, 2 // tile:2, oc:0-3
MLA_WEIGHTZERO v3, v22, v25, 3 // tile:3, oc:0-3
MLA_WEIGHTZERO v12, v22, v26, 2 // tile:2, oc:4-7
MLA_WEIGHTZERO v13, v22, v26, 3 // tile:3, oc:4-7
MLA_WEIGHTZERO v4, v23, v25, 0 // tile:4, oc:0-3
MLA_WEIGHTZERO v5, v23, v25, 1 // tile:5, oc:0-3
MLA_WEIGHTZERO v14, v23, v26, 0 // tile:4, oc:4-7
MLA_WEIGHTZERO v15, v23, v26, 1 // tile:5, oc:4-7
MLA_WEIGHTZERO v6, v23, v25, 2 // tile:6, oc:0-3
MLA_WEIGHTZERO v7, v23, v25, 3 // tile:7, oc:0-3
MLA_WEIGHTZERO v16, v23, v26, 2 // tile:6, oc:4-7
MLA_WEIGHTZERO v17, v23, v26, 3 // tile:7, oc:4-7
MLA_WEIGHTZERO v8, v24, v25, 0 // tile:8, oc:0-3
MLA_WEIGHTZERO v9, v24, v25, 1 // tile:9, oc:0-3
MLA_WEIGHTZERO v18, v24, v26, 0 // tile:8, oc:4-7
MLA_WEIGHTZERO v19, v24, v26, 1 // tile:9, oc:4-7
cbz x6, TILE10_ADD_DSTV
ld1 {v22.4s, v23.4s}, [x27], #32 // input dequant bias
ld1 {v24.2s}, [x27], #8
ld1 {v25.4s, v26.4s}, [x28], #32 // weight kernel sum
MLA_WEIGHTZERO v0, v22, v25, 0 // tile:0, oc:0-3
MLA_WEIGHTZERO v1, v22, v25, 1 // tile:1, oc:0-3
MLA_WEIGHTZERO v10, v22, v26, 0 // tile:0, oc:4-7
MLA_WEIGHTZERO v11, v22, v26, 1 // tile:1, oc:4-7
MLA_WEIGHTZERO v2, v22, v25, 2 // tile:2, oc:0-3
MLA_WEIGHTZERO v3, v22, v25, 3 // tile:3, oc:0-3
MLA_WEIGHTZERO v12, v22, v26, 2 // tile:2, oc:4-7
MLA_WEIGHTZERO v13, v22, v26, 3 // tile:3, oc:4-7
MLA_WEIGHTZERO v4, v23, v25, 0 // tile:4, oc:0-3
MLA_WEIGHTZERO v5, v23, v25, 1 // tile:5, oc:0-3
MLA_WEIGHTZERO v14, v23, v26, 0 // tile:4, oc:4-7
MLA_WEIGHTZERO v15, v23, v26, 1 // tile:5, oc:4-7
MLA_WEIGHTZERO v6, v23, v25, 2 // tile:6, oc:0-3
MLA_WEIGHTZERO v7, v23, v25, 3 // tile:7, oc:0-3
MLA_WEIGHTZERO v16, v23, v26, 2 // tile:6, oc:4-7
MLA_WEIGHTZERO v17, v23, v26, 3 // tile:7, oc:4-7
MLA_WEIGHTZERO v8, v24, v25, 0 // tile:8, oc:0-3
MLA_WEIGHTZERO v9, v24, v25, 1 // tile:9, oc:0-3
MLA_WEIGHTZERO v18, v24, v26, 0 // tile:8, oc:4-7
MLA_WEIGHTZERO v19, v24, v26, 1 // tile:9, oc:4-7
TILE10_ADD_DSTV:
cbz x19, TILE10_L8_ACCUM_BUFFER
ld1 {v20.4s, v21.4s, v22.4s, v23.4s}, [x10], #64
ld1 {v24.4s, v25.4s, v26.4s, v27.4s}, [x10], #64
ld1 {v28.4s, v29.4s, v30.4s, v31.4s}, [x10], #64
ADD_FLOAT v0, v1, v2, v3, v20, v21, v22, v23
ADD_FLOAT v4, v5, v6, v7, v24, v25, v26, v27
ADD_FLOAT v8, v9, v10, v11, v28, v29, v30, v31
ld1 {v20.4s, v21.4s, v22.4s, v23.4s}, [x10], #64
ld1 {v24.4s, v25.4s, v26.4s, v27.4s}, [x10], x12
ADD_FLOAT v12, v13, v14, v15, v20, v21, v22, v23
ADD_FLOAT v16, v17, v18, v19, v24, v25, v26, v27
TILE10_L8_ACCUM_BUFFER:
add x19, x19, #1
cmp x19, x26
beq TILE10_POST
st1 {v0.4s, v1.4s, v2.4s, v3.4s}, [x10], #64
st1 {v4.4s, v5.4s, v6.4s, v7.4s}, [x10], #64
st1 {v8.4s, v9.4s, v10.4s, v11.4s}, [x10], #64
st1 {v12.4s, v13.4s, v14.4s, v15.4s}, [x10], #64
st1 {v16.4s, v17.4s, v18.4s, v19.4s}, [x10], x12
b L8_TILE10_BLOCKNUM
TILE10_POST:
cbz x28, Tile10QuanUseInt8
sub x5, x5, #2
cbz x9, L8_TILE10_RELU
ld1 {v20.4s, v21.4s}, [x20], #32 // bias
ADD_BIAS_FLOAT v0, v1, v2, v3, v20
ADD_BIAS_FLOAT v4, v5, v6, v7, v20
ADD_BIAS_FLOAT v10, v11, v12, v13, v21
ADD_BIAS_FLOAT v14, v15, v16, v17, v21
fadd v8.4s, v8.4s, v20.4s
fadd v9.4s, v9.4s, v20.4s
fadd v18.4s, v18.4s, v21.4s
fadd v19.4s, v19.4s, v21.4s
L8_TILE10_RELU:
cbz x14, TILE10_STORE
ld1r {v30.4s}, [x14], #4 // f32 min
ld1r {v31.4s}, [x14] // f32 max
ReLU_FP32 v0, v1, v2, v3, v30, v31
ReLU_FP32 v4, v5, v6, v7, v30, v31
ReLU_FP32 v8, v9, v10, v11, v30, v31
ReLU_FP32 v12, v13, v14, v15, v30, v31
ReLU_FP32 v16, v17, v18, v19, v30, v31
sub x14, x14, #4
TILE10_STORE:
st1 {v0.4s, v1.4s, v2.4s, v3.4s}, [x0], #64
st1 {v4.4s, v5.4s, v6.4s, v7.4s}, [x0], #64
st1 {v8.4s, v9.4s}, [x0], x4
st1 {v10.4s, v11.4s, v12.4s, v13.4s}, [x0], #64
st1 {v14.4s, v15.4s, v16.4s, v17.4s}, [x0], #64
st1 {v18.4s, v19.4s}, [x0], x4
b Tile10LoopCheck
Tile10QuanUseInt8:
sub x5, x5, #2
ld1 {v20.4s, v21.4s}, [x9], #32 // bias
ld1r {v31.4s}, [x14], #4 // int8 max
ld1r {v30.4s}, [x14] // int8 min
ADD_BIAS_FLOAT v0, v1, v2, v3, v20
ADD_BIAS_FLOAT v4, v5, v6, v7, v20
ADD_BIAS_FLOAT v10, v11, v12, v13, v21
ADD_BIAS_FLOAT v14, v15, v16, v17, v21
fadd v8.4s, v8.4s, v20.4s
fadd v9.4s, v9.4s, v20.4s
fadd v18.4s, v18.4s, v21.4s
fadd v19.4s, v19.4s, v21.4s
sub x14, x14, #4
dup v31.16b, v31.b[0]
dup v30.16b, v30.b[0]
FloatToInt32 v0, v1, v2, v3
FloatToInt32 v4, v5, v6, v7
FloatToInt32 v10, v11, v12, v13
FloatToInt32 v14, v15, v16, v17
FloatToInt32 v8, v9, v18, v19
Int32ToInt16 v0, v1, v2, v3, v20, v21
Int32ToInt16 v4, v5, v6, v7, v22, v23
sqxtn v24.4h, v8.4s
sqxtn2 v24.8h, v9.4s
Int32ToInt16 v10, v11, v12, v13, v25, v26
Int32ToInt16 v14, v15, v16, v17, v27, v28
sqxtn v29.4h, v18.4s
sqxtn2 v29.8h, v19.4s
Int16ToInt8 v20, v21, v22, v23, v0, v1
sqxtn v2.8b, v24.8h
Int16ToInt8 v25, v26, v27, v28, v3, v4
sqxtn v5.8b, v29.8h
smax v0.16b, v30.16b, v0.16b
smax v1.16b, v30.16b, v1.16b
smax v2.8b, v30.8b, v2.8b
smax v3.16b, v30.16b, v3.16b
smax v4.16b, v30.16b, v4.16b
smax v5.8b, v30.8b, v5.8b
smin v0.16b, v31.16b, v0.16b
smin v1.16b, v31.16b, v1.16b
smin v2.8b, v31.8b, v2.8b
smin v3.16b, v31.16b, v3.16b
smin v4.16b, v31.16b, v4.16b
smin v5.8b, v31.8b, v5.8b
st1 {v0.16b, v1.16b}, [x0], #32
st1 {v2.8b}, [x0], x4
st1 {v3.16b, v4.16b}, [x0], #32
st1 {v5.8b}, [x0], x4
Tile10LoopCheck:
cbz x5, End
mov x8, x15 // revert input kernel sum
mov x27, x6 // revert input dequant bias
mov x23, x21 // revert input dequant scale
b LoopDz8_TILE_10
LoopDz4_TILE_10:
mov x11, x1 // src
mov x19, #0
L4_TILE10_BLOCKNUM:
mov x13, x3 // src_depth_quad
SET_0_5 v12, v13, v16, v17, v20
SET_0_5 v21, v24, v25, v28, v29
L4_LoopSz_TILE_10:
ld1 {v8.16b, v9.16b}, [x2] // weight
ld1 {v3.16b, v4.16b, v5.16b, v6.16b}, [x11], #64 // src: E0-E9
ld1 {v7.16b}, [x11], #16
subs x13, x13, #1
add x2, x2, #64 // x2+lp*hp
.inst 0x4e88a46c // smmla v12.4s, v3.16b, v8.16b // tile0-oc0, tile0-oc1, tile1-oc0, tile1-oc1
.inst 0x4e89a46d // smmla v13.4s, v3.16b, v9.16b // tile0-oc2, tile0-oc3, tile1-oc2, tile1-oc3
.inst 0x4e88a490 // smmla v16.4s, v4.16b, v8.16b // tile2-oc0, tile2-oc1, tile3-oc0, tile3-oc1
.inst 0x4e89a491 // smmla v17.4s, v4.16b, v9.16b // tile2-oc2, tile2-oc3, tile3-oc2, tile3-oc3
.inst 0x4e88a4b4 // smmla v20.4s, v5.16b, v8.16b // tile4-oc0, tile4-oc1, tile5-oc0, tile5-oc1
.inst 0x4e89a4b5 // smmla v21.4s, v5.16b, v9.16b // tile4-oc2, tile4-oc3, tile5-oc2, tile5-oc3
.inst 0x4e88a4d8 // smmla v24.4s, v6.16b, v8.16b // tile6-oc0, tile6-oc1, tile7-oc0, tile7-oc1
.inst 0x4e89a4d9 // smmla v25.4s, v6.16b, v9.16b // tile6-oc2, tile6-oc3, tile7-oc2, tile7-oc3
.inst 0x4e88a4fc // smmla v28.4s, v7.16b, v8.16b // tile8-oc0, tile8-oc1, tile9-oc0, tile9-oc1
.inst 0x4e89a4fd // smmla v29.4s, v7.16b, v9.16b // tile8-oc2, tile8-oc3, tile9-oc2, tile9-oc3
bne L4_LoopSz_TILE_10
// transpose
uzp1 v0.2d, v12.2d, v13.2d // E0: oc:0-3
uzp2 v1.2d, v12.2d, v13.2d // E1: oc:0-3
uzp1 v2.2d, v16.2d, v17.2d
uzp2 v3.2d, v16.2d, v17.2d
uzp1 v4.2d, v20.2d, v21.2d
uzp2 v5.2d, v20.2d, v21.2d
uzp1 v6.2d, v24.2d, v25.2d
uzp2 v7.2d, v24.2d, v25.2d
uzp1 v8.2d, v28.2d, v29.2d
uzp2 v9.2d, v28.2d, v29.2d
Int32ToFloat v0, v1, v2, v3
Int32ToFloat v4, v5, v6, v7
scvtf v8.4s, v8.4s
scvtf v9.4s, v9.4s
L4_Tile10Quan:
ld1 {v20.4s}, [x2] // weight scale
add x2, x2, #32
ld1 {v22.4s, v23.4s}, [x8], #32 // x kernel sum
ld1 {v24.d}[0], [x8], #8
ld1 {v25.4s}, [x2] // weight quan zeropoint
add x2, x2, #32
MUL_SCALE v20, v0, v1, v2, v3
MUL_SCALE v20, v4, v5, v6, v7
fmul v8.4s, v8.4s, v20.4s
fmul v9.4s, v9.4s, v20.4s
cbz x21, L4_TILE10_MLA
ld1 {v27.4s, v28.4s}, [x23], #32 // input dequant scale
ld1 {v29.d}[0], [x23], x24
MUL_INPUT_SCALE v27, v0, v1, v2, v3
MUL_INPUT_SCALE v28, v4, v5, v6, v7
fmul v8.4s, v8.4s, v29.s[0]
fmul v9.4s, v9.4s, v29.s[1]
L4_TILE10_MLA:
MLA_WEIGHTZERO v0, v22, v25, 0 // tile:0, oc:0-3
MLA_WEIGHTZERO v1, v22, v25, 1 // tile:1, oc:0-3
MLA_WEIGHTZERO v2, v22, v25, 2 // tile:2, oc:0-3
MLA_WEIGHTZERO v3, v22, v25, 3 // tile:3, oc:0-3
MLA_WEIGHTZERO v4, v23, v25, 0 // tile:4, oc:0-3
MLA_WEIGHTZERO v5, v23, v25, 1 // tile:5, oc:0-3
MLA_WEIGHTZERO v6, v23, v25, 2 // tile:6, oc:0-3
MLA_WEIGHTZERO v7, v23, v25, 3 // tile:7, oc:0-3
MLA_WEIGHTZERO v8, v24, v25, 0 // tile:8, oc:0-3
MLA_WEIGHTZERO v9, v24, v25, 1 // tile:9, oc:0-3
cbz x27, L4_TILE10_ADD_DSTV
ld1 {v22.4s, v23.4s}, [x27], #32 // input dequant bias
ld1 {v24.2s}, [x27], #8
ld1 {v25.4s}, [x28] // weight kernel sum
MLA_WEIGHTZERO v0, v22, v25, 0 // tile:0, oc:0-3
MLA_WEIGHTZERO v1, v22, v25, 1 // tile:1, oc:0-3
MLA_WEIGHTZERO v2, v22, v25, 2 // tile:2, oc:0-3
MLA_WEIGHTZERO v3, v22, v25, 3 // tile:3, oc:0-3
MLA_WEIGHTZERO v4, v23, v25, 0 // tile:4, oc:0-3
MLA_WEIGHTZERO v5, v23, v25, 1 // tile:5, oc:0-3
MLA_WEIGHTZERO v6, v23, v25, 2 // tile:6, oc:0-3
MLA_WEIGHTZERO v7, v23, v25, 3 // tile:7, oc:0-3
MLA_WEIGHTZERO v8, v24, v25, 0 // tile:8, oc:0-3
MLA_WEIGHTZERO v9, v24, v25, 1 // tile:9, oc:0-3
add x28, x28, #32
L4_TILE10_ADD_DSTV:
cbz x19, L4_TILE10_TEMP_BUFFER
ld1 {v20.4s, v21.4s, v22.4s, v23.4s}, [x10], #64
ld1 {v24.4s, v25.4s, v26.4s, v27.4s}, [x10], #64
ld1 {v28.4s, v29.4s}, [x10]
ADD_FLOAT v0, v1, v2, v3, v20, v21, v22, v23
ADD_FLOAT v4, v5, v6, v7, v24, v25, v26, v27
fadd v8.4s, v8.4s, v28.4s
fadd v9.4s, v9.4s, v29.4s
sub x10, x10, #128
L4_TILE10_TEMP_BUFFER:
add x19, x19, #1
cmp x19, x26
beq L4_TILE10_POST
st1 {v0.4s, v1.4s, v2.4s, v3.4s}, [x10], #64
st1 {v4.4s, v5.4s, v6.4s, v7.4s}, [x10], #64
st1 {v8.4s, v9.4s}, [x10]
sub x10, x10, #128
b L4_TILE10_BLOCKNUM
L4_TILE10_POST:
cbz x28, Tile10QuanUseInt8_L4
cbz x9, L4_TILE10_RELU
ld1 {v20.4s}, [x20] // bias
ADD_BIAS_FLOAT v0, v1, v2, v3, v20
ADD_BIAS_FLOAT v4, v5, v6, v7, v20
fadd v8.4s, v8.4s, v20.4s
fadd v9.4s, v9.4s, v20.4s
L4_TILE10_RELU:
cbz x14, L4_TILE10_STORE
ld1r {v30.4s}, [x14], #4 // f32 min
ld1r {v31.4s}, [x14] // f32 max
ReLU_FP32 v0, v1, v2, v3, v30, v31
ReLU_FP32 v4, v5, v6, v7, v30, v31
fmax v8.4s, v8.4s, v30.4s
fmax v9.4s, v9.4s, v30.4s
fmin v8.4s, v8.4s, v31.4s
fmin v9.4s, v9.4s, v31.4s
L4_TILE10_STORE:
st1 {v0.4s, v1.4s, v2.4s, v3.4s}, [x0], #64
st1 {v4.4s, v5.4s, v6.4s, v7.4s}, [x0], #64
st1 {v8.4s, v9.4s}, [x0], x4
b End
Tile10QuanUseInt8_L4:
ld1 {v20.4s}, [x9] // bias
ld1r {v31.4s}, [x14], #4 // int8 max
ld1r {v30.4s}, [x14] // int8 min
ADD_BIAS_FLOAT v0, v1, v2, v3, v20
ADD_BIAS_FLOAT v4, v5, v6, v7, v20
fadd v8.4s, v8.4s, v20.4s
fadd v9.4s, v9.4s, v20.4s
sub x14, x14, #4
dup v31.16b, v31.b[0]
dup v30.16b, v30.b[0]
FloatToInt32 v0, v1, v2, v3
FloatToInt32 v4, v5, v6, v7
fcvtas v8.4s, v8.4s
fcvtas v9.4s, v9.4s
Int32ToInt16 v0, v1, v2, v3, v16, v17
Int32ToInt16 v4, v5, v6, v7, v18, v19
sqxtn v24.4h, v8.4s
sqxtn2 v24.8h, v9.4s
Int16ToInt8 v16, v17, v18, v19, v21, v22
sqxtn v23.8b, v24.8h
smax v21.16b, v30.16b, v21.16b
smax v22.16b, v30.16b, v22.16b
smax v23.8b, v30.8b, v23.8b
smin v21.16b, v31.16b, v21.16b
smin v22.16b, v31.16b, v22.16b
smin v23.8b, v31.8b, v23.8b
st1 {v21.16b, v22.16b}, [x0], #32
st1 {v23.8b}, [x0], x4
b End
TILE_8:
// post parameters initilize
mov x25, #0
cbz x28, INT8_POST_INIT
cbz x27, RELU_VECTOR
lsr x25, x22, #1 // input block quant: realDstCount * sizeof(float)
RELU_VECTOR:
cbz x14, TILE_Remain
ld1r {v30.4s}, [x14], #4 // f32 min
ld1r {v31.4s}, [x14] // f32 max
b TILE_Remain
INT8_POST_INIT:
ld1r {v31.4s}, [x14], #4 // int8 max
ld1r {v30.4s}, [x14] // int8 min
dup v31.16b, v31.b[0]
dup v30.16b, v30.b[0]
TILE_Remain:
cmp x7, #8
blt TILE_4
mov x24, x5 // dst_depth_quad
mov x6, x0 // dst
mov x12, x2 // weight
mov x20, x9 // bias
cbz x28, LoopDz_TILE_8
sub x4, x4, #64 // For float32 output, add #64 when tile8 end.
LoopDz_TILE_8:
cmp x24, #2
blt LoopDz4_TILE_8
mov x11, x1 // src
mov x19, #0
L8_TILE8_BLOCKNUM:
mov x13, x3 // src_depth_quad
SET_0_4 v12, v16, v20, v24
SET_0_4 v13, v17, v21, v25
SET_0_4 v14, v18, v22, v26
SET_0_4 v15, v19, v23, v27
LoopSz_TILE_8:
ld1 {v8.16b, v9.16b, v10.16b, v11.16b}, [x12], #64 // weight
ld1 {v3.16b, v4.16b, v5.16b, v6.16b}, [x11], x22 // src: E0-E7
subs x13, x13, #1
.inst 0x4e88a46c // smmla v12.4s, v3.16b, v8.16b // tile0-oc0, tile0-oc1, tile1-oc0, tile1-oc1
.inst 0x4e89a46d // smmla v13.4s, v3.16b, v9.16b // tile0-oc2, tile0-oc3, tile1-oc2, tile1-oc3
.inst 0x4e8aa46e // smmla v14.4s, v3.16b, v10.16b // tile0-oc4, tile0-oc5, tile1-oc4, tile1-oc5
.inst 0x4e8ba46f // smmla v15.4s, v3.16b, v11.16b // tile0-oc6, tile0-oc7, tile1-oc6, tile1-oc7
.inst 0x4e88a490 // smmla v16.4s, v4.16b, v8.16b // tile2-oc0, tile2-oc1, tile3-oc0, tile3-oc1
.inst 0x4e89a491 // smmla v17.4s, v4.16b, v9.16b // tile2-oc2, tile2-oc3, tile3-oc2, tile3-oc3
.inst 0x4e8aa492 // smmla v18.4s, v4.16b, v10.16b // tile2-oc4, tile2-oc5, tile3-oc4, tile3-oc5
.inst 0x4e8ba493 // smmla v19.4s, v4.16b, v11.16b // tile2-oc6, tile2-oc7, tile3-oc6, tile3-oc7
.inst 0x4e88a4b4 // smmla v20.4s, v5.16b, v8.16b // tile4-oc0, tile4-oc1, tile5-oc0, tile5-oc1
.inst 0x4e89a4b5 // smmla v21.4s, v5.16b, v9.16b // tile4-oc2, tile4-oc3, tile5-oc2, tile5-oc3
.inst 0x4e8aa4b6 // smmla v22.4s, v5.16b, v10.16b // tile4-oc4, tile4-oc5, tile5-oc4, tile5-oc5
.inst 0x4e8ba4b7 // smmla v23.4s, v5.16b, v11.16b // tile4-oc6, tile4-oc7, tile5-oc6, tile5-oc7
.inst 0x4e88a4d8 // smmla v24.4s, v6.16b, v8.16b // tile6-oc0, tile6-oc1, tile7-oc0, tile7-oc1
.inst 0x4e89a4d9 // smmla v25.4s, v6.16b, v9.16b // tile6-oc2, tile6-oc3, tile7-oc2, tile7-oc3
.inst 0x4e8aa4da // smmla v26.4s, v6.16b, v10.16b // tile6-oc4, tile6-oc5, tile7-oc4, tile7-oc5
.inst 0x4e8ba4db // smmla v27.4s, v6.16b, v11.16b // tile6-oc6, tile6-oc7, tile7-oc6, tile7-oc7
bne LoopSz_TILE_8
LoopSzEnd_TILE_8:
uzp1 v0.2d, v12.2d, v13.2d // E0: oc:0-3
uzp2 v1.2d, v12.2d, v13.2d // E1: oc:0-3
uzp1 v8.2d, v14.2d, v15.2d // E0: oc:4-7
uzp2 v9.2d, v14.2d, v15.2d // E1: oc:4-7
uzp1 v2.2d, v16.2d, v17.2d // E2: oc:0-3
uzp2 v3.2d, v16.2d, v17.2d // E3: oc:0-3
uzp1 v10.2d, v18.2d, v19.2d // E2: oc:4-7
uzp2 v11.2d, v18.2d, v19.2d // E3: oc:4-7
uzp1 v4.2d, v20.2d, v21.2d // E4: oc:0-3
uzp2 v5.2d, v20.2d, v21.2d // E5: oc:0-3
uzp1 v12.2d, v22.2d, v23.2d // E4: oc:4-7
uzp2 v13.2d, v22.2d, v23.2d // E5: oc:4-7
uzp1 v6.2d, v24.2d, v25.2d // E6: oc:0-3
uzp2 v7.2d, v24.2d, v25.2d // E7: oc:0-3
uzp1 v14.2d, v26.2d, v27.2d // E6: oc:4-7
uzp2 v15.2d, v26.2d, v27.2d // E7: oc:4-7
Int32ToFloat v0, v1, v2, v3
Int32ToFloat v4, v5, v6, v7
Int32ToFloat v8, v9, v10, v11
Int32ToFloat v12, v13, v14, v15
Tile8Quan:
ld1 {v20.4s, v21.4s}, [x12], #32 // scale
ld1 {v22.4s, v23.4s}, [x8] // x kernel sum
ld1 {v25.4s, v26.4s}, [x12], #32 // weight quan zeropoint
MUL_SCALE v20, v0, v1, v2, v3
MUL_SCALE v20, v4, v5, v6, v7
MUL_SCALE v21, v8, v9, v10, v11
MUL_SCALE v21, v12, v13, v14, v15
add x8, x8, x22, LSR #1
cbz x21, TILE8_MLA
ld1 {v18.4s, v19.4s}, [x23], x25 // input dequant scale
MUL_INPUT_SCALE v18, v0, v1, v2, v3
MUL_INPUT_SCALE v19, v4, v5, v6, v7
MUL_INPUT_SCALE v18, v8, v9, v10, v11
MUL_INPUT_SCALE v19, v12, v13, v14, v15
TILE8_MLA:
MLA_WEIGHTZERO v0, v22, v25, 0
MLA_WEIGHTZERO v1, v22, v25, 1
MLA_WEIGHTZERO v2, v22, v25, 2
MLA_WEIGHTZERO v3, v22, v25, 3
MLA_WEIGHTZERO v4, v23, v25, 0
MLA_WEIGHTZERO v5, v23, v25, 1
MLA_WEIGHTZERO v6, v23, v25, 2
MLA_WEIGHTZERO v7, v23, v25, 3
MLA_WEIGHTZERO v8, v22, v26, 0
MLA_WEIGHTZERO v9, v22, v26, 1
MLA_WEIGHTZERO v10, v22, v26, 2
MLA_WEIGHTZERO v11, v22, v26, 3
MLA_WEIGHTZERO v12, v23, v26, 0
MLA_WEIGHTZERO v13, v23, v26, 1
MLA_WEIGHTZERO v14, v23, v26, 2
MLA_WEIGHTZERO v15, v23, v26, 3
cbz x27, TILE8_ADD_DSTV
ld1 {v22.4s, v23.4s}, [x27], x25 // input dequant bias
ld1 {v25.4s, v26.4s}, [x28], #32 // weight kernel sum
MLA_WEIGHTZERO v0, v22, v25, 0
MLA_WEIGHTZERO v1, v22, v25, 1
MLA_WEIGHTZERO v2, v22, v25, 2
MLA_WEIGHTZERO v3, v22, v25, 3
MLA_WEIGHTZERO v4, v23, v25, 0
MLA_WEIGHTZERO v5, v23, v25, 1
MLA_WEIGHTZERO v6, v23, v25, 2
MLA_WEIGHTZERO v7, v23, v25, 3
MLA_WEIGHTZERO v8, v22, v26, 0
MLA_WEIGHTZERO v9, v22, v26, 1
MLA_WEIGHTZERO v10, v22, v26, 2
MLA_WEIGHTZERO v11, v22, v26, 3
MLA_WEIGHTZERO v12, v23, v26, 0
MLA_WEIGHTZERO v13, v23, v26, 1
MLA_WEIGHTZERO v14, v23, v26, 2
MLA_WEIGHTZERO v15, v23, v26, 3
TILE8_ADD_DSTV:
cbz x19, TILE8_TEMP_BUFFER
ld1 {v20.4s, v21.4s, v22.4s, v23.4s}, [x10], #64
ld1 {v24.4s, v25.4s, v26.4s, v27.4s}, [x10], #64
ld1 {v16.4s, v17.4s, v18.4s, v19.4s}, [x10], #64
ADD_FLOAT v0, v1, v2, v3, v20, v21, v22, v23
ADD_FLOAT v4, v5, v6, v7, v24, v25, v26, v27
ld1 {v20.4s, v21.4s, v22.4s, v23.4s}, [x10]
ADD_FLOAT v8, v9, v10, v11, v16, v17, v18, v19
ADD_FLOAT v12, v13, v14, v15, v20, v21, v22, v23
sub x10, x10, #192
TILE8_TEMP_BUFFER:
add x19, x19, #1
cmp x19, x26
beq TILE8_POST
st1 {v0.4s, v1.4s, v2.4s, v3.4s}, [x10], #64
st1 {v4.4s, v5.4s, v6.4s, v7.4s}, [x10], #64
st1 {v8.4s, v9.4s, v10.4s, v11.4s}, [x10], #64
st1 {v12.4s, v13.4s, v14.4s, v15.4s}, [x10]
sub x10, x10, #192
b L8_TILE8_BLOCKNUM
TILE8_POST:
cbz x28, Tile8QuanUseInt8
sub x24, x24, #2 // dz-2
cbz x9, TILE8_RELU
ld1 {v16.4s, v17.4s}, [x20], #32 // bias
ADD_BIAS_FLOAT v0, v1, v2, v3, v16
ADD_BIAS_FLOAT v4, v5, v6, v7, v16
ADD_BIAS_FLOAT v8, v9, v10, v11, v17
ADD_BIAS_FLOAT v12, v13, v14, v15, v17
TILE8_RELU:
cbz x14, TILE8_STORE
ReLU_FP32 v0, v1, v2, v3, v30, v31
ReLU_FP32 v4, v5, v6, v7, v30, v31
ReLU_FP32 v8, v9, v10, v11, v30, v31
ReLU_FP32 v12, v13, v14, v15, v30, v31
TILE8_STORE:
st1 {v0.4s, v1.4s, v2.4s, v3.4s}, [x6], #64
st1 {v4.4s, v5.4s, v6.4s, v7.4s}, [x6], x4
st1 {v8.4s, v9.4s, v10.4s, v11.4s}, [x6], #64
st1 {v12.4s, v13.4s, v14.4s, v15.4s}, [x6], x4
cbz x24, TILE8_FLOAT_END
b Tile8LoopCheck
Tile8QuanUseInt8:
sub x24, x24, #2 // dz-2
ld1 {v16.4s, v17.4s}, [x20], #32
ADD_BIAS_FLOAT v0, v1, v2, v3, v16
ADD_BIAS_FLOAT v4, v5, v6, v7, v16
ADD_BIAS_FLOAT v8, v9, v10, v11, v17
ADD_BIAS_FLOAT v12, v13, v14, v15, v17
FloatToInt32 v0, v1, v2, v3
FloatToInt32 v4, v5, v6, v7
FloatToInt32 v8, v9, v10, v11
FloatToInt32 v12, v13, v14, v15
Int32ToInt16 v0, v1, v2, v3, v20, v21
Int32ToInt16 v4, v5, v6, v7, v22, v23
Int32ToInt16 v8, v9, v10, v11, v24, v25
Int32ToInt16 v12, v13, v14, v15, v26, v27
Int16ToInt8 v20, v21, v22, v23, v28, v29
Int16ToInt8 v24, v25, v26, v27, v18, v19
smax v28.16b, v30.16b, v28.16b
smax v29.16b, v30.16b, v29.16b
smax v18.16b, v30.16b, v18.16b
smax v19.16b, v30.16b, v19.16b
smin v28.16b, v31.16b, v28.16b
smin v29.16b, v31.16b, v29.16b
smin v18.16b, v31.16b, v18.16b
smin v19.16b, v31.16b, v19.16b
st1 {v28.16b, v29.16b}, [x6], x4
st1 {v18.16b, v19.16b}, [x6], x4 // dst += dz * dst_step
cbz x24, TILE8_INT8_END
Tile8LoopCheck:
mov x8, x15 // revert input kernel sum
mov x23, x21 // revert input dequant scale
cbz x27, LoopDz_TILE_8
REVERT_INPUT_DEQUANT_BIAS x27, x19, x26, x25
b LoopDz_TILE_8
LoopDz4_TILE_8:
mov x11, x1 // src
mov x19, #0
L4_TILE8_BLOCKNUM:
mov x13, x3 // src_depth_quad
SET_0_4 v12, v16, v20, v24 // oc:0,1,0,1
SET_0_4 v13, v17, v21, v25 // oc:2,3,2,3
L4_LoopSz_TILE_8:
ld1 {v8.16b, v9.16b}, [x12] // weight
ld1 {v3.16b, v4.16b, v5.16b, v6.16b}, [x11], x22 // src: E0-E7
subs x13, x13, #1
add x12, x12, #64
.inst 0x4e88a46c // smmla v12.4s, v3.16b, v8.16b // tile0-oc0, tile0-oc1, tile1-oc0, tile1-oc1
.inst 0x4e89a46d // smmla v13.4s, v3.16b, v9.16b // tile0-oc2, tile0-oc3, tile1-oc2, tile1-oc3
.inst 0x4e88a490 // smmla v16.4s, v4.16b, v8.16b // tile2-oc0, tile2-oc1, tile3-oc0, tile3-oc1
.inst 0x4e89a491 // smmla v17.4s, v4.16b, v9.16b // tile2-oc2, tile2-oc3, tile3-oc2, tile3-oc3
.inst 0x4e88a4b4 // smmla v20.4s, v5.16b, v8.16b // tile4-oc0, tile4-oc1, tile5-oc0, tile5-oc1
.inst 0x4e89a4b5 // smmla v21.4s, v5.16b, v9.16b // tile4-oc2, tile4-oc3, tile5-oc2, tile5-oc3
.inst 0x4e88a4d8 // smmla v24.4s, v6.16b, v8.16b // tile6-oc0, tile6-oc1, tile7-oc0, tile7-oc1
.inst 0x4e89a4d9 // smmla v25.4s, v6.16b, v9.16b // tile6-oc2, tile6-oc3, tile7-oc2, tile7-oc3
bne L4_LoopSz_TILE_8
LoopSz4End_TILE_8:
uzp1 v0.2d, v12.2d, v13.2d // E0: oc:0-3
uzp2 v1.2d, v12.2d, v13.2d // E1: oc:0-3
uzp1 v2.2d, v16.2d, v17.2d // E2: oc:0-3
uzp2 v3.2d, v16.2d, v17.2d // E3: oc:0-3
uzp1 v4.2d, v20.2d, v21.2d // E4: oc:0-3
uzp2 v5.2d, v20.2d, v21.2d // E5: oc:0-3
uzp1 v6.2d, v24.2d, v25.2d // E6: oc:0-3
uzp2 v7.2d, v24.2d, v25.2d // E7: oc:0-3
Int32ToFloat v0, v1, v2, v3
Int32ToFloat v4, v5, v6, v7
L4_Tile8Quan:
ld1 {v20.4s}, [x12] // scale
add x12, x12, #32
ld1 {v22.4s, v23.4s}, [x8] // x kernel sum
ld1 {v25.4s}, [x12] // weight quan zeropoint
add x12, x12, #32
add x8, x8, x22, LSR #1
MUL_SCALE v20, v0, v1, v2, v3
MUL_SCALE v20, v4, v5, v6, v7
cbz x21, L4_TILE8_MLA
ld1 {v18.4s, v19.4s}, [x23], x25
MUL_INPUT_SCALE v18, v0, v1, v2, v3
MUL_INPUT_SCALE v19, v4, v5, v6, v7
L4_TILE8_MLA:
MLA_WEIGHTZERO v0, v22, v25, 0
MLA_WEIGHTZERO v1, v22, v25, 1
MLA_WEIGHTZERO v2, v22, v25, 2
MLA_WEIGHTZERO v3, v22, v25, 3
MLA_WEIGHTZERO v4, v23, v25, 0
MLA_WEIGHTZERO v5, v23, v25, 1
MLA_WEIGHTZERO v6, v23, v25, 2
MLA_WEIGHTZERO v7, v23, v25, 3
cbz x27, L4_TILE8_ADD_DSTV
ld1 {v22.4s, v23.4s}, [x27], x25 // input dequant bias
ld1 {v25.4s}, [x28] // weight kernel sum
MLA_WEIGHTZERO v0, v22, v25, 0
MLA_WEIGHTZERO v1, v22, v25, 1
MLA_WEIGHTZERO v2, v22, v25, 2
MLA_WEIGHTZERO v3, v22, v25, 3
MLA_WEIGHTZERO v4, v23, v25, 0
MLA_WEIGHTZERO v5, v23, v25, 1
MLA_WEIGHTZERO v6, v23, v25, 2
MLA_WEIGHTZERO v7, v23, v25, 3
add x28, x28, #32
L4_TILE8_ADD_DSTV:
cbz x19, L4_TILE8_TEMP_BUFFER
ld1 {v20.4s, v21.4s, v22.4s, v23.4s}, [x10], #64
ld1 {v24.4s, v25.4s, v26.4s, v27.4s}, [x10]
ADD_FLOAT v0, v1, v2, v3, v20, v21, v22, v23
ADD_FLOAT v4, v5, v6, v7, v24, v25, v26, v27
sub x10, x10, #64
L4_TILE8_TEMP_BUFFER:
add x19, x19, #1
cmp x19, x26
beq L4_TILE8_POST
st1 {v0.4s, v1.4s, v2.4s, v3.4s}, [x10], #64
st1 {v4.4s, v5.4s, v6.4s, v7.4s}, [x10]
sub x10, x10, #64
b L4_TILE8_BLOCKNUM
L4_TILE8_POST:
cbz x28, Tile8QuanUseInt8_L4
cbz x9, L4_TILE8_RELU
ld1 {v16.4s}, [x20], #16 // bias
ADD_BIAS_FLOAT v0, v1, v2, v3, v16
ADD_BIAS_FLOAT v4, v5, v6, v7, v16
L4_TILE8_RELU:
cbz x14, L4_TILE8_STORE
ReLU_FP32 v0, v1, v2, v3, v30, v31
ReLU_FP32 v4, v5, v6, v7, v30, v31
L4_TILE8_STORE:
st1 {v0.4s, v1.4s, v2.4s, v3.4s}, [x6], #64
st1 {v4.4s, v5.4s, v6.4s, v7.4s}, [x6], x4
b TILE8_FLOAT_END
Tile8QuanUseInt8_L4:
ld1 {v16.4s}, [x20]
ADD_BIAS_FLOAT v0, v1, v2, v3, v16
ADD_BIAS_FLOAT v4, v5, v6, v7, v16
FloatToInt32 v0, v1, v2, v3
FloatToInt32 v4, v5, v6, v7
Int32ToInt16 v0, v1, v2, v3, v20, v21
Int32ToInt16 v4, v5, v6, v7, v22, v23
Int16ToInt8 v20, v21, v22, v23, v16, v17
smax v16.16b, v30.16b, v16.16b
smax v17.16b, v30.16b, v17.16b
smin v16.16b, v31.16b, v16.16b
smin v17.16b, v31.16b, v17.16b
st1 {v16.16b, v17.16b}, [x6], x4
b TILE8_INT8_END
TILE8_FLOAT_END:
sub x7, x7, #8
cbz x7, End
add x0, x0, #128
add x1, x1, #64
add x23, x21, #32 // input dequant scale
add x8, x15, #32 // input kernel sum
add x4, x4, #64 // Revert x4 for following tile.
cbz x27, TILE_4
REVERT_INPUT_DEQUANT_BIAS x27, x19, x26, x25
REVERT_WEIGHT_KERNEL_SUM x28, x24, x26, x5
add x27, x27, #32 // update input dequant bias: + 8 * sizeof(float)
b TILE_4
TILE8_INT8_END:
sub x7, x7, #8
cbz x7, End
add x1, x1, #64 // source
add x0, x0, #32 // dst:8*pack*sizeof(int8)
add x8, x15, #32 // input kernel sum
cbz x21, TILE_4
add x23, x21, #32 // input dequant scale
TILE_4:
cmp x7, #4
blt TILE_2
mov x24, x5 // dst_depth_quad
mov x6, x0 // dst
mov x12, x2 // weight
mov x20, x9 // bias
mov x15, x8
mov x21, x23
LoopDz_TILE_4:
cmp x24, #2
mov x11, x1 // src
mov x19, #0
blt LoopDz4_TILE_4
TILE4_BLOCKNUM:
mov x13, x3 // src_depth_quad
SET_0_4 v12, v13, v14, v15
SET_0_4 v16, v17, v18, v19
LoopSz_TILE_4:
ld1 {v8.16b, v9.16b, v10.16b, v11.16b}, [x12], #64 // weight
ld1 {v4.16b, v5.16b}, [x11], x22 // src
subs x13, x13, #1
.inst 0x4e88a48c // smmla v12.4s, v4.16b, v8.16b // tile0-oc0, tile0-oc1, tile1-oc0, tile1-oc1
.inst 0x4e89a48d // smmla v13.4s, v4.16b, v9.16b // tile0-oc2, tile0-oc3, tile1-oc2, tile1-oc3
.inst 0x4e8aa48e // smmla v14.4s, v4.16b, v10.16b // tile0-oc4, tile0-oc5, tile1-oc4, tile1-oc5
.inst 0x4e8ba48f // smmla v15.4s, v4.16b, v11.16b // tile0-oc6, tile0-oc7, tile1-oc6, tile1-oc7
.inst 0x4e88a4b0 // smmla v16.4s, v5.16b, v8.16b // tile2-oc0, tile2-oc1, tile3-oc0, tile3-oc1
.inst 0x4e89a4b1 // smmla v17.4s, v5.16b, v9.16b // tile2-oc2, tile2-oc3, tile3-oc2, tile3-oc3
.inst 0x4e8aa4b2 // smmla v18.4s, v5.16b, v10.16b // tile2-oc4, tile2-oc5, tile3-oc4, tile3-oc5
.inst 0x4e8ba4b3 // smmla v19.4s, v5.16b, v11.16b // tile2-oc6, tile2-oc7, tile3-oc6, tile3-oc7
bne LoopSz_TILE_4
LoopSzEnd_TILE_4:
uzp1 v0.2d, v12.2d, v13.2d // E0: oc:0-3
uzp2 v1.2d, v12.2d, v13.2d // E1: oc:0-3
uzp1 v4.2d, v14.2d, v15.2d // E0: oc:4-7
uzp2 v5.2d, v14.2d, v15.2d // E1: oc:4-7
uzp1 v2.2d, v16.2d, v17.2d
uzp2 v3.2d, v16.2d, v17.2d
uzp1 v6.2d, v18.2d, v19.2d
uzp2 v7.2d, v18.2d, v19.2d
Int32ToFloat v0, v1, v2, v3
Int32ToFloat v4, v5, v6, v7
Tile4Quan:
ld1 {v20.4s, v21.4s}, [x12], #32 // scale
ld1 {v22.4s}, [x8] // x kernel sum
ld1 {v25.4s, v26.4s}, [x12], #32 // weight quan zeropoint
MUL_SCALE v20, v0, v1, v2, v3
MUL_SCALE v21, v4, v5, v6, v7
add x8, x8, x22, LSR #1
cbz x21, TILE4_MLA
ld1 {v27.4s}, [x23], x25
MUL_INPUT_SCALE v27, v0, v1, v2, v3
MUL_INPUT_SCALE v27, v4, v5, v6, v7
TILE4_MLA:
MLA_WEIGHTZERO v0, v22, v25, 0 // tile:0, oc:0-3
MLA_WEIGHTZERO v1, v22, v25, 1 // tile:1, oc:0-3
MLA_WEIGHTZERO v2, v22, v25, 2 // tile:2, oc:0-3
MLA_WEIGHTZERO v3, v22, v25, 3 // tile:3, oc:0-3
MLA_WEIGHTZERO v4, v22, v26, 0 // tile:0, oc:4-7
MLA_WEIGHTZERO v5, v22, v26, 1 // tile:1, oc:4-7
MLA_WEIGHTZERO v6, v22, v26, 2 // tile:2, oc:4-7
MLA_WEIGHTZERO v7, v22, v26, 3 // tile:3, oc:4-7
cbz x27, TILE4_ADD_DSTV
ld1 {v22.4s}, [x27], x25 // input dequant bias
ld1 {v25.4s, v26.4s}, [x28], #32 // weight kernel sum
MLA_WEIGHTZERO v0, v22, v25, 0 // tile:0, oc:0-3
MLA_WEIGHTZERO v1, v22, v25, 1 // tile:1, oc:0-3
MLA_WEIGHTZERO v2, v22, v25, 2 // tile:2, oc:0-3
MLA_WEIGHTZERO v3, v22, v25, 3 // tile:3, oc:0-3
MLA_WEIGHTZERO v4, v22, v26, 0 // tile:0, oc:4-7
MLA_WEIGHTZERO v5, v22, v26, 1 // tile:1, oc:4-7
MLA_WEIGHTZERO v6, v22, v26, 2 // tile:2, oc:4-7
MLA_WEIGHTZERO v7, v22, v26, 3 // tile:3, oc:4-7
TILE4_ADD_DSTV:
cbz x19, TILE4_L8_ACCUM_BUFFER
ld1 {v15.4s, v16.4s, v17.4s, v18.4s}, [x10], #64
ld1 {v19.4s, v20.4s, v21.4s, v22.4s}, [x10]
ADD_FLOAT v0, v1, v2, v3, v15, v16, v17, v18
ADD_FLOAT v4, v5, v6, v7, v19, v20, v21, v22
sub x10, x10, #64
TILE4_L8_ACCUM_BUFFER:
add x19, x19, #1
cmp x19, x26
beq TILE4_POST
st1 {v0.4s, v1.4s, v2.4s, v3.4s}, [x10], #64
st1 {v4.4s, v5.4s, v6.4s, v7.4s}, [x10]
sub x10, x10, #64
b TILE4_BLOCKNUM
TILE4_POST:
cbz x28, Tile4QuanUseInt8
sub x24, x24, #2
cbz x9, TILE4_RELU
ld1 {v16.4s, v17.4s}, [x20], #32 // bias
ADD_BIAS_FLOAT v0, v1, v2, v3, v16
ADD_BIAS_FLOAT v4, v5, v6, v7, v17
TILE4_RELU:
cbz x14, TILE4_STORE
ReLU_FP32 v0, v1, v2, v3, v30, v31
ReLU_FP32 v4, v5, v6, v7, v30, v31
TILE4_STORE:
st1 {v0.4s, v1.4s, v2.4s, v3.4s}, [x6], x4
st1 {v4.4s, v5.4s, v6.4s, v7.4s}, [x6], x4
cbz x24, TILE4_FLOAT_END
b Tile4LoopCheck
Tile4QuanUseInt8:
sub x24, x24, #2
ld1 {v16.4s, v17.4s}, [x20], #32 // bias
ADD_BIAS_FLOAT v0, v1, v2, v3, v16
ADD_BIAS_FLOAT v4, v5, v6, v7, v17
FloatToInt32 v0, v1, v2, v3
FloatToInt32 v4, v5, v6, v7
Int32ToInt16 v0, v1, v2, v3, v8, v9
Int32ToInt16 v4, v5, v6, v7, v10, v11
Int16ToInt8_ONE v8, v9, v19
Int16ToInt8_ONE v10, v11, v20
smax v19.16b, v30.16b, v19.16b
smin v19.16b, v31.16b, v19.16b
smax v20.16b, v30.16b, v20.16b
smin v20.16b, v31.16b, v20.16b
st1 {v19.16b}, [x6], x4 // dst += dz * dst_step
st1 {v20.16b}, [x6], x4
cbz x24, TILE4_INT8_END
Tile4LoopCheck:
mov x8, x15
mov x23, x21
cbz x27, LoopDz_TILE_4
REVERT_INPUT_DEQUANT_BIAS x27, x19, x26, x25
b LoopDz_TILE_4
LoopDz4_TILE_4:
mov x11, x1 // src
mov x19, #0
L4_TILE4_BLOCKNUM:
mov x13, x3 // src_depth_quad
SET_0_4 v12, v13, v16, v17
L4_LoopSz_TILE_4:
ld1 {v8.16b, v9.16b}, [x12] // weight
ld1 {v4.16b, v5.16b}, [x11], x22 // src
subs x13, x13, #1
add x12, x12, #64
.inst 0x4e88a48c // smmla v12.4s, v4.16b, v8.16b // tile0-oc0, tile0-oc1, tile1-oc0, tile1-oc1
.inst 0x4e89a48d // smmla v13.4s, v4.16b, v9.16b // tile0-oc2, tile0-oc3, tile1-oc2, tile1-oc3
.inst 0x4e88a4b0 // smmla v16.4s, v5.16b, v8.16b // tile2-oc0, tile2-oc1, tile3-oc0, tile3-oc1
.inst 0x4e89a4b1 // smmla v17.4s, v5.16b, v9.16b // tile2-oc2, tile2-oc3, tile3-oc2, tile3-oc3
bne L4_LoopSz_TILE_4
uzp1 v0.2d, v12.2d, v13.2d // E0: oc:0-3
uzp2 v1.2d, v12.2d, v13.2d // E1: oc:0-3
uzp1 v2.2d, v16.2d, v17.2d
uzp2 v3.2d, v16.2d, v17.2d
Int32ToFloat v0, v1, v2, v3
L4_Tile4Quan:
ld1 {v20.4s}, [x12] // scale
add x12, x12, #32
ld1 {v22.4s}, [x8] // x kernel sum
ld1 {v25.4s}, [x12] // weight quan zeropoint
add x12, x12, #32
MUL_SCALE v20, v0, v1, v2, v3
add x8, x8, x22, LSR #1
cbz x21, L4_TILE4_MLA
ld1 {v27.4s}, [x23], x25
MUL_INPUT_SCALE v27, v0, v1, v2, v3
L4_TILE4_MLA:
MLA_WEIGHTZERO v0, v22, v25, 0 // tile:0, oc:0-3
MLA_WEIGHTZERO v1, v22, v25, 1 // tile:1, oc:0-3
MLA_WEIGHTZERO v2, v22, v25, 2 // tile:2, oc:0-3
MLA_WEIGHTZERO v3, v22, v25, 3 // tile:3, oc:0-3
cbz x27, L4_TILE4_ADD_DSTV
ld1 {v22.4s}, [x27], x25 // input dequant bias
ld1 {v25.4s}, [x28] // weight kernel sum
MLA_WEIGHTZERO v0, v22, v25, 0 // tile:0, oc:0-3
MLA_WEIGHTZERO v1, v22, v25, 1 // tile:1, oc:0-3
MLA_WEIGHTZERO v2, v22, v25, 2 // tile:2, oc:0-3
MLA_WEIGHTZERO v3, v22, v25, 3 // tile:3, oc:0-3
add x28, x28, #32
L4_TILE4_ADD_DSTV:
cbz x19, L4_TILE4_ACCUM_BUFFER
ld1 {v15.4s, v16.4s, v17.4s, v18.4s}, [x10]
ADD_FLOAT v0, v1, v2, v3, v15, v16, v17, v18
L4_TILE4_ACCUM_BUFFER:
add x19, x19, #1
cmp x19, x26
beq L4_TILE4_POST
st1 {v0.4s, v1.4s, v2.4s, v3.4s}, [x10]
b L4_TILE4_BLOCKNUM
L4_TILE4_POST:
cbz x28, Tile4QuanUseInt8_L4
cbz x9, L4_TILE4_RELU
ld1 {v16.4s}, [x20], #16 // bias
ADD_BIAS_FLOAT v0, v1, v2, v3, v16
L4_TILE4_RELU:
cbz x14, L4_TILE4_STORE
ReLU_FP32 v0, v1, v2, v3, v30, v31
L4_TILE4_STORE:
st1 {v0.4s, v1.4s, v2.4s, v3.4s}, [x6], x4
b TILE4_FLOAT_END
Tile4QuanUseInt8_L4:
ld1 {v16.4s}, [x20] // bias
ADD_BIAS_FLOAT v0, v1, v2, v3, v16
FloatToInt32 v0, v1, v2, v3
Int32ToInt16 v0, v1, v2, v3, v8, v9
Int16ToInt8_ONE v8, v9, v19
smax v19.16b, v30.16b, v19.16b
smin v19.16b, v31.16b, v19.16b
st1 {v19.16b}, [x6], x4 // dst += dz * dst_step
b TILE4_INT8_END
TILE4_FLOAT_END:
add x0, x0, #64
sub x7, x7, #4
add x1, x1, #32
add x8, x15, #16
add x23, x21, #16
cbz x27, TILE_2
REVERT_INPUT_DEQUANT_BIAS x27, x19, x26, x25
REVERT_WEIGHT_KERNEL_SUM x28, x24, x26, x5
add x27, x27, #16
b TILE_2
TILE4_INT8_END:
add x0, x0, #16
sub x7, x7, #4
add x1, x1, #32
add x8, x15, #16
cbz x21, TILE_2
add x23, x21, #16
TILE_2:
cmp x7, #2
blt TILE_1
mov x24, x5 // dst_depth_quad
mov x6, x0 // dst
mov x12, x2 // weight
mov x20, x9 // bias
mov x15, x8
mov x21, x23
LoopDz_TILE_2:
cmp x24, #2
blt LoopDz4_TILE_2
mov x11, x1 // src
mov x19, #0
TILE2_BLOCKNUM:
mov x13, x3 // src_depth_quad
SET_0_4 v12, v13, v14, v15
LoopSz_TILE_2:
ld1 {v8.16b, v9.16b, v10.16b, v11.16b}, [x12], #64
ld1 {v4.16b}, [x11], x22 // src
.inst 0x4e88a48c // smmla v12.4s, v4.16b, v8.16b // tile0-oc0, tile0-oc1, tile1-oc0, tile1-oc1
.inst 0x4e89a48d // smmla v13.4s, v4.16b, v9.16b // tile0-oc2, tile0-oc3, tile1-oc2, tile1-oc3
.inst 0x4e8aa48e // smmla v14.4s, v4.16b, v10.16b // tile0-oc4, tile0-oc5, tile1-oc4, tile1-oc5
.inst 0x4e8ba48f // smmla v15.4s, v4.16b, v11.16b // tile0-oc6, tile0-oc7, tile1-oc6, tile1-oc7
subs x13, x13, #1
bne LoopSz_TILE_2
LoopSzEnd_TILE_2:
uzp1 v0.2d, v12.2d, v13.2d // E0: oc:0-3
uzp2 v1.2d, v12.2d, v13.2d // E1: oc:0-3
uzp1 v2.2d, v14.2d, v15.2d // E0: oc:4-7
uzp2 v3.2d, v14.2d, v15.2d // E1: oc:4-7
Int32ToFloat v0, v1, v2, v3
Tile2Quan:
ld1 {v20.4s, v21.4s}, [x12], #32 // scale
ld1 {v22.d}[0], [x8] // x kernel sum
ld1 {v25.4s, v26.4s}, [x12], #32 // weight quan zeropoint
fmul v0.4s, v0.4s, v20.4s
fmul v1.4s, v1.4s, v20.4s
fmul v2.4s, v2.4s, v21.4s
fmul v3.4s, v3.4s, v21.4s
add x8, x8, x22, LSR #1
cbz x21, TILE2_MLA
ld1 {v27.d}[0], [x23], x25
fmul v0.4s, v0.4s, v27.s[0]
fmul v1.4s, v1.4s, v27.s[1]
fmul v2.4s, v2.4s, v27.s[0]
fmul v3.4s, v3.4s, v27.s[1]
TILE2_MLA:
MLA_WEIGHTZERO v0, v22, v25, 0 // tile:0, oc:0-3
MLA_WEIGHTZERO v1, v22, v25, 1 // tile:1, oc:0-3
MLA_WEIGHTZERO v2, v22, v26, 0 // tile:0, oc:4-7
MLA_WEIGHTZERO v3, v22, v26, 1 // tile:1, oc:4-7
cbz x27, TILE2_ADD_DSTV
ld1 {v22.2s}, [x27], x25 // input dequant bias
ld1 {v25.4s, v26.4s}, [x28], #32 // weight kernel sum
MLA_WEIGHTZERO v0, v22, v25, 0 // tile:0, oc:0-3
MLA_WEIGHTZERO v1, v22, v25, 1 // tile:1, oc:0-3
MLA_WEIGHTZERO v2, v22, v26, 0 // tile:0, oc:4-7
MLA_WEIGHTZERO v3, v22, v26, 1 // tile:1, oc:4-7
TILE2_ADD_DSTV:
cbz x19, TILE2_L8_ACCUM_BUFFER
ld1 {v15.4s, v16.4s, v17.4s, v18.4s}, [x10]
ADD_FLOAT v0, v1, v2, v3, v15, v16, v17, v18
TILE2_L8_ACCUM_BUFFER:
add x19, x19, #1
cmp x19, x26
beq TILE2_POST
st1 {v0.4s, v1.4s, v2.4s, v3.4s}, [x10]
b TILE2_BLOCKNUM
TILE2_POST:
cbz x28, Tile2QuanUseInt8
sub x24, x24, #2
cbz x9, TILE2_RELU
ld1 {v16.4s, v17.4s}, [x20], #32 // bias
fadd v0.4s, v0.4s, v16.4s
fadd v1.4s, v1.4s, v16.4s
fadd v2.4s, v2.4s, v17.4s
fadd v3.4s, v3.4s, v17.4s
TILE2_RELU:
cbz x14, TILE2_STORE
ReLU_FP32 v0, v1, v2, v3, v30, v31
TILE2_STORE:
st1 {v0.4s, v1.4s}, [x6], x4
st1 {v2.4s, v3.4s}, [x6], x4
cbz x24, TILE2_FLOAT_END
b Tile2LoopCheck
Tile2QuanUseInt8:
sub x24, x24, #2
ld1 {v16.4s, v17.4s}, [x20], #32 // bias
fadd v0.4s, v0.4s, v16.4s
fadd v1.4s, v1.4s, v16.4s
fadd v2.4s, v2.4s, v17.4s
fadd v3.4s, v3.4s, v17.4s
fcvtas v0.4s, v0.4s
fcvtas v1.4s, v1.4s
fcvtas v2.4s, v2.4s
fcvtas v3.4s, v3.4s
sqxtn v6.4h, v0.4s
sqxtn2 v6.8h, v1.4s
sqxtn v7.4h, v2.4s
sqxtn2 v7.8h, v3.4s
sqxtn v19.8b, v6.8h
sqxtn v20.8b, v7.8h
smax v19.8b, v30.8b, v19.8b
smin v19.8b, v31.8b, v19.8b
smax v20.8b, v30.8b, v20.8b
smin v20.8b, v31.8b, v20.8b
st1 {v19.8b}, [x6], x4 // dst += dz * dst_step
st1 {v20.8b}, [x6], x4
cbz x24, TILE2_INT8_END
Tile2LoopCheck:
mov x8, x15
mov x23, x21
cbz x27, LoopDz_TILE_2
REVERT_INPUT_DEQUANT_BIAS x27, x19, x26, x25
bge LoopDz_TILE_2
LoopDz4_TILE_2:
mov x11, x1 // src
mov x19, #0
L4_TILE2_BLOCKNUM:
mov x13, x3 // src_depth_quad
movi v12.16b, #0
movi v13.16b, #0
L4_LoopSz_TILE_2:
ld1 {v8.16b, v9.16b}, [x12]
ld1 {v4.16b}, [x11], x22 // src
.inst 0x4e88a48c // smmla v12.4s, v4.16b, v8.16b // tile0-oc0, tile0-oc1, tile1-oc0, tile1-oc1
.inst 0x4e89a48d // smmla v13.4s, v4.16b, v9.16b // tile0-oc2, tile0-oc3, tile1-oc2, tile1-oc3
subs x13, x13, #1
add x12, x12, #64
bne L4_LoopSz_TILE_2
uzp1 v0.2d, v12.2d, v13.2d // E0: oc:0-3
uzp2 v1.2d, v12.2d, v13.2d // E1: oc:0-3
scvtf v0.4s, v0.4s
scvtf v1.4s, v1.4s
L4_Tile2Quan:
ld1 {v20.4s}, [x12] // scale
add x12, x12, #32
ld1 {v22.d}[0], [x8] // x kernel sum
ld1 {v25.4s}, [x12] // weight quan zeropoint
add x12, x12, #32
fmul v0.4s, v0.4s, v20.4s
fmul v1.4s, v1.4s, v20.4s
add x8, x8, x22, LSR #1
cbz x21, L4_TILE2_MLA
ld1 {v27.d}[0], [x23], x25
fmul v0.4s, v0.4s, v27.s[0]
fmul v1.4s, v1.4s, v27.s[1]
L4_TILE2_MLA:
MLA_WEIGHTZERO v0, v22, v25, 0 // tile:0, oc:0-3
MLA_WEIGHTZERO v1, v22, v25, 1 // tile:1, oc:0-3
cbz x27, L4_TILE2_ADD_DSTV
ld1 {v22.2s}, [x27], x25 // input dequant bias
ld1 {v25.4s}, [x28] // weight kernel sum
MLA_WEIGHTZERO v0, v22, v25, 0 // tile:0, oc:0-3
MLA_WEIGHTZERO v1, v22, v25, 1 // tile:1, oc:0-3
add x28, x28, #32
L4_TILE2_ADD_DSTV:
cbz x19, L4_TILE2_ACCUM_BUFFER
ld1 {v15.4s, v16.4s}, [x10]
fadd v0.4s, v0.4s, v15.4s
fadd v1.4s, v1.4s, v16.4s
L4_TILE2_ACCUM_BUFFER:
add x19, x19, #1
cmp x19, x26
beq L4_TILE2_POST
st1 {v0.4s, v1.4s}, [x10]
b L4_TILE2_BLOCKNUM
L4_TILE2_POST:
cbz x28, Tile2QuanUseInt8_L4
cbz x9, L4_TILE2_RELU
ld1 {v16.4s}, [x20], #16 // bias
fadd v0.4s, v0.4s, v16.4s
fadd v1.4s, v1.4s, v16.4s
L4_TILE2_RELU:
cbz x14, TILE2_STORE_L4
ReLU_FP32_2 v0, v1, v30, v31
TILE2_STORE_L4:
st1 {v0.4s, v1.4s}, [x6], x4
b TILE2_FLOAT_END
Tile2QuanUseInt8_L4:
ld1 {v16.4s}, [x20] // bias
fadd v0.4s, v0.4s, v16.4s
fadd v1.4s, v1.4s, v16.4s
fcvtas v0.4s, v0.4s
fcvtas v1.4s, v1.4s
sqxtn v6.4h, v0.4s
sqxtn2 v6.8h, v1.4s
sqxtn v19.8b, v6.8h
smax v19.8b, v30.8b, v19.8b
smin v19.8b, v31.8b, v19.8b
st1 {v19.8b}, [x6], x4 // dst += dz * dst_step
TILE2_FLOAT_END:
add x0, x0, #32 // float
sub x7, x7, #2
add x1, x1, #16
add x8, x15, #8
add x23, x21, #8
cbz x27, TILE_1
REVERT_INPUT_DEQUANT_BIAS x27, x19, x26, x25
REVERT_WEIGHT_KERNEL_SUM x28, x24, x26, x5
add x27, x27, #8
b TILE_1
TILE2_INT8_END:
add x0, x0, #8 // float
sub x7, x7, #2
add x1, x1, #16
add x8, x15, #8
cbz x21, TILE_1
add x23, x21, #8
TILE_1:
cmp x7, #1
blt End
mov x24, x5 // dst_depth_quad
mov x6, x0 // dst
mov x12, x2 // weight
mov x20, x9 // bias
mov x15, x8
mov x21, x23
LoopDz_TILE_1:
cmp x24, #2
blt LoopDz4_TILE_1
mov x11, x1 // src
mov x19, #0
TILE1_BLOCKNUM:
mov x13, x3 // src_depth_quad
movi v16.4s, #0
movi v17.4s, #0
movi v18.4s, #0
movi v19.4s, #0
LoopSz_TILE_1:
ld1 {v8.16b, v9.16b, v10.16b, v11.16b}, [x12], #64 // weight
ld1 {v2.8b}, [x11], x22 // src
subs x13, x13, #1
.inst 0x4e88a450 // smmla v16.4s, v2.16b, v8.16b
.inst 0x4e89a451 // smmla v17.4s, v2.16b, v9.16b
.inst 0x4e8aa452 // smmla v18.4s, v2.16b, v10.16b
.inst 0x4e8ba453 // smmla v19.4s, v2.16b, v11.16b
bne LoopSz_TILE_1
LoopSzEnd_TILE_1:
uzp1 v25.2d, v16.2d, v17.2d
uzp1 v26.2d, v18.2d, v19.2d
scvtf v25.4s, v25.4s
scvtf v26.4s, v26.4s
Tile1Quan:
ld1 {v0.4s, v1.4s}, [x12], #32 // scale
ld1 {v6.s}[0], [x8] // x kernel sum
ld1 {v8.4s, v9.4s}, [x12], #32 // weight quan zeropoint
fmul v25.4s, v25.4s, v0.4s
fmul v26.4s, v26.4s, v1.4s
add x8, x8, x22, LSR #1
cbz x21, TILE1_MLA
ld1 {v10.s}[0], [x23], x25
fmul v25.4s, v25.4s, v10.s[0]
fmul v26.4s, v26.4s, v10.s[0]
TILE1_MLA:
MLA_WEIGHTZERO v25, v6, v8, 0 // tile:0, oc:0-3
MLA_WEIGHTZERO v26, v6, v9, 0 // tile:0, oc:4-7
cbz x27, TILE1_ADD_DSTV
ld1 {v6.s}[0], [x27], x25 // input dequant bias
ld1 {v8.4s, v9.4s}, [x28], #32 // weight kernel sum
MLA_WEIGHTZERO v25, v6, v8, 0 // tile:0, oc:0-3
MLA_WEIGHTZERO v26, v6, v9, 0 // tile:0, oc:4-7
TILE1_ADD_DSTV:
cbz x19, TILE1_L8_ACCUM_BUFFER
ld1 {v15.4s, v16.4s}, [x10]
fadd v25.4s, v25.4s, v15.4s
fadd v26.4s, v26.4s, v16.4s
TILE1_L8_ACCUM_BUFFER:
add x19, x19, #1
cmp x19, x26
beq TILE1_POST
st1 {v25.4s, v26.4s}, [x10]
b TILE1_BLOCKNUM
TILE1_POST:
cbz x28, Tile1QuanUseInt8
sub x24, x24, #2
cbz x9, TILE1_RELU
ld1 {v16.4s, v17.4s}, [x20], #32 // bias
fadd v25.4s, v25.4s, v16.4s
fadd v26.4s, v26.4s, v17.4s
TILE1_RELU:
cbz x14, TILE1_STORE
fmin v25.4s, v25.4s, v31.4s
fmax v25.4s, v25.4s, v30.4s
fmin v26.4s, v26.4s, v31.4s
fmax v26.4s, v26.4s, v30.4s
TILE1_STORE:
st1 {v25.4s}, [x6], x4
st1 {v26.4s}, [x6], x4
cbz x24, End
b Tile1LoopEnd
Tile1QuanUseInt8:
sub x24, x24, #2
ld1 {v16.4s, v17.4s}, [x20], #32 // bias
fadd v25.4s, v25.4s, v16.4s
fadd v26.4s, v26.4s, v17.4s
fcvtas v25.4s, v25.4s
fcvtas v26.4s, v26.4s
sqxtn v6.4h, v25.4s
sqxtn v7.4h, v26.4s
sqxtn v6.8b, v6.8h
sqxtn v7.8b, v7.8h
smax v6.16b, v30.16b, v6.16b
smin v6.16b, v31.16b, v6.16b
smax v7.16b, v30.16b, v7.16b
smin v7.16b, v31.16b, v7.16b
st1 {v6.s}[0], [x6], x4 // dst += dz * dst_step
st1 {v7.s}[0], [x6], x4
cbz x24, End
Tile1LoopEnd:
mov x8, x15
mov x23, x21
cbz x27, LoopDz_TILE_1
REVERT_INPUT_DEQUANT_BIAS x27, x19, x26, x25
b LoopDz_TILE_1
LoopDz4_TILE_1:
mov x11, x1 // src
mov x19, #0
L4_TILE1_BLOCKNUM:
mov x13, x3 // src_depth_quad
movi v16.4s, #0
movi v17.4s, #0
LoopSz4_TILE_1:
ld1 {v8.16b, v9.16b}, [x12] // weight
ld1 {v2.8b}, [x11], x22 // src
subs x13, x13, #1
add x12, x12, #64
.inst 0x4e88a450 // smmla v16.4s, v2.16b, v8.16b
.inst 0x4e89a451 // smmla v17.4s, v2.16b, v9.16b
bne LoopSz4_TILE_1
L4_LoopSzEnd_TILE_1:
uzp1 v25.2d, v16.2d, v17.2d
scvtf v25.4s, v25.4s
L4_Tile1Quan:
ld1 {v0.4s}, [x12] // scale
add x12, x12, #32
ld1 {v6.s}[0], [x8] // x kernel sum
ld1 {v8.4s}, [x12] // weight quan zeropoint
add x12, x12, #32
fmul v25.4s, v25.4s, v0.4s
add x8, x8, x22, LSR #1
cbz x21, L4_TILE1_MLA
ld1 {v10.s}[0], [x23], x25
fmul v25.4s, v25.4s, v10.s[0]
L4_TILE1_MLA:
MLA_WEIGHTZERO v25, v6, v8, 0 // tile:0, oc:0-3
cbz x27, L4_TILE1_ADD_DSTV
ld1 {v6.s}[0], [x27], x25 // input dequant bias
ld1 {v8.4s}, [x28] // weight kernel sum
MLA_WEIGHTZERO v25, v6, v8, 0 // tile:0, oc:0-3
add x28, x28, #32
L4_TILE1_ADD_DSTV:
cbz x19, L4_TILE1_ACCUM_BUFFER
ld1 {v15.4s}, [x10]
fadd v25.4s, v25.4s, v15.4s
L4_TILE1_ACCUM_BUFFER:
add x19, x19, #1
cmp x19, x26
beq L4_TILE1_POST
st1 {v25.4s}, [x10]
b L4_TILE1_BLOCKNUM
L4_TILE1_POST:
cbz x28, Tile1QuanUseInt8_L4
cbz x9, L4_TILE1_RELU
ld1 {v16.4s}, [x20], #16 // bias
fadd v25.4s, v25.4s, v16.4s
L4_TILE1_RELU:
cbz x14, L4_TILE1_STORE
fmin v25.4s, v25.4s, v31.4s
fmax v25.4s, v25.4s, v30.4s
L4_TILE1_STORE:
st1 {v25.4s}, [x6], x4
b End
Tile1QuanUseInt8_L4:
ld1 {v16.4s}, [x20] // bias
fadd v27.4s, v27.4s, v16.4s
fcvtas v27.4s, v27.4s
sqxtn v6.4h, v27.4s
sqxtn v6.8b, v6.8h
smax v6.8b, v30.8b, v6.8b
smin v6.8b, v31.8b, v6.8b
st1 {v6.s}[0], [x6], x4 // dst += dz * dst_step
End:
ldp x27, x28, [sp, #(16 * 8)]
ldp x25, x26, [sp, #(16 * 7)]
ldp x23, x24, [sp, #(16 * 6)]
ldp x19, x20, [sp, #(16 * 5)]
ldp x21, x22, [sp, #(16 * 4)]
ldp d8, d9, [sp, #(16 * 3)]
ldp d10, d11, [sp, #(16 * 2)]
ldp d12, d13, [sp, #(16 * 1)]
ldp d14, d15, [sp], #(16 * 10)
ret
#endif // __aarch64__