LCOV - code coverage report
Current view: top level - src/elpa2/kernels - complex_sse_1hv_template.c (source / functions) Hit Total Coverage
Test: coverage_50ab7a7628bba174fc62cee3ab72b26e81f87fe5.info Lines: 188 240 78.3 %
Date: 2018-01-10 09:29:53 Functions: 2 2 100.0 %

          Line data    Source code
       1             : //    This file is part of ELPA.
       2             : //
       3             : //    The ELPA library was originally created by the ELPA consortium,
       4             : //    consisting of the following organizations:
       5             : //
       6             : //    - Max Planck Computing and Data Facility (MPCDF), formerly known as
       7             : //      Rechenzentrum Garching der Max-Planck-Gesellschaft (RZG),
       8             : //    - Bergische Universität Wuppertal, Lehrstuhl für angewandte
       9             : //      Informatik,
      10             : //    - Technische Universität München, Lehrstuhl für Informatik mit
      11             : //      Schwerpunkt Wissenschaftliches Rechnen ,
      12             : //    - Fritz-Haber-Institut, Berlin, Abt. Theorie,
      13             : //    - Max-Plack-Institut für Mathematik in den Naturwissenschaften,
      14             : //      Leipzig, Abt. Komplexe Strukutren in Biologie und Kognition,
      15             : //      and
      16             : //    - IBM Deutschland GmbH
      17             : //
      18             : //    This particular source code file contains additions, changes and
      19             : //    enhancements authored by Intel Corporation which is not part of
      20             : //    the ELPA consortium.
      21             : //
      22             : //    More information can be found here:
      23             : //    http://elpa.mpcdf.mpg.de/
      24             : //
      25             : //    ELPA is free software: you can redistribute it and/or modify
      26             : //    it under the terms of the version 3 of the license of the
      27             : //    GNU Lesser General Public License as published by the Free
      28             : //    Software Foundation.
      29             : //
      30             : //    ELPA is distributed in the hope that it will be useful,
      31             : //    but WITHOUT ANY WARRANTY; without even the implied warranty of
      32             : //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      33             : //    GNU Lesser General Public License for more details.
      34             : //
      35             : //    You should have received a copy of the GNU Lesser General Public License
      36             : //    along with ELPA.  If not, see <http://www.gnu.org/licenses/>
      37             : //
      38             : //    ELPA reflects a substantial effort on the part of the original
      39             : //    ELPA consortium, and we ask you to respect the spirit of the
      40             : //    license that we chose: i.e., please contribute any changes you
      41             : //    may have back to the original ELPA library distribution, and keep
      42             : //    any derivatives of ELPA under the same license that we chose for
      43             : //    the original distribution, the GNU Lesser General Public License.
      44             : //
      45             : //
      46             : // --------------------------------------------------------------------------------------------------
      47             : //
      48             : // This file contains the compute intensive kernels for the Householder transformations.
      49             : // It should be compiled with the highest possible optimization level.
      50             : //
      51             : // On Intel Nehalem or Intel Westmere or AMD Magny Cours use -O3 -msse3
      52             : // On Intel Sandy Bridge use -O3 -mavx
      53             : //
      54             : // Copyright of the original code rests with the authors inside the ELPA
      55             : // consortium. The copyright of any additional modifications shall rest
      56             : // with their original authors, but shall adhere to the licensing terms
      57             : // distributed along with the original code in the file "COPYING".
      58             : //
      59             : // Author: Alexander Heinecke (alexander.heinecke@mytum.de)
      60             : // Adapted for building a shared-library by Andreas Marek, MPCDF (andreas.marek@mpcdf.mpg.de)
      61             : // --------------------------------------------------------------------------------------------------
      62             : 
      63             : #include "config-f90.h"
      64             : 
      65             : #include <complex.h>
      66             : #include <x86intrin.h>
      67             : 
      68             : #ifdef DOUBLE_PRECISION_COMPLEX
      69             : #define offset 2
      70             : #define __SSE_DATATYPE __m128d
      71             : #define _SSE_LOAD _mm_load_pd
      72             : #define _SSE_STORE _mm_store_pd
      73             : #define _SSE_MUL _mm_mul_pd
      74             : #define _SSE_ADD _mm_add_pd
      75             : #define _SSE_XOR _mm_xor_pd
      76             : #define _SSE_MADDSUB _mm_maddsub_pd
      77             : #define _SSE_ADDSUB _mm_addsub_pd
      78             : #define _SSE_SHUFFLE _mm_shuffle_pd
      79             : #define _SHUFFLE _MM_SHUFFLE2(0,1)
      80             : #endif
      81             : #ifdef SINGLE_PRECISION_COMPLEX
      82             : #define offset 4
      83             : #define __SSE_DATATYPE __m128
      84             : #define _SSE_LOAD _mm_load_ps
      85             : #define _SSE_STORE _mm_store_ps
      86             : #define _SSE_MUL _mm_mul_ps
      87             : #define _SSE_ADD _mm_add_ps
      88             : #define _SSE_XOR _mm_xor_ps
      89             : #define _SSE_MADDSUB _mm_maddsub_ps
      90             : #define _SSE_ADDSUB _mm_addsub_ps
      91             : #define _SSE_SHUFFLE _mm_shuffle_ps
      92             : #define _SHUFFLE 0xb1
      93             : #endif
      94             : 
      95             : #define __forceinline __attribute__((always_inline))
      96             : 
      97             : #ifdef HAVE_SSE_INTRINSICS
      98             : #undef __AVX__
      99             : #endif
     100             : 
     101             : #ifdef DOUBLE_PRECISION_COMPLEX
     102             : //Forward declaration
     103             : static __forceinline void hh_trafo_complex_kernel_6_SSE_1hv_double(double complex* q, double complex* hh, int nb, int ldq);
     104             : static __forceinline void hh_trafo_complex_kernel_4_SSE_1hv_double(double complex* q, double complex* hh, int nb, int ldq);
     105             : static __forceinline void hh_trafo_complex_kernel_2_SSE_1hv_double(double complex* q, double complex* hh, int nb, int ldq);
     106             : #endif
     107             : 
     108             : #ifdef SINGLE_PRECISION_COMPLEX
     109             : static __forceinline void hh_trafo_complex_kernel_6_SSE_1hv_single(float complex* q, float complex* hh, int nb, int ldq);
     110             : static __forceinline void hh_trafo_complex_kernel_4_SSE_1hv_single(float complex* q, float complex* hh, int nb, int ldq);
     111             : static __forceinline void hh_trafo_complex_kernel_2_SSE_1hv_single(float complex* q, float complex* hh, int nb, int ldq);
     112             : #endif
     113             : 
     114             : #ifdef DOUBLE_PRECISION_COMPLEX
     115             : /*
     116             : !f>#ifdef WITH_COMPLEX_SSE_BLOCK1_KERNEL
     117             : !f> interface
     118             : !f>   subroutine single_hh_trafo_complex_sse_1hv_double(q, hh, pnb, pnq, pldq) &
     119             : !f>                             bind(C, name="single_hh_trafo_complex_sse_1hv_double")
     120             : !f>     use, intrinsic :: iso_c_binding
     121             : !f>     integer(kind=c_int)     :: pnb, pnq, pldq
     122             : !f>     ! complex(kind=c_double_complex)     :: q(*)
     123             : !f>     type(c_ptr), value                   :: q
     124             : !f>     complex(kind=c_double_complex)     :: hh(pnb,2)
     125             : !f>   end subroutine
     126             : !f> end interface
     127             : !f>#endif
     128             : */
     129             : #endif
     130             : 
     131             : #ifdef SINGLE_PRECISION_COMPLEX
     132             : /*
     133             : !f>#ifdef HAVE_SSE_INTRINSICS
     134             : !f> interface
     135             : !f>   subroutine single_hh_trafo_complex_sse_1hv_single(q, hh, pnb, pnq, pldq) &
     136             : !f>                             bind(C, name="single_hh_trafo_complex_sse_1hv_single")
     137             : !f>     use, intrinsic :: iso_c_binding
     138             : !f>     integer(kind=c_int)     :: pnb, pnq, pldq
     139             : !f>     ! complex(kind=c_float_complex)   :: q(*)
     140             : !f>     type(c_ptr), value                :: q
     141             : !f>     complex(kind=c_float_complex)   :: hh(pnb,2)
     142             : !f>   end subroutine
     143             : !f> end interface
     144             : !f>#endif
     145             : */
     146             : #endif
     147             : 
     148             : #ifdef DOUBLE_PRECISION_COMPLEX
     149     1333248 : void single_hh_trafo_complex_sse_1hv_double(double complex* q, double complex* hh, int* pnb, int* pnq, int* pldq)
     150             : #endif
     151             : #ifdef SINGLE_PRECISION_COMPLEX
     152      666624 : void single_hh_trafo_complex_sse_1hv_single(float complex* q, float complex* hh, int* pnb, int* pnq, int* pldq)
     153             : #endif
     154             : {
     155             :         int i;
     156     1999872 :         int nb = *pnb;
     157     1999872 :         int nq = *pldq;
     158     1999872 :         int ldq = *pldq;
     159             :         //int ldh = *pldh;
     160             : 
     161    13999104 :         for (i = 0; i < nq-4; i+=6)
     162             :         {
     163             : #ifdef DOUBLE_PRECISION_COMPLEX
     164     7999488 :                 hh_trafo_complex_kernel_6_SSE_1hv_double(&q[i], hh, nb, ldq);
     165             : #endif
     166             : #ifdef SINGLE_PRECISION_COMPLEX
     167     3999744 :                 hh_trafo_complex_kernel_6_SSE_1hv_single(&q[i], hh, nb, ldq);
     168             : #endif
     169             :         }
     170     1999872 :         if (nq-i == 0) {
     171           0 :           return;
     172             :         } else {
     173             : 
     174     1999872 :         if (nq-i > 2)
     175             :         {
     176             : #ifdef DOUBLE_PRECISION_COMPLEX
     177     1333248 :                 hh_trafo_complex_kernel_4_SSE_1hv_double(&q[i], hh, nb, ldq);
     178             : #endif
     179             : #ifdef SINGLE_PRECISION_COMPLEX
     180      666624 :                 hh_trafo_complex_kernel_4_SSE_1hv_single(&q[i], hh, nb, ldq);
     181             : #endif
     182             :         }
     183             :         else
     184             :         {
     185             : #ifdef DOUBLE_PRECISION_COMPLEX
     186           0 :                 hh_trafo_complex_kernel_2_SSE_1hv_double(&q[i], hh, nb, ldq);
     187             : #endif
     188             : #ifdef SINGLE_PRECISION_COMPLEX
     189           0 :                 hh_trafo_complex_kernel_2_SSE_1hv_single(&q[i], hh, nb, ldq);
     190             : #endif
     191             :         }
     192             :     }
     193             : }
     194             : 
     195             : #ifdef DOUBLE_PRECISION_COMPLEX
     196             : static __forceinline void hh_trafo_complex_kernel_6_SSE_1hv_double(double complex* q, double complex* hh, int nb, int ldq)
     197             : #endif
     198             : #ifdef SINGLE_PRECISION_COMPLEX
     199             : static __forceinline void hh_trafo_complex_kernel_6_SSE_1hv_single(float complex* q, float complex* hh, int nb, int ldq)
     200             : #endif
     201             : {
     202             : 
     203             : #ifdef DOUBLE_PRECISION_COMPLEX
     204     7999488 :         double* q_dbl = (double*)q;
     205     7999488 :         double* hh_dbl = (double*)hh;
     206             : #endif
     207             : #ifdef SINGLE_PRECISION_COMPLEX
     208     3999744 :         float* q_dbl = (float*)q;
     209     3999744 :         float* hh_dbl = (float*)hh;
     210             : #endif
     211             :         __SSE_DATATYPE x1, x2, x3, x4, x5, x6;
     212             :         __SSE_DATATYPE q1, q2, q3, q4, q5, q6;
     213             :         __SSE_DATATYPE h1_real, h1_imag;
     214             :         __SSE_DATATYPE tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
     215    11999232 :         int i=0;
     216             : 
     217             : #ifdef DOUBLE_PRECISION_COMPLEX
     218     7999488 :         __SSE_DATATYPE sign = (__SSE_DATATYPE)_mm_set_epi64x(0x8000000000000000, 0x8000000000000000);
     219             : #endif
     220             : #ifdef SINGLE_PRECISION_COMPLEX
     221     3999744 :         __SSE_DATATYPE sign = (__SSE_DATATYPE)_mm_set_epi32(0x80000000, 0x80000000, 0x80000000, 0x80000000);
     222             : #endif
     223             : 
     224    11999232 :         x1 = _SSE_LOAD(&q_dbl[0]);
     225    23998464 :         x2 = _SSE_LOAD(&q_dbl[offset]);
     226    23998464 :         x3 = _SSE_LOAD(&q_dbl[2*offset]);
     227             : #ifdef DOUBLE_PRECISION_COMPLEX
     228    15998976 :         x4 = _SSE_LOAD(&q_dbl[3*offset]);
     229    15998976 :         x5 = _SSE_LOAD(&q_dbl[4*offset]);
     230    15998976 :         x6 = _SSE_LOAD(&q_dbl[5*offset]);
     231             : #endif
     232   383975424 :         for (i = 1; i < nb; i++)
     233             :         {
     234             : 
     235             : #ifdef DOUBLE_PRECISION_COMPLEX
     236   495968256 :                 h1_real = _mm_loaddup_pd(&hh_dbl[i*2]);
     237   495968256 :                 h1_imag = _mm_loaddup_pd(&hh_dbl[(i*2)+1]);
     238             : #endif
     239             : #ifdef SINGLE_PRECISION_COMPLEX
     240   495968256 :                 h1_real = _mm_moveldup_ps(_mm_castpd_ps(_mm_loaddup_pd( (double *)(&hh_dbl[i*2]) )));
     241   495968256 :                 h1_imag = _mm_moveldup_ps(_mm_castpd_ps(_mm_loaddup_pd( (double *)(&hh_dbl[(i*2)+1]) )));
     242             : #endif
     243             : #ifndef __ELPA_USE_FMA__
     244             :                 // conjugate
     245   371976192 :                 h1_imag = _SSE_XOR(h1_imag, sign);
     246             : #endif
     247             : 
     248   743952384 :                 q1 = _SSE_LOAD(&q_dbl[(2*i*ldq)+0]);
     249   743952384 :                 q2 = _SSE_LOAD(&q_dbl[(2*i*ldq)+offset]);
     250   743952384 :                 q3 = _SSE_LOAD(&q_dbl[(2*i*ldq)+2*offset]);
     251             : #ifdef DOUBLE_PRECISION_COMPLEX
     252   495968256 :                 q4 = _SSE_LOAD(&q_dbl[(2*i*ldq)+3*offset]);
     253   495968256 :                 q5 = _SSE_LOAD(&q_dbl[(2*i*ldq)+4*offset]);
     254   495968256 :                 q6 = _SSE_LOAD(&q_dbl[(2*i*ldq)+5*offset]);
     255             : #endif
     256             : 
     257   371976192 :                 tmp1 = _SSE_MUL(h1_imag, q1);
     258             : 
     259             : #ifdef __ELPA_USE_FMA__
     260             :                 x1 = _SSE_ADD(x1, _mm_msubadd_pd(h1_real, q1, _SSE_SHUFFLE(tmp1, tmp1, _SHUFFLE)));
     261             : #else
     262  1487904768 :                 x1 = _SSE_ADD(x1, _SSE_ADDSUB( _SSE_MUL(h1_real, q1), _SSE_SHUFFLE(tmp1, tmp1, _SHUFFLE)));
     263             : #endif
     264   371976192 :                 tmp2 = _SSE_MUL(h1_imag, q2);
     265             : #ifdef __ELPA_USE_FMA__
     266             :                 x2 = _SSE_ADD(x2, _mm_msubadd_pd(h1_real, q2, _SSE_SHUFFLE(tmp2, tmp2, _SHUFFLE)));
     267             : #else
     268  1487904768 :                 x2 = _SSE_ADD(x2, _SSE_ADDSUB( _SSE_MUL(h1_real, q2), _SSE_SHUFFLE(tmp2, tmp2, _SHUFFLE)));
     269             : #endif
     270   371976192 :                 tmp3 = _SSE_MUL(h1_imag, q3);
     271             : #ifdef __ELPA_USE_FMA__
     272             :                 x3 = _SSE_ADD(x3, _mm_msubadd_pd(h1_real, q3, _SSE_SHUFFLE(tmp3, tmp3, _SHUFFLE)));
     273             : #else
     274  1487904768 :                 x3 = _SSE_ADD(x3, _SSE_ADDSUB( _SSE_MUL(h1_real, q3), _SSE_SHUFFLE(tmp3, tmp3, _SHUFFLE)));
     275             : #endif
     276             : 
     277             : #ifdef DOUBLE_PRECISION_COMPLEX
     278   247984128 :                 tmp4 = _SSE_MUL(h1_imag, q4);
     279             : #ifdef __ELPA_USE_FMA__
     280             :                 x4 = _SSE_ADD(x4, _mm_msubadd_pd(h1_real, q4, _SSE_SHUFFLE(tmp4, tmp4, _SHUFFLE)));
     281             : #else
     282   991936512 :                 x4 = _SSE_ADD(x4, _SSE_ADDSUB( _SSE_MUL(h1_real, q4), _SSE_SHUFFLE(tmp4, tmp4, _SHUFFLE)));
     283             : #endif
     284   247984128 :                 tmp5 = _SSE_MUL(h1_imag, q5);
     285             : #ifdef __ELPA_USE_FMA__
     286             :                 x5 = _SSE_ADD(x5, _mm_msubadd_pd(h1_real, q5, _SSE_SHUFFLE(tmp5, tmp5, _SHUFFLE)));
     287             : #else
     288   991936512 :                 x5 = _SSE_ADD(x5, _SSE_ADDSUB( _SSE_MUL(h1_real, q5), _SSE_SHUFFLE(tmp5, tmp5, _SHUFFLE)));
     289             : #endif
     290   247984128 :                 tmp6 = _SSE_MUL(h1_imag, q6);
     291             : #ifdef __ELPA_USE_FMA__
     292             :                 x6 = _SSE_ADD(x6, _mm_msubadd_pd(h1_real, q6, _SSE_SHUFFLE(tmp6, tmp6, _SHUFFLE)));
     293             : #else
     294   991936512 :                 x6 = _SSE_ADD(x6, _SSE_ADDSUB( _SSE_MUL(h1_real, q6), _SSE_SHUFFLE(tmp6, tmp6, _SHUFFLE)));
     295             : #endif
     296             : 
     297             : #endif /* DOUBLE_PRECISION_COMPLEX */
     298             :         }
     299             : 
     300             : #ifdef DOUBLE_PRECISION_COMPLEX
     301     7999488 :         h1_real = _mm_loaddup_pd(&hh_dbl[0]);
     302    15998976 :         h1_imag = _mm_loaddup_pd(&hh_dbl[1]);
     303             : #endif
     304             : #ifdef SINGLE_PRECISION_COMPLEX
     305    11999232 :         h1_real = _mm_moveldup_ps(_mm_castpd_ps(_mm_loaddup_pd( (double *)(&hh_dbl[0]) )));
     306    15998976 :         h1_imag = _mm_moveldup_ps(_mm_castpd_ps(_mm_loaddup_pd( (double *)(&hh_dbl[1]) )));
     307             : #endif
     308    11999232 :         h1_real = _SSE_XOR(h1_real, sign);
     309    11999232 :         h1_imag = _SSE_XOR(h1_imag, sign);
     310             : 
     311    11999232 :         tmp1 = _SSE_MUL(h1_imag, x1);
     312             : 
     313             : #ifdef __ELPA_USE_FMA__
     314             :         x1 = _SSE_MADDSUB(h1_real, x1, _SSE_SHUFFLE(tmp1, tmp1, _SHUFFLE));
     315             : #else
     316    35997696 :         x1 = _SSE_ADDSUB( _SSE_MUL(h1_real, x1), _SSE_SHUFFLE(tmp1, tmp1, _SHUFFLE));
     317             : #endif
     318    11999232 :         tmp2 = _SSE_MUL(h1_imag, x2);
     319             : #ifdef __ELPA_USE_FMA__
     320             :         x2 = _SSE_MADDSUB(h1_real, x2, _SSE_SHUFFLE(tmp2, tmp2, _SHUFFLE));
     321             : #else
     322    35997696 :         x2 = _SSE_ADDSUB( _SSE_MUL(h1_real, x2), _SSE_SHUFFLE(tmp2, tmp2, _SHUFFLE));
     323             : #endif
     324    11999232 :         tmp3 = _SSE_MUL(h1_imag, x3);
     325             : #ifdef __ELPA_USE_FMA__
     326             :         x3 = _SSE_MADDSUB(h1_real, x3, _SSE_SHUFFLE(tmp3, tmp3, _SHUFFLE));
     327             : #else
     328    35997696 :         x3 = _SSE_ADDSUB( _SSE_MUL(h1_real, x3), _SSE_SHUFFLE(tmp3, tmp3, _SHUFFLE));
     329             : #endif
     330             : 
     331             : #ifdef DOUBLE_PRECISION_COMPLEX
     332     7999488 :         tmp4 = _SSE_MUL(h1_imag, x4);
     333             : #ifdef __ELPA_USE_FMA__
     334             :         x4 = _SSE_MADDSUB(h1_real, x4, _SSE_SHUFFLE(tmp4, tmp4, _SHUFFLE));
     335             : #else
     336    23998464 :         x4 = _SSE_ADDSUB( _SSE_MUL(h1_real, x4), _SSE_SHUFFLE(tmp4, tmp4, _SHUFFLE));
     337             : #endif
     338     7999488 :         tmp5 = _SSE_MUL(h1_imag, x5);
     339             : #ifdef __ELPA_USE_FMA__
     340             :         x5 = _SSE_MADDSUB(h1_real, x5, _SSE_SHUFFLE(tmp5, tmp5, _SHUFFLE));
     341             : #else
     342    23998464 :         x5 = _SSE_ADDSUB( _SSE_MUL(h1_real, x5), _SSE_SHUFFLE(tmp5, tmp5, _SHUFFLE));
     343             : #endif
     344     7999488 :         tmp6 = _SSE_MUL(h1_imag, x6);
     345             : #ifdef __ELPA_USE_FMA__
     346             :         x6 = _SSE_MADDSUB(h1_real, x6, _SSE_SHUFFLE(tmp6, tmp6, _SHUFFLE));
     347             : #else
     348    23998464 :         x6 = _SSE_ADDSUB( _SSE_MUL(h1_real, x6), _SSE_SHUFFLE(tmp6, tmp6, _SHUFFLE));
     349             : #endif
     350             : #endif /* DOUBLE_PRECISION_COMPLEX */
     351             : 
     352    11999232 :         q1 = _SSE_LOAD(&q_dbl[0]);
     353    23998464 :         q2 = _SSE_LOAD(&q_dbl[offset]);
     354    23998464 :         q3 = _SSE_LOAD(&q_dbl[2*offset]);
     355             : #ifdef DOUBLE_PRECISION_COMPLEX 
     356    15998976 :         q4 = _SSE_LOAD(&q_dbl[3*offset]);
     357    15998976 :         q5 = _SSE_LOAD(&q_dbl[4*offset]);
     358    15998976 :         q6 = _SSE_LOAD(&q_dbl[5*offset]);
     359             : #endif
     360             : 
     361    11999232 :         q1 = _SSE_ADD(q1, x1);
     362    11999232 :         q2 = _SSE_ADD(q2, x2);
     363    11999232 :         q3 = _SSE_ADD(q3, x3);
     364             : #ifdef DOUBLE_PRECISION_COMPLEX 
     365     7999488 :         q4 = _SSE_ADD(q4, x4);
     366     7999488 :         q5 = _SSE_ADD(q5, x5);
     367     7999488 :         q6 = _SSE_ADD(q6, x6);
     368             : #endif
     369             : 
     370             :         _SSE_STORE(&q_dbl[0], q1);
     371    11999232 :         _SSE_STORE(&q_dbl[offset], q2);
     372    11999232 :         _SSE_STORE(&q_dbl[2*offset], q3);
     373             : #ifdef DOUBLE_PRECISION_COMPLEX 
     374     7999488 :         _SSE_STORE(&q_dbl[3*offset], q4);
     375     7999488 :         _SSE_STORE(&q_dbl[4*offset], q5);
     376     7999488 :         _SSE_STORE(&q_dbl[5*offset], q6);
     377             : #endif
     378   383975424 :         for (i = 1; i < nb; i++)
     379             :         {
     380             : #ifdef DOUBLE_PRECISION_COMPLEX
     381   495968256 :                 h1_real = _mm_loaddup_pd(&hh_dbl[i*2]);
     382   495968256 :                 h1_imag = _mm_loaddup_pd(&hh_dbl[(i*2)+1]);
     383             : #endif
     384             : #ifdef SINGLE_PRECISION_COMPLEX
     385   495968256 :                 h1_real = _mm_moveldup_ps(_mm_castpd_ps(_mm_loaddup_pd( (double *)(&hh_dbl[i*2]) )));
     386   495968256 :                 h1_imag = _mm_moveldup_ps(_mm_castpd_ps(_mm_loaddup_pd( (double *)(&hh_dbl[(i*2)+1]) )));
     387             : #endif
     388             : 
     389   743952384 :                 q1 = _SSE_LOAD(&q_dbl[(2*i*ldq)+0]);
     390   743952384 :                 q2 = _SSE_LOAD(&q_dbl[(2*i*ldq)+offset]);
     391   743952384 :                 q3 = _SSE_LOAD(&q_dbl[(2*i*ldq)+2*offset]);
     392             : #ifdef DOUBLE_PRECISION_COMPLEX
     393   495968256 :                 q4 = _SSE_LOAD(&q_dbl[(2*i*ldq)+3*offset]);
     394   495968256 :                 q5 = _SSE_LOAD(&q_dbl[(2*i*ldq)+4*offset]);
     395   495968256 :                 q6 = _SSE_LOAD(&q_dbl[(2*i*ldq)+5*offset]);
     396             : #endif
     397   371976192 :                 tmp1 = _SSE_MUL(h1_imag, x1);
     398             : 
     399             : #ifdef __ELPA_USE_FMA__
     400             :                 q1 = _SSE_ADD(q1, _SSE_MADDSUB(h1_real, x1, _SSE_SHUFFLE(tmp1, tmp1, _SHUFFLE)));
     401             : #else
     402  1487904768 :                 q1 = _SSE_ADD(q1, _SSE_ADDSUB( _SSE_MUL(h1_real, x1), _SSE_SHUFFLE(tmp1, tmp1, _SHUFFLE)));
     403             : #endif
     404   371976192 :                 tmp2 = _SSE_MUL(h1_imag, x2);
     405             : #ifdef __ELPA_USE_FMA__
     406             :                 q2 = _SSE_ADD(q2, _SSE_MADDSUB(h1_real, x2, _SSE_SHUFFLE(tmp2, tmp2, _SHUFFLE)));
     407             : #else
     408  1487904768 :                 q2 = _SSE_ADD(q2, _SSE_ADDSUB( _SSE_MUL(h1_real, x2), _SSE_SHUFFLE(tmp2, tmp2, _SHUFFLE)));
     409             : #endif
     410   371976192 :                 tmp3 = _SSE_MUL(h1_imag, x3);
     411             : #ifdef __ELPA_USE_FMA__
     412             :                 q3 = _SSE_ADD(q3, _SSE_MADDSUB(h1_real, x3, _SSE_SHUFFLE(tmp3, tmp3, _SHUFFLE)));
     413             : #else
     414  1487904768 :                 q3 = _SSE_ADD(q3, _SSE_ADDSUB( _SSE_MUL(h1_real, x3), _SSE_SHUFFLE(tmp3, tmp3, _SHUFFLE)));
     415             : #endif
     416             : 
     417             : #ifdef DOUBLE_PRECISION_COMPLEX
     418   247984128 :                 tmp4 = _SSE_MUL(h1_imag, x4);
     419             : #ifdef __ELPA_USE_FMA__
     420             :                 q4 = _SSE_ADD(q4, _SSE_MADDSUB(h1_real, x4, _SSE_SHUFFLE(tmp4, tmp4, _SHUFFLE)));
     421             : #else
     422   991936512 :                 q4 = _SSE_ADD(q4, _SSE_ADDSUB( _SSE_MUL(h1_real, x4), _SSE_SHUFFLE(tmp4, tmp4, _SHUFFLE)));
     423             : #endif
     424   247984128 :                 tmp5 = _SSE_MUL(h1_imag, x5);
     425             : #ifdef __ELPA_USE_FMA__
     426             :                 q5 = _SSE_ADD(q5, _SSE_MADDSUB(h1_real, x5, _SSE_SHUFFLE(tmp5, tmp5, _SHUFFLE)));
     427             : #else
     428   991936512 :                 q5 = _SSE_ADD(q5, _SSE_ADDSUB( _SSE_MUL(h1_real, x5), _SSE_SHUFFLE(tmp5, tmp5, _SHUFFLE)));
     429             : #endif
     430   247984128 :                 tmp6 = _SSE_MUL(h1_imag, x6);
     431             : #ifdef __ELPA_USE_FMA__
     432             :                 q6 = _SSE_ADD(q6, _SSE_MADDSUB(h1_real, x6, _SSE_SHUFFLE(tmp6, tmp6, _SHUFFLE)));
     433             : #else
     434   991936512 :                 q6 = _SSE_ADD(q6, _SSE_ADDSUB( _SSE_MUL(h1_real, x6), _SSE_SHUFFLE(tmp6, tmp6, _SHUFFLE)));
     435             : #endif
     436             : #endif /* DOUBLE_PRECISION_COMPLEX */
     437             : 
     438   371976192 :                 _SSE_STORE(&q_dbl[(2*i*ldq)+0], q1);
     439   371976192 :                 _SSE_STORE(&q_dbl[(2*i*ldq)+offset], q2);
     440   371976192 :                 _SSE_STORE(&q_dbl[(2*i*ldq)+2*offset], q3);
     441             : #ifdef DOUBLE_PRECISION_COMPLEX
     442   247984128 :                 _SSE_STORE(&q_dbl[(2*i*ldq)+3*offset], q4);
     443   247984128 :                 _SSE_STORE(&q_dbl[(2*i*ldq)+4*offset], q5);
     444   247984128 :                 _SSE_STORE(&q_dbl[(2*i*ldq)+5*offset], q6);
     445             : #endif
     446             :         }
     447             : }
     448             : 
     449             : #ifdef DOUBLE_PRECISION_COMPLEX
     450             : static __forceinline void hh_trafo_complex_kernel_4_SSE_1hv_double(double complex* q, double complex* hh, int nb, int ldq)
     451             : #endif
     452             : #ifdef SINGLE_PRECISION_COMPLEX
     453             : static __forceinline void hh_trafo_complex_kernel_4_SSE_1hv_single(float complex* q, float complex* hh, int nb, int ldq)
     454             : #endif
     455             : {
     456             : #ifdef DOUBLE_PRECISION_COMPLEX
     457     1333248 :         double* q_dbl = (double*)q;
     458     1333248 :         double* hh_dbl = (double*)hh;
     459             : #endif
     460             : #ifdef SINGLE_PRECISION_COMPLEX
     461      666624 :         float* q_dbl = (float*)q;
     462      666624 :         float* hh_dbl = (float*)hh;
     463             : #endif
     464             :         __SSE_DATATYPE x1, x2, x3, x4;
     465             :         __SSE_DATATYPE q1, q2, q3, q4;
     466             :         __SSE_DATATYPE h1_real, h1_imag;
     467             :         __SSE_DATATYPE tmp1, tmp2, tmp3, tmp4;
     468     1999872 :         int i=0;
     469             : #ifdef DOUBLE_PRECISION_COMPLEX
     470     1333248 :         __SSE_DATATYPE sign = (__SSE_DATATYPE)_mm_set_epi64x(0x8000000000000000, 0x8000000000000000);
     471             : #endif
     472             : #ifdef SINGLE_PRECISION_COMPLEX
     473      666624 :         __SSE_DATATYPE sign = (__SSE_DATATYPE)_mm_set_epi32(0x80000000, 0x80000000, 0x80000000, 0x80000000);
     474             : #endif
     475             : 
     476     1999872 :         x1 = _SSE_LOAD(&q_dbl[0]);
     477     3999744 :         x2 = _SSE_LOAD(&q_dbl[offset]);
     478             : #ifdef DOUBLE_PRECISION_COMPLEX
     479     2666496 :         x3 = _SSE_LOAD(&q_dbl[2*offset]);
     480     2666496 :         x4 = _SSE_LOAD(&q_dbl[3*offset]);
     481             : #endif
     482    63995904 :         for (i = 1; i < nb; i++)
     483             :         {
     484             : #ifdef DOUBLE_PRECISION_COMPLEX
     485    82661376 :                 h1_real = _mm_loaddup_pd(&hh_dbl[i*2]);
     486    82661376 :                 h1_imag = _mm_loaddup_pd(&hh_dbl[(i*2)+1]);
     487             : #endif
     488             : #ifdef SINGLE_PRECISION_COMPLEX
     489    82661376 :                 h1_real = _mm_moveldup_ps(_mm_castpd_ps(_mm_loaddup_pd( (double *)(&hh_dbl[i*2]) )));
     490    82661376 :                 h1_imag = _mm_moveldup_ps(_mm_castpd_ps(_mm_loaddup_pd( (double *)(&hh_dbl[(i*2)+1]) )));
     491             : #endif
     492             : #ifndef __ELPA_USE_FMA__
     493             :                 // conjugate
     494    61996032 :                 h1_imag = _SSE_XOR(h1_imag, sign);
     495             : #endif
     496             : 
     497   123992064 :                 q1 = _SSE_LOAD(&q_dbl[(2*i*ldq)+0]);
     498   123992064 :                 q2 = _SSE_LOAD(&q_dbl[(2*i*ldq)+offset]);
     499             : #ifdef DOUBLE_PRECISION_COMPLEX
     500    82661376 :                 q3 = _SSE_LOAD(&q_dbl[(2*i*ldq)+2*offset]);
     501    82661376 :                 q4 = _SSE_LOAD(&q_dbl[(2*i*ldq)+3*offset]);
     502             : #endif
     503    61996032 :                 tmp1 = _SSE_MUL(h1_imag, q1);
     504             : 
     505             : #ifdef __ELPA_USE_FMA__
     506             :                 x1 = _SSE_ADD(x1, _mm_msubadd_pd(h1_real, q1, _SSE_SHUFFLE(tmp1, tmp1, _SHUFFLE)));
     507             : #else
     508   247984128 :                 x1 = _SSE_ADD(x1, _SSE_ADDSUB( _SSE_MUL(h1_real, q1), _SSE_SHUFFLE(tmp1, tmp1, _SHUFFLE)));
     509             : #endif
     510             : 
     511    61996032 :                 tmp2 = _SSE_MUL(h1_imag, q2);
     512             : #ifdef __ELPA_USE_FMA__
     513             :                 x2 = _SSE_ADD(x2, _mm_msubadd_pd(h1_real, q2, _SSE_SHUFFLE(tmp2, tmp2, _SHUFFLE)));
     514             : #else
     515   247984128 :                 x2 = _SSE_ADD(x2, _SSE_ADDSUB( _SSE_MUL(h1_real, q2), _SSE_SHUFFLE(tmp2, tmp2, _SHUFFLE)));
     516             : #endif
     517             : 
     518             : #ifdef DOUBLE_PRECISION_COMPLEX
     519    41330688 :                 tmp3 = _SSE_MUL(h1_imag, q3);
     520             : #ifdef __ELPA_USE_FMA__
     521             :                 x3 = _SSE_ADD(x3, _mm_msubadd_pd(h1_real, q3, _SSE_SHUFFLE(tmp3, tmp3, _SHUFFLE)));
     522             : #else
     523   165322752 :                 x3 = _SSE_ADD(x3, _SSE_ADDSUB( _SSE_MUL(h1_real, q3), _SSE_SHUFFLE(tmp3, tmp3, _SHUFFLE)));
     524             : #endif
     525    41330688 :                 tmp4 = _SSE_MUL(h1_imag, q4);
     526             : #ifdef __ELPA_USE_FMA__
     527             :                 x4 = _SSE_ADD(x4, _mm_msubadd_pd(h1_real, q4, _SSE_SHUFFLE(tmp4, tmp4, _SHUFFLE)));
     528             : #else
     529   165322752 :                 x4 = _SSE_ADD(x4, _SSE_ADDSUB( _SSE_MUL(h1_real, q4), _SSE_SHUFFLE(tmp4, tmp4, _SHUFFLE)));
     530             : #endif
     531             : #endif /* DOUBLE_PRECISION_COMPLEX */
     532             :         }
     533             : 
     534             : #ifdef DOUBLE_PRECISION_COMPLEX
     535     1333248 :         h1_real = _mm_loaddup_pd(&hh_dbl[0]);
     536     2666496 :         h1_imag = _mm_loaddup_pd(&hh_dbl[1]);
     537             : #endif
     538             : #ifdef SINGLE_PRECISION_COMPLEX
     539     1999872 :         h1_real = _mm_moveldup_ps(_mm_castpd_ps(_mm_loaddup_pd( (double *)(&hh_dbl[0]) )));
     540     2666496 :         h1_imag = _mm_moveldup_ps(_mm_castpd_ps(_mm_loaddup_pd( (double *)(&hh_dbl[1]) )));
     541             : #endif
     542     1999872 :         h1_real = _SSE_XOR(h1_real, sign);
     543     1999872 :         h1_imag = _SSE_XOR(h1_imag, sign);
     544             : 
     545     1999872 :         tmp1 = _SSE_MUL(h1_imag, x1);
     546             : 
     547             : #ifdef __ELPA_USE_FMA__
     548             :         x1 = _SSE_MADDSUB(h1_real, x1, _SSE_SHUFFLE(tmp1, tmp1, _SHUFFLE));
     549             : #else
     550     5999616 :         x1 = _SSE_ADDSUB( _SSE_MUL(h1_real, x1), _SSE_SHUFFLE(tmp1, tmp1, _SHUFFLE));
     551             : #endif
     552     1999872 :         tmp2 = _SSE_MUL(h1_imag, x2);
     553             : #ifdef __ELPA_USE_FMA__
     554             :         x2 = _SSE_MADDSUB(h1_real, x2, _SSE_SHUFFLE(tmp2, tmp2, _SHUFFLE));
     555             : #else
     556     5999616 :         x2 = _SSE_ADDSUB( _SSE_MUL(h1_real, x2), _SSE_SHUFFLE(tmp2, tmp2, _SHUFFLE));
     557             : #endif
     558             : 
     559             : #ifdef DOUBLE_PRECISION_COMPLEX
     560     1333248 :         tmp3 = _SSE_MUL(h1_imag, x3);
     561             : #ifdef __ELPA_USE_FMA__
     562             :         x3 = _SSE_MADDSUB(h1_real, x3, _SSE_SHUFFLE(tmp3, tmp3, _SHUFFLE));
     563             : #else
     564     3999744 :         x3 = _SSE_ADDSUB( _SSE_MUL(h1_real, x3), _SSE_SHUFFLE(tmp3, tmp3, _SHUFFLE));
     565             : #endif
     566     1333248 :         tmp4 = _SSE_MUL(h1_imag, x4);
     567             : #ifdef __ELPA_USE_FMA__
     568             :         x4 = _SSE_MADDSUB(h1_real, x4, _SSE_SHUFFLE(tmp4, tmp4, _SHUFFLE));
     569             : #else
     570     3999744 :         x4 = _SSE_ADDSUB( _SSE_MUL(h1_real, x4), _SSE_SHUFFLE(tmp4, tmp4, _SHUFFLE));
     571             : #endif
     572             : #endif /* DOUBLE_PRECISION_COMPLEX */
     573             : 
     574     1999872 :         q1 = _SSE_LOAD(&q_dbl[0]);
     575     3999744 :         q2 = _SSE_LOAD(&q_dbl[offset]);
     576             : #ifdef DOUBLE_PRECISION_COMPLEX
     577     2666496 :         q3 = _SSE_LOAD(&q_dbl[2*offset]);
     578     2666496 :         q4 = _SSE_LOAD(&q_dbl[3*offset]);
     579             : #endif
     580     1999872 :         q1 = _SSE_ADD(q1, x1);
     581     1999872 :         q2 = _SSE_ADD(q2, x2);
     582             : #ifdef DOUBLE_PRECISION_COMPLEX
     583     1333248 :         q3 = _SSE_ADD(q3, x3);
     584     1333248 :         q4 = _SSE_ADD(q4, x4);
     585             : #endif
     586             :         _SSE_STORE(&q_dbl[0], q1);
     587     1999872 :         _SSE_STORE(&q_dbl[offset], q2);
     588             : #ifdef DOUBLE_PRECISION_COMPLEX
     589     1333248 :         _SSE_STORE(&q_dbl[2*offset], q3);
     590     1333248 :         _SSE_STORE(&q_dbl[3*offset], q4);
     591             : #endif
     592    63995904 :         for (i = 1; i < nb; i++)
     593             :         {
     594             : #ifdef DOUBLE_PRECISION_COMPLEX
     595    82661376 :                 h1_real = _mm_loaddup_pd(&hh_dbl[i*2]);
     596    82661376 :                 h1_imag = _mm_loaddup_pd(&hh_dbl[(i*2)+1]);
     597             : #endif
     598             : #ifdef SINGLE_PRECISION_COMPLEX
     599    82661376 :                 h1_real = _mm_moveldup_ps(_mm_castpd_ps(_mm_loaddup_pd( (double *)(&hh_dbl[i*2]) )));
     600    82661376 :                 h1_imag = _mm_moveldup_ps(_mm_castpd_ps(_mm_loaddup_pd( (double *)(&hh_dbl[(i*2)+1]) )));
     601             : #endif
     602   123992064 :                 q1 = _SSE_LOAD(&q_dbl[(2*i*ldq)+0]);
     603   123992064 :                 q2 = _SSE_LOAD(&q_dbl[(2*i*ldq)+offset]);
     604             : #ifdef DOUBLE_PRECISION_COMPLEX
     605    82661376 :                 q3 = _SSE_LOAD(&q_dbl[(2*i*ldq)+2*offset]);
     606    82661376 :                 q4 = _SSE_LOAD(&q_dbl[(2*i*ldq)+3*offset]);
     607             : #endif
     608    61996032 :                 tmp1 = _SSE_MUL(h1_imag, x1);
     609             : 
     610             : #ifdef __ELPA_USE_FMA__
     611             :                 q1 = _SSE_ADD(q1, _SSE_MADDSUB(h1_real, x1, _SSE_SHUFFLE(tmp1, tmp1, _SHUFFLE)));
     612             : #else
     613   247984128 :                 q1 = _SSE_ADD(q1, _SSE_ADDSUB( _SSE_MUL(h1_real, x1), _SSE_SHUFFLE(tmp1, tmp1, _SHUFFLE)));
     614             : #endif
     615    61996032 :                 tmp2 = _SSE_MUL(h1_imag, x2);
     616             : #ifdef __ELPA_USE_FMA__
     617             :                 q2 = _SSE_ADD(q2, _SSE_MADDSUB(h1_real, x2, _SSE_SHUFFLE(tmp2, tmp2, _SHUFFLE)));
     618             : #else
     619   247984128 :                 q2 = _SSE_ADD(q2, _SSE_ADDSUB( _SSE_MUL(h1_real, x2), _SSE_SHUFFLE(tmp2, tmp2, _SHUFFLE)));
     620             : #endif
     621             : 
     622             : #ifdef DOUBLE_PRECISION_COMPLEX
     623    41330688 :                 tmp3 = _SSE_MUL(h1_imag, x3);
     624             : #ifdef __ELPA_USE_FMA__
     625             :                 q3 = _SSE_ADD(q3, _SSE_MADDSUB(h1_real, x3, _SSE_SHUFFLE(tmp3, tmp3, _SHUFFLE)));
     626             : #else
     627   165322752 :                 q3 = _SSE_ADD(q3, _SSE_ADDSUB( _SSE_MUL(h1_real, x3), _SSE_SHUFFLE(tmp3, tmp3, _SHUFFLE)));
     628             : #endif
     629    41330688 :                 tmp4 = _SSE_MUL(h1_imag, x4);
     630             : #ifdef __ELPA_USE_FMA__
     631             :                 q4 = _SSE_ADD(q4, _SSE_MADDSUB(h1_real, x4, _SSE_SHUFFLE(tmp4, tmp4, _SHUFFLE)));
     632             : #else
     633   165322752 :                 q4 = _SSE_ADD(q4, _SSE_ADDSUB( _SSE_MUL(h1_real, x4), _SSE_SHUFFLE(tmp4, tmp4, _SHUFFLE)));
     634             : #endif
     635             : #endif /* DOUBLE_PRECISION_COMPLEX */
     636             : 
     637    61996032 :                 _SSE_STORE(&q_dbl[(2*i*ldq)+0], q1);
     638    61996032 :                 _SSE_STORE(&q_dbl[(2*i*ldq)+offset], q2);
     639             : #ifdef DOUBLE_PRECISION_COMPLEX
     640    41330688 :                 _SSE_STORE(&q_dbl[(2*i*ldq)+2*offset], q3);
     641    41330688 :                 _SSE_STORE(&q_dbl[(2*i*ldq)+3*offset], q4);
     642             : #endif
     643             :         }
     644             : }
     645             : 
     646             : #ifdef DOUBLE_PRECISION_COMPLEX
     647             : static __forceinline void hh_trafo_complex_kernel_2_SSE_1hv_double(double complex* q, double complex* hh, int nb, int ldq)
     648             : #endif
     649             : #ifdef SINGLE_PRECISION_COMPLEX
     650             : static __forceinline void hh_trafo_complex_kernel_2_SSE_1hv_single(float complex* q, float complex* hh, int nb, int ldq)
     651             : #endif
     652             : {
     653             : 
     654             : #ifdef DOUBLE_PRECISION_COMPLEX
     655           0 :         double* q_dbl = (double*)q;
     656           0 :         double* hh_dbl = (double*)hh;
     657             : #endif
     658             : #ifdef SINGLE_PRECISION_COMPLEX
     659           0 :         float* q_dbl = (float*)q;
     660           0 :         float* hh_dbl = (float*)hh;
     661             : #endif
     662             :         __SSE_DATATYPE x1, x2;
     663             :         __SSE_DATATYPE q1, q2;
     664             :         __SSE_DATATYPE h1_real, h1_imag;
     665             :         __SSE_DATATYPE tmp1, tmp2;
     666           0 :         int i=0;
     667             : 
     668             : #ifdef DOUBLE_PRECISION_COMPLEX
     669           0 :         __SSE_DATATYPE sign = (__SSE_DATATYPE)_mm_set_epi64x(0x8000000000000000, 0x8000000000000000);
     670             : #endif
     671             : #ifdef SINGLE_PRECISION_COMPLEX
     672           0 :         __SSE_DATATYPE sign = (__SSE_DATATYPE)_mm_set_epi32(0x80000000, 0x80000000, 0x80000000, 0x80000000);
     673             : #endif
     674           0 :         x1 = _SSE_LOAD(&q_dbl[0]);
     675             : #ifdef DOUBLE_PRECISION_COMPLEX
     676           0 :         x2 = _SSE_LOAD(&q_dbl[offset]);
     677             : #endif
     678           0 :         for (i = 1; i < nb; i++)
     679             :         {
     680             : #ifdef DOUBLE_PRECISION_COMPLEX
     681           0 :                 h1_real = _mm_loaddup_pd(&hh_dbl[i*2]);
     682           0 :                 h1_imag = _mm_loaddup_pd(&hh_dbl[(i*2)+1]);
     683             : #endif
     684             : #ifdef SINGLE_PRECISION_COMPLEX
     685           0 :                 h1_real = _mm_moveldup_ps(_mm_castpd_ps(_mm_loaddup_pd( (double *)(&hh_dbl[i*2]) )));
     686           0 :                 h1_imag = _mm_moveldup_ps(_mm_castpd_ps(_mm_loaddup_pd( (double *)(&hh_dbl[(i*2)+1]) )));
     687             : #endif
     688             : #ifndef __ELPA_USE_FMA__
     689             :                 // conjugate
     690           0 :                 h1_imag = _SSE_XOR(h1_imag, sign);
     691             : #endif
     692             : 
     693           0 :                 q1 = _SSE_LOAD(&q_dbl[(2*i*ldq)+0]);
     694             : #ifdef DOUBLE_PRECISION_COMPLEX
     695           0 :                 q2 = _SSE_LOAD(&q_dbl[(2*i*ldq)+offset]);
     696             : #endif
     697           0 :                 tmp1 = _SSE_MUL(h1_imag, q1);
     698             : 
     699             : #ifdef __ELPA_USE_FMA__
     700             :                 x1 = _SSE_ADD(x1, _mm_msubadd_pd(h1_real, q1, _SSE_SHUFFLE(tmp1, tmp1, _SHUFFLE)));
     701             : #else
     702           0 :                 x1 = _SSE_ADD(x1, _SSE_ADDSUB( _SSE_MUL(h1_real, q1), _SSE_SHUFFLE(tmp1, tmp1, _SHUFFLE)));
     703             : #endif
     704             : 
     705             : #ifdef DOUBLE_PRECISION_COMPLEX
     706           0 :                 tmp2 = _SSE_MUL(h1_imag, q2);
     707             : #ifdef __ELPA_USE_FMA__
     708             :                 x2 = _SSE_ADD(x2, _mm_msubadd_pd(h1_real, q2, _SSE_SHUFFLE(tmp2, tmp2, _SHUFFLE)));
     709             : #else
     710           0 :                 x2 = _SSE_ADD(x2, _SSE_ADDSUB( _SSE_MUL(h1_real, q2), _SSE_SHUFFLE(tmp2, tmp2, _SHUFFLE)));
     711             : #endif
     712             : #endif /* DOUBLE_PRECISION_COMPLEX */
     713             :         }
     714             : 
     715             : #ifdef DOUBLE_PRECISION_COMPLEX
     716           0 :         h1_real = _mm_loaddup_pd(&hh_dbl[0]);
     717           0 :         h1_imag = _mm_loaddup_pd(&hh_dbl[1]);
     718             : #endif
     719             : #ifdef SINGLE_PRECISION_COMPLEX
     720           0 :         h1_real = _mm_moveldup_ps(_mm_castpd_ps(_mm_loaddup_pd( (double *)(&hh_dbl[0]) )));
     721           0 :         h1_imag = _mm_moveldup_ps(_mm_castpd_ps(_mm_loaddup_pd( (double *)(&hh_dbl[1]) )));
     722             : #endif
     723           0 :         h1_real = _SSE_XOR(h1_real, sign);
     724           0 :         h1_imag = _SSE_XOR(h1_imag, sign);
     725             : 
     726           0 :         tmp1 = _SSE_MUL(h1_imag, x1);
     727             : 
     728             : #ifdef __ELPA_USE_FMA__
     729             :         x1 = _SSE_MADDSUB(h1_real, x1, _SSE_SHUFFLE(tmp1, tmp1, _SHUFFLE));
     730             : #else
     731           0 :         x1 = _SSE_ADDSUB( _SSE_MUL(h1_real, x1), _SSE_SHUFFLE(tmp1, tmp1, _SHUFFLE));
     732             : #endif
     733             : 
     734             : #ifdef DOUBLE_PRECISION_COMPLEX
     735           0 :         tmp2 = _SSE_MUL(h1_imag, x2);
     736             : #ifdef __ELPA_USE_FMA__
     737             :         x2 = _SSE_MADDSUB(h1_real, x2, _SSE_SHUFFLE(tmp2, tmp2, _SHUFFLE));
     738             : #else
     739           0 :         x2 = _SSE_ADDSUB( _SSE_MUL(h1_real, x2), _SSE_SHUFFLE(tmp2, tmp2, _SHUFFLE));
     740             : #endif
     741             : #endif /* DOUBLE_PRECISION_COMPLEX */
     742           0 :         q1 = _SSE_LOAD(&q_dbl[0]);
     743             : #ifdef DOUBLE_PRECISION_COMPLEX
     744           0 :         q2 = _SSE_LOAD(&q_dbl[offset]);
     745             : #endif
     746           0 :         q1 = _SSE_ADD(q1, x1);
     747             : #ifdef DOUBLE_PRECISION_COMPLEX
     748           0 :         q2 = _SSE_ADD(q2, x2);
     749             : #endif
     750             :         _SSE_STORE(&q_dbl[0], q1);
     751             : #ifdef DOUBLE_PRECISION_COMPLEX
     752           0 :         _SSE_STORE(&q_dbl[offset], q2);
     753             : #endif
     754           0 :         for (i = 1; i < nb; i++)
     755             :         {
     756             : #ifdef DOUBLE_PRECISION_COMPLEX
     757           0 :                 h1_real = _mm_loaddup_pd(&hh_dbl[i*2]);
     758           0 :                 h1_imag = _mm_loaddup_pd(&hh_dbl[(i*2)+1]);
     759             : #endif
     760             : #ifdef SINGLE_PRECISION_COMPLEX
     761           0 :                 h1_real = _mm_moveldup_ps(_mm_castpd_ps(_mm_loaddup_pd( (double *)(&hh_dbl[i*2]) )));
     762           0 :                 h1_imag = _mm_moveldup_ps(_mm_castpd_ps(_mm_loaddup_pd( (double *)(&hh_dbl[(i*2)+1]) )));
     763             : #endif
     764             : 
     765           0 :                 q1 = _SSE_LOAD(&q_dbl[(2*i*ldq)+0]);
     766             : #ifdef DOUBLE_PRECISION_COMPLEX
     767           0 :                 q2 = _SSE_LOAD(&q_dbl[(2*i*ldq)+offset]);
     768             : #endif
     769           0 :                 tmp1 = _SSE_MUL(h1_imag, x1);
     770             : 
     771             : #ifdef __ELPA_USE_FMA__
     772             :                 q1 = _SSE_ADD(q1, _SSE_MADDSUB(h1_real, x1, _SSE_SHUFFLE(tmp1, tmp1, _SHUFFLE)));
     773             : #else
     774           0 :                 q1 = _SSE_ADD(q1, _SSE_ADDSUB( _SSE_MUL(h1_real, x1), _SSE_SHUFFLE(tmp1, tmp1, _SHUFFLE)));
     775             : #endif
     776             : 
     777             : #ifdef DOUBLE_PRECISION_COMPLEX
     778           0 :                 tmp2 = _SSE_MUL(h1_imag, x2);
     779             : #ifdef __ELPA_USE_FMA__
     780             :                 q2 = _SSE_ADD(q2, _SSE_MADDSUB(h1_real, x2, _SSE_SHUFFLE(tmp2, tmp2, _SHUFFLE)));
     781             : #else
     782           0 :                 q2 = _SSE_ADD(q2, _SSE_ADDSUB( _SSE_MUL(h1_real, x2), _SSE_SHUFFLE(tmp2, tmp2, _SHUFFLE)));
     783             : #endif
     784             : #endif /* DOUBLE_PRECISION_COMPLEX */
     785           0 :                 _SSE_STORE(&q_dbl[(2*i*ldq)+0], q1);
     786             : #ifdef DOUBLE_PRECISION_COMPLEX
     787           0 :                 _SSE_STORE(&q_dbl[(2*i*ldq)+offset], q2);
     788             : #endif
     789             :         }
     790             : }

Generated by: LCOV version 1.12