]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/openmp/runtime/src/z_Windows_NT-586_asm.asm
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / openmp / runtime / src / z_Windows_NT-586_asm.asm
1 ;  z_Windows_NT-586_asm.asm:  - microtasking routines specifically
2 ;    written for IA-32 architecture and Intel(R) 64 running Windows* OS
3
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         TITLE   z_Windows_NT-586_asm.asm
16
17 ; ============================= IA-32 architecture ==========================
18 ifdef _M_IA32
19
20         .586P
21
22 if @Version gt 510
23         .model HUGE
24 else
25 _TEXT   SEGMENT PARA USE32 PUBLIC 'CODE'
26 _TEXT   ENDS
27 _DATA   SEGMENT DWORD USE32 PUBLIC 'DATA'
28 _DATA   ENDS
29 CONST   SEGMENT DWORD USE32 PUBLIC 'CONST'
30 CONST   ENDS
31 _BSS    SEGMENT DWORD USE32 PUBLIC 'BSS'
32 _BSS    ENDS
33 $$SYMBOLS       SEGMENT BYTE USE32 'DEBSYM'
34 $$SYMBOLS       ENDS
35 $$TYPES SEGMENT BYTE USE32 'DEBTYP'
36 $$TYPES ENDS
37 _TLS    SEGMENT DWORD USE32 PUBLIC 'TLS'
38 _TLS    ENDS
39 FLAT    GROUP _DATA, CONST, _BSS
40         ASSUME  CS: FLAT, DS: FLAT, SS: FLAT
41 endif
42
43
44 ;------------------------------------------------------------------------
45 ; FUNCTION ___kmp_x86_pause
46 ;
47 ; void
48 ; __kmp_x86_pause( void )
49 PUBLIC  ___kmp_x86_pause
50 _p$ = 4
51 _d$ = 8
52 _TEXT   SEGMENT
53         ALIGN 16
54 ___kmp_x86_pause PROC NEAR
55
56         db      0f3H
57         db      090H    ;; pause
58         ret
59
60 ___kmp_x86_pause ENDP
61 _TEXT   ENDS
62
63 ;------------------------------------------------------------------------
64 ; FUNCTION ___kmp_x86_cpuid
65 ;
66 ; void
67 ; __kmp_x86_cpuid( int mode, int mode2, struct kmp_cpuid *p );
68 PUBLIC  ___kmp_x86_cpuid
69 _TEXT   SEGMENT
70         ALIGN 16
71 _mode$  = 8
72 _mode2$ = 12
73 _p$     = 16
74 _eax$   = 0
75 _ebx$   = 4
76 _ecx$   = 8
77 _edx$   = 12
78
79 ___kmp_x86_cpuid PROC NEAR
80
81         push      ebp
82         mov       ebp, esp
83
84         push      edi
85         push      ebx
86         push      ecx
87         push      edx
88
89         mov       eax, DWORD PTR _mode$[ebp]
90         mov       ecx, DWORD PTR _mode2$[ebp]
91         cpuid                                   ; Query the CPUID for the current processor
92
93         mov       edi, DWORD PTR _p$[ebp]
94         mov       DWORD PTR _eax$[ edi ], eax
95         mov       DWORD PTR _ebx$[ edi ], ebx
96         mov       DWORD PTR _ecx$[ edi ], ecx
97         mov       DWORD PTR _edx$[ edi ], edx
98
99         pop       edx
100         pop       ecx
101         pop       ebx
102         pop       edi
103
104         mov       esp, ebp
105         pop       ebp
106         ret
107
108 ___kmp_x86_cpuid ENDP
109 _TEXT     ENDS
110
111 ;------------------------------------------------------------------------
112 ; FUNCTION ___kmp_test_then_add32
113 ;
114 ; kmp_int32
115 ; __kmp_test_then_add32( volatile kmp_int32 *p, kmp_int32 d );
116 PUBLIC  ___kmp_test_then_add32
117 _p$ = 4
118 _d$ = 8
119 _TEXT   SEGMENT
120         ALIGN 16
121 ___kmp_test_then_add32 PROC NEAR
122
123         mov     eax, DWORD PTR _d$[esp]
124         mov     ecx, DWORD PTR _p$[esp]
125 lock    xadd    DWORD PTR [ecx], eax
126         ret
127
128 ___kmp_test_then_add32 ENDP
129 _TEXT   ENDS
130
131 ;------------------------------------------------------------------------
132 ; FUNCTION ___kmp_compare_and_store8
133 ;
134 ; kmp_int8
135 ; __kmp_compare_and_store8( volatile kmp_int8 *p, kmp_int8 cv, kmp_int8 sv );
136 PUBLIC  ___kmp_compare_and_store8
137 _TEXT   SEGMENT
138         ALIGN 16
139 _p$ = 4
140 _cv$ = 8
141 _sv$ = 12
142
143 ___kmp_compare_and_store8 PROC NEAR
144
145         mov       ecx, DWORD PTR _p$[esp]
146         mov       al, BYTE PTR _cv$[esp]
147         mov       dl, BYTE PTR _sv$[esp]
148 lock    cmpxchg   BYTE PTR [ecx], dl
149         sete      al           ; if al == [ecx] set al = 1 else set al = 0
150         and       eax, 1       ; sign extend previous instruction
151         ret
152
153 ___kmp_compare_and_store8 ENDP
154 _TEXT     ENDS
155
156 ;------------------------------------------------------------------------
157 ; FUNCTION ___kmp_compare_and_store16
158 ;
159 ; kmp_int16
160 ; __kmp_compare_and_store16( volatile kmp_int16 *p, kmp_int16 cv, kmp_int16 sv );
161 PUBLIC  ___kmp_compare_and_store16
162 _TEXT   SEGMENT
163         ALIGN 16
164 _p$ = 4
165 _cv$ = 8
166 _sv$ = 12
167
168 ___kmp_compare_and_store16 PROC NEAR
169
170         mov       ecx, DWORD PTR _p$[esp]
171         mov       ax, WORD PTR _cv$[esp]
172         mov       dx, WORD PTR _sv$[esp]
173 lock    cmpxchg   WORD PTR [ecx], dx
174         sete      al           ; if ax == [ecx] set al = 1 else set al = 0
175         and       eax, 1       ; sign extend previous instruction
176         ret
177
178 ___kmp_compare_and_store16 ENDP
179 _TEXT     ENDS
180
181 ;------------------------------------------------------------------------
182 ; FUNCTION ___kmp_compare_and_store32
183 ;
184 ; kmp_int32
185 ; __kmp_compare_and_store32( volatile kmp_int32 *p, kmp_int32 cv, kmp_int32 sv );
186 PUBLIC  ___kmp_compare_and_store32
187 _TEXT   SEGMENT
188         ALIGN 16
189 _p$ = 4
190 _cv$ = 8
191 _sv$ = 12
192
193 ___kmp_compare_and_store32 PROC NEAR
194
195         mov       ecx, DWORD PTR _p$[esp]
196         mov       eax, DWORD PTR _cv$[esp]
197         mov       edx, DWORD PTR _sv$[esp]
198 lock    cmpxchg   DWORD PTR [ecx], edx
199         sete      al           ; if eax == [ecx] set al = 1 else set al = 0
200         and       eax, 1       ; sign extend previous instruction
201         ret
202
203 ___kmp_compare_and_store32 ENDP
204 _TEXT     ENDS
205
206 ;------------------------------------------------------------------------
207 ; FUNCTION ___kmp_compare_and_store64
208 ;
209 ; kmp_int32
210 ; __kmp_compare_and_store64( volatile kmp_int64 *p, kmp_int64 cv, kmp_int64 sv );
211 PUBLIC  ___kmp_compare_and_store64
212 _TEXT   SEGMENT
213         ALIGN 16
214 _p$ = 8
215 _cv_low$ = 12
216 _cv_high$ = 16
217 _sv_low$ = 20
218 _sv_high$ = 24
219
220 ___kmp_compare_and_store64 PROC NEAR
221
222         push      ebp
223         mov       ebp, esp
224         push      ebx
225         push      edi
226         mov       edi, DWORD PTR _p$[ebp]
227         mov       eax, DWORD PTR _cv_low$[ebp]
228         mov       edx, DWORD PTR _cv_high$[ebp]
229         mov       ebx, DWORD PTR _sv_low$[ebp]
230         mov       ecx, DWORD PTR _sv_high$[ebp]
231 lock    cmpxchg8b QWORD PTR [edi]
232         sete      al           ; if edx:eax == [edi] set al = 1 else set al = 0
233         and       eax, 1       ; sign extend previous instruction
234         pop       edi
235         pop       ebx
236         mov       esp, ebp
237         pop       ebp
238         ret
239
240 ___kmp_compare_and_store64 ENDP
241 _TEXT     ENDS
242
243 ;------------------------------------------------------------------------
244 ; FUNCTION ___kmp_xchg_fixed8
245 ;
246 ; kmp_int8
247 ; __kmp_xchg_fixed8( volatile kmp_int8 *p, kmp_int8 d );
248 PUBLIC  ___kmp_xchg_fixed8
249 _TEXT   SEGMENT
250         ALIGN 16
251 _p$ = 4
252 _d$ = 8
253
254 ___kmp_xchg_fixed8 PROC NEAR
255
256         mov       ecx, DWORD PTR _p$[esp]
257         mov       al,  BYTE PTR _d$[esp]
258 lock    xchg      BYTE PTR [ecx], al
259         ret
260
261 ___kmp_xchg_fixed8 ENDP
262 _TEXT     ENDS
263
264 ;------------------------------------------------------------------------
265 ; FUNCTION ___kmp_xchg_fixed16
266 ;
267 ; kmp_int16
268 ; __kmp_xchg_fixed16( volatile kmp_int16 *p, kmp_int16 d );
269 PUBLIC  ___kmp_xchg_fixed16
270 _TEXT   SEGMENT
271         ALIGN 16
272 _p$ = 4
273 _d$ = 8
274
275 ___kmp_xchg_fixed16 PROC NEAR
276
277         mov       ecx, DWORD PTR _p$[esp]
278         mov       ax,  WORD PTR  _d$[esp]
279 lock    xchg      WORD PTR [ecx], ax
280         ret
281
282 ___kmp_xchg_fixed16 ENDP
283 _TEXT     ENDS
284
285 ;------------------------------------------------------------------------
286 ; FUNCTION ___kmp_xchg_fixed32
287 ;
288 ; kmp_int32
289 ; __kmp_xchg_fixed32( volatile kmp_int32 *p, kmp_int32 d );
290 PUBLIC  ___kmp_xchg_fixed32
291 _TEXT   SEGMENT
292         ALIGN 16
293 _p$ = 4
294 _d$ = 8
295
296 ___kmp_xchg_fixed32 PROC NEAR
297
298         mov       ecx, DWORD PTR _p$[esp]
299         mov       eax, DWORD PTR _d$[esp]
300 lock    xchg      DWORD PTR [ecx], eax
301         ret
302
303 ___kmp_xchg_fixed32 ENDP
304 _TEXT     ENDS
305
306
307 ;------------------------------------------------------------------------
308 ; FUNCTION ___kmp_xchg_real32
309 ;
310 ; kmp_real32
311 ; __kmp_xchg_real32( volatile kmp_real32 *p, kmp_real32 d );
312 PUBLIC  ___kmp_xchg_real32
313 _TEXT   SEGMENT
314         ALIGN 16
315 _p$ = 8
316 _d$ = 12
317 _old_value$ = -4
318
319 ___kmp_xchg_real32 PROC NEAR
320
321         push    ebp
322         mov     ebp, esp
323         sub     esp, 4
324         push    esi
325         mov     esi, DWORD PTR _p$[ebp]
326
327         fld     DWORD PTR [esi]
328                         ;; load <addr>
329         fst     DWORD PTR _old_value$[ebp]
330                         ;; store into old_value
331
332         mov     eax, DWORD PTR _d$[ebp]
333
334 lock    xchg    DWORD PTR [esi], eax
335
336         fld     DWORD PTR _old_value$[ebp]
337                         ;; return old_value
338         pop     esi
339         mov     esp, ebp
340         pop     ebp
341         ret
342
343 ___kmp_xchg_real32 ENDP
344 _TEXT   ENDS
345
346
347 ;------------------------------------------------------------------------
348 ; FUNCTION ___kmp_compare_and_store_ret8
349 ;
350 ; kmp_int8
351 ; __kmp_compare_and_store_ret8( volatile kmp_int8 *p, kmp_int8 cv, kmp_int8 sv );
352 PUBLIC  ___kmp_compare_and_store_ret8
353 _TEXT   SEGMENT
354         ALIGN 16
355 _p$ = 4
356 _cv$ = 8
357 _sv$ = 12
358
359 ___kmp_compare_and_store_ret8 PROC NEAR
360
361         mov       ecx, DWORD PTR _p$[esp]
362         mov       al, BYTE PTR _cv$[esp]
363         mov       dl, BYTE PTR _sv$[esp]
364 lock    cmpxchg   BYTE PTR [ecx], dl
365         ret
366
367 ___kmp_compare_and_store_ret8 ENDP
368 _TEXT     ENDS
369
370 ;------------------------------------------------------------------------
371 ; FUNCTION ___kmp_compare_and_store_ret16
372 ;
373 ; kmp_int16
374 ; __kmp_compare_and_store_ret16( volatile kmp_int16 *p, kmp_int16 cv, kmp_int16 sv );
375 PUBLIC  ___kmp_compare_and_store_ret16
376 _TEXT   SEGMENT
377         ALIGN 16
378 _p$ = 4
379 _cv$ = 8
380 _sv$ = 12
381
382 ___kmp_compare_and_store_ret16 PROC NEAR
383
384         mov       ecx, DWORD PTR _p$[esp]
385         mov       ax, WORD PTR _cv$[esp]
386         mov       dx, WORD PTR _sv$[esp]
387 lock    cmpxchg   WORD PTR [ecx], dx
388         ret
389
390 ___kmp_compare_and_store_ret16 ENDP
391 _TEXT     ENDS
392
393 ;------------------------------------------------------------------------
394 ; FUNCTION ___kmp_compare_and_store_ret32
395 ;
396 ; kmp_int32
397 ; __kmp_compare_and_store_ret32( volatile kmp_int32 *p, kmp_int32 cv, kmp_int32 sv );
398 PUBLIC  ___kmp_compare_and_store_ret32
399 _TEXT   SEGMENT
400         ALIGN 16
401 _p$ = 4
402 _cv$ = 8
403 _sv$ = 12
404
405 ___kmp_compare_and_store_ret32 PROC NEAR
406
407         mov       ecx, DWORD PTR _p$[esp]
408         mov       eax, DWORD PTR _cv$[esp]
409         mov       edx, DWORD PTR _sv$[esp]
410 lock    cmpxchg   DWORD PTR [ecx], edx
411         ret
412
413 ___kmp_compare_and_store_ret32 ENDP
414 _TEXT     ENDS
415
416 ;------------------------------------------------------------------------
417 ; FUNCTION ___kmp_compare_and_store_ret64
418 ;
419 ; kmp_int64
420 ; __kmp_compare_and_store_ret64( volatile kmp_int64 *p, kmp_int64 cv, kmp_int64 sv );
421 PUBLIC  ___kmp_compare_and_store_ret64
422 _TEXT   SEGMENT
423         ALIGN 16
424 _p$ = 8
425 _cv_low$ = 12
426 _cv_high$ = 16
427 _sv_low$ = 20
428 _sv_high$ = 24
429
430 ___kmp_compare_and_store_ret64 PROC NEAR
431
432         push      ebp
433         mov       ebp, esp
434         push      ebx
435         push      edi
436         mov       edi, DWORD PTR _p$[ebp]
437         mov       eax, DWORD PTR _cv_low$[ebp]
438         mov       edx, DWORD PTR _cv_high$[ebp]
439         mov       ebx, DWORD PTR _sv_low$[ebp]
440         mov       ecx, DWORD PTR _sv_high$[ebp]
441 lock    cmpxchg8b QWORD PTR [edi]
442         pop       edi
443         pop       ebx
444         mov       esp, ebp
445         pop       ebp
446         ret
447
448 ___kmp_compare_and_store_ret64 ENDP
449 _TEXT     ENDS
450
451 ;------------------------------------------------------------------------
452 ; FUNCTION ___kmp_load_x87_fpu_control_word
453 ;
454 ; void
455 ; __kmp_load_x87_fpu_control_word( kmp_int16 *p );
456 ;
457 ; parameters:
458 ;       p:      4(%esp)
459 PUBLIC  ___kmp_load_x87_fpu_control_word
460 _TEXT   SEGMENT
461         ALIGN 16
462 _p$ = 4
463
464 ___kmp_load_x87_fpu_control_word PROC NEAR
465
466         mov       eax, DWORD PTR _p$[esp]
467         fldcw     WORD PTR [eax]
468         ret
469
470 ___kmp_load_x87_fpu_control_word ENDP
471 _TEXT     ENDS
472
473 ;------------------------------------------------------------------------
474 ; FUNCTION ___kmp_store_x87_fpu_control_word
475 ;
476 ; void
477 ; __kmp_store_x87_fpu_control_word( kmp_int16 *p );
478 ;
479 ; parameters:
480 ;       p:      4(%esp)
481 PUBLIC  ___kmp_store_x87_fpu_control_word
482 _TEXT   SEGMENT
483         ALIGN 16
484 _p$ = 4
485
486 ___kmp_store_x87_fpu_control_word PROC NEAR
487
488         mov       eax, DWORD PTR _p$[esp]
489         fstcw     WORD PTR [eax]
490         ret
491
492 ___kmp_store_x87_fpu_control_word ENDP
493 _TEXT     ENDS
494
495 ;------------------------------------------------------------------------
496 ; FUNCTION ___kmp_clear_x87_fpu_status_word
497 ;
498 ; void
499 ; __kmp_clear_x87_fpu_status_word();
500 PUBLIC  ___kmp_clear_x87_fpu_status_word
501 _TEXT   SEGMENT
502         ALIGN 16
503
504 ___kmp_clear_x87_fpu_status_word PROC NEAR
505
506         fnclex
507         ret
508
509 ___kmp_clear_x87_fpu_status_word ENDP
510 _TEXT     ENDS
511
512
513 ;------------------------------------------------------------------------
514 ; FUNCTION ___kmp_invoke_microtask
515 ;
516 ; typedef void  (*microtask_t)( int *gtid, int *tid, ... );
517 ;
518 ; int
519 ; __kmp_invoke_microtask( microtask_t pkfn,
520 ;                         int gtid, int tid,
521 ;                         int argc, void *p_argv[] )
522 PUBLIC  ___kmp_invoke_microtask
523 _TEXT   SEGMENT
524         ALIGN 16
525 _pkfn$ = 8
526 _gtid$ = 12
527 _tid$ = 16
528 _argc$ = 20
529 _argv$ = 24
530 if OMPT_SUPPORT
531 _exit_frame$ = 28
532 endif
533 _i$ = -8
534 _stk_adj$ = -16
535 _vptr$ = -12
536 _qptr$ = -4
537
538 ___kmp_invoke_microtask PROC NEAR
539 ; Line 102
540         push    ebp
541         mov     ebp, esp
542         sub     esp, 16                                 ; 00000010H
543         push    ebx
544         push    esi
545         push    edi
546 if OMPT_SUPPORT
547         mov     eax, DWORD PTR _exit_frame$[ebp]
548         mov     DWORD PTR [eax], ebp
549 endif
550 ; Line 114
551         mov     eax, DWORD PTR _argc$[ebp]
552         mov     DWORD PTR _i$[ebp], eax
553
554 ;; ------------------------------------------------------------
555         lea     edx, DWORD PTR [eax*4+8]
556         mov     ecx, esp                                ; Save current SP into ECX
557         mov     eax,edx         ; Save the size of the args in eax
558         sub     ecx,edx         ; esp-((#args+2)*4) -> ecx -- without mods, stack ptr would be this
559         mov     edx,ecx         ; Save to edx
560         and     ecx,-128        ; Mask off 7 bits
561         sub     edx,ecx         ; Amount to subtract from esp
562         sub     esp,edx         ; Prepare stack ptr-- Now it will be aligned on 128-byte boundary at the call
563
564         add     edx,eax         ; Calculate total size of the stack decrement.
565         mov     DWORD PTR _stk_adj$[ebp], edx
566 ;; ------------------------------------------------------------
567
568         jmp     SHORT $L22237
569 $L22238:
570         mov     ecx, DWORD PTR _i$[ebp]
571         sub     ecx, 1
572         mov     DWORD PTR _i$[ebp], ecx
573 $L22237:
574         cmp     DWORD PTR _i$[ebp], 0
575         jle     SHORT $L22239
576 ; Line 116
577         mov     edx, DWORD PTR _i$[ebp]
578         mov     eax, DWORD PTR _argv$[ebp]
579         mov     ecx, DWORD PTR [eax+edx*4-4]
580         mov     DWORD PTR _vptr$[ebp], ecx
581 ; Line 123
582         mov     eax, DWORD PTR _vptr$[ebp]
583 ; Line 124
584         push    eax
585 ; Line 127
586         jmp     SHORT $L22238
587 $L22239:
588 ; Line 129
589         lea     edx, DWORD PTR _tid$[ebp]
590         mov     DWORD PTR _vptr$[ebp], edx
591 ; Line 130
592         lea     eax, DWORD PTR _gtid$[ebp]
593         mov     DWORD PTR _qptr$[ebp], eax
594 ; Line 143
595         mov     eax, DWORD PTR _vptr$[ebp]
596 ; Line 144
597         push    eax
598 ; Line 145
599         mov     eax, DWORD PTR _qptr$[ebp]
600 ; Line 146
601         push    eax
602 ; Line 147
603         call    DWORD PTR _pkfn$[ebp]
604 ; Line 148
605         add     esp, DWORD PTR _stk_adj$[ebp]
606 ; Line 152
607         mov     eax, 1
608 ; Line 153
609         pop     edi
610         pop     esi
611         pop     ebx
612         mov     esp, ebp
613         pop     ebp
614         ret     0
615 ___kmp_invoke_microtask ENDP
616 _TEXT   ENDS
617
618 endif
619
620 ; ==================================== Intel(R) 64 ===================================
621
622 ifdef _M_AMD64
623
624 ;------------------------------------------------------------------------
625 ; FUNCTION __kmp_x86_cpuid
626 ;
627 ; void
628 ; __kmp_x86_cpuid( int mode, int mode2, struct kmp_cpuid *p );
629 ;
630 ; parameters:
631 ;       mode:           ecx
632 ;       mode2:          edx
633 ;       cpuid_buffer:   r8
634 PUBLIC  __kmp_x86_cpuid
635 _TEXT   SEGMENT
636         ALIGN 16
637
638 __kmp_x86_cpuid PROC FRAME ;NEAR
639
640         push      rbp
641         .pushreg  rbp
642         mov       rbp, rsp
643         .setframe rbp, 0
644         push      rbx                           ; callee-save register
645         .pushreg  rbx
646         .ENDPROLOG
647
648         mov       r10, r8                       ; p parameter
649         mov       eax, ecx                      ; mode parameter
650         mov       ecx, edx                      ; mode2 parameter
651         cpuid                                   ; Query the CPUID for the current processor
652
653         mov       DWORD PTR 0[ r10 ], eax       ; store results into buffer
654         mov       DWORD PTR 4[ r10 ], ebx
655         mov       DWORD PTR 8[ r10 ], ecx
656         mov       DWORD PTR 12[ r10 ], edx
657
658         pop       rbx                           ; callee-save register
659         mov       rsp, rbp
660         pop       rbp
661         ret
662
663 __kmp_x86_cpuid ENDP
664 _TEXT     ENDS
665
666
667 ;------------------------------------------------------------------------
668 ; FUNCTION __kmp_test_then_add32
669 ;
670 ; kmp_int32
671 ; __kmp_test_then_add32( volatile kmp_int32 *p, kmp_int32 d );
672 ;
673 ; parameters:
674 ;       p:      rcx
675 ;       d:      edx
676 ;
677 ; return:       eax
678 PUBLIC  __kmp_test_then_add32
679 _TEXT   SEGMENT
680         ALIGN 16
681 __kmp_test_then_add32 PROC ;NEAR
682
683         mov     eax, edx
684 lock    xadd    DWORD PTR [rcx], eax
685         ret
686
687 __kmp_test_then_add32 ENDP
688 _TEXT   ENDS
689
690
691 ;------------------------------------------------------------------------
692 ; FUNCTION __kmp_test_then_add64
693 ;
694 ; kmp_int32
695 ; __kmp_test_then_add64( volatile kmp_int64 *p, kmp_int64 d );
696 ;
697 ; parameters:
698 ;       p:      rcx
699 ;       d:      rdx
700 ;
701 ; return:       rax
702 PUBLIC  __kmp_test_then_add64
703 _TEXT   SEGMENT
704         ALIGN 16
705 __kmp_test_then_add64 PROC ;NEAR
706
707         mov     rax, rdx
708 lock    xadd    QWORD PTR [rcx], rax
709         ret
710
711 __kmp_test_then_add64 ENDP
712 _TEXT   ENDS
713
714
715 ;------------------------------------------------------------------------
716 ; FUNCTION __kmp_compare_and_store8
717 ;
718 ; kmp_int8
719 ; __kmp_compare_and_store8( volatile kmp_int8 *p, kmp_int8 cv, kmp_int8 sv );
720 ; parameters:
721 ;       p:      rcx
722 ;       cv:     edx
723 ;       sv:     r8d
724 ;
725 ; return:       eax
726 PUBLIC  __kmp_compare_and_store8
727 _TEXT   SEGMENT
728         ALIGN 16
729
730 __kmp_compare_and_store8 PROC ;NEAR
731
732         mov       al, dl        ; "cv"
733         mov       edx, r8d      ; "sv"
734 lock    cmpxchg   BYTE PTR [rcx], dl
735         sete      al            ; if al == [rcx] set al = 1 else set al = 0
736         and       rax, 1        ; sign extend previous instruction
737         ret
738
739 __kmp_compare_and_store8 ENDP
740 _TEXT     ENDS
741
742
743 ;------------------------------------------------------------------------
744 ; FUNCTION __kmp_compare_and_store16
745 ;
746 ; kmp_int16
747 ; __kmp_compare_and_store16( volatile kmp_int16 *p, kmp_int16 cv, kmp_int16 sv );
748 ; parameters:
749 ;       p:      rcx
750 ;       cv:     edx
751 ;       sv:     r8d
752 ;
753 ; return:       eax
754 PUBLIC  __kmp_compare_and_store16
755 _TEXT   SEGMENT
756         ALIGN 16
757
758 __kmp_compare_and_store16 PROC ;NEAR
759
760         mov       ax, dx        ; "cv"
761         mov       edx, r8d      ; "sv"
762 lock    cmpxchg   WORD PTR [rcx], dx
763         sete      al            ; if ax == [rcx] set al = 1 else set al = 0
764         and       rax, 1        ; sign extend previous instruction
765         ret
766
767 __kmp_compare_and_store16 ENDP
768 _TEXT     ENDS
769
770
771 ;------------------------------------------------------------------------
772 ; FUNCTION __kmp_compare_and_store32
773 ;
774 ; kmp_int32
775 ; __kmp_compare_and_store32( volatile kmp_int32 *p, kmp_int32 cv, kmp_int32 sv );
776 ; parameters:
777 ;       p:      rcx
778 ;       cv:     edx
779 ;       sv:     r8d
780 ;
781 ; return:       eax
782 PUBLIC  __kmp_compare_and_store32
783 _TEXT   SEGMENT
784         ALIGN 16
785
786 __kmp_compare_and_store32 PROC ;NEAR
787
788         mov       eax, edx      ; "cv"
789         mov       edx, r8d      ; "sv"
790 lock    cmpxchg   DWORD PTR [rcx], edx
791         sete      al            ; if eax == [rcx] set al = 1 else set al = 0
792         and       rax, 1        ; sign extend previous instruction
793         ret
794
795 __kmp_compare_and_store32 ENDP
796 _TEXT     ENDS
797
798
799 ;------------------------------------------------------------------------
800 ; FUNCTION __kmp_compare_and_store64
801 ;
802 ; kmp_int32
803 ; __kmp_compare_and_store64( volatile kmp_int64 *p, kmp_int64 cv, kmp_int64 sv );
804 ; parameters:
805 ;       p:      rcx
806 ;       cv:     rdx
807 ;       sv:     r8
808 ;
809 ; return:       eax
810 PUBLIC  __kmp_compare_and_store64
811 _TEXT   SEGMENT
812         ALIGN 16
813
814 __kmp_compare_and_store64 PROC ;NEAR
815
816         mov       rax, rdx      ; "cv"
817         mov       rdx, r8       ; "sv"
818 lock    cmpxchg   QWORD PTR [rcx], rdx
819         sete      al           ; if rax == [rcx] set al = 1 else set al = 0
820         and       rax, 1       ; sign extend previous instruction
821         ret
822
823 __kmp_compare_and_store64 ENDP
824 _TEXT     ENDS
825
826
827 ;------------------------------------------------------------------------
828 ; FUNCTION ___kmp_xchg_fixed8
829 ;
830 ; kmp_int8
831 ; __kmp_xchg_fixed8( volatile kmp_int8 *p, kmp_int8 d );
832 ;
833 ; parameters:
834 ;       p:      rcx
835 ;       d:      dl
836 ;
837 ; return:       al
838 PUBLIC  __kmp_xchg_fixed8
839 _TEXT   SEGMENT
840         ALIGN 16
841
842 __kmp_xchg_fixed8 PROC ;NEAR
843
844         mov       al,  dl
845 lock    xchg      BYTE PTR [rcx], al
846         ret
847
848 __kmp_xchg_fixed8 ENDP
849 _TEXT     ENDS
850
851
852 ;------------------------------------------------------------------------
853 ; FUNCTION ___kmp_xchg_fixed16
854 ;
855 ; kmp_int16
856 ; __kmp_xchg_fixed16( volatile kmp_int16 *p, kmp_int16 d );
857 ;
858 ; parameters:
859 ;       p:      rcx
860 ;       d:      dx
861 ;
862 ; return:       ax
863 PUBLIC  __kmp_xchg_fixed16
864 _TEXT   SEGMENT
865         ALIGN 16
866
867 __kmp_xchg_fixed16 PROC ;NEAR
868
869         mov       ax,  dx
870 lock    xchg      WORD PTR [rcx], ax
871         ret
872
873 __kmp_xchg_fixed16 ENDP
874 _TEXT     ENDS
875
876
877 ;------------------------------------------------------------------------
878 ; FUNCTION ___kmp_xchg_fixed32
879 ;
880 ; kmp_int32
881 ; __kmp_xchg_fixed32( volatile kmp_int32 *p, kmp_int32 d );
882 ;
883 ; parameters:
884 ;       p:      rcx
885 ;       d:      edx
886 ;
887 ; return:       eax
888 PUBLIC  __kmp_xchg_fixed32
889 _TEXT   SEGMENT
890         ALIGN 16
891 __kmp_xchg_fixed32 PROC ;NEAR
892
893         mov     eax, edx
894 lock    xchg    DWORD PTR [rcx], eax
895         ret
896
897 __kmp_xchg_fixed32 ENDP
898 _TEXT   ENDS
899
900
901 ;------------------------------------------------------------------------
902 ; FUNCTION ___kmp_xchg_fixed64
903 ;
904 ; kmp_int64
905 ; __kmp_xchg_fixed64( volatile kmp_int64 *p, kmp_int64 d );
906 ;
907 ; parameters:
908 ;       p:      rcx
909 ;       d:      rdx
910 ;
911 ; return:       rax
912 PUBLIC  __kmp_xchg_fixed64
913 _TEXT   SEGMENT
914         ALIGN 16
915 __kmp_xchg_fixed64 PROC ;NEAR
916
917         mov     rax, rdx
918 lock    xchg    QWORD PTR [rcx], rax
919         ret
920
921 __kmp_xchg_fixed64 ENDP
922 _TEXT   ENDS
923
924
925 ;------------------------------------------------------------------------
926 ; FUNCTION __kmp_compare_and_store_ret8
927 ;
928 ; kmp_int8
929 ; __kmp_compare_and_store_ret8( volatile kmp_int8 *p, kmp_int8 cv, kmp_int8 sv );
930 ; parameters:
931 ;       p:      rcx
932 ;       cv:     edx
933 ;       sv:     r8d
934 ;
935 ; return:       eax
936 PUBLIC  __kmp_compare_and_store_ret8
937 _TEXT   SEGMENT
938         ALIGN 16
939
940 __kmp_compare_and_store_ret8 PROC ;NEAR
941         mov       al, dl        ; "cv"
942         mov       edx, r8d      ; "sv"
943 lock    cmpxchg   BYTE PTR [rcx], dl
944                         ; Compare AL with [rcx].  If equal set
945                         ; ZF and exchange DL with [rcx].  Else, clear
946                         ; ZF and load [rcx] into AL.
947         ret
948
949 __kmp_compare_and_store_ret8 ENDP
950 _TEXT     ENDS
951
952
953 ;------------------------------------------------------------------------
954 ; FUNCTION __kmp_compare_and_store_ret16
955 ;
956 ; kmp_int16
957 ; __kmp_compare_and_store_ret16( volatile kmp_int16 *p, kmp_int16 cv, kmp_int16 sv );
958 ; parameters:
959 ;       p:      rcx
960 ;       cv:     edx
961 ;       sv:     r8d
962 ;
963 ; return:       eax
964 PUBLIC  __kmp_compare_and_store_ret16
965 _TEXT   SEGMENT
966         ALIGN 16
967
968 __kmp_compare_and_store_ret16 PROC ;NEAR
969
970         mov       ax, dx        ; "cv"
971         mov       edx, r8d      ; "sv"
972 lock    cmpxchg   WORD PTR [rcx], dx
973         ret
974
975 __kmp_compare_and_store_ret16 ENDP
976 _TEXT     ENDS
977
978
979 ;------------------------------------------------------------------------
980 ; FUNCTION __kmp_compare_and_store_ret32
981 ;
982 ; kmp_int32
983 ; __kmp_compare_and_store_ret32( volatile kmp_int32 *p, kmp_int32 cv, kmp_int32 sv );
984 ; parameters:
985 ;       p:      rcx
986 ;       cv:     edx
987 ;       sv:     r8d
988 ;
989 ; return:       eax
990 PUBLIC  __kmp_compare_and_store_ret32
991 _TEXT   SEGMENT
992         ALIGN 16
993
994 __kmp_compare_and_store_ret32 PROC ;NEAR
995
996         mov       eax, edx      ; "cv"
997         mov       edx, r8d      ; "sv"
998 lock    cmpxchg   DWORD PTR [rcx], edx
999         ret
1000
1001 __kmp_compare_and_store_ret32 ENDP
1002 _TEXT     ENDS
1003
1004
1005 ;------------------------------------------------------------------------
1006 ; FUNCTION __kmp_compare_and_store_ret64
1007 ;
1008 ; kmp_int64
1009 ; __kmp_compare_and_store_ret64( volatile kmp_int64 *p, kmp_int64 cv, kmp_int64 sv );
1010 ; parameters:
1011 ;       p:      rcx
1012 ;       cv:     rdx
1013 ;       sv:     r8
1014 ;
1015 ; return:       rax
1016 PUBLIC  __kmp_compare_and_store_ret64
1017 _TEXT   SEGMENT
1018         ALIGN 16
1019
1020 __kmp_compare_and_store_ret64 PROC ;NEAR
1021
1022         mov       rax, rdx      ; "cv"
1023         mov       rdx, r8       ; "sv"
1024 lock    cmpxchg   QWORD PTR [rcx], rdx
1025         ret
1026
1027 __kmp_compare_and_store_ret64 ENDP
1028 _TEXT     ENDS
1029
1030
1031 ;------------------------------------------------------------------------
1032 ; FUNCTION __kmp_compare_and_store_loop8
1033 ;
1034 ; kmp_int8
1035 ; __kmp_compare_and_store_loop8( volatile kmp_int8 *p, kmp_int8 cv, kmp_int8 sv );
1036 ; parameters:
1037 ;       p:      rcx
1038 ;       cv:     edx
1039 ;       sv:     r8d
1040 ;
1041 ; return:       al
1042 PUBLIC  __kmp_compare_and_store_loop8
1043 _TEXT   SEGMENT
1044         ALIGN 16
1045
1046 __kmp_compare_and_store_loop8 PROC ;NEAR
1047 $__kmp_loop:
1048         mov       al, dl        ; "cv"
1049         mov       edx, r8d      ; "sv"
1050 lock    cmpxchg   BYTE PTR [rcx], dl
1051                         ; Compare AL with [rcx].  If equal set
1052                         ; ZF and exchange DL with [rcx].  Else, clear
1053                         ; ZF and load [rcx] into AL.
1054         jz      SHORT $__kmp_success
1055
1056         db      0f3H
1057         db      090H                    ; pause
1058
1059         jmp     SHORT $__kmp_loop
1060
1061 $__kmp_success:
1062         ret
1063
1064 __kmp_compare_and_store_loop8 ENDP
1065 _TEXT     ENDS
1066
1067
1068 ;------------------------------------------------------------------------
1069 ; FUNCTION __kmp_xchg_real32
1070 ;
1071 ; kmp_real32
1072 ; __kmp_xchg_real32( volatile kmp_real32 *p, kmp_real32 d );
1073 ;
1074 ; parameters:
1075 ;       p:      rcx
1076 ;       d:      xmm1 (lower 4 bytes)
1077 ;
1078 ; return:       xmm0 (lower 4 bytes)
1079 PUBLIC  __kmp_xchg_real32
1080 _TEXT   SEGMENT
1081         ALIGN 16
1082 __kmp_xchg_real32 PROC ;NEAR
1083
1084         movd    eax, xmm1               ; load d
1085
1086 lock    xchg    DWORD PTR [rcx], eax
1087
1088         movd    xmm0, eax               ; load old value into return register
1089         ret
1090
1091 __kmp_xchg_real32 ENDP
1092 _TEXT   ENDS
1093
1094
1095 ;------------------------------------------------------------------------
1096 ; FUNCTION __kmp_xchg_real64
1097 ;
1098 ; kmp_real64
1099 ; __kmp_xchg_real64( volatile kmp_real64 *p, kmp_real64 d );
1100 ;
1101 ; parameters:
1102 ;       p:      rcx
1103 ;       d:      xmm1 (lower 8 bytes)
1104 ;
1105 ; return:       xmm0 (lower 8 bytes)
1106 PUBLIC  __kmp_xchg_real64
1107 _TEXT   SEGMENT
1108         ALIGN 16
1109 __kmp_xchg_real64 PROC ;NEAR
1110
1111         movd    rax, xmm1               ; load "d"
1112
1113 lock    xchg    QWORD PTR [rcx], rax
1114
1115         movd    xmm0, rax               ; load old value into return register
1116         ret
1117
1118 __kmp_xchg_real64 ENDP
1119 _TEXT   ENDS
1120
1121 ;------------------------------------------------------------------------
1122 ; FUNCTION __kmp_load_x87_fpu_control_word
1123 ;
1124 ; void
1125 ; __kmp_load_x87_fpu_control_word( kmp_int16 *p );
1126 ;
1127 ; parameters:
1128 ;       p:      rcx
1129 PUBLIC  __kmp_load_x87_fpu_control_word
1130 _TEXT   SEGMENT
1131         ALIGN 16
1132 __kmp_load_x87_fpu_control_word PROC ;NEAR
1133
1134         fldcw   WORD PTR [rcx]
1135         ret
1136
1137 __kmp_load_x87_fpu_control_word ENDP
1138 _TEXT   ENDS
1139
1140
1141 ;------------------------------------------------------------------------
1142 ; FUNCTION __kmp_store_x87_fpu_control_word
1143 ;
1144 ; void
1145 ; __kmp_store_x87_fpu_control_word( kmp_int16 *p );
1146 ;
1147 ; parameters:
1148 ;       p:      rcx
1149 PUBLIC  __kmp_store_x87_fpu_control_word
1150 _TEXT   SEGMENT
1151         ALIGN 16
1152 __kmp_store_x87_fpu_control_word PROC ;NEAR
1153
1154         fstcw   WORD PTR [rcx]
1155         ret
1156
1157 __kmp_store_x87_fpu_control_word ENDP
1158 _TEXT   ENDS
1159
1160
1161 ;------------------------------------------------------------------------
1162 ; FUNCTION __kmp_clear_x87_fpu_status_word
1163 ;
1164 ; void
1165 ; __kmp_clear_x87_fpu_status_word()
1166 PUBLIC  __kmp_clear_x87_fpu_status_word
1167 _TEXT   SEGMENT
1168         ALIGN 16
1169 __kmp_clear_x87_fpu_status_word PROC ;NEAR
1170
1171         fnclex
1172         ret
1173
1174 __kmp_clear_x87_fpu_status_word ENDP
1175 _TEXT   ENDS
1176
1177
1178 ;------------------------------------------------------------------------
1179 ; FUNCTION __kmp_invoke_microtask
1180 ;
1181 ; typedef void  (*microtask_t)( int *gtid, int *tid, ... );
1182 ;
1183 ; int
1184 ; __kmp_invoke_microtask( microtask_t pkfn,
1185 ;                         int gtid, int tid,
1186 ;                         int argc, void *p_argv[] ) {
1187 ;
1188 ;     (*pkfn) ( &gtid, &tid, argv[0], ... );
1189 ;     return 1;
1190 ; }
1191 ;
1192 ; note:
1193 ;      just before call to pkfn must have rsp 128-byte aligned for compiler
1194 ;
1195 ; parameters:
1196 ;      rcx:   pkfn      16[rbp]
1197 ;      edx:   gtid      24[rbp]
1198 ;      r8d:   tid       32[rbp]
1199 ;      r9d:   argc      40[rbp]
1200 ;      [st]:  p_argv    48[rbp]
1201 ;
1202 ; reg temps:
1203 ;      rax:   used all over the place
1204 ;      rdx:   used all over the place
1205 ;      rcx:   used as argument counter for push parms loop
1206 ;      r10:   used to hold pkfn function pointer argument
1207 ;
1208 ; return:      eax    (always 1/TRUE)
1209 $_pkfn   = 16
1210 $_gtid   = 24
1211 $_tid    = 32
1212 $_argc   = 40
1213 $_p_argv = 48
1214 if OMPT_SUPPORT
1215 $_exit_frame = 56
1216 endif
1217
1218 PUBLIC  __kmp_invoke_microtask
1219 _TEXT   SEGMENT
1220         ALIGN 16
1221
1222 __kmp_invoke_microtask PROC FRAME ;NEAR
1223         mov     QWORD PTR 16[rsp], rdx  ; home gtid parameter
1224         mov     QWORD PTR 24[rsp], r8   ; home tid parameter
1225         push    rbp             ; save base pointer
1226         .pushreg rbp
1227         sub     rsp, 0          ; no fixed allocation necessary - end prolog
1228
1229         lea     rbp, QWORD PTR [rsp]    ; establish the base pointer
1230         .setframe rbp, 0
1231         .ENDPROLOG
1232 if OMPT_SUPPORT
1233         mov     rax, QWORD PTR $_exit_frame[rbp]
1234         mov     QWORD PTR [rax], rbp
1235 endif
1236         mov     r10, rcx        ; save pkfn pointer for later
1237
1238 ;; ------------------------------------------------------------
1239         mov     rax, r9         ; rax <= argc
1240         cmp     rax, 2
1241         jge     SHORT $_kmp_invoke_stack_align
1242         mov     rax, 2          ; set 4 homes if less than 2 parms
1243 $_kmp_invoke_stack_align:
1244         lea     rdx, QWORD PTR [rax*8+16] ; rax <= (argc + 2) * 8
1245         mov     rax, rsp        ; Save current SP into rax
1246         sub     rax, rdx        ; rsp - ((argc+2)*8) -> rax
1247                                 ; without align, rsp would be this
1248         and     rax, -128       ; Mask off 7 bits (128-byte align)
1249         add     rax, rdx        ; add space for push's in a loop below
1250         mov     rsp, rax        ; Prepare the stack ptr
1251                                 ; Now it will align to 128-byte at the call
1252 ;; ------------------------------------------------------------
1253                                 ; setup pkfn parameter stack
1254         mov     rax, r9         ; rax <= argc
1255         shl     rax, 3          ; rax <= argc*8
1256         mov     rdx, QWORD PTR $_p_argv[rbp]    ; rdx <= p_argv
1257         add     rdx, rax        ; rdx <= &p_argv[argc]
1258         mov     rcx, r9         ; rcx <= argc
1259         jecxz   SHORT $_kmp_invoke_pass_parms   ; nothing to push if argc=0
1260         cmp     ecx, 1          ; if argc=1 branch ahead
1261         je      SHORT $_kmp_invoke_one_parm
1262         sub     ecx, 2          ; if argc=2 branch ahead, subtract two from
1263         je      SHORT $_kmp_invoke_two_parms
1264
1265 $_kmp_invoke_push_parms:        ; push last - 5th parms to pkfn on stack
1266         sub     rdx, 8          ; decrement p_argv pointer to previous parm
1267         mov     r8, QWORD PTR [rdx] ; r8 <= p_argv[rcx-1]
1268         push    r8              ; push p_argv[rcx-1] onto stack (reverse order)
1269         sub     ecx, 1
1270         jecxz   SHORT $_kmp_invoke_two_parms
1271         jmp     SHORT $_kmp_invoke_push_parms
1272
1273 $_kmp_invoke_two_parms:
1274         sub     rdx, 8          ; put 4th parm to pkfn in r9
1275         mov     r9, QWORD PTR [rdx] ; r9 <= p_argv[1]
1276
1277 $_kmp_invoke_one_parm:
1278         sub     rdx, 8          ; put 3rd parm to pkfn in r8
1279         mov     r8, QWORD PTR [rdx] ; r8 <= p_argv[0]
1280
1281 $_kmp_invoke_pass_parms:        ; put 1st & 2nd parms to pkfn in registers
1282         lea     rdx, QWORD PTR $_tid[rbp]  ; rdx <= &tid (2nd parm to pkfn)
1283         lea     rcx, QWORD PTR $_gtid[rbp] ; rcx <= &gtid (1st parm to pkfn)
1284         sub     rsp, 32         ; add stack space for first four parms
1285         mov     rax, r10        ; rax <= pkfn
1286         call    rax             ; call (*pkfn)()
1287         mov     rax, 1          ; move 1 into return register;
1288
1289         lea     rsp, QWORD PTR [rbp]    ; restore stack pointer
1290
1291 ;       add     rsp, 0          ; no fixed allocation necessary - start epilog
1292         pop     rbp             ; restore frame pointer
1293         ret
1294 __kmp_invoke_microtask ENDP
1295 _TEXT   ENDS
1296
1297 endif
1298
1299 END