1299 lines · plain
1; z_Windows_NT-586_asm.asm: - microtasking routines specifically2; written for IA-32 architecture and Intel(R) 64 running Windows* OS3 4;5;//===----------------------------------------------------------------------===//6;//7;// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.8;// See https://llvm.org/LICENSE.txt for license information.9;// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception10;//11;//===----------------------------------------------------------------------===//12;13 14 TITLE z_Windows_NT-586_asm.asm15 16; ============================= IA-32 architecture ==========================17ifdef _M_IA3218 19 .586P20 21if @Version gt 51022 .model HUGE23else24_TEXT SEGMENT PARA USE32 PUBLIC 'CODE'25_TEXT ENDS26_DATA SEGMENT DWORD USE32 PUBLIC 'DATA'27_DATA ENDS28CONST SEGMENT DWORD USE32 PUBLIC 'CONST'29CONST ENDS30_BSS SEGMENT DWORD USE32 PUBLIC 'BSS'31_BSS ENDS32$$SYMBOLS SEGMENT BYTE USE32 'DEBSYM'33$$SYMBOLS ENDS34$$TYPES SEGMENT BYTE USE32 'DEBTYP'35$$TYPES ENDS36_TLS SEGMENT DWORD USE32 PUBLIC 'TLS'37_TLS ENDS38FLAT GROUP _DATA, CONST, _BSS39 ASSUME CS: FLAT, DS: FLAT, SS: FLAT40endif41 42 43;------------------------------------------------------------------------44; FUNCTION ___kmp_x86_pause45;46; void47; __kmp_x86_pause( void )48PUBLIC ___kmp_x86_pause49_p$ = 450_d$ = 851_TEXT SEGMENT52 ALIGN 1653___kmp_x86_pause PROC NEAR54 55 db 0f3H56 db 090H ;; pause57 ret58 59___kmp_x86_pause ENDP60_TEXT ENDS61 62;------------------------------------------------------------------------63; FUNCTION ___kmp_x86_cpuid64;65; void66; __kmp_x86_cpuid( int mode, int mode2, struct kmp_cpuid *p );67PUBLIC ___kmp_x86_cpuid68_TEXT SEGMENT69 ALIGN 1670_mode$ = 871_mode2$ = 1272_p$ = 1673_eax$ = 074_ebx$ = 475_ecx$ = 876_edx$ = 1277 78___kmp_x86_cpuid PROC NEAR79 80 push ebp81 mov ebp, esp82 83 push edi84 push ebx85 push ecx86 push edx87 88 mov eax, DWORD PTR _mode$[ebp]89 mov ecx, DWORD PTR _mode2$[ebp]90 cpuid ; Query the CPUID for the current processor91 92 mov edi, DWORD PTR _p$[ebp]93 mov DWORD PTR _eax$[ edi ], eax94 mov DWORD PTR _ebx$[ edi ], ebx95 mov DWORD PTR _ecx$[ edi ], ecx96 mov DWORD PTR _edx$[ edi ], edx97 98 pop edx99 pop ecx100 pop ebx101 pop edi102 103 mov esp, ebp104 pop ebp105 ret106 107___kmp_x86_cpuid ENDP108_TEXT ENDS109 110;------------------------------------------------------------------------111; FUNCTION ___kmp_test_then_add32112;113; kmp_int32114; __kmp_test_then_add32( volatile kmp_int32 *p, kmp_int32 d );115PUBLIC ___kmp_test_then_add32116_p$ = 4117_d$ = 8118_TEXT SEGMENT119 ALIGN 16120___kmp_test_then_add32 PROC NEAR121 122 mov eax, DWORD PTR _d$[esp]123 mov ecx, DWORD PTR _p$[esp]124lock xadd DWORD PTR [ecx], eax125 ret126 127___kmp_test_then_add32 ENDP128_TEXT ENDS129 130;------------------------------------------------------------------------131; FUNCTION ___kmp_compare_and_store8132;133; kmp_int8134; __kmp_compare_and_store8( volatile kmp_int8 *p, kmp_int8 cv, kmp_int8 sv );135PUBLIC ___kmp_compare_and_store8136_TEXT SEGMENT137 ALIGN 16138_p$ = 4139_cv$ = 8140_sv$ = 12141 142___kmp_compare_and_store8 PROC NEAR143 144 mov ecx, DWORD PTR _p$[esp]145 mov al, BYTE PTR _cv$[esp]146 mov dl, BYTE PTR _sv$[esp]147lock cmpxchg BYTE PTR [ecx], dl148 sete al ; if al == [ecx] set al = 1 else set al = 0149 and eax, 1 ; sign extend previous instruction150 ret151 152___kmp_compare_and_store8 ENDP153_TEXT ENDS154 155;------------------------------------------------------------------------156; FUNCTION ___kmp_compare_and_store16157;158; kmp_int16159; __kmp_compare_and_store16( volatile kmp_int16 *p, kmp_int16 cv, kmp_int16 sv );160PUBLIC ___kmp_compare_and_store16161_TEXT SEGMENT162 ALIGN 16163_p$ = 4164_cv$ = 8165_sv$ = 12166 167___kmp_compare_and_store16 PROC NEAR168 169 mov ecx, DWORD PTR _p$[esp]170 mov ax, WORD PTR _cv$[esp]171 mov dx, WORD PTR _sv$[esp]172lock cmpxchg WORD PTR [ecx], dx173 sete al ; if ax == [ecx] set al = 1 else set al = 0174 and eax, 1 ; sign extend previous instruction175 ret176 177___kmp_compare_and_store16 ENDP178_TEXT ENDS179 180;------------------------------------------------------------------------181; FUNCTION ___kmp_compare_and_store32182;183; kmp_int32184; __kmp_compare_and_store32( volatile kmp_int32 *p, kmp_int32 cv, kmp_int32 sv );185PUBLIC ___kmp_compare_and_store32186_TEXT SEGMENT187 ALIGN 16188_p$ = 4189_cv$ = 8190_sv$ = 12191 192___kmp_compare_and_store32 PROC NEAR193 194 mov ecx, DWORD PTR _p$[esp]195 mov eax, DWORD PTR _cv$[esp]196 mov edx, DWORD PTR _sv$[esp]197lock cmpxchg DWORD PTR [ecx], edx198 sete al ; if eax == [ecx] set al = 1 else set al = 0199 and eax, 1 ; sign extend previous instruction200 ret201 202___kmp_compare_and_store32 ENDP203_TEXT ENDS204 205;------------------------------------------------------------------------206; FUNCTION ___kmp_compare_and_store64207;208; kmp_int32209; __kmp_compare_and_store64( volatile kmp_int64 *p, kmp_int64 cv, kmp_int64 sv );210PUBLIC ___kmp_compare_and_store64211_TEXT SEGMENT212 ALIGN 16213_p$ = 8214_cv_low$ = 12215_cv_high$ = 16216_sv_low$ = 20217_sv_high$ = 24218 219___kmp_compare_and_store64 PROC NEAR220 221 push ebp222 mov ebp, esp223 push ebx224 push edi225 mov edi, DWORD PTR _p$[ebp]226 mov eax, DWORD PTR _cv_low$[ebp]227 mov edx, DWORD PTR _cv_high$[ebp]228 mov ebx, DWORD PTR _sv_low$[ebp]229 mov ecx, DWORD PTR _sv_high$[ebp]230lock cmpxchg8b QWORD PTR [edi]231 sete al ; if edx:eax == [edi] set al = 1 else set al = 0232 and eax, 1 ; sign extend previous instruction233 pop edi234 pop ebx235 mov esp, ebp236 pop ebp237 ret238 239___kmp_compare_and_store64 ENDP240_TEXT ENDS241 242;------------------------------------------------------------------------243; FUNCTION ___kmp_xchg_fixed8244;245; kmp_int8246; __kmp_xchg_fixed8( volatile kmp_int8 *p, kmp_int8 d );247PUBLIC ___kmp_xchg_fixed8248_TEXT SEGMENT249 ALIGN 16250_p$ = 4251_d$ = 8252 253___kmp_xchg_fixed8 PROC NEAR254 255 mov ecx, DWORD PTR _p$[esp]256 mov al, BYTE PTR _d$[esp]257lock xchg BYTE PTR [ecx], al258 ret259 260___kmp_xchg_fixed8 ENDP261_TEXT ENDS262 263;------------------------------------------------------------------------264; FUNCTION ___kmp_xchg_fixed16265;266; kmp_int16267; __kmp_xchg_fixed16( volatile kmp_int16 *p, kmp_int16 d );268PUBLIC ___kmp_xchg_fixed16269_TEXT SEGMENT270 ALIGN 16271_p$ = 4272_d$ = 8273 274___kmp_xchg_fixed16 PROC NEAR275 276 mov ecx, DWORD PTR _p$[esp]277 mov ax, WORD PTR _d$[esp]278lock xchg WORD PTR [ecx], ax279 ret280 281___kmp_xchg_fixed16 ENDP282_TEXT ENDS283 284;------------------------------------------------------------------------285; FUNCTION ___kmp_xchg_fixed32286;287; kmp_int32288; __kmp_xchg_fixed32( volatile kmp_int32 *p, kmp_int32 d );289PUBLIC ___kmp_xchg_fixed32290_TEXT SEGMENT291 ALIGN 16292_p$ = 4293_d$ = 8294 295___kmp_xchg_fixed32 PROC NEAR296 297 mov ecx, DWORD PTR _p$[esp]298 mov eax, DWORD PTR _d$[esp]299lock xchg DWORD PTR [ecx], eax300 ret301 302___kmp_xchg_fixed32 ENDP303_TEXT ENDS304 305 306;------------------------------------------------------------------------307; FUNCTION ___kmp_xchg_real32308;309; kmp_real32310; __kmp_xchg_real32( volatile kmp_real32 *p, kmp_real32 d );311PUBLIC ___kmp_xchg_real32312_TEXT SEGMENT313 ALIGN 16314_p$ = 8315_d$ = 12316_old_value$ = -4317 318___kmp_xchg_real32 PROC NEAR319 320 push ebp321 mov ebp, esp322 sub esp, 4323 push esi324 mov esi, DWORD PTR _p$[ebp]325 326 fld DWORD PTR [esi]327 ;; load <addr>328 fst DWORD PTR _old_value$[ebp]329 ;; store into old_value330 331 mov eax, DWORD PTR _d$[ebp]332 333lock xchg DWORD PTR [esi], eax334 335 fld DWORD PTR _old_value$[ebp]336 ;; return old_value337 pop esi338 mov esp, ebp339 pop ebp340 ret341 342___kmp_xchg_real32 ENDP343_TEXT ENDS344 345 346;------------------------------------------------------------------------347; FUNCTION ___kmp_compare_and_store_ret8348;349; kmp_int8350; __kmp_compare_and_store_ret8( volatile kmp_int8 *p, kmp_int8 cv, kmp_int8 sv );351PUBLIC ___kmp_compare_and_store_ret8352_TEXT SEGMENT353 ALIGN 16354_p$ = 4355_cv$ = 8356_sv$ = 12357 358___kmp_compare_and_store_ret8 PROC NEAR359 360 mov ecx, DWORD PTR _p$[esp]361 mov al, BYTE PTR _cv$[esp]362 mov dl, BYTE PTR _sv$[esp]363lock cmpxchg BYTE PTR [ecx], dl364 ret365 366___kmp_compare_and_store_ret8 ENDP367_TEXT ENDS368 369;------------------------------------------------------------------------370; FUNCTION ___kmp_compare_and_store_ret16371;372; kmp_int16373; __kmp_compare_and_store_ret16( volatile kmp_int16 *p, kmp_int16 cv, kmp_int16 sv );374PUBLIC ___kmp_compare_and_store_ret16375_TEXT SEGMENT376 ALIGN 16377_p$ = 4378_cv$ = 8379_sv$ = 12380 381___kmp_compare_and_store_ret16 PROC NEAR382 383 mov ecx, DWORD PTR _p$[esp]384 mov ax, WORD PTR _cv$[esp]385 mov dx, WORD PTR _sv$[esp]386lock cmpxchg WORD PTR [ecx], dx387 ret388 389___kmp_compare_and_store_ret16 ENDP390_TEXT ENDS391 392;------------------------------------------------------------------------393; FUNCTION ___kmp_compare_and_store_ret32394;395; kmp_int32396; __kmp_compare_and_store_ret32( volatile kmp_int32 *p, kmp_int32 cv, kmp_int32 sv );397PUBLIC ___kmp_compare_and_store_ret32398_TEXT SEGMENT399 ALIGN 16400_p$ = 4401_cv$ = 8402_sv$ = 12403 404___kmp_compare_and_store_ret32 PROC NEAR405 406 mov ecx, DWORD PTR _p$[esp]407 mov eax, DWORD PTR _cv$[esp]408 mov edx, DWORD PTR _sv$[esp]409lock cmpxchg DWORD PTR [ecx], edx410 ret411 412___kmp_compare_and_store_ret32 ENDP413_TEXT ENDS414 415;------------------------------------------------------------------------416; FUNCTION ___kmp_compare_and_store_ret64417;418; kmp_int64419; __kmp_compare_and_store_ret64( volatile kmp_int64 *p, kmp_int64 cv, kmp_int64 sv );420PUBLIC ___kmp_compare_and_store_ret64421_TEXT SEGMENT422 ALIGN 16423_p$ = 8424_cv_low$ = 12425_cv_high$ = 16426_sv_low$ = 20427_sv_high$ = 24428 429___kmp_compare_and_store_ret64 PROC NEAR430 431 push ebp432 mov ebp, esp433 push ebx434 push edi435 mov edi, DWORD PTR _p$[ebp]436 mov eax, DWORD PTR _cv_low$[ebp]437 mov edx, DWORD PTR _cv_high$[ebp]438 mov ebx, DWORD PTR _sv_low$[ebp]439 mov ecx, DWORD PTR _sv_high$[ebp]440lock cmpxchg8b QWORD PTR [edi]441 pop edi442 pop ebx443 mov esp, ebp444 pop ebp445 ret446 447___kmp_compare_and_store_ret64 ENDP448_TEXT ENDS449 450;------------------------------------------------------------------------451; FUNCTION ___kmp_load_x87_fpu_control_word452;453; void454; __kmp_load_x87_fpu_control_word( kmp_int16 *p );455;456; parameters:457; p: 4(%esp)458PUBLIC ___kmp_load_x87_fpu_control_word459_TEXT SEGMENT460 ALIGN 16461_p$ = 4462 463___kmp_load_x87_fpu_control_word PROC NEAR464 465 mov eax, DWORD PTR _p$[esp]466 fldcw WORD PTR [eax]467 ret468 469___kmp_load_x87_fpu_control_word ENDP470_TEXT ENDS471 472;------------------------------------------------------------------------473; FUNCTION ___kmp_store_x87_fpu_control_word474;475; void476; __kmp_store_x87_fpu_control_word( kmp_int16 *p );477;478; parameters:479; p: 4(%esp)480PUBLIC ___kmp_store_x87_fpu_control_word481_TEXT SEGMENT482 ALIGN 16483_p$ = 4484 485___kmp_store_x87_fpu_control_word PROC NEAR486 487 mov eax, DWORD PTR _p$[esp]488 fstcw WORD PTR [eax]489 ret490 491___kmp_store_x87_fpu_control_word ENDP492_TEXT ENDS493 494;------------------------------------------------------------------------495; FUNCTION ___kmp_clear_x87_fpu_status_word496;497; void498; __kmp_clear_x87_fpu_status_word();499PUBLIC ___kmp_clear_x87_fpu_status_word500_TEXT SEGMENT501 ALIGN 16502 503___kmp_clear_x87_fpu_status_word PROC NEAR504 505 fnclex506 ret507 508___kmp_clear_x87_fpu_status_word ENDP509_TEXT ENDS510 511 512;------------------------------------------------------------------------513; FUNCTION ___kmp_invoke_microtask514;515; typedef void (*microtask_t)( int *gtid, int *tid, ... );516;517; int518; __kmp_invoke_microtask( microtask_t pkfn,519; int gtid, int tid,520; int argc, void *p_argv[] )521PUBLIC ___kmp_invoke_microtask522_TEXT SEGMENT523 ALIGN 16524_pkfn$ = 8525_gtid$ = 12526_tid$ = 16527_argc$ = 20528_argv$ = 24529if OMPT_SUPPORT530_exit_frame$ = 28531endif532_i$ = -8533_stk_adj$ = -16534_vptr$ = -12535_qptr$ = -4536 537___kmp_invoke_microtask PROC NEAR538; Line 102539 push ebp540 mov ebp, esp541 sub esp, 16 ; 00000010H542 push ebx543 push esi544 push edi545if OMPT_SUPPORT546 mov eax, DWORD PTR _exit_frame$[ebp]547 mov DWORD PTR [eax], ebp548endif549; Line 114550 mov eax, DWORD PTR _argc$[ebp]551 mov DWORD PTR _i$[ebp], eax552 553;; ------------------------------------------------------------554 lea edx, DWORD PTR [eax*4+8]555 mov ecx, esp ; Save current SP into ECX556 mov eax,edx ; Save the size of the args in eax557 sub ecx,edx ; esp-((#args+2)*4) -> ecx -- without mods, stack ptr would be this558 mov edx,ecx ; Save to edx559 and ecx,-128 ; Mask off 7 bits560 sub edx,ecx ; Amount to subtract from esp561 sub esp,edx ; Prepare stack ptr-- Now it will be aligned on 128-byte boundary at the call562 563 add edx,eax ; Calculate total size of the stack decrement.564 mov DWORD PTR _stk_adj$[ebp], edx565;; ------------------------------------------------------------566 567 jmp SHORT $L22237568$L22238:569 mov ecx, DWORD PTR _i$[ebp]570 sub ecx, 1571 mov DWORD PTR _i$[ebp], ecx572$L22237:573 cmp DWORD PTR _i$[ebp], 0574 jle SHORT $L22239575; Line 116576 mov edx, DWORD PTR _i$[ebp]577 mov eax, DWORD PTR _argv$[ebp]578 mov ecx, DWORD PTR [eax+edx*4-4]579 mov DWORD PTR _vptr$[ebp], ecx580; Line 123581 mov eax, DWORD PTR _vptr$[ebp]582; Line 124583 push eax584; Line 127585 jmp SHORT $L22238586$L22239:587; Line 129588 lea edx, DWORD PTR _tid$[ebp]589 mov DWORD PTR _vptr$[ebp], edx590; Line 130591 lea eax, DWORD PTR _gtid$[ebp]592 mov DWORD PTR _qptr$[ebp], eax593; Line 143594 mov eax, DWORD PTR _vptr$[ebp]595; Line 144596 push eax597; Line 145598 mov eax, DWORD PTR _qptr$[ebp]599; Line 146600 push eax601; Line 147602 call DWORD PTR _pkfn$[ebp]603; Line 148604 add esp, DWORD PTR _stk_adj$[ebp]605; Line 152606 mov eax, 1607; Line 153608 pop edi609 pop esi610 pop ebx611 mov esp, ebp612 pop ebp613 ret 0614___kmp_invoke_microtask ENDP615_TEXT ENDS616 617endif618 619; ==================================== Intel(R) 64 ===================================620 621ifdef _M_AMD64622 623;------------------------------------------------------------------------624; FUNCTION __kmp_x86_cpuid625;626; void627; __kmp_x86_cpuid( int mode, int mode2, struct kmp_cpuid *p );628;629; parameters:630; mode: ecx631; mode2: edx632; cpuid_buffer: r8633PUBLIC __kmp_x86_cpuid634_TEXT SEGMENT635 ALIGN 16636 637__kmp_x86_cpuid PROC FRAME ;NEAR638 639 push rbp640 .pushreg rbp641 mov rbp, rsp642 .setframe rbp, 0643 push rbx ; callee-save register644 .pushreg rbx645 .ENDPROLOG646 647 mov r10, r8 ; p parameter648 mov eax, ecx ; mode parameter649 mov ecx, edx ; mode2 parameter650 cpuid ; Query the CPUID for the current processor651 652 mov DWORD PTR 0[ r10 ], eax ; store results into buffer653 mov DWORD PTR 4[ r10 ], ebx654 mov DWORD PTR 8[ r10 ], ecx655 mov DWORD PTR 12[ r10 ], edx656 657 pop rbx ; callee-save register658 mov rsp, rbp659 pop rbp660 ret661 662__kmp_x86_cpuid ENDP663_TEXT ENDS664 665 666;------------------------------------------------------------------------667; FUNCTION __kmp_test_then_add32668;669; kmp_int32670; __kmp_test_then_add32( volatile kmp_int32 *p, kmp_int32 d );671;672; parameters:673; p: rcx674; d: edx675;676; return: eax677PUBLIC __kmp_test_then_add32678_TEXT SEGMENT679 ALIGN 16680__kmp_test_then_add32 PROC ;NEAR681 682 mov eax, edx683lock xadd DWORD PTR [rcx], eax684 ret685 686__kmp_test_then_add32 ENDP687_TEXT ENDS688 689 690;------------------------------------------------------------------------691; FUNCTION __kmp_test_then_add64692;693; kmp_int32694; __kmp_test_then_add64( volatile kmp_int64 *p, kmp_int64 d );695;696; parameters:697; p: rcx698; d: rdx699;700; return: rax701PUBLIC __kmp_test_then_add64702_TEXT SEGMENT703 ALIGN 16704__kmp_test_then_add64 PROC ;NEAR705 706 mov rax, rdx707lock xadd QWORD PTR [rcx], rax708 ret709 710__kmp_test_then_add64 ENDP711_TEXT ENDS712 713 714;------------------------------------------------------------------------715; FUNCTION __kmp_compare_and_store8716;717; kmp_int8718; __kmp_compare_and_store8( volatile kmp_int8 *p, kmp_int8 cv, kmp_int8 sv );719; parameters:720; p: rcx721; cv: edx722; sv: r8d723;724; return: eax725PUBLIC __kmp_compare_and_store8726_TEXT SEGMENT727 ALIGN 16728 729__kmp_compare_and_store8 PROC ;NEAR730 731 mov al, dl ; "cv"732 mov edx, r8d ; "sv"733lock cmpxchg BYTE PTR [rcx], dl734 sete al ; if al == [rcx] set al = 1 else set al = 0735 and rax, 1 ; sign extend previous instruction736 ret737 738__kmp_compare_and_store8 ENDP739_TEXT ENDS740 741 742;------------------------------------------------------------------------743; FUNCTION __kmp_compare_and_store16744;745; kmp_int16746; __kmp_compare_and_store16( volatile kmp_int16 *p, kmp_int16 cv, kmp_int16 sv );747; parameters:748; p: rcx749; cv: edx750; sv: r8d751;752; return: eax753PUBLIC __kmp_compare_and_store16754_TEXT SEGMENT755 ALIGN 16756 757__kmp_compare_and_store16 PROC ;NEAR758 759 mov ax, dx ; "cv"760 mov edx, r8d ; "sv"761lock cmpxchg WORD PTR [rcx], dx762 sete al ; if ax == [rcx] set al = 1 else set al = 0763 and rax, 1 ; sign extend previous instruction764 ret765 766__kmp_compare_and_store16 ENDP767_TEXT ENDS768 769 770;------------------------------------------------------------------------771; FUNCTION __kmp_compare_and_store32772;773; kmp_int32774; __kmp_compare_and_store32( volatile kmp_int32 *p, kmp_int32 cv, kmp_int32 sv );775; parameters:776; p: rcx777; cv: edx778; sv: r8d779;780; return: eax781PUBLIC __kmp_compare_and_store32782_TEXT SEGMENT783 ALIGN 16784 785__kmp_compare_and_store32 PROC ;NEAR786 787 mov eax, edx ; "cv"788 mov edx, r8d ; "sv"789lock cmpxchg DWORD PTR [rcx], edx790 sete al ; if eax == [rcx] set al = 1 else set al = 0791 and rax, 1 ; sign extend previous instruction792 ret793 794__kmp_compare_and_store32 ENDP795_TEXT ENDS796 797 798;------------------------------------------------------------------------799; FUNCTION __kmp_compare_and_store64800;801; kmp_int32802; __kmp_compare_and_store64( volatile kmp_int64 *p, kmp_int64 cv, kmp_int64 sv );803; parameters:804; p: rcx805; cv: rdx806; sv: r8807;808; return: eax809PUBLIC __kmp_compare_and_store64810_TEXT SEGMENT811 ALIGN 16812 813__kmp_compare_and_store64 PROC ;NEAR814 815 mov rax, rdx ; "cv"816 mov rdx, r8 ; "sv"817lock cmpxchg QWORD PTR [rcx], rdx818 sete al ; if rax == [rcx] set al = 1 else set al = 0819 and rax, 1 ; sign extend previous instruction820 ret821 822__kmp_compare_and_store64 ENDP823_TEXT ENDS824 825 826;------------------------------------------------------------------------827; FUNCTION ___kmp_xchg_fixed8828;829; kmp_int8830; __kmp_xchg_fixed8( volatile kmp_int8 *p, kmp_int8 d );831;832; parameters:833; p: rcx834; d: dl835;836; return: al837PUBLIC __kmp_xchg_fixed8838_TEXT SEGMENT839 ALIGN 16840 841__kmp_xchg_fixed8 PROC ;NEAR842 843 mov al, dl844lock xchg BYTE PTR [rcx], al845 ret846 847__kmp_xchg_fixed8 ENDP848_TEXT ENDS849 850 851;------------------------------------------------------------------------852; FUNCTION ___kmp_xchg_fixed16853;854; kmp_int16855; __kmp_xchg_fixed16( volatile kmp_int16 *p, kmp_int16 d );856;857; parameters:858; p: rcx859; d: dx860;861; return: ax862PUBLIC __kmp_xchg_fixed16863_TEXT SEGMENT864 ALIGN 16865 866__kmp_xchg_fixed16 PROC ;NEAR867 868 mov ax, dx869lock xchg WORD PTR [rcx], ax870 ret871 872__kmp_xchg_fixed16 ENDP873_TEXT ENDS874 875 876;------------------------------------------------------------------------877; FUNCTION ___kmp_xchg_fixed32878;879; kmp_int32880; __kmp_xchg_fixed32( volatile kmp_int32 *p, kmp_int32 d );881;882; parameters:883; p: rcx884; d: edx885;886; return: eax887PUBLIC __kmp_xchg_fixed32888_TEXT SEGMENT889 ALIGN 16890__kmp_xchg_fixed32 PROC ;NEAR891 892 mov eax, edx893lock xchg DWORD PTR [rcx], eax894 ret895 896__kmp_xchg_fixed32 ENDP897_TEXT ENDS898 899 900;------------------------------------------------------------------------901; FUNCTION ___kmp_xchg_fixed64902;903; kmp_int64904; __kmp_xchg_fixed64( volatile kmp_int64 *p, kmp_int64 d );905;906; parameters:907; p: rcx908; d: rdx909;910; return: rax911PUBLIC __kmp_xchg_fixed64912_TEXT SEGMENT913 ALIGN 16914__kmp_xchg_fixed64 PROC ;NEAR915 916 mov rax, rdx917lock xchg QWORD PTR [rcx], rax918 ret919 920__kmp_xchg_fixed64 ENDP921_TEXT ENDS922 923 924;------------------------------------------------------------------------925; FUNCTION __kmp_compare_and_store_ret8926;927; kmp_int8928; __kmp_compare_and_store_ret8( volatile kmp_int8 *p, kmp_int8 cv, kmp_int8 sv );929; parameters:930; p: rcx931; cv: edx932; sv: r8d933;934; return: eax935PUBLIC __kmp_compare_and_store_ret8936_TEXT SEGMENT937 ALIGN 16938 939__kmp_compare_and_store_ret8 PROC ;NEAR940 mov al, dl ; "cv"941 mov edx, r8d ; "sv"942lock cmpxchg BYTE PTR [rcx], dl943 ; Compare AL with [rcx]. If equal set944 ; ZF and exchange DL with [rcx]. Else, clear945 ; ZF and load [rcx] into AL.946 ret947 948__kmp_compare_and_store_ret8 ENDP949_TEXT ENDS950 951 952;------------------------------------------------------------------------953; FUNCTION __kmp_compare_and_store_ret16954;955; kmp_int16956; __kmp_compare_and_store_ret16( volatile kmp_int16 *p, kmp_int16 cv, kmp_int16 sv );957; parameters:958; p: rcx959; cv: edx960; sv: r8d961;962; return: eax963PUBLIC __kmp_compare_and_store_ret16964_TEXT SEGMENT965 ALIGN 16966 967__kmp_compare_and_store_ret16 PROC ;NEAR968 969 mov ax, dx ; "cv"970 mov edx, r8d ; "sv"971lock cmpxchg WORD PTR [rcx], dx972 ret973 974__kmp_compare_and_store_ret16 ENDP975_TEXT ENDS976 977 978;------------------------------------------------------------------------979; FUNCTION __kmp_compare_and_store_ret32980;981; kmp_int32982; __kmp_compare_and_store_ret32( volatile kmp_int32 *p, kmp_int32 cv, kmp_int32 sv );983; parameters:984; p: rcx985; cv: edx986; sv: r8d987;988; return: eax989PUBLIC __kmp_compare_and_store_ret32990_TEXT SEGMENT991 ALIGN 16992 993__kmp_compare_and_store_ret32 PROC ;NEAR994 995 mov eax, edx ; "cv"996 mov edx, r8d ; "sv"997lock cmpxchg DWORD PTR [rcx], edx998 ret999 1000__kmp_compare_and_store_ret32 ENDP1001_TEXT ENDS1002 1003 1004;------------------------------------------------------------------------1005; FUNCTION __kmp_compare_and_store_ret641006;1007; kmp_int641008; __kmp_compare_and_store_ret64( volatile kmp_int64 *p, kmp_int64 cv, kmp_int64 sv );1009; parameters:1010; p: rcx1011; cv: rdx1012; sv: r81013;1014; return: rax1015PUBLIC __kmp_compare_and_store_ret641016_TEXT SEGMENT1017 ALIGN 161018 1019__kmp_compare_and_store_ret64 PROC ;NEAR1020 1021 mov rax, rdx ; "cv"1022 mov rdx, r8 ; "sv"1023lock cmpxchg QWORD PTR [rcx], rdx1024 ret1025 1026__kmp_compare_and_store_ret64 ENDP1027_TEXT ENDS1028 1029 1030;------------------------------------------------------------------------1031; FUNCTION __kmp_compare_and_store_loop81032;1033; kmp_int81034; __kmp_compare_and_store_loop8( volatile kmp_int8 *p, kmp_int8 cv, kmp_int8 sv );1035; parameters:1036; p: rcx1037; cv: edx1038; sv: r8d1039;1040; return: al1041PUBLIC __kmp_compare_and_store_loop81042_TEXT SEGMENT1043 ALIGN 161044 1045__kmp_compare_and_store_loop8 PROC ;NEAR1046$__kmp_loop:1047 mov al, dl ; "cv"1048 mov edx, r8d ; "sv"1049lock cmpxchg BYTE PTR [rcx], dl1050 ; Compare AL with [rcx]. If equal set1051 ; ZF and exchange DL with [rcx]. Else, clear1052 ; ZF and load [rcx] into AL.1053 jz SHORT $__kmp_success1054 1055 db 0f3H1056 db 090H ; pause1057 1058 jmp SHORT $__kmp_loop1059 1060$__kmp_success:1061 ret1062 1063__kmp_compare_and_store_loop8 ENDP1064_TEXT ENDS1065 1066 1067;------------------------------------------------------------------------1068; FUNCTION __kmp_xchg_real321069;1070; kmp_real321071; __kmp_xchg_real32( volatile kmp_real32 *p, kmp_real32 d );1072;1073; parameters:1074; p: rcx1075; d: xmm1 (lower 4 bytes)1076;1077; return: xmm0 (lower 4 bytes)1078PUBLIC __kmp_xchg_real321079_TEXT SEGMENT1080 ALIGN 161081__kmp_xchg_real32 PROC ;NEAR1082 1083 movd eax, xmm1 ; load d1084 1085lock xchg DWORD PTR [rcx], eax1086 1087 movd xmm0, eax ; load old value into return register1088 ret1089 1090__kmp_xchg_real32 ENDP1091_TEXT ENDS1092 1093 1094;------------------------------------------------------------------------1095; FUNCTION __kmp_xchg_real641096;1097; kmp_real641098; __kmp_xchg_real64( volatile kmp_real64 *p, kmp_real64 d );1099;1100; parameters:1101; p: rcx1102; d: xmm1 (lower 8 bytes)1103;1104; return: xmm0 (lower 8 bytes)1105PUBLIC __kmp_xchg_real641106_TEXT SEGMENT1107 ALIGN 161108__kmp_xchg_real64 PROC ;NEAR1109 1110 movd rax, xmm1 ; load "d"1111 1112lock xchg QWORD PTR [rcx], rax1113 1114 movd xmm0, rax ; load old value into return register1115 ret1116 1117__kmp_xchg_real64 ENDP1118_TEXT ENDS1119 1120;------------------------------------------------------------------------1121; FUNCTION __kmp_load_x87_fpu_control_word1122;1123; void1124; __kmp_load_x87_fpu_control_word( kmp_int16 *p );1125;1126; parameters:1127; p: rcx1128PUBLIC __kmp_load_x87_fpu_control_word1129_TEXT SEGMENT1130 ALIGN 161131__kmp_load_x87_fpu_control_word PROC ;NEAR1132 1133 fldcw WORD PTR [rcx]1134 ret1135 1136__kmp_load_x87_fpu_control_word ENDP1137_TEXT ENDS1138 1139 1140;------------------------------------------------------------------------1141; FUNCTION __kmp_store_x87_fpu_control_word1142;1143; void1144; __kmp_store_x87_fpu_control_word( kmp_int16 *p );1145;1146; parameters:1147; p: rcx1148PUBLIC __kmp_store_x87_fpu_control_word1149_TEXT SEGMENT1150 ALIGN 161151__kmp_store_x87_fpu_control_word PROC ;NEAR1152 1153 fstcw WORD PTR [rcx]1154 ret1155 1156__kmp_store_x87_fpu_control_word ENDP1157_TEXT ENDS1158 1159 1160;------------------------------------------------------------------------1161; FUNCTION __kmp_clear_x87_fpu_status_word1162;1163; void1164; __kmp_clear_x87_fpu_status_word()1165PUBLIC __kmp_clear_x87_fpu_status_word1166_TEXT SEGMENT1167 ALIGN 161168__kmp_clear_x87_fpu_status_word PROC ;NEAR1169 1170 fnclex1171 ret1172 1173__kmp_clear_x87_fpu_status_word ENDP1174_TEXT ENDS1175 1176 1177;------------------------------------------------------------------------1178; FUNCTION __kmp_invoke_microtask1179;1180; typedef void (*microtask_t)( int *gtid, int *tid, ... );1181;1182; int1183; __kmp_invoke_microtask( microtask_t pkfn,1184; int gtid, int tid,1185; int argc, void *p_argv[] ) {1186;1187; (*pkfn) ( >id, &tid, argv[0], ... );1188; return 1;1189; }1190;1191; note:1192; just before call to pkfn must have rsp 128-byte aligned for compiler1193;1194; parameters:1195; rcx: pkfn 16[rbp]1196; edx: gtid 24[rbp]1197; r8d: tid 32[rbp]1198; r9d: argc 40[rbp]1199; [st]: p_argv 48[rbp]1200;1201; reg temps:1202; rax: used all over the place1203; rdx: used all over the place1204; rcx: used as argument counter for push parms loop1205; r10: used to hold pkfn function pointer argument1206;1207; return: eax (always 1/TRUE)1208$_pkfn = 161209$_gtid = 241210$_tid = 321211$_argc = 401212$_p_argv = 481213if OMPT_SUPPORT1214$_exit_frame = 561215endif1216 1217PUBLIC __kmp_invoke_microtask1218_TEXT SEGMENT1219 ALIGN 161220 1221__kmp_invoke_microtask PROC FRAME ;NEAR1222 mov QWORD PTR 16[rsp], rdx ; home gtid parameter1223 mov QWORD PTR 24[rsp], r8 ; home tid parameter1224 push rbp ; save base pointer1225 .pushreg rbp1226 sub rsp, 0 ; no fixed allocation necessary - end prolog1227 1228 lea rbp, QWORD PTR [rsp] ; establish the base pointer1229 .setframe rbp, 01230 .ENDPROLOG1231if OMPT_SUPPORT1232 mov rax, QWORD PTR $_exit_frame[rbp]1233 mov QWORD PTR [rax], rbp1234endif1235 mov r10, rcx ; save pkfn pointer for later1236 1237;; ------------------------------------------------------------1238 mov rax, r9 ; rax <= argc1239 cmp rax, 21240 jge SHORT $_kmp_invoke_stack_align1241 mov rax, 2 ; set 4 homes if less than 2 parms1242$_kmp_invoke_stack_align:1243 lea rdx, QWORD PTR [rax*8+16] ; rax <= (argc + 2) * 81244 mov rax, rsp ; Save current SP into rax1245 sub rax, rdx ; rsp - ((argc+2)*8) -> rax1246 ; without align, rsp would be this1247 and rax, -128 ; Mask off 7 bits (128-byte align)1248 add rax, rdx ; add space for push's in a loop below1249 mov rsp, rax ; Prepare the stack ptr1250 ; Now it will align to 128-byte at the call1251;; ------------------------------------------------------------1252 ; setup pkfn parameter stack1253 mov rax, r9 ; rax <= argc1254 shl rax, 3 ; rax <= argc*81255 mov rdx, QWORD PTR $_p_argv[rbp] ; rdx <= p_argv1256 add rdx, rax ; rdx <= &p_argv[argc]1257 mov rcx, r9 ; rcx <= argc1258 jecxz SHORT $_kmp_invoke_pass_parms ; nothing to push if argc=01259 cmp ecx, 1 ; if argc=1 branch ahead1260 je SHORT $_kmp_invoke_one_parm1261 sub ecx, 2 ; if argc=2 branch ahead, subtract two from1262 je SHORT $_kmp_invoke_two_parms1263 1264$_kmp_invoke_push_parms: ; push last - 5th parms to pkfn on stack1265 sub rdx, 8 ; decrement p_argv pointer to previous parm1266 mov r8, QWORD PTR [rdx] ; r8 <= p_argv[rcx-1]1267 push r8 ; push p_argv[rcx-1] onto stack (reverse order)1268 sub ecx, 11269 jecxz SHORT $_kmp_invoke_two_parms1270 jmp SHORT $_kmp_invoke_push_parms1271 1272$_kmp_invoke_two_parms:1273 sub rdx, 8 ; put 4th parm to pkfn in r91274 mov r9, QWORD PTR [rdx] ; r9 <= p_argv[1]1275 1276$_kmp_invoke_one_parm:1277 sub rdx, 8 ; put 3rd parm to pkfn in r81278 mov r8, QWORD PTR [rdx] ; r8 <= p_argv[0]1279 1280$_kmp_invoke_pass_parms: ; put 1st & 2nd parms to pkfn in registers1281 lea rdx, QWORD PTR $_tid[rbp] ; rdx <= &tid (2nd parm to pkfn)1282 lea rcx, QWORD PTR $_gtid[rbp] ; rcx <= >id (1st parm to pkfn)1283 sub rsp, 32 ; add stack space for first four parms1284 mov rax, r10 ; rax <= pkfn1285 call rax ; call (*pkfn)()1286 mov rax, 1 ; move 1 into return register;1287 1288 lea rsp, QWORD PTR [rbp] ; restore stack pointer1289 1290; add rsp, 0 ; no fixed allocation necessary - start epilog1291 pop rbp ; restore frame pointer1292 ret1293__kmp_invoke_microtask ENDP1294_TEXT ENDS1295 1296endif1297 1298END1299