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) ( >id, &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 <= >id (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