blob: d94df0bf8dd98bb37e489d9b01fc4b0fbf79affd [file] [log] [blame]
Rob Pike8e82a672008-06-30 11:50:36 -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"
Rob Pike8e82a672008-06-30 11:50:36 -07008
Keith Randall5a546962013-08-07 10:23:24 -07009TEXT _rt0_go(SB),NOSPLIT,$0
Rob Pike8e82a672008-06-30 11:50:36 -070010 // copy arguments forward on an even stack
Russ Cox36b414f2013-03-06 15:03:04 -050011 MOVQ DI, AX // argc
12 MOVQ SI, BX // argv
Rob Pike8e82a672008-06-30 11:50:36 -070013 SUBQ $(4*8+7), SP // 2args 2auto
Ian Lance Taylora4f8d362010-04-09 14:15:15 -070014 ANDQ $~15, SP
Rob Pike8e82a672008-06-30 11:50:36 -070015 MOVQ AX, 16(SP)
16 MOVQ BX, 24(SP)
Dmitriy Vyukov428062d2011-12-07 16:53:17 +030017
18 // create istack out of the given (operating system) stack.
Russ Coxf8d49b52013-02-28 16:24:38 -050019 // _cgo_init may update stackguard.
Dmitriy Vyukov428062d2011-12-07 16:53:17 +030020 MOVQ $runtime·g0(SB), DI
Alex Brainman8d6958f2012-01-20 12:59:44 +110021 LEAQ (-64*1024+104)(SP), BX
Dmitriy Vyukov428062d2011-12-07 16:53:17 +030022 MOVQ BX, g_stackguard(DI)
Dmitriy Vyukovf5becf42013-06-03 12:28:24 +040023 MOVQ BX, g_stackguard0(DI)
Dmitriy Vyukov428062d2011-12-07 16:53:17 +030024 MOVQ SP, g_stackbase(DI)
Rob Pike8e82a672008-06-30 11:50:36 -070025
Keith Randalla5d40242013-03-12 10:47:44 -070026 // find out information about the processor we're on
27 MOVQ $0, AX
28 CPUID
29 CMPQ AX, $0
30 JE nocpuinfo
31 MOVQ $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.
38 MOVQ _cgo_init(SB), AX
Ian Lance Taylora4f8d362010-04-09 14:15:15 -070039 TESTQ AX, AX
Russ Coxe473f422010-08-04 17:50:22 -070040 JZ needtls
Alex Brainman8d6958f2012-01-20 12:59:44 +110041 // g0 already in DI
42 MOVQ DI, CX // Win64 uses CX for first parameter
Russ Cox89f185f2014-06-26 11:54:39 -040043 MOVQ $setg_gcc<>(SB), SI
Alex Brainman8d6958f2012-01-20 12:59:44 +110044 CALL AX
Dmitriy Vyukovf5becf42013-06-03 12:28:24 +040045 // update stackguard after _cgo_init
46 MOVQ $runtime·g0(SB), CX
47 MOVQ g_stackguard0(CX), AX
48 MOVQ AX, g_stackguard(CX)
Wei Guangjing9f636592011-07-19 10:47:33 -040049 CMPL runtime·iswindows(SB), $0
50 JEQ ok
Ian Lance Taylora4f8d362010-04-09 14:15:15 -070051
Russ Coxe473f422010-08-04 17:50:22 -070052needtls:
Akshat Kumara72bebf2012-08-31 13:21:13 -040053 // skip TLS setup on Plan 9
54 CMPL runtime·isplan9(SB), $1
55 JEQ ok
Aram Hăvărneanua46b4342014-01-17 17:58:10 +130056 // skip TLS setup on Solaris
57 CMPL runtime·issolaris(SB), $1
58 JEQ ok
Akshat Kumara72bebf2012-08-31 13:21:13 -040059
Russ Cox68b42552010-11-04 14:00:19 -040060 LEAQ runtime·tls0(SB), DI
61 CALL runtime·settls(SB)
Russ Coxe473f422010-08-04 17:50:22 -070062
63 // store through it, to make sure it works
64 get_tls(BX)
65 MOVQ $0x123, g(BX)
Russ Cox68b42552010-11-04 14:00:19 -040066 MOVQ runtime·tls0(SB), AX
Russ Coxe473f422010-08-04 17:50:22 -070067 CMPQ AX, $0x123
68 JEQ 2(PC)
69 MOVL AX, 0 // abort
70ok:
71 // set the per-goroutine and per-mach "registers"
72 get_tls(BX)
Russ Cox68b42552010-11-04 14:00:19 -040073 LEAQ runtime·g0(SB), CX
Russ Coxe473f422010-08-04 17:50:22 -070074 MOVQ CX, g(BX)
Russ Cox68b42552010-11-04 14:00:19 -040075 LEAQ runtime·m0(SB), AX
Russ Coxe473f422010-08-04 17:50:22 -070076
77 // save m->g0 = g0
78 MOVQ CX, m_g0(AX)
Russ Cox89f185f2014-06-26 11:54:39 -040079 // save m0 to g0->m
80 MOVQ AX, g_m(CX)
Rob Pike8e82a672008-06-30 11:50:36 -070081
Ken Thompson8f53bc02008-12-15 15:07:35 -080082 CLD // convention is D is always left cleared
Russ Cox68b42552010-11-04 14:00:19 -040083 CALL runtime·check(SB)
Rob Pike8e82a672008-06-30 11:50:36 -070084
Rob Pike8e82a672008-06-30 11:50:36 -070085 MOVL 16(SP), AX // copy argc
86 MOVL AX, 0(SP)
87 MOVQ 24(SP), AX // copy argv
88 MOVQ AX, 8(SP)
Russ Cox68b42552010-11-04 14:00:19 -040089 CALL runtime·args(SB)
90 CALL runtime·osinit(SB)
Keith Randalla5d40242013-03-12 10:47:44 -070091 CALL runtime·hashinit(SB)
Russ Cox68b42552010-11-04 14:00:19 -040092 CALL runtime·schedinit(SB)
Russ Coxf7f63292008-08-05 14:21:42 -070093
Ken Thompson751ce3a2008-07-11 19:16:39 -070094 // create a new goroutine to start program
Russ Cox9aa1e9a2014-08-12 19:51:20 -040095 MOVQ $runtime·main·f(SB), BP // entry
96 PUSHQ BP
Russ Cox7343e032009-06-17 15:12:16 -070097 PUSHQ $0 // arg size
Russ Cox9ddfb642013-07-16 16:24:09 -040098 ARGSIZE(16)
Russ Cox68b42552010-11-04 14:00:19 -040099 CALL runtime·newproc(SB)
Russ Cox9ddfb642013-07-16 16:24:09 -0400100 ARGSIZE(-1)
Russ Coxebd1eef2008-09-22 13:47:59 -0700101 POPQ AX
102 POPQ AX
Russ Cox79e1db22008-12-04 08:30:54 -0800103
Russ Coxebd1eef2008-09-22 13:47:59 -0700104 // start this M
Russ Cox68b42552010-11-04 14:00:19 -0400105 CALL runtime·mstart(SB)
Rob Pike8e82a672008-06-30 11:50:36 -0700106
Russ Cox36aa7d42012-03-08 14:03:56 -0500107 MOVL $0xf1, 0xf1 // crash
Rob Pike8e82a672008-06-30 11:50:36 -0700108 RET
109
Russ Cox1903ad72013-02-21 17:01:13 -0500110DATA runtime·main·f+0(SB)/8,$runtime·main(SB)
Keith Randall5a546962013-08-07 10:23:24 -0700111GLOBL runtime·main·f(SB),RODATA,$8
Russ Cox1903ad72013-02-21 17:01:13 -0500112
Keith Randall5a546962013-08-07 10:23:24 -0700113TEXT runtime·breakpoint(SB),NOSPLIT,$0-0
Ken Thompson751ce3a2008-07-11 19:16:39 -0700114 BYTE $0xcc
Rob Pike8e82a672008-06-30 11:50:36 -0700115 RET
116
Keith Randall5a546962013-08-07 10:23:24 -0700117TEXT runtime·asminit(SB),NOSPLIT,$0-0
Russ Cox1707a992012-02-14 01:23:15 -0500118 // No per-thread init.
119 RET
120
Ken Thompson751ce3a2008-07-11 19:16:39 -0700121/*
122 * go-routine
123 */
Rob Piked3204ef2008-06-30 14:39:47 -0700124
Russ Coxf9ca3b52011-03-07 10:37:42 -0500125// void gosave(Gobuf*)
Russ Cox7343e032009-06-17 15:12:16 -0700126// save state in Gobuf; setjmp
Keith Randall5a546962013-08-07 10:23:24 -0700127TEXT runtime·gosave(SB), NOSPLIT, $0-8
Ken Thompson751ce3a2008-07-11 19:16:39 -0700128 MOVQ 8(SP), AX // gobuf
Russ Cox7343e032009-06-17 15:12:16 -0700129 LEAQ 8(SP), BX // caller's SP
130 MOVQ BX, gobuf_sp(AX)
131 MOVQ 0(SP), BX // caller's PC
132 MOVQ BX, gobuf_pc(AX)
Russ Coxd67e7e32013-06-12 15:22:26 -0400133 MOVQ $0, gobuf_ret(AX)
134 MOVQ $0, gobuf_ctxt(AX)
Russ Coxe473f422010-08-04 17:50:22 -0700135 get_tls(CX)
136 MOVQ g(CX), BX
137 MOVQ BX, gobuf_g(AX)
Ken Thompson751ce3a2008-07-11 19:16:39 -0700138 RET
139
Ian Lance Taylor06272482013-06-12 15:05:10 -0700140// void gogo(Gobuf*)
Russ Cox7343e032009-06-17 15:12:16 -0700141// restore state from Gobuf; longjmp
Keith Randall5a546962013-08-07 10:23:24 -0700142TEXT runtime·gogo(SB), NOSPLIT, $0-8
Russ Cox7343e032009-06-17 15:12:16 -0700143 MOVQ 8(SP), BX // gobuf
Russ Coxe473f422010-08-04 17:50:22 -0700144 MOVQ gobuf_g(BX), DX
145 MOVQ 0(DX), CX // make sure g != nil
146 get_tls(CX)
147 MOVQ DX, g(CX)
Russ Cox7343e032009-06-17 15:12:16 -0700148 MOVQ gobuf_sp(BX), SP // restore SP
Russ Coxd67e7e32013-06-12 15:22:26 -0400149 MOVQ gobuf_ret(BX), AX
150 MOVQ gobuf_ctxt(BX), DX
151 MOVQ $0, gobuf_sp(BX) // clear to help garbage collector
152 MOVQ $0, gobuf_ret(BX)
153 MOVQ $0, gobuf_ctxt(BX)
Russ Cox7343e032009-06-17 15:12:16 -0700154 MOVQ gobuf_pc(BX), BX
155 JMP BX
156
Russ Coxf9ca3b52011-03-07 10:37:42 -0500157// void mcall(void (*fn)(G*))
158// Switch to m->g0's stack, call fn(g).
Russ Cox370276a2011-04-27 23:21:12 -0400159// Fn must never return. It should gogo(&g->sched)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500160// to keep running g.
Keith Randall5a546962013-08-07 10:23:24 -0700161TEXT runtime·mcall(SB), NOSPLIT, $0-8
Russ Coxf9ca3b52011-03-07 10:37:42 -0500162 MOVQ fn+0(FP), DI
163
164 get_tls(CX)
Russ Cox528534c2013-06-05 07:16:53 -0400165 MOVQ g(CX), AX // save state in g->sched
Russ Coxf9ca3b52011-03-07 10:37:42 -0500166 MOVQ 0(SP), BX // caller's PC
167 MOVQ BX, (g_sched+gobuf_pc)(AX)
168 LEAQ 8(SP), BX // caller's SP
169 MOVQ BX, (g_sched+gobuf_sp)(AX)
170 MOVQ AX, (g_sched+gobuf_g)(AX)
171
172 // switch to m->g0 & its stack, call fn
Russ Cox89f185f2014-06-26 11:54:39 -0400173 MOVQ g(CX), BX
174 MOVQ g_m(BX), BX
Russ Coxf9ca3b52011-03-07 10:37:42 -0500175 MOVQ m_g0(BX), SI
176 CMPQ SI, AX // if g == m->g0 call badmcall
Russ Cox9ddfb642013-07-16 16:24:09 -0400177 JNE 3(PC)
Keith Randall32b770b2013-08-29 15:53:34 -0700178 MOVQ $runtime·badmcall(SB), AX
179 JMP AX
Russ Coxf9ca3b52011-03-07 10:37:42 -0500180 MOVQ SI, g(CX) // g = m->g0
Russ Cox528534c2013-06-05 07:16:53 -0400181 MOVQ (g_sched+gobuf_sp)(SI), SP // sp = m->g0->sched.sp
Russ Coxf9ca3b52011-03-07 10:37:42 -0500182 PUSHQ AX
Russ Cox9ddfb642013-07-16 16:24:09 -0400183 ARGSIZE(8)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500184 CALL DI
185 POPQ AX
Keith Randall32b770b2013-08-29 15:53:34 -0700186 MOVQ $runtime·badmcall2(SB), AX
187 JMP AX
Russ Coxf9ca3b52011-03-07 10:37:42 -0500188 RET
189
Keith Randall4aa50432014-07-30 09:01:52 -0700190// switchtoM is a dummy routine that onM leaves at the bottom
191// of the G stack. We need to distinguish the routine that
192// lives at the bottom of the G stack from the one that lives
193// at the top of the M stack because the one at the top of
194// the M stack terminates the stack walk (see topofstack()).
195TEXT runtime·switchtoM(SB), NOSPLIT, $0-8
196 RET
197
198// void onM(void (*fn)())
199// calls fn() on the M stack.
200// switches to the M stack if not already on it, and
201// switches back when fn() returns.
202TEXT runtime·onM(SB), NOSPLIT, $0-8
203 MOVQ fn+0(FP), DI // DI = fn
204 get_tls(CX)
205 MOVQ g(CX), AX // AX = g
206 MOVQ g_m(AX), BX // BX = m
207 MOVQ m_g0(BX), DX // DX = g0
208 CMPQ AX, DX
209 JEQ onm
210
211 // save our state in g->sched. Pretend to
212 // be switchtoM if the G stack is scanned.
Russ Cox9aa1e9a2014-08-12 19:51:20 -0400213 MOVQ $runtime·switchtoM(SB), BP
214 MOVQ BP, (g_sched+gobuf_pc)(AX)
Keith Randall4aa50432014-07-30 09:01:52 -0700215 MOVQ SP, (g_sched+gobuf_sp)(AX)
216 MOVQ AX, (g_sched+gobuf_g)(AX)
217
218 // switch to g0
219 MOVQ DX, g(CX)
220 MOVQ (g_sched+gobuf_sp)(DX), SP
221
222 // call target function
223 ARGSIZE(0)
224 CALL DI
225
226 // switch back to g
227 get_tls(CX)
228 MOVQ g(CX), AX
229 MOVQ g_m(AX), BX
230 MOVQ m_curg(BX), AX
231 MOVQ AX, g(CX)
232 MOVQ (g_sched+gobuf_sp)(AX), SP
233 MOVQ $0, (g_sched+gobuf_sp)(AX)
234 RET
235
236onm:
237 // already on m stack, just call directly
238 CALL DI
239 RET
240
Rob Pike2da97832008-07-12 11:30:53 -0700241/*
242 * support for morestack
243 */
244
Russ Cox7343e032009-06-17 15:12:16 -0700245// Called during function prolog when more stack is needed.
Russ Coxe473f422010-08-04 17:50:22 -0700246// Caller has already done get_tls(CX); MOVQ m(CX), BX.
Russ Cox58f12ff2013-07-18 16:53:45 -0400247//
248// The traceback routines see morestack on a g0 as being
249// the top of a stack (for example, morestack calling newstack
250// calling the scheduler calling newm calling gc), so we must
251// record an argument size. For that purpose, it has no arguments.
Keith Randall5a546962013-08-07 10:23:24 -0700252TEXT runtime·morestack(SB),NOSPLIT,$0-0
Russ Coxe473f422010-08-04 17:50:22 -0700253 // Cannot grow scheduler stack (m->g0).
254 MOVQ m_g0(BX), SI
255 CMPQ g(CX), SI
256 JNE 2(PC)
257 INT $3
258
Russ Cox7343e032009-06-17 15:12:16 -0700259 // Called from f.
260 // Set m->morebuf to f's caller.
261 MOVQ 8(SP), AX // f's caller's PC
Russ Coxe473f422010-08-04 17:50:22 -0700262 MOVQ AX, (m_morebuf+gobuf_pc)(BX)
Russ Cox7343e032009-06-17 15:12:16 -0700263 LEAQ 16(SP), AX // f's caller's SP
Russ Coxe473f422010-08-04 17:50:22 -0700264 MOVQ AX, (m_morebuf+gobuf_sp)(BX)
Russ Cox141a4a12011-01-14 14:05:20 -0500265 MOVQ AX, m_moreargp(BX)
Russ Coxe473f422010-08-04 17:50:22 -0700266 get_tls(CX)
267 MOVQ g(CX), SI
268 MOVQ SI, (m_morebuf+gobuf_g)(BX)
Russ Cox7343e032009-06-17 15:12:16 -0700269
Russ Cox6fa3c892013-06-27 11:32:01 -0400270 // Set g->sched to context in f.
271 MOVQ 0(SP), AX // f's PC
272 MOVQ AX, (g_sched+gobuf_pc)(SI)
273 MOVQ SI, (g_sched+gobuf_g)(SI)
274 LEAQ 8(SP), AX // f's SP
275 MOVQ AX, (g_sched+gobuf_sp)(SI)
276 MOVQ DX, (g_sched+gobuf_ctxt)(SI)
Russ Cox7343e032009-06-17 15:12:16 -0700277
Russ Coxf9ca3b52011-03-07 10:37:42 -0500278 // Call newstack on m->g0's stack.
Russ Coxe473f422010-08-04 17:50:22 -0700279 MOVQ m_g0(BX), BP
280 MOVQ BP, g(CX)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500281 MOVQ (g_sched+gobuf_sp)(BP), SP
Russ Cox68b42552010-11-04 14:00:19 -0400282 CALL runtime·newstack(SB)
Russ Cox7343e032009-06-17 15:12:16 -0700283 MOVQ $0, 0x1003 // crash if newstack returns
284 RET
285
Keith Randall9cd57062013-08-02 13:03:14 -0700286// Called from panic. Mimics morestack,
Russ Coxbba278a2009-07-08 18:16:09 -0700287// reuses stack growth code to create a frame
288// with the desired args running the desired function.
289//
290// func call(fn *byte, arg *byte, argsize uint32).
Keith Randall5a546962013-08-07 10:23:24 -0700291TEXT runtime·newstackcall(SB), NOSPLIT, $0-20
Russ Coxe473f422010-08-04 17:50:22 -0700292 get_tls(CX)
Russ Cox89f185f2014-06-26 11:54:39 -0400293 MOVQ g(CX), BX
294 MOVQ g_m(BX), BX
Russ Coxe473f422010-08-04 17:50:22 -0700295
Russ Coxbba278a2009-07-08 18:16:09 -0700296 // Save our caller's state as the PC and SP to
297 // restore when returning from f.
298 MOVQ 0(SP), AX // our caller's PC
Russ Coxe473f422010-08-04 17:50:22 -0700299 MOVQ AX, (m_morebuf+gobuf_pc)(BX)
Russ Coxbba278a2009-07-08 18:16:09 -0700300 LEAQ 8(SP), AX // our caller's SP
Russ Coxe473f422010-08-04 17:50:22 -0700301 MOVQ AX, (m_morebuf+gobuf_sp)(BX)
302 MOVQ g(CX), AX
303 MOVQ AX, (m_morebuf+gobuf_g)(BX)
Russ Coxf0d73fb2013-06-27 16:51:06 -0400304
305 // Save our own state as the PC and SP to restore
306 // if this goroutine needs to be restarted.
Russ Cox9aa1e9a2014-08-12 19:51:20 -0400307 MOVQ $runtime·newstackcall(SB), BP
308 MOVQ BP, (g_sched+gobuf_pc)(AX)
Russ Coxf0d73fb2013-06-27 16:51:06 -0400309 MOVQ SP, (g_sched+gobuf_sp)(AX)
Russ Coxbba278a2009-07-08 18:16:09 -0700310
311 // Set up morestack arguments to call f on a new stack.
Russ Cox83727cc2010-03-29 21:48:22 -0700312 // We set f's frame size to 1, as a hint to newstack
Keith Randall9cd57062013-08-02 13:03:14 -0700313 // that this is a call from runtime·newstackcall.
Russ Cox83727cc2010-03-29 21:48:22 -0700314 // If it turns out that f needs a larger frame than
315 // the default stack, f's usual stack growth prolog will
316 // allocate a new segment (and recopy the arguments).
Russ Coxbba278a2009-07-08 18:16:09 -0700317 MOVQ 8(SP), AX // fn
Russ Coxe473f422010-08-04 17:50:22 -0700318 MOVQ 16(SP), DX // arg frame
Russ Coxbba278a2009-07-08 18:16:09 -0700319 MOVL 24(SP), CX // arg size
320
Russ Cox6fa3c892013-06-27 11:32:01 -0400321 MOVQ AX, m_cret(BX) // f's PC
Russ Cox141a4a12011-01-14 14:05:20 -0500322 MOVQ DX, m_moreargp(BX) // argument frame pointer
323 MOVL CX, m_moreargsize(BX) // f's argument size
324 MOVL $1, m_moreframesize(BX) // f's frame size
Russ Coxbba278a2009-07-08 18:16:09 -0700325
Russ Coxf9ca3b52011-03-07 10:37:42 -0500326 // Call newstack on m->g0's stack.
Russ Coxe473f422010-08-04 17:50:22 -0700327 MOVQ m_g0(BX), BP
328 get_tls(CX)
329 MOVQ BP, g(CX)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500330 MOVQ (g_sched+gobuf_sp)(BP), SP
Russ Cox68b42552010-11-04 14:00:19 -0400331 CALL runtime·newstack(SB)
Russ Coxbba278a2009-07-08 18:16:09 -0700332 MOVQ $0, 0x1103 // crash if newstack returns
333 RET
334
Keith Randall9cd57062013-08-02 13:03:14 -0700335// reflect·call: call a function with the given argument list
336// func call(f *FuncVal, arg *byte, argsize uint32).
337// we don't have variable-sized frames, so we use a small number
338// of constant-sized-frame functions to encode a few bits of size in the pc.
339// Caution: ugly multiline assembly macros in your future!
340
341#define DISPATCH(NAME,MAXSIZE) \
342 CMPQ CX, $MAXSIZE; \
343 JA 3(PC); \
Rob Pikeaff78832014-07-30 10:11:44 -0700344 MOVQ $NAME(SB), AX; \
Keith Randall9cd57062013-08-02 13:03:14 -0700345 JMP AX
Rob Pikeaff78832014-07-30 10:11:44 -0700346// Note: can't just "JMP NAME(SB)" - bad inlining results.
Keith Randall9cd57062013-08-02 13:03:14 -0700347
Russ Cox72c5d5e2014-04-08 11:11:35 -0400348TEXT reflect·call(SB), NOSPLIT, $0-24
Keith Randall9cd57062013-08-02 13:03:14 -0700349 MOVLQZX argsize+16(FP), CX
Rob Pikeaff78832014-07-30 10:11:44 -0700350 DISPATCH(runtime·call16, 16)
351 DISPATCH(runtime·call32, 32)
352 DISPATCH(runtime·call64, 64)
353 DISPATCH(runtime·call128, 128)
354 DISPATCH(runtime·call256, 256)
355 DISPATCH(runtime·call512, 512)
356 DISPATCH(runtime·call1024, 1024)
357 DISPATCH(runtime·call2048, 2048)
358 DISPATCH(runtime·call4096, 4096)
359 DISPATCH(runtime·call8192, 8192)
360 DISPATCH(runtime·call16384, 16384)
361 DISPATCH(runtime·call32768, 32768)
362 DISPATCH(runtime·call65536, 65536)
363 DISPATCH(runtime·call131072, 131072)
364 DISPATCH(runtime·call262144, 262144)
365 DISPATCH(runtime·call524288, 524288)
366 DISPATCH(runtime·call1048576, 1048576)
367 DISPATCH(runtime·call2097152, 2097152)
368 DISPATCH(runtime·call4194304, 4194304)
369 DISPATCH(runtime·call8388608, 8388608)
370 DISPATCH(runtime·call16777216, 16777216)
371 DISPATCH(runtime·call33554432, 33554432)
372 DISPATCH(runtime·call67108864, 67108864)
373 DISPATCH(runtime·call134217728, 134217728)
374 DISPATCH(runtime·call268435456, 268435456)
375 DISPATCH(runtime·call536870912, 536870912)
376 DISPATCH(runtime·call1073741824, 1073741824)
Keith Randall9cd57062013-08-02 13:03:14 -0700377 MOVQ $runtime·badreflectcall(SB), AX
378 JMP AX
379
Keith Randallcee8bca2014-05-21 14:28:34 -0700380// Argument map for the callXX frames. Each has one
381// stack map (for the single call) with 3 arguments.
382DATA gcargs_reflectcall<>+0x00(SB)/4, $1 // 1 stackmap
383DATA gcargs_reflectcall<>+0x04(SB)/4, $6 // 3 args
384DATA gcargs_reflectcall<>+0x08(SB)/4, $(const_BitsPointer+(const_BitsPointer<<2)+(const_BitsScalar<<4))
385GLOBL gcargs_reflectcall<>(SB),RODATA,$12
386
387// callXX frames have no locals
388DATA gclocals_reflectcall<>+0x00(SB)/4, $1 // 1 stackmap
389DATA gclocals_reflectcall<>+0x04(SB)/4, $0 // 0 locals
390GLOBL gclocals_reflectcall<>(SB),RODATA,$8
391
Keith Randall12e46e42013-08-06 14:33:55 -0700392#define CALLFN(NAME,MAXSIZE) \
Rob Pikeaff78832014-07-30 10:11:44 -0700393TEXT NAME(SB), WRAPPER, $MAXSIZE-24; \
Keith Randallcee8bca2014-05-21 14:28:34 -0700394 FUNCDATA $FUNCDATA_ArgsPointerMaps,gcargs_reflectcall<>(SB); \
395 FUNCDATA $FUNCDATA_LocalsPointerMaps,gclocals_reflectcall<>(SB);\
Keith Randall9cd57062013-08-02 13:03:14 -0700396 /* copy arguments to stack */ \
397 MOVQ argptr+8(FP), SI; \
398 MOVLQZX argsize+16(FP), CX; \
399 MOVQ SP, DI; \
400 REP;MOVSB; \
401 /* call function */ \
402 MOVQ f+0(FP), DX; \
Keith Randallcee8bca2014-05-21 14:28:34 -0700403 PCDATA $PCDATA_StackMapIndex, $0; \
Keith Randall9cd57062013-08-02 13:03:14 -0700404 CALL (DX); \
405 /* copy return values back */ \
406 MOVQ argptr+8(FP), DI; \
407 MOVLQZX argsize+16(FP), CX; \
Russ Cox72c5d5e2014-04-08 11:11:35 -0400408 MOVLQZX retoffset+20(FP), BX; \
Keith Randall9cd57062013-08-02 13:03:14 -0700409 MOVQ SP, SI; \
Russ Cox72c5d5e2014-04-08 11:11:35 -0400410 ADDQ BX, DI; \
411 ADDQ BX, SI; \
412 SUBQ BX, CX; \
Keith Randall9cd57062013-08-02 13:03:14 -0700413 REP;MOVSB; \
414 RET
415
Rob Pikeaff78832014-07-30 10:11:44 -0700416CALLFN(runtime·call16, 16)
417CALLFN(runtime·call32, 32)
418CALLFN(runtime·call64, 64)
419CALLFN(runtime·call128, 128)
420CALLFN(runtime·call256, 256)
421CALLFN(runtime·call512, 512)
422CALLFN(runtime·call1024, 1024)
423CALLFN(runtime·call2048, 2048)
424CALLFN(runtime·call4096, 4096)
425CALLFN(runtime·call8192, 8192)
426CALLFN(runtime·call16384, 16384)
427CALLFN(runtime·call32768, 32768)
428CALLFN(runtime·call65536, 65536)
429CALLFN(runtime·call131072, 131072)
430CALLFN(runtime·call262144, 262144)
431CALLFN(runtime·call524288, 524288)
432CALLFN(runtime·call1048576, 1048576)
433CALLFN(runtime·call2097152, 2097152)
434CALLFN(runtime·call4194304, 4194304)
435CALLFN(runtime·call8388608, 8388608)
436CALLFN(runtime·call16777216, 16777216)
437CALLFN(runtime·call33554432, 33554432)
438CALLFN(runtime·call67108864, 67108864)
439CALLFN(runtime·call134217728, 134217728)
440CALLFN(runtime·call268435456, 268435456)
441CALLFN(runtime·call536870912, 536870912)
442CALLFN(runtime·call1073741824, 1073741824)
Keith Randall9cd57062013-08-02 13:03:14 -0700443
Russ Cox7343e032009-06-17 15:12:16 -0700444// Return point when leaving stack.
Russ Cox58f12ff2013-07-18 16:53:45 -0400445//
446// Lessstack can appear in stack traces for the same reason
447// as morestack; in that context, it has 0 arguments.
Keith Randall5a546962013-08-07 10:23:24 -0700448TEXT runtime·lessstack(SB), NOSPLIT, $0-0
Russ Cox7343e032009-06-17 15:12:16 -0700449 // Save return value in m->cret
Russ Coxe473f422010-08-04 17:50:22 -0700450 get_tls(CX)
Russ Cox89f185f2014-06-26 11:54:39 -0400451 MOVQ g(CX), BX
452 MOVQ g_m(BX), BX
Russ Coxe473f422010-08-04 17:50:22 -0700453 MOVQ AX, m_cret(BX)
Russ Cox7343e032009-06-17 15:12:16 -0700454
Russ Coxf9ca3b52011-03-07 10:37:42 -0500455 // Call oldstack on m->g0's stack.
456 MOVQ m_g0(BX), BP
457 MOVQ BP, g(CX)
458 MOVQ (g_sched+gobuf_sp)(BP), SP
Russ Cox68b42552010-11-04 14:00:19 -0400459 CALL runtime·oldstack(SB)
Russ Cox7343e032009-06-17 15:12:16 -0700460 MOVQ $0, 0x1004 // crash if oldstack returns
461 RET
462
Ken Thompson1ed7f182009-05-01 18:07:33 -0700463// morestack trampolines
Keith Randall5a546962013-08-07 10:23:24 -0700464TEXT runtime·morestack00(SB),NOSPLIT,$0
Russ Coxe473f422010-08-04 17:50:22 -0700465 get_tls(CX)
Russ Cox89f185f2014-06-26 11:54:39 -0400466 MOVQ g(CX), BX
467 MOVQ g_m(BX), BX
Ken Thompson1ed7f182009-05-01 18:07:33 -0700468 MOVQ $0, AX
Russ Cox141a4a12011-01-14 14:05:20 -0500469 MOVQ AX, m_moreframesize(BX)
Russ Cox68b42552010-11-04 14:00:19 -0400470 MOVQ $runtime·morestack(SB), AX
Ken Thompson1ed7f182009-05-01 18:07:33 -0700471 JMP AX
472
Keith Randall5a546962013-08-07 10:23:24 -0700473TEXT runtime·morestack01(SB),NOSPLIT,$0
Russ Coxe473f422010-08-04 17:50:22 -0700474 get_tls(CX)
Russ Cox89f185f2014-06-26 11:54:39 -0400475 MOVQ g(CX), BX
476 MOVQ g_m(BX), BX
Ken Thompson1ed7f182009-05-01 18:07:33 -0700477 SHLQ $32, AX
Russ Cox141a4a12011-01-14 14:05:20 -0500478 MOVQ AX, m_moreframesize(BX)
Russ Cox68b42552010-11-04 14:00:19 -0400479 MOVQ $runtime·morestack(SB), AX
Ken Thompson1ed7f182009-05-01 18:07:33 -0700480 JMP AX
481
Keith Randall5a546962013-08-07 10:23:24 -0700482TEXT runtime·morestack10(SB),NOSPLIT,$0
Russ Coxe473f422010-08-04 17:50:22 -0700483 get_tls(CX)
Russ Cox89f185f2014-06-26 11:54:39 -0400484 MOVQ g(CX), BX
485 MOVQ g_m(BX), BX
Ken Thompson1ed7f182009-05-01 18:07:33 -0700486 MOVLQZX AX, AX
Russ Cox141a4a12011-01-14 14:05:20 -0500487 MOVQ AX, m_moreframesize(BX)
Russ Cox68b42552010-11-04 14:00:19 -0400488 MOVQ $runtime·morestack(SB), AX
Ken Thompson1ed7f182009-05-01 18:07:33 -0700489 JMP AX
490
Keith Randall5a546962013-08-07 10:23:24 -0700491TEXT runtime·morestack11(SB),NOSPLIT,$0
Russ Coxe473f422010-08-04 17:50:22 -0700492 get_tls(CX)
Russ Cox89f185f2014-06-26 11:54:39 -0400493 MOVQ g(CX), BX
494 MOVQ g_m(BX), BX
Russ Cox141a4a12011-01-14 14:05:20 -0500495 MOVQ AX, m_moreframesize(BX)
Russ Cox68b42552010-11-04 14:00:19 -0400496 MOVQ $runtime·morestack(SB), AX
Ken Thompson1ed7f182009-05-01 18:07:33 -0700497 JMP AX
498
Ken Thompson5963f592009-05-03 19:09:14 -0700499// subcases of morestack01
500// with const of 8,16,...48
Keith Randall5a546962013-08-07 10:23:24 -0700501TEXT runtime·morestack8(SB),NOSPLIT,$0
Dmitriy Vyukove84d9e12013-07-29 22:22:34 +0400502 MOVQ $1, R8
Russ Cox68b42552010-11-04 14:00:19 -0400503 MOVQ $morestack<>(SB), AX
Ken Thompson5963f592009-05-03 19:09:14 -0700504 JMP AX
505
Keith Randall5a546962013-08-07 10:23:24 -0700506TEXT runtime·morestack16(SB),NOSPLIT,$0
Dmitriy Vyukove84d9e12013-07-29 22:22:34 +0400507 MOVQ $2, R8
Russ Cox68b42552010-11-04 14:00:19 -0400508 MOVQ $morestack<>(SB), AX
Ken Thompson5963f592009-05-03 19:09:14 -0700509 JMP AX
510
Keith Randall5a546962013-08-07 10:23:24 -0700511TEXT runtime·morestack24(SB),NOSPLIT,$0
Dmitriy Vyukove84d9e12013-07-29 22:22:34 +0400512 MOVQ $3, R8
Russ Cox68b42552010-11-04 14:00:19 -0400513 MOVQ $morestack<>(SB), AX
Ken Thompson5963f592009-05-03 19:09:14 -0700514 JMP AX
515
Keith Randall5a546962013-08-07 10:23:24 -0700516TEXT runtime·morestack32(SB),NOSPLIT,$0
Dmitriy Vyukove84d9e12013-07-29 22:22:34 +0400517 MOVQ $4, R8
Russ Cox68b42552010-11-04 14:00:19 -0400518 MOVQ $morestack<>(SB), AX
Ken Thompson5963f592009-05-03 19:09:14 -0700519 JMP AX
520
Keith Randall5a546962013-08-07 10:23:24 -0700521TEXT runtime·morestack40(SB),NOSPLIT,$0
Dmitriy Vyukove84d9e12013-07-29 22:22:34 +0400522 MOVQ $5, R8
Russ Cox68b42552010-11-04 14:00:19 -0400523 MOVQ $morestack<>(SB), AX
Ken Thompson5963f592009-05-03 19:09:14 -0700524 JMP AX
525
Keith Randall5a546962013-08-07 10:23:24 -0700526TEXT runtime·morestack48(SB),NOSPLIT,$0
Dmitriy Vyukove84d9e12013-07-29 22:22:34 +0400527 MOVQ $6, R8
Russ Cox68b42552010-11-04 14:00:19 -0400528 MOVQ $morestack<>(SB), AX
Ken Thompson5963f592009-05-03 19:09:14 -0700529 JMP AX
530
Keith Randall5a546962013-08-07 10:23:24 -0700531TEXT morestack<>(SB),NOSPLIT,$0
Russ Coxe473f422010-08-04 17:50:22 -0700532 get_tls(CX)
Russ Cox89f185f2014-06-26 11:54:39 -0400533 MOVQ g(CX), BX
534 MOVQ g_m(BX), BX
Dmitriy Vyukove84d9e12013-07-29 22:22:34 +0400535 SHLQ $35, R8
536 MOVQ R8, m_moreframesize(BX)
Russ Cox68b42552010-11-04 14:00:19 -0400537 MOVQ $runtime·morestack(SB), AX
Rob Pike2da97832008-07-12 11:30:53 -0700538 JMP AX
539
Russ Coxc2dd33a2014-03-04 13:53:08 -0500540TEXT runtime·morestack00_noctxt(SB),NOSPLIT,$0
541 MOVL $0, DX
542 JMP runtime·morestack00(SB)
543
544TEXT runtime·morestack01_noctxt(SB),NOSPLIT,$0
545 MOVL $0, DX
546 JMP runtime·morestack01(SB)
547
548TEXT runtime·morestack10_noctxt(SB),NOSPLIT,$0
549 MOVL $0, DX
550 JMP runtime·morestack10(SB)
551
552TEXT runtime·morestack11_noctxt(SB),NOSPLIT,$0
553 MOVL $0, DX
554 JMP runtime·morestack11(SB)
555
556TEXT runtime·morestack8_noctxt(SB),NOSPLIT,$0
557 MOVL $0, DX
558 JMP runtime·morestack8(SB)
559
560TEXT runtime·morestack16_noctxt(SB),NOSPLIT,$0
561 MOVL $0, DX
562 JMP runtime·morestack16(SB)
563
564TEXT runtime·morestack24_noctxt(SB),NOSPLIT,$0
565 MOVL $0, DX
566 JMP runtime·morestack24(SB)
567
568TEXT runtime·morestack32_noctxt(SB),NOSPLIT,$0
569 MOVL $0, DX
570 JMP runtime·morestack32(SB)
571
572TEXT runtime·morestack40_noctxt(SB),NOSPLIT,$0
573 MOVL $0, DX
574 JMP runtime·morestack40(SB)
575
576TEXT runtime·morestack48_noctxt(SB),NOSPLIT,$0
577 MOVL $0, DX
578 JMP runtime·morestack48(SB)
579
Russ Coxd28acc42008-08-04 16:43:49 -0700580// bool cas(int32 *val, int32 old, int32 new)
581// Atomically:
582// if(*val == old){
583// *val = new;
584// return 1;
Ken Thompson1e1cc4e2009-01-27 12:03:53 -0800585// } else
Russ Coxd28acc42008-08-04 16:43:49 -0700586// return 0;
Keith Randall5a546962013-08-07 10:23:24 -0700587TEXT runtime·cas(SB), NOSPLIT, $0-16
Russ Coxd28acc42008-08-04 16:43:49 -0700588 MOVQ 8(SP), BX
589 MOVL 16(SP), AX
590 MOVL 20(SP), CX
591 LOCK
592 CMPXCHGL CX, 0(BX)
593 JZ 3(PC)
594 MOVL $0, AX
595 RET
596 MOVL $1, AX
597 RET
Ken Thompson1e1cc4e2009-01-27 12:03:53 -0800598
Russ Cox9ddfb642013-07-16 16:24:09 -0400599// bool runtime·cas64(uint64 *val, uint64 old, uint64 new)
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400600// Atomically:
601// if(*val == *old){
602// *val = new;
603// return 1;
604// } else {
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400605// return 0;
606// }
Keith Randall5a546962013-08-07 10:23:24 -0700607TEXT runtime·cas64(SB), NOSPLIT, $0-24
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400608 MOVQ 8(SP), BX
Russ Coxfb63e4f2013-07-12 00:03:32 -0400609 MOVQ 16(SP), AX
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400610 MOVQ 24(SP), CX
611 LOCK
612 CMPXCHGQ CX, 0(BX)
613 JNZ cas64_fail
614 MOVL $1, AX
615 RET
616cas64_fail:
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400617 MOVL $0, AX
618 RET
619
Russ Cox67793502011-02-16 13:21:13 -0500620// bool casp(void **val, void *old, void *new)
621// Atomically:
622// if(*val == old){
623// *val = new;
624// return 1;
625// } else
626// return 0;
Keith Randall5a546962013-08-07 10:23:24 -0700627TEXT runtime·casp(SB), NOSPLIT, $0-24
Russ Cox67793502011-02-16 13:21:13 -0500628 MOVQ 8(SP), BX
629 MOVQ 16(SP), AX
630 MOVQ 24(SP), CX
631 LOCK
632 CMPXCHGQ CX, 0(BX)
633 JZ 3(PC)
634 MOVL $0, AX
635 RET
636 MOVL $1, AX
637 RET
638
Dmitriy Vyukov491aa152011-07-15 11:27:16 -0400639// uint32 xadd(uint32 volatile *val, int32 delta)
640// Atomically:
641// *val += delta;
642// return *val;
Keith Randall5a546962013-08-07 10:23:24 -0700643TEXT runtime·xadd(SB), NOSPLIT, $0-12
Dmitriy Vyukov491aa152011-07-15 11:27:16 -0400644 MOVQ 8(SP), BX
645 MOVL 16(SP), AX
646 MOVL AX, CX
647 LOCK
648 XADDL AX, 0(BX)
649 ADDL CX, AX
650 RET
651
Keith Randall5a546962013-08-07 10:23:24 -0700652TEXT runtime·xadd64(SB), NOSPLIT, $0-16
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400653 MOVQ 8(SP), BX
654 MOVQ 16(SP), AX
655 MOVQ AX, CX
656 LOCK
657 XADDQ AX, 0(BX)
658 ADDQ CX, AX
659 RET
660
Keith Randall5a546962013-08-07 10:23:24 -0700661TEXT runtime·xchg(SB), NOSPLIT, $0-12
Dmitriy Vyukov4e5086b2011-07-29 12:44:06 -0400662 MOVQ 8(SP), BX
663 MOVL 16(SP), AX
664 XCHGL AX, 0(BX)
665 RET
666
Keith Randall5a546962013-08-07 10:23:24 -0700667TEXT runtime·xchg64(SB), NOSPLIT, $0-16
Dmitriy Vyukovadd33492013-03-05 09:46:52 +0200668 MOVQ 8(SP), BX
669 MOVQ 16(SP), AX
670 XCHGQ AX, 0(BX)
671 RET
672
Dmitriy Vyukov9cbd2fb2014-01-22 11:27:16 +0400673TEXT runtime·xchgp(SB), NOSPLIT, $0-16
674 MOVQ 8(SP), BX
675 MOVQ 16(SP), AX
676 XCHGQ AX, 0(BX)
677 RET
678
Keith Randall5a546962013-08-07 10:23:24 -0700679TEXT runtime·procyield(SB),NOSPLIT,$0-0
Dmitriy Vyukov4e5086b2011-07-29 12:44:06 -0400680 MOVL 8(SP), AX
681again:
682 PAUSE
683 SUBL $1, AX
684 JNZ again
685 RET
686
Keith Randall5a546962013-08-07 10:23:24 -0700687TEXT runtime·atomicstorep(SB), NOSPLIT, $0-16
Dmitriy Vyukov86a659c2011-07-13 11:22:41 -0700688 MOVQ 8(SP), BX
689 MOVQ 16(SP), AX
690 XCHGQ AX, 0(BX)
691 RET
692
Keith Randall5a546962013-08-07 10:23:24 -0700693TEXT runtime·atomicstore(SB), NOSPLIT, $0-12
Dmitriy Vyukov91f0f182011-07-29 13:47:24 -0400694 MOVQ 8(SP), BX
695 MOVL 16(SP), AX
696 XCHGL AX, 0(BX)
697 RET
698
Keith Randall5a546962013-08-07 10:23:24 -0700699TEXT runtime·atomicstore64(SB), NOSPLIT, $0-16
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400700 MOVQ 8(SP), BX
701 MOVQ 16(SP), AX
702 XCHGQ AX, 0(BX)
703 RET
704
Russ Coxaa3222d82009-06-02 23:02:12 -0700705// void jmpdefer(fn, sp);
706// called from deferreturn.
Ken Thompson1e1cc4e2009-01-27 12:03:53 -0800707// 1. pop the caller
708// 2. sub 5 bytes from the callers return
709// 3. jmp to the argument
Keith Randalla97a91d2013-08-07 14:03:50 -0700710TEXT runtime·jmpdefer(SB), NOSPLIT, $0-16
Russ Cox6066fdc2013-02-22 10:47:54 -0500711 MOVQ 8(SP), DX // fn
Russ Coxaa3222d82009-06-02 23:02:12 -0700712 MOVQ 16(SP), BX // caller sp
713 LEAQ -8(BX), SP // caller sp after CALL
714 SUBQ $5, (SP) // return to CALL again
Russ Cox6066fdc2013-02-22 10:47:54 -0500715 MOVQ 0(DX), BX
Russ Cox1903ad72013-02-21 17:01:13 -0500716 JMP BX // but first run the deferred function
Russ Cox133a1582009-10-03 10:37:12 -0700717
Russ Coxd67e7e32013-06-12 15:22:26 -0400718// Save state of caller into g->sched. Smashes R8, R9.
Keith Randall5a546962013-08-07 10:23:24 -0700719TEXT gosave<>(SB),NOSPLIT,$0
Russ Coxd67e7e32013-06-12 15:22:26 -0400720 get_tls(R8)
721 MOVQ g(R8), R8
722 MOVQ 0(SP), R9
723 MOVQ R9, (g_sched+gobuf_pc)(R8)
724 LEAQ 8(SP), R9
725 MOVQ R9, (g_sched+gobuf_sp)(R8)
726 MOVQ $0, (g_sched+gobuf_ret)(R8)
727 MOVQ $0, (g_sched+gobuf_ctxt)(R8)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500728 RET
729
730// asmcgocall(void(*fn)(void*), void *arg)
Russ Coxadd89dd2009-10-12 10:26:38 -0700731// Call fn(arg) on the scheduler stack,
732// aligned appropriately for the gcc ABI.
Russ Coxf9ca3b52011-03-07 10:37:42 -0500733// See cgocall.c for more details.
Keith Randall5a546962013-08-07 10:23:24 -0700734TEXT runtime·asmcgocall(SB),NOSPLIT,$0-16
Russ Coxf9ca3b52011-03-07 10:37:42 -0500735 MOVQ fn+0(FP), AX
736 MOVQ arg+8(FP), BX
737 MOVQ SP, DX
Russ Coxadd89dd2009-10-12 10:26:38 -0700738
739 // Figure out if we need to switch to m->g0 stack.
Russ Coxf9ca3b52011-03-07 10:37:42 -0500740 // We get called to create new OS threads too, and those
741 // come in on the m->g0 stack already.
742 get_tls(CX)
Russ Cox89f185f2014-06-26 11:54:39 -0400743 MOVQ g(CX), BP
744 MOVQ g_m(BP), BP
Russ Coxf9ca3b52011-03-07 10:37:42 -0500745 MOVQ m_g0(BP), SI
746 MOVQ g(CX), DI
747 CMPQ SI, DI
Aram Hăvărneanua46b4342014-01-17 17:58:10 +1300748 JEQ nosave
749 MOVQ m_gsignal(BP), SI
750 CMPQ SI, DI
751 JEQ nosave
752
753 MOVQ m_g0(BP), SI
Russ Coxd67e7e32013-06-12 15:22:26 -0400754 CALL gosave<>(SB)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500755 MOVQ SI, g(CX)
756 MOVQ (g_sched+gobuf_sp)(SI), SP
Aram Hăvărneanua46b4342014-01-17 17:58:10 +1300757nosave:
Russ Coxadd89dd2009-10-12 10:26:38 -0700758
759 // Now on a scheduling stack (a pthread-created stack).
Alex Brainman7f075ec2012-09-03 12:12:51 +1000760 // Make sure we have enough room for 4 stack-backed fast-call
761 // registers as per windows amd64 calling convention.
762 SUBQ $64, SP
Russ Cox133a1582009-10-03 10:37:12 -0700763 ANDQ $~15, SP // alignment for gcc ABI
Alex Brainman7f075ec2012-09-03 12:12:51 +1000764 MOVQ DI, 48(SP) // save g
765 MOVQ DX, 40(SP) // save SP
Russ Coxf9ca3b52011-03-07 10:37:42 -0500766 MOVQ BX, DI // DI = first argument in AMD64 ABI
Wei Guangjing9f636592011-07-19 10:47:33 -0400767 MOVQ BX, CX // CX = first argument in Win64
Russ Coxf9ca3b52011-03-07 10:37:42 -0500768 CALL AX
Russ Coxadd89dd2009-10-12 10:26:38 -0700769
Russ Coxe473f422010-08-04 17:50:22 -0700770 // Restore registers, g, stack pointer.
Russ Coxf9ca3b52011-03-07 10:37:42 -0500771 get_tls(CX)
Alex Brainman7f075ec2012-09-03 12:12:51 +1000772 MOVQ 48(SP), DI
Russ Coxf9ca3b52011-03-07 10:37:42 -0500773 MOVQ DI, g(CX)
Alex Brainman7f075ec2012-09-03 12:12:51 +1000774 MOVQ 40(SP), SP
Russ Cox133a1582009-10-03 10:37:12 -0700775 RET
776
Russ Coxf9ca3b52011-03-07 10:37:42 -0500777// cgocallback(void (*fn)(void*), void *frame, uintptr framesize)
Russ Cox3d2dfc52013-02-22 16:08:56 -0500778// Turn the fn into a Go func (by taking its address) and call
779// cgocallback_gofunc.
Keith Randall5a546962013-08-07 10:23:24 -0700780TEXT runtime·cgocallback(SB),NOSPLIT,$24-24
Russ Cox3d2dfc52013-02-22 16:08:56 -0500781 LEAQ fn+0(FP), AX
782 MOVQ AX, 0(SP)
783 MOVQ frame+8(FP), AX
784 MOVQ AX, 8(SP)
785 MOVQ framesize+16(FP), AX
786 MOVQ AX, 16(SP)
787 MOVQ $runtime·cgocallback_gofunc(SB), AX
788 CALL AX
789 RET
790
791// cgocallback_gofunc(FuncVal*, void *frame, uintptr framesize)
792// See cgocall.c for more details.
Keith Randall5a546962013-08-07 10:23:24 -0700793TEXT runtime·cgocallback_gofunc(SB),NOSPLIT,$8-24
Russ Cox89f185f2014-06-26 11:54:39 -0400794 // If g is nil, Go did not create the current thread.
795 // Call needm to obtain one m for temporary use.
Russ Cox6c976392013-02-20 17:48:23 -0500796 // In this case, we're running on the thread stack, so there's
797 // lots of space, but the linker doesn't know. Hide the call from
798 // the linker analysis by using an indirect call through AX.
799 get_tls(CX)
800#ifdef GOOS_windows
Russ Coxdba623b2013-07-23 18:40:02 -0400801 MOVL $0, BP
Russ Cox6c976392013-02-20 17:48:23 -0500802 CMPQ CX, $0
Russ Coxcefdb9c2013-07-23 22:59:32 -0400803 JEQ 2(PC)
Russ Cox6c976392013-02-20 17:48:23 -0500804#endif
Russ Cox89f185f2014-06-26 11:54:39 -0400805 MOVQ g(CX), BP
Russ Cox6c976392013-02-20 17:48:23 -0500806 CMPQ BP, $0
Russ Cox89f185f2014-06-26 11:54:39 -0400807 JEQ needm
808 MOVQ g_m(BP), BP
809 MOVQ BP, R8 // holds oldm until end of function
810 JMP havem
Russ Cox6c976392013-02-20 17:48:23 -0500811needm:
Russ Cox89f185f2014-06-26 11:54:39 -0400812 MOVQ $0, 0(SP)
Russ Cox6c976392013-02-20 17:48:23 -0500813 MOVQ $runtime·needm(SB), AX
814 CALL AX
Russ Coxf0112822013-07-24 09:01:57 -0400815 MOVQ 0(SP), R8
Russ Coxe473f422010-08-04 17:50:22 -0700816 get_tls(CX)
Russ Cox89f185f2014-06-26 11:54:39 -0400817 MOVQ g(CX), BP
818 MOVQ g_m(BP), BP
Russ Cox9b732382012-03-08 12:12:40 -0500819
Russ Cox6c976392013-02-20 17:48:23 -0500820havem:
821 // Now there's a valid m, and we're running on its m->g0.
822 // Save current m->g0->sched.sp on stack and then set it to SP.
823 // Save current sp in m->g0->sched.sp in preparation for
824 // switch back to m->curg stack.
Russ Coxdba623b2013-07-23 18:40:02 -0400825 // NOTE: unwindm knows that the saved g->sched.sp is at 0(SP).
Russ Coxf9ca3b52011-03-07 10:37:42 -0500826 MOVQ m_g0(BP), SI
Russ Coxdba623b2013-07-23 18:40:02 -0400827 MOVQ (g_sched+gobuf_sp)(SI), AX
828 MOVQ AX, 0(SP)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500829 MOVQ SP, (g_sched+gobuf_sp)(SI)
Ian Lance Taylor2d0ff3f2010-04-09 13:30:11 -0700830
Russ Coxdba623b2013-07-23 18:40:02 -0400831 // Switch to m->curg stack and call runtime.cgocallbackg.
832 // Because we are taking over the execution of m->curg
833 // but *not* resuming what had been running, we need to
834 // save that information (m->curg->sched) so we can restore it.
Russ Cox528534c2013-06-05 07:16:53 -0400835 // We can restore m->curg->sched.sp easily, because calling
Alex Brainman72e83482011-08-18 12:17:09 -0400836 // runtime.cgocallbackg leaves SP unchanged upon return.
Russ Cox528534c2013-06-05 07:16:53 -0400837 // To save m->curg->sched.pc, we push it onto the stack.
Russ Coxf9ca3b52011-03-07 10:37:42 -0500838 // This has the added benefit that it looks to the traceback
Alex Brainman72e83482011-08-18 12:17:09 -0400839 // routine like cgocallbackg is going to return to that
Russ Coxdba623b2013-07-23 18:40:02 -0400840 // PC (because the frame we allocate below has the same
841 // size as cgocallback_gofunc's frame declared above)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500842 // so that the traceback will seamlessly trace back into
843 // the earlier calls.
Russ Coxdba623b2013-07-23 18:40:02 -0400844 //
Russ Coxf0112822013-07-24 09:01:57 -0400845 // In the new goroutine, 0(SP) holds the saved R8.
Russ Coxf9ca3b52011-03-07 10:37:42 -0500846 MOVQ m_curg(BP), SI
847 MOVQ SI, g(CX)
848 MOVQ (g_sched+gobuf_sp)(SI), DI // prepare stack as DI
Russ Coxf9ca3b52011-03-07 10:37:42 -0500849 MOVQ (g_sched+gobuf_pc)(SI), BP
Russ Coxdba623b2013-07-23 18:40:02 -0400850 MOVQ BP, -8(DI)
Russ Coxf0112822013-07-24 09:01:57 -0400851 LEAQ -(8+8)(DI), SP
852 MOVQ R8, 0(SP)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500853 CALL runtime·cgocallbackg(SB)
Russ Coxf0112822013-07-24 09:01:57 -0400854 MOVQ 0(SP), R8
Russ Coxf9ca3b52011-03-07 10:37:42 -0500855
Russ Cox528534c2013-06-05 07:16:53 -0400856 // Restore g->sched (== m->curg->sched) from saved values.
Russ Coxe473f422010-08-04 17:50:22 -0700857 get_tls(CX)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500858 MOVQ g(CX), SI
Russ Coxf0112822013-07-24 09:01:57 -0400859 MOVQ 8(SP), BP
Russ Coxf9ca3b52011-03-07 10:37:42 -0500860 MOVQ BP, (g_sched+gobuf_pc)(SI)
Russ Coxf0112822013-07-24 09:01:57 -0400861 LEAQ (8+8)(SP), DI
Russ Coxf9ca3b52011-03-07 10:37:42 -0500862 MOVQ DI, (g_sched+gobuf_sp)(SI)
863
864 // Switch back to m->g0's stack and restore m->g0->sched.sp.
865 // (Unlike m->curg, the g0 goroutine never uses sched.pc,
866 // so we do not have to restore it.)
Russ Cox89f185f2014-06-26 11:54:39 -0400867 MOVQ g(CX), BP
868 MOVQ g_m(BP), BP
Russ Coxf9ca3b52011-03-07 10:37:42 -0500869 MOVQ m_g0(BP), SI
870 MOVQ SI, g(CX)
871 MOVQ (g_sched+gobuf_sp)(SI), SP
Russ Coxdba623b2013-07-23 18:40:02 -0400872 MOVQ 0(SP), AX
873 MOVQ AX, (g_sched+gobuf_sp)(SI)
Russ Cox6c976392013-02-20 17:48:23 -0500874
875 // If the m on entry was nil, we called needm above to borrow an m
876 // for the duration of the call. Since the call is over, return it with dropm.
Russ Coxf0112822013-07-24 09:01:57 -0400877 CMPQ R8, $0
Russ Cox6c976392013-02-20 17:48:23 -0500878 JNE 3(PC)
879 MOVQ $runtime·dropm(SB), AX
880 CALL AX
Russ Coxf9ca3b52011-03-07 10:37:42 -0500881
882 // Done!
Ian Lance Taylor2d0ff3f2010-04-09 13:30:11 -0700883 RET
884
Russ Cox89f185f2014-06-26 11:54:39 -0400885// void setg(G*); set g. for use by needm.
886TEXT runtime·setg(SB), NOSPLIT, $0-16
887 MOVQ gg+0(FP), BX
Russ Cox6c976392013-02-20 17:48:23 -0500888#ifdef GOOS_windows
Russ Cox89f185f2014-06-26 11:54:39 -0400889 CMPQ BX, $0
Russ Cox6c976392013-02-20 17:48:23 -0500890 JNE settls
891 MOVQ $0, 0x28(GS)
892 RET
893settls:
Russ Cox89f185f2014-06-26 11:54:39 -0400894 MOVQ g_m(BX), AX
Russ Cox6c976392013-02-20 17:48:23 -0500895 LEAQ m_tls(AX), AX
896 MOVQ AX, 0x28(GS)
897#endif
898 get_tls(CX)
Russ Cox6c976392013-02-20 17:48:23 -0500899 MOVQ BX, g(CX)
900 RET
901
Russ Cox89f185f2014-06-26 11:54:39 -0400902// void setg_gcc(G*); set g called from gcc.
903TEXT setg_gcc<>(SB),NOSPLIT,$0
Russ Cox6a70f9d2013-03-25 18:14:02 -0400904 get_tls(AX)
Russ Cox89f185f2014-06-26 11:54:39 -0400905 MOVQ DI, g(AX)
Russ Cox6a70f9d2013-03-25 18:14:02 -0400906 RET
907
Devon H. O'Dell5a4a08f2009-12-08 18:19:30 -0800908// check that SP is in range [g->stackbase, g->stackguard)
Keith Randall5a546962013-08-07 10:23:24 -0700909TEXT runtime·stackcheck(SB), NOSPLIT, $0-0
Russ Coxe473f422010-08-04 17:50:22 -0700910 get_tls(CX)
911 MOVQ g(CX), AX
912 CMPQ g_stackbase(AX), SP
Russ Cox01eaf782010-03-30 10:53:16 -0700913 JHI 2(PC)
914 INT $3
Russ Coxe473f422010-08-04 17:50:22 -0700915 CMPQ SP, g_stackguard(AX)
Russ Cox01eaf782010-03-30 10:53:16 -0700916 JHI 2(PC)
917 INT $3
918 RET
919
Keith Randall5a546962013-08-07 10:23:24 -0700920TEXT runtime·getcallerpc(SB),NOSPLIT,$0-8
Russ Cox6c196012010-04-05 12:51:09 -0700921 MOVQ x+0(FP),AX // addr of first arg
922 MOVQ -8(AX),AX // get calling pc
923 RET
924
Keith Randall14c81432014-06-17 21:59:50 -0700925TEXT runtime·gogetcallerpc(SB),NOSPLIT,$0-16
926 MOVQ p+0(FP),AX // addr of first arg
Keith Randall61dca942014-06-16 23:03:03 -0700927 MOVQ -8(AX),AX // get calling pc
Keith Randall14c81432014-06-17 21:59:50 -0700928 MOVQ AX,ret+8(FP)
Keith Randall61dca942014-06-16 23:03:03 -0700929 RET
930
Keith Randall5a546962013-08-07 10:23:24 -0700931TEXT runtime·setcallerpc(SB),NOSPLIT,$0-16
Russ Cox6c196012010-04-05 12:51:09 -0700932 MOVQ x+0(FP),AX // addr of first arg
933 MOVQ x+8(FP), BX
934 MOVQ BX, -8(AX) // set calling pc
935 RET
936
Keith Randall5a546962013-08-07 10:23:24 -0700937TEXT runtime·getcallersp(SB),NOSPLIT,$0-8
Russ Cox6c196012010-04-05 12:51:09 -0700938 MOVQ sp+0(FP), AX
939 RET
940
Damian Gryski8e765da2012-02-02 14:09:27 -0500941// int64 runtime·cputicks(void)
Keith Randall5a546962013-08-07 10:23:24 -0700942TEXT runtime·cputicks(SB),NOSPLIT,$0-0
Damian Gryski8e765da2012-02-02 14:09:27 -0500943 RDTSC
944 SHLQ $32, DX
945 ADDQ DX, AX
946 RET
947
Keith Randall5a546962013-08-07 10:23:24 -0700948TEXT runtime·stackguard(SB),NOSPLIT,$0-16
Russ Cox9e5db8c2012-03-15 15:22:30 -0400949 MOVQ SP, DX
950 MOVQ DX, sp+0(FP)
951 get_tls(CX)
952 MOVQ g(CX), BX
953 MOVQ g_stackguard(BX), DX
Russ Cox07720b62013-03-22 12:57:55 -0400954 MOVQ DX, limit+8(FP)
Russ Cox9e5db8c2012-03-15 15:22:30 -0400955 RET
956
Russ Cox68b42552010-11-04 14:00:19 -0400957GLOBL runtime·tls0(SB), $64
Keith Randalla5d40242013-03-12 10:47:44 -0700958
959// hash function using AES hardware instructions
Keith Randalla2a97682014-07-31 15:07:05 -0700960TEXT runtime·aeshash(SB),NOSPLIT,$0-32
961 MOVQ p+0(FP), AX // ptr to data
962 MOVQ s+8(FP), CX // size
Keith Randalla5d40242013-03-12 10:47:44 -0700963 JMP runtime·aeshashbody(SB)
964
Keith Randalla2a97682014-07-31 15:07:05 -0700965TEXT runtime·aeshashstr(SB),NOSPLIT,$0-32
966 MOVQ p+0(FP), AX // ptr to string struct
967 // s+8(FP) is ignored, it is always sizeof(String)
Keith Randalla5d40242013-03-12 10:47:44 -0700968 MOVQ 8(AX), CX // length of string
969 MOVQ (AX), AX // string data
970 JMP runtime·aeshashbody(SB)
971
972// AX: data
973// CX: length
Keith Randalla2a97682014-07-31 15:07:05 -0700974TEXT runtime·aeshashbody(SB),NOSPLIT,$0-32
975 MOVQ h+16(FP), X0 // seed to low 64 bits of xmm0
Keith Randalla5d40242013-03-12 10:47:44 -0700976 PINSRQ $1, CX, X0 // size to high 64 bits of xmm0
Keith Randalldb53d972013-03-20 14:34:26 -0700977 MOVO runtime·aeskeysched+0(SB), X2
978 MOVO runtime·aeskeysched+16(SB), X3
Keith Randallee669722013-05-15 09:40:14 -0700979 CMPQ CX, $16
980 JB aessmall
Keith Randalla5d40242013-03-12 10:47:44 -0700981aesloop:
982 CMPQ CX, $16
Keith Randallee669722013-05-15 09:40:14 -0700983 JBE aesloopend
Keith Randalla5d40242013-03-12 10:47:44 -0700984 MOVOU (AX), X1
985 AESENC X2, X0
986 AESENC X1, X0
987 SUBQ $16, CX
988 ADDQ $16, AX
989 JMP aesloop
Keith Randallee669722013-05-15 09:40:14 -0700990// 1-16 bytes remaining
Keith Randalla5d40242013-03-12 10:47:44 -0700991aesloopend:
Keith Randallee669722013-05-15 09:40:14 -0700992 // This load may overlap with the previous load above.
993 // We'll hash some bytes twice, but that's ok.
994 MOVOU -16(AX)(CX*1), X1
995 JMP partial
996// 0-15 bytes
997aessmall:
Keith Randalla5d40242013-03-12 10:47:44 -0700998 TESTQ CX, CX
Keith Randallee669722013-05-15 09:40:14 -0700999 JE finalize // 0 bytes
Keith Randalla5d40242013-03-12 10:47:44 -07001000
Keith Randallee669722013-05-15 09:40:14 -07001001 CMPB AX, $0xf0
1002 JA highpartial
Keith Randalla5d40242013-03-12 10:47:44 -07001003
Keith Randallee669722013-05-15 09:40:14 -07001004 // 16 bytes loaded at this address won't cross
1005 // a page boundary, so we can load it directly.
Keith Randalla5d40242013-03-12 10:47:44 -07001006 MOVOU (AX), X1
1007 ADDQ CX, CX
Russ Cox9aa1e9a2014-08-12 19:51:20 -04001008 MOVQ $masks<>(SB), BP
1009 PAND (BP)(CX*8), X1
Keith Randalla5d40242013-03-12 10:47:44 -07001010 JMP partial
1011highpartial:
Keith Randallee669722013-05-15 09:40:14 -07001012 // address ends in 1111xxxx. Might be up against
Keith Randalla5d40242013-03-12 10:47:44 -07001013 // a page boundary, so load ending at last byte.
1014 // Then shift bytes down using pshufb.
1015 MOVOU -16(AX)(CX*1), X1
1016 ADDQ CX, CX
Russ Cox9aa1e9a2014-08-12 19:51:20 -04001017 MOVQ $shifts<>(SB), BP
1018 PSHUFB (BP)(CX*8), X1
Keith Randalla5d40242013-03-12 10:47:44 -07001019partial:
1020 // incorporate partial block into hash
1021 AESENC X3, X0
1022 AESENC X1, X0
1023finalize:
1024 // finalize hash
1025 AESENC X2, X0
1026 AESENC X3, X0
1027 AESENC X2, X0
Keith Randalla2a97682014-07-31 15:07:05 -07001028 MOVQ X0, res+24(FP)
Keith Randalla5d40242013-03-12 10:47:44 -07001029 RET
1030
Keith Randalla2a97682014-07-31 15:07:05 -07001031TEXT runtime·aeshash32(SB),NOSPLIT,$0-32
1032 MOVQ p+0(FP), AX // ptr to data
1033 // s+8(FP) is ignored, it is always sizeof(int32)
1034 MOVQ h+16(FP), X0 // seed
Keith Randalla5d40242013-03-12 10:47:44 -07001035 PINSRD $2, (AX), X0 // data
Keith Randalldb53d972013-03-20 14:34:26 -07001036 AESENC runtime·aeskeysched+0(SB), X0
1037 AESENC runtime·aeskeysched+16(SB), X0
1038 AESENC runtime·aeskeysched+0(SB), X0
Keith Randalla2a97682014-07-31 15:07:05 -07001039 MOVQ X0, res+24(FP)
Keith Randalla5d40242013-03-12 10:47:44 -07001040 RET
1041
Keith Randalla2a97682014-07-31 15:07:05 -07001042TEXT runtime·aeshash64(SB),NOSPLIT,$0-32
1043 MOVQ p+0(FP), AX // ptr to data
1044 // s+8(FP) is ignored, it is always sizeof(int64)
1045 MOVQ h+16(FP), X0 // seed
Keith Randalla5d40242013-03-12 10:47:44 -07001046 PINSRQ $1, (AX), X0 // data
Keith Randalldb53d972013-03-20 14:34:26 -07001047 AESENC runtime·aeskeysched+0(SB), X0
1048 AESENC runtime·aeskeysched+16(SB), X0
1049 AESENC runtime·aeskeysched+0(SB), X0
Keith Randalla2a97682014-07-31 15:07:05 -07001050 MOVQ X0, res+24(FP)
Keith Randalla5d40242013-03-12 10:47:44 -07001051 RET
1052
1053// simple mask to get rid of data in the high part of the register.
Russ Cox9ddfb642013-07-16 16:24:09 -04001054DATA masks<>+0x00(SB)/8, $0x0000000000000000
1055DATA masks<>+0x08(SB)/8, $0x0000000000000000
1056DATA masks<>+0x10(SB)/8, $0x00000000000000ff
1057DATA masks<>+0x18(SB)/8, $0x0000000000000000
1058DATA masks<>+0x20(SB)/8, $0x000000000000ffff
1059DATA masks<>+0x28(SB)/8, $0x0000000000000000
1060DATA masks<>+0x30(SB)/8, $0x0000000000ffffff
1061DATA masks<>+0x38(SB)/8, $0x0000000000000000
1062DATA masks<>+0x40(SB)/8, $0x00000000ffffffff
1063DATA masks<>+0x48(SB)/8, $0x0000000000000000
1064DATA masks<>+0x50(SB)/8, $0x000000ffffffffff
1065DATA masks<>+0x58(SB)/8, $0x0000000000000000
1066DATA masks<>+0x60(SB)/8, $0x0000ffffffffffff
1067DATA masks<>+0x68(SB)/8, $0x0000000000000000
1068DATA masks<>+0x70(SB)/8, $0x00ffffffffffffff
1069DATA masks<>+0x78(SB)/8, $0x0000000000000000
1070DATA masks<>+0x80(SB)/8, $0xffffffffffffffff
1071DATA masks<>+0x88(SB)/8, $0x0000000000000000
1072DATA masks<>+0x90(SB)/8, $0xffffffffffffffff
1073DATA masks<>+0x98(SB)/8, $0x00000000000000ff
1074DATA masks<>+0xa0(SB)/8, $0xffffffffffffffff
1075DATA masks<>+0xa8(SB)/8, $0x000000000000ffff
1076DATA masks<>+0xb0(SB)/8, $0xffffffffffffffff
1077DATA masks<>+0xb8(SB)/8, $0x0000000000ffffff
1078DATA masks<>+0xc0(SB)/8, $0xffffffffffffffff
1079DATA masks<>+0xc8(SB)/8, $0x00000000ffffffff
1080DATA masks<>+0xd0(SB)/8, $0xffffffffffffffff
1081DATA masks<>+0xd8(SB)/8, $0x000000ffffffffff
1082DATA masks<>+0xe0(SB)/8, $0xffffffffffffffff
1083DATA masks<>+0xe8(SB)/8, $0x0000ffffffffffff
1084DATA masks<>+0xf0(SB)/8, $0xffffffffffffffff
1085DATA masks<>+0xf8(SB)/8, $0x00ffffffffffffff
Keith Randall5a546962013-08-07 10:23:24 -07001086GLOBL masks<>(SB),RODATA,$256
Keith Randalla5d40242013-03-12 10:47:44 -07001087
Russ Cox9ddfb642013-07-16 16:24:09 -04001088// these are arguments to pshufb. They move data down from
1089// the high bytes of the register to the low bytes of the register.
1090// index is how many bytes to move.
1091DATA shifts<>+0x00(SB)/8, $0x0000000000000000
1092DATA shifts<>+0x08(SB)/8, $0x0000000000000000
1093DATA shifts<>+0x10(SB)/8, $0xffffffffffffff0f
1094DATA shifts<>+0x18(SB)/8, $0xffffffffffffffff
1095DATA shifts<>+0x20(SB)/8, $0xffffffffffff0f0e
1096DATA shifts<>+0x28(SB)/8, $0xffffffffffffffff
1097DATA shifts<>+0x30(SB)/8, $0xffffffffff0f0e0d
1098DATA shifts<>+0x38(SB)/8, $0xffffffffffffffff
1099DATA shifts<>+0x40(SB)/8, $0xffffffff0f0e0d0c
1100DATA shifts<>+0x48(SB)/8, $0xffffffffffffffff
1101DATA shifts<>+0x50(SB)/8, $0xffffff0f0e0d0c0b
1102DATA shifts<>+0x58(SB)/8, $0xffffffffffffffff
1103DATA shifts<>+0x60(SB)/8, $0xffff0f0e0d0c0b0a
1104DATA shifts<>+0x68(SB)/8, $0xffffffffffffffff
1105DATA shifts<>+0x70(SB)/8, $0xff0f0e0d0c0b0a09
1106DATA shifts<>+0x78(SB)/8, $0xffffffffffffffff
1107DATA shifts<>+0x80(SB)/8, $0x0f0e0d0c0b0a0908
1108DATA shifts<>+0x88(SB)/8, $0xffffffffffffffff
1109DATA shifts<>+0x90(SB)/8, $0x0e0d0c0b0a090807
1110DATA shifts<>+0x98(SB)/8, $0xffffffffffffff0f
1111DATA shifts<>+0xa0(SB)/8, $0x0d0c0b0a09080706
1112DATA shifts<>+0xa8(SB)/8, $0xffffffffffff0f0e
1113DATA shifts<>+0xb0(SB)/8, $0x0c0b0a0908070605
1114DATA shifts<>+0xb8(SB)/8, $0xffffffffff0f0e0d
1115DATA shifts<>+0xc0(SB)/8, $0x0b0a090807060504
1116DATA shifts<>+0xc8(SB)/8, $0xffffffff0f0e0d0c
1117DATA shifts<>+0xd0(SB)/8, $0x0a09080706050403
1118DATA shifts<>+0xd8(SB)/8, $0xffffff0f0e0d0c0b
1119DATA shifts<>+0xe0(SB)/8, $0x0908070605040302
1120DATA shifts<>+0xe8(SB)/8, $0xffff0f0e0d0c0b0a
1121DATA shifts<>+0xf0(SB)/8, $0x0807060504030201
1122DATA shifts<>+0xf8(SB)/8, $0xff0f0e0d0c0b0a09
Keith Randall5a546962013-08-07 10:23:24 -07001123GLOBL shifts<>(SB),RODATA,$256
Keith Randall3d5daa22013-04-02 16:26:15 -07001124
Keith Randall7aa4e5a2014-08-07 14:52:55 -07001125TEXT runtime·memeq(SB),NOSPLIT,$0-25
Keith Randall0c6b55e2014-07-16 14:16:19 -07001126 MOVQ a+0(FP), SI
1127 MOVQ b+8(FP), DI
1128 MOVQ size+16(FP), BX
1129 CALL runtime·memeqbody(SB)
1130 MOVB AX, ret+24(FP)
1131 RET
1132
Keith Randallb36ed902014-06-16 21:00:37 -07001133// eqstring tests whether two strings are equal.
1134// See runtime_test.go:eqstring_generic for
1135// equivlaent Go code.
1136TEXT runtime·eqstring(SB),NOSPLIT,$0-33
1137 MOVQ s1len+8(FP), AX
1138 MOVQ s2len+24(FP), BX
1139 CMPQ AX, BX
1140 JNE different
1141 MOVQ s1str+0(FP), SI
1142 MOVQ s2str+16(FP), DI
1143 CMPQ SI, DI
1144 JEQ same
1145 CALL runtime·memeqbody(SB)
1146 MOVB AX, v+32(FP)
1147 RET
1148same:
1149 MOVB $1, v+32(FP)
1150 RET
1151different:
1152 MOVB $0, v+32(FP)
1153 RET
1154
Keith Randall3d5daa22013-04-02 16:26:15 -07001155// a in SI
1156// b in DI
1157// count in BX
Keith Randall5a546962013-08-07 10:23:24 -07001158TEXT runtime·memeqbody(SB),NOSPLIT,$0-0
Keith Randall3d5daa22013-04-02 16:26:15 -07001159 XORQ AX, AX
1160
1161 CMPQ BX, $8
1162 JB small
1163
1164 // 64 bytes at a time using xmm registers
1165hugeloop:
1166 CMPQ BX, $64
1167 JB bigloop
1168 MOVOU (SI), X0
1169 MOVOU (DI), X1
1170 MOVOU 16(SI), X2
1171 MOVOU 16(DI), X3
1172 MOVOU 32(SI), X4
1173 MOVOU 32(DI), X5
1174 MOVOU 48(SI), X6
1175 MOVOU 48(DI), X7
1176 PCMPEQB X1, X0
1177 PCMPEQB X3, X2
1178 PCMPEQB X5, X4
1179 PCMPEQB X7, X6
1180 PAND X2, X0
1181 PAND X6, X4
1182 PAND X4, X0
1183 PMOVMSKB X0, DX
1184 ADDQ $64, SI
1185 ADDQ $64, DI
1186 SUBQ $64, BX
1187 CMPL DX, $0xffff
1188 JEQ hugeloop
1189 RET
1190
1191 // 8 bytes at a time using 64-bit register
1192bigloop:
1193 CMPQ BX, $8
1194 JBE leftover
1195 MOVQ (SI), CX
1196 MOVQ (DI), DX
1197 ADDQ $8, SI
1198 ADDQ $8, DI
1199 SUBQ $8, BX
1200 CMPQ CX, DX
1201 JEQ bigloop
1202 RET
1203
1204 // remaining 0-8 bytes
1205leftover:
1206 MOVQ -8(SI)(BX*1), CX
1207 MOVQ -8(DI)(BX*1), DX
1208 CMPQ CX, DX
1209 SETEQ AX
1210 RET
1211
1212small:
1213 CMPQ BX, $0
1214 JEQ equal
1215
1216 LEAQ 0(BX*8), CX
1217 NEGQ CX
1218
1219 CMPB SI, $0xf8
1220 JA si_high
1221
1222 // load at SI won't cross a page boundary.
1223 MOVQ (SI), SI
1224 JMP si_finish
1225si_high:
1226 // address ends in 11111xxx. Load up to bytes we want, move to correct position.
1227 MOVQ -8(SI)(BX*1), SI
1228 SHRQ CX, SI
1229si_finish:
1230
1231 // same for DI.
1232 CMPB DI, $0xf8
1233 JA di_high
1234 MOVQ (DI), DI
1235 JMP di_finish
1236di_high:
1237 MOVQ -8(DI)(BX*1), DI
1238 SHRQ CX, DI
1239di_finish:
1240
1241 SUBQ SI, DI
1242 SHLQ CX, DI
1243equal:
1244 SETEQ AX
1245 RET
Keith Randallb3946dc2013-05-14 16:05:51 -07001246
Keith Randall5a546962013-08-07 10:23:24 -07001247TEXT runtime·cmpstring(SB),NOSPLIT,$0-40
Keith Randallb3946dc2013-05-14 16:05:51 -07001248 MOVQ s1+0(FP), SI
1249 MOVQ s1+8(FP), BX
1250 MOVQ s2+16(FP), DI
1251 MOVQ s2+24(FP), DX
1252 CALL runtime·cmpbody(SB)
1253 MOVQ AX, res+32(FP)
1254 RET
1255
Keith Randall5a546962013-08-07 10:23:24 -07001256TEXT bytes·Compare(SB),NOSPLIT,$0-56
Keith Randallb3946dc2013-05-14 16:05:51 -07001257 MOVQ s1+0(FP), SI
1258 MOVQ s1+8(FP), BX
1259 MOVQ s2+24(FP), DI
1260 MOVQ s2+32(FP), DX
1261 CALL runtime·cmpbody(SB)
1262 MOVQ AX, res+48(FP)
1263 RET
1264
1265// input:
1266// SI = a
1267// DI = b
1268// BX = alen
1269// DX = blen
1270// output:
1271// AX = 1/0/-1
Keith Randall5a546962013-08-07 10:23:24 -07001272TEXT runtime·cmpbody(SB),NOSPLIT,$0-0
Keith Randallb3946dc2013-05-14 16:05:51 -07001273 CMPQ SI, DI
1274 JEQ cmp_allsame
1275 CMPQ BX, DX
1276 MOVQ DX, BP
1277 CMOVQLT BX, BP // BP = min(alen, blen) = # of bytes to compare
1278 CMPQ BP, $8
1279 JB cmp_small
1280
1281cmp_loop:
1282 CMPQ BP, $16
1283 JBE cmp_0through16
1284 MOVOU (SI), X0
1285 MOVOU (DI), X1
1286 PCMPEQB X0, X1
1287 PMOVMSKB X1, AX
1288 XORQ $0xffff, AX // convert EQ to NE
1289 JNE cmp_diff16 // branch if at least one byte is not equal
1290 ADDQ $16, SI
1291 ADDQ $16, DI
1292 SUBQ $16, BP
1293 JMP cmp_loop
1294
1295 // AX = bit mask of differences
1296cmp_diff16:
1297 BSFQ AX, BX // index of first byte that differs
1298 XORQ AX, AX
1299 MOVB (SI)(BX*1), CX
1300 CMPB CX, (DI)(BX*1)
1301 SETHI AX
1302 LEAQ -1(AX*2), AX // convert 1/0 to +1/-1
1303 RET
1304
1305 // 0 through 16 bytes left, alen>=8, blen>=8
1306cmp_0through16:
1307 CMPQ BP, $8
1308 JBE cmp_0through8
1309 MOVQ (SI), AX
1310 MOVQ (DI), CX
1311 CMPQ AX, CX
1312 JNE cmp_diff8
1313cmp_0through8:
1314 MOVQ -8(SI)(BP*1), AX
1315 MOVQ -8(DI)(BP*1), CX
1316 CMPQ AX, CX
1317 JEQ cmp_allsame
1318
1319 // AX and CX contain parts of a and b that differ.
1320cmp_diff8:
1321 BSWAPQ AX // reverse order of bytes
1322 BSWAPQ CX
1323 XORQ AX, CX
1324 BSRQ CX, CX // index of highest bit difference
1325 SHRQ CX, AX // move a's bit to bottom
1326 ANDQ $1, AX // mask bit
1327 LEAQ -1(AX*2), AX // 1/0 => +1/-1
1328 RET
1329
1330 // 0-7 bytes in common
1331cmp_small:
1332 LEAQ (BP*8), CX // bytes left -> bits left
1333 NEGQ CX // - bits lift (== 64 - bits left mod 64)
1334 JEQ cmp_allsame
1335
1336 // load bytes of a into high bytes of AX
1337 CMPB SI, $0xf8
1338 JA cmp_si_high
1339 MOVQ (SI), SI
1340 JMP cmp_si_finish
1341cmp_si_high:
1342 MOVQ -8(SI)(BP*1), SI
1343 SHRQ CX, SI
1344cmp_si_finish:
1345 SHLQ CX, SI
1346
1347 // load bytes of b in to high bytes of BX
1348 CMPB DI, $0xf8
1349 JA cmp_di_high
1350 MOVQ (DI), DI
1351 JMP cmp_di_finish
1352cmp_di_high:
1353 MOVQ -8(DI)(BP*1), DI
1354 SHRQ CX, DI
1355cmp_di_finish:
1356 SHLQ CX, DI
1357
1358 BSWAPQ SI // reverse order of bytes
1359 BSWAPQ DI
1360 XORQ SI, DI // find bit differences
1361 JEQ cmp_allsame
1362 BSRQ DI, CX // index of highest bit difference
1363 SHRQ CX, SI // move a's bit to bottom
1364 ANDQ $1, SI // mask bit
1365 LEAQ -1(SI*2), AX // 1/0 => +1/-1
1366 RET
1367
1368cmp_allsame:
1369 XORQ AX, AX
1370 XORQ CX, CX
1371 CMPQ BX, DX
1372 SETGT AX // 1 if alen > blen
1373 SETEQ CX // 1 if alen == blen
1374 LEAQ -1(CX)(AX*2), AX // 1,0,-1 result
1375 RET
Brad Fitzpatricke2a1bd62013-08-01 16:11:19 -07001376
Keith Randall5a546962013-08-07 10:23:24 -07001377TEXT bytes·IndexByte(SB),NOSPLIT,$0
Brad Fitzpatricke2a1bd62013-08-01 16:11:19 -07001378 MOVQ s+0(FP), SI
1379 MOVQ s_len+8(FP), BX
1380 MOVB c+24(FP), AL
Brad Fitzpatrick598c7892013-08-05 15:04:05 -07001381 CALL runtime·indexbytebody(SB)
1382 MOVQ AX, ret+32(FP)
1383 RET
1384
Keith Randall5a546962013-08-07 10:23:24 -07001385TEXT strings·IndexByte(SB),NOSPLIT,$0
Brad Fitzpatrick598c7892013-08-05 15:04:05 -07001386 MOVQ s+0(FP), SI
1387 MOVQ s_len+8(FP), BX
1388 MOVB c+16(FP), AL
1389 CALL runtime·indexbytebody(SB)
1390 MOVQ AX, ret+24(FP)
1391 RET
1392
1393// input:
1394// SI: data
1395// BX: data len
1396// AL: byte sought
1397// output:
1398// AX
Keith Randall5a546962013-08-07 10:23:24 -07001399TEXT runtime·indexbytebody(SB),NOSPLIT,$0
Brad Fitzpatricke2a1bd62013-08-01 16:11:19 -07001400 MOVQ SI, DI
1401
1402 CMPQ BX, $16
1403 JLT indexbyte_small
1404
1405 // round up to first 16-byte boundary
1406 TESTQ $15, SI
1407 JZ aligned
1408 MOVQ SI, CX
1409 ANDQ $~15, CX
1410 ADDQ $16, CX
1411
1412 // search the beginning
1413 SUBQ SI, CX
1414 REPN; SCASB
1415 JZ success
1416
1417// DI is 16-byte aligned; get ready to search using SSE instructions
1418aligned:
1419 // round down to last 16-byte boundary
1420 MOVQ BX, R11
1421 ADDQ SI, R11
1422 ANDQ $~15, R11
1423
1424 // shuffle X0 around so that each byte contains c
1425 MOVD AX, X0
1426 PUNPCKLBW X0, X0
1427 PUNPCKLBW X0, X0
1428 PSHUFL $0, X0, X0
1429 JMP condition
1430
1431sse:
1432 // move the next 16-byte chunk of the buffer into X1
1433 MOVO (DI), X1
1434 // compare bytes in X0 to X1
1435 PCMPEQB X0, X1
1436 // take the top bit of each byte in X1 and put the result in DX
1437 PMOVMSKB X1, DX
1438 TESTL DX, DX
1439 JNZ ssesuccess
1440 ADDQ $16, DI
1441
1442condition:
1443 CMPQ DI, R11
1444 JLT sse
1445
1446 // search the end
1447 MOVQ SI, CX
1448 ADDQ BX, CX
1449 SUBQ R11, CX
1450 // if CX == 0, the zero flag will be set and we'll end up
1451 // returning a false success
1452 JZ failure
1453 REPN; SCASB
1454 JZ success
1455
1456failure:
Brad Fitzpatrick598c7892013-08-05 15:04:05 -07001457 MOVQ $-1, AX
Brad Fitzpatricke2a1bd62013-08-01 16:11:19 -07001458 RET
1459
1460// handle for lengths < 16
1461indexbyte_small:
1462 MOVQ BX, CX
1463 REPN; SCASB
1464 JZ success
Brad Fitzpatrick598c7892013-08-05 15:04:05 -07001465 MOVQ $-1, AX
Brad Fitzpatricke2a1bd62013-08-01 16:11:19 -07001466 RET
1467
1468// we've found the chunk containing the byte
1469// now just figure out which specific byte it is
1470ssesuccess:
1471 // get the index of the least significant set bit
1472 BSFW DX, DX
1473 SUBQ SI, DI
1474 ADDQ DI, DX
Brad Fitzpatrick598c7892013-08-05 15:04:05 -07001475 MOVQ DX, AX
Brad Fitzpatricke2a1bd62013-08-01 16:11:19 -07001476 RET
1477
1478success:
1479 SUBQ SI, DI
1480 SUBL $1, DI
Brad Fitzpatrick598c7892013-08-05 15:04:05 -07001481 MOVQ DI, AX
Brad Fitzpatricke2a1bd62013-08-01 16:11:19 -07001482 RET
1483
Keith Randall5a546962013-08-07 10:23:24 -07001484TEXT bytes·Equal(SB),NOSPLIT,$0-49
Brad Fitzpatricke2a1bd62013-08-01 16:11:19 -07001485 MOVQ a_len+8(FP), BX
1486 MOVQ b_len+32(FP), CX
1487 XORQ AX, AX
1488 CMPQ BX, CX
1489 JNE eqret
1490 MOVQ a+0(FP), SI
1491 MOVQ b+24(FP), DI
1492 CALL runtime·memeqbody(SB)
1493eqret:
1494 MOVB AX, ret+48(FP)
1495 RET
Keith Randall6c7cbf02014-04-01 12:51:02 -07001496
1497// A Duff's device for zeroing memory.
1498// The compiler jumps to computed addresses within
1499// this routine to zero chunks of memory. Do not
1500// change this code without also changing the code
1501// in ../../cmd/6g/ggen.c:clearfat.
1502// AX: zero
1503// DI: ptr to memory to be zeroed
1504// DI is updated as a side effect.
1505TEXT runtime·duffzero(SB), NOSPLIT, $0-0
1506 STOSQ
1507 STOSQ
1508 STOSQ
1509 STOSQ
1510 STOSQ
1511 STOSQ
1512 STOSQ
1513 STOSQ
1514 STOSQ
1515 STOSQ
1516 STOSQ
1517 STOSQ
1518 STOSQ
1519 STOSQ
1520 STOSQ
1521 STOSQ
1522 STOSQ
1523 STOSQ
1524 STOSQ
1525 STOSQ
1526 STOSQ
1527 STOSQ
1528 STOSQ
1529 STOSQ
1530 STOSQ
1531 STOSQ
1532 STOSQ
1533 STOSQ
1534 STOSQ
1535 STOSQ
1536 STOSQ
1537 STOSQ
1538 STOSQ
1539 STOSQ
1540 STOSQ
1541 STOSQ
1542 STOSQ
1543 STOSQ
1544 STOSQ
1545 STOSQ
1546 STOSQ
1547 STOSQ
1548 STOSQ
1549 STOSQ
1550 STOSQ
1551 STOSQ
1552 STOSQ
1553 STOSQ
1554 STOSQ
1555 STOSQ
1556 STOSQ
1557 STOSQ
1558 STOSQ
1559 STOSQ
1560 STOSQ
1561 STOSQ
1562 STOSQ
1563 STOSQ
1564 STOSQ
1565 STOSQ
1566 STOSQ
1567 STOSQ
1568 STOSQ
1569 STOSQ
1570 STOSQ
1571 STOSQ
1572 STOSQ
1573 STOSQ
1574 STOSQ
1575 STOSQ
1576 STOSQ
1577 STOSQ
1578 STOSQ
1579 STOSQ
1580 STOSQ
1581 STOSQ
1582 STOSQ
1583 STOSQ
1584 STOSQ
1585 STOSQ
1586 STOSQ
1587 STOSQ
1588 STOSQ
1589 STOSQ
1590 STOSQ
1591 STOSQ
1592 STOSQ
1593 STOSQ
1594 STOSQ
1595 STOSQ
1596 STOSQ
1597 STOSQ
1598 STOSQ
1599 STOSQ
1600 STOSQ
1601 STOSQ
1602 STOSQ
1603 STOSQ
1604 STOSQ
1605 STOSQ
1606 STOSQ
1607 STOSQ
1608 STOSQ
1609 STOSQ
1610 STOSQ
1611 STOSQ
1612 STOSQ
1613 STOSQ
1614 STOSQ
1615 STOSQ
1616 STOSQ
1617 STOSQ
1618 STOSQ
1619 STOSQ
1620 STOSQ
1621 STOSQ
1622 STOSQ
1623 STOSQ
1624 STOSQ
1625 STOSQ
1626 STOSQ
1627 STOSQ
1628 STOSQ
1629 STOSQ
1630 STOSQ
1631 STOSQ
1632 STOSQ
1633 STOSQ
1634 RET
1635
1636// A Duff's device for copying memory.
1637// The compiler jumps to computed addresses within
1638// this routine to copy chunks of memory. Source
1639// and destination must not overlap. Do not
1640// change this code without also changing the code
1641// in ../../cmd/6g/cgen.c:sgen.
1642// SI: ptr to source memory
1643// DI: ptr to destination memory
1644// SI and DI are updated as a side effect.
1645
1646// NOTE: this is equivalent to a sequence of MOVSQ but
1647// for some reason that is 3.5x slower than this code.
1648// The STOSQ above seem fine, though.
1649TEXT runtime·duffcopy(SB), NOSPLIT, $0-0
1650 MOVQ (SI),CX
1651 ADDQ $8,SI
1652 MOVQ CX,(DI)
1653 ADDQ $8,DI
1654
1655 MOVQ (SI),CX
1656 ADDQ $8,SI
1657 MOVQ CX,(DI)
1658 ADDQ $8,DI
1659
1660 MOVQ (SI),CX
1661 ADDQ $8,SI
1662 MOVQ CX,(DI)
1663 ADDQ $8,DI
1664
1665 MOVQ (SI),CX
1666 ADDQ $8,SI
1667 MOVQ CX,(DI)
1668 ADDQ $8,DI
1669
1670 MOVQ (SI),CX
1671 ADDQ $8,SI
1672 MOVQ CX,(DI)
1673 ADDQ $8,DI
1674
1675 MOVQ (SI),CX
1676 ADDQ $8,SI
1677 MOVQ CX,(DI)
1678 ADDQ $8,DI
1679
1680 MOVQ (SI),CX
1681 ADDQ $8,SI
1682 MOVQ CX,(DI)
1683 ADDQ $8,DI
1684
1685 MOVQ (SI),CX
1686 ADDQ $8,SI
1687 MOVQ CX,(DI)
1688 ADDQ $8,DI
1689
1690 MOVQ (SI),CX
1691 ADDQ $8,SI
1692 MOVQ CX,(DI)
1693 ADDQ $8,DI
1694
1695 MOVQ (SI),CX
1696 ADDQ $8,SI
1697 MOVQ CX,(DI)
1698 ADDQ $8,DI
1699
1700 MOVQ (SI),CX
1701 ADDQ $8,SI
1702 MOVQ CX,(DI)
1703 ADDQ $8,DI
1704
1705 MOVQ (SI),CX
1706 ADDQ $8,SI
1707 MOVQ CX,(DI)
1708 ADDQ $8,DI
1709
1710 MOVQ (SI),CX
1711 ADDQ $8,SI
1712 MOVQ CX,(DI)
1713 ADDQ $8,DI
1714
1715 MOVQ (SI),CX
1716 ADDQ $8,SI
1717 MOVQ CX,(DI)
1718 ADDQ $8,DI
1719
1720 MOVQ (SI),CX
1721 ADDQ $8,SI
1722 MOVQ CX,(DI)
1723 ADDQ $8,DI
1724
1725 MOVQ (SI),CX
1726 ADDQ $8,SI
1727 MOVQ CX,(DI)
1728 ADDQ $8,DI
1729
1730 MOVQ (SI),CX
1731 ADDQ $8,SI
1732 MOVQ CX,(DI)
1733 ADDQ $8,DI
1734
1735 MOVQ (SI),CX
1736 ADDQ $8,SI
1737 MOVQ CX,(DI)
1738 ADDQ $8,DI
1739
1740 MOVQ (SI),CX
1741 ADDQ $8,SI
1742 MOVQ CX,(DI)
1743 ADDQ $8,DI
1744
1745 MOVQ (SI),CX
1746 ADDQ $8,SI
1747 MOVQ CX,(DI)
1748 ADDQ $8,DI
1749
1750 MOVQ (SI),CX
1751 ADDQ $8,SI
1752 MOVQ CX,(DI)
1753 ADDQ $8,DI
1754
1755 MOVQ (SI),CX
1756 ADDQ $8,SI
1757 MOVQ CX,(DI)
1758 ADDQ $8,DI
1759
1760 MOVQ (SI),CX
1761 ADDQ $8,SI
1762 MOVQ CX,(DI)
1763 ADDQ $8,DI
1764
1765 MOVQ (SI),CX
1766 ADDQ $8,SI
1767 MOVQ CX,(DI)
1768 ADDQ $8,DI
1769
1770 MOVQ (SI),CX
1771 ADDQ $8,SI
1772 MOVQ CX,(DI)
1773 ADDQ $8,DI
1774
1775 MOVQ (SI),CX
1776 ADDQ $8,SI
1777 MOVQ CX,(DI)
1778 ADDQ $8,DI
1779
1780 MOVQ (SI),CX
1781 ADDQ $8,SI
1782 MOVQ CX,(DI)
1783 ADDQ $8,DI
1784
1785 MOVQ (SI),CX
1786 ADDQ $8,SI
1787 MOVQ CX,(DI)
1788 ADDQ $8,DI
1789
1790 MOVQ (SI),CX
1791 ADDQ $8,SI
1792 MOVQ CX,(DI)
1793 ADDQ $8,DI
1794
1795 MOVQ (SI),CX
1796 ADDQ $8,SI
1797 MOVQ CX,(DI)
1798 ADDQ $8,DI
1799
1800 MOVQ (SI),CX
1801 ADDQ $8,SI
1802 MOVQ CX,(DI)
1803 ADDQ $8,DI
1804
1805 MOVQ (SI),CX
1806 ADDQ $8,SI
1807 MOVQ CX,(DI)
1808 ADDQ $8,DI
1809
1810 MOVQ (SI),CX
1811 ADDQ $8,SI
1812 MOVQ CX,(DI)
1813 ADDQ $8,DI
1814
1815 MOVQ (SI),CX
1816 ADDQ $8,SI
1817 MOVQ CX,(DI)
1818 ADDQ $8,DI
1819
1820 MOVQ (SI),CX
1821 ADDQ $8,SI
1822 MOVQ CX,(DI)
1823 ADDQ $8,DI
1824
1825 MOVQ (SI),CX
1826 ADDQ $8,SI
1827 MOVQ CX,(DI)
1828 ADDQ $8,DI
1829
1830 MOVQ (SI),CX
1831 ADDQ $8,SI
1832 MOVQ CX,(DI)
1833 ADDQ $8,DI
1834
1835 MOVQ (SI),CX
1836 ADDQ $8,SI
1837 MOVQ CX,(DI)
1838 ADDQ $8,DI
1839
1840 MOVQ (SI),CX
1841 ADDQ $8,SI
1842 MOVQ CX,(DI)
1843 ADDQ $8,DI
1844
1845 MOVQ (SI),CX
1846 ADDQ $8,SI
1847 MOVQ CX,(DI)
1848 ADDQ $8,DI
1849
1850 MOVQ (SI),CX
1851 ADDQ $8,SI
1852 MOVQ CX,(DI)
1853 ADDQ $8,DI
1854
1855 MOVQ (SI),CX
1856 ADDQ $8,SI
1857 MOVQ CX,(DI)
1858 ADDQ $8,DI
1859
1860 MOVQ (SI),CX
1861 ADDQ $8,SI
1862 MOVQ CX,(DI)
1863 ADDQ $8,DI
1864
1865 MOVQ (SI),CX
1866 ADDQ $8,SI
1867 MOVQ CX,(DI)
1868 ADDQ $8,DI
1869
1870 MOVQ (SI),CX
1871 ADDQ $8,SI
1872 MOVQ CX,(DI)
1873 ADDQ $8,DI
1874
1875 MOVQ (SI),CX
1876 ADDQ $8,SI
1877 MOVQ CX,(DI)
1878 ADDQ $8,DI
1879
1880 MOVQ (SI),CX
1881 ADDQ $8,SI
1882 MOVQ CX,(DI)
1883 ADDQ $8,DI
1884
1885 MOVQ (SI),CX
1886 ADDQ $8,SI
1887 MOVQ CX,(DI)
1888 ADDQ $8,DI
1889
1890 MOVQ (SI),CX
1891 ADDQ $8,SI
1892 MOVQ CX,(DI)
1893 ADDQ $8,DI
1894
1895 MOVQ (SI),CX
1896 ADDQ $8,SI
1897 MOVQ CX,(DI)
1898 ADDQ $8,DI
1899
1900 MOVQ (SI),CX
1901 ADDQ $8,SI
1902 MOVQ CX,(DI)
1903 ADDQ $8,DI
1904
1905 MOVQ (SI),CX
1906 ADDQ $8,SI
1907 MOVQ CX,(DI)
1908 ADDQ $8,DI
1909
1910 MOVQ (SI),CX
1911 ADDQ $8,SI
1912 MOVQ CX,(DI)
1913 ADDQ $8,DI
1914
1915 MOVQ (SI),CX
1916 ADDQ $8,SI
1917 MOVQ CX,(DI)
1918 ADDQ $8,DI
1919
1920 MOVQ (SI),CX
1921 ADDQ $8,SI
1922 MOVQ CX,(DI)
1923 ADDQ $8,DI
1924
1925 MOVQ (SI),CX
1926 ADDQ $8,SI
1927 MOVQ CX,(DI)
1928 ADDQ $8,DI
1929
1930 MOVQ (SI),CX
1931 ADDQ $8,SI
1932 MOVQ CX,(DI)
1933 ADDQ $8,DI
1934
1935 MOVQ (SI),CX
1936 ADDQ $8,SI
1937 MOVQ CX,(DI)
1938 ADDQ $8,DI
1939
1940 MOVQ (SI),CX
1941 ADDQ $8,SI
1942 MOVQ CX,(DI)
1943 ADDQ $8,DI
1944
1945 MOVQ (SI),CX
1946 ADDQ $8,SI
1947 MOVQ CX,(DI)
1948 ADDQ $8,DI
1949
1950 MOVQ (SI),CX
1951 ADDQ $8,SI
1952 MOVQ CX,(DI)
1953 ADDQ $8,DI
1954
1955 MOVQ (SI),CX
1956 ADDQ $8,SI
1957 MOVQ CX,(DI)
1958 ADDQ $8,DI
1959
1960 MOVQ (SI),CX
1961 ADDQ $8,SI
1962 MOVQ CX,(DI)
1963 ADDQ $8,DI
1964
1965 MOVQ (SI),CX
1966 ADDQ $8,SI
1967 MOVQ CX,(DI)
1968 ADDQ $8,DI
1969
1970 MOVQ (SI),CX
1971 ADDQ $8,SI
1972 MOVQ CX,(DI)
1973 ADDQ $8,DI
1974
1975 MOVQ (SI),CX
1976 ADDQ $8,SI
1977 MOVQ CX,(DI)
1978 ADDQ $8,DI
1979
1980 MOVQ (SI),CX
1981 ADDQ $8,SI
1982 MOVQ CX,(DI)
1983 ADDQ $8,DI
1984
1985 MOVQ (SI),CX
1986 ADDQ $8,SI
1987 MOVQ CX,(DI)
1988 ADDQ $8,DI
1989
1990 MOVQ (SI),CX
1991 ADDQ $8,SI
1992 MOVQ CX,(DI)
1993 ADDQ $8,DI
1994
1995 MOVQ (SI),CX
1996 ADDQ $8,SI
1997 MOVQ CX,(DI)
1998 ADDQ $8,DI
1999
2000 MOVQ (SI),CX
2001 ADDQ $8,SI
2002 MOVQ CX,(DI)
2003 ADDQ $8,DI
2004
2005 MOVQ (SI),CX
2006 ADDQ $8,SI
2007 MOVQ CX,(DI)
2008 ADDQ $8,DI
2009
2010 MOVQ (SI),CX
2011 ADDQ $8,SI
2012 MOVQ CX,(DI)
2013 ADDQ $8,DI
2014
2015 MOVQ (SI),CX
2016 ADDQ $8,SI
2017 MOVQ CX,(DI)
2018 ADDQ $8,DI
2019
2020 MOVQ (SI),CX
2021 ADDQ $8,SI
2022 MOVQ CX,(DI)
2023 ADDQ $8,DI
2024
2025 MOVQ (SI),CX
2026 ADDQ $8,SI
2027 MOVQ CX,(DI)
2028 ADDQ $8,DI
2029
2030 MOVQ (SI),CX
2031 ADDQ $8,SI
2032 MOVQ CX,(DI)
2033 ADDQ $8,DI
2034
2035 MOVQ (SI),CX
2036 ADDQ $8,SI
2037 MOVQ CX,(DI)
2038 ADDQ $8,DI
2039
2040 MOVQ (SI),CX
2041 ADDQ $8,SI
2042 MOVQ CX,(DI)
2043 ADDQ $8,DI
2044
2045 MOVQ (SI),CX
2046 ADDQ $8,SI
2047 MOVQ CX,(DI)
2048 ADDQ $8,DI
2049
2050 MOVQ (SI),CX
2051 ADDQ $8,SI
2052 MOVQ CX,(DI)
2053 ADDQ $8,DI
2054
2055 MOVQ (SI),CX
2056 ADDQ $8,SI
2057 MOVQ CX,(DI)
2058 ADDQ $8,DI
2059
2060 MOVQ (SI),CX
2061 ADDQ $8,SI
2062 MOVQ CX,(DI)
2063 ADDQ $8,DI
2064
2065 MOVQ (SI),CX
2066 ADDQ $8,SI
2067 MOVQ CX,(DI)
2068 ADDQ $8,DI
2069
2070 MOVQ (SI),CX
2071 ADDQ $8,SI
2072 MOVQ CX,(DI)
2073 ADDQ $8,DI
2074
2075 MOVQ (SI),CX
2076 ADDQ $8,SI
2077 MOVQ CX,(DI)
2078 ADDQ $8,DI
2079
2080 MOVQ (SI),CX
2081 ADDQ $8,SI
2082 MOVQ CX,(DI)
2083 ADDQ $8,DI
2084
2085 MOVQ (SI),CX
2086 ADDQ $8,SI
2087 MOVQ CX,(DI)
2088 ADDQ $8,DI
2089
2090 MOVQ (SI),CX
2091 ADDQ $8,SI
2092 MOVQ CX,(DI)
2093 ADDQ $8,DI
2094
2095 MOVQ (SI),CX
2096 ADDQ $8,SI
2097 MOVQ CX,(DI)
2098 ADDQ $8,DI
2099
2100 MOVQ (SI),CX
2101 ADDQ $8,SI
2102 MOVQ CX,(DI)
2103 ADDQ $8,DI
2104
2105 MOVQ (SI),CX
2106 ADDQ $8,SI
2107 MOVQ CX,(DI)
2108 ADDQ $8,DI
2109
2110 MOVQ (SI),CX
2111 ADDQ $8,SI
2112 MOVQ CX,(DI)
2113 ADDQ $8,DI
2114
2115 MOVQ (SI),CX
2116 ADDQ $8,SI
2117 MOVQ CX,(DI)
2118 ADDQ $8,DI
2119
2120 MOVQ (SI),CX
2121 ADDQ $8,SI
2122 MOVQ CX,(DI)
2123 ADDQ $8,DI
2124
2125 MOVQ (SI),CX
2126 ADDQ $8,SI
2127 MOVQ CX,(DI)
2128 ADDQ $8,DI
2129
2130 MOVQ (SI),CX
2131 ADDQ $8,SI
2132 MOVQ CX,(DI)
2133 ADDQ $8,DI
2134
2135 MOVQ (SI),CX
2136 ADDQ $8,SI
2137 MOVQ CX,(DI)
2138 ADDQ $8,DI
2139
2140 MOVQ (SI),CX
2141 ADDQ $8,SI
2142 MOVQ CX,(DI)
2143 ADDQ $8,DI
2144
2145 MOVQ (SI),CX
2146 ADDQ $8,SI
2147 MOVQ CX,(DI)
2148 ADDQ $8,DI
2149
2150 MOVQ (SI),CX
2151 ADDQ $8,SI
2152 MOVQ CX,(DI)
2153 ADDQ $8,DI
2154
2155 MOVQ (SI),CX
2156 ADDQ $8,SI
2157 MOVQ CX,(DI)
2158 ADDQ $8,DI
2159
2160 MOVQ (SI),CX
2161 ADDQ $8,SI
2162 MOVQ CX,(DI)
2163 ADDQ $8,DI
2164
2165 MOVQ (SI),CX
2166 ADDQ $8,SI
2167 MOVQ CX,(DI)
2168 ADDQ $8,DI
2169
2170 MOVQ (SI),CX
2171 ADDQ $8,SI
2172 MOVQ CX,(DI)
2173 ADDQ $8,DI
2174
2175 MOVQ (SI),CX
2176 ADDQ $8,SI
2177 MOVQ CX,(DI)
2178 ADDQ $8,DI
2179
2180 MOVQ (SI),CX
2181 ADDQ $8,SI
2182 MOVQ CX,(DI)
2183 ADDQ $8,DI
2184
2185 MOVQ (SI),CX
2186 ADDQ $8,SI
2187 MOVQ CX,(DI)
2188 ADDQ $8,DI
2189
2190 MOVQ (SI),CX
2191 ADDQ $8,SI
2192 MOVQ CX,(DI)
2193 ADDQ $8,DI
2194
2195 MOVQ (SI),CX
2196 ADDQ $8,SI
2197 MOVQ CX,(DI)
2198 ADDQ $8,DI
2199
2200 MOVQ (SI),CX
2201 ADDQ $8,SI
2202 MOVQ CX,(DI)
2203 ADDQ $8,DI
2204
2205 MOVQ (SI),CX
2206 ADDQ $8,SI
2207 MOVQ CX,(DI)
2208 ADDQ $8,DI
2209
2210 MOVQ (SI),CX
2211 ADDQ $8,SI
2212 MOVQ CX,(DI)
2213 ADDQ $8,DI
2214
2215 MOVQ (SI),CX
2216 ADDQ $8,SI
2217 MOVQ CX,(DI)
2218 ADDQ $8,DI
2219
2220 MOVQ (SI),CX
2221 ADDQ $8,SI
2222 MOVQ CX,(DI)
2223 ADDQ $8,DI
2224
2225 MOVQ (SI),CX
2226 ADDQ $8,SI
2227 MOVQ CX,(DI)
2228 ADDQ $8,DI
2229
2230 MOVQ (SI),CX
2231 ADDQ $8,SI
2232 MOVQ CX,(DI)
2233 ADDQ $8,DI
2234
2235 MOVQ (SI),CX
2236 ADDQ $8,SI
2237 MOVQ CX,(DI)
2238 ADDQ $8,DI
2239
2240 MOVQ (SI),CX
2241 ADDQ $8,SI
2242 MOVQ CX,(DI)
2243 ADDQ $8,DI
2244
2245 MOVQ (SI),CX
2246 ADDQ $8,SI
2247 MOVQ CX,(DI)
2248 ADDQ $8,DI
2249
2250 MOVQ (SI),CX
2251 ADDQ $8,SI
2252 MOVQ CX,(DI)
2253 ADDQ $8,DI
2254
2255 MOVQ (SI),CX
2256 ADDQ $8,SI
2257 MOVQ CX,(DI)
2258 ADDQ $8,DI
2259
2260 MOVQ (SI),CX
2261 ADDQ $8,SI
2262 MOVQ CX,(DI)
2263 ADDQ $8,DI
2264
2265 MOVQ (SI),CX
2266 ADDQ $8,SI
2267 MOVQ CX,(DI)
2268 ADDQ $8,DI
2269
2270 MOVQ (SI),CX
2271 ADDQ $8,SI
2272 MOVQ CX,(DI)
2273 ADDQ $8,DI
2274
2275 MOVQ (SI),CX
2276 ADDQ $8,SI
2277 MOVQ CX,(DI)
2278 ADDQ $8,DI
2279
2280 MOVQ (SI),CX
2281 ADDQ $8,SI
2282 MOVQ CX,(DI)
2283 ADDQ $8,DI
2284
2285 MOVQ (SI),CX
2286 ADDQ $8,SI
2287 MOVQ CX,(DI)
2288 ADDQ $8,DI
2289
2290 RET
Dmitriy Vyukov350a8fc2014-05-02 17:32:42 +01002291
2292TEXT runtime·timenow(SB), NOSPLIT, $0-0
2293 JMP time·now(SB)
Keith Randall0c6b55e2014-07-16 14:16:19 -07002294
2295TEXT runtime·fastrand2(SB), NOSPLIT, $0-4
2296 get_tls(CX)
2297 MOVQ g(CX), AX
2298 MOVQ g_m(AX), AX
2299 MOVL m_fastrand(AX), DX
2300 ADDL DX, DX
2301 MOVL DX, BX
2302 XORL $0x88888eef, DX
2303 CMOVLMI BX, DX
2304 MOVL DX, m_fastrand(AX)
2305 MOVL DX, ret+0(FP)
2306 RET