#define SSE
#include "SSE3Dnow.h"
#include "atlas_misc.h"

void ATL_USERMM
(const int M, const int N, const int K, const float alpha, const float *A, const int lda, const float *B, const int ldb, const float beta, float *C, const int ldc)

{
   /*--- achitecture specific declarations ---*/

   /*--- program specific declarations ---*/
   int i, j, k;
   vector betavec;
   vector zerovec = {0.0,0.0,0.0,0.0};
   const float *pA0 = A;
   const float *pB0 = B;
   float *pC0 = C;
   float *pC1 = C+(ldc)SHIFT;
   const float *stM = A + M*KB;
   const float *stN = B + NB*KB;
   const int incAm = 1*KB-KB+60;
   const int incBm = -KB+60;
   const int incCm = 1 SHIFT;
   const int incAn = -M*KB;
   const int incBn = 2*KB;
   const int incCn = (ldc*2-M)SHIFT;

   /*--- initial arhitecture specific statements ---*/
   vec_enter();

   /*--- main program statements ---*/
   vec_mov_mr_1(&beta,reg0);
   vec_mov_rm(reg0,&betavec);
   do /* N-loop */
   {
      do /* M-loop */
      {
#ifdef BETA0
         vec_mov_mr(zerovec,reg7);
         vec_mov_rr(reg7,reg0);
         vec_mov_rr(reg7,reg1);
#elif defined(BETA1)
         vec_mov_mr_1(pC0,reg0);
         vec_mov_mr_1(pC1,reg1);
#else
         vec_mov_mr(betavec,reg7);
         vec_mov_mr_1(pC0,reg0);
         vec_mul_rr(reg7,reg0);
         vec_mov_mr_1(pC1,reg1);
         vec_mul_rr(reg7,reg1);
#endif
         vec_mov_mr_a(pA0,reg6);
         vec_mov_mr_a(pB0,reg2);
         vec_mov_mr_a(pB0+KB,reg3);
         vec_mul_rr(reg6,reg2);
         vec_add_rr(reg2,reg0);
         vec_mov_mr_a(pB0+4,reg4);
         vec_mul_rr(reg6,reg3);
         vec_add_rr(reg3,reg1);
         vec_mov_mr_a(pA0+4,reg6);
         vec_mov_mr_a(pB0+4+KB,reg5);
         vec_mul_rr(reg6,reg4);
         vec_add_rr(reg4,reg0);
         vec_mov_mr_a(pB0+8,reg2);
         vec_mul_rr(reg6,reg5);
         vec_add_rr(reg5,reg1);
         vec_mov_mr_a(pA0+8,reg6);
         vec_mov_mr_a(pB0+8+KB,reg3);
         vec_mul_rr(reg6,reg2);
         vec_add_rr(reg2,reg0);
         vec_mov_mr_a(pB0+12,reg4);
         vec_mul_rr(reg6,reg3);
         vec_add_rr(reg3,reg1);
         vec_mov_mr_a(pA0+12,reg6);
         vec_mov_mr_a(pB0+12+KB,reg5);
         vec_mul_rr(reg6,reg4);
         vec_add_rr(reg4,reg0);
         vec_mov_mr_a(pB0+16,reg2);
         vec_mul_rr(reg6,reg5);
         vec_add_rr(reg5,reg1);
         vec_mov_mr_a(pA0+16,reg6);
         vec_mov_mr_a(pB0+16+KB,reg3);
         vec_mul_rr(reg6,reg2);
         vec_add_rr(reg2,reg0);
         vec_mov_mr_a(pB0+20,reg4);
         vec_mul_rr(reg6,reg3);
         vec_add_rr(reg3,reg1);
         vec_mov_mr_a(pA0+20,reg6);
         vec_mov_mr_a(pB0+20+KB,reg5);
         vec_mul_rr(reg6,reg4);
         vec_add_rr(reg4,reg0);
         vec_mov_mr_a(pB0+24,reg2);
         vec_mul_rr(reg6,reg5);
         vec_add_rr(reg5,reg1);
         vec_mov_mr_a(pA0+24,reg6);
         vec_mov_mr_a(pB0+24+KB,reg3);
         vec_mul_rr(reg6,reg2);
         vec_add_rr(reg2,reg0);
         vec_mov_mr_a(pB0+28,reg4);
         vec_mul_rr(reg6,reg3);
         vec_add_rr(reg3,reg1);
         vec_mov_mr_a(pA0+28,reg6);
         vec_mov_mr_a(pB0+28+KB,reg5);
         vec_mul_rr(reg6,reg4);
         vec_add_rr(reg4,reg0);
         vec_mov_mr_a(pB0+32,reg2);
         vec_mul_rr(reg6,reg5);
         vec_add_rr(reg5,reg1);
         vec_mov_mr_a(pA0+32,reg6);
         vec_mov_mr_a(pB0+32+KB,reg3);
         vec_mul_rr(reg6,reg2);
         vec_add_rr(reg2,reg0);
         vec_mov_mr_a(pB0+36,reg4);
         vec_mul_rr(reg6,reg3);
         vec_add_rr(reg3,reg1);
         vec_mov_mr_a(pA0+36,reg6);
         vec_mov_mr_a(pB0+36+KB,reg5);
         vec_mul_rr(reg6,reg4);
         vec_add_rr(reg4,reg0);
         vec_mov_mr_a(pB0+40,reg2);
         vec_mul_rr(reg6,reg5);
         vec_add_rr(reg5,reg1);
         vec_mov_mr_a(pA0+40,reg6);
         vec_mov_mr_a(pB0+40+KB,reg3);
         vec_mul_rr(reg6,reg2);
         vec_add_rr(reg2,reg0);
         vec_mov_mr_a(pB0+44,reg4);
         vec_mul_rr(reg6,reg3);
         vec_add_rr(reg3,reg1);
         vec_mov_mr_a(pA0+44,reg6);
         vec_mov_mr_a(pB0+44+KB,reg5);
         vec_mul_rr(reg6,reg4);
         vec_add_rr(reg4,reg0);
         vec_mov_mr_a(pB0+48,reg2);
         vec_mul_rr(reg6,reg5);
         vec_add_rr(reg5,reg1);
         vec_mov_mr_a(pA0+48,reg6);
         vec_mov_mr_a(pB0+48+KB,reg3);
         vec_mul_rr(reg6,reg2);
         vec_add_rr(reg2,reg0);
         vec_mov_mr_a(pB0+52,reg4);
         vec_mul_rr(reg6,reg3);
         vec_add_rr(reg3,reg1);
         vec_mov_mr_a(pA0+52,reg6);
         vec_mov_mr_a(pB0+52+KB,reg5);
         vec_mul_rr(reg6,reg4);
         vec_add_rr(reg4,reg0);
         vec_mov_mr_a(pB0+56,reg2);
         vec_mul_rr(reg6,reg5);
         vec_add_rr(reg5,reg1);
         vec_mov_mr_a(pA0+56,reg6);
         vec_mov_mr_a(pB0+56+KB,reg3);
         vec_mul_rr(reg6,reg2);
         vec_add_rr(reg2,reg0);
         vec_mul_rr(reg6,reg3);
         vec_add_rr(reg3,reg1);
         vec_sum(reg0);
         vec_sum(reg1);
         vec_mov_rm_1(reg0,pC0);
         vec_mov_rm_1(reg1,pC1);
         pA0 += incAm;
         pB0 += incBm;
         pC0 += incCm;
         pC1 += incCm;
      }
      while(pA0 != stM);

      pA0 += incAn;
      pB0 += incBn;
      pC0 += incCn;
      pC1 += incCn;
   }
   while(pB0 != stN);

   vec_exit();
}
