~ubuntu-branches/ubuntu/saucy/nwchem/saucy

« back to all changes in this revision

Viewing changes to src/tools/ga-5-1/armci/src/common/x86copy.c

  • Committer: Package Import Robot
  • Author(s): Michael Banck, Michael Banck, Daniel Leidert
  • Date: 2012-02-09 20:02:41 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20120209200241-jgk03qfsphal4ug2
Tags: 6.1-1
* New upstream release.

[ Michael Banck ]
* debian/patches/02_makefile_flags.patch: Updated.
* debian/patches/02_makefile_flags.patch: Use internal blas and lapack code.
* debian/patches/02_makefile_flags.patch: Define GCC4 for LINUX and LINUX64
  (Closes: #632611 and LP: #791308).
* debian/control (Build-Depends): Added openssh-client.
* debian/rules (USE_SCALAPACK, SCALAPACK): Removed variables (Closes:
  #654658).
* debian/rules (LIBDIR, USE_MPIF4, ARMCI_NETWORK): New variables.
* debian/TODO: New file.
* debian/control (Build-Depends): Removed libblas-dev, liblapack-dev and
  libscalapack-mpi-dev.
* debian/patches/04_show_testsuite_diff_output.patch: New patch, shows the
  diff output for failed tests.
* debian/patches/series: Adjusted.
* debian/testsuite: Optionally run all tests if "all" is passed as option.
* debian/rules: Run debian/testsuite with "all" if DEB_BUILD_OPTIONS
  contains "checkall".

[ Daniel Leidert ]
* debian/control: Used wrap-and-sort. Added Vcs-Svn and Vcs-Browser fields.
  (Priority): Moved to extra according to policy section 2.5.
  (Standards-Version): Bumped to 3.9.2.
  (Description): Fixed a typo.
* debian/watch: Added.
* debian/patches/03_hurd-i386_define_path_max.patch: Added.
  - Define MAX_PATH if not defines to fix FTBFS on hurd.
* debian/patches/series: Adjusted.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// $Id: x86copy.gcc,v 1.14 2003-02-06 18:49:36 manoj Exp $
 
2
// memory copy implementation derived from examples 3 and 4 at
 
3
// http://www.sgi.com/developers/library/resources/asc_cpu.html
 
4
//
 
5
// void *armci_asm_memcpy(void *dst, const void *src, size_t n, int id);
 
6
// id={0/1} - is used to support up to 2 threads
 
7
//
 
8
// we turn the assembly memcpy on/off based on checking of the CPU type
 
9
//
 
10
 
 
11
#include <stdio.h>
 
12
#include <string.h>
 
13
 
 
14
 
 
15
// EAX
 
16
#define CPUFAMILY  0x00000F00
 
17
#define MODEL      0x000000F0
 
18
// EDX
 
19
#define MMXSUPPORT 0x00800000
 
20
#define SSESUPPORT 0x02000000
 
21
#define IA64       0x70000000
 
22
static  char vendor[13];
 
23
typedef enum {unkown=0,p5, p2, p2m, p3, p4, pro, p6, K5, K6, K7, ia64} CPUTYPE;
 
24
 
 
25
 
 
26
#define EX4  // use sgi's example_4_cpy if n is greater than 2k
 
27
             // use memcpy and example_3_memcpy for the rest 
 
28
//#define  EX3  // use memcpy and example_3_memcpy
 
29
 
 
30
static char tbuf0[2048];
 
31
static char tbuf1[2048];
 
32
static char *ptbuf;
 
33
static int use_asm_copy=-1;
 
34
 
 
35
//
 
36
void *asm_memcpy3(void *dst, const void *src, size_t n)
 
37
{
 
38
 
 
39
        asm __volatile__ ("\
 
40
              pushl %%ebx;\
 
41
              shr $6, %2;\
 
42
        loopl:\
 
43
              prefetchnta 64(%0);\
 
44
              prefetchnta 96(%0);\
 
45
              movq 0(%0), %%mm1;\
 
46
              movq 8(%0), %%mm2;\
 
47
              movq 16(%0), %%mm3;\
 
48
              movq 24(%0), %%mm4;\
 
49
              movq 32(%0), %%mm5;\
 
50
              movq 40(%0), %%mm6;\
 
51
              movq 48(%0), %%mm7;\
 
52
              movq 56(%0), %%mm0;\
 
53
              movntq %%mm1, 0(%1);\
 
54
              movntq %%mm2, 8(%1);\
 
55
              movntq %%mm3, 16(%1);\
 
56
              movntq %%mm4, 24(%1);\
 
57
              movntq %%mm5, 32(%1);\
 
58
              movntq %%mm6, 40(%1);\
 
59
              movntq %%mm7, 48(%1);\
 
60
              movntq %%mm0, 56(%1);\
 
61
              add $64, %0;\
 
62
              add $64, %1;\
 
63
              dec %2;\
 
64
              jnz loopl;\
 
65
              emms;\
 
66
              popl %%ebx;"
 
67
              : 
 
68
              : "r"(src), "r"(dst), "c"(n)
 
69
              : "%eax"
 
70
              );
 
71
 
 
72
        return dst;
 
73
}
 
74
 
 
75
 
 
76
void *asm_memcpy4(void *dst, const void *src, size_t n, int bufid)
 
77
{
 
78
        
 
79
        int dum;
 
80
 
 
81
        if(bufid == 0) 
 
82
                ptbuf = tbuf0;
 
83
        else    
 
84
                ptbuf = tbuf1;      
 
85
 
 
86
        asm __volatile__ ("\
 
87
                shr $11, %0;\
 
88
\
 
89
        loop2k:\
 
90
                movl $2048, %%ecx;\
 
91
                shr $6, %%ecx;\
 
92
\
 
93
        loopMemToL1: \
 
94
                prefetchnta 64(%%esi); \
 
95
                prefetchnta 96(%%esi); \
 
96
\
 
97
                movq 0(%%esi), %%mm1; \
 
98
                movq 8(%%esi), %%mm2; \
 
99
                movq 16(%%esi), %%mm3; \
 
100
                movq 24(%%esi), %%mm4; \
 
101
                movq 32(%%esi), %%mm5; \
 
102
                movq 40(%%esi), %%mm6; \
 
103
                movq 48(%%esi), %%mm7; \
 
104
                movq 56(%%esi), %%mm0; \
 
105
\
 
106
                movq  %%mm1, 0(%4); \
 
107
                movq  %%mm2, 8(%4); \
 
108
                movq  %%mm3, 16(%4); \
 
109
                movq  %%mm4, 24(%4); \
 
110
                movq  %%mm5, 32(%4); \
 
111
                movq  %%mm6, 40(%4); \
 
112
                movq  %%mm7, 48(%4); \
 
113
                movq  %%mm0, 56(%4); \
 
114
\
 
115
                add $64, %%esi;\
 
116
                add $64, %4;\
 
117
                dec %%ecx ;\
 
118
                jnz loopMemToL1 ;\
 
119
\
 
120
                subl $2048, %4;\
 
121
                movl $2048, %%ecx;\
 
122
                shr $6, %%ecx;\
 
123
\
 
124
        loopL1ToMem: \
 
125
\
 
126
                movq 0(%4), %%mm1; \
 
127
                movq 8(%4), %%mm2; \
 
128
                movq 16(%4), %%mm3; \
 
129
                movq 24(%4), %%mm4;\
 
130
                movq 32(%4), %%mm5; \
 
131
                movq 40(%4), %%mm6; \
 
132
                movq 48(%4), %%mm7; \
 
133
                movq 56(%4), %%mm0; \
 
134
\
 
135
                movntq %%mm1, 0(%%edi); \
 
136
                movntq %%mm2, 8(%%edi); \
 
137
                movntq %%mm3, 16(%%edi); \
 
138
                movntq %%mm4, 24(%%edi); \
 
139
                movntq %%mm5, 32(%%edi); \
 
140
                movntq %%mm6, 40(%%edi); \
 
141
                movntq %%mm7, 48(%%edi); \
 
142
                movntq %%mm0, 56(%%edi); \
 
143
\
 
144
                add $64, %4;\
 
145
                add $64, %%edi;\
 
146
                dec %%ecx;\
 
147
                jnz loopL1ToMem ;\
 
148
\
 
149
                subl $2048, %4;\
 
150
                dec %0;\
 
151
                jnz loop2k; \
 
152
                emms;"
 
153
                : "=r"(dum)
 
154
                : "S"(src), "D"(dst), "0"(n), "r"(ptbuf)
 
155
                : "%ecx", "memory"
 
156
                 );
 
157
 
 
158
        return dst;
 
159
}
 
160
 
 
161
CPUTYPE cpu_check()
 
162
{
 
163
 
 
164
    int family;
 
165
    int model;
 
166
    int mmxsupport;
 
167
    int ssesupport;
 
168
    int isIA64;
 
169
    unsigned int reax;
 
170
    unsigned int redx;
 
171
 
 
172
    asm __volatile__ ("\
 
173
         movl %%ebx, %%edi;\
 
174
         movl $1, %%eax;\
 
175
         cpuid;\
 
176
         movl %%eax, %0;\
 
177
         movl %%edi, %%ebx;"\
 
178
        :"=r"(reax)
 
179
        :"0"(reax)
 
180
        :"%eax", "%edi"
 
181
        );
 
182
 
 
183
   asm __volatile__ ("\
 
184
         movl %%ebx, %%edi;\
 
185
         movl $1, %%eax;\
 
186
         cpuid;\
 
187
         movl %%edx, %0;\
 
188
         movl %%edi, %%ebx;"\
 
189
        :"=r"(redx)
 
190
        :"0"(redx)
 
191
        :"%eax", "%edx", "%edi"
 
192
      );
 
193
 
 
194
    asm __volatile__ (
 
195
         "movl $vendor, %%esi;"
 
196
         "movl %%ebx, %%edi;"
 
197
         "movl $0, %%eax;"
 
198
         "cpuid;"
 
199
         "movl %%ebx, 0(%%esi);"
 
200
         "movl %%edx, 4(%%esi);"
 
201
         "movl %%ecx, 8(%%esi);"
 
202
         "movl %%edi, %%ebx"
 
203
        :
 
204
        :
 
205
         : "%ecx", "%edx", "%esi", "%edi"
 
206
        );
 
207
 
 
208
#ifdef DEBUG
 
209
    printf("eax=%x\n", reax);
 
210
    printf("edx=%x\n", redx);
 
211
    printf("vendor = %s\n", vendor);
 
212
#endif
 
213
 
 
214
    family = (CPUFAMILY & reax) >> 8;
 
215
    model  = (MODEL     & reax) >> 4;
 
216
 
 
217
    mmxsupport = (redx & MMXSUPPORT);
 
218
    ssesupport = (redx & SSESUPPORT);
 
219
    isIA64     = (redx & IA64);
 
220
 
 
221
#ifdef DEBUG
 
222
    printf("mmx support = %s\n", mmxsupport ? "yes" : "no");
 
223
    printf("SSE support = %s\n", ssesupport ? "yes" : "no");
 
224
#endif
 
225
 
 
226
    if(strcmp(vendor, "GenuineIntel") == 0){
 
227
 
 
228
//        if(isIA64)
 
229
//            return ia64;
 
230
 
 
231
        switch(family){
 
232
        case 5: // P5
 
233
            return p5;
 
234
            break;
 
235
        case 6: // pro,P2,P3
 
236
            if(model == 1) return pro;
 
237
            else if(model == 3 || model == 5) return p2;
 
238
            else if(model == 6 ) return p2m; //pentium II mobile/celeron
 
239
            else if( model==7 || model == 8 ) //celeron/p3
 
240
                return p3;
 
241
            else
 
242
                return unkown;
 
243
            break;
 
244
        case 0xf: // extended family
 
245
            if((reax & 0x0ff00000) == 0 && model == 0) return p4;
 
246
            break;
 
247
        }
 
248
    }
 
249
    else if(strcmp(vendor, "AuthenticAMD") == 0){
 
250
        if(family == 5){
 
251
            if(model < 4)
 
252
                return K5;
 
253
            else
 
254
                return K6;
 
255
        }
 
256
 
 
257
        else if(family == 6){
 
258
            return K7;
 
259
        }
 
260
        else
 
261
            return unkown;
 
262
    }
 
263
    else {
 
264
        if(family == 5)
 
265
            return p5;
 
266
        else if(family == 6)
 
267
            return p6;
 
268
    }
 
269
 
 
270
    return unkown;
 
271
}
 
272
 
 
273
 
 
274
static inline int asmcpy_works()
 
275
{
 
276
        CPUTYPE type = cpu_check();
 
277
 
 
278
        if( type == p3 || type == K7 || type == p4)
 
279
                return 1;
 
280
        else
 
281
                return 0;
 
282
}
 
283
 
 
284
#include "tas-i386.h"
 
285
int _x86copy_mutex=0;
 
286
 
 
287
//
 
288
// n <128     memcpy
 
289
// 128>n<2048 MMX copy       
 
290
// n >2047    MMX copy with buffer
 
291
//
 
292
void *armci_asm_memcpy_nofence(void *dst, const void *src, size_t n, int bufid)
 
293
{
 
294
 
 
295
    int locked=0;
 
296
    int residual;
 
297
    if(use_asm_copy<0) use_asm_copy = asmcpy_works();
 
298
    if(!use_asm_copy || (n<128) ) return memcpy(dst, src, n);
 
299
     
 
300
 
 
301
  /* memcpy4 has problems in multithreaded environment -- we allow only
 
302
   * one thread to use it
 
303
   */
 
304
  if(n>=2048)locked = testandset((int*)&_x86copy_mutex);
 
305
 
 
306
  if(locked){
 
307
    residual = (int)n % 64;
 
308
    if(residual != 0) memcpy(dst, src, residual);
 
309
    if(n>=64)
 
310
       asm_memcpy3((char*)dst+residual, (char*)src+residual, n - residual);
 
311
  }else {
 
312
 
 
313
    residual = (int)n % 2048;
 
314
 
 
315
    if(residual != 0){
 
316
       int res64 = residual%64;
 
317
       if(res64 != 0) memcpy(dst, src, res64);
 
318
       if(residual >= 64)
 
319
          asm_memcpy3((char*)dst+res64, (char*)src+res64, residual - res64);
 
320
    }
 
321
 
 
322
    if(n>=2048){
 
323
        asm_memcpy4((char*)dst + residual, (char*)src + residual, 
 
324
                    n - residual, bufid);
 
325
        _x86copy_mutex = 0;
 
326
    }
 
327
  }
 
328
 
 
329
    return dst;
 
330
}
 
331
 
 
332
 
 
333
 
 
334
void *armci_asm_memcpy(void *dst, const void *src, size_t n, int bufid)
 
335
{
 
336
void *p;
 
337
    if(use_asm_copy<0) use_asm_copy = asmcpy_works();
 
338
    if(!use_asm_copy ||n<128) return memcpy(dst, src, n);
 
339
     p = armci_asm_memcpy_nofence(dst,src,n,bufid);
 
340
     __asm__ __volatile__ ("sfence":::"memory");
 
341
     return p;
 
342
}
 
343
 
 
344
 
 
345
void armci_asm_mem_fence()
 
346
{
 
347
 __asm__ __volatile__ ("sfence":::"memory");
 
348
}