|  | ;  z_Windows_NT-586_asm.asm:  - microtasking routines specifically | 
|  | ;    written for IA-32 architecture and Intel(R) 64 running Windows* OS | 
|  |  | 
|  | ; | 
|  | ;//===----------------------------------------------------------------------===// | 
|  | ;// | 
|  | ;//                     The LLVM Compiler Infrastructure | 
|  | ;// | 
|  | ;// This file is dual licensed under the MIT and the University of Illinois Open | 
|  | ;// Source Licenses. See LICENSE.txt for details. | 
|  | ;// | 
|  | ;//===----------------------------------------------------------------------===// | 
|  | ; | 
|  |  | 
|  | TITLE   z_Windows_NT-586_asm.asm | 
|  |  | 
|  | ; ============================= IA-32 architecture ========================== | 
|  | ifdef _M_IA32 | 
|  |  | 
|  | .586P | 
|  |  | 
|  | if @Version gt 510 | 
|  | .model HUGE | 
|  | else | 
|  | _TEXT   SEGMENT PARA USE32 PUBLIC 'CODE' | 
|  | _TEXT   ENDS | 
|  | _DATA   SEGMENT DWORD USE32 PUBLIC 'DATA' | 
|  | _DATA   ENDS | 
|  | CONST   SEGMENT DWORD USE32 PUBLIC 'CONST' | 
|  | CONST   ENDS | 
|  | _BSS    SEGMENT DWORD USE32 PUBLIC 'BSS' | 
|  | _BSS    ENDS | 
|  | $$SYMBOLS       SEGMENT BYTE USE32 'DEBSYM' | 
|  | $$SYMBOLS       ENDS | 
|  | $$TYPES SEGMENT BYTE USE32 'DEBTYP' | 
|  | $$TYPES ENDS | 
|  | _TLS    SEGMENT DWORD USE32 PUBLIC 'TLS' | 
|  | _TLS    ENDS | 
|  | FLAT    GROUP _DATA, CONST, _BSS | 
|  | ASSUME  CS: FLAT, DS: FLAT, SS: FLAT | 
|  | endif | 
|  |  | 
|  |  | 
|  | ;------------------------------------------------------------------------ | 
|  | ; FUNCTION ___kmp_x86_pause | 
|  | ; | 
|  | ; void | 
|  | ; __kmp_x86_pause( void ) | 
|  | PUBLIC  ___kmp_x86_pause | 
|  | _p$ = 4 | 
|  | _d$ = 8 | 
|  | _TEXT   SEGMENT | 
|  | ALIGN 16 | 
|  | ___kmp_x86_pause PROC NEAR | 
|  |  | 
|  | db      0f3H | 
|  | db      090H    ;; pause | 
|  | ret | 
|  |  | 
|  | ___kmp_x86_pause ENDP | 
|  | _TEXT   ENDS | 
|  |  | 
|  | ;------------------------------------------------------------------------ | 
|  | ; FUNCTION ___kmp_x86_cpuid | 
|  | ; | 
|  | ; void | 
|  | ; __kmp_x86_cpuid( int mode, int mode2, struct kmp_cpuid *p ); | 
|  | PUBLIC  ___kmp_x86_cpuid | 
|  | _TEXT   SEGMENT | 
|  | ALIGN 16 | 
|  | _mode$  = 8 | 
|  | _mode2$ = 12 | 
|  | _p$     = 16 | 
|  | _eax$   = 0 | 
|  | _ebx$   = 4 | 
|  | _ecx$   = 8 | 
|  | _edx$   = 12 | 
|  |  | 
|  | ___kmp_x86_cpuid PROC NEAR | 
|  |  | 
|  | push      ebp | 
|  | mov       ebp, esp | 
|  |  | 
|  | push      edi | 
|  | push      ebx | 
|  | push      ecx | 
|  | push      edx | 
|  |  | 
|  | mov	  eax, DWORD PTR _mode$[ebp] | 
|  | mov	  ecx, DWORD PTR _mode2$[ebp] | 
|  | cpuid					; Query the CPUID for the current processor | 
|  |  | 
|  | mov       edi, DWORD PTR _p$[ebp] | 
|  | mov 	  DWORD PTR _eax$[ edi ], eax | 
|  | mov 	  DWORD PTR _ebx$[ edi ], ebx | 
|  | mov 	  DWORD PTR _ecx$[ edi ], ecx | 
|  | mov 	  DWORD PTR _edx$[ edi ], edx | 
|  |  | 
|  | pop       edx | 
|  | pop       ecx | 
|  | pop       ebx | 
|  | pop       edi | 
|  |  | 
|  | mov       esp, ebp | 
|  | pop       ebp | 
|  | ret | 
|  |  | 
|  | ___kmp_x86_cpuid ENDP | 
|  | _TEXT     ENDS | 
|  |  | 
|  | ;------------------------------------------------------------------------ | 
|  | ; FUNCTION ___kmp_test_then_add32 | 
|  | ; | 
|  | ; kmp_int32 | 
|  | ; __kmp_test_then_add32( volatile kmp_int32 *p, kmp_int32 d ); | 
|  | PUBLIC  ___kmp_test_then_add32 | 
|  | _p$ = 4 | 
|  | _d$ = 8 | 
|  | _TEXT   SEGMENT | 
|  | ALIGN 16 | 
|  | ___kmp_test_then_add32 PROC NEAR | 
|  |  | 
|  | mov     eax, DWORD PTR _d$[esp] | 
|  | mov     ecx, DWORD PTR _p$[esp] | 
|  | lock    xadd    DWORD PTR [ecx], eax | 
|  | ret | 
|  |  | 
|  | ___kmp_test_then_add32 ENDP | 
|  | _TEXT   ENDS | 
|  |  | 
|  | ;------------------------------------------------------------------------ | 
|  | ; FUNCTION ___kmp_compare_and_store8 | 
|  | ; | 
|  | ; kmp_int8 | 
|  | ; __kmp_compare_and_store8( volatile kmp_int8 *p, kmp_int8 cv, kmp_int8 sv ); | 
|  | PUBLIC  ___kmp_compare_and_store8 | 
|  | _TEXT   SEGMENT | 
|  | ALIGN 16 | 
|  | _p$ = 4 | 
|  | _cv$ = 8 | 
|  | _sv$ = 12 | 
|  |  | 
|  | ___kmp_compare_and_store8 PROC NEAR | 
|  |  | 
|  | mov       ecx, DWORD PTR _p$[esp] | 
|  | mov       al, BYTE PTR _cv$[esp] | 
|  | mov       dl, BYTE PTR _sv$[esp] | 
|  | lock    cmpxchg   BYTE PTR [ecx], dl | 
|  | sete      al           ; if al == [ecx] set al = 1 else set al = 0 | 
|  | and       eax, 1       ; sign extend previous instruction | 
|  | ret | 
|  |  | 
|  | ___kmp_compare_and_store8 ENDP | 
|  | _TEXT     ENDS | 
|  |  | 
|  | ;------------------------------------------------------------------------ | 
|  | ; FUNCTION ___kmp_compare_and_store16 | 
|  | ; | 
|  | ; kmp_int16 | 
|  | ; __kmp_compare_and_store16( volatile kmp_int16 *p, kmp_int16 cv, kmp_int16 sv ); | 
|  | PUBLIC  ___kmp_compare_and_store16 | 
|  | _TEXT   SEGMENT | 
|  | ALIGN 16 | 
|  | _p$ = 4 | 
|  | _cv$ = 8 | 
|  | _sv$ = 12 | 
|  |  | 
|  | ___kmp_compare_and_store16 PROC NEAR | 
|  |  | 
|  | mov       ecx, DWORD PTR _p$[esp] | 
|  | mov       ax, WORD PTR _cv$[esp] | 
|  | mov       dx, WORD PTR _sv$[esp] | 
|  | lock    cmpxchg   WORD PTR [ecx], dx | 
|  | sete      al           ; if ax == [ecx] set al = 1 else set al = 0 | 
|  | and       eax, 1       ; sign extend previous instruction | 
|  | ret | 
|  |  | 
|  | ___kmp_compare_and_store16 ENDP | 
|  | _TEXT     ENDS | 
|  |  | 
|  | ;------------------------------------------------------------------------ | 
|  | ; FUNCTION ___kmp_compare_and_store32 | 
|  | ; | 
|  | ; kmp_int32 | 
|  | ; __kmp_compare_and_store32( volatile kmp_int32 *p, kmp_int32 cv, kmp_int32 sv ); | 
|  | PUBLIC  ___kmp_compare_and_store32 | 
|  | _TEXT   SEGMENT | 
|  | ALIGN 16 | 
|  | _p$ = 4 | 
|  | _cv$ = 8 | 
|  | _sv$ = 12 | 
|  |  | 
|  | ___kmp_compare_and_store32 PROC NEAR | 
|  |  | 
|  | mov       ecx, DWORD PTR _p$[esp] | 
|  | mov       eax, DWORD PTR _cv$[esp] | 
|  | mov       edx, DWORD PTR _sv$[esp] | 
|  | lock    cmpxchg   DWORD PTR [ecx], edx | 
|  | sete      al           ; if eax == [ecx] set al = 1 else set al = 0 | 
|  | and       eax, 1       ; sign extend previous instruction | 
|  | ret | 
|  |  | 
|  | ___kmp_compare_and_store32 ENDP | 
|  | _TEXT     ENDS | 
|  |  | 
|  | ;------------------------------------------------------------------------ | 
|  | ; FUNCTION ___kmp_compare_and_store64 | 
|  | ; | 
|  | ; kmp_int32 | 
|  | ; __kmp_compare_and_store64( volatile kmp_int64 *p, kmp_int64 cv, kmp_int64 sv ); | 
|  | PUBLIC  ___kmp_compare_and_store64 | 
|  | _TEXT   SEGMENT | 
|  | ALIGN 16 | 
|  | _p$ = 8 | 
|  | _cv_low$ = 12 | 
|  | _cv_high$ = 16 | 
|  | _sv_low$ = 20 | 
|  | _sv_high$ = 24 | 
|  |  | 
|  | ___kmp_compare_and_store64 PROC NEAR | 
|  |  | 
|  | push      ebp | 
|  | mov       ebp, esp | 
|  | push      ebx | 
|  | push      edi | 
|  | mov       edi, DWORD PTR _p$[ebp] | 
|  | mov       eax, DWORD PTR _cv_low$[ebp] | 
|  | mov       edx, DWORD PTR _cv_high$[ebp] | 
|  | mov       ebx, DWORD PTR _sv_low$[ebp] | 
|  | mov       ecx, DWORD PTR _sv_high$[ebp] | 
|  | lock    cmpxchg8b QWORD PTR [edi] | 
|  | sete      al           ; if edx:eax == [edi] set al = 1 else set al = 0 | 
|  | and       eax, 1       ; sign extend previous instruction | 
|  | pop       edi | 
|  | pop       ebx | 
|  | mov       esp, ebp | 
|  | pop       ebp | 
|  | ret | 
|  |  | 
|  | ___kmp_compare_and_store64 ENDP | 
|  | _TEXT     ENDS | 
|  |  | 
|  | ;------------------------------------------------------------------------ | 
|  | ; FUNCTION ___kmp_xchg_fixed8 | 
|  | ; | 
|  | ; kmp_int8 | 
|  | ; __kmp_xchg_fixed8( volatile kmp_int8 *p, kmp_int8 d ); | 
|  | PUBLIC  ___kmp_xchg_fixed8 | 
|  | _TEXT   SEGMENT | 
|  | ALIGN 16 | 
|  | _p$ = 4 | 
|  | _d$ = 8 | 
|  |  | 
|  | ___kmp_xchg_fixed8 PROC NEAR | 
|  |  | 
|  | mov       ecx, DWORD PTR _p$[esp] | 
|  | mov       al,  BYTE PTR _d$[esp] | 
|  | lock    xchg      BYTE PTR [ecx], al | 
|  | ret | 
|  |  | 
|  | ___kmp_xchg_fixed8 ENDP | 
|  | _TEXT     ENDS | 
|  |  | 
|  | ;------------------------------------------------------------------------ | 
|  | ; FUNCTION ___kmp_xchg_fixed16 | 
|  | ; | 
|  | ; kmp_int16 | 
|  | ; __kmp_xchg_fixed16( volatile kmp_int16 *p, kmp_int16 d ); | 
|  | PUBLIC  ___kmp_xchg_fixed16 | 
|  | _TEXT   SEGMENT | 
|  | ALIGN 16 | 
|  | _p$ = 4 | 
|  | _d$ = 8 | 
|  |  | 
|  | ___kmp_xchg_fixed16 PROC NEAR | 
|  |  | 
|  | mov       ecx, DWORD PTR _p$[esp] | 
|  | mov       ax,  WORD PTR  _d$[esp] | 
|  | lock    xchg      WORD PTR [ecx], ax | 
|  | ret | 
|  |  | 
|  | ___kmp_xchg_fixed16 ENDP | 
|  | _TEXT     ENDS | 
|  |  | 
|  | ;------------------------------------------------------------------------ | 
|  | ; FUNCTION ___kmp_xchg_fixed32 | 
|  | ; | 
|  | ; kmp_int32 | 
|  | ; __kmp_xchg_fixed32( volatile kmp_int32 *p, kmp_int32 d ); | 
|  | PUBLIC  ___kmp_xchg_fixed32 | 
|  | _TEXT   SEGMENT | 
|  | ALIGN 16 | 
|  | _p$ = 4 | 
|  | _d$ = 8 | 
|  |  | 
|  | ___kmp_xchg_fixed32 PROC NEAR | 
|  |  | 
|  | mov       ecx, DWORD PTR _p$[esp] | 
|  | mov       eax, DWORD PTR _d$[esp] | 
|  | lock    xchg      DWORD PTR [ecx], eax | 
|  | ret | 
|  |  | 
|  | ___kmp_xchg_fixed32 ENDP | 
|  | _TEXT     ENDS | 
|  |  | 
|  |  | 
|  | ;------------------------------------------------------------------------ | 
|  | ; FUNCTION ___kmp_xchg_real32 | 
|  | ; | 
|  | ; kmp_real32 | 
|  | ; __kmp_xchg_real32( volatile kmp_real32 *p, kmp_real32 d ); | 
|  | PUBLIC  ___kmp_xchg_real32 | 
|  | _TEXT   SEGMENT | 
|  | ALIGN 16 | 
|  | _p$ = 8 | 
|  | _d$ = 12 | 
|  | _old_value$ = -4 | 
|  |  | 
|  | ___kmp_xchg_real32 PROC NEAR | 
|  |  | 
|  | push    ebp | 
|  | mov     ebp, esp | 
|  | sub     esp, 4 | 
|  | push    esi | 
|  | mov     esi, DWORD PTR _p$[ebp] | 
|  |  | 
|  | fld     DWORD PTR [esi] | 
|  | ;; load <addr> | 
|  | fst     DWORD PTR _old_value$[ebp] | 
|  | ;; store into old_value | 
|  |  | 
|  | mov     eax, DWORD PTR _d$[ebp] | 
|  |  | 
|  | lock    xchg    DWORD PTR [esi], eax | 
|  |  | 
|  | fld     DWORD PTR _old_value$[ebp] | 
|  | ;; return old_value | 
|  | pop     esi | 
|  | mov     esp, ebp | 
|  | pop     ebp | 
|  | ret | 
|  |  | 
|  | ___kmp_xchg_real32 ENDP | 
|  | _TEXT   ENDS | 
|  |  | 
|  |  | 
|  | ;------------------------------------------------------------------------ | 
|  | ; FUNCTION ___kmp_compare_and_store_ret8 | 
|  | ; | 
|  | ; kmp_int8 | 
|  | ; __kmp_compare_and_store_ret8( volatile kmp_int8 *p, kmp_int8 cv, kmp_int8 sv ); | 
|  | PUBLIC  ___kmp_compare_and_store_ret8 | 
|  | _TEXT   SEGMENT | 
|  | ALIGN 16 | 
|  | _p$ = 4 | 
|  | _cv$ = 8 | 
|  | _sv$ = 12 | 
|  |  | 
|  | ___kmp_compare_and_store_ret8 PROC NEAR | 
|  |  | 
|  | mov       ecx, DWORD PTR _p$[esp] | 
|  | mov       al, BYTE PTR _cv$[esp] | 
|  | mov       dl, BYTE PTR _sv$[esp] | 
|  | lock    cmpxchg   BYTE PTR [ecx], dl | 
|  | ret | 
|  |  | 
|  | ___kmp_compare_and_store_ret8 ENDP | 
|  | _TEXT     ENDS | 
|  |  | 
|  | ;------------------------------------------------------------------------ | 
|  | ; FUNCTION ___kmp_compare_and_store_ret16 | 
|  | ; | 
|  | ; kmp_int16 | 
|  | ; __kmp_compare_and_store_ret16( volatile kmp_int16 *p, kmp_int16 cv, kmp_int16 sv ); | 
|  | PUBLIC  ___kmp_compare_and_store_ret16 | 
|  | _TEXT   SEGMENT | 
|  | ALIGN 16 | 
|  | _p$ = 4 | 
|  | _cv$ = 8 | 
|  | _sv$ = 12 | 
|  |  | 
|  | ___kmp_compare_and_store_ret16 PROC NEAR | 
|  |  | 
|  | mov       ecx, DWORD PTR _p$[esp] | 
|  | mov       ax, WORD PTR _cv$[esp] | 
|  | mov       dx, WORD PTR _sv$[esp] | 
|  | lock    cmpxchg   WORD PTR [ecx], dx | 
|  | ret | 
|  |  | 
|  | ___kmp_compare_and_store_ret16 ENDP | 
|  | _TEXT     ENDS | 
|  |  | 
|  | ;------------------------------------------------------------------------ | 
|  | ; FUNCTION ___kmp_compare_and_store_ret32 | 
|  | ; | 
|  | ; kmp_int32 | 
|  | ; __kmp_compare_and_store_ret32( volatile kmp_int32 *p, kmp_int32 cv, kmp_int32 sv ); | 
|  | PUBLIC  ___kmp_compare_and_store_ret32 | 
|  | _TEXT   SEGMENT | 
|  | ALIGN 16 | 
|  | _p$ = 4 | 
|  | _cv$ = 8 | 
|  | _sv$ = 12 | 
|  |  | 
|  | ___kmp_compare_and_store_ret32 PROC NEAR | 
|  |  | 
|  | mov       ecx, DWORD PTR _p$[esp] | 
|  | mov       eax, DWORD PTR _cv$[esp] | 
|  | mov       edx, DWORD PTR _sv$[esp] | 
|  | lock    cmpxchg   DWORD PTR [ecx], edx | 
|  | ret | 
|  |  | 
|  | ___kmp_compare_and_store_ret32 ENDP | 
|  | _TEXT     ENDS | 
|  |  | 
|  | ;------------------------------------------------------------------------ | 
|  | ; FUNCTION ___kmp_compare_and_store_ret64 | 
|  | ; | 
|  | ; kmp_int64 | 
|  | ; __kmp_compare_and_store_ret64( volatile kmp_int64 *p, kmp_int64 cv, kmp_int64 sv ); | 
|  | PUBLIC  ___kmp_compare_and_store_ret64 | 
|  | _TEXT   SEGMENT | 
|  | ALIGN 16 | 
|  | _p$ = 8 | 
|  | _cv_low$ = 12 | 
|  | _cv_high$ = 16 | 
|  | _sv_low$ = 20 | 
|  | _sv_high$ = 24 | 
|  |  | 
|  | ___kmp_compare_and_store_ret64 PROC NEAR | 
|  |  | 
|  | push      ebp | 
|  | mov       ebp, esp | 
|  | push      ebx | 
|  | push      edi | 
|  | mov       edi, DWORD PTR _p$[ebp] | 
|  | mov       eax, DWORD PTR _cv_low$[ebp] | 
|  | mov       edx, DWORD PTR _cv_high$[ebp] | 
|  | mov       ebx, DWORD PTR _sv_low$[ebp] | 
|  | mov       ecx, DWORD PTR _sv_high$[ebp] | 
|  | lock    cmpxchg8b QWORD PTR [edi] | 
|  | pop       edi | 
|  | pop       ebx | 
|  | mov       esp, ebp | 
|  | pop       ebp | 
|  | ret | 
|  |  | 
|  | ___kmp_compare_and_store_ret64 ENDP | 
|  | _TEXT     ENDS | 
|  |  | 
|  | ;------------------------------------------------------------------------ | 
|  | ; FUNCTION ___kmp_load_x87_fpu_control_word | 
|  | ; | 
|  | ; void | 
|  | ; __kmp_load_x87_fpu_control_word( kmp_int16 *p ); | 
|  | ; | 
|  | ; parameters: | 
|  | ;       p:      4(%esp) | 
|  | PUBLIC  ___kmp_load_x87_fpu_control_word | 
|  | _TEXT   SEGMENT | 
|  | ALIGN 16 | 
|  | _p$ = 4 | 
|  |  | 
|  | ___kmp_load_x87_fpu_control_word PROC NEAR | 
|  |  | 
|  | mov       eax, DWORD PTR _p$[esp] | 
|  | fldcw     WORD PTR [eax] | 
|  | ret | 
|  |  | 
|  | ___kmp_load_x87_fpu_control_word ENDP | 
|  | _TEXT     ENDS | 
|  |  | 
|  | ;------------------------------------------------------------------------ | 
|  | ; FUNCTION ___kmp_store_x87_fpu_control_word | 
|  | ; | 
|  | ; void | 
|  | ; __kmp_store_x87_fpu_control_word( kmp_int16 *p ); | 
|  | ; | 
|  | ; parameters: | 
|  | ;       p:      4(%esp) | 
|  | PUBLIC  ___kmp_store_x87_fpu_control_word | 
|  | _TEXT   SEGMENT | 
|  | ALIGN 16 | 
|  | _p$ = 4 | 
|  |  | 
|  | ___kmp_store_x87_fpu_control_word PROC NEAR | 
|  |  | 
|  | mov       eax, DWORD PTR _p$[esp] | 
|  | fstcw     WORD PTR [eax] | 
|  | ret | 
|  |  | 
|  | ___kmp_store_x87_fpu_control_word ENDP | 
|  | _TEXT     ENDS | 
|  |  | 
|  | ;------------------------------------------------------------------------ | 
|  | ; FUNCTION ___kmp_clear_x87_fpu_status_word | 
|  | ; | 
|  | ; void | 
|  | ; __kmp_clear_x87_fpu_status_word(); | 
|  | PUBLIC  ___kmp_clear_x87_fpu_status_word | 
|  | _TEXT   SEGMENT | 
|  | ALIGN 16 | 
|  |  | 
|  | ___kmp_clear_x87_fpu_status_word PROC NEAR | 
|  |  | 
|  | fnclex | 
|  | ret | 
|  |  | 
|  | ___kmp_clear_x87_fpu_status_word ENDP | 
|  | _TEXT     ENDS | 
|  |  | 
|  |  | 
|  | ;------------------------------------------------------------------------ | 
|  | ; FUNCTION ___kmp_invoke_microtask | 
|  | ; | 
|  | ; typedef void  (*microtask_t)( int *gtid, int *tid, ... ); | 
|  | ; | 
|  | ; int | 
|  | ; __kmp_invoke_microtask( microtask_t pkfn, | 
|  | ;                         int gtid, int tid, | 
|  | ;                         int argc, void *p_argv[] ) | 
|  | PUBLIC  ___kmp_invoke_microtask | 
|  | _TEXT   SEGMENT | 
|  | ALIGN 16 | 
|  | _pkfn$ = 8 | 
|  | _gtid$ = 12 | 
|  | _tid$ = 16 | 
|  | _argc$ = 20 | 
|  | _argv$ = 24 | 
|  | if OMPT_SUPPORT | 
|  | _exit_frame$ = 28 | 
|  | endif | 
|  | _i$ = -8 | 
|  | _stk_adj$ = -16 | 
|  | _vptr$ = -12 | 
|  | _qptr$ = -4 | 
|  |  | 
|  | ___kmp_invoke_microtask PROC NEAR | 
|  | ; Line 102 | 
|  | push    ebp | 
|  | mov     ebp, esp | 
|  | sub     esp, 16                                 ; 00000010H | 
|  | push    ebx | 
|  | push    esi | 
|  | push    edi | 
|  | if OMPT_SUPPORT | 
|  | mov     eax, DWORD PTR _exit_frame$[ebp] | 
|  | mov     DWORD PTR [eax], ebp | 
|  | endif | 
|  | ; Line 114 | 
|  | mov     eax, DWORD PTR _argc$[ebp] | 
|  | mov     DWORD PTR _i$[ebp], eax | 
|  |  | 
|  | ;; ------------------------------------------------------------ | 
|  | lea     edx, DWORD PTR [eax*4+8] | 
|  | mov     ecx, esp                                ; Save current SP into ECX | 
|  | mov	eax,edx		; Save the size of the args in eax | 
|  | sub	ecx,edx		; esp-((#args+2)*4) -> ecx -- without mods, stack ptr would be this | 
|  | mov	edx,ecx		; Save to edx | 
|  | and	ecx,-128	; Mask off 7 bits | 
|  | sub	edx,ecx		; Amount to subtract from esp | 
|  | sub	esp,edx		; Prepare stack ptr-- Now it will be aligned on 128-byte boundary at the call | 
|  |  | 
|  | add	edx,eax		; Calculate total size of the stack decrement. | 
|  | mov     DWORD PTR _stk_adj$[ebp], edx | 
|  | ;; ------------------------------------------------------------ | 
|  |  | 
|  | jmp     SHORT $L22237 | 
|  | $L22238: | 
|  | mov     ecx, DWORD PTR _i$[ebp] | 
|  | sub     ecx, 1 | 
|  | mov     DWORD PTR _i$[ebp], ecx | 
|  | $L22237: | 
|  | cmp     DWORD PTR _i$[ebp], 0 | 
|  | jle     SHORT $L22239 | 
|  | ; Line 116 | 
|  | mov     edx, DWORD PTR _i$[ebp] | 
|  | mov     eax, DWORD PTR _argv$[ebp] | 
|  | mov     ecx, DWORD PTR [eax+edx*4-4] | 
|  | mov     DWORD PTR _vptr$[ebp], ecx | 
|  | ; Line 123 | 
|  | mov     eax, DWORD PTR _vptr$[ebp] | 
|  | ; Line 124 | 
|  | push    eax | 
|  | ; Line 127 | 
|  | jmp     SHORT $L22238 | 
|  | $L22239: | 
|  | ; Line 129 | 
|  | lea     edx, DWORD PTR _tid$[ebp] | 
|  | mov     DWORD PTR _vptr$[ebp], edx | 
|  | ; Line 130 | 
|  | lea     eax, DWORD PTR _gtid$[ebp] | 
|  | mov     DWORD PTR _qptr$[ebp], eax | 
|  | ; Line 143 | 
|  | mov     eax, DWORD PTR _vptr$[ebp] | 
|  | ; Line 144 | 
|  | push    eax | 
|  | ; Line 145 | 
|  | mov     eax, DWORD PTR _qptr$[ebp] | 
|  | ; Line 146 | 
|  | push    eax | 
|  | ; Line 147 | 
|  | call    DWORD PTR _pkfn$[ebp] | 
|  | ; Line 148 | 
|  | add     esp, DWORD PTR _stk_adj$[ebp] | 
|  | ; Line 152 | 
|  | mov     eax, 1 | 
|  | ; Line 153 | 
|  | pop     edi | 
|  | pop     esi | 
|  | pop     ebx | 
|  | mov     esp, ebp | 
|  | pop     ebp | 
|  | ret     0 | 
|  | ___kmp_invoke_microtask ENDP | 
|  | _TEXT   ENDS | 
|  |  | 
|  | endif | 
|  |  | 
|  | ; ==================================== Intel(R) 64 =================================== | 
|  |  | 
|  | ifdef _M_AMD64 | 
|  |  | 
|  | ;------------------------------------------------------------------------ | 
|  | ; FUNCTION __kmp_x86_cpuid | 
|  | ; | 
|  | ; void | 
|  | ; __kmp_x86_cpuid( int mode, int mode2, struct kmp_cpuid *p ); | 
|  | ; | 
|  | ; parameters: | 
|  | ;	mode:		ecx | 
|  | ;	mode2:		edx | 
|  | ;	cpuid_buffer: 	r8 | 
|  | PUBLIC  __kmp_x86_cpuid | 
|  | _TEXT   SEGMENT | 
|  | ALIGN 16 | 
|  |  | 
|  | __kmp_x86_cpuid PROC FRAME ;NEAR | 
|  |  | 
|  | push      rbp | 
|  | .pushreg  rbp | 
|  | mov       rbp, rsp | 
|  | .setframe rbp, 0 | 
|  | push      rbx				; callee-save register | 
|  | .pushreg  rbx | 
|  | .ENDPROLOG | 
|  |  | 
|  | mov	  r10, r8                       ; p parameter | 
|  | mov	  eax, ecx			; mode parameter | 
|  | mov	  ecx, edx                      ; mode2 parameter | 
|  | cpuid					; Query the CPUID for the current processor | 
|  |  | 
|  | mov 	  DWORD PTR 0[ r10 ], eax	; store results into buffer | 
|  | mov 	  DWORD PTR 4[ r10 ], ebx | 
|  | mov 	  DWORD PTR 8[ r10 ], ecx | 
|  | mov 	  DWORD PTR 12[ r10 ], edx | 
|  |  | 
|  | pop       rbx				; callee-save register | 
|  | mov       rsp, rbp | 
|  | pop       rbp | 
|  | ret | 
|  |  | 
|  | __kmp_x86_cpuid ENDP | 
|  | _TEXT     ENDS | 
|  |  | 
|  |  | 
|  | ;------------------------------------------------------------------------ | 
|  | ; FUNCTION __kmp_test_then_add32 | 
|  | ; | 
|  | ; kmp_int32 | 
|  | ; __kmp_test_then_add32( volatile kmp_int32 *p, kmp_int32 d ); | 
|  | ; | 
|  | ; parameters: | 
|  | ;	p:	rcx | 
|  | ;	d:	edx | 
|  | ; | 
|  | ; return: 	eax | 
|  | PUBLIC  __kmp_test_then_add32 | 
|  | _TEXT   SEGMENT | 
|  | ALIGN 16 | 
|  | __kmp_test_then_add32 PROC ;NEAR | 
|  |  | 
|  | mov     eax, edx | 
|  | lock    xadd    DWORD PTR [rcx], eax | 
|  | ret | 
|  |  | 
|  | __kmp_test_then_add32 ENDP | 
|  | _TEXT   ENDS | 
|  |  | 
|  |  | 
|  | ;------------------------------------------------------------------------ | 
|  | ; FUNCTION __kmp_test_then_add64 | 
|  | ; | 
|  | ; kmp_int32 | 
|  | ; __kmp_test_then_add64( volatile kmp_int64 *p, kmp_int64 d ); | 
|  | ; | 
|  | ; parameters: | 
|  | ;	p:	rcx | 
|  | ;	d:	rdx | 
|  | ; | 
|  | ; return: 	rax | 
|  | PUBLIC  __kmp_test_then_add64 | 
|  | _TEXT   SEGMENT | 
|  | ALIGN 16 | 
|  | __kmp_test_then_add64 PROC ;NEAR | 
|  |  | 
|  | mov     rax, rdx | 
|  | lock    xadd    QWORD PTR [rcx], rax | 
|  | ret | 
|  |  | 
|  | __kmp_test_then_add64 ENDP | 
|  | _TEXT   ENDS | 
|  |  | 
|  |  | 
|  | ;------------------------------------------------------------------------ | 
|  | ; FUNCTION __kmp_compare_and_store8 | 
|  | ; | 
|  | ; kmp_int8 | 
|  | ; __kmp_compare_and_store8( volatile kmp_int8 *p, kmp_int8 cv, kmp_int8 sv ); | 
|  | ; parameters: | 
|  | ;	p:	rcx | 
|  | ;	cv:	edx | 
|  | ;	sv:	r8d | 
|  | ; | 
|  | ; return:	eax | 
|  | PUBLIC  __kmp_compare_and_store8 | 
|  | _TEXT   SEGMENT | 
|  | ALIGN 16 | 
|  |  | 
|  | __kmp_compare_and_store8 PROC ;NEAR | 
|  |  | 
|  | mov       al, dl	; "cv" | 
|  | mov	  edx, r8d	; "sv" | 
|  | lock    cmpxchg   BYTE PTR [rcx], dl | 
|  | sete      al           	; if al == [rcx] set al = 1 else set al = 0 | 
|  | and       rax, 1       	; sign extend previous instruction | 
|  | ret | 
|  |  | 
|  | __kmp_compare_and_store8 ENDP | 
|  | _TEXT     ENDS | 
|  |  | 
|  |  | 
|  | ;------------------------------------------------------------------------ | 
|  | ; FUNCTION __kmp_compare_and_store16 | 
|  | ; | 
|  | ; kmp_int16 | 
|  | ; __kmp_compare_and_store16( volatile kmp_int16 *p, kmp_int16 cv, kmp_int16 sv ); | 
|  | ; parameters: | 
|  | ;	p:	rcx | 
|  | ;	cv:	edx | 
|  | ;	sv:	r8d | 
|  | ; | 
|  | ; return:	eax | 
|  | PUBLIC  __kmp_compare_and_store16 | 
|  | _TEXT   SEGMENT | 
|  | ALIGN 16 | 
|  |  | 
|  | __kmp_compare_and_store16 PROC ;NEAR | 
|  |  | 
|  | mov       ax, dx	; "cv" | 
|  | mov	  edx, r8d	; "sv" | 
|  | lock    cmpxchg   WORD PTR [rcx], dx | 
|  | sete      al           	; if ax == [rcx] set al = 1 else set al = 0 | 
|  | and       rax, 1       	; sign extend previous instruction | 
|  | ret | 
|  |  | 
|  | __kmp_compare_and_store16 ENDP | 
|  | _TEXT     ENDS | 
|  |  | 
|  |  | 
|  | ;------------------------------------------------------------------------ | 
|  | ; FUNCTION __kmp_compare_and_store32 | 
|  | ; | 
|  | ; kmp_int32 | 
|  | ; __kmp_compare_and_store32( volatile kmp_int32 *p, kmp_int32 cv, kmp_int32 sv ); | 
|  | ; parameters: | 
|  | ;	p:	rcx | 
|  | ;	cv:	edx | 
|  | ;	sv:	r8d | 
|  | ; | 
|  | ; return:	eax | 
|  | PUBLIC  __kmp_compare_and_store32 | 
|  | _TEXT   SEGMENT | 
|  | ALIGN 16 | 
|  |  | 
|  | __kmp_compare_and_store32 PROC ;NEAR | 
|  |  | 
|  | mov       eax, edx	; "cv" | 
|  | mov	  edx, r8d	; "sv" | 
|  | lock    cmpxchg   DWORD PTR [rcx], edx | 
|  | sete      al           	; if eax == [rcx] set al = 1 else set al = 0 | 
|  | and       rax, 1       	; sign extend previous instruction | 
|  | ret | 
|  |  | 
|  | __kmp_compare_and_store32 ENDP | 
|  | _TEXT     ENDS | 
|  |  | 
|  |  | 
|  | ;------------------------------------------------------------------------ | 
|  | ; FUNCTION __kmp_compare_and_store64 | 
|  | ; | 
|  | ; kmp_int32 | 
|  | ; __kmp_compare_and_store64( volatile kmp_int64 *p, kmp_int64 cv, kmp_int64 sv ); | 
|  | ; parameters: | 
|  | ;	p:	rcx | 
|  | ;	cv:	rdx | 
|  | ;	sv:	r8 | 
|  | ; | 
|  | ; return:	eax | 
|  | PUBLIC  __kmp_compare_and_store64 | 
|  | _TEXT   SEGMENT | 
|  | ALIGN 16 | 
|  |  | 
|  | __kmp_compare_and_store64 PROC ;NEAR | 
|  |  | 
|  | mov       rax, rdx	; "cv" | 
|  | mov	  rdx, r8	; "sv" | 
|  | lock    cmpxchg   QWORD PTR [rcx], rdx | 
|  | sete      al           ; if rax == [rcx] set al = 1 else set al = 0 | 
|  | and       rax, 1       ; sign extend previous instruction | 
|  | ret | 
|  |  | 
|  | __kmp_compare_and_store64 ENDP | 
|  | _TEXT     ENDS | 
|  |  | 
|  |  | 
|  | ;------------------------------------------------------------------------ | 
|  | ; FUNCTION ___kmp_xchg_fixed8 | 
|  | ; | 
|  | ; kmp_int8 | 
|  | ; __kmp_xchg_fixed8( volatile kmp_int8 *p, kmp_int8 d ); | 
|  | ; | 
|  | ; parameters: | 
|  | ;	p:	rcx | 
|  | ;	d:	dl | 
|  | ; | 
|  | ; return: 	al | 
|  | PUBLIC  __kmp_xchg_fixed8 | 
|  | _TEXT   SEGMENT | 
|  | ALIGN 16 | 
|  |  | 
|  | __kmp_xchg_fixed8 PROC ;NEAR | 
|  |  | 
|  | mov       al,  dl | 
|  | lock    xchg      BYTE PTR [rcx], al | 
|  | ret | 
|  |  | 
|  | __kmp_xchg_fixed8 ENDP | 
|  | _TEXT     ENDS | 
|  |  | 
|  |  | 
|  | ;------------------------------------------------------------------------ | 
|  | ; FUNCTION ___kmp_xchg_fixed16 | 
|  | ; | 
|  | ; kmp_int16 | 
|  | ; __kmp_xchg_fixed16( volatile kmp_int16 *p, kmp_int16 d ); | 
|  | ; | 
|  | ; parameters: | 
|  | ;	p:	rcx | 
|  | ;	d:	dx | 
|  | ; | 
|  | ; return: 	ax | 
|  | PUBLIC  __kmp_xchg_fixed16 | 
|  | _TEXT   SEGMENT | 
|  | ALIGN 16 | 
|  |  | 
|  | __kmp_xchg_fixed16 PROC ;NEAR | 
|  |  | 
|  | mov       ax,  dx | 
|  | lock    xchg      WORD PTR [rcx], ax | 
|  | ret | 
|  |  | 
|  | __kmp_xchg_fixed16 ENDP | 
|  | _TEXT     ENDS | 
|  |  | 
|  |  | 
|  | ;------------------------------------------------------------------------ | 
|  | ; FUNCTION ___kmp_xchg_fixed32 | 
|  | ; | 
|  | ; kmp_int32 | 
|  | ; __kmp_xchg_fixed32( volatile kmp_int32 *p, kmp_int32 d ); | 
|  | ; | 
|  | ; parameters: | 
|  | ;	p:	rcx | 
|  | ;	d:	edx | 
|  | ; | 
|  | ; return: 	eax | 
|  | PUBLIC  __kmp_xchg_fixed32 | 
|  | _TEXT   SEGMENT | 
|  | ALIGN 16 | 
|  | __kmp_xchg_fixed32 PROC ;NEAR | 
|  |  | 
|  | mov     eax, edx | 
|  | lock    xchg    DWORD PTR [rcx], eax | 
|  | ret | 
|  |  | 
|  | __kmp_xchg_fixed32 ENDP | 
|  | _TEXT   ENDS | 
|  |  | 
|  |  | 
|  | ;------------------------------------------------------------------------ | 
|  | ; FUNCTION ___kmp_xchg_fixed64 | 
|  | ; | 
|  | ; kmp_int64 | 
|  | ; __kmp_xchg_fixed64( volatile kmp_int64 *p, kmp_int64 d ); | 
|  | ; | 
|  | ; parameters: | 
|  | ;	p:	rcx | 
|  | ;	d:	rdx | 
|  | ; | 
|  | ; return: 	rax | 
|  | PUBLIC  __kmp_xchg_fixed64 | 
|  | _TEXT   SEGMENT | 
|  | ALIGN 16 | 
|  | __kmp_xchg_fixed64 PROC ;NEAR | 
|  |  | 
|  | mov     rax, rdx | 
|  | lock    xchg    QWORD PTR [rcx], rax | 
|  | ret | 
|  |  | 
|  | __kmp_xchg_fixed64 ENDP | 
|  | _TEXT   ENDS | 
|  |  | 
|  |  | 
|  | ;------------------------------------------------------------------------ | 
|  | ; FUNCTION __kmp_compare_and_store_ret8 | 
|  | ; | 
|  | ; kmp_int8 | 
|  | ; __kmp_compare_and_store_ret8( volatile kmp_int8 *p, kmp_int8 cv, kmp_int8 sv ); | 
|  | ; parameters: | 
|  | ;	p:	rcx | 
|  | ;	cv:	edx | 
|  | ;	sv:	r8d | 
|  | ; | 
|  | ; return:	eax | 
|  | PUBLIC  __kmp_compare_and_store_ret8 | 
|  | _TEXT   SEGMENT | 
|  | ALIGN 16 | 
|  |  | 
|  | __kmp_compare_and_store_ret8 PROC ;NEAR | 
|  | mov       al, dl	; "cv" | 
|  | mov	  edx, r8d	; "sv" | 
|  | lock    cmpxchg   BYTE PTR [rcx], dl | 
|  | ; Compare AL with [rcx].  If equal set | 
|  | ; ZF and exchange DL with [rcx].  Else, clear | 
|  | ; ZF and load [rcx] into AL. | 
|  | ret | 
|  |  | 
|  | __kmp_compare_and_store_ret8 ENDP | 
|  | _TEXT     ENDS | 
|  |  | 
|  |  | 
|  | ;------------------------------------------------------------------------ | 
|  | ; FUNCTION __kmp_compare_and_store_ret16 | 
|  | ; | 
|  | ; kmp_int16 | 
|  | ; __kmp_compare_and_store_ret16( volatile kmp_int16 *p, kmp_int16 cv, kmp_int16 sv ); | 
|  | ; parameters: | 
|  | ;	p:	rcx | 
|  | ;	cv:	edx | 
|  | ;	sv:	r8d | 
|  | ; | 
|  | ; return:	eax | 
|  | PUBLIC  __kmp_compare_and_store_ret16 | 
|  | _TEXT   SEGMENT | 
|  | ALIGN 16 | 
|  |  | 
|  | __kmp_compare_and_store_ret16 PROC ;NEAR | 
|  |  | 
|  | mov       ax, dx	; "cv" | 
|  | mov	  edx, r8d	; "sv" | 
|  | lock    cmpxchg   WORD PTR [rcx], dx | 
|  | ret | 
|  |  | 
|  | __kmp_compare_and_store_ret16 ENDP | 
|  | _TEXT     ENDS | 
|  |  | 
|  |  | 
|  | ;------------------------------------------------------------------------ | 
|  | ; FUNCTION __kmp_compare_and_store_ret32 | 
|  | ; | 
|  | ; kmp_int32 | 
|  | ; __kmp_compare_and_store_ret32( volatile kmp_int32 *p, kmp_int32 cv, kmp_int32 sv ); | 
|  | ; parameters: | 
|  | ;	p:	rcx | 
|  | ;	cv:	edx | 
|  | ;	sv:	r8d | 
|  | ; | 
|  | ; return:	eax | 
|  | PUBLIC  __kmp_compare_and_store_ret32 | 
|  | _TEXT   SEGMENT | 
|  | ALIGN 16 | 
|  |  | 
|  | __kmp_compare_and_store_ret32 PROC ;NEAR | 
|  |  | 
|  | mov       eax, edx	; "cv" | 
|  | mov	  edx, r8d	; "sv" | 
|  | lock    cmpxchg   DWORD PTR [rcx], edx | 
|  | ret | 
|  |  | 
|  | __kmp_compare_and_store_ret32 ENDP | 
|  | _TEXT     ENDS | 
|  |  | 
|  |  | 
|  | ;------------------------------------------------------------------------ | 
|  | ; FUNCTION __kmp_compare_and_store_ret64 | 
|  | ; | 
|  | ; kmp_int64 | 
|  | ; __kmp_compare_and_store_ret64( volatile kmp_int64 *p, kmp_int64 cv, kmp_int64 sv ); | 
|  | ; parameters: | 
|  | ;	p:	rcx | 
|  | ;	cv:	rdx | 
|  | ;	sv:	r8 | 
|  | ; | 
|  | ; return:	rax | 
|  | PUBLIC  __kmp_compare_and_store_ret64 | 
|  | _TEXT   SEGMENT | 
|  | ALIGN 16 | 
|  |  | 
|  | __kmp_compare_and_store_ret64 PROC ;NEAR | 
|  |  | 
|  | mov       rax, rdx	; "cv" | 
|  | mov	  rdx, r8	; "sv" | 
|  | lock    cmpxchg   QWORD PTR [rcx], rdx | 
|  | ret | 
|  |  | 
|  | __kmp_compare_and_store_ret64 ENDP | 
|  | _TEXT     ENDS | 
|  |  | 
|  |  | 
|  | ;------------------------------------------------------------------------ | 
|  | ; FUNCTION __kmp_compare_and_store_loop8 | 
|  | ; | 
|  | ; kmp_int8 | 
|  | ; __kmp_compare_and_store_loop8( volatile kmp_int8 *p, kmp_int8 cv, kmp_int8 sv ); | 
|  | ; parameters: | 
|  | ;	p:	rcx | 
|  | ;	cv:	edx | 
|  | ;	sv:	r8d | 
|  | ; | 
|  | ; return:	al | 
|  | PUBLIC  __kmp_compare_and_store_loop8 | 
|  | _TEXT   SEGMENT | 
|  | ALIGN 16 | 
|  |  | 
|  | __kmp_compare_and_store_loop8 PROC ;NEAR | 
|  | $__kmp_loop: | 
|  | mov       al, dl	; "cv" | 
|  | mov	  edx, r8d	; "sv" | 
|  | lock    cmpxchg   BYTE PTR [rcx], dl | 
|  | ; Compare AL with [rcx].  If equal set | 
|  | ; ZF and exchange DL with [rcx].  Else, clear | 
|  | ; ZF and load [rcx] into AL. | 
|  | jz     	SHORT $__kmp_success | 
|  |  | 
|  | db      0f3H | 
|  | db      090H    		; pause | 
|  |  | 
|  | jmp	SHORT $__kmp_loop | 
|  |  | 
|  | $__kmp_success: | 
|  | ret | 
|  |  | 
|  | __kmp_compare_and_store_loop8 ENDP | 
|  | _TEXT     ENDS | 
|  |  | 
|  |  | 
|  | ;------------------------------------------------------------------------ | 
|  | ; FUNCTION __kmp_xchg_real32 | 
|  | ; | 
|  | ; kmp_real32 | 
|  | ; __kmp_xchg_real32( volatile kmp_real32 *p, kmp_real32 d ); | 
|  | ; | 
|  | ; parameters: | 
|  | ;	p:	rcx | 
|  | ;       d:	xmm1 (lower 4 bytes) | 
|  | ; | 
|  | ; return:	xmm0 (lower 4 bytes) | 
|  | PUBLIC  __kmp_xchg_real32 | 
|  | _TEXT   SEGMENT | 
|  | ALIGN 16 | 
|  | __kmp_xchg_real32 PROC ;NEAR | 
|  |  | 
|  | movd	eax, xmm1		; load d | 
|  |  | 
|  | lock    xchg    DWORD PTR [rcx], eax | 
|  |  | 
|  | movd	xmm0, eax		; load old value into return register | 
|  | ret | 
|  |  | 
|  | __kmp_xchg_real32 ENDP | 
|  | _TEXT   ENDS | 
|  |  | 
|  |  | 
|  | ;------------------------------------------------------------------------ | 
|  | ; FUNCTION __kmp_xchg_real64 | 
|  | ; | 
|  | ; kmp_real64 | 
|  | ; __kmp_xchg_real64( volatile kmp_real64 *p, kmp_real64 d ); | 
|  | ; | 
|  | ; parameters: | 
|  | ;	p:	rcx | 
|  | ;	d:	xmm1 (lower 8 bytes) | 
|  | ; | 
|  | ; return:	xmm0 (lower 8 bytes) | 
|  | PUBLIC  __kmp_xchg_real64 | 
|  | _TEXT   SEGMENT | 
|  | ALIGN 16 | 
|  | __kmp_xchg_real64 PROC ;NEAR | 
|  |  | 
|  | movd	rax, xmm1		; load "d" | 
|  |  | 
|  | lock    xchg    QWORD PTR [rcx], rax | 
|  |  | 
|  | movd	xmm0, rax		; load old value into return register | 
|  | ret | 
|  |  | 
|  | __kmp_xchg_real64 ENDP | 
|  | _TEXT   ENDS | 
|  |  | 
|  | ;------------------------------------------------------------------------ | 
|  | ; FUNCTION __kmp_load_x87_fpu_control_word | 
|  | ; | 
|  | ; void | 
|  | ; __kmp_load_x87_fpu_control_word( kmp_int16 *p ); | 
|  | ; | 
|  | ; parameters: | 
|  | ;	p:	rcx | 
|  | PUBLIC  __kmp_load_x87_fpu_control_word | 
|  | _TEXT   SEGMENT | 
|  | ALIGN 16 | 
|  | __kmp_load_x87_fpu_control_word PROC ;NEAR | 
|  |  | 
|  | fldcw   WORD PTR [rcx] | 
|  | ret | 
|  |  | 
|  | __kmp_load_x87_fpu_control_word ENDP | 
|  | _TEXT   ENDS | 
|  |  | 
|  |  | 
|  | ;------------------------------------------------------------------------ | 
|  | ; FUNCTION __kmp_store_x87_fpu_control_word | 
|  | ; | 
|  | ; void | 
|  | ; __kmp_store_x87_fpu_control_word( kmp_int16 *p ); | 
|  | ; | 
|  | ; parameters: | 
|  | ;	p:	rcx | 
|  | PUBLIC  __kmp_store_x87_fpu_control_word | 
|  | _TEXT   SEGMENT | 
|  | ALIGN 16 | 
|  | __kmp_store_x87_fpu_control_word PROC ;NEAR | 
|  |  | 
|  | fstcw   WORD PTR [rcx] | 
|  | ret | 
|  |  | 
|  | __kmp_store_x87_fpu_control_word ENDP | 
|  | _TEXT   ENDS | 
|  |  | 
|  |  | 
|  | ;------------------------------------------------------------------------ | 
|  | ; FUNCTION __kmp_clear_x87_fpu_status_word | 
|  | ; | 
|  | ; void | 
|  | ; __kmp_clear_x87_fpu_status_word() | 
|  | PUBLIC  __kmp_clear_x87_fpu_status_word | 
|  | _TEXT   SEGMENT | 
|  | ALIGN 16 | 
|  | __kmp_clear_x87_fpu_status_word PROC ;NEAR | 
|  |  | 
|  | fnclex | 
|  | ret | 
|  |  | 
|  | __kmp_clear_x87_fpu_status_word ENDP | 
|  | _TEXT   ENDS | 
|  |  | 
|  |  | 
|  | ;------------------------------------------------------------------------ | 
|  | ; FUNCTION __kmp_invoke_microtask | 
|  | ; | 
|  | ; typedef void  (*microtask_t)( int *gtid, int *tid, ... ); | 
|  | ; | 
|  | ; int | 
|  | ; __kmp_invoke_microtask( microtask_t pkfn, | 
|  | ;                         int gtid, int tid, | 
|  | ;                         int argc, void *p_argv[] ) { | 
|  | ; | 
|  | ;     (*pkfn) ( >id, &tid, argv[0], ... ); | 
|  | ;     return 1; | 
|  | ; } | 
|  | ; | 
|  | ; note: | 
|  | ;      just before call to pkfn must have rsp 128-byte aligned for compiler | 
|  | ; | 
|  | ; parameters: | 
|  | ;      rcx:   pkfn	16[rbp] | 
|  | ;      edx:   gtid	24[rbp] | 
|  | ;      r8d:   tid	32[rbp] | 
|  | ;      r9d:   argc	40[rbp] | 
|  | ;      [st]:  p_argv	48[rbp] | 
|  | ; | 
|  | ; reg temps: | 
|  | ;      rax:   used all over the place | 
|  | ;      rdx:   used all over the place | 
|  | ;      rcx:   used as argument counter for push parms loop | 
|  | ;      r10:   used to hold pkfn function pointer argument | 
|  | ; | 
|  | ; return:      eax    (always 1/TRUE) | 
|  | $_pkfn   = 16 | 
|  | $_gtid   = 24 | 
|  | $_tid    = 32 | 
|  | $_argc   = 40 | 
|  | $_p_argv = 48 | 
|  | if OMPT_SUPPORT | 
|  | $_exit_frame = 56 | 
|  | endif | 
|  |  | 
|  | PUBLIC  __kmp_invoke_microtask | 
|  | _TEXT   SEGMENT | 
|  | ALIGN 16 | 
|  |  | 
|  | __kmp_invoke_microtask PROC FRAME ;NEAR | 
|  | mov	QWORD PTR 16[rsp], rdx	; home gtid parameter | 
|  | mov 	QWORD PTR 24[rsp], r8	; home tid parameter | 
|  | push    rbp		; save base pointer | 
|  | .pushreg rbp | 
|  | sub	rsp, 0		; no fixed allocation necessary - end prolog | 
|  |  | 
|  | lea     rbp, QWORD PTR [rsp]   	; establish the base pointer | 
|  | .setframe rbp, 0 | 
|  | .ENDPROLOG | 
|  | if OMPT_SUPPORT | 
|  | mov     rax, QWORD PTR $_exit_frame[rbp] | 
|  | mov     QWORD PTR [rax], rbp | 
|  | endif | 
|  | mov	r10, rcx	; save pkfn pointer for later | 
|  |  | 
|  | ;; ------------------------------------------------------------ | 
|  | mov     rax, r9		; rax <= argc | 
|  | cmp     rax, 2 | 
|  | jge     SHORT $_kmp_invoke_stack_align | 
|  | mov     rax, 2          ; set 4 homes if less than 2 parms | 
|  | $_kmp_invoke_stack_align: | 
|  | lea     rdx, QWORD PTR [rax*8+16] ; rax <= (argc + 2) * 8 | 
|  | mov     rax, rsp        ; Save current SP into rax | 
|  | sub	rax, rdx	; rsp - ((argc+2)*8) -> rax | 
|  | ; without align, rsp would be this | 
|  | and     rax, -128       ; Mask off 7 bits (128-byte align) | 
|  | add     rax, rdx        ; add space for push's in a loop below | 
|  | mov     rsp, rax        ; Prepare the stack ptr | 
|  | ; Now it will align to 128-byte at the call | 
|  | ;; ------------------------------------------------------------ | 
|  | ; setup pkfn parameter stack | 
|  | mov	rax, r9		; rax <= argc | 
|  | shl	rax, 3		; rax <= argc*8 | 
|  | mov	rdx, QWORD PTR $_p_argv[rbp]	; rdx <= p_argv | 
|  | add	rdx, rax	; rdx <= &p_argv[argc] | 
|  | mov	rcx, r9		; rcx <= argc | 
|  | jecxz	SHORT $_kmp_invoke_pass_parms	; nothing to push if argc=0 | 
|  | cmp	ecx, 1		; if argc=1 branch ahead | 
|  | je	SHORT $_kmp_invoke_one_parm | 
|  | sub	ecx, 2		; if argc=2 branch ahead, subtract two from | 
|  | je	SHORT $_kmp_invoke_two_parms | 
|  |  | 
|  | $_kmp_invoke_push_parms:	; push last - 5th parms to pkfn on stack | 
|  | sub	rdx, 8		; decrement p_argv pointer to previous parm | 
|  | mov 	r8, QWORD PTR [rdx] ; r8 <= p_argv[rcx-1] | 
|  | push	r8		; push p_argv[rcx-1] onto stack (reverse order) | 
|  | sub	ecx, 1 | 
|  | jecxz	SHORT $_kmp_invoke_two_parms | 
|  | jmp	SHORT $_kmp_invoke_push_parms | 
|  |  | 
|  | $_kmp_invoke_two_parms: | 
|  | sub	rdx, 8		; put 4th parm to pkfn in r9 | 
|  | mov	r9, QWORD PTR [rdx] ; r9 <= p_argv[1] | 
|  |  | 
|  | $_kmp_invoke_one_parm: | 
|  | sub	rdx, 8		; put 3rd parm to pkfn in r8 | 
|  | mov	r8, QWORD PTR [rdx] ; r8 <= p_argv[0] | 
|  |  | 
|  | $_kmp_invoke_pass_parms:	; put 1st & 2nd parms to pkfn in registers | 
|  | lea	rdx, QWORD PTR $_tid[rbp]  ; rdx <= &tid (2nd parm to pkfn) | 
|  | lea	rcx, QWORD PTR $_gtid[rbp] ; rcx <= >id (1st parm to pkfn) | 
|  | sub     rsp, 32         ; add stack space for first four parms | 
|  | mov	rax, r10	; rax <= pkfn | 
|  | call	rax		; call (*pkfn)() | 
|  | mov	rax, 1		; move 1 into return register; | 
|  |  | 
|  | lea     rsp, QWORD PTR [rbp]	; restore stack pointer | 
|  |  | 
|  | ;	add	rsp, 0		; no fixed allocation necessary - start epilog | 
|  | pop     rbp		; restore frame pointer | 
|  | ret | 
|  | __kmp_invoke_microtask ENDP | 
|  | _TEXT   ENDS | 
|  |  | 
|  | endif | 
|  |  | 
|  | END |