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