1*5f39d1b3SJooyung Han // 2*5f39d1b3SJooyung Han // Licensed under the Apache License, Version 2.0 (the "License"); 3*5f39d1b3SJooyung Han // you may not use this file except in compliance with the License. 4*5f39d1b3SJooyung Han // You may obtain a copy of the License at 5*5f39d1b3SJooyung Han // 6*5f39d1b3SJooyung Han // http://www.apache.org/licenses/LICENSE-2.0 7*5f39d1b3SJooyung Han // 8*5f39d1b3SJooyung Han // Unless required by applicable law or agreed to in writing, software 9*5f39d1b3SJooyung Han // distributed under the License is distributed on an "AS IS" BASIS, 10*5f39d1b3SJooyung Han // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11*5f39d1b3SJooyung Han // See the License for the specific language governing permissions and 12*5f39d1b3SJooyung Han // limitations under the License. 13*5f39d1b3SJooyung Han 14*5f39d1b3SJooyung Han // kernel_SSE.h: a collection of Intel SSE optimized kernels. 15*5f39d1b3SJooyung Han // Check in kernel_default.h which one(s) are actually used by default. 16*5f39d1b3SJooyung Han // Others are mere experiments; they are still covered by tests 17*5f39d1b3SJooyung Han // in case they might be useful some day. 18*5f39d1b3SJooyung Han // 19*5f39d1b3SJooyung Han 20*5f39d1b3SJooyung Han #ifndef GEMMLOWP_INTERNAL_KERNEL_AVX_H_ 21*5f39d1b3SJooyung Han #define GEMMLOWP_INTERNAL_KERNEL_AVX_H_ 22*5f39d1b3SJooyung Han 23*5f39d1b3SJooyung Han #include "kernel.h" 24*5f39d1b3SJooyung Han 25*5f39d1b3SJooyung Han #include <string.h> 26*5f39d1b3SJooyung Han #include <cassert> 27*5f39d1b3SJooyung Han 28*5f39d1b3SJooyung Han namespace gemmlowp { 29*5f39d1b3SJooyung Han 30*5f39d1b3SJooyung Han #ifdef GEMMLOWP_AVX2_64 31*5f39d1b3SJooyung Han struct AVX2_64_Kernel24x8Depth2 : KernelBase { 32*5f39d1b3SJooyung Han typedef KernelFormat<KernelSideFormat<CellFormat<8, 2, CellOrder::WidthMajor>, 3>, 33*5f39d1b3SJooyung Han KernelSideFormat<CellFormat<4, 2, CellOrder::WidthMajor>, 1>> 34*5f39d1b3SJooyung Han Format; 35*5f39d1b3SJooyung Han NameAVX2_64_Kernel24x8Depth236*5f39d1b3SJooyung Han const char *Name() const override { return "AVX, 24x8, depth 2"; } 37*5f39d1b3SJooyung Han RunAVX2_64_Kernel24x8Depth238*5f39d1b3SJooyung Han void Run(std::int32_t *dst_ptr, std::size_t dst_row_stride, std::size_t dst_col_stride, 39*5f39d1b3SJooyung Han const std::uint8_t *lhs_ptr, const std::uint8_t *rhs_ptr, std::size_t start_depth, 40*5f39d1b3SJooyung Han std::size_t run_depth) const override { 41*5f39d1b3SJooyung Han ScopedProfilingLabel label("optimized kernel"); 42*5f39d1b3SJooyung Han assert(dst_row_stride == 1); 43*5f39d1b3SJooyung Han const std::int64_t run_depth_cells = run_depth / Format::kDepth; 44*5f39d1b3SJooyung Han const std::int64_t dst_col_stride_q = dst_col_stride; 45*5f39d1b3SJooyung Han 46*5f39d1b3SJooyung Han /* Main loop */ 47*5f39d1b3SJooyung Han 48*5f39d1b3SJooyung Han // A 2x8 cell of Rhs is stored in 16bit in ymm1 . 49*5f39d1b3SJooyung Han // A 24x2 block of 3 8x2 cells Lhs is stored in 16bit in ymm0, replaced 50*5f39d1b3SJooyung Han // every Iteration. 51*5f39d1b3SJooyung Han // A 8x8 block of accumulators is stored in 32bit in xmm4--xmm15. 52*5f39d1b3SJooyung Han // 53*5f39d1b3SJooyung Han // +-------+-------+-------+-------+ 54*5f39d1b3SJooyung Han // |ymm1[0] |ymm2[2] | 55*5f39d1b3SJooyung Han // Rhs +-------+---------------+-------+ 56*5f39d1b3SJooyung Han // |ymm1[1] |ymm1[4] | 57*5f39d1b3SJooyung Han // +-------+-------+-------+-------+ 58*5f39d1b3SJooyung Han // 59*5f39d1b3SJooyung Han // | | | | | 60*5f39d1b3SJooyung Han // 61*5f39d1b3SJooyung Han // Lhs | | | | | 62*5f39d1b3SJooyung Han // 63*5f39d1b3SJooyung Han // +--+--+ - - - - +-------+-------+-------+-------+ 64*5f39d1b3SJooyung Han // |ymm0 | | ymm4 | ymm5 | ymm6 | ymm7 | 65*5f39d1b3SJooyung Han // |ymm0 | (Iter1) | ymm4 | ymm5 | ymm6 | ymm7 | 66*5f39d1b3SJooyung Han // |ymm0 | | ymm4 | ymm5 | ymm6 | ymm7 | 67*5f39d1b3SJooyung Han // |ymm0 | | ymm4 | ymm5 | ymm6 | ymm7 | 68*5f39d1b3SJooyung Han // +--+--+ - - - - +-------+-------+-------+-------+ 69*5f39d1b3SJooyung Han // |ymm0 | | ymm8 | ymm9 | ymm10 | ymm11 | 70*5f39d1b3SJooyung Han // |ymm0 | (Iter2) | ymm8 | ymm9 | ymm10 | ymm11 | 71*5f39d1b3SJooyung Han // |ymm0 | | ymm8 | ymm9 | ymm10 | ymm11 | 72*5f39d1b3SJooyung Han // |ymm0 | | ymm8 | ymm9 | ymm10 | ymm11 | 73*5f39d1b3SJooyung Han // +--+--+ - - - - +-------+-------+-------+-------+ 74*5f39d1b3SJooyung Han // |ymm0 | | ymm12 | ymm13 | ymm14 | ymm15 | 75*5f39d1b3SJooyung Han // |ymm0 | (Iter3) | ymm12 | ymm13 | ymm14 | ymm15 | 76*5f39d1b3SJooyung Han // |ymm0 | | ymm12 | ymm13 | ymm14 | ymm15 | 77*5f39d1b3SJooyung Han // |ymm0 | | ymm12 | ymm13 | ymm14 | ymm15 | 78*5f39d1b3SJooyung Han // +--+--+ - - - - +-------+-------+-------+-------+ 79*5f39d1b3SJooyung Han // 80*5f39d1b3SJooyung Han // Accumulator 81*5f39d1b3SJooyung Han 82*5f39d1b3SJooyung Han asm volatile( 83*5f39d1b3SJooyung Han // Set registers for destination 84*5f39d1b3SJooyung Han "movq %[dst_col_stride_q], %%r12\n\t" // stride is r12 85*5f39d1b3SJooyung Han "shlq $2, %%r12\n\t" // set stride dword 86*5f39d1b3SJooyung Han "leaq (%%r12,%%r12,0x2), %%r13\n\t" // load stride aligned r13 87*5f39d1b3SJooyung Han 88*5f39d1b3SJooyung Han // Set accumulators to zero. 89*5f39d1b3SJooyung Han "vpxor %%ymm4, %%ymm4, %%ymm4 \n\t" // zero accumulators 90*5f39d1b3SJooyung Han "vpxor %%ymm5, %%ymm5, %%ymm5 \n\t" // zero accumulators 91*5f39d1b3SJooyung Han "vpxor %%ymm6, %%ymm6, %%ymm6 \n\t" // zero accumulators 92*5f39d1b3SJooyung Han "vpxor %%ymm7, %%ymm7, %%ymm7 \n\t" // zero accumulators 93*5f39d1b3SJooyung Han "vpxor %%ymm8, %%ymm8, %%ymm8 \n\t" // zero accumulators 94*5f39d1b3SJooyung Han "vpxor %%ymm9, %%ymm9, %%ymm9 \n\t" // zero accumulators 95*5f39d1b3SJooyung Han "vpxor %%ymm10, %%ymm10, %%ymm10\n\t" // zero accumulators 96*5f39d1b3SJooyung Han "vpxor %%ymm11, %%ymm11, %%ymm11\n\t" // zero accumulators 97*5f39d1b3SJooyung Han "vpxor %%ymm12, %%ymm12, %%ymm12\n\t" // zero accumulators 98*5f39d1b3SJooyung Han "vpxor %%ymm13, %%ymm13, %%ymm13\n\t" // zero accumulators 99*5f39d1b3SJooyung Han "vpxor %%ymm14, %%ymm14, %%ymm14\n\t" // zero accumulators 100*5f39d1b3SJooyung Han "vpxor %%ymm15, %%ymm15, %%ymm15\n\t" // zero accumulators 101*5f39d1b3SJooyung Han 102*5f39d1b3SJooyung Han "movq %[run_depth_cells], %%r14 \n\t" // load cell depth r14 103*5f39d1b3SJooyung Han "subq $2, %%r14 \n\t" // cell depth is 2 104*5f39d1b3SJooyung Han "js outerLoop1%= \n\t" // outerloop for matrix 105*5f39d1b3SJooyung Han 106*5f39d1b3SJooyung Han // Loop for K unrolled by 4 107*5f39d1b3SJooyung Han "outerLoop2%=: \n\t" // outer loop unroll 108*5f39d1b3SJooyung Han 109*5f39d1b3SJooyung Han // K = 0,1,2,3 110*5f39d1b3SJooyung Han // RHS cell to ymm1 111*5f39d1b3SJooyung Han 112*5f39d1b3SJooyung Han // lower half 113*5f39d1b3SJooyung Han "vpmovzxbw (%[rhs_ptr]), %%ymm1 \n\t" // mov rhs to ymm1 114*5f39d1b3SJooyung Han "vpermq $0x44,%%ymm1, %%ymm1 \n\t" 115*5f39d1b3SJooyung Han // LHS cell elements 0 and 1 116*5f39d1b3SJooyung Han "vpmovzxbw 0x00(%[lhs_ptr]), %%ymm0\n\t" // mov lhs to ymm0 117*5f39d1b3SJooyung Han "vpshufd $0x00,%%ymm1,%%ymm2 \n\t" // move rhs 0 element to all ymm2 118*5f39d1b3SJooyung Han "vpshufd $0x55,%%ymm1,%%ymm3 \n\t" // move rhs 1 element to all ymm3 119*5f39d1b3SJooyung Han "vpmaddwd %%ymm0, %%ymm2, %%ymm2 \n\t" // mul add lhs rhs0 into ymm2 120*5f39d1b3SJooyung Han "vpmaddwd %%ymm0, %%ymm3, %%ymm3 \n\t" // mul add lhs rhs1 into ymm3 121*5f39d1b3SJooyung Han "vpaddd %%ymm2, %%ymm4, %%ymm4 \n\t" // add muladd lhs + rhs0 into ymm4 122*5f39d1b3SJooyung Han "vpaddd %%ymm3, %%ymm5, %%ymm5 \n\t" // add muladd lhs + rhs1 into ymm5 123*5f39d1b3SJooyung Han // LHS cell elements 2 and 3 124*5f39d1b3SJooyung Han "vpshufd $0xaa, %%ymm1, %%ymm2 \n\t" // move rhs 2 element to all ymm2 125*5f39d1b3SJooyung Han "vpmaddwd %%ymm0, %%ymm2, %%ymm2 \n\t" // mul add lhs rh3 into ymm2 126*5f39d1b3SJooyung Han "vpshufd $0xff,%%ymm1,%%ymm3 \n\t" // mov rhs 3 element into all ymm3 127*5f39d1b3SJooyung Han "vpmaddwd %%ymm0, %%ymm3, %%ymm3 \n\t" // mul add lhs rh4 into ymm3 128*5f39d1b3SJooyung Han "vpaddd %%ymm2, %%ymm6, %%ymm6 \n\t" // add muladd lhs + rhs2 into ymm6 129*5f39d1b3SJooyung Han "vpaddd %%ymm3, %%ymm7, %%ymm7 \n\t" // add muladd lhs + rhs3 into ymm7 130*5f39d1b3SJooyung Han 131*5f39d1b3SJooyung Han // cache prefect lhs //see if it works better? 132*5f39d1b3SJooyung Han //"prefetcht0 0x80(%[lhs_ptr]) \n\t" //prefetch cache lines 133*5f39d1b3SJooyung Han "vpmovzxbw (%[rhs_ptr]), %%ymm1 \n\t" // mov rhs to ymm1 134*5f39d1b3SJooyung Han "vpermq $0x44,%%ymm1, %%ymm1 \n\t" 135*5f39d1b3SJooyung Han 136*5f39d1b3SJooyung Han // K = 5,6,7,8 137*5f39d1b3SJooyung Han // next LHS cell elements 0 and 1 138*5f39d1b3SJooyung Han "vpmovzxbw 0x10(%[lhs_ptr]), %%ymm0 \n\t" // mov lhs to ymm0 139*5f39d1b3SJooyung Han "vpshufd $0x00,%%ymm1,%%ymm2 \n\t" // mov rhs 0 element to all ymm2 140*5f39d1b3SJooyung Han "vpshufd $0x55,%%ymm1,%%ymm3 \n\t" // mov rhs 1 element to all ymm3 141*5f39d1b3SJooyung Han "vpmaddwd %%ymm0, %%ymm2, %%ymm2 \n\t" // mul add lhs rhs0 into ymm2 142*5f39d1b3SJooyung Han "vpmaddwd %%ymm0, %%ymm3, %%ymm3 \n\t" // mul add lhs rhs1 into ymm3 143*5f39d1b3SJooyung Han "vpaddd %%ymm2, %%ymm8, %%ymm8 \n\t" // add muladd lhs + rhs0 into ymm8 144*5f39d1b3SJooyung Han "vpaddd %%ymm3, %%ymm9, %%ymm9 \n\t" // add muladd lhs + rhs1 into ymm9 145*5f39d1b3SJooyung Han // next LHS cell elements 2 and 3 146*5f39d1b3SJooyung Han "vpshufd $0xaa,%%ymm1,%%ymm2 \n\t" // mov rhs 2 element to all ymm2 147*5f39d1b3SJooyung Han "vpshufd $0xff,%%ymm1,%%ymm3 \n\t" // mov rhs 3 element to all ymm3 148*5f39d1b3SJooyung Han "vpmaddwd %%ymm0, %%ymm2, %%ymm2 \n\t" // mul add lhs rhs2 into ymm2 149*5f39d1b3SJooyung Han "vpmaddwd %%ymm0, %%ymm3, %%ymm3 \n\t" // mul add lhs rhs3 into ymm3 150*5f39d1b3SJooyung Han "vpaddd %%ymm2, %%ymm10, %%ymm10 \n\t" // add muladd lhs + rhs2 into ymm10 151*5f39d1b3SJooyung Han "vpaddd %%ymm3, %%ymm11, %%ymm11 \n\t" // add muladd lhs + rhs3 into ymm11 152*5f39d1b3SJooyung Han 153*5f39d1b3SJooyung Han // rhs lower half 154*5f39d1b3SJooyung Han "vpmovzxbw (%[rhs_ptr]), %%ymm1 \n\t" // mov rhs to ymm1 155*5f39d1b3SJooyung Han "vpermq $0x44,%%ymm1, %%ymm1 \n\t" // duplcate lower 16 156*5f39d1b3SJooyung Han 157*5f39d1b3SJooyung Han // next LHS cell elements 0 and 1 158*5f39d1b3SJooyung Han "vpmovzxbw 0x20(%[lhs_ptr]), %%ymm0 \n\t" // mov lhs to ymm0 159*5f39d1b3SJooyung Han "vpshufd $0x00,%%ymm1,%%ymm2 \n\t" // mov rhs 0 element to all ymm2 160*5f39d1b3SJooyung Han "vpshufd $0x55,%%ymm1,%%ymm3 \n\t" // mov rhs 1 element to all ymm3 161*5f39d1b3SJooyung Han "vpmaddwd %%ymm0, %%ymm2, %%ymm2 \n\t" // mul add lhs rhs0 into ymm2 162*5f39d1b3SJooyung Han "vpmaddwd %%ymm0, %%ymm3, %%ymm3 \n\t" // mul add lhs rhs1 into ymm3 163*5f39d1b3SJooyung Han "vpaddd %%ymm2, %%ymm12, %%ymm12 \n\t" // add muladd lhs + rhs0 into ymm8 164*5f39d1b3SJooyung Han "vpaddd %%ymm3, %%ymm13, %%ymm13 \n\t" // add muladd lhs + rhs1 into ymm9 165*5f39d1b3SJooyung Han 166*5f39d1b3SJooyung Han // cache prefetch rhs //see if it works better? 167*5f39d1b3SJooyung Han //"prefetcht0 0x80(%[rhs_ptr]) \n\t" 168*5f39d1b3SJooyung Han 169*5f39d1b3SJooyung Han // next LHS cell elements 2 and 3 170*5f39d1b3SJooyung Han "vpshufd $0xaa,%%ymm1,%%ymm2 \n\t" // mov rhs 2 element to all ymm2 171*5f39d1b3SJooyung Han "vpshufd $0xff,%%ymm1,%%ymm3 \n\t" // mov rhs 3 element to all ymm3 172*5f39d1b3SJooyung Han "vpmaddwd %%ymm0, %%ymm2, %%ymm2 \n\t" // mul add lhs rhs2 into ymm2 173*5f39d1b3SJooyung Han "vpmaddwd %%ymm0, %%ymm3, %%ymm3 \n\t" // mul add lhs rhs3 into ymm3 174*5f39d1b3SJooyung Han "vpaddd %%ymm2, %%ymm14, %%ymm14 \n\t" // add muladd lhs + rhs2 into ymm10 175*5f39d1b3SJooyung Han "vpaddd %%ymm3, %%ymm15, %%ymm15 \n\t" // add muladd lhs + rhs3 into ymm11 176*5f39d1b3SJooyung Han 177*5f39d1b3SJooyung Han // current result in ymm4, ymm5, ymm6, ymm7, ymm8, ymm9, ymm10 ymm11 ymm12 ymm13 ymm14 ymm15 178*5f39d1b3SJooyung Han 179*5f39d1b3SJooyung Han // rhs+10 lower half 180*5f39d1b3SJooyung Han "vpmovzxbw 0x08(%[rhs_ptr]), %%ymm1 \n\t" // mov rhs to ymm1 181*5f39d1b3SJooyung Han "vpermq $0x44,%%ymm1, %%ymm1 \n\t" 182*5f39d1b3SJooyung Han // next LHS cell elements 0 and 1 183*5f39d1b3SJooyung Han "vpmovzxbw 0x30(%[lhs_ptr]), %%ymm0 \n\t" // mov lhs to ymm0 184*5f39d1b3SJooyung Han "vpshufd $0x00,%%ymm1,%%ymm2 \n\t" // move rhs 0 element to ymm2 185*5f39d1b3SJooyung Han "vpshufd $0x55,%%ymm1,%%ymm3 \n\t" // move rhs 1 element to ymm3 186*5f39d1b3SJooyung Han "vpmaddwd %%ymm0, %%ymm2, %%ymm2 \n\t" // muladd lhs rhs0 into ymm2 187*5f39d1b3SJooyung Han "vpmaddwd %%ymm0, %%ymm3, %%ymm3 \n\t" // muladd lhs rhs1 into ymm3 188*5f39d1b3SJooyung Han "vpaddd %%ymm2, %%ymm4, %%ymm4 \n\t" // accumulate to ymm4 189*5f39d1b3SJooyung Han "vpaddd %%ymm3, %%ymm5, %%ymm5 \n\t" // accumulate to ymm5 190*5f39d1b3SJooyung Han // next LHS cell elements 2 and 3 191*5f39d1b3SJooyung Han "vpshufd $0xaa,%%ymm1,%%ymm2 \n\t" // mov rhs 2 element to ymm2 192*5f39d1b3SJooyung Han "vpshufd $0xff,%%ymm1,%%ymm3 \n\t" // mov rhs 3 element to ymm2 193*5f39d1b3SJooyung Han "vpmaddwd %%ymm0, %%ymm2, %%ymm2 \n\t" // mul add lhs rhs2 into ymm2 194*5f39d1b3SJooyung Han "vpmaddwd %%ymm0, %%ymm3, %%ymm3 \n\t" // mull add lhs rhs3 into ymm3 195*5f39d1b3SJooyung Han "vpaddd %%ymm2, %%ymm6, %%ymm6 \n\t" // add lhs rhs2 to ymm6 196*5f39d1b3SJooyung Han "vpaddd %%ymm3, %%ymm7, %%ymm7 \n\t" // add lhs rhs3 to ymm7 197*5f39d1b3SJooyung Han 198*5f39d1b3SJooyung Han // rhs+10 lower half 199*5f39d1b3SJooyung Han "vpmovzxbw 0x08(%[rhs_ptr]), %%ymm1 \n\t" // mov rhs to ymm1 200*5f39d1b3SJooyung Han "vpermq $0x44,%%ymm1, %%ymm1 \n\t" 201*5f39d1b3SJooyung Han 202*5f39d1b3SJooyung Han // next LHS cell elements 4 and 5 203*5f39d1b3SJooyung Han "vpmovzxbw 0x40(%[lhs_ptr]), %%ymm0 \n\t" // mov lhs to ymm0 204*5f39d1b3SJooyung Han "vpshufd $0x00,%%ymm1,%%ymm2 \n\t" // move rhs 0 element to ymm2 205*5f39d1b3SJooyung Han "vpshufd $0x55,%%ymm1,%%ymm3 \n\t" // move rhs 1 element to ymm3 206*5f39d1b3SJooyung Han "vpmaddwd %%ymm0, %%ymm2, %%ymm2 \n\t" // muladd lhs rhs0 into ymm2 207*5f39d1b3SJooyung Han "vpmaddwd %%ymm0, %%ymm3, %%ymm3 \n\t" // muladd lhs rhs1 into ymm3 208*5f39d1b3SJooyung Han "vpaddd %%ymm2, %%ymm8, %%ymm8 \n\t" // accumulate to ymm8 209*5f39d1b3SJooyung Han "vpaddd %%ymm3, %%ymm9, %%ymm9 \n\t" // accumulate to ymm9 210*5f39d1b3SJooyung Han // next LHS cell elements 6 and 7 211*5f39d1b3SJooyung Han "vpshufd $0xaa,%%ymm1,%%ymm2 \n\t" // mov rhs 2 element to ymm2 212*5f39d1b3SJooyung Han "vpshufd $0xff,%%ymm1,%%ymm3 \n\t" // mov rhs 3 element to ymm2 213*5f39d1b3SJooyung Han "vpmaddwd %%ymm0, %%ymm2, %%ymm2 \n\t" // mul add lhs rhs2 into ymm2 214*5f39d1b3SJooyung Han "vpmaddwd %%ymm0, %%ymm3, %%ymm3 \n\t" // mull add lhs rhs3 into ymm3 215*5f39d1b3SJooyung Han "vpaddd %%ymm2, %%ymm10, %%ymm10 \n\t" // add lhs rhs2 to ymm10 216*5f39d1b3SJooyung Han "vpaddd %%ymm3, %%ymm11, %%ymm11 \n\t" // add lhs rhs3 to ymm11 217*5f39d1b3SJooyung Han 218*5f39d1b3SJooyung Han "vpmovzxbw 0x08(%[rhs_ptr]), %%ymm1 \n\t" // mov rhs to ymm1 219*5f39d1b3SJooyung Han "vpermq $0x44,%%ymm1, %%ymm1 \n\t" 220*5f39d1b3SJooyung Han // next LHS cell elements 9 and 10 221*5f39d1b3SJooyung Han "vpmovzxbw 0x50(%[lhs_ptr]), %%ymm0 \n\t" // mov lhs to ymm0 222*5f39d1b3SJooyung Han "vpshufd $0x00,%%ymm1,%%ymm2 \n\t" // move rhs 0 element to ymm2 223*5f39d1b3SJooyung Han "vpshufd $0x55,%%ymm1,%%ymm3 \n\t" // move rhs 1 element to ymm3 224*5f39d1b3SJooyung Han "vpmaddwd %%ymm0, %%ymm2, %%ymm2 \n\t" // muladd lhs rhs0 into ymm2 225*5f39d1b3SJooyung Han "vpmaddwd %%ymm0, %%ymm3, %%ymm3 \n\t" // muladd lhs rhs1 into ymm3 226*5f39d1b3SJooyung Han "vpaddd %%ymm2, %%ymm12, %%ymm12 \n\t" // accumulate to ymm12 227*5f39d1b3SJooyung Han "vpaddd %%ymm3, %%ymm13, %%ymm13 \n\t" // accumulate to ymm13 228*5f39d1b3SJooyung Han 229*5f39d1b3SJooyung Han // next LHS cell elements 11 and 12 230*5f39d1b3SJooyung Han "vpshufd $0xaa,%%ymm1,%%ymm2 \n\t" // mov rhs 2 element to ymm2 231*5f39d1b3SJooyung Han "vpshufd $0xff,%%ymm1,%%ymm3 \n\t" // mov rhs 3 element to ymm2 232*5f39d1b3SJooyung Han "vpmaddwd %%ymm0, %%ymm2, %%ymm2 \n\t" // mul add lhs rhs2 into ymm2 233*5f39d1b3SJooyung Han "vpmaddwd %%ymm0, %%ymm3, %%ymm3 \n\t" // mull add lhs rhs3 into ymm3 234*5f39d1b3SJooyung Han "vpaddd %%ymm2, %%ymm14, %%ymm14 \n\t" // add lhs rhs2 to ymm14 235*5f39d1b3SJooyung Han "vpaddd %%ymm3, %%ymm15, %%ymm15 \n\t" // add lhs rhs3 to ymm15 236*5f39d1b3SJooyung Han 237*5f39d1b3SJooyung Han // completed rhs+10 238*5f39d1b3SJooyung Han "addq $0x60, %[lhs_ptr] \n\t" // increment stride lhs 239*5f39d1b3SJooyung Han "addq $0x10, %[rhs_ptr] \n\t" // increment stride rhs 240*5f39d1b3SJooyung Han 241*5f39d1b3SJooyung Han "subq $2, %[run_depth_cells] \n\t" 242*5f39d1b3SJooyung Han "ja outerLoop2%= \n\t" 243*5f39d1b3SJooyung Han 244*5f39d1b3SJooyung Han "movq %[run_depth_cells], %%r14 \n\t" 245*5f39d1b3SJooyung Han "decq %%r14 \n\t" 246*5f39d1b3SJooyung Han "js finish%= \n\t" 247*5f39d1b3SJooyung Han 248*5f39d1b3SJooyung Han // Loop for K unrolled by 2 249*5f39d1b3SJooyung Han "outerLoop1%=: \n\t" 250*5f39d1b3SJooyung Han 251*5f39d1b3SJooyung Han // rhs lower 252*5f39d1b3SJooyung Han "vpmovzxbw (%[rhs_ptr]), %%ymm1 \n\t" // get rhs into ymm1 253*5f39d1b3SJooyung Han "vpermq $0x44,%%ymm1, %%ymm1 \n\t" 254*5f39d1b3SJooyung Han 255*5f39d1b3SJooyung Han // LHS cell 256*5f39d1b3SJooyung Han "vpmovzxbw (%[lhs_ptr]), %%ymm0 \n\t" // lhs in into ymm0 257*5f39d1b3SJooyung Han "vpshufd $0x00,%%ymm1,%%ymm2 \n\t" // rhs element 0 into ymm2 258*5f39d1b3SJooyung Han "vpshufd $0x55,%%ymm1,%%ymm3 \n\t" // rhs element 1 into ymm3 259*5f39d1b3SJooyung Han "vpmaddwd %%ymm0, %%ymm2, %%ymm2 \n\t" // muladd lhs rhs element 0 ymm2 260*5f39d1b3SJooyung Han "vpmaddwd %%ymm0, %%ymm3, %%ymm3 \n\t" // muladd lhs rhs element 1 ymm3 261*5f39d1b3SJooyung Han "vpaddd %%ymm2, %%ymm4, %%ymm4 \n\t" // acc element 0 ymm4 262*5f39d1b3SJooyung Han "vpaddd %%ymm3, %%ymm5, %%ymm5 \n\t" // acc element 1 ymm5 263*5f39d1b3SJooyung Han "vpshufd $0xaa,%%ymm1,%%ymm2 \n\t" // rhs element 2 into ymm2 264*5f39d1b3SJooyung Han "vpshufd $0xff,%%ymm1,%%ymm3 \n\t" // rhs element 3 into ymm3 265*5f39d1b3SJooyung Han "vpmaddwd %%ymm0, %%ymm2, %%ymm2 \n\t" // muladd lhs rhs element 2 ymm2 266*5f39d1b3SJooyung Han "vpmaddwd %%ymm0, %%ymm3, %%ymm3 \n\t" // muladd lhs rhs element 3 ymm3 267*5f39d1b3SJooyung Han "vpaddd %%ymm2, %%ymm6, %%ymm6 \n\t" // acc element 2 into ymm6 268*5f39d1b3SJooyung Han "vpaddd %%ymm3, %%ymm7, %%ymm7 \n\t" // acc element 3 into ymm7 269*5f39d1b3SJooyung Han 270*5f39d1b3SJooyung Han // lhs+10 271*5f39d1b3SJooyung Han "vpmovzxbw 0x10(%[lhs_ptr]), %%ymm0 \n\t" // lhs in into ymm0 272*5f39d1b3SJooyung Han "vpshufd $0x00, %%ymm1, %%ymm2 \n\t" // rhs element 0 into ymm2 273*5f39d1b3SJooyung Han "vpshufd $0x55, %%ymm1, %%ymm3 \n\t" // rhs element 1 into ymm3 274*5f39d1b3SJooyung Han "vpmaddwd %%ymm0, %%ymm2, %%ymm2 \n\t" // muladd lhs rhs element 0 ymm2 275*5f39d1b3SJooyung Han "vpmaddwd %%ymm0, %%ymm3, %%ymm3 \n\t" // muladd lhs rhs element 1 ymm3 276*5f39d1b3SJooyung Han "vpaddd %%ymm2, %%ymm8, %%ymm8 \n\t" // acc element 0 ymm8 277*5f39d1b3SJooyung Han "vpaddd %%ymm3, %%ymm9, %%ymm9 \n\t" // acc element 1 ymm9 278*5f39d1b3SJooyung Han "vpshufd $0xaa,%%ymm1,%%ymm2 \n\t" // rhs element 2 into ymm2 279*5f39d1b3SJooyung Han "vpshufd $0xff,%%ymm1,%%ymm3 \n\t" // rhs element 3 into ymm3 280*5f39d1b3SJooyung Han "vpmaddwd %%ymm0, %%ymm2, %%ymm2 \n\t" // muladd lhs rhs element 2 ymm2 281*5f39d1b3SJooyung Han "vpmaddwd %%ymm0, %%ymm3, %%ymm3 \n\t" // muladd lhs rhs element 3 ymm3 282*5f39d1b3SJooyung Han "vpaddd %%ymm2, %%ymm10, %%ymm10 \n\t" // acc element 2 into ymm10 283*5f39d1b3SJooyung Han "vpaddd %%ymm3, %%ymm11, %%ymm11 \n\t" // acc element 3 into ymm11 284*5f39d1b3SJooyung Han 285*5f39d1b3SJooyung Han "vpmovzxbw 0x20(%[lhs_ptr]), %%ymm0 \n\t" 286*5f39d1b3SJooyung Han "vpshufd $0x00, %%ymm1, %%ymm2 \n\t" // rhs element 0 into ymm2 287*5f39d1b3SJooyung Han "vpshufd $0x55, %%ymm1, %%ymm3 \n\t" // rhs element 1 into ymm3 288*5f39d1b3SJooyung Han "vpmaddwd %%ymm0, %%ymm2, %%ymm2 \n\t" // muladd lhs rhs element 0 ymm2 289*5f39d1b3SJooyung Han "vpmaddwd %%ymm0, %%ymm3, %%ymm3 \n\t" // muladd lhs rhs element 1 ymm3 290*5f39d1b3SJooyung Han "vpaddd %%ymm2, %%ymm12, %%ymm12 \n\t" // acc element 0 ymm12 291*5f39d1b3SJooyung Han "vpaddd %%ymm3, %%ymm13, %%ymm13 \n\t" // acc element 1 ymm13 292*5f39d1b3SJooyung Han "vpshufd $0xaa,%%ymm1,%%ymm2 \n\t" // rhs element 2 into ymm2 293*5f39d1b3SJooyung Han "vpshufd $0xff,%%ymm1,%%ymm3 \n\t" // rhs element 3 into ymm3 294*5f39d1b3SJooyung Han "vpmaddwd %%ymm0, %%ymm2, %%ymm2 \n\t" // muladd lhs rhs element 2 ymm2 295*5f39d1b3SJooyung Han "vpmaddwd %%ymm0, %%ymm3, %%ymm3 \n\t" // muladd lhs rhs element 3 ymm3 296*5f39d1b3SJooyung Han "vpaddd %%ymm2, %%ymm14, %%ymm14 \n\t" // acc element 2 into ymm14 297*5f39d1b3SJooyung Han "vpaddd %%ymm3, %%ymm15, %%ymm15 \n\t" // acc element 3 into ymm15 298*5f39d1b3SJooyung Han 299*5f39d1b3SJooyung Han // update matrix pointers 300*5f39d1b3SJooyung Han "addq $0x30, %[lhs_ptr] \n\t" 301*5f39d1b3SJooyung Han "addq $0x08, %[rhs_ptr] \n\t" 302*5f39d1b3SJooyung Han 303*5f39d1b3SJooyung Han "decq %[run_depth_cells] \n\t" 304*5f39d1b3SJooyung Han "jnz outerLoop1%= \n\t" 305*5f39d1b3SJooyung Han 306*5f39d1b3SJooyung Han "finish%=:\n\t" 307*5f39d1b3SJooyung Han 308*5f39d1b3SJooyung Han "test %[start_depth], %[start_depth] \n\t" 309*5f39d1b3SJooyung Han "jz storeDst%= \n\t" 310*5f39d1b3SJooyung Han 311*5f39d1b3SJooyung Han "vpaddd 0x00(%[dst_ptr]), %%ymm4, %%ymm4 \n\t" // rhs0 312*5f39d1b3SJooyung Han "vpaddd 0x20(%[dst_ptr]), %%ymm8, %%ymm8 \n\t" // rhs0 313*5f39d1b3SJooyung Han "vpaddd 0x40(%[dst_ptr]), %%ymm12, %%ymm12 \n\t" // rhs0 314*5f39d1b3SJooyung Han 315*5f39d1b3SJooyung Han "vpaddd 0x00(%[dst_ptr], %%r12, 1) , %%ymm5, %%ymm5 \n\t" // rhs1 316*5f39d1b3SJooyung Han "vpaddd 0x20(%[dst_ptr], %%r12, 1) , %%ymm9, %%ymm9 \n\t" // rhs1 317*5f39d1b3SJooyung Han "vpaddd 0x40(%[dst_ptr], %%r12, 1) , %%ymm13, %%ymm13 \n\t" // rhs1 318*5f39d1b3SJooyung Han 319*5f39d1b3SJooyung Han "vpaddd 0x00(%[dst_ptr], %%r12, 2) , %%ymm6, %%ymm6 \n\t" // rhs2 320*5f39d1b3SJooyung Han "vpaddd 0x20(%[dst_ptr], %%r12, 2) , %%ymm10, %%ymm10 \n\t" // rhs2 321*5f39d1b3SJooyung Han "vpaddd 0x40(%[dst_ptr], %%r12, 2) , %%ymm14, %%ymm14 \n\t" // rhs2 322*5f39d1b3SJooyung Han 323*5f39d1b3SJooyung Han "vpaddd 0x00(%[dst_ptr], %%r13, 1) , %%ymm7, %%ymm7 \n\t" // rhs3 324*5f39d1b3SJooyung Han "vpaddd 0x20(%[dst_ptr], %%r13, 1) , %%ymm11, %%ymm11 \n\t" // rhs3 325*5f39d1b3SJooyung Han "vpaddd 0x40(%[dst_ptr], %%r13, 1) , %%ymm15, %%ymm15 \n\t" // rhs3 326*5f39d1b3SJooyung Han 327*5f39d1b3SJooyung Han "storeDst%=:\n\t" 328*5f39d1b3SJooyung Han 329*5f39d1b3SJooyung Han "vmovdqu %%ymm4, 0x00(%[dst_ptr]) \n\t" // rhs0 330*5f39d1b3SJooyung Han "vmovdqu %%ymm8, 0x20(%[dst_ptr]) \n\t" // rhs0 331*5f39d1b3SJooyung Han "vmovdqu %%ymm12, 0x40(%[dst_ptr]) \n\t" // rhs0 332*5f39d1b3SJooyung Han 333*5f39d1b3SJooyung Han "vmovdqu %%ymm5, 0x00(%[dst_ptr], %%r12, 1) \n\t" // rhs1 334*5f39d1b3SJooyung Han "vmovdqu %%ymm9, 0x20(%[dst_ptr], %%r12, 1) \n\t" // rhs1 335*5f39d1b3SJooyung Han "vmovdqu %%ymm13, 0x40(%[dst_ptr], %%r12, 1) \n\t" // rhs1 336*5f39d1b3SJooyung Han 337*5f39d1b3SJooyung Han "vmovdqu %%ymm6, 0x00(%[dst_ptr], %%r12, 2) \n\t" // rhs2 338*5f39d1b3SJooyung Han "vmovdqu %%ymm10, 0x20(%[dst_ptr], %%r12, 2) \n\t" // rhs2 339*5f39d1b3SJooyung Han "vmovdqu %%ymm14, 0x40(%[dst_ptr], %%r12, 2) \n\t" // rhs2 340*5f39d1b3SJooyung Han 341*5f39d1b3SJooyung Han "vmovdqu %%ymm7, 0x00(%[dst_ptr], %%r13, 1) \n\t" // rhs3 342*5f39d1b3SJooyung Han "vmovdqu %%ymm11, 0x20(%[dst_ptr], %%r13, 1) \n\t" // rhs3 343*5f39d1b3SJooyung Han "vmovdqu %%ymm15, 0x40(%[dst_ptr], %%r13, 1) \n\t" // rhs3 344*5f39d1b3SJooyung Han 345*5f39d1b3SJooyung Han : // outputs 346*5f39d1b3SJooyung Han [lhs_ptr] "+r"(lhs_ptr), [rhs_ptr] "+r"(rhs_ptr), 347*5f39d1b3SJooyung Han [dst_ptr] "+r"(dst_ptr) 348*5f39d1b3SJooyung Han : // inputs 349*5f39d1b3SJooyung Han [start_depth] "r"(start_depth), [dst_col_stride_q] "r"(dst_col_stride_q), 350*5f39d1b3SJooyung Han [run_depth_cells] "r"(run_depth_cells) 351*5f39d1b3SJooyung Han : // clobbers 352*5f39d1b3SJooyung Han "cc", "memory", "%ymm0", "%ymm1", "%ymm2", "%ymm3", "%ymm4", "%ymm5", "%ymm6", "%ymm7", 353*5f39d1b3SJooyung Han "%ymm8", "%ymm9", "%ymm10", "%ymm11", "%ymm12", "%ymm13", "%ymm14", "%ymm15", "%r12", 354*5f39d1b3SJooyung Han "%r13", "%r14"); 355*5f39d1b3SJooyung Han } 356*5f39d1b3SJooyung Han }; 357*5f39d1b3SJooyung Han #endif 358*5f39d1b3SJooyung Han 359*5f39d1b3SJooyung Han } // namespace gemmlowp 360*5f39d1b3SJooyung Han 361*5f39d1b3SJooyung Han #endif // GEMMLOWP_INTERNAL_KERNEL_AVX_H_ 362