LEFT | RIGHT |
(no file at all) | |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 #include "zasm_GOOS_GOARCH.h" | 5 #include "zasm_GOOS_GOARCH.h" |
6 #include "funcdata.h" | 6 #include "funcdata.h" |
7 #include "../../cmd/ld/textflag.h" | 7 #include "../../cmd/ld/textflag.h" |
8 | 8 |
9 TEXT _rt0_go(SB),NOSPLIT,$0 | 9 TEXT _rt0_go(SB),NOSPLIT,$0 |
10 // copy arguments forward on an even stack | 10 // copy arguments forward on an even stack |
(...skipping 22 matching lines...) Expand all Loading... |
33 MOVL CX, runtime·cpuid_ecx(SB) | 33 MOVL CX, runtime·cpuid_ecx(SB) |
34 MOVL DX, runtime·cpuid_edx(SB) | 34 MOVL DX, runtime·cpuid_edx(SB) |
35 nocpuinfo:······ | 35 nocpuinfo:······ |
36 | 36 |
37 // if there is an _cgo_init, call it to let it | 37 // if there is an _cgo_init, call it to let it |
38 // initialize and to set up GS. if not, | 38 // initialize and to set up GS. if not, |
39 // we set up GS ourselves. | 39 // we set up GS ourselves. |
40 MOVL _cgo_init(SB), AX | 40 MOVL _cgo_init(SB), AX |
41 TESTL AX, AX | 41 TESTL AX, AX |
42 JZ needtls | 42 JZ needtls |
43 » MOVL» $setmg_gcc<>(SB), BX | 43 » MOVL» $setg_gcc<>(SB), BX |
44 MOVL BX, 4(SP) | 44 MOVL BX, 4(SP) |
45 MOVL BP, 0(SP) | 45 MOVL BP, 0(SP) |
46 CALL AX | 46 CALL AX |
47 // update stackguard after _cgo_init | 47 // update stackguard after _cgo_init |
48 MOVL $runtime·g0(SB), CX | 48 MOVL $runtime·g0(SB), CX |
49 MOVL g_stackguard0(CX), AX | 49 MOVL g_stackguard0(CX), AX |
50 MOVL AX, g_stackguard(CX) | 50 MOVL AX, g_stackguard(CX) |
51 // skip runtime·ldt0setup(SB) and tls test after _cgo_init for non-windo
ws | 51 // skip runtime·ldt0setup(SB) and tls test after _cgo_init for non-windo
ws |
52 CMPL runtime·iswindows(SB), $0 | 52 CMPL runtime·iswindows(SB), $0 |
53 JEQ ok | 53 JEQ ok |
(...skipping 11 matching lines...) Expand all Loading... |
65 MOVL runtime·tls0(SB), AX | 65 MOVL runtime·tls0(SB), AX |
66 CMPL AX, $0x123 | 66 CMPL AX, $0x123 |
67 JEQ ok | 67 JEQ ok |
68 MOVL AX, 0 // abort | 68 MOVL AX, 0 // abort |
69 ok: | 69 ok: |
70 // set up m and g "registers" | 70 // set up m and g "registers" |
71 get_tls(BX) | 71 get_tls(BX) |
72 LEAL runtime·g0(SB), CX | 72 LEAL runtime·g0(SB), CX |
73 MOVL CX, g(BX) | 73 MOVL CX, g(BX) |
74 LEAL runtime·m0(SB), AX | 74 LEAL runtime·m0(SB), AX |
75 MOVL AX, m(BX) | |
76 | 75 |
77 // save m->g0 = g0 | 76 // save m->g0 = g0 |
78 MOVL CX, m_g0(AX) | 77 MOVL CX, m_g0(AX) |
| 78 // save g0->m = m0 |
| 79 MOVL AX, g_m(CX) |
79 | 80 |
80 CALL runtime·emptyfunc(SB) // fault if stack check is wrong | 81 CALL runtime·emptyfunc(SB) // fault if stack check is wrong |
81 | 82 |
82 // convention is D is always cleared | 83 // convention is D is always cleared |
83 CLD | 84 CLD |
84 | 85 |
85 CALL runtime·check(SB) | 86 CALL runtime·check(SB) |
86 | 87 |
87 // saved argc, argv | 88 // saved argc, argv |
88 MOVL 120(SP), AX | 89 MOVL 120(SP), AX |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
171 ········ | 172 ········ |
172 get_tls(CX) | 173 get_tls(CX) |
173 MOVL g(CX), AX // save state in g->sched | 174 MOVL g(CX), AX // save state in g->sched |
174 MOVL 0(SP), BX // caller's PC | 175 MOVL 0(SP), BX // caller's PC |
175 MOVL BX, (g_sched+gobuf_pc)(AX) | 176 MOVL BX, (g_sched+gobuf_pc)(AX) |
176 LEAL 4(SP), BX // caller's SP | 177 LEAL 4(SP), BX // caller's SP |
177 MOVL BX, (g_sched+gobuf_sp)(AX) | 178 MOVL BX, (g_sched+gobuf_sp)(AX) |
178 MOVL AX, (g_sched+gobuf_g)(AX) | 179 MOVL AX, (g_sched+gobuf_g)(AX) |
179 | 180 |
180 // switch to m->g0 & its stack, call fn | 181 // switch to m->g0 & its stack, call fn |
181 » MOVL» m(CX), BX | 182 » MOVL» g(CX), BX |
| 183 » MOVL» g_m(BX), BX |
182 MOVL m_g0(BX), SI | 184 MOVL m_g0(BX), SI |
183 CMPL SI, AX // if g == m->g0 call badmcall | 185 CMPL SI, AX // if g == m->g0 call badmcall |
184 JNE 3(PC) | 186 JNE 3(PC) |
185 MOVL $runtime·badmcall(SB), AX | 187 MOVL $runtime·badmcall(SB), AX |
186 JMP AX | 188 JMP AX |
187 MOVL SI, g(CX) // g = m->g0 | 189 MOVL SI, g(CX) // g = m->g0 |
188 MOVL (g_sched+gobuf_sp)(SI), SP // sp = m->g0->sched.sp | 190 MOVL (g_sched+gobuf_sp)(SI), SP // sp = m->g0->sched.sp |
189 PUSHL AX | 191 PUSHL AX |
190 CALL DI | 192 CALL DI |
191 POPL AX | 193 POPL AX |
192 MOVL $runtime·badmcall2(SB), AX | 194 MOVL $runtime·badmcall2(SB), AX |
193 JMP AX | 195 JMP AX |
194 RET | 196 RET |
195 | 197 |
196 /* | 198 /* |
197 * support for morestack | 199 * support for morestack |
198 */ | 200 */ |
199 | 201 |
200 // Called during function prolog when more stack is needed. | 202 // Called during function prolog when more stack is needed. |
201 // | 203 // |
202 // The traceback routines see morestack on a g0 as being | 204 // The traceback routines see morestack on a g0 as being |
203 // the top of a stack (for example, morestack calling newstack | 205 // the top of a stack (for example, morestack calling newstack |
204 // calling the scheduler calling newm calling gc), so we must | 206 // calling the scheduler calling newm calling gc), so we must |
205 // record an argument size. For that purpose, it has no arguments. | 207 // record an argument size. For that purpose, it has no arguments. |
206 TEXT runtime·morestack(SB),NOSPLIT,$0-0 | 208 TEXT runtime·morestack(SB),NOSPLIT,$0-0 |
207 // Cannot grow scheduler stack (m->g0). | 209 // Cannot grow scheduler stack (m->g0). |
208 get_tls(CX) | 210 get_tls(CX) |
209 » MOVL» m(CX), BX | 211 » MOVL» g(CX), BX |
| 212 » MOVL» g_m(BX), BX |
210 MOVL m_g0(BX), SI | 213 MOVL m_g0(BX), SI |
211 CMPL g(CX), SI | 214 CMPL g(CX), SI |
212 JNE 2(PC) | 215 JNE 2(PC) |
213 INT $3 | 216 INT $3 |
214 | 217 |
215 // frame size in DI | 218 // frame size in DI |
216 // arg size in AX | 219 // arg size in AX |
217 // Save in m. | 220 // Save in m. |
218 MOVL DI, m_moreframesize(BX) | 221 MOVL DI, m_moreframesize(BX) |
219 MOVL AX, m_moreargsize(BX) | 222 MOVL AX, m_moreargsize(BX) |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
251 MOVL $0, DX | 254 MOVL $0, DX |
252 JMP runtime·morestack(SB) | 255 JMP runtime·morestack(SB) |
253 | 256 |
254 // Called from panic. Mimics morestack, | 257 // Called from panic. Mimics morestack, |
255 // reuses stack growth code to create a frame | 258 // reuses stack growth code to create a frame |
256 // with the desired args running the desired function. | 259 // with the desired args running the desired function. |
257 // | 260 // |
258 // func call(fn *byte, arg *byte, argsize uint32). | 261 // func call(fn *byte, arg *byte, argsize uint32). |
259 TEXT runtime·newstackcall(SB), NOSPLIT, $0-12 | 262 TEXT runtime·newstackcall(SB), NOSPLIT, $0-12 |
260 get_tls(CX) | 263 get_tls(CX) |
261 » MOVL» m(CX), BX | 264 » MOVL» g(CX), BX |
| 265 » MOVL» g_m(BX), BX |
262 | 266 |
263 // Save our caller's state as the PC and SP to | 267 // Save our caller's state as the PC and SP to |
264 // restore when returning from f. | 268 // restore when returning from f. |
265 MOVL 0(SP), AX // our caller's PC | 269 MOVL 0(SP), AX // our caller's PC |
266 MOVL AX, (m_morebuf+gobuf_pc)(BX) | 270 MOVL AX, (m_morebuf+gobuf_pc)(BX) |
267 LEAL 4(SP), AX // our caller's SP | 271 LEAL 4(SP), AX // our caller's SP |
268 MOVL AX, (m_morebuf+gobuf_sp)(BX) | 272 MOVL AX, (m_morebuf+gobuf_sp)(BX) |
269 MOVL g(CX), AX | 273 MOVL g(CX), AX |
270 MOVL AX, (m_morebuf+gobuf_g)(BX) | 274 MOVL AX, (m_morebuf+gobuf_g)(BX) |
271 | 275 |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
408 CALLFN(call536870912, 536870912) | 412 CALLFN(call536870912, 536870912) |
409 CALLFN(call1073741824, 1073741824) | 413 CALLFN(call1073741824, 1073741824) |
410 | 414 |
411 // Return point when leaving stack. | 415 // Return point when leaving stack. |
412 // | 416 // |
413 // Lessstack can appear in stack traces for the same reason | 417 // Lessstack can appear in stack traces for the same reason |
414 // as morestack; in that context, it has 0 arguments. | 418 // as morestack; in that context, it has 0 arguments. |
415 TEXT runtime·lessstack(SB), NOSPLIT, $0-0 | 419 TEXT runtime·lessstack(SB), NOSPLIT, $0-0 |
416 // Save return value in m->cret | 420 // Save return value in m->cret |
417 get_tls(CX) | 421 get_tls(CX) |
418 » MOVL» m(CX), BX | 422 » MOVL» g(CX), BX |
| 423 » MOVL» g_m(BX), BX |
419 MOVL AX, m_cret(BX) | 424 MOVL AX, m_cret(BX) |
420 | 425 |
421 // Call oldstack on m->g0's stack. | 426 // Call oldstack on m->g0's stack. |
422 MOVL m_g0(BX), BP | 427 MOVL m_g0(BX), BP |
423 MOVL BP, g(CX) | 428 MOVL BP, g(CX) |
424 MOVL (g_sched+gobuf_sp)(BP), SP | 429 MOVL (g_sched+gobuf_sp)(BP), SP |
425 CALL runtime·oldstack(SB) | 430 CALL runtime·oldstack(SB) |
426 MOVL $0, 0x1004 // crash if oldstack returns | 431 MOVL $0, 0x1004 // crash if oldstack returns |
427 RET | 432 RET |
428 | 433 |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
599 // See cgocall.c for more details. | 604 // See cgocall.c for more details. |
600 TEXT runtime·asmcgocall(SB),NOSPLIT,$0-8 | 605 TEXT runtime·asmcgocall(SB),NOSPLIT,$0-8 |
601 MOVL fn+0(FP), AX | 606 MOVL fn+0(FP), AX |
602 MOVL arg+4(FP), BX | 607 MOVL arg+4(FP), BX |
603 MOVL SP, DX | 608 MOVL SP, DX |
604 | 609 |
605 // Figure out if we need to switch to m->g0 stack. | 610 // Figure out if we need to switch to m->g0 stack. |
606 // We get called to create new OS threads too, and those | 611 // We get called to create new OS threads too, and those |
607 // come in on the m->g0 stack already. | 612 // come in on the m->g0 stack already. |
608 get_tls(CX) | 613 get_tls(CX) |
609 » MOVL» m(CX), BP | 614 » MOVL» g(CX), BP |
| 615 » MOVL» g_m(BP), BP |
610 MOVL m_g0(BP), SI | 616 MOVL m_g0(BP), SI |
611 MOVL g(CX), DI | 617 MOVL g(CX), DI |
612 CMPL SI, DI | 618 CMPL SI, DI |
613 JEQ 4(PC) | 619 JEQ 4(PC) |
614 CALL gosave<>(SB) | 620 CALL gosave<>(SB) |
615 MOVL SI, g(CX) | 621 MOVL SI, g(CX) |
616 MOVL (g_sched+gobuf_sp)(SI), SP | 622 MOVL (g_sched+gobuf_sp)(SI), SP |
617 | 623 |
618 // Now on a scheduling stack (a pthread-created stack). | 624 // Now on a scheduling stack (a pthread-created stack). |
619 SUBL $32, SP | 625 SUBL $32, SP |
(...skipping 20 matching lines...) Expand all Loading... |
640 MOVL AX, 4(SP) | 646 MOVL AX, 4(SP) |
641 MOVL framesize+8(FP), AX | 647 MOVL framesize+8(FP), AX |
642 MOVL AX, 8(SP) | 648 MOVL AX, 8(SP) |
643 MOVL $runtime·cgocallback_gofunc(SB), AX | 649 MOVL $runtime·cgocallback_gofunc(SB), AX |
644 CALL AX | 650 CALL AX |
645 RET | 651 RET |
646 | 652 |
647 // cgocallback_gofunc(FuncVal*, void *frame, uintptr framesize) | 653 // cgocallback_gofunc(FuncVal*, void *frame, uintptr framesize) |
648 // See cgocall.c for more details. | 654 // See cgocall.c for more details. |
649 TEXT runtime·cgocallback_gofunc(SB),NOSPLIT,$12-12 | 655 TEXT runtime·cgocallback_gofunc(SB),NOSPLIT,$12-12 |
650 » // If m is nil, Go did not create the current thread. | 656 » // If g is nil, Go did not create the current thread. |
651 // Call needm to obtain one for temporary use. | 657 // Call needm to obtain one for temporary use. |
652 // In this case, we're running on the thread stack, so there's | 658 // In this case, we're running on the thread stack, so there's |
653 // lots of space, but the linker doesn't know. Hide the call from | 659 // lots of space, but the linker doesn't know. Hide the call from |
654 // the linker analysis by using an indirect call through AX. | 660 // the linker analysis by using an indirect call through AX. |
655 get_tls(CX) | 661 get_tls(CX) |
656 #ifdef GOOS_windows | 662 #ifdef GOOS_windows |
657 MOVL $0, BP | 663 MOVL $0, BP |
658 CMPL CX, $0 | 664 CMPL CX, $0 |
659 » JEQ» 2(PC) | 665 » JEQ» 2(PC) // TODO |
660 #endif | 666 #endif |
661 » MOVL» m(CX), BP | 667 » MOVL» g(CX), BP |
| 668 » CMPL» BP, $0 |
| 669 » JEQ» needm |
| 670 » MOVL» g_m(BP), BP |
662 MOVL BP, DX // saved copy of oldm | 671 MOVL BP, DX // saved copy of oldm |
663 » CMPL» BP, $0 | 672 » JMP» havem |
664 » JNE» havem | |
665 needm: | 673 needm: |
666 » MOVL» DX, 0(SP) | 674 » MOVL» $0, 0(SP) |
667 MOVL $runtime·needm(SB), AX | 675 MOVL $runtime·needm(SB), AX |
668 CALL AX | 676 CALL AX |
669 MOVL 0(SP), DX | 677 MOVL 0(SP), DX |
670 get_tls(CX) | 678 get_tls(CX) |
671 » MOVL» m(CX), BP | 679 » MOVL» g(CX), BP |
| 680 » MOVL» g_m(BP), BP |
672 | 681 |
673 havem: | 682 havem: |
674 // Now there's a valid m, and we're running on its m->g0. | 683 // Now there's a valid m, and we're running on its m->g0. |
675 // Save current m->g0->sched.sp on stack and then set it to SP. | 684 // Save current m->g0->sched.sp on stack and then set it to SP. |
676 // Save current sp in m->g0->sched.sp in preparation for | 685 // Save current sp in m->g0->sched.sp in preparation for |
677 // switch back to m->curg stack. | 686 // switch back to m->curg stack. |
678 // NOTE: unwindm knows that the saved g->sched.sp is at 0(SP). | 687 // NOTE: unwindm knows that the saved g->sched.sp is at 0(SP). |
679 MOVL m_g0(BP), SI | 688 MOVL m_g0(BP), SI |
680 MOVL (g_sched+gobuf_sp)(SI), AX | 689 MOVL (g_sched+gobuf_sp)(SI), AX |
681 MOVL AX, 0(SP) | 690 MOVL AX, 0(SP) |
(...skipping 29 matching lines...) Expand all Loading... |
711 get_tls(CX) | 720 get_tls(CX) |
712 MOVL g(CX), SI | 721 MOVL g(CX), SI |
713 MOVL 12(SP), BP | 722 MOVL 12(SP), BP |
714 MOVL BP, (g_sched+gobuf_pc)(SI) | 723 MOVL BP, (g_sched+gobuf_pc)(SI) |
715 LEAL (12+4)(SP), DI | 724 LEAL (12+4)(SP), DI |
716 MOVL DI, (g_sched+gobuf_sp)(SI) | 725 MOVL DI, (g_sched+gobuf_sp)(SI) |
717 | 726 |
718 // Switch back to m->g0's stack and restore m->g0->sched.sp. | 727 // Switch back to m->g0's stack and restore m->g0->sched.sp. |
719 // (Unlike m->curg, the g0 goroutine never uses sched.pc, | 728 // (Unlike m->curg, the g0 goroutine never uses sched.pc, |
720 // so we do not have to restore it.) | 729 // so we do not have to restore it.) |
721 » MOVL» m(CX), BP | 730 » MOVL» g(CX), BP |
| 731 » MOVL» g_m(BP), BP |
722 MOVL m_g0(BP), SI | 732 MOVL m_g0(BP), SI |
723 MOVL SI, g(CX) | 733 MOVL SI, g(CX) |
724 MOVL (g_sched+gobuf_sp)(SI), SP | 734 MOVL (g_sched+gobuf_sp)(SI), SP |
725 MOVL 0(SP), AX | 735 MOVL 0(SP), AX |
726 MOVL AX, (g_sched+gobuf_sp)(SI) | 736 MOVL AX, (g_sched+gobuf_sp)(SI) |
727 ········ | 737 ········ |
728 // If the m on entry was nil, we called needm above to borrow an m | 738 // If the m on entry was nil, we called needm above to borrow an m |
729 // for the duration of the call. Since the call is over, return it with
dropm. | 739 // for the duration of the call. Since the call is over, return it with
dropm. |
730 CMPL DX, $0 | 740 CMPL DX, $0 |
731 JNE 3(PC) | 741 JNE 3(PC) |
732 MOVL $runtime·dropm(SB), AX | 742 MOVL $runtime·dropm(SB), AX |
733 CALL AX | 743 CALL AX |
734 | 744 |
735 // Done! | 745 // Done! |
736 RET | 746 RET |
737 | 747 |
738 // void setmg(M*, G*); set m and g. for use by needm. | 748 // void setg(G*); set g. for use by needm. |
739 TEXT runtime·setmg(SB), NOSPLIT, $0-8 | 749 TEXT runtime·setg(SB), NOSPLIT, $0-8 |
| 750 » MOVL» gg+0(FP), BX |
740 #ifdef GOOS_windows | 751 #ifdef GOOS_windows |
741 » MOVL» mm+0(FP), AX | 752 » CMPL» BX, $0 |
742 » CMPL» AX, $0 | |
743 JNE settls | 753 JNE settls |
744 MOVL $0, 0x14(FS) | 754 MOVL $0, 0x14(FS) |
745 RET | 755 RET |
746 settls: | 756 settls: |
| 757 MOVL g_m(BX), AX |
747 LEAL m_tls(AX), AX | 758 LEAL m_tls(AX), AX |
748 MOVL AX, 0x14(FS) | 759 MOVL AX, 0x14(FS) |
749 #endif | 760 #endif |
750 MOVL mm+0(FP), AX | |
751 get_tls(CX) | 761 get_tls(CX) |
752 MOVL mm+0(FP), AX | |
753 MOVL AX, m(CX) | |
754 MOVL gg+4(FP), BX | |
755 MOVL BX, g(CX) | 762 MOVL BX, g(CX) |
756 RET | 763 RET |
757 | 764 |
758 // void setmg_gcc(M*, G*); set m and g. for use by gcc | 765 // void setg_gcc(G*); set g. for use by gcc |
759 TEXT setmg_gcc<>(SB), NOSPLIT, $0 | 766 TEXT setg_gcc<>(SB), NOSPLIT, $0 |
760 get_tls(AX) | 767 get_tls(AX) |
761 » MOVL» mm+0(FP), DX | 768 » MOVL» gg+0(FP), DX |
762 » MOVL» DX, m(AX) | 769 » MOVL» DX, g(AX) |
763 » MOVL» gg+4(FP), DX | |
764 » MOVL» DX,g (AX) | |
765 RET | 770 RET |
766 | 771 |
767 // check that SP is in range [g->stackbase, g->stackguard) | 772 // check that SP is in range [g->stackbase, g->stackguard) |
768 TEXT runtime·stackcheck(SB), NOSPLIT, $0-0 | 773 TEXT runtime·stackcheck(SB), NOSPLIT, $0-0 |
769 get_tls(CX) | 774 get_tls(CX) |
770 MOVL g(CX), AX | 775 MOVL g(CX), AX |
771 CMPL g_stackbase(AX), SP | 776 CMPL g_stackbase(AX), SP |
772 JHI 2(PC) | 777 JHI 2(PC) |
773 INT $3 | 778 INT $3 |
774 CMPL SP, g_stackguard(AX) | 779 CMPL SP, g_stackguard(AX) |
(...skipping 1410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2185 ········ | 2190 ········ |
2186 MOVL (SI),CX | 2191 MOVL (SI),CX |
2187 ADDL $4,SI | 2192 ADDL $4,SI |
2188 MOVL CX,(DI) | 2193 MOVL CX,(DI) |
2189 ADDL $4,DI | 2194 ADDL $4,DI |
2190 ········ | 2195 ········ |
2191 RET | 2196 RET |
2192 | 2197 |
2193 TEXT runtime·timenow(SB), NOSPLIT, $0-0 | 2198 TEXT runtime·timenow(SB), NOSPLIT, $0-0 |
2194 JMP time·now(SB) | 2199 JMP time·now(SB) |
LEFT | RIGHT |