Files
opencv/3rdparty/mlas/lib/x86_64/FgemmKernelAvx512FCommon.h
T

530 lines
21 KiB
C

/*++
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the MIT License.
Module Name:
FgemmKernelAvx512FCommon.h
Abstract:
This module implements the kernels for the floating point matrix/matrix
multiply operation (SGEMM and DGEMM).
This implementation uses AVX512F instructions.
--*/
/*++
Macro Description:
This macro multiplies and accumulates for 2 ZMMWORDs by N rows of the output
matrix.
Arguments:
RowCount - Supplies the number of rows to process.
VectorOffset - Supplies the byte offset from matrix B to fetch elements.
BroadcastOffset - Supplies the byte offset from matrix A to fetch elements.
PrefetchOffset - Optionally supplies the byte offset from matrix B to
prefetch elements.
Implicit Arguments:
rdi - Supplies the address into the matrix A data.
rbx - Supplies the address into the matrix A data plus 3 rows.
r13 - Supplies the address into the matrix A data plus 6 rows.
r14 - Supplies the address into the matrix A data plus 9 rows.
rsi - Supplies the address into the matrix B data.
r10 - Supplies the length in bytes of a row from matrix A.
zmm4-zmm27 - Supplies the block accumulators.
--*/
.macro ComputeBlockAvx512FBy2 RowCount, VectorOffset, BroadcastOffset, PrefetchOffset
.ifnb \PrefetchOffset\()
prefetcht0 [rsi+\VectorOffset\()+\PrefetchOffset\()]
prefetcht0 [rsi+r12+\VectorOffset\()+\PrefetchOffset\()]
.endif
.if \RowCount\() == 1
vbroadcastsf zmm3,[rdi+\BroadcastOffset\()]
vfmadd231pf zmm4,zmm3,ZMMWORD PTR [rsi+\VectorOffset\()]
vfmadd231pf zmm5,zmm3,ZMMWORD PTR [rsi+r12+\VectorOffset\()]
.else
vmovapf zmm0,ZMMWORD PTR [rsi+\VectorOffset\()]
vmovapf zmm1,ZMMWORD PTR [rsi+r12+\VectorOffset\()]
EmitIfCountGE \RowCount\(), 1, "vbroadcastsf zmm3,[rdi+\BroadcastOffset\()]"
EmitIfCountGE \RowCount\(), 1, "vfmadd231pf zmm4,zmm3,zmm0"
EmitIfCountGE \RowCount\(), 1, "vfmadd231pf zmm5,zmm3,zmm1"
EmitIfCountGE \RowCount\(), 2, "vbroadcastsf zmm3,[rdi+r10+\BroadcastOffset\()]"
EmitIfCountGE \RowCount\(), 2, "vfmadd231pf zmm6,zmm3,zmm0"
EmitIfCountGE \RowCount\(), 2, "vfmadd231pf zmm7,zmm3,zmm1"
EmitIfCountGE \RowCount\(), 3, "vbroadcastsf zmm3,[rdi+r10*2+\BroadcastOffset\()]"
EmitIfCountGE \RowCount\(), 3, "vfmadd231pf zmm8,zmm3,zmm0"
EmitIfCountGE \RowCount\(), 3, "vfmadd231pf zmm9,zmm3,zmm1"
EmitIfCountGE \RowCount\(), 4, "vbroadcastsf zmm3,[rbx+\BroadcastOffset\()]"
EmitIfCountGE \RowCount\(), 4, "vfmadd231pf zmm10,zmm3,zmm0"
EmitIfCountGE \RowCount\(), 4, "vfmadd231pf zmm11,zmm3,zmm1"
EmitIfCountGE \RowCount\(), 5, "vbroadcastsf zmm3,[rbx+r10+\BroadcastOffset\()]"
EmitIfCountGE \RowCount\(), 5, "vfmadd231pf zmm12,zmm3,zmm0"
EmitIfCountGE \RowCount\(), 5, "vfmadd231pf zmm13,zmm3,zmm1"
EmitIfCountGE \RowCount\(), 6, "vbroadcastsf zmm3,[rbx+r10*2+\BroadcastOffset\()]"
EmitIfCountGE \RowCount\(), 6, "vfmadd231pf zmm14,zmm3,zmm0"
EmitIfCountGE \RowCount\(), 6, "vfmadd231pf zmm15,zmm3,zmm1"
EmitIfCountGE \RowCount\(), 12, "vbroadcastsf zmm3,[r13+\BroadcastOffset\()]"
EmitIfCountGE \RowCount\(), 12, "vfmadd231pf zmm16,zmm3,zmm0"
EmitIfCountGE \RowCount\(), 12, "vfmadd231pf zmm17,zmm3,zmm1"
EmitIfCountGE \RowCount\(), 12, "vbroadcastsf zmm3,[r13+r10+\BroadcastOffset\()]"
EmitIfCountGE \RowCount\(), 12, "vfmadd231pf zmm18,zmm3,zmm0"
EmitIfCountGE \RowCount\(), 12, "vfmadd231pf zmm19,zmm3,zmm1"
EmitIfCountGE \RowCount\(), 12, "vbroadcastsf zmm3,[r13+r10*2+\BroadcastOffset\()]"
EmitIfCountGE \RowCount\(), 12, "vfmadd231pf zmm20,zmm3,zmm0"
EmitIfCountGE \RowCount\(), 12, "vfmadd231pf zmm21,zmm3,zmm1"
EmitIfCountGE \RowCount\(), 12, "vbroadcastsf zmm3,[r14+\BroadcastOffset\()]"
EmitIfCountGE \RowCount\(), 12, "vfmadd231pf zmm22,zmm3,zmm0"
EmitIfCountGE \RowCount\(), 12, "vfmadd231pf zmm23,zmm3,zmm1"
EmitIfCountGE \RowCount\(), 12, "vbroadcastsf zmm3,[r14+r10+\BroadcastOffset\()]"
EmitIfCountGE \RowCount\(), 12, "vfmadd231pf zmm24,zmm3,zmm0"
EmitIfCountGE \RowCount\(), 12, "vfmadd231pf zmm25,zmm3,zmm1"
EmitIfCountGE \RowCount\(), 12, "vbroadcastsf zmm3,[r14+r10*2+\BroadcastOffset\()]"
EmitIfCountGE \RowCount\(), 12, "vfmadd231pf zmm26,zmm3,zmm0"
EmitIfCountGE \RowCount\(), 12, "vfmadd231pf zmm27,zmm3,zmm1"
.endif
.endm
/*++
Macro Description:
This macro multiplies and accumulates for 1 ZMMWORD by N rows of the output
matrix.
Arguments:
RowCount - Supplies the number of rows to process.
VectorOffset - Supplies the byte offset from matrix B to fetch elements.
BroadcastOffset - Supplies the byte offset from matrix A to fetch elements.
PrefetchOffset - Optionally supplies the byte offset from matrix B to
prefetch elements.
Implicit Arguments:
rdi - Supplies the address into the matrix A data.
rbx - Supplies the address into the matrix A data plus 3 rows.
r13 - Supplies the address into the matrix A data plus 6 rows.
r14 - Supplies the address into the matrix A data plus 9 rows.
rsi - Supplies the address into the matrix B data.
r10 - Supplies the length in bytes of a row from matrix A.
zmm4-zmm27 - Supplies the block accumulators.
--*/
.macro ComputeBlockAvx512FBy1 RowCount, VectorOffset, BroadcastOffset, PrefetchOffset
.ifnb \PrefetchOffset\()
prefetcht0 [rsi+\VectorOffset\()+\PrefetchOffset\()]
.endif
vmovapf zmm0,ZMMWORD PTR [rsi+\VectorOffset\()]
EmitIfCountGE \RowCount\(), 1, "vfmadd231pf_bcst zmm5,zmm0,[rdi+\BroadcastOffset\()]"
EmitIfCountGE \RowCount\(), 2, "vfmadd231pf_bcst zmm7,zmm0,[rdi+r10+\BroadcastOffset\()]"
EmitIfCountGE \RowCount\(), 3, "vfmadd231pf_bcst zmm9,zmm0,[rdi+r10*2+\BroadcastOffset\()]"
EmitIfCountGE \RowCount\(), 4, "vfmadd231pf_bcst zmm11,zmm0,[rbx+\BroadcastOffset\()]"
EmitIfCountGE \RowCount\(), 5, "vfmadd231pf_bcst zmm13,zmm0,[rbx+r10+\BroadcastOffset\()]"
EmitIfCountGE \RowCount\(), 6, "vfmadd231pf_bcst zmm15,zmm0,[rbx+r10*2+\BroadcastOffset\()]"
EmitIfCountGE \RowCount\(), 12, "vfmadd231pf_bcst zmm17,zmm0,[r13+\BroadcastOffset\()]"
EmitIfCountGE \RowCount\(), 12, "vfmadd231pf_bcst zmm19,zmm0,[r13+r10+\BroadcastOffset\()]"
EmitIfCountGE \RowCount\(), 12, "vfmadd231pf_bcst zmm21,zmm0,[r13+r10*2+\BroadcastOffset\()]"
EmitIfCountGE \RowCount\(), 12, "vfmadd231pf_bcst zmm23,zmm0,[r14+\BroadcastOffset\()]"
EmitIfCountGE \RowCount\(), 12, "vfmadd231pf_bcst zmm25,zmm0,[r14+r10+\BroadcastOffset\()]"
EmitIfCountGE \RowCount\(), 12, "vfmadd231pf_bcst zmm27,zmm0,[r14+r10*2+\BroadcastOffset\()]"
.endm
/*++
Macro Description:
This macro generates code to execute the block compute macro multiple
times and advancing the matrix A and matrix B data pointers.
Arguments:
ComputeBlock - Supplies the macro to compute a single block.
RowCount - Supplies the number of rows to process.
Implicit Arguments:
rdi - Supplies the address into the matrix A data.
rsi - Supplies the address into the matrix B data.
rcx - Supplies the number of columns from matrix A and the number of rows
from matrix B to iterate over.
r10 - Supplies the length in bytes of a row from matrix A.
zmm4-zmm27 - Supplies the block accumulators.
--*/
.macro ComputeBlockAvx512FLoop ComputeBlock, RowCount
.if \RowCount\() > 3
lea rbx,[r10*2+r10]
.if \RowCount\() == 12
lea r13,[rdi+rbx*2] # compute matrix A plus 6 rows
lea r14,[r13+rbx] # compute matrix A plus 9 rows
.endif
add rbx,rdi # compute matrix A plus 3 rows
.endif
ComputeBlockLoop \ComputeBlock\(), \RowCount\(), \RowCount\() > 3
.if \RowCount\() > 3
lea rbx,[rax*2+rax]
.if \RowCount\() == 12
lea r13,[rdx+rbx*2] # compute matrix C plus 6 rows
lea r14,[r13+rbx] # compute matrix C plus 9 rows
.endif
add rbx,rdx # compute matrix C plus 3 rows
.endif
.endm
/*++
Macro Description:
This macro generates code to compute matrix multiplication for a fixed set
of rows.
Arguments:
RowCount - Supplies the number of rows to process.
Implicit Arguments:
rdi - Supplies the address of matrix A.
rsi - Supplies the address of matrix B.
r11 - Supplies the address of matrix A.
r9 - Supplies the number of columns from matrix B and matrix C to iterate
over.
rdx - Supplies the address of matrix C.
rcx - Supplies the number of columns from matrix A and the number of rows
from matrix B to iterate over.
r10 - Supplies the length in bytes of a row from matrix A.
rax - Supplies the length in bytes of a row from matrix C.
r15 - Stores the ZeroMode argument from the stack frame.
--*/
.macro ProcessCountM RowCount
cmp r9,.LFgemmZmmElementCount
jbe .LProcessRemainingCountN\@
.LProcessNextColumnLoop2xN\@:
EmitIfCountGE \RowCount\(), 12, "vmovapf zmm16,zmm4"
# clear upper block accumulators
EmitIfCountGE \RowCount\(), 12, "vmovapf zmm17,zmm5"
EmitIfCountGE \RowCount\(), 12, "vmovapf zmm18,zmm4"
EmitIfCountGE \RowCount\(), 12, "vmovapf zmm19,zmm5"
EmitIfCountGE \RowCount\(), 12, "vmovapf zmm20,zmm4"
EmitIfCountGE \RowCount\(), 12, "vmovapf zmm21,zmm5"
EmitIfCountGE \RowCount\(), 12, "vmovapf zmm22,zmm4"
EmitIfCountGE \RowCount\(), 12, "vmovapf zmm23,zmm5"
EmitIfCountGE \RowCount\(), 12, "vmovapf zmm24,zmm4"
EmitIfCountGE \RowCount\(), 12, "vmovapf zmm25,zmm5"
EmitIfCountGE \RowCount\(), 12, "vmovapf zmm26,zmm4"
EmitIfCountGE \RowCount\(), 12, "vmovapf zmm27,zmm5"
ComputeBlockAvx512FLoop ComputeBlockAvx512FBy2, \RowCount\()
add rsi,r12 # advance matrix B by 64*CountK bytes
test r15b,r15b # ZeroMode?
jnz .LMultiplyAlpha2xNBlock\@
EmitIfCountGE \RowCount\(), 1, "vfmadd213pf zmm4,zmm31,ZMMWORD PTR [rdx]"
EmitIfCountGE \RowCount\(), 2, "vfmadd213pf zmm6,zmm31,ZMMWORD PTR [rdx+rax]"
EmitIfCountGE \RowCount\(), 3, "vfmadd213pf zmm8,zmm31,ZMMWORD PTR [rdx+rax*2]"
EmitIfCountGE \RowCount\(), 4, "vfmadd213pf zmm10,zmm31,ZMMWORD PTR [rbx]"
EmitIfCountGE \RowCount\(), 5, "vfmadd213pf zmm12,zmm31,ZMMWORD PTR [rbx+rax]"
EmitIfCountGE \RowCount\(), 6, "vfmadd213pf zmm14,zmm31,ZMMWORD PTR [rbx+rax*2]"
EmitIfCountGE \RowCount\(), 12, "vfmadd213pf zmm16,zmm31,ZMMWORD PTR [r13]"
EmitIfCountGE \RowCount\(), 12, "vfmadd213pf zmm18,zmm31,ZMMWORD PTR [r13+rax]"
EmitIfCountGE \RowCount\(), 12, "vfmadd213pf zmm20,zmm31,ZMMWORD PTR [r13+rax*2]"
EmitIfCountGE \RowCount\(), 12, "vfmadd213pf zmm22,zmm31,ZMMWORD PTR [r14]"
EmitIfCountGE \RowCount\(), 12, "vfmadd213pf zmm24,zmm31,ZMMWORD PTR [r14+rax]"
EmitIfCountGE \RowCount\(), 12, "vfmadd213pf zmm26,zmm31,ZMMWORD PTR [r14+rax*2]"
jmp .LStore2xNBlock\@
.LMultiplyAlpha2xNBlock\@:
EmitIfCountGE \RowCount\(), 1, "vmulpf zmm4,zmm4,zmm31"
EmitIfCountGE \RowCount\(), 2, "vmulpf zmm6,zmm6,zmm31"
EmitIfCountGE \RowCount\(), 3, "vmulpf zmm8,zmm8,zmm31"
EmitIfCountGE \RowCount\(), 4, "vmulpf zmm10,zmm10,zmm31"
EmitIfCountGE \RowCount\(), 5, "vmulpf zmm12,zmm12,zmm31"
EmitIfCountGE \RowCount\(), 6, "vmulpf zmm14,zmm14,zmm31"
EmitIfCountGE \RowCount\(), 12, "vmulpf zmm16,zmm16,zmm31"
EmitIfCountGE \RowCount\(), 12, "vmulpf zmm18,zmm18,zmm31"
EmitIfCountGE \RowCount\(), 12, "vmulpf zmm20,zmm20,zmm31"
EmitIfCountGE \RowCount\(), 12, "vmulpf zmm22,zmm22,zmm31"
EmitIfCountGE \RowCount\(), 12, "vmulpf zmm24,zmm24,zmm31"
EmitIfCountGE \RowCount\(), 12, "vmulpf zmm26,zmm26,zmm31"
.LStore2xNBlock\@:
EmitIfCountGE \RowCount\(), 1, "vmovupf ZMMWORD PTR [rdx],zmm4"
EmitIfCountGE \RowCount\(), 2, "vmovupf ZMMWORD PTR [rdx+rax],zmm6"
EmitIfCountGE \RowCount\(), 3, "vmovupf ZMMWORD PTR [rdx+rax*2],zmm8"
EmitIfCountGE \RowCount\(), 4, "vmovupf ZMMWORD PTR [rbx],zmm10"
EmitIfCountGE \RowCount\(), 5, "vmovupf ZMMWORD PTR [rbx+rax],zmm12"
EmitIfCountGE \RowCount\(), 6, "vmovupf ZMMWORD PTR [rbx+rax*2],zmm14"
EmitIfCountGE \RowCount\(), 12, "vmovupf ZMMWORD PTR [r13],zmm16"
EmitIfCountGE \RowCount\(), 12, "vmovupf ZMMWORD PTR [r13+rax],zmm18"
EmitIfCountGE \RowCount\(), 12, "vmovupf ZMMWORD PTR [r13+rax*2],zmm20"
EmitIfCountGE \RowCount\(), 12, "vmovupf ZMMWORD PTR [r14],zmm22"
EmitIfCountGE \RowCount\(), 12, "vmovupf ZMMWORD PTR [r14+rax],zmm24"
EmitIfCountGE \RowCount\(), 12, "vmovupf ZMMWORD PTR [r14+rax*2],zmm26"
add rdx,64 # advance matrix C by ZMMWORD
.if \RowCount\() > 3
add rbx,64 # advance matrix C plus 3 rows by ZMMWORD
.if \RowCount\() == 12
add r13,64 # advance matrix C plus 6 rows by ZMMWORD
add r14,64 # advance matrix C plus 9 rows by ZMMWORD
.endif
.endif
sub r9,.LFgemmZmmElementCount
.LOutput1xNBlock\@:
sub r9,.LFgemmZmmElementCount
jae .LOutput1xNBlockWithMask\@
lea rcx,[r9+.LFgemmZmmElementCount]
# correct for over-subtract above
mov ebp,1
shl ebp,cl
dec ebp
kmovw k1,ebp # update mask for remaining columns
xor r9,r9 # no more columns remaining
.LOutput1xNBlockWithMask\@:
test r15b,r15b # ZeroMode?
jnz .LMultiplyAlpha1xNBlockWithMask\@
EmitIfCountGE \RowCount\(), 1, "vfmadd213pf zmm5{k1},zmm31,ZMMWORD PTR [rdx]"
EmitIfCountGE \RowCount\(), 2, "vfmadd213pf zmm7{k1},zmm31,ZMMWORD PTR [rdx+rax]"
EmitIfCountGE \RowCount\(), 3, "vfmadd213pf zmm9{k1},zmm31,ZMMWORD PTR [rdx+rax*2]"
EmitIfCountGE \RowCount\(), 4, "vfmadd213pf zmm11{k1},zmm31,ZMMWORD PTR [rbx]"
EmitIfCountGE \RowCount\(), 5, "vfmadd213pf zmm13{k1},zmm31,ZMMWORD PTR [rbx+rax]"
EmitIfCountGE \RowCount\(), 6, "vfmadd213pf zmm15{k1},zmm31,ZMMWORD PTR [rbx+rax*2]"
EmitIfCountGE \RowCount\(), 12, "vfmadd213pf zmm17{k1},zmm31,ZMMWORD PTR [r13]"
EmitIfCountGE \RowCount\(), 12, "vfmadd213pf zmm19{k1},zmm31,ZMMWORD PTR [r13+rax]"
EmitIfCountGE \RowCount\(), 12, "vfmadd213pf zmm21{k1},zmm31,ZMMWORD PTR [r13+rax*2]"
EmitIfCountGE \RowCount\(), 12, "vfmadd213pf zmm23{k1},zmm31,ZMMWORD PTR [r14]"
EmitIfCountGE \RowCount\(), 12, "vfmadd213pf zmm25{k1},zmm31,ZMMWORD PTR [r14+rax]"
EmitIfCountGE \RowCount\(), 12, "vfmadd213pf zmm27{k1},zmm31,ZMMWORD PTR [r14+rax*2]"
jmp .LStore1xNBlockWithMask\@
.LMultiplyAlpha1xNBlockWithMask\@:
EmitIfCountGE \RowCount\(), 1, "vmulpf zmm5,zmm5,zmm31"
EmitIfCountGE \RowCount\(), 2, "vmulpf zmm7,zmm7,zmm31"
EmitIfCountGE \RowCount\(), 3, "vmulpf zmm9,zmm9,zmm31"
EmitIfCountGE \RowCount\(), 4, "vmulpf zmm11,zmm11,zmm31"
EmitIfCountGE \RowCount\(), 5, "vmulpf zmm13,zmm13,zmm31"
EmitIfCountGE \RowCount\(), 6, "vmulpf zmm15,zmm15,zmm31"
EmitIfCountGE \RowCount\(), 12, "vmulpf zmm17,zmm17,zmm31"
EmitIfCountGE \RowCount\(), 12, "vmulpf zmm19,zmm19,zmm31"
EmitIfCountGE \RowCount\(), 12, "vmulpf zmm21,zmm21,zmm31"
EmitIfCountGE \RowCount\(), 12, "vmulpf zmm23,zmm23,zmm31"
EmitIfCountGE \RowCount\(), 12, "vmulpf zmm25,zmm25,zmm31"
EmitIfCountGE \RowCount\(), 12, "vmulpf zmm27,zmm27,zmm31"
.LStore1xNBlockWithMask\@:
EmitIfCountGE \RowCount\(), 1, "vmovupf ZMMWORD PTR [rdx]{k1},zmm5"
EmitIfCountGE \RowCount\(), 2, "vmovupf ZMMWORD PTR [rdx+rax]{k1},zmm7"
EmitIfCountGE \RowCount\(), 3, "vmovupf ZMMWORD PTR [rdx+rax*2]{k1},zmm9"
EmitIfCountGE \RowCount\(), 4, "vmovupf ZMMWORD PTR [rbx]{k1},zmm11"
EmitIfCountGE \RowCount\(), 5, "vmovupf ZMMWORD PTR [rbx+rax]{k1},zmm13"
EmitIfCountGE \RowCount\(), 6, "vmovupf ZMMWORD PTR [rbx+rax*2]{k1},zmm15"
EmitIfCountGE \RowCount\(), 12, "vmovupf ZMMWORD PTR [r13]{k1},zmm17"
EmitIfCountGE \RowCount\(), 12, "vmovupf ZMMWORD PTR [r13+rax]{k1},zmm19"
EmitIfCountGE \RowCount\(), 12, "vmovupf ZMMWORD PTR [r13+rax*2]{k1},zmm21"
EmitIfCountGE \RowCount\(), 12, "vmovupf ZMMWORD PTR [r14]{k1},zmm23"
EmitIfCountGE \RowCount\(), 12, "vmovupf ZMMWORD PTR [r14+rax]{k1},zmm25"
EmitIfCountGE \RowCount\(), 12, "vmovupf ZMMWORD PTR [r14+rax*2]{k1},zmm27"
add rdx,64 # advance matrix C by ZMMWORD
mov rdi,r11 # reload matrix A
vzeroall
cmp r9,.LFgemmZmmElementCount
ja .LProcessNextColumnLoop2xN\@
test r9,r9
jz .LExitKernel
.LProcessRemainingCountN\@:
EmitIfCountGE \RowCount\(), 12, "vmovapf zmm17,zmm5"
# clear upper block accumulators
EmitIfCountGE \RowCount\(), 12, "vmovapf zmm19,zmm5"
EmitIfCountGE \RowCount\(), 12, "vmovapf zmm21,zmm5"
EmitIfCountGE \RowCount\(), 12, "vmovapf zmm23,zmm5"
EmitIfCountGE \RowCount\(), 12, "vmovapf zmm25,zmm5"
EmitIfCountGE \RowCount\(), 12, "vmovapf zmm27,zmm5"
ComputeBlockAvx512FLoop ComputeBlockAvx512FBy1, \RowCount\()
jmp .LOutput1xNBlock\@
.endm
/*++
Macro Description:
This macro generates the inner kernel to compute matrix multiplication.
Arguments:
FunctionName - Supplies the name for the generated function.
--*/
.macro FgemmKernelAvx512FFunction FunctionName
/*++
Routine Description:
This routine is an inner kernel to compute matrix multiplication for a
set of rows.
Arguments:
A (rdi) - Supplies the address of matrix A.
B (rsi) - Supplies the address of matrix B. The matrix data has been packed
using MlasSgemmCopyPackB or MlasSgemmTransposePackB.
C (rdx) - Supplies the address of matrix C.
CountK (rcx) - Supplies the number of columns from matrix A and the number
of rows from matrix B to iterate over.
CountM (r8) - Supplies the maximum number of rows that can be processed for
matrix A and matrix C. The actual number of rows handled for this
invocation depends on the kernel implementation.
CountN (r9) - Supplies the number of columns from matrix B and matrix C to
iterate over.
lda - Supplies the first dimension of matrix A.
ldc - Supplies the first dimension of matrix C.
Alpha (xmm0) - Supplies the scalar alpha multiplier (see GEMM definition).
ZeroMode - Supplies true if the output matrix must be zero initialized,
else false if the output matrix is accumulated into.
Return Value:
Returns the number of rows handled.
--*/
FUNCTION_ENTRY \FunctionName\()
push rbp
push rbx
push r15
mov .LFgemmKernelFrame_SavedR12[rsp],r12
mov .LFgemmKernelFrame_SavedR13[rsp],r13
mov .LFgemmKernelFrame_SavedR14[rsp],r14
mov r11,rdi
mov r10,.LFgemmKernelFrame_lda[rsp]
shl r10,.LFgemmElementShift # convert lda to bytes
mov rax,.LFgemmKernelFrame_ldc[rsp]
shl rax,.LFgemmElementShift # convert ldc to bytes
mov r12,rcx
shl r12,6 # compute 64*CountK bytes
mov ebp,-1
kmovw k1,ebp # update mask to write all columns
movzx r15,BYTE PTR .LFgemmKernelFrame_ZeroMode[rsp]
vbroadcastsf zmm31,xmm0
vzeroall
//
// Process CountM rows of the matrices.
//
cmp r8,12
jb .LProcessCountMLessThan12
mov r8d,12 # return 12 rows handled
ProcessCountM 12
.LProcessCountMLessThan12:
cmp r8,5
ja .LProcessCountM6
je .LProcessCountM5
cmp r8,3
ja .LProcessCountM4
je .LProcessCountM3
cmp r8,1
je .LProcessCountM1
.LProcessCountM2:
ProcessCountM 2
.LProcessCountM4:
ProcessCountM 4
.LProcessCountM6:
mov r8d,6 # return 6 rows handled
ProcessCountM 6
//
// Restore non-volatile registers and return.
//
.LExitKernel:
mov eax,r8d
mov r12,.LFgemmKernelFrame_SavedR12[rsp]
mov r13,.LFgemmKernelFrame_SavedR13[rsp]
mov r14,.LFgemmKernelFrame_SavedR14[rsp]
pop r15
pop rbx
pop rbp
ret
.LProcessCountM1:
ProcessCountM 1
.LProcessCountM3:
ProcessCountM 3
.LProcessCountM5:
ProcessCountM 5
.endm