You've already forked linux-packaging-mono
1300 lines
30 KiB
NASM
1300 lines
30 KiB
NASM
; 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
|