From 697e198e8a530be338b7114d2e24d2d1bb7e3392 Mon Sep 17 00:00:00 2001 From: wernsaar Date: Wed, 27 Nov 2013 16:15:06 +0100 Subject: [PATCH] added zgemm_kernel for ARMV6 --- kernel/arm/KERNEL.ARMV6 | 2 +- kernel/arm/zgemm_kernel_2x2_vfp.S | 1311 +++++++++++++++++++++++++++++++++++++ 2 files changed, 1312 insertions(+), 1 deletion(-) create mode 100644 kernel/arm/zgemm_kernel_2x2_vfp.S diff --git a/kernel/arm/KERNEL.ARMV6 b/kernel/arm/KERNEL.ARMV6 index 1ab2683..58e4d27 100644 --- a/kernel/arm/KERNEL.ARMV6 +++ b/kernel/arm/KERNEL.ARMV6 @@ -111,7 +111,7 @@ CGEMMOTCOPY = cgemm_tcopy_2_vfp.S CGEMMONCOPYOBJ = cgemm_oncopy.o CGEMMOTCOPYOBJ = cgemm_otcopy.o -ZGEMMKERNEL = ../generic/zgemmkernel_2x2.c +ZGEMMKERNEL = zgemm_kernel_2x2_vfp.S ZGEMMONCOPY = zgemm_ncopy_2_vfp.S ZGEMMOTCOPY = zgemm_tcopy_2_vfp.S ZGEMMONCOPYOBJ = zgemm_oncopy.o diff --git a/kernel/arm/zgemm_kernel_2x2_vfp.S b/kernel/arm/zgemm_kernel_2x2_vfp.S new file mode 100644 index 0000000..7f76649 --- /dev/null +++ b/kernel/arm/zgemm_kernel_2x2_vfp.S @@ -0,0 +1,1311 @@ +/*************************************************************************** +Copyright (c) 2013, The OpenBLAS Project +All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: +1. Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in +the documentation and/or other materials provided with the +distribution. +3. Neither the name of the OpenBLAS project nor the names of +its contributors may be used to endorse or promote products +derived from this software without specific prior written permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE OPENBLAS PROJECT OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*****************************************************************************/ + +/************************************************************************************** +* 2013/11/05 Saar +* BLASTEST : OK +* CTEST : OK +* TEST : OK +* +* 2013/11/02 Saar +* UNROLL_N 2 +* UNROLL_M 2 +* ZGEMM_P 64 +* ZGEMM_Q 120 +* ZGEMM_R 4096 +* A_PRE 96 +* B_PRE 96 +* C_PRE 64 +* +* Performance on Odroid U2: +* +* 1 Core: 1.62 GFLOPS ATLAS: 1.39 GFLOPS +* 2 Cores: 3.20 GFLOPS ATLAS: 2.54 GFLOPS +* 3 Cores: 4.72 GFLOPS ATLAS: 3.76 GFLOPS +* 4 Cores: 5.93 GFLOPS ATLAS: 4.88 GFLOPS +**************************************************************************************/ + +#define ASSEMBLER +#include "common.h" + +#define STACKSIZE 256 + +#define OLD_M r0 +#define OLD_N r1 +#define OLD_K r2 +#define OLD_A r3 +#define OLD_ALPHA_R d0 +#define OLD_ALPHA_I d1 + +/****************************************************** +* [fp, #-128] - [fp, #-64] is reserved +* for store and restore of floating point +* registers +*******************************************************/ + +#define A [fp, #-248 ] +#define LDC [fp, #-252 ] +#define M [fp, #-256 ] +#define N [fp, #-260 ] +#define K [fp, #-264 ] + +#define ALPHA_I [fp, #-272] +#define ALPHA_R [fp, #-280] + +#define B [fp, #4 ] +#define C [fp, #8 ] +#define OLD_LDC [fp, #12 ] + +#define I r0 +#define J r1 +#define L r2 + +#define AO r5 +#define BO r6 + +#define CO1 r8 +#define CO2 r9 + +#define K1 r7 +#define BC r12 + +#define A_PRE 96 +#define B_PRE 96 +#define C_PRE 64 + +#if defined(NN) || defined(NT) || defined(TN) || defined(TT) + + #define KMAC_R fnmacd + #define KMAC_I fmacd + + #define FMAC_R1 fmacd + #define FMAC_R2 fnmacd + #define FMAC_I1 fmacd + #define FMAC_I2 fmacd + +#elif defined(CN) || defined(CT) + + #define KMAC_R fmacd + #define KMAC_I fnmacd + + #define FMAC_R1 fmacd + #define FMAC_R2 fnmacd + #define FMAC_I1 fmacd + #define FMAC_I2 fmacd + +#elif defined(NC) || defined(TC) + + #define KMAC_R fmacd + #define KMAC_I fnmacd + + #define FMAC_R1 fmacd + #define FMAC_R2 fmacd + #define FMAC_I1 fnmacd + #define FMAC_I2 fmacd + +#else + + #define KMAC_R fnmacd + #define KMAC_I fmacd + + #define FMAC_R1 fmacd + #define FMAC_R2 fmacd + #define FMAC_I1 fnmacd + #define FMAC_I2 fmacd + +#endif + + + +/************************************************************************************** +* Macro definitions +**************************************************************************************/ + +.macro INIT2x2 + + vsub.f64 d8 , d8 , d8 + vmov.f64 d9 , d8 + vmov.f64 d10, d8 + vmov.f64 d11, d8 + vmov.f64 d12, d8 + vmov.f64 d13, d8 + vmov.f64 d14, d8 + vmov.f64 d15, d8 + +.endm + +.macro KERNEL2x2_I + + fldd d0 , [ AO ] + fldd d1 , [ AO, #8 ] + + fldd d2 , [ AO, #16 ] + fldd d3 , [ AO, #24 ] + + fldd d4 , [ BO ] + fldd d5 , [ BO, #8 ] + + fldd d6 , [ BO, #16 ] + fldd d7 , [ BO, #24 ] + + fmuld d8 , d0, d4 + KMAC_R d8 , d1, d5 + fmuld d9 , d0, d5 + KMAC_I d9 , d1, d4 + + fmuld d10 , d2, d4 + KMAC_R d10 , d3, d5 + fmuld d11 , d2, d5 + KMAC_I d11 , d3, d4 + + fmuld d12 , d0, d6 + KMAC_R d12 , d1, d7 + fmuld d13 , d0, d7 + KMAC_I d13 , d1, d6 + + fmuld d14 , d2, d6 + KMAC_R d14 , d3, d7 + fmuld d15 , d2, d7 + KMAC_I d15 , d3, d6 + + add BO , BO, #32 + add AO , AO, #32 + +.endm + + + +.macro KERNEL2x2_M1 + + fldd d0 , [ AO ] + fldd d1 , [ AO, #8 ] + fldd d2 , [ AO, #16 ] + fldd d3 , [ AO, #24 ] + + fldd d4 , [ BO ] + fldd d5 , [ BO, #8 ] + fldd d6 , [ BO, #16 ] + fldd d7 , [ BO, #24 ] + + fmacd d8 , d0, d4 + KMAC_R d8 , d1, d5 + fmacd d9 , d0, d5 + KMAC_I d9 , d1, d4 + + fmacd d10 , d2, d4 + KMAC_R d10 , d3, d5 + fmacd d11 , d2, d5 + KMAC_I d11 , d3, d4 + + fmacd d12 , d0, d6 + KMAC_R d12 , d1, d7 + fmacd d13 , d0, d7 + KMAC_I d13 , d1, d6 + + fmacd d14 , d2, d6 + KMAC_R d14 , d3, d7 + fmacd d15 , d2, d7 + KMAC_I d15 , d3, d6 + + add BO , BO, #32 + add AO , AO, #32 + +.endm + +.macro KERNEL2x2_M2 + + fldd d0 , [ AO ] + fldd d1 , [ AO, #8 ] + fldd d2 , [ AO, #16 ] + fldd d3 , [ AO, #24 ] + + fldd d4 , [ BO ] + fldd d5 , [ BO, #8 ] + fldd d6 , [ BO, #16 ] + fldd d7 , [ BO, #24 ] + + fmacd d8 , d0, d4 + KMAC_R d8 , d1, d5 + fmacd d9 , d0, d5 + KMAC_I d9 , d1, d4 + + fmacd d10 , d2, d4 + KMAC_R d10 , d3, d5 + fmacd d11 , d2, d5 + KMAC_I d11 , d3, d4 + + fmacd d12 , d0, d6 + KMAC_R d12 , d1, d7 + fmacd d13 , d0, d7 + KMAC_I d13 , d1, d6 + + fmacd d14 , d2, d6 + KMAC_R d14 , d3, d7 + fmacd d15 , d2, d7 + KMAC_I d15 , d3, d6 + + add BO , BO, #32 + add AO , AO, #32 + + +.endm + + +.macro KERNEL2x2_E + + fldd d0 , [ AO ] + fldd d1 , [ AO, #8 ] + fldd d2 , [ AO, #16 ] + fldd d3 , [ AO, #24 ] + + fldd d4 , [ BO ] + fldd d5 , [ BO, #8 ] + fldd d6 , [ BO, #16 ] + fldd d7 , [ BO, #24 ] + + fmacd d8 , d0, d4 + KMAC_R d8 , d1, d5 + fmacd d9 , d0, d5 + KMAC_I d9 , d1, d4 + + fmacd d10 , d2, d4 + KMAC_R d10 , d3, d5 + fmacd d11 , d2, d5 + KMAC_I d11 , d3, d4 + + fmacd d12 , d0, d6 + KMAC_R d12 , d1, d7 + fmacd d13 , d0, d7 + KMAC_I d13 , d1, d6 + + fmacd d14 , d2, d6 + KMAC_R d14 , d3, d7 + fmacd d15 , d2, d7 + KMAC_I d15 , d3, d6 + + add BO , BO, #32 + add AO , AO, #32 + +.endm + +.macro KERNEL2x2_SUB + + fldd d0 , [ AO ] + fldd d1 , [ AO, #8 ] + fldd d2 , [ AO, #16 ] + fldd d3 , [ AO, #24 ] + + fldd d4 , [ BO ] + fldd d5 , [ BO, #8 ] + fldd d6 , [ BO, #16 ] + fldd d7 , [ BO, #24 ] + + fmacd d8 , d0, d4 + KMAC_R d8 , d1, d5 + fmacd d9 , d0, d5 + KMAC_I d9 , d1, d4 + + fmacd d10 , d2, d4 + KMAC_R d10 , d3, d5 + fmacd d11 , d2, d5 + KMAC_I d11 , d3, d4 + + fmacd d12 , d0, d6 + KMAC_R d12 , d1, d7 + fmacd d13 , d0, d7 + KMAC_I d13 , d1, d6 + + fmacd d14 , d2, d6 + KMAC_R d14 , d3, d7 + fmacd d15 , d2, d7 + KMAC_I d15 , d3, d6 + + add BO , BO, #32 + add AO , AO, #32 + + +.endm + + +.macro SAVE2x2 + + ldr r3 , LDC + add CO2 , CO1, r3 + + fldd d0, ALPHA_R + fldd d1, ALPHA_I + + fldmiad CO1, { d4 - d7 } + + FMAC_R1 d4 , d0 , d8 + FMAC_I1 d5 , d0 , d9 + FMAC_R2 d4 , d1 , d9 + FMAC_I2 d5 , d1 , d8 + + FMAC_R1 d6 , d0 , d10 + FMAC_I1 d7 , d0 , d11 + FMAC_R2 d6 , d1 , d11 + FMAC_I2 d7 , d1 , d10 + + fstmiad CO1, { d4 - d7 } + + fldmiad CO2, { d4 - d7 } + + FMAC_R1 d4 , d0 , d12 + FMAC_I1 d5 , d0 , d13 + FMAC_R2 d4 , d1 , d13 + FMAC_I2 d5 , d1 , d12 + + FMAC_R1 d6 , d0 , d14 + FMAC_I1 d7 , d0 , d15 + FMAC_R2 d6 , d1 , d15 + FMAC_I2 d7 , d1 , d14 + + fstmiad CO2, { d4 - d7 } + + add CO1, CO1, #32 + +.endm + +/******************************************************************************/ + +.macro INIT1x2 + + vsub.f64 d8 , d8 , d8 + vmov.f64 d9 , d8 + vmov.f64 d12, d8 + vmov.f64 d13, d8 + +.endm + +.macro KERNEL1x2_I + + fldd d0 , [ AO ] + fldd d1 , [ AO, #8 ] + + fldd d4 , [ BO ] + fldd d5 , [ BO, #8 ] + + fldd d6 , [ BO, #16 ] + fldd d7 , [ BO, #24 ] + + fmuld d8 , d0, d4 + KMAC_R d8 , d1, d5 + fmuld d9 , d0, d5 + KMAC_I d9 , d1, d4 + + fmuld d12 , d0, d6 + KMAC_R d12 , d1, d7 + fmuld d13 , d0, d7 + KMAC_I d13 , d1, d6 + + add BO , BO, #32 + add AO , AO, #16 + +.endm + + + +.macro KERNEL1x2_M1 + + fldd d0 , [ AO ] + fldd d1 , [ AO, #8 ] + + fldd d4 , [ BO ] + fldd d5 , [ BO, #8 ] + fldd d6 , [ BO, #16 ] + fldd d7 , [ BO, #24 ] + + fmacd d8 , d0, d4 + KMAC_R d8 , d1, d5 + fmacd d9 , d0, d5 + KMAC_I d9 , d1, d4 + + fmacd d12 , d0, d6 + KMAC_R d12 , d1, d7 + fmacd d13 , d0, d7 + KMAC_I d13 , d1, d6 + + add BO , BO, #32 + add AO , AO, #16 + +.endm + +.macro KERNEL1x2_M2 + + fldd d0 , [ AO ] + fldd d1 , [ AO, #8 ] + + fldd d4 , [ BO ] + fldd d5 , [ BO, #8 ] + fldd d6 , [ BO, #16 ] + fldd d7 , [ BO, #24 ] + + fmacd d8 , d0, d4 + KMAC_R d8 , d1, d5 + fmacd d9 , d0, d5 + KMAC_I d9 , d1, d4 + + fmacd d12 , d0, d6 + KMAC_R d12 , d1, d7 + fmacd d13 , d0, d7 + KMAC_I d13 , d1, d6 + + add BO , BO, #32 + add AO , AO, #16 + + +.endm + + +.macro KERNEL1x2_E + + fldd d0 , [ AO ] + fldd d1 , [ AO, #8 ] + + fldd d4 , [ BO ] + fldd d5 , [ BO, #8 ] + fldd d6 , [ BO, #16 ] + fldd d7 , [ BO, #24 ] + + fmacd d8 , d0, d4 + KMAC_R d8 , d1, d5 + fmacd d9 , d0, d5 + KMAC_I d9 , d1, d4 + + fmacd d12 , d0, d6 + KMAC_R d12 , d1, d7 + fmacd d13 , d0, d7 + KMAC_I d13 , d1, d6 + + add BO , BO, #32 + add AO , AO, #16 + +.endm + +.macro KERNEL1x2_SUB + + fldd d0 , [ AO ] + fldd d1 , [ AO, #8 ] + + fldd d4 , [ BO ] + fldd d5 , [ BO, #8 ] + fldd d6 , [ BO, #16 ] + fldd d7 , [ BO, #24 ] + + fmacd d8 , d0, d4 + KMAC_R d8 , d1, d5 + fmacd d9 , d0, d5 + KMAC_I d9 , d1, d4 + + fmacd d12 , d0, d6 + KMAC_R d12 , d1, d7 + fmacd d13 , d0, d7 + KMAC_I d13 , d1, d6 + + add BO , BO, #32 + add AO , AO, #16 + + +.endm + + +.macro SAVE1x2 + + ldr r3 , LDC + add CO2 , CO1, r3 + + fldd d0, ALPHA_R + fldd d1, ALPHA_I + + fldmiad CO1, { d4 - d5 } + + FMAC_R1 d4 , d0 , d8 + FMAC_I1 d5 , d0 , d9 + FMAC_R2 d4 , d1 , d9 + FMAC_I2 d5 , d1 , d8 + + fstmiad CO1, { d4 - d5 } + + fldmiad CO2, { d4 - d5 } + + FMAC_R1 d4 , d0 , d12 + FMAC_I1 d5 , d0 , d13 + FMAC_R2 d4 , d1 , d13 + FMAC_I2 d5 , d1 , d12 + + fstmiad CO2, { d4 - d5 } + + add CO1, CO1, #16 + +.endm + + +/******************************************************************************/ + +.macro INIT2x1 + + vsub.f64 d8 , d8 , d8 + vmov.f64 d9 , d8 + vmov.f64 d10, d8 + vmov.f64 d11, d8 + +.endm + +.macro KERNEL2x1_I + + fldd d0 , [ AO ] + fldd d1 , [ AO, #8 ] + + fldd d2 , [ AO, #16 ] + fldd d3 , [ AO, #24 ] + + fldd d4 , [ BO ] + fldd d5 , [ BO, #8 ] + + fmuld d8 , d0, d4 + KMAC_R d8 , d1, d5 + fmuld d9 , d0, d5 + KMAC_I d9 , d1, d4 + + fmuld d10 , d2, d4 + KMAC_R d10 , d3, d5 + fmuld d11 , d2, d5 + KMAC_I d11 , d3, d4 + + add BO , BO, #16 + add AO , AO, #32 + +.endm + + + +.macro KERNEL2x1_M1 + + fldd d0 , [ AO ] + fldd d1 , [ AO, #8 ] + fldd d2 , [ AO, #16 ] + fldd d3 , [ AO, #24 ] + + fldd d4 , [ BO ] + fldd d5 , [ BO, #8 ] + + fmacd d8 , d0, d4 + KMAC_R d8 , d1, d5 + fmacd d9 , d0, d5 + KMAC_I d9 , d1, d4 + + fmacd d10 , d2, d4 + KMAC_R d10 , d3, d5 + fmacd d11 , d2, d5 + KMAC_I d11 , d3, d4 + + add BO , BO, #16 + add AO , AO, #32 + +.endm + +.macro KERNEL2x1_M2 + + fldd d0 , [ AO ] + fldd d1 , [ AO, #8 ] + fldd d2 , [ AO, #16 ] + fldd d3 , [ AO, #24 ] + + fldd d4 , [ BO ] + fldd d5 , [ BO, #8 ] + + fmacd d8 , d0, d4 + KMAC_R d8 , d1, d5 + fmacd d9 , d0, d5 + KMAC_I d9 , d1, d4 + + fmacd d10 , d2, d4 + KMAC_R d10 , d3, d5 + fmacd d11 , d2, d5 + KMAC_I d11 , d3, d4 + + add BO , BO, #16 + add AO , AO, #32 + + +.endm + + +.macro KERNEL2x1_E + + fldd d0 , [ AO ] + fldd d1 , [ AO, #8 ] + fldd d2 , [ AO, #16 ] + fldd d3 , [ AO, #24 ] + + fldd d4 , [ BO ] + fldd d5 , [ BO, #8 ] + + fmacd d8 , d0, d4 + KMAC_R d8 , d1, d5 + fmacd d9 , d0, d5 + KMAC_I d9 , d1, d4 + + fmacd d10 , d2, d4 + KMAC_R d10 , d3, d5 + fmacd d11 , d2, d5 + KMAC_I d11 , d3, d4 + + add BO , BO, #16 + add AO , AO, #32 + +.endm + +.macro KERNEL2x1_SUB + + fldd d0 , [ AO ] + fldd d1 , [ AO, #8 ] + fldd d2 , [ AO, #16 ] + fldd d3 , [ AO, #24 ] + + fldd d4 , [ BO ] + fldd d5 , [ BO, #8 ] + + fmacd d8 , d0, d4 + KMAC_R d8 , d1, d5 + fmacd d9 , d0, d5 + KMAC_I d9 , d1, d4 + + fmacd d10 , d2, d4 + KMAC_R d10 , d3, d5 + fmacd d11 , d2, d5 + KMAC_I d11 , d3, d4 + + add BO , BO, #16 + add AO , AO, #32 + + +.endm + + +.macro SAVE2x1 + + fldd d0, ALPHA_R + fldd d1, ALPHA_I + + fldmiad CO1, { d4 - d7 } + + FMAC_R1 d4 , d0 , d8 + FMAC_I1 d5 , d0 , d9 + FMAC_R2 d4 , d1 , d9 + FMAC_I2 d5 , d1 , d8 + + FMAC_R1 d6 , d0 , d10 + FMAC_I1 d7 , d0 , d11 + FMAC_R2 d6 , d1 , d11 + FMAC_I2 d7 , d1 , d10 + + fstmiad CO1, { d4 - d7 } + + add CO1, CO1, #32 + +.endm + + +/******************************************************************************/ + +.macro INIT1x1 + + vsub.f64 d8 , d8 , d8 + vmov.f64 d9 , d8 + +.endm + +.macro KERNEL1x1_I + + fldd d0 , [ AO ] + fldd d1 , [ AO, #8 ] + + fldd d4 , [ BO ] + fldd d5 , [ BO, #8 ] + + fmuld d8 , d0, d4 + KMAC_R d8 , d1, d5 + fmuld d9 , d0, d5 + KMAC_I d9 , d1, d4 + + add BO , BO, #16 + add AO , AO, #16 + +.endm + + + +.macro KERNEL1x1_M1 + + fldd d0 , [ AO ] + fldd d1 , [ AO, #8 ] + + fldd d4 , [ BO ] + fldd d5 , [ BO, #8 ] + + fmacd d8 , d0, d4 + KMAC_R d8 , d1, d5 + fmacd d9 , d0, d5 + KMAC_I d9 , d1, d4 + + add BO , BO, #16 + add AO , AO, #16 + +.endm + +.macro KERNEL1x1_M2 + + fldd d0 , [ AO ] + fldd d1 , [ AO, #8 ] + + fldd d4 , [ BO ] + fldd d5 , [ BO, #8 ] + + fmacd d8 , d0, d4 + KMAC_R d8 , d1, d5 + fmacd d9 , d0, d5 + KMAC_I d9 , d1, d4 + + add BO , BO, #16 + add AO , AO, #16 + + +.endm + + +.macro KERNEL1x1_E + + fldd d0 , [ AO ] + fldd d1 , [ AO, #8 ] + + fldd d4 , [ BO ] + fldd d5 , [ BO, #8 ] + + fmacd d8 , d0, d4 + KMAC_R d8 , d1, d5 + fmacd d9 , d0, d5 + KMAC_I d9 , d1, d4 + + add BO , BO, #16 + add AO , AO, #16 + +.endm + +.macro KERNEL1x1_SUB + + fldd d0 , [ AO ] + fldd d1 , [ AO, #8 ] + + fldd d4 , [ BO ] + fldd d5 , [ BO, #8 ] + + fmacd d8 , d0, d4 + KMAC_R d8 , d1, d5 + fmacd d9 , d0, d5 + KMAC_I d9 , d1, d4 + + add BO , BO, #16 + add AO , AO, #16 + + +.endm + + +.macro SAVE1x1 + + fldd d0, ALPHA_R + fldd d1, ALPHA_I + + fldmiad CO1, { d4 - d5 } + + FMAC_R1 d4 , d0 , d8 + FMAC_I1 d5 , d0 , d9 + FMAC_R2 d4 , d1 , d9 + FMAC_I2 d5 , d1 , d8 + + fstmiad CO1, { d4 - d5 } + + add CO1, CO1, #16 + +.endm + + +/******************************************************************************/ + + +/************************************************************************************** +* End of macro definitions +**************************************************************************************/ + + PROLOGUE + + .align 5 + + push {r4 - r9, fp} + add fp, sp, #24 + sub sp, sp, #STACKSIZE // reserve stack + + str OLD_M, M + str OLD_N, N + str OLD_K, K + str OLD_A, A + vstr OLD_ALPHA_R, ALPHA_R + vstr OLD_ALPHA_I, ALPHA_I + + sub r3, fp, #128 + vstm r3, { d8 - d15} // store floating point registers + + ldr r3, OLD_LDC + lsl r3, r3, #4 // ldc = ldc * 8 * 2 + str r3, LDC + + ldr K1, K + ldr BC, B + + ldr J, N + asrs J, J, #1 // J = J / 2 + ble zgemm_kernel_L1_BEGIN + +zgemm_kernel_L2_BEGIN: + + ldr CO1, C // CO1 = C + ldr r4 , LDC + lsl r4 , r4 , #1 // LDC * 2 + add r3 , r4, CO1 + str r3 , C // store C + + ldr AO, A // AO = A + pld [AO , #A_PRE-64] + pld [AO , #A_PRE-32] + + + +zgemm_kernel_L2_M2_BEGIN: + + ldr I, M + asrs I, I, #1 // I = I / 2 + ble zgemm_kernel_L2_M1_BEGIN + +zgemm_kernel_L2_M2_20: + + + mov BO, BC + asrs L , K1, #3 // L = L / 8 + cmp L , #3 + blt zgemm_kernel_L2_M2_30 + .align 5 + + + + KERNEL2x2_I + KERNEL2x2_M2 + KERNEL2x2_M1 + KERNEL2x2_M2 + + KERNEL2x2_M1 + KERNEL2x2_M2 + KERNEL2x2_M1 + KERNEL2x2_M2 + + sub L, L, #2 + +zgemm_kernel_L2_M2_22: + + KERNEL2x2_M1 + KERNEL2x2_M2 + KERNEL2x2_M1 + KERNEL2x2_M2 + + KERNEL2x2_M1 + KERNEL2x2_M2 + KERNEL2x2_M1 + KERNEL2x2_M2 + + subs L, L, #1 + bgt zgemm_kernel_L2_M2_22 + + KERNEL2x2_M1 + KERNEL2x2_M2 + KERNEL2x2_M1 + KERNEL2x2_M2 + + KERNEL2x2_M1 + KERNEL2x2_M2 + KERNEL2x2_M1 + KERNEL2x2_E + + b zgemm_kernel_L2_M2_44 + + +zgemm_kernel_L2_M2_30: + tst L, #3 + ble zgemm_kernel_L2_M2_40 + + tst L, #2 + ble zgemm_kernel_L2_M2_32 + + KERNEL2x2_I + KERNEL2x2_M2 + KERNEL2x2_M1 + KERNEL2x2_M2 + + KERNEL2x2_M1 + KERNEL2x2_M2 + KERNEL2x2_M1 + KERNEL2x2_M2 + + KERNEL2x2_M1 + KERNEL2x2_M2 + KERNEL2x2_M1 + KERNEL2x2_M2 + + + KERNEL2x2_M1 + KERNEL2x2_M2 + KERNEL2x2_M1 + KERNEL2x2_E + + b zgemm_kernel_L2_M2_44 + +zgemm_kernel_L2_M2_32: + + tst L, #1 + ble zgemm_kernel_L2_M2_40 + + KERNEL2x2_I + KERNEL2x2_M2 + KERNEL2x2_M1 + KERNEL2x2_M2 + + KERNEL2x2_M1 + KERNEL2x2_M2 + KERNEL2x2_M1 + KERNEL2x2_E + + b zgemm_kernel_L2_M2_44 + + +zgemm_kernel_L2_M2_40: + + INIT2x2 + + +zgemm_kernel_L2_M2_44: + + ands L , K1, #7 // L = L % 8 + ble zgemm_kernel_L2_M2_100 + +zgemm_kernel_L2_M2_46: + + KERNEL2x2_SUB + + subs L, L, #1 + bne zgemm_kernel_L2_M2_46 + +zgemm_kernel_L2_M2_100: + + SAVE2x2 + +zgemm_kernel_L2_M2_END: + + subs I, I, #1 + bne zgemm_kernel_L2_M2_20 + + +zgemm_kernel_L2_M1_BEGIN: + + ldr I, M + tst I, #1 // I = I % 2 + ble zgemm_kernel_L2_END + +zgemm_kernel_L2_M1_20: + + INIT1x2 + + mov BO, BC + asrs L , K1, #3 // L = L / 8 + ble zgemm_kernel_L2_M1_40 + +zgemm_kernel_L2_M1_22: + + KERNEL1x2_SUB + KERNEL1x2_SUB + KERNEL1x2_SUB + KERNEL1x2_SUB + + KERNEL1x2_SUB + KERNEL1x2_SUB + KERNEL1x2_SUB + KERNEL1x2_SUB + + subs L, L, #1 + bgt zgemm_kernel_L2_M1_22 + + +zgemm_kernel_L2_M1_40: + + ands L , K1, #7 // L = L % 8 + ble zgemm_kernel_L2_M1_100 + +zgemm_kernel_L2_M1_42: + + KERNEL1x2_SUB + + subs L, L, #1 + bgt zgemm_kernel_L2_M1_42 + +zgemm_kernel_L2_M1_100: + + SAVE1x2 + + +zgemm_kernel_L2_END: + + mov r3, BC + mov r4, K1 + lsl r4, r4, #5 // k * 2 * 8 * 2 + add r3, r3, r4 // B = B + K * 4 * 8 + mov BC, r3 + + subs J , #1 // j-- + bgt zgemm_kernel_L2_BEGIN + + + +/*********************************************************************************************/ + +zgemm_kernel_L1_BEGIN: + + ldr J , N + tst J , #1 + ble zgemm_kernel_L999 + + + ldr CO1, C // CO1 = C + ldr r4 , LDC + add r3 , r4, CO1 + str r3 , C // store C + + ldr AO, A // AO = A + +zgemm_kernel_L1_M2_BEGIN: + + ldr I, M + asrs I, I, #1 // I = I / 2 + ble zgemm_kernel_L1_M1_BEGIN + +zgemm_kernel_L1_M2_20: + + + mov BO, BC + asrs L , K1, #3 // L = L / 8 + cmp L , #3 + blt zgemm_kernel_L1_M2_30 + .align 5 + + + + KERNEL2x1_I + KERNEL2x1_M2 + KERNEL2x1_M1 + KERNEL2x1_M2 + + KERNEL2x1_M1 + KERNEL2x1_M2 + KERNEL2x1_M1 + KERNEL2x1_M2 + + sub L, L, #2 + +zgemm_kernel_L1_M2_22: + + KERNEL2x1_M1 + KERNEL2x1_M2 + KERNEL2x1_M1 + KERNEL2x1_M2 + + KERNEL2x1_M1 + KERNEL2x1_M2 + KERNEL2x1_M1 + KERNEL2x1_M2 + + subs L, L, #1 + bgt zgemm_kernel_L1_M2_22 + + KERNEL2x1_M1 + KERNEL2x1_M2 + KERNEL2x1_M1 + KERNEL2x1_M2 + + KERNEL2x1_M1 + KERNEL2x1_M2 + KERNEL2x1_M1 + KERNEL2x1_E + + b zgemm_kernel_L1_M2_44 + + +zgemm_kernel_L1_M2_30: + tst L, #3 + ble zgemm_kernel_L1_M2_40 + + tst L, #2 + ble zgemm_kernel_L1_M2_32 + + KERNEL2x1_I + KERNEL2x1_M2 + KERNEL2x1_M1 + KERNEL2x1_M2 + + KERNEL2x1_M1 + KERNEL2x1_M2 + KERNEL2x1_M1 + KERNEL2x1_M2 + + KERNEL2x1_M1 + KERNEL2x1_M2 + KERNEL2x1_M1 + KERNEL2x1_M2 + + + KERNEL2x1_M1 + KERNEL2x1_M2 + KERNEL2x1_M1 + KERNEL2x1_E + + b zgemm_kernel_L1_M2_44 + +zgemm_kernel_L1_M2_32: + + tst L, #1 + ble zgemm_kernel_L1_M2_40 + + KERNEL2x1_I + KERNEL2x1_M2 + KERNEL2x1_M1 + KERNEL2x1_M2 + + KERNEL2x1_M1 + KERNEL2x1_M2 + KERNEL2x1_M1 + KERNEL2x1_E + + b zgemm_kernel_L1_M2_44 + + +zgemm_kernel_L1_M2_40: + + INIT2x1 + + +zgemm_kernel_L1_M2_44: + + ands L , K1, #7 // L = L % 8 + ble zgemm_kernel_L1_M2_100 + +zgemm_kernel_L1_M2_46: + + KERNEL2x1_SUB + + subs L, L, #1 + bne zgemm_kernel_L1_M2_46 + +zgemm_kernel_L1_M2_100: + + SAVE2x1 + +zgemm_kernel_L1_M2_END: + + subs I, I, #1 + bne zgemm_kernel_L1_M2_20 + + +zgemm_kernel_L1_M1_BEGIN: + + ldr I, M + tst I, #1 // I = I % 2 + ble zgemm_kernel_L1_END + +zgemm_kernel_L1_M1_20: + + INIT1x1 + + mov BO, BC + asrs L , K1, #3 // L = L / 8 + ble zgemm_kernel_L1_M1_40 + +zgemm_kernel_L1_M1_22: + + KERNEL1x1_SUB + KERNEL1x1_SUB + KERNEL1x1_SUB + KERNEL1x1_SUB + + KERNEL1x1_SUB + KERNEL1x1_SUB + KERNEL1x1_SUB + KERNEL1x1_SUB + + subs L, L, #1 + bgt zgemm_kernel_L1_M1_22 + + +zgemm_kernel_L1_M1_40: + + ands L , K1, #7 // L = L % 8 + ble zgemm_kernel_L1_M1_100 + +zgemm_kernel_L1_M1_42: + + KERNEL1x1_SUB + + subs L, L, #1 + bgt zgemm_kernel_L1_M1_42 + +zgemm_kernel_L1_M1_100: + + SAVE1x1 + + +zgemm_kernel_L1_END: + + + +zgemm_kernel_L999: + + sub r3, fp, #128 + vldm r3, { d8 - d15} // restore floating point registers + + movs r0, #0 // set return value + sub sp, fp, #24 + pop {r4 - r9, fp} + bx lr + + EPILOGUE + -- 2.7.4