1*5f39d1b3SJooyung Han // Copyright 2015 The Gemmlowp Authors. All Rights Reserved. 2*5f39d1b3SJooyung Han // 3*5f39d1b3SJooyung Han // Licensed under the Apache License, Version 2.0 (the "License"); 4*5f39d1b3SJooyung Han // you may not use this file except in compliance with the License. 5*5f39d1b3SJooyung Han // You may obtain a copy of the License at 6*5f39d1b3SJooyung Han // 7*5f39d1b3SJooyung Han // http://www.apache.org/licenses/LICENSE-2.0 8*5f39d1b3SJooyung Han // 9*5f39d1b3SJooyung Han // Unless required by applicable law or agreed to in writing, software 10*5f39d1b3SJooyung Han // distributed under the License is distributed on an "AS IS" BASIS, 11*5f39d1b3SJooyung Han // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*5f39d1b3SJooyung Han // See the License for the specific language governing permissions and 13*5f39d1b3SJooyung Han // limitations under the License. 14*5f39d1b3SJooyung Han 15*5f39d1b3SJooyung Han // kernel_SSE.h: a collection of Intel SSE optimized kernels. 16*5f39d1b3SJooyung Han // Check in kernel_default.h which one(s) are actually used by default. 17*5f39d1b3SJooyung Han // Others are mere experiments; they are still covered by tests 18*5f39d1b3SJooyung Han // in case they might be useful some day. 19*5f39d1b3SJooyung Han // 20*5f39d1b3SJooyung Han 21*5f39d1b3SJooyung Han #ifndef GEMMLOWP_INTERNAL_KERNEL_SSE_H_ 22*5f39d1b3SJooyung Han #define GEMMLOWP_INTERNAL_KERNEL_SSE_H_ 23*5f39d1b3SJooyung Han 24*5f39d1b3SJooyung Han #include "kernel.h" 25*5f39d1b3SJooyung Han 26*5f39d1b3SJooyung Han #include <string.h> 27*5f39d1b3SJooyung Han #include <cassert> 28*5f39d1b3SJooyung Han 29*5f39d1b3SJooyung Han namespace gemmlowp { 30*5f39d1b3SJooyung Han 31*5f39d1b3SJooyung Han #ifdef GEMMLOWP_SSE4_32 32*5f39d1b3SJooyung Han struct SSE4_32_Kernel4x4Depth2 : KernelBase { 33*5f39d1b3SJooyung Han typedef KernelFormat< 34*5f39d1b3SJooyung Han KernelSideFormat<CellFormat<4, 2, CellOrder::WidthMajor>, 1>, 35*5f39d1b3SJooyung Han KernelSideFormat<CellFormat<4, 2, CellOrder::WidthMajor>, 1> > 36*5f39d1b3SJooyung Han Format; 37*5f39d1b3SJooyung Han NameSSE4_32_Kernel4x4Depth238*5f39d1b3SJooyung Han const char* Name() const override { return "SSE, 4x4, depth 2"; } 39*5f39d1b3SJooyung Han RunSSE4_32_Kernel4x4Depth240*5f39d1b3SJooyung Han void Run(std::int32_t* dst_ptr, std::size_t dst_row_stride, 41*5f39d1b3SJooyung Han std::size_t dst_col_stride, const std::uint8_t* lhs_ptr, 42*5f39d1b3SJooyung Han const std::uint8_t* rhs_ptr, std::size_t start_depth, 43*5f39d1b3SJooyung Han std::size_t run_depth) const override { 44*5f39d1b3SJooyung Han ScopedProfilingLabel label("optimized kernel"); 45*5f39d1b3SJooyung Han assert(dst_row_stride == 1); 46*5f39d1b3SJooyung Han (void)dst_row_stride; 47*5f39d1b3SJooyung Han std::int32_t run_depth_cells = run_depth / Format::kDepth; 48*5f39d1b3SJooyung Han /* Main loop */ 49*5f39d1b3SJooyung Han 50*5f39d1b3SJooyung Han // A 2x4 cell of Rhs is stored in 16bit in xmm1 . 51*5f39d1b3SJooyung Han // A 4x2 block Lhs is stored in 16bit in xmm0. 52*5f39d1b3SJooyung Han // A 4x4 block of accumulators is stored in 32bit in xmm4--xmm7. 53*5f39d1b3SJooyung Han // 54*5f39d1b3SJooyung Han // +-------+-------+-------+-------+ 55*5f39d1b3SJooyung Han // |xmm1[0]|xmm1[2]|xmm1[4]|xmm1[6]| 56*5f39d1b3SJooyung Han // Rhs +-------+---------------+-------+ 57*5f39d1b3SJooyung Han // |xmm1[1]|xmm1[3]|xmm1[5]|xmm1[7]| 58*5f39d1b3SJooyung Han // +-------+-------+-------+-------+ 59*5f39d1b3SJooyung Han // 60*5f39d1b3SJooyung Han // | | | | | 61*5f39d1b3SJooyung Han // 62*5f39d1b3SJooyung Han // Lhs | | | | | 63*5f39d1b3SJooyung Han // 64*5f39d1b3SJooyung Han // +--+--+ - - - - +-------+-------+-------+-------+ 65*5f39d1b3SJooyung Han // |xmm0 | | xmm4 | xmm5 | xmm6 | xmm7 | 66*5f39d1b3SJooyung Han // |xmm0 | (Iter1) | xmm4 | xmm5 | xmm6 | xmm7 | 67*5f39d1b3SJooyung Han // |xmm0 | | xmm4 | xmm5 | xmm6 | xmm7 | 68*5f39d1b3SJooyung Han // |xmm0 | | xmm4 | xmm5 | xmm6 | xmm7 | 69*5f39d1b3SJooyung Han // +--+--+ - - - - +-------+-------+-------+-------+ 70*5f39d1b3SJooyung Han // 71*5f39d1b3SJooyung Han // Accumulator 72*5f39d1b3SJooyung Han 73*5f39d1b3SJooyung Han asm volatile( 74*5f39d1b3SJooyung Han 75*5f39d1b3SJooyung Han // set accumulators to zero. 76*5f39d1b3SJooyung Han "pxor %%xmm4 , %%xmm4 \n\t" 77*5f39d1b3SJooyung Han "pxor %%xmm5 , %%xmm5 \n\t" 78*5f39d1b3SJooyung Han "pxor %%xmm6 , %%xmm6 \n\t" 79*5f39d1b3SJooyung Han "pxor %%xmm7 , %%xmm7 \n\t" 80*5f39d1b3SJooyung Han 81*5f39d1b3SJooyung Han "movl %[run_depth_cells], %%eax\n\t" 82*5f39d1b3SJooyung Han "subl $2, %%eax\n\t" 83*5f39d1b3SJooyung Han "js outerLoop1%=\n\t" 84*5f39d1b3SJooyung Han 85*5f39d1b3SJooyung Han // Loop for K unrolled by 4 86*5f39d1b3SJooyung Han "outerLoop2%=:\n\t" 87*5f39d1b3SJooyung Han 88*5f39d1b3SJooyung Han // K = 1,2 89*5f39d1b3SJooyung Han // RHS cell to xmm1 90*5f39d1b3SJooyung Han "pmovzxbw (%[rhs_ptr]), %%xmm1\n\t" 91*5f39d1b3SJooyung Han 92*5f39d1b3SJooyung Han // LHS cell 93*5f39d1b3SJooyung Han "pmovzxbw 0x00(%[lhs_ptr]), %%xmm0\n\t" 94*5f39d1b3SJooyung Han "pshufd $0x00,%%xmm1,%%xmm2 \n\t" 95*5f39d1b3SJooyung Han "pshufd $0x55,%%xmm1,%%xmm3 \n\t" 96*5f39d1b3SJooyung Han "pmaddwd %%xmm0, %%xmm2 \n\t" 97*5f39d1b3SJooyung Han "pmaddwd %%xmm0, %%xmm3 \n\t" 98*5f39d1b3SJooyung Han "paddd %%xmm2, %%xmm4 \n\t" 99*5f39d1b3SJooyung Han "paddd %%xmm3, %%xmm5 \n\t" 100*5f39d1b3SJooyung Han 101*5f39d1b3SJooyung Han "prefetcht0 0x80(%[lhs_ptr]) \n\t" 102*5f39d1b3SJooyung Han 103*5f39d1b3SJooyung Han "pshufd $0xaa,%%xmm1,%%xmm2 \n\t" 104*5f39d1b3SJooyung Han "pmaddwd %%xmm0, %%xmm2 \n\t" 105*5f39d1b3SJooyung Han "pshufd $0xff,%%xmm1,%%xmm3 \n\t" 106*5f39d1b3SJooyung Han "pmaddwd %%xmm0, %%xmm3 \n\t" 107*5f39d1b3SJooyung Han 108*5f39d1b3SJooyung Han "prefetcht0 0x80(%[rhs_ptr]) \n\t" 109*5f39d1b3SJooyung Han 110*5f39d1b3SJooyung Han // K = 3,4 111*5f39d1b3SJooyung Han // RHS cell to xmm1 112*5f39d1b3SJooyung Han "pmovzxbw 0x08(%[rhs_ptr]), %%xmm1\n\t" 113*5f39d1b3SJooyung Han 114*5f39d1b3SJooyung Han "paddd %%xmm2, %%xmm6 \n\t" 115*5f39d1b3SJooyung Han "paddd %%xmm3, %%xmm7 \n\t" 116*5f39d1b3SJooyung Han 117*5f39d1b3SJooyung Han // LHS cell 118*5f39d1b3SJooyung Han "pmovzxbw 0x08(%[lhs_ptr]), %%xmm0\n\t" 119*5f39d1b3SJooyung Han "pshufd $0x00,%%xmm1,%%xmm2 \n\t" 120*5f39d1b3SJooyung Han "pshufd $0x55,%%xmm1,%%xmm3 \n\t" 121*5f39d1b3SJooyung Han "pmaddwd %%xmm0, %%xmm2 \n\t" 122*5f39d1b3SJooyung Han "pmaddwd %%xmm0, %%xmm3 \n\t" 123*5f39d1b3SJooyung Han "paddd %%xmm2, %%xmm4 \n\t" 124*5f39d1b3SJooyung Han "paddd %%xmm3, %%xmm5 \n\t" 125*5f39d1b3SJooyung Han "pshufd $0xaa,%%xmm1,%%xmm2 \n\t" 126*5f39d1b3SJooyung Han "pshufd $0xff,%%xmm1,%%xmm3 \n\t" 127*5f39d1b3SJooyung Han 128*5f39d1b3SJooyung Han "addl $0x10, %[lhs_ptr] \n\t" 129*5f39d1b3SJooyung Han "addl $0x10, %[rhs_ptr] \n\t" 130*5f39d1b3SJooyung Han 131*5f39d1b3SJooyung Han "pmaddwd %%xmm0, %%xmm3 \n\t" 132*5f39d1b3SJooyung Han "paddd %%xmm3, %%xmm7 \n\t" 133*5f39d1b3SJooyung Han "pmaddwd %%xmm0, %%xmm2 \n\t" 134*5f39d1b3SJooyung Han "paddd %%xmm2, %%xmm6 \n\t" 135*5f39d1b3SJooyung Han 136*5f39d1b3SJooyung Han "subl $2, %[run_depth_cells]\n\t" 137*5f39d1b3SJooyung Han "ja outerLoop2%=\n\t" 138*5f39d1b3SJooyung Han 139*5f39d1b3SJooyung Han "movl %[run_depth_cells], %%eax\n\t" 140*5f39d1b3SJooyung Han "decl %%eax\n\t" 141*5f39d1b3SJooyung Han "js finish%=\n\t" 142*5f39d1b3SJooyung Han 143*5f39d1b3SJooyung Han // Loop for K unrolled by 2 144*5f39d1b3SJooyung Han "outerLoop1%=:\n\t" 145*5f39d1b3SJooyung Han 146*5f39d1b3SJooyung Han // RHS cell to xmm1 147*5f39d1b3SJooyung Han "pmovzxbw (%[rhs_ptr]), %%xmm1\n\t" 148*5f39d1b3SJooyung Han 149*5f39d1b3SJooyung Han // LHS cell 150*5f39d1b3SJooyung Han "pmovzxbw 0x00(%[lhs_ptr]), %%xmm0\n\t" 151*5f39d1b3SJooyung Han "pshufd $0x00,%%xmm1,%%xmm2 \n\t" 152*5f39d1b3SJooyung Han "pmaddwd %%xmm0, %%xmm2 \n\t" 153*5f39d1b3SJooyung Han "paddd %%xmm2, %%xmm4 \n\t" 154*5f39d1b3SJooyung Han "pshufd $0x55,%%xmm1,%%xmm3 \n\t" 155*5f39d1b3SJooyung Han "pmaddwd %%xmm0, %%xmm3 \n\t" 156*5f39d1b3SJooyung Han "paddd %%xmm3, %%xmm5 \n\t" 157*5f39d1b3SJooyung Han 158*5f39d1b3SJooyung Han "pshufd $0xaa,%%xmm1,%%xmm2 \n\t" 159*5f39d1b3SJooyung Han "pmaddwd %%xmm0, %%xmm2 \n\t" 160*5f39d1b3SJooyung Han "paddd %%xmm2, %%xmm6 \n\t" 161*5f39d1b3SJooyung Han "pshufd $0xff,%%xmm1,%%xmm3 \n\t" 162*5f39d1b3SJooyung Han "pmaddwd %%xmm0, %%xmm3 \n\t" 163*5f39d1b3SJooyung Han "paddd %%xmm3, %%xmm7 \n\t" 164*5f39d1b3SJooyung Han 165*5f39d1b3SJooyung Han "addl $0x08, %[lhs_ptr]\n\t" 166*5f39d1b3SJooyung Han "addl $0x08, %[rhs_ptr]\n\t" 167*5f39d1b3SJooyung Han 168*5f39d1b3SJooyung Han "decl %[run_depth_cells]\n\t" 169*5f39d1b3SJooyung Han "jnz outerLoop1%=\n\t" 170*5f39d1b3SJooyung Han 171*5f39d1b3SJooyung Han "finish%=:\n\t" 172*5f39d1b3SJooyung Han 173*5f39d1b3SJooyung Han "movl %[dst_col_stride], %%eax\n\t" 174*5f39d1b3SJooyung Han "shll $2, %%eax\n\t" 175*5f39d1b3SJooyung Han 176*5f39d1b3SJooyung Han "movl %[start_depth], %%ecx\n\t" 177*5f39d1b3SJooyung Han "test %%ecx, %%ecx\n\t" 178*5f39d1b3SJooyung Han "jz storeDst%=\n\t" 179*5f39d1b3SJooyung Han 180*5f39d1b3SJooyung Han "leal (%%eax,%%eax,0x2), %%ecx\n\t" 181*5f39d1b3SJooyung Han "paddd 0x00(%[dst_ptr]) , %%xmm4 \n\t" 182*5f39d1b3SJooyung Han "paddd 0x00(%[dst_ptr], %%eax, 1) , %%xmm5 \n\t" 183*5f39d1b3SJooyung Han "paddd 0x00(%[dst_ptr], %%eax, 2) , %%xmm6 \n\t" 184*5f39d1b3SJooyung Han "paddd 0x00(%[dst_ptr], %%ecx, 1) , %%xmm7 \n\t" 185*5f39d1b3SJooyung Han 186*5f39d1b3SJooyung Han "storeDst%=:\n\t" 187*5f39d1b3SJooyung Han 188*5f39d1b3SJooyung Han "leal (%%eax,%%eax,0x2), %%ecx\n\t" 189*5f39d1b3SJooyung Han "movdqu %%xmm4 , 0x00(%[dst_ptr]) \n\t" 190*5f39d1b3SJooyung Han "movdqu %%xmm5 , 0x00(%[dst_ptr], %%eax, 1)\n\t" 191*5f39d1b3SJooyung Han "movdqu %%xmm6 , 0x00(%[dst_ptr], %%eax, 2)\n\t" 192*5f39d1b3SJooyung Han "movdqu %%xmm7 , 0x00(%[dst_ptr], %%ecx, 1)\n\t" 193*5f39d1b3SJooyung Han 194*5f39d1b3SJooyung Han : // outputs 195*5f39d1b3SJooyung Han [lhs_ptr] "+r"(lhs_ptr), [rhs_ptr] "+r"(rhs_ptr), 196*5f39d1b3SJooyung Han [dst_ptr] "+r"(dst_ptr) 197*5f39d1b3SJooyung Han : // inputs 198*5f39d1b3SJooyung Han [start_depth] "g"(start_depth), [dst_col_stride] "g"(dst_col_stride), 199*5f39d1b3SJooyung Han [run_depth_cells] "g"(run_depth_cells) 200*5f39d1b3SJooyung Han : // clobbers 201*5f39d1b3SJooyung Han "cc", "memory", "%xmm0", "%xmm1", "%xmm3", "%xmm2", "%xmm4", "%xmm5", 202*5f39d1b3SJooyung Han "%xmm6", "%xmm7", "%eax", "%ecx"); 203*5f39d1b3SJooyung Han } 204*5f39d1b3SJooyung Han }; 205*5f39d1b3SJooyung Han #endif 206*5f39d1b3SJooyung Han #ifdef GEMMLOWP_SSE4_64 207*5f39d1b3SJooyung Han struct SSE4_64_Kernel12x4Depth2 : KernelBase { 208*5f39d1b3SJooyung Han typedef KernelFormat< 209*5f39d1b3SJooyung Han KernelSideFormat<CellFormat<4, 2, CellOrder::WidthMajor>, 3>, 210*5f39d1b3SJooyung Han KernelSideFormat<CellFormat<4, 2, CellOrder::WidthMajor>, 1> > 211*5f39d1b3SJooyung Han Format; 212*5f39d1b3SJooyung Han NameSSE4_64_Kernel12x4Depth2213*5f39d1b3SJooyung Han const char* Name() const override { return "SSE, 12x4, depth 2"; } 214*5f39d1b3SJooyung Han RunSSE4_64_Kernel12x4Depth2215*5f39d1b3SJooyung Han void Run(std::int32_t* dst_ptr, std::size_t dst_row_stride, 216*5f39d1b3SJooyung Han std::size_t dst_col_stride, const std::uint8_t* lhs_ptr, 217*5f39d1b3SJooyung Han const std::uint8_t* rhs_ptr, std::size_t start_depth, 218*5f39d1b3SJooyung Han std::size_t run_depth) const override { 219*5f39d1b3SJooyung Han ScopedProfilingLabel label("optimized kernel"); 220*5f39d1b3SJooyung Han assert(dst_row_stride == 1); 221*5f39d1b3SJooyung Han (void)dst_row_stride; 222*5f39d1b3SJooyung Han const std::int64_t run_depth_cells = run_depth / Format::kDepth; 223*5f39d1b3SJooyung Han const std::int64_t dst_col_stride_q = dst_col_stride; 224*5f39d1b3SJooyung Han 225*5f39d1b3SJooyung Han /* Main loop */ 226*5f39d1b3SJooyung Han 227*5f39d1b3SJooyung Han // A 2x4 cell of Rhs is stored in 16bit in xmm1 . 228*5f39d1b3SJooyung Han // A 12x2 block of 3 4x2 cells Lhs is stored in 16bit in xmm0, replaced 229*5f39d1b3SJooyung Han // every Iteration. 230*5f39d1b3SJooyung Han // A 12x4 block of accumulators is stored in 32bit in xmm4--xmm15. 231*5f39d1b3SJooyung Han // 232*5f39d1b3SJooyung Han // +-------+-------+-------+-------+ 233*5f39d1b3SJooyung Han // |xmm1[0]|xmm1[2]|xmm1[4]|xmm1[6]| 234*5f39d1b3SJooyung Han // Rhs +-------+---------------+-------+ 235*5f39d1b3SJooyung Han // |xmm1[1]|xmm1[3]|xmm1[5]|xmm1[7]| 236*5f39d1b3SJooyung Han // +-------+-------+-------+-------+ 237*5f39d1b3SJooyung Han // 238*5f39d1b3SJooyung Han // | | | | | 239*5f39d1b3SJooyung Han // 240*5f39d1b3SJooyung Han // Lhs | | | | | 241*5f39d1b3SJooyung Han // 242*5f39d1b3SJooyung Han // +--+--+ - - - - +-------+-------+-------+-------+ 243*5f39d1b3SJooyung Han // |xmm0 | | xmm4 | xmm5 | xmm6 | xmm7 | 244*5f39d1b3SJooyung Han // |xmm0 | (Iter1) | xmm4 | xmm5 | xmm6 | xmm7 | 245*5f39d1b3SJooyung Han // |xmm0 | | xmm4 | xmm5 | xmm6 | xmm7 | 246*5f39d1b3SJooyung Han // |xmm0 | | xmm4 | xmm5 | xmm6 | xmm7 | 247*5f39d1b3SJooyung Han // +--+--+ - - - - +-------+-------+-------+-------+ 248*5f39d1b3SJooyung Han // |xmm0 | | xmm8 | xmm9 | xmm10 | xmm11 | 249*5f39d1b3SJooyung Han // |xmm0 | (Iter2) | xmm8 | xmm9 | xmm10 | xmm11 | 250*5f39d1b3SJooyung Han // |xmm0 | | xmm8 | xmm9 | xmm10 | xmm11 | 251*5f39d1b3SJooyung Han // |xmm0 | | xmm8 | xmm9 | xmm10 | xmm11 | 252*5f39d1b3SJooyung Han // +--+--+ - - - - +-------+-------+-------+-------+ 253*5f39d1b3SJooyung Han // |xmm0 | | xmm12 | xmm13 | xmm14 | xmm15 | 254*5f39d1b3SJooyung Han // |xmm0 | (Iter3) | xmm12 | xmm13 | xmm14 | xmm15 | 255*5f39d1b3SJooyung Han // |xmm0 | | xmm12 | xmm13 | xmm14 | xmm15 | 256*5f39d1b3SJooyung Han // |xmm0 | | xmm12 | xmm13 | xmm14 | xmm15 | 257*5f39d1b3SJooyung Han // +--+--+ - - - - +-------+-------+-------+-------+ 258*5f39d1b3SJooyung Han // 259*5f39d1b3SJooyung Han // Accumulator 260*5f39d1b3SJooyung Han 261*5f39d1b3SJooyung Han asm volatile( 262*5f39d1b3SJooyung Han 263*5f39d1b3SJooyung Han // Set registers for destination 264*5f39d1b3SJooyung Han "movq %[dst_col_stride_q], %%r12\n\t" 265*5f39d1b3SJooyung Han "shlq $2, %%r12\n\t" 266*5f39d1b3SJooyung Han "leaq (%%r12,%%r12,0x2), %%r13\n\t" 267*5f39d1b3SJooyung Han 268*5f39d1b3SJooyung Han // Set accumulators to zero. 269*5f39d1b3SJooyung Han "pxor %%xmm4 , %%xmm4 \n\t" 270*5f39d1b3SJooyung Han "pxor %%xmm5 , %%xmm5 \n\t" 271*5f39d1b3SJooyung Han "pxor %%xmm6 , %%xmm6 \n\t" 272*5f39d1b3SJooyung Han "pxor %%xmm7 , %%xmm7 \n\t" 273*5f39d1b3SJooyung Han "pxor %%xmm8 , %%xmm8 \n\t" 274*5f39d1b3SJooyung Han "pxor %%xmm9 , %%xmm9 \n\t" 275*5f39d1b3SJooyung Han "pxor %%xmm10 , %%xmm10\n\t" 276*5f39d1b3SJooyung Han "pxor %%xmm11 , %%xmm11\n\t" 277*5f39d1b3SJooyung Han "pxor %%xmm12 , %%xmm12\n\t" 278*5f39d1b3SJooyung Han "pxor %%xmm13 , %%xmm13\n\t" 279*5f39d1b3SJooyung Han "pxor %%xmm14 , %%xmm14\n\t" 280*5f39d1b3SJooyung Han "pxor %%xmm15 , %%xmm15\n\t" 281*5f39d1b3SJooyung Han 282*5f39d1b3SJooyung Han "movq %[run_depth_cells], %%r14\n\t" 283*5f39d1b3SJooyung Han "subq $2, %%r14\n\t" 284*5f39d1b3SJooyung Han "js outerLoop1%=\n\t" 285*5f39d1b3SJooyung Han 286*5f39d1b3SJooyung Han // Loop for K unrolled by 4 287*5f39d1b3SJooyung Han "outerLoop2%=:\n\t" 288*5f39d1b3SJooyung Han 289*5f39d1b3SJooyung Han // K = 1,2 290*5f39d1b3SJooyung Han // RHS cell to xmm1 291*5f39d1b3SJooyung Han 292*5f39d1b3SJooyung Han "pmovzxbw (%[rhs_ptr]), %%xmm1\n\t" 293*5f39d1b3SJooyung Han 294*5f39d1b3SJooyung Han // LHS cell 295*5f39d1b3SJooyung Han "pmovzxbw 0x00(%[lhs_ptr]), %%xmm0\n\t" 296*5f39d1b3SJooyung Han "pshufd $0x00,%%xmm1,%%xmm2 \n\t" 297*5f39d1b3SJooyung Han "pshufd $0x55,%%xmm1,%%xmm3 \n\t" 298*5f39d1b3SJooyung Han "pmaddwd %%xmm0, %%xmm2 \n\t" 299*5f39d1b3SJooyung Han "pmaddwd %%xmm0, %%xmm3 \n\t" 300*5f39d1b3SJooyung Han "paddd %%xmm2, %%xmm4 \n\t" 301*5f39d1b3SJooyung Han "paddd %%xmm3, %%xmm5 \n\t" 302*5f39d1b3SJooyung Han 303*5f39d1b3SJooyung Han "prefetcht0 0x80(%[lhs_ptr]) \n\t" 304*5f39d1b3SJooyung Han 305*5f39d1b3SJooyung Han "pshufd $0xaa,%%xmm1,%%xmm2 \n\t" 306*5f39d1b3SJooyung Han "pmaddwd %%xmm0, %%xmm2 \n\t" 307*5f39d1b3SJooyung Han "pshufd $0xff,%%xmm1,%%xmm3 \n\t" 308*5f39d1b3SJooyung Han "pmaddwd %%xmm0, %%xmm3 \n\t" 309*5f39d1b3SJooyung Han 310*5f39d1b3SJooyung Han // next LHS cell 311*5f39d1b3SJooyung Han "pmovzxbw 0x08(%[lhs_ptr]), %%xmm0\n\t" 312*5f39d1b3SJooyung Han 313*5f39d1b3SJooyung Han "paddd %%xmm2, %%xmm6 \n\t" 314*5f39d1b3SJooyung Han "paddd %%xmm3, %%xmm7 \n\t" 315*5f39d1b3SJooyung Han 316*5f39d1b3SJooyung Han "pshufd $0x00,%%xmm1,%%xmm2 \n\t" 317*5f39d1b3SJooyung Han "pshufd $0x55,%%xmm1,%%xmm3 \n\t" 318*5f39d1b3SJooyung Han "pmaddwd %%xmm0, %%xmm2 \n\t" 319*5f39d1b3SJooyung Han "pmaddwd %%xmm0, %%xmm3 \n\t" 320*5f39d1b3SJooyung Han "paddd %%xmm2, %%xmm8 \n\t" 321*5f39d1b3SJooyung Han "paddd %%xmm3, %%xmm9 \n\t" 322*5f39d1b3SJooyung Han 323*5f39d1b3SJooyung Han "prefetcht0 0x80(%[rhs_ptr]) \n\t" 324*5f39d1b3SJooyung Han 325*5f39d1b3SJooyung Han "pshufd $0xaa,%%xmm1,%%xmm2 \n\t" 326*5f39d1b3SJooyung Han "pshufd $0xff,%%xmm1,%%xmm3 \n\t" 327*5f39d1b3SJooyung Han "pmaddwd %%xmm0, %%xmm2 \n\t" 328*5f39d1b3SJooyung Han "pmaddwd %%xmm0, %%xmm3 \n\t" 329*5f39d1b3SJooyung Han "paddd %%xmm2, %%xmm10 \n\t" 330*5f39d1b3SJooyung Han "paddd %%xmm3, %%xmm11 \n\t" 331*5f39d1b3SJooyung Han 332*5f39d1b3SJooyung Han // next LHS cell 333*5f39d1b3SJooyung Han "pmovzxbw 0x10(%[lhs_ptr]), %%xmm0\n\t" 334*5f39d1b3SJooyung Han "pshufd $0x00,%%xmm1,%%xmm2 \n\t" 335*5f39d1b3SJooyung Han "pshufd $0x55,%%xmm1,%%xmm3 \n\t" 336*5f39d1b3SJooyung Han "pmaddwd %%xmm0, %%xmm2 \n\t" 337*5f39d1b3SJooyung Han "pmaddwd %%xmm0, %%xmm3 \n\t" 338*5f39d1b3SJooyung Han "paddd %%xmm2, %%xmm12 \n\t" 339*5f39d1b3SJooyung Han "paddd %%xmm3, %%xmm13 \n\t" 340*5f39d1b3SJooyung Han 341*5f39d1b3SJooyung Han "pshufd $0xaa,%%xmm1,%%xmm2 \n\t" 342*5f39d1b3SJooyung Han "pshufd $0xff,%%xmm1,%%xmm3 \n\t" 343*5f39d1b3SJooyung Han "pmaddwd %%xmm0, %%xmm2 \n\t" 344*5f39d1b3SJooyung Han "pmaddwd %%xmm0, %%xmm3 \n\t" 345*5f39d1b3SJooyung Han "paddd %%xmm2, %%xmm14 \n\t" 346*5f39d1b3SJooyung Han "paddd %%xmm3, %%xmm15 \n\t" 347*5f39d1b3SJooyung Han 348*5f39d1b3SJooyung Han // K = 3,4 349*5f39d1b3SJooyung Han // RHS cell to xmm1 350*5f39d1b3SJooyung Han "pmovzxbw 0x08(%[rhs_ptr]), %%xmm1\n\t" 351*5f39d1b3SJooyung Han 352*5f39d1b3SJooyung Han // LHS cell 353*5f39d1b3SJooyung Han "pmovzxbw 0x18(%[lhs_ptr]), %%xmm0\n\t" 354*5f39d1b3SJooyung Han "pshufd $0x00,%%xmm1,%%xmm2 \n\t" 355*5f39d1b3SJooyung Han "pshufd $0x55,%%xmm1,%%xmm3 \n\t" 356*5f39d1b3SJooyung Han "pmaddwd %%xmm0, %%xmm2 \n\t" 357*5f39d1b3SJooyung Han "pmaddwd %%xmm0, %%xmm3 \n\t" 358*5f39d1b3SJooyung Han "paddd %%xmm2, %%xmm4 \n\t" 359*5f39d1b3SJooyung Han "paddd %%xmm3, %%xmm5 \n\t" 360*5f39d1b3SJooyung Han 361*5f39d1b3SJooyung Han "pshufd $0xaa,%%xmm1,%%xmm2 \n\t" 362*5f39d1b3SJooyung Han "pshufd $0xff,%%xmm1,%%xmm3 \n\t" 363*5f39d1b3SJooyung Han "pmaddwd %%xmm0, %%xmm2 \n\t" 364*5f39d1b3SJooyung Han "pmaddwd %%xmm0, %%xmm3 \n\t" 365*5f39d1b3SJooyung Han "paddd %%xmm2, %%xmm6 \n\t" 366*5f39d1b3SJooyung Han "paddd %%xmm3, %%xmm7 \n\t" 367*5f39d1b3SJooyung Han 368*5f39d1b3SJooyung Han // next LHS cell 369*5f39d1b3SJooyung Han "pmovzxbw 0x20(%[lhs_ptr]), %%xmm0\n\t" 370*5f39d1b3SJooyung Han "pshufd $0x00,%%xmm1,%%xmm2 \n\t" 371*5f39d1b3SJooyung Han "pshufd $0x55,%%xmm1,%%xmm3 \n\t" 372*5f39d1b3SJooyung Han "pmaddwd %%xmm0, %%xmm2 \n\t" 373*5f39d1b3SJooyung Han "pmaddwd %%xmm0, %%xmm3 \n\t" 374*5f39d1b3SJooyung Han "paddd %%xmm2, %%xmm8 \n\t" 375*5f39d1b3SJooyung Han "paddd %%xmm3, %%xmm9 \n\t" 376*5f39d1b3SJooyung Han 377*5f39d1b3SJooyung Han "pshufd $0xaa,%%xmm1,%%xmm2 \n\t" 378*5f39d1b3SJooyung Han "pshufd $0xff,%%xmm1,%%xmm3 \n\t" 379*5f39d1b3SJooyung Han "pmaddwd %%xmm0, %%xmm2 \n\t" 380*5f39d1b3SJooyung Han "pmaddwd %%xmm0, %%xmm3 \n\t" 381*5f39d1b3SJooyung Han "paddd %%xmm2, %%xmm10 \n\t" 382*5f39d1b3SJooyung Han "paddd %%xmm3, %%xmm11 \n\t" 383*5f39d1b3SJooyung Han 384*5f39d1b3SJooyung Han // next LHS cell 385*5f39d1b3SJooyung Han "pmovzxbw 0x28(%[lhs_ptr]), %%xmm0\n\t" 386*5f39d1b3SJooyung Han 387*5f39d1b3SJooyung Han "addq $0x30, %[lhs_ptr] \n\t" 388*5f39d1b3SJooyung Han "addq $0x10, %[rhs_ptr] \n\t" 389*5f39d1b3SJooyung Han 390*5f39d1b3SJooyung Han "pshufd $0x00,%%xmm1,%%xmm2 \n\t" 391*5f39d1b3SJooyung Han "pshufd $0x55,%%xmm1,%%xmm3 \n\t" 392*5f39d1b3SJooyung Han "pmaddwd %%xmm0, %%xmm2 \n\t" 393*5f39d1b3SJooyung Han "pmaddwd %%xmm0, %%xmm3 \n\t" 394*5f39d1b3SJooyung Han "paddd %%xmm2, %%xmm12 \n\t" 395*5f39d1b3SJooyung Han "paddd %%xmm3, %%xmm13 \n\t" 396*5f39d1b3SJooyung Han 397*5f39d1b3SJooyung Han "pshufd $0xaa,%%xmm1,%%xmm2 \n\t" 398*5f39d1b3SJooyung Han "pshufd $0xff,%%xmm1,%%xmm3 \n\t" 399*5f39d1b3SJooyung Han "pmaddwd %%xmm0, %%xmm2 \n\t" 400*5f39d1b3SJooyung Han "pmaddwd %%xmm0, %%xmm3 \n\t" 401*5f39d1b3SJooyung Han "paddd %%xmm2, %%xmm14 \n\t" 402*5f39d1b3SJooyung Han "paddd %%xmm3, %%xmm15 \n\t" 403*5f39d1b3SJooyung Han 404*5f39d1b3SJooyung Han "subq $2, %[run_depth_cells]\n\t" 405*5f39d1b3SJooyung Han "ja outerLoop2%=\n\t" 406*5f39d1b3SJooyung Han 407*5f39d1b3SJooyung Han "movq %[run_depth_cells], %%r14\n\t" 408*5f39d1b3SJooyung Han "decq %%r14\n\t" 409*5f39d1b3SJooyung Han "js finish%=\n\t" 410*5f39d1b3SJooyung Han 411*5f39d1b3SJooyung Han // Loop for K unrolled by 2 412*5f39d1b3SJooyung Han "outerLoop1%=:\n\t" 413*5f39d1b3SJooyung Han 414*5f39d1b3SJooyung Han // RHS cell to xmm1 415*5f39d1b3SJooyung Han "pmovzxbw (%[rhs_ptr]), %%xmm1\n\t" 416*5f39d1b3SJooyung Han 417*5f39d1b3SJooyung Han // LHS cell 418*5f39d1b3SJooyung Han "pmovzxbw 0x00(%[lhs_ptr]), %%xmm0\n\t" 419*5f39d1b3SJooyung Han "pshufd $0x00,%%xmm1,%%xmm2 \n\t" 420*5f39d1b3SJooyung Han "pshufd $0x55,%%xmm1,%%xmm3 \n\t" 421*5f39d1b3SJooyung Han "pmaddwd %%xmm0, %%xmm2 \n\t" 422*5f39d1b3SJooyung Han "pmaddwd %%xmm0, %%xmm3 \n\t" 423*5f39d1b3SJooyung Han "paddd %%xmm2, %%xmm4 \n\t" 424*5f39d1b3SJooyung Han "paddd %%xmm3, %%xmm5 \n\t" 425*5f39d1b3SJooyung Han "pshufd $0xaa,%%xmm1,%%xmm2 \n\t" 426*5f39d1b3SJooyung Han "pshufd $0xff,%%xmm1,%%xmm3 \n\t" 427*5f39d1b3SJooyung Han "pmaddwd %%xmm0, %%xmm2 \n\t" 428*5f39d1b3SJooyung Han "pmaddwd %%xmm0, %%xmm3 \n\t" 429*5f39d1b3SJooyung Han "paddd %%xmm2, %%xmm6 \n\t" 430*5f39d1b3SJooyung Han "paddd %%xmm3, %%xmm7 \n\t" 431*5f39d1b3SJooyung Han 432*5f39d1b3SJooyung Han // next LHS cell 433*5f39d1b3SJooyung Han "pmovzxbw 0x08(%[lhs_ptr]), %%xmm0\n\t" 434*5f39d1b3SJooyung Han "pshufd $0x00,%%xmm1,%%xmm2 \n\t" 435*5f39d1b3SJooyung Han "pshufd $0x55,%%xmm1,%%xmm3 \n\t" 436*5f39d1b3SJooyung Han "pmaddwd %%xmm0, %%xmm2 \n\t" 437*5f39d1b3SJooyung Han "pmaddwd %%xmm0, %%xmm3 \n\t" 438*5f39d1b3SJooyung Han "paddd %%xmm2, %%xmm8 \n\t" 439*5f39d1b3SJooyung Han "paddd %%xmm3, %%xmm9 \n\t" 440*5f39d1b3SJooyung Han "pshufd $0xaa,%%xmm1,%%xmm2 \n\t" 441*5f39d1b3SJooyung Han "pshufd $0xff,%%xmm1,%%xmm3 \n\t" 442*5f39d1b3SJooyung Han "pmaddwd %%xmm0, %%xmm2 \n\t" 443*5f39d1b3SJooyung Han "pmaddwd %%xmm0, %%xmm3 \n\t" 444*5f39d1b3SJooyung Han "paddd %%xmm2, %%xmm10 \n\t" 445*5f39d1b3SJooyung Han "paddd %%xmm3, %%xmm11 \n\t" 446*5f39d1b3SJooyung Han 447*5f39d1b3SJooyung Han // next LHS cell 448*5f39d1b3SJooyung Han "pmovzxbw 0x10(%[lhs_ptr]), %%xmm0\n\t" 449*5f39d1b3SJooyung Han 450*5f39d1b3SJooyung Han "addq $0x18, %[lhs_ptr] \n\t" 451*5f39d1b3SJooyung Han "addq $0x08, %[rhs_ptr] \n\t" 452*5f39d1b3SJooyung Han 453*5f39d1b3SJooyung Han "pshufd $0x00,%%xmm1,%%xmm2 \n\t" 454*5f39d1b3SJooyung Han "pshufd $0x55,%%xmm1,%%xmm3 \n\t" 455*5f39d1b3SJooyung Han "pmaddwd %%xmm0, %%xmm2 \n\t" 456*5f39d1b3SJooyung Han "pmaddwd %%xmm0, %%xmm3 \n\t" 457*5f39d1b3SJooyung Han "paddd %%xmm2, %%xmm12 \n\t" 458*5f39d1b3SJooyung Han "paddd %%xmm3, %%xmm13 \n\t" 459*5f39d1b3SJooyung Han "pshufd $0xaa,%%xmm1,%%xmm2 \n\t" 460*5f39d1b3SJooyung Han "pshufd $0xff,%%xmm1,%%xmm3 \n\t" 461*5f39d1b3SJooyung Han "pmaddwd %%xmm0, %%xmm2 \n\t" 462*5f39d1b3SJooyung Han "pmaddwd %%xmm0, %%xmm3 \n\t" 463*5f39d1b3SJooyung Han "paddd %%xmm2, %%xmm14 \n\t" 464*5f39d1b3SJooyung Han "paddd %%xmm3, %%xmm15 \n\t" 465*5f39d1b3SJooyung Han 466*5f39d1b3SJooyung Han "decq %[run_depth_cells]\n\t" 467*5f39d1b3SJooyung Han "jnz outerLoop1%=\n\t" 468*5f39d1b3SJooyung Han 469*5f39d1b3SJooyung Han "finish%=:\n\t" 470*5f39d1b3SJooyung Han 471*5f39d1b3SJooyung Han "test %[start_depth], %[start_depth]\n\t" 472*5f39d1b3SJooyung Han "jz storeDst%=\n\t" 473*5f39d1b3SJooyung Han 474*5f39d1b3SJooyung Han "paddd 0x00(%[dst_ptr]) , %%xmm4 \n\t" 475*5f39d1b3SJooyung Han "paddd 0x10(%[dst_ptr]) , %%xmm8 \n\t" 476*5f39d1b3SJooyung Han "paddd 0x20(%[dst_ptr]) , %%xmm12\n\t" 477*5f39d1b3SJooyung Han "paddd 0x00(%[dst_ptr], %%r12, 1) , %%xmm5 \n\t" 478*5f39d1b3SJooyung Han "paddd 0x10(%[dst_ptr], %%r12, 1) , %%xmm9 \n\t" 479*5f39d1b3SJooyung Han "paddd 0x20(%[dst_ptr], %%r12, 1) , %%xmm13\n\t" 480*5f39d1b3SJooyung Han "paddd 0x00(%[dst_ptr], %%r12, 2) , %%xmm6 \n\t" 481*5f39d1b3SJooyung Han "paddd 0x10(%[dst_ptr], %%r12, 2) , %%xmm10\n\t" 482*5f39d1b3SJooyung Han "paddd 0x20(%[dst_ptr], %%r12, 2) , %%xmm14\n\t" 483*5f39d1b3SJooyung Han "paddd 0x00(%[dst_ptr], %%r13, 1) , %%xmm7 \n\t" 484*5f39d1b3SJooyung Han "paddd 0x10(%[dst_ptr], %%r13, 1) , %%xmm11\n\t" 485*5f39d1b3SJooyung Han "paddd 0x20(%[dst_ptr], %%r13, 1) , %%xmm15\n\t" 486*5f39d1b3SJooyung Han 487*5f39d1b3SJooyung Han "storeDst%=:\n\t" 488*5f39d1b3SJooyung Han 489*5f39d1b3SJooyung Han "movdqu %%xmm4 , 0x00(%[dst_ptr]) \n\t" 490*5f39d1b3SJooyung Han "movdqu %%xmm8 , 0x10(%[dst_ptr]) \n\t" 491*5f39d1b3SJooyung Han "movdqu %%xmm12 , 0x20(%[dst_ptr]) \n\t" 492*5f39d1b3SJooyung Han "movdqu %%xmm5 , 0x00(%[dst_ptr], %%r12, 1)\n\t" 493*5f39d1b3SJooyung Han "movdqu %%xmm9 , 0x10(%[dst_ptr], %%r12, 1)\n\t" 494*5f39d1b3SJooyung Han "movdqu %%xmm13 , 0x20(%[dst_ptr], %%r12, 1)\n\t" 495*5f39d1b3SJooyung Han "movdqu %%xmm6 , 0x00(%[dst_ptr], %%r12, 2)\n\t" 496*5f39d1b3SJooyung Han "movdqu %%xmm10 , 0x10(%[dst_ptr], %%r12, 2)\n\t" 497*5f39d1b3SJooyung Han "movdqu %%xmm14 , 0x20(%[dst_ptr], %%r12, 2)\n\t" 498*5f39d1b3SJooyung Han "movdqu %%xmm7 , 0x00(%[dst_ptr], %%r13, 1)\n\t" 499*5f39d1b3SJooyung Han "movdqu %%xmm11 , 0x10(%[dst_ptr], %%r13, 1)\n\t" 500*5f39d1b3SJooyung Han "movdqu %%xmm15 , 0x20(%[dst_ptr], %%r13, 1)\n\t" 501*5f39d1b3SJooyung Han 502*5f39d1b3SJooyung Han : // outputs 503*5f39d1b3SJooyung Han [lhs_ptr] "+r"(lhs_ptr), [rhs_ptr] "+r"(rhs_ptr), 504*5f39d1b3SJooyung Han [dst_ptr] "+r"(dst_ptr) 505*5f39d1b3SJooyung Han : // inputs 506*5f39d1b3SJooyung Han [start_depth] "r"(start_depth), 507*5f39d1b3SJooyung Han [dst_col_stride_q] "r"(dst_col_stride_q), 508*5f39d1b3SJooyung Han [run_depth_cells] "r"(run_depth_cells) 509*5f39d1b3SJooyung Han : // clobbers 510*5f39d1b3SJooyung Han "cc", "memory", "%xmm0", "%xmm1", "%xmm3", "%xmm2", "%xmm4", "%xmm5", 511*5f39d1b3SJooyung Han "%xmm6", "%xmm7", "%xmm8", "%xmm9", "%xmm10", "%r12", "%r13", "%r14", 512*5f39d1b3SJooyung Han "%xmm11", "%xmm12", "%xmm13", "%xmm14", "%xmm15"); 513*5f39d1b3SJooyung Han } 514*5f39d1b3SJooyung Han }; 515*5f39d1b3SJooyung Han #endif 516*5f39d1b3SJooyung Han 517*5f39d1b3SJooyung Han } // namespace gemmlowp 518*5f39d1b3SJooyung Han 519*5f39d1b3SJooyung Han #endif // GEMMLOWP_INTERNAL_KERNEL_SSE_H_ 520