7
7
TEXT _rt0_amd64(SB),7,$-8
8
8
// copy arguments forward on an even stack
10
LEAQ 8(DI), BX // argv
11
11
SUBQ $(4*8+7), SP // 2args 2auto
16
16
// create istack out of the given (operating system) stack.
17
// initcgo may update stackguard.
17
// _cgo_init may update stackguard.
18
18
MOVQ $runtime·g0(SB), DI
19
19
LEAQ (-64*1024+104)(SP), BX
20
20
MOVQ BX, g_stackguard(DI)
21
21
MOVQ SP, g_stackbase(DI)
23
// if there is an initcgo, call it.
23
// find out information about the processor we're on
30
MOVL CX, runtime·cpuid_ecx(SB)
31
MOVL DX, runtime·cpuid_edx(SB)
34
// if there is an _cgo_init, call it.
35
MOVQ _cgo_init(SB), AX
27
38
// g0 already in DI
28
39
MOVQ DI, CX // Win64 uses CX for first parameter
40
MOVQ $setmg_gcc<>(SB), SI
30
42
CMPL runtime·iswindows(SB), $0
46
// skip TLS setup on Plan 9
47
CMPL runtime·isplan9(SB), $1
34
50
LEAQ runtime·tls0(SB), DI
35
51
CALL runtime·settls(SB)
114
134
MOVQ gobuf_pc(BX), BX
117
// void gogocall(Gobuf*, void (*fn)(void))
137
// void gogocall(Gobuf*, void (*fn)(void), uintptr r0)
118
138
// restore state from Gobuf but then call fn.
119
139
// (call fn, returning to state in Gobuf)
120
140
TEXT runtime·gogocall(SB), 7, $0
141
MOVQ 24(SP), DX // context
121
142
MOVQ 16(SP), AX // fn
122
143
MOVQ 8(SP), BX // gobuf
126
MOVQ 0(DX), CX // make sure g != nil
147
MOVQ 0(DI), CX // make sure g != nil
127
148
MOVQ gobuf_sp(BX), SP // restore SP
128
149
MOVQ gobuf_pc(BX), BX
131
152
POPQ BX // not reached
154
// void gogocallfn(Gobuf*, FuncVal*)
155
// restore state from Gobuf but then call fn.
156
// (call fn, returning to state in Gobuf)
157
TEXT runtime·gogocallfn(SB), 7, $0
158
MOVQ 16(SP), DX // fn
159
MOVQ 8(SP), BX // gobuf
163
MOVQ 0(AX), CX // make sure g != nil
164
MOVQ gobuf_sp(BX), SP // restore SP
165
MOVQ gobuf_pc(BX), BX
169
POPQ BX // not reached
133
171
// void mcall(void (*fn)(G*))
134
172
// Switch to m->g0's stack, call fn(g).
135
173
// Fn must never return. It should gogo(&g->sched)
484
TEXT runtime·atomicstore64(SB), 7, $0
405
490
// void jmpdefer(fn, sp);
406
491
// called from deferreturn.
407
492
// 1. pop the caller
408
493
// 2. sub 5 bytes from the callers return
409
494
// 3. jmp to the argument
410
495
TEXT runtime·jmpdefer(SB), 7, $0
412
497
MOVQ 16(SP), BX // caller sp
413
498
LEAQ -8(BX), SP // caller sp after CALL
414
499
SUBQ $5, (SP) // return to CALL again
415
JMP AX // but first run the deferred function
501
JMP BX // but first run the deferred function
417
503
// Dummy function to use in saved gobuf.PC,
418
504
// to match SP pointing at a return address.
446
532
MOVQ (g_sched+gobuf_sp)(SI), SP
448
534
// Now on a scheduling stack (a pthread-created stack).
535
// Make sure we have enough room for 4 stack-backed fast-call
536
// registers as per windows amd64 calling convention.
450
538
ANDQ $~15, SP // alignment for gcc ABI
451
MOVQ DI, 32(SP) // save g
452
MOVQ DX, 24(SP) // save SP
539
MOVQ DI, 48(SP) // save g
540
MOVQ DX, 40(SP) // save SP
453
541
MOVQ BX, DI // DI = first argument in AMD64 ABI
454
542
MOVQ BX, CX // CX = first argument in Win64
457
545
// Restore registers, g, stack pointer.
464
552
// cgocallback(void (*fn)(void*), void *frame, uintptr framesize)
465
// See cgocall.c for more details.
553
// Turn the fn into a Go func (by taking its address) and call
554
// cgocallback_gofunc.
466
555
TEXT runtime·cgocallback(SB),7,$24
469
MOVQ framesize+16(FP), DX
560
MOVQ framesize+16(FP), AX
562
MOVQ $runtime·cgocallback_gofunc(SB), AX
566
// cgocallback_gofunc(FuncVal*, void *frame, uintptr framesize)
567
// See cgocall.c for more details.
568
TEXT runtime·cgocallback_gofunc(SB),7,$24
569
// If m is nil, Go did not create the current thread.
570
// Call needm to obtain one for temporary use.
571
// In this case, we're running on the thread stack, so there's
572
// lots of space, but the linker doesn't know. Hide the call from
573
// the linker analysis by using an indirect call through AX.
586
MOVQ $runtime·needm(SB), AX
592
// Now there's a valid m, and we're running on its m->g0.
471
593
// Save current m->g0->sched.sp on stack and then set it to SP.
475
// If m is nil, it is almost certainly because we have been called
476
// on a thread that Go did not create. We're going to crash as
477
// soon as we try to use m; instead, try to print a nice error and exit.
480
CALL runtime·badcallback(SB)
594
// Save current sp in m->g0->sched.sp in preparation for
595
// switch back to m->curg stack.
482
596
MOVQ m_g0(BP), SI
483
597
PUSHQ (g_sched+gobuf_sp)(SI)
484
598
MOVQ SP, (g_sched+gobuf_sp)(SI)
535
653
MOVQ (g_sched+gobuf_sp)(SI), SP
536
654
POPQ (g_sched+gobuf_sp)(SI)
656
// If the m on entry was nil, we called needm above to borrow an m
657
// for the duration of the call. Since the call is over, return it with dropm.
661
MOVQ $runtime·dropm(SB), AX
667
// void setmg(M*, G*); set m and g. for use by needm.
668
TEXT runtime·setmg(SB), 7, $0
686
// void setmg_gcc(M*, G*); set m and g called from gcc.
687
TEXT setmg_gcc<>(SB),7,$0
541
693
// check that SP is in range [g->stackbase, g->stackguard)
542
694
TEXT runtime·stackcheck(SB), 7, $0
595
747
MOVQ g_stackguard(BX), DX
599
751
GLOBL runtime·tls0(SB), $64
753
// hash function using AES hardware instructions
754
TEXT runtime·aeshash(SB),7,$0
755
MOVQ 8(SP), DX // ptr to hash value
756
MOVQ 16(SP), CX // size
757
MOVQ 24(SP), AX // ptr to data
758
JMP runtime·aeshashbody(SB)
760
TEXT runtime·aeshashstr(SB),7,$0
761
MOVQ 8(SP), DX // ptr to hash value
762
MOVQ 24(SP), AX // ptr to string struct
763
MOVQ 8(AX), CX // length of string
764
MOVQ (AX), AX // string data
765
JMP runtime·aeshashbody(SB)
769
// DX: ptr to seed input / hash output
770
TEXT runtime·aeshashbody(SB),7,$0
771
MOVQ (DX), X0 // seed to low 64 bits of xmm0
772
PINSRQ $1, CX, X0 // size to high 64 bits of xmm0
773
MOVO runtime·aeskeysched+0(SB), X2
774
MOVO runtime·aeskeysched+16(SB), X3
786
JE finalize // no partial block
791
// address ends in 0xxxx. 16 bytes loaded
792
// at this address won't cross a page boundary, so
793
// we can load it directly.
796
PAND masks(SB)(CX*8), X1
799
// address ends in 1xxxx. Might be up against
800
// a page boundary, so load ending at last byte.
801
// Then shift bytes down using pshufb.
802
MOVOU -16(AX)(CX*1), X1
804
PSHUFB shifts(SB)(CX*8), X1
806
// incorporate partial block into hash
817
TEXT runtime·aeshash32(SB),7,$0
818
MOVQ 8(SP), DX // ptr to hash value
819
MOVQ 24(SP), AX // ptr to data
820
MOVQ (DX), X0 // seed
821
PINSRD $2, (AX), X0 // data
822
AESENC runtime·aeskeysched+0(SB), X0
823
AESENC runtime·aeskeysched+16(SB), X0
824
AESENC runtime·aeskeysched+0(SB), X0
828
TEXT runtime·aeshash64(SB),7,$0
829
MOVQ 8(SP), DX // ptr to hash value
830
MOVQ 24(SP), AX // ptr to data
831
MOVQ (DX), X0 // seed
832
PINSRQ $1, (AX), X0 // data
833
AESENC runtime·aeskeysched+0(SB), X0
834
AESENC runtime·aeskeysched+16(SB), X0
835
AESENC runtime·aeskeysched+0(SB), X0
839
// simple mask to get rid of data in the high part of the register.
841
QUAD $0x0000000000000000
842
QUAD $0x0000000000000000
843
QUAD $0x00000000000000ff
844
QUAD $0x0000000000000000
845
QUAD $0x000000000000ffff
846
QUAD $0x0000000000000000
847
QUAD $0x0000000000ffffff
848
QUAD $0x0000000000000000
849
QUAD $0x00000000ffffffff
850
QUAD $0x0000000000000000
851
QUAD $0x000000ffffffffff
852
QUAD $0x0000000000000000
853
QUAD $0x0000ffffffffffff
854
QUAD $0x0000000000000000
855
QUAD $0x00ffffffffffffff
856
QUAD $0x0000000000000000
857
QUAD $0xffffffffffffffff
858
QUAD $0x0000000000000000
859
QUAD $0xffffffffffffffff
860
QUAD $0x00000000000000ff
861
QUAD $0xffffffffffffffff
862
QUAD $0x000000000000ffff
863
QUAD $0xffffffffffffffff
864
QUAD $0x0000000000ffffff
865
QUAD $0xffffffffffffffff
866
QUAD $0x00000000ffffffff
867
QUAD $0xffffffffffffffff
868
QUAD $0x000000ffffffffff
869
QUAD $0xffffffffffffffff
870
QUAD $0x0000ffffffffffff
871
QUAD $0xffffffffffffffff
872
QUAD $0x00ffffffffffffff
874
// these are arguments to pshufb. They move data down from
875
// the high bytes of the register to the low bytes of the register.
876
// index is how many bytes to move.
878
QUAD $0x0000000000000000
879
QUAD $0x0000000000000000
880
QUAD $0xffffffffffffff0f
881
QUAD $0xffffffffffffffff
882
QUAD $0xffffffffffff0f0e
883
QUAD $0xffffffffffffffff
884
QUAD $0xffffffffff0f0e0d
885
QUAD $0xffffffffffffffff
886
QUAD $0xffffffff0f0e0d0c
887
QUAD $0xffffffffffffffff
888
QUAD $0xffffff0f0e0d0c0b
889
QUAD $0xffffffffffffffff
890
QUAD $0xffff0f0e0d0c0b0a
891
QUAD $0xffffffffffffffff
892
QUAD $0xff0f0e0d0c0b0a09
893
QUAD $0xffffffffffffffff
894
QUAD $0x0f0e0d0c0b0a0908
895
QUAD $0xffffffffffffffff
896
QUAD $0x0e0d0c0b0a090807
897
QUAD $0xffffffffffffff0f
898
QUAD $0x0d0c0b0a09080706
899
QUAD $0xffffffffffff0f0e
900
QUAD $0x0c0b0a0908070605
901
QUAD $0xffffffffff0f0e0d
902
QUAD $0x0b0a090807060504
903
QUAD $0xffffffff0f0e0d0c
904
QUAD $0x0a09080706050403
905
QUAD $0xffffff0f0e0d0c0b
906
QUAD $0x0908070605040302
907
QUAD $0xffff0f0e0d0c0b0a
908
QUAD $0x0807060504030201
909
QUAD $0xff0f0e0d0c0b0a09
911
TEXT runtime·memeq(SB),7,$0
914
MOVQ count+16(FP), BX
915
JMP runtime·memeqbody(SB)
918
TEXT bytes·Equal(SB),7,$0
920
MOVQ b_len+32(FP), CX
926
CALL runtime·memeqbody(SB)
934
TEXT runtime·memeqbody(SB),7,$0
940
// 64 bytes at a time using xmm registers
967
// 8 bytes at a time using 64-bit register
980
// remaining 0-8 bytes
982
MOVQ -8(SI)(BX*1), CX
983
MOVQ -8(DI)(BX*1), DX
998
// load at SI won't cross a page boundary.
1002
// address ends in 11111xxx. Load up to bytes we want, move to correct position.
1003
MOVQ -8(SI)(BX*1), SI
1013
MOVQ -8(DI)(BX*1), DI