OLD | NEW |
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 | 7 |
8 TEXT _rt0_go(SB),7,$0 | 8 TEXT _rt0_go(SB),7,$0 |
9 // copy arguments forward on an even stack | 9 // copy arguments forward on an even stack |
10 MOVQ DI, AX // argc | 10 MOVQ DI, AX // argc |
(...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
556 MOVQ frame+8(FP), AX | 556 MOVQ frame+8(FP), AX |
557 MOVQ AX, 8(SP) | 557 MOVQ AX, 8(SP) |
558 MOVQ framesize+16(FP), AX | 558 MOVQ framesize+16(FP), AX |
559 MOVQ AX, 16(SP) | 559 MOVQ AX, 16(SP) |
560 MOVQ $runtime·cgocallback_gofunc(SB), AX | 560 MOVQ $runtime·cgocallback_gofunc(SB), AX |
561 CALL AX | 561 CALL AX |
562 RET | 562 RET |
563 | 563 |
564 // cgocallback_gofunc(FuncVal*, void *frame, uintptr framesize) | 564 // cgocallback_gofunc(FuncVal*, void *frame, uintptr framesize) |
565 // See cgocall.c for more details. | 565 // See cgocall.c for more details. |
566 TEXT runtime·cgocallback_gofunc(SB),7,$16-24 | 566 TEXT runtime·cgocallback_gofunc(SB),7,$8-24 |
567 // If m is nil, Go did not create the current thread. | 567 // If m is nil, Go did not create the current thread. |
568 // Call needm to obtain one for temporary use. | 568 // Call needm to obtain one for temporary use. |
569 // In this case, we're running on the thread stack, so there's | 569 // In this case, we're running on the thread stack, so there's |
570 // lots of space, but the linker doesn't know. Hide the call from | 570 // lots of space, but the linker doesn't know. Hide the call from |
571 // the linker analysis by using an indirect call through AX. | 571 // the linker analysis by using an indirect call through AX. |
572 get_tls(CX) | 572 get_tls(CX) |
573 #ifdef GOOS_windows | 573 #ifdef GOOS_windows |
574 MOVL $0, BP | 574 MOVL $0, BP |
575 CMPQ CX, $0 | 575 CMPQ CX, $0 |
576 JEQ 2(PC) | 576 JEQ 2(PC) |
577 #endif | 577 #endif |
578 MOVQ m(CX), BP | 578 MOVQ m(CX), BP |
579 » MOVQ» BP, 8(SP) | 579 » MOVQ» BP, R8 // holds oldm until end of function |
580 CMPQ BP, $0 | 580 CMPQ BP, $0 |
581 JNE havem | 581 JNE havem |
582 needm: | 582 needm: |
| 583 MOVQ R8, 0(SP) |
583 MOVQ $runtime·needm(SB), AX | 584 MOVQ $runtime·needm(SB), AX |
584 CALL AX | 585 CALL AX |
| 586 MOVQ 0(SP), R8 |
585 get_tls(CX) | 587 get_tls(CX) |
586 MOVQ m(CX), BP | 588 MOVQ m(CX), BP |
587 | 589 |
588 havem: | 590 havem: |
589 // Now there's a valid m, and we're running on its m->g0. | 591 // Now there's a valid m, and we're running on its m->g0. |
590 // Save current m->g0->sched.sp on stack and then set it to SP. | 592 // Save current m->g0->sched.sp on stack and then set it to SP. |
591 // Save current sp in m->g0->sched.sp in preparation for | 593 // Save current sp in m->g0->sched.sp in preparation for |
592 // switch back to m->curg stack. | 594 // switch back to m->curg stack. |
593 // NOTE: unwindm knows that the saved g->sched.sp is at 0(SP). | 595 // NOTE: unwindm knows that the saved g->sched.sp is at 0(SP). |
594 MOVQ m_g0(BP), SI | 596 MOVQ m_g0(BP), SI |
595 MOVQ (g_sched+gobuf_sp)(SI), AX | 597 MOVQ (g_sched+gobuf_sp)(SI), AX |
596 MOVQ AX, 0(SP) | 598 MOVQ AX, 0(SP) |
597 MOVQ SP, (g_sched+gobuf_sp)(SI) | 599 MOVQ SP, (g_sched+gobuf_sp)(SI) |
598 | 600 |
599 // Switch to m->curg stack and call runtime.cgocallbackg. | 601 // Switch to m->curg stack and call runtime.cgocallbackg. |
600 // Because we are taking over the execution of m->curg | 602 // Because we are taking over the execution of m->curg |
601 // but *not* resuming what had been running, we need to | 603 // but *not* resuming what had been running, we need to |
602 // save that information (m->curg->sched) so we can restore it. | 604 // save that information (m->curg->sched) so we can restore it. |
603 // We can restore m->curg->sched.sp easily, because calling | 605 // We can restore m->curg->sched.sp easily, because calling |
604 // runtime.cgocallbackg leaves SP unchanged upon return. | 606 // runtime.cgocallbackg leaves SP unchanged upon return. |
605 // To save m->curg->sched.pc, we push it onto the stack. | 607 // To save m->curg->sched.pc, we push it onto the stack. |
606 // This has the added benefit that it looks to the traceback | 608 // This has the added benefit that it looks to the traceback |
607 // routine like cgocallbackg is going to return to that | 609 // routine like cgocallbackg is going to return to that |
608 // PC (because the frame we allocate below has the same | 610 // PC (because the frame we allocate below has the same |
609 // size as cgocallback_gofunc's frame declared above) | 611 // size as cgocallback_gofunc's frame declared above) |
610 // so that the traceback will seamlessly trace back into | 612 // so that the traceback will seamlessly trace back into |
611 // the earlier calls. | 613 // the earlier calls. |
612 // | 614 // |
613 » // In the new goroutine, 0(SP) and 8(SP) are unused except | 615 » // In the new goroutine, 0(SP) holds the saved R8. |
614 » // on Windows, where they are the SEH block. | |
615 MOVQ m_curg(BP), SI | 616 MOVQ m_curg(BP), SI |
616 MOVQ SI, g(CX) | 617 MOVQ SI, g(CX) |
617 MOVQ (g_sched+gobuf_sp)(SI), DI // prepare stack as DI | 618 MOVQ (g_sched+gobuf_sp)(SI), DI // prepare stack as DI |
618 MOVQ (g_sched+gobuf_pc)(SI), BP | 619 MOVQ (g_sched+gobuf_pc)(SI), BP |
619 MOVQ BP, -8(DI) | 620 MOVQ BP, -8(DI) |
620 » LEAQ» -(8+16)(DI), SP | 621 » LEAQ» -(8+8)(DI), SP |
| 622 » MOVQ» R8, 0(SP) |
621 CALL runtime·cgocallbackg(SB) | 623 CALL runtime·cgocallbackg(SB) |
| 624 MOVQ 0(SP), R8 |
622 | 625 |
623 // Restore g->sched (== m->curg->sched) from saved values. | 626 // Restore g->sched (== m->curg->sched) from saved values. |
624 get_tls(CX) | 627 get_tls(CX) |
625 MOVQ g(CX), SI | 628 MOVQ g(CX), SI |
626 » MOVQ» 16(SP), BP | 629 » MOVQ» 8(SP), BP |
627 MOVQ BP, (g_sched+gobuf_pc)(SI) | 630 MOVQ BP, (g_sched+gobuf_pc)(SI) |
628 » LEAQ» (16+8)(SP), DI | 631 » LEAQ» (8+8)(SP), DI |
629 MOVQ DI, (g_sched+gobuf_sp)(SI) | 632 MOVQ DI, (g_sched+gobuf_sp)(SI) |
630 | 633 |
631 // Switch back to m->g0's stack and restore m->g0->sched.sp. | 634 // Switch back to m->g0's stack and restore m->g0->sched.sp. |
632 // (Unlike m->curg, the g0 goroutine never uses sched.pc, | 635 // (Unlike m->curg, the g0 goroutine never uses sched.pc, |
633 // so we do not have to restore it.) | 636 // so we do not have to restore it.) |
634 MOVQ m(CX), BP | 637 MOVQ m(CX), BP |
635 MOVQ m_g0(BP), SI | 638 MOVQ m_g0(BP), SI |
636 MOVQ SI, g(CX) | 639 MOVQ SI, g(CX) |
637 MOVQ (g_sched+gobuf_sp)(SI), SP | 640 MOVQ (g_sched+gobuf_sp)(SI), SP |
638 MOVQ 0(SP), AX | 641 MOVQ 0(SP), AX |
639 MOVQ AX, (g_sched+gobuf_sp)(SI) | 642 MOVQ AX, (g_sched+gobuf_sp)(SI) |
640 ········ | 643 ········ |
641 // If the m on entry was nil, we called needm above to borrow an m | 644 // If the m on entry was nil, we called needm above to borrow an m |
642 // for the duration of the call. Since the call is over, return it with
dropm. | 645 // for the duration of the call. Since the call is over, return it with
dropm. |
643 » MOVQ» 8(SP), BP | 646 » CMPQ» R8, $0 |
644 » CMPQ» BP, $0 | |
645 JNE 3(PC) | 647 JNE 3(PC) |
646 MOVQ $runtime·dropm(SB), AX | 648 MOVQ $runtime·dropm(SB), AX |
647 CALL AX | 649 CALL AX |
648 | 650 |
649 // Done! | 651 // Done! |
650 RET | 652 RET |
651 | 653 |
652 // void setmg(M*, G*); set m and g. for use by needm. | 654 // void setmg(M*, G*); set m and g. for use by needm. |
653 TEXT runtime·setmg(SB), 7, $0-16 | 655 TEXT runtime·setmg(SB), 7, $0-16 |
654 MOVQ mm+0(FP), AX | 656 MOVQ mm+0(FP), AX |
(...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1134 RET | 1136 RET |
1135 | 1137 |
1136 cmp_allsame: | 1138 cmp_allsame: |
1137 XORQ AX, AX | 1139 XORQ AX, AX |
1138 XORQ CX, CX | 1140 XORQ CX, CX |
1139 CMPQ BX, DX | 1141 CMPQ BX, DX |
1140 SETGT AX // 1 if alen > blen | 1142 SETGT AX // 1 if alen > blen |
1141 SETEQ CX // 1 if alen == blen | 1143 SETEQ CX // 1 if alen == blen |
1142 LEAQ -1(CX)(AX*2), AX // 1,0,-1 result | 1144 LEAQ -1(CX)(AX*2), AX // 1,0,-1 result |
1143 RET | 1145 RET |
OLD | NEW |