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