blob: d2c6e304691b754c3b438b292ebdd49e563e045e [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"
Keith Randall5a546962013-08-07 10:23:24 -07007#include "../../cmd/ld/textflag.h"
Russ Cox8522a472009-06-17 15:15:55 -07008
Keith Randall5a546962013-08-07 10:23:24 -07009TEXT _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
22 MOVL BX, g_stackguard(BP)
Dmitriy Vyukovf5becf42013-06-03 12:28:24 +040023 MOVL BX, g_stackguard0(BP)
Dmitriy Vyukov428062d2011-12-07 16:53:17 +030024 MOVL SP, g_stackbase(BP)
25
Keith Randalla5d40242013-03-12 10:47:44 -070026 // find out information about the processor we're on
27 MOVL $0, AX
28 CPUID
29 CMPL AX, $0
30 JE nocpuinfo
31 MOVL $1, AX
32 CPUID
33 MOVL CX, runtime·cpuid_ecx(SB)
34 MOVL DX, runtime·cpuid_edx(SB)
35nocpuinfo:
36
Russ Coxf8d49b52013-02-28 16:24:38 -050037 // if there is an _cgo_init, call it to let it
Russ Cox133a1582009-10-03 10:37:12 -070038 // initialize and to set up GS. if not,
39 // we set up GS ourselves.
Russ Coxf8d49b52013-02-28 16:24:38 -050040 MOVL _cgo_init(SB), AX
Russ Cox133a1582009-10-03 10:37:12 -070041 TESTL AX, AX
Dmitriy Vyukovfbfed492011-11-09 23:11:48 +030042 JZ needtls
Russ Cox89f185f2014-06-26 11:54:39 -040043 MOVL $setg_gcc<>(SB), BX
Russ Cox6a70f9d2013-03-25 18:14:02 -040044 MOVL BX, 4(SP)
Russ Cox3b85b722013-03-11 00:51:42 -040045 MOVL BP, 0(SP)
Russ Cox133a1582009-10-03 10:37:12 -070046 CALL AX
Dmitriy Vyukovf5becf42013-06-03 12:28:24 +040047 // update stackguard after _cgo_init
48 MOVL $runtime·g0(SB), CX
49 MOVL g_stackguard0(CX), AX
50 MOVL AX, g_stackguard(CX)
Russ Coxf8d49b52013-02-28 16:24:38 -050051 // skip runtime·ldt0setup(SB) and tls test after _cgo_init for non-windows
Wei Guangjing1aa2d882011-01-20 10:22:20 -050052 CMPL runtime·iswindows(SB), $0
53 JEQ ok
Dmitriy Vyukovfbfed492011-11-09 23:11:48 +030054needtls:
Yuval Pavel Zholkover2aa2ceb2011-07-25 12:25:41 -040055 // skip runtime·ldt0setup(SB) and tls test on Plan 9 in all cases
56 CMPL runtime·isplan9(SB), $1
57 JEQ ok
58
Russ Cox1b14bdb2009-09-22 16:28:32 -070059 // set up %gs
Russ Cox68b42552010-11-04 14:00:19 -040060 CALL runtime·ldt0setup(SB)
Russ Cox0d3a0432009-03-30 00:01:07 -070061
Russ Cox0d3a0432009-03-30 00:01:07 -070062 // store through it, to make sure it works
Hector Chu6bfe5f52010-01-06 17:58:55 -080063 get_tls(BX)
64 MOVL $0x123, g(BX)
Russ Cox68b42552010-11-04 14:00:19 -040065 MOVL runtime·tls0(SB), AX
Russ Cox0d3a0432009-03-30 00:01:07 -070066 CMPL AX, $0x123
67 JEQ ok
Russ Cox133a1582009-10-03 10:37:12 -070068 MOVL AX, 0 // abort
Russ Cox0d3a0432009-03-30 00:01:07 -070069ok:
Russ Cox0d3a0432009-03-30 00:01:07 -070070 // set up m and g "registers"
Hector Chu6bfe5f52010-01-06 17:58:55 -080071 get_tls(BX)
Russ Cox68b42552010-11-04 14:00:19 -040072 LEAL runtime·g0(SB), CX
Hector Chu6bfe5f52010-01-06 17:58:55 -080073 MOVL CX, g(BX)
Russ Cox68b42552010-11-04 14:00:19 -040074 LEAL runtime·m0(SB), AX
Russ Cox0d3a0432009-03-30 00:01:07 -070075
76 // save m->g0 = g0
Russ Cox8522a472009-06-17 15:15:55 -070077 MOVL CX, m_g0(AX)
Russ Cox89f185f2014-06-26 11:54:39 -040078 // save g0->m = m0
79 MOVL AX, g_m(CX)
Russ Cox0d3a0432009-03-30 00:01:07 -070080
Russ Cox68b42552010-11-04 14:00:19 -040081 CALL runtime·emptyfunc(SB) // fault if stack check is wrong
Russ Cox0d3a0432009-03-30 00:01:07 -070082
83 // convention is D is always cleared
84 CLD
85
Russ Cox68b42552010-11-04 14:00:19 -040086 CALL runtime·check(SB)
Russ Cox0d3a0432009-03-30 00:01:07 -070087
88 // saved argc, argv
89 MOVL 120(SP), AX
90 MOVL AX, 0(SP)
91 MOVL 124(SP), AX
92 MOVL AX, 4(SP)
Russ Cox68b42552010-11-04 14:00:19 -040093 CALL runtime·args(SB)
94 CALL runtime·osinit(SB)
Keith Randalla5d40242013-03-12 10:47:44 -070095 CALL runtime·hashinit(SB)
Russ Cox68b42552010-11-04 14:00:19 -040096 CALL runtime·schedinit(SB)
Russ Cox0d3a0432009-03-30 00:01:07 -070097
98 // create a new goroutine to start program
Russ Cox1903ad72013-02-21 17:01:13 -050099 PUSHL $runtime·main·f(SB) // entry
Russ Cox8522a472009-06-17 15:15:55 -0700100 PUSHL $0 // arg size
Russ Cox9ddfb642013-07-16 16:24:09 -0400101 ARGSIZE(8)
Russ Cox68b42552010-11-04 14:00:19 -0400102 CALL runtime·newproc(SB)
Russ Cox9ddfb642013-07-16 16:24:09 -0400103 ARGSIZE(-1)
Russ Cox0d3a0432009-03-30 00:01:07 -0700104 POPL AX
105 POPL AX
106
107 // start this M
Russ Cox68b42552010-11-04 14:00:19 -0400108 CALL runtime·mstart(SB)
Russ Cox0d3a0432009-03-30 00:01:07 -0700109
110 INT $3
111 RET
112
Russ Cox1903ad72013-02-21 17:01:13 -0500113DATA runtime·main·f+0(SB)/4,$runtime·main(SB)
Keith Randall5a546962013-08-07 10:23:24 -0700114GLOBL runtime·main·f(SB),RODATA,$4
Russ Cox1903ad72013-02-21 17:01:13 -0500115
Keith Randall5a546962013-08-07 10:23:24 -0700116TEXT runtime·breakpoint(SB),NOSPLIT,$0-0
Russ Cox1b14bdb2009-09-22 16:28:32 -0700117 INT $3
Russ Cox0d3a0432009-03-30 00:01:07 -0700118 RET
119
Keith Randall5a546962013-08-07 10:23:24 -0700120TEXT runtime·asminit(SB),NOSPLIT,$0-0
Carl Shapiro019c8fc2013-04-02 13:45:56 -0700121 // Linux and MinGW start the FPU in extended double precision.
Russ Cox1707a992012-02-14 01:23:15 -0500122 // Other operating systems use double precision.
123 // Change to double precision to match them,
124 // and to match other hardware that only has double.
125 PUSHL $0x27F
126 FLDCW 0(SP)
127 POPL AX
128 RET
129
Russ Cox8522a472009-06-17 15:15:55 -0700130/*
131 * go-routine
132 */
Russ Cox0d3a0432009-03-30 00:01:07 -0700133
Russ Coxf9ca3b52011-03-07 10:37:42 -0500134// void gosave(Gobuf*)
Russ Cox8522a472009-06-17 15:15:55 -0700135// save state in Gobuf; setjmp
Keith Randall5a546962013-08-07 10:23:24 -0700136TEXT runtime·gosave(SB), NOSPLIT, $0-4
Russ Cox8522a472009-06-17 15:15:55 -0700137 MOVL 4(SP), AX // gobuf
138 LEAL 4(SP), BX // caller's SP
139 MOVL BX, gobuf_sp(AX)
140 MOVL 0(SP), BX // caller's PC
141 MOVL BX, gobuf_pc(AX)
Russ Coxd67e7e32013-06-12 15:22:26 -0400142 MOVL $0, gobuf_ret(AX)
143 MOVL $0, gobuf_ctxt(AX)
Hector Chu6bfe5f52010-01-06 17:58:55 -0800144 get_tls(CX)
145 MOVL g(CX), BX
Russ Cox8522a472009-06-17 15:15:55 -0700146 MOVL BX, gobuf_g(AX)
Russ Cox0d3a0432009-03-30 00:01:07 -0700147 RET
148
Ian Lance Taylor06272482013-06-12 15:05:10 -0700149// void gogo(Gobuf*)
Russ Cox8522a472009-06-17 15:15:55 -0700150// restore state from Gobuf; longjmp
Keith Randall5a546962013-08-07 10:23:24 -0700151TEXT runtime·gogo(SB), NOSPLIT, $0-4
Russ Cox8522a472009-06-17 15:15:55 -0700152 MOVL 4(SP), BX // gobuf
153 MOVL gobuf_g(BX), DX
154 MOVL 0(DX), CX // make sure g != nil
Hector Chu6bfe5f52010-01-06 17:58:55 -0800155 get_tls(CX)
156 MOVL DX, g(CX)
Russ Cox8522a472009-06-17 15:15:55 -0700157 MOVL gobuf_sp(BX), SP // restore SP
Russ Coxd67e7e32013-06-12 15:22:26 -0400158 MOVL gobuf_ret(BX), AX
159 MOVL gobuf_ctxt(BX), DX
160 MOVL $0, gobuf_sp(BX) // clear to help garbage collector
161 MOVL $0, gobuf_ret(BX)
162 MOVL $0, gobuf_ctxt(BX)
Russ Cox8522a472009-06-17 15:15:55 -0700163 MOVL gobuf_pc(BX), BX
Russ Cox0d3a0432009-03-30 00:01:07 -0700164 JMP BX
Russ Cox8522a472009-06-17 15:15:55 -0700165
Russ Coxf9ca3b52011-03-07 10:37:42 -0500166// void mcall(void (*fn)(G*))
167// Switch to m->g0's stack, call fn(g).
Russ Cox370276a2011-04-27 23:21:12 -0400168// Fn must never return. It should gogo(&g->sched)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500169// to keep running g.
Keith Randall5a546962013-08-07 10:23:24 -0700170TEXT runtime·mcall(SB), NOSPLIT, $0-4
Russ Coxf9ca3b52011-03-07 10:37:42 -0500171 MOVL fn+0(FP), DI
172
173 get_tls(CX)
Russ Cox528534c2013-06-05 07:16:53 -0400174 MOVL g(CX), AX // save state in g->sched
Russ Coxf9ca3b52011-03-07 10:37:42 -0500175 MOVL 0(SP), BX // caller's PC
176 MOVL BX, (g_sched+gobuf_pc)(AX)
177 LEAL 4(SP), BX // caller's SP
178 MOVL BX, (g_sched+gobuf_sp)(AX)
179 MOVL AX, (g_sched+gobuf_g)(AX)
180
181 // switch to m->g0 & its stack, call fn
Russ Cox89f185f2014-06-26 11:54:39 -0400182 MOVL g(CX), BX
183 MOVL g_m(BX), BX
Russ Coxf9ca3b52011-03-07 10:37:42 -0500184 MOVL m_g0(BX), SI
185 CMPL SI, AX // if g == m->g0 call badmcall
Keith Randall32b770b2013-08-29 15:53:34 -0700186 JNE 3(PC)
187 MOVL $runtime·badmcall(SB), AX
188 JMP AX
Russ Coxf9ca3b52011-03-07 10:37:42 -0500189 MOVL SI, g(CX) // g = m->g0
Russ Cox528534c2013-06-05 07:16:53 -0400190 MOVL (g_sched+gobuf_sp)(SI), SP // sp = m->g0->sched.sp
Russ Coxf9ca3b52011-03-07 10:37:42 -0500191 PUSHL AX
192 CALL DI
193 POPL AX
Keith Randall32b770b2013-08-29 15:53:34 -0700194 MOVL $runtime·badmcall2(SB), AX
195 JMP AX
Russ Coxf9ca3b52011-03-07 10:37:42 -0500196 RET
197
Keith Randall4aa50432014-07-30 09:01:52 -0700198// switchtoM is a dummy routine that onM leaves at the bottom
199// of the G stack. We need to distinguish the routine that
200// lives at the bottom of the G stack from the one that lives
201// at the top of the M stack because the one at the top of
202// the M stack terminates the stack walk (see topofstack()).
203TEXT runtime·switchtoM(SB), NOSPLIT, $0-4
204 RET
205
206// void onM(void (*fn)())
207// calls fn() on the M stack.
208// switches to the M stack if not already on it, and
209// switches back when fn() returns.
210TEXT runtime·onM(SB), NOSPLIT, $0-4
211 MOVL fn+0(FP), DI // DI = fn
212 get_tls(CX)
213 MOVL g(CX), AX // AX = g
214 MOVL g_m(AX), BX // BX = m
215 MOVL m_g0(BX), DX // DX = g0
216 CMPL AX, DX
217 JEQ onm
218
219 // save our state in g->sched. Pretend to
220 // be switchtoM if the G stack is scanned.
221 MOVL $runtime·switchtoM(SB), (g_sched+gobuf_pc)(AX)
222 MOVL SP, (g_sched+gobuf_sp)(AX)
223 MOVL AX, (g_sched+gobuf_g)(AX)
224
225 // switch to g0
226 MOVL DX, g(CX)
227 MOVL (g_sched+gobuf_sp)(DX), SP
228
229 // call target function
230 ARGSIZE(0)
231 CALL DI
232
233 // switch back to g
234 get_tls(CX)
235 MOVL g(CX), AX
236 MOVL g_m(AX), BX
237 MOVL m_curg(BX), AX
238 MOVL AX, g(CX)
239 MOVL (g_sched+gobuf_sp)(AX), SP
240 MOVL $0, (g_sched+gobuf_sp)(AX)
241 RET
242
243onm:
244 // already on m stack, just call directly
245 CALL DI
246 RET
247
Russ Cox8522a472009-06-17 15:15:55 -0700248/*
249 * support for morestack
250 */
251
252// Called during function prolog when more stack is needed.
Russ Cox58f12ff2013-07-18 16:53:45 -0400253//
254// The traceback routines see morestack on a g0 as being
255// the top of a stack (for example, morestack calling newstack
256// calling the scheduler calling newm calling gc), so we must
257// record an argument size. For that purpose, it has no arguments.
Keith Randall5a546962013-08-07 10:23:24 -0700258TEXT runtime·morestack(SB),NOSPLIT,$0-0
Russ Cox8522a472009-06-17 15:15:55 -0700259 // Cannot grow scheduler stack (m->g0).
Hector Chu6bfe5f52010-01-06 17:58:55 -0800260 get_tls(CX)
Russ Cox89f185f2014-06-26 11:54:39 -0400261 MOVL g(CX), BX
262 MOVL g_m(BX), BX
Russ Cox8522a472009-06-17 15:15:55 -0700263 MOVL m_g0(BX), SI
Hector Chu6bfe5f52010-01-06 17:58:55 -0800264 CMPL g(CX), SI
Russ Cox8522a472009-06-17 15:15:55 -0700265 JNE 2(PC)
266 INT $3
267
Russ Cox6066fdc2013-02-22 10:47:54 -0500268 // frame size in DI
Russ Cox8522a472009-06-17 15:15:55 -0700269 // arg size in AX
270 // Save in m.
Russ Cox6066fdc2013-02-22 10:47:54 -0500271 MOVL DI, m_moreframesize(BX)
Russ Cox141a4a12011-01-14 14:05:20 -0500272 MOVL AX, m_moreargsize(BX)
Russ Cox8522a472009-06-17 15:15:55 -0700273
274 // Called from f.
275 // Set m->morebuf to f's caller.
276 MOVL 4(SP), DI // f's caller's PC
277 MOVL DI, (m_morebuf+gobuf_pc)(BX)
278 LEAL 8(SP), CX // f's caller's SP
279 MOVL CX, (m_morebuf+gobuf_sp)(BX)
Russ Cox141a4a12011-01-14 14:05:20 -0500280 MOVL CX, m_moreargp(BX)
Hector Chu6bfe5f52010-01-06 17:58:55 -0800281 get_tls(CX)
282 MOVL g(CX), SI
Russ Cox8522a472009-06-17 15:15:55 -0700283 MOVL SI, (m_morebuf+gobuf_g)(BX)
284
Russ Cox6fa3c892013-06-27 11:32:01 -0400285 // Set g->sched to context in f.
286 MOVL 0(SP), AX // f's PC
287 MOVL AX, (g_sched+gobuf_pc)(SI)
288 MOVL SI, (g_sched+gobuf_g)(SI)
289 LEAL 4(SP), AX // f's SP
290 MOVL AX, (g_sched+gobuf_sp)(SI)
291 MOVL DX, (g_sched+gobuf_ctxt)(SI)
Russ Cox8522a472009-06-17 15:15:55 -0700292
Russ Coxf9ca3b52011-03-07 10:37:42 -0500293 // Call newstack on m->g0's stack.
Russ Cox8522a472009-06-17 15:15:55 -0700294 MOVL m_g0(BX), BP
Hector Chu6bfe5f52010-01-06 17:58:55 -0800295 MOVL BP, g(CX)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500296 MOVL (g_sched+gobuf_sp)(BP), AX
Russ Cox7e14bd82010-12-07 17:19:36 -0500297 MOVL -4(AX), BX // fault if CALL would, before smashing SP
298 MOVL AX, SP
Russ Cox68b42552010-11-04 14:00:19 -0400299 CALL runtime·newstack(SB)
Russ Cox8522a472009-06-17 15:15:55 -0700300 MOVL $0, 0x1003 // crash if newstack returns
Russ Cox0d3a0432009-03-30 00:01:07 -0700301 RET
302
Russ Coxc2dd33a2014-03-04 13:53:08 -0500303TEXT runtime·morestack_noctxt(SB),NOSPLIT,$0-0
304 MOVL $0, DX
305 JMP runtime·morestack(SB)
306
Keith Randall9cd57062013-08-02 13:03:14 -0700307// Called from panic. Mimics morestack,
Russ Coxbba278a2009-07-08 18:16:09 -0700308// reuses stack growth code to create a frame
309// with the desired args running the desired function.
310//
311// func call(fn *byte, arg *byte, argsize uint32).
Keith Randall5a546962013-08-07 10:23:24 -0700312TEXT runtime·newstackcall(SB), NOSPLIT, $0-12
Hector Chu6bfe5f52010-01-06 17:58:55 -0800313 get_tls(CX)
Russ Cox89f185f2014-06-26 11:54:39 -0400314 MOVL g(CX), BX
315 MOVL g_m(BX), BX
Russ Coxbba278a2009-07-08 18:16:09 -0700316
317 // Save our caller's state as the PC and SP to
318 // restore when returning from f.
319 MOVL 0(SP), AX // our caller's PC
320 MOVL AX, (m_morebuf+gobuf_pc)(BX)
321 LEAL 4(SP), AX // our caller's SP
322 MOVL AX, (m_morebuf+gobuf_sp)(BX)
Hector Chu6bfe5f52010-01-06 17:58:55 -0800323 MOVL g(CX), AX
Russ Coxbba278a2009-07-08 18:16:09 -0700324 MOVL AX, (m_morebuf+gobuf_g)(BX)
325
Russ Coxf0d73fb2013-06-27 16:51:06 -0400326 // Save our own state as the PC and SP to restore
327 // if this goroutine needs to be restarted.
Keith Randall9cd57062013-08-02 13:03:14 -0700328 MOVL $runtime·newstackcall(SB), (g_sched+gobuf_pc)(AX)
Russ Coxf0d73fb2013-06-27 16:51:06 -0400329 MOVL SP, (g_sched+gobuf_sp)(AX)
330
Russ Coxbba278a2009-07-08 18:16:09 -0700331 // Set up morestack arguments to call f on a new stack.
Russ Cox83727cc2010-03-29 21:48:22 -0700332 // We set f's frame size to 1, as a hint to newstack
Keith Randall9cd57062013-08-02 13:03:14 -0700333 // that this is a call from runtime·newstackcall.
Russ Cox83727cc2010-03-29 21:48:22 -0700334 // If it turns out that f needs a larger frame than
335 // the default stack, f's usual stack growth prolog will
336 // allocate a new segment (and recopy the arguments).
Russ Coxbba278a2009-07-08 18:16:09 -0700337 MOVL 4(SP), AX // fn
338 MOVL 8(SP), DX // arg frame
339 MOVL 12(SP), CX // arg size
340
Russ Cox6fa3c892013-06-27 11:32:01 -0400341 MOVL AX, m_cret(BX) // f's PC
Russ Cox141a4a12011-01-14 14:05:20 -0500342 MOVL DX, m_moreargp(BX) // f's argument pointer
343 MOVL CX, m_moreargsize(BX) // f's argument size
344 MOVL $1, m_moreframesize(BX) // f's frame size
Russ Coxbba278a2009-07-08 18:16:09 -0700345
Russ Coxf9ca3b52011-03-07 10:37:42 -0500346 // Call newstack on m->g0's stack.
Russ Coxbba278a2009-07-08 18:16:09 -0700347 MOVL m_g0(BX), BP
Hector Chu6bfe5f52010-01-06 17:58:55 -0800348 get_tls(CX)
349 MOVL BP, g(CX)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500350 MOVL (g_sched+gobuf_sp)(BP), SP
Russ Cox68b42552010-11-04 14:00:19 -0400351 CALL runtime·newstack(SB)
Russ Coxbba278a2009-07-08 18:16:09 -0700352 MOVL $0, 0x1103 // crash if newstack returns
353 RET
354
Keith Randall9cd57062013-08-02 13:03:14 -0700355// reflect·call: call a function with the given argument list
356// func call(f *FuncVal, arg *byte, argsize uint32).
357// we don't have variable-sized frames, so we use a small number
358// of constant-sized-frame functions to encode a few bits of size in the pc.
359// Caution: ugly multiline assembly macros in your future!
360
361#define DISPATCH(NAME,MAXSIZE) \
362 CMPL CX, $MAXSIZE; \
363 JA 3(PC); \
Rob Pikeaff78832014-07-30 10:11:44 -0700364 MOVL $NAME(SB), AX; \
Keith Randall9cd57062013-08-02 13:03:14 -0700365 JMP AX
Rob Pikeaff78832014-07-30 10:11:44 -0700366// Note: can't just "JMP NAME(SB)" - bad inlining results.
Keith Randall9cd57062013-08-02 13:03:14 -0700367
Russ Cox72c5d5e2014-04-08 11:11:35 -0400368TEXT reflect·call(SB), NOSPLIT, $0-16
Keith Randall9cd57062013-08-02 13:03:14 -0700369 MOVL argsize+8(FP), CX
Rob Pikeaff78832014-07-30 10:11:44 -0700370 DISPATCH(runtime·call16, 16)
371 DISPATCH(runtime·call32, 32)
372 DISPATCH(runtime·call64, 64)
373 DISPATCH(runtime·call128, 128)
374 DISPATCH(runtime·call256, 256)
375 DISPATCH(runtime·call512, 512)
376 DISPATCH(runtime·call1024, 1024)
377 DISPATCH(runtime·call2048, 2048)
378 DISPATCH(runtime·call4096, 4096)
379 DISPATCH(runtime·call8192, 8192)
380 DISPATCH(runtime·call16384, 16384)
381 DISPATCH(runtime·call32768, 32768)
382 DISPATCH(runtime·call65536, 65536)
383 DISPATCH(runtime·call131072, 131072)
384 DISPATCH(runtime·call262144, 262144)
385 DISPATCH(runtime·call524288, 524288)
386 DISPATCH(runtime·call1048576, 1048576)
387 DISPATCH(runtime·call2097152, 2097152)
388 DISPATCH(runtime·call4194304, 4194304)
389 DISPATCH(runtime·call8388608, 8388608)
390 DISPATCH(runtime·call16777216, 16777216)
391 DISPATCH(runtime·call33554432, 33554432)
392 DISPATCH(runtime·call67108864, 67108864)
393 DISPATCH(runtime·call134217728, 134217728)
394 DISPATCH(runtime·call268435456, 268435456)
395 DISPATCH(runtime·call536870912, 536870912)
396 DISPATCH(runtime·call1073741824, 1073741824)
Keith Randall9cd57062013-08-02 13:03:14 -0700397 MOVL $runtime·badreflectcall(SB), AX
398 JMP AX
399
Keith Randallcee8bca2014-05-21 14:28:34 -0700400// Argument map for the callXX frames. Each has one
401// stack map (for the single call) with 3 arguments.
402DATA gcargs_reflectcall<>+0x00(SB)/4, $1 // 1 stackmap
403DATA gcargs_reflectcall<>+0x04(SB)/4, $6 // 3 args
404DATA gcargs_reflectcall<>+0x08(SB)/4, $(const_BitsPointer+(const_BitsPointer<<2)+(const_BitsScalar<<4))
405GLOBL gcargs_reflectcall<>(SB),RODATA,$12
406
407// callXX frames have no locals
408DATA gclocals_reflectcall<>+0x00(SB)/4, $1 // 1 stackmap
409DATA gclocals_reflectcall<>+0x04(SB)/4, $0 // 0 locals
410GLOBL gclocals_reflectcall<>(SB),RODATA,$8
411
Keith Randall12e46e42013-08-06 14:33:55 -0700412#define CALLFN(NAME,MAXSIZE) \
Rob Pikeaff78832014-07-30 10:11:44 -0700413TEXT NAME(SB), WRAPPER, $MAXSIZE-16; \
Keith Randallcee8bca2014-05-21 14:28:34 -0700414 FUNCDATA $FUNCDATA_ArgsPointerMaps,gcargs_reflectcall<>(SB); \
415 FUNCDATA $FUNCDATA_LocalsPointerMaps,gclocals_reflectcall<>(SB);\
Keith Randall9cd57062013-08-02 13:03:14 -0700416 /* copy arguments to stack */ \
417 MOVL argptr+4(FP), SI; \
418 MOVL argsize+8(FP), CX; \
419 MOVL SP, DI; \
420 REP;MOVSB; \
421 /* call function */ \
422 MOVL f+0(FP), DX; \
Russ Cox4a000b92014-02-25 17:00:08 -0500423 MOVL (DX), AX; \
Keith Randallcee8bca2014-05-21 14:28:34 -0700424 PCDATA $PCDATA_StackMapIndex, $0; \
Russ Cox4a000b92014-02-25 17:00:08 -0500425 CALL AX; \
Keith Randall9cd57062013-08-02 13:03:14 -0700426 /* copy return values back */ \
427 MOVL argptr+4(FP), DI; \
428 MOVL argsize+8(FP), CX; \
Russ Cox72c5d5e2014-04-08 11:11:35 -0400429 MOVL retoffset+12(FP), BX; \
Keith Randall9cd57062013-08-02 13:03:14 -0700430 MOVL SP, SI; \
Russ Cox72c5d5e2014-04-08 11:11:35 -0400431 ADDL BX, DI; \
432 ADDL BX, SI; \
433 SUBL BX, CX; \
Keith Randall9cd57062013-08-02 13:03:14 -0700434 REP;MOVSB; \
435 RET
436
Rob Pikeaff78832014-07-30 10:11:44 -0700437CALLFN(runtime·call16, 16)
438CALLFN(runtime·call32, 32)
439CALLFN(runtime·call64, 64)
440CALLFN(runtime·call128, 128)
441CALLFN(runtime·call256, 256)
442CALLFN(runtime·call512, 512)
443CALLFN(runtime·call1024, 1024)
444CALLFN(runtime·call2048, 2048)
445CALLFN(runtime·call4096, 4096)
446CALLFN(runtime·call8192, 8192)
447CALLFN(runtime·call16384, 16384)
448CALLFN(runtime·call32768, 32768)
449CALLFN(runtime·call65536, 65536)
450CALLFN(runtime·call131072, 131072)
451CALLFN(runtime·call262144, 262144)
452CALLFN(runtime·call524288, 524288)
453CALLFN(runtime·call1048576, 1048576)
454CALLFN(runtime·call2097152, 2097152)
455CALLFN(runtime·call4194304, 4194304)
456CALLFN(runtime·call8388608, 8388608)
457CALLFN(runtime·call16777216, 16777216)
458CALLFN(runtime·call33554432, 33554432)
459CALLFN(runtime·call67108864, 67108864)
460CALLFN(runtime·call134217728, 134217728)
461CALLFN(runtime·call268435456, 268435456)
462CALLFN(runtime·call536870912, 536870912)
463CALLFN(runtime·call1073741824, 1073741824)
Russ Coxbba278a2009-07-08 18:16:09 -0700464
Russ Cox8522a472009-06-17 15:15:55 -0700465// Return point when leaving stack.
Russ Cox58f12ff2013-07-18 16:53:45 -0400466//
467// Lessstack can appear in stack traces for the same reason
468// as morestack; in that context, it has 0 arguments.
Keith Randall5a546962013-08-07 10:23:24 -0700469TEXT runtime·lessstack(SB), NOSPLIT, $0-0
Russ Cox8522a472009-06-17 15:15:55 -0700470 // Save return value in m->cret
Hector Chu6bfe5f52010-01-06 17:58:55 -0800471 get_tls(CX)
Russ Cox89f185f2014-06-26 11:54:39 -0400472 MOVL g(CX), BX
473 MOVL g_m(BX), BX
Russ Cox8522a472009-06-17 15:15:55 -0700474 MOVL AX, m_cret(BX)
475
Russ Coxf9ca3b52011-03-07 10:37:42 -0500476 // Call oldstack on m->g0's stack.
477 MOVL m_g0(BX), BP
478 MOVL BP, g(CX)
479 MOVL (g_sched+gobuf_sp)(BP), SP
Russ Cox68b42552010-11-04 14:00:19 -0400480 CALL runtime·oldstack(SB)
Russ Cox8522a472009-06-17 15:15:55 -0700481 MOVL $0, 0x1004 // crash if oldstack returns
482 RET
483
484
Russ Cox0d3a0432009-03-30 00:01:07 -0700485// bool cas(int32 *val, int32 old, int32 new)
486// Atomically:
487// if(*val == old){
488// *val = new;
489// return 1;
490// }else
491// return 0;
Keith Randall5a546962013-08-07 10:23:24 -0700492TEXT runtime·cas(SB), NOSPLIT, $0-12
Russ Cox0d3a0432009-03-30 00:01:07 -0700493 MOVL 4(SP), BX
494 MOVL 8(SP), AX
495 MOVL 12(SP), CX
496 LOCK
497 CMPXCHGL CX, 0(BX)
498 JZ 3(PC)
499 MOVL $0, AX
500 RET
501 MOVL $1, AX
502 RET
503
Russ Coxf70a19f2013-07-12 00:42:46 -0400504// bool runtime·cas64(uint64 *val, uint64 old, uint64 new)
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400505// Atomically:
506// if(*val == *old){
507// *val = new;
508// return 1;
509// } else {
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400510// return 0;
511// }
Keith Randall5a546962013-08-07 10:23:24 -0700512TEXT runtime·cas64(SB), NOSPLIT, $0-20
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400513 MOVL 4(SP), BP
Russ Coxf70a19f2013-07-12 00:42:46 -0400514 MOVL 8(SP), AX
515 MOVL 12(SP), DX
516 MOVL 16(SP), BX
517 MOVL 20(SP), CX
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400518 LOCK
519 CMPXCHG8B 0(BP)
520 JNZ cas64_fail
521 MOVL $1, AX
522 RET
523cas64_fail:
Dmitriy Vyukovfd04f052012-04-05 18:59:50 +0400524 MOVL $0, AX
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400525 RET
526
Hector Chu6bfe5f52010-01-06 17:58:55 -0800527// bool casp(void **p, void *old, void *new)
528// Atomically:
529// if(*p == old){
530// *p = new;
531// return 1;
532// }else
533// return 0;
Keith Randall5a546962013-08-07 10:23:24 -0700534TEXT runtime·casp(SB), NOSPLIT, $0-12
Hector Chu6bfe5f52010-01-06 17:58:55 -0800535 MOVL 4(SP), BX
536 MOVL 8(SP), AX
537 MOVL 12(SP), CX
538 LOCK
539 CMPXCHGL CX, 0(BX)
540 JZ 3(PC)
541 MOVL $0, AX
542 RET
543 MOVL $1, AX
544 RET
545
Dmitriy Vyukov491aa152011-07-15 11:27:16 -0400546// uint32 xadd(uint32 volatile *val, int32 delta)
547// Atomically:
548// *val += delta;
549// return *val;
Keith Randall5a546962013-08-07 10:23:24 -0700550TEXT runtime·xadd(SB), NOSPLIT, $0-8
Dmitriy Vyukov491aa152011-07-15 11:27:16 -0400551 MOVL 4(SP), BX
552 MOVL 8(SP), AX
553 MOVL AX, CX
554 LOCK
555 XADDL AX, 0(BX)
556 ADDL CX, AX
557 RET
558
Keith Randall5a546962013-08-07 10:23:24 -0700559TEXT runtime·xchg(SB), NOSPLIT, $0-8
Dmitriy Vyukov4e5086b2011-07-29 12:44:06 -0400560 MOVL 4(SP), BX
561 MOVL 8(SP), AX
562 XCHGL AX, 0(BX)
563 RET
564
Dmitriy Vyukov9cbd2fb2014-01-22 11:27:16 +0400565TEXT runtime·xchgp(SB), NOSPLIT, $0-8
566 MOVL 4(SP), BX
567 MOVL 8(SP), AX
568 XCHGL AX, 0(BX)
569 RET
570
Keith Randall5a546962013-08-07 10:23:24 -0700571TEXT runtime·procyield(SB),NOSPLIT,$0-0
Dmitriy Vyukov4e5086b2011-07-29 12:44:06 -0400572 MOVL 4(SP), AX
573again:
574 PAUSE
575 SUBL $1, AX
576 JNZ again
577 RET
578
Keith Randall5a546962013-08-07 10:23:24 -0700579TEXT runtime·atomicstorep(SB), NOSPLIT, $0-8
Dmitriy Vyukov86a659c2011-07-13 11:22:41 -0700580 MOVL 4(SP), BX
581 MOVL 8(SP), AX
582 XCHGL AX, 0(BX)
583 RET
584
Keith Randall5a546962013-08-07 10:23:24 -0700585TEXT runtime·atomicstore(SB), NOSPLIT, $0-8
Dmitriy Vyukov91f0f182011-07-29 13:47:24 -0400586 MOVL 4(SP), BX
587 MOVL 8(SP), AX
588 XCHGL AX, 0(BX)
589 RET
590
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400591// uint64 atomicload64(uint64 volatile* addr);
592// so actually
593// void atomicload64(uint64 *res, uint64 volatile *addr);
Keith Randall5a546962013-08-07 10:23:24 -0700594TEXT runtime·atomicload64(SB), NOSPLIT, $0-8
Brad Fitzpatrick598c7892013-08-05 15:04:05 -0700595 MOVL 4(SP), BX
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400596 MOVL 8(SP), AX
597 // MOVQ (%EAX), %MM0
598 BYTE $0x0f; BYTE $0x6f; BYTE $0x00
599 // MOVQ %MM0, 0(%EBX)
600 BYTE $0x0f; BYTE $0x7f; BYTE $0x03
601 // EMMS
602 BYTE $0x0F; BYTE $0x77
603 RET
604
605// void runtime·atomicstore64(uint64 volatile* addr, uint64 v);
Keith Randall5a546962013-08-07 10:23:24 -0700606TEXT runtime·atomicstore64(SB), NOSPLIT, $0-12
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400607 MOVL 4(SP), AX
608 // MOVQ and EMMS were introduced on the Pentium MMX.
609 // MOVQ 0x8(%ESP), %MM0
610 BYTE $0x0f; BYTE $0x6f; BYTE $0x44; BYTE $0x24; BYTE $0x08
611 // MOVQ %MM0, (%EAX)
612 BYTE $0x0f; BYTE $0x7f; BYTE $0x00
613 // EMMS
614 BYTE $0x0F; BYTE $0x77
615 // This is essentially a no-op, but it provides required memory fencing.
616 // It can be replaced with MFENCE, but MFENCE was introduced only on the Pentium4 (SSE2).
617 MOVL $0, AX
618 LOCK
619 XADDL AX, (SP)
620 RET
621
Russ Coxaa3222d82009-06-02 23:02:12 -0700622// void jmpdefer(fn, sp);
623// called from deferreturn.
Russ Cox0d3a0432009-03-30 00:01:07 -0700624// 1. pop the caller
625// 2. sub 5 bytes from the callers return
626// 3. jmp to the argument
Keith Randalla97a91d2013-08-07 14:03:50 -0700627TEXT runtime·jmpdefer(SB), NOSPLIT, $0-8
Russ Cox6066fdc2013-02-22 10:47:54 -0500628 MOVL 4(SP), DX // fn
Russ Coxaa3222d82009-06-02 23:02:12 -0700629 MOVL 8(SP), BX // caller sp
630 LEAL -4(BX), SP // caller sp after CALL
631 SUBL $5, (SP) // return to CALL again
Russ Cox6066fdc2013-02-22 10:47:54 -0500632 MOVL 0(DX), BX
Russ Cox1903ad72013-02-21 17:01:13 -0500633 JMP BX // but first run the deferred function
Russ Cox0d3a0432009-03-30 00:01:07 -0700634
Russ Coxd67e7e32013-06-12 15:22:26 -0400635// Save state of caller into g->sched.
Keith Randall5a546962013-08-07 10:23:24 -0700636TEXT gosave<>(SB),NOSPLIT,$0
Russ Coxd67e7e32013-06-12 15:22:26 -0400637 PUSHL AX
638 PUSHL BX
639 get_tls(BX)
640 MOVL g(BX), BX
641 LEAL arg+0(FP), AX
642 MOVL AX, (g_sched+gobuf_sp)(BX)
643 MOVL -4(AX), AX
644 MOVL AX, (g_sched+gobuf_pc)(BX)
645 MOVL $0, (g_sched+gobuf_ret)(BX)
646 MOVL $0, (g_sched+gobuf_ctxt)(BX)
647 POPL BX
648 POPL AX
Russ Coxf9ca3b52011-03-07 10:37:42 -0500649 RET
650
651// asmcgocall(void(*fn)(void*), void *arg)
652// Call fn(arg) on the scheduler stack,
653// aligned appropriately for the gcc ABI.
654// See cgocall.c for more details.
Keith Randall5a546962013-08-07 10:23:24 -0700655TEXT runtime·asmcgocall(SB),NOSPLIT,$0-8
Russ Coxf9ca3b52011-03-07 10:37:42 -0500656 MOVL fn+0(FP), AX
657 MOVL arg+4(FP), BX
658 MOVL SP, DX
659
660 // Figure out if we need to switch to m->g0 stack.
661 // We get called to create new OS threads too, and those
662 // come in on the m->g0 stack already.
663 get_tls(CX)
Russ Cox89f185f2014-06-26 11:54:39 -0400664 MOVL g(CX), BP
665 MOVL g_m(BP), BP
Russ Coxf9ca3b52011-03-07 10:37:42 -0500666 MOVL m_g0(BP), SI
667 MOVL g(CX), DI
668 CMPL SI, DI
Russ Coxd67e7e32013-06-12 15:22:26 -0400669 JEQ 4(PC)
670 CALL gosave<>(SB)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500671 MOVL SI, g(CX)
672 MOVL (g_sched+gobuf_sp)(SI), SP
673
674 // Now on a scheduling stack (a pthread-created stack).
675 SUBL $32, SP
676 ANDL $~15, SP // alignment, perhaps unnecessary
677 MOVL DI, 8(SP) // save g
678 MOVL DX, 4(SP) // save SP
679 MOVL BX, 0(SP) // first argument in x86-32 ABI
680 CALL AX
681
682 // Restore registers, g, stack pointer.
683 get_tls(CX)
684 MOVL 8(SP), DI
685 MOVL DI, g(CX)
686 MOVL 4(SP), SP
687 RET
688
689// cgocallback(void (*fn)(void*), void *frame, uintptr framesize)
Russ Cox3d2dfc52013-02-22 16:08:56 -0500690// Turn the fn into a Go func (by taking its address) and call
691// cgocallback_gofunc.
Keith Randall5a546962013-08-07 10:23:24 -0700692TEXT runtime·cgocallback(SB),NOSPLIT,$12-12
Russ Cox3d2dfc52013-02-22 16:08:56 -0500693 LEAL fn+0(FP), AX
694 MOVL AX, 0(SP)
695 MOVL frame+4(FP), AX
696 MOVL AX, 4(SP)
697 MOVL framesize+8(FP), AX
698 MOVL AX, 8(SP)
699 MOVL $runtime·cgocallback_gofunc(SB), AX
700 CALL AX
701 RET
702
703// cgocallback_gofunc(FuncVal*, void *frame, uintptr framesize)
704// See cgocall.c for more details.
Keith Randall5a546962013-08-07 10:23:24 -0700705TEXT runtime·cgocallback_gofunc(SB),NOSPLIT,$12-12
Russ Cox89f185f2014-06-26 11:54:39 -0400706 // If g is nil, Go did not create the current thread.
Russ Cox6c976392013-02-20 17:48:23 -0500707 // Call needm to obtain one for temporary use.
708 // In this case, we're running on the thread stack, so there's
709 // lots of space, but the linker doesn't know. Hide the call from
710 // the linker analysis by using an indirect call through AX.
711 get_tls(CX)
712#ifdef GOOS_windows
Russ Coxdba623b2013-07-23 18:40:02 -0400713 MOVL $0, BP
Russ Cox6c976392013-02-20 17:48:23 -0500714 CMPL CX, $0
Russ Cox89f185f2014-06-26 11:54:39 -0400715 JEQ 2(PC) // TODO
Russ Cox6c976392013-02-20 17:48:23 -0500716#endif
Russ Cox89f185f2014-06-26 11:54:39 -0400717 MOVL g(CX), BP
Russ Cox6c976392013-02-20 17:48:23 -0500718 CMPL BP, $0
Russ Cox89f185f2014-06-26 11:54:39 -0400719 JEQ needm
720 MOVL g_m(BP), BP
721 MOVL BP, DX // saved copy of oldm
722 JMP havem
Russ Cox6c976392013-02-20 17:48:23 -0500723needm:
Russ Cox89f185f2014-06-26 11:54:39 -0400724 MOVL $0, 0(SP)
Russ Cox6c976392013-02-20 17:48:23 -0500725 MOVL $runtime·needm(SB), AX
726 CALL AX
Russ Coxf0112822013-07-24 09:01:57 -0400727 MOVL 0(SP), DX
Russ Coxf9ca3b52011-03-07 10:37:42 -0500728 get_tls(CX)
Russ Cox89f185f2014-06-26 11:54:39 -0400729 MOVL g(CX), BP
730 MOVL g_m(BP), BP
Russ Cox9b732382012-03-08 12:12:40 -0500731
Russ Cox6c976392013-02-20 17:48:23 -0500732havem:
733 // Now there's a valid m, and we're running on its m->g0.
734 // Save current m->g0->sched.sp on stack and then set it to SP.
735 // Save current sp in m->g0->sched.sp in preparation for
736 // switch back to m->curg stack.
Russ Coxdba623b2013-07-23 18:40:02 -0400737 // NOTE: unwindm knows that the saved g->sched.sp is at 0(SP).
Russ Coxf9ca3b52011-03-07 10:37:42 -0500738 MOVL m_g0(BP), SI
Russ Coxdba623b2013-07-23 18:40:02 -0400739 MOVL (g_sched+gobuf_sp)(SI), AX
740 MOVL AX, 0(SP)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500741 MOVL SP, (g_sched+gobuf_sp)(SI)
742
Russ Coxdba623b2013-07-23 18:40:02 -0400743 // Switch to m->curg stack and call runtime.cgocallbackg.
744 // Because we are taking over the execution of m->curg
745 // but *not* resuming what had been running, we need to
746 // save that information (m->curg->sched) so we can restore it.
Russ Cox528534c2013-06-05 07:16:53 -0400747 // We can restore m->curg->sched.sp easily, because calling
Alex Brainman72e83482011-08-18 12:17:09 -0400748 // runtime.cgocallbackg leaves SP unchanged upon return.
Russ Cox528534c2013-06-05 07:16:53 -0400749 // To save m->curg->sched.pc, we push it onto the stack.
Russ Coxf9ca3b52011-03-07 10:37:42 -0500750 // This has the added benefit that it looks to the traceback
Alex Brainman72e83482011-08-18 12:17:09 -0400751 // routine like cgocallbackg is going to return to that
Russ Coxdba623b2013-07-23 18:40:02 -0400752 // PC (because the frame we allocate below has the same
753 // size as cgocallback_gofunc's frame declared above)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500754 // so that the traceback will seamlessly trace back into
755 // the earlier calls.
Russ Coxdba623b2013-07-23 18:40:02 -0400756 //
Russ Coxf0112822013-07-24 09:01:57 -0400757 // In the new goroutine, 0(SP) holds the saved oldm (DX) register.
758 // 4(SP) and 8(SP) are unused.
Russ Coxf9ca3b52011-03-07 10:37:42 -0500759 MOVL m_curg(BP), SI
760 MOVL SI, g(CX)
Russ Coxdba623b2013-07-23 18:40:02 -0400761 MOVL (g_sched+gobuf_sp)(SI), DI // prepare stack as DI
Russ Coxf9ca3b52011-03-07 10:37:42 -0500762 MOVL (g_sched+gobuf_pc)(SI), BP
Russ Coxdba623b2013-07-23 18:40:02 -0400763 MOVL BP, -4(DI)
Russ Coxf0112822013-07-24 09:01:57 -0400764 LEAL -(4+12)(DI), SP
765 MOVL DX, 0(SP)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500766 CALL runtime·cgocallbackg(SB)
Russ Coxf0112822013-07-24 09:01:57 -0400767 MOVL 0(SP), DX
Russ Coxf9ca3b52011-03-07 10:37:42 -0500768
Russ Cox528534c2013-06-05 07:16:53 -0400769 // Restore g->sched (== m->curg->sched) from saved values.
Russ Coxf9ca3b52011-03-07 10:37:42 -0500770 get_tls(CX)
771 MOVL g(CX), SI
Russ Coxf0112822013-07-24 09:01:57 -0400772 MOVL 12(SP), BP
Russ Coxf9ca3b52011-03-07 10:37:42 -0500773 MOVL BP, (g_sched+gobuf_pc)(SI)
Russ Coxf0112822013-07-24 09:01:57 -0400774 LEAL (12+4)(SP), DI
Russ Coxf9ca3b52011-03-07 10:37:42 -0500775 MOVL DI, (g_sched+gobuf_sp)(SI)
776
777 // Switch back to m->g0's stack and restore m->g0->sched.sp.
778 // (Unlike m->curg, the g0 goroutine never uses sched.pc,
779 // so we do not have to restore it.)
Russ Cox89f185f2014-06-26 11:54:39 -0400780 MOVL g(CX), BP
781 MOVL g_m(BP), BP
Russ Coxf9ca3b52011-03-07 10:37:42 -0500782 MOVL m_g0(BP), SI
783 MOVL SI, g(CX)
784 MOVL (g_sched+gobuf_sp)(SI), SP
Russ Coxdba623b2013-07-23 18:40:02 -0400785 MOVL 0(SP), AX
786 MOVL AX, (g_sched+gobuf_sp)(SI)
Russ Cox6c976392013-02-20 17:48:23 -0500787
788 // If the m on entry was nil, we called needm above to borrow an m
789 // for the duration of the call. Since the call is over, return it with dropm.
Russ Coxf0112822013-07-24 09:01:57 -0400790 CMPL DX, $0
Russ Cox6c976392013-02-20 17:48:23 -0500791 JNE 3(PC)
792 MOVL $runtime·dropm(SB), AX
793 CALL AX
Russ Coxf9ca3b52011-03-07 10:37:42 -0500794
795 // Done!
796 RET
797
Russ Cox89f185f2014-06-26 11:54:39 -0400798// void setg(G*); set g. for use by needm.
799TEXT runtime·setg(SB), NOSPLIT, $0-8
800 MOVL gg+0(FP), BX
Russ Cox6c976392013-02-20 17:48:23 -0500801#ifdef GOOS_windows
Russ Cox89f185f2014-06-26 11:54:39 -0400802 CMPL BX, $0
Russ Cox6c976392013-02-20 17:48:23 -0500803 JNE settls
804 MOVL $0, 0x14(FS)
805 RET
806settls:
Russ Cox89f185f2014-06-26 11:54:39 -0400807 MOVL g_m(BX), AX
Russ Cox6c976392013-02-20 17:48:23 -0500808 LEAL m_tls(AX), AX
809 MOVL AX, 0x14(FS)
810#endif
Russ Cox6c976392013-02-20 17:48:23 -0500811 get_tls(CX)
Russ Cox6c976392013-02-20 17:48:23 -0500812 MOVL BX, g(CX)
813 RET
814
Russ Cox89f185f2014-06-26 11:54:39 -0400815// void setg_gcc(G*); set g. for use by gcc
816TEXT setg_gcc<>(SB), NOSPLIT, $0
Russ Cox6a70f9d2013-03-25 18:14:02 -0400817 get_tls(AX)
Russ Cox89f185f2014-06-26 11:54:39 -0400818 MOVL gg+0(FP), DX
819 MOVL DX, g(AX)
Russ Cox6a70f9d2013-03-25 18:14:02 -0400820 RET
821
Russ Coxf9ca3b52011-03-07 10:37:42 -0500822// check that SP is in range [g->stackbase, g->stackguard)
Keith Randall5a546962013-08-07 10:23:24 -0700823TEXT runtime·stackcheck(SB), NOSPLIT, $0-0
Russ Coxf9ca3b52011-03-07 10:37:42 -0500824 get_tls(CX)
825 MOVL g(CX), AX
826 CMPL g_stackbase(AX), SP
827 JHI 2(PC)
828 INT $3
829 CMPL SP, g_stackguard(AX)
830 JHI 2(PC)
831 INT $3
832 RET
833
Keith Randall5a546962013-08-07 10:23:24 -0700834TEXT runtime·getcallerpc(SB),NOSPLIT,$0-4
Russ Cox0d3a0432009-03-30 00:01:07 -0700835 MOVL x+0(FP),AX // addr of first arg
836 MOVL -4(AX),AX // get calling pc
837 RET
838
Keith Randall61dca942014-06-16 23:03:03 -0700839TEXT runtime·gogetcallerpc(SB),NOSPLIT,$0-8
Keith Randall14c81432014-06-17 21:59:50 -0700840 MOVL p+0(FP),AX // addr of first arg
Keith Randall61dca942014-06-16 23:03:03 -0700841 MOVL -4(AX),AX // get calling pc
Keith Randall14c81432014-06-17 21:59:50 -0700842 MOVL AX, ret+4(FP)
Keith Randall61dca942014-06-16 23:03:03 -0700843 RET
844
Keith Randall5a546962013-08-07 10:23:24 -0700845TEXT runtime·setcallerpc(SB),NOSPLIT,$0-8
Russ Cox0d3a0432009-03-30 00:01:07 -0700846 MOVL x+0(FP),AX // addr of first arg
847 MOVL x+4(FP), BX
848 MOVL BX, -4(AX) // set calling pc
849 RET
850
Keith Randall5a546962013-08-07 10:23:24 -0700851TEXT runtime·getcallersp(SB), NOSPLIT, $0-4
Russ Cox6c196012010-04-05 12:51:09 -0700852 MOVL sp+0(FP), AX
853 RET
854
Damian Gryski8e765da2012-02-02 14:09:27 -0500855// int64 runtime·cputicks(void), so really
856// void runtime·cputicks(int64 *ticks)
Keith Randall5a546962013-08-07 10:23:24 -0700857TEXT runtime·cputicks(SB),NOSPLIT,$0-4
Shenghou Ma6392b432012-02-06 12:49:28 -0500858 RDTSC
Damian Gryski8e765da2012-02-02 14:09:27 -0500859 MOVL ret+0(FP), DI
860 MOVL AX, 0(DI)
861 MOVL DX, 4(DI)
862 RET
863
Keith Randall5a546962013-08-07 10:23:24 -0700864TEXT runtime·ldt0setup(SB),NOSPLIT,$16-0
Russ Cox0d3a0432009-03-30 00:01:07 -0700865 // set up ldt 7 to point at tls0
866 // 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 -0700867 // the entry number is just a hint. setldt will set up GS with what it used.
Russ Cox0d3a0432009-03-30 00:01:07 -0700868 MOVL $7, 0(SP)
Russ Cox68b42552010-11-04 14:00:19 -0400869 LEAL runtime·tls0(SB), AX
Russ Cox0d3a0432009-03-30 00:01:07 -0700870 MOVL AX, 4(SP)
871 MOVL $32, 8(SP) // sizeof(tls array)
Russ Cox68b42552010-11-04 14:00:19 -0400872 CALL runtime·setldt(SB)
Russ Cox0d3a0432009-03-30 00:01:07 -0700873 RET
874
Russ Cox9ddfb642013-07-16 16:24:09 -0400875TEXT runtime·emptyfunc(SB),0,$0-0
Russ Cox0d3a0432009-03-30 00:01:07 -0700876 RET
877
Keith Randall5a546962013-08-07 10:23:24 -0700878TEXT runtime·abort(SB),NOSPLIT,$0-0
Russ Cox0d3a0432009-03-30 00:01:07 -0700879 INT $0x3
Russ Cox133a1582009-10-03 10:37:12 -0700880
Keith Randall5a546962013-08-07 10:23:24 -0700881TEXT runtime·stackguard(SB),NOSPLIT,$0-8
Russ Cox9e5db8c2012-03-15 15:22:30 -0400882 MOVL SP, DX
883 MOVL DX, sp+0(FP)
884 get_tls(CX)
885 MOVL g(CX), BX
886 MOVL g_stackguard(BX), DX
Russ Cox07720b62013-03-22 12:57:55 -0400887 MOVL DX, limit+4(FP)
Russ Cox9e5db8c2012-03-15 15:22:30 -0400888 RET
889
Russ Cox68b42552010-11-04 14:00:19 -0400890GLOBL runtime·tls0(SB), $32
Keith Randalla5d40242013-03-12 10:47:44 -0700891
892// hash function using AES hardware instructions
Keith Randalla2a97682014-07-31 15:07:05 -0700893TEXT runtime·aeshash(SB),NOSPLIT,$0-16
894 MOVL p+0(FP), AX // ptr to data
895 MOVL s+4(FP), CX // size
Keith Randalla5d40242013-03-12 10:47:44 -0700896 JMP runtime·aeshashbody(SB)
897
Keith Randalla2a97682014-07-31 15:07:05 -0700898TEXT runtime·aeshashstr(SB),NOSPLIT,$0-16
899 MOVL p+0(FP), AX // ptr to string object
900 // s+4(FP) is ignored, it is always sizeof(String)
Keith Randalla5d40242013-03-12 10:47:44 -0700901 MOVL 4(AX), CX // length of string
902 MOVL (AX), AX // string data
903 JMP runtime·aeshashbody(SB)
904
905// AX: data
906// CX: length
Keith Randalla2a97682014-07-31 15:07:05 -0700907TEXT runtime·aeshashbody(SB),NOSPLIT,$0-16
908 MOVL h+8(FP), X0 // seed to low 32 bits of xmm0
Keith Randalla5d40242013-03-12 10:47:44 -0700909 PINSRD $1, CX, X0 // size to next 32 bits of xmm0
Keith Randalldb53d972013-03-20 14:34:26 -0700910 MOVO runtime·aeskeysched+0(SB), X2
911 MOVO runtime·aeskeysched+16(SB), X3
Keith Randallee669722013-05-15 09:40:14 -0700912 CMPL CX, $16
913 JB aessmall
Keith Randalla5d40242013-03-12 10:47:44 -0700914aesloop:
915 CMPL CX, $16
Keith Randallee669722013-05-15 09:40:14 -0700916 JBE aesloopend
Keith Randalla5d40242013-03-12 10:47:44 -0700917 MOVOU (AX), X1
918 AESENC X2, X0
919 AESENC X1, X0
920 SUBL $16, CX
921 ADDL $16, AX
922 JMP aesloop
Keith Randallee669722013-05-15 09:40:14 -0700923// 1-16 bytes remaining
Keith Randalla5d40242013-03-12 10:47:44 -0700924aesloopend:
Keith Randallee669722013-05-15 09:40:14 -0700925 // This load may overlap with the previous load above.
926 // We'll hash some bytes twice, but that's ok.
927 MOVOU -16(AX)(CX*1), X1
928 JMP partial
929// 0-15 bytes
930aessmall:
Keith Randalla5d40242013-03-12 10:47:44 -0700931 TESTL CX, CX
Keith Randallee669722013-05-15 09:40:14 -0700932 JE finalize // 0 bytes
Keith Randalla5d40242013-03-12 10:47:44 -0700933
Keith Randallee669722013-05-15 09:40:14 -0700934 CMPB AX, $0xf0
935 JA highpartial
Keith Randalla5d40242013-03-12 10:47:44 -0700936
Keith Randallee669722013-05-15 09:40:14 -0700937 // 16 bytes loaded at this address won't cross
938 // a page boundary, so we can load it directly.
Keith Randalla5d40242013-03-12 10:47:44 -0700939 MOVOU (AX), X1
940 ADDL CX, CX
Russ Cox9ddfb642013-07-16 16:24:09 -0400941 PAND masks<>(SB)(CX*8), X1
Keith Randalla5d40242013-03-12 10:47:44 -0700942 JMP partial
943highpartial:
Keith Randallee669722013-05-15 09:40:14 -0700944 // address ends in 1111xxxx. Might be up against
Keith Randalla5d40242013-03-12 10:47:44 -0700945 // a page boundary, so load ending at last byte.
946 // Then shift bytes down using pshufb.
947 MOVOU -16(AX)(CX*1), X1
948 ADDL CX, CX
Russ Cox9ddfb642013-07-16 16:24:09 -0400949 PSHUFB shifts<>(SB)(CX*8), X1
Keith Randalla5d40242013-03-12 10:47:44 -0700950partial:
951 // incorporate partial block into hash
952 AESENC X3, X0
953 AESENC X1, X0
954finalize:
955 // finalize hash
956 AESENC X2, X0
957 AESENC X3, X0
958 AESENC X2, X0
Keith Randalla2a97682014-07-31 15:07:05 -0700959 MOVL X0, res+12(FP)
Keith Randalla5d40242013-03-12 10:47:44 -0700960 RET
961
Keith Randalla2a97682014-07-31 15:07:05 -0700962TEXT runtime·aeshash32(SB),NOSPLIT,$0-16
963 MOVL p+0(FP), AX // ptr to data
964 // s+4(FP) is ignored, it is always sizeof(int32)
965 MOVL h+8(FP), X0 // seed
Keith Randalla5d40242013-03-12 10:47:44 -0700966 PINSRD $1, (AX), X0 // data
Keith Randalldb53d972013-03-20 14:34:26 -0700967 AESENC runtime·aeskeysched+0(SB), X0
968 AESENC runtime·aeskeysched+16(SB), X0
969 AESENC runtime·aeskeysched+0(SB), X0
Keith Randalla2a97682014-07-31 15:07:05 -0700970 MOVL X0, res+12(FP)
Keith Randalla5d40242013-03-12 10:47:44 -0700971 RET
972
Keith Randalla2a97682014-07-31 15:07:05 -0700973TEXT runtime·aeshash64(SB),NOSPLIT,$0-16
974 MOVL p+0(FP), AX // ptr to data
975 // s+4(FP) is ignored, it is always sizeof(int64)
Keith Randalla5d40242013-03-12 10:47:44 -0700976 MOVQ (AX), X0 // data
Keith Randalla2a97682014-07-31 15:07:05 -0700977 PINSRD $2, h+8(FP), X0 // seed
Keith Randalldb53d972013-03-20 14:34:26 -0700978 AESENC runtime·aeskeysched+0(SB), X0
979 AESENC runtime·aeskeysched+16(SB), X0
980 AESENC runtime·aeskeysched+0(SB), X0
Keith Randalla2a97682014-07-31 15:07:05 -0700981 MOVL X0, res+12(FP)
Keith Randalla5d40242013-03-12 10:47:44 -0700982 RET
983
Keith Randalla5d40242013-03-12 10:47:44 -0700984// simple mask to get rid of data in the high part of the register.
Russ Cox9ddfb642013-07-16 16:24:09 -0400985DATA masks<>+0x00(SB)/4, $0x00000000
986DATA masks<>+0x04(SB)/4, $0x00000000
987DATA masks<>+0x08(SB)/4, $0x00000000
988DATA masks<>+0x0c(SB)/4, $0x00000000
Keith Randalla5d40242013-03-12 10:47:44 -0700989
Russ Cox9ddfb642013-07-16 16:24:09 -0400990DATA masks<>+0x10(SB)/4, $0x000000ff
991DATA masks<>+0x14(SB)/4, $0x00000000
992DATA masks<>+0x18(SB)/4, $0x00000000
993DATA masks<>+0x1c(SB)/4, $0x00000000
Keith Randalla5d40242013-03-12 10:47:44 -0700994
Russ Cox9ddfb642013-07-16 16:24:09 -0400995DATA masks<>+0x20(SB)/4, $0x0000ffff
996DATA masks<>+0x24(SB)/4, $0x00000000
997DATA masks<>+0x28(SB)/4, $0x00000000
998DATA masks<>+0x2c(SB)/4, $0x00000000
Keith Randalla5d40242013-03-12 10:47:44 -0700999
Russ Cox9ddfb642013-07-16 16:24:09 -04001000DATA masks<>+0x30(SB)/4, $0x00ffffff
1001DATA masks<>+0x34(SB)/4, $0x00000000
1002DATA masks<>+0x38(SB)/4, $0x00000000
1003DATA masks<>+0x3c(SB)/4, $0x00000000
Keith Randalla5d40242013-03-12 10:47:44 -07001004
Russ Cox9ddfb642013-07-16 16:24:09 -04001005DATA masks<>+0x40(SB)/4, $0xffffffff
1006DATA masks<>+0x44(SB)/4, $0x00000000
1007DATA masks<>+0x48(SB)/4, $0x00000000
1008DATA masks<>+0x4c(SB)/4, $0x00000000
Keith Randalla5d40242013-03-12 10:47:44 -07001009
Russ Cox9ddfb642013-07-16 16:24:09 -04001010DATA masks<>+0x50(SB)/4, $0xffffffff
1011DATA masks<>+0x54(SB)/4, $0x000000ff
1012DATA masks<>+0x58(SB)/4, $0x00000000
1013DATA masks<>+0x5c(SB)/4, $0x00000000
Keith Randalla5d40242013-03-12 10:47:44 -07001014
Russ Cox9ddfb642013-07-16 16:24:09 -04001015DATA masks<>+0x60(SB)/4, $0xffffffff
1016DATA masks<>+0x64(SB)/4, $0x0000ffff
1017DATA masks<>+0x68(SB)/4, $0x00000000
1018DATA masks<>+0x6c(SB)/4, $0x00000000
Keith Randalla5d40242013-03-12 10:47:44 -07001019
Russ Cox9ddfb642013-07-16 16:24:09 -04001020DATA masks<>+0x70(SB)/4, $0xffffffff
1021DATA masks<>+0x74(SB)/4, $0x00ffffff
1022DATA masks<>+0x78(SB)/4, $0x00000000
1023DATA masks<>+0x7c(SB)/4, $0x00000000
Keith Randalla5d40242013-03-12 10:47:44 -07001024
Russ Cox9ddfb642013-07-16 16:24:09 -04001025DATA masks<>+0x80(SB)/4, $0xffffffff
1026DATA masks<>+0x84(SB)/4, $0xffffffff
1027DATA masks<>+0x88(SB)/4, $0x00000000
1028DATA masks<>+0x8c(SB)/4, $0x00000000
Keith Randalla5d40242013-03-12 10:47:44 -07001029
Russ Cox9ddfb642013-07-16 16:24:09 -04001030DATA masks<>+0x90(SB)/4, $0xffffffff
1031DATA masks<>+0x94(SB)/4, $0xffffffff
1032DATA masks<>+0x98(SB)/4, $0x000000ff
1033DATA masks<>+0x9c(SB)/4, $0x00000000
Keith Randalla5d40242013-03-12 10:47:44 -07001034
Russ Cox9ddfb642013-07-16 16:24:09 -04001035DATA masks<>+0xa0(SB)/4, $0xffffffff
1036DATA masks<>+0xa4(SB)/4, $0xffffffff
1037DATA masks<>+0xa8(SB)/4, $0x0000ffff
1038DATA masks<>+0xac(SB)/4, $0x00000000
Keith Randalla5d40242013-03-12 10:47:44 -07001039
Russ Cox9ddfb642013-07-16 16:24:09 -04001040DATA masks<>+0xb0(SB)/4, $0xffffffff
1041DATA masks<>+0xb4(SB)/4, $0xffffffff
1042DATA masks<>+0xb8(SB)/4, $0x00ffffff
1043DATA masks<>+0xbc(SB)/4, $0x00000000
Keith Randalla5d40242013-03-12 10:47:44 -07001044
Russ Cox9ddfb642013-07-16 16:24:09 -04001045DATA masks<>+0xc0(SB)/4, $0xffffffff
1046DATA masks<>+0xc4(SB)/4, $0xffffffff
1047DATA masks<>+0xc8(SB)/4, $0xffffffff
1048DATA masks<>+0xcc(SB)/4, $0x00000000
Keith Randalla5d40242013-03-12 10:47:44 -07001049
Russ Cox9ddfb642013-07-16 16:24:09 -04001050DATA masks<>+0xd0(SB)/4, $0xffffffff
1051DATA masks<>+0xd4(SB)/4, $0xffffffff
1052DATA masks<>+0xd8(SB)/4, $0xffffffff
1053DATA masks<>+0xdc(SB)/4, $0x000000ff
Keith Randalla5d40242013-03-12 10:47:44 -07001054
Russ Cox9ddfb642013-07-16 16:24:09 -04001055DATA masks<>+0xe0(SB)/4, $0xffffffff
1056DATA masks<>+0xe4(SB)/4, $0xffffffff
1057DATA masks<>+0xe8(SB)/4, $0xffffffff
1058DATA masks<>+0xec(SB)/4, $0x0000ffff
Keith Randalla5d40242013-03-12 10:47:44 -07001059
Russ Cox9ddfb642013-07-16 16:24:09 -04001060DATA masks<>+0xf0(SB)/4, $0xffffffff
1061DATA masks<>+0xf4(SB)/4, $0xffffffff
1062DATA masks<>+0xf8(SB)/4, $0xffffffff
1063DATA masks<>+0xfc(SB)/4, $0x00ffffff
Keith Randalla5d40242013-03-12 10:47:44 -07001064
Keith Randall5a546962013-08-07 10:23:24 -07001065GLOBL masks<>(SB),RODATA,$256
Keith Randalla5d40242013-03-12 10:47:44 -07001066
Russ Cox9ddfb642013-07-16 16:24:09 -04001067// these are arguments to pshufb. They move data down from
1068// the high bytes of the register to the low bytes of the register.
1069// index is how many bytes to move.
1070DATA shifts<>+0x00(SB)/4, $0x00000000
1071DATA shifts<>+0x04(SB)/4, $0x00000000
1072DATA shifts<>+0x08(SB)/4, $0x00000000
1073DATA shifts<>+0x0c(SB)/4, $0x00000000
1074
1075DATA shifts<>+0x10(SB)/4, $0xffffff0f
1076DATA shifts<>+0x14(SB)/4, $0xffffffff
1077DATA shifts<>+0x18(SB)/4, $0xffffffff
1078DATA shifts<>+0x1c(SB)/4, $0xffffffff
1079
1080DATA shifts<>+0x20(SB)/4, $0xffff0f0e
1081DATA shifts<>+0x24(SB)/4, $0xffffffff
1082DATA shifts<>+0x28(SB)/4, $0xffffffff
1083DATA shifts<>+0x2c(SB)/4, $0xffffffff
1084
1085DATA shifts<>+0x30(SB)/4, $0xff0f0e0d
1086DATA shifts<>+0x34(SB)/4, $0xffffffff
1087DATA shifts<>+0x38(SB)/4, $0xffffffff
1088DATA shifts<>+0x3c(SB)/4, $0xffffffff
1089
1090DATA shifts<>+0x40(SB)/4, $0x0f0e0d0c
1091DATA shifts<>+0x44(SB)/4, $0xffffffff
1092DATA shifts<>+0x48(SB)/4, $0xffffffff
1093DATA shifts<>+0x4c(SB)/4, $0xffffffff
1094
1095DATA shifts<>+0x50(SB)/4, $0x0e0d0c0b
1096DATA shifts<>+0x54(SB)/4, $0xffffff0f
1097DATA shifts<>+0x58(SB)/4, $0xffffffff
1098DATA shifts<>+0x5c(SB)/4, $0xffffffff
1099
1100DATA shifts<>+0x60(SB)/4, $0x0d0c0b0a
1101DATA shifts<>+0x64(SB)/4, $0xffff0f0e
1102DATA shifts<>+0x68(SB)/4, $0xffffffff
1103DATA shifts<>+0x6c(SB)/4, $0xffffffff
1104
1105DATA shifts<>+0x70(SB)/4, $0x0c0b0a09
1106DATA shifts<>+0x74(SB)/4, $0xff0f0e0d
1107DATA shifts<>+0x78(SB)/4, $0xffffffff
1108DATA shifts<>+0x7c(SB)/4, $0xffffffff
1109
1110DATA shifts<>+0x80(SB)/4, $0x0b0a0908
1111DATA shifts<>+0x84(SB)/4, $0x0f0e0d0c
1112DATA shifts<>+0x88(SB)/4, $0xffffffff
1113DATA shifts<>+0x8c(SB)/4, $0xffffffff
1114
1115DATA shifts<>+0x90(SB)/4, $0x0a090807
1116DATA shifts<>+0x94(SB)/4, $0x0e0d0c0b
1117DATA shifts<>+0x98(SB)/4, $0xffffff0f
1118DATA shifts<>+0x9c(SB)/4, $0xffffffff
1119
1120DATA shifts<>+0xa0(SB)/4, $0x09080706
1121DATA shifts<>+0xa4(SB)/4, $0x0d0c0b0a
1122DATA shifts<>+0xa8(SB)/4, $0xffff0f0e
1123DATA shifts<>+0xac(SB)/4, $0xffffffff
1124
1125DATA shifts<>+0xb0(SB)/4, $0x08070605
1126DATA shifts<>+0xb4(SB)/4, $0x0c0b0a09
1127DATA shifts<>+0xb8(SB)/4, $0xff0f0e0d
1128DATA shifts<>+0xbc(SB)/4, $0xffffffff
1129
1130DATA shifts<>+0xc0(SB)/4, $0x07060504
1131DATA shifts<>+0xc4(SB)/4, $0x0b0a0908
1132DATA shifts<>+0xc8(SB)/4, $0x0f0e0d0c
1133DATA shifts<>+0xcc(SB)/4, $0xffffffff
1134
1135DATA shifts<>+0xd0(SB)/4, $0x06050403
1136DATA shifts<>+0xd4(SB)/4, $0x0a090807
1137DATA shifts<>+0xd8(SB)/4, $0x0e0d0c0b
1138DATA shifts<>+0xdc(SB)/4, $0xffffff0f
1139
1140DATA shifts<>+0xe0(SB)/4, $0x05040302
1141DATA shifts<>+0xe4(SB)/4, $0x09080706
1142DATA shifts<>+0xe8(SB)/4, $0x0d0c0b0a
1143DATA shifts<>+0xec(SB)/4, $0xffff0f0e
1144
1145DATA shifts<>+0xf0(SB)/4, $0x04030201
1146DATA shifts<>+0xf4(SB)/4, $0x08070605
1147DATA shifts<>+0xf8(SB)/4, $0x0c0b0a09
1148DATA shifts<>+0xfc(SB)/4, $0xff0f0e0d
1149
Keith Randall5a546962013-08-07 10:23:24 -07001150GLOBL shifts<>(SB),RODATA,$256
Russ Cox9ddfb642013-07-16 16:24:09 -04001151
Keith Randall5a546962013-08-07 10:23:24 -07001152TEXT runtime·memeq(SB),NOSPLIT,$0-12
Keith Randall3d5daa22013-04-02 16:26:15 -07001153 MOVL a+0(FP), SI
1154 MOVL b+4(FP), DI
1155 MOVL count+8(FP), BX
1156 JMP runtime·memeqbody(SB)
1157
Keith Randall0c6b55e2014-07-16 14:16:19 -07001158TEXT runtime·gomemeq(SB),NOSPLIT,$0-13
1159 MOVL a+0(FP), SI
1160 MOVL b+4(FP), DI
1161 MOVL size+8(FP), BX
1162 CALL runtime·memeqbody(SB)
1163 MOVB AX, ret+12(FP)
1164 RET
1165
Keith Randallb36ed902014-06-16 21:00:37 -07001166// eqstring tests whether two strings are equal.
1167// See runtime_test.go:eqstring_generic for
1168// equivlaent Go code.
1169TEXT runtime·eqstring(SB),NOSPLIT,$0-17
1170 MOVL s1len+4(FP), AX
1171 MOVL s2len+12(FP), BX
1172 CMPL AX, BX
1173 JNE different
1174 MOVL s1str+0(FP), SI
1175 MOVL s2str+8(FP), DI
1176 CMPL SI, DI
1177 JEQ same
1178 CALL runtime·memeqbody(SB)
1179 MOVB AX, v+16(FP)
1180 RET
1181same:
1182 MOVB $1, v+16(FP)
1183 RET
1184different:
1185 MOVB $0, v+16(FP)
1186 RET
1187
Keith Randall5a546962013-08-07 10:23:24 -07001188TEXT bytes·Equal(SB),NOSPLIT,$0-25
Keith Randall3d5daa22013-04-02 16:26:15 -07001189 MOVL a_len+4(FP), BX
1190 MOVL b_len+16(FP), CX
1191 XORL AX, AX
1192 CMPL BX, CX
1193 JNE eqret
1194 MOVL a+0(FP), SI
1195 MOVL b+12(FP), DI
1196 CALL runtime·memeqbody(SB)
1197eqret:
1198 MOVB AX, ret+24(FP)
1199 RET
1200
1201// a in SI
1202// b in DI
1203// count in BX
Keith Randall5a546962013-08-07 10:23:24 -07001204TEXT runtime·memeqbody(SB),NOSPLIT,$0-0
Keith Randall3d5daa22013-04-02 16:26:15 -07001205 XORL AX, AX
1206
1207 CMPL BX, $4
1208 JB small
1209
1210 // 64 bytes at a time using xmm registers
1211hugeloop:
1212 CMPL BX, $64
1213 JB bigloop
1214 TESTL $0x4000000, runtime·cpuid_edx(SB) // check for sse2
1215 JE bigloop
1216 MOVOU (SI), X0
1217 MOVOU (DI), X1
1218 MOVOU 16(SI), X2
1219 MOVOU 16(DI), X3
1220 MOVOU 32(SI), X4
1221 MOVOU 32(DI), X5
1222 MOVOU 48(SI), X6
1223 MOVOU 48(DI), X7
1224 PCMPEQB X1, X0
1225 PCMPEQB X3, X2
1226 PCMPEQB X5, X4
1227 PCMPEQB X7, X6
1228 PAND X2, X0
1229 PAND X6, X4
1230 PAND X4, X0
1231 PMOVMSKB X0, DX
1232 ADDL $64, SI
1233 ADDL $64, DI
1234 SUBL $64, BX
1235 CMPL DX, $0xffff
1236 JEQ hugeloop
1237 RET
1238
1239 // 4 bytes at a time using 32-bit register
1240bigloop:
1241 CMPL BX, $4
1242 JBE leftover
1243 MOVL (SI), CX
1244 MOVL (DI), DX
1245 ADDL $4, SI
1246 ADDL $4, DI
1247 SUBL $4, BX
1248 CMPL CX, DX
1249 JEQ bigloop
1250 RET
1251
1252 // remaining 0-4 bytes
1253leftover:
1254 MOVL -4(SI)(BX*1), CX
1255 MOVL -4(DI)(BX*1), DX
1256 CMPL CX, DX
1257 SETEQ AX
1258 RET
1259
1260small:
1261 CMPL BX, $0
1262 JEQ equal
1263
1264 LEAL 0(BX*8), CX
1265 NEGL CX
1266
1267 MOVL SI, DX
1268 CMPB DX, $0xfc
1269 JA si_high
1270
1271 // load at SI won't cross a page boundary.
1272 MOVL (SI), SI
1273 JMP si_finish
1274si_high:
1275 // address ends in 111111xx. Load up to bytes we want, move to correct position.
1276 MOVL -4(SI)(BX*1), SI
1277 SHRL CX, SI
1278si_finish:
1279
1280 // same for DI.
1281 MOVL DI, DX
1282 CMPB DX, $0xfc
1283 JA di_high
1284 MOVL (DI), DI
1285 JMP di_finish
1286di_high:
1287 MOVL -4(DI)(BX*1), DI
1288 SHRL CX, DI
1289di_finish:
1290
1291 SUBL SI, DI
1292 SHLL CX, DI
1293equal:
1294 SETEQ AX
1295 RET
Keith Randallb3946dc2013-05-14 16:05:51 -07001296
Keith Randall5a546962013-08-07 10:23:24 -07001297TEXT runtime·cmpstring(SB),NOSPLIT,$0-20
Keith Randallb3946dc2013-05-14 16:05:51 -07001298 MOVL s1+0(FP), SI
1299 MOVL s1+4(FP), BX
1300 MOVL s2+8(FP), DI
1301 MOVL s2+12(FP), DX
1302 CALL runtime·cmpbody(SB)
1303 MOVL AX, res+16(FP)
1304 RET
1305
Keith Randall5a546962013-08-07 10:23:24 -07001306TEXT bytes·Compare(SB),NOSPLIT,$0-28
Keith Randallb3946dc2013-05-14 16:05:51 -07001307 MOVL s1+0(FP), SI
1308 MOVL s1+4(FP), BX
1309 MOVL s2+12(FP), DI
1310 MOVL s2+16(FP), DX
1311 CALL runtime·cmpbody(SB)
1312 MOVL AX, res+24(FP)
1313 RET
1314
Keith Randall5a546962013-08-07 10:23:24 -07001315TEXT bytes·IndexByte(SB),NOSPLIT,$0
Brad Fitzpatricke2a1bd62013-08-01 16:11:19 -07001316 MOVL s+0(FP), SI
1317 MOVL s_len+4(FP), CX
1318 MOVB c+12(FP), AL
1319 MOVL SI, DI
1320 CLD; REPN; SCASB
1321 JZ 3(PC)
1322 MOVL $-1, ret+16(FP)
1323 RET
1324 SUBL SI, DI
1325 SUBL $1, DI
1326 MOVL DI, ret+16(FP)
1327 RET
1328
Keith Randall5a546962013-08-07 10:23:24 -07001329TEXT strings·IndexByte(SB),NOSPLIT,$0
Brad Fitzpatrick598c7892013-08-05 15:04:05 -07001330 MOVL s+0(FP), SI
1331 MOVL s_len+4(FP), CX
1332 MOVB c+8(FP), AL
1333 MOVL SI, DI
1334 CLD; REPN; SCASB
1335 JZ 3(PC)
1336 MOVL $-1, ret+12(FP)
1337 RET
1338 SUBL SI, DI
1339 SUBL $1, DI
1340 MOVL DI, ret+12(FP)
1341 RET
1342
Keith Randallb3946dc2013-05-14 16:05:51 -07001343// input:
1344// SI = a
1345// DI = b
1346// BX = alen
1347// DX = blen
1348// output:
1349// AX = 1/0/-1
Keith Randall5a546962013-08-07 10:23:24 -07001350TEXT runtime·cmpbody(SB),NOSPLIT,$0-0
Keith Randallb3946dc2013-05-14 16:05:51 -07001351 CMPL SI, DI
1352 JEQ cmp_allsame
1353 CMPL BX, DX
1354 MOVL DX, BP
1355 CMOVLLT BX, BP // BP = min(alen, blen)
1356 CMPL BP, $4
1357 JB cmp_small
1358 TESTL $0x4000000, runtime·cpuid_edx(SB) // check for sse2
1359 JE cmp_mediumloop
1360cmp_largeloop:
1361 CMPL BP, $16
1362 JB cmp_mediumloop
1363 MOVOU (SI), X0
1364 MOVOU (DI), X1
1365 PCMPEQB X0, X1
1366 PMOVMSKB X1, AX
1367 XORL $0xffff, AX // convert EQ to NE
1368 JNE cmp_diff16 // branch if at least one byte is not equal
1369 ADDL $16, SI
1370 ADDL $16, DI
1371 SUBL $16, BP
1372 JMP cmp_largeloop
1373
1374cmp_diff16:
1375 BSFL AX, BX // index of first byte that differs
1376 XORL AX, AX
1377 MOVB (SI)(BX*1), CX
1378 CMPB CX, (DI)(BX*1)
1379 SETHI AX
1380 LEAL -1(AX*2), AX // convert 1/0 to +1/-1
1381 RET
1382
1383cmp_mediumloop:
1384 CMPL BP, $4
1385 JBE cmp_0through4
1386 MOVL (SI), AX
1387 MOVL (DI), CX
1388 CMPL AX, CX
1389 JNE cmp_diff4
1390 ADDL $4, SI
1391 ADDL $4, DI
1392 SUBL $4, BP
1393 JMP cmp_mediumloop
1394
1395cmp_0through4:
1396 MOVL -4(SI)(BP*1), AX
1397 MOVL -4(DI)(BP*1), CX
1398 CMPL AX, CX
1399 JEQ cmp_allsame
1400
1401cmp_diff4:
1402 BSWAPL AX // reverse order of bytes
1403 BSWAPL CX
1404 XORL AX, CX // find bit differences
1405 BSRL CX, CX // index of highest bit difference
1406 SHRL CX, AX // move a's bit to bottom
1407 ANDL $1, AX // mask bit
1408 LEAL -1(AX*2), AX // 1/0 => +1/-1
1409 RET
1410
1411 // 0-3 bytes in common
1412cmp_small:
1413 LEAL (BP*8), CX
1414 NEGL CX
1415 JEQ cmp_allsame
1416
1417 // load si
1418 CMPB SI, $0xfc
1419 JA cmp_si_high
1420 MOVL (SI), SI
1421 JMP cmp_si_finish
1422cmp_si_high:
1423 MOVL -4(SI)(BP*1), SI
1424 SHRL CX, SI
1425cmp_si_finish:
1426 SHLL CX, SI
1427
1428 // same for di
1429 CMPB DI, $0xfc
1430 JA cmp_di_high
1431 MOVL (DI), DI
1432 JMP cmp_di_finish
1433cmp_di_high:
1434 MOVL -4(DI)(BP*1), DI
1435 SHRL CX, DI
1436cmp_di_finish:
1437 SHLL CX, DI
1438
1439 BSWAPL SI // reverse order of bytes
1440 BSWAPL DI
1441 XORL SI, DI // find bit differences
1442 JEQ cmp_allsame
1443 BSRL DI, CX // index of highest bit difference
1444 SHRL CX, SI // move a's bit to bottom
1445 ANDL $1, SI // mask bit
1446 LEAL -1(SI*2), AX // 1/0 => +1/-1
1447 RET
1448
1449 // all the bytes in common are the same, so we just need
1450 // to compare the lengths.
1451cmp_allsame:
1452 XORL AX, AX
1453 XORL CX, CX
1454 CMPL BX, DX
1455 SETGT AX // 1 if alen > blen
1456 SETEQ CX // 1 if alen == blen
1457 LEAL -1(CX)(AX*2), AX // 1,0,-1 result
1458 RET
Keith Randall6c7cbf02014-04-01 12:51:02 -07001459
1460// A Duff's device for zeroing memory.
1461// The compiler jumps to computed addresses within
1462// this routine to zero chunks of memory. Do not
1463// change this code without also changing the code
1464// in ../../cmd/8g/ggen.c:clearfat.
1465// AX: zero
1466// DI: ptr to memory to be zeroed
1467// DI is updated as a side effect.
1468TEXT runtime·duffzero(SB), NOSPLIT, $0-0
1469 STOSL
1470 STOSL
1471 STOSL
1472 STOSL
1473 STOSL
1474 STOSL
1475 STOSL
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 RET
1598
1599// A Duff's device for copying memory.
1600// The compiler jumps to computed addresses within
1601// this routine to copy chunks of memory. Source
1602// and destination must not overlap. Do not
1603// change this code without also changing the code
1604// in ../../cmd/6g/cgen.c:sgen.
1605// SI: ptr to source memory
1606// DI: ptr to destination memory
1607// SI and DI are updated as a side effect.
1608
1609// NOTE: this is equivalent to a sequence of MOVSL but
1610// for some reason MOVSL is really slow.
1611TEXT runtime·duffcopy(SB), NOSPLIT, $0-0
1612 MOVL (SI),CX
1613 ADDL $4,SI
1614 MOVL CX,(DI)
1615 ADDL $4,DI
1616
1617 MOVL (SI),CX
1618 ADDL $4,SI
1619 MOVL CX,(DI)
1620 ADDL $4,DI
1621
1622 MOVL (SI),CX
1623 ADDL $4,SI
1624 MOVL CX,(DI)
1625 ADDL $4,DI
1626
1627 MOVL (SI),CX
1628 ADDL $4,SI
1629 MOVL CX,(DI)
1630 ADDL $4,DI
1631
1632 MOVL (SI),CX
1633 ADDL $4,SI
1634 MOVL CX,(DI)
1635 ADDL $4,DI
1636
1637 MOVL (SI),CX
1638 ADDL $4,SI
1639 MOVL CX,(DI)
1640 ADDL $4,DI
1641
1642 MOVL (SI),CX
1643 ADDL $4,SI
1644 MOVL CX,(DI)
1645 ADDL $4,DI
1646
1647 MOVL (SI),CX
1648 ADDL $4,SI
1649 MOVL CX,(DI)
1650 ADDL $4,DI
1651
1652 MOVL (SI),CX
1653 ADDL $4,SI
1654 MOVL CX,(DI)
1655 ADDL $4,DI
1656
1657 MOVL (SI),CX
1658 ADDL $4,SI
1659 MOVL CX,(DI)
1660 ADDL $4,DI
1661
1662 MOVL (SI),CX
1663 ADDL $4,SI
1664 MOVL CX,(DI)
1665 ADDL $4,DI
1666
1667 MOVL (SI),CX
1668 ADDL $4,SI
1669 MOVL CX,(DI)
1670 ADDL $4,DI
1671
1672 MOVL (SI),CX
1673 ADDL $4,SI
1674 MOVL CX,(DI)
1675 ADDL $4,DI
1676
1677 MOVL (SI),CX
1678 ADDL $4,SI
1679 MOVL CX,(DI)
1680 ADDL $4,DI
1681
1682 MOVL (SI),CX
1683 ADDL $4,SI
1684 MOVL CX,(DI)
1685 ADDL $4,DI
1686
1687 MOVL (SI),CX
1688 ADDL $4,SI
1689 MOVL CX,(DI)
1690 ADDL $4,DI
1691
1692 MOVL (SI),CX
1693 ADDL $4,SI
1694 MOVL CX,(DI)
1695 ADDL $4,DI
1696
1697 MOVL (SI),CX
1698 ADDL $4,SI
1699 MOVL CX,(DI)
1700 ADDL $4,DI
1701
1702 MOVL (SI),CX
1703 ADDL $4,SI
1704 MOVL CX,(DI)
1705 ADDL $4,DI
1706
1707 MOVL (SI),CX
1708 ADDL $4,SI
1709 MOVL CX,(DI)
1710 ADDL $4,DI
1711
1712 MOVL (SI),CX
1713 ADDL $4,SI
1714 MOVL CX,(DI)
1715 ADDL $4,DI
1716
1717 MOVL (SI),CX
1718 ADDL $4,SI
1719 MOVL CX,(DI)
1720 ADDL $4,DI
1721
1722 MOVL (SI),CX
1723 ADDL $4,SI
1724 MOVL CX,(DI)
1725 ADDL $4,DI
1726
1727 MOVL (SI),CX
1728 ADDL $4,SI
1729 MOVL CX,(DI)
1730 ADDL $4,DI
1731
1732 MOVL (SI),CX
1733 ADDL $4,SI
1734 MOVL CX,(DI)
1735 ADDL $4,DI
1736
1737 MOVL (SI),CX
1738 ADDL $4,SI
1739 MOVL CX,(DI)
1740 ADDL $4,DI
1741
1742 MOVL (SI),CX
1743 ADDL $4,SI
1744 MOVL CX,(DI)
1745 ADDL $4,DI
1746
1747 MOVL (SI),CX
1748 ADDL $4,SI
1749 MOVL CX,(DI)
1750 ADDL $4,DI
1751
1752 MOVL (SI),CX
1753 ADDL $4,SI
1754 MOVL CX,(DI)
1755 ADDL $4,DI
1756
1757 MOVL (SI),CX
1758 ADDL $4,SI
1759 MOVL CX,(DI)
1760 ADDL $4,DI
1761
1762 MOVL (SI),CX
1763 ADDL $4,SI
1764 MOVL CX,(DI)
1765 ADDL $4,DI
1766
1767 MOVL (SI),CX
1768 ADDL $4,SI
1769 MOVL CX,(DI)
1770 ADDL $4,DI
1771
1772 MOVL (SI),CX
1773 ADDL $4,SI
1774 MOVL CX,(DI)
1775 ADDL $4,DI
1776
1777 MOVL (SI),CX
1778 ADDL $4,SI
1779 MOVL CX,(DI)
1780 ADDL $4,DI
1781
1782 MOVL (SI),CX
1783 ADDL $4,SI
1784 MOVL CX,(DI)
1785 ADDL $4,DI
1786
1787 MOVL (SI),CX
1788 ADDL $4,SI
1789 MOVL CX,(DI)
1790 ADDL $4,DI
1791
1792 MOVL (SI),CX
1793 ADDL $4,SI
1794 MOVL CX,(DI)
1795 ADDL $4,DI
1796
1797 MOVL (SI),CX
1798 ADDL $4,SI
1799 MOVL CX,(DI)
1800 ADDL $4,DI
1801
1802 MOVL (SI),CX
1803 ADDL $4,SI
1804 MOVL CX,(DI)
1805 ADDL $4,DI
1806
1807 MOVL (SI),CX
1808 ADDL $4,SI
1809 MOVL CX,(DI)
1810 ADDL $4,DI
1811
1812 MOVL (SI),CX
1813 ADDL $4,SI
1814 MOVL CX,(DI)
1815 ADDL $4,DI
1816
1817 MOVL (SI),CX
1818 ADDL $4,SI
1819 MOVL CX,(DI)
1820 ADDL $4,DI
1821
1822 MOVL (SI),CX
1823 ADDL $4,SI
1824 MOVL CX,(DI)
1825 ADDL $4,DI
1826
1827 MOVL (SI),CX
1828 ADDL $4,SI
1829 MOVL CX,(DI)
1830 ADDL $4,DI
1831
1832 MOVL (SI),CX
1833 ADDL $4,SI
1834 MOVL CX,(DI)
1835 ADDL $4,DI
1836
1837 MOVL (SI),CX
1838 ADDL $4,SI
1839 MOVL CX,(DI)
1840 ADDL $4,DI
1841
1842 MOVL (SI),CX
1843 ADDL $4,SI
1844 MOVL CX,(DI)
1845 ADDL $4,DI
1846
1847 MOVL (SI),CX
1848 ADDL $4,SI
1849 MOVL CX,(DI)
1850 ADDL $4,DI
1851
1852 MOVL (SI),CX
1853 ADDL $4,SI
1854 MOVL CX,(DI)
1855 ADDL $4,DI
1856
1857 MOVL (SI),CX
1858 ADDL $4,SI
1859 MOVL CX,(DI)
1860 ADDL $4,DI
1861
1862 MOVL (SI),CX
1863 ADDL $4,SI
1864 MOVL CX,(DI)
1865 ADDL $4,DI
1866
1867 MOVL (SI),CX
1868 ADDL $4,SI
1869 MOVL CX,(DI)
1870 ADDL $4,DI
1871
1872 MOVL (SI),CX
1873 ADDL $4,SI
1874 MOVL CX,(DI)
1875 ADDL $4,DI
1876
1877 MOVL (SI),CX
1878 ADDL $4,SI
1879 MOVL CX,(DI)
1880 ADDL $4,DI
1881
1882 MOVL (SI),CX
1883 ADDL $4,SI
1884 MOVL CX,(DI)
1885 ADDL $4,DI
1886
1887 MOVL (SI),CX
1888 ADDL $4,SI
1889 MOVL CX,(DI)
1890 ADDL $4,DI
1891
1892 MOVL (SI),CX
1893 ADDL $4,SI
1894 MOVL CX,(DI)
1895 ADDL $4,DI
1896
1897 MOVL (SI),CX
1898 ADDL $4,SI
1899 MOVL CX,(DI)
1900 ADDL $4,DI
1901
1902 MOVL (SI),CX
1903 ADDL $4,SI
1904 MOVL CX,(DI)
1905 ADDL $4,DI
1906
1907 MOVL (SI),CX
1908 ADDL $4,SI
1909 MOVL CX,(DI)
1910 ADDL $4,DI
1911
1912 MOVL (SI),CX
1913 ADDL $4,SI
1914 MOVL CX,(DI)
1915 ADDL $4,DI
1916
1917 MOVL (SI),CX
1918 ADDL $4,SI
1919 MOVL CX,(DI)
1920 ADDL $4,DI
1921
1922 MOVL (SI),CX
1923 ADDL $4,SI
1924 MOVL CX,(DI)
1925 ADDL $4,DI
1926
1927 MOVL (SI),CX
1928 ADDL $4,SI
1929 MOVL CX,(DI)
1930 ADDL $4,DI
1931
1932 MOVL (SI),CX
1933 ADDL $4,SI
1934 MOVL CX,(DI)
1935 ADDL $4,DI
1936
1937 MOVL (SI),CX
1938 ADDL $4,SI
1939 MOVL CX,(DI)
1940 ADDL $4,DI
1941
1942 MOVL (SI),CX
1943 ADDL $4,SI
1944 MOVL CX,(DI)
1945 ADDL $4,DI
1946
1947 MOVL (SI),CX
1948 ADDL $4,SI
1949 MOVL CX,(DI)
1950 ADDL $4,DI
1951
1952 MOVL (SI),CX
1953 ADDL $4,SI
1954 MOVL CX,(DI)
1955 ADDL $4,DI
1956
1957 MOVL (SI),CX
1958 ADDL $4,SI
1959 MOVL CX,(DI)
1960 ADDL $4,DI
1961
1962 MOVL (SI),CX
1963 ADDL $4,SI
1964 MOVL CX,(DI)
1965 ADDL $4,DI
1966
1967 MOVL (SI),CX
1968 ADDL $4,SI
1969 MOVL CX,(DI)
1970 ADDL $4,DI
1971
1972 MOVL (SI),CX
1973 ADDL $4,SI
1974 MOVL CX,(DI)
1975 ADDL $4,DI
1976
1977 MOVL (SI),CX
1978 ADDL $4,SI
1979 MOVL CX,(DI)
1980 ADDL $4,DI
1981
1982 MOVL (SI),CX
1983 ADDL $4,SI
1984 MOVL CX,(DI)
1985 ADDL $4,DI
1986
1987 MOVL (SI),CX
1988 ADDL $4,SI
1989 MOVL CX,(DI)
1990 ADDL $4,DI
1991
1992 MOVL (SI),CX
1993 ADDL $4,SI
1994 MOVL CX,(DI)
1995 ADDL $4,DI
1996
1997 MOVL (SI),CX
1998 ADDL $4,SI
1999 MOVL CX,(DI)
2000 ADDL $4,DI
2001
2002 MOVL (SI),CX
2003 ADDL $4,SI
2004 MOVL CX,(DI)
2005 ADDL $4,DI
2006
2007 MOVL (SI),CX
2008 ADDL $4,SI
2009 MOVL CX,(DI)
2010 ADDL $4,DI
2011
2012 MOVL (SI),CX
2013 ADDL $4,SI
2014 MOVL CX,(DI)
2015 ADDL $4,DI
2016
2017 MOVL (SI),CX
2018 ADDL $4,SI
2019 MOVL CX,(DI)
2020 ADDL $4,DI
2021
2022 MOVL (SI),CX
2023 ADDL $4,SI
2024 MOVL CX,(DI)
2025 ADDL $4,DI
2026
2027 MOVL (SI),CX
2028 ADDL $4,SI
2029 MOVL CX,(DI)
2030 ADDL $4,DI
2031
2032 MOVL (SI),CX
2033 ADDL $4,SI
2034 MOVL CX,(DI)
2035 ADDL $4,DI
2036
2037 MOVL (SI),CX
2038 ADDL $4,SI
2039 MOVL CX,(DI)
2040 ADDL $4,DI
2041
2042 MOVL (SI),CX
2043 ADDL $4,SI
2044 MOVL CX,(DI)
2045 ADDL $4,DI
2046
2047 MOVL (SI),CX
2048 ADDL $4,SI
2049 MOVL CX,(DI)
2050 ADDL $4,DI
2051
2052 MOVL (SI),CX
2053 ADDL $4,SI
2054 MOVL CX,(DI)
2055 ADDL $4,DI
2056
2057 MOVL (SI),CX
2058 ADDL $4,SI
2059 MOVL CX,(DI)
2060 ADDL $4,DI
2061
2062 MOVL (SI),CX
2063 ADDL $4,SI
2064 MOVL CX,(DI)
2065 ADDL $4,DI
2066
2067 MOVL (SI),CX
2068 ADDL $4,SI
2069 MOVL CX,(DI)
2070 ADDL $4,DI
2071
2072 MOVL (SI),CX
2073 ADDL $4,SI
2074 MOVL CX,(DI)
2075 ADDL $4,DI
2076
2077 MOVL (SI),CX
2078 ADDL $4,SI
2079 MOVL CX,(DI)
2080 ADDL $4,DI
2081
2082 MOVL (SI),CX
2083 ADDL $4,SI
2084 MOVL CX,(DI)
2085 ADDL $4,DI
2086
2087 MOVL (SI),CX
2088 ADDL $4,SI
2089 MOVL CX,(DI)
2090 ADDL $4,DI
2091
2092 MOVL (SI),CX
2093 ADDL $4,SI
2094 MOVL CX,(DI)
2095 ADDL $4,DI
2096
2097 MOVL (SI),CX
2098 ADDL $4,SI
2099 MOVL CX,(DI)
2100 ADDL $4,DI
2101
2102 MOVL (SI),CX
2103 ADDL $4,SI
2104 MOVL CX,(DI)
2105 ADDL $4,DI
2106
2107 MOVL (SI),CX
2108 ADDL $4,SI
2109 MOVL CX,(DI)
2110 ADDL $4,DI
2111
2112 MOVL (SI),CX
2113 ADDL $4,SI
2114 MOVL CX,(DI)
2115 ADDL $4,DI
2116
2117 MOVL (SI),CX
2118 ADDL $4,SI
2119 MOVL CX,(DI)
2120 ADDL $4,DI
2121
2122 MOVL (SI),CX
2123 ADDL $4,SI
2124 MOVL CX,(DI)
2125 ADDL $4,DI
2126
2127 MOVL (SI),CX
2128 ADDL $4,SI
2129 MOVL CX,(DI)
2130 ADDL $4,DI
2131
2132 MOVL (SI),CX
2133 ADDL $4,SI
2134 MOVL CX,(DI)
2135 ADDL $4,DI
2136
2137 MOVL (SI),CX
2138 ADDL $4,SI
2139 MOVL CX,(DI)
2140 ADDL $4,DI
2141
2142 MOVL (SI),CX
2143 ADDL $4,SI
2144 MOVL CX,(DI)
2145 ADDL $4,DI
2146
2147 MOVL (SI),CX
2148 ADDL $4,SI
2149 MOVL CX,(DI)
2150 ADDL $4,DI
2151
2152 MOVL (SI),CX
2153 ADDL $4,SI
2154 MOVL CX,(DI)
2155 ADDL $4,DI
2156
2157 MOVL (SI),CX
2158 ADDL $4,SI
2159 MOVL CX,(DI)
2160 ADDL $4,DI
2161
2162 MOVL (SI),CX
2163 ADDL $4,SI
2164 MOVL CX,(DI)
2165 ADDL $4,DI
2166
2167 MOVL (SI),CX
2168 ADDL $4,SI
2169 MOVL CX,(DI)
2170 ADDL $4,DI
2171
2172 MOVL (SI),CX
2173 ADDL $4,SI
2174 MOVL CX,(DI)
2175 ADDL $4,DI
2176
2177 MOVL (SI),CX
2178 ADDL $4,SI
2179 MOVL CX,(DI)
2180 ADDL $4,DI
2181
2182 MOVL (SI),CX
2183 ADDL $4,SI
2184 MOVL CX,(DI)
2185 ADDL $4,DI
2186
2187 MOVL (SI),CX
2188 ADDL $4,SI
2189 MOVL CX,(DI)
2190 ADDL $4,DI
2191
2192 MOVL (SI),CX
2193 ADDL $4,SI
2194 MOVL CX,(DI)
2195 ADDL $4,DI
2196
2197 MOVL (SI),CX
2198 ADDL $4,SI
2199 MOVL CX,(DI)
2200 ADDL $4,DI
2201
2202 MOVL (SI),CX
2203 ADDL $4,SI
2204 MOVL CX,(DI)
2205 ADDL $4,DI
2206
2207 MOVL (SI),CX
2208 ADDL $4,SI
2209 MOVL CX,(DI)
2210 ADDL $4,DI
2211
2212 MOVL (SI),CX
2213 ADDL $4,SI
2214 MOVL CX,(DI)
2215 ADDL $4,DI
2216
2217 MOVL (SI),CX
2218 ADDL $4,SI
2219 MOVL CX,(DI)
2220 ADDL $4,DI
2221
2222 MOVL (SI),CX
2223 ADDL $4,SI
2224 MOVL CX,(DI)
2225 ADDL $4,DI
2226
2227 MOVL (SI),CX
2228 ADDL $4,SI
2229 MOVL CX,(DI)
2230 ADDL $4,DI
2231
2232 MOVL (SI),CX
2233 ADDL $4,SI
2234 MOVL CX,(DI)
2235 ADDL $4,DI
2236
2237 MOVL (SI),CX
2238 ADDL $4,SI
2239 MOVL CX,(DI)
2240 ADDL $4,DI
2241
2242 MOVL (SI),CX
2243 ADDL $4,SI
2244 MOVL CX,(DI)
2245 ADDL $4,DI
2246
2247 MOVL (SI),CX
2248 ADDL $4,SI
2249 MOVL CX,(DI)
2250 ADDL $4,DI
2251
2252 RET
Dmitriy Vyukov350a8fc2014-05-02 17:32:42 +01002253
2254TEXT runtime·timenow(SB), NOSPLIT, $0-0
2255 JMP time·now(SB)
Keith Randall0c6b55e2014-07-16 14:16:19 -07002256
2257TEXT runtime·fastrand2(SB), NOSPLIT, $0-4
2258 get_tls(CX)
2259 MOVL g(CX), AX
2260 MOVL g_m(AX), AX
2261 MOVL m_fastrand(AX), DX
2262 ADDL DX, DX
2263 MOVL DX, BX
2264 XORL $0x88888eef, DX
2265 CMOVLMI BX, DX
2266 MOVL DX, m_fastrand(AX)
2267 MOVL DX, ret+0(FP)
2268 RET
2269
Keith Randalla2a97682014-07-31 15:07:05 -07002270// The goeq trampoline is necessary while we have
Keith Randall0c6b55e2014-07-16 14:16:19 -07002271// both Go and C calls to alg functions. Once we move all call
Keith Randalla2a97682014-07-31 15:07:05 -07002272// sites to Go, we can redo the eq functions to use the
2273// Go calling convention and remove this.
Keith Randall0c6b55e2014-07-16 14:16:19 -07002274
2275// convert call to:
2276// func (alg unsafe.Pointer, p, q unsafe.Pointer, size uintptr) bool
2277// to:
2278// func (eq *bool, size uintptr, p, q unsafe.Pointer)
2279TEXT runtime·goeq(SB), NOSPLIT, $16-17
2280 FUNCDATA $FUNCDATA_ArgsPointerMaps,gcargs_goeq<>(SB)
2281 FUNCDATA $FUNCDATA_LocalsPointerMaps,gclocals_goeq<>(SB)
2282 MOVL alg+0(FP), AX
2283 MOVL alg_equal(AX), AX
2284 MOVL p+4(FP), CX
2285 MOVL q+8(FP), DX
2286 MOVL size+12(FP), DI
2287 LEAL ret+16(FP), SI
2288 MOVL SI, 0(SP)
2289 MOVL DI, 4(SP)
2290 MOVL CX, 8(SP)
2291 MOVL DX, 12(SP)
2292 PCDATA $PCDATA_StackMapIndex, $0
2293 CALL *AX
2294 RET
2295
2296DATA gcargs_goeq<>+0x00(SB)/4, $1 // 1 stackmap
2297DATA gcargs_goeq<>+0x04(SB)/4, $10 // 5 args
2298DATA gcargs_goeq<>+0x08(SB)/4, $(const_BitsPointer+(const_BitsPointer<<2)+(const_BitsPointer<<4))
2299GLOBL gcargs_goeq<>(SB),RODATA,$12
2300
2301DATA gclocals_goeq<>+0x00(SB)/4, $1 // 1 stackmap
2302DATA gclocals_goeq<>+0x04(SB)/4, $0 // 0 locals
2303GLOBL gclocals_goeq<>(SB),RODATA,$8