C 130
Kernels x86_64 sandybridge bli_gemm_asm_d8x4.c Guest on 1st June 2020 10:14:14 AM
  1. /*
  2.  
  3.    BLIS    
  4.    An object-based framework for developing high-performance BLAS-like
  5.    libraries.
  6.  
  7.    Copyright (C) 2014, The University of Texas at Austin
  8.  
  9.    Redistribution and use in source and binary forms, with or without
  10.    modification, are permitted provided that the following conditions are
  11.    met:
  12.     - Redistributions of source code must retain the above copyright
  13.       notice, this list of conditions and the following disclaimer.
  14.     - Redistributions in binary form must reproduce the above copyright
  15.       notice, this list of conditions and the following disclaimer in the
  16.       documentation and/or other materials provided with the distribution.
  17.     - Neither the name of The University of Texas at Austin nor the names
  18.       of its contributors may be used to endorse or promote products
  19.       derived from this software without specific prior written permission.
  20.  
  21.    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  22.    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  23.    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  24.    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  25.    HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  26.    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  27.    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  28.    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  29.    THEORY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  30.    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  31.    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  32.  
  33. */
  34.  
  35. /* NOTE: The micro-kernels in this file were partially inspired by portions
  36.    of code found in OpenBLAS 0.2.8 (http://www.openblas.net/). -FGVZ */
  37.  
  38. #include "blis.h"
  39.  
  40. void bli_sgemm_asm_8x8
  41.      (
  42.        dim_t               k,
  43.        float*     restrict alpha,
  44.        float*     restrict a,
  45.        float*     restrict b,
  46.        float*     restrict beta,
  47.        float*     restrict c, inc_t rs_c, inc_t cs_c,
  48.        auxinfo_t* restrict data,
  49.        cntx_t*    restrict cntx
  50.      )
  51. {
  52.         //void*   a_next = bli_auxinfo_next_a( data );
  53.         //void*   b_next = bli_auxinfo_next_b( data );
  54.  
  55.     uint64_t   k_iter = k / 4;
  56.     uint64_t   k_left = k % 4;
  57.  
  58.         __asm__ volatile
  59.         (
  60.         "                                            \n\t"
  61.         "                                            \n\t"
  62.         "movq                %2, %%rax               \n\t" // load address of a.
  63.         "movq                %3, %%rbx               \n\t" // load address of b.
  64.         //"movq                %9, %%r15               \n\t" // load address of b_next.
  65.         "                                            \n\t"
  66.         "vmovaps    0 * 32(%%rax), %%ymm0            \n\t" // initialize loop by pre-loading
  67.         "vmovsldup  0 * 32(%%rbx), %%ymm2            \n\t" // elements of a and b.
  68.         "vpermilps   $0x4e, %%ymm2, %%ymm3           \n\t"
  69.         "                                            \n\t"
  70.         "movq                %6, %%rcx               \n\t" // load address of c
  71.         "movq                %8, %%rdi               \n\t" // load cs_c
  72.         "leaq        (,%%rdi,4), %%rdi               \n\t" // cs_c *= sizeof(float)
  73.         "leaq   (%%rcx,%%rdi,4), %%r10               \n\t" // load address of c + 4*cs_c;
  74.         "                                            \n\t"
  75.         "leaq   (%%rdi,%%rdi,2), %%r14               \n\t" // r14 = 3*cs_c;
  76.         "prefetcht0   7 * 8(%%rcx)                   \n\t" // prefetch c + 0*cs_c
  77.         "prefetcht0   7 * 8(%%rcx,%%rdi)             \n\t" // prefetch c + 1*cs_c
  78.         "prefetcht0   7 * 8(%%rcx,%%rdi,2)           \n\t" // prefetch c + 2*cs_c
  79.         "prefetcht0   7 * 8(%%rcx,%%r14)             \n\t" // prefetch c + 3*cs_c
  80.         "prefetcht0   7 * 8(%%r10)                   \n\t" // prefetch c + 4*cs_c
  81.         "prefetcht0   7 * 8(%%r10,%%rdi)             \n\t" // prefetch c + 5*cs_c
  82.         "prefetcht0   7 * 8(%%r10,%%rdi,2)           \n\t" // prefetch c + 6*cs_c
  83.         "prefetcht0   7 * 8(%%r10,%%r14)             \n\t" // prefetch c + 7*cs_c
  84.         "                                            \n\t"
  85.         "vxorps    %%ymm8,  %%ymm8,  %%ymm8          \n\t"
  86.         "vxorps    %%ymm9,  %%ymm9,  %%ymm9          \n\t"
  87.         "vxorps    %%ymm10, %%ymm10, %%ymm10         \n\t"
  88.         "vxorps    %%ymm11, %%ymm11, %%ymm11         \n\t"
  89.         "vxorps    %%ymm12, %%ymm12, %%ymm12         \n\t"
  90.         "vxorps    %%ymm13, %%ymm13, %%ymm13         \n\t"
  91.         "vxorps    %%ymm14, %%ymm14, %%ymm14         \n\t"
  92.         "vxorps    %%ymm15, %%ymm15, %%ymm15         \n\t"
  93.         "                                            \n\t"
  94.         "                                            \n\t"
  95.         "                                            \n\t"
  96.         "movq      %0, %%rsi                         \n\t" // i = k_iter;
  97.         "testq  %%rsi, %%rsi                         \n\t" // check i via logical AND.
  98.         "je     .SCONSIDKLEFT                        \n\t" // if i == 0, jump to code that
  99.         "                                            \n\t" // contains the k_left loop.
  100.         "                                            \n\t"
  101.         "                                            \n\t"
  102.         ".SLOOPKITER:                                \n\t" // MAIN LOOP
  103.         "                                            \n\t"
  104.         "                                            \n\t"
  105.         "                                            \n\t" // iteration 0
  106.         "prefetcht0  16 * 32(%%rax)                  \n\t"
  107.         "vmulps            %%ymm0,  %%ymm2, %%ymm6   \n\t"
  108.         "vperm2f128 $0x03, %%ymm2,  %%ymm2, %%ymm4   \n\t"
  109.         "vmovshdup  0 * 32(%%rbx),  %%ymm2           \n\t"
  110.         "vmulps            %%ymm0,  %%ymm3, %%ymm7   \n\t"
  111.         "vperm2f128 $0x03, %%ymm3,  %%ymm3, %%ymm5   \n\t"
  112.         "vaddps            %%ymm15, %%ymm6, %%ymm15  \n\t"
  113.         "vaddps            %%ymm13, %%ymm7, %%ymm13  \n\t"
  114.         "                                            \n\t"
  115.         "vmovaps    1 * 32(%%rax),  %%ymm1           \n\t"
  116.         "vpermilps  $0x4e, %%ymm2,  %%ymm3           \n\t"
  117.         "vmulps            %%ymm0,  %%ymm4, %%ymm6   \n\t"
  118.         "vmulps            %%ymm0,  %%ymm5, %%ymm7   \n\t"
  119.         "vaddps            %%ymm11, %%ymm6, %%ymm11  \n\t"
  120.         "vaddps            %%ymm9,  %%ymm7, %%ymm9   \n\t"
  121.         "                                            \n\t"
  122.         "vmulps            %%ymm0,  %%ymm2, %%ymm6   \n\t"
  123.         "vperm2f128 $0x03, %%ymm2,  %%ymm2, %%ymm4   \n\t"
  124.         "vmovsldup  1 * 32(%%rbx),  %%ymm2           \n\t"
  125.         "vmulps            %%ymm0,  %%ymm3, %%ymm7   \n\t"
  126.         "vperm2f128 $0x03, %%ymm3,  %%ymm3, %%ymm5   \n\t"
  127.         "vaddps            %%ymm14, %%ymm6, %%ymm14  \n\t"
  128.         "vaddps            %%ymm12, %%ymm7, %%ymm12  \n\t"
  129.         "                                            \n\t"
  130.         "vpermilps  $0x4e, %%ymm2,  %%ymm3           \n\t"
  131.         "vmulps            %%ymm0,  %%ymm4, %%ymm6   \n\t"
  132.         "vmulps            %%ymm0,  %%ymm5, %%ymm7   \n\t"
  133.         "vaddps            %%ymm10, %%ymm6, %%ymm10  \n\t"
  134.         "vaddps            %%ymm8,  %%ymm7, %%ymm8   \n\t"
  135.         "                                            \n\t"
  136.         "                                            \n\t" // iteration 1
  137.         "vmulps            %%ymm1,  %%ymm2, %%ymm6   \n\t"
  138.         "vperm2f128 $0x03, %%ymm2,  %%ymm2, %%ymm4   \n\t"
  139.         "vmovshdup  1 * 32(%%rbx), %%ymm2            \n\t"
  140.         "vmulps            %%ymm1,  %%ymm3, %%ymm7   \n\t"
  141.         "vperm2f128 $0x03, %%ymm3,  %%ymm3, %%ymm5   \n\t"
  142.         "vaddps            %%ymm15, %%ymm6, %%ymm15  \n\t"
  143.         "vaddps            %%ymm13, %%ymm7, %%ymm13  \n\t"
  144.         "                                            \n\t"
  145.         "vmovaps    2 * 32(%%rax),  %%ymm0           \n\t"
  146.         "vpermilps  $0x4e, %%ymm2,  %%ymm3           \n\t"
  147.         "vmulps            %%ymm1,  %%ymm4, %%ymm6   \n\t"
  148.         "vmulps            %%ymm1,  %%ymm5, %%ymm7   \n\t"
  149.         "vaddps            %%ymm11, %%ymm6, %%ymm11  \n\t"
  150.         "vaddps            %%ymm9,  %%ymm7, %%ymm9   \n\t"
  151.         "                                            \n\t"
  152.         "vmulps            %%ymm1,  %%ymm2, %%ymm6   \n\t"
  153.         "vperm2f128 $0x03, %%ymm2,  %%ymm2, %%ymm4   \n\t"
  154.         "vmovsldup  2 * 32(%%rbx),  %%ymm2           \n\t"
  155.         "vmulps            %%ymm1,  %%ymm3, %%ymm7   \n\t"
  156.         "vperm2f128 $0x03, %%ymm3,  %%ymm3, %%ymm5   \n\t"
  157.         "vaddps            %%ymm14, %%ymm6, %%ymm14  \n\t"
  158.         "vaddps            %%ymm12, %%ymm7, %%ymm12  \n\t"
  159.         "                                            \n\t"
  160.         "vpermilps  $0x4e, %%ymm2,  %%ymm3           \n\t"
  161.         "vmulps            %%ymm1,  %%ymm4, %%ymm6   \n\t"
  162.         "vmulps            %%ymm1,  %%ymm5, %%ymm7   \n\t"
  163.         "vaddps            %%ymm10, %%ymm6, %%ymm10  \n\t"
  164.         "vaddps            %%ymm8,  %%ymm7, %%ymm8   \n\t"
  165.         "                                            \n\t"
  166.         "                                            \n\t"
  167.         "                                            \n\t" // iteration 2
  168.         "prefetcht0  18 * 32(%%rax)                  \n\t"
  169.         "vmulps            %%ymm0,  %%ymm2, %%ymm6   \n\t"
  170.         "vperm2f128 $0x03, %%ymm2,  %%ymm2, %%ymm4   \n\t"
  171.         "vmovshdup  2 * 32(%%rbx),  %%ymm2           \n\t"
  172.         "vmulps            %%ymm0,  %%ymm3, %%ymm7   \n\t"
  173.         "vperm2f128 $0x03, %%ymm3,  %%ymm3, %%ymm5   \n\t"
  174.         "vaddps            %%ymm15, %%ymm6, %%ymm15  \n\t"
  175.         "vaddps            %%ymm13, %%ymm7, %%ymm13  \n\t"
  176.         "                                            \n\t"
  177.         "vmovaps    3 * 32(%%rax),  %%ymm1           \n\t"
  178.         "addq           $4 * 8 * 4, %%rax            \n\t" // a += 4*8 (unroll x mr)
  179.         "vpermilps  $0x4e, %%ymm2,  %%ymm3           \n\t"
  180.         "vmulps            %%ymm0,  %%ymm4, %%ymm6   \n\t"
  181.         "vmulps            %%ymm0,  %%ymm5, %%ymm7   \n\t"
  182.         "vaddps            %%ymm11, %%ymm6, %%ymm11  \n\t"
  183.         "vaddps            %%ymm9,  %%ymm7, %%ymm9   \n\t"
  184.         "                                            \n\t"
  185.         "vmulps            %%ymm0,  %%ymm2, %%ymm6   \n\t"
  186.         "vperm2f128 $0x03, %%ymm2,  %%ymm2, %%ymm4   \n\t"
  187.         "vmovsldup  3 * 32(%%rbx),  %%ymm2           \n\t"
  188.         "vmulps            %%ymm0,  %%ymm3, %%ymm7   \n\t"
  189.         "vperm2f128 $0x03, %%ymm3,  %%ymm3, %%ymm5   \n\t"
  190.         "vaddps            %%ymm14, %%ymm6, %%ymm14  \n\t"
  191.         "vaddps            %%ymm12, %%ymm7, %%ymm12  \n\t"
  192.         "                                            \n\t"
  193.         "vpermilps  $0x4e, %%ymm2,  %%ymm3           \n\t"
  194.         "vmulps            %%ymm0,  %%ymm4, %%ymm6   \n\t"
  195.         "vmulps            %%ymm0,  %%ymm5, %%ymm7   \n\t"
  196.         "vaddps            %%ymm10, %%ymm6, %%ymm10  \n\t"
  197.         "vaddps            %%ymm8,  %%ymm7, %%ymm8   \n\t"
  198.         "                                            \n\t"
  199.         "                                            \n\t"
  200.         "                                            \n\t" // iteration 3
  201.         "vmulps            %%ymm1,  %%ymm2, %%ymm6   \n\t"
  202.         "vperm2f128 $0x03, %%ymm2,  %%ymm2, %%ymm4   \n\t"
  203.         "vmovshdup  3 * 32(%%rbx), %%ymm2            \n\t"
  204.         "addq           $4 * 8 * 4, %%rbx            \n\t" // b += 4*8 (unroll x nr)
  205.         "vmulps            %%ymm1,  %%ymm3, %%ymm7   \n\t"
  206.         "vperm2f128 $0x03, %%ymm3,  %%ymm3, %%ymm5   \n\t"
  207.         "vaddps            %%ymm15, %%ymm6, %%ymm15  \n\t"
  208.         "vaddps            %%ymm13, %%ymm7, %%ymm13  \n\t"
  209.         "                                            \n\t"
  210.         "vmovaps    0 * 32(%%rax),  %%ymm0           \n\t"
  211.         "vpermilps  $0x4e, %%ymm2,  %%ymm3           \n\t"
  212.         "vmulps            %%ymm1,  %%ymm4, %%ymm6   \n\t"
  213.         "vmulps            %%ymm1,  %%ymm5, %%ymm7   \n\t"
  214.         "vaddps            %%ymm11, %%ymm6, %%ymm11  \n\t"
  215.         "vaddps            %%ymm9,  %%ymm7, %%ymm9   \n\t"
  216.         "                                            \n\t"
  217.         "vmulps            %%ymm1,  %%ymm2, %%ymm6   \n\t"
  218.         "vperm2f128 $0x03, %%ymm2,  %%ymm2, %%ymm4   \n\t"
  219.         "vmovsldup  0 * 32(%%rbx),  %%ymm2           \n\t"
  220.         "vmulps            %%ymm1,  %%ymm3, %%ymm7   \n\t"
  221.         "vperm2f128 $0x03, %%ymm3,  %%ymm3, %%ymm5   \n\t"
  222.         "vaddps            %%ymm14, %%ymm6, %%ymm14  \n\t"
  223.         "vaddps            %%ymm12, %%ymm7, %%ymm12  \n\t"
  224.         "                                            \n\t"
  225.         "vpermilps  $0x4e, %%ymm2,  %%ymm3           \n\t"
  226.         "vmulps            %%ymm1,  %%ymm4, %%ymm6   \n\t"
  227.         "vmulps            %%ymm1,  %%ymm5, %%ymm7   \n\t"
  228.         "vaddps            %%ymm10, %%ymm6, %%ymm10  \n\t"
  229.         "vaddps            %%ymm8,  %%ymm7, %%ymm8   \n\t"
  230.         "                                            \n\t"
  231.         "                                            \n\t"
  232.         "                                            \n\t"
  233.         "                                            \n\t"
  234.         "decq   %%rsi                                \n\t" // i -= 1;
  235.         "jne    .SLOOPKITER                          \n\t" // iterate again if i != 0.
  236.         "                                            \n\t"
  237.         "                                            \n\t"
  238.         "                                            \n\t"
  239.         "                                            \n\t"
  240.         "                                            \n\t"
  241.         "                                            \n\t"
  242.         ".SCONSIDKLEFT:                              \n\t"
  243.         "                                            \n\t"
  244.         "movq      %1, %%rsi                         \n\t" // i = k_left;
  245.         "testq  %%rsi, %%rsi                         \n\t" // check i via logical AND.
  246.         "je     .SPOSTACCUM                          \n\t" // if i == 0, we're done; jump to end.
  247.         "                                            \n\t" // else, we prepare to enter k_left loop.
  248.         "                                            \n\t"
  249.         "                                            \n\t"
  250.         ".SLOOPKLEFT:                                \n\t" // EDGE LOOP
  251.         "                                            \n\t"
  252.         "                                            \n\t"
  253.         "prefetcht0  16 * 32(%%rax)                  \n\t"
  254.         "vmulps            %%ymm0,  %%ymm2, %%ymm6   \n\t"
  255.         "vperm2f128  $0x3, %%ymm2,  %%ymm2, %%ymm4   \n\t"
  256.         "vmovshdup  0 * 32(%%rbx),  %%ymm2           \n\t"
  257.         "vmulps            %%ymm0,  %%ymm3, %%ymm7   \n\t"
  258.         "vperm2f128  $0x3, %%ymm3,  %%ymm3, %%ymm5   \n\t"
  259.         "vaddps            %%ymm15, %%ymm6, %%ymm15  \n\t"
  260.         "vaddps            %%ymm13, %%ymm7, %%ymm13  \n\t"
  261.         "                                            \n\t"
  262.         "vmovaps    1 * 32(%%rax),  %%ymm1           \n\t"
  263.         "addq           $8 * 1 * 4, %%rax            \n\t" // a += 8 (1 x mr)
  264.         "vpermilps  $0x4e, %%ymm2,  %%ymm3           \n\t"
  265.         "vmulps            %%ymm0,  %%ymm4, %%ymm6   \n\t"
  266.         "vmulps            %%ymm0,  %%ymm5, %%ymm7   \n\t"
  267.         "vaddps            %%ymm11, %%ymm6, %%ymm11  \n\t"
  268.         "vaddps            %%ymm9,  %%ymm7, %%ymm9   \n\t"
  269.         "                                            \n\t"
  270.         "vmulps            %%ymm0,  %%ymm2, %%ymm6   \n\t"
  271.         "vperm2f128  $0x3, %%ymm2,  %%ymm2, %%ymm4   \n\t"
  272.         "vmovsldup  1 * 32(%%rbx),  %%ymm2           \n\t"
  273.         "addq           $8 * 1 * 4, %%rbx            \n\t" // b += 8 (1 x nr)
  274.         "vmulps            %%ymm0,  %%ymm3, %%ymm7   \n\t"
  275.         "vperm2f128  $0x3, %%ymm3,  %%ymm3, %%ymm5   \n\t"
  276.         "vaddps            %%ymm14, %%ymm6, %%ymm14  \n\t"
  277.         "vaddps            %%ymm12, %%ymm7, %%ymm12  \n\t"
  278.         "                                            \n\t"
  279.         "vpermilps  $0x4e, %%ymm2,  %%ymm3           \n\t"
  280.         "vmulps            %%ymm0,  %%ymm4, %%ymm6   \n\t"
  281.         "vmulps            %%ymm0,  %%ymm5, %%ymm7   \n\t"
  282.         "vmovaps           %%ymm1,  %%ymm0           \n\t"
  283.         "vaddps            %%ymm10, %%ymm6, %%ymm10  \n\t"
  284.         "vaddps            %%ymm8,  %%ymm7, %%ymm8   \n\t"
  285.         "                                            \n\t"
  286.         "                                            \n\t"
  287.         "                                            \n\t"
  288.         "decq   %%rsi                                \n\t" // i -= 1;
  289.         "jne    .SLOOPKLEFT                          \n\t" // iterate again if i != 0.
  290.         "                                            \n\t"
  291.         "                                            \n\t"
  292.         "                                            \n\t"
  293.         ".SPOSTACCUM:                                \n\t"
  294.         "                                            \n\t"
  295.         "                                            \n\t" // ymm15:  ymm13:  ymm11:  ymm9:
  296.         "                                            \n\t" // ( ab00  ( ab02  ( ab04  ( ab06
  297.         "                                            \n\t" //   ab10    ab12    ab14    ab16  
  298.         "                                            \n\t" //   ab22    ab20    ab26    ab24
  299.         "                                            \n\t" //   ab32    ab30    ab36    ab34
  300.         "                                            \n\t" //   ab44    ab46    ab40    ab42
  301.         "                                            \n\t" //   ab54    ab56    ab50    ab52  
  302.         "                                            \n\t" //   ab66    ab64    ab62    ab60
  303.         "                                            \n\t" //   ab76 )  ab74 )  ab72 )  ab70 )
  304.         "                                            \n\t"
  305.         "                                            \n\t" // ymm14:  ymm12:  ymm10:  ymm8:
  306.         "                                            \n\t" // ( ab01  ( ab03  ( ab05  ( ab07
  307.         "                                            \n\t" //   ab11    ab13    ab15    ab17  
  308.         "                                            \n\t" //   ab23    ab21    ab27    ab25
  309.         "                                            \n\t" //   ab33    ab31    ab37    ab35
  310.         "                                            \n\t" //   ab45    ab47    ab41    ab43
  311.         "                                            \n\t" //   ab55    ab57    ab51    ab53  
  312.         "                                            \n\t" //   ab67    ab65    ab63    ab61
  313.         "                                            \n\t" //   ab77 )  ab75 )  ab73 )  ab71 )
  314.         "                                            \n\t"
  315.         "vmovaps          %%ymm15, %%ymm7            \n\t"
  316.         "vshufps   $0xe4, %%ymm13, %%ymm15, %%ymm15  \n\t"
  317.         "vshufps   $0xe4, %%ymm7,  %%ymm13, %%ymm13  \n\t"
  318.         "                                            \n\t"
  319.         "vmovaps          %%ymm11, %%ymm7            \n\t"
  320.         "vshufps   $0xe4, %%ymm9,  %%ymm11, %%ymm11  \n\t"
  321.         "vshufps   $0xe4, %%ymm7,  %%ymm9,  %%ymm9   \n\t"
  322.         "                                            \n\t"
  323.         "vmovaps          %%ymm14, %%ymm7            \n\t"
  324.         "vshufps   $0xe4, %%ymm12, %%ymm14, %%ymm14  \n\t"
  325.         "vshufps   $0xe4, %%ymm7,  %%ymm12, %%ymm12  \n\t"
  326.         "                                            \n\t"
  327.         "vmovaps          %%ymm10, %%ymm7            \n\t"
  328.         "vshufps   $0xe4, %%ymm8,  %%ymm10, %%ymm10  \n\t"
  329.         "vshufps   $0xe4, %%ymm7,  %%ymm8,  %%ymm8   \n\t"
  330.         "                                            \n\t"
  331.         "                                            \n\t" // ymm15:  ymm13:  ymm11:  ymm9:
  332.         "                                            \n\t" // ( ab00  ( ab02  ( ab04  ( ab06
  333.         "                                            \n\t" //   ab10    ab12    ab14    ab16  
  334.         "                                            \n\t" //   ab20    ab22    ab24    ab26
  335.         "                                            \n\t" //   ab30    ab32    ab34    ab36
  336.         "                                            \n\t" //   ab44    ab46    ab40    ab42
  337.         "                                            \n\t" //   ab54    ab56    ab50    ab52  
  338.         "                                            \n\t" //   ab64    ab66    ab60    ab62
  339.         "                                            \n\t" //   ab74 )  ab76 )  ab70 )  ab72 )
  340.         "                                            \n\t"
  341.         "                                            \n\t" // ymm14:  ymm12:  ymm10:  ymm8:
  342.         "                                            \n\t" // ( ab01  ( ab03  ( ab05  ( ab07
  343.         "                                            \n\t" //   ab11    ab13    ab15    ab17  
  344.         "                                            \n\t" //   ab21    ab23    ab25    ab27
  345.         "                                            \n\t" //   ab31    ab33    ab35    ab37
  346.         "                                            \n\t" //   ab45    ab47    ab41    ab43
  347.         "                                            \n\t" //   ab55    ab57    ab51    ab53  
  348.         "                                            \n\t" //   ab65    ab67    ab61    ab63
  349.         "                                            \n\t" //   ab75 )  ab77 )  ab71 )  ab73 )
  350.         "                                            \n\t"
  351.         "vmovaps           %%ymm15, %%ymm7           \n\t"
  352.         "vperm2f128 $0x30, %%ymm11, %%ymm15, %%ymm15 \n\t"
  353.         "vperm2f128 $0x12, %%ymm11, %%ymm7,  %%ymm11 \n\t"
  354.         "                                            \n\t"
  355.         "vmovaps           %%ymm13, %%ymm7           \n\t"
  356.         "vperm2f128 $0x30, %%ymm9,  %%ymm13, %%ymm13 \n\t"
  357.         "vperm2f128 $0x12, %%ymm9,  %%ymm7,  %%ymm9  \n\t"
  358.         "                                            \n\t"
  359.         "vmovaps           %%ymm14, %%ymm7           \n\t"
  360.         "vperm2f128 $0x30, %%ymm10, %%ymm14, %%ymm14 \n\t"
  361.         "vperm2f128 $0x12, %%ymm10, %%ymm7,  %%ymm10 \n\t"
  362.         "                                            \n\t"
  363.         "vmovaps           %%ymm12, %%ymm7           \n\t"
  364.         "vperm2f128 $0x30, %%ymm8,  %%ymm12, %%ymm12 \n\t"
  365.         "vperm2f128 $0x12, %%ymm8,  %%ymm7,  %%ymm8  \n\t"
  366.         "                                            \n\t"
  367.         "                                            \n\t" // ymm15:  ymm13:  ymm11:  ymm9:
  368.         "                                            \n\t" // ( ab00  ( ab02  ( ab04  ( ab06
  369.         "                                            \n\t" //   ab10    ab12    ab14    ab16  
  370.         "                                            \n\t" //   ab20    ab22    ab24    ab26
  371.         "                                            \n\t" //   ab30    ab32    ab34    ab36
  372.         "                                            \n\t" //   ab40    ab42    ab44    ab46
  373.         "                                            \n\t" //   ab50    ab52    ab54    ab56  
  374.         "                                            \n\t" //   ab60    ab62    ab64    ab66
  375.         "                                            \n\t" //   ab70 )  ab72 )  ab74 )  ab76 )
  376.         "                                            \n\t"
  377.         "                                            \n\t" // ymm14:  ymm12:  ymm10:  ymm8:
  378.         "                                            \n\t" // ( ab01  ( ab03  ( ab05  ( ab07
  379.         "                                            \n\t" //   ab11    ab13    ab15    ab17  
  380.         "                                            \n\t" //   ab21    ab23    ab25    ab27
  381.         "                                            \n\t" //   ab31    ab33    ab35    ab37
  382.         "                                            \n\t" //   ab41    ab43    ab45    ab47
  383.         "                                            \n\t" //   ab51    ab53    ab55    ab57  
  384.         "                                            \n\t" //   ab61    ab63    ab65    ab67
  385.         "                                            \n\t" //   ab71 )  ab73 )  ab75 )  ab77 )
  386.         "                                            \n\t"
  387.         "                                            \n\t"
  388.         "                                            \n\t"
  389.         "movq         %4, %%rax                      \n\t" // load address of alpha
  390.         "movq         %5, %%rbx                      \n\t" // load address of beta
  391.         "vbroadcastss    (%%rax), %%ymm0             \n\t" // load alpha and duplicate
  392.         "vbroadcastss    (%%rbx), %%ymm4             \n\t" // load beta and duplicate
  393.         "                                            \n\t"
  394.         "vmulps           %%ymm0,  %%ymm8,  %%ymm8   \n\t" // scale by alpha
  395.         "vmulps           %%ymm0,  %%ymm9,  %%ymm9   \n\t"
  396.         "vmulps           %%ymm0,  %%ymm10, %%ymm10  \n\t"
  397.         "vmulps           %%ymm0,  %%ymm11, %%ymm11  \n\t"
  398.         "vmulps           %%ymm0,  %%ymm12, %%ymm12  \n\t"
  399.         "vmulps           %%ymm0,  %%ymm13, %%ymm13  \n\t"
  400.         "vmulps           %%ymm0,  %%ymm14, %%ymm14  \n\t"
  401.         "vmulps           %%ymm0,  %%ymm15, %%ymm15  \n\t"
  402.         "                                            \n\t"
  403.         "                                            \n\t"
  404.         "                                            \n\t"
  405.         "                                            \n\t"
  406.         "                                            \n\t"
  407.         "                                            \n\t"
  408.         "movq                %7, %%rsi               \n\t" // load rs_c
  409.         "leaq        (,%%rsi,4), %%rsi               \n\t" // rsi = rs_c * sizeof(float)
  410.         "                                            \n\t"
  411.         "leaq   (%%rcx,%%rsi,4), %%rdx               \n\t" // load address of c + 4*rs_c;
  412.         "                                            \n\t"
  413.         "leaq        (,%%rsi,2), %%r12               \n\t" // r12 = 2*rs_c;
  414.         "leaq   (%%r12,%%rsi,1), %%r13               \n\t" // r13 = 3*rs_c;
  415.         "                                            \n\t"
  416.         "                                            \n\t"
  417.         "                                            \n\t" // now avoid loading C if beta == 0
  418.         "                                            \n\t"
  419.         "vxorps    %%ymm0,  %%ymm0,  %%ymm0          \n\t" // set ymm0 to zero.
  420.         "vucomiss  %%xmm0,  %%xmm4                   \n\t" // set ZF if beta == 0.
  421.         "je      .SBETAZERO                          \n\t" // if ZF = 1, jump to beta == 0 case
  422.         "                                            \n\t"
  423.         "                                            \n\t"
  424.         "cmpq       $4, %%rsi                        \n\t" // set ZF if (4*cs_c) == 4.
  425.         "jz      .SCOLSTORED                         \n\t" // jump to column storage case
  426.         "                                            \n\t"
  427.         "                                            \n\t"
  428.         "                                            \n\t"
  429.         ".SGENSTORED:                                \n\t"
  430.         "                                            \n\t"
  431.         "                                            \n\t" // update c00:c70
  432.         "vmovlps    (%%rcx),        %%xmm0,  %%xmm0  \n\t"
  433.         "vmovhps    (%%rcx,%%rsi),  %%xmm0,  %%xmm0  \n\t"
  434.         "vmovlps    (%%rcx,%%r12),  %%xmm1,  %%xmm1  \n\t"
  435.         "vmovhps    (%%rcx,%%r13),  %%xmm1,  %%xmm1  \n\t"
  436.         "vshufps    $0x88, %%xmm1,  %%xmm0,  %%xmm0  \n\t"
  437.         "vmovlps    (%%rdx),        %%xmm2,  %%xmm2  \n\t"
  438.         "vmovhps    (%%rdx,%%rsi),  %%xmm2,  %%xmm2  \n\t"
  439.         "vmovlps    (%%rdx,%%r12),  %%xmm3,  %%xmm3  \n\t"
  440.         "vmovhps    (%%rdx,%%r13),  %%xmm3,  %%xmm3  \n\t"
  441.         "vshufps    $0x88, %%xmm3,  %%xmm2,  %%xmm2  \n\t"
  442.         "vperm2f128 $0x20, %%ymm2,  %%ymm0,  %%ymm0  \n\t"
  443.         "                                            \n\t"
  444.         "vmulps            %%ymm4,  %%ymm0,  %%ymm0  \n\t" // scale by beta,
  445.         "vaddps            %%ymm15, %%ymm0,  %%ymm0  \n\t" // add the gemm result,
  446.         "                                            \n\t"
  447.         "vextractf128  $1, %%ymm0,  %%xmm2           \n\t"
  448.         "vmovss            %%xmm0, (%%rcx)           \n\t"
  449.         "vpermilps  $0x39, %%xmm0,  %%xmm1           \n\t"
  450.         "vmovss            %%xmm1, (%%rcx,%%rsi)     \n\t"
  451.         "vpermilps  $0x39, %%xmm1,  %%xmm0           \n\t"
  452.         "vmovss            %%xmm0, (%%rcx,%%r12)     \n\t"
  453.         "vpermilps  $0x39, %%xmm0,  %%xmm1           \n\t"
  454.         "vmovss            %%xmm1, (%%rcx,%%r13)     \n\t"
  455.         "vmovss            %%xmm2, (%%rdx)           \n\t"
  456.         "vpermilps  $0x39, %%xmm2,  %%xmm3           \n\t"
  457.         "vmovss            %%xmm3, (%%rdx,%%rsi)     \n\t"
  458.         "vpermilps  $0x39, %%xmm3,  %%xmm2           \n\t"
  459.         "vmovss            %%xmm2, (%%rdx,%%r12)     \n\t"
  460.         "vpermilps  $0x39, %%xmm2,  %%xmm3           \n\t"
  461.         "vmovss            %%xmm3, (%%rdx,%%r13)     \n\t"
  462.         "                                            \n\t"
  463.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  464.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  465.         "                                            \n\t"
  466.         "                                            \n\t"
  467.         "                                            \n\t" // update c01:c71
  468.         "vmovlps    (%%rcx),        %%xmm0,  %%xmm0  \n\t"
  469.         "vmovhps    (%%rcx,%%rsi),  %%xmm0,  %%xmm0  \n\t"
  470.         "vmovlps    (%%rcx,%%r12),  %%xmm1,  %%xmm1  \n\t"
  471.         "vmovhps    (%%rcx,%%r13),  %%xmm1,  %%xmm1  \n\t"
  472.         "vshufps    $0x88, %%xmm1,  %%xmm0,  %%xmm0  \n\t"
  473.         "vmovlps    (%%rdx),        %%xmm2,  %%xmm2  \n\t"
  474.         "vmovhps    (%%rdx,%%rsi),  %%xmm2,  %%xmm2  \n\t"
  475.         "vmovlps    (%%rdx,%%r12),  %%xmm3,  %%xmm3  \n\t"
  476.         "vmovhps    (%%rdx,%%r13),  %%xmm3,  %%xmm3  \n\t"
  477.         "vshufps    $0x88, %%xmm3,  %%xmm2,  %%xmm2  \n\t"
  478.         "vperm2f128 $0x20, %%ymm2,  %%ymm0,  %%ymm0  \n\t"
  479.         "                                            \n\t"
  480.         "vmulps            %%ymm4,  %%ymm0,  %%ymm0  \n\t" // scale by beta,
  481.         "vaddps            %%ymm14, %%ymm0,  %%ymm0  \n\t" // add the gemm result,
  482.         "                                            \n\t"
  483.         "vextractf128  $1, %%ymm0,  %%xmm2           \n\t"
  484.         "vmovss            %%xmm0, (%%rcx)           \n\t"
  485.         "vpermilps  $0x39, %%xmm0,  %%xmm1           \n\t"
  486.         "vmovss            %%xmm1, (%%rcx,%%rsi)     \n\t"
  487.         "vpermilps  $0x39, %%xmm1,  %%xmm0           \n\t"
  488.         "vmovss            %%xmm0, (%%rcx,%%r12)     \n\t"
  489.         "vpermilps  $0x39, %%xmm0,  %%xmm1           \n\t"
  490.         "vmovss            %%xmm1, (%%rcx,%%r13)     \n\t"
  491.         "vmovss            %%xmm2, (%%rdx)           \n\t"
  492.         "vpermilps  $0x39, %%xmm2,  %%xmm3           \n\t"
  493.         "vmovss            %%xmm3, (%%rdx,%%rsi)     \n\t"
  494.         "vpermilps  $0x39, %%xmm3,  %%xmm2           \n\t"
  495.         "vmovss            %%xmm2, (%%rdx,%%r12)     \n\t"
  496.         "vpermilps  $0x39, %%xmm2,  %%xmm3           \n\t"
  497.         "vmovss            %%xmm3, (%%rdx,%%r13)     \n\t"
  498.         "                                            \n\t"
  499.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  500.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  501.         "                                            \n\t"
  502.         "                                            \n\t"
  503.         "                                            \n\t" // update c02:c72
  504.         "vmovlps    (%%rcx),        %%xmm0,  %%xmm0  \n\t"
  505.         "vmovhps    (%%rcx,%%rsi),  %%xmm0,  %%xmm0  \n\t"
  506.         "vmovlps    (%%rcx,%%r12),  %%xmm1,  %%xmm1  \n\t"
  507.         "vmovhps    (%%rcx,%%r13),  %%xmm1,  %%xmm1  \n\t"
  508.         "vshufps    $0x88, %%xmm1,  %%xmm0,  %%xmm0  \n\t"
  509.         "vmovlps    (%%rdx),        %%xmm2,  %%xmm2  \n\t"
  510.         "vmovhps    (%%rdx,%%rsi),  %%xmm2,  %%xmm2  \n\t"
  511.         "vmovlps    (%%rdx,%%r12),  %%xmm3,  %%xmm3  \n\t"
  512.         "vmovhps    (%%rdx,%%r13),  %%xmm3,  %%xmm3  \n\t"
  513.         "vshufps    $0x88, %%xmm3,  %%xmm2,  %%xmm2  \n\t"
  514.         "vperm2f128 $0x20, %%ymm2,  %%ymm0,  %%ymm0  \n\t"
  515.         "                                            \n\t"
  516.         "vmulps            %%ymm4,  %%ymm0,  %%ymm0  \n\t" // scale by beta,
  517.         "vaddps            %%ymm13, %%ymm0,  %%ymm0  \n\t" // add the gemm result,
  518.         "                                            \n\t"
  519.         "vextractf128  $1, %%ymm0,  %%xmm2           \n\t"
  520.         "vmovss            %%xmm0, (%%rcx)           \n\t"
  521.         "vpermilps  $0x39, %%xmm0,  %%xmm1           \n\t"
  522.         "vmovss            %%xmm1, (%%rcx,%%rsi)     \n\t"
  523.         "vpermilps  $0x39, %%xmm1,  %%xmm0           \n\t"
  524.         "vmovss            %%xmm0, (%%rcx,%%r12)     \n\t"
  525.         "vpermilps  $0x39, %%xmm0,  %%xmm1           \n\t"
  526.         "vmovss            %%xmm1, (%%rcx,%%r13)     \n\t"
  527.         "vmovss            %%xmm2, (%%rdx)           \n\t"
  528.         "vpermilps  $0x39, %%xmm2,  %%xmm3           \n\t"
  529.         "vmovss            %%xmm3, (%%rdx,%%rsi)     \n\t"
  530.         "vpermilps  $0x39, %%xmm3,  %%xmm2           \n\t"
  531.         "vmovss            %%xmm2, (%%rdx,%%r12)     \n\t"
  532.         "vpermilps  $0x39, %%xmm2,  %%xmm3           \n\t"
  533.         "vmovss            %%xmm3, (%%rdx,%%r13)     \n\t"
  534.         "                                            \n\t"
  535.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  536.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  537.         "                                            \n\t"
  538.         "                                            \n\t"
  539.         "                                            \n\t" // update c03:c73
  540.         "vmovlps    (%%rcx),        %%xmm0,  %%xmm0  \n\t"
  541.         "vmovhps    (%%rcx,%%rsi),  %%xmm0,  %%xmm0  \n\t"
  542.         "vmovlps    (%%rcx,%%r12),  %%xmm1,  %%xmm1  \n\t"
  543.         "vmovhps    (%%rcx,%%r13),  %%xmm1,  %%xmm1  \n\t"
  544.         "vshufps    $0x88, %%xmm1,  %%xmm0,  %%xmm0  \n\t"
  545.         "vmovlps    (%%rdx),        %%xmm2,  %%xmm2  \n\t"
  546.         "vmovhps    (%%rdx,%%rsi),  %%xmm2,  %%xmm2  \n\t"
  547.         "vmovlps    (%%rdx,%%r12),  %%xmm3,  %%xmm3  \n\t"
  548.         "vmovhps    (%%rdx,%%r13),  %%xmm3,  %%xmm3  \n\t"
  549.         "vshufps    $0x88, %%xmm3,  %%xmm2,  %%xmm2  \n\t"
  550.         "vperm2f128 $0x20, %%ymm2,  %%ymm0,  %%ymm0  \n\t"
  551.         "                                            \n\t"
  552.         "vmulps            %%ymm4,  %%ymm0,  %%ymm0  \n\t" // scale by beta,
  553.         "vaddps            %%ymm12, %%ymm0,  %%ymm0  \n\t" // add the gemm result,
  554.         "                                            \n\t"
  555.         "vextractf128  $1, %%ymm0,  %%xmm2           \n\t"
  556.         "vmovss            %%xmm0, (%%rcx)           \n\t"
  557.         "vpermilps  $0x39, %%xmm0,  %%xmm1           \n\t"
  558.         "vmovss            %%xmm1, (%%rcx,%%rsi)     \n\t"
  559.         "vpermilps  $0x39, %%xmm1,  %%xmm0           \n\t"
  560.         "vmovss            %%xmm0, (%%rcx,%%r12)     \n\t"
  561.         "vpermilps  $0x39, %%xmm0,  %%xmm1           \n\t"
  562.         "vmovss            %%xmm1, (%%rcx,%%r13)     \n\t"
  563.         "vmovss            %%xmm2, (%%rdx)           \n\t"
  564.         "vpermilps  $0x39, %%xmm2,  %%xmm3           \n\t"
  565.         "vmovss            %%xmm3, (%%rdx,%%rsi)     \n\t"
  566.         "vpermilps  $0x39, %%xmm3,  %%xmm2           \n\t"
  567.         "vmovss            %%xmm2, (%%rdx,%%r12)     \n\t"
  568.         "vpermilps  $0x39, %%xmm2,  %%xmm3           \n\t"
  569.         "vmovss            %%xmm3, (%%rdx,%%r13)     \n\t"
  570.         "                                            \n\t"
  571.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  572.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  573.         "                                            \n\t"
  574.         "                                            \n\t"
  575.         "                                            \n\t" // update c04:c74
  576.         "vmovlps    (%%rcx),        %%xmm0,  %%xmm0  \n\t"
  577.         "vmovhps    (%%rcx,%%rsi),  %%xmm0,  %%xmm0  \n\t"
  578.         "vmovlps    (%%rcx,%%r12),  %%xmm1,  %%xmm1  \n\t"
  579.         "vmovhps    (%%rcx,%%r13),  %%xmm1,  %%xmm1  \n\t"
  580.         "vshufps    $0x88, %%xmm1,  %%xmm0,  %%xmm0  \n\t"
  581.         "vmovlps    (%%rdx),        %%xmm2,  %%xmm2  \n\t"
  582.         "vmovhps    (%%rdx,%%rsi),  %%xmm2,  %%xmm2  \n\t"
  583.         "vmovlps    (%%rdx,%%r12),  %%xmm3,  %%xmm3  \n\t"
  584.         "vmovhps    (%%rdx,%%r13),  %%xmm3,  %%xmm3  \n\t"
  585.         "vshufps    $0x88, %%xmm3,  %%xmm2,  %%xmm2  \n\t"
  586.         "vperm2f128 $0x20, %%ymm2,  %%ymm0,  %%ymm0  \n\t"
  587.         "                                            \n\t"
  588.         "vmulps            %%ymm4,  %%ymm0,  %%ymm0  \n\t" // scale by beta,
  589.         "vaddps            %%ymm11, %%ymm0,  %%ymm0  \n\t" // add the gemm result,
  590.         "                                            \n\t"
  591.         "vextractf128  $1, %%ymm0,  %%xmm2           \n\t"
  592.         "vmovss            %%xmm0, (%%rcx)           \n\t"
  593.         "vpermilps  $0x39, %%xmm0,  %%xmm1           \n\t"
  594.         "vmovss            %%xmm1, (%%rcx,%%rsi)     \n\t"
  595.         "vpermilps  $0x39, %%xmm1,  %%xmm0           \n\t"
  596.         "vmovss            %%xmm0, (%%rcx,%%r12)     \n\t"
  597.         "vpermilps  $0x39, %%xmm0,  %%xmm1           \n\t"
  598.         "vmovss            %%xmm1, (%%rcx,%%r13)     \n\t"
  599.         "vmovss            %%xmm2, (%%rdx)           \n\t"
  600.         "vpermilps  $0x39, %%xmm2,  %%xmm3           \n\t"
  601.         "vmovss            %%xmm3, (%%rdx,%%rsi)     \n\t"
  602.         "vpermilps  $0x39, %%xmm3,  %%xmm2           \n\t"
  603.         "vmovss            %%xmm2, (%%rdx,%%r12)     \n\t"
  604.         "vpermilps  $0x39, %%xmm2,  %%xmm3           \n\t"
  605.         "vmovss            %%xmm3, (%%rdx,%%r13)     \n\t"
  606.         "                                            \n\t"
  607.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  608.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  609.         "                                            \n\t"
  610.         "                                            \n\t"
  611.         "                                            \n\t" // update c05:c75
  612.         "vmovlps    (%%rcx),        %%xmm0,  %%xmm0  \n\t"
  613.         "vmovhps    (%%rcx,%%rsi),  %%xmm0,  %%xmm0  \n\t"
  614.         "vmovlps    (%%rcx,%%r12),  %%xmm1,  %%xmm1  \n\t"
  615.         "vmovhps    (%%rcx,%%r13),  %%xmm1,  %%xmm1  \n\t"
  616.         "vshufps    $0x88, %%xmm1,  %%xmm0,  %%xmm0  \n\t"
  617.         "vmovlps    (%%rdx),        %%xmm2,  %%xmm2  \n\t"
  618.         "vmovhps    (%%rdx,%%rsi),  %%xmm2,  %%xmm2  \n\t"
  619.         "vmovlps    (%%rdx,%%r12),  %%xmm3,  %%xmm3  \n\t"
  620.         "vmovhps    (%%rdx,%%r13),  %%xmm3,  %%xmm3  \n\t"
  621.         "vshufps    $0x88, %%xmm3,  %%xmm2,  %%xmm2  \n\t"
  622.         "vperm2f128 $0x20, %%ymm2,  %%ymm0,  %%ymm0  \n\t"
  623.         "                                            \n\t"
  624.         "vmulps            %%ymm4,  %%ymm0,  %%ymm0  \n\t" // scale by beta,
  625.         "vaddps            %%ymm10, %%ymm0,  %%ymm0  \n\t" // add the gemm result,
  626.         "                                            \n\t"
  627.         "vextractf128  $1, %%ymm0,  %%xmm2           \n\t"
  628.         "vmovss            %%xmm0, (%%rcx)           \n\t"
  629.         "vpermilps  $0x39, %%xmm0,  %%xmm1           \n\t"
  630.         "vmovss            %%xmm1, (%%rcx,%%rsi)     \n\t"
  631.         "vpermilps  $0x39, %%xmm1,  %%xmm0           \n\t"
  632.         "vmovss            %%xmm0, (%%rcx,%%r12)     \n\t"
  633.         "vpermilps  $0x39, %%xmm0,  %%xmm1           \n\t"
  634.         "vmovss            %%xmm1, (%%rcx,%%r13)     \n\t"
  635.         "vmovss            %%xmm2, (%%rdx)           \n\t"
  636.         "vpermilps  $0x39, %%xmm2,  %%xmm3           \n\t"
  637.         "vmovss            %%xmm3, (%%rdx,%%rsi)     \n\t"
  638.         "vpermilps  $0x39, %%xmm3,  %%xmm2           \n\t"
  639.         "vmovss            %%xmm2, (%%rdx,%%r12)     \n\t"
  640.         "vpermilps  $0x39, %%xmm2,  %%xmm3           \n\t"
  641.         "vmovss            %%xmm3, (%%rdx,%%r13)     \n\t"
  642.         "                                            \n\t"
  643.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  644.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  645.         "                                            \n\t"
  646.         "                                            \n\t"
  647.         "                                            \n\t" // update c06:c76
  648.         "vmovlps    (%%rcx),        %%xmm0,  %%xmm0  \n\t"
  649.         "vmovhps    (%%rcx,%%rsi),  %%xmm0,  %%xmm0  \n\t"
  650.         "vmovlps    (%%rcx,%%r12),  %%xmm1,  %%xmm1  \n\t"
  651.         "vmovhps    (%%rcx,%%r13),  %%xmm1,  %%xmm1  \n\t"
  652.         "vshufps    $0x88, %%xmm1,  %%xmm0,  %%xmm0  \n\t"
  653.         "vmovlps    (%%rdx),        %%xmm2,  %%xmm2  \n\t"
  654.         "vmovhps    (%%rdx,%%rsi),  %%xmm2,  %%xmm2  \n\t"
  655.         "vmovlps    (%%rdx,%%r12),  %%xmm3,  %%xmm3  \n\t"
  656.         "vmovhps    (%%rdx,%%r13),  %%xmm3,  %%xmm3  \n\t"
  657.         "vshufps    $0x88, %%xmm3,  %%xmm2,  %%xmm2  \n\t"
  658.         "vperm2f128 $0x20, %%ymm2,  %%ymm0,  %%ymm0  \n\t"
  659.         "                                            \n\t"
  660.         "vmulps            %%ymm4,  %%ymm0,  %%ymm0  \n\t" // scale by beta,
  661.         "vaddps            %%ymm9,  %%ymm0,  %%ymm0  \n\t" // add the gemm result,
  662.         "                                            \n\t"
  663.         "vextractf128  $1, %%ymm0,  %%xmm2           \n\t"
  664.         "vmovss            %%xmm0, (%%rcx)           \n\t"
  665.         "vpermilps  $0x39, %%xmm0,  %%xmm1           \n\t"
  666.         "vmovss            %%xmm1, (%%rcx,%%rsi)     \n\t"
  667.         "vpermilps  $0x39, %%xmm1,  %%xmm0           \n\t"
  668.         "vmovss            %%xmm0, (%%rcx,%%r12)     \n\t"
  669.         "vpermilps  $0x39, %%xmm0,  %%xmm1           \n\t"
  670.         "vmovss            %%xmm1, (%%rcx,%%r13)     \n\t"
  671.         "vmovss            %%xmm2, (%%rdx)           \n\t"
  672.         "vpermilps  $0x39, %%xmm2,  %%xmm3           \n\t"
  673.         "vmovss            %%xmm3, (%%rdx,%%rsi)     \n\t"
  674.         "vpermilps  $0x39, %%xmm3,  %%xmm2           \n\t"
  675.         "vmovss            %%xmm2, (%%rdx,%%r12)     \n\t"
  676.         "vpermilps  $0x39, %%xmm2,  %%xmm3           \n\t"
  677.         "vmovss            %%xmm3, (%%rdx,%%r13)     \n\t"
  678.         "                                            \n\t"
  679.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  680.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  681.         "                                            \n\t"
  682.         "                                            \n\t"
  683.         "                                            \n\t" // update c07:c77
  684.         "vmovlps    (%%rcx),        %%xmm0,  %%xmm0  \n\t"
  685.         "vmovhps    (%%rcx,%%rsi),  %%xmm0,  %%xmm0  \n\t"
  686.         "vmovlps    (%%rcx,%%r12),  %%xmm1,  %%xmm1  \n\t"
  687.         "vmovhps    (%%rcx,%%r13),  %%xmm1,  %%xmm1  \n\t"
  688.         "vshufps    $0x88, %%xmm1,  %%xmm0,  %%xmm0  \n\t"
  689.         "vmovlps    (%%rdx),        %%xmm2,  %%xmm2  \n\t"
  690.         "vmovhps    (%%rdx,%%rsi),  %%xmm2,  %%xmm2  \n\t"
  691.         "vmovlps    (%%rdx,%%r12),  %%xmm3,  %%xmm3  \n\t"
  692.         "vmovhps    (%%rdx,%%r13),  %%xmm3,  %%xmm3  \n\t"
  693.         "vshufps    $0x88, %%xmm3,  %%xmm2,  %%xmm2  \n\t"
  694.         "vperm2f128 $0x20, %%ymm2,  %%ymm0,  %%ymm0  \n\t"
  695.         "                                            \n\t"
  696.         "vmulps            %%ymm4,  %%ymm0,  %%ymm0  \n\t" // scale by beta,
  697.         "vaddps            %%ymm8,  %%ymm0,  %%ymm0  \n\t" // add the gemm result,
  698.         "                                            \n\t"
  699.         "vextractf128  $1, %%ymm0,  %%xmm2           \n\t"
  700.         "vmovss            %%xmm0, (%%rcx)           \n\t"
  701.         "vpermilps  $0x39, %%xmm0,  %%xmm1           \n\t"
  702.         "vmovss            %%xmm1, (%%rcx,%%rsi)     \n\t"
  703.         "vpermilps  $0x39, %%xmm1,  %%xmm0           \n\t"
  704.         "vmovss            %%xmm0, (%%rcx,%%r12)     \n\t"
  705.         "vpermilps  $0x39, %%xmm0,  %%xmm1           \n\t"
  706.         "vmovss            %%xmm1, (%%rcx,%%r13)     \n\t"
  707.         "vmovss            %%xmm2, (%%rdx)           \n\t"
  708.         "vpermilps  $0x39, %%xmm2,  %%xmm3           \n\t"
  709.         "vmovss            %%xmm3, (%%rdx,%%rsi)     \n\t"
  710.         "vpermilps  $0x39, %%xmm3,  %%xmm2           \n\t"
  711.         "vmovss            %%xmm2, (%%rdx,%%r12)     \n\t"
  712.         "vpermilps  $0x39, %%xmm2,  %%xmm3           \n\t"
  713.         "vmovss            %%xmm3, (%%rdx,%%r13)     \n\t"
  714.         "                                            \n\t"
  715.         "                                            \n\t"
  716.         "                                            \n\t"
  717.         "jmp    .SDONE                               \n\t" // jump to end.
  718.         "                                            \n\t"
  719.         "                                            \n\t"
  720.         "                                            \n\t"
  721.         ".SCOLSTORED:                                \n\t"
  722.         "                                            \n\t"
  723.         "                                            \n\t"
  724.         "vmovups    (%%rcx),       %%ymm0            \n\t" // load c00:c70,
  725.         "vmulps           %%ymm4,  %%ymm0,  %%ymm0   \n\t" // scale by beta,
  726.         "vaddps           %%ymm15, %%ymm0,  %%ymm0   \n\t" // add the gemm result,
  727.         "vmovups          %%ymm0,  (%%rcx)           \n\t" // and store back to memory.
  728.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  729.         "                                            \n\t"
  730.         "vmovups    (%%rcx),       %%ymm1            \n\t" // load c01:c71,
  731.         "vmulps           %%ymm4,  %%ymm1,  %%ymm1   \n\t" // scale by beta,
  732.         "vaddps           %%ymm14, %%ymm1,  %%ymm1   \n\t" // add the gemm result,
  733.         "vmovups          %%ymm1,  (%%rcx)           \n\t" // and store back to memory.
  734.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  735.         "                                            \n\t"
  736.         "vmovups    (%%rcx),       %%ymm0            \n\t" // load c02:c72,
  737.         "vmulps           %%ymm4,  %%ymm0,  %%ymm0   \n\t" // scale by beta,
  738.         "vaddps           %%ymm13, %%ymm0,  %%ymm0   \n\t" // add the gemm result,
  739.         "vmovups          %%ymm0,  (%%rcx)           \n\t" // and store back to memory.
  740.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  741.         "                                            \n\t"
  742.         "vmovups    (%%rcx),       %%ymm1            \n\t" // load c03:c73,
  743.         "vmulps           %%ymm4,  %%ymm1,  %%ymm1   \n\t" // scale by beta,
  744.         "vaddps           %%ymm12, %%ymm1,  %%ymm1   \n\t" // add the gemm result,
  745.         "vmovups          %%ymm1,  (%%rcx)           \n\t" // and store back to memory.
  746.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  747.         "                                            \n\t"
  748.         "vmovups    (%%rcx),       %%ymm0            \n\t" // load c04:c74,
  749.         "vmulps           %%ymm4,  %%ymm0,  %%ymm0   \n\t" // scale by beta,
  750.         "vaddps           %%ymm11, %%ymm0,  %%ymm0   \n\t" // add the gemm result,
  751.         "vmovups          %%ymm0,  (%%rcx)           \n\t" // and store back to memory.
  752.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  753.         "                                            \n\t"
  754.         "vmovups    (%%rcx),       %%ymm1            \n\t" // load c05:c75,
  755.         "vmulps           %%ymm4,  %%ymm1,  %%ymm1   \n\t" // scale by beta,
  756.         "vaddps           %%ymm10, %%ymm1,  %%ymm1   \n\t" // add the gemm result,
  757.         "vmovups          %%ymm1,  (%%rcx)           \n\t" // and store back to memory.
  758.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  759.         "                                            \n\t"
  760.         "vmovups    (%%rcx),       %%ymm0            \n\t" // load c06:c76,
  761.         "vmulps           %%ymm4,  %%ymm0,  %%ymm0   \n\t" // scale by beta,
  762.         "vaddps           %%ymm9,  %%ymm0,  %%ymm0   \n\t" // add the gemm result,
  763.         "vmovups          %%ymm0,  (%%rcx)           \n\t" // and store back to memory.
  764.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  765.         "                                            \n\t"
  766.         "vmovups    (%%rcx),       %%ymm1            \n\t" // load c07:c77,
  767.         "vmulps           %%ymm4,  %%ymm1,  %%ymm1   \n\t" // scale by beta,
  768.         "vaddps           %%ymm8,  %%ymm1,  %%ymm1   \n\t" // add the gemm result,
  769.         "vmovups          %%ymm1,  (%%rcx)           \n\t" // and store back to memory.
  770.         "                                            \n\t"
  771.         "                                            \n\t"
  772.         "jmp    .SDONE                               \n\t" // jump to end.
  773.         "                                            \n\t"
  774.         "                                            \n\t"
  775.         "                                            \n\t"
  776.         "                                            \n\t"
  777.         ".SBETAZERO:                                 \n\t"
  778.         "                                            \n\t"
  779.         "cmpq       $4, %%rsi                        \n\t" // set ZF if (4*cs_c) == 4.
  780.         "jz      .SCOLSTORBZ                         \n\t" // jump to column storage case
  781.         "                                            \n\t"
  782.         "                                            \n\t"
  783.         "                                            \n\t"
  784.         ".SGENSTORBZ:                                \n\t"
  785.         "                                            \n\t"
  786.         "                                            \n\t" // update c00:c70
  787.         "vmovups           %%ymm15, %%ymm0           \n\t"
  788.         "vextractf128  $1, %%ymm0,  %%xmm2           \n\t"
  789.         "vmovss            %%xmm0, (%%rcx)           \n\t"
  790.         "vpermilps  $0x39, %%xmm0,  %%xmm1           \n\t"
  791.         "vmovss            %%xmm1, (%%rcx,%%rsi)     \n\t"
  792.         "vpermilps  $0x39, %%xmm1,  %%xmm0           \n\t"
  793.         "vmovss            %%xmm0, (%%rcx,%%r12)     \n\t"
  794.         "vpermilps  $0x39, %%xmm0,  %%xmm1           \n\t"
  795.         "vmovss            %%xmm1, (%%rcx,%%r13)     \n\t"
  796.         "vmovss            %%xmm2, (%%rdx)           \n\t"
  797.         "vpermilps  $0x39, %%xmm2,  %%xmm3           \n\t"
  798.         "vmovss            %%xmm3, (%%rdx,%%rsi)     \n\t"
  799.         "vpermilps  $0x39, %%xmm3,  %%xmm2           \n\t"
  800.         "vmovss            %%xmm2, (%%rdx,%%r12)     \n\t"
  801.         "vpermilps  $0x39, %%xmm2,  %%xmm3           \n\t"
  802.         "vmovss            %%xmm3, (%%rdx,%%r13)     \n\t"
  803.         "                                            \n\t"
  804.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  805.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  806.         "                                            \n\t"
  807.         "                                            \n\t"
  808.         "                                            \n\t" // update c01:c71
  809.         "vmovups           %%ymm14, %%ymm0           \n\t"
  810.         "vextractf128  $1, %%ymm0,  %%xmm2           \n\t"
  811.         "vmovss            %%xmm0, (%%rcx)           \n\t"
  812.         "vpermilps  $0x39, %%xmm0,  %%xmm1           \n\t"
  813.         "vmovss            %%xmm1, (%%rcx,%%rsi)     \n\t"
  814.         "vpermilps  $0x39, %%xmm1,  %%xmm0           \n\t"
  815.         "vmovss            %%xmm0, (%%rcx,%%r12)     \n\t"
  816.         "vpermilps  $0x39, %%xmm0,  %%xmm1           \n\t"
  817.         "vmovss            %%xmm1, (%%rcx,%%r13)     \n\t"
  818.         "vmovss            %%xmm2, (%%rdx)           \n\t"
  819.         "vpermilps  $0x39, %%xmm2,  %%xmm3           \n\t"
  820.         "vmovss            %%xmm3, (%%rdx,%%rsi)     \n\t"
  821.         "vpermilps  $0x39, %%xmm3,  %%xmm2           \n\t"
  822.         "vmovss            %%xmm2, (%%rdx,%%r12)     \n\t"
  823.         "vpermilps  $0x39, %%xmm2,  %%xmm3           \n\t"
  824.         "vmovss            %%xmm3, (%%rdx,%%r13)     \n\t"
  825.         "                                            \n\t"
  826.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  827.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  828.         "                                            \n\t"
  829.         "                                            \n\t"
  830.         "                                            \n\t" // update c02:c72
  831.         "vmovups           %%ymm13, %%ymm0           \n\t"
  832.         "vextractf128  $1, %%ymm0,  %%xmm2           \n\t"
  833.         "vmovss            %%xmm0, (%%rcx)           \n\t"
  834.         "vpermilps  $0x39, %%xmm0,  %%xmm1           \n\t"
  835.         "vmovss            %%xmm1, (%%rcx,%%rsi)     \n\t"
  836.         "vpermilps  $0x39, %%xmm1,  %%xmm0           \n\t"
  837.         "vmovss            %%xmm0, (%%rcx,%%r12)     \n\t"
  838.         "vpermilps  $0x39, %%xmm0,  %%xmm1           \n\t"
  839.         "vmovss            %%xmm1, (%%rcx,%%r13)     \n\t"
  840.         "vmovss            %%xmm2, (%%rdx)           \n\t"
  841.         "vpermilps  $0x39, %%xmm2,  %%xmm3           \n\t"
  842.         "vmovss            %%xmm3, (%%rdx,%%rsi)     \n\t"
  843.         "vpermilps  $0x39, %%xmm3,  %%xmm2           \n\t"
  844.         "vmovss            %%xmm2, (%%rdx,%%r12)     \n\t"
  845.         "vpermilps  $0x39, %%xmm2,  %%xmm3           \n\t"
  846.         "vmovss            %%xmm3, (%%rdx,%%r13)     \n\t"
  847.         "                                            \n\t"
  848.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  849.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  850.         "                                            \n\t"
  851.         "                                            \n\t"
  852.         "                                            \n\t" // update c03:c73
  853.         "vmovups           %%ymm12, %%ymm0           \n\t"
  854.         "vextractf128  $1, %%ymm0,  %%xmm2           \n\t"
  855.         "vmovss            %%xmm0, (%%rcx)           \n\t"
  856.         "vpermilps  $0x39, %%xmm0,  %%xmm1           \n\t"
  857.         "vmovss            %%xmm1, (%%rcx,%%rsi)     \n\t"
  858.         "vpermilps  $0x39, %%xmm1,  %%xmm0           \n\t"
  859.         "vmovss            %%xmm0, (%%rcx,%%r12)     \n\t"
  860.         "vpermilps  $0x39, %%xmm0,  %%xmm1           \n\t"
  861.         "vmovss            %%xmm1, (%%rcx,%%r13)     \n\t"
  862.         "vmovss            %%xmm2, (%%rdx)           \n\t"
  863.         "vpermilps  $0x39, %%xmm2,  %%xmm3           \n\t"
  864.         "vmovss            %%xmm3, (%%rdx,%%rsi)     \n\t"
  865.         "vpermilps  $0x39, %%xmm3,  %%xmm2           \n\t"
  866.         "vmovss            %%xmm2, (%%rdx,%%r12)     \n\t"
  867.         "vpermilps  $0x39, %%xmm2,  %%xmm3           \n\t"
  868.         "vmovss            %%xmm3, (%%rdx,%%r13)     \n\t"
  869.         "                                            \n\t"
  870.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  871.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  872.         "                                            \n\t"
  873.         "                                            \n\t"
  874.         "                                            \n\t" // update c04:c74
  875.         "vmovups           %%ymm11, %%ymm0           \n\t"
  876.         "vextractf128  $1, %%ymm0,  %%xmm2           \n\t"
  877.         "vmovss            %%xmm0, (%%rcx)           \n\t"
  878.         "vpermilps  $0x39, %%xmm0,  %%xmm1           \n\t"
  879.         "vmovss            %%xmm1, (%%rcx,%%rsi)     \n\t"
  880.         "vpermilps  $0x39, %%xmm1,  %%xmm0           \n\t"
  881.         "vmovss            %%xmm0, (%%rcx,%%r12)     \n\t"
  882.         "vpermilps  $0x39, %%xmm0,  %%xmm1           \n\t"
  883.         "vmovss            %%xmm1, (%%rcx,%%r13)     \n\t"
  884.         "vmovss            %%xmm2, (%%rdx)           \n\t"
  885.         "vpermilps  $0x39, %%xmm2,  %%xmm3           \n\t"
  886.         "vmovss            %%xmm3, (%%rdx,%%rsi)     \n\t"
  887.         "vpermilps  $0x39, %%xmm3,  %%xmm2           \n\t"
  888.         "vmovss            %%xmm2, (%%rdx,%%r12)     \n\t"
  889.         "vpermilps  $0x39, %%xmm2,  %%xmm3           \n\t"
  890.         "vmovss            %%xmm3, (%%rdx,%%r13)     \n\t"
  891.         "                                            \n\t"
  892.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  893.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  894.         "                                            \n\t"
  895.         "                                            \n\t"
  896.         "                                            \n\t" // update c05:c75
  897.         "vmovups           %%ymm10, %%ymm0           \n\t"
  898.         "vextractf128  $1, %%ymm0,  %%xmm2           \n\t"
  899.         "vmovss            %%xmm0, (%%rcx)           \n\t"
  900.         "vpermilps  $0x39, %%xmm0,  %%xmm1           \n\t"
  901.         "vmovss            %%xmm1, (%%rcx,%%rsi)     \n\t"
  902.         "vpermilps  $0x39, %%xmm1,  %%xmm0           \n\t"
  903.         "vmovss            %%xmm0, (%%rcx,%%r12)     \n\t"
  904.         "vpermilps  $0x39, %%xmm0,  %%xmm1           \n\t"
  905.         "vmovss            %%xmm1, (%%rcx,%%r13)     \n\t"
  906.         "vmovss            %%xmm2, (%%rdx)           \n\t"
  907.         "vpermilps  $0x39, %%xmm2,  %%xmm3           \n\t"
  908.         "vmovss            %%xmm3, (%%rdx,%%rsi)     \n\t"
  909.         "vpermilps  $0x39, %%xmm3,  %%xmm2           \n\t"
  910.         "vmovss            %%xmm2, (%%rdx,%%r12)     \n\t"
  911.         "vpermilps  $0x39, %%xmm2,  %%xmm3           \n\t"
  912.         "vmovss            %%xmm3, (%%rdx,%%r13)     \n\t"
  913.         "                                            \n\t"
  914.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  915.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  916.         "                                            \n\t"
  917.         "                                            \n\t"
  918.         "                                            \n\t" // update c06:c76
  919.         "vmovups           %%ymm9,  %%ymm0           \n\t"
  920.         "vextractf128  $1, %%ymm0,  %%xmm2           \n\t"
  921.         "vmovss            %%xmm0, (%%rcx)           \n\t"
  922.         "vpermilps  $0x39, %%xmm0,  %%xmm1           \n\t"
  923.         "vmovss            %%xmm1, (%%rcx,%%rsi)     \n\t"
  924.         "vpermilps  $0x39, %%xmm1,  %%xmm0           \n\t"
  925.         "vmovss            %%xmm0, (%%rcx,%%r12)     \n\t"
  926.         "vpermilps  $0x39, %%xmm0,  %%xmm1           \n\t"
  927.         "vmovss            %%xmm1, (%%rcx,%%r13)     \n\t"
  928.         "vmovss            %%xmm2, (%%rdx)           \n\t"
  929.         "vpermilps  $0x39, %%xmm2,  %%xmm3           \n\t"
  930.         "vmovss            %%xmm3, (%%rdx,%%rsi)     \n\t"
  931.         "vpermilps  $0x39, %%xmm3,  %%xmm2           \n\t"
  932.         "vmovss            %%xmm2, (%%rdx,%%r12)     \n\t"
  933.         "vpermilps  $0x39, %%xmm2,  %%xmm3           \n\t"
  934.         "vmovss            %%xmm3, (%%rdx,%%r13)     \n\t"
  935.         "                                            \n\t"
  936.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  937.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  938.         "                                            \n\t"
  939.         "                                            \n\t"
  940.         "                                            \n\t" // update c07:c77
  941.         "vmovups           %%ymm8,  %%ymm0           \n\t"
  942.         "vextractf128  $1, %%ymm0,  %%xmm2           \n\t"
  943.         "vmovss            %%xmm0, (%%rcx)           \n\t"
  944.         "vpermilps  $0x39, %%xmm0,  %%xmm1           \n\t"
  945.         "vmovss            %%xmm1, (%%rcx,%%rsi)     \n\t"
  946.         "vpermilps  $0x39, %%xmm1,  %%xmm0           \n\t"
  947.         "vmovss            %%xmm0, (%%rcx,%%r12)     \n\t"
  948.         "vpermilps  $0x39, %%xmm0,  %%xmm1           \n\t"
  949.         "vmovss            %%xmm1, (%%rcx,%%r13)     \n\t"
  950.         "vmovss            %%xmm2, (%%rdx)           \n\t"
  951.         "vpermilps  $0x39, %%xmm2,  %%xmm3           \n\t"
  952.         "vmovss            %%xmm3, (%%rdx,%%rsi)     \n\t"
  953.         "vpermilps  $0x39, %%xmm3,  %%xmm2           \n\t"
  954.         "vmovss            %%xmm2, (%%rdx,%%r12)     \n\t"
  955.         "vpermilps  $0x39, %%xmm2,  %%xmm3           \n\t"
  956.         "vmovss            %%xmm3, (%%rdx,%%r13)     \n\t"
  957.         "                                            \n\t"
  958.         "                                            \n\t"
  959.         "jmp    .SDONE                               \n\t" // jump to end.
  960.         "                                            \n\t"
  961.         "                                            \n\t"
  962.         "                                            \n\t"
  963.         ".SCOLSTORBZ:                                \n\t"
  964.         "                                            \n\t"
  965.         "                                            \n\t"
  966.         "vmovups          %%ymm15, (%%rcx)           \n\t" // and store back to memory.
  967.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  968.         "                                            \n\t"
  969.         "vmovups          %%ymm14, (%%rcx)           \n\t" // and store back to memory.
  970.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  971.         "                                            \n\t"
  972.         "vmovups          %%ymm13, (%%rcx)           \n\t" // and store back to memory.
  973.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  974.         "                                            \n\t"
  975.         "vmovups          %%ymm12, (%%rcx)           \n\t" // and store back to memory.
  976.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  977.         "                                            \n\t"
  978.         "vmovups          %%ymm11, (%%rcx)           \n\t" // and store back to memory.
  979.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  980.         "                                            \n\t"
  981.         "vmovups          %%ymm10, (%%rcx)           \n\t" // and store back to memory.
  982.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  983.         "                                            \n\t"
  984.         "vmovups          %%ymm9,  (%%rcx)           \n\t" // and store back to memory.
  985.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  986.         "                                            \n\t"
  987.         "vmovups          %%ymm8,  (%%rcx)           \n\t" // and store back to memory.
  988.         "                                            \n\t"
  989.         "                                            \n\t"
  990.         "                                            \n\t"
  991.         "                                            \n\t"
  992.         "                                            \n\t"
  993.         ".SDONE:                                     \n\t"
  994.     "                                            \n\t"
  995.     "vzeroupper                                  \n\t"
  996.     "                                            \n\t"
  997.  
  998.         : // output operands (none)
  999.         : // input operands
  1000.           "m" (k_iter), // 0
  1001.           "m" (k_left), // 1
  1002.           "m" (a),      // 2
  1003.           "m" (b),      // 3
  1004.           "m" (alpha),  // 4
  1005.           "m" (beta),   // 5
  1006.           "m" (c),      // 6
  1007.           "m" (rs_c),   // 7
  1008.           "m" (cs_c)/*,   // 8
  1009.           "m" (b_next), // 9
  1010.           "m" (a_next)*/  // 10
  1011.         : // register clobber list
  1012.           "rax", "rbx", "rcx", "rdx", "rsi", "rdi",
  1013.           "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
  1014.           "xmm0", "xmm1", "xmm2", "xmm3",
  1015.           "xmm4", "xmm5", "xmm6", "xmm7",
  1016.           "xmm8", "xmm9", "xmm10", "xmm11",
  1017.           "xmm12", "xmm13", "xmm14", "xmm15",
  1018.           "memory"
  1019.         );
  1020. }
  1021.  
  1022. void bli_dgemm_asm_8x4
  1023.      (
  1024.        dim_t               k,
  1025.        double*    restrict alpha,
  1026.        double*    restrict a,
  1027.        double*    restrict b,
  1028.        double*    restrict beta,
  1029.        double*    restrict c, inc_t rs_c, inc_t cs_c,
  1030.        auxinfo_t* restrict data,
  1031.        cntx_t*    restrict cntx
  1032.      )
  1033. {
  1034.         //void*   a_next = bli_auxinfo_next_a( data );
  1035.         void*   b_next = bli_auxinfo_next_b( data );
  1036.  
  1037.         uint64_t   k_iter = k / 4;
  1038.         uint64_t   k_left = k % 4;
  1039.  
  1040.         __asm__ volatile
  1041.         (
  1042.         "                                            \n\t"
  1043.         "                                            \n\t"
  1044.         "movq                %2, %%rax               \n\t" // load address of a.
  1045.         "movq                %3, %%rbx               \n\t" // load address of b.
  1046.         "movq                %9, %%r15               \n\t" // load address of b_next.
  1047.         //"movq               %10, %%r14               \n\t" // load address of a_next.
  1048.         "addq          $-4 * 64, %%r15               \n\t"
  1049.         "                                            \n\t"
  1050.         "vmovapd   0 * 32(%%rax), %%ymm0             \n\t" // initialize loop by pre-loading
  1051.         "vmovapd   0 * 32(%%rbx), %%ymm2             \n\t" // elements of a and b.
  1052.         "vpermilpd  $0x5, %%ymm2, %%ymm3             \n\t"
  1053.         "                                            \n\t"
  1054.         "movq                %6, %%rcx               \n\t" // load address of c
  1055.         "movq                %8, %%rdi               \n\t" // load cs_c
  1056.         "leaq        (,%%rdi,8), %%rdi               \n\t" // cs_c *= sizeof(double)
  1057.         "leaq   (%%rcx,%%rdi,2), %%r10               \n\t" // load address of c + 2*cs_c;
  1058.         "                                            \n\t"
  1059.         "prefetcht0   3 * 8(%%rcx)                   \n\t" // prefetch c + 0*cs_c
  1060.         "prefetcht0   3 * 8(%%rcx,%%rdi)             \n\t" // prefetch c + 1*cs_c
  1061.         "prefetcht0   3 * 8(%%r10)                   \n\t" // prefetch c + 2*cs_c
  1062.         "prefetcht0   3 * 8(%%r10,%%rdi)             \n\t" // prefetch c + 3*cs_c
  1063.         "                                            \n\t"
  1064.         "vxorpd    %%ymm8,  %%ymm8,  %%ymm8          \n\t"
  1065.         "vxorpd    %%ymm9,  %%ymm9,  %%ymm9          \n\t"
  1066.         "vxorpd    %%ymm10, %%ymm10, %%ymm10         \n\t"
  1067.         "vxorpd    %%ymm11, %%ymm11, %%ymm11         \n\t"
  1068.         "vxorpd    %%ymm12, %%ymm12, %%ymm12         \n\t"
  1069.         "vxorpd    %%ymm13, %%ymm13, %%ymm13         \n\t"
  1070.         "vxorpd    %%ymm14, %%ymm14, %%ymm14         \n\t"
  1071.         "vxorpd    %%ymm15, %%ymm15, %%ymm15         \n\t"
  1072.         "                                            \n\t"
  1073.         "                                            \n\t"
  1074.         "                                            \n\t"
  1075.         "movq      %0, %%rsi                         \n\t" // i = k_iter;
  1076.         "testq  %%rsi, %%rsi                         \n\t" // check i via logical AND.
  1077.         "je     .DCONSIDKLEFT                        \n\t" // if i == 0, jump to code that
  1078.         "                                            \n\t" // contains the k_left loop.
  1079.         "                                            \n\t"
  1080.         "                                            \n\t"
  1081.         ".DLOOPKITER:                                \n\t" // MAIN LOOP
  1082.         "                                            \n\t"
  1083.         "addq         $4 * 4 * 8,  %%r15             \n\t" // b_next += 4*4 (unroll x nr)
  1084.         "                                            \n\t"
  1085.         "                                            \n\t" // iteration 0
  1086.         "vmovapd   1 * 32(%%rax),  %%ymm1            \n\t"
  1087.         "vmulpd           %%ymm0,  %%ymm2,  %%ymm6   \n\t"
  1088.         "vperm2f128 $0x3, %%ymm2,  %%ymm2,  %%ymm4   \n\t"
  1089.         "vmulpd           %%ymm0,  %%ymm3,  %%ymm7   \n\t"
  1090.         "vperm2f128 $0x3, %%ymm3,  %%ymm3,  %%ymm5   \n\t"
  1091.         "vaddpd           %%ymm15, %%ymm6,  %%ymm15  \n\t"
  1092.         "vaddpd           %%ymm13, %%ymm7,  %%ymm13  \n\t"
  1093.         "                                            \n\t"
  1094.         "prefetcht0  16 * 32(%%rax)                  \n\t"
  1095.         "vmulpd           %%ymm1,  %%ymm2,  %%ymm6   \n\t"
  1096.         "vmovapd   1 * 32(%%rbx),  %%ymm2            \n\t"
  1097.         "vmulpd           %%ymm1,  %%ymm3,  %%ymm7   \n\t"
  1098.         "vpermilpd  $0x5, %%ymm2,  %%ymm3            \n\t"
  1099.         "vaddpd           %%ymm14, %%ymm6,  %%ymm14  \n\t"
  1100.         "vaddpd           %%ymm12, %%ymm7,  %%ymm12  \n\t"
  1101.         "                                            \n\t"
  1102.         "vmulpd           %%ymm0,  %%ymm4,  %%ymm6   \n\t"
  1103.         "vmulpd           %%ymm0,  %%ymm5,  %%ymm7   \n\t"
  1104.         "vmovapd   2 * 32(%%rax),  %%ymm0            \n\t"
  1105.         "vaddpd           %%ymm11, %%ymm6,  %%ymm11  \n\t"
  1106.         "vaddpd           %%ymm9,  %%ymm7,  %%ymm9   \n\t"
  1107.         "prefetcht0   0 * 32(%%r15)                  \n\t" // prefetch b_next[0*4]
  1108.         "                                            \n\t"
  1109.         "vmulpd           %%ymm1,  %%ymm4,  %%ymm6   \n\t"
  1110.         "vmulpd           %%ymm1,  %%ymm5,  %%ymm7   \n\t"
  1111.         "vaddpd           %%ymm10, %%ymm6,  %%ymm10  \n\t"
  1112.         "vaddpd           %%ymm8,  %%ymm7,  %%ymm8   \n\t"
  1113.         "                                            \n\t"
  1114.         "                                            \n\t"
  1115.         "                                            \n\t" // iteration 1
  1116.         "vmovapd   3 * 32(%%rax),  %%ymm1            \n\t"
  1117.         "vmulpd           %%ymm0,  %%ymm2,  %%ymm6   \n\t"
  1118.         "vperm2f128 $0x3, %%ymm2,  %%ymm2,  %%ymm4   \n\t"
  1119.         "vmulpd           %%ymm0,  %%ymm3,  %%ymm7   \n\t"
  1120.         "vperm2f128 $0x3, %%ymm3,  %%ymm3,  %%ymm5   \n\t"
  1121.         "vaddpd           %%ymm15, %%ymm6,  %%ymm15  \n\t"
  1122.         "vaddpd           %%ymm13, %%ymm7,  %%ymm13  \n\t"
  1123.         "                                            \n\t"
  1124.         "prefetcht0  18 * 32(%%rax)                  \n\t"
  1125.         "vmulpd           %%ymm1,  %%ymm2,  %%ymm6   \n\t"
  1126.         "vmovapd   2 * 32(%%rbx),  %%ymm2            \n\t"
  1127.         "vmulpd           %%ymm1,  %%ymm3,  %%ymm7   \n\t"
  1128.         "vpermilpd  $0x5, %%ymm2,  %%ymm3            \n\t"
  1129.         "vaddpd           %%ymm14, %%ymm6,  %%ymm14  \n\t"
  1130.         "vaddpd           %%ymm12, %%ymm7,  %%ymm12  \n\t"
  1131.         "                                            \n\t"
  1132.         "vmulpd           %%ymm0,  %%ymm4,  %%ymm6   \n\t"
  1133.         "vmulpd           %%ymm0,  %%ymm5,  %%ymm7   \n\t"
  1134.         "vmovapd   4 * 32(%%rax),  %%ymm0            \n\t"
  1135.         "vaddpd           %%ymm11, %%ymm6,  %%ymm11  \n\t"
  1136.         "vaddpd           %%ymm9,  %%ymm7,  %%ymm9   \n\t"
  1137.         "                                            \n\t"
  1138.         "vmulpd           %%ymm1,  %%ymm4,  %%ymm6   \n\t"
  1139.         "vmulpd           %%ymm1,  %%ymm5,  %%ymm7   \n\t"
  1140.         "vaddpd           %%ymm10, %%ymm6,  %%ymm10  \n\t"
  1141.         "vaddpd           %%ymm8,  %%ymm7,  %%ymm8   \n\t"
  1142.         "                                            \n\t"
  1143.         "                                            \n\t"
  1144.         "                                            \n\t" // iteration 2
  1145.         "vmovapd   5 * 32(%%rax),  %%ymm1            \n\t"
  1146.         "vmulpd           %%ymm0,  %%ymm2,  %%ymm6   \n\t"
  1147.         "vperm2f128 $0x3, %%ymm2,  %%ymm2,  %%ymm4   \n\t"
  1148.         "vmulpd           %%ymm0,  %%ymm3,  %%ymm7   \n\t"
  1149.         "vperm2f128 $0x3, %%ymm3,  %%ymm3,  %%ymm5   \n\t"
  1150.         "vaddpd           %%ymm15, %%ymm6,  %%ymm15  \n\t"
  1151.         "vaddpd           %%ymm13, %%ymm7,  %%ymm13  \n\t"
  1152.         "                                            \n\t"
  1153.         "prefetcht0  20 * 32(%%rax)                  \n\t"
  1154.         "vmulpd           %%ymm1,  %%ymm2,  %%ymm6   \n\t"
  1155.         "vmovapd   3 * 32(%%rbx),  %%ymm2            \n\t"
  1156.         "addq         $4 * 4 * 8,  %%rbx             \n\t" // b += 4*4 (unroll x nr)
  1157.         "vmulpd           %%ymm1,  %%ymm3,  %%ymm7   \n\t"
  1158.         "vpermilpd  $0x5, %%ymm2,  %%ymm3            \n\t"
  1159.         "vaddpd           %%ymm14, %%ymm6,  %%ymm14  \n\t"
  1160.         "vaddpd           %%ymm12, %%ymm7,  %%ymm12  \n\t"
  1161.         "                                            \n\t"
  1162.         "vmulpd           %%ymm0,  %%ymm4,  %%ymm6   \n\t"
  1163.         "vmulpd           %%ymm0,  %%ymm5,  %%ymm7   \n\t"
  1164.         "vmovapd   6 * 32(%%rax),  %%ymm0            \n\t"
  1165.         "vaddpd           %%ymm11, %%ymm6,  %%ymm11  \n\t"
  1166.         "vaddpd           %%ymm9,  %%ymm7,  %%ymm9   \n\t"
  1167.         "prefetcht0   2 * 32(%%r15)                  \n\t" // prefetch b_next[2*4]
  1168.         "                                            \n\t"
  1169.         "vmulpd           %%ymm1,  %%ymm4,  %%ymm6   \n\t"
  1170.         "vmulpd           %%ymm1,  %%ymm5,  %%ymm7   \n\t"
  1171.         "vaddpd           %%ymm10, %%ymm6,  %%ymm10  \n\t"
  1172.         "vaddpd           %%ymm8,  %%ymm7,  %%ymm8   \n\t"
  1173.         "                                            \n\t"
  1174.         "                                            \n\t"
  1175.         "                                            \n\t" // iteration 3
  1176.         "vmovapd   7 * 32(%%rax),  %%ymm1            \n\t"
  1177.         "addq         $4 * 8 * 8,  %%rax             \n\t" // a += 4*8 (unroll x mr)
  1178.         "vmulpd           %%ymm0,  %%ymm2,  %%ymm6   \n\t"
  1179.         "vperm2f128 $0x3, %%ymm2,  %%ymm2,  %%ymm4   \n\t"
  1180.         "vmulpd           %%ymm0,  %%ymm3,  %%ymm7   \n\t"
  1181.         "vperm2f128 $0x3, %%ymm3,  %%ymm3,  %%ymm5   \n\t"
  1182.         "vaddpd           %%ymm15, %%ymm6,  %%ymm15  \n\t"
  1183.         "vaddpd           %%ymm13, %%ymm7,  %%ymm13  \n\t"
  1184.         "                                            \n\t"
  1185.         //"prefetcht0  22 * 32(%%rax)                  \n\t"
  1186.         "prefetcht0  14 * 32(%%rax)                  \n\t"
  1187.         "vmulpd           %%ymm1,  %%ymm2,  %%ymm6   \n\t"
  1188.         "vmovapd   0 * 32(%%rbx),  %%ymm2            \n\t"
  1189.         "vmulpd           %%ymm1,  %%ymm3,  %%ymm7   \n\t"
  1190.         "vpermilpd  $0x5, %%ymm2,  %%ymm3            \n\t"
  1191.         "vaddpd           %%ymm14, %%ymm6,  %%ymm14  \n\t"
  1192.         "vaddpd           %%ymm12, %%ymm7,  %%ymm12  \n\t"
  1193.         "                                            \n\t"
  1194.         "vmulpd           %%ymm0,  %%ymm4,  %%ymm6   \n\t"
  1195.         "vmulpd           %%ymm0,  %%ymm5,  %%ymm7   \n\t"
  1196.         "vmovapd   0 * 32(%%rax),  %%ymm0            \n\t"
  1197.         "vaddpd           %%ymm11, %%ymm6,  %%ymm11  \n\t"
  1198.         "vaddpd           %%ymm9,  %%ymm7,  %%ymm9   \n\t"
  1199.         "                                            \n\t"
  1200.         "vmulpd           %%ymm1,  %%ymm4,  %%ymm6   \n\t"
  1201.         "vmulpd           %%ymm1,  %%ymm5,  %%ymm7   \n\t"
  1202.         "vaddpd           %%ymm10, %%ymm6,  %%ymm10  \n\t"
  1203.         "vaddpd           %%ymm8,  %%ymm7,  %%ymm8   \n\t"
  1204.         "                                            \n\t"
  1205.         "                                            \n\t"
  1206.         "                                            \n\t"
  1207.         //"addq   $4 * 8 * 8, %%rax                    \n\t" // a      += 4*8 (unroll x mr)
  1208.         //"addq   $4 * 4 * 8, %%rbx                    \n\t" // b      += 4*4 (unroll x nr)
  1209.         "                                            \n\t"
  1210.         "decq   %%rsi                                \n\t" // i -= 1;
  1211.         "jne    .DLOOPKITER                          \n\t" // iterate again if i != 0.
  1212.         "                                            \n\t"
  1213.         "                                            \n\t"
  1214.         "                                            \n\t"
  1215.         "                                            \n\t"
  1216.         "                                            \n\t"
  1217.         "                                            \n\t"
  1218.         ".DCONSIDKLEFT:                              \n\t"
  1219.         "                                            \n\t"
  1220.         "movq      %1, %%rsi                         \n\t" // i = k_left;
  1221.         "testq  %%rsi, %%rsi                         \n\t" // check i via logical AND.
  1222.         "je     .DPOSTACCUM                          \n\t" // if i == 0, we're done; jump to end.
  1223.         "                                            \n\t" // else, we prepare to enter k_left loop.
  1224.         "                                            \n\t"
  1225.         "                                            \n\t"
  1226.         ".DLOOPKLEFT:                                \n\t" // EDGE LOOP
  1227.         "                                            \n\t"
  1228.         "vmovapd   1 * 32(%%rax),  %%ymm1            \n\t"
  1229.         "addq         $8 * 1 * 8,  %%rax             \n\t" // a += 8 (1 x mr)
  1230.         "vmulpd           %%ymm0,  %%ymm2, %%ymm6    \n\t"
  1231.         "vperm2f128 $0x3, %%ymm2,  %%ymm2, %%ymm4    \n\t"
  1232.         "vmulpd           %%ymm0,  %%ymm3, %%ymm7    \n\t"
  1233.         "vperm2f128 $0x3, %%ymm3,  %%ymm3, %%ymm5    \n\t"
  1234.         "vaddpd           %%ymm15, %%ymm6, %%ymm15   \n\t"
  1235.         "vaddpd           %%ymm13, %%ymm7, %%ymm13   \n\t"
  1236.         "                                            \n\t"
  1237.         "prefetcht0  14 * 32(%%rax)                  \n\t"
  1238.         "vmulpd           %%ymm1,  %%ymm2, %%ymm6    \n\t"
  1239.         "vmovapd   1 * 32(%%rbx),  %%ymm2            \n\t"
  1240.         "addq         $4 * 1 * 8,  %%rbx             \n\t" // b += 4 (1 x nr)
  1241.         "vmulpd           %%ymm1,  %%ymm3, %%ymm7    \n\t"
  1242.         "vpermilpd  $0x5, %%ymm2,  %%ymm3            \n\t"
  1243.         "vaddpd           %%ymm14, %%ymm6, %%ymm14   \n\t"
  1244.         "vaddpd           %%ymm12, %%ymm7, %%ymm12   \n\t"
  1245.         "                                            \n\t"
  1246.         "vmulpd           %%ymm0,  %%ymm4, %%ymm6    \n\t"
  1247.         "vmulpd           %%ymm0,  %%ymm5, %%ymm7    \n\t"
  1248.         "vmovapd   0 * 32(%%rax),  %%ymm0            \n\t"
  1249.         "vaddpd           %%ymm11, %%ymm6, %%ymm11   \n\t"
  1250.         "vaddpd           %%ymm9,  %%ymm7, %%ymm9    \n\t"
  1251.         "                                            \n\t"
  1252.         "vmulpd           %%ymm1,  %%ymm4, %%ymm6    \n\t"
  1253.         "vmulpd           %%ymm1,  %%ymm5, %%ymm7    \n\t"
  1254.         "vaddpd           %%ymm10, %%ymm6, %%ymm10   \n\t"
  1255.         "vaddpd           %%ymm8,  %%ymm7, %%ymm8    \n\t"
  1256.         "                                            \n\t"
  1257.         "                                            \n\t"
  1258.         "decq   %%rsi                                \n\t" // i -= 1;
  1259.         "jne    .DLOOPKLEFT                          \n\t" // iterate again if i != 0.
  1260.         "                                            \n\t"
  1261.         "                                            \n\t"
  1262.         "                                            \n\t"
  1263.         ".DPOSTACCUM:                                \n\t"
  1264.         "                                            \n\t"
  1265.         "                                            \n\t"
  1266.         "                                            \n\t" // ymm15:  ymm13:  ymm11:  ymm9:
  1267.         "                                            \n\t" // ( ab00  ( ab01  ( ab02  ( ab03
  1268.         "                                            \n\t" //   ab11    ab10    ab13    ab12  
  1269.         "                                            \n\t" //   ab22    ab23    ab20    ab21
  1270.         "                                            \n\t" //   ab33 )  ab32 )  ab31 )  ab30 )
  1271.         "                                            \n\t"
  1272.         "                                            \n\t" // ymm14:  ymm12:  ymm10:  ymm8:
  1273.         "                                            \n\t" // ( ab40  ( ab41  ( ab42  ( ab43
  1274.         "                                            \n\t" //   ab51    ab50    ab53    ab52  
  1275.         "                                            \n\t" //   ab62    ab63    ab60    ab61
  1276.         "                                            \n\t" //   ab73 )  ab72 )  ab71 )  ab70 )
  1277.         "                                            \n\t"
  1278.         "vmovapd          %%ymm15, %%ymm7            \n\t"
  1279.         "vshufpd    $0xa, %%ymm15, %%ymm13, %%ymm15  \n\t"
  1280.         "vshufpd    $0xa, %%ymm13, %%ymm7,  %%ymm13  \n\t"
  1281.         "                                            \n\t"
  1282.         "vmovapd          %%ymm11, %%ymm7            \n\t"
  1283.         "vshufpd    $0xa, %%ymm11, %%ymm9,  %%ymm11  \n\t"
  1284.         "vshufpd    $0xa, %%ymm9,  %%ymm7,  %%ymm9   \n\t"
  1285.         "                                            \n\t"
  1286.         "vmovapd          %%ymm14, %%ymm7            \n\t"
  1287.         "vshufpd    $0xa, %%ymm14, %%ymm12, %%ymm14  \n\t"
  1288.         "vshufpd    $0xa, %%ymm12, %%ymm7,  %%ymm12  \n\t"
  1289.         "                                            \n\t"
  1290.         "vmovapd          %%ymm10, %%ymm7            \n\t"
  1291.         "vshufpd    $0xa, %%ymm10, %%ymm8,  %%ymm10  \n\t"
  1292.         "vshufpd    $0xa, %%ymm8,  %%ymm7,  %%ymm8   \n\t"
  1293.         "                                            \n\t"
  1294.         "                                            \n\t" // ymm15:  ymm13:  ymm11:  ymm9:
  1295.         "                                            \n\t" // ( ab01  ( ab00  ( ab03  ( ab02
  1296.         "                                            \n\t" //   ab11    ab10    ab13    ab12  
  1297.         "                                            \n\t" //   ab23    ab22    ab21    ab20
  1298.         "                                            \n\t" //   ab33 )  ab32 )  ab31 )  ab30 )
  1299.         "                                            \n\t"
  1300.         "                                            \n\t" // ymm14:  ymm12:  ymm10:  ymm8:
  1301.         "                                            \n\t" // ( ab41  ( ab40  ( ab43  ( ab42
  1302.         "                                            \n\t" //   ab51    ab50    ab53    ab52  
  1303.         "                                            \n\t" //   ab63    ab62    ab61    ab60
  1304.         "                                            \n\t" //   ab73 )  ab72 )  ab71 )  ab70 )
  1305.         "                                            \n\t"
  1306.         "vmovapd           %%ymm15, %%ymm7           \n\t"
  1307.         "vperm2f128 $0x30, %%ymm15, %%ymm11, %%ymm15 \n\t"
  1308.         "vperm2f128 $0x12, %%ymm7,  %%ymm11, %%ymm11 \n\t"
  1309.         "                                            \n\t"
  1310.         "vmovapd           %%ymm13, %%ymm7           \n\t"
  1311.         "vperm2f128 $0x30, %%ymm13, %%ymm9,  %%ymm13 \n\t"
  1312.         "vperm2f128 $0x12, %%ymm7,  %%ymm9,  %%ymm9  \n\t"
  1313.         "                                            \n\t"
  1314.         "vmovapd           %%ymm14, %%ymm7           \n\t"
  1315.         "vperm2f128 $0x30, %%ymm14, %%ymm10, %%ymm14 \n\t"
  1316.         "vperm2f128 $0x12, %%ymm7,  %%ymm10, %%ymm10 \n\t"
  1317.         "                                            \n\t"
  1318.         "vmovapd           %%ymm12, %%ymm7           \n\t"
  1319.         "vperm2f128 $0x30, %%ymm12, %%ymm8,  %%ymm12 \n\t"
  1320.         "vperm2f128 $0x12, %%ymm7,  %%ymm8,  %%ymm8  \n\t"
  1321.         "                                            \n\t"
  1322.         "                                            \n\t" // ymm9:   ymm11:  ymm13:  ymm15:
  1323.         "                                            \n\t" // ( ab00  ( ab01  ( ab02  ( ab03
  1324.         "                                            \n\t" //   ab10    ab11    ab12    ab13  
  1325.         "                                            \n\t" //   ab20    ab21    ab22    ab23
  1326.         "                                            \n\t" //   ab30 )  ab31 )  ab32 )  ab33 )
  1327.         "                                            \n\t"
  1328.         "                                            \n\t" // ymm8:   ymm10:  ymm12:  ymm14:
  1329.         "                                            \n\t" // ( ab40  ( ab41  ( ab42  ( ab43
  1330.         "                                            \n\t" //   ab50    ab51    ab52    ab53  
  1331.         "                                            \n\t" //   ab60    ab61    ab62    ab63
  1332.         "                                            \n\t" //   ab70 )  ab71 )  ab72 )  ab73 )
  1333.         "                                            \n\t"
  1334.         "                                            \n\t"
  1335.         "movq         %4, %%rax                      \n\t" // load address of alpha
  1336.         "movq         %5, %%rbx                      \n\t" // load address of beta
  1337.         "vbroadcastsd    (%%rax), %%ymm0             \n\t" // load alpha and duplicate
  1338.         "vbroadcastsd    (%%rbx), %%ymm2             \n\t" // load beta and duplicate
  1339.         "                                            \n\t"
  1340.         "vmulpd           %%ymm0,  %%ymm8,  %%ymm8   \n\t" // scale by alpha
  1341.         "vmulpd           %%ymm0,  %%ymm9,  %%ymm9   \n\t"
  1342.         "vmulpd           %%ymm0,  %%ymm10, %%ymm10  \n\t"
  1343.         "vmulpd           %%ymm0,  %%ymm11, %%ymm11  \n\t"
  1344.         "vmulpd           %%ymm0,  %%ymm12, %%ymm12  \n\t"
  1345.         "vmulpd           %%ymm0,  %%ymm13, %%ymm13  \n\t"
  1346.         "vmulpd           %%ymm0,  %%ymm14, %%ymm14  \n\t"
  1347.         "vmulpd           %%ymm0,  %%ymm15, %%ymm15  \n\t"
  1348.         "                                            \n\t"
  1349.         "                                            \n\t"
  1350.         "                                            \n\t"
  1351.         "                                            \n\t"
  1352.         "                                            \n\t"
  1353.         "                                            \n\t"
  1354.         "movq                %7, %%rsi               \n\t" // load rs_c
  1355.         "leaq        (,%%rsi,8), %%rsi               \n\t" // rsi = rs_c * sizeof(double)
  1356.         "                                            \n\t"
  1357.         "leaq   (%%rcx,%%rsi,4), %%rdx               \n\t" // load address of c + 4*rs_c;
  1358.         "                                            \n\t"
  1359.         "leaq        (,%%rsi,2), %%r12               \n\t" // r12 = 2*rs_c;
  1360.         "leaq   (%%r12,%%rsi,1), %%r13               \n\t" // r13 = 3*rs_c;
  1361.         "                                            \n\t"
  1362.         "                                            \n\t"
  1363.         "                                            \n\t" // now avoid loading C if beta == 0
  1364.         "                                            \n\t"
  1365.         "vxorpd    %%ymm0,  %%ymm0,  %%ymm0          \n\t" // set ymm0 to zero.
  1366.         "vucomisd  %%xmm0,  %%xmm2                   \n\t" // set ZF if beta == 0.
  1367.         "je      .DBETAZERO                          \n\t" // if ZF = 1, jump to beta == 0 case
  1368.         "                                            \n\t"
  1369.         "                                            \n\t"
  1370.         "cmpq       $8, %%rsi                        \n\t" // set ZF if (8*cs_c) == 8.
  1371.         "jz      .DCOLSTORED                         \n\t" // jump to column storage case
  1372.         "                                            \n\t"
  1373.         "                                            \n\t"
  1374.         "                                            \n\t"
  1375.         ".DGENSTORED:                                \n\t"
  1376.         "                                            \n\t" // update c00:c33
  1377.         "                                            \n\t"
  1378.         "vextractf128 $1, %%ymm9,  %%xmm1            \n\t"
  1379.         "vmovlpd    (%%rcx),       %%xmm0,  %%xmm0   \n\t" // load c00 and c10,
  1380.         "vmovhpd    (%%rcx,%%rsi), %%xmm0,  %%xmm0   \n\t"
  1381.         "vmulpd           %%xmm2,  %%xmm0,  %%xmm0   \n\t" // scale by beta,
  1382.         "vaddpd           %%xmm9,  %%xmm0,  %%xmm0   \n\t" // add the gemm result,
  1383.         "vmovlpd          %%xmm0,  (%%rcx)           \n\t" // and store back to memory.
  1384.         "vmovhpd          %%xmm0,  (%%rcx,%%rsi)     \n\t"
  1385.         "vmovlpd    (%%rcx,%%r12), %%xmm0,  %%xmm0   \n\t" // load c20 and c30,
  1386.         "vmovhpd    (%%rcx,%%r13), %%xmm0,  %%xmm0   \n\t"
  1387.         "vmulpd           %%xmm2,  %%xmm0,  %%xmm0   \n\t" // scale by beta,
  1388.         "vaddpd           %%xmm1,  %%xmm0,  %%xmm0   \n\t" // add the gemm result,
  1389.         "vmovlpd          %%xmm0,  (%%rcx,%%r12)     \n\t" // and store back to memory.
  1390.         "vmovhpd          %%xmm0,  (%%rcx,%%r13)     \n\t"
  1391.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  1392.         "                                            \n\t"
  1393.         "vextractf128 $1, %%ymm11, %%xmm1            \n\t"
  1394.         "vmovlpd    (%%rcx),       %%xmm0,  %%xmm0   \n\t" // load c01 and c11,
  1395.         "vmovhpd    (%%rcx,%%rsi), %%xmm0,  %%xmm0   \n\t"
  1396.         "vmulpd           %%xmm2,  %%xmm0,  %%xmm0   \n\t" // scale by beta,
  1397.         "vaddpd           %%xmm11, %%xmm0,  %%xmm0   \n\t" // add the gemm result,
  1398.         "vmovlpd          %%xmm0,  (%%rcx)           \n\t" // and store back to memory.
  1399.         "vmovhpd          %%xmm0,  (%%rcx,%%rsi)     \n\t"
  1400.         "vmovlpd    (%%rcx,%%r12), %%xmm0,  %%xmm0   \n\t" // load c21 and c31,
  1401.         "vmovhpd    (%%rcx,%%r13), %%xmm0,  %%xmm0   \n\t"
  1402.         "vmulpd           %%xmm2,  %%xmm0,  %%xmm0   \n\t" // scale by beta,
  1403.         "vaddpd           %%xmm1,  %%xmm0,  %%xmm0   \n\t" // add the gemm result,
  1404.         "vmovlpd          %%xmm0,  (%%rcx,%%r12)     \n\t" // and store back to memory.
  1405.         "vmovhpd          %%xmm0,  (%%rcx,%%r13)     \n\t"
  1406.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  1407.         "                                            \n\t"
  1408.         "vextractf128 $1, %%ymm13, %%xmm1            \n\t"
  1409.         "vmovlpd    (%%rcx),       %%xmm0,  %%xmm0   \n\t" // load c02 and c12,
  1410.         "vmovhpd    (%%rcx,%%rsi), %%xmm0,  %%xmm0   \n\t"
  1411.         "vmulpd           %%xmm2,  %%xmm0,  %%xmm0   \n\t" // scale by beta,
  1412.         "vaddpd           %%xmm13, %%xmm0,  %%xmm0   \n\t" // add the gemm result,
  1413.         "vmovlpd          %%xmm0,  (%%rcx)           \n\t" // and store back to memory.
  1414.         "vmovhpd          %%xmm0,  (%%rcx,%%rsi)     \n\t"
  1415.         "vmovlpd    (%%rcx,%%r12), %%xmm0,  %%xmm0   \n\t" // load c22 and c32,
  1416.         "vmovhpd    (%%rcx,%%r13), %%xmm0,  %%xmm0   \n\t"
  1417.         "vmulpd           %%xmm2,  %%xmm0,  %%xmm0   \n\t" // scale by beta,
  1418.         "vaddpd           %%xmm1,  %%xmm0,  %%xmm0   \n\t" // add the gemm result,
  1419.         "vmovlpd          %%xmm0,  (%%rcx,%%r12)     \n\t" // and store back to memory.
  1420.         "vmovhpd          %%xmm0,  (%%rcx,%%r13)     \n\t"
  1421.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  1422.         "                                            \n\t"
  1423.         "vextractf128 $1, %%ymm15, %%xmm1            \n\t"
  1424.         "vmovlpd    (%%rcx),       %%xmm0,  %%xmm0   \n\t" // load c03 and c13,
  1425.         "vmovhpd    (%%rcx,%%rsi), %%xmm0,  %%xmm0   \n\t"
  1426.         "vmulpd           %%xmm2,  %%xmm0,  %%xmm0   \n\t" // scale by beta,
  1427.         "vaddpd           %%xmm15, %%xmm0,  %%xmm0   \n\t" // add the gemm result,
  1428.         "vmovlpd          %%xmm0,  (%%rcx)           \n\t" // and store back to memory.
  1429.         "vmovhpd          %%xmm0,  (%%rcx,%%rsi)     \n\t"
  1430.         "vmovlpd    (%%rcx,%%r12), %%xmm0,  %%xmm0   \n\t" // load c23 and c33,
  1431.         "vmovhpd    (%%rcx,%%r13), %%xmm0,  %%xmm0   \n\t"
  1432.         "vmulpd           %%xmm2,  %%xmm0,  %%xmm0   \n\t" // scale by beta,
  1433.         "vaddpd           %%xmm1,  %%xmm0,  %%xmm0   \n\t" // add the gemm result,
  1434.         "vmovlpd          %%xmm0,  (%%rcx,%%r12)     \n\t" // and store back to memory.
  1435.         "vmovhpd          %%xmm0,  (%%rcx,%%r13)     \n\t"
  1436.         "                                            \n\t"
  1437.         "                                            \n\t" // update c40:c73
  1438.         "                                            \n\t"
  1439.         "vextractf128 $1, %%ymm8,  %%xmm1            \n\t"
  1440.         "vmovlpd    (%%rdx),       %%xmm0,  %%xmm0   \n\t" // load c40 and c50,
  1441.         "vmovhpd    (%%rdx,%%rsi), %%xmm0,  %%xmm0   \n\t"
  1442.         "vmulpd           %%xmm2,  %%xmm0,  %%xmm0   \n\t" // scale by beta,
  1443.         "vaddpd           %%xmm8,  %%xmm0,  %%xmm0   \n\t" // add the gemm result,
  1444.         "vmovlpd          %%xmm0,  (%%rdx)           \n\t" // and store back to memory.
  1445.         "vmovhpd          %%xmm0,  (%%rdx,%%rsi)     \n\t"
  1446.         "vmovlpd    (%%rdx,%%r12), %%xmm0,  %%xmm0   \n\t" // load c60 and c70,
  1447.         "vmovhpd    (%%rdx,%%r13), %%xmm0,  %%xmm0   \n\t"
  1448.         "vmulpd           %%xmm2,  %%xmm0,  %%xmm0   \n\t" // scale by beta,
  1449.         "vaddpd           %%xmm1,  %%xmm0,  %%xmm0   \n\t" // add the gemm result,
  1450.         "vmovlpd          %%xmm0,  (%%rdx,%%r12)     \n\t" // and store back to memory.
  1451.         "vmovhpd          %%xmm0,  (%%rdx,%%r13)     \n\t"
  1452.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  1453.         "                                            \n\t"
  1454.         "vextractf128 $1, %%ymm10, %%xmm1            \n\t"
  1455.         "vmovlpd    (%%rdx),       %%xmm0,  %%xmm0   \n\t" // load c41 and c51,
  1456.         "vmovhpd    (%%rdx,%%rsi), %%xmm0,  %%xmm0   \n\t"
  1457.         "vmulpd           %%xmm2,  %%xmm0,  %%xmm0   \n\t" // scale by beta,
  1458.         "vaddpd           %%xmm10, %%xmm0,  %%xmm0   \n\t" // add the gemm result,
  1459.         "vmovlpd          %%xmm0,  (%%rdx)           \n\t" // and store back to memory.
  1460.         "vmovhpd          %%xmm0,  (%%rdx,%%rsi)     \n\t"
  1461.         "vmovlpd    (%%rdx,%%r12), %%xmm0,  %%xmm0   \n\t" // load c61 and c71,
  1462.         "vmovhpd    (%%rdx,%%r13), %%xmm0,  %%xmm0   \n\t"
  1463.         "vmulpd           %%xmm2,  %%xmm0,  %%xmm0   \n\t" // scale by beta,
  1464.         "vaddpd           %%xmm1,  %%xmm0,  %%xmm0   \n\t" // add the gemm result,
  1465.         "vmovlpd          %%xmm0,  (%%rdx,%%r12)     \n\t" // and store back to memory.
  1466.         "vmovhpd          %%xmm0,  (%%rdx,%%r13)     \n\t"
  1467.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  1468.         "                                            \n\t"
  1469.         "vextractf128 $1, %%ymm12, %%xmm1            \n\t"
  1470.         "vmovlpd    (%%rdx),       %%xmm0,  %%xmm0   \n\t" // load c42 and c52,
  1471.         "vmovhpd    (%%rdx,%%rsi), %%xmm0,  %%xmm0   \n\t"
  1472.         "vmulpd           %%xmm2,  %%xmm0,  %%xmm0   \n\t" // scale by beta,
  1473.         "vaddpd           %%xmm12, %%xmm0,  %%xmm0   \n\t" // add the gemm result,
  1474.         "vmovlpd          %%xmm0,  (%%rdx)           \n\t" // and store back to memory.
  1475.         "vmovhpd          %%xmm0,  (%%rdx,%%rsi)     \n\t"
  1476.         "vmovlpd    (%%rdx,%%r12), %%xmm0,  %%xmm0   \n\t" // load c62 and c72,
  1477.         "vmovhpd    (%%rdx,%%r13), %%xmm0,  %%xmm0   \n\t"
  1478.         "vmulpd           %%xmm2,  %%xmm0,  %%xmm0   \n\t" // scale by beta,
  1479.         "vaddpd           %%xmm1,  %%xmm0,  %%xmm0   \n\t" // add the gemm result,
  1480.         "vmovlpd          %%xmm0,  (%%rdx,%%r12)     \n\t" // and store back to memory.
  1481.         "vmovhpd          %%xmm0,  (%%rdx,%%r13)     \n\t"
  1482.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  1483.         "                                            \n\t"
  1484.         "vextractf128 $1, %%ymm14, %%xmm1            \n\t"
  1485.         "vmovlpd    (%%rdx),       %%xmm0,  %%xmm0   \n\t" // load c43 and c53,
  1486.         "vmovhpd    (%%rdx,%%rsi), %%xmm0,  %%xmm0   \n\t"
  1487.         "vmulpd           %%xmm2,  %%xmm0,  %%xmm0   \n\t" // scale by beta,
  1488.         "vaddpd           %%xmm14, %%xmm0,  %%xmm0   \n\t" // add the gemm result,
  1489.         "vmovlpd          %%xmm0,  (%%rdx)           \n\t" // and store back to memory.
  1490.         "vmovhpd          %%xmm0,  (%%rdx,%%rsi)     \n\t"
  1491.         "vmovlpd    (%%rdx,%%r12), %%xmm0,  %%xmm0   \n\t" // load c63 and c73,
  1492.         "vmovhpd    (%%rdx,%%r13), %%xmm0,  %%xmm0   \n\t"
  1493.         "vmulpd           %%xmm2,  %%xmm0,  %%xmm0   \n\t" // scale by beta,
  1494.         "vaddpd           %%xmm1,  %%xmm0,  %%xmm0   \n\t" // add the gemm result,
  1495.         "vmovlpd          %%xmm0,  (%%rdx,%%r12)     \n\t" // and store back to memory.
  1496.         "vmovhpd          %%xmm0,  (%%rdx,%%r13)     \n\t"
  1497.         "                                            \n\t"
  1498.         "                                            \n\t"
  1499.         "jmp    .DDONE                               \n\t" // jump to end.
  1500.         "                                            \n\t"
  1501.         "                                            \n\t"
  1502.         "                                            \n\t"
  1503.         ".DCOLSTORED:                                \n\t"
  1504.         "                                            \n\t" // update c00:c33
  1505.         "                                            \n\t"
  1506.         "vmovupd    (%%rcx),       %%ymm0            \n\t" // load c00:c30,
  1507.         "vmulpd           %%ymm2,  %%ymm0,  %%ymm0   \n\t" // scale by beta,
  1508.         "vaddpd           %%ymm9,  %%ymm0,  %%ymm0   \n\t" // add the gemm result,
  1509.         "vmovupd          %%ymm0,  (%%rcx)           \n\t" // and store back to memory.
  1510.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  1511.         "                                            \n\t"
  1512.         "vmovupd    (%%rcx),       %%ymm0            \n\t" // load c01:c31,
  1513.         "vmulpd           %%ymm2,  %%ymm0,  %%ymm0   \n\t" // scale by beta,
  1514.         "vaddpd           %%ymm11, %%ymm0,  %%ymm0   \n\t" // add the gemm result,
  1515.         "vmovupd          %%ymm0,  (%%rcx)           \n\t" // and store back to memory.
  1516.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  1517.         "                                            \n\t"
  1518.         "vmovupd    (%%rcx),       %%ymm0            \n\t" // load c02:c32,
  1519.         "vmulpd           %%ymm2,  %%ymm0,  %%ymm0   \n\t" // scale by beta,
  1520.         "vaddpd           %%ymm13, %%ymm0,  %%ymm0   \n\t" // add the gemm result,
  1521.         "vmovupd          %%ymm0,  (%%rcx)           \n\t" // and store back to memory.
  1522.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  1523.         "                                            \n\t"
  1524.         "vmovupd    (%%rcx),       %%ymm0            \n\t" // load c03:c33,
  1525.         "vmulpd           %%ymm2,  %%ymm0,  %%ymm0   \n\t" // scale by beta,
  1526.         "vaddpd           %%ymm15, %%ymm0,  %%ymm0   \n\t" // add the gemm result,
  1527.         "vmovupd          %%ymm0,  (%%rcx)           \n\t" // and store back to memory.
  1528.         "                                            \n\t"
  1529.         "                                            \n\t" // update c40:c73
  1530.         "                                            \n\t"
  1531.         "vmovupd    (%%rdx),       %%ymm0            \n\t" // load c40:c70,
  1532.         "vmulpd           %%ymm2,  %%ymm0,  %%ymm0   \n\t" // scale by beta,
  1533.         "vaddpd           %%ymm8,  %%ymm0,  %%ymm0   \n\t" // add the gemm result,
  1534.         "vmovupd          %%ymm0,  (%%rdx)           \n\t" // and store back to memory.
  1535.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  1536.         "                                            \n\t"
  1537.         "vmovupd    (%%rdx),       %%ymm0            \n\t" // load c41:c71,
  1538.         "vmulpd           %%ymm2,  %%ymm0,  %%ymm0   \n\t" // scale by beta,
  1539.         "vaddpd           %%ymm10, %%ymm0,  %%ymm0   \n\t" // add the gemm result,
  1540.         "vmovupd          %%ymm0,  (%%rdx)           \n\t" // and store back to memory.
  1541.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  1542.         "                                            \n\t"
  1543.         "vmovupd    (%%rdx),       %%ymm0            \n\t" // load c42:c72,
  1544.         "vmulpd           %%ymm2,  %%ymm0,  %%ymm0   \n\t" // scale by beta,
  1545.         "vaddpd           %%ymm12, %%ymm0,  %%ymm0   \n\t" // add the gemm result,
  1546.         "vmovupd          %%ymm0,  (%%rdx)           \n\t" // and store back to memory.
  1547.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  1548.         "                                            \n\t"
  1549.         "vmovupd    (%%rdx),       %%ymm0            \n\t" // load c43:c73,
  1550.         "vmulpd           %%ymm2,  %%ymm0,  %%ymm0   \n\t" // scale by beta,
  1551.         "vaddpd           %%ymm14, %%ymm0,  %%ymm0   \n\t" // add the gemm result,
  1552.         "vmovupd          %%ymm0,  (%%rdx)           \n\t" // and store back to memory.
  1553.         "                                            \n\t"
  1554.         "                                            \n\t"
  1555.         "jmp    .DDONE                               \n\t" // jump to end.
  1556.         "                                            \n\t"
  1557.         "                                            \n\t"
  1558.         "                                            \n\t"
  1559.         "                                            \n\t"
  1560.         ".DBETAZERO:                                 \n\t"
  1561.         "                                            \n\t"
  1562.         "cmpq       $8, %%rsi                        \n\t" // set ZF if (8*cs_c) == 8.
  1563.         "jz      .DCOLSTORBZ                         \n\t" // jump to column storage case
  1564.         "                                            \n\t"
  1565.         "                                            \n\t"
  1566.         "                                            \n\t"
  1567.         ".DGENSTORBZ:                                \n\t"
  1568.         "                                            \n\t" // update c00:c33
  1569.         "                                            \n\t"
  1570.         "vextractf128 $1, %%ymm9,  %%xmm1            \n\t"
  1571.         "vmovlpd          %%xmm9,  (%%rcx)           \n\t" // store to c00:c30
  1572.         "vmovhpd          %%xmm9,  (%%rcx,%%rsi)     \n\t"
  1573.         "vmovlpd          %%xmm1,  (%%rcx,%%r12)     \n\t"
  1574.         "vmovhpd          %%xmm1,  (%%rcx,%%r13)     \n\t"
  1575.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  1576.         "                                            \n\t"
  1577.         "vextractf128 $1, %%ymm11, %%xmm1            \n\t"
  1578.         "vmovlpd          %%xmm11, (%%rcx)           \n\t" // store to c01:c31
  1579.         "vmovhpd          %%xmm11, (%%rcx,%%rsi)     \n\t"
  1580.         "vmovlpd          %%xmm1,  (%%rcx,%%r12)     \n\t"
  1581.         "vmovhpd          %%xmm1,  (%%rcx,%%r13)     \n\t"
  1582.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  1583.         "                                            \n\t"
  1584.         "vextractf128 $1, %%ymm13, %%xmm1            \n\t"
  1585.         "vmovlpd          %%xmm13, (%%rcx)           \n\t" // store to c02:c32
  1586.         "vmovhpd          %%xmm13, (%%rcx,%%rsi)     \n\t"
  1587.         "vmovlpd          %%xmm1,  (%%rcx,%%r12)     \n\t"
  1588.         "vmovhpd          %%xmm1,  (%%rcx,%%r13)     \n\t"
  1589.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  1590.         "                                            \n\t"
  1591.         "vextractf128 $1, %%ymm15, %%xmm1            \n\t"
  1592.         "vmovlpd          %%xmm15, (%%rcx)           \n\t" // store to c03:c33
  1593.         "vmovhpd          %%xmm15, (%%rcx,%%rsi)     \n\t"
  1594.         "vmovlpd          %%xmm1,  (%%rcx,%%r12)     \n\t"
  1595.         "vmovhpd          %%xmm1,  (%%rcx,%%r13)     \n\t"
  1596.         "                                            \n\t"
  1597.         "                                            \n\t" // update c40:c73
  1598.         "                                            \n\t"
  1599.         "vextractf128 $1, %%ymm8,  %%xmm1            \n\t"
  1600.         "vmovlpd          %%xmm8,  (%%rdx)           \n\t" // store to c40:c70
  1601.         "vmovhpd          %%xmm8,  (%%rdx,%%rsi)     \n\t"
  1602.         "vmovlpd          %%xmm1,  (%%rdx,%%r12)     \n\t"
  1603.         "vmovhpd          %%xmm1,  (%%rdx,%%r13)     \n\t"
  1604.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  1605.         "                                            \n\t"
  1606.         "vextractf128 $1, %%ymm10, %%xmm1            \n\t"
  1607.         "vmovlpd          %%xmm10, (%%rdx)           \n\t" // store to c41:c71
  1608.         "vmovhpd          %%xmm10, (%%rdx,%%rsi)     \n\t"
  1609.         "vmovlpd          %%xmm1,  (%%rdx,%%r12)     \n\t"
  1610.         "vmovhpd          %%xmm1,  (%%rdx,%%r13)     \n\t"
  1611.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  1612.         "                                            \n\t"
  1613.         "vextractf128 $1, %%ymm12, %%xmm1            \n\t"
  1614.         "vmovlpd          %%xmm12, (%%rdx)           \n\t" // store to c42:c72
  1615.         "vmovhpd          %%xmm12, (%%rdx,%%rsi)     \n\t"
  1616.         "vmovlpd          %%xmm1,  (%%rdx,%%r12)     \n\t"
  1617.         "vmovhpd          %%xmm1,  (%%rdx,%%r13)     \n\t"
  1618.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  1619.         "                                            \n\t"
  1620.         "vextractf128 $1, %%ymm14, %%xmm1            \n\t"
  1621.         "vmovlpd          %%xmm14, (%%rdx)           \n\t" // store to c43:c73
  1622.         "vmovhpd          %%xmm14, (%%rdx,%%rsi)     \n\t"
  1623.         "vmovlpd          %%xmm1,  (%%rdx,%%r12)     \n\t"
  1624.         "vmovhpd          %%xmm1,  (%%rdx,%%r13)     \n\t"
  1625.         "                                            \n\t"
  1626.         "                                            \n\t"
  1627.         "jmp    .DDONE                               \n\t" // jump to end.
  1628.         "                                            \n\t"
  1629.         "                                            \n\t"
  1630.         "                                            \n\t"
  1631.         ".DCOLSTORBZ:                                \n\t"
  1632.         "                                            \n\t" // update c00:c33
  1633.         "                                            \n\t"
  1634.         "vmovupd          %%ymm9,  (%%rcx)           \n\t" // store c00:c30
  1635.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  1636.         "                                            \n\t"
  1637.         "vmovupd          %%ymm11, (%%rcx)           \n\t" // store c01:c31
  1638.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  1639.         "                                            \n\t"
  1640.         "vmovupd          %%ymm13, (%%rcx)           \n\t" // store c02:c32
  1641.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  1642.         "                                            \n\t"
  1643.         "vmovupd          %%ymm15, (%%rcx)           \n\t" // store c03:c33
  1644.         "                                            \n\t"
  1645.         "                                            \n\t" // update c40:c73
  1646.         "                                            \n\t"
  1647.         "vmovupd          %%ymm8,  (%%rdx)           \n\t" // store c40:c70
  1648.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  1649.         "                                            \n\t"
  1650.         "vmovupd          %%ymm10, (%%rdx)           \n\t" // store c41:c71
  1651.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  1652.         "                                            \n\t"
  1653.         "vmovupd          %%ymm12, (%%rdx)           \n\t" // store c42:c72
  1654.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  1655.         "                                            \n\t"
  1656.         "vmovupd          %%ymm14, (%%rdx)           \n\t" // store c43:c73
  1657.         "                                            \n\t"
  1658.         "                                            \n\t"
  1659.         "                                            \n\t"
  1660.         "                                            \n\t"
  1661.         "                                            \n\t"
  1662.         ".DDONE:                                     \n\t"
  1663.     "                                            \n\t"
  1664.     "vzeroupper                                  \n\t"
  1665.         "                                            \n\t"
  1666.  
  1667.         : // output operands (none)
  1668.         : // input operands
  1669.           "m" (k_iter), // 0
  1670.           "m" (k_left), // 1
  1671.           "m" (a),      // 2
  1672.           "m" (b),      // 3
  1673.           "m" (alpha),  // 4
  1674.           "m" (beta),   // 5
  1675.           "m" (c),      // 6
  1676.           "m" (rs_c),   // 7
  1677.           "m" (cs_c),   // 8
  1678.           "m" (b_next)/*, // 9
  1679.           "m" (a_next)*/  // 10
  1680.         : // register clobber list
  1681.           "rax", "rbx", "rcx", "rdx", "rsi", "rdi",
  1682.           "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
  1683.           "xmm0", "xmm1", "xmm2", "xmm3",
  1684.           "xmm4", "xmm5", "xmm6", "xmm7",
  1685.           "xmm8", "xmm9", "xmm10", "xmm11",
  1686.           "xmm12", "xmm13", "xmm14", "xmm15",
  1687.           "memory"
  1688.         );
  1689. }
  1690.  
  1691. void bli_cgemm_asm_8x4
  1692.      (
  1693.        dim_t               k,
  1694.        scomplex*  restrict alpha,
  1695.        scomplex*  restrict a,
  1696.        scomplex*  restrict b,
  1697.        scomplex*  restrict beta,
  1698.        scomplex*  restrict c, inc_t rs_c, inc_t cs_c,
  1699.        auxinfo_t* restrict data,
  1700.        cntx_t*    restrict cntx
  1701.      )
  1702. {
  1703.         //void*   a_next = bli_auxinfo_next_a( data );
  1704.         void*   b_next = bli_auxinfo_next_b( data );
  1705.  
  1706.         uint64_t   k_iter = k / 4;
  1707.         uint64_t   k_left = k % 4;
  1708.  
  1709.         __asm__ volatile
  1710.         (
  1711.         "                                            \n\t"
  1712.         "                                            \n\t"
  1713.         "movq                %2, %%rax               \n\t" // load address of a.
  1714.         "movq                %3, %%rbx               \n\t" // load address of b.
  1715.         "movq                %9, %%r15               \n\t" // load address of b_next.
  1716.         //"movq               %10, %%r14               \n\t" // load address of a_next.
  1717.         "addq          $-4 * 64, %%r15               \n\t"
  1718.         "                                            \n\t"
  1719.         "vmovaps        0 * 32(%%rax), %%ymm0        \n\t" // initialize loop by pre-loading
  1720.         "vmovsldup      0 * 32(%%rbx), %%ymm2        \n\t"
  1721.         "vpermilps     $0x4e, %%ymm2,  %%ymm3        \n\t"
  1722.         "                                            \n\t"
  1723.         "movq                %6, %%rcx               \n\t" // load address of c
  1724.         "movq                %8, %%rdi               \n\t" // load cs_c
  1725.         "leaq        (,%%rdi,8), %%rdi               \n\t" // cs_c *= sizeof(scomplex)
  1726.         "leaq   (%%rcx,%%rdi,2), %%r10               \n\t" // load address of c + 2*cs_c;
  1727.         "                                            \n\t"
  1728.         "prefetcht0   3 * 8(%%rcx)                   \n\t" // prefetch c + 0*cs_c
  1729.         "prefetcht0   3 * 8(%%rcx,%%rdi)             \n\t" // prefetch c + 1*cs_c
  1730.         "prefetcht0   3 * 8(%%r10)                   \n\t" // prefetch c + 2*cs_c
  1731.         "prefetcht0   3 * 8(%%r10,%%rdi)             \n\t" // prefetch c + 3*cs_c
  1732.         "                                            \n\t"
  1733.         "vxorps    %%ymm8,  %%ymm8,  %%ymm8          \n\t"
  1734.         "vxorps    %%ymm9,  %%ymm9,  %%ymm9          \n\t"
  1735.         "vxorps    %%ymm10, %%ymm10, %%ymm10         \n\t"
  1736.         "vxorps    %%ymm11, %%ymm11, %%ymm11         \n\t"
  1737.         "vxorps    %%ymm12, %%ymm12, %%ymm12         \n\t"
  1738.         "vxorps    %%ymm13, %%ymm13, %%ymm13         \n\t"
  1739.         "vxorps    %%ymm14, %%ymm14, %%ymm14         \n\t"
  1740.         "vxorps    %%ymm15, %%ymm15, %%ymm15         \n\t"
  1741.         "                                            \n\t"
  1742.         "                                            \n\t"
  1743.         "                                            \n\t"
  1744.         "movq      %0, %%rsi                         \n\t" // i = k_iter;
  1745.         "testq  %%rsi, %%rsi                         \n\t" // check i via logical AND.
  1746.         "je     .CCONSIDKLEFT                        \n\t" // if i == 0, jump to code that
  1747.         "                                            \n\t" // contains the k_left loop.
  1748.         "                                            \n\t"
  1749.         "                                            \n\t"
  1750.         ".CLOOPKITER:                                \n\t" // MAIN LOOP
  1751.         "                                            \n\t"
  1752.         "addq         $4 * 4 * 8,  %%r15             \n\t" // b_next += 4*4 (unroll x nr)
  1753.         "                                            \n\t"
  1754.         "                                            \n\t" // iteration 0
  1755.         "prefetcht0     8 * 32(%%rax)                \n\t"
  1756.         "vmovaps        1 * 32(%%rax),      %%ymm1   \n\t"
  1757.         "vmulps           %%ymm0,  %%ymm2,  %%ymm6   \n\t"
  1758.         "vperm2f128 $0x3, %%ymm2,  %%ymm2,  %%ymm4   \n\t"
  1759.         "vmulps           %%ymm0,  %%ymm3,  %%ymm7   \n\t"
  1760.         "vperm2f128 $0x3, %%ymm3,  %%ymm3,  %%ymm5   \n\t"
  1761.         "vaddps           %%ymm6,  %%ymm15, %%ymm15  \n\t"
  1762.         "vaddps           %%ymm7,  %%ymm13, %%ymm13  \n\t"
  1763.         "                                            \n\t"
  1764.         "vmulps           %%ymm1,  %%ymm2,  %%ymm6   \n\t"
  1765.         "vmovshdup      0 * 32(%%rbx),      %%ymm2   \n\t"
  1766.         "vmulps           %%ymm1,  %%ymm3,  %%ymm7   \n\t"
  1767.         "vpermilps $0x4e, %%ymm2,  %%ymm3            \n\t"
  1768.         "vaddps           %%ymm6,  %%ymm14, %%ymm14  \n\t"
  1769.         "vaddps           %%ymm7,  %%ymm12, %%ymm12  \n\t"
  1770.         "                                            \n\t"
  1771.         "vmulps           %%ymm0,  %%ymm4,  %%ymm6   \n\t"
  1772.         "vmulps           %%ymm0,  %%ymm5,  %%ymm7   \n\t"
  1773.         "vpermilps $0xb1, %%ymm0,  %%ymm0            \n\t"
  1774.         "vaddps           %%ymm6,  %%ymm11, %%ymm11  \n\t"
  1775.         "vaddps           %%ymm7,  %%ymm9,  %%ymm9   \n\t"
  1776.         "                                            \n\t"
  1777.         "vmulps           %%ymm1,  %%ymm4,  %%ymm6   \n\t"
  1778.         "vperm2f128 $0x3, %%ymm2,  %%ymm2,  %%ymm4   \n\t"
  1779.         "vmulps           %%ymm1,  %%ymm5,  %%ymm7   \n\t"
  1780.         "vperm2f128 $0x3, %%ymm3,  %%ymm3,  %%ymm5   \n\t"
  1781.         "vaddps           %%ymm6,  %%ymm10, %%ymm10  \n\t"
  1782.         "vaddps           %%ymm7,  %%ymm8,  %%ymm8   \n\t"
  1783.         "prefetcht0   0 * 32(%%r15)                  \n\t" // prefetch b_next[0*4]
  1784.         "                                            \n\t"
  1785.         "vpermilps $0xb1, %%ymm1,  %%ymm1            \n\t"
  1786.         "vmulps           %%ymm0,  %%ymm2,  %%ymm6   \n\t"
  1787.         "vmulps           %%ymm0,  %%ymm3,  %%ymm7   \n\t"
  1788.         "vaddsubps        %%ymm6,  %%ymm15, %%ymm15  \n\t"
  1789.         "vaddsubps        %%ymm7,  %%ymm13, %%ymm13  \n\t"
  1790.         "                                            \n\t"
  1791.         "vmulps           %%ymm1,  %%ymm2,  %%ymm6   \n\t"
  1792.         "vmovsldup      1 * 32(%%rbx),      %%ymm2   \n\t"
  1793.         "vmulps           %%ymm1,  %%ymm3,  %%ymm7   \n\t"
  1794.         "vpermilps $0x4e, %%ymm2,  %%ymm3            \n\t"
  1795.         "vaddsubps        %%ymm6,  %%ymm14, %%ymm14  \n\t"
  1796.         "vaddsubps        %%ymm7,  %%ymm12, %%ymm12  \n\t"
  1797.         "                                            \n\t"
  1798.         "vmulps           %%ymm0,  %%ymm4,  %%ymm6   \n\t"
  1799.         "vmulps           %%ymm0,  %%ymm5,  %%ymm7   \n\t"
  1800.         "vmovaps        2 * 32(%%rax),      %%ymm0   \n\t"
  1801.         "vaddsubps        %%ymm6,  %%ymm11, %%ymm11  \n\t"
  1802.         "vaddsubps        %%ymm7,  %%ymm9,  %%ymm9   \n\t"
  1803.         "                                            \n\t"
  1804.         "vmulps           %%ymm1,  %%ymm4,  %%ymm6   \n\t"
  1805.         "vmulps           %%ymm1,  %%ymm5,  %%ymm7   \n\t"
  1806.         "vaddsubps        %%ymm6,  %%ymm10, %%ymm10  \n\t"
  1807.         "vaddsubps        %%ymm7,  %%ymm8,  %%ymm8   \n\t"
  1808.         "                                            \n\t"
  1809.         "                                            \n\t"
  1810.         "                                            \n\t" // iteration 1
  1811.         "prefetcht0    10 * 32(%%rax)                \n\t"
  1812.         "vmovaps        3 * 32(%%rax),      %%ymm1   \n\t"
  1813.         "vmulps           %%ymm0,  %%ymm2,  %%ymm6   \n\t"
  1814.         "vperm2f128 $0x3, %%ymm2,  %%ymm2,  %%ymm4   \n\t"
  1815.         "vmulps           %%ymm0,  %%ymm3,  %%ymm7   \n\t"
  1816.         "vperm2f128 $0x3, %%ymm3,  %%ymm3,  %%ymm5   \n\t"
  1817.         "vaddps           %%ymm6,  %%ymm15, %%ymm15  \n\t"
  1818.         "vaddps           %%ymm7,  %%ymm13, %%ymm13  \n\t"
  1819.         "                                            \n\t"
  1820.         "vmulps           %%ymm1,  %%ymm2,  %%ymm6   \n\t"
  1821.         "vmovshdup      1 * 32(%%rbx),      %%ymm2   \n\t"
  1822.         "vmulps           %%ymm1,  %%ymm3,  %%ymm7   \n\t"
  1823.         "vpermilps $0x4e, %%ymm2,  %%ymm3            \n\t"
  1824.         "vaddps           %%ymm6,  %%ymm14, %%ymm14  \n\t"
  1825.         "vaddps           %%ymm7,  %%ymm12, %%ymm12  \n\t"
  1826.         "                                            \n\t"
  1827.         "vmulps           %%ymm0,  %%ymm4,  %%ymm6   \n\t"
  1828.         "vmulps           %%ymm0,  %%ymm5,  %%ymm7   \n\t"
  1829.         "vpermilps $0xb1, %%ymm0,  %%ymm0            \n\t"
  1830.         "vaddps           %%ymm6,  %%ymm11, %%ymm11  \n\t"
  1831.         "vaddps           %%ymm7,  %%ymm9,  %%ymm9   \n\t"
  1832.         "                                            \n\t"
  1833.         "vmulps           %%ymm1,  %%ymm4,  %%ymm6   \n\t"
  1834.         "vperm2f128 $0x3, %%ymm2,  %%ymm2,  %%ymm4   \n\t"
  1835.         "vmulps           %%ymm1,  %%ymm5,  %%ymm7   \n\t"
  1836.         "vperm2f128 $0x3, %%ymm3,  %%ymm3,  %%ymm5   \n\t"
  1837.         "vaddps           %%ymm6,  %%ymm10, %%ymm10  \n\t"
  1838.         "vaddps           %%ymm7,  %%ymm8,  %%ymm8   \n\t"
  1839.         "                                            \n\t"
  1840.         "vpermilps $0xb1, %%ymm1,  %%ymm1            \n\t"
  1841.         "vmulps           %%ymm0,  %%ymm2,  %%ymm6   \n\t"
  1842.         "vmulps           %%ymm0,  %%ymm3,  %%ymm7   \n\t"
  1843.         "vaddsubps        %%ymm6,  %%ymm15, %%ymm15  \n\t"
  1844.         "vaddsubps        %%ymm7,  %%ymm13, %%ymm13  \n\t"
  1845.         "                                            \n\t"
  1846.         "vmulps           %%ymm1,  %%ymm2,  %%ymm6   \n\t"
  1847.         "vmovsldup      2 * 32(%%rbx),      %%ymm2   \n\t"
  1848.         "vmulps           %%ymm1,  %%ymm3,  %%ymm7   \n\t"
  1849.         "vpermilps $0x4e, %%ymm2,  %%ymm3            \n\t"
  1850.         "vaddsubps        %%ymm6,  %%ymm14, %%ymm14  \n\t"
  1851.         "vaddsubps        %%ymm7,  %%ymm12, %%ymm12  \n\t"
  1852.         "                                            \n\t"
  1853.         "vmulps           %%ymm0,  %%ymm4,  %%ymm6   \n\t"
  1854.         "vmulps           %%ymm0,  %%ymm5,  %%ymm7   \n\t"
  1855.         "vmovaps        4 * 32(%%rax),      %%ymm0   \n\t"
  1856.         "vaddsubps        %%ymm6,  %%ymm11, %%ymm11  \n\t"
  1857.         "vaddsubps        %%ymm7,  %%ymm9,  %%ymm9   \n\t"
  1858.         "                                            \n\t"
  1859.         "vmulps           %%ymm1,  %%ymm4,  %%ymm6   \n\t"
  1860.         "vmulps           %%ymm1,  %%ymm5,  %%ymm7   \n\t"
  1861.         "vaddsubps        %%ymm6,  %%ymm10, %%ymm10  \n\t"
  1862.         "vaddsubps        %%ymm7,  %%ymm8,  %%ymm8   \n\t"
  1863.         "                                            \n\t"
  1864.         "                                            \n\t"
  1865.         "                                            \n\t" // iteration 2
  1866.         "prefetcht0    12 * 32(%%rax)                \n\t"
  1867.         "vmovaps        5 * 32(%%rax),      %%ymm1   \n\t"
  1868.         "vmulps           %%ymm0,  %%ymm2,  %%ymm6   \n\t"
  1869.         "vperm2f128 $0x3, %%ymm2,  %%ymm2,  %%ymm4   \n\t"
  1870.         "vmulps           %%ymm0,  %%ymm3,  %%ymm7   \n\t"
  1871.         "vperm2f128 $0x3, %%ymm3,  %%ymm3,  %%ymm5   \n\t"
  1872.         "vaddps           %%ymm6,  %%ymm15, %%ymm15  \n\t"
  1873.         "vaddps           %%ymm7,  %%ymm13, %%ymm13  \n\t"
  1874.         "                                            \n\t"
  1875.         "vmulps           %%ymm1,  %%ymm2,  %%ymm6   \n\t"
  1876.         "vmovshdup      2 * 32(%%rbx),      %%ymm2   \n\t"
  1877.         "vmulps           %%ymm1,  %%ymm3,  %%ymm7   \n\t"
  1878.         "vpermilps $0x4e, %%ymm2,  %%ymm3            \n\t"
  1879.         "vaddps           %%ymm6,  %%ymm14, %%ymm14  \n\t"
  1880.         "vaddps           %%ymm7,  %%ymm12, %%ymm12  \n\t"
  1881.         "                                            \n\t"
  1882.         "vmulps           %%ymm0,  %%ymm4,  %%ymm6   \n\t"
  1883.         "vmulps           %%ymm0,  %%ymm5,  %%ymm7   \n\t"
  1884.         "vpermilps $0xb1, %%ymm0,  %%ymm0            \n\t"
  1885.         "vaddps           %%ymm6,  %%ymm11, %%ymm11  \n\t"
  1886.         "vaddps           %%ymm7,  %%ymm9,  %%ymm9   \n\t"
  1887.         "                                            \n\t"
  1888.         "vmulps           %%ymm1,  %%ymm4,  %%ymm6   \n\t"
  1889.         "vperm2f128 $0x3, %%ymm2,  %%ymm2,  %%ymm4   \n\t"
  1890.         "vmulps           %%ymm1,  %%ymm5,  %%ymm7   \n\t"
  1891.         "vperm2f128 $0x3, %%ymm3,  %%ymm3,  %%ymm5   \n\t"
  1892.         "vaddps           %%ymm6,  %%ymm10, %%ymm10  \n\t"
  1893.         "vaddps           %%ymm7,  %%ymm8,  %%ymm8   \n\t"
  1894.         "prefetcht0   2 * 32(%%r15)                  \n\t" // prefetch b_next[2*4]
  1895.         "                                            \n\t"
  1896.         "vpermilps $0xb1, %%ymm1,  %%ymm1            \n\t"
  1897.         "vmulps           %%ymm0,  %%ymm2,  %%ymm6   \n\t"
  1898.         "vmulps           %%ymm0,  %%ymm3,  %%ymm7   \n\t"
  1899.         "vaddsubps        %%ymm6,  %%ymm15, %%ymm15  \n\t"
  1900.         "vaddsubps        %%ymm7,  %%ymm13, %%ymm13  \n\t"
  1901.         "                                            \n\t"
  1902.         "vmulps           %%ymm1,  %%ymm2,  %%ymm6   \n\t"
  1903.         "vmovsldup      3 * 32(%%rbx),      %%ymm2   \n\t"
  1904.         "vmulps           %%ymm1,  %%ymm3,  %%ymm7   \n\t"
  1905.         "vpermilps $0x4e, %%ymm2,  %%ymm3            \n\t"
  1906.         "vaddsubps        %%ymm6,  %%ymm14, %%ymm14  \n\t"
  1907.         "vaddsubps        %%ymm7,  %%ymm12, %%ymm12  \n\t"
  1908.         "                                            \n\t"
  1909.         "vmulps           %%ymm0,  %%ymm4,  %%ymm6   \n\t"
  1910.         "vmulps           %%ymm0,  %%ymm5,  %%ymm7   \n\t"
  1911.         "vmovaps        6 * 32(%%rax),      %%ymm0   \n\t"
  1912.         "vaddsubps        %%ymm6,  %%ymm11, %%ymm11  \n\t"
  1913.         "vaddsubps        %%ymm7,  %%ymm9,  %%ymm9   \n\t"
  1914.         "                                            \n\t"
  1915.         "vmulps           %%ymm1,  %%ymm4,  %%ymm6   \n\t"
  1916.         "vmulps           %%ymm1,  %%ymm5,  %%ymm7   \n\t"
  1917.         "vaddsubps        %%ymm6,  %%ymm10, %%ymm10  \n\t"
  1918.         "vaddsubps        %%ymm7,  %%ymm8,  %%ymm8   \n\t"
  1919.         "                                            \n\t"
  1920.         "                                            \n\t"
  1921.         "                                            \n\t" // iteration 3
  1922.         "prefetcht0    14 * 32(%%rax)                \n\t"
  1923.         "vmovaps        7 * 32(%%rax),      %%ymm1   \n\t"
  1924.         "vmulps           %%ymm0,  %%ymm2,  %%ymm6   \n\t"
  1925.         "vperm2f128 $0x3, %%ymm2,  %%ymm2,  %%ymm4   \n\t"
  1926.         "vmulps           %%ymm0,  %%ymm3,  %%ymm7   \n\t"
  1927.         "vperm2f128 $0x3, %%ymm3,  %%ymm3,  %%ymm5   \n\t"
  1928.         "vaddps           %%ymm6,  %%ymm15, %%ymm15  \n\t"
  1929.         "vaddps           %%ymm7,  %%ymm13, %%ymm13  \n\t"
  1930.         "                                            \n\t"
  1931.         "vmulps           %%ymm1,  %%ymm2,  %%ymm6   \n\t"
  1932.         "vmovshdup      3 * 32(%%rbx),      %%ymm2   \n\t"
  1933.         "vmulps           %%ymm1,  %%ymm3,  %%ymm7   \n\t"
  1934.         "vpermilps $0x4e, %%ymm2,  %%ymm3            \n\t"
  1935.         "vaddps           %%ymm6,  %%ymm14, %%ymm14  \n\t"
  1936.         "vaddps           %%ymm7,  %%ymm12, %%ymm12  \n\t"
  1937.         "                                            \n\t"
  1938.         "vmulps           %%ymm0,  %%ymm4,  %%ymm6   \n\t"
  1939.         "vmulps           %%ymm0,  %%ymm5,  %%ymm7   \n\t"
  1940.         "vpermilps $0xb1, %%ymm0,  %%ymm0            \n\t"
  1941.         "vaddps           %%ymm6,  %%ymm11, %%ymm11  \n\t"
  1942.         "vaddps           %%ymm7,  %%ymm9,  %%ymm9   \n\t"
  1943.         "                                            \n\t"
  1944.         "vmulps           %%ymm1,  %%ymm4,  %%ymm6   \n\t"
  1945.         "vperm2f128 $0x3, %%ymm2,  %%ymm2,  %%ymm4   \n\t"
  1946.         "vmulps           %%ymm1,  %%ymm5,  %%ymm7   \n\t"
  1947.         "vperm2f128 $0x3, %%ymm3,  %%ymm3,  %%ymm5   \n\t"
  1948.         "vaddps           %%ymm6,  %%ymm10, %%ymm10  \n\t"
  1949.         "vaddps           %%ymm7,  %%ymm8,  %%ymm8   \n\t"
  1950.         "                                            \n\t"
  1951.         "vpermilps $0xb1, %%ymm1,  %%ymm1            \n\t"
  1952.         "vmulps           %%ymm0,  %%ymm2,  %%ymm6   \n\t"
  1953.         "vmulps           %%ymm0,  %%ymm3,  %%ymm7   \n\t"
  1954.         "vaddsubps        %%ymm6,  %%ymm15, %%ymm15  \n\t"
  1955.         "vaddsubps        %%ymm7,  %%ymm13, %%ymm13  \n\t"
  1956.         "                                            \n\t"
  1957.         "vmulps           %%ymm1,  %%ymm2,  %%ymm6   \n\t"
  1958.         "vmovsldup      4 * 32(%%rbx),      %%ymm2   \n\t"
  1959.         "vmulps           %%ymm1,  %%ymm3,  %%ymm7   \n\t"
  1960.         "vpermilps $0x4e, %%ymm2,  %%ymm3            \n\t"
  1961.         "vaddsubps        %%ymm6,  %%ymm14, %%ymm14  \n\t"
  1962.         "vaddsubps        %%ymm7,  %%ymm12, %%ymm12  \n\t"
  1963.         "                                            \n\t"
  1964.         "vmulps           %%ymm0,  %%ymm4,  %%ymm6   \n\t"
  1965.         "vmulps           %%ymm0,  %%ymm5,  %%ymm7   \n\t"
  1966.         "vmovaps        8 * 32(%%rax),      %%ymm0   \n\t"
  1967.         "vaddsubps        %%ymm6,  %%ymm11, %%ymm11  \n\t"
  1968.         "vaddsubps        %%ymm7,  %%ymm9,  %%ymm9   \n\t"
  1969.         "                                            \n\t"
  1970.         "vmulps           %%ymm1,  %%ymm4,  %%ymm6   \n\t"
  1971.         "vmulps           %%ymm1,  %%ymm5,  %%ymm7   \n\t"
  1972.         "vaddsubps        %%ymm6,  %%ymm10, %%ymm10  \n\t"
  1973.         "vaddsubps        %%ymm7,  %%ymm8,  %%ymm8   \n\t"
  1974.         "                                            \n\t"
  1975.         "                                            \n\t"
  1976.         "addq          $8 * 4 * 8, %%rax             \n\t" // a += 8*4 (unroll x mr)
  1977.         "addq          $4 * 4 * 8, %%rbx             \n\t" // b += 4*4 (unroll x nr)
  1978.         "                                            \n\t"
  1979.         "                                            \n\t"
  1980.         "decq   %%rsi                                \n\t" // i -= 1;
  1981.         "jne    .CLOOPKITER                          \n\t" // iterate again if i != 0.
  1982.         "                                            \n\t"
  1983.         "                                            \n\t"
  1984.         "                                            \n\t"
  1985.         "                                            \n\t"
  1986.         "                                            \n\t"
  1987.         "                                            \n\t"
  1988.         ".CCONSIDKLEFT:                              \n\t"
  1989.         "                                            \n\t"
  1990.         "movq      %1, %%rsi                         \n\t" // i = k_left;
  1991.         "testq  %%rsi, %%rsi                         \n\t" // check i via logical AND.
  1992.         "je     .CPOSTACCUM                          \n\t" // if i == 0, we're done; jump to end.
  1993.         "                                            \n\t" // else, we prepare to enter k_left loop.
  1994.         "                                            \n\t"
  1995.         "                                            \n\t"
  1996.         ".CLOOPKLEFT:                                \n\t" // EDGE LOOP
  1997.         "                                            \n\t"
  1998.         "                                            \n\t" // iteration 0
  1999.         "prefetcht0     8 * 32(%%rax)                \n\t"
  2000.         "vmovaps        1 * 32(%%rax),      %%ymm1   \n\t"
  2001.         "vmulps           %%ymm0,  %%ymm2,  %%ymm6   \n\t"
  2002.         "vperm2f128 $0x3, %%ymm2,  %%ymm2,  %%ymm4   \n\t"
  2003.         "vmulps           %%ymm0,  %%ymm3,  %%ymm7   \n\t"
  2004.         "vperm2f128 $0x3, %%ymm3,  %%ymm3,  %%ymm5   \n\t"
  2005.         "vaddps           %%ymm6,  %%ymm15, %%ymm15  \n\t"
  2006.         "vaddps           %%ymm7,  %%ymm13, %%ymm13  \n\t"
  2007.         "                                            \n\t"
  2008.         "vmulps           %%ymm1,  %%ymm2,  %%ymm6   \n\t"
  2009.         "vmovshdup      0 * 32(%%rbx),      %%ymm2   \n\t"
  2010.         "vmulps           %%ymm1,  %%ymm3,  %%ymm7   \n\t"
  2011.         "vpermilps $0x4e, %%ymm2,  %%ymm3            \n\t"
  2012.         "vaddps           %%ymm6,  %%ymm14, %%ymm14  \n\t"
  2013.         "vaddps           %%ymm7,  %%ymm12, %%ymm12  \n\t"
  2014.         "                                            \n\t"
  2015.         "vmulps           %%ymm0,  %%ymm4,  %%ymm6   \n\t"
  2016.         "vmulps           %%ymm0,  %%ymm5,  %%ymm7   \n\t"
  2017.         "vpermilps $0xb1, %%ymm0,  %%ymm0            \n\t"
  2018.         "vaddps           %%ymm6,  %%ymm11, %%ymm11  \n\t"
  2019.         "vaddps           %%ymm7,  %%ymm9,  %%ymm9   \n\t"
  2020.         "                                            \n\t"
  2021.         "vmulps           %%ymm1,  %%ymm4,  %%ymm6   \n\t"
  2022.         "vperm2f128 $0x3, %%ymm2,  %%ymm2,  %%ymm4   \n\t"
  2023.         "vmulps           %%ymm1,  %%ymm5,  %%ymm7   \n\t"
  2024.         "vperm2f128 $0x3, %%ymm3,  %%ymm3,  %%ymm5   \n\t"
  2025.         "vaddps           %%ymm6,  %%ymm10, %%ymm10  \n\t"
  2026.         "vaddps           %%ymm7,  %%ymm8,  %%ymm8   \n\t"
  2027.         "                                            \n\t"
  2028.         "vpermilps $0xb1, %%ymm1,  %%ymm1            \n\t"
  2029.         "vmulps           %%ymm0,  %%ymm2,  %%ymm6   \n\t"
  2030.         "vmulps           %%ymm0,  %%ymm3,  %%ymm7   \n\t"
  2031.         "vaddsubps        %%ymm6,  %%ymm15, %%ymm15  \n\t"
  2032.         "vaddsubps        %%ymm7,  %%ymm13, %%ymm13  \n\t"
  2033.         "                                            \n\t"
  2034.         "vmulps           %%ymm1,  %%ymm2,  %%ymm6   \n\t"
  2035.         "vmovsldup      1 * 32(%%rbx),      %%ymm2   \n\t"
  2036.         "vmulps           %%ymm1,  %%ymm3,  %%ymm7   \n\t"
  2037.         "vpermilps $0x4e, %%ymm2,  %%ymm3            \n\t"
  2038.         "vaddsubps        %%ymm6,  %%ymm14, %%ymm14  \n\t"
  2039.         "vaddsubps        %%ymm7,  %%ymm12, %%ymm12  \n\t"
  2040.         "                                            \n\t"
  2041.         "vmulps           %%ymm0,  %%ymm4,  %%ymm6   \n\t"
  2042.         "vmulps           %%ymm0,  %%ymm5,  %%ymm7   \n\t"
  2043.         "vmovaps        2 * 32(%%rax),      %%ymm0   \n\t"
  2044.         "vaddsubps        %%ymm6,  %%ymm11, %%ymm11  \n\t"
  2045.         "vaddsubps        %%ymm7,  %%ymm9,  %%ymm9   \n\t"
  2046.         "                                            \n\t"
  2047.         "vmulps           %%ymm1,  %%ymm4,  %%ymm6   \n\t"
  2048.         "vmulps           %%ymm1,  %%ymm5,  %%ymm7   \n\t"
  2049.         "vaddsubps        %%ymm6,  %%ymm10, %%ymm10  \n\t"
  2050.         "vaddsubps        %%ymm7,  %%ymm8,  %%ymm8   \n\t"
  2051.         "                                            \n\t"
  2052.         "                                            \n\t"
  2053.         "addq          $8 * 1 * 8, %%rax             \n\t" // a += 8 (1 x mr)
  2054.         "addq          $4 * 1 * 8, %%rbx             \n\t" // b += 4 (1 x nr)
  2055.         "                                            \n\t"
  2056.         "                                            \n\t"
  2057.         "decq   %%rsi                                \n\t" // i -= 1;
  2058.         "jne    .CLOOPKLEFT                          \n\t" // iterate again if i != 0.
  2059.         "                                            \n\t"
  2060.         "                                            \n\t"
  2061.         "                                            \n\t"
  2062.         ".CPOSTACCUM:                                \n\t"
  2063.         "                                            \n\t"
  2064.         "                                            \n\t" // ymm15:  ymm13:  ymm11:  ymm9:
  2065.         "                                            \n\t" // ( ab00  ( ab01  ( ab02  ( ab03
  2066.         "                                            \n\t" //   ab10    ab11    ab12    ab13
  2067.         "                                            \n\t" //   ab21    ab20    ab23    ab22
  2068.         "                                            \n\t" //   ab31    ab30    ab33    ab32
  2069.         "                                            \n\t" //   ab42    ab43    ab40    ab41
  2070.         "                                            \n\t" //   ab52    ab53    ab50    ab51
  2071.         "                                            \n\t" //   ab63    ab62    ab61    ab60
  2072.         "                                            \n\t" //   ab73 )  ab72 )  ab71 )  ab70 )
  2073.         "                                            \n\t"
  2074.         "                                            \n\t" // ymm14:  ymm12:  ymm10:  ymm8:
  2075.         "                                            \n\t" // ( ab80  ( ab81  ( ab82  ( ab83
  2076.         "                                            \n\t" //   ab90    ab91    ab92    ab93
  2077.         "                                            \n\t" //   aba1    aba0    aba3    aba2
  2078.         "                                            \n\t" //   abb1    abb0    abb3    abb2
  2079.         "                                            \n\t" //   abc2    abc3    abc0    abc1
  2080.         "                                            \n\t" //   abd2    abd3    abd0    abd1
  2081.         "                                            \n\t" //   abe3    abe2    abe1    abe0
  2082.         "                                            \n\t" //   abf3    abf2    abf1    abf0 )
  2083.         "                                            \n\t"
  2084.         "vmovaps          %%ymm15, %%ymm7            \n\t"
  2085.         "vshufps   $0xe4, %%ymm13, %%ymm15, %%ymm15  \n\t"
  2086.         "vshufps   $0xe4, %%ymm7,  %%ymm13, %%ymm13  \n\t"
  2087.         "                                            \n\t"
  2088.         "vmovaps          %%ymm11, %%ymm7            \n\t"
  2089.         "vshufps   $0xe4, %%ymm9,  %%ymm11, %%ymm11  \n\t"
  2090.         "vshufps   $0xe4, %%ymm7,  %%ymm9,  %%ymm9   \n\t"
  2091.         "                                            \n\t"
  2092.         "vmovaps          %%ymm14, %%ymm7            \n\t"
  2093.         "vshufps   $0xe4, %%ymm12, %%ymm14, %%ymm14  \n\t"
  2094.         "vshufps   $0xe4, %%ymm7,  %%ymm12, %%ymm12  \n\t"
  2095.         "                                            \n\t"
  2096.         "vmovaps          %%ymm10, %%ymm7            \n\t"
  2097.         "vshufps   $0xe4, %%ymm8,  %%ymm10, %%ymm10  \n\t"
  2098.         "vshufps   $0xe4, %%ymm7,  %%ymm8,  %%ymm8   \n\t"
  2099.         "                                            \n\t"
  2100.         "                                            \n\t" // ymm15:  ymm13:  ymm11:  ymm9:
  2101.         "                                            \n\t" // ( ab00  ( ab01  ( ab02  ( ab03
  2102.         "                                            \n\t" //   ab10    ab11    ab12    ab13
  2103.         "                                            \n\t" //   ab20    ab21    ab22    ab23
  2104.         "                                            \n\t" //   ab30    ab31    ab32    ab33
  2105.         "                                            \n\t" //   ab42    ab43    ab40    ab41
  2106.         "                                            \n\t" //   ab52    ab53    ab50    ab51
  2107.         "                                            \n\t" //   ab62    ab63    ab60    ab61
  2108.         "                                            \n\t" //   ab72 )  ab73 )  ab70 )  ab71 )
  2109.         "                                            \n\t"
  2110.         "                                            \n\t" // ymm14:  ymm12:  ymm10:  ymm8:
  2111.         "                                            \n\t" // ( ab80  ( ab81  ( ab82  ( ab83
  2112.         "                                            \n\t" //   ab90    ab91    ab92    ab93
  2113.         "                                            \n\t" //   aba0    aba1    aba2    aba3
  2114.         "                                            \n\t" //   abb0    abb1    abb2    abb3
  2115.         "                                            \n\t" //   abc2    abc3    abc0    abc1
  2116.         "                                            \n\t" //   abd2    abd3    abd0    abd1
  2117.         "                                            \n\t" //   abe2    abe3    abe0    abe1
  2118.         "                                            \n\t" //   abf2 )  abf3 )  abf0 )  abf1 )
  2119.         "                                            \n\t"
  2120.         "vmovaps           %%ymm15, %%ymm7           \n\t"
  2121.         "vperm2f128 $0x12, %%ymm15, %%ymm11, %%ymm15 \n\t"
  2122.         "vperm2f128 $0x30, %%ymm7,  %%ymm11, %%ymm11 \n\t"
  2123.         "                                            \n\t"
  2124.         "vmovaps           %%ymm13, %%ymm7           \n\t"
  2125.         "vperm2f128 $0x12, %%ymm13, %%ymm9,  %%ymm13 \n\t"
  2126.         "vperm2f128 $0x30, %%ymm7,  %%ymm9,  %%ymm9  \n\t"
  2127.         "                                            \n\t"
  2128.         "vmovaps           %%ymm14, %%ymm7           \n\t"
  2129.         "vperm2f128 $0x12, %%ymm14, %%ymm10, %%ymm14 \n\t"
  2130.         "vperm2f128 $0x30, %%ymm7,  %%ymm10, %%ymm10 \n\t"
  2131.         "                                            \n\t"
  2132.         "vmovaps           %%ymm12, %%ymm7           \n\t"
  2133.         "vperm2f128 $0x12, %%ymm12, %%ymm8,  %%ymm12 \n\t"
  2134.         "vperm2f128 $0x30, %%ymm7,  %%ymm8,  %%ymm8  \n\t"
  2135.         "                                            \n\t"
  2136.         "                                            \n\t" // ymm15:  ymm13:  ymm11:  ymm9:
  2137.         "                                            \n\t" // ( ab00  ( ab01  ( ab02  ( ab03
  2138.         "                                            \n\t" //   ab10    ab11    ab12    ab13
  2139.         "                                            \n\t" //   ab20    ab21    ab22    ab23
  2140.         "                                            \n\t" //   ab30    ab31    ab32    ab33
  2141.         "                                            \n\t" //   ab40    ab41    ab42    ab43
  2142.         "                                            \n\t" //   ab50    ab51    ab52    ab53
  2143.         "                                            \n\t" //   ab60    ab61    ab62    ab63
  2144.         "                                            \n\t" //   ab70 )  ab71 )  ab72 )  ab73 )
  2145.         "                                            \n\t"
  2146.         "                                            \n\t" // ymm14:  ymm12:  ymm10:  ymm8:
  2147.         "                                            \n\t" // ( ab80  ( ab81  ( ab82  ( ab83
  2148.         "                                            \n\t" //   ab90    ab91    ab92    ab93
  2149.         "                                            \n\t" //   aba0    aba1    aba2    aba3
  2150.         "                                            \n\t" //   abb0    abb1    abb2    abb3
  2151.         "                                            \n\t" //   abc0    abc1    abc2    abc3
  2152.         "                                            \n\t" //   abd0    abd1    abd2    abd3
  2153.         "                                            \n\t" //   abe0    abe1    abe2    abe3
  2154.         "                                            \n\t" //   abf0 )  abf1 )  abf2 )  abf3 )
  2155.         "                                            \n\t"
  2156.         "                                            \n\t"
  2157.         "                                            \n\t"
  2158.         "                                            \n\t"
  2159.         "                                            \n\t" // scale by alpha
  2160.         "                                            \n\t"
  2161.         "movq         %4, %%rax                      \n\t" // load address of alpha
  2162.         "vbroadcastss    (%%rax), %%ymm7             \n\t" // load alpha_r and duplicate
  2163.         "vbroadcastss   4(%%rax), %%ymm6             \n\t" // load alpha_i and duplicate
  2164.         "                                            \n\t"
  2165.         "vpermilps $0xb1, %%ymm15, %%ymm3            \n\t"
  2166.         "vmulps           %%ymm7,  %%ymm15, %%ymm15  \n\t"
  2167.         "vmulps           %%ymm6,  %%ymm3,  %%ymm3   \n\t"
  2168.         "vaddsubps        %%ymm3,  %%ymm15, %%ymm15  \n\t"
  2169.         "                                            \n\t"
  2170.         "vpermilps $0xb1, %%ymm14, %%ymm2            \n\t"
  2171.         "vmulps           %%ymm7,  %%ymm14, %%ymm14  \n\t"
  2172.         "vmulps           %%ymm6,  %%ymm2,  %%ymm2   \n\t"
  2173.         "vaddsubps        %%ymm2,  %%ymm14, %%ymm14  \n\t"
  2174.         "                                            \n\t"
  2175.         "vpermilps $0xb1, %%ymm13, %%ymm1            \n\t"
  2176.         "vmulps           %%ymm7,  %%ymm13, %%ymm13  \n\t"
  2177.         "vmulps           %%ymm6,  %%ymm1,  %%ymm1   \n\t"
  2178.         "vaddsubps        %%ymm1,  %%ymm13, %%ymm13  \n\t"
  2179.         "                                            \n\t"
  2180.         "vpermilps $0xb1, %%ymm12, %%ymm0            \n\t"
  2181.         "vmulps           %%ymm7,  %%ymm12, %%ymm12  \n\t"
  2182.         "vmulps           %%ymm6,  %%ymm0,  %%ymm0   \n\t"
  2183.         "vaddsubps        %%ymm0,  %%ymm12, %%ymm12  \n\t"
  2184.         "                                            \n\t"
  2185.         "vpermilps $0xb1, %%ymm11, %%ymm3            \n\t"
  2186.         "vmulps           %%ymm7,  %%ymm11, %%ymm11  \n\t"
  2187.         "vmulps           %%ymm6,  %%ymm3,  %%ymm3   \n\t"
  2188.         "vaddsubps        %%ymm3,  %%ymm11, %%ymm11  \n\t"
  2189.         "                                            \n\t"
  2190.         "vpermilps $0xb1, %%ymm10, %%ymm2            \n\t"
  2191.         "vmulps           %%ymm7,  %%ymm10, %%ymm10  \n\t"
  2192.         "vmulps           %%ymm6,  %%ymm2,  %%ymm2   \n\t"
  2193.         "vaddsubps        %%ymm2,  %%ymm10, %%ymm10  \n\t"
  2194.         "                                            \n\t"
  2195.         "vpermilps $0xb1, %%ymm9,  %%ymm1            \n\t"
  2196.         "vmulps           %%ymm7,  %%ymm9,  %%ymm9   \n\t"
  2197.         "vmulps           %%ymm6,  %%ymm1,  %%ymm1   \n\t"
  2198.         "vaddsubps        %%ymm1,  %%ymm9,  %%ymm9   \n\t"
  2199.         "                                            \n\t"
  2200.         "vpermilps $0xb1, %%ymm8,  %%ymm0            \n\t"
  2201.         "vmulps           %%ymm7,  %%ymm8,  %%ymm8   \n\t"
  2202.         "vmulps           %%ymm6,  %%ymm0,  %%ymm0   \n\t"
  2203.         "vaddsubps        %%ymm0,  %%ymm8,  %%ymm8   \n\t"
  2204.         "                                            \n\t"
  2205.         "                                            \n\t"
  2206.         "                                            \n\t"
  2207.         "                                            \n\t"
  2208.         "movq         %5, %%rbx                      \n\t" // load address of beta
  2209.         "vbroadcastss    (%%rbx), %%ymm7             \n\t" // load beta_r and duplicate
  2210.         "vbroadcastss   4(%%rbx), %%ymm6             \n\t" // load beta_i and duplicate
  2211.         "                                            \n\t"
  2212.         "                                            \n\t"
  2213.         "                                            \n\t"
  2214.         "                                            \n\t"
  2215.         "                                            \n\t"
  2216.         "                                            \n\t"
  2217.         "                                            \n\t"
  2218.         "movq                %7, %%rsi               \n\t" // load rs_c
  2219.         "leaq        (,%%rsi,8), %%rsi               \n\t" // rsi = rs_c * sizeof(scomplex)
  2220.         "                                            \n\t"
  2221.         "leaq   (%%rcx,%%rsi,4), %%rdx               \n\t" // load address of c + 4*rs_c;
  2222.         "                                            \n\t"
  2223.         "leaq        (,%%rsi,2), %%r12               \n\t" // r12 = 2*rs_c;
  2224.         "leaq   (%%r12,%%rsi,1), %%r13               \n\t" // r13 = 3*rs_c;
  2225.         "                                            \n\t"
  2226.         "                                            \n\t"
  2227.         "                                            \n\t" // now avoid loading C if beta == 0
  2228.         "                                            \n\t"
  2229.         "vxorps    %%ymm0,  %%ymm0,  %%ymm0          \n\t" // set ymm0 to zero.
  2230.         "vucomiss  %%xmm0,  %%xmm7                   \n\t" // set ZF if beta_r == 0.
  2231.         "sete       %%r8b                            \n\t" // r8b = ( ZF == 1 ? 1 : 0 );
  2232.         "vucomiss  %%xmm0,  %%xmm6                   \n\t" // set ZF if beta_i == 0.
  2233.         "sete       %%r9b                            \n\t" // r9b = ( ZF == 1 ? 1 : 0 );
  2234.         "andb       %%r8b, %%r9b                     \n\t" // set ZF if r8b & r9b == 1.
  2235.         "jne      .CBETAZERO                         \n\t" // if ZF = 0, jump to beta == 0 case
  2236.         "                                            \n\t"
  2237.         "                                            \n\t"
  2238.         "cmpq       $8, %%rsi                        \n\t" // set ZF if (8*cs_c) == 8.
  2239.         "jz      .CCOLSTORED                         \n\t" // jump to column storage case
  2240.         "                                            \n\t"
  2241.         "                                            \n\t"
  2242.         "                                            \n\t"
  2243.         ".CGENSTORED:                                \n\t"
  2244.         "                                            \n\t"
  2245.         "                                            \n\t" // update c00:c70
  2246.         "                                            \n\t"
  2247.         "vmovlpd    (%%rcx),       %%xmm0,  %%xmm0   \n\t" // load (c00,10) into xmm0[0:1]
  2248.         "vmovhpd    (%%rcx,%%rsi), %%xmm0,  %%xmm0   \n\t" // load (c20,30) into xmm0[2:3]
  2249.         "vmovlpd    (%%rcx,%%r12), %%xmm2,  %%xmm2   \n\t" // load (c40,50) into xmm2[0:1]
  2250.         "vmovhpd    (%%rcx,%%r13), %%xmm2,  %%xmm2   \n\t" // load (c60,70) into xmm2[2:3]
  2251.         "vinsertf128  $1, %%xmm2,  %%ymm0,  %%ymm0   \n\t" // ymm0 := (ymm0[0:3],xmm2)
  2252.         "vpermilps $0xb1, %%ymm0,  %%ymm2            \n\t" // scale ymm0 by beta
  2253.         "vmulps           %%ymm7,  %%ymm0,  %%ymm0   \n\t"
  2254.         "vmulps           %%ymm6,  %%ymm2,  %%ymm2   \n\t"
  2255.         "vaddsubps        %%ymm2,  %%ymm0,  %%ymm0   \n\t"
  2256.         "vaddps           %%ymm15, %%ymm0,  %%ymm0   \n\t" // add the gemm result to ymm0
  2257.         "vextractf128 $1, %%ymm0,  %%xmm2            \n\t" // xmm2 := ymm0[4:7]
  2258.         "vmovlpd          %%xmm0,  (%%rcx)           \n\t" // store (c00,c10)
  2259.         "vmovhpd          %%xmm0,  (%%rcx,%%rsi)     \n\t" // store (c20,c30)
  2260.         "vmovlpd          %%xmm2,  (%%rcx,%%r12)     \n\t" // store (c40,c50)
  2261.         "vmovhpd          %%xmm2,  (%%rcx,%%r13)     \n\t" // store (c60,c70)
  2262.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  2263.         "                                            \n\t"
  2264.         "                                            \n\t" // update c80:cf0
  2265.         "                                            \n\t"
  2266.         "vmovlpd    (%%rdx),       %%xmm0,  %%xmm0   \n\t" // load (c80,90) into xmm0[0:1]
  2267.         "vmovhpd    (%%rdx,%%rsi), %%xmm0,  %%xmm0   \n\t" // load (ca0,b0) into xmm0[2:3]
  2268.         "vmovlpd    (%%rdx,%%r12), %%xmm2,  %%xmm2   \n\t" // load (cc0,d0) into xmm2[0:1]
  2269.         "vmovhpd    (%%rdx,%%r13), %%xmm2,  %%xmm2   \n\t" // load (ce0,f0) into xmm2[2:3]
  2270.         "vinsertf128  $1, %%xmm2,  %%ymm0,  %%ymm0   \n\t" // ymm0 := (ymm0[0:3],xmm2)
  2271.         "vpermilps $0xb1, %%ymm0,  %%ymm2            \n\t" // scale ymm0 by beta
  2272.         "vmulps           %%ymm7,  %%ymm0,  %%ymm0   \n\t"
  2273.         "vmulps           %%ymm6,  %%ymm2,  %%ymm2   \n\t"
  2274.         "vaddsubps        %%ymm2,  %%ymm0,  %%ymm0   \n\t"
  2275.         "vaddps           %%ymm14, %%ymm0,  %%ymm0   \n\t" // add the gemm result to ymm0
  2276.         "vextractf128 $1, %%ymm0,  %%xmm2            \n\t" // xmm2 := ymm0[4:7]
  2277.         "vmovlpd          %%xmm0,  (%%rdx)           \n\t" // store (c80,c90)
  2278.         "vmovhpd          %%xmm0,  (%%rdx,%%rsi)     \n\t" // store (ca0,cb0)
  2279.         "vmovlpd          %%xmm2,  (%%rdx,%%r12)     \n\t" // store (cc0,cd0)
  2280.         "vmovhpd          %%xmm2,  (%%rdx,%%r13)     \n\t" // store (ce0,cf0)
  2281.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  2282.         "                                            \n\t"
  2283.         "                                            \n\t" // update c01:c71
  2284.         "                                            \n\t"
  2285.         "vmovlpd    (%%rcx),       %%xmm0,  %%xmm0   \n\t" // load (c01,11) into xmm0[0:1]
  2286.         "vmovhpd    (%%rcx,%%rsi), %%xmm0,  %%xmm0   \n\t" // load (c21,31) into xmm0[2:3]
  2287.         "vmovlpd    (%%rcx,%%r12), %%xmm2,  %%xmm2   \n\t" // load (c41,51) into xmm2[0:1]
  2288.         "vmovhpd    (%%rcx,%%r13), %%xmm2,  %%xmm2   \n\t" // load (c61,71) into xmm2[2:3]
  2289.         "vinsertf128  $1, %%xmm2,  %%ymm0,  %%ymm0   \n\t" // ymm0 := (ymm0[0:3],xmm2)
  2290.         "vpermilps $0xb1, %%ymm0,  %%ymm2            \n\t" // scale ymm0 by beta
  2291.         "vmulps           %%ymm7,  %%ymm0,  %%ymm0   \n\t"
  2292.         "vmulps           %%ymm6,  %%ymm2,  %%ymm2   \n\t"
  2293.         "vaddsubps        %%ymm2,  %%ymm0,  %%ymm0   \n\t"
  2294.         "vaddps           %%ymm13, %%ymm0,  %%ymm0   \n\t" // add the gemm result to ymm0
  2295.         "vextractf128 $1, %%ymm0,  %%xmm2            \n\t" // xmm2 := ymm0[4:7]
  2296.         "vmovlpd          %%xmm0,  (%%rcx)           \n\t" // store (c01,c11)
  2297.         "vmovhpd          %%xmm0,  (%%rcx,%%rsi)     \n\t" // store (c21,c31)
  2298.         "vmovlpd          %%xmm2,  (%%rcx,%%r12)     \n\t" // store (c41,c51)
  2299.         "vmovhpd          %%xmm2,  (%%rcx,%%r13)     \n\t" // store (c61,c71)
  2300.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  2301.         "                                            \n\t"
  2302.         "                                            \n\t" // update c81:cf1
  2303.         "                                            \n\t"
  2304.         "vmovlpd    (%%rdx),       %%xmm0,  %%xmm0   \n\t" // load (c81,91) into xmm0[0:1]
  2305.         "vmovhpd    (%%rdx,%%rsi), %%xmm0,  %%xmm0   \n\t" // load (ca1,b1) into xmm0[2:3]
  2306.         "vmovlpd    (%%rdx,%%r12), %%xmm2,  %%xmm2   \n\t" // load (cc1,d1) into xmm2[0:1]
  2307.         "vmovhpd    (%%rdx,%%r13), %%xmm2,  %%xmm2   \n\t" // load (ce1,f1) into xmm2[2:3]
  2308.         "vinsertf128  $1, %%xmm2,  %%ymm0,  %%ymm0   \n\t" // ymm0 := (ymm0[0:3],xmm2)
  2309.         "vpermilps $0xb1, %%ymm0,  %%ymm2            \n\t" // scale ymm0 by beta
  2310.         "vmulps           %%ymm7,  %%ymm0,  %%ymm0   \n\t"
  2311.         "vmulps           %%ymm6,  %%ymm2,  %%ymm2   \n\t"
  2312.         "vaddsubps        %%ymm2,  %%ymm0,  %%ymm0   \n\t"
  2313.         "vaddps           %%ymm12, %%ymm0,  %%ymm0   \n\t" // add the gemm result to ymm0
  2314.         "vextractf128 $1, %%ymm0,  %%xmm2            \n\t" // xmm2 := ymm0[4:7]
  2315.         "vmovlpd          %%xmm0,  (%%rdx)           \n\t" // store (c81,c91)
  2316.         "vmovhpd          %%xmm0,  (%%rdx,%%rsi)     \n\t" // store (ca1,cb1)
  2317.         "vmovlpd          %%xmm2,  (%%rdx,%%r12)     \n\t" // store (cc1,cd1)
  2318.         "vmovhpd          %%xmm2,  (%%rdx,%%r13)     \n\t" // store (ce1,cf1)
  2319.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  2320.         "                                            \n\t"
  2321.         "                                            \n\t" // update c02:c72
  2322.         "                                            \n\t"
  2323.         "vmovlpd    (%%rcx),       %%xmm0,  %%xmm0   \n\t" // load (c02,12) into xmm0[0:1]
  2324.         "vmovhpd    (%%rcx,%%rsi), %%xmm0,  %%xmm0   \n\t" // load (c22,32) into xmm0[2:3]
  2325.         "vmovlpd    (%%rcx,%%r12), %%xmm2,  %%xmm2   \n\t" // load (c42,52) into xmm2[0:1]
  2326.         "vmovhpd    (%%rcx,%%r13), %%xmm2,  %%xmm2   \n\t" // load (c62,72) into xmm2[2:3]
  2327.         "vinsertf128  $1, %%xmm2,  %%ymm0,  %%ymm0   \n\t" // ymm0 := (ymm0[0:3],xmm2)
  2328.         "vpermilps $0xb1, %%ymm0,  %%ymm2            \n\t" // scale ymm0 by beta
  2329.         "vmulps           %%ymm7,  %%ymm0,  %%ymm0   \n\t"
  2330.         "vmulps           %%ymm6,  %%ymm2,  %%ymm2   \n\t"
  2331.         "vaddsubps        %%ymm2,  %%ymm0,  %%ymm0   \n\t"
  2332.         "vaddps           %%ymm11, %%ymm0,  %%ymm0   \n\t" // add the gemm result to ymm0
  2333.         "vextractf128 $1, %%ymm0,  %%xmm2            \n\t" // xmm2 := ymm0[4:7]
  2334.         "vmovlpd          %%xmm0,  (%%rcx)           \n\t" // store (c02,c12)
  2335.         "vmovhpd          %%xmm0,  (%%rcx,%%rsi)     \n\t" // store (c22,c32)
  2336.         "vmovlpd          %%xmm2,  (%%rcx,%%r12)     \n\t" // store (c42,c52)
  2337.         "vmovhpd          %%xmm2,  (%%rcx,%%r13)     \n\t" // store (c62,c72)
  2338.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  2339.         "                                            \n\t"
  2340.         "                                            \n\t" // update c82:cf2
  2341.         "                                            \n\t"
  2342.         "vmovlpd    (%%rdx),       %%xmm0,  %%xmm0   \n\t" // load (c82,92) into xmm0[0:1]
  2343.         "vmovhpd    (%%rdx,%%rsi), %%xmm0,  %%xmm0   \n\t" // load (ca2,b2) into xmm0[2:3]
  2344.         "vmovlpd    (%%rdx,%%r12), %%xmm2,  %%xmm2   \n\t" // load (cc2,d2) into xmm2[0:1]
  2345.         "vmovhpd    (%%rdx,%%r13), %%xmm2,  %%xmm2   \n\t" // load (ce2,f2) into xmm2[2:3]
  2346.         "vinsertf128  $1, %%xmm2,  %%ymm0,  %%ymm0   \n\t" // ymm0 := (ymm0[0:3],xmm2)
  2347.         "vpermilps $0xb1, %%ymm0,  %%ymm2            \n\t" // scale ymm0 by beta
  2348.         "vmulps           %%ymm7,  %%ymm0,  %%ymm0   \n\t"
  2349.         "vmulps           %%ymm6,  %%ymm2,  %%ymm2   \n\t"
  2350.         "vaddsubps        %%ymm2,  %%ymm0,  %%ymm0   \n\t"
  2351.         "vaddps           %%ymm10, %%ymm0,  %%ymm0   \n\t" // add the gemm result to ymm0
  2352.         "vextractf128 $1, %%ymm0,  %%xmm2            \n\t" // xmm2 := ymm0[4:7]
  2353.         "vmovlpd          %%xmm0,  (%%rdx)           \n\t" // store (c82,c92)
  2354.         "vmovhpd          %%xmm0,  (%%rdx,%%rsi)     \n\t" // store (ca2,cb2)
  2355.         "vmovlpd          %%xmm2,  (%%rdx,%%r12)     \n\t" // store (cc2,cd2)
  2356.         "vmovhpd          %%xmm2,  (%%rdx,%%r13)     \n\t" // store (ce2,cf2)
  2357.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  2358.         "                                            \n\t"
  2359.         "                                            \n\t" // update c03:c73
  2360.         "                                            \n\t"
  2361.         "vmovlpd    (%%rcx),       %%xmm0,  %%xmm0   \n\t" // load (c03,13) into xmm0[0:1]
  2362.         "vmovhpd    (%%rcx,%%rsi), %%xmm0,  %%xmm0   \n\t" // load (c23,33) into xmm0[2:3]
  2363.         "vmovlpd    (%%rcx,%%r12), %%xmm2,  %%xmm2   \n\t" // load (c43,53) into xmm2[0:1]
  2364.         "vmovhpd    (%%rcx,%%r13), %%xmm2,  %%xmm2   \n\t" // load (c63,73) into xmm2[2:3]
  2365.         "vinsertf128  $1, %%xmm2,  %%ymm0,  %%ymm0   \n\t" // ymm0 := (ymm0[0:3],xmm2)
  2366.         "vpermilps $0xb1, %%ymm0,  %%ymm2            \n\t" // scale ymm0 by beta
  2367.         "vmulps           %%ymm7,  %%ymm0,  %%ymm0   \n\t"
  2368.         "vmulps           %%ymm6,  %%ymm2,  %%ymm2   \n\t"
  2369.         "vaddsubps        %%ymm2,  %%ymm0,  %%ymm0   \n\t"
  2370.         "vaddps           %%ymm9,  %%ymm0,  %%ymm0   \n\t" // add the gemm result to ymm0
  2371.         "vextractf128 $1, %%ymm0,  %%xmm2            \n\t" // xmm2 := ymm0[4:7]
  2372.         "vmovlpd          %%xmm0,  (%%rcx)           \n\t" // store (c03,c13)
  2373.         "vmovhpd          %%xmm0,  (%%rcx,%%rsi)     \n\t" // store (c23,c33)
  2374.         "vmovlpd          %%xmm2,  (%%rcx,%%r12)     \n\t" // store (c43,c53)
  2375.         "vmovhpd          %%xmm2,  (%%rcx,%%r13)     \n\t" // store (c63,c73)
  2376.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  2377.         "                                            \n\t"
  2378.         "                                            \n\t" // update c83:cf3
  2379.         "                                            \n\t"
  2380.         "vmovlpd    (%%rdx),       %%xmm0,  %%xmm0   \n\t" // load (c83,93) into xmm0[0:1]
  2381.         "vmovhpd    (%%rdx,%%rsi), %%xmm0,  %%xmm0   \n\t" // load (ca3,b3) into xmm0[2:3]
  2382.         "vmovlpd    (%%rdx,%%r12), %%xmm2,  %%xmm2   \n\t" // load (cc3,d3) into xmm2[0:1]
  2383.         "vmovhpd    (%%rdx,%%r13), %%xmm2,  %%xmm2   \n\t" // load (ce3,f3) into xmm2[2:3]
  2384.         "vinsertf128  $1, %%xmm2,  %%ymm0,  %%ymm0   \n\t" // ymm0 := (ymm0[0:3],xmm2)
  2385.         "vpermilps $0xb1, %%ymm0,  %%ymm2            \n\t" // scale ymm0 by beta
  2386.         "vmulps           %%ymm7,  %%ymm0,  %%ymm0   \n\t"
  2387.         "vmulps           %%ymm6,  %%ymm2,  %%ymm2   \n\t"
  2388.         "vaddsubps        %%ymm2,  %%ymm0,  %%ymm0   \n\t"
  2389.         "vaddps           %%ymm8,  %%ymm0,  %%ymm0   \n\t" // add the gemm result to ymm0
  2390.         "vextractf128 $1, %%ymm0,  %%xmm2            \n\t" // xmm2 := ymm0[4:7]
  2391.         "vmovlpd          %%xmm0,  (%%rdx)           \n\t" // store (c83,c93)
  2392.         "vmovhpd          %%xmm0,  (%%rdx,%%rsi)     \n\t" // store (ca3,cb3)
  2393.         "vmovlpd          %%xmm2,  (%%rdx,%%r12)     \n\t" // store (cc3,cd3)
  2394.         "vmovhpd          %%xmm2,  (%%rdx,%%r13)     \n\t" // store (ce3,cf3)
  2395.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  2396.         "                                            \n\t"
  2397.         "                                            \n\t"
  2398.         "                                            \n\t"
  2399.         "jmp    .CDONE                               \n\t" // jump to end.
  2400.         "                                            \n\t"
  2401.         "                                            \n\t"
  2402.         "                                            \n\t"
  2403.         ".CCOLSTORED:                                \n\t"
  2404.         "                                            \n\t"
  2405.         "                                            \n\t" // update c00:c70
  2406.         "                                            \n\t"
  2407.         "vmovups    (%%rcx),       %%ymm0            \n\t" // load c00:c70 into ymm0
  2408.         "vpermilps $0xb1, %%ymm0,  %%ymm2            \n\t" // scale ymm0 by beta
  2409.         "vmulps           %%ymm7,  %%ymm0,  %%ymm0   \n\t"
  2410.         "vmulps           %%ymm6,  %%ymm2,  %%ymm2   \n\t"
  2411.         "vaddsubps        %%ymm2,  %%ymm0,  %%ymm0   \n\t"
  2412.         "vaddps           %%ymm15, %%ymm0,  %%ymm0   \n\t" // add the gemm result to ymm0
  2413.         "vmovups          %%ymm0,  (%%rcx)           \n\t" // store c00:c70
  2414.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  2415.         "                                            \n\t"
  2416.         "                                            \n\t" // update c80:cf0
  2417.         "                                            \n\t"
  2418.         "vmovups    (%%rdx),       %%ymm0            \n\t" // load c80:f0 into ymm0
  2419.         "vpermilps $0xb1, %%ymm0,  %%ymm2            \n\t" // scale ymm0 by beta
  2420.         "vmulps           %%ymm7,  %%ymm0,  %%ymm0   \n\t"
  2421.         "vmulps           %%ymm6,  %%ymm2,  %%ymm2   \n\t"
  2422.         "vaddsubps        %%ymm2,  %%ymm0,  %%ymm0   \n\t"
  2423.         "vaddps           %%ymm14, %%ymm0,  %%ymm0   \n\t" // add the gemm result to ymm0
  2424.         "vmovups          %%ymm0,  (%%rdx)           \n\t" // store c80:cf0
  2425.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  2426.         "                                            \n\t"
  2427.         "                                            \n\t" // update c00:c70
  2428.         "                                            \n\t"
  2429.         "vmovups    (%%rcx),       %%ymm0            \n\t" // load c01:c71 into ymm0
  2430.         "vpermilps $0xb1, %%ymm0,  %%ymm2            \n\t" // scale ymm0 by beta
  2431.         "vmulps           %%ymm7,  %%ymm0,  %%ymm0   \n\t"
  2432.         "vmulps           %%ymm6,  %%ymm2,  %%ymm2   \n\t"
  2433.         "vaddsubps        %%ymm2,  %%ymm0,  %%ymm0   \n\t"
  2434.         "vaddps           %%ymm13, %%ymm0,  %%ymm0   \n\t" // add the gemm result to ymm0
  2435.         "vmovups          %%ymm0,  (%%rcx)           \n\t" // store c01:c71
  2436.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  2437.         "                                            \n\t"
  2438.         "                                            \n\t" // update c81:cf1
  2439.         "                                            \n\t"
  2440.         "vmovups    (%%rdx),       %%ymm0            \n\t" // load c81:f1 into ymm0
  2441.         "vpermilps $0xb1, %%ymm0,  %%ymm2            \n\t" // scale ymm0 by beta
  2442.         "vmulps           %%ymm7,  %%ymm0,  %%ymm0   \n\t"
  2443.         "vmulps           %%ymm6,  %%ymm2,  %%ymm2   \n\t"
  2444.         "vaddsubps        %%ymm2,  %%ymm0,  %%ymm0   \n\t"
  2445.         "vaddps           %%ymm12, %%ymm0,  %%ymm0   \n\t" // add the gemm result to ymm0
  2446.         "vmovups          %%ymm0,  (%%rdx)           \n\t" // store c81:cf1
  2447.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  2448.         "                                            \n\t"
  2449.         "                                            \n\t" // update c02:c72
  2450.         "                                            \n\t"
  2451.         "vmovups    (%%rcx),       %%ymm0            \n\t" // load c02:c72 into ymm0
  2452.         "vpermilps $0xb1, %%ymm0,  %%ymm2            \n\t" // scale ymm0 by beta
  2453.         "vmulps           %%ymm7,  %%ymm0,  %%ymm0   \n\t"
  2454.         "vmulps           %%ymm6,  %%ymm2,  %%ymm2   \n\t"
  2455.         "vaddsubps        %%ymm2,  %%ymm0,  %%ymm0   \n\t"
  2456.         "vaddps           %%ymm11, %%ymm0,  %%ymm0   \n\t" // add the gemm result to ymm0
  2457.         "vmovups          %%ymm0,  (%%rcx)           \n\t" // store c02:c72
  2458.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  2459.         "                                            \n\t"
  2460.         "                                            \n\t" // update c82:cf2
  2461.         "                                            \n\t"
  2462.         "vmovups    (%%rdx),       %%ymm0            \n\t" // load c82:f2 into ymm0
  2463.         "vpermilps $0xb1, %%ymm0,  %%ymm2            \n\t" // scale ymm0 by beta
  2464.         "vmulps           %%ymm7,  %%ymm0,  %%ymm0   \n\t"
  2465.         "vmulps           %%ymm6,  %%ymm2,  %%ymm2   \n\t"
  2466.         "vaddsubps        %%ymm2,  %%ymm0,  %%ymm0   \n\t"
  2467.         "vaddps           %%ymm10, %%ymm0,  %%ymm0   \n\t" // add the gemm result to ymm0
  2468.         "vmovups          %%ymm0,  (%%rdx)           \n\t" // store c82:cf2
  2469.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  2470.         "                                            \n\t"
  2471.         "                                            \n\t" // update c03:c73
  2472.         "                                            \n\t"
  2473.         "vmovups    (%%rcx),       %%ymm0            \n\t" // load c03:c73 into ymm0
  2474.         "vpermilps $0xb1, %%ymm0,  %%ymm2            \n\t" // scale ymm0 by beta
  2475.         "vmulps           %%ymm7,  %%ymm0,  %%ymm0   \n\t"
  2476.         "vmulps           %%ymm6,  %%ymm2,  %%ymm2   \n\t"
  2477.         "vaddsubps        %%ymm2,  %%ymm0,  %%ymm0   \n\t"
  2478.         "vaddps           %%ymm9,  %%ymm0,  %%ymm0   \n\t" // add the gemm result to ymm0
  2479.         "vmovups          %%ymm0,  (%%rcx)           \n\t" // store c03:c73
  2480.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  2481.         "                                            \n\t"
  2482.         "                                            \n\t" // update c83:cf3
  2483.         "                                            \n\t"
  2484.         "vmovups    (%%rdx),       %%ymm0            \n\t" // load c83:f3 into ymm0
  2485.         "vpermilps $0xb1, %%ymm0,  %%ymm2            \n\t" // scale ymm0 by beta
  2486.         "vmulps           %%ymm7,  %%ymm0,  %%ymm0   \n\t"
  2487.         "vmulps           %%ymm6,  %%ymm2,  %%ymm2   \n\t"
  2488.         "vaddsubps        %%ymm2,  %%ymm0,  %%ymm0   \n\t"
  2489.         "vaddps           %%ymm8,  %%ymm0,  %%ymm0   \n\t" // add the gemm result to ymm0
  2490.         "vmovups          %%ymm0,  (%%rdx)           \n\t" // store c83:cf3
  2491.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  2492.         "                                            \n\t"
  2493.         "                                            \n\t"
  2494.         "                                            \n\t"
  2495.         "jmp    .CDONE                               \n\t" // jump to end.
  2496.         "                                            \n\t"
  2497.         "                                            \n\t"
  2498.         "                                            \n\t"
  2499.         ".CBETAZERO:                                 \n\t"
  2500.         "                                            \n\t"
  2501.         "cmpq       $8, %%rsi                        \n\t" // set ZF if (8*cs_c) == 8.
  2502.         "jz      .CCOLSTORBZ                         \n\t" // jump to column storage case
  2503.         "                                            \n\t"
  2504.         "                                            \n\t"
  2505.         "                                            \n\t"
  2506.         ".CGENSTORBZ:                                \n\t"
  2507.         "                                            \n\t"
  2508.         "                                            \n\t" // update c00:c70
  2509.         "                                            \n\t"
  2510.         "vextractf128 $1, %%ymm15, %%xmm2            \n\t" // xmm2 := ymm0[4:7]
  2511.         "vmovlpd          %%xmm15, (%%rcx)           \n\t" // store (c00,c10)
  2512.         "vmovhpd          %%xmm15, (%%rcx,%%rsi)     \n\t" // store (c20,c30)
  2513.         "vmovlpd          %%xmm2,  (%%rcx,%%r12)     \n\t" // store (c40,c50)
  2514.         "vmovhpd          %%xmm2,  (%%rcx,%%r13)     \n\t" // store (c60,c70)
  2515.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  2516.         "                                            \n\t"
  2517.         "                                            \n\t" // update c80:cf0
  2518.         "                                            \n\t"
  2519.         "vextractf128 $1, %%ymm14, %%xmm2            \n\t" // xmm2 := ymm0[4:7]
  2520.         "vmovlpd          %%xmm14, (%%rdx)           \n\t" // store (c80,c90)
  2521.         "vmovhpd          %%xmm14, (%%rdx,%%rsi)     \n\t" // store (ca0,cb0)
  2522.         "vmovlpd          %%xmm2,  (%%rdx,%%r12)     \n\t" // store (cc0,cd0)
  2523.         "vmovhpd          %%xmm2,  (%%rdx,%%r13)     \n\t" // store (ce0,cf0)
  2524.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  2525.         "                                            \n\t"
  2526.         "                                            \n\t" // update c01:c71
  2527.         "                                            \n\t"
  2528.         "vextractf128 $1, %%ymm13, %%xmm2            \n\t" // xmm2 := ymm0[4:7]
  2529.         "vmovlpd          %%xmm13, (%%rcx)           \n\t" // store (c01,c11)
  2530.         "vmovhpd          %%xmm13, (%%rcx,%%rsi)     \n\t" // store (c21,c31)
  2531.         "vmovlpd          %%xmm2,  (%%rcx,%%r12)     \n\t" // store (c41,c51)
  2532.         "vmovhpd          %%xmm2,  (%%rcx,%%r13)     \n\t" // store (c61,c71)
  2533.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  2534.         "                                            \n\t"
  2535.         "                                            \n\t" // update c81:cf1
  2536.         "                                            \n\t"
  2537.         "vextractf128 $1, %%ymm12, %%xmm2            \n\t" // xmm2 := ymm0[4:7]
  2538.         "vmovlpd          %%xmm12, (%%rdx)           \n\t" // store (c81,c91)
  2539.         "vmovhpd          %%xmm12, (%%rdx,%%rsi)     \n\t" // store (ca1,cb1)
  2540.         "vmovlpd          %%xmm2,  (%%rdx,%%r12)     \n\t" // store (cc1,cd1)
  2541.         "vmovhpd          %%xmm2,  (%%rdx,%%r13)     \n\t" // store (ce1,cf1)
  2542.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  2543.         "                                            \n\t"
  2544.         "                                            \n\t" // update c02:c72
  2545.         "                                            \n\t"
  2546.         "vextractf128 $1, %%ymm11, %%xmm2            \n\t" // xmm2 := ymm0[4:7]
  2547.         "vmovlpd          %%xmm11, (%%rcx)           \n\t" // store (c02,c12)
  2548.         "vmovhpd          %%xmm11, (%%rcx,%%rsi)     \n\t" // store (c22,c32)
  2549.         "vmovlpd          %%xmm2,  (%%rcx,%%r12)     \n\t" // store (c42,c52)
  2550.         "vmovhpd          %%xmm2,  (%%rcx,%%r13)     \n\t" // store (c62,c72)
  2551.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  2552.         "                                            \n\t"
  2553.         "                                            \n\t" // update c82:cf2
  2554.         "                                            \n\t"
  2555.         "vextractf128 $1, %%ymm10, %%xmm2            \n\t" // xmm2 := ymm0[4:7]
  2556.         "vmovlpd          %%xmm10, (%%rdx)           \n\t" // store (c82,c92)
  2557.         "vmovhpd          %%xmm10, (%%rdx,%%rsi)     \n\t" // store (ca2,cb2)
  2558.         "vmovlpd          %%xmm2,  (%%rdx,%%r12)     \n\t" // store (cc2,cd2)
  2559.         "vmovhpd          %%xmm2,  (%%rdx,%%r13)     \n\t" // store (ce2,cf2)
  2560.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  2561.         "                                            \n\t"
  2562.         "                                            \n\t" // update c03:c73
  2563.         "                                            \n\t"
  2564.         "vextractf128 $1, %%ymm9,  %%xmm2            \n\t" // xmm2 := ymm0[4:7]
  2565.         "vmovlpd          %%xmm9,  (%%rcx)           \n\t" // store (c03,c13)
  2566.         "vmovhpd          %%xmm9,  (%%rcx,%%rsi)     \n\t" // store (c23,c33)
  2567.         "vmovlpd          %%xmm2,  (%%rcx,%%r12)     \n\t" // store (c43,c53)
  2568.         "vmovhpd          %%xmm2,  (%%rcx,%%r13)     \n\t" // store (c63,c73)
  2569.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  2570.         "                                            \n\t"
  2571.         "                                            \n\t" // update c83:cf3
  2572.         "                                            \n\t"
  2573.         "vextractf128 $1, %%ymm8,  %%xmm2            \n\t" // xmm2 := ymm0[4:7]
  2574.         "vmovlpd          %%xmm8,  (%%rdx)           \n\t" // store (c83,c93)
  2575.         "vmovhpd          %%xmm8,  (%%rdx,%%rsi)     \n\t" // store (ca3,cb3)
  2576.         "vmovlpd          %%xmm2,  (%%rdx,%%r12)     \n\t" // store (cc3,cd3)
  2577.         "vmovhpd          %%xmm2,  (%%rdx,%%r13)     \n\t" // store (ce3,cf3)
  2578.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  2579.         "                                            \n\t"
  2580.         "                                            \n\t"
  2581.         "                                            \n\t"
  2582.         "jmp    .CDONE                               \n\t" // jump to end.
  2583.         "                                            \n\t"
  2584.         "                                            \n\t"
  2585.         "                                            \n\t"
  2586.         ".CCOLSTORBZ:                                \n\t"
  2587.         "                                            \n\t"
  2588.         "                                            \n\t"
  2589.         "vmovups          %%ymm15, (%%rcx)           \n\t" // store c00:c70
  2590.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  2591.         "                                            \n\t"
  2592.         "vmovups          %%ymm14, (%%rdx)           \n\t" // store c80:cf0
  2593.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  2594.         "                                            \n\t"
  2595.         "vmovups          %%ymm13, (%%rcx)           \n\t" // store c01:c71
  2596.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  2597.         "                                            \n\t"
  2598.         "vmovups          %%ymm12, (%%rdx)           \n\t" // store c81:cf1
  2599.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  2600.         "                                            \n\t"
  2601.         "vmovups          %%ymm11, (%%rcx)           \n\t" // store c02:c72
  2602.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  2603.         "                                            \n\t"
  2604.         "vmovups          %%ymm10, (%%rdx)           \n\t" // store c82:cf2
  2605.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  2606.         "                                            \n\t"
  2607.         "vmovups          %%ymm9,  (%%rcx)           \n\t" // store c03:c73
  2608.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  2609.         "                                            \n\t"
  2610.         "vmovups          %%ymm8,  (%%rdx)           \n\t" // store c83:cf3
  2611.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  2612.         "                                            \n\t"
  2613.         "                                            \n\t"
  2614.         "                                            \n\t"
  2615.         "                                            \n\t"
  2616.         "                                            \n\t"
  2617.         ".CDONE:                                     \n\t"
  2618.     "                                            \n\t"
  2619.     "vzeroupper                                  \n\t"
  2620.         "                                            \n\t"
  2621.  
  2622.         : // output operands (none)
  2623.         : // input operands
  2624.           "m" (k_iter), // 0
  2625.           "m" (k_left), // 1
  2626.           "m" (a),      // 2
  2627.           "m" (b),      // 3
  2628.           "m" (alpha),  // 4
  2629.           "m" (beta),   // 5
  2630.           "m" (c),      // 6
  2631.           "m" (rs_c),   // 7
  2632.           "m" (cs_c),   // 8
  2633.           "m" (b_next)/*, // 9
  2634.           "m" (a_next)*/  // 10
  2635.         : // register clobber list
  2636.           "rax", "rbx", "rcx", "rdx", "rsi", "rdi",
  2637.           "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
  2638.           "xmm0", "xmm1", "xmm2", "xmm3",
  2639.           "xmm4", "xmm5", "xmm6", "xmm7",
  2640.           "xmm8", "xmm9", "xmm10", "xmm11",
  2641.           "xmm12", "xmm13", "xmm14", "xmm15",
  2642.           "memory"
  2643.         );
  2644. }
  2645.  
  2646.  
  2647.  
  2648. void bli_zgemm_asm_4x4
  2649.      (
  2650.        dim_t               k,
  2651.        dcomplex*  restrict alpha,
  2652.        dcomplex*  restrict a,
  2653.        dcomplex*  restrict b,
  2654.        dcomplex*  restrict beta,
  2655.        dcomplex*  restrict c, inc_t rs_c, inc_t cs_c,
  2656.        auxinfo_t* restrict data,
  2657.        cntx_t*    restrict cntx
  2658.      )
  2659. {
  2660.         //void*   a_next = bli_auxinfo_next_a( data );
  2661.         //void*   b_next = bli_auxinfo_next_b( data );
  2662.  
  2663.     uint64_t   k_iter = k / 4;
  2664.     uint64_t   k_left = k % 4;
  2665.  
  2666.         __asm__ volatile
  2667.         (
  2668.         "                                            \n\t"
  2669.         "                                            \n\t"
  2670.         "movq                %2, %%rax               \n\t" // load address of a.
  2671.         "movq                %3, %%rbx               \n\t" // load address of b.
  2672.         //"movq                %9, %%r15               \n\t" // load address of b_next.
  2673.         //"movq               %10, %%r14               \n\t" // load address of a_next.
  2674.         "                                            \n\t"
  2675.         "vmovapd        0 * 32(%%rax), %%ymm0        \n\t" // initialize loop by pre-loading
  2676.         "vmovddup   0 + 0 * 32(%%rbx), %%ymm2        \n\t"
  2677.         "vmovddup   0 + 1 * 32(%%rbx), %%ymm3        \n\t"
  2678.         "                                            \n\t"
  2679.         "movq                %6, %%rcx               \n\t" // load address of c
  2680.         "movq                %8, %%rdi               \n\t" // load cs_c
  2681.         "leaq        (,%%rdi,8), %%rdi               \n\t" // cs_c *= sizeof(dcomplex)
  2682.         "leaq        (,%%rdi,2), %%rdi               \n\t"
  2683.         "leaq   (%%rcx,%%rdi,2), %%r10               \n\t" // load address of c + 2*cs_c;
  2684.         "                                            \n\t"
  2685.         "prefetcht0   3 * 8(%%rcx)                   \n\t" // prefetch c + 0*cs_c
  2686.         "prefetcht0   3 * 8(%%rcx,%%rdi)             \n\t" // prefetch c + 1*cs_c
  2687.         "prefetcht0   3 * 8(%%r10)                   \n\t" // prefetch c + 2*cs_c
  2688.         "prefetcht0   3 * 8(%%r10,%%rdi)             \n\t" // prefetch c + 3*cs_c
  2689.         "                                            \n\t"
  2690.         "vxorpd    %%ymm8,  %%ymm8,  %%ymm8          \n\t"
  2691.         "vxorpd    %%ymm9,  %%ymm9,  %%ymm9          \n\t"
  2692.         "vxorpd    %%ymm10, %%ymm10, %%ymm10         \n\t"
  2693.         "vxorpd    %%ymm11, %%ymm11, %%ymm11         \n\t"
  2694.         "vxorpd    %%ymm12, %%ymm12, %%ymm12         \n\t"
  2695.         "vxorpd    %%ymm13, %%ymm13, %%ymm13         \n\t"
  2696.         "vxorpd    %%ymm14, %%ymm14, %%ymm14         \n\t"
  2697.         "vxorpd    %%ymm15, %%ymm15, %%ymm15         \n\t"
  2698.         "                                            \n\t"
  2699.         "                                            \n\t"
  2700.         "                                            \n\t"
  2701.         "movq      %0, %%rsi                         \n\t" // i = k_iter;
  2702.         "testq  %%rsi, %%rsi                         \n\t" // check i via logical AND.
  2703.         "je     .ZCONSIDKLEFT                        \n\t" // if i == 0, jump to code that
  2704.         "                                            \n\t" // contains the k_left loop.
  2705.         "                                            \n\t"
  2706.         "                                            \n\t"
  2707.         ".ZLOOPKITER:                                \n\t" // MAIN LOOP
  2708.         "                                            \n\t"
  2709.         "                                            \n\t"
  2710.         "                                            \n\t" // iteration 0
  2711.         "vmovapd        1 * 32(%%rax),      %%ymm1   \n\t"
  2712.         "vmulpd           %%ymm0,  %%ymm2,  %%ymm6   \n\t"
  2713.         "vperm2f128 $0x3, %%ymm2,  %%ymm2,  %%ymm4   \n\t"
  2714.         "vmulpd           %%ymm0,  %%ymm3,  %%ymm7   \n\t"
  2715.         "vperm2f128 $0x3, %%ymm3,  %%ymm3,  %%ymm5   \n\t"
  2716.         "vaddpd           %%ymm6,  %%ymm15, %%ymm15  \n\t"
  2717.         "vaddpd           %%ymm7,  %%ymm11, %%ymm11  \n\t"
  2718.         "                                            \n\t"
  2719.         "prefetcht0    16 * 32(%%rax)                \n\t"
  2720.         "vmulpd           %%ymm1,  %%ymm2,  %%ymm6   \n\t"
  2721.         "vmovddup   8 + 0 * 32(%%rbx),      %%ymm2   \n\t"
  2722.         "vmulpd           %%ymm1,  %%ymm3,  %%ymm7   \n\t"
  2723.         "vmovddup   8 + 1 * 32(%%rbx),      %%ymm3   \n\t"
  2724.         "vaddpd           %%ymm6,  %%ymm14, %%ymm14  \n\t"
  2725.         "vaddpd           %%ymm7,  %%ymm10, %%ymm10  \n\t"
  2726.         "                                            \n\t"
  2727.         "vmulpd           %%ymm0,  %%ymm4,  %%ymm6   \n\t"
  2728.         "vmulpd           %%ymm0,  %%ymm5,  %%ymm7   \n\t"
  2729.         "vpermilpd  $0x5, %%ymm0,  %%ymm0            \n\t"
  2730.         "vaddpd           %%ymm6,  %%ymm13, %%ymm13  \n\t"
  2731.         "vaddpd           %%ymm7,  %%ymm9,  %%ymm9   \n\t"
  2732.         "                                            \n\t"
  2733.         "vmulpd           %%ymm1,  %%ymm4,  %%ymm6   \n\t"
  2734.         "vperm2f128 $0x3, %%ymm2,  %%ymm2,  %%ymm4   \n\t"
  2735.         "vmulpd           %%ymm1,  %%ymm5,  %%ymm7   \n\t"
  2736.         "vperm2f128 $0x3, %%ymm3,  %%ymm3,  %%ymm5   \n\t"
  2737.         "vaddpd           %%ymm6,  %%ymm12, %%ymm12  \n\t"
  2738.         "vaddpd           %%ymm7,  %%ymm8,  %%ymm8   \n\t"
  2739.         "                                            \n\t"
  2740.         "vpermilpd  $0x5, %%ymm1,  %%ymm1            \n\t"
  2741.         "vmulpd           %%ymm0,  %%ymm2,  %%ymm6   \n\t"
  2742.         "vmulpd           %%ymm0,  %%ymm3,  %%ymm7   \n\t"
  2743.         "vaddsubpd        %%ymm6,  %%ymm15, %%ymm15  \n\t"
  2744.         "vaddsubpd        %%ymm7,  %%ymm11, %%ymm11  \n\t"
  2745.         "                                            \n\t"
  2746.         "vmulpd           %%ymm1,  %%ymm2,  %%ymm6   \n\t"
  2747.         "vmovddup   0 + 2 * 32(%%rbx),      %%ymm2   \n\t"
  2748.         "vmulpd           %%ymm1,  %%ymm3,  %%ymm7   \n\t"
  2749.         "vmovddup   0 + 3 * 32(%%rbx),      %%ymm3   \n\t"
  2750.         "vaddsubpd        %%ymm6,  %%ymm14, %%ymm14  \n\t"
  2751.         "vaddsubpd        %%ymm7,  %%ymm10, %%ymm10  \n\t"
  2752.         "                                            \n\t"
  2753.         "vmulpd           %%ymm0,  %%ymm4,  %%ymm6   \n\t"
  2754.         "vmulpd           %%ymm0,  %%ymm5,  %%ymm7   \n\t"
  2755.         "vmovapd        2 * 32(%%rax),      %%ymm0   \n\t"
  2756.         "vaddsubpd        %%ymm6,  %%ymm13, %%ymm13  \n\t"
  2757.         "vaddsubpd        %%ymm7,  %%ymm9,  %%ymm9   \n\t"
  2758.         "                                            \n\t"
  2759.         "vmulpd           %%ymm1,  %%ymm4,  %%ymm6   \n\t"
  2760.         "vmulpd           %%ymm1,  %%ymm5,  %%ymm7   \n\t"
  2761.         "vaddsubpd        %%ymm6,  %%ymm12, %%ymm12  \n\t"
  2762.         "vaddsubpd        %%ymm7,  %%ymm8,  %%ymm8   \n\t"
  2763.         "                                            \n\t"
  2764.         "                                            \n\t"
  2765.         "                                            \n\t" // iteration 1
  2766.         "vmovapd        3 * 32(%%rax),      %%ymm1   \n\t"
  2767.         "vmulpd           %%ymm0,  %%ymm2,  %%ymm6   \n\t"
  2768.         "vperm2f128 $0x3, %%ymm2,  %%ymm2,  %%ymm4   \n\t"
  2769.         "vmulpd           %%ymm0,  %%ymm3,  %%ymm7   \n\t"
  2770.         "vperm2f128 $0x3, %%ymm3,  %%ymm3,  %%ymm5   \n\t"
  2771.         "vaddpd           %%ymm6,  %%ymm15, %%ymm15  \n\t"
  2772.         "vaddpd           %%ymm7,  %%ymm11, %%ymm11  \n\t"
  2773.         "                                            \n\t"
  2774.         "prefetcht0    18 * 32(%%rax)                \n\t"
  2775.         "vmulpd           %%ymm1,  %%ymm2,  %%ymm6   \n\t"
  2776.         "vmovddup   8 + 2 * 32(%%rbx),      %%ymm2   \n\t"
  2777.         "vmulpd           %%ymm1,  %%ymm3,  %%ymm7   \n\t"
  2778.         "vmovddup   8 + 3 * 32(%%rbx),      %%ymm3   \n\t"
  2779.         "vaddpd           %%ymm6,  %%ymm14, %%ymm14  \n\t"
  2780.         "vaddpd           %%ymm7,  %%ymm10, %%ymm10  \n\t"
  2781.         "                                            \n\t"
  2782.         "vmulpd           %%ymm0,  %%ymm4,  %%ymm6   \n\t"
  2783.         "vmulpd           %%ymm0,  %%ymm5,  %%ymm7   \n\t"
  2784.         "vpermilpd  $0x5, %%ymm0,  %%ymm0            \n\t"
  2785.         "vaddpd           %%ymm6,  %%ymm13, %%ymm13  \n\t"
  2786.         "vaddpd           %%ymm7,  %%ymm9,  %%ymm9   \n\t"
  2787.         "                                            \n\t"
  2788.         "vmulpd           %%ymm1,  %%ymm4,  %%ymm6   \n\t"
  2789.         "vperm2f128 $0x3, %%ymm2,  %%ymm2,  %%ymm4   \n\t"
  2790.         "vmulpd           %%ymm1,  %%ymm5,  %%ymm7   \n\t"
  2791.         "vperm2f128 $0x3, %%ymm3,  %%ymm3,  %%ymm5   \n\t"
  2792.         "vaddpd           %%ymm6,  %%ymm12, %%ymm12  \n\t"
  2793.         "vaddpd           %%ymm7,  %%ymm8,  %%ymm8   \n\t"
  2794.         "                                            \n\t"
  2795.         "vpermilpd  $0x5, %%ymm1,  %%ymm1            \n\t"
  2796.         "vmulpd           %%ymm0,  %%ymm2,  %%ymm6   \n\t"
  2797.         "vmulpd           %%ymm0,  %%ymm3,  %%ymm7   \n\t"
  2798.         "vaddsubpd        %%ymm6,  %%ymm15, %%ymm15  \n\t"
  2799.         "vaddsubpd        %%ymm7,  %%ymm11, %%ymm11  \n\t"
  2800.         "                                            \n\t"
  2801.         "vmulpd           %%ymm1,  %%ymm2,  %%ymm6   \n\t"
  2802.         "vmovddup   0 + 4 * 32(%%rbx),      %%ymm2   \n\t"
  2803.         "vmulpd           %%ymm1,  %%ymm3,  %%ymm7   \n\t"
  2804.         "vmovddup   0 + 5 * 32(%%rbx),      %%ymm3   \n\t"
  2805.         "vaddsubpd        %%ymm6,  %%ymm14, %%ymm14  \n\t"
  2806.         "vaddsubpd        %%ymm7,  %%ymm10, %%ymm10  \n\t"
  2807.         "                                            \n\t"
  2808.         "vmulpd           %%ymm0,  %%ymm4,  %%ymm6   \n\t"
  2809.         "vmulpd           %%ymm0,  %%ymm5,  %%ymm7   \n\t"
  2810.         "vmovapd        4 * 32(%%rax),      %%ymm0   \n\t"
  2811.         "vaddsubpd        %%ymm6,  %%ymm13, %%ymm13  \n\t"
  2812.         "vaddsubpd        %%ymm7,  %%ymm9,  %%ymm9   \n\t"
  2813.         "                                            \n\t"
  2814.         "vmulpd           %%ymm1,  %%ymm4,  %%ymm6   \n\t"
  2815.         "vmulpd           %%ymm1,  %%ymm5,  %%ymm7   \n\t"
  2816.         "vaddsubpd        %%ymm6,  %%ymm12, %%ymm12  \n\t"
  2817.         "vaddsubpd        %%ymm7,  %%ymm8,  %%ymm8   \n\t"
  2818.         "                                            \n\t"
  2819.         "                                            \n\t"
  2820.         "                                            \n\t" // iteration 2
  2821.         "vmovapd        5 * 32(%%rax),      %%ymm1   \n\t"
  2822.         "vmulpd           %%ymm0,  %%ymm2,  %%ymm6   \n\t"
  2823.         "vperm2f128 $0x3, %%ymm2,  %%ymm2,  %%ymm4   \n\t"
  2824.         "vmulpd           %%ymm0,  %%ymm3,  %%ymm7   \n\t"
  2825.         "vperm2f128 $0x3, %%ymm3,  %%ymm3,  %%ymm5   \n\t"
  2826.         "vaddpd           %%ymm6,  %%ymm15, %%ymm15  \n\t"
  2827.         "vaddpd           %%ymm7,  %%ymm11, %%ymm11  \n\t"
  2828.         "                                            \n\t"
  2829.         "prefetcht0    20 * 32(%%rax)                \n\t"
  2830.         "vmulpd           %%ymm1,  %%ymm2,  %%ymm6   \n\t"
  2831.         "vmovddup   8 + 4 * 32(%%rbx),      %%ymm2   \n\t"
  2832.         "vmulpd           %%ymm1,  %%ymm3,  %%ymm7   \n\t"
  2833.         "vmovddup   8 + 5 * 32(%%rbx),      %%ymm3   \n\t"
  2834.         "vaddpd           %%ymm6,  %%ymm14, %%ymm14  \n\t"
  2835.         "vaddpd           %%ymm7,  %%ymm10, %%ymm10  \n\t"
  2836.         "                                            \n\t"
  2837.         "vmulpd           %%ymm0,  %%ymm4,  %%ymm6   \n\t"
  2838.         "vmulpd           %%ymm0,  %%ymm5,  %%ymm7   \n\t"
  2839.         "vpermilpd  $0x5, %%ymm0,  %%ymm0            \n\t"
  2840.         "vaddpd           %%ymm6,  %%ymm13, %%ymm13  \n\t"
  2841.         "vaddpd           %%ymm7,  %%ymm9,  %%ymm9   \n\t"
  2842.         "                                            \n\t"
  2843.         "vmulpd           %%ymm1,  %%ymm4,  %%ymm6   \n\t"
  2844.         "vperm2f128 $0x3, %%ymm2,  %%ymm2,  %%ymm4   \n\t"
  2845.         "vmulpd           %%ymm1,  %%ymm5,  %%ymm7   \n\t"
  2846.         "vperm2f128 $0x3, %%ymm3,  %%ymm3,  %%ymm5   \n\t"
  2847.         "vaddpd           %%ymm6,  %%ymm12, %%ymm12  \n\t"
  2848.         "vaddpd           %%ymm7,  %%ymm8,  %%ymm8   \n\t"
  2849.         "                                            \n\t"
  2850.         "vpermilpd  $0x5, %%ymm1,  %%ymm1            \n\t"
  2851.         "vmulpd           %%ymm0,  %%ymm2,  %%ymm6   \n\t"
  2852.         "vmulpd           %%ymm0,  %%ymm3,  %%ymm7   \n\t"
  2853.         "vaddsubpd        %%ymm6,  %%ymm15, %%ymm15  \n\t"
  2854.         "vaddsubpd        %%ymm7,  %%ymm11, %%ymm11  \n\t"
  2855.         "                                            \n\t"
  2856.         "vmulpd           %%ymm1,  %%ymm2,  %%ymm6   \n\t"
  2857.         "vmovddup   0 + 6 * 32(%%rbx),      %%ymm2   \n\t"
  2858.         "vmulpd           %%ymm1,  %%ymm3,  %%ymm7   \n\t"
  2859.         "vmovddup   0 + 7 * 32(%%rbx),      %%ymm3   \n\t"
  2860.         "vaddsubpd        %%ymm6,  %%ymm14, %%ymm14  \n\t"
  2861.         "vaddsubpd        %%ymm7,  %%ymm10, %%ymm10  \n\t"
  2862.         "                                            \n\t"
  2863.         "vmulpd           %%ymm0,  %%ymm4,  %%ymm6   \n\t"
  2864.         "vmulpd           %%ymm0,  %%ymm5,  %%ymm7   \n\t"
  2865.         "vmovapd        6 * 32(%%rax),      %%ymm0   \n\t"
  2866.         "vaddsubpd        %%ymm6,  %%ymm13, %%ymm13  \n\t"
  2867.         "vaddsubpd        %%ymm7,  %%ymm9,  %%ymm9   \n\t"
  2868.         "                                            \n\t"
  2869.         "vmulpd           %%ymm1,  %%ymm4,  %%ymm6   \n\t"
  2870.         "vmulpd           %%ymm1,  %%ymm5,  %%ymm7   \n\t"
  2871.         "vaddsubpd        %%ymm6,  %%ymm12, %%ymm12  \n\t"
  2872.         "vaddsubpd        %%ymm7,  %%ymm8,  %%ymm8   \n\t"
  2873.         "                                            \n\t"
  2874.         "                                            \n\t"
  2875.         "                                            \n\t" // iteration 3
  2876.         "vmovapd        7 * 32(%%rax),      %%ymm1   \n\t"
  2877.         "vmulpd           %%ymm0,  %%ymm2,  %%ymm6   \n\t"
  2878.         "vperm2f128 $0x3, %%ymm2,  %%ymm2,  %%ymm4   \n\t"
  2879.         "vmulpd           %%ymm0,  %%ymm3,  %%ymm7   \n\t"
  2880.         "vperm2f128 $0x3, %%ymm3,  %%ymm3,  %%ymm5   \n\t"
  2881.         "vaddpd           %%ymm6,  %%ymm15, %%ymm15  \n\t"
  2882.         "vaddpd           %%ymm7,  %%ymm11, %%ymm11  \n\t"
  2883.         "                                            \n\t"
  2884.         "prefetcht0    22 * 32(%%rax)                \n\t"
  2885.         "vmulpd           %%ymm1,  %%ymm2,  %%ymm6   \n\t"
  2886.         "vmovddup   8 + 6 * 32(%%rbx),      %%ymm2   \n\t"
  2887.         "vmulpd           %%ymm1,  %%ymm3,  %%ymm7   \n\t"
  2888.         "vmovddup   8 + 7 * 32(%%rbx),      %%ymm3   \n\t"
  2889.         "vaddpd           %%ymm6,  %%ymm14, %%ymm14  \n\t"
  2890.         "vaddpd           %%ymm7,  %%ymm10, %%ymm10  \n\t"
  2891.         "                                            \n\t"
  2892.         "vmulpd           %%ymm0,  %%ymm4,  %%ymm6   \n\t"
  2893.         "vmulpd           %%ymm0,  %%ymm5,  %%ymm7   \n\t"
  2894.         "vpermilpd  $0x5, %%ymm0,  %%ymm0            \n\t"
  2895.         "vaddpd           %%ymm6,  %%ymm13, %%ymm13  \n\t"
  2896.         "vaddpd           %%ymm7,  %%ymm9,  %%ymm9   \n\t"
  2897.         "                                            \n\t"
  2898.         "vmulpd           %%ymm1,  %%ymm4,  %%ymm6   \n\t"
  2899.         "vperm2f128 $0x3, %%ymm2,  %%ymm2,  %%ymm4   \n\t"
  2900.         "vmulpd           %%ymm1,  %%ymm5,  %%ymm7   \n\t"
  2901.         "vperm2f128 $0x3, %%ymm3,  %%ymm3,  %%ymm5   \n\t"
  2902.         "vaddpd           %%ymm6,  %%ymm12, %%ymm12  \n\t"
  2903.         "vaddpd           %%ymm7,  %%ymm8,  %%ymm8   \n\t"
  2904.         "                                            \n\t"
  2905.         "vpermilpd  $0x5, %%ymm1,  %%ymm1            \n\t"
  2906.         "vmulpd           %%ymm0,  %%ymm2,  %%ymm6   \n\t"
  2907.         "vmulpd           %%ymm0,  %%ymm3,  %%ymm7   \n\t"
  2908.         "vaddsubpd        %%ymm6,  %%ymm15, %%ymm15  \n\t"
  2909.         "vaddsubpd        %%ymm7,  %%ymm11, %%ymm11  \n\t"
  2910.         "                                            \n\t"
  2911.         "vmulpd           %%ymm1,  %%ymm2,  %%ymm6   \n\t"
  2912.         "vmovddup   0 + 8 * 32(%%rbx),      %%ymm2   \n\t"
  2913.         "vmulpd           %%ymm1,  %%ymm3,  %%ymm7   \n\t"
  2914.         "vmovddup   0 + 9 * 32(%%rbx),      %%ymm3   \n\t"
  2915.         "vaddsubpd        %%ymm6,  %%ymm14, %%ymm14  \n\t"
  2916.         "vaddsubpd        %%ymm7,  %%ymm10, %%ymm10  \n\t"
  2917.         "                                            \n\t"
  2918.         "vmulpd           %%ymm0,  %%ymm4,  %%ymm6   \n\t"
  2919.         "vmulpd           %%ymm0,  %%ymm5,  %%ymm7   \n\t"
  2920.         "vmovapd        8 * 32(%%rax),      %%ymm0   \n\t"
  2921.         "vaddsubpd        %%ymm6,  %%ymm13, %%ymm13  \n\t"
  2922.         "vaddsubpd        %%ymm7,  %%ymm9,  %%ymm9   \n\t"
  2923.         "                                            \n\t"
  2924.         "vmulpd           %%ymm1,  %%ymm4,  %%ymm6   \n\t"
  2925.         "vmulpd           %%ymm1,  %%ymm5,  %%ymm7   \n\t"
  2926.         "vaddsubpd        %%ymm6,  %%ymm12, %%ymm12  \n\t"
  2927.         "vaddsubpd        %%ymm7,  %%ymm8,  %%ymm8   \n\t"
  2928.         "                                            \n\t"
  2929.         "                                            \n\t"
  2930.         "addq         $4 * 4 * 16, %%rbx             \n\t" // b += 4*4 (unroll x nr)
  2931.         "addq         $4 * 4 * 16, %%rax             \n\t" // a += 4*4 (unroll x mr)
  2932.         "                                            \n\t"
  2933.         "                                            \n\t"
  2934.         "decq   %%rsi                                \n\t" // i -= 1;
  2935.         "jne    .ZLOOPKITER                          \n\t" // iterate again if i != 0.
  2936.         "                                            \n\t"
  2937.         "                                            \n\t"
  2938.         "                                            \n\t"
  2939.         "                                            \n\t"
  2940.         "                                            \n\t"
  2941.         "                                            \n\t"
  2942.         ".ZCONSIDKLEFT:                              \n\t"
  2943.         "                                            \n\t"
  2944.         "movq      %1, %%rsi                         \n\t" // i = k_left;
  2945.         "testq  %%rsi, %%rsi                         \n\t" // check i via logical AND.
  2946.         "je     .ZPOSTACCUM                          \n\t" // if i == 0, we're done; jump to end.
  2947.         "                                            \n\t" // else, we prepare to enter k_left loop.
  2948.         "                                            \n\t"
  2949.         "                                            \n\t"
  2950.         ".ZLOOPKLEFT:                                \n\t" // EDGE LOOP
  2951.         "                                            \n\t"
  2952.         "                                            \n\t" // iteration 0
  2953.         "vmovapd        1 * 32(%%rax),      %%ymm1   \n\t"
  2954.         "vmulpd           %%ymm0,  %%ymm2,  %%ymm6   \n\t"
  2955.         "vperm2f128 $0x3, %%ymm2,  %%ymm2,  %%ymm4   \n\t"
  2956.         "vmulpd           %%ymm0,  %%ymm3,  %%ymm7   \n\t"
  2957.         "vperm2f128 $0x3, %%ymm3,  %%ymm3,  %%ymm5   \n\t"
  2958.         "vaddpd           %%ymm6,  %%ymm15, %%ymm15  \n\t"
  2959.         "vaddpd           %%ymm7,  %%ymm11, %%ymm11  \n\t"
  2960.         "                                            \n\t"
  2961.         "prefetcht0    16 * 32(%%rax)                \n\t"
  2962.         "vmulpd           %%ymm1,  %%ymm2,  %%ymm6   \n\t"
  2963.         "vmovddup   8 + 0 * 32(%%rbx),      %%ymm2   \n\t"
  2964.         "vmulpd           %%ymm1,  %%ymm3,  %%ymm7   \n\t"
  2965.         "vmovddup   8 + 1 * 32(%%rbx),      %%ymm3   \n\t"
  2966.         "vaddpd           %%ymm6,  %%ymm14, %%ymm14  \n\t"
  2967.         "vaddpd           %%ymm7,  %%ymm10, %%ymm10  \n\t"
  2968.         "                                            \n\t"
  2969.         "vmulpd           %%ymm0,  %%ymm4,  %%ymm6   \n\t"
  2970.         "vmulpd           %%ymm0,  %%ymm5,  %%ymm7   \n\t"
  2971.         "vpermilpd  $0x5, %%ymm0,  %%ymm0            \n\t"
  2972.         "vaddpd           %%ymm6,  %%ymm13, %%ymm13  \n\t"
  2973.         "vaddpd           %%ymm7,  %%ymm9,  %%ymm9   \n\t"
  2974.         "                                            \n\t"
  2975.         "vmulpd           %%ymm1,  %%ymm4,  %%ymm6   \n\t"
  2976.         "vperm2f128 $0x3, %%ymm2,  %%ymm2,  %%ymm4   \n\t"
  2977.         "vmulpd           %%ymm1,  %%ymm5,  %%ymm7   \n\t"
  2978.         "vperm2f128 $0x3, %%ymm3,  %%ymm3,  %%ymm5   \n\t"
  2979.         "vaddpd           %%ymm6,  %%ymm12, %%ymm12  \n\t"
  2980.         "vaddpd           %%ymm7,  %%ymm8,  %%ymm8   \n\t"
  2981.         "                                            \n\t"
  2982.         "vpermilpd  $0x5, %%ymm1,  %%ymm1            \n\t"
  2983.         "vmulpd           %%ymm0,  %%ymm2,  %%ymm6   \n\t"
  2984.         "vmulpd           %%ymm0,  %%ymm3,  %%ymm7   \n\t"
  2985.         "vaddsubpd        %%ymm6,  %%ymm15, %%ymm15  \n\t"
  2986.         "vaddsubpd        %%ymm7,  %%ymm11, %%ymm11  \n\t"
  2987.         "                                            \n\t"
  2988.         "vmulpd           %%ymm1,  %%ymm2,  %%ymm6   \n\t"
  2989.         "vmovddup   0 + 2 * 32(%%rbx),      %%ymm2   \n\t"
  2990.         "vmulpd           %%ymm1,  %%ymm3,  %%ymm7   \n\t"
  2991.         "vmovddup   0 + 3 * 32(%%rbx),      %%ymm3   \n\t"
  2992.         "vaddsubpd        %%ymm6,  %%ymm14, %%ymm14  \n\t"
  2993.         "vaddsubpd        %%ymm7,  %%ymm10, %%ymm10  \n\t"
  2994.         "                                            \n\t"
  2995.         "vmulpd           %%ymm0,  %%ymm4,  %%ymm6   \n\t"
  2996.         "vmulpd           %%ymm0,  %%ymm5,  %%ymm7   \n\t"
  2997.         "vmovapd        2 * 32(%%rax),      %%ymm0   \n\t"
  2998.         "vaddsubpd        %%ymm6,  %%ymm13, %%ymm13  \n\t"
  2999.         "vaddsubpd        %%ymm7,  %%ymm9,  %%ymm9   \n\t"
  3000.         "                                            \n\t"
  3001.         "vmulpd           %%ymm1,  %%ymm4,  %%ymm6   \n\t"
  3002.         "vmulpd           %%ymm1,  %%ymm5,  %%ymm7   \n\t"
  3003.         "vaddsubpd        %%ymm6,  %%ymm12, %%ymm12  \n\t"
  3004.         "vaddsubpd        %%ymm7,  %%ymm8,  %%ymm8   \n\t"
  3005.         "                                            \n\t"
  3006.         "                                            \n\t"
  3007.         "addq         $4 * 1 * 16, %%rax             \n\t" // a += 4 (1 x mr)
  3008.         "addq         $4 * 1 * 16, %%rbx             \n\t" // b += 4 (1 x nr)
  3009.         "                                            \n\t"
  3010.         "                                            \n\t"
  3011.         "decq   %%rsi                                \n\t" // i -= 1;
  3012.         "jne    .ZLOOPKLEFT                          \n\t" // iterate again if i != 0.
  3013.         "                                            \n\t"
  3014.         "                                            \n\t"
  3015.         "                                            \n\t"
  3016.         ".ZPOSTACCUM:                                \n\t"
  3017.         "                                            \n\t"
  3018.         "                                            \n\t" // ymm15:  ymm13:  ymm11:  ymm9:
  3019.         "                                            \n\t" // ( ab00  ( ab01  ( ab02  ( ab03
  3020.         "                                            \n\t" //   ab10    ab11    ab12    ab13  
  3021.         "                                            \n\t" //   ab21    ab20    ab23    ab22
  3022.         "                                            \n\t" //   ab31 )  ab30 )  ab33 )  ab32 )
  3023.         "                                            \n\t"
  3024.         "                                            \n\t" // ymm14:  ymm12:  ymm10:  ymm8:
  3025.         "                                            \n\t" // ( ab40  ( ab41  ( ab42  ( ab43
  3026.         "                                            \n\t" //   ab50    ab51    ab52    ab53  
  3027.         "                                            \n\t" //   ab61    ab60    ab63    ab62
  3028.         "                                            \n\t" //   ab71 )  ab70 )  ab73 )  ab72 )
  3029.         "                                            \n\t"
  3030.         "                                            \n\t"
  3031.         "vmovapd           %%ymm15, %%ymm7           \n\t"
  3032.         "vperm2f128 $0x12, %%ymm15, %%ymm13, %%ymm15 \n\t"
  3033.         "vperm2f128 $0x30, %%ymm7,  %%ymm13, %%ymm13 \n\t"
  3034.         "                                            \n\t"
  3035.         "vmovapd           %%ymm11, %%ymm7           \n\t"
  3036.         "vperm2f128 $0x12, %%ymm11, %%ymm9,  %%ymm11 \n\t"
  3037.         "vperm2f128 $0x30, %%ymm7,  %%ymm9,  %%ymm9  \n\t"
  3038.         "                                            \n\t"
  3039.         "vmovapd           %%ymm14, %%ymm7           \n\t"
  3040.         "vperm2f128 $0x12, %%ymm14, %%ymm12, %%ymm14 \n\t"
  3041.         "vperm2f128 $0x30, %%ymm7,  %%ymm12, %%ymm12 \n\t"
  3042.         "                                            \n\t"
  3043.         "vmovapd           %%ymm10, %%ymm7           \n\t"
  3044.         "vperm2f128 $0x12, %%ymm10, %%ymm8,  %%ymm10 \n\t"
  3045.         "vperm2f128 $0x30, %%ymm7,  %%ymm8,  %%ymm8  \n\t"
  3046.         "                                            \n\t"
  3047.         "                                            \n\t"
  3048.         "                                            \n\t" // ymm15:  ymm13:  ymm11:  ymm9:
  3049.         "                                            \n\t" // ( ab00  ( ab01  ( ab02  ( ab03
  3050.         "                                            \n\t" //   ab10    ab11    ab12    ab13  
  3051.         "                                            \n\t" //   ab20    ab21    ab22    ab23
  3052.         "                                            \n\t" //   ab30 )  ab31 )  ab32 )  ab33 )
  3053.         "                                            \n\t"
  3054.         "                                            \n\t" // ymm14:  ymm12:  ymm10:  ymm8:
  3055.         "                                            \n\t" // ( ab40  ( ab41  ( ab42  ( ab43
  3056.         "                                            \n\t" //   ab50    ab51    ab52    ab53  
  3057.         "                                            \n\t" //   ab60    ab61    ab62    ab63
  3058.         "                                            \n\t" //   ab70 )  ab71 )  ab72 )  ab73 )
  3059.         "                                            \n\t"
  3060.         "                                            \n\t"
  3061.         "                                            \n\t" // scale by alpha
  3062.         "                                            \n\t"
  3063.         "movq         %4, %%rax                      \n\t" // load address of alpha
  3064.         "vbroadcastsd    (%%rax), %%ymm7             \n\t" // load alpha_r and duplicate
  3065.         "vbroadcastsd   8(%%rax), %%ymm6             \n\t" // load alpha_i and duplicate
  3066.         "                                            \n\t"
  3067.         "vpermilpd  $0x5, %%ymm15, %%ymm3            \n\t"
  3068.         "vmulpd           %%ymm7,  %%ymm15, %%ymm15  \n\t"
  3069.         "vmulpd           %%ymm6,  %%ymm3,  %%ymm3   \n\t"
  3070.         "vaddsubpd        %%ymm3,  %%ymm15, %%ymm15  \n\t"
  3071.         "                                            \n\t"
  3072.         "vpermilpd  $0x5, %%ymm14, %%ymm2            \n\t"
  3073.         "vmulpd           %%ymm7,  %%ymm14, %%ymm14  \n\t"
  3074.         "vmulpd           %%ymm6,  %%ymm2,  %%ymm2   \n\t"
  3075.         "vaddsubpd        %%ymm2,  %%ymm14, %%ymm14  \n\t"
  3076.         "                                            \n\t"
  3077.         "vpermilpd  $0x5, %%ymm13, %%ymm1            \n\t"
  3078.         "vmulpd           %%ymm7,  %%ymm13, %%ymm13  \n\t"
  3079.         "vmulpd           %%ymm6,  %%ymm1,  %%ymm1   \n\t"
  3080.         "vaddsubpd        %%ymm1,  %%ymm13, %%ymm13  \n\t"
  3081.         "                                            \n\t"
  3082.         "vpermilpd  $0x5, %%ymm12, %%ymm0            \n\t"
  3083.         "vmulpd           %%ymm7,  %%ymm12, %%ymm12  \n\t"
  3084.         "vmulpd           %%ymm6,  %%ymm0,  %%ymm0   \n\t"
  3085.         "vaddsubpd        %%ymm0,  %%ymm12, %%ymm12  \n\t"
  3086.         "                                            \n\t"
  3087.         "vpermilpd  $0x5, %%ymm11, %%ymm3            \n\t"
  3088.         "vmulpd           %%ymm7,  %%ymm11, %%ymm11  \n\t"
  3089.         "vmulpd           %%ymm6,  %%ymm3,  %%ymm3   \n\t"
  3090.         "vaddsubpd        %%ymm3,  %%ymm11, %%ymm11  \n\t"
  3091.         "                                            \n\t"
  3092.         "vpermilpd  $0x5, %%ymm10, %%ymm2            \n\t"
  3093.         "vmulpd           %%ymm7,  %%ymm10, %%ymm10  \n\t"
  3094.         "vmulpd           %%ymm6,  %%ymm2,  %%ymm2   \n\t"
  3095.         "vaddsubpd        %%ymm2,  %%ymm10, %%ymm10  \n\t"
  3096.         "                                            \n\t"
  3097.         "vpermilpd  $0x5, %%ymm9,  %%ymm1            \n\t"
  3098.         "vmulpd           %%ymm7,  %%ymm9,  %%ymm9   \n\t"
  3099.         "vmulpd           %%ymm6,  %%ymm1,  %%ymm1   \n\t"
  3100.         "vaddsubpd        %%ymm1,  %%ymm9,  %%ymm9   \n\t"
  3101.         "                                            \n\t"
  3102.         "vpermilpd  $0x5, %%ymm8,  %%ymm0            \n\t"
  3103.         "vmulpd           %%ymm7,  %%ymm8,  %%ymm8   \n\t"
  3104.         "vmulpd           %%ymm6,  %%ymm0,  %%ymm0   \n\t"
  3105.         "vaddsubpd        %%ymm0,  %%ymm8,  %%ymm8   \n\t"
  3106.         "                                            \n\t"
  3107.         "                                            \n\t"
  3108.         "                                            \n\t"
  3109.         "                                            \n\t"
  3110.         "movq         %5, %%rbx                      \n\t" // load address of beta
  3111.         "vbroadcastsd    (%%rbx), %%ymm7             \n\t" // load beta_r and duplicate
  3112.         "vbroadcastsd   8(%%rbx), %%ymm6             \n\t" // load beta_i and duplicate
  3113.         "                                            \n\t"
  3114.         "                                            \n\t"
  3115.         "                                            \n\t"
  3116.         "                                            \n\t"
  3117.         "                                            \n\t"
  3118.         "                                            \n\t"
  3119.         "                                            \n\t"
  3120.         "movq                %7, %%rsi               \n\t" // load rs_c
  3121.         "leaq        (,%%rsi,8), %%rsi               \n\t" // rsi = rs_c * sizeof(dcomplex)
  3122.         "leaq        (,%%rsi,2), %%rsi               \n\t"
  3123.         "leaq   (%%rcx,%%rsi,2), %%rdx               \n\t" // load address of c + 2*rs_c;
  3124.         "                                            \n\t"
  3125.         "                                            \n\t"
  3126.         "                                            \n\t" // now avoid loading C if beta == 0
  3127.         "                                            \n\t"
  3128.         "vxorpd    %%ymm0,  %%ymm0,  %%ymm0          \n\t" // set ymm0 to zero.
  3129.         "vucomisd  %%xmm0,  %%xmm7                   \n\t" // set ZF if beta_r == 0.
  3130.         "sete       %%r8b                            \n\t" // r8b = ( ZF == 1 ? 1 : 0 );
  3131.         "vucomisd  %%xmm0,  %%xmm6                   \n\t" // set ZF if beta_i == 0.
  3132.         "sete       %%r9b                            \n\t" // r9b = ( ZF == 1 ? 1 : 0 );
  3133.         "andb       %%r8b, %%r9b                     \n\t" // set ZF if r8b & r9b == 1.
  3134.         "jne      .ZBETAZERO                         \n\t" // if ZF = 0, jump to beta == 0 case
  3135.         "                                            \n\t"
  3136.         "                                            \n\t"
  3137.         "cmpq      $16, %%rsi                        \n\t" // set ZF if (16*cs_c) == 16.
  3138.         "jz      .ZCOLSTORED                         \n\t" // jump to column storage case
  3139.         "                                            \n\t"
  3140.         "                                            \n\t"
  3141.         "                                            \n\t"
  3142.         ".ZGENSTORED:                                \n\t"
  3143.         "                                            \n\t" // update c00:c30
  3144.         "                                            \n\t"
  3145.         "vmovupd    (%%rcx),       %%xmm0            \n\t" // load (c00,c10) into xmm0
  3146.         "vmovupd    (%%rcx,%%rsi), %%xmm2            \n\t" // load (c20,c30) into xmm2
  3147.         "vinsertf128  $1, %%xmm2,  %%ymm0,  %%ymm0   \n\t" // ymm0 := (ymm0[0:1],xmm2)
  3148.         "vpermilpd  $0x5, %%ymm0,  %%ymm2            \n\t" // scale ymm0 by beta
  3149.         "vmulpd           %%ymm7,  %%ymm0,  %%ymm0   \n\t"
  3150.         "vmulpd           %%ymm6,  %%ymm2,  %%ymm2   \n\t"
  3151.         "vaddsubpd        %%ymm2,  %%ymm0,  %%ymm0   \n\t"
  3152.         "vaddpd           %%ymm15, %%ymm0,  %%ymm0   \n\t" // add the gemm result to ymm0
  3153.         "vextractf128 $1, %%ymm0,  %%xmm2            \n\t" // xmm2 := ymm0[2:3]
  3154.         "vmovupd          %%xmm0,  (%%rcx)           \n\t" // store (c00,c10)
  3155.         "vmovupd          %%xmm2,  (%%rcx,%%rsi)     \n\t" // store (c20,c30)
  3156.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  3157.         "                                            \n\t"
  3158.         "                                            \n\t" // update c40:c70
  3159.         "                                            \n\t"
  3160.         "vmovupd    (%%rdx),       %%xmm0            \n\t" // load (c40,c50) into xmm0
  3161.         "vmovupd    (%%rdx,%%rsi), %%xmm2            \n\t" // load (c60,c70) into xmm2
  3162.         "vinsertf128  $1, %%xmm2,  %%ymm0,  %%ymm0   \n\t" // ymm0 := (ymm0[0:1],xmm2)
  3163.         "vpermilpd  $0x5, %%ymm0,  %%ymm2            \n\t" // scale ymm0 by beta
  3164.         "vmulpd           %%ymm7,  %%ymm0,  %%ymm0   \n\t"
  3165.         "vmulpd           %%ymm6,  %%ymm2,  %%ymm2   \n\t"
  3166.         "vaddsubpd        %%ymm2,  %%ymm0,  %%ymm0   \n\t"
  3167.         "vaddpd           %%ymm14, %%ymm0,  %%ymm0   \n\t" // add the gemm result to ymm0
  3168.         "vextractf128 $1, %%ymm0,  %%xmm2            \n\t" // xmm2 := ymm0[2:3]
  3169.         "vmovupd          %%xmm0,  (%%rdx)           \n\t" // store (c40,c50)
  3170.         "vmovupd          %%xmm2,  (%%rdx,%%rsi)     \n\t" // store (c60,c70)
  3171.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  3172.         "                                            \n\t"
  3173.         "                                            \n\t" // update c01:c31
  3174.         "                                            \n\t"
  3175.         "vmovupd    (%%rcx),       %%xmm0            \n\t" // load (c01,c11) into xmm0
  3176.         "vmovupd    (%%rcx,%%rsi), %%xmm2            \n\t" // load (c21,c31) into xmm2
  3177.         "vinsertf128  $1, %%xmm2,  %%ymm0,  %%ymm0   \n\t" // ymm0 := (ymm0[0:1],xmm2)
  3178.         "vpermilpd  $0x5, %%ymm0,  %%ymm2            \n\t" // scale ymm0 by beta
  3179.         "vmulpd           %%ymm7,  %%ymm0,  %%ymm0   \n\t"
  3180.         "vmulpd           %%ymm6,  %%ymm2,  %%ymm2   \n\t"
  3181.         "vaddsubpd        %%ymm2,  %%ymm0,  %%ymm0   \n\t"
  3182.         "vaddpd           %%ymm13, %%ymm0,  %%ymm0   \n\t" // add the gemm result to ymm0
  3183.         "vextractf128 $1, %%ymm0,  %%xmm2            \n\t" // xmm2 := ymm0[2:3]
  3184.         "vmovupd          %%xmm0,  (%%rcx)           \n\t" // store (c01,c11)
  3185.         "vmovupd          %%xmm2,  (%%rcx,%%rsi)     \n\t" // store (c21,c31)
  3186.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  3187.         "                                            \n\t"
  3188.         "                                            \n\t" // update c41:c71
  3189.         "                                            \n\t"
  3190.         "vmovupd    (%%rdx),       %%xmm0            \n\t" // load (c41,c51) into xmm0
  3191.         "vmovupd    (%%rdx,%%rsi), %%xmm2            \n\t" // load (c61,c71) into xmm2
  3192.         "vinsertf128  $1, %%xmm2,  %%ymm0,  %%ymm0   \n\t" // ymm0 := (ymm0[0:1],xmm2)
  3193.         "vpermilpd  $0x5, %%ymm0,  %%ymm2            \n\t" // scale ymm0 by beta
  3194.         "vmulpd           %%ymm7,  %%ymm0,  %%ymm0   \n\t"
  3195.         "vmulpd           %%ymm6,  %%ymm2,  %%ymm2   \n\t"
  3196.         "vaddsubpd        %%ymm2,  %%ymm0,  %%ymm0   \n\t"
  3197.         "vaddpd           %%ymm12, %%ymm0,  %%ymm0   \n\t" // add the gemm result to ymm0
  3198.         "vextractf128 $1, %%ymm0,  %%xmm2            \n\t" // xmm2 := ymm0[2:3]
  3199.         "vmovupd          %%xmm0,  (%%rdx)           \n\t" // store (c41,c51)
  3200.         "vmovupd          %%xmm2,  (%%rdx,%%rsi)     \n\t" // store (c61,c71)
  3201.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  3202.         "                                            \n\t"
  3203.         "                                            \n\t" // update c02:c32
  3204.         "                                            \n\t"
  3205.         "vmovupd    (%%rcx),       %%xmm0            \n\t" // load (c02,c12) into xmm0
  3206.         "vmovupd    (%%rcx,%%rsi), %%xmm2            \n\t" // load (c22,c32) into xmm2
  3207.         "vinsertf128  $1, %%xmm2,  %%ymm0,  %%ymm0   \n\t" // ymm0 := (ymm0[0:1],xmm2)
  3208.         "vpermilpd  $0x5, %%ymm0,  %%ymm2            \n\t" // scale ymm0 by beta
  3209.         "vmulpd           %%ymm7,  %%ymm0,  %%ymm0   \n\t"
  3210.         "vmulpd           %%ymm6,  %%ymm2,  %%ymm2   \n\t"
  3211.         "vaddsubpd        %%ymm2,  %%ymm0,  %%ymm0   \n\t"
  3212.         "vaddpd           %%ymm11, %%ymm0,  %%ymm0   \n\t" // add the gemm result to ymm0
  3213.         "vextractf128 $1, %%ymm0,  %%xmm2            \n\t" // xmm2 := ymm0[2:3]
  3214.         "vmovupd          %%xmm0,  (%%rcx)           \n\t" // store (c02,c12)
  3215.         "vmovupd          %%xmm2,  (%%rcx,%%rsi)     \n\t" // store (c22,c32)
  3216.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  3217.         "                                            \n\t"
  3218.         "                                            \n\t" // update c42:c72
  3219.         "                                            \n\t"
  3220.         "vmovupd    (%%rdx),       %%xmm0            \n\t" // load (c42,c52) into xmm0
  3221.         "vmovupd    (%%rdx,%%rsi), %%xmm2            \n\t" // load (c62,c72) into xmm2
  3222.         "vinsertf128  $1, %%xmm2,  %%ymm0,  %%ymm0   \n\t" // ymm0 := (ymm0[0:1],xmm2)
  3223.         "vpermilpd  $0x5, %%ymm0,  %%ymm2            \n\t" // scale ymm0 by beta
  3224.         "vmulpd           %%ymm7,  %%ymm0,  %%ymm0   \n\t"
  3225.         "vmulpd           %%ymm6,  %%ymm2,  %%ymm2   \n\t"
  3226.         "vaddsubpd        %%ymm2,  %%ymm0,  %%ymm0   \n\t"
  3227.         "vaddpd           %%ymm10, %%ymm0,  %%ymm0   \n\t" // add the gemm result to ymm0
  3228.         "vextractf128 $1, %%ymm0,  %%xmm2            \n\t" // xmm2 := ymm0[2:3]
  3229.         "vmovupd          %%xmm0,  (%%rdx)           \n\t" // store (c42,c52)
  3230.         "vmovupd          %%xmm2,  (%%rdx,%%rsi)     \n\t" // store (c62,c72)
  3231.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  3232.         "                                            \n\t"
  3233.         "                                            \n\t" // update c03:c33
  3234.         "                                            \n\t"
  3235.         "vmovupd    (%%rcx),       %%xmm0            \n\t" // load (c03,c13) into xmm0
  3236.         "vmovupd    (%%rcx,%%rsi), %%xmm2            \n\t" // load (c23,c33) into xmm2
  3237.         "vinsertf128  $1, %%xmm2,  %%ymm0,  %%ymm0   \n\t" // ymm0 := (ymm0[0:1],xmm2)
  3238.         "vpermilpd  $0x5, %%ymm0,  %%ymm2            \n\t" // scale ymm0 by beta
  3239.         "vmulpd           %%ymm7,  %%ymm0,  %%ymm0   \n\t"
  3240.         "vmulpd           %%ymm6,  %%ymm2,  %%ymm2   \n\t"
  3241.         "vaddsubpd        %%ymm2,  %%ymm0,  %%ymm0   \n\t"
  3242.         "vaddpd           %%ymm9,  %%ymm0,  %%ymm0   \n\t" // add the gemm result to ymm0
  3243.         "vextractf128 $1, %%ymm0,  %%xmm2            \n\t" // xmm2 := ymm0[2:3]
  3244.         "vmovupd          %%xmm0,  (%%rcx)           \n\t" // store (c03,c13)
  3245.         "vmovupd          %%xmm2,  (%%rcx,%%rsi)     \n\t" // store (c23,c33)
  3246.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  3247.         "                                            \n\t"
  3248.         "                                            \n\t" // update c43:c73
  3249.         "                                            \n\t"
  3250.         "vmovupd    (%%rdx),       %%xmm0            \n\t" // load (c43,c53) into xmm0
  3251.         "vmovupd    (%%rdx,%%rsi), %%xmm2            \n\t" // load (c63,c73) into xmm2
  3252.         "vinsertf128  $1, %%xmm2,  %%ymm0,  %%ymm0   \n\t" // ymm0 := (ymm0[0:1],xmm2)
  3253.         "vpermilpd  $0x5, %%ymm0,  %%ymm2            \n\t" // scale ymm0 by beta
  3254.         "vmulpd           %%ymm7,  %%ymm0,  %%ymm0   \n\t"
  3255.         "vmulpd           %%ymm6,  %%ymm2,  %%ymm2   \n\t"
  3256.         "vaddsubpd        %%ymm2,  %%ymm0,  %%ymm0   \n\t"
  3257.         "vaddpd           %%ymm8,  %%ymm0,  %%ymm0   \n\t" // add the gemm result to ymm0
  3258.         "vextractf128 $1, %%ymm0,  %%xmm2            \n\t" // xmm2 := ymm0[2:3]
  3259.         "vmovupd          %%xmm0,  (%%rdx)           \n\t" // store (c43,c53)
  3260.         "vmovupd          %%xmm2,  (%%rdx,%%rsi)     \n\t" // store (c63,c73)
  3261.         "                                            \n\t"
  3262.         "                                            \n\t"
  3263.         "                                            \n\t"
  3264.         "jmp    .ZDONE                               \n\t" // jump to end.
  3265.         "                                            \n\t"
  3266.         "                                            \n\t"
  3267.         "                                            \n\t"
  3268.         ".ZCOLSTORED:                                \n\t"
  3269.         "                                            \n\t" // update c00:c30
  3270.         "                                            \n\t"
  3271.         "vmovupd    (%%rcx),       %%ymm0            \n\t" // load c00:c30 into ymm0
  3272.         "vpermilpd  $0x5, %%ymm0,  %%ymm2            \n\t" // scale ymm0 by beta
  3273.         "vmulpd           %%ymm7,  %%ymm0,  %%ymm0   \n\t"
  3274.         "vmulpd           %%ymm6,  %%ymm2,  %%ymm2   \n\t"
  3275.         "vaddsubpd        %%ymm2,  %%ymm0,  %%ymm0   \n\t"
  3276.         "vaddpd           %%ymm15, %%ymm0,  %%ymm0   \n\t" // add the gemm result to ymm0
  3277.         "vmovupd          %%ymm0,  (%%rcx)           \n\t" // store c00:c30
  3278.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  3279.         "                                            \n\t"
  3280.         "                                            \n\t" // update c40:c70
  3281.         "                                            \n\t"
  3282.         "vmovupd    (%%rdx),       %%ymm0            \n\t" // load c40:c70 into ymm0
  3283.         "vpermilpd  $0x5, %%ymm0,  %%ymm2            \n\t" // scale ymm0 by beta
  3284.         "vmulpd           %%ymm7,  %%ymm0,  %%ymm0   \n\t"
  3285.         "vmulpd           %%ymm6,  %%ymm2,  %%ymm2   \n\t"
  3286.         "vaddsubpd        %%ymm2,  %%ymm0,  %%ymm0   \n\t"
  3287.         "vaddpd           %%ymm14, %%ymm0,  %%ymm0   \n\t" // add the gemm result to ymm0
  3288.         "vmovupd          %%ymm0,  (%%rdx)           \n\t" // store c40:c70
  3289.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  3290.         "                                            \n\t"
  3291.         "                                            \n\t" // update c01:c31
  3292.         "                                            \n\t"
  3293.         "vmovupd    (%%rcx),       %%ymm0            \n\t" // load c01:c31 into ymm0
  3294.         "vpermilpd  $0x5, %%ymm0,  %%ymm2            \n\t" // scale ymm0 by beta
  3295.         "vmulpd           %%ymm7,  %%ymm0,  %%ymm0   \n\t"
  3296.         "vmulpd           %%ymm6,  %%ymm2,  %%ymm2   \n\t"
  3297.         "vaddsubpd        %%ymm2,  %%ymm0,  %%ymm0   \n\t"
  3298.         "vaddpd           %%ymm13, %%ymm0,  %%ymm0   \n\t" // add the gemm result to ymm0
  3299.         "vmovupd          %%ymm0,  (%%rcx)           \n\t" // store c01:c31
  3300.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  3301.         "                                            \n\t"
  3302.         "                                            \n\t" // update c41:c71
  3303.         "                                            \n\t"
  3304.         "vmovupd    (%%rdx),       %%ymm0            \n\t" // load c41:c71 into ymm0
  3305.         "vpermilpd  $0x5, %%ymm0,  %%ymm2            \n\t" // scale ymm0 by beta
  3306.         "vmulpd           %%ymm7,  %%ymm0,  %%ymm0   \n\t"
  3307.         "vmulpd           %%ymm6,  %%ymm2,  %%ymm2   \n\t"
  3308.         "vaddsubpd        %%ymm2,  %%ymm0,  %%ymm0   \n\t"
  3309.         "vaddpd           %%ymm12, %%ymm0,  %%ymm0   \n\t" // add the gemm result to ymm0
  3310.         "vmovupd          %%ymm0,  (%%rdx)           \n\t" // store c41:c71
  3311.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  3312.         "                                            \n\t"
  3313.         "                                            \n\t" // update c02:c32
  3314.         "                                            \n\t"
  3315.         "vmovupd    (%%rcx),       %%ymm0            \n\t" // load c02:c32 into ymm0
  3316.         "vpermilpd  $0x5, %%ymm0,  %%ymm2            \n\t" // scale ymm0 by beta
  3317.         "vmulpd           %%ymm7,  %%ymm0,  %%ymm0   \n\t"
  3318.         "vmulpd           %%ymm6,  %%ymm2,  %%ymm2   \n\t"
  3319.         "vaddsubpd        %%ymm2,  %%ymm0,  %%ymm0   \n\t"
  3320.         "vaddpd           %%ymm11, %%ymm0,  %%ymm0   \n\t" // add the gemm result to ymm0
  3321.         "vmovupd          %%ymm0,  (%%rcx)           \n\t" // store c02:c32
  3322.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  3323.         "                                            \n\t"
  3324.         "                                            \n\t" // update c42:c72
  3325.         "                                            \n\t"
  3326.         "vmovupd    (%%rdx),       %%ymm0            \n\t" // load c42:c72 into ymm0
  3327.         "vpermilpd  $0x5, %%ymm0,  %%ymm2            \n\t" // scale ymm0 by beta
  3328.         "vmulpd           %%ymm7,  %%ymm0,  %%ymm0   \n\t"
  3329.         "vmulpd           %%ymm6,  %%ymm2,  %%ymm2   \n\t"
  3330.         "vaddsubpd        %%ymm2,  %%ymm0,  %%ymm0   \n\t"
  3331.         "vaddpd           %%ymm10, %%ymm0,  %%ymm0   \n\t" // add the gemm result to ymm0
  3332.         "vmovupd          %%ymm0,  (%%rdx)           \n\t" // store c42:c72
  3333.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  3334.         "                                            \n\t"
  3335.         "                                            \n\t" // update c03:c33
  3336.         "                                            \n\t"
  3337.         "vmovupd    (%%rcx),       %%ymm0            \n\t" // load c03:c33 into ymm0
  3338.         "vpermilpd  $0x5, %%ymm0,  %%ymm2            \n\t" // scale ymm0 by beta
  3339.         "vmulpd           %%ymm7,  %%ymm0,  %%ymm0   \n\t"
  3340.         "vmulpd           %%ymm6,  %%ymm2,  %%ymm2   \n\t"
  3341.         "vaddsubpd        %%ymm2,  %%ymm0,  %%ymm0   \n\t"
  3342.         "vaddpd           %%ymm9,  %%ymm0,  %%ymm0   \n\t" // add the gemm result to ymm0
  3343.         "vmovupd          %%ymm0,  (%%rcx)           \n\t" // store c03:c33
  3344.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  3345.         "                                            \n\t"
  3346.         "                                            \n\t" // update c43:c73
  3347.         "                                            \n\t"
  3348.         "vmovupd    (%%rdx),       %%ymm0            \n\t" // load c43:c73 into ymm0
  3349.         "vpermilpd  $0x5, %%ymm0,  %%ymm2            \n\t" // scale ymm0 by beta
  3350.         "vmulpd           %%ymm7,  %%ymm0,  %%ymm0   \n\t"
  3351.         "vmulpd           %%ymm6,  %%ymm2,  %%ymm2   \n\t"
  3352.         "vaddsubpd        %%ymm2,  %%ymm0,  %%ymm0   \n\t"
  3353.         "vaddpd           %%ymm8,  %%ymm0,  %%ymm0   \n\t" // add the gemm result to ymm0
  3354.         "vmovupd          %%ymm0,  (%%rdx)           \n\t" // store c43:c73
  3355.         "                                            \n\t"
  3356.         "                                            \n\t"
  3357.         "                                            \n\t"
  3358.         "jmp    .ZDONE                               \n\t" // jump to end.
  3359.         "                                            \n\t"
  3360.         "                                            \n\t"
  3361.         "                                            \n\t"
  3362.         ".ZBETAZERO:                                 \n\t"
  3363.         "                                            \n\t"
  3364.         "cmpq      $16, %%rsi                        \n\t" // set ZF if (16*cs_c) == 16.
  3365.         "jz      .ZCOLSTORBZ                         \n\t" // jump to column storage case
  3366.         "                                            \n\t"
  3367.         "                                            \n\t"
  3368.         "                                            \n\t"
  3369.         ".ZGENSTORBZ:                                \n\t"
  3370.         "                                            \n\t" // update c00:c30
  3371.         "                                            \n\t"
  3372.         "vextractf128 $1, %%ymm15, %%xmm2            \n\t"
  3373.         "vmovupd          %%xmm15, (%%rcx)           \n\t" // store (c00,c10)
  3374.         "vmovupd          %%xmm2,  (%%rcx,%%rsi)     \n\t" // store (c20,c30)
  3375.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  3376.         "                                            \n\t"
  3377.         "                                            \n\t" // update c40:c70
  3378.         "                                            \n\t"
  3379.         "vextractf128 $1, %%ymm14, %%xmm2            \n\t"
  3380.         "vmovupd          %%xmm14, (%%rdx)           \n\t" // store (c40,c50)
  3381.         "vmovupd          %%xmm2,  (%%rdx,%%rsi)     \n\t" // store (c60,c70)
  3382.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  3383.         "                                            \n\t"
  3384.         "                                            \n\t" // update c01:c31
  3385.         "                                            \n\t"
  3386.         "vextractf128 $1, %%ymm13, %%xmm2            \n\t"
  3387.         "vmovupd          %%xmm13, (%%rcx)           \n\t" // store (c01,c11)
  3388.         "vmovupd          %%xmm2,  (%%rcx,%%rsi)     \n\t" // store (c21,c31)
  3389.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  3390.         "                                            \n\t"
  3391.         "                                            \n\t" // update c41:c71
  3392.         "                                            \n\t"
  3393.         "vextractf128 $1, %%ymm12, %%xmm2            \n\t"
  3394.         "vmovupd          %%xmm12, (%%rdx)           \n\t" // store (c41,c51)
  3395.         "vmovupd          %%xmm2,  (%%rdx,%%rsi)     \n\t" // store (c61,c71)
  3396.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  3397.         "                                            \n\t"
  3398.         "                                            \n\t" // update c02:c32
  3399.         "                                            \n\t"
  3400.         "vextractf128 $1, %%ymm11, %%xmm2            \n\t"
  3401.         "vmovupd          %%xmm11, (%%rcx)           \n\t" // store (c02,c12)
  3402.         "vmovupd          %%xmm2,  (%%rcx,%%rsi)     \n\t" // store (c22,c32)
  3403.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  3404.         "                                            \n\t"
  3405.         "                                            \n\t" // update c42:c72
  3406.         "                                            \n\t"
  3407.         "vextractf128 $1, %%ymm10, %%xmm2            \n\t"
  3408.         "vmovupd          %%xmm10, (%%rdx)           \n\t" // store (c42,c52)
  3409.         "vmovupd          %%xmm2,  (%%rdx,%%rsi)     \n\t" // store (c62,c72)
  3410.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  3411.         "                                            \n\t"
  3412.         "                                            \n\t" // update c03:c33
  3413.         "                                            \n\t"
  3414.         "vextractf128 $1, %%ymm9,  %%xmm2            \n\t"
  3415.         "vmovupd          %%xmm9,  (%%rcx)           \n\t" // store (c03,c13)
  3416.         "vmovupd          %%xmm2,  (%%rcx,%%rsi)     \n\t" // store (c23,c33)
  3417.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  3418.         "                                            \n\t"
  3419.         "                                            \n\t" // update c43:c73
  3420.         "                                            \n\t"
  3421.         "vextractf128 $1, %%ymm8,  %%xmm2            \n\t"
  3422.         "vmovupd          %%xmm8,  (%%rdx)           \n\t" // store (c43,c53)
  3423.         "vmovupd          %%xmm2,  (%%rdx,%%rsi)     \n\t" // store (c63,c73)
  3424.         "                                            \n\t"
  3425.         "                                            \n\t"
  3426.         "                                            \n\t"
  3427.         "jmp    .ZDONE                               \n\t" // jump to end.
  3428.         "                                            \n\t"
  3429.         "                                            \n\t"
  3430.         "                                            \n\t"
  3431.         ".ZCOLSTORBZ:                                \n\t"
  3432.         "                                            \n\t"
  3433.         "                                            \n\t"
  3434.         "vmovupd          %%ymm15, (%%rcx)           \n\t" // store c00:c30
  3435.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  3436.         "                                            \n\t"
  3437.         "vmovupd          %%ymm14, (%%rdx)           \n\t" // store c40:c70
  3438.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  3439.         "                                            \n\t"
  3440.         "vmovupd          %%ymm13, (%%rcx)           \n\t" // store c01:c31
  3441.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  3442.         "                                            \n\t"
  3443.         "vmovupd          %%ymm12, (%%rdx)           \n\t" // store c41:c71
  3444.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  3445.         "                                            \n\t"
  3446.         "vmovupd          %%ymm11, (%%rcx)           \n\t" // store c02:c32
  3447.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  3448.         "                                            \n\t"
  3449.         "vmovupd          %%ymm10, (%%rdx)           \n\t" // store c42:c72
  3450.         "addq      %%rdi, %%rdx                      \n\t" // c += cs_c;
  3451.         "                                            \n\t"
  3452.         "vmovupd          %%ymm9,  (%%rcx)           \n\t" // store c03:c33
  3453.         "addq      %%rdi, %%rcx                      \n\t" // c += cs_c;
  3454.         "                                            \n\t"
  3455.         "vmovupd          %%ymm8,  (%%rdx)           \n\t" // store c43:c73
  3456.         "                                            \n\t"
  3457.         "                                            \n\t"
  3458.         "                                            \n\t"
  3459.         "                                            \n\t"
  3460.         "                                            \n\t"
  3461.         ".ZDONE:                                     \n\t"
  3462.     "                                            \n\t"
  3463.     "vzeroupper                                  \n\t"
  3464.         "                                            \n\t"
  3465.  
  3466.         : // output operands (none)
  3467.         : // input operands
  3468.           "m" (k_iter), // 0
  3469.           "m" (k_left), // 1
  3470.           "m" (a),      // 2
  3471.           "m" (b),      // 3
  3472.           "m" (alpha),  // 4
  3473.           "m" (beta),   // 5
  3474.           "m" (c),      // 6
  3475.           "m" (rs_c),   // 7
  3476.           "m" (cs_c)/*,   // 8
  3477.           "m" (b_next), // 9
  3478.           "m" (a_next)*/  // 10
  3479.         : // register clobber list
  3480.           "rax", "rbx", "rcx", "rdx", "rsi", "rdi",
  3481.           "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
  3482.           "xmm0", "xmm1", "xmm2", "xmm3",
  3483.           "xmm4", "xmm5", "xmm6", "xmm7",
  3484.           "xmm8", "xmm9", "xmm10", "xmm11",
  3485.           "xmm12", "xmm13", "xmm14", "xmm15",
  3486.           "memory"
  3487.         );
  3488. }

Paste is for source code and general debugging text.

Login or Register to edit, delete and keep track of your pastes and more.

Raw Paste