1345153Sdim;  z_Windows_NT-586_asm.asm:  - microtasking routines specifically
2345153Sdim;    written for IA-32 architecture and Intel(R) 64 running Windows* OS
3345153Sdim
4345153Sdim;
5345153Sdim;//===----------------------------------------------------------------------===//
6345153Sdim;//
7353358Sdim;// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
8353358Sdim;// See https://llvm.org/LICENSE.txt for license information.
9353358Sdim;// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
10345153Sdim;//
11345153Sdim;//===----------------------------------------------------------------------===//
12345153Sdim;
13345153Sdim
14345153Sdim        TITLE   z_Windows_NT-586_asm.asm
15345153Sdim
16345153Sdim; ============================= IA-32 architecture ==========================
17345153Sdimifdef _M_IA32
18345153Sdim
19345153Sdim        .586P
20345153Sdim
21345153Sdimif @Version gt 510
22345153Sdim        .model HUGE
23345153Sdimelse
24345153Sdim_TEXT   SEGMENT PARA USE32 PUBLIC 'CODE'
25345153Sdim_TEXT   ENDS
26345153Sdim_DATA   SEGMENT DWORD USE32 PUBLIC 'DATA'
27345153Sdim_DATA   ENDS
28345153SdimCONST   SEGMENT DWORD USE32 PUBLIC 'CONST'
29345153SdimCONST   ENDS
30345153Sdim_BSS    SEGMENT DWORD USE32 PUBLIC 'BSS'
31345153Sdim_BSS    ENDS
32345153Sdim$$SYMBOLS       SEGMENT BYTE USE32 'DEBSYM'
33345153Sdim$$SYMBOLS       ENDS
34345153Sdim$$TYPES SEGMENT BYTE USE32 'DEBTYP'
35345153Sdim$$TYPES ENDS
36345153Sdim_TLS    SEGMENT DWORD USE32 PUBLIC 'TLS'
37345153Sdim_TLS    ENDS
38345153SdimFLAT    GROUP _DATA, CONST, _BSS
39345153Sdim        ASSUME  CS: FLAT, DS: FLAT, SS: FLAT
40345153Sdimendif
41345153Sdim
42345153Sdim
43345153Sdim;------------------------------------------------------------------------
44345153Sdim; FUNCTION ___kmp_x86_pause
45345153Sdim;
46345153Sdim; void
47345153Sdim; __kmp_x86_pause( void )
48345153SdimPUBLIC  ___kmp_x86_pause
49345153Sdim_p$ = 4
50345153Sdim_d$ = 8
51345153Sdim_TEXT   SEGMENT
52345153Sdim        ALIGN 16
53345153Sdim___kmp_x86_pause PROC NEAR
54345153Sdim
55345153Sdim        db      0f3H
56345153Sdim        db      090H    ;; pause
57345153Sdim        ret
58345153Sdim
59345153Sdim___kmp_x86_pause ENDP
60345153Sdim_TEXT   ENDS
61345153Sdim
62345153Sdim;------------------------------------------------------------------------
63345153Sdim; FUNCTION ___kmp_x86_cpuid
64345153Sdim;
65345153Sdim; void
66345153Sdim; __kmp_x86_cpuid( int mode, int mode2, struct kmp_cpuid *p );
67345153SdimPUBLIC  ___kmp_x86_cpuid
68345153Sdim_TEXT   SEGMENT
69345153Sdim        ALIGN 16
70345153Sdim_mode$  = 8
71345153Sdim_mode2$ = 12
72345153Sdim_p$     = 16
73345153Sdim_eax$   = 0
74345153Sdim_ebx$   = 4
75345153Sdim_ecx$   = 8
76345153Sdim_edx$   = 12
77345153Sdim
78345153Sdim___kmp_x86_cpuid PROC NEAR
79345153Sdim
80345153Sdim        push      ebp
81345153Sdim        mov       ebp, esp
82345153Sdim
83345153Sdim        push      edi
84345153Sdim        push      ebx
85345153Sdim        push      ecx
86345153Sdim        push      edx
87345153Sdim
88345153Sdim        mov	  eax, DWORD PTR _mode$[ebp]
89345153Sdim        mov	  ecx, DWORD PTR _mode2$[ebp]
90345153Sdim	cpuid					; Query the CPUID for the current processor
91345153Sdim
92345153Sdim        mov       edi, DWORD PTR _p$[ebp]
93345153Sdim	mov 	  DWORD PTR _eax$[ edi ], eax
94345153Sdim	mov 	  DWORD PTR _ebx$[ edi ], ebx
95345153Sdim	mov 	  DWORD PTR _ecx$[ edi ], ecx
96345153Sdim	mov 	  DWORD PTR _edx$[ edi ], edx
97345153Sdim
98345153Sdim        pop       edx
99345153Sdim        pop       ecx
100345153Sdim        pop       ebx
101345153Sdim        pop       edi
102345153Sdim
103345153Sdim        mov       esp, ebp
104345153Sdim        pop       ebp
105345153Sdim        ret
106345153Sdim
107345153Sdim___kmp_x86_cpuid ENDP
108345153Sdim_TEXT     ENDS
109345153Sdim
110345153Sdim;------------------------------------------------------------------------
111345153Sdim; FUNCTION ___kmp_test_then_add32
112345153Sdim;
113345153Sdim; kmp_int32
114345153Sdim; __kmp_test_then_add32( volatile kmp_int32 *p, kmp_int32 d );
115345153SdimPUBLIC  ___kmp_test_then_add32
116345153Sdim_p$ = 4
117345153Sdim_d$ = 8
118345153Sdim_TEXT   SEGMENT
119345153Sdim        ALIGN 16
120345153Sdim___kmp_test_then_add32 PROC NEAR
121345153Sdim
122345153Sdim        mov     eax, DWORD PTR _d$[esp]
123345153Sdim        mov     ecx, DWORD PTR _p$[esp]
124345153Sdimlock    xadd    DWORD PTR [ecx], eax
125345153Sdim        ret
126345153Sdim
127345153Sdim___kmp_test_then_add32 ENDP
128345153Sdim_TEXT   ENDS
129345153Sdim
130345153Sdim;------------------------------------------------------------------------
131345153Sdim; FUNCTION ___kmp_compare_and_store8
132345153Sdim;
133345153Sdim; kmp_int8
134345153Sdim; __kmp_compare_and_store8( volatile kmp_int8 *p, kmp_int8 cv, kmp_int8 sv );
135345153SdimPUBLIC  ___kmp_compare_and_store8
136345153Sdim_TEXT   SEGMENT
137345153Sdim        ALIGN 16
138345153Sdim_p$ = 4
139345153Sdim_cv$ = 8
140345153Sdim_sv$ = 12
141345153Sdim
142345153Sdim___kmp_compare_and_store8 PROC NEAR
143345153Sdim
144345153Sdim        mov       ecx, DWORD PTR _p$[esp]
145345153Sdim        mov       al, BYTE PTR _cv$[esp]
146345153Sdim        mov       dl, BYTE PTR _sv$[esp]
147345153Sdimlock    cmpxchg   BYTE PTR [ecx], dl
148345153Sdim        sete      al           ; if al == [ecx] set al = 1 else set al = 0
149345153Sdim        and       eax, 1       ; sign extend previous instruction
150345153Sdim        ret
151345153Sdim
152345153Sdim___kmp_compare_and_store8 ENDP
153345153Sdim_TEXT     ENDS
154345153Sdim
155345153Sdim;------------------------------------------------------------------------
156345153Sdim; FUNCTION ___kmp_compare_and_store16
157345153Sdim;
158345153Sdim; kmp_int16
159345153Sdim; __kmp_compare_and_store16( volatile kmp_int16 *p, kmp_int16 cv, kmp_int16 sv );
160345153SdimPUBLIC  ___kmp_compare_and_store16
161345153Sdim_TEXT   SEGMENT
162345153Sdim        ALIGN 16
163345153Sdim_p$ = 4
164345153Sdim_cv$ = 8
165345153Sdim_sv$ = 12
166345153Sdim
167345153Sdim___kmp_compare_and_store16 PROC NEAR
168345153Sdim
169345153Sdim        mov       ecx, DWORD PTR _p$[esp]
170345153Sdim        mov       ax, WORD PTR _cv$[esp]
171345153Sdim        mov       dx, WORD PTR _sv$[esp]
172345153Sdimlock    cmpxchg   WORD PTR [ecx], dx
173345153Sdim        sete      al           ; if ax == [ecx] set al = 1 else set al = 0
174345153Sdim        and       eax, 1       ; sign extend previous instruction
175345153Sdim        ret
176345153Sdim
177345153Sdim___kmp_compare_and_store16 ENDP
178345153Sdim_TEXT     ENDS
179345153Sdim
180345153Sdim;------------------------------------------------------------------------
181345153Sdim; FUNCTION ___kmp_compare_and_store32
182345153Sdim;
183345153Sdim; kmp_int32
184345153Sdim; __kmp_compare_and_store32( volatile kmp_int32 *p, kmp_int32 cv, kmp_int32 sv );
185345153SdimPUBLIC  ___kmp_compare_and_store32
186345153Sdim_TEXT   SEGMENT
187345153Sdim        ALIGN 16
188345153Sdim_p$ = 4
189345153Sdim_cv$ = 8
190345153Sdim_sv$ = 12
191345153Sdim
192345153Sdim___kmp_compare_and_store32 PROC NEAR
193345153Sdim
194345153Sdim        mov       ecx, DWORD PTR _p$[esp]
195345153Sdim        mov       eax, DWORD PTR _cv$[esp]
196345153Sdim        mov       edx, DWORD PTR _sv$[esp]
197345153Sdimlock    cmpxchg   DWORD PTR [ecx], edx
198345153Sdim        sete      al           ; if eax == [ecx] set al = 1 else set al = 0
199345153Sdim        and       eax, 1       ; sign extend previous instruction
200345153Sdim        ret
201345153Sdim
202345153Sdim___kmp_compare_and_store32 ENDP
203345153Sdim_TEXT     ENDS
204345153Sdim
205345153Sdim;------------------------------------------------------------------------
206345153Sdim; FUNCTION ___kmp_compare_and_store64
207345153Sdim;
208345153Sdim; kmp_int32
209345153Sdim; __kmp_compare_and_store64( volatile kmp_int64 *p, kmp_int64 cv, kmp_int64 sv );
210345153SdimPUBLIC  ___kmp_compare_and_store64
211345153Sdim_TEXT   SEGMENT
212345153Sdim        ALIGN 16
213345153Sdim_p$ = 8
214345153Sdim_cv_low$ = 12
215345153Sdim_cv_high$ = 16
216345153Sdim_sv_low$ = 20
217345153Sdim_sv_high$ = 24
218345153Sdim
219345153Sdim___kmp_compare_and_store64 PROC NEAR
220345153Sdim
221345153Sdim        push      ebp
222345153Sdim        mov       ebp, esp
223345153Sdim        push      ebx
224345153Sdim        push      edi
225345153Sdim        mov       edi, DWORD PTR _p$[ebp]
226345153Sdim        mov       eax, DWORD PTR _cv_low$[ebp]
227345153Sdim        mov       edx, DWORD PTR _cv_high$[ebp]
228345153Sdim        mov       ebx, DWORD PTR _sv_low$[ebp]
229345153Sdim        mov       ecx, DWORD PTR _sv_high$[ebp]
230345153Sdimlock    cmpxchg8b QWORD PTR [edi]
231345153Sdim        sete      al           ; if edx:eax == [edi] set al = 1 else set al = 0
232345153Sdim        and       eax, 1       ; sign extend previous instruction
233345153Sdim        pop       edi
234345153Sdim        pop       ebx
235345153Sdim        mov       esp, ebp
236345153Sdim        pop       ebp
237345153Sdim        ret
238345153Sdim
239345153Sdim___kmp_compare_and_store64 ENDP
240345153Sdim_TEXT     ENDS
241345153Sdim
242345153Sdim;------------------------------------------------------------------------
243345153Sdim; FUNCTION ___kmp_xchg_fixed8
244345153Sdim;
245345153Sdim; kmp_int8
246345153Sdim; __kmp_xchg_fixed8( volatile kmp_int8 *p, kmp_int8 d );
247345153SdimPUBLIC  ___kmp_xchg_fixed8
248345153Sdim_TEXT   SEGMENT
249345153Sdim        ALIGN 16
250345153Sdim_p$ = 4
251345153Sdim_d$ = 8
252345153Sdim
253345153Sdim___kmp_xchg_fixed8 PROC NEAR
254345153Sdim
255345153Sdim        mov       ecx, DWORD PTR _p$[esp]
256345153Sdim        mov       al,  BYTE PTR _d$[esp]
257345153Sdimlock    xchg      BYTE PTR [ecx], al
258345153Sdim        ret
259345153Sdim
260345153Sdim___kmp_xchg_fixed8 ENDP
261345153Sdim_TEXT     ENDS
262345153Sdim
263345153Sdim;------------------------------------------------------------------------
264345153Sdim; FUNCTION ___kmp_xchg_fixed16
265345153Sdim;
266345153Sdim; kmp_int16
267345153Sdim; __kmp_xchg_fixed16( volatile kmp_int16 *p, kmp_int16 d );
268345153SdimPUBLIC  ___kmp_xchg_fixed16
269345153Sdim_TEXT   SEGMENT
270345153Sdim        ALIGN 16
271345153Sdim_p$ = 4
272345153Sdim_d$ = 8
273345153Sdim
274345153Sdim___kmp_xchg_fixed16 PROC NEAR
275345153Sdim
276345153Sdim        mov       ecx, DWORD PTR _p$[esp]
277345153Sdim        mov       ax,  WORD PTR  _d$[esp]
278345153Sdimlock    xchg      WORD PTR [ecx], ax
279345153Sdim        ret
280345153Sdim
281345153Sdim___kmp_xchg_fixed16 ENDP
282345153Sdim_TEXT     ENDS
283345153Sdim
284345153Sdim;------------------------------------------------------------------------
285345153Sdim; FUNCTION ___kmp_xchg_fixed32
286345153Sdim;
287345153Sdim; kmp_int32
288345153Sdim; __kmp_xchg_fixed32( volatile kmp_int32 *p, kmp_int32 d );
289345153SdimPUBLIC  ___kmp_xchg_fixed32
290345153Sdim_TEXT   SEGMENT
291345153Sdim        ALIGN 16
292345153Sdim_p$ = 4
293345153Sdim_d$ = 8
294345153Sdim
295345153Sdim___kmp_xchg_fixed32 PROC NEAR
296345153Sdim
297345153Sdim        mov       ecx, DWORD PTR _p$[esp]
298345153Sdim        mov       eax, DWORD PTR _d$[esp]
299345153Sdimlock    xchg      DWORD PTR [ecx], eax
300345153Sdim        ret
301345153Sdim
302345153Sdim___kmp_xchg_fixed32 ENDP
303345153Sdim_TEXT     ENDS
304345153Sdim
305345153Sdim
306345153Sdim;------------------------------------------------------------------------
307345153Sdim; FUNCTION ___kmp_xchg_real32
308345153Sdim;
309345153Sdim; kmp_real32
310345153Sdim; __kmp_xchg_real32( volatile kmp_real32 *p, kmp_real32 d );
311345153SdimPUBLIC  ___kmp_xchg_real32
312345153Sdim_TEXT   SEGMENT
313345153Sdim        ALIGN 16
314345153Sdim_p$ = 8
315345153Sdim_d$ = 12
316345153Sdim_old_value$ = -4
317345153Sdim
318345153Sdim___kmp_xchg_real32 PROC NEAR
319345153Sdim
320345153Sdim        push    ebp
321345153Sdim        mov     ebp, esp
322345153Sdim        sub     esp, 4
323345153Sdim        push    esi
324345153Sdim        mov     esi, DWORD PTR _p$[ebp]
325345153Sdim
326345153Sdim        fld     DWORD PTR [esi]
327345153Sdim                        ;; load <addr>
328345153Sdim        fst     DWORD PTR _old_value$[ebp]
329345153Sdim                        ;; store into old_value
330345153Sdim
331345153Sdim        mov     eax, DWORD PTR _d$[ebp]
332345153Sdim
333345153Sdimlock    xchg    DWORD PTR [esi], eax
334345153Sdim
335345153Sdim        fld     DWORD PTR _old_value$[ebp]
336345153Sdim                        ;; return old_value
337345153Sdim        pop     esi
338345153Sdim        mov     esp, ebp
339345153Sdim        pop     ebp
340345153Sdim        ret
341345153Sdim
342345153Sdim___kmp_xchg_real32 ENDP
343345153Sdim_TEXT   ENDS
344345153Sdim
345345153Sdim
346345153Sdim;------------------------------------------------------------------------
347345153Sdim; FUNCTION ___kmp_compare_and_store_ret8
348345153Sdim;
349345153Sdim; kmp_int8
350345153Sdim; __kmp_compare_and_store_ret8( volatile kmp_int8 *p, kmp_int8 cv, kmp_int8 sv );
351345153SdimPUBLIC  ___kmp_compare_and_store_ret8
352345153Sdim_TEXT   SEGMENT
353345153Sdim        ALIGN 16
354345153Sdim_p$ = 4
355345153Sdim_cv$ = 8
356345153Sdim_sv$ = 12
357345153Sdim
358345153Sdim___kmp_compare_and_store_ret8 PROC NEAR
359345153Sdim
360345153Sdim        mov       ecx, DWORD PTR _p$[esp]
361345153Sdim        mov       al, BYTE PTR _cv$[esp]
362345153Sdim        mov       dl, BYTE PTR _sv$[esp]
363345153Sdimlock    cmpxchg   BYTE PTR [ecx], dl
364345153Sdim        ret
365345153Sdim
366345153Sdim___kmp_compare_and_store_ret8 ENDP
367345153Sdim_TEXT     ENDS
368345153Sdim
369345153Sdim;------------------------------------------------------------------------
370345153Sdim; FUNCTION ___kmp_compare_and_store_ret16
371345153Sdim;
372345153Sdim; kmp_int16
373345153Sdim; __kmp_compare_and_store_ret16( volatile kmp_int16 *p, kmp_int16 cv, kmp_int16 sv );
374345153SdimPUBLIC  ___kmp_compare_and_store_ret16
375345153Sdim_TEXT   SEGMENT
376345153Sdim        ALIGN 16
377345153Sdim_p$ = 4
378345153Sdim_cv$ = 8
379345153Sdim_sv$ = 12
380345153Sdim
381345153Sdim___kmp_compare_and_store_ret16 PROC NEAR
382345153Sdim
383345153Sdim        mov       ecx, DWORD PTR _p$[esp]
384345153Sdim        mov       ax, WORD PTR _cv$[esp]
385345153Sdim        mov       dx, WORD PTR _sv$[esp]
386345153Sdimlock    cmpxchg   WORD PTR [ecx], dx
387345153Sdim        ret
388345153Sdim
389345153Sdim___kmp_compare_and_store_ret16 ENDP
390345153Sdim_TEXT     ENDS
391345153Sdim
392345153Sdim;------------------------------------------------------------------------
393345153Sdim; FUNCTION ___kmp_compare_and_store_ret32
394345153Sdim;
395345153Sdim; kmp_int32
396345153Sdim; __kmp_compare_and_store_ret32( volatile kmp_int32 *p, kmp_int32 cv, kmp_int32 sv );
397345153SdimPUBLIC  ___kmp_compare_and_store_ret32
398345153Sdim_TEXT   SEGMENT
399345153Sdim        ALIGN 16
400345153Sdim_p$ = 4
401345153Sdim_cv$ = 8
402345153Sdim_sv$ = 12
403345153Sdim
404345153Sdim___kmp_compare_and_store_ret32 PROC NEAR
405345153Sdim
406345153Sdim        mov       ecx, DWORD PTR _p$[esp]
407345153Sdim        mov       eax, DWORD PTR _cv$[esp]
408345153Sdim        mov       edx, DWORD PTR _sv$[esp]
409345153Sdimlock    cmpxchg   DWORD PTR [ecx], edx
410345153Sdim        ret
411345153Sdim
412345153Sdim___kmp_compare_and_store_ret32 ENDP
413345153Sdim_TEXT     ENDS
414345153Sdim
415345153Sdim;------------------------------------------------------------------------
416345153Sdim; FUNCTION ___kmp_compare_and_store_ret64
417345153Sdim;
418345153Sdim; kmp_int64
419345153Sdim; __kmp_compare_and_store_ret64( volatile kmp_int64 *p, kmp_int64 cv, kmp_int64 sv );
420345153SdimPUBLIC  ___kmp_compare_and_store_ret64
421345153Sdim_TEXT   SEGMENT
422345153Sdim        ALIGN 16
423345153Sdim_p$ = 8
424345153Sdim_cv_low$ = 12
425345153Sdim_cv_high$ = 16
426345153Sdim_sv_low$ = 20
427345153Sdim_sv_high$ = 24
428345153Sdim
429345153Sdim___kmp_compare_and_store_ret64 PROC NEAR
430345153Sdim
431345153Sdim        push      ebp
432345153Sdim        mov       ebp, esp
433345153Sdim        push      ebx
434345153Sdim        push      edi
435345153Sdim        mov       edi, DWORD PTR _p$[ebp]
436345153Sdim        mov       eax, DWORD PTR _cv_low$[ebp]
437345153Sdim        mov       edx, DWORD PTR _cv_high$[ebp]
438345153Sdim        mov       ebx, DWORD PTR _sv_low$[ebp]
439345153Sdim        mov       ecx, DWORD PTR _sv_high$[ebp]
440345153Sdimlock    cmpxchg8b QWORD PTR [edi]
441345153Sdim        pop       edi
442345153Sdim        pop       ebx
443345153Sdim        mov       esp, ebp
444345153Sdim        pop       ebp
445345153Sdim        ret
446345153Sdim
447345153Sdim___kmp_compare_and_store_ret64 ENDP
448345153Sdim_TEXT     ENDS
449345153Sdim
450345153Sdim;------------------------------------------------------------------------
451345153Sdim; FUNCTION ___kmp_load_x87_fpu_control_word
452345153Sdim;
453345153Sdim; void
454345153Sdim; __kmp_load_x87_fpu_control_word( kmp_int16 *p );
455345153Sdim;
456345153Sdim; parameters:
457345153Sdim;       p:      4(%esp)
458345153SdimPUBLIC  ___kmp_load_x87_fpu_control_word
459345153Sdim_TEXT   SEGMENT
460345153Sdim        ALIGN 16
461345153Sdim_p$ = 4
462345153Sdim
463345153Sdim___kmp_load_x87_fpu_control_word PROC NEAR
464345153Sdim
465345153Sdim        mov       eax, DWORD PTR _p$[esp]
466345153Sdim        fldcw     WORD PTR [eax]
467345153Sdim        ret
468345153Sdim
469345153Sdim___kmp_load_x87_fpu_control_word ENDP
470345153Sdim_TEXT     ENDS
471345153Sdim
472345153Sdim;------------------------------------------------------------------------
473345153Sdim; FUNCTION ___kmp_store_x87_fpu_control_word
474345153Sdim;
475345153Sdim; void
476345153Sdim; __kmp_store_x87_fpu_control_word( kmp_int16 *p );
477345153Sdim;
478345153Sdim; parameters:
479345153Sdim;       p:      4(%esp)
480345153SdimPUBLIC  ___kmp_store_x87_fpu_control_word
481345153Sdim_TEXT   SEGMENT
482345153Sdim        ALIGN 16
483345153Sdim_p$ = 4
484345153Sdim
485345153Sdim___kmp_store_x87_fpu_control_word PROC NEAR
486345153Sdim
487345153Sdim        mov       eax, DWORD PTR _p$[esp]
488345153Sdim        fstcw     WORD PTR [eax]
489345153Sdim        ret
490345153Sdim
491345153Sdim___kmp_store_x87_fpu_control_word ENDP
492345153Sdim_TEXT     ENDS
493345153Sdim
494345153Sdim;------------------------------------------------------------------------
495345153Sdim; FUNCTION ___kmp_clear_x87_fpu_status_word
496345153Sdim;
497345153Sdim; void
498345153Sdim; __kmp_clear_x87_fpu_status_word();
499345153SdimPUBLIC  ___kmp_clear_x87_fpu_status_word
500345153Sdim_TEXT   SEGMENT
501345153Sdim        ALIGN 16
502345153Sdim
503345153Sdim___kmp_clear_x87_fpu_status_word PROC NEAR
504345153Sdim
505345153Sdim        fnclex
506345153Sdim        ret
507345153Sdim
508345153Sdim___kmp_clear_x87_fpu_status_word ENDP
509345153Sdim_TEXT     ENDS
510345153Sdim
511345153Sdim
512345153Sdim;------------------------------------------------------------------------
513345153Sdim; FUNCTION ___kmp_invoke_microtask
514345153Sdim;
515345153Sdim; typedef void  (*microtask_t)( int *gtid, int *tid, ... );
516345153Sdim;
517345153Sdim; int
518345153Sdim; __kmp_invoke_microtask( microtask_t pkfn,
519345153Sdim;                         int gtid, int tid,
520345153Sdim;                         int argc, void *p_argv[] )
521345153SdimPUBLIC  ___kmp_invoke_microtask
522345153Sdim_TEXT   SEGMENT
523345153Sdim        ALIGN 16
524345153Sdim_pkfn$ = 8
525345153Sdim_gtid$ = 12
526345153Sdim_tid$ = 16
527345153Sdim_argc$ = 20
528345153Sdim_argv$ = 24
529345153Sdimif OMPT_SUPPORT
530345153Sdim_exit_frame$ = 28
531345153Sdimendif
532345153Sdim_i$ = -8
533345153Sdim_stk_adj$ = -16
534345153Sdim_vptr$ = -12
535345153Sdim_qptr$ = -4
536345153Sdim
537345153Sdim___kmp_invoke_microtask PROC NEAR
538345153Sdim; Line 102
539345153Sdim        push    ebp
540345153Sdim        mov     ebp, esp
541345153Sdim        sub     esp, 16                                 ; 00000010H
542345153Sdim        push    ebx
543345153Sdim        push    esi
544345153Sdim        push    edi
545345153Sdimif OMPT_SUPPORT
546345153Sdim        mov     eax, DWORD PTR _exit_frame$[ebp]
547345153Sdim        mov     DWORD PTR [eax], ebp
548345153Sdimendif
549345153Sdim; Line 114
550345153Sdim        mov     eax, DWORD PTR _argc$[ebp]
551345153Sdim        mov     DWORD PTR _i$[ebp], eax
552345153Sdim
553345153Sdim;; ------------------------------------------------------------
554345153Sdim	lea     edx, DWORD PTR [eax*4+8]
555345153Sdim	mov     ecx, esp                                ; Save current SP into ECX
556345153Sdim	mov	eax,edx		; Save the size of the args in eax
557345153Sdim	sub	ecx,edx		; esp-((#args+2)*4) -> ecx -- without mods, stack ptr would be this
558345153Sdim	mov	edx,ecx		; Save to edx
559345153Sdim	and	ecx,-128	; Mask off 7 bits
560345153Sdim	sub	edx,ecx		; Amount to subtract from esp
561345153Sdim	sub	esp,edx		; Prepare stack ptr-- Now it will be aligned on 128-byte boundary at the call
562345153Sdim
563345153Sdim	add	edx,eax		; Calculate total size of the stack decrement.
564345153Sdim        mov     DWORD PTR _stk_adj$[ebp], edx
565345153Sdim;; ------------------------------------------------------------
566345153Sdim
567345153Sdim        jmp     SHORT $L22237
568345153Sdim$L22238:
569345153Sdim        mov     ecx, DWORD PTR _i$[ebp]
570345153Sdim        sub     ecx, 1
571345153Sdim        mov     DWORD PTR _i$[ebp], ecx
572345153Sdim$L22237:
573345153Sdim        cmp     DWORD PTR _i$[ebp], 0
574345153Sdim        jle     SHORT $L22239
575345153Sdim; Line 116
576345153Sdim        mov     edx, DWORD PTR _i$[ebp]
577345153Sdim        mov     eax, DWORD PTR _argv$[ebp]
578345153Sdim        mov     ecx, DWORD PTR [eax+edx*4-4]
579345153Sdim        mov     DWORD PTR _vptr$[ebp], ecx
580345153Sdim; Line 123
581345153Sdim        mov     eax, DWORD PTR _vptr$[ebp]
582345153Sdim; Line 124
583345153Sdim        push    eax
584345153Sdim; Line 127
585345153Sdim        jmp     SHORT $L22238
586345153Sdim$L22239:
587345153Sdim; Line 129
588345153Sdim        lea     edx, DWORD PTR _tid$[ebp]
589345153Sdim        mov     DWORD PTR _vptr$[ebp], edx
590345153Sdim; Line 130
591345153Sdim        lea     eax, DWORD PTR _gtid$[ebp]
592345153Sdim        mov     DWORD PTR _qptr$[ebp], eax
593345153Sdim; Line 143
594345153Sdim        mov     eax, DWORD PTR _vptr$[ebp]
595345153Sdim; Line 144
596345153Sdim        push    eax
597345153Sdim; Line 145
598345153Sdim        mov     eax, DWORD PTR _qptr$[ebp]
599345153Sdim; Line 146
600345153Sdim        push    eax
601345153Sdim; Line 147
602345153Sdim        call    DWORD PTR _pkfn$[ebp]
603345153Sdim; Line 148
604345153Sdim        add     esp, DWORD PTR _stk_adj$[ebp]
605345153Sdim; Line 152
606345153Sdim        mov     eax, 1
607345153Sdim; Line 153
608345153Sdim        pop     edi
609345153Sdim        pop     esi
610345153Sdim        pop     ebx
611345153Sdim        mov     esp, ebp
612345153Sdim        pop     ebp
613345153Sdim        ret     0
614345153Sdim___kmp_invoke_microtask ENDP
615345153Sdim_TEXT   ENDS
616345153Sdim
617345153Sdimendif
618345153Sdim
619345153Sdim; ==================================== Intel(R) 64 ===================================
620345153Sdim
621345153Sdimifdef _M_AMD64
622345153Sdim
623345153Sdim;------------------------------------------------------------------------
624345153Sdim; FUNCTION __kmp_x86_cpuid
625345153Sdim;
626345153Sdim; void
627345153Sdim; __kmp_x86_cpuid( int mode, int mode2, struct kmp_cpuid *p );
628345153Sdim;
629345153Sdim; parameters:
630345153Sdim;	mode:		ecx
631345153Sdim;	mode2:		edx
632345153Sdim;	cpuid_buffer: 	r8
633345153SdimPUBLIC  __kmp_x86_cpuid
634345153Sdim_TEXT   SEGMENT
635345153Sdim        ALIGN 16
636345153Sdim
637345153Sdim__kmp_x86_cpuid PROC FRAME ;NEAR
638345153Sdim
639345153Sdim        push      rbp
640345153Sdim        .pushreg  rbp
641345153Sdim        mov       rbp, rsp
642345153Sdim        .setframe rbp, 0
643345153Sdim        push      rbx				; callee-save register
644345153Sdim        .pushreg  rbx
645345153Sdim        .ENDPROLOG
646345153Sdim
647345153Sdim	mov	  r10, r8                       ; p parameter
648345153Sdim        mov	  eax, ecx			; mode parameter
649345153Sdim        mov	  ecx, edx                      ; mode2 parameter
650345153Sdim	cpuid					; Query the CPUID for the current processor
651345153Sdim
652345153Sdim	mov 	  DWORD PTR 0[ r10 ], eax	; store results into buffer
653345153Sdim	mov 	  DWORD PTR 4[ r10 ], ebx
654345153Sdim	mov 	  DWORD PTR 8[ r10 ], ecx
655345153Sdim	mov 	  DWORD PTR 12[ r10 ], edx
656345153Sdim
657345153Sdim        pop       rbx				; callee-save register
658345153Sdim        mov       rsp, rbp
659345153Sdim        pop       rbp
660345153Sdim        ret
661345153Sdim
662345153Sdim__kmp_x86_cpuid ENDP
663345153Sdim_TEXT     ENDS
664345153Sdim
665345153Sdim
666345153Sdim;------------------------------------------------------------------------
667345153Sdim; FUNCTION __kmp_test_then_add32
668345153Sdim;
669345153Sdim; kmp_int32
670345153Sdim; __kmp_test_then_add32( volatile kmp_int32 *p, kmp_int32 d );
671345153Sdim;
672345153Sdim; parameters:
673345153Sdim;	p:	rcx
674345153Sdim;	d:	edx
675345153Sdim;
676345153Sdim; return: 	eax
677345153SdimPUBLIC  __kmp_test_then_add32
678345153Sdim_TEXT   SEGMENT
679345153Sdim        ALIGN 16
680345153Sdim__kmp_test_then_add32 PROC ;NEAR
681345153Sdim
682345153Sdim        mov     eax, edx
683345153Sdimlock    xadd    DWORD PTR [rcx], eax
684345153Sdim        ret
685345153Sdim
686345153Sdim__kmp_test_then_add32 ENDP
687345153Sdim_TEXT   ENDS
688345153Sdim
689345153Sdim
690345153Sdim;------------------------------------------------------------------------
691345153Sdim; FUNCTION __kmp_test_then_add64
692345153Sdim;
693345153Sdim; kmp_int32
694345153Sdim; __kmp_test_then_add64( volatile kmp_int64 *p, kmp_int64 d );
695345153Sdim;
696345153Sdim; parameters:
697345153Sdim;	p:	rcx
698345153Sdim;	d:	rdx
699345153Sdim;
700345153Sdim; return: 	rax
701345153SdimPUBLIC  __kmp_test_then_add64
702345153Sdim_TEXT   SEGMENT
703345153Sdim        ALIGN 16
704345153Sdim__kmp_test_then_add64 PROC ;NEAR
705345153Sdim
706345153Sdim        mov     rax, rdx
707345153Sdimlock    xadd    QWORD PTR [rcx], rax
708345153Sdim        ret
709345153Sdim
710345153Sdim__kmp_test_then_add64 ENDP
711345153Sdim_TEXT   ENDS
712345153Sdim
713345153Sdim
714345153Sdim;------------------------------------------------------------------------
715345153Sdim; FUNCTION __kmp_compare_and_store8
716345153Sdim;
717345153Sdim; kmp_int8
718345153Sdim; __kmp_compare_and_store8( volatile kmp_int8 *p, kmp_int8 cv, kmp_int8 sv );
719345153Sdim; parameters:
720345153Sdim;	p:	rcx
721345153Sdim;	cv:	edx
722345153Sdim;	sv:	r8d
723345153Sdim;
724345153Sdim; return:	eax
725345153SdimPUBLIC  __kmp_compare_and_store8
726345153Sdim_TEXT   SEGMENT
727345153Sdim        ALIGN 16
728345153Sdim
729345153Sdim__kmp_compare_and_store8 PROC ;NEAR
730345153Sdim
731345153Sdim        mov       al, dl	; "cv"
732345153Sdim	mov	  edx, r8d	; "sv"
733345153Sdimlock    cmpxchg   BYTE PTR [rcx], dl
734345153Sdim        sete      al           	; if al == [rcx] set al = 1 else set al = 0
735345153Sdim        and       rax, 1       	; sign extend previous instruction
736345153Sdim        ret
737345153Sdim
738345153Sdim__kmp_compare_and_store8 ENDP
739345153Sdim_TEXT     ENDS
740345153Sdim
741345153Sdim
742345153Sdim;------------------------------------------------------------------------
743345153Sdim; FUNCTION __kmp_compare_and_store16
744345153Sdim;
745345153Sdim; kmp_int16
746345153Sdim; __kmp_compare_and_store16( volatile kmp_int16 *p, kmp_int16 cv, kmp_int16 sv );
747345153Sdim; parameters:
748345153Sdim;	p:	rcx
749345153Sdim;	cv:	edx
750345153Sdim;	sv:	r8d
751345153Sdim;
752345153Sdim; return:	eax
753345153SdimPUBLIC  __kmp_compare_and_store16
754345153Sdim_TEXT   SEGMENT
755345153Sdim        ALIGN 16
756345153Sdim
757345153Sdim__kmp_compare_and_store16 PROC ;NEAR
758345153Sdim
759345153Sdim        mov       ax, dx	; "cv"
760345153Sdim	mov	  edx, r8d	; "sv"
761345153Sdimlock    cmpxchg   WORD PTR [rcx], dx
762345153Sdim        sete      al           	; if ax == [rcx] set al = 1 else set al = 0
763345153Sdim        and       rax, 1       	; sign extend previous instruction
764345153Sdim        ret
765345153Sdim
766345153Sdim__kmp_compare_and_store16 ENDP
767345153Sdim_TEXT     ENDS
768345153Sdim
769345153Sdim
770345153Sdim;------------------------------------------------------------------------
771345153Sdim; FUNCTION __kmp_compare_and_store32
772345153Sdim;
773345153Sdim; kmp_int32
774345153Sdim; __kmp_compare_and_store32( volatile kmp_int32 *p, kmp_int32 cv, kmp_int32 sv );
775345153Sdim; parameters:
776345153Sdim;	p:	rcx
777345153Sdim;	cv:	edx
778345153Sdim;	sv:	r8d
779345153Sdim;
780345153Sdim; return:	eax
781345153SdimPUBLIC  __kmp_compare_and_store32
782345153Sdim_TEXT   SEGMENT
783345153Sdim        ALIGN 16
784345153Sdim
785345153Sdim__kmp_compare_and_store32 PROC ;NEAR
786345153Sdim
787345153Sdim        mov       eax, edx	; "cv"
788345153Sdim	mov	  edx, r8d	; "sv"
789345153Sdimlock    cmpxchg   DWORD PTR [rcx], edx
790345153Sdim        sete      al           	; if eax == [rcx] set al = 1 else set al = 0
791345153Sdim        and       rax, 1       	; sign extend previous instruction
792345153Sdim        ret
793345153Sdim
794345153Sdim__kmp_compare_and_store32 ENDP
795345153Sdim_TEXT     ENDS
796345153Sdim
797345153Sdim
798345153Sdim;------------------------------------------------------------------------
799345153Sdim; FUNCTION __kmp_compare_and_store64
800345153Sdim;
801345153Sdim; kmp_int32
802345153Sdim; __kmp_compare_and_store64( volatile kmp_int64 *p, kmp_int64 cv, kmp_int64 sv );
803345153Sdim; parameters:
804345153Sdim;	p:	rcx
805345153Sdim;	cv:	rdx
806345153Sdim;	sv:	r8
807345153Sdim;
808345153Sdim; return:	eax
809345153SdimPUBLIC  __kmp_compare_and_store64
810345153Sdim_TEXT   SEGMENT
811345153Sdim        ALIGN 16
812345153Sdim
813345153Sdim__kmp_compare_and_store64 PROC ;NEAR
814345153Sdim
815345153Sdim        mov       rax, rdx	; "cv"
816345153Sdim	mov	  rdx, r8	; "sv"
817345153Sdimlock    cmpxchg   QWORD PTR [rcx], rdx
818345153Sdim        sete      al           ; if rax == [rcx] set al = 1 else set al = 0
819345153Sdim        and       rax, 1       ; sign extend previous instruction
820345153Sdim        ret
821345153Sdim
822345153Sdim__kmp_compare_and_store64 ENDP
823345153Sdim_TEXT     ENDS
824345153Sdim
825345153Sdim
826345153Sdim;------------------------------------------------------------------------
827345153Sdim; FUNCTION ___kmp_xchg_fixed8
828345153Sdim;
829345153Sdim; kmp_int8
830345153Sdim; __kmp_xchg_fixed8( volatile kmp_int8 *p, kmp_int8 d );
831345153Sdim;
832345153Sdim; parameters:
833345153Sdim;	p:	rcx
834345153Sdim;	d:	dl
835345153Sdim;
836345153Sdim; return: 	al
837345153SdimPUBLIC  __kmp_xchg_fixed8
838345153Sdim_TEXT   SEGMENT
839345153Sdim        ALIGN 16
840345153Sdim
841345153Sdim__kmp_xchg_fixed8 PROC ;NEAR
842345153Sdim
843345153Sdim        mov       al,  dl
844345153Sdimlock    xchg      BYTE PTR [rcx], al
845345153Sdim        ret
846345153Sdim
847345153Sdim__kmp_xchg_fixed8 ENDP
848345153Sdim_TEXT     ENDS
849345153Sdim
850345153Sdim
851345153Sdim;------------------------------------------------------------------------
852345153Sdim; FUNCTION ___kmp_xchg_fixed16
853345153Sdim;
854345153Sdim; kmp_int16
855345153Sdim; __kmp_xchg_fixed16( volatile kmp_int16 *p, kmp_int16 d );
856345153Sdim;
857345153Sdim; parameters:
858345153Sdim;	p:	rcx
859345153Sdim;	d:	dx
860345153Sdim;
861345153Sdim; return: 	ax
862345153SdimPUBLIC  __kmp_xchg_fixed16
863345153Sdim_TEXT   SEGMENT
864345153Sdim        ALIGN 16
865345153Sdim
866345153Sdim__kmp_xchg_fixed16 PROC ;NEAR
867345153Sdim
868345153Sdim        mov       ax,  dx
869345153Sdimlock    xchg      WORD PTR [rcx], ax
870345153Sdim        ret
871345153Sdim
872345153Sdim__kmp_xchg_fixed16 ENDP
873345153Sdim_TEXT     ENDS
874345153Sdim
875345153Sdim
876345153Sdim;------------------------------------------------------------------------
877345153Sdim; FUNCTION ___kmp_xchg_fixed32
878345153Sdim;
879345153Sdim; kmp_int32
880345153Sdim; __kmp_xchg_fixed32( volatile kmp_int32 *p, kmp_int32 d );
881345153Sdim;
882345153Sdim; parameters:
883345153Sdim;	p:	rcx
884345153Sdim;	d:	edx
885345153Sdim;
886345153Sdim; return: 	eax
887345153SdimPUBLIC  __kmp_xchg_fixed32
888345153Sdim_TEXT   SEGMENT
889345153Sdim        ALIGN 16
890345153Sdim__kmp_xchg_fixed32 PROC ;NEAR
891345153Sdim
892345153Sdim        mov     eax, edx
893345153Sdimlock    xchg    DWORD PTR [rcx], eax
894345153Sdim        ret
895345153Sdim
896345153Sdim__kmp_xchg_fixed32 ENDP
897345153Sdim_TEXT   ENDS
898345153Sdim
899345153Sdim
900345153Sdim;------------------------------------------------------------------------
901345153Sdim; FUNCTION ___kmp_xchg_fixed64
902345153Sdim;
903345153Sdim; kmp_int64
904345153Sdim; __kmp_xchg_fixed64( volatile kmp_int64 *p, kmp_int64 d );
905345153Sdim;
906345153Sdim; parameters:
907345153Sdim;	p:	rcx
908345153Sdim;	d:	rdx
909345153Sdim;
910345153Sdim; return: 	rax
911345153SdimPUBLIC  __kmp_xchg_fixed64
912345153Sdim_TEXT   SEGMENT
913345153Sdim        ALIGN 16
914345153Sdim__kmp_xchg_fixed64 PROC ;NEAR
915345153Sdim
916345153Sdim        mov     rax, rdx
917345153Sdimlock    xchg    QWORD PTR [rcx], rax
918345153Sdim        ret
919345153Sdim
920345153Sdim__kmp_xchg_fixed64 ENDP
921345153Sdim_TEXT   ENDS
922345153Sdim
923345153Sdim
924345153Sdim;------------------------------------------------------------------------
925345153Sdim; FUNCTION __kmp_compare_and_store_ret8
926345153Sdim;
927345153Sdim; kmp_int8
928345153Sdim; __kmp_compare_and_store_ret8( volatile kmp_int8 *p, kmp_int8 cv, kmp_int8 sv );
929345153Sdim; parameters:
930345153Sdim;	p:	rcx
931345153Sdim;	cv:	edx
932345153Sdim;	sv:	r8d
933345153Sdim;
934345153Sdim; return:	eax
935345153SdimPUBLIC  __kmp_compare_and_store_ret8
936345153Sdim_TEXT   SEGMENT
937345153Sdim        ALIGN 16
938345153Sdim
939345153Sdim__kmp_compare_and_store_ret8 PROC ;NEAR
940345153Sdim        mov       al, dl	; "cv"
941345153Sdim	mov	  edx, r8d	; "sv"
942345153Sdimlock    cmpxchg   BYTE PTR [rcx], dl
943345153Sdim                        ; Compare AL with [rcx].  If equal set
944345153Sdim                        ; ZF and exchange DL with [rcx].  Else, clear
945345153Sdim                        ; ZF and load [rcx] into AL.
946345153Sdim        ret
947345153Sdim
948345153Sdim__kmp_compare_and_store_ret8 ENDP
949345153Sdim_TEXT     ENDS
950345153Sdim
951345153Sdim
952345153Sdim;------------------------------------------------------------------------
953345153Sdim; FUNCTION __kmp_compare_and_store_ret16
954345153Sdim;
955345153Sdim; kmp_int16
956345153Sdim; __kmp_compare_and_store_ret16( volatile kmp_int16 *p, kmp_int16 cv, kmp_int16 sv );
957345153Sdim; parameters:
958345153Sdim;	p:	rcx
959345153Sdim;	cv:	edx
960345153Sdim;	sv:	r8d
961345153Sdim;
962345153Sdim; return:	eax
963345153SdimPUBLIC  __kmp_compare_and_store_ret16
964345153Sdim_TEXT   SEGMENT
965345153Sdim        ALIGN 16
966345153Sdim
967345153Sdim__kmp_compare_and_store_ret16 PROC ;NEAR
968345153Sdim
969345153Sdim        mov       ax, dx	; "cv"
970345153Sdim	mov	  edx, r8d	; "sv"
971345153Sdimlock    cmpxchg   WORD PTR [rcx], dx
972345153Sdim        ret
973345153Sdim
974345153Sdim__kmp_compare_and_store_ret16 ENDP
975345153Sdim_TEXT     ENDS
976345153Sdim
977345153Sdim
978345153Sdim;------------------------------------------------------------------------
979345153Sdim; FUNCTION __kmp_compare_and_store_ret32
980345153Sdim;
981345153Sdim; kmp_int32
982345153Sdim; __kmp_compare_and_store_ret32( volatile kmp_int32 *p, kmp_int32 cv, kmp_int32 sv );
983345153Sdim; parameters:
984345153Sdim;	p:	rcx
985345153Sdim;	cv:	edx
986345153Sdim;	sv:	r8d
987345153Sdim;
988345153Sdim; return:	eax
989345153SdimPUBLIC  __kmp_compare_and_store_ret32
990345153Sdim_TEXT   SEGMENT
991345153Sdim        ALIGN 16
992345153Sdim
993345153Sdim__kmp_compare_and_store_ret32 PROC ;NEAR
994345153Sdim
995345153Sdim        mov       eax, edx	; "cv"
996345153Sdim	mov	  edx, r8d	; "sv"
997345153Sdimlock    cmpxchg   DWORD PTR [rcx], edx
998345153Sdim        ret
999345153Sdim
1000345153Sdim__kmp_compare_and_store_ret32 ENDP
1001345153Sdim_TEXT     ENDS
1002345153Sdim
1003345153Sdim
1004345153Sdim;------------------------------------------------------------------------
1005345153Sdim; FUNCTION __kmp_compare_and_store_ret64
1006345153Sdim;
1007345153Sdim; kmp_int64
1008345153Sdim; __kmp_compare_and_store_ret64( volatile kmp_int64 *p, kmp_int64 cv, kmp_int64 sv );
1009345153Sdim; parameters:
1010345153Sdim;	p:	rcx
1011345153Sdim;	cv:	rdx
1012345153Sdim;	sv:	r8
1013345153Sdim;
1014345153Sdim; return:	rax
1015345153SdimPUBLIC  __kmp_compare_and_store_ret64
1016345153Sdim_TEXT   SEGMENT
1017345153Sdim        ALIGN 16
1018345153Sdim
1019345153Sdim__kmp_compare_and_store_ret64 PROC ;NEAR
1020345153Sdim
1021345153Sdim        mov       rax, rdx	; "cv"
1022345153Sdim	mov	  rdx, r8	; "sv"
1023345153Sdimlock    cmpxchg   QWORD PTR [rcx], rdx
1024345153Sdim        ret
1025345153Sdim
1026345153Sdim__kmp_compare_and_store_ret64 ENDP
1027345153Sdim_TEXT     ENDS
1028345153Sdim
1029345153Sdim
1030345153Sdim;------------------------------------------------------------------------
1031345153Sdim; FUNCTION __kmp_compare_and_store_loop8
1032345153Sdim;
1033345153Sdim; kmp_int8
1034345153Sdim; __kmp_compare_and_store_loop8( volatile kmp_int8 *p, kmp_int8 cv, kmp_int8 sv );
1035345153Sdim; parameters:
1036345153Sdim;	p:	rcx
1037345153Sdim;	cv:	edx
1038345153Sdim;	sv:	r8d
1039345153Sdim;
1040345153Sdim; return:	al
1041345153SdimPUBLIC  __kmp_compare_and_store_loop8
1042345153Sdim_TEXT   SEGMENT
1043345153Sdim        ALIGN 16
1044345153Sdim
1045345153Sdim__kmp_compare_and_store_loop8 PROC ;NEAR
1046345153Sdim$__kmp_loop:
1047345153Sdim        mov       al, dl	; "cv"
1048345153Sdim	mov	  edx, r8d	; "sv"
1049345153Sdimlock    cmpxchg   BYTE PTR [rcx], dl
1050345153Sdim                        ; Compare AL with [rcx].  If equal set
1051345153Sdim                        ; ZF and exchange DL with [rcx].  Else, clear
1052345153Sdim                        ; ZF and load [rcx] into AL.
1053345153Sdim        jz     	SHORT $__kmp_success
1054345153Sdim
1055345153Sdim        db      0f3H
1056345153Sdim        db      090H    		; pause
1057345153Sdim
1058345153Sdim	jmp	SHORT $__kmp_loop
1059345153Sdim
1060345153Sdim$__kmp_success:
1061345153Sdim        ret
1062345153Sdim
1063345153Sdim__kmp_compare_and_store_loop8 ENDP
1064345153Sdim_TEXT     ENDS
1065345153Sdim
1066345153Sdim
1067345153Sdim;------------------------------------------------------------------------
1068345153Sdim; FUNCTION __kmp_xchg_real32
1069345153Sdim;
1070345153Sdim; kmp_real32
1071345153Sdim; __kmp_xchg_real32( volatile kmp_real32 *p, kmp_real32 d );
1072345153Sdim;
1073345153Sdim; parameters:
1074345153Sdim;	p:	rcx
1075345153Sdim;       d:	xmm1 (lower 4 bytes)
1076345153Sdim;
1077345153Sdim; return:	xmm0 (lower 4 bytes)
1078345153SdimPUBLIC  __kmp_xchg_real32
1079345153Sdim_TEXT   SEGMENT
1080345153Sdim        ALIGN 16
1081345153Sdim__kmp_xchg_real32 PROC ;NEAR
1082345153Sdim
1083345153Sdim	movd	eax, xmm1		; load d
1084345153Sdim
1085345153Sdimlock    xchg    DWORD PTR [rcx], eax
1086345153Sdim
1087345153Sdim	movd	xmm0, eax		; load old value into return register
1088345153Sdim        ret
1089345153Sdim
1090345153Sdim__kmp_xchg_real32 ENDP
1091345153Sdim_TEXT   ENDS
1092345153Sdim
1093345153Sdim
1094345153Sdim;------------------------------------------------------------------------
1095345153Sdim; FUNCTION __kmp_xchg_real64
1096345153Sdim;
1097345153Sdim; kmp_real64
1098345153Sdim; __kmp_xchg_real64( volatile kmp_real64 *p, kmp_real64 d );
1099345153Sdim;
1100345153Sdim; parameters:
1101345153Sdim;	p:	rcx
1102345153Sdim;	d:	xmm1 (lower 8 bytes)
1103345153Sdim;
1104345153Sdim; return:	xmm0 (lower 8 bytes)
1105345153SdimPUBLIC  __kmp_xchg_real64
1106345153Sdim_TEXT   SEGMENT
1107345153Sdim        ALIGN 16
1108345153Sdim__kmp_xchg_real64 PROC ;NEAR
1109345153Sdim
1110345153Sdim	movd	rax, xmm1		; load "d"
1111345153Sdim
1112345153Sdimlock    xchg    QWORD PTR [rcx], rax
1113345153Sdim
1114345153Sdim	movd	xmm0, rax		; load old value into return register
1115345153Sdim        ret
1116345153Sdim
1117345153Sdim__kmp_xchg_real64 ENDP
1118345153Sdim_TEXT   ENDS
1119345153Sdim
1120345153Sdim;------------------------------------------------------------------------
1121345153Sdim; FUNCTION __kmp_load_x87_fpu_control_word
1122345153Sdim;
1123345153Sdim; void
1124345153Sdim; __kmp_load_x87_fpu_control_word( kmp_int16 *p );
1125345153Sdim;
1126345153Sdim; parameters:
1127345153Sdim;	p:	rcx
1128345153SdimPUBLIC  __kmp_load_x87_fpu_control_word
1129345153Sdim_TEXT   SEGMENT
1130345153Sdim        ALIGN 16
1131345153Sdim__kmp_load_x87_fpu_control_word PROC ;NEAR
1132345153Sdim
1133345153Sdim        fldcw   WORD PTR [rcx]
1134345153Sdim        ret
1135345153Sdim
1136345153Sdim__kmp_load_x87_fpu_control_word ENDP
1137345153Sdim_TEXT   ENDS
1138345153Sdim
1139345153Sdim
1140345153Sdim;------------------------------------------------------------------------
1141345153Sdim; FUNCTION __kmp_store_x87_fpu_control_word
1142345153Sdim;
1143345153Sdim; void
1144345153Sdim; __kmp_store_x87_fpu_control_word( kmp_int16 *p );
1145345153Sdim;
1146345153Sdim; parameters:
1147345153Sdim;	p:	rcx
1148345153SdimPUBLIC  __kmp_store_x87_fpu_control_word
1149345153Sdim_TEXT   SEGMENT
1150345153Sdim        ALIGN 16
1151345153Sdim__kmp_store_x87_fpu_control_word PROC ;NEAR
1152345153Sdim
1153345153Sdim        fstcw   WORD PTR [rcx]
1154345153Sdim        ret
1155345153Sdim
1156345153Sdim__kmp_store_x87_fpu_control_word ENDP
1157345153Sdim_TEXT   ENDS
1158345153Sdim
1159345153Sdim
1160345153Sdim;------------------------------------------------------------------------
1161345153Sdim; FUNCTION __kmp_clear_x87_fpu_status_word
1162345153Sdim;
1163345153Sdim; void
1164345153Sdim; __kmp_clear_x87_fpu_status_word()
1165345153SdimPUBLIC  __kmp_clear_x87_fpu_status_word
1166345153Sdim_TEXT   SEGMENT
1167345153Sdim        ALIGN 16
1168345153Sdim__kmp_clear_x87_fpu_status_word PROC ;NEAR
1169345153Sdim
1170345153Sdim        fnclex
1171345153Sdim        ret
1172345153Sdim
1173345153Sdim__kmp_clear_x87_fpu_status_word ENDP
1174345153Sdim_TEXT   ENDS
1175345153Sdim
1176345153Sdim
1177345153Sdim;------------------------------------------------------------------------
1178345153Sdim; FUNCTION __kmp_invoke_microtask
1179345153Sdim;
1180345153Sdim; typedef void  (*microtask_t)( int *gtid, int *tid, ... );
1181345153Sdim;
1182345153Sdim; int
1183345153Sdim; __kmp_invoke_microtask( microtask_t pkfn,
1184345153Sdim;                         int gtid, int tid,
1185345153Sdim;                         int argc, void *p_argv[] ) {
1186345153Sdim;
1187345153Sdim;     (*pkfn) ( &gtid, &tid, argv[0], ... );
1188345153Sdim;     return 1;
1189345153Sdim; }
1190345153Sdim;
1191345153Sdim; note:
1192345153Sdim;      just before call to pkfn must have rsp 128-byte aligned for compiler
1193345153Sdim;
1194345153Sdim; parameters:
1195345153Sdim;      rcx:   pkfn	16[rbp]
1196345153Sdim;      edx:   gtid	24[rbp]
1197345153Sdim;      r8d:   tid	32[rbp]
1198345153Sdim;      r9d:   argc	40[rbp]
1199345153Sdim;      [st]:  p_argv	48[rbp]
1200345153Sdim;
1201345153Sdim; reg temps:
1202345153Sdim;      rax:   used all over the place
1203345153Sdim;      rdx:   used all over the place
1204345153Sdim;      rcx:   used as argument counter for push parms loop
1205345153Sdim;      r10:   used to hold pkfn function pointer argument
1206345153Sdim;
1207345153Sdim; return:      eax    (always 1/TRUE)
1208345153Sdim$_pkfn   = 16
1209345153Sdim$_gtid   = 24
1210345153Sdim$_tid    = 32
1211345153Sdim$_argc   = 40
1212345153Sdim$_p_argv = 48
1213345153Sdimif OMPT_SUPPORT
1214345153Sdim$_exit_frame = 56
1215345153Sdimendif
1216345153Sdim
1217345153SdimPUBLIC  __kmp_invoke_microtask
1218345153Sdim_TEXT   SEGMENT
1219345153Sdim        ALIGN 16
1220345153Sdim
1221345153Sdim__kmp_invoke_microtask PROC FRAME ;NEAR
1222345153Sdim	mov	QWORD PTR 16[rsp], rdx	; home gtid parameter
1223345153Sdim	mov 	QWORD PTR 24[rsp], r8	; home tid parameter
1224345153Sdim        push    rbp		; save base pointer
1225345153Sdim        .pushreg rbp
1226345153Sdim	sub	rsp, 0		; no fixed allocation necessary - end prolog
1227345153Sdim
1228345153Sdim        lea     rbp, QWORD PTR [rsp]   	; establish the base pointer
1229345153Sdim        .setframe rbp, 0
1230345153Sdim        .ENDPROLOG
1231345153Sdimif OMPT_SUPPORT
1232345153Sdim        mov     rax, QWORD PTR $_exit_frame[rbp]
1233345153Sdim        mov     QWORD PTR [rax], rbp
1234345153Sdimendif
1235345153Sdim	mov	r10, rcx	; save pkfn pointer for later
1236345153Sdim
1237345153Sdim;; ------------------------------------------------------------
1238345153Sdim        mov     rax, r9		; rax <= argc
1239345153Sdim        cmp     rax, 2
1240345153Sdim        jge     SHORT $_kmp_invoke_stack_align
1241345153Sdim        mov     rax, 2          ; set 4 homes if less than 2 parms
1242345153Sdim$_kmp_invoke_stack_align:
1243345153Sdim	lea     rdx, QWORD PTR [rax*8+16] ; rax <= (argc + 2) * 8
1244345153Sdim	mov     rax, rsp        ; Save current SP into rax
1245345153Sdim	sub	rax, rdx	; rsp - ((argc+2)*8) -> rax
1246345153Sdim				; without align, rsp would be this
1247345153Sdim	and     rax, -128       ; Mask off 7 bits (128-byte align)
1248345153Sdim	add     rax, rdx        ; add space for push's in a loop below
1249345153Sdim	mov     rsp, rax        ; Prepare the stack ptr
1250345153Sdim				; Now it will align to 128-byte at the call
1251345153Sdim;; ------------------------------------------------------------
1252345153Sdim        			; setup pkfn parameter stack
1253345153Sdim	mov	rax, r9		; rax <= argc
1254345153Sdim	shl	rax, 3		; rax <= argc*8
1255345153Sdim	mov	rdx, QWORD PTR $_p_argv[rbp]	; rdx <= p_argv
1256345153Sdim	add	rdx, rax	; rdx <= &p_argv[argc]
1257345153Sdim	mov	rcx, r9		; rcx <= argc
1258345153Sdim	jecxz	SHORT $_kmp_invoke_pass_parms	; nothing to push if argc=0
1259345153Sdim	cmp	ecx, 1		; if argc=1 branch ahead
1260345153Sdim	je	SHORT $_kmp_invoke_one_parm
1261345153Sdim	sub	ecx, 2		; if argc=2 branch ahead, subtract two from
1262345153Sdim	je	SHORT $_kmp_invoke_two_parms
1263345153Sdim
1264345153Sdim$_kmp_invoke_push_parms:	; push last - 5th parms to pkfn on stack
1265345153Sdim	sub	rdx, 8		; decrement p_argv pointer to previous parm
1266345153Sdim	mov 	r8, QWORD PTR [rdx] ; r8 <= p_argv[rcx-1]
1267345153Sdim	push	r8		; push p_argv[rcx-1] onto stack (reverse order)
1268345153Sdim	sub	ecx, 1
1269345153Sdim	jecxz	SHORT $_kmp_invoke_two_parms
1270345153Sdim	jmp	SHORT $_kmp_invoke_push_parms
1271345153Sdim
1272345153Sdim$_kmp_invoke_two_parms:
1273345153Sdim	sub	rdx, 8		; put 4th parm to pkfn in r9
1274345153Sdim	mov	r9, QWORD PTR [rdx] ; r9 <= p_argv[1]
1275345153Sdim
1276345153Sdim$_kmp_invoke_one_parm:
1277345153Sdim        sub	rdx, 8		; put 3rd parm to pkfn in r8
1278345153Sdim	mov	r8, QWORD PTR [rdx] ; r8 <= p_argv[0]
1279345153Sdim
1280345153Sdim$_kmp_invoke_pass_parms:	; put 1st & 2nd parms to pkfn in registers
1281345153Sdim	lea	rdx, QWORD PTR $_tid[rbp]  ; rdx <= &tid (2nd parm to pkfn)
1282345153Sdim	lea	rcx, QWORD PTR $_gtid[rbp] ; rcx <= &gtid (1st parm to pkfn)
1283345153Sdim        sub     rsp, 32         ; add stack space for first four parms
1284345153Sdim	mov	rax, r10	; rax <= pkfn
1285345153Sdim	call	rax		; call (*pkfn)()
1286345153Sdim	mov	rax, 1		; move 1 into return register;
1287345153Sdim
1288345153Sdim        lea     rsp, QWORD PTR [rbp]	; restore stack pointer
1289345153Sdim
1290345153Sdim;	add	rsp, 0		; no fixed allocation necessary - start epilog
1291345153Sdim        pop     rbp		; restore frame pointer
1292345153Sdim        ret
1293345153Sdim__kmp_invoke_microtask ENDP
1294345153Sdim_TEXT   ENDS
1295345153Sdim
1296345153Sdimendif
1297345153Sdim
1298345153SdimEND
1299