blob: 0d46a9eff78035a6fca583a0f4b6800c32cabcde [file] [log] [blame]
Russ Cox0d3a0432009-03-30 00:01:07 -07001// Copyright 2009 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
Russ Cox55889402011-12-19 15:51:13 -05005#include "zasm_GOOS_GOARCH.h"
Russ Cox9ddfb642013-07-16 16:24:09 -04006#include "funcdata.h"
Russ Coxcb040d52014-09-04 23:05:18 -04007#include "textflag.h"
Russ Cox8522a472009-06-17 15:15:55 -07008
Russ Cox7ba41e92014-09-03 11:11:16 -04009TEXT runtime·rt0_go(SB),NOSPLIT,$0
Russ Cox0d3a0432009-03-30 00:01:07 -070010 // copy arguments forward on an even stack
Russ Coxdfc22e292013-03-07 19:57:10 -080011 MOVL argc+0(FP), AX
12 MOVL argv+4(FP), BX
Russ Cox0d3a0432009-03-30 00:01:07 -070013 SUBL $128, SP // plenty of scratch
Russ Cox133a1582009-10-03 10:37:12 -070014 ANDL $~15, SP
Russ Cox0d3a0432009-03-30 00:01:07 -070015 MOVL AX, 120(SP) // save argc, argv away
16 MOVL BX, 124(SP)
17
Dmitriy Vyukov428062d2011-12-07 16:53:17 +030018 // set default stack bounds.
Russ Coxf8d49b52013-02-28 16:24:38 -050019 // _cgo_init may update stackguard.
Dmitriy Vyukov428062d2011-12-07 16:53:17 +030020 MOVL $runtime·g0(SB), BP
21 LEAL (-64*1024+104)(SP), BX
Dmitriy Vyukovf5becf42013-06-03 12:28:24 +040022 MOVL BX, g_stackguard0(BP)
Russ Cox15b76ad2014-09-09 13:39:57 -040023 MOVL BX, g_stackguard1(BP)
24 MOVL BX, (g_stack+stack_lo)(BP)
25 MOVL SP, (g_stack+stack_hi)(BP)
Dmitriy Vyukov428062d2011-12-07 16:53:17 +030026
Keith Randalla5d40242013-03-12 10:47:44 -070027 // find out information about the processor we're on
28 MOVL $0, AX
29 CPUID
30 CMPL AX, $0
31 JE nocpuinfo
32 MOVL $1, AX
33 CPUID
34 MOVL CX, runtime·cpuid_ecx(SB)
35 MOVL DX, runtime·cpuid_edx(SB)
36nocpuinfo:
37
Russ Coxf8d49b52013-02-28 16:24:38 -050038 // if there is an _cgo_init, call it to let it
Russ Cox133a1582009-10-03 10:37:12 -070039 // initialize and to set up GS. if not,
40 // we set up GS ourselves.
Russ Coxf8d49b52013-02-28 16:24:38 -050041 MOVL _cgo_init(SB), AX
Russ Cox133a1582009-10-03 10:37:12 -070042 TESTL AX, AX
Dmitriy Vyukovfbfed492011-11-09 23:11:48 +030043 JZ needtls
Russ Cox89f185f2014-06-26 11:54:39 -040044 MOVL $setg_gcc<>(SB), BX
Russ Cox6a70f9d2013-03-25 18:14:02 -040045 MOVL BX, 4(SP)
Russ Cox3b85b722013-03-11 00:51:42 -040046 MOVL BP, 0(SP)
Russ Cox133a1582009-10-03 10:37:12 -070047 CALL AX
Russ Cox15b76ad2014-09-09 13:39:57 -040048
Dmitriy Vyukovf5becf42013-06-03 12:28:24 +040049 // update stackguard after _cgo_init
50 MOVL $runtime·g0(SB), CX
Russ Cox15b76ad2014-09-09 13:39:57 -040051 MOVL (g_stack+stack_lo)(CX), AX
52 ADDL $const_StackGuard, AX
53 MOVL AX, g_stackguard0(CX)
54 MOVL AX, g_stackguard1(CX)
55
Russ Coxf8d49b52013-02-28 16:24:38 -050056 // skip runtime·ldt0setup(SB) and tls test after _cgo_init for non-windows
Wei Guangjing1aa2d882011-01-20 10:22:20 -050057 CMPL runtime·iswindows(SB), $0
58 JEQ ok
Dmitriy Vyukovfbfed492011-11-09 23:11:48 +030059needtls:
Yuval Pavel Zholkover2aa2ceb2011-07-25 12:25:41 -040060 // skip runtime·ldt0setup(SB) and tls test on Plan 9 in all cases
61 CMPL runtime·isplan9(SB), $1
62 JEQ ok
63
Russ Cox1b14bdb2009-09-22 16:28:32 -070064 // set up %gs
Russ Cox68b42552010-11-04 14:00:19 -040065 CALL runtime·ldt0setup(SB)
Russ Cox0d3a0432009-03-30 00:01:07 -070066
Russ Cox0d3a0432009-03-30 00:01:07 -070067 // store through it, to make sure it works
Hector Chu6bfe5f52010-01-06 17:58:55 -080068 get_tls(BX)
69 MOVL $0x123, g(BX)
Russ Cox68b42552010-11-04 14:00:19 -040070 MOVL runtime·tls0(SB), AX
Russ Cox0d3a0432009-03-30 00:01:07 -070071 CMPL AX, $0x123
72 JEQ ok
Russ Cox133a1582009-10-03 10:37:12 -070073 MOVL AX, 0 // abort
Russ Cox0d3a0432009-03-30 00:01:07 -070074ok:
Russ Cox0d3a0432009-03-30 00:01:07 -070075 // set up m and g "registers"
Hector Chu6bfe5f52010-01-06 17:58:55 -080076 get_tls(BX)
Russ Cox68b42552010-11-04 14:00:19 -040077 LEAL runtime·g0(SB), CX
Hector Chu6bfe5f52010-01-06 17:58:55 -080078 MOVL CX, g(BX)
Russ Cox68b42552010-11-04 14:00:19 -040079 LEAL runtime·m0(SB), AX
Russ Cox0d3a0432009-03-30 00:01:07 -070080
81 // save m->g0 = g0
Russ Cox8522a472009-06-17 15:15:55 -070082 MOVL CX, m_g0(AX)
Russ Cox89f185f2014-06-26 11:54:39 -040083 // save g0->m = m0
84 MOVL AX, g_m(CX)
Russ Cox0d3a0432009-03-30 00:01:07 -070085
Russ Cox68b42552010-11-04 14:00:19 -040086 CALL runtime·emptyfunc(SB) // fault if stack check is wrong
Russ Cox0d3a0432009-03-30 00:01:07 -070087
88 // convention is D is always cleared
89 CLD
90
Russ Cox68b42552010-11-04 14:00:19 -040091 CALL runtime·check(SB)
Russ Cox0d3a0432009-03-30 00:01:07 -070092
93 // saved argc, argv
94 MOVL 120(SP), AX
95 MOVL AX, 0(SP)
96 MOVL 124(SP), AX
97 MOVL AX, 4(SP)
Russ Cox68b42552010-11-04 14:00:19 -040098 CALL runtime·args(SB)
99 CALL runtime·osinit(SB)
100 CALL runtime·schedinit(SB)
Russ Cox0d3a0432009-03-30 00:01:07 -0700101
102 // create a new goroutine to start program
Russ Cox1903ad72013-02-21 17:01:13 -0500103 PUSHL $runtime·main·f(SB) // entry
Russ Cox8522a472009-06-17 15:15:55 -0700104 PUSHL $0 // arg size
Russ Cox68b42552010-11-04 14:00:19 -0400105 CALL runtime·newproc(SB)
Russ Cox0d3a0432009-03-30 00:01:07 -0700106 POPL AX
107 POPL AX
108
109 // start this M
Russ Cox68b42552010-11-04 14:00:19 -0400110 CALL runtime·mstart(SB)
Russ Cox0d3a0432009-03-30 00:01:07 -0700111
112 INT $3
113 RET
114
Russ Cox1903ad72013-02-21 17:01:13 -0500115DATA runtime·main·f+0(SB)/4,$runtime·main(SB)
Keith Randall5a546962013-08-07 10:23:24 -0700116GLOBL runtime·main·f(SB),RODATA,$4
Russ Cox1903ad72013-02-21 17:01:13 -0500117
Keith Randall5a546962013-08-07 10:23:24 -0700118TEXT runtime·breakpoint(SB),NOSPLIT,$0-0
Russ Cox1b14bdb2009-09-22 16:28:32 -0700119 INT $3
Russ Cox0d3a0432009-03-30 00:01:07 -0700120 RET
121
Keith Randall5a546962013-08-07 10:23:24 -0700122TEXT runtime·asminit(SB),NOSPLIT,$0-0
Carl Shapiro019c8fc2013-04-02 13:45:56 -0700123 // Linux and MinGW start the FPU in extended double precision.
Russ Cox1707a992012-02-14 01:23:15 -0500124 // Other operating systems use double precision.
125 // Change to double precision to match them,
126 // and to match other hardware that only has double.
127 PUSHL $0x27F
128 FLDCW 0(SP)
129 POPL AX
130 RET
131
Russ Cox8522a472009-06-17 15:15:55 -0700132/*
133 * go-routine
134 */
Russ Cox0d3a0432009-03-30 00:01:07 -0700135
Russ Coxf9ca3b52011-03-07 10:37:42 -0500136// void gosave(Gobuf*)
Russ Cox8522a472009-06-17 15:15:55 -0700137// save state in Gobuf; setjmp
Keith Randall5a546962013-08-07 10:23:24 -0700138TEXT runtime·gosave(SB), NOSPLIT, $0-4
Russ Cox25f6b022014-08-27 11:32:17 -0400139 MOVL buf+0(FP), AX // gobuf
140 LEAL buf+0(FP), BX // caller's SP
Russ Cox8522a472009-06-17 15:15:55 -0700141 MOVL BX, gobuf_sp(AX)
142 MOVL 0(SP), BX // caller's PC
143 MOVL BX, gobuf_pc(AX)
Russ Coxd67e7e32013-06-12 15:22:26 -0400144 MOVL $0, gobuf_ret(AX)
145 MOVL $0, gobuf_ctxt(AX)
Hector Chu6bfe5f52010-01-06 17:58:55 -0800146 get_tls(CX)
147 MOVL g(CX), BX
Russ Cox8522a472009-06-17 15:15:55 -0700148 MOVL BX, gobuf_g(AX)
Russ Cox0d3a0432009-03-30 00:01:07 -0700149 RET
150
Ian Lance Taylor06272482013-06-12 15:05:10 -0700151// void gogo(Gobuf*)
Russ Cox8522a472009-06-17 15:15:55 -0700152// restore state from Gobuf; longjmp
Keith Randall5a546962013-08-07 10:23:24 -0700153TEXT runtime·gogo(SB), NOSPLIT, $0-4
Russ Cox25f6b022014-08-27 11:32:17 -0400154 MOVL buf+0(FP), BX // gobuf
Russ Cox8522a472009-06-17 15:15:55 -0700155 MOVL gobuf_g(BX), DX
156 MOVL 0(DX), CX // make sure g != nil
Hector Chu6bfe5f52010-01-06 17:58:55 -0800157 get_tls(CX)
158 MOVL DX, g(CX)
Russ Cox8522a472009-06-17 15:15:55 -0700159 MOVL gobuf_sp(BX), SP // restore SP
Russ Coxd67e7e32013-06-12 15:22:26 -0400160 MOVL gobuf_ret(BX), AX
161 MOVL gobuf_ctxt(BX), DX
162 MOVL $0, gobuf_sp(BX) // clear to help garbage collector
163 MOVL $0, gobuf_ret(BX)
164 MOVL $0, gobuf_ctxt(BX)
Russ Cox8522a472009-06-17 15:15:55 -0700165 MOVL gobuf_pc(BX), BX
Russ Cox0d3a0432009-03-30 00:01:07 -0700166 JMP BX
Russ Cox8522a472009-06-17 15:15:55 -0700167
Russ Cox012ceed2014-09-03 11:35:22 -0400168// func mcall(fn func(*g))
Russ Coxf9ca3b52011-03-07 10:37:42 -0500169// Switch to m->g0's stack, call fn(g).
Russ Cox370276a2011-04-27 23:21:12 -0400170// Fn must never return. It should gogo(&g->sched)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500171// to keep running g.
Keith Randall5a546962013-08-07 10:23:24 -0700172TEXT runtime·mcall(SB), NOSPLIT, $0-4
Russ Coxf9ca3b52011-03-07 10:37:42 -0500173 MOVL fn+0(FP), DI
174
175 get_tls(CX)
Russ Cox528534c2013-06-05 07:16:53 -0400176 MOVL g(CX), AX // save state in g->sched
Russ Coxf9ca3b52011-03-07 10:37:42 -0500177 MOVL 0(SP), BX // caller's PC
178 MOVL BX, (g_sched+gobuf_pc)(AX)
Russ Cox25f6b022014-08-27 11:32:17 -0400179 LEAL fn+0(FP), BX // caller's SP
Russ Coxf9ca3b52011-03-07 10:37:42 -0500180 MOVL BX, (g_sched+gobuf_sp)(AX)
181 MOVL AX, (g_sched+gobuf_g)(AX)
182
183 // switch to m->g0 & its stack, call fn
Russ Cox89f185f2014-06-26 11:54:39 -0400184 MOVL g(CX), BX
185 MOVL g_m(BX), BX
Russ Coxf9ca3b52011-03-07 10:37:42 -0500186 MOVL m_g0(BX), SI
187 CMPL SI, AX // if g == m->g0 call badmcall
Keith Randall32b770b2013-08-29 15:53:34 -0700188 JNE 3(PC)
189 MOVL $runtime·badmcall(SB), AX
190 JMP AX
Russ Coxf9ca3b52011-03-07 10:37:42 -0500191 MOVL SI, g(CX) // g = m->g0
Russ Cox528534c2013-06-05 07:16:53 -0400192 MOVL (g_sched+gobuf_sp)(SI), SP // sp = m->g0->sched.sp
Russ Coxf9ca3b52011-03-07 10:37:42 -0500193 PUSHL AX
Russ Cox012ceed2014-09-03 11:35:22 -0400194 MOVL DI, DX
195 MOVL 0(DI), DI
Russ Coxf9ca3b52011-03-07 10:37:42 -0500196 CALL DI
197 POPL AX
Keith Randall32b770b2013-08-29 15:53:34 -0700198 MOVL $runtime·badmcall2(SB), AX
199 JMP AX
Russ Coxf9ca3b52011-03-07 10:37:42 -0500200 RET
201
Keith Randall4aa50432014-07-30 09:01:52 -0700202// switchtoM is a dummy routine that onM leaves at the bottom
203// of the G stack. We need to distinguish the routine that
204// lives at the bottom of the G stack from the one that lives
205// at the top of the M stack because the one at the top of
206// the M stack terminates the stack walk (see topofstack()).
Russ Coxe844f532014-09-12 07:46:11 -0400207TEXT runtime·switchtoM(SB), NOSPLIT, $0-0
Keith Randall4aa50432014-07-30 09:01:52 -0700208 RET
209
Russ Cox1d550b82014-09-11 12:08:30 -0400210// func onM_signalok(fn func())
211TEXT runtime·onM_signalok(SB), NOSPLIT, $0-4
212 get_tls(CX)
213 MOVL g(CX), AX // AX = g
214 MOVL g_m(AX), BX // BX = m
215 MOVL m_gsignal(BX), DX // DX = gsignal
216 CMPL AX, DX
217 JEQ ongsignal
218 JMP runtime·onM(SB)
219
220ongsignal:
221 MOVL fn+0(FP), DI // DI = fn
222 MOVL DI, DX
223 MOVL 0(DI), DI
224 CALL DI
225 RET
226
Russ Cox012ceed2014-09-03 11:35:22 -0400227// func onM(fn func())
Keith Randall4aa50432014-07-30 09:01:52 -0700228TEXT runtime·onM(SB), NOSPLIT, $0-4
229 MOVL fn+0(FP), DI // DI = fn
230 get_tls(CX)
231 MOVL g(CX), AX // AX = g
232 MOVL g_m(AX), BX // BX = m
Russ Cox32ecf572014-09-04 00:10:10 -0400233
Keith Randall4aa50432014-07-30 09:01:52 -0700234 MOVL m_g0(BX), DX // DX = g0
235 CMPL AX, DX
236 JEQ onm
237
Russ Cox32ecf572014-09-04 00:10:10 -0400238 MOVL m_curg(BX), BP
239 CMPL AX, BP
240 JEQ oncurg
241
242 // Not g0, not curg. Must be gsignal, but that's not allowed.
243 // Hide call from linker nosplit analysis.
244 MOVL $runtime·badonm(SB), AX
245 CALL AX
246
247oncurg:
Keith Randall4aa50432014-07-30 09:01:52 -0700248 // save our state in g->sched. Pretend to
249 // be switchtoM if the G stack is scanned.
250 MOVL $runtime·switchtoM(SB), (g_sched+gobuf_pc)(AX)
251 MOVL SP, (g_sched+gobuf_sp)(AX)
252 MOVL AX, (g_sched+gobuf_g)(AX)
253
254 // switch to g0
255 MOVL DX, g(CX)
Russ Coxd16a2ad2014-09-04 22:48:08 -0400256 MOVL (g_sched+gobuf_sp)(DX), BX
257 // make it look like mstart called onM on g0, to stop traceback
258 SUBL $4, BX
259 MOVL $runtime·mstart(SB), DX
260 MOVL DX, 0(BX)
261 MOVL BX, SP
Keith Randall4aa50432014-07-30 09:01:52 -0700262
263 // call target function
Russ Cox012ceed2014-09-03 11:35:22 -0400264 MOVL DI, DX
265 MOVL 0(DI), DI
Keith Randall4aa50432014-07-30 09:01:52 -0700266 CALL DI
267
268 // switch back to g
269 get_tls(CX)
270 MOVL g(CX), AX
271 MOVL g_m(AX), BX
272 MOVL m_curg(BX), AX
273 MOVL AX, g(CX)
274 MOVL (g_sched+gobuf_sp)(AX), SP
275 MOVL $0, (g_sched+gobuf_sp)(AX)
276 RET
277
278onm:
279 // already on m stack, just call directly
Russ Cox012ceed2014-09-03 11:35:22 -0400280 MOVL DI, DX
281 MOVL 0(DI), DI
Keith Randall4aa50432014-07-30 09:01:52 -0700282 CALL DI
283 RET
284
Russ Cox8522a472009-06-17 15:15:55 -0700285/*
286 * support for morestack
287 */
288
289// Called during function prolog when more stack is needed.
Russ Cox58f12ff2013-07-18 16:53:45 -0400290//
291// The traceback routines see morestack on a g0 as being
292// the top of a stack (for example, morestack calling newstack
293// calling the scheduler calling newm calling gc), so we must
294// record an argument size. For that purpose, it has no arguments.
Keith Randall5a546962013-08-07 10:23:24 -0700295TEXT runtime·morestack(SB),NOSPLIT,$0-0
Russ Cox8522a472009-06-17 15:15:55 -0700296 // Cannot grow scheduler stack (m->g0).
Hector Chu6bfe5f52010-01-06 17:58:55 -0800297 get_tls(CX)
Russ Cox89f185f2014-06-26 11:54:39 -0400298 MOVL g(CX), BX
299 MOVL g_m(BX), BX
Russ Cox8522a472009-06-17 15:15:55 -0700300 MOVL m_g0(BX), SI
Hector Chu6bfe5f52010-01-06 17:58:55 -0800301 CMPL g(CX), SI
Russ Cox8522a472009-06-17 15:15:55 -0700302 JNE 2(PC)
303 INT $3
304
Russ Coxf8f630f2014-09-05 16:51:45 -0400305 // Cannot grow signal stack.
306 MOVL m_gsignal(BX), SI
307 CMPL g(CX), SI
308 JNE 2(PC)
309 INT $3
310
Russ Cox8522a472009-06-17 15:15:55 -0700311 // Called from f.
312 // Set m->morebuf to f's caller.
313 MOVL 4(SP), DI // f's caller's PC
314 MOVL DI, (m_morebuf+gobuf_pc)(BX)
315 LEAL 8(SP), CX // f's caller's SP
316 MOVL CX, (m_morebuf+gobuf_sp)(BX)
Hector Chu6bfe5f52010-01-06 17:58:55 -0800317 get_tls(CX)
318 MOVL g(CX), SI
Russ Cox8522a472009-06-17 15:15:55 -0700319 MOVL SI, (m_morebuf+gobuf_g)(BX)
320
Russ Cox6fa3c892013-06-27 11:32:01 -0400321 // Set g->sched to context in f.
322 MOVL 0(SP), AX // f's PC
323 MOVL AX, (g_sched+gobuf_pc)(SI)
324 MOVL SI, (g_sched+gobuf_g)(SI)
325 LEAL 4(SP), AX // f's SP
326 MOVL AX, (g_sched+gobuf_sp)(SI)
327 MOVL DX, (g_sched+gobuf_ctxt)(SI)
Russ Cox8522a472009-06-17 15:15:55 -0700328
Russ Coxf9ca3b52011-03-07 10:37:42 -0500329 // Call newstack on m->g0's stack.
Russ Cox8522a472009-06-17 15:15:55 -0700330 MOVL m_g0(BX), BP
Hector Chu6bfe5f52010-01-06 17:58:55 -0800331 MOVL BP, g(CX)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500332 MOVL (g_sched+gobuf_sp)(BP), AX
Russ Cox7e14bd82010-12-07 17:19:36 -0500333 MOVL -4(AX), BX // fault if CALL would, before smashing SP
334 MOVL AX, SP
Russ Cox68b42552010-11-04 14:00:19 -0400335 CALL runtime·newstack(SB)
Russ Cox8522a472009-06-17 15:15:55 -0700336 MOVL $0, 0x1003 // crash if newstack returns
Russ Cox0d3a0432009-03-30 00:01:07 -0700337 RET
338
Russ Coxc2dd33a2014-03-04 13:53:08 -0500339TEXT runtime·morestack_noctxt(SB),NOSPLIT,$0-0
340 MOVL $0, DX
341 JMP runtime·morestack(SB)
342
Keith Randall52631982014-09-08 10:14:41 -0700343// reflectcall: call a function with the given argument list
Russ Cox84736952014-09-06 13:19:08 -0400344// func call(f *FuncVal, arg *byte, argsize, retoffset uint32).
Keith Randall9cd57062013-08-02 13:03:14 -0700345// we don't have variable-sized frames, so we use a small number
346// of constant-sized-frame functions to encode a few bits of size in the pc.
347// Caution: ugly multiline assembly macros in your future!
348
349#define DISPATCH(NAME,MAXSIZE) \
350 CMPL CX, $MAXSIZE; \
351 JA 3(PC); \
Russ Coxf8f630f2014-09-05 16:51:45 -0400352 MOVL $NAME(SB), AX; \
Keith Randall9cd57062013-08-02 13:03:14 -0700353 JMP AX
Rob Pikeaff78832014-07-30 10:11:44 -0700354// Note: can't just "JMP NAME(SB)" - bad inlining results.
Keith Randall9cd57062013-08-02 13:03:14 -0700355
Russ Coxcb6f5ac2014-10-15 13:12:16 -0400356TEXT ·reflectcall(SB), NOSPLIT, $0-16
Keith Randall9cd57062013-08-02 13:03:14 -0700357 MOVL argsize+8(FP), CX
Rob Pikeaff78832014-07-30 10:11:44 -0700358 DISPATCH(runtime·call16, 16)
359 DISPATCH(runtime·call32, 32)
360 DISPATCH(runtime·call64, 64)
361 DISPATCH(runtime·call128, 128)
362 DISPATCH(runtime·call256, 256)
363 DISPATCH(runtime·call512, 512)
364 DISPATCH(runtime·call1024, 1024)
365 DISPATCH(runtime·call2048, 2048)
366 DISPATCH(runtime·call4096, 4096)
367 DISPATCH(runtime·call8192, 8192)
368 DISPATCH(runtime·call16384, 16384)
369 DISPATCH(runtime·call32768, 32768)
370 DISPATCH(runtime·call65536, 65536)
371 DISPATCH(runtime·call131072, 131072)
372 DISPATCH(runtime·call262144, 262144)
373 DISPATCH(runtime·call524288, 524288)
374 DISPATCH(runtime·call1048576, 1048576)
375 DISPATCH(runtime·call2097152, 2097152)
376 DISPATCH(runtime·call4194304, 4194304)
377 DISPATCH(runtime·call8388608, 8388608)
378 DISPATCH(runtime·call16777216, 16777216)
379 DISPATCH(runtime·call33554432, 33554432)
380 DISPATCH(runtime·call67108864, 67108864)
381 DISPATCH(runtime·call134217728, 134217728)
382 DISPATCH(runtime·call268435456, 268435456)
383 DISPATCH(runtime·call536870912, 536870912)
384 DISPATCH(runtime·call1073741824, 1073741824)
Keith Randall9cd57062013-08-02 13:03:14 -0700385 MOVL $runtime·badreflectcall(SB), AX
386 JMP AX
387
Keith Randall12e46e42013-08-06 14:33:55 -0700388#define CALLFN(NAME,MAXSIZE) \
Russ Coxcb6f5ac2014-10-15 13:12:16 -0400389TEXT NAME(SB), WRAPPER, $MAXSIZE-16; \
390 NO_LOCAL_POINTERS; \
Keith Randall9cd57062013-08-02 13:03:14 -0700391 /* copy arguments to stack */ \
392 MOVL argptr+4(FP), SI; \
393 MOVL argsize+8(FP), CX; \
394 MOVL SP, DI; \
395 REP;MOVSB; \
396 /* call function */ \
397 MOVL f+0(FP), DX; \
Russ Cox4a000b92014-02-25 17:00:08 -0500398 MOVL (DX), AX; \
Keith Randallcee8bca2014-05-21 14:28:34 -0700399 PCDATA $PCDATA_StackMapIndex, $0; \
Russ Cox4a000b92014-02-25 17:00:08 -0500400 CALL AX; \
Keith Randall9cd57062013-08-02 13:03:14 -0700401 /* copy return values back */ \
402 MOVL argptr+4(FP), DI; \
403 MOVL argsize+8(FP), CX; \
Russ Cox72c5d5e2014-04-08 11:11:35 -0400404 MOVL retoffset+12(FP), BX; \
Keith Randall9cd57062013-08-02 13:03:14 -0700405 MOVL SP, SI; \
Russ Cox72c5d5e2014-04-08 11:11:35 -0400406 ADDL BX, DI; \
407 ADDL BX, SI; \
408 SUBL BX, CX; \
Keith Randall9cd57062013-08-02 13:03:14 -0700409 REP;MOVSB; \
410 RET
411
Russ Coxcb6f5ac2014-10-15 13:12:16 -0400412CALLFN(·call16, 16)
413CALLFN(·call32, 32)
414CALLFN(·call64, 64)
415CALLFN(·call128, 128)
416CALLFN(·call256, 256)
417CALLFN(·call512, 512)
418CALLFN(·call1024, 1024)
419CALLFN(·call2048, 2048)
420CALLFN(·call4096, 4096)
421CALLFN(·call8192, 8192)
422CALLFN(·call16384, 16384)
423CALLFN(·call32768, 32768)
424CALLFN(·call65536, 65536)
425CALLFN(·call131072, 131072)
426CALLFN(·call262144, 262144)
427CALLFN(·call524288, 524288)
428CALLFN(·call1048576, 1048576)
429CALLFN(·call2097152, 2097152)
430CALLFN(·call4194304, 4194304)
431CALLFN(·call8388608, 8388608)
432CALLFN(·call16777216, 16777216)
433CALLFN(·call33554432, 33554432)
434CALLFN(·call67108864, 67108864)
435CALLFN(·call134217728, 134217728)
436CALLFN(·call268435456, 268435456)
437CALLFN(·call536870912, 536870912)
438CALLFN(·call1073741824, 1073741824)
Russ Coxbba278a2009-07-08 18:16:09 -0700439
Russ Cox0d3a0432009-03-30 00:01:07 -0700440// bool cas(int32 *val, int32 old, int32 new)
441// Atomically:
442// if(*val == old){
443// *val = new;
444// return 1;
445// }else
446// return 0;
Russ Cox25f6b022014-08-27 11:32:17 -0400447TEXT runtime·cas(SB), NOSPLIT, $0-13
448 MOVL ptr+0(FP), BX
449 MOVL old+4(FP), AX
450 MOVL new+8(FP), CX
Russ Cox0d3a0432009-03-30 00:01:07 -0700451 LOCK
452 CMPXCHGL CX, 0(BX)
Russ Cox25f6b022014-08-27 11:32:17 -0400453 JZ 4(PC)
Russ Cox0d3a0432009-03-30 00:01:07 -0700454 MOVL $0, AX
Russ Cox25f6b022014-08-27 11:32:17 -0400455 MOVB AX, ret+12(FP)
Russ Cox0d3a0432009-03-30 00:01:07 -0700456 RET
457 MOVL $1, AX
Russ Cox25f6b022014-08-27 11:32:17 -0400458 MOVB AX, ret+12(FP)
Russ Cox0d3a0432009-03-30 00:01:07 -0700459 RET
460
Russ Coxd21638b2014-08-27 21:59:49 -0400461TEXT runtime·casuintptr(SB), NOSPLIT, $0-13
462 JMP runtime·cas(SB)
463
Russ Cox3a7f6642014-08-29 16:20:48 -0400464TEXT runtime·atomicloaduintptr(SB), NOSPLIT, $0-8
465 JMP runtime·atomicload(SB)
466
Keith Randall47d6af22014-08-30 11:03:28 -0700467TEXT runtime·atomicloaduint(SB), NOSPLIT, $0-8
468 JMP runtime·atomicload(SB)
469
Russ Cox2b1659b2014-10-07 23:27:25 -0400470TEXT runtime·atomicstoreuintptr(SB), NOSPLIT, $0-8
471 JMP runtime·atomicstore(SB)
472
Russ Coxf70a19f2013-07-12 00:42:46 -0400473// bool runtime·cas64(uint64 *val, uint64 old, uint64 new)
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400474// Atomically:
475// if(*val == *old){
476// *val = new;
477// return 1;
478// } else {
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400479// return 0;
480// }
Russ Cox25f6b022014-08-27 11:32:17 -0400481TEXT runtime·cas64(SB), NOSPLIT, $0-21
482 MOVL ptr+0(FP), BP
483 MOVL old_lo+4(FP), AX
484 MOVL old_hi+8(FP), DX
485 MOVL new_lo+12(FP), BX
486 MOVL new_hi+16(FP), CX
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400487 LOCK
488 CMPXCHG8B 0(BP)
489 JNZ cas64_fail
490 MOVL $1, AX
Russ Cox25f6b022014-08-27 11:32:17 -0400491 MOVB AX, ret+20(FP)
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400492 RET
493cas64_fail:
Dmitriy Vyukovfd04f052012-04-05 18:59:50 +0400494 MOVL $0, AX
Russ Cox25f6b022014-08-27 11:32:17 -0400495 MOVB AX, ret+20(FP)
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400496 RET
497
Hector Chu6bfe5f52010-01-06 17:58:55 -0800498// bool casp(void **p, void *old, void *new)
499// Atomically:
500// if(*p == old){
501// *p = new;
502// return 1;
503// }else
504// return 0;
Russ Cox25f6b022014-08-27 11:32:17 -0400505TEXT runtime·casp(SB), NOSPLIT, $0-13
506 MOVL ptr+0(FP), BX
507 MOVL old+4(FP), AX
508 MOVL new+8(FP), CX
Hector Chu6bfe5f52010-01-06 17:58:55 -0800509 LOCK
510 CMPXCHGL CX, 0(BX)
Russ Cox25f6b022014-08-27 11:32:17 -0400511 JZ 4(PC)
Hector Chu6bfe5f52010-01-06 17:58:55 -0800512 MOVL $0, AX
Russ Cox25f6b022014-08-27 11:32:17 -0400513 MOVB AX, ret+12(FP)
Hector Chu6bfe5f52010-01-06 17:58:55 -0800514 RET
515 MOVL $1, AX
Russ Cox25f6b022014-08-27 11:32:17 -0400516 MOVB AX, ret+12(FP)
Hector Chu6bfe5f52010-01-06 17:58:55 -0800517 RET
518
Dmitriy Vyukov491aa152011-07-15 11:27:16 -0400519// uint32 xadd(uint32 volatile *val, int32 delta)
520// Atomically:
521// *val += delta;
522// return *val;
Russ Cox25f6b022014-08-27 11:32:17 -0400523TEXT runtime·xadd(SB), NOSPLIT, $0-12
524 MOVL ptr+0(FP), BX
525 MOVL delta+4(FP), AX
Dmitriy Vyukov491aa152011-07-15 11:27:16 -0400526 MOVL AX, CX
527 LOCK
528 XADDL AX, 0(BX)
529 ADDL CX, AX
Russ Cox25f6b022014-08-27 11:32:17 -0400530 MOVL AX, ret+8(FP)
Dmitriy Vyukov491aa152011-07-15 11:27:16 -0400531 RET
532
Russ Cox25f6b022014-08-27 11:32:17 -0400533TEXT runtime·xchg(SB), NOSPLIT, $0-12
534 MOVL ptr+0(FP), BX
535 MOVL new+4(FP), AX
Dmitriy Vyukov4e5086b2011-07-29 12:44:06 -0400536 XCHGL AX, 0(BX)
Russ Cox25f6b022014-08-27 11:32:17 -0400537 MOVL AX, ret+8(FP)
Dmitriy Vyukov4e5086b2011-07-29 12:44:06 -0400538 RET
539
Russ Cox25f6b022014-08-27 11:32:17 -0400540TEXT runtime·xchgp(SB), NOSPLIT, $0-12
541 MOVL ptr+0(FP), BX
542 MOVL new+4(FP), AX
Dmitriy Vyukov9cbd2fb2014-01-22 11:27:16 +0400543 XCHGL AX, 0(BX)
Russ Cox25f6b022014-08-27 11:32:17 -0400544 MOVL AX, ret+8(FP)
Dmitriy Vyukov9cbd2fb2014-01-22 11:27:16 +0400545 RET
546
Dmitriy Vyukov91a670d2014-09-04 10:04:04 +0400547TEXT runtime·xchguintptr(SB), NOSPLIT, $0-12
548 JMP runtime·xchg(SB)
549
Keith Randall5a546962013-08-07 10:23:24 -0700550TEXT runtime·procyield(SB),NOSPLIT,$0-0
Russ Cox25f6b022014-08-27 11:32:17 -0400551 MOVL cycles+0(FP), AX
Dmitriy Vyukov4e5086b2011-07-29 12:44:06 -0400552again:
553 PAUSE
554 SUBL $1, AX
555 JNZ again
556 RET
557
Keith Randall5a546962013-08-07 10:23:24 -0700558TEXT runtime·atomicstorep(SB), NOSPLIT, $0-8
Russ Cox25f6b022014-08-27 11:32:17 -0400559 MOVL ptr+0(FP), BX
560 MOVL val+4(FP), AX
Dmitriy Vyukov86a659c2011-07-13 11:22:41 -0700561 XCHGL AX, 0(BX)
562 RET
563
Keith Randall5a546962013-08-07 10:23:24 -0700564TEXT runtime·atomicstore(SB), NOSPLIT, $0-8
Russ Cox25f6b022014-08-27 11:32:17 -0400565 MOVL ptr+0(FP), BX
566 MOVL val+4(FP), AX
Dmitriy Vyukov91f0f182011-07-29 13:47:24 -0400567 XCHGL AX, 0(BX)
568 RET
569
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400570// uint64 atomicload64(uint64 volatile* addr);
Russ Cox25f6b022014-08-27 11:32:17 -0400571TEXT runtime·atomicload64(SB), NOSPLIT, $0-12
572 MOVL ptr+0(FP), AX
573 LEAL ret_lo+4(FP), BX
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400574 // MOVQ (%EAX), %MM0
575 BYTE $0x0f; BYTE $0x6f; BYTE $0x00
576 // MOVQ %MM0, 0(%EBX)
577 BYTE $0x0f; BYTE $0x7f; BYTE $0x03
578 // EMMS
579 BYTE $0x0F; BYTE $0x77
580 RET
581
582// void runtime·atomicstore64(uint64 volatile* addr, uint64 v);
Keith Randall5a546962013-08-07 10:23:24 -0700583TEXT runtime·atomicstore64(SB), NOSPLIT, $0-12
Russ Cox25f6b022014-08-27 11:32:17 -0400584 MOVL ptr+0(FP), AX
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400585 // MOVQ and EMMS were introduced on the Pentium MMX.
586 // MOVQ 0x8(%ESP), %MM0
587 BYTE $0x0f; BYTE $0x6f; BYTE $0x44; BYTE $0x24; BYTE $0x08
588 // MOVQ %MM0, (%EAX)
589 BYTE $0x0f; BYTE $0x7f; BYTE $0x00
590 // EMMS
591 BYTE $0x0F; BYTE $0x77
592 // This is essentially a no-op, but it provides required memory fencing.
593 // It can be replaced with MFENCE, but MFENCE was introduced only on the Pentium4 (SSE2).
594 MOVL $0, AX
595 LOCK
596 XADDL AX, (SP)
597 RET
598
Dmitriy Vyukovff3fa1b2014-08-19 17:38:00 +0400599// void runtime·atomicor8(byte volatile*, byte);
Russ Cox25f6b022014-08-27 11:32:17 -0400600TEXT runtime·atomicor8(SB), NOSPLIT, $0-5
Dmitriy Vyukovff3fa1b2014-08-19 17:38:00 +0400601 MOVL ptr+0(FP), AX
602 MOVB val+4(FP), BX
603 LOCK
604 ORB BX, (AX)
605 RET
606
Russ Coxaa3222d82009-06-02 23:02:12 -0700607// void jmpdefer(fn, sp);
608// called from deferreturn.
Russ Cox0d3a0432009-03-30 00:01:07 -0700609// 1. pop the caller
610// 2. sub 5 bytes from the callers return
611// 3. jmp to the argument
Keith Randalla97a91d2013-08-07 14:03:50 -0700612TEXT runtime·jmpdefer(SB), NOSPLIT, $0-8
Russ Cox25f6b022014-08-27 11:32:17 -0400613 MOVL fv+0(FP), DX // fn
614 MOVL argp+4(FP), BX // caller sp
Russ Coxaa3222d82009-06-02 23:02:12 -0700615 LEAL -4(BX), SP // caller sp after CALL
616 SUBL $5, (SP) // return to CALL again
Russ Cox6066fdc2013-02-22 10:47:54 -0500617 MOVL 0(DX), BX
Russ Cox1903ad72013-02-21 17:01:13 -0500618 JMP BX // but first run the deferred function
Russ Cox0d3a0432009-03-30 00:01:07 -0700619
Russ Coxd67e7e32013-06-12 15:22:26 -0400620// Save state of caller into g->sched.
Keith Randall5a546962013-08-07 10:23:24 -0700621TEXT gosave<>(SB),NOSPLIT,$0
Russ Coxd67e7e32013-06-12 15:22:26 -0400622 PUSHL AX
623 PUSHL BX
624 get_tls(BX)
625 MOVL g(BX), BX
626 LEAL arg+0(FP), AX
627 MOVL AX, (g_sched+gobuf_sp)(BX)
628 MOVL -4(AX), AX
629 MOVL AX, (g_sched+gobuf_pc)(BX)
630 MOVL $0, (g_sched+gobuf_ret)(BX)
631 MOVL $0, (g_sched+gobuf_ctxt)(BX)
632 POPL BX
633 POPL AX
Russ Coxf9ca3b52011-03-07 10:37:42 -0500634 RET
635
636// asmcgocall(void(*fn)(void*), void *arg)
637// Call fn(arg) on the scheduler stack,
638// aligned appropriately for the gcc ABI.
639// See cgocall.c for more details.
Russ Cox653fb6d2014-09-16 17:39:55 -0400640TEXT ·asmcgocall(SB),NOSPLIT,$0-8
Russ Cox54138e12014-09-03 11:36:14 -0400641 MOVL fn+0(FP), AX
642 MOVL arg+4(FP), BX
Russ Coxcb767242014-09-04 00:01:55 -0400643 CALL asmcgocall<>(SB)
Russ Cox54138e12014-09-03 11:36:14 -0400644 RET
645
Russ Cox653fb6d2014-09-16 17:39:55 -0400646TEXT ·asmcgocall_errno(SB),NOSPLIT,$0-12
Russ Coxf9ca3b52011-03-07 10:37:42 -0500647 MOVL fn+0(FP), AX
648 MOVL arg+4(FP), BX
Russ Coxcb767242014-09-04 00:01:55 -0400649 CALL asmcgocall<>(SB)
650 MOVL AX, ret+8(FP)
651 RET
652
Russ Cox40dd6bf2014-09-14 13:57:28 -0400653TEXT asmcgocall<>(SB),NOSPLIT,$0-0
Russ Coxcb767242014-09-04 00:01:55 -0400654 // fn in AX, arg in BX
Russ Coxf9ca3b52011-03-07 10:37:42 -0500655 MOVL SP, DX
656
657 // Figure out if we need to switch to m->g0 stack.
658 // We get called to create new OS threads too, and those
659 // come in on the m->g0 stack already.
660 get_tls(CX)
Russ Cox89f185f2014-06-26 11:54:39 -0400661 MOVL g(CX), BP
662 MOVL g_m(BP), BP
Russ Coxf9ca3b52011-03-07 10:37:42 -0500663 MOVL m_g0(BP), SI
664 MOVL g(CX), DI
665 CMPL SI, DI
Russ Coxd67e7e32013-06-12 15:22:26 -0400666 JEQ 4(PC)
667 CALL gosave<>(SB)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500668 MOVL SI, g(CX)
669 MOVL (g_sched+gobuf_sp)(SI), SP
670
671 // Now on a scheduling stack (a pthread-created stack).
672 SUBL $32, SP
673 ANDL $~15, SP // alignment, perhaps unnecessary
674 MOVL DI, 8(SP) // save g
Keith Randall47f251c2014-09-11 20:36:23 -0700675 MOVL (g_stack+stack_hi)(DI), DI
676 SUBL DX, DI
677 MOVL DI, 4(SP) // save depth in stack (can't just save SP, as stack might be copied during a callback)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500678 MOVL BX, 0(SP) // first argument in x86-32 ABI
679 CALL AX
680
681 // Restore registers, g, stack pointer.
682 get_tls(CX)
683 MOVL 8(SP), DI
Keith Randall47f251c2014-09-11 20:36:23 -0700684 MOVL (g_stack+stack_hi)(DI), SI
685 SUBL 4(SP), SI
Russ Coxf9ca3b52011-03-07 10:37:42 -0500686 MOVL DI, g(CX)
Keith Randall47f251c2014-09-11 20:36:23 -0700687 MOVL SI, SP
Russ Coxf9ca3b52011-03-07 10:37:42 -0500688 RET
689
690// cgocallback(void (*fn)(void*), void *frame, uintptr framesize)
Russ Cox3d2dfc52013-02-22 16:08:56 -0500691// Turn the fn into a Go func (by taking its address) and call
692// cgocallback_gofunc.
Keith Randall5a546962013-08-07 10:23:24 -0700693TEXT runtime·cgocallback(SB),NOSPLIT,$12-12
Russ Cox3d2dfc52013-02-22 16:08:56 -0500694 LEAL fn+0(FP), AX
695 MOVL AX, 0(SP)
696 MOVL frame+4(FP), AX
697 MOVL AX, 4(SP)
698 MOVL framesize+8(FP), AX
699 MOVL AX, 8(SP)
700 MOVL $runtime·cgocallback_gofunc(SB), AX
701 CALL AX
702 RET
703
704// cgocallback_gofunc(FuncVal*, void *frame, uintptr framesize)
705// See cgocall.c for more details.
Russ Cox653fb6d2014-09-16 17:39:55 -0400706TEXT ·cgocallback_gofunc(SB),NOSPLIT,$12-12
Russ Coxe844f532014-09-12 07:46:11 -0400707 NO_LOCAL_POINTERS
708
Russ Cox89f185f2014-06-26 11:54:39 -0400709 // If g is nil, Go did not create the current thread.
Russ Cox6c976392013-02-20 17:48:23 -0500710 // Call needm to obtain one for temporary use.
711 // In this case, we're running on the thread stack, so there's
712 // lots of space, but the linker doesn't know. Hide the call from
713 // the linker analysis by using an indirect call through AX.
714 get_tls(CX)
715#ifdef GOOS_windows
Russ Coxdba623b2013-07-23 18:40:02 -0400716 MOVL $0, BP
Russ Cox6c976392013-02-20 17:48:23 -0500717 CMPL CX, $0
Russ Cox89f185f2014-06-26 11:54:39 -0400718 JEQ 2(PC) // TODO
Russ Cox6c976392013-02-20 17:48:23 -0500719#endif
Russ Cox89f185f2014-06-26 11:54:39 -0400720 MOVL g(CX), BP
Russ Cox6c976392013-02-20 17:48:23 -0500721 CMPL BP, $0
Russ Cox89f185f2014-06-26 11:54:39 -0400722 JEQ needm
723 MOVL g_m(BP), BP
724 MOVL BP, DX // saved copy of oldm
725 JMP havem
Russ Cox6c976392013-02-20 17:48:23 -0500726needm:
Russ Cox89f185f2014-06-26 11:54:39 -0400727 MOVL $0, 0(SP)
Russ Cox6c976392013-02-20 17:48:23 -0500728 MOVL $runtime·needm(SB), AX
729 CALL AX
Russ Coxf0112822013-07-24 09:01:57 -0400730 MOVL 0(SP), DX
Russ Coxf9ca3b52011-03-07 10:37:42 -0500731 get_tls(CX)
Russ Cox89f185f2014-06-26 11:54:39 -0400732 MOVL g(CX), BP
733 MOVL g_m(BP), BP
Russ Cox9b732382012-03-08 12:12:40 -0500734
Russ Coxc4efaac2014-10-28 21:53:09 -0400735 // Set m->sched.sp = SP, so that if a panic happens
736 // during the function we are about to execute, it will
737 // have a valid SP to run on the g0 stack.
738 // The next few lines (after the havem label)
739 // will save this SP onto the stack and then write
740 // the same SP back to m->sched.sp. That seems redundant,
741 // but if an unrecovered panic happens, unwindm will
742 // restore the g->sched.sp from the stack location
743 // and then onM will try to use it. If we don't set it here,
744 // that restored SP will be uninitialized (typically 0) and
745 // will not be usable.
746 MOVL m_g0(BP), SI
747 MOVL SP, (g_sched+gobuf_sp)(SI)
748
Russ Cox6c976392013-02-20 17:48:23 -0500749havem:
750 // Now there's a valid m, and we're running on its m->g0.
751 // Save current m->g0->sched.sp on stack and then set it to SP.
752 // Save current sp in m->g0->sched.sp in preparation for
753 // switch back to m->curg stack.
Russ Coxdba623b2013-07-23 18:40:02 -0400754 // NOTE: unwindm knows that the saved g->sched.sp is at 0(SP).
Russ Coxf9ca3b52011-03-07 10:37:42 -0500755 MOVL m_g0(BP), SI
Russ Coxdba623b2013-07-23 18:40:02 -0400756 MOVL (g_sched+gobuf_sp)(SI), AX
757 MOVL AX, 0(SP)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500758 MOVL SP, (g_sched+gobuf_sp)(SI)
759
Russ Coxdba623b2013-07-23 18:40:02 -0400760 // Switch to m->curg stack and call runtime.cgocallbackg.
761 // Because we are taking over the execution of m->curg
762 // but *not* resuming what had been running, we need to
763 // save that information (m->curg->sched) so we can restore it.
Russ Cox528534c2013-06-05 07:16:53 -0400764 // We can restore m->curg->sched.sp easily, because calling
Alex Brainman72e83482011-08-18 12:17:09 -0400765 // runtime.cgocallbackg leaves SP unchanged upon return.
Russ Cox528534c2013-06-05 07:16:53 -0400766 // To save m->curg->sched.pc, we push it onto the stack.
Russ Coxf9ca3b52011-03-07 10:37:42 -0500767 // This has the added benefit that it looks to the traceback
Alex Brainman72e83482011-08-18 12:17:09 -0400768 // routine like cgocallbackg is going to return to that
Russ Coxdba623b2013-07-23 18:40:02 -0400769 // PC (because the frame we allocate below has the same
770 // size as cgocallback_gofunc's frame declared above)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500771 // so that the traceback will seamlessly trace back into
772 // the earlier calls.
Russ Coxdba623b2013-07-23 18:40:02 -0400773 //
Russ Coxf0112822013-07-24 09:01:57 -0400774 // In the new goroutine, 0(SP) holds the saved oldm (DX) register.
775 // 4(SP) and 8(SP) are unused.
Russ Coxf9ca3b52011-03-07 10:37:42 -0500776 MOVL m_curg(BP), SI
777 MOVL SI, g(CX)
Russ Coxdba623b2013-07-23 18:40:02 -0400778 MOVL (g_sched+gobuf_sp)(SI), DI // prepare stack as DI
Russ Coxf9ca3b52011-03-07 10:37:42 -0500779 MOVL (g_sched+gobuf_pc)(SI), BP
Russ Coxdba623b2013-07-23 18:40:02 -0400780 MOVL BP, -4(DI)
Russ Coxf0112822013-07-24 09:01:57 -0400781 LEAL -(4+12)(DI), SP
782 MOVL DX, 0(SP)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500783 CALL runtime·cgocallbackg(SB)
Russ Coxf0112822013-07-24 09:01:57 -0400784 MOVL 0(SP), DX
Russ Coxf9ca3b52011-03-07 10:37:42 -0500785
Russ Cox528534c2013-06-05 07:16:53 -0400786 // Restore g->sched (== m->curg->sched) from saved values.
Russ Coxf9ca3b52011-03-07 10:37:42 -0500787 get_tls(CX)
788 MOVL g(CX), SI
Russ Coxf0112822013-07-24 09:01:57 -0400789 MOVL 12(SP), BP
Russ Coxf9ca3b52011-03-07 10:37:42 -0500790 MOVL BP, (g_sched+gobuf_pc)(SI)
Russ Coxf0112822013-07-24 09:01:57 -0400791 LEAL (12+4)(SP), DI
Russ Coxf9ca3b52011-03-07 10:37:42 -0500792 MOVL DI, (g_sched+gobuf_sp)(SI)
793
794 // Switch back to m->g0's stack and restore m->g0->sched.sp.
795 // (Unlike m->curg, the g0 goroutine never uses sched.pc,
796 // so we do not have to restore it.)
Russ Cox89f185f2014-06-26 11:54:39 -0400797 MOVL g(CX), BP
798 MOVL g_m(BP), BP
Russ Coxf9ca3b52011-03-07 10:37:42 -0500799 MOVL m_g0(BP), SI
800 MOVL SI, g(CX)
801 MOVL (g_sched+gobuf_sp)(SI), SP
Russ Coxdba623b2013-07-23 18:40:02 -0400802 MOVL 0(SP), AX
803 MOVL AX, (g_sched+gobuf_sp)(SI)
Russ Cox6c976392013-02-20 17:48:23 -0500804
805 // If the m on entry was nil, we called needm above to borrow an m
806 // for the duration of the call. Since the call is over, return it with dropm.
Russ Coxf0112822013-07-24 09:01:57 -0400807 CMPL DX, $0
Russ Cox6c976392013-02-20 17:48:23 -0500808 JNE 3(PC)
809 MOVL $runtime·dropm(SB), AX
810 CALL AX
Russ Coxf9ca3b52011-03-07 10:37:42 -0500811
812 // Done!
813 RET
814
Russ Cox89f185f2014-06-26 11:54:39 -0400815// void setg(G*); set g. for use by needm.
Russ Cox25f6b022014-08-27 11:32:17 -0400816TEXT runtime·setg(SB), NOSPLIT, $0-4
Russ Cox89f185f2014-06-26 11:54:39 -0400817 MOVL gg+0(FP), BX
Russ Cox6c976392013-02-20 17:48:23 -0500818#ifdef GOOS_windows
Russ Cox89f185f2014-06-26 11:54:39 -0400819 CMPL BX, $0
Russ Cox6c976392013-02-20 17:48:23 -0500820 JNE settls
821 MOVL $0, 0x14(FS)
822 RET
823settls:
Russ Cox89f185f2014-06-26 11:54:39 -0400824 MOVL g_m(BX), AX
Russ Cox6c976392013-02-20 17:48:23 -0500825 LEAL m_tls(AX), AX
826 MOVL AX, 0x14(FS)
827#endif
Russ Cox6c976392013-02-20 17:48:23 -0500828 get_tls(CX)
Russ Cox6c976392013-02-20 17:48:23 -0500829 MOVL BX, g(CX)
830 RET
831
Russ Cox89f185f2014-06-26 11:54:39 -0400832// void setg_gcc(G*); set g. for use by gcc
833TEXT setg_gcc<>(SB), NOSPLIT, $0
Russ Cox6a70f9d2013-03-25 18:14:02 -0400834 get_tls(AX)
Russ Cox89f185f2014-06-26 11:54:39 -0400835 MOVL gg+0(FP), DX
836 MOVL DX, g(AX)
Russ Cox6a70f9d2013-03-25 18:14:02 -0400837 RET
838
Russ Cox8ac35be2014-09-09 14:02:37 -0400839// check that SP is in range [g->stack.lo, g->stack.hi)
Keith Randall5a546962013-08-07 10:23:24 -0700840TEXT runtime·stackcheck(SB), NOSPLIT, $0-0
Russ Coxf9ca3b52011-03-07 10:37:42 -0500841 get_tls(CX)
842 MOVL g(CX), AX
Russ Cox15b76ad2014-09-09 13:39:57 -0400843 CMPL (g_stack+stack_hi)(AX), SP
Russ Coxf9ca3b52011-03-07 10:37:42 -0500844 JHI 2(PC)
845 INT $3
Russ Cox15b76ad2014-09-09 13:39:57 -0400846 CMPL SP, (g_stack+stack_lo)(AX)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500847 JHI 2(PC)
848 INT $3
849 RET
850
Russ Cox25f6b022014-08-27 11:32:17 -0400851TEXT runtime·getcallerpc(SB),NOSPLIT,$0-8
852 MOVL argp+0(FP),AX // addr of first arg
Russ Cox0d3a0432009-03-30 00:01:07 -0700853 MOVL -4(AX),AX // get calling pc
Russ Cox25f6b022014-08-27 11:32:17 -0400854 MOVL AX, ret+4(FP)
Russ Cox0d3a0432009-03-30 00:01:07 -0700855 RET
856
Keith Randall61dca942014-06-16 23:03:03 -0700857TEXT runtime·gogetcallerpc(SB),NOSPLIT,$0-8
Keith Randall14c81432014-06-17 21:59:50 -0700858 MOVL p+0(FP),AX // addr of first arg
Keith Randall61dca942014-06-16 23:03:03 -0700859 MOVL -4(AX),AX // get calling pc
Keith Randall14c81432014-06-17 21:59:50 -0700860 MOVL AX, ret+4(FP)
Keith Randall61dca942014-06-16 23:03:03 -0700861 RET
862
Keith Randall5a546962013-08-07 10:23:24 -0700863TEXT runtime·setcallerpc(SB),NOSPLIT,$0-8
Russ Cox25f6b022014-08-27 11:32:17 -0400864 MOVL argp+0(FP),AX // addr of first arg
865 MOVL pc+4(FP), BX
Russ Cox0d3a0432009-03-30 00:01:07 -0700866 MOVL BX, -4(AX) // set calling pc
867 RET
868
Russ Cox25f6b022014-08-27 11:32:17 -0400869TEXT runtime·getcallersp(SB), NOSPLIT, $0-8
870 MOVL argp+0(FP), AX
871 MOVL AX, ret+4(FP)
Russ Cox6c196012010-04-05 12:51:09 -0700872 RET
873
Rémy Oudompheng39ffa8b2014-08-26 08:34:46 +0200874// func gogetcallersp(p unsafe.Pointer) uintptr
875TEXT runtime·gogetcallersp(SB),NOSPLIT,$0-8
876 MOVL p+0(FP),AX // addr of first arg
877 MOVL AX, ret+4(FP)
878 RET
879
Damian Gryski8e765da2012-02-02 14:09:27 -0500880// int64 runtime·cputicks(void), so really
881// void runtime·cputicks(int64 *ticks)
Russ Cox25f6b022014-08-27 11:32:17 -0400882TEXT runtime·cputicks(SB),NOSPLIT,$0-8
Shenghou Ma6392b432012-02-06 12:49:28 -0500883 RDTSC
Russ Cox25f6b022014-08-27 11:32:17 -0400884 MOVL AX, ret_lo+0(FP)
885 MOVL DX, ret_hi+4(FP)
Damian Gryski8e765da2012-02-02 14:09:27 -0500886 RET
887
Keith Randall5a546962013-08-07 10:23:24 -0700888TEXT runtime·ldt0setup(SB),NOSPLIT,$16-0
Russ Cox0d3a0432009-03-30 00:01:07 -0700889 // set up ldt 7 to point at tls0
890 // ldt 1 would be fine on Linux, but on OS X, 7 is as low as we can go.
Russ Cox1b14bdb2009-09-22 16:28:32 -0700891 // the entry number is just a hint. setldt will set up GS with what it used.
Russ Cox0d3a0432009-03-30 00:01:07 -0700892 MOVL $7, 0(SP)
Russ Cox68b42552010-11-04 14:00:19 -0400893 LEAL runtime·tls0(SB), AX
Russ Cox0d3a0432009-03-30 00:01:07 -0700894 MOVL AX, 4(SP)
895 MOVL $32, 8(SP) // sizeof(tls array)
Russ Cox68b42552010-11-04 14:00:19 -0400896 CALL runtime·setldt(SB)
Russ Cox0d3a0432009-03-30 00:01:07 -0700897 RET
898
Russ Cox9ddfb642013-07-16 16:24:09 -0400899TEXT runtime·emptyfunc(SB),0,$0-0
Russ Cox0d3a0432009-03-30 00:01:07 -0700900 RET
901
Keith Randall5a546962013-08-07 10:23:24 -0700902TEXT runtime·abort(SB),NOSPLIT,$0-0
Russ Cox0d3a0432009-03-30 00:01:07 -0700903 INT $0x3
Russ Cox133a1582009-10-03 10:37:12 -0700904
Keith Randalla5d40242013-03-12 10:47:44 -0700905// hash function using AES hardware instructions
Keith Randalla2a97682014-07-31 15:07:05 -0700906TEXT runtime·aeshash(SB),NOSPLIT,$0-16
907 MOVL p+0(FP), AX // ptr to data
908 MOVL s+4(FP), CX // size
Keith Randalla5d40242013-03-12 10:47:44 -0700909 JMP runtime·aeshashbody(SB)
910
Keith Randalla2a97682014-07-31 15:07:05 -0700911TEXT runtime·aeshashstr(SB),NOSPLIT,$0-16
912 MOVL p+0(FP), AX // ptr to string object
913 // s+4(FP) is ignored, it is always sizeof(String)
Keith Randalla5d40242013-03-12 10:47:44 -0700914 MOVL 4(AX), CX // length of string
915 MOVL (AX), AX // string data
916 JMP runtime·aeshashbody(SB)
917
918// AX: data
919// CX: length
Keith Randalla2a97682014-07-31 15:07:05 -0700920TEXT runtime·aeshashbody(SB),NOSPLIT,$0-16
921 MOVL h+8(FP), X0 // seed to low 32 bits of xmm0
Keith Randalla5d40242013-03-12 10:47:44 -0700922 PINSRD $1, CX, X0 // size to next 32 bits of xmm0
Keith Randalldb53d972013-03-20 14:34:26 -0700923 MOVO runtime·aeskeysched+0(SB), X2
924 MOVO runtime·aeskeysched+16(SB), X3
Keith Randallee669722013-05-15 09:40:14 -0700925 CMPL CX, $16
926 JB aessmall
Keith Randalla5d40242013-03-12 10:47:44 -0700927aesloop:
928 CMPL CX, $16
Keith Randallee669722013-05-15 09:40:14 -0700929 JBE aesloopend
Keith Randalla5d40242013-03-12 10:47:44 -0700930 MOVOU (AX), X1
931 AESENC X2, X0
932 AESENC X1, X0
933 SUBL $16, CX
934 ADDL $16, AX
935 JMP aesloop
Keith Randallee669722013-05-15 09:40:14 -0700936// 1-16 bytes remaining
Keith Randalla5d40242013-03-12 10:47:44 -0700937aesloopend:
Keith Randallee669722013-05-15 09:40:14 -0700938 // This load may overlap with the previous load above.
939 // We'll hash some bytes twice, but that's ok.
940 MOVOU -16(AX)(CX*1), X1
941 JMP partial
942// 0-15 bytes
943aessmall:
Keith Randalla5d40242013-03-12 10:47:44 -0700944 TESTL CX, CX
Keith Randallee669722013-05-15 09:40:14 -0700945 JE finalize // 0 bytes
Keith Randalla5d40242013-03-12 10:47:44 -0700946
Keith Randallee669722013-05-15 09:40:14 -0700947 CMPB AX, $0xf0
948 JA highpartial
Keith Randalla5d40242013-03-12 10:47:44 -0700949
Keith Randallee669722013-05-15 09:40:14 -0700950 // 16 bytes loaded at this address won't cross
951 // a page boundary, so we can load it directly.
Keith Randalla5d40242013-03-12 10:47:44 -0700952 MOVOU (AX), X1
953 ADDL CX, CX
Russ Cox9ddfb642013-07-16 16:24:09 -0400954 PAND masks<>(SB)(CX*8), X1
Keith Randalla5d40242013-03-12 10:47:44 -0700955 JMP partial
956highpartial:
Keith Randallee669722013-05-15 09:40:14 -0700957 // address ends in 1111xxxx. Might be up against
Keith Randalla5d40242013-03-12 10:47:44 -0700958 // a page boundary, so load ending at last byte.
959 // Then shift bytes down using pshufb.
960 MOVOU -16(AX)(CX*1), X1
961 ADDL CX, CX
Russ Cox9ddfb642013-07-16 16:24:09 -0400962 PSHUFB shifts<>(SB)(CX*8), X1
Keith Randalla5d40242013-03-12 10:47:44 -0700963partial:
964 // incorporate partial block into hash
965 AESENC X3, X0
966 AESENC X1, X0
967finalize:
968 // finalize hash
969 AESENC X2, X0
970 AESENC X3, X0
971 AESENC X2, X0
Russ Cox25f6b022014-08-27 11:32:17 -0400972 MOVL X0, ret+12(FP)
Keith Randalla5d40242013-03-12 10:47:44 -0700973 RET
974
Keith Randalla2a97682014-07-31 15:07:05 -0700975TEXT runtime·aeshash32(SB),NOSPLIT,$0-16
976 MOVL p+0(FP), AX // ptr to data
977 // s+4(FP) is ignored, it is always sizeof(int32)
978 MOVL h+8(FP), X0 // seed
Keith Randalla5d40242013-03-12 10:47:44 -0700979 PINSRD $1, (AX), X0 // data
Keith Randalldb53d972013-03-20 14:34:26 -0700980 AESENC runtime·aeskeysched+0(SB), X0
981 AESENC runtime·aeskeysched+16(SB), X0
982 AESENC runtime·aeskeysched+0(SB), X0
Russ Cox25f6b022014-08-27 11:32:17 -0400983 MOVL X0, ret+12(FP)
Keith Randalla5d40242013-03-12 10:47:44 -0700984 RET
985
Keith Randalla2a97682014-07-31 15:07:05 -0700986TEXT runtime·aeshash64(SB),NOSPLIT,$0-16
987 MOVL p+0(FP), AX // ptr to data
988 // s+4(FP) is ignored, it is always sizeof(int64)
Keith Randalla5d40242013-03-12 10:47:44 -0700989 MOVQ (AX), X0 // data
Keith Randalla2a97682014-07-31 15:07:05 -0700990 PINSRD $2, h+8(FP), X0 // seed
Keith Randalldb53d972013-03-20 14:34:26 -0700991 AESENC runtime·aeskeysched+0(SB), X0
992 AESENC runtime·aeskeysched+16(SB), X0
993 AESENC runtime·aeskeysched+0(SB), X0
Russ Cox25f6b022014-08-27 11:32:17 -0400994 MOVL X0, ret+12(FP)
Keith Randalla5d40242013-03-12 10:47:44 -0700995 RET
996
Keith Randalla5d40242013-03-12 10:47:44 -0700997// simple mask to get rid of data in the high part of the register.
Russ Cox9ddfb642013-07-16 16:24:09 -0400998DATA masks<>+0x00(SB)/4, $0x00000000
999DATA masks<>+0x04(SB)/4, $0x00000000
1000DATA masks<>+0x08(SB)/4, $0x00000000
1001DATA masks<>+0x0c(SB)/4, $0x00000000
Keith Randalla5d40242013-03-12 10:47:44 -07001002
Russ Cox9ddfb642013-07-16 16:24:09 -04001003DATA masks<>+0x10(SB)/4, $0x000000ff
1004DATA masks<>+0x14(SB)/4, $0x00000000
1005DATA masks<>+0x18(SB)/4, $0x00000000
1006DATA masks<>+0x1c(SB)/4, $0x00000000
Keith Randalla5d40242013-03-12 10:47:44 -07001007
Russ Cox9ddfb642013-07-16 16:24:09 -04001008DATA masks<>+0x20(SB)/4, $0x0000ffff
1009DATA masks<>+0x24(SB)/4, $0x00000000
1010DATA masks<>+0x28(SB)/4, $0x00000000
1011DATA masks<>+0x2c(SB)/4, $0x00000000
Keith Randalla5d40242013-03-12 10:47:44 -07001012
Russ Cox9ddfb642013-07-16 16:24:09 -04001013DATA masks<>+0x30(SB)/4, $0x00ffffff
1014DATA masks<>+0x34(SB)/4, $0x00000000
1015DATA masks<>+0x38(SB)/4, $0x00000000
1016DATA masks<>+0x3c(SB)/4, $0x00000000
Keith Randalla5d40242013-03-12 10:47:44 -07001017
Russ Cox9ddfb642013-07-16 16:24:09 -04001018DATA masks<>+0x40(SB)/4, $0xffffffff
1019DATA masks<>+0x44(SB)/4, $0x00000000
1020DATA masks<>+0x48(SB)/4, $0x00000000
1021DATA masks<>+0x4c(SB)/4, $0x00000000
Keith Randalla5d40242013-03-12 10:47:44 -07001022
Russ Cox9ddfb642013-07-16 16:24:09 -04001023DATA masks<>+0x50(SB)/4, $0xffffffff
1024DATA masks<>+0x54(SB)/4, $0x000000ff
1025DATA masks<>+0x58(SB)/4, $0x00000000
1026DATA masks<>+0x5c(SB)/4, $0x00000000
Keith Randalla5d40242013-03-12 10:47:44 -07001027
Russ Cox9ddfb642013-07-16 16:24:09 -04001028DATA masks<>+0x60(SB)/4, $0xffffffff
1029DATA masks<>+0x64(SB)/4, $0x0000ffff
1030DATA masks<>+0x68(SB)/4, $0x00000000
1031DATA masks<>+0x6c(SB)/4, $0x00000000
Keith Randalla5d40242013-03-12 10:47:44 -07001032
Russ Cox9ddfb642013-07-16 16:24:09 -04001033DATA masks<>+0x70(SB)/4, $0xffffffff
1034DATA masks<>+0x74(SB)/4, $0x00ffffff
1035DATA masks<>+0x78(SB)/4, $0x00000000
1036DATA masks<>+0x7c(SB)/4, $0x00000000
Keith Randalla5d40242013-03-12 10:47:44 -07001037
Russ Cox9ddfb642013-07-16 16:24:09 -04001038DATA masks<>+0x80(SB)/4, $0xffffffff
1039DATA masks<>+0x84(SB)/4, $0xffffffff
1040DATA masks<>+0x88(SB)/4, $0x00000000
1041DATA masks<>+0x8c(SB)/4, $0x00000000
Keith Randalla5d40242013-03-12 10:47:44 -07001042
Russ Cox9ddfb642013-07-16 16:24:09 -04001043DATA masks<>+0x90(SB)/4, $0xffffffff
1044DATA masks<>+0x94(SB)/4, $0xffffffff
1045DATA masks<>+0x98(SB)/4, $0x000000ff
1046DATA masks<>+0x9c(SB)/4, $0x00000000
Keith Randalla5d40242013-03-12 10:47:44 -07001047
Russ Cox9ddfb642013-07-16 16:24:09 -04001048DATA masks<>+0xa0(SB)/4, $0xffffffff
1049DATA masks<>+0xa4(SB)/4, $0xffffffff
1050DATA masks<>+0xa8(SB)/4, $0x0000ffff
1051DATA masks<>+0xac(SB)/4, $0x00000000
Keith Randalla5d40242013-03-12 10:47:44 -07001052
Russ Cox9ddfb642013-07-16 16:24:09 -04001053DATA masks<>+0xb0(SB)/4, $0xffffffff
1054DATA masks<>+0xb4(SB)/4, $0xffffffff
1055DATA masks<>+0xb8(SB)/4, $0x00ffffff
1056DATA masks<>+0xbc(SB)/4, $0x00000000
Keith Randalla5d40242013-03-12 10:47:44 -07001057
Russ Cox9ddfb642013-07-16 16:24:09 -04001058DATA masks<>+0xc0(SB)/4, $0xffffffff
1059DATA masks<>+0xc4(SB)/4, $0xffffffff
1060DATA masks<>+0xc8(SB)/4, $0xffffffff
1061DATA masks<>+0xcc(SB)/4, $0x00000000
Keith Randalla5d40242013-03-12 10:47:44 -07001062
Russ Cox9ddfb642013-07-16 16:24:09 -04001063DATA masks<>+0xd0(SB)/4, $0xffffffff
1064DATA masks<>+0xd4(SB)/4, $0xffffffff
1065DATA masks<>+0xd8(SB)/4, $0xffffffff
1066DATA masks<>+0xdc(SB)/4, $0x000000ff
Keith Randalla5d40242013-03-12 10:47:44 -07001067
Russ Cox9ddfb642013-07-16 16:24:09 -04001068DATA masks<>+0xe0(SB)/4, $0xffffffff
1069DATA masks<>+0xe4(SB)/4, $0xffffffff
1070DATA masks<>+0xe8(SB)/4, $0xffffffff
1071DATA masks<>+0xec(SB)/4, $0x0000ffff
Keith Randalla5d40242013-03-12 10:47:44 -07001072
Russ Cox9ddfb642013-07-16 16:24:09 -04001073DATA masks<>+0xf0(SB)/4, $0xffffffff
1074DATA masks<>+0xf4(SB)/4, $0xffffffff
1075DATA masks<>+0xf8(SB)/4, $0xffffffff
1076DATA masks<>+0xfc(SB)/4, $0x00ffffff
Keith Randalla5d40242013-03-12 10:47:44 -07001077
Keith Randall5a546962013-08-07 10:23:24 -07001078GLOBL masks<>(SB),RODATA,$256
Keith Randalla5d40242013-03-12 10:47:44 -07001079
Russ Cox9ddfb642013-07-16 16:24:09 -04001080// these are arguments to pshufb. They move data down from
1081// the high bytes of the register to the low bytes of the register.
1082// index is how many bytes to move.
1083DATA shifts<>+0x00(SB)/4, $0x00000000
1084DATA shifts<>+0x04(SB)/4, $0x00000000
1085DATA shifts<>+0x08(SB)/4, $0x00000000
1086DATA shifts<>+0x0c(SB)/4, $0x00000000
1087
1088DATA shifts<>+0x10(SB)/4, $0xffffff0f
1089DATA shifts<>+0x14(SB)/4, $0xffffffff
1090DATA shifts<>+0x18(SB)/4, $0xffffffff
1091DATA shifts<>+0x1c(SB)/4, $0xffffffff
1092
1093DATA shifts<>+0x20(SB)/4, $0xffff0f0e
1094DATA shifts<>+0x24(SB)/4, $0xffffffff
1095DATA shifts<>+0x28(SB)/4, $0xffffffff
1096DATA shifts<>+0x2c(SB)/4, $0xffffffff
1097
1098DATA shifts<>+0x30(SB)/4, $0xff0f0e0d
1099DATA shifts<>+0x34(SB)/4, $0xffffffff
1100DATA shifts<>+0x38(SB)/4, $0xffffffff
1101DATA shifts<>+0x3c(SB)/4, $0xffffffff
1102
1103DATA shifts<>+0x40(SB)/4, $0x0f0e0d0c
1104DATA shifts<>+0x44(SB)/4, $0xffffffff
1105DATA shifts<>+0x48(SB)/4, $0xffffffff
1106DATA shifts<>+0x4c(SB)/4, $0xffffffff
1107
1108DATA shifts<>+0x50(SB)/4, $0x0e0d0c0b
1109DATA shifts<>+0x54(SB)/4, $0xffffff0f
1110DATA shifts<>+0x58(SB)/4, $0xffffffff
1111DATA shifts<>+0x5c(SB)/4, $0xffffffff
1112
1113DATA shifts<>+0x60(SB)/4, $0x0d0c0b0a
1114DATA shifts<>+0x64(SB)/4, $0xffff0f0e
1115DATA shifts<>+0x68(SB)/4, $0xffffffff
1116DATA shifts<>+0x6c(SB)/4, $0xffffffff
1117
1118DATA shifts<>+0x70(SB)/4, $0x0c0b0a09
1119DATA shifts<>+0x74(SB)/4, $0xff0f0e0d
1120DATA shifts<>+0x78(SB)/4, $0xffffffff
1121DATA shifts<>+0x7c(SB)/4, $0xffffffff
1122
1123DATA shifts<>+0x80(SB)/4, $0x0b0a0908
1124DATA shifts<>+0x84(SB)/4, $0x0f0e0d0c
1125DATA shifts<>+0x88(SB)/4, $0xffffffff
1126DATA shifts<>+0x8c(SB)/4, $0xffffffff
1127
1128DATA shifts<>+0x90(SB)/4, $0x0a090807
1129DATA shifts<>+0x94(SB)/4, $0x0e0d0c0b
1130DATA shifts<>+0x98(SB)/4, $0xffffff0f
1131DATA shifts<>+0x9c(SB)/4, $0xffffffff
1132
1133DATA shifts<>+0xa0(SB)/4, $0x09080706
1134DATA shifts<>+0xa4(SB)/4, $0x0d0c0b0a
1135DATA shifts<>+0xa8(SB)/4, $0xffff0f0e
1136DATA shifts<>+0xac(SB)/4, $0xffffffff
1137
1138DATA shifts<>+0xb0(SB)/4, $0x08070605
1139DATA shifts<>+0xb4(SB)/4, $0x0c0b0a09
1140DATA shifts<>+0xb8(SB)/4, $0xff0f0e0d
1141DATA shifts<>+0xbc(SB)/4, $0xffffffff
1142
1143DATA shifts<>+0xc0(SB)/4, $0x07060504
1144DATA shifts<>+0xc4(SB)/4, $0x0b0a0908
1145DATA shifts<>+0xc8(SB)/4, $0x0f0e0d0c
1146DATA shifts<>+0xcc(SB)/4, $0xffffffff
1147
1148DATA shifts<>+0xd0(SB)/4, $0x06050403
1149DATA shifts<>+0xd4(SB)/4, $0x0a090807
1150DATA shifts<>+0xd8(SB)/4, $0x0e0d0c0b
1151DATA shifts<>+0xdc(SB)/4, $0xffffff0f
1152
1153DATA shifts<>+0xe0(SB)/4, $0x05040302
1154DATA shifts<>+0xe4(SB)/4, $0x09080706
1155DATA shifts<>+0xe8(SB)/4, $0x0d0c0b0a
1156DATA shifts<>+0xec(SB)/4, $0xffff0f0e
1157
1158DATA shifts<>+0xf0(SB)/4, $0x04030201
1159DATA shifts<>+0xf4(SB)/4, $0x08070605
1160DATA shifts<>+0xf8(SB)/4, $0x0c0b0a09
1161DATA shifts<>+0xfc(SB)/4, $0xff0f0e0d
1162
Keith Randall5a546962013-08-07 10:23:24 -07001163GLOBL shifts<>(SB),RODATA,$256
Russ Cox9ddfb642013-07-16 16:24:09 -04001164
Keith Randall7aa4e5a2014-08-07 14:52:55 -07001165TEXT runtime·memeq(SB),NOSPLIT,$0-13
Keith Randall0c6b55e2014-07-16 14:16:19 -07001166 MOVL a+0(FP), SI
1167 MOVL b+4(FP), DI
1168 MOVL size+8(FP), BX
1169 CALL runtime·memeqbody(SB)
1170 MOVB AX, ret+12(FP)
1171 RET
1172
Keith Randallb36ed902014-06-16 21:00:37 -07001173// eqstring tests whether two strings are equal.
1174// See runtime_test.go:eqstring_generic for
Josh Bleecher Snyder339a24d2014-08-19 08:50:35 -07001175// equivalent Go code.
Keith Randallb36ed902014-06-16 21:00:37 -07001176TEXT runtime·eqstring(SB),NOSPLIT,$0-17
1177 MOVL s1len+4(FP), AX
1178 MOVL s2len+12(FP), BX
1179 CMPL AX, BX
1180 JNE different
1181 MOVL s1str+0(FP), SI
1182 MOVL s2str+8(FP), DI
1183 CMPL SI, DI
1184 JEQ same
1185 CALL runtime·memeqbody(SB)
1186 MOVB AX, v+16(FP)
1187 RET
1188same:
1189 MOVB $1, v+16(FP)
1190 RET
1191different:
1192 MOVB $0, v+16(FP)
1193 RET
1194
Keith Randall5a546962013-08-07 10:23:24 -07001195TEXT bytes·Equal(SB),NOSPLIT,$0-25
Keith Randall3d5daa22013-04-02 16:26:15 -07001196 MOVL a_len+4(FP), BX
1197 MOVL b_len+16(FP), CX
1198 XORL AX, AX
1199 CMPL BX, CX
1200 JNE eqret
1201 MOVL a+0(FP), SI
1202 MOVL b+12(FP), DI
1203 CALL runtime·memeqbody(SB)
1204eqret:
1205 MOVB AX, ret+24(FP)
1206 RET
1207
1208// a in SI
1209// b in DI
1210// count in BX
Keith Randall5a546962013-08-07 10:23:24 -07001211TEXT runtime·memeqbody(SB),NOSPLIT,$0-0
Keith Randall3d5daa22013-04-02 16:26:15 -07001212 XORL AX, AX
1213
1214 CMPL BX, $4
1215 JB small
1216
1217 // 64 bytes at a time using xmm registers
1218hugeloop:
1219 CMPL BX, $64
1220 JB bigloop
1221 TESTL $0x4000000, runtime·cpuid_edx(SB) // check for sse2
1222 JE bigloop
1223 MOVOU (SI), X0
1224 MOVOU (DI), X1
1225 MOVOU 16(SI), X2
1226 MOVOU 16(DI), X3
1227 MOVOU 32(SI), X4
1228 MOVOU 32(DI), X5
1229 MOVOU 48(SI), X6
1230 MOVOU 48(DI), X7
1231 PCMPEQB X1, X0
1232 PCMPEQB X3, X2
1233 PCMPEQB X5, X4
1234 PCMPEQB X7, X6
1235 PAND X2, X0
1236 PAND X6, X4
1237 PAND X4, X0
1238 PMOVMSKB X0, DX
1239 ADDL $64, SI
1240 ADDL $64, DI
1241 SUBL $64, BX
1242 CMPL DX, $0xffff
1243 JEQ hugeloop
1244 RET
1245
1246 // 4 bytes at a time using 32-bit register
1247bigloop:
1248 CMPL BX, $4
1249 JBE leftover
1250 MOVL (SI), CX
1251 MOVL (DI), DX
1252 ADDL $4, SI
1253 ADDL $4, DI
1254 SUBL $4, BX
1255 CMPL CX, DX
1256 JEQ bigloop
1257 RET
1258
1259 // remaining 0-4 bytes
1260leftover:
1261 MOVL -4(SI)(BX*1), CX
1262 MOVL -4(DI)(BX*1), DX
1263 CMPL CX, DX
1264 SETEQ AX
1265 RET
1266
1267small:
1268 CMPL BX, $0
1269 JEQ equal
1270
1271 LEAL 0(BX*8), CX
1272 NEGL CX
1273
1274 MOVL SI, DX
1275 CMPB DX, $0xfc
1276 JA si_high
1277
1278 // load at SI won't cross a page boundary.
1279 MOVL (SI), SI
1280 JMP si_finish
1281si_high:
1282 // address ends in 111111xx. Load up to bytes we want, move to correct position.
1283 MOVL -4(SI)(BX*1), SI
1284 SHRL CX, SI
1285si_finish:
1286
1287 // same for DI.
1288 MOVL DI, DX
1289 CMPB DX, $0xfc
1290 JA di_high
1291 MOVL (DI), DI
1292 JMP di_finish
1293di_high:
1294 MOVL -4(DI)(BX*1), DI
1295 SHRL CX, DI
1296di_finish:
1297
1298 SUBL SI, DI
1299 SHLL CX, DI
1300equal:
1301 SETEQ AX
1302 RET
Keith Randallb3946dc2013-05-14 16:05:51 -07001303
Keith Randall5a546962013-08-07 10:23:24 -07001304TEXT runtime·cmpstring(SB),NOSPLIT,$0-20
Russ Cox25f6b022014-08-27 11:32:17 -04001305 MOVL s1_base+0(FP), SI
1306 MOVL s1_len+4(FP), BX
1307 MOVL s2_base+8(FP), DI
1308 MOVL s2_len+12(FP), DX
Keith Randallb3946dc2013-05-14 16:05:51 -07001309 CALL runtime·cmpbody(SB)
Russ Cox25f6b022014-08-27 11:32:17 -04001310 MOVL AX, ret+16(FP)
Keith Randallb3946dc2013-05-14 16:05:51 -07001311 RET
1312
Russ Cox6179aca2014-08-28 10:46:59 -04001313TEXT runtime·cmpbytes(SB),NOSPLIT,$0-28
Keith Randallb3946dc2013-05-14 16:05:51 -07001314 MOVL s1+0(FP), SI
1315 MOVL s1+4(FP), BX
1316 MOVL s2+12(FP), DI
1317 MOVL s2+16(FP), DX
1318 CALL runtime·cmpbody(SB)
Russ Cox25f6b022014-08-27 11:32:17 -04001319 MOVL AX, ret+24(FP)
Keith Randallb3946dc2013-05-14 16:05:51 -07001320 RET
1321
Keith Randall5a546962013-08-07 10:23:24 -07001322TEXT bytes·IndexByte(SB),NOSPLIT,$0
Brad Fitzpatricke2a1bd62013-08-01 16:11:19 -07001323 MOVL s+0(FP), SI
1324 MOVL s_len+4(FP), CX
1325 MOVB c+12(FP), AL
1326 MOVL SI, DI
1327 CLD; REPN; SCASB
1328 JZ 3(PC)
1329 MOVL $-1, ret+16(FP)
1330 RET
1331 SUBL SI, DI
1332 SUBL $1, DI
1333 MOVL DI, ret+16(FP)
1334 RET
1335
Keith Randall5a546962013-08-07 10:23:24 -07001336TEXT strings·IndexByte(SB),NOSPLIT,$0
Brad Fitzpatrick598c7892013-08-05 15:04:05 -07001337 MOVL s+0(FP), SI
1338 MOVL s_len+4(FP), CX
1339 MOVB c+8(FP), AL
1340 MOVL SI, DI
1341 CLD; REPN; SCASB
1342 JZ 3(PC)
1343 MOVL $-1, ret+12(FP)
1344 RET
1345 SUBL SI, DI
1346 SUBL $1, DI
1347 MOVL DI, ret+12(FP)
1348 RET
1349
Keith Randallb3946dc2013-05-14 16:05:51 -07001350// input:
1351// SI = a
1352// DI = b
1353// BX = alen
1354// DX = blen
1355// output:
1356// AX = 1/0/-1
Keith Randall5a546962013-08-07 10:23:24 -07001357TEXT runtime·cmpbody(SB),NOSPLIT,$0-0
Keith Randallb3946dc2013-05-14 16:05:51 -07001358 CMPL SI, DI
1359 JEQ cmp_allsame
1360 CMPL BX, DX
1361 MOVL DX, BP
1362 CMOVLLT BX, BP // BP = min(alen, blen)
1363 CMPL BP, $4
1364 JB cmp_small
1365 TESTL $0x4000000, runtime·cpuid_edx(SB) // check for sse2
1366 JE cmp_mediumloop
1367cmp_largeloop:
1368 CMPL BP, $16
1369 JB cmp_mediumloop
1370 MOVOU (SI), X0
1371 MOVOU (DI), X1
1372 PCMPEQB X0, X1
1373 PMOVMSKB X1, AX
1374 XORL $0xffff, AX // convert EQ to NE
1375 JNE cmp_diff16 // branch if at least one byte is not equal
1376 ADDL $16, SI
1377 ADDL $16, DI
1378 SUBL $16, BP
1379 JMP cmp_largeloop
1380
1381cmp_diff16:
1382 BSFL AX, BX // index of first byte that differs
1383 XORL AX, AX
1384 MOVB (SI)(BX*1), CX
1385 CMPB CX, (DI)(BX*1)
1386 SETHI AX
1387 LEAL -1(AX*2), AX // convert 1/0 to +1/-1
1388 RET
1389
1390cmp_mediumloop:
1391 CMPL BP, $4
1392 JBE cmp_0through4
1393 MOVL (SI), AX
1394 MOVL (DI), CX
1395 CMPL AX, CX
1396 JNE cmp_diff4
1397 ADDL $4, SI
1398 ADDL $4, DI
1399 SUBL $4, BP
1400 JMP cmp_mediumloop
1401
1402cmp_0through4:
1403 MOVL -4(SI)(BP*1), AX
1404 MOVL -4(DI)(BP*1), CX
1405 CMPL AX, CX
1406 JEQ cmp_allsame
1407
1408cmp_diff4:
1409 BSWAPL AX // reverse order of bytes
1410 BSWAPL CX
1411 XORL AX, CX // find bit differences
1412 BSRL CX, CX // index of highest bit difference
1413 SHRL CX, AX // move a's bit to bottom
1414 ANDL $1, AX // mask bit
1415 LEAL -1(AX*2), AX // 1/0 => +1/-1
1416 RET
1417
1418 // 0-3 bytes in common
1419cmp_small:
1420 LEAL (BP*8), CX
1421 NEGL CX
1422 JEQ cmp_allsame
1423
1424 // load si
1425 CMPB SI, $0xfc
1426 JA cmp_si_high
1427 MOVL (SI), SI
1428 JMP cmp_si_finish
1429cmp_si_high:
1430 MOVL -4(SI)(BP*1), SI
1431 SHRL CX, SI
1432cmp_si_finish:
1433 SHLL CX, SI
1434
1435 // same for di
1436 CMPB DI, $0xfc
1437 JA cmp_di_high
1438 MOVL (DI), DI
1439 JMP cmp_di_finish
1440cmp_di_high:
1441 MOVL -4(DI)(BP*1), DI
1442 SHRL CX, DI
1443cmp_di_finish:
1444 SHLL CX, DI
1445
1446 BSWAPL SI // reverse order of bytes
1447 BSWAPL DI
1448 XORL SI, DI // find bit differences
1449 JEQ cmp_allsame
1450 BSRL DI, CX // index of highest bit difference
1451 SHRL CX, SI // move a's bit to bottom
1452 ANDL $1, SI // mask bit
1453 LEAL -1(SI*2), AX // 1/0 => +1/-1
1454 RET
1455
1456 // all the bytes in common are the same, so we just need
1457 // to compare the lengths.
1458cmp_allsame:
1459 XORL AX, AX
1460 XORL CX, CX
1461 CMPL BX, DX
1462 SETGT AX // 1 if alen > blen
1463 SETEQ CX // 1 if alen == blen
1464 LEAL -1(CX)(AX*2), AX // 1,0,-1 result
1465 RET
Keith Randall6c7cbf02014-04-01 12:51:02 -07001466
1467// A Duff's device for zeroing memory.
1468// The compiler jumps to computed addresses within
1469// this routine to zero chunks of memory. Do not
1470// change this code without also changing the code
1471// in ../../cmd/8g/ggen.c:clearfat.
1472// AX: zero
1473// DI: ptr to memory to be zeroed
1474// DI is updated as a side effect.
1475TEXT runtime·duffzero(SB), NOSPLIT, $0-0
1476 STOSL
1477 STOSL
1478 STOSL
1479 STOSL
1480 STOSL
1481 STOSL
1482 STOSL
1483 STOSL
1484 STOSL
1485 STOSL
1486 STOSL
1487 STOSL
1488 STOSL
1489 STOSL
1490 STOSL
1491 STOSL
1492 STOSL
1493 STOSL
1494 STOSL
1495 STOSL
1496 STOSL
1497 STOSL
1498 STOSL
1499 STOSL
1500 STOSL
1501 STOSL
1502 STOSL
1503 STOSL
1504 STOSL
1505 STOSL
1506 STOSL
1507 STOSL
1508 STOSL
1509 STOSL
1510 STOSL
1511 STOSL
1512 STOSL
1513 STOSL
1514 STOSL
1515 STOSL
1516 STOSL
1517 STOSL
1518 STOSL
1519 STOSL
1520 STOSL
1521 STOSL
1522 STOSL
1523 STOSL
1524 STOSL
1525 STOSL
1526 STOSL
1527 STOSL
1528 STOSL
1529 STOSL
1530 STOSL
1531 STOSL
1532 STOSL
1533 STOSL
1534 STOSL
1535 STOSL
1536 STOSL
1537 STOSL
1538 STOSL
1539 STOSL
1540 STOSL
1541 STOSL
1542 STOSL
1543 STOSL
1544 STOSL
1545 STOSL
1546 STOSL
1547 STOSL
1548 STOSL
1549 STOSL
1550 STOSL
1551 STOSL
1552 STOSL
1553 STOSL
1554 STOSL
1555 STOSL
1556 STOSL
1557 STOSL
1558 STOSL
1559 STOSL
1560 STOSL
1561 STOSL
1562 STOSL
1563 STOSL
1564 STOSL
1565 STOSL
1566 STOSL
1567 STOSL
1568 STOSL
1569 STOSL
1570 STOSL
1571 STOSL
1572 STOSL
1573 STOSL
1574 STOSL
1575 STOSL
1576 STOSL
1577 STOSL
1578 STOSL
1579 STOSL
1580 STOSL
1581 STOSL
1582 STOSL
1583 STOSL
1584 STOSL
1585 STOSL
1586 STOSL
1587 STOSL
1588 STOSL
1589 STOSL
1590 STOSL
1591 STOSL
1592 STOSL
1593 STOSL
1594 STOSL
1595 STOSL
1596 STOSL
1597 STOSL
1598 STOSL
1599 STOSL
1600 STOSL
1601 STOSL
1602 STOSL
1603 STOSL
1604 RET
1605
1606// A Duff's device for copying memory.
1607// The compiler jumps to computed addresses within
1608// this routine to copy chunks of memory. Source
1609// and destination must not overlap. Do not
1610// change this code without also changing the code
1611// in ../../cmd/6g/cgen.c:sgen.
1612// SI: ptr to source memory
1613// DI: ptr to destination memory
1614// SI and DI are updated as a side effect.
1615
1616// NOTE: this is equivalent to a sequence of MOVSL but
1617// for some reason MOVSL is really slow.
1618TEXT runtime·duffcopy(SB), NOSPLIT, $0-0
1619 MOVL (SI),CX
1620 ADDL $4,SI
1621 MOVL CX,(DI)
1622 ADDL $4,DI
1623
1624 MOVL (SI),CX
1625 ADDL $4,SI
1626 MOVL CX,(DI)
1627 ADDL $4,DI
1628
1629 MOVL (SI),CX
1630 ADDL $4,SI
1631 MOVL CX,(DI)
1632 ADDL $4,DI
1633
1634 MOVL (SI),CX
1635 ADDL $4,SI
1636 MOVL CX,(DI)
1637 ADDL $4,DI
1638
1639 MOVL (SI),CX
1640 ADDL $4,SI
1641 MOVL CX,(DI)
1642 ADDL $4,DI
1643
1644 MOVL (SI),CX
1645 ADDL $4,SI
1646 MOVL CX,(DI)
1647 ADDL $4,DI
1648
1649 MOVL (SI),CX
1650 ADDL $4,SI
1651 MOVL CX,(DI)
1652 ADDL $4,DI
1653
1654 MOVL (SI),CX
1655 ADDL $4,SI
1656 MOVL CX,(DI)
1657 ADDL $4,DI
1658
1659 MOVL (SI),CX
1660 ADDL $4,SI
1661 MOVL CX,(DI)
1662 ADDL $4,DI
1663
1664 MOVL (SI),CX
1665 ADDL $4,SI
1666 MOVL CX,(DI)
1667 ADDL $4,DI
1668
1669 MOVL (SI),CX
1670 ADDL $4,SI
1671 MOVL CX,(DI)
1672 ADDL $4,DI
1673
1674 MOVL (SI),CX
1675 ADDL $4,SI
1676 MOVL CX,(DI)
1677 ADDL $4,DI
1678
1679 MOVL (SI),CX
1680 ADDL $4,SI
1681 MOVL CX,(DI)
1682 ADDL $4,DI
1683
1684 MOVL (SI),CX
1685 ADDL $4,SI
1686 MOVL CX,(DI)
1687 ADDL $4,DI
1688
1689 MOVL (SI),CX
1690 ADDL $4,SI
1691 MOVL CX,(DI)
1692 ADDL $4,DI
1693
1694 MOVL (SI),CX
1695 ADDL $4,SI
1696 MOVL CX,(DI)
1697 ADDL $4,DI
1698
1699 MOVL (SI),CX
1700 ADDL $4,SI
1701 MOVL CX,(DI)
1702 ADDL $4,DI
1703
1704 MOVL (SI),CX
1705 ADDL $4,SI
1706 MOVL CX,(DI)
1707 ADDL $4,DI
1708
1709 MOVL (SI),CX
1710 ADDL $4,SI
1711 MOVL CX,(DI)
1712 ADDL $4,DI
1713
1714 MOVL (SI),CX
1715 ADDL $4,SI
1716 MOVL CX,(DI)
1717 ADDL $4,DI
1718
1719 MOVL (SI),CX
1720 ADDL $4,SI
1721 MOVL CX,(DI)
1722 ADDL $4,DI
1723
1724 MOVL (SI),CX
1725 ADDL $4,SI
1726 MOVL CX,(DI)
1727 ADDL $4,DI
1728
1729 MOVL (SI),CX
1730 ADDL $4,SI
1731 MOVL CX,(DI)
1732 ADDL $4,DI
1733
1734 MOVL (SI),CX
1735 ADDL $4,SI
1736 MOVL CX,(DI)
1737 ADDL $4,DI
1738
1739 MOVL (SI),CX
1740 ADDL $4,SI
1741 MOVL CX,(DI)
1742 ADDL $4,DI
1743
1744 MOVL (SI),CX
1745 ADDL $4,SI
1746 MOVL CX,(DI)
1747 ADDL $4,DI
1748
1749 MOVL (SI),CX
1750 ADDL $4,SI
1751 MOVL CX,(DI)
1752 ADDL $4,DI
1753
1754 MOVL (SI),CX
1755 ADDL $4,SI
1756 MOVL CX,(DI)
1757 ADDL $4,DI
1758
1759 MOVL (SI),CX
1760 ADDL $4,SI
1761 MOVL CX,(DI)
1762 ADDL $4,DI
1763
1764 MOVL (SI),CX
1765 ADDL $4,SI
1766 MOVL CX,(DI)
1767 ADDL $4,DI
1768
1769 MOVL (SI),CX
1770 ADDL $4,SI
1771 MOVL CX,(DI)
1772 ADDL $4,DI
1773
1774 MOVL (SI),CX
1775 ADDL $4,SI
1776 MOVL CX,(DI)
1777 ADDL $4,DI
1778
1779 MOVL (SI),CX
1780 ADDL $4,SI
1781 MOVL CX,(DI)
1782 ADDL $4,DI
1783
1784 MOVL (SI),CX
1785 ADDL $4,SI
1786 MOVL CX,(DI)
1787 ADDL $4,DI
1788
1789 MOVL (SI),CX
1790 ADDL $4,SI
1791 MOVL CX,(DI)
1792 ADDL $4,DI
1793
1794 MOVL (SI),CX
1795 ADDL $4,SI
1796 MOVL CX,(DI)
1797 ADDL $4,DI
1798
1799 MOVL (SI),CX
1800 ADDL $4,SI
1801 MOVL CX,(DI)
1802 ADDL $4,DI
1803
1804 MOVL (SI),CX
1805 ADDL $4,SI
1806 MOVL CX,(DI)
1807 ADDL $4,DI
1808
1809 MOVL (SI),CX
1810 ADDL $4,SI
1811 MOVL CX,(DI)
1812 ADDL $4,DI
1813
1814 MOVL (SI),CX
1815 ADDL $4,SI
1816 MOVL CX,(DI)
1817 ADDL $4,DI
1818
1819 MOVL (SI),CX
1820 ADDL $4,SI
1821 MOVL CX,(DI)
1822 ADDL $4,DI
1823
1824 MOVL (SI),CX
1825 ADDL $4,SI
1826 MOVL CX,(DI)
1827 ADDL $4,DI
1828
1829 MOVL (SI),CX
1830 ADDL $4,SI
1831 MOVL CX,(DI)
1832 ADDL $4,DI
1833
1834 MOVL (SI),CX
1835 ADDL $4,SI
1836 MOVL CX,(DI)
1837 ADDL $4,DI
1838
1839 MOVL (SI),CX
1840 ADDL $4,SI
1841 MOVL CX,(DI)
1842 ADDL $4,DI
1843
1844 MOVL (SI),CX
1845 ADDL $4,SI
1846 MOVL CX,(DI)
1847 ADDL $4,DI
1848
1849 MOVL (SI),CX
1850 ADDL $4,SI
1851 MOVL CX,(DI)
1852 ADDL $4,DI
1853
1854 MOVL (SI),CX
1855 ADDL $4,SI
1856 MOVL CX,(DI)
1857 ADDL $4,DI
1858
1859 MOVL (SI),CX
1860 ADDL $4,SI
1861 MOVL CX,(DI)
1862 ADDL $4,DI
1863
1864 MOVL (SI),CX
1865 ADDL $4,SI
1866 MOVL CX,(DI)
1867 ADDL $4,DI
1868
1869 MOVL (SI),CX
1870 ADDL $4,SI
1871 MOVL CX,(DI)
1872 ADDL $4,DI
1873
1874 MOVL (SI),CX
1875 ADDL $4,SI
1876 MOVL CX,(DI)
1877 ADDL $4,DI
1878
1879 MOVL (SI),CX
1880 ADDL $4,SI
1881 MOVL CX,(DI)
1882 ADDL $4,DI
1883
1884 MOVL (SI),CX
1885 ADDL $4,SI
1886 MOVL CX,(DI)
1887 ADDL $4,DI
1888
1889 MOVL (SI),CX
1890 ADDL $4,SI
1891 MOVL CX,(DI)
1892 ADDL $4,DI
1893
1894 MOVL (SI),CX
1895 ADDL $4,SI
1896 MOVL CX,(DI)
1897 ADDL $4,DI
1898
1899 MOVL (SI),CX
1900 ADDL $4,SI
1901 MOVL CX,(DI)
1902 ADDL $4,DI
1903
1904 MOVL (SI),CX
1905 ADDL $4,SI
1906 MOVL CX,(DI)
1907 ADDL $4,DI
1908
1909 MOVL (SI),CX
1910 ADDL $4,SI
1911 MOVL CX,(DI)
1912 ADDL $4,DI
1913
1914 MOVL (SI),CX
1915 ADDL $4,SI
1916 MOVL CX,(DI)
1917 ADDL $4,DI
1918
1919 MOVL (SI),CX
1920 ADDL $4,SI
1921 MOVL CX,(DI)
1922 ADDL $4,DI
1923
1924 MOVL (SI),CX
1925 ADDL $4,SI
1926 MOVL CX,(DI)
1927 ADDL $4,DI
1928
1929 MOVL (SI),CX
1930 ADDL $4,SI
1931 MOVL CX,(DI)
1932 ADDL $4,DI
1933
1934 MOVL (SI),CX
1935 ADDL $4,SI
1936 MOVL CX,(DI)
1937 ADDL $4,DI
1938
1939 MOVL (SI),CX
1940 ADDL $4,SI
1941 MOVL CX,(DI)
1942 ADDL $4,DI
1943
1944 MOVL (SI),CX
1945 ADDL $4,SI
1946 MOVL CX,(DI)
1947 ADDL $4,DI
1948
1949 MOVL (SI),CX
1950 ADDL $4,SI
1951 MOVL CX,(DI)
1952 ADDL $4,DI
1953
1954 MOVL (SI),CX
1955 ADDL $4,SI
1956 MOVL CX,(DI)
1957 ADDL $4,DI
1958
1959 MOVL (SI),CX
1960 ADDL $4,SI
1961 MOVL CX,(DI)
1962 ADDL $4,DI
1963
1964 MOVL (SI),CX
1965 ADDL $4,SI
1966 MOVL CX,(DI)
1967 ADDL $4,DI
1968
1969 MOVL (SI),CX
1970 ADDL $4,SI
1971 MOVL CX,(DI)
1972 ADDL $4,DI
1973
1974 MOVL (SI),CX
1975 ADDL $4,SI
1976 MOVL CX,(DI)
1977 ADDL $4,DI
1978
1979 MOVL (SI),CX
1980 ADDL $4,SI
1981 MOVL CX,(DI)
1982 ADDL $4,DI
1983
1984 MOVL (SI),CX
1985 ADDL $4,SI
1986 MOVL CX,(DI)
1987 ADDL $4,DI
1988
1989 MOVL (SI),CX
1990 ADDL $4,SI
1991 MOVL CX,(DI)
1992 ADDL $4,DI
1993
1994 MOVL (SI),CX
1995 ADDL $4,SI
1996 MOVL CX,(DI)
1997 ADDL $4,DI
1998
1999 MOVL (SI),CX
2000 ADDL $4,SI
2001 MOVL CX,(DI)
2002 ADDL $4,DI
2003
2004 MOVL (SI),CX
2005 ADDL $4,SI
2006 MOVL CX,(DI)
2007 ADDL $4,DI
2008
2009 MOVL (SI),CX
2010 ADDL $4,SI
2011 MOVL CX,(DI)
2012 ADDL $4,DI
2013
2014 MOVL (SI),CX
2015 ADDL $4,SI
2016 MOVL CX,(DI)
2017 ADDL $4,DI
2018
2019 MOVL (SI),CX
2020 ADDL $4,SI
2021 MOVL CX,(DI)
2022 ADDL $4,DI
2023
2024 MOVL (SI),CX
2025 ADDL $4,SI
2026 MOVL CX,(DI)
2027 ADDL $4,DI
2028
2029 MOVL (SI),CX
2030 ADDL $4,SI
2031 MOVL CX,(DI)
2032 ADDL $4,DI
2033
2034 MOVL (SI),CX
2035 ADDL $4,SI
2036 MOVL CX,(DI)
2037 ADDL $4,DI
2038
2039 MOVL (SI),CX
2040 ADDL $4,SI
2041 MOVL CX,(DI)
2042 ADDL $4,DI
2043
2044 MOVL (SI),CX
2045 ADDL $4,SI
2046 MOVL CX,(DI)
2047 ADDL $4,DI
2048
2049 MOVL (SI),CX
2050 ADDL $4,SI
2051 MOVL CX,(DI)
2052 ADDL $4,DI
2053
2054 MOVL (SI),CX
2055 ADDL $4,SI
2056 MOVL CX,(DI)
2057 ADDL $4,DI
2058
2059 MOVL (SI),CX
2060 ADDL $4,SI
2061 MOVL CX,(DI)
2062 ADDL $4,DI
2063
2064 MOVL (SI),CX
2065 ADDL $4,SI
2066 MOVL CX,(DI)
2067 ADDL $4,DI
2068
2069 MOVL (SI),CX
2070 ADDL $4,SI
2071 MOVL CX,(DI)
2072 ADDL $4,DI
2073
2074 MOVL (SI),CX
2075 ADDL $4,SI
2076 MOVL CX,(DI)
2077 ADDL $4,DI
2078
2079 MOVL (SI),CX
2080 ADDL $4,SI
2081 MOVL CX,(DI)
2082 ADDL $4,DI
2083
2084 MOVL (SI),CX
2085 ADDL $4,SI
2086 MOVL CX,(DI)
2087 ADDL $4,DI
2088
2089 MOVL (SI),CX
2090 ADDL $4,SI
2091 MOVL CX,(DI)
2092 ADDL $4,DI
2093
2094 MOVL (SI),CX
2095 ADDL $4,SI
2096 MOVL CX,(DI)
2097 ADDL $4,DI
2098
2099 MOVL (SI),CX
2100 ADDL $4,SI
2101 MOVL CX,(DI)
2102 ADDL $4,DI
2103
2104 MOVL (SI),CX
2105 ADDL $4,SI
2106 MOVL CX,(DI)
2107 ADDL $4,DI
2108
2109 MOVL (SI),CX
2110 ADDL $4,SI
2111 MOVL CX,(DI)
2112 ADDL $4,DI
2113
2114 MOVL (SI),CX
2115 ADDL $4,SI
2116 MOVL CX,(DI)
2117 ADDL $4,DI
2118
2119 MOVL (SI),CX
2120 ADDL $4,SI
2121 MOVL CX,(DI)
2122 ADDL $4,DI
2123
2124 MOVL (SI),CX
2125 ADDL $4,SI
2126 MOVL CX,(DI)
2127 ADDL $4,DI
2128
2129 MOVL (SI),CX
2130 ADDL $4,SI
2131 MOVL CX,(DI)
2132 ADDL $4,DI
2133
2134 MOVL (SI),CX
2135 ADDL $4,SI
2136 MOVL CX,(DI)
2137 ADDL $4,DI
2138
2139 MOVL (SI),CX
2140 ADDL $4,SI
2141 MOVL CX,(DI)
2142 ADDL $4,DI
2143
2144 MOVL (SI),CX
2145 ADDL $4,SI
2146 MOVL CX,(DI)
2147 ADDL $4,DI
2148
2149 MOVL (SI),CX
2150 ADDL $4,SI
2151 MOVL CX,(DI)
2152 ADDL $4,DI
2153
2154 MOVL (SI),CX
2155 ADDL $4,SI
2156 MOVL CX,(DI)
2157 ADDL $4,DI
2158
2159 MOVL (SI),CX
2160 ADDL $4,SI
2161 MOVL CX,(DI)
2162 ADDL $4,DI
2163
2164 MOVL (SI),CX
2165 ADDL $4,SI
2166 MOVL CX,(DI)
2167 ADDL $4,DI
2168
2169 MOVL (SI),CX
2170 ADDL $4,SI
2171 MOVL CX,(DI)
2172 ADDL $4,DI
2173
2174 MOVL (SI),CX
2175 ADDL $4,SI
2176 MOVL CX,(DI)
2177 ADDL $4,DI
2178
2179 MOVL (SI),CX
2180 ADDL $4,SI
2181 MOVL CX,(DI)
2182 ADDL $4,DI
2183
2184 MOVL (SI),CX
2185 ADDL $4,SI
2186 MOVL CX,(DI)
2187 ADDL $4,DI
2188
2189 MOVL (SI),CX
2190 ADDL $4,SI
2191 MOVL CX,(DI)
2192 ADDL $4,DI
2193
2194 MOVL (SI),CX
2195 ADDL $4,SI
2196 MOVL CX,(DI)
2197 ADDL $4,DI
2198
2199 MOVL (SI),CX
2200 ADDL $4,SI
2201 MOVL CX,(DI)
2202 ADDL $4,DI
2203
2204 MOVL (SI),CX
2205 ADDL $4,SI
2206 MOVL CX,(DI)
2207 ADDL $4,DI
2208
2209 MOVL (SI),CX
2210 ADDL $4,SI
2211 MOVL CX,(DI)
2212 ADDL $4,DI
2213
2214 MOVL (SI),CX
2215 ADDL $4,SI
2216 MOVL CX,(DI)
2217 ADDL $4,DI
2218
2219 MOVL (SI),CX
2220 ADDL $4,SI
2221 MOVL CX,(DI)
2222 ADDL $4,DI
2223
2224 MOVL (SI),CX
2225 ADDL $4,SI
2226 MOVL CX,(DI)
2227 ADDL $4,DI
2228
2229 MOVL (SI),CX
2230 ADDL $4,SI
2231 MOVL CX,(DI)
2232 ADDL $4,DI
2233
2234 MOVL (SI),CX
2235 ADDL $4,SI
2236 MOVL CX,(DI)
2237 ADDL $4,DI
2238
2239 MOVL (SI),CX
2240 ADDL $4,SI
2241 MOVL CX,(DI)
2242 ADDL $4,DI
2243
2244 MOVL (SI),CX
2245 ADDL $4,SI
2246 MOVL CX,(DI)
2247 ADDL $4,DI
2248
2249 MOVL (SI),CX
2250 ADDL $4,SI
2251 MOVL CX,(DI)
2252 ADDL $4,DI
2253
2254 MOVL (SI),CX
2255 ADDL $4,SI
2256 MOVL CX,(DI)
2257 ADDL $4,DI
2258
2259 RET
Dmitriy Vyukov350a8fc2014-05-02 17:32:42 +01002260
Keith Randall3306d112014-09-02 14:33:33 -07002261TEXT runtime·fastrand1(SB), NOSPLIT, $0-4
Keith Randall0c6b55e2014-07-16 14:16:19 -07002262 get_tls(CX)
2263 MOVL g(CX), AX
2264 MOVL g_m(AX), AX
2265 MOVL m_fastrand(AX), DX
2266 ADDL DX, DX
2267 MOVL DX, BX
2268 XORL $0x88888eef, DX
2269 CMOVLMI BX, DX
2270 MOVL DX, m_fastrand(AX)
2271 MOVL DX, ret+0(FP)
2272 RET
Keith Randallf4407372014-09-03 08:49:43 -07002273
2274TEXT runtime·return0(SB), NOSPLIT, $0
2275 MOVL $0, AX
2276 RET
Keith Randall1b6807b2014-09-25 07:59:01 -07002277
2278// Called from cgo wrappers, this function returns g->m->curg.stack.hi.
2279// Must obey the gcc calling convention.
Keith Randall1aa65fe2014-09-25 08:37:04 -07002280TEXT _cgo_topofstack(SB),NOSPLIT,$0
Keith Randall1b6807b2014-09-25 07:59:01 -07002281 get_tls(CX)
2282 MOVL g(CX), AX
2283 MOVL g_m(AX), AX
2284 MOVL m_curg(AX), AX
2285 MOVL (g_stack+stack_hi)(AX), AX
2286 RET