blob: 840065ea9e069f97b6632abd0aad15e40ae4b034 [file] [log] [blame]
Jim Cownie5e8470a2013-09-27 10:38:44 +00001// z_Linux_asm.s: - microtasking routines specifically
2// written for Intel platforms running Linux* OS
Jim Cownie5e8470a2013-09-27 10:38:44 +00003
4//
5////===----------------------------------------------------------------------===//
6////
7//// The LLVM Compiler Infrastructure
8////
9//// This file is dual licensed under the MIT and the University of Illinois Open
10//// Source Licenses. See LICENSE.txt for details.
11////
12////===----------------------------------------------------------------------===//
13//
14
15// -----------------------------------------------------------------------
16// macros
17// -----------------------------------------------------------------------
18
Jonathan Peyton92907c22015-05-29 16:13:56 +000019#include "kmp_platform.h"
20
Jim Cownie5e8470a2013-09-27 10:38:44 +000021#if KMP_ARCH_X86 || KMP_ARCH_X86_64
22
23# if __MIC__ || __MIC2__
24//
25// the 'delay r16/r32/r64' should be used instead of the 'pause'.
26// The delay operation has the effect of removing the current thread from
27// the round-robin HT mechanism, and therefore speeds up the issue rate of
28// the other threads on the same core.
29//
30// A value of 0 works fine for <= 2 threads per core, but causes the EPCC
31// barrier time to increase greatly for 3 or more threads per core.
32//
33// A value of 100 works pretty well for up to 4 threads per core, but isn't
34// quite as fast as 0 for 2 threads per core.
35//
36// We need to check what happens for oversubscription / > 4 threads per core.
37// It is possible that we need to pass the delay value in as a parameter
38// that the caller determines based on the total # threads / # cores.
39//
40//.macro pause_op
41// mov $100, %rax
42// delay %rax
43//.endm
44# else
45# define pause_op .byte 0xf3,0x90
46# endif // __MIC__ || __MIC2__
47
48# if defined __APPLE__ && defined __MACH__
49# define KMP_PREFIX_UNDERSCORE(x) _##x // extra underscore for OS X* symbols
Andrey Churbanov054c50bf2015-02-10 18:51:52 +000050# define KMP_LABEL(x) L_##x // form the name of label
51.macro KMP_CFI_DEF_OFFSET
52.endmacro
53.macro KMP_CFI_OFFSET
54.endmacro
55.macro KMP_CFI_REGISTER
56.endmacro
57.macro KMP_CFI_DEF
58.endmacro
Jim Cownie5e8470a2013-09-27 10:38:44 +000059.macro ALIGN
60 .align $0
61.endmacro
62.macro DEBUG_INFO
63/* Not sure what .size does in icc, not sure if we need to do something
64 similar for OS X*.
65*/
66.endmacro
67.macro PROC
68 ALIGN 4
69 .globl KMP_PREFIX_UNDERSCORE($0)
70KMP_PREFIX_UNDERSCORE($0):
71.endmacro
72# else // defined __APPLE__ && defined __MACH__
73# define KMP_PREFIX_UNDERSCORE(x) x // no extra underscore for Linux* OS symbols
Andrey Churbanovc5bccf942015-02-10 19:31:17 +000074// Format labels so that they don't override function names in gdb's backtraces
75// MIC assembler doesn't accept .L syntax, the L works fine there (as well as on OS X*)
Andrey Churbanov054c50bf2015-02-10 18:51:52 +000076# if __MIC__ || __MIC2__
77# define KMP_LABEL(x) L_##x // local label
78# else
79# define KMP_LABEL(x) .L_##x // local label hidden from backtraces
80# endif // __MIC__ || __MIC2__
Jim Cownie5e8470a2013-09-27 10:38:44 +000081.macro ALIGN size
82 .align 1<<(\size)
83.endm
84.macro DEBUG_INFO proc
Andrey Churbanov054c50bf2015-02-10 18:51:52 +000085 .cfi_endproc
Jim Cownie5e8470a2013-09-27 10:38:44 +000086// Not sure why we need .type and .size for the functions
87 .align 16
88 .type \proc,@function
89 .size \proc,.-\proc
90.endm
91.macro PROC proc
92 ALIGN 4
93 .globl KMP_PREFIX_UNDERSCORE(\proc)
94KMP_PREFIX_UNDERSCORE(\proc):
Andrey Churbanov054c50bf2015-02-10 18:51:52 +000095 .cfi_startproc
96.endm
97.macro KMP_CFI_DEF_OFFSET sz
98 .cfi_def_cfa_offset \sz
99.endm
100.macro KMP_CFI_OFFSET reg, sz
101 .cfi_offset \reg,\sz
102.endm
103.macro KMP_CFI_REGISTER reg
104 .cfi_def_cfa_register \reg
105.endm
106.macro KMP_CFI_DEF reg, sz
107 .cfi_def_cfa \reg,\sz
Jim Cownie5e8470a2013-09-27 10:38:44 +0000108.endm
109# endif // defined __APPLE__ && defined __MACH__
Jim Cownie181b4bb2013-12-23 17:28:57 +0000110#endif // KMP_ARCH_X86 || KMP_ARCH_x86_64
Jim Cownie5e8470a2013-09-27 10:38:44 +0000111
112
113// -----------------------------------------------------------------------
114// data
115// -----------------------------------------------------------------------
116
117#ifdef KMP_GOMP_COMPAT
118
119//
120// Support for unnamed common blocks.
121//
122// Because the symbol ".gomp_critical_user_" contains a ".", we have to
123// put this stuff in assembly.
124//
125
126# if KMP_ARCH_X86
127# if defined __APPLE__ && defined __MACH__
128 .data
129 .comm .gomp_critical_user_,32
130 .data
131 .globl ___kmp_unnamed_critical_addr
132___kmp_unnamed_critical_addr:
133 .long .gomp_critical_user_
134# else /* Linux* OS */
135 .data
136 .comm .gomp_critical_user_,32,8
137 .data
138 ALIGN 4
139 .global __kmp_unnamed_critical_addr
140__kmp_unnamed_critical_addr:
141 .4byte .gomp_critical_user_
142 .type __kmp_unnamed_critical_addr,@object
143 .size __kmp_unnamed_critical_addr,4
144# endif /* defined __APPLE__ && defined __MACH__ */
145# endif /* KMP_ARCH_X86 */
146
147# if KMP_ARCH_X86_64
148# if defined __APPLE__ && defined __MACH__
149 .data
150 .comm .gomp_critical_user_,32
151 .data
152 .globl ___kmp_unnamed_critical_addr
153___kmp_unnamed_critical_addr:
154 .quad .gomp_critical_user_
155# else /* Linux* OS */
156 .data
157 .comm .gomp_critical_user_,32,8
158 .data
159 ALIGN 8
160 .global __kmp_unnamed_critical_addr
161__kmp_unnamed_critical_addr:
162 .8byte .gomp_critical_user_
163 .type __kmp_unnamed_critical_addr,@object
164 .size __kmp_unnamed_critical_addr,8
165# endif /* defined __APPLE__ && defined __MACH__ */
166# endif /* KMP_ARCH_X86_64 */
167
168#endif /* KMP_GOMP_COMPAT */
169
170
Jim Cownie3051f972014-08-07 10:12:54 +0000171#if KMP_ARCH_X86 && !KMP_ARCH_PPC64
Jim Cownie5e8470a2013-09-27 10:38:44 +0000172
173// -----------------------------------------------------------------------
174// microtasking routines specifically written for IA-32 architecture
175// running Linux* OS
176// -----------------------------------------------------------------------
177//
178
179 .ident "Intel Corporation"
180 .data
181 ALIGN 4
182// void
183// __kmp_x86_pause( void );
184//
185
186 .text
187 PROC __kmp_x86_pause
188
189 pause_op
190 ret
191
192 DEBUG_INFO __kmp_x86_pause
193
194//
195// void
196// __kmp_x86_cpuid( int mode, int mode2, void *cpuid_buffer );
197//
198 PROC __kmp_x86_cpuid
199
200 pushl %ebp
201 movl %esp,%ebp
202 pushl %edi
203 pushl %ebx
204 pushl %ecx
205 pushl %edx
206
207 movl 8(%ebp), %eax
208 movl 12(%ebp), %ecx
209 cpuid // Query the CPUID for the current processor
210
211 movl 16(%ebp), %edi
212 movl %eax, 0(%edi)
213 movl %ebx, 4(%edi)
214 movl %ecx, 8(%edi)
215 movl %edx, 12(%edi)
216
217 popl %edx
218 popl %ecx
219 popl %ebx
220 popl %edi
221 movl %ebp, %esp
222 popl %ebp
223 ret
224
225 DEBUG_INFO __kmp_x86_cpuid
226
227
228# if !KMP_ASM_INTRINS
229
230//------------------------------------------------------------------------
231//
232// kmp_int32
233// __kmp_test_then_add32( volatile kmp_int32 *p, kmp_int32 d );
234//
235
236 PROC __kmp_test_then_add32
237
238 movl 4(%esp), %ecx
239 movl 8(%esp), %eax
240 lock
241 xaddl %eax,(%ecx)
242 ret
243
244 DEBUG_INFO __kmp_test_then_add32
245
246//------------------------------------------------------------------------
247//
248// FUNCTION __kmp_xchg_fixed8
249//
250// kmp_int32
251// __kmp_xchg_fixed8( volatile kmp_int8 *p, kmp_int8 d );
252//
253// parameters:
254// p: 4(%esp)
255// d: 8(%esp)
256//
257// return: %al
258
259 PROC __kmp_xchg_fixed8
260
261 movl 4(%esp), %ecx // "p"
262 movb 8(%esp), %al // "d"
263
264 lock
265 xchgb %al,(%ecx)
266 ret
267
268 DEBUG_INFO __kmp_xchg_fixed8
269
270
271//------------------------------------------------------------------------
272//
273// FUNCTION __kmp_xchg_fixed16
274//
275// kmp_int16
276// __kmp_xchg_fixed16( volatile kmp_int16 *p, kmp_int16 d );
277//
278// parameters:
279// p: 4(%esp)
280// d: 8(%esp)
281// return: %ax
282
283 PROC __kmp_xchg_fixed16
284
285 movl 4(%esp), %ecx // "p"
286 movw 8(%esp), %ax // "d"
287
288 lock
289 xchgw %ax,(%ecx)
290 ret
291
292 DEBUG_INFO __kmp_xchg_fixed16
293
294
295//------------------------------------------------------------------------
296//
297// FUNCTION __kmp_xchg_fixed32
298//
299// kmp_int32
300// __kmp_xchg_fixed32( volatile kmp_int32 *p, kmp_int32 d );
301//
302// parameters:
303// p: 4(%esp)
304// d: 8(%esp)
305//
306// return: %eax
307
308 PROC __kmp_xchg_fixed32
309
310 movl 4(%esp), %ecx // "p"
311 movl 8(%esp), %eax // "d"
312
313 lock
314 xchgl %eax,(%ecx)
315 ret
316
317 DEBUG_INFO __kmp_xchg_fixed32
318
319
320//
321// kmp_int8
322// __kmp_compare_and_store8( volatile kmp_int8 *p, kmp_int8 cv, kmp_int8 sv );
323//
324
325 PROC __kmp_compare_and_store8
326
327 movl 4(%esp), %ecx
328 movb 8(%esp), %al
329 movb 12(%esp), %dl
330 lock
331 cmpxchgb %dl,(%ecx)
332 sete %al // if %al == (%ecx) set %al = 1 else set %al = 0
333 and $1, %eax // sign extend previous instruction
334 ret
335
336 DEBUG_INFO __kmp_compare_and_store8
337
338//
339// kmp_int16
340// __kmp_compare_and_store16( volatile kmp_int16 *p, kmp_int16 cv, kmp_int16 sv );
341//
342
343 PROC __kmp_compare_and_store16
344
345 movl 4(%esp), %ecx
346 movw 8(%esp), %ax
347 movw 12(%esp), %dx
348 lock
349 cmpxchgw %dx,(%ecx)
350 sete %al // if %ax == (%ecx) set %al = 1 else set %al = 0
351 and $1, %eax // sign extend previous instruction
352 ret
353
354 DEBUG_INFO __kmp_compare_and_store16
355
356//
357// kmp_int32
358// __kmp_compare_and_store32( volatile kmp_int32 *p, kmp_int32 cv, kmp_int32 sv );
359//
360
361 PROC __kmp_compare_and_store32
362
363 movl 4(%esp), %ecx
364 movl 8(%esp), %eax
365 movl 12(%esp), %edx
366 lock
367 cmpxchgl %edx,(%ecx)
368 sete %al // if %eax == (%ecx) set %al = 1 else set %al = 0
369 and $1, %eax // sign extend previous instruction
370 ret
371
372 DEBUG_INFO __kmp_compare_and_store32
373
374//
375// kmp_int32
376// __kmp_compare_and_store64( volatile kmp_int64 *p, kmp_int64 cv, kmp_int64 sv );
377//
378 PROC __kmp_compare_and_store64
379
380 pushl %ebp
381 movl %esp, %ebp
382 pushl %ebx
383 pushl %edi
384 movl 8(%ebp), %edi
385 movl 12(%ebp), %eax // "cv" low order word
386 movl 16(%ebp), %edx // "cv" high order word
387 movl 20(%ebp), %ebx // "sv" low order word
388 movl 24(%ebp), %ecx // "sv" high order word
389 lock
390 cmpxchg8b (%edi)
391 sete %al // if %edx:eax == (%edi) set %al = 1 else set %al = 0
392 and $1, %eax // sign extend previous instruction
393 popl %edi
394 popl %ebx
395 movl %ebp, %esp
396 popl %ebp
397 ret
398
399 DEBUG_INFO __kmp_compare_and_store64
400
401//
402// kmp_int8
403// __kmp_compare_and_store_ret8( volatile kmp_int8 *p, kmp_int8 cv, kmp_int8 sv );
404//
405
406 PROC __kmp_compare_and_store_ret8
407
408 movl 4(%esp), %ecx
409 movb 8(%esp), %al
410 movb 12(%esp), %dl
411 lock
412 cmpxchgb %dl,(%ecx)
413 ret
414
415 DEBUG_INFO __kmp_compare_and_store_ret8
416
417//
418// kmp_int16
419// __kmp_compare_and_store_ret16( volatile kmp_int16 *p, kmp_int16 cv, kmp_int16 sv );
420//
421
422 PROC __kmp_compare_and_store_ret16
423
424 movl 4(%esp), %ecx
425 movw 8(%esp), %ax
426 movw 12(%esp), %dx
427 lock
428 cmpxchgw %dx,(%ecx)
429 ret
430
431 DEBUG_INFO __kmp_compare_and_store_ret16
432
433//
434// kmp_int32
435// __kmp_compare_and_store_ret32( volatile kmp_int32 *p, kmp_int32 cv, kmp_int32 sv );
436//
437
438 PROC __kmp_compare_and_store_ret32
439
440 movl 4(%esp), %ecx
441 movl 8(%esp), %eax
442 movl 12(%esp), %edx
443 lock
444 cmpxchgl %edx,(%ecx)
445 ret
446
447 DEBUG_INFO __kmp_compare_and_store_ret32
448
449//
450// kmp_int64
451// __kmp_compare_and_store_ret64( volatile kmp_int64 *p, kmp_int64 cv, kmp_int64 sv );
452//
453 PROC __kmp_compare_and_store_ret64
454
455 pushl %ebp
456 movl %esp, %ebp
457 pushl %ebx
458 pushl %edi
459 movl 8(%ebp), %edi
460 movl 12(%ebp), %eax // "cv" low order word
461 movl 16(%ebp), %edx // "cv" high order word
462 movl 20(%ebp), %ebx // "sv" low order word
463 movl 24(%ebp), %ecx // "sv" high order word
464 lock
465 cmpxchg8b (%edi)
466 popl %edi
467 popl %ebx
468 movl %ebp, %esp
469 popl %ebp
470 ret
471
472 DEBUG_INFO __kmp_compare_and_store_ret64
473
474
475//------------------------------------------------------------------------
476//
477// FUNCTION __kmp_xchg_real32
478//
479// kmp_real32
480// __kmp_xchg_real32( volatile kmp_real32 *addr, kmp_real32 data );
481//
482// parameters:
483// addr: 4(%esp)
484// data: 8(%esp)
485//
486// return: %eax
487
488
489 PROC __kmp_xchg_real32
490
491 pushl %ebp
492 movl %esp, %ebp
493 subl $4, %esp
494 pushl %esi
495
496 movl 4(%ebp), %esi
497 flds (%esi)
498 // load <addr>
499 fsts -4(%ebp)
500 // store old value
501
502 movl 8(%ebp), %eax
503
504 lock
505 xchgl %eax, (%esi)
506
507 flds -4(%ebp)
508 // return old value
509
510 popl %esi
511 movl %ebp, %esp
512 popl %ebp
513 ret
514
515 DEBUG_INFO __kmp_xchg_real32
516
517# endif /* !KMP_ASM_INTRINS */
518
519
520//------------------------------------------------------------------------
521//
Jim Cownie5e8470a2013-09-27 10:38:44 +0000522// FUNCTION __kmp_load_x87_fpu_control_word
523//
524// void
525// __kmp_load_x87_fpu_control_word( kmp_int16 *p );
526//
527// parameters:
528// p: 4(%esp)
529//
530
531 PROC __kmp_load_x87_fpu_control_word
532
533 movl 4(%esp), %eax
534 fldcw (%eax)
535 ret
536
537 DEBUG_INFO __kmp_load_x87_fpu_control_word
538
539
540//------------------------------------------------------------------------
541//
542// FUNCTION __kmp_store_x87_fpu_control_word
543//
544// void
545// __kmp_store_x87_fpu_control_word( kmp_int16 *p );
546//
547// parameters:
548// p: 4(%esp)
549//
550
551 PROC __kmp_store_x87_fpu_control_word
552
553 movl 4(%esp), %eax
554 fstcw (%eax)
555 ret
556
557 DEBUG_INFO __kmp_store_x87_fpu_control_word
558
559
560//------------------------------------------------------------------------
561//
562// FUNCTION __kmp_clear_x87_fpu_status_word
563//
564// void
565// __kmp_clear_x87_fpu_status_word();
566//
567//
568
569 PROC __kmp_clear_x87_fpu_status_word
570
571 fnclex
572 ret
573
574 DEBUG_INFO __kmp_clear_x87_fpu_status_word
575
576
577//------------------------------------------------------------------------
578//
579// typedef void (*microtask_t)( int *gtid, int *tid, ... );
580//
581// int
582// __kmp_invoke_microtask( microtask_t pkfn, int gtid, int tid,
583// int argc, void *p_argv[] ) {
584// (*pkfn)( & gtid, & gtid, argv[0], ... );
585// return 1;
586// }
587
588// -- Begin __kmp_invoke_microtask
589// mark_begin;
590 PROC __kmp_invoke_microtask
591
592 pushl %ebp
Andrey Churbanov054c50bf2015-02-10 18:51:52 +0000593 KMP_CFI_DEF_OFFSET 8
594 KMP_CFI_OFFSET ebp,-8
Jim Cownie5e8470a2013-09-27 10:38:44 +0000595 movl %esp,%ebp // establish the base pointer for this routine.
Andrey Churbanov054c50bf2015-02-10 18:51:52 +0000596 KMP_CFI_REGISTER ebp
Jim Cownie5e8470a2013-09-27 10:38:44 +0000597 subl $8,%esp // allocate space for two local variables.
598 // These varibales are:
599 // argv: -4(%ebp)
600 // temp: -8(%ebp)
601 //
602 pushl %ebx // save %ebx to use during this routine
Andrey Churbanovd7d088f2015-04-29 16:42:24 +0000603 //
604#if OMPT_SUPPORT
605 movl 28(%ebp),%ebx // get exit_frame address
606 movl %ebp,(%ebx) // save exit_frame
607#endif
608
Jim Cownie5e8470a2013-09-27 10:38:44 +0000609 movl 20(%ebp),%ebx // Stack alignment - # args
610 addl $2,%ebx // #args +2 Always pass at least 2 args (gtid and tid)
611 shll $2,%ebx // Number of bytes used on stack: (#args+2)*4
612 movl %esp,%eax //
613 subl %ebx,%eax // %esp-((#args+2)*4) -> %eax -- without mods, stack ptr would be this
614 movl %eax,%ebx // Save to %ebx
615 andl $0xFFFFFF80,%eax // mask off 7 bits
616 subl %eax,%ebx // Amount to subtract from %esp
617 subl %ebx,%esp // Prepare the stack ptr --
618 // now it will be aligned on 128-byte boundary at the call
619
620 movl 24(%ebp),%eax // copy from p_argv[]
621 movl %eax,-4(%ebp) // into the local variable *argv.
622
623 movl 20(%ebp),%ebx // argc is 20(%ebp)
624 shll $2,%ebx
625
Andrey Churbanov054c50bf2015-02-10 18:51:52 +0000626KMP_LABEL(invoke_2):
Jim Cownie5e8470a2013-09-27 10:38:44 +0000627 cmpl $0,%ebx
Andrey Churbanov054c50bf2015-02-10 18:51:52 +0000628 jg KMP_LABEL(invoke_4)
629 jmp KMP_LABEL(invoke_3)
Jim Cownie5e8470a2013-09-27 10:38:44 +0000630 ALIGN 2
Andrey Churbanov054c50bf2015-02-10 18:51:52 +0000631KMP_LABEL(invoke_4):
Jim Cownie5e8470a2013-09-27 10:38:44 +0000632 movl -4(%ebp),%eax
633 subl $4,%ebx // decrement argc.
634 addl %ebx,%eax // index into argv.
635 movl (%eax),%edx
636 pushl %edx
637
Andrey Churbanov054c50bf2015-02-10 18:51:52 +0000638 jmp KMP_LABEL(invoke_2)
Jim Cownie5e8470a2013-09-27 10:38:44 +0000639 ALIGN 2
Andrey Churbanov054c50bf2015-02-10 18:51:52 +0000640KMP_LABEL(invoke_3):
Jim Cownie5e8470a2013-09-27 10:38:44 +0000641 leal 16(%ebp),%eax // push & tid
642 pushl %eax
643
644 leal 12(%ebp),%eax // push & gtid
645 pushl %eax
646
647 movl 8(%ebp),%ebx
648 call *%ebx // call (*pkfn)();
649
650 movl $1,%eax // return 1;
651
652 movl -12(%ebp),%ebx // restore %ebx
653 leave
Andrey Churbanov054c50bf2015-02-10 18:51:52 +0000654 KMP_CFI_DEF esp,4
Jim Cownie5e8470a2013-09-27 10:38:44 +0000655 ret
656
657 DEBUG_INFO __kmp_invoke_microtask
658// -- End __kmp_invoke_microtask
659
660
661// kmp_uint64
662// __kmp_hardware_timestamp(void)
663 PROC __kmp_hardware_timestamp
664 rdtsc
665 ret
666
667 DEBUG_INFO __kmp_hardware_timestamp
668// -- End __kmp_hardware_timestamp
669
670// -----------------------------------------------------------------------
671#endif /* KMP_ARCH_X86 */
672
673
674#if KMP_ARCH_X86_64
675
676// -----------------------------------------------------------------------
677// microtasking routines specifically written for IA-32 architecture and
678// Intel(R) 64 running Linux* OS
679// -----------------------------------------------------------------------
680
681// -- Machine type P
682// mark_description "Intel Corporation";
683 .ident "Intel Corporation"
684// -- .file "z_Linux_asm.s"
685 .data
686 ALIGN 4
687
Jim Cownie4cc4bb42014-10-07 16:25:50 +0000688// To prevent getting our code into .data section .text added to every routine definition for x86_64.
Jim Cownie5e8470a2013-09-27 10:38:44 +0000689//------------------------------------------------------------------------
690//
691// FUNCTION __kmp_x86_cpuid
692//
693// void
694// __kmp_x86_cpuid( int mode, int mode2, void *cpuid_buffer );
695//
696// parameters:
697// mode: %edi
698// mode2: %esi
699// cpuid_buffer: %rdx
700
701 .text
702 PROC __kmp_x86_cpuid
703
704 pushq %rbp
705 movq %rsp,%rbp
706 pushq %rbx // callee-save register
707
708 movl %esi, %ecx // "mode2"
709 movl %edi, %eax // "mode"
710 movq %rdx, %rsi // cpuid_buffer
711 cpuid // Query the CPUID for the current processor
712
713 movl %eax, 0(%rsi) // store results into buffer
714 movl %ebx, 4(%rsi)
715 movl %ecx, 8(%rsi)
716 movl %edx, 12(%rsi)
717
718 popq %rbx // callee-save register
719 movq %rbp, %rsp
720 popq %rbp
721 ret
722
723 DEBUG_INFO __kmp_x86_cpuid
724
725
726
727# if !KMP_ASM_INTRINS
728
729//------------------------------------------------------------------------
730//
731// FUNCTION __kmp_test_then_add32
732//
733// kmp_int32
734// __kmp_test_then_add32( volatile kmp_int32 *p, kmp_int32 d );
735//
736// parameters:
737// p: %rdi
738// d: %esi
739//
740// return: %eax
741
742 .text
743 PROC __kmp_test_then_add32
744
745 movl %esi, %eax // "d"
746 lock
747 xaddl %eax,(%rdi)
748 ret
749
750 DEBUG_INFO __kmp_test_then_add32
751
752
753//------------------------------------------------------------------------
754//
755// FUNCTION __kmp_test_then_add64
756//
757// kmp_int64
758// __kmp_test_then_add64( volatile kmp_int64 *p, kmp_int64 d );
759//
760// parameters:
761// p: %rdi
762// d: %rsi
763// return: %rax
764
765 .text
766 PROC __kmp_test_then_add64
767
768 movq %rsi, %rax // "d"
769 lock
770 xaddq %rax,(%rdi)
771 ret
772
773 DEBUG_INFO __kmp_test_then_add64
774
775
776//------------------------------------------------------------------------
777//
778// FUNCTION __kmp_xchg_fixed8
779//
780// kmp_int32
781// __kmp_xchg_fixed8( volatile kmp_int8 *p, kmp_int8 d );
782//
783// parameters:
784// p: %rdi
785// d: %sil
786//
787// return: %al
788
789 .text
790 PROC __kmp_xchg_fixed8
791
792 movb %sil, %al // "d"
793
794 lock
795 xchgb %al,(%rdi)
796 ret
797
798 DEBUG_INFO __kmp_xchg_fixed8
799
800
801//------------------------------------------------------------------------
802//
803// FUNCTION __kmp_xchg_fixed16
804//
805// kmp_int16
806// __kmp_xchg_fixed16( volatile kmp_int16 *p, kmp_int16 d );
807//
808// parameters:
809// p: %rdi
810// d: %si
811// return: %ax
812
813 .text
814 PROC __kmp_xchg_fixed16
815
816 movw %si, %ax // "d"
817
818 lock
819 xchgw %ax,(%rdi)
820 ret
821
822 DEBUG_INFO __kmp_xchg_fixed16
823
824
825//------------------------------------------------------------------------
826//
827// FUNCTION __kmp_xchg_fixed32
828//
829// kmp_int32
830// __kmp_xchg_fixed32( volatile kmp_int32 *p, kmp_int32 d );
831//
832// parameters:
833// p: %rdi
834// d: %esi
835//
836// return: %eax
837
838 .text
839 PROC __kmp_xchg_fixed32
840
841 movl %esi, %eax // "d"
842
843 lock
844 xchgl %eax,(%rdi)
845 ret
846
847 DEBUG_INFO __kmp_xchg_fixed32
848
849
850//------------------------------------------------------------------------
851//
852// FUNCTION __kmp_xchg_fixed64
853//
854// kmp_int64
855// __kmp_xchg_fixed64( volatile kmp_int64 *p, kmp_int64 d );
856//
857// parameters:
858// p: %rdi
859// d: %rsi
860// return: %rax
861
862 .text
863 PROC __kmp_xchg_fixed64
864
865 movq %rsi, %rax // "d"
866
867 lock
868 xchgq %rax,(%rdi)
869 ret
870
871 DEBUG_INFO __kmp_xchg_fixed64
872
873
874//------------------------------------------------------------------------
875//
876// FUNCTION __kmp_compare_and_store8
877//
878// kmp_int8
879// __kmp_compare_and_store8( volatile kmp_int8 *p, kmp_int8 cv, kmp_int8 sv );
880//
881// parameters:
882// p: %rdi
883// cv: %esi
884// sv: %edx
885//
886// return: %eax
887
888 .text
889 PROC __kmp_compare_and_store8
890
891 movb %sil, %al // "cv"
892 lock
893 cmpxchgb %dl,(%rdi)
894 sete %al // if %al == (%rdi) set %al = 1 else set %al = 0
895 andq $1, %rax // sign extend previous instruction for return value
896 ret
897
898 DEBUG_INFO __kmp_compare_and_store8
899
900
901//------------------------------------------------------------------------
902//
903// FUNCTION __kmp_compare_and_store16
904//
905// kmp_int16
906// __kmp_compare_and_store16( volatile kmp_int16 *p, kmp_int16 cv, kmp_int16 sv );
907//
908// parameters:
909// p: %rdi
910// cv: %si
911// sv: %dx
912//
913// return: %eax
914
915 .text
916 PROC __kmp_compare_and_store16
917
918 movw %si, %ax // "cv"
919 lock
920 cmpxchgw %dx,(%rdi)
921 sete %al // if %ax == (%rdi) set %al = 1 else set %al = 0
922 andq $1, %rax // sign extend previous instruction for return value
923 ret
924
925 DEBUG_INFO __kmp_compare_and_store16
926
927
928//------------------------------------------------------------------------
929//
930// FUNCTION __kmp_compare_and_store32
931//
932// kmp_int32
933// __kmp_compare_and_store32( volatile kmp_int32 *p, kmp_int32 cv, kmp_int32 sv );
934//
935// parameters:
936// p: %rdi
937// cv: %esi
938// sv: %edx
939//
940// return: %eax
941
942 .text
943 PROC __kmp_compare_and_store32
944
945 movl %esi, %eax // "cv"
946 lock
947 cmpxchgl %edx,(%rdi)
948 sete %al // if %eax == (%rdi) set %al = 1 else set %al = 0
949 andq $1, %rax // sign extend previous instruction for return value
950 ret
951
952 DEBUG_INFO __kmp_compare_and_store32
953
954
955//------------------------------------------------------------------------
956//
957// FUNCTION __kmp_compare_and_store64
958//
959// kmp_int32
960// __kmp_compare_and_store64( volatile kmp_int64 *p, kmp_int64 cv, kmp_int64 sv );
961//
962// parameters:
963// p: %rdi
964// cv: %rsi
965// sv: %rdx
966// return: %eax
967
968 .text
969 PROC __kmp_compare_and_store64
970
971 movq %rsi, %rax // "cv"
972 lock
973 cmpxchgq %rdx,(%rdi)
974 sete %al // if %rax == (%rdi) set %al = 1 else set %al = 0
975 andq $1, %rax // sign extend previous instruction for return value
976 ret
977
978 DEBUG_INFO __kmp_compare_and_store64
979
980//------------------------------------------------------------------------
981//
982// FUNCTION __kmp_compare_and_store_ret8
983//
984// kmp_int8
985// __kmp_compare_and_store_ret8( volatile kmp_int8 *p, kmp_int8 cv, kmp_int8 sv );
986//
987// parameters:
988// p: %rdi
989// cv: %esi
990// sv: %edx
991//
992// return: %eax
993
994 .text
995 PROC __kmp_compare_and_store_ret8
996
997 movb %sil, %al // "cv"
998 lock
999 cmpxchgb %dl,(%rdi)
1000 ret
1001
1002 DEBUG_INFO __kmp_compare_and_store_ret8
1003
1004
1005//------------------------------------------------------------------------
1006//
1007// FUNCTION __kmp_compare_and_store_ret16
1008//
1009// kmp_int16
1010// __kmp_compare_and_store16_ret( volatile kmp_int16 *p, kmp_int16 cv, kmp_int16 sv );
1011//
1012// parameters:
1013// p: %rdi
1014// cv: %si
1015// sv: %dx
1016//
1017// return: %eax
1018
1019 .text
1020 PROC __kmp_compare_and_store_ret16
1021
1022 movw %si, %ax // "cv"
1023 lock
1024 cmpxchgw %dx,(%rdi)
1025 ret
1026
1027 DEBUG_INFO __kmp_compare_and_store_ret16
1028
1029
1030//------------------------------------------------------------------------
1031//
1032// FUNCTION __kmp_compare_and_store_ret32
1033//
1034// kmp_int32
1035// __kmp_compare_and_store_ret32( volatile kmp_int32 *p, kmp_int32 cv, kmp_int32 sv );
1036//
1037// parameters:
1038// p: %rdi
1039// cv: %esi
1040// sv: %edx
1041//
1042// return: %eax
1043
1044 .text
1045 PROC __kmp_compare_and_store_ret32
1046
1047 movl %esi, %eax // "cv"
1048 lock
1049 cmpxchgl %edx,(%rdi)
1050 ret
1051
1052 DEBUG_INFO __kmp_compare_and_store_ret32
1053
1054
1055//------------------------------------------------------------------------
1056//
1057// FUNCTION __kmp_compare_and_store_ret64
1058//
1059// kmp_int64
1060// __kmp_compare_and_store_ret64( volatile kmp_int64 *p, kmp_int64 cv, kmp_int64 sv );
1061//
1062// parameters:
1063// p: %rdi
1064// cv: %rsi
1065// sv: %rdx
1066// return: %eax
1067
1068 .text
1069 PROC __kmp_compare_and_store_ret64
1070
1071 movq %rsi, %rax // "cv"
1072 lock
1073 cmpxchgq %rdx,(%rdi)
1074 ret
1075
1076 DEBUG_INFO __kmp_compare_and_store_ret64
1077
1078# endif /* !KMP_ASM_INTRINS */
1079
1080
1081# if ! (__MIC__ || __MIC2__)
1082
Jim Cownie5e8470a2013-09-27 10:38:44 +00001083# if !KMP_ASM_INTRINS
1084
1085//------------------------------------------------------------------------
1086//
1087// FUNCTION __kmp_xchg_real32
1088//
1089// kmp_real32
1090// __kmp_xchg_real32( volatile kmp_real32 *addr, kmp_real32 data );
1091//
1092// parameters:
1093// addr: %rdi
1094// data: %xmm0 (lower 4 bytes)
1095//
1096// return: %xmm0 (lower 4 bytes)
1097
1098 .text
1099 PROC __kmp_xchg_real32
1100
1101 movd %xmm0, %eax // load "data" to eax
1102
1103 lock
1104 xchgl %eax, (%rdi)
1105
1106 movd %eax, %xmm0 // load old value into return register
1107
1108 ret
1109
1110 DEBUG_INFO __kmp_xchg_real32
1111
1112
1113//------------------------------------------------------------------------
1114//
1115// FUNCTION __kmp_xchg_real64
1116//
1117// kmp_real64
1118// __kmp_xchg_real64( volatile kmp_real64 *addr, kmp_real64 data );
1119//
1120// parameters:
1121// addr: %rdi
1122// data: %xmm0 (lower 8 bytes)
1123// return: %xmm0 (lower 8 bytes)
1124//
1125
1126 .text
1127 PROC __kmp_xchg_real64
1128
1129 movd %xmm0, %rax // load "data" to rax
1130
1131 lock
1132 xchgq %rax, (%rdi)
1133
1134 movd %rax, %xmm0 // load old value into return register
1135 ret
1136
1137 DEBUG_INFO __kmp_xchg_real64
1138
1139
1140# endif /* !(__MIC__ || __MIC2__) */
1141
1142# endif /* !KMP_ASM_INTRINS */
1143
1144
1145//------------------------------------------------------------------------
1146//
1147// FUNCTION __kmp_load_x87_fpu_control_word
1148//
1149// void
1150// __kmp_load_x87_fpu_control_word( kmp_int16 *p );
1151//
1152// parameters:
1153// p: %rdi
1154//
1155
1156 .text
1157 PROC __kmp_load_x87_fpu_control_word
1158
1159 fldcw (%rdi)
1160 ret
1161
1162 DEBUG_INFO __kmp_load_x87_fpu_control_word
1163
1164
1165//------------------------------------------------------------------------
1166//
1167// FUNCTION __kmp_store_x87_fpu_control_word
1168//
1169// void
1170// __kmp_store_x87_fpu_control_word( kmp_int16 *p );
1171//
1172// parameters:
1173// p: %rdi
1174//
1175
1176 .text
1177 PROC __kmp_store_x87_fpu_control_word
1178
1179 fstcw (%rdi)
1180 ret
1181
1182 DEBUG_INFO __kmp_store_x87_fpu_control_word
1183
1184
1185//------------------------------------------------------------------------
1186//
1187// FUNCTION __kmp_clear_x87_fpu_status_word
1188//
1189// void
1190// __kmp_clear_x87_fpu_status_word();
1191//
1192//
1193
1194 .text
1195 PROC __kmp_clear_x87_fpu_status_word
1196
1197#if __MIC__ || __MIC2__
1198// TODO: remove the workaround for problem with fnclex instruction (no CQ known)
1199 fstenv -32(%rsp) // store FP env
1200 andw $~0x80ff, 4-32(%rsp) // clear 0-7,15 bits of FP SW
1201 fldenv -32(%rsp) // load FP env back
1202 ret
1203#else
1204 fnclex
1205 ret
1206#endif
1207
1208 DEBUG_INFO __kmp_clear_x87_fpu_status_word
1209
1210
1211//------------------------------------------------------------------------
1212//
1213// typedef void (*microtask_t)( int *gtid, int *tid, ... );
1214//
1215// int
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001216// __kmp_invoke_microtask( void (*pkfn) (int gtid, int tid, ...),
Jim Cownie5e8470a2013-09-27 10:38:44 +00001217// int gtid, int tid,
1218// int argc, void *p_argv[] ) {
1219// (*pkfn)( & gtid, & tid, argv[0], ... );
1220// return 1;
1221// }
1222//
1223// note:
1224// at call to pkfn must have %rsp 128-byte aligned for compiler
1225//
1226// parameters:
1227// %rdi: pkfn
1228// %esi: gtid
1229// %edx: tid
1230// %ecx: argc
1231// %r8: p_argv
Andrey Churbanovd7d088f2015-04-29 16:42:24 +00001232// %r9: &exit_frame
Jim Cownie5e8470a2013-09-27 10:38:44 +00001233//
1234// locals:
1235// __gtid: gtid parm pushed on stack so can pass &gtid to pkfn
1236// __tid: tid parm pushed on stack so can pass &tid to pkfn
1237//
1238// reg temps:
1239// %rax: used all over the place
1240// %rdx: used in stack pointer alignment calculation
1241// %r11: used to traverse p_argv array
1242// %rsi: used as temporary for stack parameters
1243// used as temporary for number of pkfn parms to push
1244// %rbx: used to hold pkfn address, and zero constant, callee-save
1245//
1246// return: %eax (always 1/TRUE)
1247//
1248
1249__gtid = -16
1250__tid = -24
1251
1252// -- Begin __kmp_invoke_microtask
1253// mark_begin;
1254 .text
1255 PROC __kmp_invoke_microtask
1256
1257 pushq %rbp // save base pointer
Andrey Churbanov054c50bf2015-02-10 18:51:52 +00001258 KMP_CFI_DEF_OFFSET 16
1259 KMP_CFI_OFFSET rbp,-16
Jim Cownie5e8470a2013-09-27 10:38:44 +00001260 movq %rsp,%rbp // establish the base pointer for this routine.
Andrey Churbanov054c50bf2015-02-10 18:51:52 +00001261 KMP_CFI_REGISTER rbp
Andrey Churbanovd7d088f2015-04-29 16:42:24 +00001262
1263#if OMPT_SUPPORT
1264 movq %rbp, (%r9) // save exit_frame
1265#endif
1266
Jim Cownie5e8470a2013-09-27 10:38:44 +00001267 pushq %rbx // %rbx is callee-saved register
Jim Cownie5e8470a2013-09-27 10:38:44 +00001268 pushq %rsi // Put gtid on stack so can pass &tgid to pkfn
1269 pushq %rdx // Put tid on stack so can pass &tid to pkfn
1270
1271 movq %rcx, %rax // Stack alignment calculation begins; argc -> %rax
1272 movq $0, %rbx // constant for cmovs later
1273 subq $4, %rax // subtract four args passed in registers to pkfn
1274#if __MIC__ || __MIC2__
Andrey Churbanov054c50bf2015-02-10 18:51:52 +00001275 js KMP_LABEL(kmp_0) // jump to movq
1276 jmp KMP_LABEL(kmp_0_exit) // jump ahead
1277KMP_LABEL(kmp_0):
Jim Cownie5e8470a2013-09-27 10:38:44 +00001278 movq %rbx, %rax // zero negative value in %rax <- max(0, argc-4)
Andrey Churbanov054c50bf2015-02-10 18:51:52 +00001279KMP_LABEL(kmp_0_exit):
Jim Cownie5e8470a2013-09-27 10:38:44 +00001280#else
1281 cmovsq %rbx, %rax // zero negative value in %rax <- max(0, argc-4)
1282#endif // __MIC__ || __MIC2__
1283
1284 movq %rax, %rsi // save max(0, argc-4) -> %rsi for later
1285 shlq $3, %rax // Number of bytes used on stack: max(0, argc-4)*8
1286
1287 movq %rsp, %rdx //
1288 subq %rax, %rdx // %rsp-(max(0,argc-4)*8) -> %rdx --
1289 // without align, stack ptr would be this
1290 movq %rdx, %rax // Save to %rax
1291
1292 andq $0xFFFFFFFFFFFFFF80, %rax // mask off lower 7 bits (128 bytes align)
1293 subq %rax, %rdx // Amount to subtract from %rsp
1294 subq %rdx, %rsp // Prepare the stack ptr --
1295 // now %rsp will align to 128-byte boundary at call site
1296
1297 // setup pkfn parameter reg and stack
1298 movq %rcx, %rax // argc -> %rax
1299 cmpq $0, %rsi
Andrey Churbanov054c50bf2015-02-10 18:51:52 +00001300 je KMP_LABEL(kmp_invoke_pass_parms) // jump ahead if no parms to push
Jim Cownie5e8470a2013-09-27 10:38:44 +00001301 shlq $3, %rcx // argc*8 -> %rcx
1302 movq %r8, %rdx // p_argv -> %rdx
1303 addq %rcx, %rdx // &p_argv[argc] -> %rdx
1304
1305 movq %rsi, %rcx // max (0, argc-4) -> %rcx
1306
Andrey Churbanov054c50bf2015-02-10 18:51:52 +00001307KMP_LABEL(kmp_invoke_push_parms):
1308 // push nth - 7th parms to pkfn on stack
Jim Cownie5e8470a2013-09-27 10:38:44 +00001309 subq $8, %rdx // decrement p_argv pointer to previous parm
1310 movq (%rdx), %rsi // p_argv[%rcx-1] -> %rsi
1311 pushq %rsi // push p_argv[%rcx-1] onto stack (reverse order)
1312 subl $1, %ecx
1313
1314// C69570: "X86_64_RELOC_BRANCH not supported" error at linking on mac_32e
1315// if the name of the label that is an operand of this jecxz starts with a dot (".");
1316// Apple's linker does not support 1-byte length relocation;
1317// Resolution: replace all .labelX entries with L_labelX.
1318
Andrey Churbanov054c50bf2015-02-10 18:51:52 +00001319 jecxz KMP_LABEL(kmp_invoke_pass_parms) // stop when four p_argv[] parms left
1320 jmp KMP_LABEL(kmp_invoke_push_parms)
Jim Cownie5e8470a2013-09-27 10:38:44 +00001321 ALIGN 3
Andrey Churbanov054c50bf2015-02-10 18:51:52 +00001322KMP_LABEL(kmp_invoke_pass_parms): // put 1st - 6th parms to pkfn in registers.
Jim Cownie5e8470a2013-09-27 10:38:44 +00001323 // order here is important to avoid trashing
1324 // registers used for both input and output parms!
1325 movq %rdi, %rbx // pkfn -> %rbx
1326 leaq __gtid(%rbp), %rdi // &gtid -> %rdi (store 1st parm to pkfn)
1327 leaq __tid(%rbp), %rsi // &tid -> %rsi (store 2nd parm to pkfn)
1328
1329 movq %r8, %r11 // p_argv -> %r11
1330
1331#if __MIC__ || __MIC2__
1332 cmpq $4, %rax // argc >= 4?
Andrey Churbanov054c50bf2015-02-10 18:51:52 +00001333 jns KMP_LABEL(kmp_4) // jump to movq
1334 jmp KMP_LABEL(kmp_4_exit) // jump ahead
1335KMP_LABEL(kmp_4):
Jim Cownie5e8470a2013-09-27 10:38:44 +00001336 movq 24(%r11), %r9 // p_argv[3] -> %r9 (store 6th parm to pkfn)
Andrey Churbanov054c50bf2015-02-10 18:51:52 +00001337KMP_LABEL(kmp_4_exit):
Jim Cownie5e8470a2013-09-27 10:38:44 +00001338
1339 cmpq $3, %rax // argc >= 3?
Andrey Churbanov054c50bf2015-02-10 18:51:52 +00001340 jns KMP_LABEL(kmp_3) // jump to movq
1341 jmp KMP_LABEL(kmp_3_exit) // jump ahead
1342KMP_LABEL(kmp_3):
Jim Cownie5e8470a2013-09-27 10:38:44 +00001343 movq 16(%r11), %r8 // p_argv[2] -> %r8 (store 5th parm to pkfn)
Andrey Churbanov054c50bf2015-02-10 18:51:52 +00001344KMP_LABEL(kmp_3_exit):
Jim Cownie5e8470a2013-09-27 10:38:44 +00001345
1346 cmpq $2, %rax // argc >= 2?
Andrey Churbanov054c50bf2015-02-10 18:51:52 +00001347 jns KMP_LABEL(kmp_2) // jump to movq
1348 jmp KMP_LABEL(kmp_2_exit) // jump ahead
1349KMP_LABEL(kmp_2):
Jim Cownie5e8470a2013-09-27 10:38:44 +00001350 movq 8(%r11), %rcx // p_argv[1] -> %rcx (store 4th parm to pkfn)
Andrey Churbanov054c50bf2015-02-10 18:51:52 +00001351KMP_LABEL(kmp_2_exit):
Jim Cownie5e8470a2013-09-27 10:38:44 +00001352
1353 cmpq $1, %rax // argc >= 1?
Andrey Churbanov054c50bf2015-02-10 18:51:52 +00001354 jns KMP_LABEL(kmp_1) // jump to movq
1355 jmp KMP_LABEL(kmp_1_exit) // jump ahead
1356KMP_LABEL(kmp_1):
Jim Cownie5e8470a2013-09-27 10:38:44 +00001357 movq (%r11), %rdx // p_argv[0] -> %rdx (store 3rd parm to pkfn)
Andrey Churbanov054c50bf2015-02-10 18:51:52 +00001358KMP_LABEL(kmp_1_exit):
Jim Cownie5e8470a2013-09-27 10:38:44 +00001359#else
1360 cmpq $4, %rax // argc >= 4?
1361 cmovnsq 24(%r11), %r9 // p_argv[3] -> %r9 (store 6th parm to pkfn)
1362
1363 cmpq $3, %rax // argc >= 3?
1364 cmovnsq 16(%r11), %r8 // p_argv[2] -> %r8 (store 5th parm to pkfn)
1365
1366 cmpq $2, %rax // argc >= 2?
1367 cmovnsq 8(%r11), %rcx // p_argv[1] -> %rcx (store 4th parm to pkfn)
1368
1369 cmpq $1, %rax // argc >= 1?
1370 cmovnsq (%r11), %rdx // p_argv[0] -> %rdx (store 3rd parm to pkfn)
1371#endif // __MIC__ || __MIC2__
1372
1373 call *%rbx // call (*pkfn)();
1374 movq $1, %rax // move 1 into return register;
1375
1376 movq -8(%rbp), %rbx // restore %rbx using %rbp since %rsp was modified
1377 movq %rbp, %rsp // restore stack pointer
1378 popq %rbp // restore frame pointer
Andrey Churbanov054c50bf2015-02-10 18:51:52 +00001379 KMP_CFI_DEF rsp,8
Jim Cownie5e8470a2013-09-27 10:38:44 +00001380 ret
1381
1382 DEBUG_INFO __kmp_invoke_microtask
1383// -- End __kmp_invoke_microtask
1384
1385// kmp_uint64
1386// __kmp_hardware_timestamp(void)
1387 .text
1388 PROC __kmp_hardware_timestamp
1389 rdtsc
1390 shlq $32, %rdx
1391 orq %rdx, %rax
1392 ret
1393
1394 DEBUG_INFO __kmp_hardware_timestamp
1395// -- End __kmp_hardware_timestamp
1396
1397//------------------------------------------------------------------------
1398//
1399// FUNCTION __kmp_bsr32
1400//
1401// int
1402// __kmp_bsr32( int );
1403//
1404
1405 .text
1406 PROC __kmp_bsr32
1407
1408 bsr %edi,%eax
1409 ret
1410
1411 DEBUG_INFO __kmp_bsr32
1412
1413
1414// -----------------------------------------------------------------------
1415#endif /* KMP_ARCH_X86_64 */
Jim Cownie181b4bb2013-12-23 17:28:57 +00001416
1417#if KMP_ARCH_ARM
1418 .data
1419 .comm .gomp_critical_user_,32,8
1420 .data
1421 .align 4
1422 .global __kmp_unnamed_critical_addr
1423__kmp_unnamed_critical_addr:
1424 .4byte .gomp_critical_user_
1425 .size __kmp_unnamed_critical_addr,4
1426#endif /* KMP_ARCH_ARM */
1427
Andrey Churbanovcbda8682015-01-13 14:43:35 +00001428#if KMP_ARCH_PPC64 || KMP_ARCH_AARCH64
Jim Cownie3051f972014-08-07 10:12:54 +00001429 .data
1430 .comm .gomp_critical_user_,32,8
1431 .data
1432 .align 8
1433 .global __kmp_unnamed_critical_addr
1434__kmp_unnamed_critical_addr:
1435 .8byte .gomp_critical_user_
1436 .size __kmp_unnamed_critical_addr,8
Andrey Churbanovcbda8682015-01-13 14:43:35 +00001437#endif /* KMP_ARCH_PPC64 || KMP_ARCH_AARCH64 */
Jim Cownie181b4bb2013-12-23 17:28:57 +00001438
1439#if defined(__linux__)
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001440# if KMP_ARCH_ARM
1441.section .note.GNU-stack,"",%progbits
1442# else
Jim Cownie181b4bb2013-12-23 17:28:57 +00001443.section .note.GNU-stack,"",@progbits
Jim Cownie4cc4bb42014-10-07 16:25:50 +00001444# endif
Jim Cownie181b4bb2013-12-23 17:28:57 +00001445#endif