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-style2// 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.
44
5#include "zasm_GOOS_GOARCH.h"5#include "zasm_GOOS_GOARCH.h"
6#include "funcdata.h"6#include "funcdata.h"
7#include "textflag.h"7#include "textflag.h"
88
9TEXT runtime·rt0_go(SB),NOSPLIT,$09TEXT runtime·rt0_go(SB), NOSPLIT, $0
10        // copy arguments forward on an even stack10        // copy arguments forward on an even stack
11        MOVQ        DI, AX                // argc11        MOVQ DI, AX       // argc
12        MOVQ        SI, BX                // argv12        MOVQ SI, BX       // argv
13        SUBQ        $(4*8+7), SP                // 2args 2auto13        SUBQ $(4*8+7), SP // 2args 2auto
14        ANDQ        $~15, SP14        ANDQ $~15, SP
15        MOVQ        AX, 16(SP)15        MOVQ AX, 16(SP)
16        MOVQ        BX, 24(SP)16        MOVQ BX, 24(SP)
17         17
18        // create istack out of the given (operating system) stack.18        // create istack out of the given (operating system) stack.
19        // _cgo_init may update stackguard.19        // _cgo_init may update stackguard.
20        MOVQ        $runtime·g0(SB), DI20        MOVQ $runtime·g0(SB), DI
21        LEAQ        (-64*1024+104)(SP), BX21        LEAQ (-64*1024+104)(SP), BX
22        MOVQ        BX, g_stackguard0(DI)22        MOVQ BX, g_stackguard0(DI)
23        MOVQ        BX, g_stackguard1(DI)23        MOVQ BX, g_stackguard1(DI)
24        MOVQ        BX, (g_stack+stack_lo)(DI)24        MOVQ BX, (g_stack+stack_lo)(DI)
25        MOVQ        SP, (g_stack+stack_hi)(DI)25        MOVQ SP, (g_stack+stack_hi)(DI)
2626
27        // find out information about the processor we're on27        // find out information about the processor we're on
28        MOVQ        $0, AX28        MOVQ $0, AX
29        CPUID29        CPUID
30        CMPQ        AX, $030        CMPQ AX, $0
31        JE        nocpuinfo31        JE   nocpuinfo
32        MOVQ        $1, AX32        MOVQ $1, AX
33        CPUID33        CPUID
34        MOVL        CX, runtime·cpuid_ecx(SB)34        MOVL CX, runtime·cpuid_ecx(SB)
35        MOVL        DX, runtime·cpuid_edx(SB)35        MOVL DX, runtime·cpuid_edx(SB)
36
36nocpuinfo:        37nocpuinfo:
37         38
38        // if there is an _cgo_init, call it.39        // if there is an _cgo_init, call it.
39        MOVQ        _cgo_init(SB), AX40        MOVQ  _cgo_init(SB), AX
40        TESTQ        AX, AX41        TESTQ AX, AX
41        JZ        needtls42        JZ    needtls
43
42        // g0 already in DI44        // g0 already in DI
43        MOVQ        DI, CX        // Win64 uses CX for first parameter45        MOVQ DI, CX              // Win64 uses CX for first parameter
44        MOVQ        $setg_gcc<>(SB), SI46        MOVQ $setg_gcc<>(SB), SI
45        CALL        AX47        CALL AX
4648
47        // update stackguard after _cgo_init49        // update stackguard after _cgo_init
48        MOVQ        $runtime·g0(SB), CX50        MOVQ $runtime·g0(SB), CX
49        MOVQ        (g_stack+stack_lo)(CX), AX51        MOVQ (g_stack+stack_lo)(CX), AX
50        ADDQ        $const_StackGuard, AX52        ADDQ $const_StackGuard, AX
51        MOVQ        AX, g_stackguard0(CX)53        MOVQ AX, g_stackguard0(CX)
52        MOVQ        AX, g_stackguard1(CX)54        MOVQ AX, g_stackguard1(CX)
5355
54        CMPL        runtime·iswindows(SB), $056        CMPL runtime·iswindows(SB), $0
55        JEQ ok57        JEQ  ok
58
56needtls:59needtls:
57        // skip TLS setup on Plan 960        // skip TLS setup on Plan 9
58        CMPL        runtime·isplan9(SB), $161        CMPL runtime·isplan9(SB), $1
59        JEQ ok62        JEQ  ok
63
60        // skip TLS setup on Solaris64        // skip TLS setup on Solaris
61        CMPL        runtime·issolaris(SB), $165        CMPL runtime·issolaris(SB), $1
62        JEQ ok66        JEQ  ok
6367
64        LEAQ        runtime·tls0(SB), DI68        LEAQ runtime·tls0(SB), DI
65        CALL        runtime·settls(SB)69        CALL runtime·settls(SB)
6670
67        // store through it, to make sure it works71        // store through it, to make sure it works
68        get_tls(BX)72        get_tls(BX)
69        MOVQ        $0x123, g(BX)73        MOVQ $0x123, g(BX)
70        MOVQ        runtime·tls0(SB), AX74        MOVQ runtime·tls0(SB), AX
71        CMPQ        AX, $0x12375        CMPQ AX, $0x123
72        JEQ 2(PC)76        JEQ  2(PC)
73        MOVL        AX, 0        // abort77        MOVL AX, 0                // abort
78
74ok:79ok:
75        // set the per-goroutine and per-mach "registers"80        // set the per-goroutine and per-mach "registers"
76        get_tls(BX)81        get_tls(BX)
77        LEAQ        runtime·g0(SB), CX82        LEAQ runtime·g0(SB), CX
78        MOVQ        CX, g(BX)83        MOVQ CX, g(BX)
79        LEAQ        runtime·m0(SB), AX84        LEAQ runtime·m0(SB), AX
8085
81        // save m->g0 = g086        // save m->g0 = g0
82        MOVQ        CX, m_g0(AX)87        MOVQ CX, m_g0(AX)
88
83        // save m0 to g0->m89        // save m0 to g0->m
84        MOVQ        AX, g_m(CX)90        MOVQ AX, g_m(CX)
8591
86        CLD                                // convention is D is always left cleared92        CLD                    // convention is D is always left cleared
87        CALL        runtime·check(SB)93        CALL runtime·check(SB)
8894
89        MOVL        16(SP), AX                // copy argc95        MOVL 16(SP), AX            // copy argc
90        MOVL        AX, 0(SP)96        MOVL AX, 0(SP)
91        MOVQ        24(SP), AX                // copy argv97        MOVQ 24(SP), AX            // copy argv
92        MOVQ        AX, 8(SP)98        MOVQ AX, 8(SP)
93        CALL        runtime·args(SB)99        CALL runtime·args(SB)
94        CALL        runtime·osinit(SB)100        CALL runtime·osinit(SB)
95        CALL        runtime·schedinit(SB)101        CALL runtime·schedinit(SB)
96102
97        // create a new goroutine to start program103        // create a new goroutine to start program
98        MOVQ        $runtime·main·f(SB), BP                // entry104        MOVQ  $runtime·main·f(SB), BP // entry
99        PUSHQ        BP105        PUSHQ BP
100        PUSHQ        $0                        // arg size106        PUSHQ $0                      // arg size
101        CALL        runtime·newproc(SB)107        CALL  runtime·newproc(SB)
102        POPQ        AX108        POPQ  AX
103        POPQ        AX109        POPQ  AX
104110
105        // start this M111        // start this M
106        CALL        runtime·mstart(SB)112        CALL runtime·mstart(SB)
107113
108        MOVL        $0xf1, 0xf1  // crash114        MOVL $0xf1, 0xf1 // crash
109        RET115        RET
110116
111DATA        runtime·main·f+0(SB)/8,$runtime·main(SB)117DATA runtime·main·f+0(SB)/8, $runtime·main(SB)
112GLOBL        runtime·main·f(SB),RODATA,$8118GLOBL runtime·main·f(SB), RODATA, $8
113119
114TEXT runtime·breakpoint(SB),NOSPLIT,$0-0120TEXT runtime·breakpoint(SB), NOSPLIT, $0-0
115        BYTE        $0xcc121        BYTE $0xcc
116        RET122        RET
117123
118TEXT runtime·asminit(SB),NOSPLIT,$0-0124TEXT runtime·asminit(SB), NOSPLIT, $0-0
119        // No per-thread init.125        // No per-thread init.
120        RET126        RET
121127
122/*128/*
123 *  go-routine129 *  go-routine
124 */130 */
125
126// void gosave(Gobuf*)131// void gosave(Gobuf*)
127// save state in Gobuf; setjmp132// save state in Gobuf; setjmp
128TEXT runtime·gosave(SB), NOSPLIT, $0-8133TEXT runtime·gosave(SB), NOSPLIT, $0-8
129        MOVQ        buf+0(FP), AX                // gobuf134        MOVQ buf+0(FP), AX      // gobuf
130        LEAQ        buf+0(FP), BX                // caller's SP135        LEAQ buf+0(FP), BX      // caller's SP
131        MOVQ        BX, gobuf_sp(AX)136        MOVQ BX, gobuf_sp(AX)
132        MOVQ        0(SP), BX                // caller's PC137        MOVQ 0(SP), BX          // caller's PC
133        MOVQ        BX, gobuf_pc(AX)138        MOVQ BX, gobuf_pc(AX)
134        MOVQ        $0, gobuf_ret(AX)139        MOVQ $0, gobuf_ret(AX)
135        MOVQ        $0, gobuf_ctxt(AX)140        MOVQ $0, gobuf_ctxt(AX)
136        get_tls(CX)141        get_tls(CX)
137        MOVQ        g(CX), BX142        MOVQ g(CX), BX
138        MOVQ        BX, gobuf_g(AX)143        MOVQ BX, gobuf_g(AX)
139        RET144        RET
140145
141// void gogo(Gobuf*)146// void gogo(Gobuf*)
142// restore state from Gobuf; longjmp147// restore state from Gobuf; longjmp
143TEXT runtime·gogo(SB), NOSPLIT, $0-8148TEXT runtime·gogo(SB), NOSPLIT, $0-8
144        MOVQ        buf+0(FP), BX                // gobuf149        MOVQ buf+0(FP), BX      // gobuf
145        MOVQ        gobuf_g(BX), DX150        MOVQ gobuf_g(BX), DX
146        MOVQ        0(DX), CX                // make sure g != nil151        MOVQ 0(DX), CX          // make sure g != nil
147        get_tls(CX)152        get_tls(CX)
148        MOVQ        DX, g(CX)153        MOVQ DX, g(CX)
149        MOVQ        gobuf_sp(BX), SP        // restore SP154        MOVQ gobuf_sp(BX), SP   // restore SP
150        MOVQ        gobuf_ret(BX), AX155        MOVQ gobuf_ret(BX), AX
151        MOVQ        gobuf_ctxt(BX), DX156        MOVQ gobuf_ctxt(BX), DX
152        MOVQ        $0, gobuf_sp(BX)        // clear to help garbage collector157        MOVQ $0, gobuf_sp(BX)   // clear to help garbage collector
153        MOVQ        $0, gobuf_ret(BX)158        MOVQ $0, gobuf_ret(BX)
154        MOVQ        $0, gobuf_ctxt(BX)159        MOVQ $0, gobuf_ctxt(BX)
155        MOVQ        gobuf_pc(BX), BX160        MOVQ gobuf_pc(BX), BX
156        JMP        BX161        JMP  BX
157162
158// func mcall(fn func(*g))163// func mcall(fn func(*g))
159// Switch to m->g0's stack, call fn(g).164// Switch to m->g0's stack, call fn(g).
160// Fn must never return.  It should gogo(&g->sched)165// Fn must never return.  It should gogo(&g->sched)
161// to keep running g.166// to keep running g.
162TEXT runtime·mcall(SB), NOSPLIT, $0-8167TEXT runtime·mcall(SB), NOSPLIT, $0-8
163        MOVQ        fn+0(FP), DI168        MOVQ fn+0(FP), DI
164         169
165        get_tls(CX)170        get_tls(CX)
166        MOVQ        g(CX), AX        // save state in g->sched171        MOVQ g(CX), AX                  // save state in g->sched
167        MOVQ        0(SP), BX        // caller's PC172        MOVQ 0(SP), BX                  // caller's PC
168        MOVQ        BX, (g_sched+gobuf_pc)(AX)173        MOVQ BX, (g_sched+gobuf_pc)(AX)
169        LEAQ        fn+0(FP), BX        // caller's SP174        LEAQ fn+0(FP), BX               // caller's SP
170        MOVQ        BX, (g_sched+gobuf_sp)(AX)175        MOVQ BX, (g_sched+gobuf_sp)(AX)
171        MOVQ        AX, (g_sched+gobuf_g)(AX)176        MOVQ AX, (g_sched+gobuf_g)(AX)
172177
173        // switch to m->g0 & its stack, call fn178        // switch to m->g0 & its stack, call fn
174        MOVQ        g(CX), BX179        MOVQ g(CX), BX
175        MOVQ        g_m(BX), BX180        MOVQ g_m(BX), BX
176        MOVQ        m_g0(BX), SI181        MOVQ m_g0(BX), SI
177        CMPQ        SI, AX        // if g == m->g0 call badmcall182        CMPQ SI, AX                    // if g == m->g0 call badmcall
178        JNE        3(PC)183        JNE  3(PC)
179        MOVQ        $runtime·badmcall(SB), AX184        MOVQ $runtime·badmcall(SB), AX
180        JMP        AX185        JMP  AX
181        MOVQ        SI, g(CX)        // g = m->g0186        MOVQ  SI, g(CX)                  // g = m->g0
182        MOVQ        (g_sched+gobuf_sp)(SI), SP        // sp = m->g0->sched.sp187        MOVQ  (g_sched+gobuf_sp)(SI), SP // sp = m->g0->sched.sp
183        PUSHQ        AX188        PUSHQ AX
184        MOVQ        DI, DX189        MOVQ  DI, DX
185        MOVQ        0(DI), DI190        MOVQ  0(DI), DI
186        CALL        DI191        CALL  DI
187        POPQ        AX192        POPQ  AX
188        MOVQ        $runtime·badmcall2(SB), AX193        MOVQ  $runtime·badmcall2(SB), AX
189        JMP        AX194        JMP   AX
190        RET195        RET
191196
192// switchtoM is a dummy routine that onM leaves at the bottom197// switchtoM is a dummy routine that onM leaves at the bottom
193// of the G stack.  We need to distinguish the routine that198// of the G stack.  We need to distinguish the routine that
194// lives at the bottom of the G stack from the one that lives199// lives at the bottom of the G stack from the one that lives
195// at the top of the M stack because the one at the top of200// at the top of the M stack because the one at the top of
196// the M stack terminates the stack walk (see topofstack()).201// the M stack terminates the stack walk (see topofstack()).
197TEXT runtime·switchtoM(SB), NOSPLIT, $0-0202TEXT runtime·switchtoM(SB), NOSPLIT, $0-0
198        RET203        RET
199204
200// func onM_signalok(fn func())205// func onM_signalok(fn func())
201TEXT runtime·onM_signalok(SB), NOSPLIT, $0-8206TEXT runtime·onM_signalok(SB), NOSPLIT, $0-8
202        get_tls(CX)207        get_tls(CX)
203        MOVQ        g(CX), AX        // AX = g208        MOVQ g(CX), AX         // AX = g
204        MOVQ        g_m(AX), BX        // BX = m209        MOVQ g_m(AX), BX       // BX = m
205        MOVQ        m_gsignal(BX), DX        // DX = gsignal210        MOVQ m_gsignal(BX), DX // DX = gsignal
206        CMPQ        AX, DX211        CMPQ AX, DX
207        JEQ        ongsignal212        JEQ  ongsignal
208        JMP        runtime·onM(SB)213        JMP  runtime·onM(SB)
209214
210ongsignal:215ongsignal:
211        MOVQ        fn+0(FP), DI        // DI = fn216        MOVQ fn+0(FP), DI // DI = fn
212        MOVQ        DI, DX217        MOVQ DI, DX
213        MOVQ        0(DI), DI218        MOVQ 0(DI), DI
214        CALL        DI219        CALL DI
215        RET220        RET
216221
217// func onM(fn func())222// func onM(fn func())
218TEXT runtime·onM(SB), NOSPLIT, $0-8223TEXT runtime·onM(SB), NOSPLIT, $0-8
219        MOVQ        fn+0(FP), DI        // DI = fn224        MOVQ fn+0(FP), DI // DI = fn
220        get_tls(CX)225        get_tls(CX)
221        MOVQ        g(CX), AX        // AX = g226        MOVQ g(CX), AX    // AX = g
222        MOVQ        g_m(AX), BX        // BX = m227        MOVQ g_m(AX), BX  // BX = m
223228
224        MOVQ        m_g0(BX), DX        // DX = g0229        MOVQ m_g0(BX), DX // DX = g0
225        CMPQ        AX, DX230        CMPQ AX, DX
226        JEQ        onm231        JEQ  onm
227232
228        MOVQ        m_curg(BX), BP233        MOVQ m_curg(BX), BP
229        CMPQ        AX, BP234        CMPQ AX, BP
230        JEQ        oncurg235        JEQ  oncurg
231         236
232        // Not g0, not curg. Must be gsignal, but that's not allowed.237        // Not g0, not curg. Must be gsignal, but that's not allowed.
233        // Hide call from linker nosplit analysis.238        // Hide call from linker nosplit analysis.
234        MOVQ        $runtime·badonm(SB), AX239        MOVQ $runtime·badonm(SB), AX
235        CALL        AX240        CALL AX
236241
237oncurg:242oncurg:
238        // save our state in g->sched.  Pretend to243        // save our state in g->sched.  Pretend to
239        // be switchtoM if the G stack is scanned.244        // be switchtoM if the G stack is scanned.
240        MOVQ        $runtime·switchtoM(SB), BP245        MOVQ $runtime·switchtoM(SB), BP
241        MOVQ        BP, (g_sched+gobuf_pc)(AX)246        MOVQ BP, (g_sched+gobuf_pc)(AX)
242        MOVQ        SP, (g_sched+gobuf_sp)(AX)247        MOVQ SP, (g_sched+gobuf_sp)(AX)
243        MOVQ        AX, (g_sched+gobuf_g)(AX)248        MOVQ AX, (g_sched+gobuf_g)(AX)
244249
245        // switch to g0250        // switch to g0
246        MOVQ        DX, g(CX)251        MOVQ DX, g(CX)
247        MOVQ        (g_sched+gobuf_sp)(DX), BX252        MOVQ (g_sched+gobuf_sp)(DX), BX
253
248        // make it look like mstart called onM on g0, to stop traceback254        // make it look like mstart called onM on g0, to stop traceback
249        SUBQ        $8, BX255        SUBQ $8, BX
250        MOVQ        $runtime·mstart(SB), DX256        MOVQ $runtime·mstart(SB), DX
251        MOVQ        DX, 0(BX)257        MOVQ DX, 0(BX)
252        MOVQ        BX, SP258        MOVQ BX, SP
253259
254        // call target function260        // call target function
255        MOVQ        DI, DX261        MOVQ DI, DX
256        MOVQ        0(DI), DI262        MOVQ 0(DI), DI
257        CALL        DI263        CALL DI
258264
259        // switch back to g265        // switch back to g
260        get_tls(CX)266        get_tls(CX)
261        MOVQ        g(CX), AX267        MOVQ g(CX), AX
262        MOVQ        g_m(AX), BX268        MOVQ g_m(AX), BX
263        MOVQ        m_curg(BX), AX269        MOVQ m_curg(BX), AX
264        MOVQ        AX, g(CX)270        MOVQ AX, g(CX)
265        MOVQ        (g_sched+gobuf_sp)(AX), SP271        MOVQ (g_sched+gobuf_sp)(AX), SP
266        MOVQ        $0, (g_sched+gobuf_sp)(AX)272        MOVQ $0, (g_sched+gobuf_sp)(AX)
267        RET273        RET
268274
269onm:275onm:
270        // already on m stack, just call directly276        // already on m stack, just call directly
271        MOVQ        DI, DX277        MOVQ DI, DX
272        MOVQ        0(DI), DI278        MOVQ 0(DI), DI
273        CALL        DI279        CALL DI
274        RET280        RET
275281
276/*282/*
277 * support for morestack283 * support for morestack
278 */284 */
279
280// Called during function prolog when more stack is needed.285// Called during function prolog when more stack is needed.
281//286//
282// The traceback routines see morestack on a g0 as being287// The traceback routines see morestack on a g0 as being
283// the top of a stack (for example, morestack calling newstack288// the top of a stack (for example, morestack calling newstack
284// calling the scheduler calling newm calling gc), so we must289// calling the scheduler calling newm calling gc), so we must
285// record an argument size. For that purpose, it has no arguments.290// record an argument size. For that purpose, it has no arguments.
286TEXT runtime·morestack(SB),NOSPLIT,$0-0291TEXT runtime·morestack(SB), NOSPLIT, $0-0
287        // Cannot grow scheduler stack (m->g0).292        // Cannot grow scheduler stack (m->g0).
288        get_tls(CX)293        get_tls(CX)
289        MOVQ        g(CX), BX294        MOVQ g(CX), BX
290        MOVQ        g_m(BX), BX295        MOVQ g_m(BX), BX
291        MOVQ        m_g0(BX), SI296        MOVQ m_g0(BX), SI
292        CMPQ        g(CX), SI297        CMPQ g(CX), SI
293        JNE        2(PC)298        JNE  2(PC)
294        INT        $3299        INT  $3
295300
296        // Cannot grow signal stack (m->gsignal).301        // Cannot grow signal stack (m->gsignal).
297        MOVQ        m_gsignal(BX), SI302        MOVQ m_gsignal(BX), SI
298        CMPQ        g(CX), SI303        CMPQ g(CX), SI
299        JNE        2(PC)304        JNE  2(PC)
300        INT        $3305        INT  $3
301306
302        // Called from f.307        // Called from f.
303        // Set m->morebuf to f's caller.308        // Set m->morebuf to f's caller.
304        MOVQ        8(SP), AX        // f's caller's PC309        MOVQ 8(SP), AX                    // f's caller's PC
305        MOVQ        AX, (m_morebuf+gobuf_pc)(BX)310        MOVQ AX, (m_morebuf+gobuf_pc)(BX)
306        LEAQ        16(SP), AX        // f's caller's SP311        LEAQ 16(SP), AX                   // f's caller's SP
307        MOVQ        AX, (m_morebuf+gobuf_sp)(BX)312        MOVQ AX, (m_morebuf+gobuf_sp)(BX)
308        get_tls(CX)313        get_tls(CX)
309        MOVQ        g(CX), SI314        MOVQ g(CX), SI
310        MOVQ        SI, (m_morebuf+gobuf_g)(BX)315        MOVQ SI, (m_morebuf+gobuf_g)(BX)
311316
312        // Set g->sched to context in f.317        // Set g->sched to context in f.
313        MOVQ        0(SP), AX // f's PC318        MOVQ 0(SP), AX                    // f's PC
314        MOVQ        AX, (g_sched+gobuf_pc)(SI)319        MOVQ AX, (g_sched+gobuf_pc)(SI)
315        MOVQ        SI, (g_sched+gobuf_g)(SI)320        MOVQ SI, (g_sched+gobuf_g)(SI)
316        LEAQ        8(SP), AX // f's SP321        LEAQ 8(SP), AX                    // f's SP
317        MOVQ        AX, (g_sched+gobuf_sp)(SI)322        MOVQ AX, (g_sched+gobuf_sp)(SI)
318        MOVQ        DX, (g_sched+gobuf_ctxt)(SI)323        MOVQ DX, (g_sched+gobuf_ctxt)(SI)
319324
320        // Call newstack on m->g0's stack.325        // Call newstack on m->g0's stack.
321        MOVQ        m_g0(BX), BP326        MOVQ m_g0(BX), BP
322        MOVQ        BP, g(CX)327        MOVQ BP, g(CX)
323        MOVQ        (g_sched+gobuf_sp)(BP), SP328        MOVQ (g_sched+gobuf_sp)(BP), SP
324        CALL        runtime·newstack(SB)329        CALL runtime·newstack(SB)
325        MOVQ        $0, 0x1003        // crash if newstack returns330        MOVQ $0, 0x1003                 // crash if newstack returns
326        RET331        RET
327332
328// morestack but not preserving ctxt.333// morestack but not preserving ctxt.
329TEXT runtime·morestack_noctxt(SB),NOSPLIT,$0334TEXT runtime·morestack_noctxt(SB), NOSPLIT, $0
330        MOVL        $0, DX335        MOVL $0, DX
331        JMP        runtime·morestack(SB)336        JMP  runtime·morestack(SB)
332337
333// reflectcall: call a function with the given argument list338// reflectcall: call a function with the given argument list
334// func call(f *FuncVal, arg *byte, argsize, retoffset uint32).339// func call(f *FuncVal, arg *byte, argsize, retoffset uint32).
335// we don't have variable-sized frames, so we use a small number340// we don't have variable-sized frames, so we use a small number
336// of constant-sized-frame functions to encode a few bits of size in the pc.341// of constant-sized-frame functions to encode a few bits of size in the pc.
337// Caution: ugly multiline assembly macros in your future!342// Caution: ugly multiline assembly macros in your future!
338343
339#define DISPATCH(NAME,MAXSIZE)                \344#define DISPATCH(NAME, MAXSIZE) \
340        CMPQ        CX, $MAXSIZE;                \345        CMPQ CX, $MAXSIZE;  \
341        JA        3(PC);                        \346        JA   3(PC);         \
342        MOVQ        $NAME(SB), AX;                \347        MOVQ $NAME(SB), AX; \
343        JMP        AX348        JMP  AX
349
344// Note: can't just "JMP NAME(SB)" - bad inlining results.350// Note: can't just "JMP NAME(SB)" - bad inlining results.
345351
346TEXT ·reflectcall(SB), NOSPLIT, $0-24352TEXT ·reflectcall(SB), NOSPLIT, $0-24
347        MOVLQZX argsize+16(FP), CX353        MOVLQZX argsize+16(FP), CX
348        DISPATCH(runtime·call16, 16)354        DISPATCH(runtime·call16, 16)
349        DISPATCH(runtime·call32, 32)355        DISPATCH(runtime·call32, 32)
350        DISPATCH(runtime·call64, 64)356        DISPATCH(runtime·call64, 64)
351        DISPATCH(runtime·call128, 128)357        DISPATCH(runtime·call128, 128)
352        DISPATCH(runtime·call256, 256)358        DISPATCH(runtime·call256, 256)
353        DISPATCH(runtime·call512, 512)359        DISPATCH(runtime·call512, 512)
354        DISPATCH(runtime·call1024, 1024)360        DISPATCH(runtime·call1024, 1024)
355        DISPATCH(runtime·call2048, 2048)361        DISPATCH(runtime·call2048, 2048)
356        DISPATCH(runtime·call4096, 4096)362        DISPATCH(runtime·call4096, 4096)
357        DISPATCH(runtime·call8192, 8192)363        DISPATCH(runtime·call8192, 8192)
358        DISPATCH(runtime·call16384, 16384)364        DISPATCH(runtime·call16384, 16384)
359        DISPATCH(runtime·call32768, 32768)365        DISPATCH(runtime·call32768, 32768)
360        DISPATCH(runtime·call65536, 65536)366        DISPATCH(runtime·call65536, 65536)
361        DISPATCH(runtime·call131072, 131072)367        DISPATCH(runtime·call131072, 131072)
362        DISPATCH(runtime·call262144, 262144)368        DISPATCH(runtime·call262144, 262144)
363        DISPATCH(runtime·call524288, 524288)369        DISPATCH(runtime·call524288, 524288)
364        DISPATCH(runtime·call1048576, 1048576)370        DISPATCH(runtime·call1048576, 1048576)
365        DISPATCH(runtime·call2097152, 2097152)371        DISPATCH(runtime·call2097152, 2097152)
366        DISPATCH(runtime·call4194304, 4194304)372        DISPATCH(runtime·call4194304, 4194304)
367        DISPATCH(runtime·call8388608, 8388608)373        DISPATCH(runtime·call8388608, 8388608)
368        DISPATCH(runtime·call16777216, 16777216)374        DISPATCH(runtime·call16777216, 16777216)
369        DISPATCH(runtime·call33554432, 33554432)375        DISPATCH(runtime·call33554432, 33554432)
370        DISPATCH(runtime·call67108864, 67108864)376        DISPATCH(runtime·call67108864, 67108864)
371        DISPATCH(runtime·call134217728, 134217728)377        DISPATCH(runtime·call134217728, 134217728)
372        DISPATCH(runtime·call268435456, 268435456)378        DISPATCH(runtime·call268435456, 268435456)
373        DISPATCH(runtime·call536870912, 536870912)379        DISPATCH(runtime·call536870912, 536870912)
374        DISPATCH(runtime·call1073741824, 1073741824)380        DISPATCH(runtime·call1073741824, 1073741824)
375        MOVQ        $runtime·badreflectcall(SB), AX381        MOVQ    $runtime·badreflectcall(SB), AX
376        JMP        AX382        JMP     AX
377383
378#define CALLFN(NAME,MAXSIZE)                        \384#define CALLFN(NAME, MAXSIZE) \
379TEXT NAME(SB), WRAPPER, $MAXSIZE-24;                \385TEXT NAME(SB), WRAPPER, $MAXSIZE-24; \
380        NO_LOCAL_POINTERS;                        \386        NO_LOCAL_POINTERS;                 \
381        /* copy arguments to stack */                \387        /* copy arguments to stack */      \
382        MOVQ        argptr+8(FP), SI;                \388        MOVQ    argptr+8(FP), SI;          \
383        MOVLQZX argsize+16(FP), CX;                \389        MOVLQZX argsize+16(FP), CX;        \
384        MOVQ        SP, DI;                                \390        MOVQ    SP, DI;                    \
385        REP;MOVSB;                                \391        REP;MOVSB;                         \
386        /* call function */                        \392        /* call function */                \
387        MOVQ        f+0(FP), DX;                        \393        MOVQ    f+0(FP), DX;               \
388        PCDATA  $PCDATA_StackMapIndex, $0;        \394        PCDATA  $PCDATA_StackMapIndex, $0; \
389        CALL        (DX);                                \395        CALL    (DX);                      \
390        /* copy return values back */                \396        /* copy return values back */      \
391        MOVQ        argptr+8(FP), DI;                \397        MOVQ    argptr+8(FP), DI;          \
392        MOVLQZX        argsize+16(FP), CX;                \398        MOVLQZX argsize+16(FP), CX;        \
393        MOVLQZX retoffset+20(FP), BX;                \399        MOVLQZX retoffset+20(FP), BX;      \
394        MOVQ        SP, SI;                                \400        MOVQ    SP, SI;                    \
395        ADDQ        BX, DI;                                \401        ADDQ    BX, DI;                    \
396        ADDQ        BX, SI;                                \402        ADDQ    BX, SI;                    \
397        SUBQ        BX, CX;                                \403        SUBQ    BX, CX;                    \
398        REP;MOVSB;                                \404        REP;MOVSB;                         \
399        RET405        RET
400406
401CALLFN(·call16, 16)407CALLFN(·call16, 16)
402CALLFN(·call32, 32)408CALLFN(·call32, 32)
403CALLFN(·call64, 64)409CALLFN(·call64, 64)
404CALLFN(·call128, 128)410CALLFN(·call128, 128)
405CALLFN(·call256, 256)411CALLFN(·call256, 256)
406CALLFN(·call512, 512)412CALLFN(·call512, 512)
407CALLFN(·call1024, 1024)413CALLFN(·call1024, 1024)
408CALLFN(·call2048, 2048)414CALLFN(·call2048, 2048)
409CALLFN(·call4096, 4096)415CALLFN(·call4096, 4096)
410CALLFN(·call8192, 8192)416CALLFN(·call8192, 8192)
411CALLFN(·call16384, 16384)417CALLFN(·call16384, 16384)
412CALLFN(·call32768, 32768)418CALLFN(·call32768, 32768)
413CALLFN(·call65536, 65536)419CALLFN(·call65536, 65536)
414CALLFN(·call131072, 131072)420CALLFN(·call131072, 131072)
415CALLFN(·call262144, 262144)421CALLFN(·call262144, 262144)
416CALLFN(·call524288, 524288)422CALLFN(·call524288, 524288)
417CALLFN(·call1048576, 1048576)423CALLFN(·call1048576, 1048576)
418CALLFN(·call2097152, 2097152)424CALLFN(·call2097152, 2097152)
419CALLFN(·call4194304, 4194304)425CALLFN(·call4194304, 4194304)
420CALLFN(·call8388608, 8388608)426CALLFN(·call8388608, 8388608)
421CALLFN(·call16777216, 16777216)427CALLFN(·call16777216, 16777216)
422CALLFN(·call33554432, 33554432)428CALLFN(·call33554432, 33554432)
423CALLFN(·call67108864, 67108864)429CALLFN(·call67108864, 67108864)
424CALLFN(·call134217728, 134217728)430CALLFN(·call134217728, 134217728)
425CALLFN(·call268435456, 268435456)431CALLFN(·call268435456, 268435456)
426CALLFN(·call536870912, 536870912)432CALLFN(·call536870912, 536870912)
427CALLFN(·call1073741824, 1073741824)433CALLFN(·call1073741824, 1073741824)
428434
429// bool cas(int32 *val, int32 old, int32 new)435// bool cas(int32 *val, int32 old, int32 new)
430// Atomically:436// Atomically:
431//        if(*val == old){437//        if(*val == old){
432//                *val = new;438//                *val = new;
433//                return 1;439//                return 1;
434//        } else440//        } else
435//                return 0;441//                return 0;
436TEXT runtime·cas(SB), NOSPLIT, $0-17442TEXT runtime·cas(SB), NOSPLIT, $0-17
437        MOVQ        ptr+0(FP), BX443        MOVQ     ptr+0(FP), BX
438        MOVL        old+8(FP), AX444        MOVL     old+8(FP), AX
439        MOVL        new+12(FP), CX445        MOVL     new+12(FP), CX
440        LOCK446        LOCK
441        CMPXCHGL        CX, 0(BX)447        CMPXCHGL CX, 0(BX)
442        JZ 4(PC)448        JZ       4(PC)
443        MOVL        $0, AX449        MOVL     $0, AX
444        MOVB        AX, ret+16(FP)450        MOVB     AX, ret+16(FP)
445        RET451        RET
446        MOVL        $1, AX452        MOVL $1, AX
447        MOVB        AX, ret+16(FP)453        MOVB AX, ret+16(FP)
448        RET454        RET
449455
450// bool        runtime·cas64(uint64 *val, uint64 old, uint64 new)456// bool        runtime·cas64(uint64 *val, uint64 old, uint64 new)
451// Atomically:457// Atomically:
452//        if(*val == *old){458//        if(*val == *old){
453//                *val = new;459//                *val = new;
454//                return 1;460//                return 1;
455//        } else {461//        } else {
456//                return 0;462//                return 0;
457//        }463//        }
458TEXT runtime·cas64(SB), NOSPLIT, $0-25464TEXT runtime·cas64(SB), NOSPLIT, $0-25
459        MOVQ        ptr+0(FP), BX465        MOVQ     ptr+0(FP), BX
460        MOVQ        old+8(FP), AX466        MOVQ     old+8(FP), AX
461        MOVQ        new+16(FP), CX467        MOVQ     new+16(FP), CX
462        LOCK468        LOCK
463        CMPXCHGQ        CX, 0(BX)469        CMPXCHGQ CX, 0(BX)
464        JNZ        cas64_fail470        JNZ      cas64_fail
465        MOVL        $1, AX471        MOVL     $1, AX
466        MOVB        AX, ret+24(FP)472        MOVB     AX, ret+24(FP)
467        RET473        RET
474
468cas64_fail:475cas64_fail:
469        MOVL        $0, AX476        MOVL $0, AX
470        MOVB        AX, ret+24(FP)477        MOVB AX, ret+24(FP)
471        RET478        RET
472         479
473TEXT runtime·casuintptr(SB), NOSPLIT, $0-25480TEXT runtime·casuintptr(SB), NOSPLIT, $0-25
474        JMP        runtime·cas64(SB)481        JMP runtime·cas64(SB)
475482
476TEXT runtime·atomicloaduintptr(SB), NOSPLIT, $0-16483TEXT runtime·atomicloaduintptr(SB), NOSPLIT, $0-16
477        JMP        runtime·atomicload64(SB)484        JMP runtime·atomicload64(SB)
478485
479TEXT runtime·atomicloaduint(SB), NOSPLIT, $0-16486TEXT runtime·atomicloaduint(SB), NOSPLIT, $0-16
480        JMP        runtime·atomicload64(SB)487        JMP runtime·atomicload64(SB)
481488
482TEXT runtime·atomicstoreuintptr(SB), NOSPLIT, $0-16489TEXT runtime·atomicstoreuintptr(SB), NOSPLIT, $0-16
483        JMP        runtime·atomicstore64(SB)490        JMP runtime·atomicstore64(SB)
484491
485// bool casp(void **val, void *old, void *new)492// bool casp(void **val, void *old, void *new)
486// Atomically:493// Atomically:
487//        if(*val == old){494//        if(*val == old){
488//                *val = new;495//                *val = new;
489//                return 1;496//                return 1;
490//        } else497//        } else
491//                return 0;498//                return 0;
492TEXT runtime·casp(SB), NOSPLIT, $0-25499TEXT runtime·casp(SB), NOSPLIT, $0-25
493        MOVQ        ptr+0(FP), BX500        MOVQ     ptr+0(FP), BX
494        MOVQ        old+8(FP), AX501        MOVQ     old+8(FP), AX
495        MOVQ        new+16(FP), CX502        MOVQ     new+16(FP), CX
496        LOCK503        LOCK
497        CMPXCHGQ        CX, 0(BX)504        CMPXCHGQ CX, 0(BX)
498        JZ 4(PC)505        JZ       4(PC)
499        MOVL        $0, AX506        MOVL     $0, AX
500        MOVB        AX, ret+24(FP)507        MOVB     AX, ret+24(FP)
501        RET508        RET
502        MOVL        $1, AX509        MOVL $1, AX
503        MOVB        AX, ret+24(FP)510        MOVB AX, ret+24(FP)
504        RET511        RET
505512
506// uint32 xadd(uint32 volatile *val, int32 delta)513// uint32 xadd(uint32 volatile *val, int32 delta)
507// Atomically:514// Atomically:
508//        *val += delta;515//        *val += delta;
509//        return *val;516//        return *val;
510TEXT runtime·xadd(SB), NOSPLIT, $0-20517TEXT runtime·xadd(SB), NOSPLIT, $0-20
511        MOVQ        ptr+0(FP), BX518        MOVQ  ptr+0(FP), BX
512        MOVL        delta+8(FP), AX519        MOVL  delta+8(FP), AX
513        MOVL        AX, CX520        MOVL  AX, CX
514        LOCK521        LOCK
515        XADDL        AX, 0(BX)522        XADDL AX, 0(BX)
516        ADDL        CX, AX523        ADDL  CX, AX
517        MOVL        AX, ret+16(FP)524        MOVL  AX, ret+16(FP)
518        RET525        RET
519526
520TEXT runtime·xadd64(SB), NOSPLIT, $0-24527TEXT runtime·xadd64(SB), NOSPLIT, $0-24
521        MOVQ        ptr+0(FP), BX528        MOVQ  ptr+0(FP), BX
522        MOVQ        delta+8(FP), AX529        MOVQ  delta+8(FP), AX
523        MOVQ        AX, CX530        MOVQ  AX, CX
524        LOCK531        LOCK
525        XADDQ        AX, 0(BX)532        XADDQ AX, 0(BX)
526        ADDQ        CX, AX533        ADDQ  CX, AX
527        MOVQ        AX, ret+16(FP)534        MOVQ  AX, ret+16(FP)
528        RET535        RET
529536
530TEXT runtime·xchg(SB), NOSPLIT, $0-20537TEXT runtime·xchg(SB), NOSPLIT, $0-20
531        MOVQ        ptr+0(FP), BX538        MOVQ  ptr+0(FP), BX
532        MOVL        new+8(FP), AX539        MOVL  new+8(FP), AX
533        XCHGL        AX, 0(BX)540        XCHGL AX, 0(BX)
534        MOVL        AX, ret+16(FP)541        MOVL  AX, ret+16(FP)
535        RET542        RET
536543
537TEXT runtime·xchg64(SB), NOSPLIT, $0-24544TEXT runtime·xchg64(SB), NOSPLIT, $0-24
538        MOVQ        ptr+0(FP), BX545        MOVQ  ptr+0(FP), BX
539        MOVQ        new+8(FP), AX546        MOVQ  new+8(FP), AX
540        XCHGQ        AX, 0(BX)547        XCHGQ AX, 0(BX)
541        MOVQ        AX, ret+16(FP)548        MOVQ  AX, ret+16(FP)
542        RET549        RET
543550
544TEXT runtime·xchgp(SB), NOSPLIT, $0-24551TEXT runtime·xchgp(SB), NOSPLIT, $0-24
545        MOVQ        ptr+0(FP), BX552        MOVQ  ptr+0(FP), BX
546        MOVQ        new+8(FP), AX553        MOVQ  new+8(FP), AX
547        XCHGQ        AX, 0(BX)554        XCHGQ AX, 0(BX)
548        MOVQ        AX, ret+16(FP)555        MOVQ  AX, ret+16(FP)
549        RET556        RET
550557
551TEXT runtime·xchguintptr(SB), NOSPLIT, $0-24558TEXT runtime·xchguintptr(SB), NOSPLIT, $0-24
552        JMP        runtime·xchg64(SB)559        JMP runtime·xchg64(SB)
553560
554TEXT runtime·procyield(SB),NOSPLIT,$0-0561TEXT runtime·procyield(SB), NOSPLIT, $0-0
555        MOVL        cycles+0(FP), AX562        MOVL cycles+0(FP), AX
563
556again:564again:
557        PAUSE565        PAUSE
558        SUBL        $1, AX566        SUBL $1, AX
559        JNZ        again567        JNZ  again
560        RET568        RET
561569
562TEXT runtime·atomicstorep(SB), NOSPLIT, $0-16570TEXT runtime·atomicstorep(SB), NOSPLIT, $0-16
563        MOVQ        ptr+0(FP), BX571        MOVQ  ptr+0(FP), BX
564        MOVQ        val+8(FP), AX572        MOVQ  val+8(FP), AX
565        XCHGQ        AX, 0(BX)573        XCHGQ AX, 0(BX)
566        RET574        RET
567575
568TEXT runtime·atomicstore(SB), NOSPLIT, $0-12576TEXT runtime·atomicstore(SB), NOSPLIT, $0-12
569        MOVQ        ptr+0(FP), BX577        MOVQ  ptr+0(FP), BX
570        MOVL        val+8(FP), AX578        MOVL  val+8(FP), AX
571        XCHGL        AX, 0(BX)579        XCHGL AX, 0(BX)
572        RET580        RET
573581
574TEXT runtime·atomicstore64(SB), NOSPLIT, $0-16582TEXT runtime·atomicstore64(SB), NOSPLIT, $0-16
575        MOVQ        ptr+0(FP), BX583        MOVQ  ptr+0(FP), BX
576        MOVQ        val+8(FP), AX584        MOVQ  val+8(FP), AX
577        XCHGQ        AX, 0(BX)585        XCHGQ AX, 0(BX)
578        RET586        RET
579587
580// void        runtime·atomicor8(byte volatile*, byte);588// void        runtime·atomicor8(byte volatile*, byte);
581TEXT runtime·atomicor8(SB), NOSPLIT, $0-9589TEXT runtime·atomicor8(SB), NOSPLIT, $0-9
582        MOVQ        ptr+0(FP), AX590        MOVQ ptr+0(FP), AX
583        MOVB        val+8(FP), BX591        MOVB val+8(FP), BX
584        LOCK592        LOCK
585        ORB        BX, (AX)593        ORB  BX, (AX)
586        RET594        RET
587595
588// void jmpdefer(fn, sp);596// void jmpdefer(fn, sp);
589// called from deferreturn.597// called from deferreturn.
590// 1. pop the caller598// 1. pop the caller
591// 2. sub 5 bytes from the callers return599// 2. sub 5 bytes from the callers return
592// 3. jmp to the argument600// 3. jmp to the argument
593TEXT runtime·jmpdefer(SB), NOSPLIT, $0-16601TEXT runtime·jmpdefer(SB), NOSPLIT, $0-16
594        MOVQ        fv+0(FP), DX        // fn602        MOVQ fv+0(FP), DX   // fn
595        MOVQ        argp+8(FP), BX        // caller sp603        MOVQ argp+8(FP), BX // caller sp
596        LEAQ        -8(BX), SP        // caller sp after CALL604        LEAQ -8(BX), SP     // caller sp after CALL
597        SUBQ        $5, (SP)        // return to CALL again605        SUBQ $5, (SP)       // return to CALL again
598        MOVQ        0(DX), BX606        MOVQ 0(DX), BX
599        JMP        BX        // but first run the deferred function607        JMP  BX             // but first run the deferred function
600608
601// Save state of caller into g->sched. Smashes R8, R9.609// Save state of caller into g->sched. Smashes R8, R9.
602TEXT gosave<>(SB),NOSPLIT,$0610TEXT gosave<>(SB), NOSPLIT, $0
603        get_tls(R8)611        get_tls(R8)
604        MOVQ        g(R8), R8612        MOVQ g(R8), R8
605        MOVQ        0(SP), R9613        MOVQ 0(SP), R9
606        MOVQ        R9, (g_sched+gobuf_pc)(R8)614        MOVQ R9, (g_sched+gobuf_pc)(R8)
607        LEAQ        8(SP), R9615        LEAQ 8(SP), R9
608        MOVQ        R9, (g_sched+gobuf_sp)(R8)616        MOVQ R9, (g_sched+gobuf_sp)(R8)
609        MOVQ        $0, (g_sched+gobuf_ret)(R8)617        MOVQ $0, (g_sched+gobuf_ret)(R8)
610        MOVQ        $0, (g_sched+gobuf_ctxt)(R8)618        MOVQ $0, (g_sched+gobuf_ctxt)(R8)
611        RET619        RET
612620
613// asmcgocall(void(*fn)(void*), void *arg)621// asmcgocall(void(*fn)(void*), void *arg)
614// Call fn(arg) on the scheduler stack,622// Call fn(arg) on the scheduler stack,
615// aligned appropriately for the gcc ABI.623// aligned appropriately for the gcc ABI.
616// See cgocall.c for more details.624// See cgocall.c for more details.
617TEXT ·asmcgocall(SB),NOSPLIT,$0-16625TEXT ·asmcgocall(SB), NOSPLIT, $0-16
618        MOVQ        fn+0(FP), AX626        MOVQ fn+0(FP), AX
619        MOVQ        arg+8(FP), BX627        MOVQ arg+8(FP), BX
620        CALL        asmcgocall<>(SB)628        CALL asmcgocall<>(SB)
621        RET629        RET
622630
623TEXT ·asmcgocall_errno(SB),NOSPLIT,$0-20631TEXT ·asmcgocall_errno(SB), NOSPLIT, $0-20
624        MOVQ        fn+0(FP), AX632        MOVQ fn+0(FP), AX
625        MOVQ        arg+8(FP), BX633        MOVQ arg+8(FP), BX
626        CALL        asmcgocall<>(SB)634        CALL asmcgocall<>(SB)
627        MOVL        AX, ret+16(FP)635        MOVL AX, ret+16(FP)
628        RET636        RET
629637
630// asmcgocall common code. fn in AX, arg in BX. returns errno in AX.638// asmcgocall common code. fn in AX, arg in BX. returns errno in AX.
631TEXT asmcgocall<>(SB),NOSPLIT,$0-0639TEXT asmcgocall<>(SB), NOSPLIT, $0-0
632        MOVQ        SP, DX640        MOVQ SP, DX
633641
634        // Figure out if we need to switch to m->g0 stack.642        // Figure out if we need to switch to m->g0 stack.
635        // We get called to create new OS threads too, and those643        // We get called to create new OS threads too, and those
636        // come in on the m->g0 stack already.644        // come in on the m->g0 stack already.
637        get_tls(CX)645        get_tls(CX)
638        MOVQ        g(CX), BP646        MOVQ g(CX), BP
639        MOVQ        g_m(BP), BP647        MOVQ g_m(BP), BP
640        MOVQ        m_g0(BP), SI648        MOVQ m_g0(BP), SI
641        MOVQ        g(CX), DI649        MOVQ g(CX), DI
642        CMPQ        SI, DI650        CMPQ SI, DI
643        JEQ        nosave651        JEQ  nosave
644        MOVQ        m_gsignal(BP), SI652        MOVQ m_gsignal(BP), SI
645        CMPQ        SI, DI653        CMPQ SI, DI
646        JEQ        nosave654        JEQ  nosave
647         655
648        MOVQ        m_g0(BP), SI656        MOVQ m_g0(BP), SI
649        CALL        gosave<>(SB)657        CALL gosave<>(SB)
650        MOVQ        SI, g(CX)658        MOVQ SI, g(CX)
651        MOVQ        (g_sched+gobuf_sp)(SI), SP659        MOVQ (g_sched+gobuf_sp)(SI), SP
660
652nosave:661nosave:
653662
654        // Now on a scheduling stack (a pthread-created stack).663        // Now on a scheduling stack (a pthread-created stack).
655        // Make sure we have enough room for 4 stack-backed fast-call664        // Make sure we have enough room for 4 stack-backed fast-call
656        // registers as per windows amd64 calling convention.665        // registers as per windows amd64 calling convention.
657        SUBQ        $64, SP666        SUBQ $64, SP
658        ANDQ        $~15, SP        // alignment for gcc ABI667        ANDQ $~15, SP                   // alignment for gcc ABI
659        MOVQ        DI, 48(SP)        // save g668        MOVQ DI, 48(SP)                 // save g
660        MOVQ        (g_stack+stack_hi)(DI), DI669        MOVQ (g_stack+stack_hi)(DI), DI
661        SUBQ        DX, DI670        SUBQ DX, DI
662        MOVQ        DI, 40(SP)        // save depth in stack (can't just save SP, as stack might be copied during a callback)671        MOVQ DI, 40(SP)                 // save depth in stack (can't just save SP, as stack might be copied during a callback)
663        MOVQ        BX, DI                // DI = first argument in AMD64 ABI672        MOVQ BX, DI                     // DI = first argument in AMD64 ABI
664        MOVQ        BX, CX                // CX = first argument in Win64673        MOVQ BX, CX                     // CX = first argument in Win64
665        CALL        AX674        CALL AX
666675
667        // Restore registers, g, stack pointer.676        // Restore registers, g, stack pointer.
668        get_tls(CX)677        get_tls(CX)
669        MOVQ        48(SP), DI678        MOVQ 48(SP), DI
670        MOVQ        (g_stack+stack_hi)(DI), SI679        MOVQ (g_stack+stack_hi)(DI), SI
671        SUBQ        40(SP), SI680        SUBQ 40(SP), SI
672        MOVQ        DI, g(CX)681        MOVQ DI, g(CX)
673        MOVQ        SI, SP682        MOVQ SI, SP
674        RET683        RET
675684
676// cgocallback(void (*fn)(void*), void *frame, uintptr framesize)685// cgocallback(void (*fn)(void*), void *frame, uintptr framesize)
677// Turn the fn into a Go func (by taking its address) and call686// Turn the fn into a Go func (by taking its address) and call
678// cgocallback_gofunc.687// cgocallback_gofunc.
679TEXT runtime·cgocallback(SB),NOSPLIT,$24-24688TEXT runtime·cgocallback(SB), NOSPLIT, $24-24
680        LEAQ        fn+0(FP), AX689        LEAQ fn+0(FP), AX
681        MOVQ        AX, 0(SP)690        MOVQ AX, 0(SP)
682        MOVQ        frame+8(FP), AX691        MOVQ frame+8(FP), AX
683        MOVQ        AX, 8(SP)692        MOVQ AX, 8(SP)
684        MOVQ        framesize+16(FP), AX693        MOVQ framesize+16(FP), AX
685        MOVQ        AX, 16(SP)694        MOVQ AX, 16(SP)
686        MOVQ        $runtime·cgocallback_gofunc(SB), AX695        MOVQ $runtime·cgocallback_gofunc(SB), AX
687        CALL        AX696        CALL AX
688        RET697        RET
689698
690// cgocallback_gofunc(FuncVal*, void *frame, uintptr framesize)699// cgocallback_gofunc(FuncVal*, void *frame, uintptr framesize)
691// See cgocall.c for more details.700// See cgocall.c for more details.
692TEXT ·cgocallback_gofunc(SB),NOSPLIT,$8-24701TEXT ·cgocallback_gofunc(SB), NOSPLIT, $8-24
693        NO_LOCAL_POINTERS702        NO_LOCAL_POINTERS
694703
695        // If g is nil, Go did not create the current thread.704        // If g is nil, Go did not create the current thread.
696        // Call needm to obtain one m for temporary use.705        // Call needm to obtain one m for temporary use.
697        // In this case, we're running on the thread stack, so there's706        // In this case, we're running on the thread stack, so there's
698        // lots of space, but the linker doesn't know. Hide the call from707        // lots of space, but the linker doesn't know. Hide the call from
699        // the linker analysis by using an indirect call through AX.708        // the linker analysis by using an indirect call through AX.
700        get_tls(CX)709        get_tls(CX)
710
701#ifdef GOOS_windows711#ifdef GOOS_windows
702        MOVL        $0, BP712        MOVL $0, BP
703        CMPQ        CX, $0713        CMPQ CX, $0
704        JEQ        2(PC)714        JEQ  2(PC)
715
705#endif716#endif
706        MOVQ        g(CX), BP717        MOVQ g(CX), BP
707        CMPQ        BP, $0718        CMPQ BP, $0
708        JEQ        needm719        JEQ  needm
709        MOVQ        g_m(BP), BP720        MOVQ g_m(BP), BP
710        MOVQ        BP, R8 // holds oldm until end of function721        MOVQ BP, R8      // holds oldm until end of function
711        JMP        havem722        JMP  havem
723
712needm:724needm:
713        MOVQ        $0, 0(SP)725        MOVQ $0, 0(SP)
714        MOVQ        $runtime·needm(SB), AX726        MOVQ $runtime·needm(SB), AX
715        CALL        AX727        CALL AX
716        MOVQ        0(SP), R8728        MOVQ 0(SP), R8
717        get_tls(CX)729        get_tls(CX)
718        MOVQ        g(CX), BP730        MOVQ g(CX), BP
719        MOVQ        g_m(BP), BP731        MOVQ g_m(BP), BP
720         732
721        // Set m->sched.sp = SP, so that if a panic happens733        // Set m->sched.sp = SP, so that if a panic happens
722        // during the function we are about to execute, it will734        // during the function we are about to execute, it will
723        // have a valid SP to run on the g0 stack.735        // have a valid SP to run on the g0 stack.
724        // The next few lines (after the havem label)736        // The next few lines (after the havem label)
725        // will save this SP onto the stack and then write737        // will save this SP onto the stack and then write
726        // the same SP back to m->sched.sp. That seems redundant,738        // the same SP back to m->sched.sp. That seems redundant,
727        // but if an unrecovered panic happens, unwindm will739        // but if an unrecovered panic happens, unwindm will
728        // restore the g->sched.sp from the stack location740        // restore the g->sched.sp from the stack location
729        // and then onM will try to use it. If we don't set it here,741        // and then onM will try to use it. If we don't set it here,
730        // that restored SP will be uninitialized (typically 0) and742        // that restored SP will be uninitialized (typically 0) and
731        // will not be usable.743        // will not be usable.
732        MOVQ        m_g0(BP), SI744        MOVQ m_g0(BP), SI
733        MOVQ        SP, (g_sched+gobuf_sp)(SI)745        MOVQ SP, (g_sched+gobuf_sp)(SI)
734746
735havem:747havem:
736        // Now there's a valid m, and we're running on its m->g0.748        // Now there's a valid m, and we're running on its m->g0.
737        // Save current m->g0->sched.sp on stack and then set it to SP.749        // Save current m->g0->sched.sp on stack and then set it to SP.
738        // Save current sp in m->g0->sched.sp in preparation for750        // Save current sp in m->g0->sched.sp in preparation for
739        // switch back to m->curg stack.751        // switch back to m->curg stack.
740        // NOTE: unwindm knows that the saved g->sched.sp is at 0(SP).752        // NOTE: unwindm knows that the saved g->sched.sp is at 0(SP).
741        MOVQ        m_g0(BP), SI753        MOVQ m_g0(BP), SI
742        MOVQ        (g_sched+gobuf_sp)(SI), AX754        MOVQ (g_sched+gobuf_sp)(SI), AX
743        MOVQ        AX, 0(SP)755        MOVQ AX, 0(SP)
744        MOVQ        SP, (g_sched+gobuf_sp)(SI)756        MOVQ SP, (g_sched+gobuf_sp)(SI)
745757
746        // Switch to m->curg stack and call runtime.cgocallbackg.758        // Switch to m->curg stack and call runtime.cgocallbackg.
747        // Because we are taking over the execution of m->curg759        // Because we are taking over the execution of m->curg
748        // but *not* resuming what had been running, we need to760        // but *not* resuming what had been running, we need to
749        // save that information (m->curg->sched) so we can restore it.761        // save that information (m->curg->sched) so we can restore it.
750        // We can restore m->curg->sched.sp easily, because calling762        // We can restore m->curg->sched.sp easily, because calling
751        // runtime.cgocallbackg leaves SP unchanged upon return.763        // runtime.cgocallbackg leaves SP unchanged upon return.
752        // To save m->curg->sched.pc, we push it onto the stack.764        // To save m->curg->sched.pc, we push it onto the stack.
753        // This has the added benefit that it looks to the traceback765        // This has the added benefit that it looks to the traceback
754        // routine like cgocallbackg is going to return to that766        // routine like cgocallbackg is going to return to that
755        // PC (because the frame we allocate below has the same767        // PC (because the frame we allocate below has the same
756        // size as cgocallback_gofunc's frame declared above)768        // size as cgocallback_gofunc's frame declared above)
757        // so that the traceback will seamlessly trace back into769        // so that the traceback will seamlessly trace back into
758        // the earlier calls.770        // the earlier calls.
759        //771        //
760        // In the new goroutine, 0(SP) holds the saved R8.772        // In the new goroutine, 0(SP) holds the saved R8.
761        MOVQ        m_curg(BP), SI773        MOVQ m_curg(BP), SI
762        MOVQ        SI, g(CX)774        MOVQ SI, g(CX)
763        MOVQ        (g_sched+gobuf_sp)(SI), DI  // prepare stack as DI775        MOVQ (g_sched+gobuf_sp)(SI), DI // prepare stack as DI
764        MOVQ        (g_sched+gobuf_pc)(SI), BP776        MOVQ (g_sched+gobuf_pc)(SI), BP
765        MOVQ        BP, -8(DI)777        MOVQ BP, -8(DI)
766        LEAQ        -(8+8)(DI), SP778        LEAQ -(8+8)(DI), SP
767        MOVQ        R8, 0(SP)779        MOVQ R8, 0(SP)
768        CALL        runtime·cgocallbackg(SB)780        CALL runtime·cgocallbackg(SB)
769        MOVQ        0(SP), R8781        MOVQ 0(SP), R8
770782
771        // Restore g->sched (== m->curg->sched) from saved values.783        // Restore g->sched (== m->curg->sched) from saved values.
772        get_tls(CX)784        get_tls(CX)
773        MOVQ        g(CX), SI785        MOVQ g(CX), SI
774        MOVQ        8(SP), BP786        MOVQ 8(SP), BP
775        MOVQ        BP, (g_sched+gobuf_pc)(SI)787        MOVQ BP, (g_sched+gobuf_pc)(SI)
776        LEAQ        (8+8)(SP), DI788        LEAQ (8+8)(SP), DI
777        MOVQ        DI, (g_sched+gobuf_sp)(SI)789        MOVQ DI, (g_sched+gobuf_sp)(SI)
778790
779        // Switch back to m->g0's stack and restore m->g0->sched.sp.791        // Switch back to m->g0's stack and restore m->g0->sched.sp.
780        // (Unlike m->curg, the g0 goroutine never uses sched.pc,792        // (Unlike m->curg, the g0 goroutine never uses sched.pc,
781        // so we do not have to restore it.)793        // so we do not have to restore it.)
782        MOVQ        g(CX), BP794        MOVQ g(CX), BP
783        MOVQ        g_m(BP), BP795        MOVQ g_m(BP), BP
784        MOVQ        m_g0(BP), SI796        MOVQ m_g0(BP), SI
785        MOVQ        SI, g(CX)797        MOVQ SI, g(CX)
786        MOVQ        (g_sched+gobuf_sp)(SI), SP798        MOVQ (g_sched+gobuf_sp)(SI), SP
787        MOVQ        0(SP), AX799        MOVQ 0(SP), AX
788        MOVQ        AX, (g_sched+gobuf_sp)(SI)800        MOVQ AX, (g_sched+gobuf_sp)(SI)
789         801
790        // If the m on entry was nil, we called needm above to borrow an m802        // If the m on entry was nil, we called needm above to borrow an m
791        // for the duration of the call. Since the call is over, return it with dropm.803        // for the duration of the call. Since the call is over, return it with dropm.
792        CMPQ        R8, $0804        CMPQ R8, $0
793        JNE 3(PC)805        JNE  3(PC)
794        MOVQ        $runtime·dropm(SB), AX806        MOVQ $runtime·dropm(SB), AX
795        CALL        AX807        CALL AX
796808
797        // Done!809        // Done!
798        RET810        RET
799811
800// void setg(G*); set g. for use by needm.812// void setg(G*); set g. for use by needm.
801TEXT runtime·setg(SB), NOSPLIT, $0-8813TEXT runtime·setg(SB), NOSPLIT, $0-8
802        MOVQ        gg+0(FP), BX814        MOVQ gg+0(FP), BX
815
803#ifdef GOOS_windows816#ifdef GOOS_windows
804        CMPQ        BX, $0817        CMPQ BX, $0
805        JNE        settls818        JNE  settls
806        MOVQ        $0, 0x28(GS)819        MOVQ $0, 0x28(GS)
807        RET820        RET
821
808settls:822settls:
809        MOVQ        g_m(BX), AX823        MOVQ g_m(BX), AX
810        LEAQ        m_tls(AX), AX824        LEAQ m_tls(AX), AX
811        MOVQ        AX, 0x28(GS)825        MOVQ AX, 0x28(GS)
826
812#endif827#endif
813        get_tls(CX)828        get_tls(CX)
814        MOVQ        BX, g(CX)829        MOVQ BX, g(CX)
815        RET830        RET
816831
817// void setg_gcc(G*); set g called from gcc.832// void setg_gcc(G*); set g called from gcc.
818TEXT setg_gcc<>(SB),NOSPLIT,$0833TEXT setg_gcc<>(SB), NOSPLIT, $0
819        get_tls(AX)834        get_tls(AX)
820        MOVQ        DI, g(AX)835        MOVQ DI, g(AX)
821        RET836        RET
822837
823// check that SP is in range [g->stack.lo, g->stack.hi)838// check that SP is in range [g->stack.lo, g->stack.hi)
824TEXT runtime·stackcheck(SB), NOSPLIT, $0-0839TEXT runtime·stackcheck(SB), NOSPLIT, $0-0
825        get_tls(CX)840        get_tls(CX)
826        MOVQ        g(CX), AX841        MOVQ g(CX), AX
827        CMPQ        (g_stack+stack_hi)(AX), SP842        CMPQ (g_stack+stack_hi)(AX), SP
828        JHI        2(PC)843        JHI  2(PC)
829        INT        $3844        INT  $3
830        CMPQ        SP, (g_stack+stack_lo)(AX)845        CMPQ SP, (g_stack+stack_lo)(AX)
831        JHI        2(PC)846        JHI  2(PC)
832        INT        $3847        INT  $3
833        RET848        RET
834849
835TEXT runtime·getcallerpc(SB),NOSPLIT,$0-16850TEXT runtime·getcallerpc(SB), NOSPLIT, $0-16
836        MOVQ        argp+0(FP),AX                // addr of first arg851        MOVQ argp+0(FP), AX // addr of first arg
837        MOVQ        -8(AX),AX                // get calling pc852        MOVQ -8(AX), AX     // get calling pc
838        MOVQ        AX, ret+8(FP)853        MOVQ AX, ret+8(FP)
839        RET854        RET
840855
841TEXT runtime·gogetcallerpc(SB),NOSPLIT,$0-16856TEXT runtime·gogetcallerpc(SB), NOSPLIT, $0-16
842        MOVQ        p+0(FP),AX                // addr of first arg857        MOVQ p+0(FP), AX   // addr of first arg
843        MOVQ        -8(AX),AX                // get calling pc858        MOVQ -8(AX), AX    // get calling pc
844        MOVQ        AX,ret+8(FP)859        MOVQ AX, ret+8(FP)
845        RET860        RET
846861
847TEXT runtime·setcallerpc(SB),NOSPLIT,$0-16862TEXT runtime·setcallerpc(SB), NOSPLIT, $0-16
848        MOVQ        argp+0(FP),AX                // addr of first arg863        MOVQ argp+0(FP), AX // addr of first arg
849        MOVQ        pc+8(FP), BX864        MOVQ pc+8(FP), BX
850        MOVQ        BX, -8(AX)                // set calling pc865        MOVQ BX, -8(AX)     // set calling pc
851        RET866        RET
852867
853TEXT runtime·getcallersp(SB),NOSPLIT,$0-16868TEXT runtime·getcallersp(SB), NOSPLIT, $0-16
854        MOVQ        argp+0(FP), AX869        MOVQ argp+0(FP), AX
855        MOVQ        AX, ret+8(FP)870        MOVQ AX, ret+8(FP)
856        RET871        RET
857872
858// func gogetcallersp(p unsafe.Pointer) uintptr873// func gogetcallersp(p unsafe.Pointer) uintptr
859TEXT runtime·gogetcallersp(SB),NOSPLIT,$0-16874TEXT runtime·gogetcallersp(SB), NOSPLIT, $0-16
860        MOVQ        p+0(FP),AX                // addr of first arg875        MOVQ p+0(FP), AX   // addr of first arg
861        MOVQ        AX, ret+8(FP)876        MOVQ AX, ret+8(FP)
862        RET877        RET
863878
864// int64 runtime·cputicks(void)879// int64 runtime·cputicks(void)
865TEXT runtime·cputicks(SB),NOSPLIT,$0-0880TEXT runtime·cputicks(SB), NOSPLIT, $0-0
866        RDTSC881        RDTSC
867        SHLQ        $32, DX882        SHLQ $32, DX
868        ADDQ        DX, AX883        ADDQ DX, AX
869        MOVQ        AX, ret+0(FP)884        MOVQ AX, ret+0(FP)
870        RET885        RET
871886
872// hash function using AES hardware instructions887// hash function using AES hardware instructions
873TEXT runtime·aeshash(SB),NOSPLIT,$0-32888TEXT runtime·aeshash(SB), NOSPLIT, $0-32
874        MOVQ        p+0(FP), AX        // ptr to data889        MOVQ p+0(FP), AX             // ptr to data
875        MOVQ        s+8(FP), CX        // size890        MOVQ s+8(FP), CX             // size
876        JMP        runtime·aeshashbody(SB)891        JMP  runtime·aeshashbody(SB)
877892
878TEXT runtime·aeshashstr(SB),NOSPLIT,$0-32893TEXT runtime·aeshashstr(SB), NOSPLIT, $0-32
879        MOVQ        p+0(FP), AX        // ptr to string struct894        MOVQ p+0(FP), AX // ptr to string struct
895
880        // s+8(FP) is ignored, it is always sizeof(String)896        // s+8(FP) is ignored, it is always sizeof(String)
881        MOVQ        8(AX), CX        // length of string897        MOVQ 8(AX), CX               // length of string
882        MOVQ        (AX), AX        // string data898        MOVQ (AX), AX                // string data
883        JMP        runtime·aeshashbody(SB)899        JMP  runtime·aeshashbody(SB)
884900
885// AX: data901// AX: data
886// CX: length902// CX: length
887TEXT runtime·aeshashbody(SB),NOSPLIT,$0-32903TEXT runtime·aeshashbody(SB), NOSPLIT, $0-32
888        MOVQ        h+16(FP), X0        // seed to low 64 bits of xmm0904        MOVQ   h+16(FP), X0                   // seed to low 64 bits of xmm0
889        PINSRQ        $1, CX, X0        // size to high 64 bits of xmm0905        PINSRQ $1, CX, X0                     // size to high 64 bits of xmm0
890        MOVO        runtime·aeskeysched+0(SB), X2906        MOVO   runtime·aeskeysched+0(SB), X2
891        MOVO        runtime·aeskeysched+16(SB), X3907        MOVO   runtime·aeskeysched+16(SB), X3
892        CMPQ        CX, $16908        CMPQ   CX, $16
893        JB        aessmall909        JB     aessmall
910
894aesloop:911aesloop:
895        CMPQ        CX, $16912        CMPQ   CX, $16
896        JBE        aesloopend913        JBE    aesloopend
897        MOVOU        (AX), X1914        MOVOU  (AX), X1
898        AESENC        X2, X0915        AESENC X2, X0
899        AESENC        X1, X0916        AESENC X1, X0
900        SUBQ        $16, CX917        SUBQ   $16, CX
901        ADDQ        $16, AX918        ADDQ   $16, AX
902        JMP        aesloop919        JMP    aesloop
920
903// 1-16 bytes remaining921// 1-16 bytes remaining
904aesloopend:922aesloopend:
905        // This load may overlap with the previous load above.923        // This load may overlap with the previous load above.
906        // We'll hash some bytes twice, but that's ok.924        // We'll hash some bytes twice, but that's ok.
907        MOVOU        -16(AX)(CX*1), X1925        MOVOU -16(AX)(CX*1), X1
908        JMP        partial926        JMP   partial
927
909// 0-15 bytes928// 0-15 bytes
910aessmall:929aessmall:
911        TESTQ        CX, CX930        TESTQ CX, CX
912        JE        finalize        // 0 bytes931        JE    finalize // 0 bytes
913932
914        CMPB        AX, $0xf0933        CMPB AX, $0xf0
915        JA        highpartial934        JA   highpartial
916935
917        // 16 bytes loaded at this address won't cross936        // 16 bytes loaded at this address won't cross
918        // a page boundary, so we can load it directly.937        // a page boundary, so we can load it directly.
919        MOVOU        (AX), X1938        MOVOU (AX), X1
920        ADDQ        CX, CX939        ADDQ  CX, CX
921        MOVQ        $masks<>(SB), BP940        MOVQ  $masks<>(SB), BP
922        PAND        (BP)(CX*8), X1941        PAND  (BP)(CX*8), X1
923        JMP        partial942        JMP   partial
943
924highpartial:944highpartial:
925        // address ends in 1111xxxx.  Might be up against945        // address ends in 1111xxxx.  Might be up against
926        // a page boundary, so load ending at last byte.946        // a page boundary, so load ending at last byte.
927        // Then shift bytes down using pshufb.947        // Then shift bytes down using pshufb.
928        MOVOU        -16(AX)(CX*1), X1948        MOVOU  -16(AX)(CX*1), X1
929        ADDQ        CX, CX949        ADDQ   CX, CX
930        MOVQ        $shifts<>(SB), BP950        MOVQ   $shifts<>(SB), BP
931        PSHUFB        (BP)(CX*8), X1951        PSHUFB (BP)(CX*8), X1
952
932partial:953partial:
933        // incorporate partial block into hash954        // incorporate partial block into hash
934        AESENC        X3, X0955        AESENC X3, X0
935        AESENC        X1, X0956        AESENC X1, X0
957
936finalize:        958finalize:
937        // finalize hash959        // finalize hash
938        AESENC        X2, X0960        AESENC X2, X0
939        AESENC        X3, X0961        AESENC X3, X0
940        AESENC        X2, X0962        AESENC X2, X0
941        MOVQ        X0, res+24(FP)963        MOVQ   X0, res+24(FP)
942        RET964        RET
943965
944TEXT runtime·aeshash32(SB),NOSPLIT,$0-32966TEXT runtime·aeshash32(SB), NOSPLIT, $0-32
945        MOVQ        p+0(FP), AX        // ptr to data967        MOVQ p+0(FP), AX // ptr to data
968
946        // s+8(FP) is ignored, it is always sizeof(int32)969        // s+8(FP) is ignored, it is always sizeof(int32)
947        MOVQ        h+16(FP), X0        // seed970        MOVQ   h+16(FP), X0                   // seed
948        PINSRD        $2, (AX), X0        // data971        PINSRD $2, (AX), X0                   // data
949        AESENC        runtime·aeskeysched+0(SB), X0972        AESENC runtime·aeskeysched+0(SB), X0
950        AESENC        runtime·aeskeysched+16(SB), X0973        AESENC runtime·aeskeysched+16(SB), X0
951        AESENC        runtime·aeskeysched+0(SB), X0974        AESENC runtime·aeskeysched+0(SB), X0
952        MOVQ        X0, ret+24(FP)975        MOVQ   X0, ret+24(FP)
953        RET976        RET
954977
955TEXT runtime·aeshash64(SB),NOSPLIT,$0-32978TEXT runtime·aeshash64(SB), NOSPLIT, $0-32
956        MOVQ        p+0(FP), AX        // ptr to data979        MOVQ p+0(FP), AX // ptr to data
980
957        // s+8(FP) is ignored, it is always sizeof(int64)981        // s+8(FP) is ignored, it is always sizeof(int64)
958        MOVQ        h+16(FP), X0        // seed982        MOVQ   h+16(FP), X0                   // seed
959        PINSRQ        $1, (AX), X0        // data983        PINSRQ $1, (AX), X0                   // data
960        AESENC        runtime·aeskeysched+0(SB), X0984        AESENC runtime·aeskeysched+0(SB), X0
961        AESENC        runtime·aeskeysched+16(SB), X0985        AESENC runtime·aeskeysched+16(SB), X0
962        AESENC        runtime·aeskeysched+0(SB), X0986        AESENC runtime·aeskeysched+0(SB), X0
963        MOVQ        X0, ret+24(FP)987        MOVQ   X0, ret+24(FP)
964        RET988        RET
965989
966// simple mask to get rid of data in the high part of the register.990// simple mask to get rid of data in the high part of the register.
967DATA masks<>+0x00(SB)/8, $0x0000000000000000991DATA masks<>+0x00(SB)/8, $0x0000000000000000
968DATA masks<>+0x08(SB)/8, $0x0000000000000000992DATA masks<>+0x08(SB)/8, $0x0000000000000000
969DATA masks<>+0x10(SB)/8, $0x00000000000000ff993DATA masks<>+0x10(SB)/8, $0x00000000000000ff
970DATA masks<>+0x18(SB)/8, $0x0000000000000000994DATA masks<>+0x18(SB)/8, $0x0000000000000000
971DATA masks<>+0x20(SB)/8, $0x000000000000ffff995DATA masks<>+0x20(SB)/8, $0x000000000000ffff
972DATA masks<>+0x28(SB)/8, $0x0000000000000000996DATA masks<>+0x28(SB)/8, $0x0000000000000000
973DATA masks<>+0x30(SB)/8, $0x0000000000ffffff997DATA masks<>+0x30(SB)/8, $0x0000000000ffffff
974DATA masks<>+0x38(SB)/8, $0x0000000000000000998DATA masks<>+0x38(SB)/8, $0x0000000000000000
975DATA masks<>+0x40(SB)/8, $0x00000000ffffffff999DATA masks<>+0x40(SB)/8, $0x00000000ffffffff
976DATA masks<>+0x48(SB)/8, $0x00000000000000001000DATA masks<>+0x48(SB)/8, $0x0000000000000000
977DATA masks<>+0x50(SB)/8, $0x000000ffffffffff1001DATA masks<>+0x50(SB)/8, $0x000000ffffffffff
978DATA masks<>+0x58(SB)/8, $0x00000000000000001002DATA masks<>+0x58(SB)/8, $0x0000000000000000
979DATA masks<>+0x60(SB)/8, $0x0000ffffffffffff1003DATA masks<>+0x60(SB)/8, $0x0000ffffffffffff
980DATA masks<>+0x68(SB)/8, $0x00000000000000001004DATA masks<>+0x68(SB)/8, $0x0000000000000000
981DATA masks<>+0x70(SB)/8, $0x00ffffffffffffff1005DATA masks<>+0x70(SB)/8, $0x00ffffffffffffff
982DATA masks<>+0x78(SB)/8, $0x00000000000000001006DATA masks<>+0x78(SB)/8, $0x0000000000000000
983DATA masks<>+0x80(SB)/8, $0xffffffffffffffff1007DATA masks<>+0x80(SB)/8, $0xffffffffffffffff
984DATA masks<>+0x88(SB)/8, $0x00000000000000001008DATA masks<>+0x88(SB)/8, $0x0000000000000000
985DATA masks<>+0x90(SB)/8, $0xffffffffffffffff1009DATA masks<>+0x90(SB)/8, $0xffffffffffffffff
986DATA masks<>+0x98(SB)/8, $0x00000000000000ff1010DATA masks<>+0x98(SB)/8, $0x00000000000000ff
987DATA masks<>+0xa0(SB)/8, $0xffffffffffffffff1011DATA masks<>+0xa0(SB)/8, $0xffffffffffffffff
988DATA masks<>+0xa8(SB)/8, $0x000000000000ffff1012DATA masks<>+0xa8(SB)/8, $0x000000000000ffff
989DATA masks<>+0xb0(SB)/8, $0xffffffffffffffff1013DATA masks<>+0xb0(SB)/8, $0xffffffffffffffff
990DATA masks<>+0xb8(SB)/8, $0x0000000000ffffff1014DATA masks<>+0xb8(SB)/8, $0x0000000000ffffff
991DATA masks<>+0xc0(SB)/8, $0xffffffffffffffff1015DATA masks<>+0xc0(SB)/8, $0xffffffffffffffff
992DATA masks<>+0xc8(SB)/8, $0x00000000ffffffff1016DATA masks<>+0xc8(SB)/8, $0x00000000ffffffff
993DATA masks<>+0xd0(SB)/8, $0xffffffffffffffff1017DATA masks<>+0xd0(SB)/8, $0xffffffffffffffff
994DATA masks<>+0xd8(SB)/8, $0x000000ffffffffff1018DATA masks<>+0xd8(SB)/8, $0x000000ffffffffff
995DATA masks<>+0xe0(SB)/8, $0xffffffffffffffff1019DATA masks<>+0xe0(SB)/8, $0xffffffffffffffff
996DATA masks<>+0xe8(SB)/8, $0x0000ffffffffffff1020DATA masks<>+0xe8(SB)/8, $0x0000ffffffffffff
997DATA masks<>+0xf0(SB)/8, $0xffffffffffffffff1021DATA masks<>+0xf0(SB)/8, $0xffffffffffffffff
998DATA masks<>+0xf8(SB)/8, $0x00ffffffffffffff1022DATA masks<>+0xf8(SB)/8, $0x00ffffffffffffff
999GLOBL masks<>(SB),RODATA,$2561023GLOBL masks<>(SB), RODATA, $256
10001024
1001// these are arguments to pshufb.  They move data down from1025// these are arguments to pshufb.  They move data down from
1002// the high bytes of the register to the low bytes of the register.1026// the high bytes of the register to the low bytes of the register.
1003// index is how many bytes to move.1027// index is how many bytes to move.
1004DATA shifts<>+0x00(SB)/8, $0x00000000000000001028DATA shifts<>+0x00(SB)/8, $0x0000000000000000
1005DATA shifts<>+0x08(SB)/8, $0x00000000000000001029DATA shifts<>+0x08(SB)/8, $0x0000000000000000
1006DATA shifts<>+0x10(SB)/8, $0xffffffffffffff0f1030DATA shifts<>+0x10(SB)/8, $0xffffffffffffff0f
1007DATA shifts<>+0x18(SB)/8, $0xffffffffffffffff1031DATA shifts<>+0x18(SB)/8, $0xffffffffffffffff
1008DATA shifts<>+0x20(SB)/8, $0xffffffffffff0f0e1032DATA shifts<>+0x20(SB)/8, $0xffffffffffff0f0e
1009DATA shifts<>+0x28(SB)/8, $0xffffffffffffffff1033DATA shifts<>+0x28(SB)/8, $0xffffffffffffffff
1010DATA shifts<>+0x30(SB)/8, $0xffffffffff0f0e0d1034DATA shifts<>+0x30(SB)/8, $0xffffffffff0f0e0d
1011DATA shifts<>+0x38(SB)/8, $0xffffffffffffffff1035DATA shifts<>+0x38(SB)/8, $0xffffffffffffffff
1012DATA shifts<>+0x40(SB)/8, $0xffffffff0f0e0d0c1036DATA shifts<>+0x40(SB)/8, $0xffffffff0f0e0d0c
1013DATA shifts<>+0x48(SB)/8, $0xffffffffffffffff1037DATA shifts<>+0x48(SB)/8, $0xffffffffffffffff
1014DATA shifts<>+0x50(SB)/8, $0xffffff0f0e0d0c0b1038DATA shifts<>+0x50(SB)/8, $0xffffff0f0e0d0c0b
1015DATA shifts<>+0x58(SB)/8, $0xffffffffffffffff1039DATA shifts<>+0x58(SB)/8, $0xffffffffffffffff
1016DATA shifts<>+0x60(SB)/8, $0xffff0f0e0d0c0b0a1040DATA shifts<>+0x60(SB)/8, $0xffff0f0e0d0c0b0a
1017DATA shifts<>+0x68(SB)/8, $0xffffffffffffffff1041DATA shifts<>+0x68(SB)/8, $0xffffffffffffffff
1018DATA shifts<>+0x70(SB)/8, $0xff0f0e0d0c0b0a091042DATA shifts<>+0x70(SB)/8, $0xff0f0e0d0c0b0a09
1019DATA shifts<>+0x78(SB)/8, $0xffffffffffffffff1043DATA shifts<>+0x78(SB)/8, $0xffffffffffffffff
1020DATA shifts<>+0x80(SB)/8, $0x0f0e0d0c0b0a09081044DATA shifts<>+0x80(SB)/8, $0x0f0e0d0c0b0a0908
1021DATA shifts<>+0x88(SB)/8, $0xffffffffffffffff1045DATA shifts<>+0x88(SB)/8, $0xffffffffffffffff
1022DATA shifts<>+0x90(SB)/8, $0x0e0d0c0b0a0908071046DATA shifts<>+0x90(SB)/8, $0x0e0d0c0b0a090807
1023DATA shifts<>+0x98(SB)/8, $0xffffffffffffff0f1047DATA shifts<>+0x98(SB)/8, $0xffffffffffffff0f
1024DATA shifts<>+0xa0(SB)/8, $0x0d0c0b0a090807061048DATA shifts<>+0xa0(SB)/8, $0x0d0c0b0a09080706
1025DATA shifts<>+0xa8(SB)/8, $0xffffffffffff0f0e1049DATA shifts<>+0xa8(SB)/8, $0xffffffffffff0f0e
1026DATA shifts<>+0xb0(SB)/8, $0x0c0b0a09080706051050DATA shifts<>+0xb0(SB)/8, $0x0c0b0a0908070605
1027DATA shifts<>+0xb8(SB)/8, $0xffffffffff0f0e0d1051DATA shifts<>+0xb8(SB)/8, $0xffffffffff0f0e0d
1028DATA shifts<>+0xc0(SB)/8, $0x0b0a0908070605041052DATA shifts<>+0xc0(SB)/8, $0x0b0a090807060504
1029DATA shifts<>+0xc8(SB)/8, $0xffffffff0f0e0d0c1053DATA shifts<>+0xc8(SB)/8, $0xffffffff0f0e0d0c
1030DATA shifts<>+0xd0(SB)/8, $0x0a090807060504031054DATA shifts<>+0xd0(SB)/8, $0x0a09080706050403
1031DATA shifts<>+0xd8(SB)/8, $0xffffff0f0e0d0c0b1055DATA shifts<>+0xd8(SB)/8, $0xffffff0f0e0d0c0b
1032DATA shifts<>+0xe0(SB)/8, $0x09080706050403021056DATA shifts<>+0xe0(SB)/8, $0x0908070605040302
1033DATA shifts<>+0xe8(SB)/8, $0xffff0f0e0d0c0b0a1057DATA shifts<>+0xe8(SB)/8, $0xffff0f0e0d0c0b0a
1034DATA shifts<>+0xf0(SB)/8, $0x08070605040302011058DATA shifts<>+0xf0(SB)/8, $0x0807060504030201
1035DATA shifts<>+0xf8(SB)/8, $0xff0f0e0d0c0b0a091059DATA shifts<>+0xf8(SB)/8, $0xff0f0e0d0c0b0a09
1036GLOBL shifts<>(SB),RODATA,$2561060GLOBL shifts<>(SB), RODATA, $256
10371061
1038TEXT runtime·memeq(SB),NOSPLIT,$0-251062TEXT runtime·memeq(SB), NOSPLIT, $0-25
1039        MOVQ        a+0(FP), SI1063        MOVQ a+0(FP), SI
1040        MOVQ        b+8(FP), DI1064        MOVQ b+8(FP), DI
1041        MOVQ        size+16(FP), BX1065        MOVQ size+16(FP), BX
1042        CALL        runtime·memeqbody(SB)1066        CALL runtime·memeqbody(SB)
1043        MOVB        AX, ret+24(FP)1067        MOVB AX, ret+24(FP)
1044        RET1068        RET
10451069
1046// eqstring tests whether two strings are equal.1070// eqstring tests whether two strings are equal.
1047// See runtime_test.go:eqstring_generic for1071// See runtime_test.go:eqstring_generic for
1048// equivalent Go code.1072// equivalent Go code.
1049TEXT runtime·eqstring(SB),NOSPLIT,$0-331073TEXT runtime·eqstring(SB), NOSPLIT, $0-33
1050        MOVQ        s1len+8(FP), AX1074        MOVQ s1len+8(FP), AX
1051        MOVQ        s2len+24(FP), BX1075        MOVQ s2len+24(FP), BX
1052        CMPQ        AX, BX1076        CMPQ AX, BX
1053        JNE        different1077        JNE  different
1054        MOVQ        s1str+0(FP), SI1078        MOVQ s1str+0(FP), SI
1055        MOVQ        s2str+16(FP), DI1079        MOVQ s2str+16(FP), DI
1056        CMPQ        SI, DI1080        CMPQ SI, DI
1057        JEQ        same1081        JEQ  same
1058        CALL        runtime·memeqbody(SB)1082        CALL runtime·memeqbody(SB)
1059        MOVB        AX, v+32(FP)1083        MOVB AX, v+32(FP)
1060        RET1084        RET
1085
1061same:1086same:
1062        MOVB        $1, v+32(FP)1087        MOVB $1, v+32(FP)
1063        RET1088        RET
1089
1064different:1090different:
1065        MOVB        $0, v+32(FP)1091        MOVB $0, v+32(FP)
1066        RET1092        RET
10671093
1068// a in SI1094// a in SI
1069// b in DI1095// b in DI
1070// count in BX1096// count in BX
1071TEXT runtime·memeqbody(SB),NOSPLIT,$0-01097TEXT runtime·memeqbody(SB), NOSPLIT, $0-0
1072        XORQ        AX, AX1098        XORQ AX, AX
10731099
1074        CMPQ        BX, $81100        CMPQ BX, $8
1075        JB        small1101        JB   small
1076         1102
1077        // 64 bytes at a time using xmm registers1103        // 64 bytes at a time using xmm registers
1078hugeloop:1104hugeloop:
1079        CMPQ        BX, $641105        CMPQ     BX, $64
1080        JB        bigloop1106        JB       bigloop
1081        MOVOU        (SI), X01107        MOVOU    (SI), X0
1082        MOVOU        (DI), X11108        MOVOU    (DI), X1
1083        MOVOU        16(SI), X21109        MOVOU    16(SI), X2
1084        MOVOU        16(DI), X31110        MOVOU    16(DI), X3
1085        MOVOU        32(SI), X41111        MOVOU    32(SI), X4
1086        MOVOU        32(DI), X51112        MOVOU    32(DI), X5
1087        MOVOU        48(SI), X61113        MOVOU    48(SI), X6
1088        MOVOU        48(DI), X71114        MOVOU    48(DI), X7
1089        PCMPEQB        X1, X01115        PCMPEQB  X1, X0
1090        PCMPEQB        X3, X21116        PCMPEQB  X3, X2
1091        PCMPEQB        X5, X41117        PCMPEQB  X5, X4
1092        PCMPEQB        X7, X61118        PCMPEQB  X7, X6
1093        PAND        X2, X01119        PAND     X2, X0
1094        PAND        X6, X41120        PAND     X6, X4
1095        PAND        X4, X01121        PAND     X4, X0
1096        PMOVMSKB X0, DX1122        PMOVMSKB X0, DX
1097        ADDQ        $64, SI1123        ADDQ     $64, SI
1098        ADDQ        $64, DI1124        ADDQ     $64, DI
1099        SUBQ        $64, BX1125        SUBQ     $64, BX
1100        CMPL        DX, $0xffff1126        CMPL     DX, $0xffff
1101        JEQ        hugeloop1127        JEQ      hugeloop
1102        RET1128        RET
11031129
1104        // 8 bytes at a time using 64-bit register1130// 8 bytes at a time using 64-bit register
1105bigloop:1131bigloop:
1106        CMPQ        BX, $81132        CMPQ BX, $8
1107        JBE        leftover1133        JBE  leftover
1108        MOVQ        (SI), CX1134        MOVQ (SI), CX
1109        MOVQ        (DI), DX1135        MOVQ (DI), DX
1110        ADDQ        $8, SI1136        ADDQ $8, SI
1111        ADDQ        $8, DI1137        ADDQ $8, DI
1112        SUBQ        $8, BX1138        SUBQ $8, BX
1113        CMPQ        CX, DX1139        CMPQ CX, DX
1114        JEQ        bigloop1140        JEQ  bigloop
1115        RET1141        RET
11161142
1117        // remaining 0-8 bytes1143// remaining 0-8 bytes
1118leftover:1144leftover:
1119        MOVQ        -8(SI)(BX*1), CX1145        MOVQ  -8(SI)(BX*1), CX
1120        MOVQ        -8(DI)(BX*1), DX1146        MOVQ  -8(DI)(BX*1), DX
1121        CMPQ        CX, DX1147        CMPQ  CX, DX
1122        SETEQ        AX1148        SETEQ AX
1123        RET1149        RET
11241150
1125small:1151small:
1126        CMPQ        BX, $01152        CMPQ BX, $0
1127        JEQ        equal1153        JEQ  equal
11281154
1129        LEAQ        0(BX*8), CX1155        LEAQ 0(BX*8), CX
1130        NEGQ        CX1156        NEGQ CX
11311157
1132        CMPB        SI, $0xf81158        CMPB SI, $0xf8
1133        JA        si_high1159        JA   si_high
11341160
1135        // load at SI won't cross a page boundary.1161        // load at SI won't cross a page boundary.
1136        MOVQ        (SI), SI1162        MOVQ (SI), SI
1137        JMP        si_finish1163        JMP  si_finish
1164
1138si_high:1165si_high:
1139        // address ends in 11111xxx.  Load up to bytes we want, move to correct position.1166        // address ends in 11111xxx.  Load up to bytes we want, move to correct position.
1140        MOVQ        -8(SI)(BX*1), SI1167        MOVQ -8(SI)(BX*1), SI
1141        SHRQ        CX, SI1168        SHRQ CX, SI
1169
1142si_finish:1170si_finish:
11431171
1144        // same for DI.1172        // same for DI.
1145        CMPB        DI, $0xf81173        CMPB DI, $0xf8
1146        JA        di_high1174        JA   di_high
1147        MOVQ        (DI), DI1175        MOVQ (DI), DI
1148        JMP        di_finish1176        JMP  di_finish
1177
1149di_high:1178di_high:
1150        MOVQ        -8(DI)(BX*1), DI1179        MOVQ -8(DI)(BX*1), DI
1151        SHRQ        CX, DI1180        SHRQ CX, DI
1181
1152di_finish:1182di_finish:
11531183
1154        SUBQ        SI, DI1184        SUBQ SI, DI
1155        SHLQ        CX, DI1185        SHLQ CX, DI
1186
1156equal:1187equal:
1157        SETEQ        AX1188        SETEQ AX
1158        RET1189        RET
11591190
1160TEXT runtime·cmpstring(SB),NOSPLIT,$0-401191TEXT runtime·cmpstring(SB), NOSPLIT, $0-40
1161        MOVQ        s1_base+0(FP), SI1192        MOVQ s1_base+0(FP), SI
1162        MOVQ        s1_len+8(FP), BX1193        MOVQ s1_len+8(FP), BX
1163        MOVQ        s2_base+16(FP), DI1194        MOVQ s2_base+16(FP), DI
1164        MOVQ        s2_len+24(FP), DX1195        MOVQ s2_len+24(FP), DX
1165        CALL        runtime·cmpbody(SB)1196        CALL runtime·cmpbody(SB)
1166        MOVQ        AX, ret+32(FP)1197        MOVQ AX, ret+32(FP)
1167        RET1198        RET
11681199
1169TEXT runtime·cmpbytes(SB),NOSPLIT,$0-561200TEXT runtime·cmpbytes(SB), NOSPLIT, $0-56
1170        MOVQ        s1+0(FP), SI1201        MOVQ s1+0(FP), SI
1171        MOVQ        s1+8(FP), BX1202        MOVQ s1+8(FP), BX
1172        MOVQ        s2+24(FP), DI1203        MOVQ s2+24(FP), DI
1173        MOVQ        s2+32(FP), DX1204        MOVQ s2+32(FP), DX
1174        CALL        runtime·cmpbody(SB)1205        CALL runtime·cmpbody(SB)
1175        MOVQ        AX, res+48(FP)1206        MOVQ AX, res+48(FP)
1176        RET1207        RET
11771208
1178// input:1209// input:
1179//   SI = a1210//   SI = a
1180//   DI = b1211//   DI = b
1181//   BX = alen1212//   BX = alen
1182//   DX = blen1213//   DX = blen
1183// output:1214// output:
1184//   AX = 1/0/-11215//   AX = 1/0/-1
1185TEXT runtime·cmpbody(SB),NOSPLIT,$0-01216TEXT runtime·cmpbody(SB), NOSPLIT, $0-0
1186        CMPQ        SI, DI1217        CMPQ    SI, DI
1187        JEQ        cmp_allsame1218        JEQ     cmp_allsame
1188        CMPQ        BX, DX1219        CMPQ    BX, DX
1189        MOVQ        DX, BP1220        MOVQ    DX, BP
1190        CMOVQLT        BX, BP // BP = min(alen, blen) = # of bytes to compare1221        CMOVQLT BX, BP      // BP = min(alen, blen) = # of bytes to compare
1191        CMPQ        BP, $81222        CMPQ    BP, $8
1192        JB        cmp_small1223        JB      cmp_small
11931224
1194cmp_loop:1225cmp_loop:
1195        CMPQ        BP, $161226        CMPQ     BP, $16
1196        JBE        cmp_0through161227        JBE      cmp_0through16
1197        MOVOU        (SI), X01228        MOVOU    (SI), X0
1198        MOVOU        (DI), X11229        MOVOU    (DI), X1
1199        PCMPEQB X0, X11230        PCMPEQB  X0, X1
1200        PMOVMSKB X1, AX1231        PMOVMSKB X1, AX
1201        XORQ        $0xffff, AX        // convert EQ to NE1232        XORQ     $0xffff, AX    // convert EQ to NE
1202        JNE        cmp_diff16        // branch if at least one byte is not equal1233        JNE      cmp_diff16     // branch if at least one byte is not equal
1203        ADDQ        $16, SI1234        ADDQ     $16, SI
1204        ADDQ        $16, DI1235        ADDQ     $16, DI
1205        SUBQ        $16, BP1236        SUBQ     $16, BP
1206        JMP        cmp_loop1237        JMP      cmp_loop
1207         1238
1208        // AX = bit mask of differences1239// AX = bit mask of differences
1209cmp_diff16:1240cmp_diff16:
1210        BSFQ        AX, BX        // index of first byte that differs1241        BSFQ  AX, BX         // index of first byte that differs
1211        XORQ        AX, AX1242        XORQ  AX, AX
1212        MOVB        (SI)(BX*1), CX1243        MOVB  (SI)(BX*1), CX
1213        CMPB        CX, (DI)(BX*1)1244        CMPB  CX, (DI)(BX*1)
1214        SETHI        AX1245        SETHI AX
1215        LEAQ        -1(AX*2), AX        // convert 1/0 to +1/-11246        LEAQ  -1(AX*2), AX   // convert 1/0 to +1/-1
1216        RET1247        RET
12171248
1218        // 0 through 16 bytes left, alen>=8, blen>=81249// 0 through 16 bytes left, alen>=8, blen>=8
1219cmp_0through16:1250cmp_0through16:
1220        CMPQ        BP, $81251        CMPQ BP, $8
1221        JBE        cmp_0through81252        JBE  cmp_0through8
1222        MOVQ        (SI), AX1253        MOVQ (SI), AX
1223        MOVQ        (DI), CX1254        MOVQ (DI), CX
1224        CMPQ        AX, CX1255        CMPQ AX, CX
1225        JNE        cmp_diff81256        JNE  cmp_diff8
1257
1226cmp_0through8:1258cmp_0through8:
1227        MOVQ        -8(SI)(BP*1), AX1259        MOVQ -8(SI)(BP*1), AX
1228        MOVQ        -8(DI)(BP*1), CX1260        MOVQ -8(DI)(BP*1), CX
1229        CMPQ        AX, CX1261        CMPQ AX, CX
1230        JEQ        cmp_allsame1262        JEQ  cmp_allsame
12311263
1232        // AX and CX contain parts of a and b that differ.1264        // AX and CX contain parts of a and b that differ.
1233cmp_diff8:1265cmp_diff8:
1234        BSWAPQ        AX        // reverse order of bytes1266        BSWAPQ AX           // reverse order of bytes
1235        BSWAPQ        CX1267        BSWAPQ CX
1236        XORQ        AX, CX1268        XORQ   AX, CX
1237        BSRQ        CX, CX        // index of highest bit difference1269        BSRQ   CX, CX       // index of highest bit difference
1238        SHRQ        CX, AX        // move a's bit to bottom1270        SHRQ   CX, AX       // move a's bit to bottom
1239        ANDQ        $1, AX        // mask bit1271        ANDQ   $1, AX       // mask bit
1240        LEAQ        -1(AX*2), AX // 1/0 => +1/-11272        LEAQ   -1(AX*2), AX // 1/0 => +1/-1
1241        RET1273        RET
12421274
1243        // 0-7 bytes in common1275// 0-7 bytes in common
1244cmp_small:1276cmp_small:
1245        LEAQ        (BP*8), CX        // bytes left -> bits left1277        LEAQ (BP*8), CX  // bytes left -> bits left
1246        NEGQ        CX                //  - bits lift (== 64 - bits left mod 64)1278        NEGQ CX          // - bits lift (== 64 - bits left mod 64)
1247        JEQ        cmp_allsame1279        JEQ  cmp_allsame
12481280
1249        // load bytes of a into high bytes of AX1281        // load bytes of a into high bytes of AX
1250        CMPB        SI, $0xf81282        CMPB SI, $0xf8
1251        JA        cmp_si_high1283        JA   cmp_si_high
1252        MOVQ        (SI), SI1284        MOVQ (SI), SI
1253        JMP        cmp_si_finish1285        JMP  cmp_si_finish
1286
1254cmp_si_high:1287cmp_si_high:
1255        MOVQ        -8(SI)(BP*1), SI1288        MOVQ -8(SI)(BP*1), SI
1256        SHRQ        CX, SI1289        SHRQ CX, SI
1290
1257cmp_si_finish:1291cmp_si_finish:
1258        SHLQ        CX, SI1292        SHLQ CX, SI
12591293
1260        // load bytes of b in to high bytes of BX1294        // load bytes of b in to high bytes of BX
1261        CMPB        DI, $0xf81295        CMPB DI, $0xf8
1262        JA        cmp_di_high1296        JA   cmp_di_high
1263        MOVQ        (DI), DI1297        MOVQ (DI), DI
1264        JMP        cmp_di_finish1298        JMP  cmp_di_finish
1299
1265cmp_di_high:1300cmp_di_high:
1266        MOVQ        -8(DI)(BP*1), DI1301        MOVQ -8(DI)(BP*1), DI
1267        SHRQ        CX, DI1302        SHRQ CX, DI
1303
1268cmp_di_finish:1304cmp_di_finish:
1269        SHLQ        CX, DI1305        SHLQ CX, DI
12701306
1271        BSWAPQ        SI        // reverse order of bytes1307        BSWAPQ SI           // reverse order of bytes
1272        BSWAPQ        DI1308        BSWAPQ DI
1273        XORQ        SI, DI        // find bit differences1309        XORQ   SI, DI       // find bit differences
1274        JEQ        cmp_allsame1310        JEQ    cmp_allsame
1275        BSRQ        DI, CX        // index of highest bit difference1311        BSRQ   DI, CX       // index of highest bit difference
1276        SHRQ        CX, SI        // move a's bit to bottom1312        SHRQ   CX, SI       // move a's bit to bottom
1277        ANDQ        $1, SI        // mask bit1313        ANDQ   $1, SI       // mask bit
1278        LEAQ        -1(SI*2), AX // 1/0 => +1/-11314        LEAQ   -1(SI*2), AX // 1/0 => +1/-1
1279        RET1315        RET
12801316
1281cmp_allsame:1317cmp_allsame:
1282        XORQ        AX, AX1318        XORQ  AX, AX
1283        XORQ        CX, CX1319        XORQ  CX, CX
1284        CMPQ        BX, DX1320        CMPQ  BX, DX
1285        SETGT        AX        // 1 if alen > blen1321        SETGT AX               // 1 if alen > blen
1286        SETEQ        CX        // 1 if alen == blen1322        SETEQ CX               // 1 if alen == blen
1287        LEAQ        -1(CX)(AX*2), AX        // 1,0,-1 result1323        LEAQ  -1(CX)(AX*2), AX // 1,0,-1 result
1288        RET1324        RET
12891325
1290TEXT bytes·IndexByte(SB),NOSPLIT,$01326TEXT bytes·IndexByte(SB), NOSPLIT, $0
1291        MOVQ s+0(FP), SI1327        MOVQ s+0(FP), SI
1292        MOVQ s_len+8(FP), BX1328        MOVQ s_len+8(FP), BX
1293        MOVB c+24(FP), AL1329        MOVB c+24(FP), AL
1294        CALL runtime·indexbytebody(SB)1330        CALL runtime·indexbytebody(SB)
1295        MOVQ AX, ret+32(FP)1331        MOVQ AX, ret+32(FP)
1296        RET1332        RET
12971333
1298TEXT strings·IndexByte(SB),NOSPLIT,$01334TEXT strings·IndexByte(SB), NOSPLIT, $0
1299        MOVQ s+0(FP), SI1335        MOVQ s+0(FP), SI
1300        MOVQ s_len+8(FP), BX1336        MOVQ s_len+8(FP), BX
1301        MOVB c+16(FP), AL1337        MOVB c+16(FP), AL
1302        CALL runtime·indexbytebody(SB)1338        CALL runtime·indexbytebody(SB)
1303        MOVQ AX, ret+24(FP)1339        MOVQ AX, ret+24(FP)
1304        RET1340        RET
13051341
1306// input:1342// input:
1307//   SI: data1343//   SI: data
1308//   BX: data len1344//   BX: data len
1309//   AL: byte sought1345//   AL: byte sought
1310// output:1346// output:
1311//   AX1347//   AX
1312TEXT runtime·indexbytebody(SB),NOSPLIT,$01348TEXT runtime·indexbytebody(SB), NOSPLIT, $0
1313        MOVQ SI, DI1349        MOVQ SI, DI
13141350
1315        CMPQ BX, $161351        CMPQ BX, $16
1316        JLT indexbyte_small1352        JLT  indexbyte_small
13171353
1318        // round up to first 16-byte boundary1354        // round up to first 16-byte boundary
1319        TESTQ $15, SI1355        TESTQ $15, SI
1320        JZ aligned1356        JZ    aligned
1321        MOVQ SI, CX1357        MOVQ  SI, CX
1322        ANDQ $~15, CX1358        ANDQ  $~15, CX
1323        ADDQ $16, CX1359        ADDQ  $16, CX
13241360
1325        // search the beginning1361        // search the beginning
1326        SUBQ SI, CX1362        SUBQ  SI, CX
1327        REPN; SCASB1363        REPN; SCASB
1328        JZ success1364        JZ    success
13291365
1330// DI is 16-byte aligned; get ready to search using SSE instructions1366        // DI is 16-byte aligned; get ready to search using SSE instructions
1331aligned:1367aligned:
1332        // round down to last 16-byte boundary1368        // round down to last 16-byte boundary
1333        MOVQ BX, R111369        MOVQ BX, R11
1334        ADDQ SI, R111370        ADDQ SI, R11
1335        ANDQ $~15, R111371        ANDQ $~15, R11
13361372
1337        // shuffle X0 around so that each byte contains c1373        // shuffle X0 around so that each byte contains c
1338        MOVD AX, X01374        MOVD      AX, X0
1339        PUNPCKLBW X0, X01375        PUNPCKLBW X0, X0
1340        PUNPCKLBW X0, X01376        PUNPCKLBW X0, X0
1341        PSHUFL $0, X0, X01377        PSHUFL    $0, X0, X0
1342        JMP condition1378        JMP       condition
13431379
1344sse:1380sse:
1345        // move the next 16-byte chunk of the buffer into X11381        // move the next 16-byte chunk of the buffer into X1
1346        MOVO (DI), X11382        MOVO (DI), X1
1383
1347        // compare bytes in X0 to X11384        // compare bytes in X0 to X1
1348        PCMPEQB X0, X11385        PCMPEQB X0, X1
1386
1349        // take the top bit of each byte in X1 and put the result in DX1387        // take the top bit of each byte in X1 and put the result in DX
1350        PMOVMSKB X1, DX1388        PMOVMSKB X1, DX
1351        TESTL DX, DX1389        TESTL    DX, DX
1352        JNZ ssesuccess1390        JNZ      ssesuccess
1353        ADDQ $16, DI1391        ADDQ     $16, DI
13541392
1355condition:1393condition:
1356        CMPQ DI, R111394        CMPQ DI, R11
1357        JLT sse1395        JLT  sse
13581396
1359        // search the end1397        // search the end
1360        MOVQ SI, CX1398        MOVQ SI, CX
1361        ADDQ BX, CX1399        ADDQ BX, CX
1362        SUBQ R11, CX1400        SUBQ R11, CX
1401
1363        // if CX == 0, the zero flag will be set and we'll end up1402        // if CX == 0, the zero flag will be set and we'll end up
1364        // returning a false success1403        // returning a false success
1365        JZ failure1404        JZ    failure
1366        REPN; SCASB1405        REPN; SCASB
1367        JZ success1406        JZ    success
13681407
1369failure:1408failure:
1370        MOVQ $-1, AX1409        MOVQ $-1, AX
1371        RET1410        RET
13721411
1373// handle for lengths < 161412// handle for lengths < 16
1374indexbyte_small:1413indexbyte_small:
1375        MOVQ BX, CX1414        MOVQ  BX, CX
1376        REPN; SCASB1415        REPN; SCASB
1377        JZ success1416        JZ    success
1378        MOVQ $-1, AX1417        MOVQ  $-1, AX
1379        RET1418        RET
13801419
1381// we've found the chunk containing the byte1420// we've found the chunk containing the byte
1382// now just figure out which specific byte it is1421// now just figure out which specific byte it is
1383ssesuccess:1422ssesuccess:
1384        // get the index of the least significant set bit1423        // get the index of the least significant set bit
1385        BSFW DX, DX1424        BSFW DX, DX
1386        SUBQ SI, DI1425        SUBQ SI, DI
1387        ADDQ DI, DX1426        ADDQ DI, DX
1388        MOVQ DX, AX1427        MOVQ DX, AX
1389        RET1428        RET
13901429
1391success:1430success:
1392        SUBQ SI, DI1431        SUBQ SI, DI
1393        SUBL $1, DI1432        SUBL $1, DI
1394        MOVQ DI, AX1433        MOVQ DI, AX
1395        RET1434        RET
13961435
1397TEXT bytes·Equal(SB),NOSPLIT,$0-491436TEXT bytes·Equal(SB), NOSPLIT, $0-49
1398        MOVQ        a_len+8(FP), BX1437        MOVQ a_len+8(FP), BX
1399        MOVQ        b_len+32(FP), CX1438        MOVQ b_len+32(FP), CX
1400        XORQ        AX, AX1439        XORQ AX, AX
1401        CMPQ        BX, CX1440        CMPQ BX, CX
1402        JNE        eqret1441        JNE  eqret
1403        MOVQ        a+0(FP), SI1442        MOVQ a+0(FP), SI
1404        MOVQ        b+24(FP), DI1443        MOVQ b+24(FP), DI
1405        CALL        runtime·memeqbody(SB)1444        CALL runtime·memeqbody(SB)
1445
1406eqret:1446eqret:
1407        MOVB        AX, ret+48(FP)1447        MOVB AX, ret+48(FP)
1408        RET1448        RET
14091449
1410// A Duff's device for zeroing memory.1450// A Duff's device for zeroing memory.
1411// The compiler jumps to computed addresses within1451// The compiler jumps to computed addresses within
1412// this routine to zero chunks of memory.  Do not1452// this routine to zero chunks of memory.  Do not
1413// change this code without also changing the code1453// change this code without also changing the code
1414// in ../../cmd/6g/ggen.c:clearfat.1454// in ../../cmd/6g/ggen.c:clearfat.
1415// AX: zero1455// AX: zero
1416// DI: ptr to memory to be zeroed1456// DI: ptr to memory to be zeroed
1417// DI is updated as a side effect.1457// DI is updated as a side effect.
1418TEXT runtime·duffzero(SB), NOSPLIT, $0-01458TEXT runtime·duffzero(SB), NOSPLIT, $0-0
1419        STOSQ1459        STOSQ
1420        STOSQ1460        STOSQ
1421        STOSQ1461        STOSQ
1422        STOSQ1462        STOSQ
1423        STOSQ1463        STOSQ
1424        STOSQ1464        STOSQ
1425        STOSQ1465        STOSQ
1426        STOSQ1466        STOSQ
1427        STOSQ1467        STOSQ
1428        STOSQ1468        STOSQ
1429        STOSQ1469        STOSQ
1430        STOSQ1470        STOSQ
1431        STOSQ1471        STOSQ
1432        STOSQ1472        STOSQ
1433        STOSQ1473        STOSQ
1434        STOSQ1474        STOSQ
1435        STOSQ1475        STOSQ
1436        STOSQ1476        STOSQ
1437        STOSQ1477        STOSQ
1438        STOSQ1478        STOSQ
1439        STOSQ1479        STOSQ
1440        STOSQ1480        STOSQ
1441        STOSQ1481        STOSQ
1442        STOSQ1482        STOSQ
1443        STOSQ1483        STOSQ
1444        STOSQ1484        STOSQ
1445        STOSQ1485        STOSQ
1446        STOSQ1486        STOSQ
1447        STOSQ1487        STOSQ
1448        STOSQ1488        STOSQ
1449        STOSQ1489        STOSQ
1450        STOSQ1490        STOSQ
1451        STOSQ1491        STOSQ
1452        STOSQ1492        STOSQ
1453        STOSQ1493        STOSQ
1454        STOSQ1494        STOSQ
1455        STOSQ1495        STOSQ
1456        STOSQ1496        STOSQ
1457        STOSQ1497        STOSQ
1458        STOSQ1498        STOSQ
1459        STOSQ1499        STOSQ
1460        STOSQ1500        STOSQ
1461        STOSQ1501        STOSQ
1462        STOSQ1502        STOSQ
1463        STOSQ1503        STOSQ
1464        STOSQ1504        STOSQ
1465        STOSQ1505        STOSQ
1466        STOSQ1506        STOSQ
1467        STOSQ1507        STOSQ
1468        STOSQ1508        STOSQ
1469        STOSQ1509        STOSQ
1470        STOSQ1510        STOSQ
1471        STOSQ1511        STOSQ
1472        STOSQ1512        STOSQ
1473        STOSQ1513        STOSQ
1474        STOSQ1514        STOSQ
1475        STOSQ1515        STOSQ
1476        STOSQ1516        STOSQ
1477        STOSQ1517        STOSQ
1478        STOSQ1518        STOSQ
1479        STOSQ1519        STOSQ
1480        STOSQ1520        STOSQ
1481        STOSQ1521        STOSQ
1482        STOSQ1522        STOSQ
1483        STOSQ1523        STOSQ
1484        STOSQ1524        STOSQ
1485        STOSQ1525        STOSQ
1486        STOSQ1526        STOSQ
1487        STOSQ1527        STOSQ
1488        STOSQ1528        STOSQ
1489        STOSQ1529        STOSQ
1490        STOSQ1530        STOSQ
1491        STOSQ1531        STOSQ
1492        STOSQ1532        STOSQ
1493        STOSQ1533        STOSQ
1494        STOSQ1534        STOSQ
1495        STOSQ1535        STOSQ
1496        STOSQ1536        STOSQ
1497        STOSQ1537        STOSQ
1498        STOSQ1538        STOSQ
1499        STOSQ1539        STOSQ
1500        STOSQ1540        STOSQ
1501        STOSQ1541        STOSQ
1502        STOSQ1542        STOSQ
1503        STOSQ1543        STOSQ
1504        STOSQ1544        STOSQ
1505        STOSQ1545        STOSQ
1506        STOSQ1546        STOSQ
1507        STOSQ1547        STOSQ
1508        STOSQ1548        STOSQ
1509        STOSQ1549        STOSQ
1510        STOSQ1550        STOSQ
1511        STOSQ1551        STOSQ
1512        STOSQ1552        STOSQ
1513        STOSQ1553        STOSQ
1514        STOSQ1554        STOSQ
1515        STOSQ1555        STOSQ
1516        STOSQ1556        STOSQ
1517        STOSQ1557        STOSQ
1518        STOSQ1558        STOSQ
1519        STOSQ1559        STOSQ
1520        STOSQ1560        STOSQ
1521        STOSQ1561        STOSQ
1522        STOSQ1562        STOSQ
1523        STOSQ1563        STOSQ
1524        STOSQ1564        STOSQ
1525        STOSQ1565        STOSQ
1526        STOSQ1566        STOSQ
1527        STOSQ1567        STOSQ
1528        STOSQ1568        STOSQ
1529        STOSQ1569        STOSQ
1530        STOSQ1570        STOSQ
1531        STOSQ1571        STOSQ
1532        STOSQ1572        STOSQ
1533        STOSQ1573        STOSQ
1534        STOSQ1574        STOSQ
1535        STOSQ1575        STOSQ
1536        STOSQ1576        STOSQ
1537        STOSQ1577        STOSQ
1538        STOSQ1578        STOSQ
1539        STOSQ1579        STOSQ
1540        STOSQ1580        STOSQ
1541        STOSQ1581        STOSQ
1542        STOSQ1582        STOSQ
1543        STOSQ1583        STOSQ
1544        STOSQ1584        STOSQ
1545        STOSQ1585        STOSQ
1546        STOSQ1586        STOSQ
1547        RET1587        RET
15481588
1549// A Duff's device for copying memory.1589// A Duff's device for copying memory.
1550// The compiler jumps to computed addresses within1590// The compiler jumps to computed addresses within
1551// this routine to copy chunks of memory.  Source1591// this routine to copy chunks of memory.  Source
1552// and destination must not overlap.  Do not1592// and destination must not overlap.  Do not
1553// change this code without also changing the code1593// change this code without also changing the code
1554// in ../../cmd/6g/cgen.c:sgen.1594// in ../../cmd/6g/cgen.c:sgen.
1555// SI: ptr to source memory1595// SI: ptr to source memory
1556// DI: ptr to destination memory1596// DI: ptr to destination memory
1557// SI and DI are updated as a side effect.1597// SI and DI are updated as a side effect.
15581598
1559// NOTE: this is equivalent to a sequence of MOVSQ but1599// NOTE: this is equivalent to a sequence of MOVSQ but
1560// for some reason that is 3.5x slower than this code.1600// for some reason that is 3.5x slower than this code.
1561// The STOSQ above seem fine, though.1601// The STOSQ above seem fine, though.
1562TEXT runtime·duffcopy(SB), NOSPLIT, $0-01602TEXT runtime·duffcopy(SB), NOSPLIT, $0-0
1563        MOVQ        (SI),CX1603        MOVQ (SI), CX
1564        ADDQ        $8,SI1604        ADDQ $8, SI
1565        MOVQ        CX,(DI)1605        MOVQ CX, (DI)
1566        ADDQ        $8,DI1606        ADDQ $8, DI
15671607
1568        MOVQ        (SI),CX1608        MOVQ (SI), CX
1569        ADDQ        $8,SI1609        ADDQ $8, SI
1570        MOVQ        CX,(DI)1610        MOVQ CX, (DI)
1571        ADDQ        $8,DI1611        ADDQ $8, DI
15721612
1573        MOVQ        (SI),CX1613        MOVQ (SI), CX
1574        ADDQ        $8,SI1614        ADDQ $8, SI
1575        MOVQ        CX,(DI)1615        MOVQ CX, (DI)
1576        ADDQ        $8,DI1616        ADDQ $8, DI
15771617
1578        MOVQ        (SI),CX1618        MOVQ (SI), CX
1579        ADDQ        $8,SI1619        ADDQ $8, SI
1580        MOVQ        CX,(DI)1620        MOVQ CX, (DI)
1581        ADDQ        $8,DI1621        ADDQ $8, DI
15821622
1583        MOVQ        (SI),CX1623        MOVQ (SI), CX
1584        ADDQ        $8,SI1624        ADDQ $8, SI
1585        MOVQ        CX,(DI)1625        MOVQ CX, (DI)
1586        ADDQ        $8,DI1626        ADDQ $8, DI
15871627
1588        MOVQ        (SI),CX1628        MOVQ (SI), CX
1589        ADDQ        $8,SI1629        ADDQ $8, SI
1590        MOVQ        CX,(DI)1630        MOVQ CX, (DI)
1591        ADDQ        $8,DI1631        ADDQ $8, DI
15921632
1593        MOVQ        (SI),CX1633        MOVQ (SI), CX
1594        ADDQ        $8,SI1634        ADDQ $8, SI
1595        MOVQ        CX,(DI)1635        MOVQ CX, (DI)
1596        ADDQ        $8,DI1636        ADDQ $8, DI
15971637
1598        MOVQ        (SI),CX1638        MOVQ (SI), CX
1599        ADDQ        $8,SI1639        ADDQ $8, SI
1600        MOVQ        CX,(DI)1640        MOVQ CX, (DI)
1601        ADDQ        $8,DI1641        ADDQ $8, DI
16021642
1603        MOVQ        (SI),CX1643        MOVQ (SI), CX
1604        ADDQ        $8,SI1644        ADDQ $8, SI
1605        MOVQ        CX,(DI)1645        MOVQ CX, (DI)
1606        ADDQ        $8,DI1646        ADDQ $8, DI
16071647
1608        MOVQ        (SI),CX1648        MOVQ (SI), CX
1609        ADDQ        $8,SI1649        ADDQ $8, SI
1610        MOVQ        CX,(DI)1650        MOVQ CX, (DI)
1611        ADDQ        $8,DI1651        ADDQ $8, DI
16121652
1613        MOVQ        (SI),CX1653        MOVQ (SI), CX
1614        ADDQ        $8,SI1654        ADDQ $8, SI
1615        MOVQ        CX,(DI)1655        MOVQ CX, (DI)
1616        ADDQ        $8,DI1656        ADDQ $8, DI
16171657
1618        MOVQ        (SI),CX1658        MOVQ (SI), CX
1619        ADDQ        $8,SI1659        ADDQ $8, SI
1620        MOVQ        CX,(DI)1660        MOVQ CX, (DI)
1621        ADDQ        $8,DI1661        ADDQ $8, DI
16221662
1623        MOVQ        (SI),CX1663        MOVQ (SI), CX
1624        ADDQ        $8,SI1664        ADDQ $8, SI
1625        MOVQ        CX,(DI)1665        MOVQ CX, (DI)
1626        ADDQ        $8,DI1666        ADDQ $8, DI
16271667
1628        MOVQ        (SI),CX1668        MOVQ (SI), CX
1629        ADDQ        $8,SI1669        ADDQ $8, SI
1630        MOVQ        CX,(DI)1670        MOVQ CX, (DI)
1631        ADDQ        $8,DI1671        ADDQ $8, DI
16321672
1633        MOVQ        (SI),CX1673        MOVQ (SI), CX
1634        ADDQ        $8,SI1674        ADDQ $8, SI
1635        MOVQ        CX,(DI)1675        MOVQ CX, (DI)
1636        ADDQ        $8,DI1676        ADDQ $8, DI
16371677
1638        MOVQ        (SI),CX1678        MOVQ (SI), CX
1639        ADDQ        $8,SI1679        ADDQ $8, SI
1640        MOVQ        CX,(DI)1680        MOVQ CX, (DI)
1641        ADDQ        $8,DI1681        ADDQ $8, DI
16421682
1643        MOVQ        (SI),CX1683        MOVQ (SI), CX
1644        ADDQ        $8,SI1684        ADDQ $8, SI
1645        MOVQ        CX,(DI)1685        MOVQ CX, (DI)
1646        ADDQ        $8,DI1686        ADDQ $8, DI
16471687
1648        MOVQ        (SI),CX1688        MOVQ (SI), CX
1649        ADDQ        $8,SI1689        ADDQ $8, SI
1650        MOVQ        CX,(DI)1690        MOVQ CX, (DI)
1651        ADDQ        $8,DI1691        ADDQ $8, DI
16521692
1653        MOVQ        (SI),CX1693        MOVQ (SI), CX
1654        ADDQ        $8,SI1694        ADDQ $8, SI
1655        MOVQ        CX,(DI)1695        MOVQ CX, (DI)
1656        ADDQ        $8,DI1696        ADDQ $8, DI
16571697
1658        MOVQ        (SI),CX1698        MOVQ (SI), CX
1659        ADDQ        $8,SI1699        ADDQ $8, SI
1660        MOVQ        CX,(DI)1700        MOVQ CX, (DI)
1661        ADDQ        $8,DI1701        ADDQ $8, DI
16621702
1663        MOVQ        (SI),CX1703        MOVQ (SI), CX
1664        ADDQ        $8,SI1704        ADDQ $8, SI
1665        MOVQ        CX,(DI)1705        MOVQ CX, (DI)
1666        ADDQ        $8,DI1706        ADDQ $8, DI
16671707
1668        MOVQ        (SI),CX1708        MOVQ (SI), CX
1669        ADDQ        $8,SI1709        ADDQ $8, SI
1670        MOVQ        CX,(DI)1710        MOVQ CX, (DI)
1671        ADDQ        $8,DI1711        ADDQ $8, DI
16721712
1673        MOVQ        (SI),CX1713        MOVQ (SI), CX
1674        ADDQ        $8,SI1714        ADDQ $8, SI
1675        MOVQ        CX,(DI)1715        MOVQ CX, (DI)
1676        ADDQ        $8,DI1716        ADDQ $8, DI
16771717
1678        MOVQ        (SI),CX1718        MOVQ (SI), CX
1679        ADDQ        $8,SI1719        ADDQ $8, SI
1680        MOVQ        CX,(DI)1720        MOVQ CX, (DI)
1681        ADDQ        $8,DI1721        ADDQ $8, DI
16821722
1683        MOVQ        (SI),CX1723        MOVQ (SI), CX
1684        ADDQ        $8,SI1724        ADDQ $8, SI
1685        MOVQ        CX,(DI)1725        MOVQ CX, (DI)
1686        ADDQ        $8,DI1726        ADDQ $8, DI
16871727
1688        MOVQ        (SI),CX1728        MOVQ (SI), CX
1689        ADDQ        $8,SI1729        ADDQ $8, SI
1690        MOVQ        CX,(DI)1730        MOVQ CX, (DI)
1691        ADDQ        $8,DI1731        ADDQ $8, DI
16921732
1693        MOVQ        (SI),CX1733        MOVQ (SI), CX
1694        ADDQ        $8,SI1734        ADDQ $8, SI
1695        MOVQ        CX,(DI)1735        MOVQ CX, (DI)
1696        ADDQ        $8,DI1736        ADDQ $8, DI
16971737
1698        MOVQ        (SI),CX1738        MOVQ (SI), CX
1699        ADDQ        $8,SI1739        ADDQ $8, SI
1700        MOVQ        CX,(DI)1740        MOVQ CX, (DI)
1701        ADDQ        $8,DI1741        ADDQ $8, DI
17021742
1703        MOVQ        (SI),CX1743        MOVQ (SI), CX
1704        ADDQ        $8,SI1744        ADDQ $8, SI
1705        MOVQ        CX,(DI)1745        MOVQ CX, (DI)
1706        ADDQ        $8,DI1746        ADDQ $8, DI
17071747
1708        MOVQ        (SI),CX1748        MOVQ (SI), CX
1709        ADDQ        $8,SI1749        ADDQ $8, SI
1710        MOVQ        CX,(DI)1750        MOVQ CX, (DI)
1711        ADDQ        $8,DI1751        ADDQ $8, DI
17121752
1713        MOVQ        (SI),CX1753        MOVQ (SI), CX
1714        ADDQ        $8,SI1754        ADDQ $8, SI
1715        MOVQ        CX,(DI)1755        MOVQ CX, (DI)
1716        ADDQ        $8,DI1756        ADDQ $8, DI
17171757
1718        MOVQ        (SI),CX1758        MOVQ (SI), CX
1719        ADDQ        $8,SI1759        ADDQ $8, SI
1720        MOVQ        CX,(DI)1760        MOVQ CX, (DI)
1721        ADDQ        $8,DI1761        ADDQ $8, DI
17221762
1723        MOVQ        (SI),CX1763        MOVQ (SI), CX
1724        ADDQ        $8,SI1764        ADDQ $8, SI
1725        MOVQ        CX,(DI)1765        MOVQ CX, (DI)
1726        ADDQ        $8,DI1766        ADDQ $8, DI
17271767
1728        MOVQ        (SI),CX1768        MOVQ (SI), CX
1729        ADDQ        $8,SI1769        ADDQ $8, SI
1730        MOVQ        CX,(DI)1770        MOVQ CX, (DI)
1731        ADDQ        $8,DI1771        ADDQ $8, DI
17321772
1733        MOVQ        (SI),CX1773        MOVQ (SI), CX
1734        ADDQ        $8,SI1774        ADDQ $8, SI
1735        MOVQ        CX,(DI)1775        MOVQ CX, (DI)
1736        ADDQ        $8,DI1776        ADDQ $8, DI
17371777
1738        MOVQ        (SI),CX1778        MOVQ (SI), CX
1739        ADDQ        $8,SI1779        ADDQ $8, SI
1740        MOVQ        CX,(DI)1780        MOVQ CX, (DI)
1741        ADDQ        $8,DI1781        ADDQ $8, DI
17421782
1743        MOVQ        (SI),CX1783        MOVQ (SI), CX
1744        ADDQ        $8,SI1784        ADDQ $8, SI
1745        MOVQ        CX,(DI)1785        MOVQ CX, (DI)
1746        ADDQ        $8,DI1786        ADDQ $8, DI
17471787
1748        MOVQ        (SI),CX1788        MOVQ (SI), CX
1749        ADDQ        $8,SI1789        ADDQ $8, SI
1750        MOVQ        CX,(DI)1790        MOVQ CX, (DI)
1751        ADDQ        $8,DI1791        ADDQ $8, DI
17521792
1753        MOVQ        (SI),CX1793        MOVQ (SI), CX
1754        ADDQ        $8,SI1794        ADDQ $8, SI
1755        MOVQ        CX,(DI)1795        MOVQ CX, (DI)
1756        ADDQ        $8,DI1796        ADDQ $8, DI
17571797
1758        MOVQ        (SI),CX1798        MOVQ (SI), CX
1759        ADDQ        $8,SI1799        ADDQ $8, SI
1760        MOVQ        CX,(DI)1800        MOVQ CX, (DI)
1761        ADDQ        $8,DI1801        ADDQ $8, DI
17621802
1763        MOVQ        (SI),CX1803        MOVQ (SI), CX
1764        ADDQ        $8,SI1804        ADDQ $8, SI
1765        MOVQ        CX,(DI)1805        MOVQ CX, (DI)
1766        ADDQ        $8,DI1806        ADDQ $8, DI
17671807
1768        MOVQ        (SI),CX1808        MOVQ (SI), CX
1769        ADDQ        $8,SI1809        ADDQ $8, SI
1770        MOVQ        CX,(DI)1810        MOVQ CX, (DI)
1771        ADDQ        $8,DI1811        ADDQ $8, DI
17721812
1773        MOVQ        (SI),CX1813        MOVQ (SI), CX
1774        ADDQ        $8,SI1814        ADDQ $8, SI
1775        MOVQ        CX,(DI)1815        MOVQ CX, (DI)
1776        ADDQ        $8,DI1816        ADDQ $8, DI
17771817
1778        MOVQ        (SI),CX1818        MOVQ (SI), CX
1779        ADDQ        $8,SI1819        ADDQ $8, SI
1780        MOVQ        CX,(DI)1820        MOVQ CX, (DI)
1781        ADDQ        $8,DI1821        ADDQ $8, DI
17821822
1783        MOVQ        (SI),CX1823        MOVQ (SI), CX
1784        ADDQ        $8,SI1824        ADDQ $8, SI
1785        MOVQ        CX,(DI)1825        MOVQ CX, (DI)
1786        ADDQ        $8,DI1826        ADDQ $8, DI
17871827
1788        MOVQ        (SI),CX1828        MOVQ (SI), CX
1789        ADDQ        $8,SI1829        ADDQ $8, SI
1790        MOVQ        CX,(DI)1830        MOVQ CX, (DI)
1791        ADDQ        $8,DI1831        ADDQ $8, DI
17921832
1793        MOVQ        (SI),CX1833        MOVQ (SI), CX
1794        ADDQ        $8,SI1834        ADDQ $8, SI
1795        MOVQ        CX,(DI)1835        MOVQ CX, (DI)
1796        ADDQ        $8,DI1836        ADDQ $8, DI
17971837
1798        MOVQ        (SI),CX1838        MOVQ (SI), CX
1799        ADDQ        $8,SI1839        ADDQ $8, SI
1800        MOVQ        CX,(DI)1840        MOVQ CX, (DI)
1801        ADDQ        $8,DI1841        ADDQ $8, DI
18021842
1803        MOVQ        (SI),CX1843        MOVQ (SI), CX
1804        ADDQ        $8,SI1844        ADDQ $8, SI
1805        MOVQ        CX,(DI)1845        MOVQ CX, (DI)
1806        ADDQ        $8,DI1846        ADDQ $8, DI
18071847
1808        MOVQ        (SI),CX1848        MOVQ (SI), CX
1809        ADDQ        $8,SI1849        ADDQ $8, SI
1810        MOVQ        CX,(DI)1850        MOVQ CX, (DI)
1811        ADDQ        $8,DI1851        ADDQ $8, DI
18121852
1813        MOVQ        (SI),CX1853        MOVQ (SI), CX
1814        ADDQ        $8,SI1854        ADDQ $8, SI
1815        MOVQ        CX,(DI)1855        MOVQ CX, (DI)
1816        ADDQ        $8,DI1856        ADDQ $8, DI
18171857
1818        MOVQ        (SI),CX1858        MOVQ (SI), CX
1819        ADDQ        $8,SI1859        ADDQ $8, SI
1820        MOVQ        CX,(DI)1860        MOVQ CX, (DI)
1821        ADDQ        $8,DI1861        ADDQ $8, DI
18221862
1823        MOVQ        (SI),CX1863        MOVQ (SI), CX
1824        ADDQ        $8,SI1864        ADDQ $8, SI
1825        MOVQ        CX,(DI)1865        MOVQ CX, (DI)
1826        ADDQ        $8,DI1866        ADDQ $8, DI
18271867
1828        MOVQ        (SI),CX1868        MOVQ (SI), CX
1829        ADDQ        $8,SI1869        ADDQ $8, SI
1830        MOVQ        CX,(DI)1870        MOVQ CX, (DI)
1831        ADDQ        $8,DI1871        ADDQ $8, DI
18321872
1833        MOVQ        (SI),CX1873        MOVQ (SI), CX
1834        ADDQ        $8,SI1874        ADDQ $8, SI
1835        MOVQ        CX,(DI)1875        MOVQ CX, (DI)
1836        ADDQ        $8,DI1876        ADDQ $8, DI
18371877
1838        MOVQ        (SI),CX1878        MOVQ (SI), CX
1839        ADDQ        $8,SI1879        ADDQ $8, SI
1840        MOVQ        CX,(DI)1880        MOVQ CX, (DI)
1841        ADDQ        $8,DI1881        ADDQ $8, DI
18421882
1843        MOVQ        (SI),CX1883        MOVQ (SI), CX
1844        ADDQ        $8,SI1884        ADDQ $8, SI
1845        MOVQ        CX,(DI)1885        MOVQ CX, (DI)
1846        ADDQ        $8,DI1886        ADDQ $8, DI
18471887
1848        MOVQ        (SI),CX1888        MOVQ (SI), CX
1849        ADDQ        $8,SI1889        ADDQ $8, SI
1850        MOVQ        CX,(DI)1890        MOVQ CX, (DI)
1851        ADDQ        $8,DI1891        ADDQ $8, DI
18521892
1853        MOVQ        (SI),CX1893        MOVQ (SI), CX
1854        ADDQ        $8,SI1894        ADDQ $8, SI
1855        MOVQ        CX,(DI)1895        MOVQ CX, (DI)
1856        ADDQ        $8,DI1896        ADDQ $8, DI
18571897
1858        MOVQ        (SI),CX1898        MOVQ (SI), CX
1859        ADDQ        $8,SI1899        ADDQ $8, SI
1860        MOVQ        CX,(DI)1900        MOVQ CX, (DI)
1861        ADDQ        $8,DI1901        ADDQ $8, DI
18621902
1863        MOVQ        (SI),CX1903        MOVQ (SI), CX
1864        ADDQ        $8,SI1904        ADDQ $8, SI
1865        MOVQ        CX,(DI)1905        MOVQ CX, (DI)
1866        ADDQ        $8,DI1906        ADDQ $8, DI
18671907
1868        MOVQ        (SI),CX1908        MOVQ (SI), CX
1869        ADDQ        $8,SI1909        ADDQ $8, SI
1870        MOVQ        CX,(DI)1910        MOVQ CX, (DI)
1871        ADDQ        $8,DI1911        ADDQ $8, DI
18721912
1873        MOVQ        (SI),CX1913        MOVQ (SI), CX
1874        ADDQ        $8,SI1914        ADDQ $8, SI
1875        MOVQ        CX,(DI)1915        MOVQ CX, (DI)
1876        ADDQ        $8,DI1916        ADDQ $8, DI
18771917
1878        MOVQ        (SI),CX1918        MOVQ (SI), CX
1879        ADDQ        $8,SI1919        ADDQ $8, SI
1880        MOVQ        CX,(DI)1920        MOVQ CX, (DI)
1881        ADDQ        $8,DI1921        ADDQ $8, DI
18821922
1883        MOVQ        (SI),CX1923        MOVQ (SI), CX
1884        ADDQ        $8,SI1924        ADDQ $8, SI
1885        MOVQ        CX,(DI)1925        MOVQ CX, (DI)
1886        ADDQ        $8,DI1926        ADDQ $8, DI
18871927
1888        MOVQ        (SI),CX1928        MOVQ (SI), CX
1889        ADDQ        $8,SI1929        ADDQ $8, SI
1890        MOVQ        CX,(DI)1930        MOVQ CX, (DI)
1891        ADDQ        $8,DI1931        ADDQ $8, DI
18921932
1893        MOVQ        (SI),CX1933        MOVQ (SI), CX
1894        ADDQ        $8,SI1934        ADDQ $8, SI
1895        MOVQ        CX,(DI)1935        MOVQ CX, (DI)
1896        ADDQ        $8,DI1936        ADDQ $8, DI
18971937
1898        MOVQ        (SI),CX1938        MOVQ (SI), CX
1899        ADDQ        $8,SI1939        ADDQ $8, SI
1900        MOVQ        CX,(DI)1940        MOVQ CX, (DI)
1901        ADDQ        $8,DI1941        ADDQ $8, DI
19021942
1903        MOVQ        (SI),CX1943        MOVQ (SI), CX
1904        ADDQ        $8,SI1944        ADDQ $8, SI
1905        MOVQ        CX,(DI)1945        MOVQ CX, (DI)
1906        ADDQ        $8,DI1946        ADDQ $8, DI
19071947
1908        MOVQ        (SI),CX1948        MOVQ (SI), CX
1909        ADDQ        $8,SI1949        ADDQ $8, SI
1910        MOVQ        CX,(DI)1950        MOVQ CX, (DI)
1911        ADDQ        $8,DI1951        ADDQ $8, DI
19121952
1913        MOVQ        (SI),CX1953        MOVQ (SI), CX
1914        ADDQ        $8,SI1954        ADDQ $8, SI
1915        MOVQ        CX,(DI)1955        MOVQ CX, (DI)
1916        ADDQ        $8,DI1956        ADDQ $8, DI
19171957
1918        MOVQ        (SI),CX1958        MOVQ (SI), CX
1919        ADDQ        $8,SI1959        ADDQ $8, SI
1920        MOVQ        CX,(DI)1960        MOVQ CX, (DI)
1921        ADDQ        $8,DI1961        ADDQ $8, DI
19221962
1923        MOVQ        (SI),CX1963        MOVQ (SI), CX
1924        ADDQ        $8,SI1964        ADDQ $8, SI
1925        MOVQ        CX,(DI)1965        MOVQ CX, (DI)
1926        ADDQ        $8,DI1966        ADDQ $8, DI
19271967
1928        MOVQ        (SI),CX1968        MOVQ (SI), CX
1929        ADDQ        $8,SI1969        ADDQ $8, SI
1930        MOVQ        CX,(DI)1970        MOVQ CX, (DI)
1931        ADDQ        $8,DI1971        ADDQ $8, DI
19321972
1933        MOVQ        (SI),CX1973        MOVQ (SI), CX
1934        ADDQ        $8,SI1974        ADDQ $8, SI
1935        MOVQ        CX,(DI)1975        MOVQ CX, (DI)
1936        ADDQ        $8,DI1976        ADDQ $8, DI
19371977
1938        MOVQ        (SI),CX1978        MOVQ (SI), CX
1939        ADDQ        $8,SI1979        ADDQ $8, SI
1940        MOVQ        CX,(DI)1980        MOVQ CX, (DI)
1941        ADDQ        $8,DI1981        ADDQ $8, DI
19421982
1943        MOVQ        (SI),CX1983        MOVQ (SI), CX
1944        ADDQ        $8,SI1984        ADDQ $8, SI
1945        MOVQ        CX,(DI)1985        MOVQ CX, (DI)
1946        ADDQ        $8,DI1986        ADDQ $8, DI
19471987
1948        MOVQ        (SI),CX1988        MOVQ (SI), CX
1949        ADDQ        $8,SI1989        ADDQ $8, SI
1950        MOVQ        CX,(DI)1990        MOVQ CX, (DI)
1951        ADDQ        $8,DI1991        ADDQ $8, DI
19521992
1953        MOVQ        (SI),CX1993        MOVQ (SI), CX
1954        ADDQ        $8,SI1994        ADDQ $8, SI
1955        MOVQ        CX,(DI)1995        MOVQ CX, (DI)
1956        ADDQ        $8,DI1996        ADDQ $8, DI
19571997
1958        MOVQ        (SI),CX1998        MOVQ (SI), CX
1959        ADDQ        $8,SI1999        ADDQ $8, SI
1960        MOVQ        CX,(DI)2000        MOVQ CX, (DI)
1961        ADDQ        $8,DI2001        ADDQ $8, DI
19622002
1963        MOVQ        (SI),CX2003        MOVQ (SI), CX
1964        ADDQ        $8,SI2004        ADDQ $8, SI
1965        MOVQ        CX,(DI)2005        MOVQ CX, (DI)
1966        ADDQ        $8,DI2006        ADDQ $8, DI
19672007
1968        MOVQ        (SI),CX2008        MOVQ (SI), CX
1969        ADDQ        $8,SI2009        ADDQ $8, SI
1970        MOVQ        CX,(DI)2010        MOVQ CX, (DI)
1971        ADDQ        $8,DI2011        ADDQ $8, DI
19722012
1973        MOVQ        (SI),CX2013        MOVQ (SI), CX
1974        ADDQ        $8,SI2014        ADDQ $8, SI
1975        MOVQ        CX,(DI)2015        MOVQ CX, (DI)
1976        ADDQ        $8,DI2016        ADDQ $8, DI
19772017
1978        MOVQ        (SI),CX2018        MOVQ (SI), CX
1979        ADDQ        $8,SI2019        ADDQ $8, SI
1980        MOVQ        CX,(DI)2020        MOVQ CX, (DI)
1981        ADDQ        $8,DI2021        ADDQ $8, DI
19822022
1983        MOVQ        (SI),CX2023        MOVQ (SI), CX
1984        ADDQ        $8,SI2024        ADDQ $8, SI
1985        MOVQ        CX,(DI)2025        MOVQ CX, (DI)
1986        ADDQ        $8,DI2026        ADDQ $8, DI
19872027
1988        MOVQ        (SI),CX2028        MOVQ (SI), CX
1989        ADDQ        $8,SI2029        ADDQ $8, SI
1990        MOVQ        CX,(DI)2030        MOVQ CX, (DI)
1991        ADDQ        $8,DI2031        ADDQ $8, DI
19922032
1993        MOVQ        (SI),CX2033        MOVQ (SI), CX
1994        ADDQ        $8,SI2034        ADDQ $8, SI
1995        MOVQ        CX,(DI)2035        MOVQ CX, (DI)
1996        ADDQ        $8,DI2036        ADDQ $8, DI
19972037
1998        MOVQ        (SI),CX2038        MOVQ (SI), CX
1999        ADDQ        $8,SI2039        ADDQ $8, SI
2000        MOVQ        CX,(DI)2040        MOVQ CX, (DI)
2001        ADDQ        $8,DI2041        ADDQ $8, DI
20022042
2003        MOVQ        (SI),CX2043        MOVQ (SI), CX
2004        ADDQ        $8,SI2044        ADDQ $8, SI
2005        MOVQ        CX,(DI)2045        MOVQ CX, (DI)
2006        ADDQ        $8,DI2046        ADDQ $8, DI
20072047
2008        MOVQ        (SI),CX2048        MOVQ (SI), CX
2009        ADDQ        $8,SI2049        ADDQ $8, SI
2010        MOVQ        CX,(DI)2050        MOVQ CX, (DI)
2011        ADDQ        $8,DI2051        ADDQ $8, DI
20122052
2013        MOVQ        (SI),CX2053        MOVQ (SI), CX
2014        ADDQ        $8,SI2054        ADDQ $8, SI
2015        MOVQ        CX,(DI)2055        MOVQ CX, (DI)
2016        ADDQ        $8,DI2056        ADDQ $8, DI
20172057
2018        MOVQ        (SI),CX2058        MOVQ (SI), CX
2019        ADDQ        $8,SI2059        ADDQ $8, SI
2020        MOVQ        CX,(DI)2060        MOVQ CX, (DI)
2021        ADDQ        $8,DI2061        ADDQ $8, DI
20222062
2023        MOVQ        (SI),CX2063        MOVQ (SI), CX
2024        ADDQ        $8,SI2064        ADDQ $8, SI
2025        MOVQ        CX,(DI)2065        MOVQ CX, (DI)
2026        ADDQ        $8,DI2066        ADDQ $8, DI
20272067
2028        MOVQ        (SI),CX2068        MOVQ (SI), CX
2029        ADDQ        $8,SI2069        ADDQ $8, SI
2030        MOVQ        CX,(DI)2070        MOVQ CX, (DI)
2031        ADDQ        $8,DI2071        ADDQ $8, DI
20322072
2033        MOVQ        (SI),CX2073        MOVQ (SI), CX
2034        ADDQ        $8,SI2074        ADDQ $8, SI
2035        MOVQ        CX,(DI)2075        MOVQ CX, (DI)
2036        ADDQ        $8,DI2076        ADDQ $8, DI
20372077
2038        MOVQ        (SI),CX2078        MOVQ (SI), CX
2039        ADDQ        $8,SI2079        ADDQ $8, SI
2040        MOVQ        CX,(DI)2080        MOVQ CX, (DI)
2041        ADDQ        $8,DI2081        ADDQ $8, DI
20422082
2043        MOVQ        (SI),CX2083        MOVQ (SI), CX
2044        ADDQ        $8,SI2084        ADDQ $8, SI
2045        MOVQ        CX,(DI)2085        MOVQ CX, (DI)
2046        ADDQ        $8,DI2086        ADDQ $8, DI
20472087
2048        MOVQ        (SI),CX2088        MOVQ (SI), CX
2049        ADDQ        $8,SI2089        ADDQ $8, SI
2050        MOVQ        CX,(DI)2090        MOVQ CX, (DI)
2051        ADDQ        $8,DI2091        ADDQ $8, DI
20522092
2053        MOVQ        (SI),CX2093        MOVQ (SI), CX
2054        ADDQ        $8,SI2094        ADDQ $8, SI
2055        MOVQ        CX,(DI)2095        MOVQ CX, (DI)
2056        ADDQ        $8,DI2096        ADDQ $8, DI
20572097
2058        MOVQ        (SI),CX2098        MOVQ (SI), CX
2059        ADDQ        $8,SI2099        ADDQ $8, SI
2060        MOVQ        CX,(DI)2100        MOVQ CX, (DI)
2061        ADDQ        $8,DI2101        ADDQ $8, DI
20622102
2063        MOVQ        (SI),CX2103        MOVQ (SI), CX
2064        ADDQ        $8,SI2104        ADDQ $8, SI
2065        MOVQ        CX,(DI)2105        MOVQ CX, (DI)
2066        ADDQ        $8,DI2106        ADDQ $8, DI
20672107
2068        MOVQ        (SI),CX2108        MOVQ (SI), CX
2069        ADDQ        $8,SI2109        ADDQ $8, SI
2070        MOVQ        CX,(DI)2110        MOVQ CX, (DI)
2071        ADDQ        $8,DI2111        ADDQ $8, DI
20722112
2073        MOVQ        (SI),CX2113        MOVQ (SI), CX
2074        ADDQ        $8,SI2114        ADDQ $8, SI
2075        MOVQ        CX,(DI)2115        MOVQ CX, (DI)
2076        ADDQ        $8,DI2116        ADDQ $8, DI
20772117
2078        MOVQ        (SI),CX2118        MOVQ (SI), CX
2079        ADDQ        $8,SI2119        ADDQ $8, SI
2080        MOVQ        CX,(DI)2120        MOVQ CX, (DI)
2081        ADDQ        $8,DI2121        ADDQ $8, DI
20822122
2083        MOVQ        (SI),CX2123        MOVQ (SI), CX
2084        ADDQ        $8,SI2124        ADDQ $8, SI
2085        MOVQ        CX,(DI)2125        MOVQ CX, (DI)
2086        ADDQ        $8,DI2126        ADDQ $8, DI
20872127
2088        MOVQ        (SI),CX2128        MOVQ (SI), CX
2089        ADDQ        $8,SI2129        ADDQ $8, SI
2090        MOVQ        CX,(DI)2130        MOVQ CX, (DI)
2091        ADDQ        $8,DI2131        ADDQ $8, DI
20922132
2093        MOVQ        (SI),CX2133        MOVQ (SI), CX
2094        ADDQ        $8,SI2134        ADDQ $8, SI
2095        MOVQ        CX,(DI)2135        MOVQ CX, (DI)
2096        ADDQ        $8,DI2136        ADDQ $8, DI
20972137
2098        MOVQ        (SI),CX2138        MOVQ (SI), CX
2099        ADDQ        $8,SI2139        ADDQ $8, SI
2100        MOVQ        CX,(DI)2140        MOVQ CX, (DI)
2101        ADDQ        $8,DI2141        ADDQ $8, DI
21022142
2103        MOVQ        (SI),CX2143        MOVQ (SI), CX
2104        ADDQ        $8,SI2144        ADDQ $8, SI
2105        MOVQ        CX,(DI)2145        MOVQ CX, (DI)
2106        ADDQ        $8,DI2146        ADDQ $8, DI
21072147
2108        MOVQ        (SI),CX2148        MOVQ (SI), CX
2109        ADDQ        $8,SI2149        ADDQ $8, SI
2110        MOVQ        CX,(DI)2150        MOVQ CX, (DI)
2111        ADDQ        $8,DI2151        ADDQ $8, DI
21122152
2113        MOVQ        (SI),CX2153        MOVQ (SI), CX
2114        ADDQ        $8,SI2154        ADDQ $8, SI
2115        MOVQ        CX,(DI)2155        MOVQ CX, (DI)
2116        ADDQ        $8,DI2156        ADDQ $8, DI
21172157
2118        MOVQ        (SI),CX2158        MOVQ (SI), CX
2119        ADDQ        $8,SI2159        ADDQ $8, SI
2120        MOVQ        CX,(DI)2160        MOVQ CX, (DI)
2121        ADDQ        $8,DI2161        ADDQ $8, DI
21222162
2123        MOVQ        (SI),CX2163        MOVQ (SI), CX
2124        ADDQ        $8,SI2164        ADDQ $8, SI
2125        MOVQ        CX,(DI)2165        MOVQ CX, (DI)
2126        ADDQ        $8,DI2166        ADDQ $8, DI
21272167
2128        MOVQ        (SI),CX2168        MOVQ (SI), CX
2129        ADDQ        $8,SI2169        ADDQ $8, SI
2130        MOVQ        CX,(DI)2170        MOVQ CX, (DI)
2131        ADDQ        $8,DI2171        ADDQ $8, DI
21322172
2133        MOVQ        (SI),CX2173        MOVQ (SI), CX
2134        ADDQ        $8,SI2174        ADDQ $8, SI
2135        MOVQ        CX,(DI)2175        MOVQ CX, (DI)
2136        ADDQ        $8,DI2176        ADDQ $8, DI
21372177
2138        MOVQ        (SI),CX2178        MOVQ (SI), CX
2139        ADDQ        $8,SI2179        ADDQ $8, SI
2140        MOVQ        CX,(DI)2180        MOVQ CX, (DI)
2141        ADDQ        $8,DI2181        ADDQ $8, DI
21422182
2143        MOVQ        (SI),CX2183        MOVQ (SI), CX
2144        ADDQ        $8,SI2184        ADDQ $8, SI
2145        MOVQ        CX,(DI)2185        MOVQ CX, (DI)
2146        ADDQ        $8,DI2186        ADDQ $8, DI
21472187
2148        MOVQ        (SI),CX2188        MOVQ (SI), CX
2149        ADDQ        $8,SI2189        ADDQ $8, SI
2150        MOVQ        CX,(DI)2190        MOVQ CX, (DI)
2151        ADDQ        $8,DI2191        ADDQ $8, DI
21522192
2153        MOVQ        (SI),CX2193        MOVQ (SI), CX
2154        ADDQ        $8,SI2194        ADDQ $8, SI
2155        MOVQ        CX,(DI)2195        MOVQ CX, (DI)
2156        ADDQ        $8,DI2196        ADDQ $8, DI
21572197
2158        MOVQ        (SI),CX2198        MOVQ (SI), CX
2159        ADDQ        $8,SI2199        ADDQ $8, SI
2160        MOVQ        CX,(DI)2200        MOVQ CX, (DI)
2161        ADDQ        $8,DI2201        ADDQ $8, DI
21622202
2163        MOVQ        (SI),CX2203        MOVQ (SI), CX
2164        ADDQ        $8,SI2204        ADDQ $8, SI
2165        MOVQ        CX,(DI)2205        MOVQ CX, (DI)
2166        ADDQ        $8,DI2206        ADDQ $8, DI
21672207
2168        MOVQ        (SI),CX2208        MOVQ (SI), CX
2169        ADDQ        $8,SI2209        ADDQ $8, SI
2170        MOVQ        CX,(DI)2210        MOVQ CX, (DI)
2171        ADDQ        $8,DI2211        ADDQ $8, DI
21722212
2173        MOVQ        (SI),CX2213        MOVQ (SI), CX
2174        ADDQ        $8,SI2214        ADDQ $8, SI
2175        MOVQ        CX,(DI)2215        MOVQ CX, (DI)
2176        ADDQ        $8,DI2216        ADDQ $8, DI
21772217
2178        MOVQ        (SI),CX2218        MOVQ (SI), CX
2179        ADDQ        $8,SI2219        ADDQ $8, SI
2180        MOVQ        CX,(DI)2220        MOVQ CX, (DI)
2181        ADDQ        $8,DI2221        ADDQ $8, DI
21822222
2183        MOVQ        (SI),CX2223        MOVQ (SI), CX
2184        ADDQ        $8,SI2224        ADDQ $8, SI
2185        MOVQ        CX,(DI)2225        MOVQ CX, (DI)
2186        ADDQ        $8,DI2226        ADDQ $8, DI
21872227
2188        MOVQ        (SI),CX2228        MOVQ (SI), CX
2189        ADDQ        $8,SI2229        ADDQ $8, SI
2190        MOVQ        CX,(DI)2230        MOVQ CX, (DI)
2191        ADDQ        $8,DI2231        ADDQ $8, DI
21922232
2193        MOVQ        (SI),CX2233        MOVQ (SI), CX
2194        ADDQ        $8,SI2234        ADDQ $8, SI
2195        MOVQ        CX,(DI)2235        MOVQ CX, (DI)
2196        ADDQ        $8,DI2236        ADDQ $8, DI
21972237
2198        MOVQ        (SI),CX2238        MOVQ (SI), CX
2199        ADDQ        $8,SI2239        ADDQ $8, SI
2200        MOVQ        CX,(DI)2240        MOVQ CX, (DI)
2201        ADDQ        $8,DI2241        ADDQ $8, DI
22022242
2203        RET2243        RET
22042244
2205TEXT runtime·fastrand1(SB), NOSPLIT, $0-42245TEXT runtime·fastrand1(SB), NOSPLIT, $0-4
2206        get_tls(CX)2246        get_tls(CX)
2207        MOVQ        g(CX), AX2247        MOVQ    g(CX), AX
2208        MOVQ        g_m(AX), AX2248        MOVQ    g_m(AX), AX
2209        MOVL        m_fastrand(AX), DX2249        MOVL    m_fastrand(AX), DX
2210        ADDL        DX, DX2250        ADDL    DX, DX
2211        MOVL        DX, BX2251        MOVL    DX, BX
2212        XORL        $0x88888eef, DX2252        XORL    $0x88888eef, DX
2213        CMOVLMI        BX, DX2253        CMOVLMI BX, DX
2214        MOVL        DX, m_fastrand(AX)2254        MOVL    DX, m_fastrand(AX)
2215        MOVL        DX, ret+0(FP)2255        MOVL    DX, ret+0(FP)
2216        RET2256        RET
22172257
2218TEXT runtime·return0(SB), NOSPLIT, $02258TEXT runtime·return0(SB), NOSPLIT, $0
2219        MOVL        $0, AX2259        MOVL $0, AX
2220        RET2260        RET
2221
22222261
2223// Called from cgo wrappers, this function returns g->m->curg.stack.hi.2262// Called from cgo wrappers, this function returns g->m->curg.stack.hi.
2224// Must obey the gcc calling convention.2263// Must obey the gcc calling convention.
2225TEXT _cgo_topofstack(SB),NOSPLIT,$02264TEXT _cgo_topofstack(SB), NOSPLIT, $0
2226        get_tls(CX)2265        get_tls(CX)
2227        MOVQ        g(CX), AX2266        MOVQ g(CX), AX
2228        MOVQ        g_m(AX), AX2267        MOVQ g_m(AX), AX
2229        MOVQ        m_curg(AX), AX2268        MOVQ m_curg(AX), AX
2230        MOVQ        (g_stack+stack_hi)(AX), AX2269        MOVQ (g_stack+stack_hi)(AX), AX
2231        RET2270        RET
22322271
2233// The top-most function running on a goroutine2272// The top-most function running on a goroutine
2234// returns to goexit+PCQuantum.2273// returns to goexit+PCQuantum.
2235TEXT runtime·goexit(SB),NOSPLIT,$0-02274TEXT runtime·goexit(SB), NOSPLIT, $0-0
2236        BYTE        $0x90        // NOP2275        BYTE $0x90               // NOP
2237        CALL        runtime·goexit1(SB)        // does not return2276        CALL runtime·goexit1(SB) // does not return