Home | History | Annotate | Download | only in db_vlvm
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 /* $Id: db_utilities_linalg.h,v 1.5 2011/06/17 14:03:31 mbansal Exp $ */
     18 
     19 #ifndef DB_UTILITIES_LINALG
     20 #define DB_UTILITIES_LINALG
     21 
     22 #include "db_utilities.h"
     23 
     24 
     25 
     26 /*****************************************************************
     27 *    Lean and mean begins here                                   *
     28 *****************************************************************/
     29 /*!
     30  * \defgroup LMLinAlg (LM) Linear Algebra Utilities (QR factorization, orthogonal basis, etc.)
     31  */
     32 
     33 /*!
     34  \ingroup LMBasicUtilities
     35  */
     36 inline void db_MultiplyScalar6(double A[6],double mult)
     37 {
     38     (*A++) *= mult; (*A++) *= mult; (*A++) *= mult; (*A++) *= mult; (*A++) *= mult;
     39     (*A++) *= mult;
     40 }
     41 /*!
     42  \ingroup LMBasicUtilities
     43  */
     44 inline void db_MultiplyScalar7(double A[7],double mult)
     45 {
     46     (*A++) *= mult; (*A++) *= mult; (*A++) *= mult; (*A++) *= mult; (*A++) *= mult;
     47     (*A++) *= mult; (*A++) *= mult;
     48 }
     49 /*!
     50  \ingroup LMBasicUtilities
     51  */
     52 inline void db_MultiplyScalar9(double A[9],double mult)
     53 {
     54     (*A++) *= mult; (*A++) *= mult; (*A++) *= mult; (*A++) *= mult; (*A++) *= mult;
     55     (*A++) *= mult; (*A++) *= mult; (*A++) *= mult; (*A++) *= mult;
     56 }
     57 
     58 /*!
     59  \ingroup LMBasicUtilities
     60  */
     61 inline double db_SquareSum6Stride7(const double *x)
     62 {
     63     return(db_sqr(x[0])+db_sqr(x[7])+db_sqr(x[14])+
     64         db_sqr(x[21])+db_sqr(x[28])+db_sqr(x[35]));
     65 }
     66 
     67 /*!
     68  \ingroup LMBasicUtilities
     69  */
     70 inline double db_SquareSum8Stride9(const double *x)
     71 {
     72     return(db_sqr(x[0])+db_sqr(x[9])+db_sqr(x[18])+
     73         db_sqr(x[27])+db_sqr(x[36])+db_sqr(x[45])+
     74         db_sqr(x[54])+db_sqr(x[63]));
     75 }
     76 
     77 /*!
     78  \ingroup LMLinAlg
     79  Cholesky-factorize symmetric positive definite 6 x 6 matrix A. Upper
     80 part of A is used from the input. The Cholesky factor is output as
     81 subdiagonal part in A and diagonal in d, which is 6-dimensional
     82 1.9 microseconds on 450MHz*/
     83 DB_API void db_CholeskyDecomp6x6(double A[36],double d[6]);
     84 
     85 /*!
     86  \ingroup LMLinAlg
     87  Backsubstitute L%transpose(L)*x=b for x given the Cholesky decomposition
     88 of a 6 x 6 matrix and the right hand side b. The vector b is unchanged
     89 1.3 microseconds on 450MHz*/
     90 DB_API void db_CholeskyBacksub6x6(double x[6],const double A[36],const double d[6],const double b[6]);
     91 
     92 /*!
     93  \ingroup LMLinAlg
     94  Cholesky-factorize symmetric positive definite n x n matrix A.Part
     95 above diagonal of A is used from the input, diagonal of A is assumed to
     96 be stored in d. The Cholesky factor is output as
     97 subdiagonal part in A and diagonal in d, which is n-dimensional*/
     98 DB_API void db_CholeskyDecompSeparateDiagonal(double **A,double *d,int n);
     99 
    100 /*!
    101  \ingroup LMLinAlg
    102  Backsubstitute L%transpose(L)*x=b for x given the Cholesky decomposition
    103 of an n x n matrix and the right hand side b. The vector b is unchanged*/
    104 DB_API void db_CholeskyBacksub(double *x,const double * const *A,const double *d,int n,const double *b);
    105 
    106 /*!
    107  \ingroup LMLinAlg
    108  Cholesky-factorize symmetric positive definite 3 x 3 matrix A. Part
    109 above diagonal of A is used from the input, diagonal of A is assumed to
    110 be stored in d. The Cholesky factor is output as subdiagonal part in A
    111 and diagonal in d, which is 3-dimensional*/
    112 DB_API void db_CholeskyDecomp3x3SeparateDiagonal(double A[9],double d[3]);
    113 
    114 /*!
    115  \ingroup LMLinAlg
    116  Backsubstitute L%transpose(L)*x=b for x given the Cholesky decomposition
    117 of a 3 x 3 matrix and the right hand side b. The vector b is unchanged*/
    118 DB_API void db_CholeskyBacksub3x3(double x[3],const double A[9],const double d[3],const double b[3]);
    119 
    120 /*!
    121  \ingroup LMLinAlg
    122  perform A-=B*mult*/
    123 inline void db_RowOperation3(double A[3],const double B[3],double mult)
    124 {
    125     *A++ -= mult*(*B++); *A++ -= mult*(*B++); *A++ -= mult*(*B++);
    126 }
    127 
    128 /*!
    129  \ingroup LMLinAlg
    130  */
    131 inline void db_RowOperation7(double A[7],const double B[7],double mult)
    132 {
    133     *A++ -= mult*(*B++); *A++ -= mult*(*B++); *A++ -= mult*(*B++); *A++ -= mult*(*B++); *A++ -= mult*(*B++);
    134     *A++ -= mult*(*B++); *A++ -= mult*(*B++);
    135 }
    136 
    137 /*!
    138  \ingroup LMLinAlg
    139  */
    140 inline void db_RowOperation9(double A[9],const double B[9],double mult)
    141 {
    142     *A++ -= mult*(*B++); *A++ -= mult*(*B++); *A++ -= mult*(*B++); *A++ -= mult*(*B++); *A++ -= mult*(*B++);
    143     *A++ -= mult*(*B++); *A++ -= mult*(*B++); *A++ -= mult*(*B++); *A++ -= mult*(*B++);
    144 }
    145 
    146 /*!
    147  \ingroup LMBasicUtilities
    148  Swap values of A[7] and B[7]
    149  */
    150 inline void db_Swap7(double A[7],double B[7])
    151 {
    152     double temp;
    153     temp= *A; *A++ = *B; *B++ =temp;    temp= *A; *A++ = *B; *B++ =temp;    temp= *A; *A++ = *B; *B++ =temp;
    154     temp= *A; *A++ = *B; *B++ =temp;    temp= *A; *A++ = *B; *B++ =temp;    temp= *A; *A++ = *B; *B++ =temp;
    155     temp= *A; *A++ = *B; *B++ =temp;
    156 }
    157 
    158 /*!
    159  \ingroup LMBasicUtilities
    160  Swap values of A[9] and B[9]
    161  */
    162 inline void db_Swap9(double A[9],double B[9])
    163 {
    164     double temp;
    165     temp= *A; *A++ = *B; *B++ =temp;    temp= *A; *A++ = *B; *B++ =temp;    temp= *A; *A++ = *B; *B++ =temp;
    166     temp= *A; *A++ = *B; *B++ =temp;    temp= *A; *A++ = *B; *B++ =temp;    temp= *A; *A++ = *B; *B++ =temp;
    167     temp= *A; *A++ = *B; *B++ =temp;    temp= *A; *A++ = *B; *B++ =temp;    temp= *A; *A++ = *B; *B++ =temp;
    168 }
    169 
    170 
    171 /*!
    172  \ingroup LMLinAlg
    173  */
    174 DB_API void db_Orthogonalize6x7(double A[42],int orthonormalize=0);
    175 
    176 /*!
    177  \ingroup LMLinAlg
    178  */
    179 DB_API void db_Orthogonalize8x9(double A[72],int orthonormalize=0);
    180 
    181 /*!
    182  \ingroup LMLinAlg
    183  */
    184 inline double db_OrthogonalizePair7(double *x,const double *v,double ssv)
    185 {
    186     double m,sp,sp_m;
    187 
    188     m=db_SafeReciprocal(ssv);
    189     sp=db_ScalarProduct7(x,v);
    190     sp_m=sp*m;
    191     db_RowOperation7(x,v,sp_m);
    192     return(sp*sp_m);
    193 }
    194 
    195 /*!
    196  \ingroup LMLinAlg
    197  */
    198 inline double db_OrthogonalizePair9(double *x,const double *v,double ssv)
    199 {
    200     double m,sp,sp_m;
    201 
    202     m=db_SafeReciprocal(ssv);
    203     sp=db_ScalarProduct9(x,v);
    204     sp_m=sp*m;
    205     db_RowOperation9(x,v,sp_m);
    206     return(sp*sp_m);
    207 }
    208 
    209 /*!
    210  \ingroup LMLinAlg
    211  */
    212 inline void db_OrthogonalizationSwap7(double *A,int i,double *ss)
    213 {
    214     double temp;
    215 
    216     db_Swap7(A,A+7*i);
    217     temp=ss[0]; ss[0]=ss[i]; ss[i]=temp;
    218 }
    219 /*!
    220  \ingroup LMLinAlg
    221  */
    222 inline void db_OrthogonalizationSwap9(double *A,int i,double *ss)
    223 {
    224     double temp;
    225 
    226     db_Swap9(A,A+9*i);
    227     temp=ss[0]; ss[0]=ss[i]; ss[i]=temp;
    228 }
    229 
    230 /*!
    231  \ingroup LMLinAlg
    232  */
    233 DB_API void db_NullVectorOrthonormal6x7(double x[7],const double A[42]);
    234 /*!
    235  \ingroup LMLinAlg
    236  */
    237 DB_API void db_NullVectorOrthonormal8x9(double x[9],const double A[72]);
    238 
    239 /*!
    240  \ingroup LMLinAlg
    241  */
    242 inline void db_NullVector6x7Destructive(double x[7],double A[42])
    243 {
    244     db_Orthogonalize6x7(A,1);
    245     db_NullVectorOrthonormal6x7(x,A);
    246 }
    247 
    248 /*!
    249  \ingroup LMLinAlg
    250  */
    251 inline void db_NullVector8x9Destructive(double x[9],double A[72])
    252 {
    253     db_Orthogonalize8x9(A,1);
    254     db_NullVectorOrthonormal8x9(x,A);
    255 }
    256 
    257 inline int db_ScalarProduct512_s(const short *f,const short *g)
    258 {
    259 #ifndef DB_USE_MMX
    260     int back;
    261     back=0;
    262     for(int i=1; i<=512; i++)
    263         back+=(*f++)*(*g++);
    264 
    265     return(back);
    266 #endif
    267 }
    268 
    269 
    270 inline int db_ScalarProduct32_s(const short *f,const short *g)
    271 {
    272 #ifndef DB_USE_MMX
    273     int back;
    274     back=0;
    275     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    276     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    277     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    278     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    279     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    280     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    281     back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    282 
    283     return(back);
    284 #endif
    285 }
    286 
    287 /*!
    288  \ingroup LMLinAlg
    289  Scalar product of 128-vectors (short)
    290   Compile-time control: MMX, SSE2 or standard C
    291  */
    292 inline int db_ScalarProduct128_s(const short *f,const short *g)
    293 {
    294 #ifndef DB_USE_MMX
    295     int back;
    296     back=0;
    297     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    298     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    299     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    300     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    301     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    302     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    303     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    304     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    305     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    306     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    307 
    308     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    309     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    310     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    311     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    312     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    313     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    314     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    315     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    316     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    317     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    318 
    319     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    320     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    321     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    322     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    323     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    324     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    325 
    326     return(back);
    327 #else
    328 #ifdef DB_USE_SSE2
    329     int back;
    330 
    331     _asm
    332     {
    333         mov eax,f
    334         mov ecx,g
    335         /*First iteration************************************/
    336         movdqa     xmm0,[eax]
    337          pxor    xmm7,xmm7      /*Set xmm7 to zero*/
    338         pmaddwd  xmm0,[ecx]
    339          /*Stall*/
    340         /*Standard iteration************************************/
    341         movdqa     xmm2,[eax+16]
    342          paddd   xmm7,xmm0
    343         pmaddwd  xmm2,[ecx+16]
    344          /*Stall*/
    345         movdqa     xmm1,[eax+32]
    346          paddd   xmm7,xmm2
    347         pmaddwd  xmm1,[ecx+32]
    348          /*Stall*/
    349         /*Standard iteration************************************/
    350         movdqa     xmm0,[eax+48]
    351          paddd   xmm7,xmm1
    352         pmaddwd  xmm0,[ecx+48]
    353          /*Stall*/
    354         /*Standard iteration************************************/
    355         movdqa     xmm2,[eax+64]
    356          paddd   xmm7,xmm0
    357         pmaddwd  xmm2,[ecx+64]
    358          /*Stall*/
    359         movdqa     xmm1,[eax+80]
    360          paddd   xmm7,xmm2
    361         pmaddwd  xmm1,[ecx+80]
    362          /*Stall*/
    363         /*Standard iteration************************************/
    364         movdqa     xmm0,[eax+96]
    365          paddd   xmm7,xmm1
    366         pmaddwd  xmm0,[ecx+96]
    367          /*Stall*/
    368         /*Standard iteration************************************/
    369         movdqa     xmm2,[eax+112]
    370          paddd   xmm7,xmm0
    371         pmaddwd  xmm2,[ecx+112]
    372          /*Stall*/
    373         movdqa     xmm1,[eax+128]
    374          paddd   xmm7,xmm2
    375         pmaddwd  xmm1,[ecx+128]
    376          /*Stall*/
    377         /*Standard iteration************************************/
    378         movdqa     xmm0,[eax+144]
    379          paddd   xmm7,xmm1
    380         pmaddwd  xmm0,[ecx+144]
    381          /*Stall*/
    382         /*Standard iteration************************************/
    383         movdqa     xmm2,[eax+160]
    384          paddd   xmm7,xmm0
    385         pmaddwd  xmm2,[ecx+160]
    386          /*Stall*/
    387         movdqa     xmm1,[eax+176]
    388          paddd   xmm7,xmm2
    389         pmaddwd  xmm1,[ecx+176]
    390          /*Stall*/
    391         /*Standard iteration************************************/
    392         movdqa     xmm0,[eax+192]
    393          paddd   xmm7,xmm1
    394         pmaddwd  xmm0,[ecx+192]
    395          /*Stall*/
    396         /*Standard iteration************************************/
    397         movdqa     xmm2,[eax+208]
    398          paddd   xmm7,xmm0
    399         pmaddwd  xmm2,[ecx+208]
    400          /*Stall*/
    401         movdqa     xmm1,[eax+224]
    402          paddd   xmm7,xmm2
    403         pmaddwd  xmm1,[ecx+224]
    404          /*Stall*/
    405         /*Standard iteration************************************/
    406         movdqa     xmm0,[eax+240]
    407          paddd   xmm7,xmm1
    408         pmaddwd  xmm0,[ecx+240]
    409          /*Stall*/
    410         /*Rest iteration************************************/
    411         paddd    xmm7,xmm0
    412 
    413         /* add up the sum squares */
    414         movhlps     xmm0,xmm7   /* high half to low half */
    415         paddd       xmm7,xmm0   /* add high to low */
    416         pshuflw     xmm0,xmm7, 0xE /* reshuffle */
    417         paddd       xmm7,xmm0   /* add remaining */
    418         movd        back,xmm7
    419 
    420         emms
    421     }
    422 
    423     return(back);
    424 #else
    425     int back;
    426 
    427     _asm
    428     {
    429         mov eax,f
    430         mov ecx,g
    431         /*First iteration************************************/
    432         movq     mm0,[eax]
    433          pxor    mm7,mm7      /*Set mm7 to zero*/
    434         pmaddwd  mm0,[ecx]
    435          /*Stall*/
    436         movq     mm1,[eax+8]
    437          /*Stall*/
    438         pmaddwd  mm1,[ecx+8]
    439          /*Stall*/
    440         /*Standard iteration************************************/
    441         movq     mm2,[eax+16]
    442          paddd   mm7,mm0
    443         pmaddwd  mm2,[ecx+16]
    444          /*Stall*/
    445         movq     mm0,[eax+24]
    446          paddd   mm7,mm1
    447         pmaddwd  mm0,[ecx+24]
    448          /*Stall*/
    449         movq     mm1,[eax+32]
    450          paddd   mm7,mm2
    451         pmaddwd  mm1,[ecx+32]
    452          /*Stall*/
    453         /*Standard iteration************************************/
    454         movq     mm2,[eax+40]
    455          paddd   mm7,mm0
    456         pmaddwd  mm2,[ecx+40]
    457          /*Stall*/
    458         movq     mm0,[eax+48]
    459          paddd   mm7,mm1
    460         pmaddwd  mm0,[ecx+48]
    461          /*Stall*/
    462         movq     mm1,[eax+56]
    463          paddd   mm7,mm2
    464         pmaddwd  mm1,[ecx+56]
    465          /*Stall*/
    466         /*Standard iteration************************************/
    467         movq     mm2,[eax+64]
    468          paddd   mm7,mm0
    469         pmaddwd  mm2,[ecx+64]
    470          /*Stall*/
    471         movq     mm0,[eax+72]
    472          paddd   mm7,mm1
    473         pmaddwd  mm0,[ecx+72]
    474          /*Stall*/
    475         movq     mm1,[eax+80]
    476          paddd   mm7,mm2
    477         pmaddwd  mm1,[ecx+80]
    478          /*Stall*/
    479         /*Standard iteration************************************/
    480         movq     mm2,[eax+88]
    481          paddd   mm7,mm0
    482         pmaddwd  mm2,[ecx+88]
    483          /*Stall*/
    484         movq     mm0,[eax+96]
    485          paddd   mm7,mm1
    486         pmaddwd  mm0,[ecx+96]
    487          /*Stall*/
    488         movq     mm1,[eax+104]
    489          paddd   mm7,mm2
    490         pmaddwd  mm1,[ecx+104]
    491          /*Stall*/
    492         /*Standard iteration************************************/
    493         movq     mm2,[eax+112]
    494          paddd   mm7,mm0
    495         pmaddwd  mm2,[ecx+112]
    496          /*Stall*/
    497         movq     mm0,[eax+120]
    498          paddd   mm7,mm1
    499         pmaddwd  mm0,[ecx+120]
    500          /*Stall*/
    501         movq     mm1,[eax+128]
    502          paddd   mm7,mm2
    503         pmaddwd  mm1,[ecx+128]
    504          /*Stall*/
    505         /*Standard iteration************************************/
    506         movq     mm2,[eax+136]
    507          paddd   mm7,mm0
    508         pmaddwd  mm2,[ecx+136]
    509          /*Stall*/
    510         movq     mm0,[eax+144]
    511          paddd   mm7,mm1
    512         pmaddwd  mm0,[ecx+144]
    513          /*Stall*/
    514         movq     mm1,[eax+152]
    515          paddd   mm7,mm2
    516         pmaddwd  mm1,[ecx+152]
    517          /*Stall*/
    518         /*Standard iteration************************************/
    519         movq     mm2,[eax+160]
    520          paddd   mm7,mm0
    521         pmaddwd  mm2,[ecx+160]
    522          /*Stall*/
    523         movq     mm0,[eax+168]
    524          paddd   mm7,mm1
    525         pmaddwd  mm0,[ecx+168]
    526          /*Stall*/
    527         movq     mm1,[eax+176]
    528          paddd   mm7,mm2
    529         pmaddwd  mm1,[ecx+176]
    530          /*Stall*/
    531         /*Standard iteration************************************/
    532         movq     mm2,[eax+184]
    533          paddd   mm7,mm0
    534         pmaddwd  mm2,[ecx+184]
    535          /*Stall*/
    536         movq     mm0,[eax+192]
    537          paddd   mm7,mm1
    538         pmaddwd  mm0,[ecx+192]
    539          /*Stall*/
    540         movq     mm1,[eax+200]
    541          paddd   mm7,mm2
    542         pmaddwd  mm1,[ecx+200]
    543          /*Stall*/
    544         /*Standard iteration************************************/
    545         movq     mm2,[eax+208]
    546          paddd   mm7,mm0
    547         pmaddwd  mm2,[ecx+208]
    548          /*Stall*/
    549         movq     mm0,[eax+216]
    550          paddd   mm7,mm1
    551         pmaddwd  mm0,[ecx+216]
    552          /*Stall*/
    553         movq     mm1,[eax+224]
    554          paddd   mm7,mm2
    555         pmaddwd  mm1,[ecx+224]
    556          /*Stall*/
    557         /*Standard iteration************************************/
    558         movq     mm2,[eax+232]
    559          paddd   mm7,mm0
    560         pmaddwd  mm2,[ecx+232]
    561          /*Stall*/
    562         movq     mm0,[eax+240]
    563          paddd   mm7,mm1
    564         pmaddwd  mm0,[ecx+240]
    565          /*Stall*/
    566         movq     mm1,[eax+248]
    567          paddd   mm7,mm2
    568         pmaddwd  mm1,[ecx+248]
    569          /*Stall*/
    570         /*Rest iteration************************************/
    571         paddd    mm7,mm0
    572          /*Stall*/
    573         /*Stall*/
    574          /*Stall*/
    575         paddd    mm7,mm1
    576          /*Stall*/
    577         movq     mm0,mm7
    578          psrlq   mm7,32
    579         paddd    mm0,mm7
    580          /*Stall*/
    581         /*Stall*/
    582          /*Stall*/
    583         movd     back,mm0
    584         emms
    585     }
    586 
    587     return(back);
    588 #endif
    589 #endif /*DB_USE_MMX*/
    590 }
    591 
    592 /*!
    593  \ingroup LMLinAlg
    594  Scalar product of 16 byte aligned 128-vectors (float).
    595   Compile-time control: SIMD (SSE) or standard C.
    596  */
    597 inline float db_ScalarProduct128Aligned16_f(const float *f,const float *g)
    598 {
    599 #ifndef DB_USE_SIMD
    600     float back;
    601     back=0.0;
    602     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    603     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    604     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    605     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    606     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    607     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    608     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    609     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    610     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    611     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    612 
    613     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    614     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    615     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    616     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    617     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    618     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    619     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    620     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    621     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    622     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    623 
    624     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    625     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    626     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    627     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    628     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    629     back+=(*f++)*(*g++); back+=(*f++)*(*g++); back+=(*f++)*(*g++);
    630 
    631     return(back);
    632 #else
    633     float back;
    634 
    635     _asm
    636     {
    637         mov eax,f
    638         mov ecx,g
    639         /*First iteration************************************/
    640         movaps     xmm0,[eax]
    641          xorps      xmm7,xmm7       /*Set mm7 to zero*/
    642         mulps      xmm0,[ecx]
    643          /*Stall*/
    644         movaps     xmm1,[eax+16]
    645          /*Stall*/
    646         mulps      xmm1,[ecx+16]
    647          /*Stall*/
    648         /*Standard iteration************************************/
    649         movaps     xmm2,[eax+32]
    650          addps      xmm7,xmm0
    651         mulps      xmm2,[ecx+32]
    652          /*Stall*/
    653         movaps     xmm0,[eax+48]
    654          addps      xmm7,xmm1
    655         mulps      xmm0,[ecx+48]
    656          /*Stall*/
    657         movaps     xmm1,[eax+64]
    658          addps      xmm7,xmm2
    659         mulps      xmm1,[ecx+64]
    660          /*Stall*/
    661         /*Standard iteration************************************/
    662         movaps     xmm2,[eax+80]
    663          addps      xmm7,xmm0
    664         mulps      xmm2,[ecx+80]
    665          /*Stall*/
    666         movaps     xmm0,[eax+96]
    667          addps      xmm7,xmm1
    668         mulps      xmm0,[ecx+96]
    669          /*Stall*/
    670         movaps     xmm1,[eax+112]
    671          addps      xmm7,xmm2
    672         mulps      xmm1,[ecx+112]
    673          /*Stall*/
    674         /*Standard iteration************************************/
    675         movaps     xmm2,[eax+128]
    676          addps      xmm7,xmm0
    677         mulps      xmm2,[ecx+128]
    678          /*Stall*/
    679         movaps     xmm0,[eax+144]
    680          addps      xmm7,xmm1
    681         mulps      xmm0,[ecx+144]
    682          /*Stall*/
    683         movaps     xmm1,[eax+160]
    684          addps      xmm7,xmm2
    685         mulps      xmm1,[ecx+160]
    686          /*Stall*/
    687         /*Standard iteration************************************/
    688         movaps     xmm2,[eax+176]
    689          addps      xmm7,xmm0
    690         mulps      xmm2,[ecx+176]
    691          /*Stall*/
    692         movaps     xmm0,[eax+192]
    693          addps      xmm7,xmm1
    694         mulps      xmm0,[ecx+192]
    695          /*Stall*/
    696         movaps     xmm1,[eax+208]
    697          addps      xmm7,xmm2
    698         mulps      xmm1,[ecx+208]
    699          /*Stall*/
    700         /*Standard iteration************************************/
    701         movaps     xmm2,[eax+224]
    702          addps      xmm7,xmm0
    703         mulps      xmm2,[ecx+224]
    704          /*Stall*/
    705         movaps     xmm0,[eax+240]
    706          addps      xmm7,xmm1
    707         mulps      xmm0,[ecx+240]
    708          /*Stall*/
    709         movaps     xmm1,[eax+256]
    710          addps      xmm7,xmm2
    711         mulps      xmm1,[ecx+256]
    712          /*Stall*/
    713         /*Standard iteration************************************/
    714         movaps     xmm2,[eax+272]
    715          addps      xmm7,xmm0
    716         mulps      xmm2,[ecx+272]
    717          /*Stall*/
    718         movaps     xmm0,[eax+288]
    719          addps      xmm7,xmm1
    720         mulps      xmm0,[ecx+288]
    721          /*Stall*/
    722         movaps     xmm1,[eax+304]
    723          addps      xmm7,xmm2
    724         mulps      xmm1,[ecx+304]
    725          /*Stall*/
    726         /*Standard iteration************************************/
    727         movaps     xmm2,[eax+320]
    728          addps      xmm7,xmm0
    729         mulps      xmm2,[ecx+320]
    730          /*Stall*/
    731         movaps     xmm0,[eax+336]
    732          addps      xmm7,xmm1
    733         mulps      xmm0,[ecx+336]
    734          /*Stall*/
    735         movaps     xmm1,[eax+352]
    736          addps      xmm7,xmm2
    737         mulps      xmm1,[ecx+352]
    738          /*Stall*/
    739         /*Standard iteration************************************/
    740         movaps     xmm2,[eax+368]
    741          addps      xmm7,xmm0
    742         mulps      xmm2,[ecx+368]
    743          /*Stall*/
    744         movaps     xmm0,[eax+384]
    745          addps      xmm7,xmm1
    746         mulps      xmm0,[ecx+384]
    747          /*Stall*/
    748         movaps     xmm1,[eax+400]
    749          addps      xmm7,xmm2
    750         mulps      xmm1,[ecx+400]
    751          /*Stall*/
    752         /*Standard iteration************************************/
    753         movaps     xmm2,[eax+416]
    754          addps      xmm7,xmm0
    755         mulps      xmm2,[ecx+416]
    756          /*Stall*/
    757         movaps     xmm0,[eax+432]
    758          addps      xmm7,xmm1
    759         mulps      xmm0,[ecx+432]
    760          /*Stall*/
    761         movaps     xmm1,[eax+448]
    762          addps      xmm7,xmm2
    763         mulps      xmm1,[ecx+448]
    764          /*Stall*/
    765         /*Standard iteration************************************/
    766         movaps     xmm2,[eax+464]
    767          addps      xmm7,xmm0
    768         mulps      xmm2,[ecx+464]
    769          /*Stall*/
    770         movaps     xmm0,[eax+480]
    771          addps      xmm7,xmm1
    772         mulps      xmm0,[ecx+480]
    773          /*Stall*/
    774         movaps     xmm1,[eax+496]
    775          addps      xmm7,xmm2
    776         mulps      xmm1,[ecx+496]
    777          /*Stall*/
    778         /*Rest iteration************************************/
    779         addps      xmm7,xmm0
    780          /*Stall*/
    781         addps      xmm7,xmm1
    782          /*Stall*/
    783         movaps xmm6,xmm7
    784          /*Stall*/
    785         shufps xmm6,xmm6,4Eh
    786          /*Stall*/
    787         addps  xmm7,xmm6
    788          /*Stall*/
    789         movaps xmm6,xmm7
    790          /*Stall*/
    791         shufps xmm6,xmm6,11h
    792          /*Stall*/
    793         addps  xmm7,xmm6
    794          /*Stall*/
    795         movss  back,xmm7
    796     }
    797 
    798     return(back);
    799 #endif /*DB_USE_SIMD*/
    800 }
    801 
    802 #endif /* DB_UTILITIES_LINALG */
    803