00001 #include <string.h>
00002 #include "cmimemcpy_qpx.h"
00003 
00004 #define QPX_LOAD(si,sb,fp) \
00005   do {                                  \
00006   asm volatile("qvlfdx %0,%1,%2": "=f"(fp) : "b" (si), "r" (sb));   \
00007   } while(0);
00008 
00009 #define QPX_STORE(si,sb,fp)                     \
00010   do {                                  \
00011   asm volatile("qvstfdx %2,%0,%1": : "b" (si), "r" (sb), "f"(fp) :"memory"); \
00012   } while(0);
00013 
00014 #ifndef __GNUC__
00015 #define FP_REG(i)   asm("f"#i)
00016 #define FP_REG1(i)  "fr"#i
00017 #else
00018 #define FP_REG(i)  asm("fr"#i)
00019 #define FP_REG1(i)  "fr"#i
00020 #endif
00021 
00022 
00023 static inline size_t quad_copy_512( char* dest, const char* src ) {
00024     register const double *fpp1_1, *fpp1_2;
00025     register double *fpp2_1, *fpp2_2;
00026 
00027     register double f0 FP_REG(0);
00028     register double f1 FP_REG(1);
00029     register double f2 FP_REG(2);
00030     register double f3 FP_REG(3);
00031     register double f4 FP_REG(4);
00032     register double f5 FP_REG(5);
00033     register double f6 FP_REG(6);
00034     register double f7 FP_REG(7);
00035 
00036     int r0;
00037     int r1;
00038     int r2;
00039     int r3;
00040     int r4;
00041     int r5;
00042     int r6;
00043     int r7;
00044     r0 = 0;
00045     r1 = 64;
00046     r2 = 128;
00047     r3 = 192;
00048     r4 = 256;
00049     r5 = 320;
00050     r6 = 384;
00051     r7 = 448;
00052 
00053     fpp1_1 = (const double *)src;
00054     fpp1_2 = (const double *)src +4;
00055 
00056     fpp2_1 = (double *)dest;
00057     fpp2_2 = (double *)dest +4;
00058 
00059     QPX_LOAD(fpp1_1,r0,f0);
00060     
00061     QPX_LOAD(fpp1_1,r1,f1);
00062     QPX_LOAD(fpp1_1,r2,f2);
00063     QPX_LOAD(fpp1_1,r3,f3);
00064     QPX_LOAD(fpp1_1,r4,f4);
00065     QPX_LOAD(fpp1_1,r5,f5);
00066     QPX_LOAD(fpp1_1,r6,f6);
00067     QPX_LOAD(fpp1_1,r7,f7);
00068 
00069     QPX_STORE(fpp2_1,r0,f0);
00070     QPX_LOAD(fpp1_2,r0,f0);
00071     QPX_STORE(fpp2_1,r1,f1);
00072     QPX_LOAD(fpp1_2,r1,f1);
00073     QPX_STORE(fpp2_1,r2,f2);
00074     QPX_LOAD(fpp1_2,r2,f2);
00075     QPX_STORE(fpp2_1,r3,f3);
00076     QPX_LOAD(fpp1_2,r3,f3);
00077     QPX_STORE(fpp2_1,r4,f4);
00078     QPX_LOAD(fpp1_2,r4,f4);
00079     QPX_STORE(fpp2_1,r5,f5);
00080     QPX_LOAD(fpp1_2,r5,f5);
00081     QPX_STORE(fpp2_1,r6,f6);
00082     QPX_LOAD(fpp1_2,r6,f6);
00083     QPX_STORE(fpp2_1,r7,f7);
00084     QPX_LOAD(fpp1_2,r7,f7);
00085  
00086     QPX_STORE(fpp2_2,r0,f0);
00087     QPX_STORE(fpp2_2,r1,f1);
00088     QPX_STORE(fpp2_2,r2,f2);
00089     QPX_STORE(fpp2_2,r3,f3);
00090     QPX_STORE(fpp2_2,r4,f4);
00091     QPX_STORE(fpp2_2,r5,f5);
00092     QPX_STORE(fpp2_2,r6,f6);
00093     QPX_STORE(fpp2_2,r7,f7);
00094 
00095     return 0;
00096 }
00097 
00098 void CmiMemcpy_qpx (void *dst, const void *src, size_t n)
00099 {
00100   const char *s = src;
00101   char *d = dst;
00102   int n512 = n >> 9;
00103   while (n512 --) {
00104     quad_copy_512(d, s);
00105     d += 512;
00106     s += 512;
00107   }
00108  
00109   if ( (n & 511UL) != 0 )
00110     memcpy (d, s, n & 511UL);
00111 }