Optimize cdot function for POWER10
[platform/upstream/openblas.git] / common_ia64.h
1 /*********************************************************************/
2 /* Copyright 2009, 2010 The University of Texas at Austin.           */
3 /* All rights reserved.                                              */
4 /*                                                                   */
5 /* Redistribution and use in source and binary forms, with or        */
6 /* without modification, are permitted provided that the following   */
7 /* conditions are met:                                               */
8 /*                                                                   */
9 /*   1. Redistributions of source code must retain the above         */
10 /*      copyright notice, this list of conditions and the following  */
11 /*      disclaimer.                                                  */
12 /*                                                                   */
13 /*   2. Redistributions in binary form must reproduce the above      */
14 /*      copyright notice, this list of conditions and the following  */
15 /*      disclaimer in the documentation and/or other materials       */
16 /*      provided with the distribution.                              */
17 /*                                                                   */
18 /*    THIS  SOFTWARE IS PROVIDED  BY THE  UNIVERSITY OF  TEXAS AT    */
19 /*    AUSTIN  ``AS IS''  AND ANY  EXPRESS OR  IMPLIED WARRANTIES,    */
20 /*    INCLUDING, BUT  NOT LIMITED  TO, THE IMPLIED  WARRANTIES OF    */
21 /*    MERCHANTABILITY  AND FITNESS FOR  A PARTICULAR  PURPOSE ARE    */
22 /*    DISCLAIMED.  IN  NO EVENT SHALL THE UNIVERSITY  OF TEXAS AT    */
23 /*    AUSTIN OR CONTRIBUTORS BE  LIABLE FOR ANY DIRECT, INDIRECT,    */
24 /*    INCIDENTAL,  SPECIAL, EXEMPLARY,  OR  CONSEQUENTIAL DAMAGES    */
25 /*    (INCLUDING, BUT  NOT LIMITED TO,  PROCUREMENT OF SUBSTITUTE    */
26 /*    GOODS  OR  SERVICES; LOSS  OF  USE,  DATA,  OR PROFITS;  OR    */
27 /*    BUSINESS INTERRUPTION) HOWEVER CAUSED  AND ON ANY THEORY OF    */
28 /*    LIABILITY, WHETHER  IN CONTRACT, STRICT  LIABILITY, OR TORT    */
29 /*    (INCLUDING NEGLIGENCE OR OTHERWISE)  ARISING IN ANY WAY OUT    */
30 /*    OF  THE  USE OF  THIS  SOFTWARE,  EVEN  IF ADVISED  OF  THE    */
31 /*    POSSIBILITY OF SUCH DAMAGE.                                    */
32 /*                                                                   */
33 /* The views and conclusions contained in the software and           */
34 /* documentation are those of the authors and should not be          */
35 /* interpreted as representing official policies, either expressed   */
36 /* or implied, of The University of Texas at Austin.                 */
37 /*********************************************************************/
38
39 #ifndef COMMON_IA64
40 #define COMMON_IA64
41
42 #ifndef ASSEMBLER
43
44 #ifndef MAP_WRITECOMBINED
45 #define MAP_WRITECOMBINED 0x10000
46 #endif
47
48 #define MB
49 #define WMB
50 #define RMB
51
52 #ifdef __ECC
53 #include <ia64intrin.h>
54 #endif
55
56 #define RPCC64BIT
57
58 #ifndef __ECC
59 static __inline void blas_lock(volatile unsigned long *address){
60
61   unsigned long ret;
62
63   do {
64     while (*address) {YIELDING;};
65
66     __asm__ __volatile__ ("mov ar.ccv=r0\n;;\n"
67                           "cmpxchg4.acq %0=[%2],%1,ar.ccv\n"
68                           : "=r"(ret) : "r"(1), "r"(address)
69                           : "ar.ccv", "memory");
70   } while (ret);
71 }
72 #define BLAS_LOCK_DEFINED
73
74 static __inline unsigned long rpcc(void) {
75   unsigned long clocks;
76
77   __asm__ __volatile__ ("mov %0=ar.itc" : "=r"(clocks));
78   return clocks;
79 }
80 #define RPCC_DEFINED
81
82
83 static __inline unsigned long stmxcsr(void){
84   unsigned long fp;
85
86    __asm__ __volatile__ ("mov.m %0=ar.fpsr" : "=r" (fp));
87
88    return fp;
89 }
90
91 static __inline void ldmxcsr(unsigned long fp) {
92
93    __asm__ __volatile__ ("mov.m ar.fpsr=%0" :: "r" (fp));
94
95 }
96
97 #define GET_IMAGE(res) asm __volatile__("mov %0 = f9" : "=f"(res)  : : "memory")
98
99 #else
100
101 static __inline void blas_lock(volatile unsigned long *address){
102   while (*address || _InterlockedCompareExchange((volatile int *) address,1,0))
103     ;
104 }
105 #define BLAS_LOCK_DEFINED
106
107 static __inline unsigned int rpcc(void) {
108   return __getReg(_IA64_REG_AR_ITC);
109 }
110 #define RPCC_DEFINED
111
112 static __inline unsigned int stmxcsr(void) {
113   return __getReg(_IA64_REG_AR_FPSR);
114 }
115
116 static __inline void ldmxcsr(unsigned long fp) {
117
118   return __setReg(_IA64_REG_AR_FPSR, fp);
119
120 }
121
122 #ifdef DOUBLE
123 #define GET_IMAGE(res) __stfd(&res, 9)
124 #else
125 #define GET_IMAGE(res) __stfs(&res, 9)
126 #endif
127
128 #endif
129
130 #define GET_IMAGE_CANCEL
131
132 #ifdef ENABLE_SSE_EXCEPTION
133
134 #define IDEBUG_START \
135   { \
136     unsigned long fp_sse_mode, new_fp_mode; \
137         fp_sse_mode = stmxcsr();\
138         new_fp_mode = (fp_sse_mode & ~(FE_UNDERFLOW | FE_OVERFLOW | FE_UNNORMAL | FE_INVALID));\
139         ldmxcsr(new_fp_mode);
140
141 #define IDEBUG_END \
142         ldmxcsr(fp_sse_mode); \
143         }
144
145 #endif
146
147 #ifdef SMP
148
149 #ifdef USE64BITINT
150
151 /* 64bit version */
152
153 extern unsigned long blas_quick_divide_table[];
154
155 #ifndef __ECC
156 static __inline long blas_quickdivide(unsigned long int x, unsigned long int y){
157   unsigned long ret;
158
159   if (y <= 1) return x;
160
161   __asm__ __volatile__("setf.sig f6 = %1\n\t"
162                "ldf8     f7 = [%2];;\n\t"
163                "xmpy.hu f6= f6, f7;;\n\t"
164                "getf.sig %0 = f6;;\n"
165                : "=r"(ret)
166                : "r"(x), "r"(&blas_quick_divide_table[y]) : "f6", "f7"
167                );
168
169   return ret;
170 }
171 #else
172 /* Using Intel Compiler */
173 static __inline long blas_quickdivide(unsigned long int x, unsigned long int y){
174   if (y <= 1) return x;
175   return _m64_xmahu(x, blas_quick_divide_table[y], 0);
176 }
177 #endif
178
179 #else
180  /* 32bit version */
181 extern unsigned int  blas_quick_divide_table[];
182
183 static __inline int blas_quickdivide(unsigned int x, unsigned int y){
184   if (y <= 1) return x;
185   return (int)((x * (unsigned long)blas_quick_divide_table[y]) >> 32);
186 }
187 #endif
188 #endif
189
190 #endif
191
192 #if 0
193 #ifdef DOUBLE
194 #define   GEMM_NCOPY    dgemm_ncopy
195 #define   GEMM_TCOPY    dgemm_tcopy
196 #define  ZGEMM_NCOPY    zgemm_ncopy
197 #define  ZGEMM_TCOPY    zgemm_tcopy
198 #define   GEMM_KERNEL   dgemm_kernel
199
200 #if defined(NN) || defined(NT) || defined(TN) || defined(TT)
201 #define ZGEMM_KERNEL zgemm_kernel_n
202 #endif
203 #if defined(CN) || defined(CT) || defined(RN) || defined(RT)
204 #define ZGEMM_KERNEL zgemm_kernel_l
205 #endif
206 #if defined(NC) || defined(TC) || defined(NR) || defined(TR)
207 #define ZGEMM_KERNEL zgemm_kernel_r
208 #endif
209 #if defined(CC) || defined(CR) || defined(RC) || defined(RR)
210 #define ZGEMM_KERNEL zgemm_kernel_b
211 #endif
212
213 #else
214 #define   GEMM_NCOPY    sgemm_ncopy
215 #define   GEMM_TCOPY    sgemm_tcopy
216 #define  ZGEMM_NCOPY    cgemm_ncopy
217 #define  ZGEMM_TCOPY    cgemm_tcopy
218 #define   GEMM_KERNEL   sgemm_kernel
219
220 #if defined(NN) || defined(NT) || defined(TN) || defined(TT)
221 #define ZGEMM_KERNEL cgemm_kernel_n
222 #endif
223 #if defined(CN) || defined(CT) || defined(RN) || defined(RT)
224 #define ZGEMM_KERNEL cgemm_kernel_l
225 #endif
226 #if defined(NC) || defined(TC) || defined(NR) || defined(TR)
227 #define ZGEMM_KERNEL cgemm_kernel_r
228 #endif
229 #if defined(CC) || defined(CR) || defined(RC) || defined(RR)
230 #define ZGEMM_KERNEL cgemm_kernel_b
231 #endif
232
233 #endif
234 #endif
235
236 #ifdef USE64BITINT
237 #define LDINT           ld8
238 #define INTSIZE         8
239 #define CMP4GE          cmp.ge
240 #define CMP4NE          cmp.ge
241 #define CMP4EQ          cmp.eq
242 #else
243 #define LDINT           ld4
244 #define INTSIZE         4
245 #define CMP4GE          cmp4.ge
246 #define CMP4NE          cmp4.ne
247 #define CMP4EQ          cmp4.eq
248 #endif
249
250 #define HALT            mov r0 = 0
251
252 #ifdef XDOUBLE
253 #define LD8             ld8
254 #define ST8             st8
255 #define LDFD            ldfe
256 #define LDFPD           ldfpe
257 #define LDFD_T1         ldfe.t1
258 #define LDFD_NT1        ldfe.nt1
259 #define LDFD_NT2        ldfe.nt2
260 #define LDFD_NTA        ldfe.nta
261 #define LDFPD_NT1       ldfpe.nt1
262 #define LDFPD_NT2       ldfpe.nt2
263 #define LDFPD_NTA       ldfpe.nta
264 #define STFD            stfe
265 #define STFD_NTA        stfe.nta
266 #define FADD            fadd
267 #define FSUB            fsub
268 #define FMPY            fmpy
269 #define FMA             fma
270 #define FMS             fms
271 #define FNMA            fnma
272 #define FPMA            fpma
273 #define SETF            setf.d
274 #elif defined(DOUBLE)
275 #define LD8             ld8
276 #define ST8             st8
277 #define LDF8            ldf8
278 #define LDF8_NT1        ldf8.nt1
279 #define LDF8_NTA        ldf8.nta
280 #define STF8            stf8
281 #define STF8_NTA        stf8.nta
282 #define LDFD            ldfd
283 #define LDFPD           ldfpd
284 #define LDFD_T1         ldfd.t1
285 #define LDFD_NT1        ldfd.nt1
286 #define LDFD_NT2        ldfd.nt2
287 #define LDFD_NTA        ldfd.nta
288 #define LDFPD_NT1       ldfpd.nt1
289 #define LDFPD_NT2       ldfpd.nt2
290 #define LDFPD_NTA       ldfpd.nta
291 #define STFD            stfd
292 #define STFD_NTA        stfd.nta
293 #define FADD            fadd.d
294 #define FSUB            fsub.d
295 #define FMPY            fmpy.d
296 #define FMA             fma.d
297 #define FMS             fms.d
298 #define FNMA            fnma.d
299 #define FPMA            fpma.d
300 #define SETF            setf.d
301 #else
302 #define LD8             ld4
303 #define ST8             st4
304 #define LDF8            ldfs
305 #define LDF8_NT1        ldfs.nt1
306 #define LDF8_NTA        ldfs.nta
307 #define STF8            stfs
308 #define STF8_NTA        stfs.nta
309 #define LDFD            ldfs
310 #define LDFPD           ldfps
311 #define LDFD_T1         ldfs.t1
312 #define LDFD_NT1        ldfs.nt1
313 #define LDFD_NT2        ldfs.nt2
314 #define LDFD_NTA        ldfs.nta
315 #define LDFPD_NT1       ldfps.nt1
316 #define LDFPD_NT2       ldfps.nt2
317 #define LDFPD_NTA       ldfps.nta
318 #define STFD            stfs
319 #define STFD_NTA        stfs.nta
320 #if 0
321 #define FADD            fadd.s
322 #define FSUB            fsub.s
323 #define FMPY            fmpy.s
324 #define FMA             fma.s
325 #define FMS             fms.s
326 #define FNMA            fnma.s
327 #define FPMA            fpma.s
328 #else
329 #define FADD            fadd
330 #define FSUB            fsub
331 #define FMPY            fmpy
332 #define FMA             fma
333 #define FMS             fms
334 #define FNMA            fnma
335 #define FPMA            fpma
336 #endif
337 #define SETF            setf.s
338 #endif
339
340 #ifndef F_INTERFACE
341 #define REALNAME ASMNAME
342 #else
343 #define REALNAME ASMFNAME
344 #endif
345
346 #ifdef F_INTERFACE_G77
347 #define RETURN_BY_STACK
348 #endif
349
350 #ifdef F_INTERFACE_G95
351 #define RETURN_BY_STACK
352 #endif
353
354 #ifdef F_INTERFACE_GFORT
355 #define RETURN_BY_REGS
356 #endif
357
358 #ifdef F_INTERFACE_INTEL
359 #define RETURN_BY_STACK
360 #endif
361
362 #define PROLOGUE \
363         .explicit; \
364         .text; \
365         .align 128; \
366         .global REALNAME; \
367         .proc REALNAME; \
368 REALNAME:
369
370
371 #ifdef PROFILE
372 #define PROFCODE \
373         .data; \
374         .align 8; \
375 .LP0:; \
376         data8   0; \
377         .text; \
378         alloc   out0 = ar.pfs, 8, 0, 4, 0; \
379         mov     out1 = r1; \
380         mov     out2 = b0; \
381         addl    out3 = @ltoff(.LP0), r1;;; \
382         br.call.sptk.many b0 = _mcount;;
383 #else
384 #define PROFCODE
385 #endif
386
387 #if defined(__linux__) && defined(__ELF__)
388 #define GNUSTACK .section .note.GNU-stack,"",@progbits
389 #else
390 #define GNUSTACK
391 #endif
392
393 #define EPILOGUE \
394         .endp REALNAME ; \
395         GNUSTACK
396
397 #define START_ADDRESS 0x20000fc800000000UL
398
399 #undef SEEK_ADDRESS
400
401 #if 0
402 #ifdef CONFIG_IA64_PAGE_SIZE_4KB
403 #define SEEK_ADDRESS
404 #endif
405
406 #ifdef CONFIG_IA64_PAGE_SIZE_8KB
407 #define SEEK_ADDRESS
408 #endif
409 #endif
410
411 #define BUFFER_SIZE     (128 << 20)
412
413 #ifndef PAGESIZE
414 #define PAGESIZE        (16UL << 10)
415 #endif
416 #define HUGE_PAGESIZE   (  4 << 20)
417
418 #define BASE_ADDRESS (START_ADDRESS - (BLASULONG)BUFFER_SIZE * MAX_CPU_NUMBER)
419
420 #endif