blob: 1d98fc26526ec26b0c63e532e1cdef3ab530d3cc [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
Russ Cox7ba41e92014-09-03 11:11:16 -04009TEXT runtime·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)
91 CALL runtime·schedinit(SB)
Russ Coxf7f63292008-08-05 14:21:42 -070092
Ken Thompson751ce3a2008-07-11 19:16:39 -070093 // create a new goroutine to start program
Russ Cox9aa1e9a2014-08-12 19:51:20 -040094 MOVQ $runtime·main·f(SB), BP // entry
95 PUSHQ BP
Russ Cox7343e032009-06-17 15:12:16 -070096 PUSHQ $0 // arg size
Russ Cox9ddfb642013-07-16 16:24:09 -040097 ARGSIZE(16)
Russ Cox68b42552010-11-04 14:00:19 -040098 CALL runtime·newproc(SB)
Russ Cox9ddfb642013-07-16 16:24:09 -040099 ARGSIZE(-1)
Russ Coxebd1eef2008-09-22 13:47:59 -0700100 POPQ AX
101 POPQ AX
Russ Cox79e1db22008-12-04 08:30:54 -0800102
Russ Coxebd1eef2008-09-22 13:47:59 -0700103 // start this M
Russ Cox68b42552010-11-04 14:00:19 -0400104 CALL runtime·mstart(SB)
Rob Pike8e82a672008-06-30 11:50:36 -0700105
Russ Cox36aa7d42012-03-08 14:03:56 -0500106 MOVL $0xf1, 0xf1 // crash
Rob Pike8e82a672008-06-30 11:50:36 -0700107 RET
108
Russ Cox1903ad72013-02-21 17:01:13 -0500109DATA runtime·main·f+0(SB)/8,$runtime·main(SB)
Keith Randall5a546962013-08-07 10:23:24 -0700110GLOBL runtime·main·f(SB),RODATA,$8
Russ Cox1903ad72013-02-21 17:01:13 -0500111
Keith Randall5a546962013-08-07 10:23:24 -0700112TEXT runtime·breakpoint(SB),NOSPLIT,$0-0
Ken Thompson751ce3a2008-07-11 19:16:39 -0700113 BYTE $0xcc
Rob Pike8e82a672008-06-30 11:50:36 -0700114 RET
115
Keith Randall5a546962013-08-07 10:23:24 -0700116TEXT runtime·asminit(SB),NOSPLIT,$0-0
Russ Cox1707a992012-02-14 01:23:15 -0500117 // No per-thread init.
118 RET
119
Ken Thompson751ce3a2008-07-11 19:16:39 -0700120/*
121 * go-routine
122 */
Rob Piked3204ef2008-06-30 14:39:47 -0700123
Russ Coxf9ca3b52011-03-07 10:37:42 -0500124// void gosave(Gobuf*)
Russ Cox7343e032009-06-17 15:12:16 -0700125// save state in Gobuf; setjmp
Keith Randall5a546962013-08-07 10:23:24 -0700126TEXT runtime·gosave(SB), NOSPLIT, $0-8
Russ Cox25f6b022014-08-27 11:32:17 -0400127 MOVQ buf+0(FP), AX // gobuf
128 LEAQ buf+0(FP), BX // caller's SP
Russ Cox7343e032009-06-17 15:12:16 -0700129 MOVQ BX, gobuf_sp(AX)
130 MOVQ 0(SP), BX // caller's PC
131 MOVQ BX, gobuf_pc(AX)
Russ Coxd67e7e32013-06-12 15:22:26 -0400132 MOVQ $0, gobuf_ret(AX)
133 MOVQ $0, gobuf_ctxt(AX)
Russ Coxe473f422010-08-04 17:50:22 -0700134 get_tls(CX)
135 MOVQ g(CX), BX
136 MOVQ BX, gobuf_g(AX)
Ken Thompson751ce3a2008-07-11 19:16:39 -0700137 RET
138
Ian Lance Taylor06272482013-06-12 15:05:10 -0700139// void gogo(Gobuf*)
Russ Cox7343e032009-06-17 15:12:16 -0700140// restore state from Gobuf; longjmp
Keith Randall5a546962013-08-07 10:23:24 -0700141TEXT runtime·gogo(SB), NOSPLIT, $0-8
Russ Cox25f6b022014-08-27 11:32:17 -0400142 MOVQ buf+0(FP), BX // gobuf
Russ Coxe473f422010-08-04 17:50:22 -0700143 MOVQ gobuf_g(BX), DX
144 MOVQ 0(DX), CX // make sure g != nil
145 get_tls(CX)
146 MOVQ DX, g(CX)
Russ Cox7343e032009-06-17 15:12:16 -0700147 MOVQ gobuf_sp(BX), SP // restore SP
Russ Coxd67e7e32013-06-12 15:22:26 -0400148 MOVQ gobuf_ret(BX), AX
149 MOVQ gobuf_ctxt(BX), DX
150 MOVQ $0, gobuf_sp(BX) // clear to help garbage collector
151 MOVQ $0, gobuf_ret(BX)
152 MOVQ $0, gobuf_ctxt(BX)
Russ Cox7343e032009-06-17 15:12:16 -0700153 MOVQ gobuf_pc(BX), BX
154 JMP BX
155
Russ Cox012ceed2014-09-03 11:35:22 -0400156// func mcall(fn func(*g))
Russ Coxf9ca3b52011-03-07 10:37:42 -0500157// Switch to m->g0's stack, call fn(g).
Russ Cox370276a2011-04-27 23:21:12 -0400158// Fn must never return. It should gogo(&g->sched)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500159// to keep running g.
Keith Randall5a546962013-08-07 10:23:24 -0700160TEXT runtime·mcall(SB), NOSPLIT, $0-8
Russ Coxf9ca3b52011-03-07 10:37:42 -0500161 MOVQ fn+0(FP), DI
162
163 get_tls(CX)
Russ Cox528534c2013-06-05 07:16:53 -0400164 MOVQ g(CX), AX // save state in g->sched
Russ Coxf9ca3b52011-03-07 10:37:42 -0500165 MOVQ 0(SP), BX // caller's PC
166 MOVQ BX, (g_sched+gobuf_pc)(AX)
Russ Cox25f6b022014-08-27 11:32:17 -0400167 LEAQ fn+0(FP), BX // caller's SP
Russ Coxf9ca3b52011-03-07 10:37:42 -0500168 MOVQ BX, (g_sched+gobuf_sp)(AX)
169 MOVQ AX, (g_sched+gobuf_g)(AX)
170
171 // switch to m->g0 & its stack, call fn
Russ Cox89f185f2014-06-26 11:54:39 -0400172 MOVQ g(CX), BX
173 MOVQ g_m(BX), BX
Russ Coxf9ca3b52011-03-07 10:37:42 -0500174 MOVQ m_g0(BX), SI
175 CMPQ SI, AX // if g == m->g0 call badmcall
Russ Cox9ddfb642013-07-16 16:24:09 -0400176 JNE 3(PC)
Keith Randall32b770b2013-08-29 15:53:34 -0700177 MOVQ $runtime·badmcall(SB), AX
178 JMP AX
Russ Coxf9ca3b52011-03-07 10:37:42 -0500179 MOVQ SI, g(CX) // g = m->g0
Russ Cox528534c2013-06-05 07:16:53 -0400180 MOVQ (g_sched+gobuf_sp)(SI), SP // sp = m->g0->sched.sp
Russ Coxf9ca3b52011-03-07 10:37:42 -0500181 PUSHQ AX
Russ Cox9ddfb642013-07-16 16:24:09 -0400182 ARGSIZE(8)
Russ Cox012ceed2014-09-03 11:35:22 -0400183 MOVQ DI, DX
184 MOVQ 0(DI), DI
Russ Coxf9ca3b52011-03-07 10:37:42 -0500185 CALL DI
186 POPQ AX
Keith Randall32b770b2013-08-29 15:53:34 -0700187 MOVQ $runtime·badmcall2(SB), AX
188 JMP AX
Russ Coxf9ca3b52011-03-07 10:37:42 -0500189 RET
190
Keith Randall4aa50432014-07-30 09:01:52 -0700191// switchtoM is a dummy routine that onM leaves at the bottom
192// of the G stack. We need to distinguish the routine that
193// lives at the bottom of the G stack from the one that lives
194// at the top of the M stack because the one at the top of
195// the M stack terminates the stack walk (see topofstack()).
196TEXT runtime·switchtoM(SB), NOSPLIT, $0-8
197 RET
198
Russ Cox012ceed2014-09-03 11:35:22 -0400199// func onM(fn func())
Keith Randall4aa50432014-07-30 09:01:52 -0700200// calls fn() on the M stack.
201// switches to the M stack if not already on it, and
202// switches back when fn() returns.
203TEXT runtime·onM(SB), NOSPLIT, $0-8
204 MOVQ fn+0(FP), DI // DI = fn
205 get_tls(CX)
206 MOVQ g(CX), AX // AX = g
207 MOVQ g_m(AX), BX // BX = m
208 MOVQ m_g0(BX), DX // DX = g0
209 CMPQ AX, DX
210 JEQ onm
211
212 // save our state in g->sched. Pretend to
213 // be switchtoM if the G stack is scanned.
Russ Cox9aa1e9a2014-08-12 19:51:20 -0400214 MOVQ $runtime·switchtoM(SB), BP
215 MOVQ BP, (g_sched+gobuf_pc)(AX)
Keith Randall4aa50432014-07-30 09:01:52 -0700216 MOVQ SP, (g_sched+gobuf_sp)(AX)
217 MOVQ AX, (g_sched+gobuf_g)(AX)
218
219 // switch to g0
220 MOVQ DX, g(CX)
221 MOVQ (g_sched+gobuf_sp)(DX), SP
222
223 // call target function
224 ARGSIZE(0)
Russ Cox012ceed2014-09-03 11:35:22 -0400225 MOVQ DI, DX
226 MOVQ 0(DI), DI
Keith Randall4aa50432014-07-30 09:01:52 -0700227 CALL DI
228
229 // switch back to g
230 get_tls(CX)
231 MOVQ g(CX), AX
232 MOVQ g_m(AX), BX
233 MOVQ m_curg(BX), AX
234 MOVQ AX, g(CX)
235 MOVQ (g_sched+gobuf_sp)(AX), SP
236 MOVQ $0, (g_sched+gobuf_sp)(AX)
237 RET
238
239onm:
240 // already on m stack, just call directly
Russ Cox012ceed2014-09-03 11:35:22 -0400241 MOVQ DI, DX
242 MOVQ 0(DI), DI
Keith Randall4aa50432014-07-30 09:01:52 -0700243 CALL DI
244 RET
245
Rob Pike2da97832008-07-12 11:30:53 -0700246/*
247 * support for morestack
248 */
249
Russ Cox7343e032009-06-17 15:12:16 -0700250// Called during function prolog when more stack is needed.
Russ Coxe473f422010-08-04 17:50:22 -0700251// Caller has already done get_tls(CX); MOVQ m(CX), BX.
Russ Cox58f12ff2013-07-18 16:53:45 -0400252//
253// The traceback routines see morestack on a g0 as being
254// the top of a stack (for example, morestack calling newstack
255// calling the scheduler calling newm calling gc), so we must
256// record an argument size. For that purpose, it has no arguments.
Keith Randall5a546962013-08-07 10:23:24 -0700257TEXT runtime·morestack(SB),NOSPLIT,$0-0
Russ Coxe473f422010-08-04 17:50:22 -0700258 // Cannot grow scheduler stack (m->g0).
259 MOVQ m_g0(BX), SI
260 CMPQ g(CX), SI
261 JNE 2(PC)
262 INT $3
263
Russ Cox7343e032009-06-17 15:12:16 -0700264 // Called from f.
265 // Set m->morebuf to f's caller.
266 MOVQ 8(SP), AX // f's caller's PC
Russ Coxe473f422010-08-04 17:50:22 -0700267 MOVQ AX, (m_morebuf+gobuf_pc)(BX)
Russ Cox7343e032009-06-17 15:12:16 -0700268 LEAQ 16(SP), AX // f's caller's SP
Russ Coxe473f422010-08-04 17:50:22 -0700269 MOVQ AX, (m_morebuf+gobuf_sp)(BX)
Russ Cox141a4a12011-01-14 14:05:20 -0500270 MOVQ AX, m_moreargp(BX)
Russ Coxe473f422010-08-04 17:50:22 -0700271 get_tls(CX)
272 MOVQ g(CX), SI
273 MOVQ SI, (m_morebuf+gobuf_g)(BX)
Russ Cox7343e032009-06-17 15:12:16 -0700274
Russ Cox6fa3c892013-06-27 11:32:01 -0400275 // Set g->sched to context in f.
276 MOVQ 0(SP), AX // f's PC
277 MOVQ AX, (g_sched+gobuf_pc)(SI)
278 MOVQ SI, (g_sched+gobuf_g)(SI)
279 LEAQ 8(SP), AX // f's SP
280 MOVQ AX, (g_sched+gobuf_sp)(SI)
281 MOVQ DX, (g_sched+gobuf_ctxt)(SI)
Russ Cox7343e032009-06-17 15:12:16 -0700282
Russ Coxf9ca3b52011-03-07 10:37:42 -0500283 // Call newstack on m->g0's stack.
Russ Coxe473f422010-08-04 17:50:22 -0700284 MOVQ m_g0(BX), BP
285 MOVQ BP, g(CX)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500286 MOVQ (g_sched+gobuf_sp)(BP), SP
Russ Cox68b42552010-11-04 14:00:19 -0400287 CALL runtime·newstack(SB)
Russ Cox7343e032009-06-17 15:12:16 -0700288 MOVQ $0, 0x1003 // crash if newstack returns
289 RET
290
Keith Randall9cd57062013-08-02 13:03:14 -0700291// Called from panic. Mimics morestack,
Russ Coxbba278a2009-07-08 18:16:09 -0700292// reuses stack growth code to create a frame
293// with the desired args running the desired function.
294//
295// func call(fn *byte, arg *byte, argsize uint32).
Keith Randall5a546962013-08-07 10:23:24 -0700296TEXT runtime·newstackcall(SB), NOSPLIT, $0-20
Russ Coxe473f422010-08-04 17:50:22 -0700297 get_tls(CX)
Russ Cox89f185f2014-06-26 11:54:39 -0400298 MOVQ g(CX), BX
299 MOVQ g_m(BX), BX
Russ Coxe473f422010-08-04 17:50:22 -0700300
Russ Coxbba278a2009-07-08 18:16:09 -0700301 // Save our caller's state as the PC and SP to
302 // restore when returning from f.
303 MOVQ 0(SP), AX // our caller's PC
Russ Coxe473f422010-08-04 17:50:22 -0700304 MOVQ AX, (m_morebuf+gobuf_pc)(BX)
Russ Cox25f6b022014-08-27 11:32:17 -0400305 LEAQ fv+0(FP), AX // our caller's SP
Russ Coxe473f422010-08-04 17:50:22 -0700306 MOVQ AX, (m_morebuf+gobuf_sp)(BX)
307 MOVQ g(CX), AX
308 MOVQ AX, (m_morebuf+gobuf_g)(BX)
Russ Coxf0d73fb2013-06-27 16:51:06 -0400309
310 // Save our own state as the PC and SP to restore
311 // if this goroutine needs to be restarted.
Russ Cox9aa1e9a2014-08-12 19:51:20 -0400312 MOVQ $runtime·newstackcall(SB), BP
313 MOVQ BP, (g_sched+gobuf_pc)(AX)
Russ Coxf0d73fb2013-06-27 16:51:06 -0400314 MOVQ SP, (g_sched+gobuf_sp)(AX)
Russ Coxbba278a2009-07-08 18:16:09 -0700315
316 // Set up morestack arguments to call f on a new stack.
Russ Cox83727cc2010-03-29 21:48:22 -0700317 // We set f's frame size to 1, as a hint to newstack
Keith Randall9cd57062013-08-02 13:03:14 -0700318 // that this is a call from runtime·newstackcall.
Russ Cox83727cc2010-03-29 21:48:22 -0700319 // If it turns out that f needs a larger frame than
320 // the default stack, f's usual stack growth prolog will
321 // allocate a new segment (and recopy the arguments).
Russ Cox25f6b022014-08-27 11:32:17 -0400322 MOVQ fv+0(FP), AX // fn
323 MOVQ addr+8(FP), DX // arg frame
324 MOVL size+16(FP), CX // arg size
Russ Coxbba278a2009-07-08 18:16:09 -0700325
Russ Cox6fa3c892013-06-27 11:32:01 -0400326 MOVQ AX, m_cret(BX) // f's PC
Russ Cox141a4a12011-01-14 14:05:20 -0500327 MOVQ DX, m_moreargp(BX) // argument frame pointer
328 MOVL CX, m_moreargsize(BX) // f's argument size
329 MOVL $1, m_moreframesize(BX) // f's frame size
Russ Coxbba278a2009-07-08 18:16:09 -0700330
Russ Coxf9ca3b52011-03-07 10:37:42 -0500331 // Call newstack on m->g0's stack.
Russ Coxe473f422010-08-04 17:50:22 -0700332 MOVQ m_g0(BX), BP
333 get_tls(CX)
334 MOVQ BP, g(CX)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500335 MOVQ (g_sched+gobuf_sp)(BP), SP
Russ Cox68b42552010-11-04 14:00:19 -0400336 CALL runtime·newstack(SB)
Russ Coxbba278a2009-07-08 18:16:09 -0700337 MOVQ $0, 0x1103 // crash if newstack returns
338 RET
339
Keith Randall9cd57062013-08-02 13:03:14 -0700340// reflect·call: call a function with the given argument list
341// func call(f *FuncVal, arg *byte, argsize uint32).
342// we don't have variable-sized frames, so we use a small number
343// of constant-sized-frame functions to encode a few bits of size in the pc.
344// Caution: ugly multiline assembly macros in your future!
345
346#define DISPATCH(NAME,MAXSIZE) \
347 CMPQ CX, $MAXSIZE; \
348 JA 3(PC); \
Rob Pikeaff78832014-07-30 10:11:44 -0700349 MOVQ $NAME(SB), AX; \
Keith Randall9cd57062013-08-02 13:03:14 -0700350 JMP AX
Rob Pikeaff78832014-07-30 10:11:44 -0700351// Note: can't just "JMP NAME(SB)" - bad inlining results.
Keith Randall9cd57062013-08-02 13:03:14 -0700352
Russ Cox72c5d5e2014-04-08 11:11:35 -0400353TEXT reflect·call(SB), NOSPLIT, $0-24
Keith Randall9cd57062013-08-02 13:03:14 -0700354 MOVLQZX argsize+16(FP), CX
Rob Pikeaff78832014-07-30 10:11:44 -0700355 DISPATCH(runtime·call16, 16)
356 DISPATCH(runtime·call32, 32)
357 DISPATCH(runtime·call64, 64)
358 DISPATCH(runtime·call128, 128)
359 DISPATCH(runtime·call256, 256)
360 DISPATCH(runtime·call512, 512)
361 DISPATCH(runtime·call1024, 1024)
362 DISPATCH(runtime·call2048, 2048)
363 DISPATCH(runtime·call4096, 4096)
364 DISPATCH(runtime·call8192, 8192)
365 DISPATCH(runtime·call16384, 16384)
366 DISPATCH(runtime·call32768, 32768)
367 DISPATCH(runtime·call65536, 65536)
368 DISPATCH(runtime·call131072, 131072)
369 DISPATCH(runtime·call262144, 262144)
370 DISPATCH(runtime·call524288, 524288)
371 DISPATCH(runtime·call1048576, 1048576)
372 DISPATCH(runtime·call2097152, 2097152)
373 DISPATCH(runtime·call4194304, 4194304)
374 DISPATCH(runtime·call8388608, 8388608)
375 DISPATCH(runtime·call16777216, 16777216)
376 DISPATCH(runtime·call33554432, 33554432)
377 DISPATCH(runtime·call67108864, 67108864)
378 DISPATCH(runtime·call134217728, 134217728)
379 DISPATCH(runtime·call268435456, 268435456)
380 DISPATCH(runtime·call536870912, 536870912)
381 DISPATCH(runtime·call1073741824, 1073741824)
Keith Randall9cd57062013-08-02 13:03:14 -0700382 MOVQ $runtime·badreflectcall(SB), AX
383 JMP AX
384
Keith Randallcee8bca2014-05-21 14:28:34 -0700385// Argument map for the callXX frames. Each has one
386// stack map (for the single call) with 3 arguments.
387DATA gcargs_reflectcall<>+0x00(SB)/4, $1 // 1 stackmap
388DATA gcargs_reflectcall<>+0x04(SB)/4, $6 // 3 args
389DATA gcargs_reflectcall<>+0x08(SB)/4, $(const_BitsPointer+(const_BitsPointer<<2)+(const_BitsScalar<<4))
390GLOBL gcargs_reflectcall<>(SB),RODATA,$12
391
392// callXX frames have no locals
393DATA gclocals_reflectcall<>+0x00(SB)/4, $1 // 1 stackmap
394DATA gclocals_reflectcall<>+0x04(SB)/4, $0 // 0 locals
395GLOBL gclocals_reflectcall<>(SB),RODATA,$8
396
Keith Randall12e46e42013-08-06 14:33:55 -0700397#define CALLFN(NAME,MAXSIZE) \
Rob Pikeaff78832014-07-30 10:11:44 -0700398TEXT NAME(SB), WRAPPER, $MAXSIZE-24; \
Keith Randallcee8bca2014-05-21 14:28:34 -0700399 FUNCDATA $FUNCDATA_ArgsPointerMaps,gcargs_reflectcall<>(SB); \
400 FUNCDATA $FUNCDATA_LocalsPointerMaps,gclocals_reflectcall<>(SB);\
Keith Randall9cd57062013-08-02 13:03:14 -0700401 /* copy arguments to stack */ \
402 MOVQ argptr+8(FP), SI; \
403 MOVLQZX argsize+16(FP), CX; \
404 MOVQ SP, DI; \
405 REP;MOVSB; \
406 /* call function */ \
407 MOVQ f+0(FP), DX; \
Keith Randallcee8bca2014-05-21 14:28:34 -0700408 PCDATA $PCDATA_StackMapIndex, $0; \
Keith Randall9cd57062013-08-02 13:03:14 -0700409 CALL (DX); \
410 /* copy return values back */ \
411 MOVQ argptr+8(FP), DI; \
412 MOVLQZX argsize+16(FP), CX; \
Russ Cox72c5d5e2014-04-08 11:11:35 -0400413 MOVLQZX retoffset+20(FP), BX; \
Keith Randall9cd57062013-08-02 13:03:14 -0700414 MOVQ SP, SI; \
Russ Cox72c5d5e2014-04-08 11:11:35 -0400415 ADDQ BX, DI; \
416 ADDQ BX, SI; \
417 SUBQ BX, CX; \
Keith Randall9cd57062013-08-02 13:03:14 -0700418 REP;MOVSB; \
419 RET
420
Rob Pikeaff78832014-07-30 10:11:44 -0700421CALLFN(runtime·call16, 16)
422CALLFN(runtime·call32, 32)
423CALLFN(runtime·call64, 64)
424CALLFN(runtime·call128, 128)
425CALLFN(runtime·call256, 256)
426CALLFN(runtime·call512, 512)
427CALLFN(runtime·call1024, 1024)
428CALLFN(runtime·call2048, 2048)
429CALLFN(runtime·call4096, 4096)
430CALLFN(runtime·call8192, 8192)
431CALLFN(runtime·call16384, 16384)
432CALLFN(runtime·call32768, 32768)
433CALLFN(runtime·call65536, 65536)
434CALLFN(runtime·call131072, 131072)
435CALLFN(runtime·call262144, 262144)
436CALLFN(runtime·call524288, 524288)
437CALLFN(runtime·call1048576, 1048576)
438CALLFN(runtime·call2097152, 2097152)
439CALLFN(runtime·call4194304, 4194304)
440CALLFN(runtime·call8388608, 8388608)
441CALLFN(runtime·call16777216, 16777216)
442CALLFN(runtime·call33554432, 33554432)
443CALLFN(runtime·call67108864, 67108864)
444CALLFN(runtime·call134217728, 134217728)
445CALLFN(runtime·call268435456, 268435456)
446CALLFN(runtime·call536870912, 536870912)
447CALLFN(runtime·call1073741824, 1073741824)
Keith Randall9cd57062013-08-02 13:03:14 -0700448
Russ Cox7343e032009-06-17 15:12:16 -0700449// Return point when leaving stack.
Russ Cox58f12ff2013-07-18 16:53:45 -0400450//
451// Lessstack can appear in stack traces for the same reason
452// as morestack; in that context, it has 0 arguments.
Keith Randall5a546962013-08-07 10:23:24 -0700453TEXT runtime·lessstack(SB), NOSPLIT, $0-0
Russ Cox7343e032009-06-17 15:12:16 -0700454 // Save return value in m->cret
Russ Coxe473f422010-08-04 17:50:22 -0700455 get_tls(CX)
Russ Cox89f185f2014-06-26 11:54:39 -0400456 MOVQ g(CX), BX
457 MOVQ g_m(BX), BX
Russ Coxe473f422010-08-04 17:50:22 -0700458 MOVQ AX, m_cret(BX)
Russ Cox7343e032009-06-17 15:12:16 -0700459
Russ Coxf9ca3b52011-03-07 10:37:42 -0500460 // Call oldstack on m->g0's stack.
461 MOVQ m_g0(BX), BP
462 MOVQ BP, g(CX)
463 MOVQ (g_sched+gobuf_sp)(BP), SP
Russ Cox68b42552010-11-04 14:00:19 -0400464 CALL runtime·oldstack(SB)
Russ Cox7343e032009-06-17 15:12:16 -0700465 MOVQ $0, 0x1004 // crash if oldstack returns
466 RET
467
Ken Thompson1ed7f182009-05-01 18:07:33 -0700468// morestack trampolines
Keith Randall5a546962013-08-07 10:23:24 -0700469TEXT runtime·morestack00(SB),NOSPLIT,$0
Russ Coxe473f422010-08-04 17:50:22 -0700470 get_tls(CX)
Russ Cox89f185f2014-06-26 11:54:39 -0400471 MOVQ g(CX), BX
472 MOVQ g_m(BX), BX
Ken Thompson1ed7f182009-05-01 18:07:33 -0700473 MOVQ $0, AX
Russ Cox141a4a12011-01-14 14:05:20 -0500474 MOVQ AX, m_moreframesize(BX)
Russ Cox68b42552010-11-04 14:00:19 -0400475 MOVQ $runtime·morestack(SB), AX
Ken Thompson1ed7f182009-05-01 18:07:33 -0700476 JMP AX
477
Keith Randall5a546962013-08-07 10:23:24 -0700478TEXT runtime·morestack01(SB),NOSPLIT,$0
Russ Coxe473f422010-08-04 17:50:22 -0700479 get_tls(CX)
Russ Cox89f185f2014-06-26 11:54:39 -0400480 MOVQ g(CX), BX
481 MOVQ g_m(BX), BX
Ken Thompson1ed7f182009-05-01 18:07:33 -0700482 SHLQ $32, AX
Russ Cox141a4a12011-01-14 14:05:20 -0500483 MOVQ AX, m_moreframesize(BX)
Russ Cox68b42552010-11-04 14:00:19 -0400484 MOVQ $runtime·morestack(SB), AX
Ken Thompson1ed7f182009-05-01 18:07:33 -0700485 JMP AX
486
Keith Randall5a546962013-08-07 10:23:24 -0700487TEXT runtime·morestack10(SB),NOSPLIT,$0
Russ Coxe473f422010-08-04 17:50:22 -0700488 get_tls(CX)
Russ Cox89f185f2014-06-26 11:54:39 -0400489 MOVQ g(CX), BX
490 MOVQ g_m(BX), BX
Ken Thompson1ed7f182009-05-01 18:07:33 -0700491 MOVLQZX AX, AX
Russ Cox141a4a12011-01-14 14:05:20 -0500492 MOVQ AX, m_moreframesize(BX)
Russ Cox68b42552010-11-04 14:00:19 -0400493 MOVQ $runtime·morestack(SB), AX
Ken Thompson1ed7f182009-05-01 18:07:33 -0700494 JMP AX
495
Keith Randall5a546962013-08-07 10:23:24 -0700496TEXT runtime·morestack11(SB),NOSPLIT,$0
Russ Coxe473f422010-08-04 17:50:22 -0700497 get_tls(CX)
Russ Cox89f185f2014-06-26 11:54:39 -0400498 MOVQ g(CX), BX
499 MOVQ g_m(BX), BX
Russ Cox141a4a12011-01-14 14:05:20 -0500500 MOVQ AX, m_moreframesize(BX)
Russ Cox68b42552010-11-04 14:00:19 -0400501 MOVQ $runtime·morestack(SB), AX
Ken Thompson1ed7f182009-05-01 18:07:33 -0700502 JMP AX
503
Ken Thompson5963f592009-05-03 19:09:14 -0700504// subcases of morestack01
505// with const of 8,16,...48
Keith Randall5a546962013-08-07 10:23:24 -0700506TEXT runtime·morestack8(SB),NOSPLIT,$0
Dmitriy Vyukove84d9e12013-07-29 22:22:34 +0400507 MOVQ $1, 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·morestack16(SB),NOSPLIT,$0
Dmitriy Vyukove84d9e12013-07-29 22:22:34 +0400512 MOVQ $2, 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·morestack24(SB),NOSPLIT,$0
Dmitriy Vyukove84d9e12013-07-29 22:22:34 +0400517 MOVQ $3, 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·morestack32(SB),NOSPLIT,$0
Dmitriy Vyukove84d9e12013-07-29 22:22:34 +0400522 MOVQ $4, 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·morestack40(SB),NOSPLIT,$0
Dmitriy Vyukove84d9e12013-07-29 22:22:34 +0400527 MOVQ $5, 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 runtime·morestack48(SB),NOSPLIT,$0
Dmitriy Vyukove84d9e12013-07-29 22:22:34 +0400532 MOVQ $6, R8
Russ Cox68b42552010-11-04 14:00:19 -0400533 MOVQ $morestack<>(SB), AX
Ken Thompson5963f592009-05-03 19:09:14 -0700534 JMP AX
535
Keith Randall5a546962013-08-07 10:23:24 -0700536TEXT morestack<>(SB),NOSPLIT,$0
Russ Coxe473f422010-08-04 17:50:22 -0700537 get_tls(CX)
Russ Cox89f185f2014-06-26 11:54:39 -0400538 MOVQ g(CX), BX
539 MOVQ g_m(BX), BX
Dmitriy Vyukove84d9e12013-07-29 22:22:34 +0400540 SHLQ $35, R8
541 MOVQ R8, m_moreframesize(BX)
Russ Cox68b42552010-11-04 14:00:19 -0400542 MOVQ $runtime·morestack(SB), AX
Rob Pike2da97832008-07-12 11:30:53 -0700543 JMP AX
544
Russ Coxc2dd33a2014-03-04 13:53:08 -0500545TEXT runtime·morestack00_noctxt(SB),NOSPLIT,$0
546 MOVL $0, DX
547 JMP runtime·morestack00(SB)
548
549TEXT runtime·morestack01_noctxt(SB),NOSPLIT,$0
550 MOVL $0, DX
551 JMP runtime·morestack01(SB)
552
553TEXT runtime·morestack10_noctxt(SB),NOSPLIT,$0
554 MOVL $0, DX
555 JMP runtime·morestack10(SB)
556
557TEXT runtime·morestack11_noctxt(SB),NOSPLIT,$0
558 MOVL $0, DX
559 JMP runtime·morestack11(SB)
560
561TEXT runtime·morestack8_noctxt(SB),NOSPLIT,$0
562 MOVL $0, DX
563 JMP runtime·morestack8(SB)
564
565TEXT runtime·morestack16_noctxt(SB),NOSPLIT,$0
566 MOVL $0, DX
567 JMP runtime·morestack16(SB)
568
569TEXT runtime·morestack24_noctxt(SB),NOSPLIT,$0
570 MOVL $0, DX
571 JMP runtime·morestack24(SB)
572
573TEXT runtime·morestack32_noctxt(SB),NOSPLIT,$0
574 MOVL $0, DX
575 JMP runtime·morestack32(SB)
576
577TEXT runtime·morestack40_noctxt(SB),NOSPLIT,$0
578 MOVL $0, DX
579 JMP runtime·morestack40(SB)
580
581TEXT runtime·morestack48_noctxt(SB),NOSPLIT,$0
582 MOVL $0, DX
583 JMP runtime·morestack48(SB)
584
Russ Coxd28acc42008-08-04 16:43:49 -0700585// bool cas(int32 *val, int32 old, int32 new)
586// Atomically:
587// if(*val == old){
588// *val = new;
589// return 1;
Ken Thompson1e1cc4e2009-01-27 12:03:53 -0800590// } else
Russ Coxd28acc42008-08-04 16:43:49 -0700591// return 0;
Russ Cox25f6b022014-08-27 11:32:17 -0400592TEXT runtime·cas(SB), NOSPLIT, $0-17
593 MOVQ ptr+0(FP), BX
594 MOVL old+8(FP), AX
595 MOVL new+12(FP), CX
Russ Coxd28acc42008-08-04 16:43:49 -0700596 LOCK
597 CMPXCHGL CX, 0(BX)
Russ Cox25f6b022014-08-27 11:32:17 -0400598 JZ 4(PC)
Russ Coxd28acc42008-08-04 16:43:49 -0700599 MOVL $0, AX
Russ Cox25f6b022014-08-27 11:32:17 -0400600 MOVB AX, ret+16(FP)
Russ Coxd28acc42008-08-04 16:43:49 -0700601 RET
602 MOVL $1, AX
Russ Cox25f6b022014-08-27 11:32:17 -0400603 MOVB AX, ret+16(FP)
Russ Coxd28acc42008-08-04 16:43:49 -0700604 RET
Ken Thompson1e1cc4e2009-01-27 12:03:53 -0800605
Russ Cox9ddfb642013-07-16 16:24:09 -0400606// bool runtime·cas64(uint64 *val, uint64 old, uint64 new)
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400607// Atomically:
608// if(*val == *old){
609// *val = new;
610// return 1;
611// } else {
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400612// return 0;
613// }
Russ Cox25f6b022014-08-27 11:32:17 -0400614TEXT runtime·cas64(SB), NOSPLIT, $0-25
615 MOVQ ptr+0(FP), BX
616 MOVQ old+8(FP), AX
617 MOVQ new+16(FP), CX
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400618 LOCK
619 CMPXCHGQ CX, 0(BX)
620 JNZ cas64_fail
621 MOVL $1, AX
Russ Cox25f6b022014-08-27 11:32:17 -0400622 MOVB AX, ret+24(FP)
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400623 RET
624cas64_fail:
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400625 MOVL $0, AX
Russ Cox25f6b022014-08-27 11:32:17 -0400626 MOVB AX, ret+24(FP)
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400627 RET
Russ Coxd21638b2014-08-27 21:59:49 -0400628
629TEXT runtime·casuintptr(SB), NOSPLIT, $0-25
630 JMP runtime·cas64(SB)
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400631
Russ Cox3a7f6642014-08-29 16:20:48 -0400632TEXT runtime·atomicloaduintptr(SB), NOSPLIT, $0-16
633 JMP runtime·atomicload64(SB)
634
Keith Randall47d6af22014-08-30 11:03:28 -0700635TEXT runtime·atomicloaduint(SB), NOSPLIT, $0-16
636 JMP runtime·atomicload64(SB)
637
Russ Cox67793502011-02-16 13:21:13 -0500638// bool casp(void **val, void *old, void *new)
639// Atomically:
640// if(*val == old){
641// *val = new;
642// return 1;
643// } else
644// return 0;
Russ Cox25f6b022014-08-27 11:32:17 -0400645TEXT runtime·casp(SB), NOSPLIT, $0-25
646 MOVQ ptr+0(FP), BX
647 MOVQ old+8(FP), AX
648 MOVQ new+16(FP), CX
Russ Cox67793502011-02-16 13:21:13 -0500649 LOCK
650 CMPXCHGQ CX, 0(BX)
Russ Cox25f6b022014-08-27 11:32:17 -0400651 JZ 4(PC)
Russ Cox67793502011-02-16 13:21:13 -0500652 MOVL $0, AX
Russ Cox25f6b022014-08-27 11:32:17 -0400653 MOVB AX, ret+24(FP)
Russ Cox67793502011-02-16 13:21:13 -0500654 RET
655 MOVL $1, AX
Russ Cox25f6b022014-08-27 11:32:17 -0400656 MOVB AX, ret+24(FP)
Russ Cox67793502011-02-16 13:21:13 -0500657 RET
658
Dmitriy Vyukov491aa152011-07-15 11:27:16 -0400659// uint32 xadd(uint32 volatile *val, int32 delta)
660// Atomically:
661// *val += delta;
662// return *val;
Russ Cox25f6b022014-08-27 11:32:17 -0400663TEXT runtime·xadd(SB), NOSPLIT, $0-20
664 MOVQ ptr+0(FP), BX
665 MOVL delta+8(FP), AX
Dmitriy Vyukov491aa152011-07-15 11:27:16 -0400666 MOVL AX, CX
667 LOCK
668 XADDL AX, 0(BX)
669 ADDL CX, AX
Russ Cox25f6b022014-08-27 11:32:17 -0400670 MOVL AX, ret+16(FP)
Dmitriy Vyukov491aa152011-07-15 11:27:16 -0400671 RET
672
Russ Cox25f6b022014-08-27 11:32:17 -0400673TEXT runtime·xadd64(SB), NOSPLIT, $0-24
674 MOVQ ptr+0(FP), BX
675 MOVQ delta+8(FP), AX
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400676 MOVQ AX, CX
677 LOCK
678 XADDQ AX, 0(BX)
679 ADDQ CX, AX
Russ Cox25f6b022014-08-27 11:32:17 -0400680 MOVQ AX, ret+16(FP)
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400681 RET
682
Russ Cox25f6b022014-08-27 11:32:17 -0400683TEXT runtime·xchg(SB), NOSPLIT, $0-20
684 MOVQ ptr+0(FP), BX
685 MOVL new+8(FP), AX
Dmitriy Vyukov4e5086b2011-07-29 12:44:06 -0400686 XCHGL AX, 0(BX)
Russ Cox25f6b022014-08-27 11:32:17 -0400687 MOVL AX, ret+16(FP)
Dmitriy Vyukov4e5086b2011-07-29 12:44:06 -0400688 RET
689
Russ Cox25f6b022014-08-27 11:32:17 -0400690TEXT runtime·xchg64(SB), NOSPLIT, $0-24
691 MOVQ ptr+0(FP), BX
692 MOVQ new+8(FP), AX
Dmitriy Vyukovadd33492013-03-05 09:46:52 +0200693 XCHGQ AX, 0(BX)
Russ Cox25f6b022014-08-27 11:32:17 -0400694 MOVQ AX, ret+16(FP)
Dmitriy Vyukovadd33492013-03-05 09:46:52 +0200695 RET
696
Russ Cox25f6b022014-08-27 11:32:17 -0400697TEXT runtime·xchgp(SB), NOSPLIT, $0-24
698 MOVQ ptr+0(FP), BX
699 MOVQ new+8(FP), AX
Dmitriy Vyukov9cbd2fb2014-01-22 11:27:16 +0400700 XCHGQ AX, 0(BX)
Russ Cox25f6b022014-08-27 11:32:17 -0400701 MOVQ AX, ret+16(FP)
Dmitriy Vyukov9cbd2fb2014-01-22 11:27:16 +0400702 RET
703
Keith Randall5a546962013-08-07 10:23:24 -0700704TEXT runtime·procyield(SB),NOSPLIT,$0-0
Russ Cox25f6b022014-08-27 11:32:17 -0400705 MOVL cycles+0(FP), AX
Dmitriy Vyukov4e5086b2011-07-29 12:44:06 -0400706again:
707 PAUSE
708 SUBL $1, AX
709 JNZ again
710 RET
711
Keith Randall5a546962013-08-07 10:23:24 -0700712TEXT runtime·atomicstorep(SB), NOSPLIT, $0-16
Russ Cox25f6b022014-08-27 11:32:17 -0400713 MOVQ ptr+0(FP), BX
714 MOVQ val+8(FP), AX
Dmitriy Vyukov86a659c2011-07-13 11:22:41 -0700715 XCHGQ AX, 0(BX)
716 RET
717
Keith Randall5a546962013-08-07 10:23:24 -0700718TEXT runtime·atomicstore(SB), NOSPLIT, $0-12
Russ Cox25f6b022014-08-27 11:32:17 -0400719 MOVQ ptr+0(FP), BX
720 MOVL val+8(FP), AX
Dmitriy Vyukov91f0f182011-07-29 13:47:24 -0400721 XCHGL AX, 0(BX)
722 RET
723
Keith Randall5a546962013-08-07 10:23:24 -0700724TEXT runtime·atomicstore64(SB), NOSPLIT, $0-16
Russ Cox25f6b022014-08-27 11:32:17 -0400725 MOVQ ptr+0(FP), BX
726 MOVQ val+8(FP), AX
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400727 XCHGQ AX, 0(BX)
728 RET
729
Dmitriy Vyukovff3fa1b2014-08-19 17:38:00 +0400730// void runtime·atomicor8(byte volatile*, byte);
Russ Cox25f6b022014-08-27 11:32:17 -0400731TEXT runtime·atomicor8(SB), NOSPLIT, $0-9
Dmitriy Vyukovff3fa1b2014-08-19 17:38:00 +0400732 MOVQ ptr+0(FP), AX
733 MOVB val+8(FP), BX
734 LOCK
735 ORB BX, (AX)
736 RET
737
Russ Coxaa3222d82009-06-02 23:02:12 -0700738// void jmpdefer(fn, sp);
739// called from deferreturn.
Ken Thompson1e1cc4e2009-01-27 12:03:53 -0800740// 1. pop the caller
741// 2. sub 5 bytes from the callers return
742// 3. jmp to the argument
Keith Randalla97a91d2013-08-07 14:03:50 -0700743TEXT runtime·jmpdefer(SB), NOSPLIT, $0-16
Russ Cox25f6b022014-08-27 11:32:17 -0400744 MOVQ fv+0(FP), DX // fn
745 MOVQ argp+8(FP), BX // caller sp
Russ Coxaa3222d82009-06-02 23:02:12 -0700746 LEAQ -8(BX), SP // caller sp after CALL
747 SUBQ $5, (SP) // return to CALL again
Russ Cox6066fdc2013-02-22 10:47:54 -0500748 MOVQ 0(DX), BX
Russ Cox1903ad72013-02-21 17:01:13 -0500749 JMP BX // but first run the deferred function
Russ Cox133a1582009-10-03 10:37:12 -0700750
Russ Coxd67e7e32013-06-12 15:22:26 -0400751// Save state of caller into g->sched. Smashes R8, R9.
Keith Randall5a546962013-08-07 10:23:24 -0700752TEXT gosave<>(SB),NOSPLIT,$0
Russ Coxd67e7e32013-06-12 15:22:26 -0400753 get_tls(R8)
754 MOVQ g(R8), R8
755 MOVQ 0(SP), R9
756 MOVQ R9, (g_sched+gobuf_pc)(R8)
757 LEAQ 8(SP), R9
758 MOVQ R9, (g_sched+gobuf_sp)(R8)
759 MOVQ $0, (g_sched+gobuf_ret)(R8)
760 MOVQ $0, (g_sched+gobuf_ctxt)(R8)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500761 RET
762
763// asmcgocall(void(*fn)(void*), void *arg)
Russ Coxadd89dd2009-10-12 10:26:38 -0700764// Call fn(arg) on the scheduler stack,
765// aligned appropriately for the gcc ABI.
Russ Coxf9ca3b52011-03-07 10:37:42 -0500766// See cgocall.c for more details.
Keith Randall5a546962013-08-07 10:23:24 -0700767TEXT runtime·asmcgocall(SB),NOSPLIT,$0-16
Russ Coxf9ca3b52011-03-07 10:37:42 -0500768 MOVQ fn+0(FP), AX
769 MOVQ arg+8(FP), BX
770 MOVQ SP, DX
Russ Coxadd89dd2009-10-12 10:26:38 -0700771
772 // Figure out if we need to switch to m->g0 stack.
Russ Coxf9ca3b52011-03-07 10:37:42 -0500773 // We get called to create new OS threads too, and those
774 // come in on the m->g0 stack already.
775 get_tls(CX)
Russ Cox89f185f2014-06-26 11:54:39 -0400776 MOVQ g(CX), BP
777 MOVQ g_m(BP), BP
Russ Coxf9ca3b52011-03-07 10:37:42 -0500778 MOVQ m_g0(BP), SI
779 MOVQ g(CX), DI
780 CMPQ SI, DI
Aram Hăvărneanua46b4342014-01-17 17:58:10 +1300781 JEQ nosave
782 MOVQ m_gsignal(BP), SI
783 CMPQ SI, DI
784 JEQ nosave
785
786 MOVQ m_g0(BP), SI
Russ Coxd67e7e32013-06-12 15:22:26 -0400787 CALL gosave<>(SB)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500788 MOVQ SI, g(CX)
789 MOVQ (g_sched+gobuf_sp)(SI), SP
Aram Hăvărneanua46b4342014-01-17 17:58:10 +1300790nosave:
Russ Coxadd89dd2009-10-12 10:26:38 -0700791
792 // Now on a scheduling stack (a pthread-created stack).
Alex Brainman7f075ec2012-09-03 12:12:51 +1000793 // Make sure we have enough room for 4 stack-backed fast-call
794 // registers as per windows amd64 calling convention.
795 SUBQ $64, SP
Russ Cox133a1582009-10-03 10:37:12 -0700796 ANDQ $~15, SP // alignment for gcc ABI
Alex Brainman7f075ec2012-09-03 12:12:51 +1000797 MOVQ DI, 48(SP) // save g
798 MOVQ DX, 40(SP) // save SP
Russ Coxf9ca3b52011-03-07 10:37:42 -0500799 MOVQ BX, DI // DI = first argument in AMD64 ABI
Wei Guangjing9f636592011-07-19 10:47:33 -0400800 MOVQ BX, CX // CX = first argument in Win64
Russ Coxf9ca3b52011-03-07 10:37:42 -0500801 CALL AX
Russ Coxadd89dd2009-10-12 10:26:38 -0700802
Russ Coxe473f422010-08-04 17:50:22 -0700803 // Restore registers, g, stack pointer.
Russ Coxf9ca3b52011-03-07 10:37:42 -0500804 get_tls(CX)
Alex Brainman7f075ec2012-09-03 12:12:51 +1000805 MOVQ 48(SP), DI
Russ Coxf9ca3b52011-03-07 10:37:42 -0500806 MOVQ DI, g(CX)
Alex Brainman7f075ec2012-09-03 12:12:51 +1000807 MOVQ 40(SP), SP
Russ Cox133a1582009-10-03 10:37:12 -0700808 RET
809
Russ Coxf9ca3b52011-03-07 10:37:42 -0500810// cgocallback(void (*fn)(void*), void *frame, uintptr framesize)
Russ Cox3d2dfc52013-02-22 16:08:56 -0500811// Turn the fn into a Go func (by taking its address) and call
812// cgocallback_gofunc.
Keith Randall5a546962013-08-07 10:23:24 -0700813TEXT runtime·cgocallback(SB),NOSPLIT,$24-24
Russ Cox3d2dfc52013-02-22 16:08:56 -0500814 LEAQ fn+0(FP), AX
815 MOVQ AX, 0(SP)
816 MOVQ frame+8(FP), AX
817 MOVQ AX, 8(SP)
818 MOVQ framesize+16(FP), AX
819 MOVQ AX, 16(SP)
820 MOVQ $runtime·cgocallback_gofunc(SB), AX
821 CALL AX
822 RET
823
824// cgocallback_gofunc(FuncVal*, void *frame, uintptr framesize)
825// See cgocall.c for more details.
Keith Randall5a546962013-08-07 10:23:24 -0700826TEXT runtime·cgocallback_gofunc(SB),NOSPLIT,$8-24
Russ Cox89f185f2014-06-26 11:54:39 -0400827 // If g is nil, Go did not create the current thread.
828 // Call needm to obtain one m for temporary use.
Russ Cox6c976392013-02-20 17:48:23 -0500829 // In this case, we're running on the thread stack, so there's
830 // lots of space, but the linker doesn't know. Hide the call from
831 // the linker analysis by using an indirect call through AX.
832 get_tls(CX)
833#ifdef GOOS_windows
Russ Coxdba623b2013-07-23 18:40:02 -0400834 MOVL $0, BP
Russ Cox6c976392013-02-20 17:48:23 -0500835 CMPQ CX, $0
Russ Coxcefdb9c2013-07-23 22:59:32 -0400836 JEQ 2(PC)
Russ Cox6c976392013-02-20 17:48:23 -0500837#endif
Russ Cox89f185f2014-06-26 11:54:39 -0400838 MOVQ g(CX), BP
Russ Cox6c976392013-02-20 17:48:23 -0500839 CMPQ BP, $0
Russ Cox89f185f2014-06-26 11:54:39 -0400840 JEQ needm
841 MOVQ g_m(BP), BP
842 MOVQ BP, R8 // holds oldm until end of function
843 JMP havem
Russ Cox6c976392013-02-20 17:48:23 -0500844needm:
Russ Cox89f185f2014-06-26 11:54:39 -0400845 MOVQ $0, 0(SP)
Russ Cox6c976392013-02-20 17:48:23 -0500846 MOVQ $runtime·needm(SB), AX
847 CALL AX
Russ Coxf0112822013-07-24 09:01:57 -0400848 MOVQ 0(SP), R8
Russ Coxe473f422010-08-04 17:50:22 -0700849 get_tls(CX)
Russ Cox89f185f2014-06-26 11:54:39 -0400850 MOVQ g(CX), BP
851 MOVQ g_m(BP), BP
Russ Cox9b732382012-03-08 12:12:40 -0500852
Russ Cox6c976392013-02-20 17:48:23 -0500853havem:
854 // Now there's a valid m, and we're running on its m->g0.
855 // Save current m->g0->sched.sp on stack and then set it to SP.
856 // Save current sp in m->g0->sched.sp in preparation for
857 // switch back to m->curg stack.
Russ Coxdba623b2013-07-23 18:40:02 -0400858 // NOTE: unwindm knows that the saved g->sched.sp is at 0(SP).
Russ Coxf9ca3b52011-03-07 10:37:42 -0500859 MOVQ m_g0(BP), SI
Russ Coxdba623b2013-07-23 18:40:02 -0400860 MOVQ (g_sched+gobuf_sp)(SI), AX
861 MOVQ AX, 0(SP)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500862 MOVQ SP, (g_sched+gobuf_sp)(SI)
Ian Lance Taylor2d0ff3f2010-04-09 13:30:11 -0700863
Russ Coxdba623b2013-07-23 18:40:02 -0400864 // Switch to m->curg stack and call runtime.cgocallbackg.
865 // Because we are taking over the execution of m->curg
866 // but *not* resuming what had been running, we need to
867 // save that information (m->curg->sched) so we can restore it.
Russ Cox528534c2013-06-05 07:16:53 -0400868 // We can restore m->curg->sched.sp easily, because calling
Alex Brainman72e83482011-08-18 12:17:09 -0400869 // runtime.cgocallbackg leaves SP unchanged upon return.
Russ Cox528534c2013-06-05 07:16:53 -0400870 // To save m->curg->sched.pc, we push it onto the stack.
Russ Coxf9ca3b52011-03-07 10:37:42 -0500871 // This has the added benefit that it looks to the traceback
Alex Brainman72e83482011-08-18 12:17:09 -0400872 // routine like cgocallbackg is going to return to that
Russ Coxdba623b2013-07-23 18:40:02 -0400873 // PC (because the frame we allocate below has the same
874 // size as cgocallback_gofunc's frame declared above)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500875 // so that the traceback will seamlessly trace back into
876 // the earlier calls.
Russ Coxdba623b2013-07-23 18:40:02 -0400877 //
Russ Coxf0112822013-07-24 09:01:57 -0400878 // In the new goroutine, 0(SP) holds the saved R8.
Russ Coxf9ca3b52011-03-07 10:37:42 -0500879 MOVQ m_curg(BP), SI
880 MOVQ SI, g(CX)
881 MOVQ (g_sched+gobuf_sp)(SI), DI // prepare stack as DI
Russ Coxf9ca3b52011-03-07 10:37:42 -0500882 MOVQ (g_sched+gobuf_pc)(SI), BP
Russ Coxdba623b2013-07-23 18:40:02 -0400883 MOVQ BP, -8(DI)
Russ Coxf0112822013-07-24 09:01:57 -0400884 LEAQ -(8+8)(DI), SP
885 MOVQ R8, 0(SP)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500886 CALL runtime·cgocallbackg(SB)
Russ Coxf0112822013-07-24 09:01:57 -0400887 MOVQ 0(SP), R8
Russ Coxf9ca3b52011-03-07 10:37:42 -0500888
Russ Cox528534c2013-06-05 07:16:53 -0400889 // Restore g->sched (== m->curg->sched) from saved values.
Russ Coxe473f422010-08-04 17:50:22 -0700890 get_tls(CX)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500891 MOVQ g(CX), SI
Russ Coxf0112822013-07-24 09:01:57 -0400892 MOVQ 8(SP), BP
Russ Coxf9ca3b52011-03-07 10:37:42 -0500893 MOVQ BP, (g_sched+gobuf_pc)(SI)
Russ Coxf0112822013-07-24 09:01:57 -0400894 LEAQ (8+8)(SP), DI
Russ Coxf9ca3b52011-03-07 10:37:42 -0500895 MOVQ DI, (g_sched+gobuf_sp)(SI)
896
897 // Switch back to m->g0's stack and restore m->g0->sched.sp.
898 // (Unlike m->curg, the g0 goroutine never uses sched.pc,
899 // so we do not have to restore it.)
Russ Cox89f185f2014-06-26 11:54:39 -0400900 MOVQ g(CX), BP
901 MOVQ g_m(BP), BP
Russ Coxf9ca3b52011-03-07 10:37:42 -0500902 MOVQ m_g0(BP), SI
903 MOVQ SI, g(CX)
904 MOVQ (g_sched+gobuf_sp)(SI), SP
Russ Coxdba623b2013-07-23 18:40:02 -0400905 MOVQ 0(SP), AX
906 MOVQ AX, (g_sched+gobuf_sp)(SI)
Russ Cox6c976392013-02-20 17:48:23 -0500907
908 // If the m on entry was nil, we called needm above to borrow an m
909 // for the duration of the call. Since the call is over, return it with dropm.
Russ Coxf0112822013-07-24 09:01:57 -0400910 CMPQ R8, $0
Russ Cox6c976392013-02-20 17:48:23 -0500911 JNE 3(PC)
912 MOVQ $runtime·dropm(SB), AX
913 CALL AX
Russ Coxf9ca3b52011-03-07 10:37:42 -0500914
915 // Done!
Ian Lance Taylor2d0ff3f2010-04-09 13:30:11 -0700916 RET
917
Russ Cox89f185f2014-06-26 11:54:39 -0400918// void setg(G*); set g. for use by needm.
Russ Cox25f6b022014-08-27 11:32:17 -0400919TEXT runtime·setg(SB), NOSPLIT, $0-8
Russ Cox89f185f2014-06-26 11:54:39 -0400920 MOVQ gg+0(FP), BX
Russ Cox6c976392013-02-20 17:48:23 -0500921#ifdef GOOS_windows
Russ Cox89f185f2014-06-26 11:54:39 -0400922 CMPQ BX, $0
Russ Cox6c976392013-02-20 17:48:23 -0500923 JNE settls
924 MOVQ $0, 0x28(GS)
925 RET
926settls:
Russ Cox89f185f2014-06-26 11:54:39 -0400927 MOVQ g_m(BX), AX
Russ Cox6c976392013-02-20 17:48:23 -0500928 LEAQ m_tls(AX), AX
929 MOVQ AX, 0x28(GS)
930#endif
931 get_tls(CX)
Russ Cox6c976392013-02-20 17:48:23 -0500932 MOVQ BX, g(CX)
933 RET
934
Russ Cox89f185f2014-06-26 11:54:39 -0400935// void setg_gcc(G*); set g called from gcc.
936TEXT setg_gcc<>(SB),NOSPLIT,$0
Russ Cox6a70f9d2013-03-25 18:14:02 -0400937 get_tls(AX)
Russ Cox89f185f2014-06-26 11:54:39 -0400938 MOVQ DI, g(AX)
Russ Cox6a70f9d2013-03-25 18:14:02 -0400939 RET
940
Devon H. O'Dell5a4a08f2009-12-08 18:19:30 -0800941// check that SP is in range [g->stackbase, g->stackguard)
Keith Randall5a546962013-08-07 10:23:24 -0700942TEXT runtime·stackcheck(SB), NOSPLIT, $0-0
Russ Coxe473f422010-08-04 17:50:22 -0700943 get_tls(CX)
944 MOVQ g(CX), AX
945 CMPQ g_stackbase(AX), SP
Russ Cox01eaf782010-03-30 10:53:16 -0700946 JHI 2(PC)
947 INT $3
Russ Coxe473f422010-08-04 17:50:22 -0700948 CMPQ SP, g_stackguard(AX)
Russ Cox01eaf782010-03-30 10:53:16 -0700949 JHI 2(PC)
950 INT $3
951 RET
952
Russ Cox25f6b022014-08-27 11:32:17 -0400953TEXT runtime·getcallerpc(SB),NOSPLIT,$0-16
954 MOVQ argp+0(FP),AX // addr of first arg
Russ Cox6c196012010-04-05 12:51:09 -0700955 MOVQ -8(AX),AX // get calling pc
Russ Cox25f6b022014-08-27 11:32:17 -0400956 MOVQ AX, ret+8(FP)
Russ Cox6c196012010-04-05 12:51:09 -0700957 RET
958
Keith Randall14c81432014-06-17 21:59:50 -0700959TEXT runtime·gogetcallerpc(SB),NOSPLIT,$0-16
960 MOVQ p+0(FP),AX // addr of first arg
Keith Randall61dca942014-06-16 23:03:03 -0700961 MOVQ -8(AX),AX // get calling pc
Keith Randall14c81432014-06-17 21:59:50 -0700962 MOVQ AX,ret+8(FP)
Keith Randall61dca942014-06-16 23:03:03 -0700963 RET
964
Keith Randall5a546962013-08-07 10:23:24 -0700965TEXT runtime·setcallerpc(SB),NOSPLIT,$0-16
Russ Cox25f6b022014-08-27 11:32:17 -0400966 MOVQ argp+0(FP),AX // addr of first arg
967 MOVQ pc+8(FP), BX
Russ Cox6c196012010-04-05 12:51:09 -0700968 MOVQ BX, -8(AX) // set calling pc
969 RET
970
Russ Cox25f6b022014-08-27 11:32:17 -0400971TEXT runtime·getcallersp(SB),NOSPLIT,$0-16
972 MOVQ argp+0(FP), AX
973 MOVQ AX, ret+8(FP)
Russ Cox6c196012010-04-05 12:51:09 -0700974 RET
975
Rémy Oudompheng39ffa8b2014-08-26 08:34:46 +0200976// func gogetcallersp(p unsafe.Pointer) uintptr
977TEXT runtime·gogetcallersp(SB),NOSPLIT,$0-16
978 MOVQ p+0(FP),AX // addr of first arg
979 MOVQ AX, ret+8(FP)
980 RET
981
Damian Gryski8e765da2012-02-02 14:09:27 -0500982// int64 runtime·cputicks(void)
Keith Randall5a546962013-08-07 10:23:24 -0700983TEXT runtime·cputicks(SB),NOSPLIT,$0-0
Damian Gryski8e765da2012-02-02 14:09:27 -0500984 RDTSC
985 SHLQ $32, DX
986 ADDQ DX, AX
Russ Cox25f6b022014-08-27 11:32:17 -0400987 MOVQ AX, ret+0(FP)
Damian Gryski8e765da2012-02-02 14:09:27 -0500988 RET
989
Dmitriy Vyukov684de042014-08-21 20:41:09 +0400990TEXT runtime·gocputicks(SB),NOSPLIT,$0-8
991 RDTSC
Dmitriy Vyukovf4485782014-08-22 21:27:25 +0400992 SHLQ $32, DX
993 ADDQ DX, AX
994 MOVQ AX, ret+0(FP)
Dmitriy Vyukov684de042014-08-21 20:41:09 +0400995 RET
996
Keith Randall5a546962013-08-07 10:23:24 -0700997TEXT runtime·stackguard(SB),NOSPLIT,$0-16
Russ Cox9e5db8c2012-03-15 15:22:30 -0400998 MOVQ SP, DX
999 MOVQ DX, sp+0(FP)
1000 get_tls(CX)
1001 MOVQ g(CX), BX
1002 MOVQ g_stackguard(BX), DX
Russ Cox07720b62013-03-22 12:57:55 -04001003 MOVQ DX, limit+8(FP)
Russ Cox9e5db8c2012-03-15 15:22:30 -04001004 RET
1005
Russ Cox68b42552010-11-04 14:00:19 -04001006GLOBL runtime·tls0(SB), $64
Keith Randalla5d40242013-03-12 10:47:44 -07001007
1008// hash function using AES hardware instructions
Keith Randalla2a97682014-07-31 15:07:05 -07001009TEXT runtime·aeshash(SB),NOSPLIT,$0-32
1010 MOVQ p+0(FP), AX // ptr to data
1011 MOVQ s+8(FP), CX // size
Keith Randalla5d40242013-03-12 10:47:44 -07001012 JMP runtime·aeshashbody(SB)
1013
Keith Randalla2a97682014-07-31 15:07:05 -07001014TEXT runtime·aeshashstr(SB),NOSPLIT,$0-32
1015 MOVQ p+0(FP), AX // ptr to string struct
1016 // s+8(FP) is ignored, it is always sizeof(String)
Keith Randalla5d40242013-03-12 10:47:44 -07001017 MOVQ 8(AX), CX // length of string
1018 MOVQ (AX), AX // string data
1019 JMP runtime·aeshashbody(SB)
1020
1021// AX: data
1022// CX: length
Keith Randalla2a97682014-07-31 15:07:05 -07001023TEXT runtime·aeshashbody(SB),NOSPLIT,$0-32
1024 MOVQ h+16(FP), X0 // seed to low 64 bits of xmm0
Keith Randalla5d40242013-03-12 10:47:44 -07001025 PINSRQ $1, CX, X0 // size to high 64 bits of xmm0
Keith Randalldb53d972013-03-20 14:34:26 -07001026 MOVO runtime·aeskeysched+0(SB), X2
1027 MOVO runtime·aeskeysched+16(SB), X3
Keith Randallee669722013-05-15 09:40:14 -07001028 CMPQ CX, $16
1029 JB aessmall
Keith Randalla5d40242013-03-12 10:47:44 -07001030aesloop:
1031 CMPQ CX, $16
Keith Randallee669722013-05-15 09:40:14 -07001032 JBE aesloopend
Keith Randalla5d40242013-03-12 10:47:44 -07001033 MOVOU (AX), X1
1034 AESENC X2, X0
1035 AESENC X1, X0
1036 SUBQ $16, CX
1037 ADDQ $16, AX
1038 JMP aesloop
Keith Randallee669722013-05-15 09:40:14 -07001039// 1-16 bytes remaining
Keith Randalla5d40242013-03-12 10:47:44 -07001040aesloopend:
Keith Randallee669722013-05-15 09:40:14 -07001041 // This load may overlap with the previous load above.
1042 // We'll hash some bytes twice, but that's ok.
1043 MOVOU -16(AX)(CX*1), X1
1044 JMP partial
1045// 0-15 bytes
1046aessmall:
Keith Randalla5d40242013-03-12 10:47:44 -07001047 TESTQ CX, CX
Keith Randallee669722013-05-15 09:40:14 -07001048 JE finalize // 0 bytes
Keith Randalla5d40242013-03-12 10:47:44 -07001049
Keith Randallee669722013-05-15 09:40:14 -07001050 CMPB AX, $0xf0
1051 JA highpartial
Keith Randalla5d40242013-03-12 10:47:44 -07001052
Keith Randallee669722013-05-15 09:40:14 -07001053 // 16 bytes loaded at this address won't cross
1054 // a page boundary, so we can load it directly.
Keith Randalla5d40242013-03-12 10:47:44 -07001055 MOVOU (AX), X1
1056 ADDQ CX, CX
Russ Cox9aa1e9a2014-08-12 19:51:20 -04001057 MOVQ $masks<>(SB), BP
1058 PAND (BP)(CX*8), X1
Keith Randalla5d40242013-03-12 10:47:44 -07001059 JMP partial
1060highpartial:
Keith Randallee669722013-05-15 09:40:14 -07001061 // address ends in 1111xxxx. Might be up against
Keith Randalla5d40242013-03-12 10:47:44 -07001062 // a page boundary, so load ending at last byte.
1063 // Then shift bytes down using pshufb.
1064 MOVOU -16(AX)(CX*1), X1
1065 ADDQ CX, CX
Russ Cox9aa1e9a2014-08-12 19:51:20 -04001066 MOVQ $shifts<>(SB), BP
1067 PSHUFB (BP)(CX*8), X1
Keith Randalla5d40242013-03-12 10:47:44 -07001068partial:
1069 // incorporate partial block into hash
1070 AESENC X3, X0
1071 AESENC X1, X0
1072finalize:
1073 // finalize hash
1074 AESENC X2, X0
1075 AESENC X3, X0
1076 AESENC X2, X0
Keith Randalla2a97682014-07-31 15:07:05 -07001077 MOVQ X0, res+24(FP)
Keith Randalla5d40242013-03-12 10:47:44 -07001078 RET
1079
Keith Randalla2a97682014-07-31 15:07:05 -07001080TEXT runtime·aeshash32(SB),NOSPLIT,$0-32
1081 MOVQ p+0(FP), AX // ptr to data
1082 // s+8(FP) is ignored, it is always sizeof(int32)
1083 MOVQ h+16(FP), X0 // seed
Keith Randalla5d40242013-03-12 10:47:44 -07001084 PINSRD $2, (AX), X0 // data
Keith Randalldb53d972013-03-20 14:34:26 -07001085 AESENC runtime·aeskeysched+0(SB), X0
1086 AESENC runtime·aeskeysched+16(SB), X0
1087 AESENC runtime·aeskeysched+0(SB), X0
Russ Cox25f6b022014-08-27 11:32:17 -04001088 MOVQ X0, ret+24(FP)
Keith Randalla5d40242013-03-12 10:47:44 -07001089 RET
1090
Keith Randalla2a97682014-07-31 15:07:05 -07001091TEXT runtime·aeshash64(SB),NOSPLIT,$0-32
1092 MOVQ p+0(FP), AX // ptr to data
1093 // s+8(FP) is ignored, it is always sizeof(int64)
1094 MOVQ h+16(FP), X0 // seed
Keith Randalla5d40242013-03-12 10:47:44 -07001095 PINSRQ $1, (AX), X0 // data
Keith Randalldb53d972013-03-20 14:34:26 -07001096 AESENC runtime·aeskeysched+0(SB), X0
1097 AESENC runtime·aeskeysched+16(SB), X0
1098 AESENC runtime·aeskeysched+0(SB), X0
Russ Cox25f6b022014-08-27 11:32:17 -04001099 MOVQ X0, ret+24(FP)
Keith Randalla5d40242013-03-12 10:47:44 -07001100 RET
1101
1102// simple mask to get rid of data in the high part of the register.
Russ Cox9ddfb642013-07-16 16:24:09 -04001103DATA masks<>+0x00(SB)/8, $0x0000000000000000
1104DATA masks<>+0x08(SB)/8, $0x0000000000000000
1105DATA masks<>+0x10(SB)/8, $0x00000000000000ff
1106DATA masks<>+0x18(SB)/8, $0x0000000000000000
1107DATA masks<>+0x20(SB)/8, $0x000000000000ffff
1108DATA masks<>+0x28(SB)/8, $0x0000000000000000
1109DATA masks<>+0x30(SB)/8, $0x0000000000ffffff
1110DATA masks<>+0x38(SB)/8, $0x0000000000000000
1111DATA masks<>+0x40(SB)/8, $0x00000000ffffffff
1112DATA masks<>+0x48(SB)/8, $0x0000000000000000
1113DATA masks<>+0x50(SB)/8, $0x000000ffffffffff
1114DATA masks<>+0x58(SB)/8, $0x0000000000000000
1115DATA masks<>+0x60(SB)/8, $0x0000ffffffffffff
1116DATA masks<>+0x68(SB)/8, $0x0000000000000000
1117DATA masks<>+0x70(SB)/8, $0x00ffffffffffffff
1118DATA masks<>+0x78(SB)/8, $0x0000000000000000
1119DATA masks<>+0x80(SB)/8, $0xffffffffffffffff
1120DATA masks<>+0x88(SB)/8, $0x0000000000000000
1121DATA masks<>+0x90(SB)/8, $0xffffffffffffffff
1122DATA masks<>+0x98(SB)/8, $0x00000000000000ff
1123DATA masks<>+0xa0(SB)/8, $0xffffffffffffffff
1124DATA masks<>+0xa8(SB)/8, $0x000000000000ffff
1125DATA masks<>+0xb0(SB)/8, $0xffffffffffffffff
1126DATA masks<>+0xb8(SB)/8, $0x0000000000ffffff
1127DATA masks<>+0xc0(SB)/8, $0xffffffffffffffff
1128DATA masks<>+0xc8(SB)/8, $0x00000000ffffffff
1129DATA masks<>+0xd0(SB)/8, $0xffffffffffffffff
1130DATA masks<>+0xd8(SB)/8, $0x000000ffffffffff
1131DATA masks<>+0xe0(SB)/8, $0xffffffffffffffff
1132DATA masks<>+0xe8(SB)/8, $0x0000ffffffffffff
1133DATA masks<>+0xf0(SB)/8, $0xffffffffffffffff
1134DATA masks<>+0xf8(SB)/8, $0x00ffffffffffffff
Keith Randall5a546962013-08-07 10:23:24 -07001135GLOBL masks<>(SB),RODATA,$256
Keith Randalla5d40242013-03-12 10:47:44 -07001136
Russ Cox9ddfb642013-07-16 16:24:09 -04001137// these are arguments to pshufb. They move data down from
1138// the high bytes of the register to the low bytes of the register.
1139// index is how many bytes to move.
1140DATA shifts<>+0x00(SB)/8, $0x0000000000000000
1141DATA shifts<>+0x08(SB)/8, $0x0000000000000000
1142DATA shifts<>+0x10(SB)/8, $0xffffffffffffff0f
1143DATA shifts<>+0x18(SB)/8, $0xffffffffffffffff
1144DATA shifts<>+0x20(SB)/8, $0xffffffffffff0f0e
1145DATA shifts<>+0x28(SB)/8, $0xffffffffffffffff
1146DATA shifts<>+0x30(SB)/8, $0xffffffffff0f0e0d
1147DATA shifts<>+0x38(SB)/8, $0xffffffffffffffff
1148DATA shifts<>+0x40(SB)/8, $0xffffffff0f0e0d0c
1149DATA shifts<>+0x48(SB)/8, $0xffffffffffffffff
1150DATA shifts<>+0x50(SB)/8, $0xffffff0f0e0d0c0b
1151DATA shifts<>+0x58(SB)/8, $0xffffffffffffffff
1152DATA shifts<>+0x60(SB)/8, $0xffff0f0e0d0c0b0a
1153DATA shifts<>+0x68(SB)/8, $0xffffffffffffffff
1154DATA shifts<>+0x70(SB)/8, $0xff0f0e0d0c0b0a09
1155DATA shifts<>+0x78(SB)/8, $0xffffffffffffffff
1156DATA shifts<>+0x80(SB)/8, $0x0f0e0d0c0b0a0908
1157DATA shifts<>+0x88(SB)/8, $0xffffffffffffffff
1158DATA shifts<>+0x90(SB)/8, $0x0e0d0c0b0a090807
1159DATA shifts<>+0x98(SB)/8, $0xffffffffffffff0f
1160DATA shifts<>+0xa0(SB)/8, $0x0d0c0b0a09080706
1161DATA shifts<>+0xa8(SB)/8, $0xffffffffffff0f0e
1162DATA shifts<>+0xb0(SB)/8, $0x0c0b0a0908070605
1163DATA shifts<>+0xb8(SB)/8, $0xffffffffff0f0e0d
1164DATA shifts<>+0xc0(SB)/8, $0x0b0a090807060504
1165DATA shifts<>+0xc8(SB)/8, $0xffffffff0f0e0d0c
1166DATA shifts<>+0xd0(SB)/8, $0x0a09080706050403
1167DATA shifts<>+0xd8(SB)/8, $0xffffff0f0e0d0c0b
1168DATA shifts<>+0xe0(SB)/8, $0x0908070605040302
1169DATA shifts<>+0xe8(SB)/8, $0xffff0f0e0d0c0b0a
1170DATA shifts<>+0xf0(SB)/8, $0x0807060504030201
1171DATA shifts<>+0xf8(SB)/8, $0xff0f0e0d0c0b0a09
Keith Randall5a546962013-08-07 10:23:24 -07001172GLOBL shifts<>(SB),RODATA,$256
Keith Randall3d5daa22013-04-02 16:26:15 -07001173
Keith Randall7aa4e5a2014-08-07 14:52:55 -07001174TEXT runtime·memeq(SB),NOSPLIT,$0-25
Keith Randall0c6b55e2014-07-16 14:16:19 -07001175 MOVQ a+0(FP), SI
1176 MOVQ b+8(FP), DI
1177 MOVQ size+16(FP), BX
1178 CALL runtime·memeqbody(SB)
1179 MOVB AX, ret+24(FP)
1180 RET
1181
Keith Randallb36ed902014-06-16 21:00:37 -07001182// eqstring tests whether two strings are equal.
1183// See runtime_test.go:eqstring_generic for
Josh Bleecher Snyder339a24d2014-08-19 08:50:35 -07001184// equivalent Go code.
Keith Randallb36ed902014-06-16 21:00:37 -07001185TEXT runtime·eqstring(SB),NOSPLIT,$0-33
1186 MOVQ s1len+8(FP), AX
1187 MOVQ s2len+24(FP), BX
1188 CMPQ AX, BX
1189 JNE different
1190 MOVQ s1str+0(FP), SI
1191 MOVQ s2str+16(FP), DI
1192 CMPQ SI, DI
1193 JEQ same
1194 CALL runtime·memeqbody(SB)
1195 MOVB AX, v+32(FP)
1196 RET
1197same:
1198 MOVB $1, v+32(FP)
1199 RET
1200different:
1201 MOVB $0, v+32(FP)
1202 RET
1203
Keith Randall3d5daa22013-04-02 16:26:15 -07001204// a in SI
1205// b in DI
1206// count in BX
Keith Randall5a546962013-08-07 10:23:24 -07001207TEXT runtime·memeqbody(SB),NOSPLIT,$0-0
Keith Randall3d5daa22013-04-02 16:26:15 -07001208 XORQ AX, AX
1209
1210 CMPQ BX, $8
1211 JB small
1212
1213 // 64 bytes at a time using xmm registers
1214hugeloop:
1215 CMPQ BX, $64
1216 JB bigloop
1217 MOVOU (SI), X0
1218 MOVOU (DI), X1
1219 MOVOU 16(SI), X2
1220 MOVOU 16(DI), X3
1221 MOVOU 32(SI), X4
1222 MOVOU 32(DI), X5
1223 MOVOU 48(SI), X6
1224 MOVOU 48(DI), X7
1225 PCMPEQB X1, X0
1226 PCMPEQB X3, X2
1227 PCMPEQB X5, X4
1228 PCMPEQB X7, X6
1229 PAND X2, X0
1230 PAND X6, X4
1231 PAND X4, X0
1232 PMOVMSKB X0, DX
1233 ADDQ $64, SI
1234 ADDQ $64, DI
1235 SUBQ $64, BX
1236 CMPL DX, $0xffff
1237 JEQ hugeloop
1238 RET
1239
1240 // 8 bytes at a time using 64-bit register
1241bigloop:
1242 CMPQ BX, $8
1243 JBE leftover
1244 MOVQ (SI), CX
1245 MOVQ (DI), DX
1246 ADDQ $8, SI
1247 ADDQ $8, DI
1248 SUBQ $8, BX
1249 CMPQ CX, DX
1250 JEQ bigloop
1251 RET
1252
1253 // remaining 0-8 bytes
1254leftover:
1255 MOVQ -8(SI)(BX*1), CX
1256 MOVQ -8(DI)(BX*1), DX
1257 CMPQ CX, DX
1258 SETEQ AX
1259 RET
1260
1261small:
1262 CMPQ BX, $0
1263 JEQ equal
1264
1265 LEAQ 0(BX*8), CX
1266 NEGQ CX
1267
1268 CMPB SI, $0xf8
1269 JA si_high
1270
1271 // load at SI won't cross a page boundary.
1272 MOVQ (SI), SI
1273 JMP si_finish
1274si_high:
1275 // address ends in 11111xxx. Load up to bytes we want, move to correct position.
1276 MOVQ -8(SI)(BX*1), SI
1277 SHRQ CX, SI
1278si_finish:
1279
1280 // same for DI.
1281 CMPB DI, $0xf8
1282 JA di_high
1283 MOVQ (DI), DI
1284 JMP di_finish
1285di_high:
1286 MOVQ -8(DI)(BX*1), DI
1287 SHRQ CX, DI
1288di_finish:
1289
1290 SUBQ SI, DI
1291 SHLQ CX, DI
1292equal:
1293 SETEQ AX
1294 RET
Keith Randallb3946dc2013-05-14 16:05:51 -07001295
Keith Randall5a546962013-08-07 10:23:24 -07001296TEXT runtime·cmpstring(SB),NOSPLIT,$0-40
Russ Cox25f6b022014-08-27 11:32:17 -04001297 MOVQ s1_base+0(FP), SI
1298 MOVQ s1_len+8(FP), BX
1299 MOVQ s2_base+16(FP), DI
1300 MOVQ s2_len+24(FP), DX
Keith Randallb3946dc2013-05-14 16:05:51 -07001301 CALL runtime·cmpbody(SB)
Russ Cox25f6b022014-08-27 11:32:17 -04001302 MOVQ AX, ret+32(FP)
Keith Randallb3946dc2013-05-14 16:05:51 -07001303 RET
1304
Russ Cox6179aca2014-08-28 10:46:59 -04001305TEXT runtime·cmpbytes(SB),NOSPLIT,$0-56
Keith Randallb3946dc2013-05-14 16:05:51 -07001306 MOVQ s1+0(FP), SI
1307 MOVQ s1+8(FP), BX
1308 MOVQ s2+24(FP), DI
1309 MOVQ s2+32(FP), DX
1310 CALL runtime·cmpbody(SB)
1311 MOVQ AX, res+48(FP)
1312 RET
1313
1314// input:
1315// SI = a
1316// DI = b
1317// BX = alen
1318// DX = blen
1319// output:
1320// AX = 1/0/-1
Keith Randall5a546962013-08-07 10:23:24 -07001321TEXT runtime·cmpbody(SB),NOSPLIT,$0-0
Keith Randallb3946dc2013-05-14 16:05:51 -07001322 CMPQ SI, DI
1323 JEQ cmp_allsame
1324 CMPQ BX, DX
1325 MOVQ DX, BP
1326 CMOVQLT BX, BP // BP = min(alen, blen) = # of bytes to compare
1327 CMPQ BP, $8
1328 JB cmp_small
1329
1330cmp_loop:
1331 CMPQ BP, $16
1332 JBE cmp_0through16
1333 MOVOU (SI), X0
1334 MOVOU (DI), X1
1335 PCMPEQB X0, X1
1336 PMOVMSKB X1, AX
1337 XORQ $0xffff, AX // convert EQ to NE
1338 JNE cmp_diff16 // branch if at least one byte is not equal
1339 ADDQ $16, SI
1340 ADDQ $16, DI
1341 SUBQ $16, BP
1342 JMP cmp_loop
1343
1344 // AX = bit mask of differences
1345cmp_diff16:
1346 BSFQ AX, BX // index of first byte that differs
1347 XORQ AX, AX
1348 MOVB (SI)(BX*1), CX
1349 CMPB CX, (DI)(BX*1)
1350 SETHI AX
1351 LEAQ -1(AX*2), AX // convert 1/0 to +1/-1
1352 RET
1353
1354 // 0 through 16 bytes left, alen>=8, blen>=8
1355cmp_0through16:
1356 CMPQ BP, $8
1357 JBE cmp_0through8
1358 MOVQ (SI), AX
1359 MOVQ (DI), CX
1360 CMPQ AX, CX
1361 JNE cmp_diff8
1362cmp_0through8:
1363 MOVQ -8(SI)(BP*1), AX
1364 MOVQ -8(DI)(BP*1), CX
1365 CMPQ AX, CX
1366 JEQ cmp_allsame
1367
1368 // AX and CX contain parts of a and b that differ.
1369cmp_diff8:
1370 BSWAPQ AX // reverse order of bytes
1371 BSWAPQ CX
1372 XORQ AX, CX
1373 BSRQ CX, CX // index of highest bit difference
1374 SHRQ CX, AX // move a's bit to bottom
1375 ANDQ $1, AX // mask bit
1376 LEAQ -1(AX*2), AX // 1/0 => +1/-1
1377 RET
1378
1379 // 0-7 bytes in common
1380cmp_small:
1381 LEAQ (BP*8), CX // bytes left -> bits left
1382 NEGQ CX // - bits lift (== 64 - bits left mod 64)
1383 JEQ cmp_allsame
1384
1385 // load bytes of a into high bytes of AX
1386 CMPB SI, $0xf8
1387 JA cmp_si_high
1388 MOVQ (SI), SI
1389 JMP cmp_si_finish
1390cmp_si_high:
1391 MOVQ -8(SI)(BP*1), SI
1392 SHRQ CX, SI
1393cmp_si_finish:
1394 SHLQ CX, SI
1395
1396 // load bytes of b in to high bytes of BX
1397 CMPB DI, $0xf8
1398 JA cmp_di_high
1399 MOVQ (DI), DI
1400 JMP cmp_di_finish
1401cmp_di_high:
1402 MOVQ -8(DI)(BP*1), DI
1403 SHRQ CX, DI
1404cmp_di_finish:
1405 SHLQ CX, DI
1406
1407 BSWAPQ SI // reverse order of bytes
1408 BSWAPQ DI
1409 XORQ SI, DI // find bit differences
1410 JEQ cmp_allsame
1411 BSRQ DI, CX // index of highest bit difference
1412 SHRQ CX, SI // move a's bit to bottom
1413 ANDQ $1, SI // mask bit
1414 LEAQ -1(SI*2), AX // 1/0 => +1/-1
1415 RET
1416
1417cmp_allsame:
1418 XORQ AX, AX
1419 XORQ CX, CX
1420 CMPQ BX, DX
1421 SETGT AX // 1 if alen > blen
1422 SETEQ CX // 1 if alen == blen
1423 LEAQ -1(CX)(AX*2), AX // 1,0,-1 result
1424 RET
Brad Fitzpatricke2a1bd62013-08-01 16:11:19 -07001425
Keith Randall5a546962013-08-07 10:23:24 -07001426TEXT bytes·IndexByte(SB),NOSPLIT,$0
Brad Fitzpatricke2a1bd62013-08-01 16:11:19 -07001427 MOVQ s+0(FP), SI
1428 MOVQ s_len+8(FP), BX
1429 MOVB c+24(FP), AL
Brad Fitzpatrick598c7892013-08-05 15:04:05 -07001430 CALL runtime·indexbytebody(SB)
1431 MOVQ AX, ret+32(FP)
1432 RET
1433
Keith Randall5a546962013-08-07 10:23:24 -07001434TEXT strings·IndexByte(SB),NOSPLIT,$0
Brad Fitzpatrick598c7892013-08-05 15:04:05 -07001435 MOVQ s+0(FP), SI
1436 MOVQ s_len+8(FP), BX
1437 MOVB c+16(FP), AL
1438 CALL runtime·indexbytebody(SB)
1439 MOVQ AX, ret+24(FP)
1440 RET
1441
1442// input:
1443// SI: data
1444// BX: data len
1445// AL: byte sought
1446// output:
1447// AX
Keith Randall5a546962013-08-07 10:23:24 -07001448TEXT runtime·indexbytebody(SB),NOSPLIT,$0
Brad Fitzpatricke2a1bd62013-08-01 16:11:19 -07001449 MOVQ SI, DI
1450
1451 CMPQ BX, $16
1452 JLT indexbyte_small
1453
1454 // round up to first 16-byte boundary
1455 TESTQ $15, SI
1456 JZ aligned
1457 MOVQ SI, CX
1458 ANDQ $~15, CX
1459 ADDQ $16, CX
1460
1461 // search the beginning
1462 SUBQ SI, CX
1463 REPN; SCASB
1464 JZ success
1465
1466// DI is 16-byte aligned; get ready to search using SSE instructions
1467aligned:
1468 // round down to last 16-byte boundary
1469 MOVQ BX, R11
1470 ADDQ SI, R11
1471 ANDQ $~15, R11
1472
1473 // shuffle X0 around so that each byte contains c
1474 MOVD AX, X0
1475 PUNPCKLBW X0, X0
1476 PUNPCKLBW X0, X0
1477 PSHUFL $0, X0, X0
1478 JMP condition
1479
1480sse:
1481 // move the next 16-byte chunk of the buffer into X1
1482 MOVO (DI), X1
1483 // compare bytes in X0 to X1
1484 PCMPEQB X0, X1
1485 // take the top bit of each byte in X1 and put the result in DX
1486 PMOVMSKB X1, DX
1487 TESTL DX, DX
1488 JNZ ssesuccess
1489 ADDQ $16, DI
1490
1491condition:
1492 CMPQ DI, R11
1493 JLT sse
1494
1495 // search the end
1496 MOVQ SI, CX
1497 ADDQ BX, CX
1498 SUBQ R11, CX
1499 // if CX == 0, the zero flag will be set and we'll end up
1500 // returning a false success
1501 JZ failure
1502 REPN; SCASB
1503 JZ success
1504
1505failure:
Brad Fitzpatrick598c7892013-08-05 15:04:05 -07001506 MOVQ $-1, AX
Brad Fitzpatricke2a1bd62013-08-01 16:11:19 -07001507 RET
1508
1509// handle for lengths < 16
1510indexbyte_small:
1511 MOVQ BX, CX
1512 REPN; SCASB
1513 JZ success
Brad Fitzpatrick598c7892013-08-05 15:04:05 -07001514 MOVQ $-1, AX
Brad Fitzpatricke2a1bd62013-08-01 16:11:19 -07001515 RET
1516
1517// we've found the chunk containing the byte
1518// now just figure out which specific byte it is
1519ssesuccess:
1520 // get the index of the least significant set bit
1521 BSFW DX, DX
1522 SUBQ SI, DI
1523 ADDQ DI, DX
Brad Fitzpatrick598c7892013-08-05 15:04:05 -07001524 MOVQ DX, AX
Brad Fitzpatricke2a1bd62013-08-01 16:11:19 -07001525 RET
1526
1527success:
1528 SUBQ SI, DI
1529 SUBL $1, DI
Brad Fitzpatrick598c7892013-08-05 15:04:05 -07001530 MOVQ DI, AX
Brad Fitzpatricke2a1bd62013-08-01 16:11:19 -07001531 RET
1532
Keith Randall5a546962013-08-07 10:23:24 -07001533TEXT bytes·Equal(SB),NOSPLIT,$0-49
Brad Fitzpatricke2a1bd62013-08-01 16:11:19 -07001534 MOVQ a_len+8(FP), BX
1535 MOVQ b_len+32(FP), CX
1536 XORQ AX, AX
1537 CMPQ BX, CX
1538 JNE eqret
1539 MOVQ a+0(FP), SI
1540 MOVQ b+24(FP), DI
1541 CALL runtime·memeqbody(SB)
1542eqret:
1543 MOVB AX, ret+48(FP)
1544 RET
Keith Randall6c7cbf02014-04-01 12:51:02 -07001545
1546// A Duff's device for zeroing memory.
1547// The compiler jumps to computed addresses within
1548// this routine to zero chunks of memory. Do not
1549// change this code without also changing the code
1550// in ../../cmd/6g/ggen.c:clearfat.
1551// AX: zero
1552// DI: ptr to memory to be zeroed
1553// DI is updated as a side effect.
1554TEXT runtime·duffzero(SB), NOSPLIT, $0-0
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 STOSQ
1635 STOSQ
1636 STOSQ
1637 STOSQ
1638 STOSQ
1639 STOSQ
1640 STOSQ
1641 STOSQ
1642 STOSQ
1643 STOSQ
1644 STOSQ
1645 STOSQ
1646 STOSQ
1647 STOSQ
1648 STOSQ
1649 STOSQ
1650 STOSQ
1651 STOSQ
1652 STOSQ
1653 STOSQ
1654 STOSQ
1655 STOSQ
1656 STOSQ
1657 STOSQ
1658 STOSQ
1659 STOSQ
1660 STOSQ
1661 STOSQ
1662 STOSQ
1663 STOSQ
1664 STOSQ
1665 STOSQ
1666 STOSQ
1667 STOSQ
1668 STOSQ
1669 STOSQ
1670 STOSQ
1671 STOSQ
1672 STOSQ
1673 STOSQ
1674 STOSQ
1675 STOSQ
1676 STOSQ
1677 STOSQ
1678 STOSQ
1679 STOSQ
1680 STOSQ
1681 STOSQ
1682 STOSQ
1683 RET
1684
1685// A Duff's device for copying memory.
1686// The compiler jumps to computed addresses within
1687// this routine to copy chunks of memory. Source
1688// and destination must not overlap. Do not
1689// change this code without also changing the code
1690// in ../../cmd/6g/cgen.c:sgen.
1691// SI: ptr to source memory
1692// DI: ptr to destination memory
1693// SI and DI are updated as a side effect.
1694
1695// NOTE: this is equivalent to a sequence of MOVSQ but
1696// for some reason that is 3.5x slower than this code.
1697// The STOSQ above seem fine, though.
1698TEXT runtime·duffcopy(SB), NOSPLIT, $0-0
1699 MOVQ (SI),CX
1700 ADDQ $8,SI
1701 MOVQ CX,(DI)
1702 ADDQ $8,DI
1703
1704 MOVQ (SI),CX
1705 ADDQ $8,SI
1706 MOVQ CX,(DI)
1707 ADDQ $8,DI
1708
1709 MOVQ (SI),CX
1710 ADDQ $8,SI
1711 MOVQ CX,(DI)
1712 ADDQ $8,DI
1713
1714 MOVQ (SI),CX
1715 ADDQ $8,SI
1716 MOVQ CX,(DI)
1717 ADDQ $8,DI
1718
1719 MOVQ (SI),CX
1720 ADDQ $8,SI
1721 MOVQ CX,(DI)
1722 ADDQ $8,DI
1723
1724 MOVQ (SI),CX
1725 ADDQ $8,SI
1726 MOVQ CX,(DI)
1727 ADDQ $8,DI
1728
1729 MOVQ (SI),CX
1730 ADDQ $8,SI
1731 MOVQ CX,(DI)
1732 ADDQ $8,DI
1733
1734 MOVQ (SI),CX
1735 ADDQ $8,SI
1736 MOVQ CX,(DI)
1737 ADDQ $8,DI
1738
1739 MOVQ (SI),CX
1740 ADDQ $8,SI
1741 MOVQ CX,(DI)
1742 ADDQ $8,DI
1743
1744 MOVQ (SI),CX
1745 ADDQ $8,SI
1746 MOVQ CX,(DI)
1747 ADDQ $8,DI
1748
1749 MOVQ (SI),CX
1750 ADDQ $8,SI
1751 MOVQ CX,(DI)
1752 ADDQ $8,DI
1753
1754 MOVQ (SI),CX
1755 ADDQ $8,SI
1756 MOVQ CX,(DI)
1757 ADDQ $8,DI
1758
1759 MOVQ (SI),CX
1760 ADDQ $8,SI
1761 MOVQ CX,(DI)
1762 ADDQ $8,DI
1763
1764 MOVQ (SI),CX
1765 ADDQ $8,SI
1766 MOVQ CX,(DI)
1767 ADDQ $8,DI
1768
1769 MOVQ (SI),CX
1770 ADDQ $8,SI
1771 MOVQ CX,(DI)
1772 ADDQ $8,DI
1773
1774 MOVQ (SI),CX
1775 ADDQ $8,SI
1776 MOVQ CX,(DI)
1777 ADDQ $8,DI
1778
1779 MOVQ (SI),CX
1780 ADDQ $8,SI
1781 MOVQ CX,(DI)
1782 ADDQ $8,DI
1783
1784 MOVQ (SI),CX
1785 ADDQ $8,SI
1786 MOVQ CX,(DI)
1787 ADDQ $8,DI
1788
1789 MOVQ (SI),CX
1790 ADDQ $8,SI
1791 MOVQ CX,(DI)
1792 ADDQ $8,DI
1793
1794 MOVQ (SI),CX
1795 ADDQ $8,SI
1796 MOVQ CX,(DI)
1797 ADDQ $8,DI
1798
1799 MOVQ (SI),CX
1800 ADDQ $8,SI
1801 MOVQ CX,(DI)
1802 ADDQ $8,DI
1803
1804 MOVQ (SI),CX
1805 ADDQ $8,SI
1806 MOVQ CX,(DI)
1807 ADDQ $8,DI
1808
1809 MOVQ (SI),CX
1810 ADDQ $8,SI
1811 MOVQ CX,(DI)
1812 ADDQ $8,DI
1813
1814 MOVQ (SI),CX
1815 ADDQ $8,SI
1816 MOVQ CX,(DI)
1817 ADDQ $8,DI
1818
1819 MOVQ (SI),CX
1820 ADDQ $8,SI
1821 MOVQ CX,(DI)
1822 ADDQ $8,DI
1823
1824 MOVQ (SI),CX
1825 ADDQ $8,SI
1826 MOVQ CX,(DI)
1827 ADDQ $8,DI
1828
1829 MOVQ (SI),CX
1830 ADDQ $8,SI
1831 MOVQ CX,(DI)
1832 ADDQ $8,DI
1833
1834 MOVQ (SI),CX
1835 ADDQ $8,SI
1836 MOVQ CX,(DI)
1837 ADDQ $8,DI
1838
1839 MOVQ (SI),CX
1840 ADDQ $8,SI
1841 MOVQ CX,(DI)
1842 ADDQ $8,DI
1843
1844 MOVQ (SI),CX
1845 ADDQ $8,SI
1846 MOVQ CX,(DI)
1847 ADDQ $8,DI
1848
1849 MOVQ (SI),CX
1850 ADDQ $8,SI
1851 MOVQ CX,(DI)
1852 ADDQ $8,DI
1853
1854 MOVQ (SI),CX
1855 ADDQ $8,SI
1856 MOVQ CX,(DI)
1857 ADDQ $8,DI
1858
1859 MOVQ (SI),CX
1860 ADDQ $8,SI
1861 MOVQ CX,(DI)
1862 ADDQ $8,DI
1863
1864 MOVQ (SI),CX
1865 ADDQ $8,SI
1866 MOVQ CX,(DI)
1867 ADDQ $8,DI
1868
1869 MOVQ (SI),CX
1870 ADDQ $8,SI
1871 MOVQ CX,(DI)
1872 ADDQ $8,DI
1873
1874 MOVQ (SI),CX
1875 ADDQ $8,SI
1876 MOVQ CX,(DI)
1877 ADDQ $8,DI
1878
1879 MOVQ (SI),CX
1880 ADDQ $8,SI
1881 MOVQ CX,(DI)
1882 ADDQ $8,DI
1883
1884 MOVQ (SI),CX
1885 ADDQ $8,SI
1886 MOVQ CX,(DI)
1887 ADDQ $8,DI
1888
1889 MOVQ (SI),CX
1890 ADDQ $8,SI
1891 MOVQ CX,(DI)
1892 ADDQ $8,DI
1893
1894 MOVQ (SI),CX
1895 ADDQ $8,SI
1896 MOVQ CX,(DI)
1897 ADDQ $8,DI
1898
1899 MOVQ (SI),CX
1900 ADDQ $8,SI
1901 MOVQ CX,(DI)
1902 ADDQ $8,DI
1903
1904 MOVQ (SI),CX
1905 ADDQ $8,SI
1906 MOVQ CX,(DI)
1907 ADDQ $8,DI
1908
1909 MOVQ (SI),CX
1910 ADDQ $8,SI
1911 MOVQ CX,(DI)
1912 ADDQ $8,DI
1913
1914 MOVQ (SI),CX
1915 ADDQ $8,SI
1916 MOVQ CX,(DI)
1917 ADDQ $8,DI
1918
1919 MOVQ (SI),CX
1920 ADDQ $8,SI
1921 MOVQ CX,(DI)
1922 ADDQ $8,DI
1923
1924 MOVQ (SI),CX
1925 ADDQ $8,SI
1926 MOVQ CX,(DI)
1927 ADDQ $8,DI
1928
1929 MOVQ (SI),CX
1930 ADDQ $8,SI
1931 MOVQ CX,(DI)
1932 ADDQ $8,DI
1933
1934 MOVQ (SI),CX
1935 ADDQ $8,SI
1936 MOVQ CX,(DI)
1937 ADDQ $8,DI
1938
1939 MOVQ (SI),CX
1940 ADDQ $8,SI
1941 MOVQ CX,(DI)
1942 ADDQ $8,DI
1943
1944 MOVQ (SI),CX
1945 ADDQ $8,SI
1946 MOVQ CX,(DI)
1947 ADDQ $8,DI
1948
1949 MOVQ (SI),CX
1950 ADDQ $8,SI
1951 MOVQ CX,(DI)
1952 ADDQ $8,DI
1953
1954 MOVQ (SI),CX
1955 ADDQ $8,SI
1956 MOVQ CX,(DI)
1957 ADDQ $8,DI
1958
1959 MOVQ (SI),CX
1960 ADDQ $8,SI
1961 MOVQ CX,(DI)
1962 ADDQ $8,DI
1963
1964 MOVQ (SI),CX
1965 ADDQ $8,SI
1966 MOVQ CX,(DI)
1967 ADDQ $8,DI
1968
1969 MOVQ (SI),CX
1970 ADDQ $8,SI
1971 MOVQ CX,(DI)
1972 ADDQ $8,DI
1973
1974 MOVQ (SI),CX
1975 ADDQ $8,SI
1976 MOVQ CX,(DI)
1977 ADDQ $8,DI
1978
1979 MOVQ (SI),CX
1980 ADDQ $8,SI
1981 MOVQ CX,(DI)
1982 ADDQ $8,DI
1983
1984 MOVQ (SI),CX
1985 ADDQ $8,SI
1986 MOVQ CX,(DI)
1987 ADDQ $8,DI
1988
1989 MOVQ (SI),CX
1990 ADDQ $8,SI
1991 MOVQ CX,(DI)
1992 ADDQ $8,DI
1993
1994 MOVQ (SI),CX
1995 ADDQ $8,SI
1996 MOVQ CX,(DI)
1997 ADDQ $8,DI
1998
1999 MOVQ (SI),CX
2000 ADDQ $8,SI
2001 MOVQ CX,(DI)
2002 ADDQ $8,DI
2003
2004 MOVQ (SI),CX
2005 ADDQ $8,SI
2006 MOVQ CX,(DI)
2007 ADDQ $8,DI
2008
2009 MOVQ (SI),CX
2010 ADDQ $8,SI
2011 MOVQ CX,(DI)
2012 ADDQ $8,DI
2013
2014 MOVQ (SI),CX
2015 ADDQ $8,SI
2016 MOVQ CX,(DI)
2017 ADDQ $8,DI
2018
2019 MOVQ (SI),CX
2020 ADDQ $8,SI
2021 MOVQ CX,(DI)
2022 ADDQ $8,DI
2023
2024 MOVQ (SI),CX
2025 ADDQ $8,SI
2026 MOVQ CX,(DI)
2027 ADDQ $8,DI
2028
2029 MOVQ (SI),CX
2030 ADDQ $8,SI
2031 MOVQ CX,(DI)
2032 ADDQ $8,DI
2033
2034 MOVQ (SI),CX
2035 ADDQ $8,SI
2036 MOVQ CX,(DI)
2037 ADDQ $8,DI
2038
2039 MOVQ (SI),CX
2040 ADDQ $8,SI
2041 MOVQ CX,(DI)
2042 ADDQ $8,DI
2043
2044 MOVQ (SI),CX
2045 ADDQ $8,SI
2046 MOVQ CX,(DI)
2047 ADDQ $8,DI
2048
2049 MOVQ (SI),CX
2050 ADDQ $8,SI
2051 MOVQ CX,(DI)
2052 ADDQ $8,DI
2053
2054 MOVQ (SI),CX
2055 ADDQ $8,SI
2056 MOVQ CX,(DI)
2057 ADDQ $8,DI
2058
2059 MOVQ (SI),CX
2060 ADDQ $8,SI
2061 MOVQ CX,(DI)
2062 ADDQ $8,DI
2063
2064 MOVQ (SI),CX
2065 ADDQ $8,SI
2066 MOVQ CX,(DI)
2067 ADDQ $8,DI
2068
2069 MOVQ (SI),CX
2070 ADDQ $8,SI
2071 MOVQ CX,(DI)
2072 ADDQ $8,DI
2073
2074 MOVQ (SI),CX
2075 ADDQ $8,SI
2076 MOVQ CX,(DI)
2077 ADDQ $8,DI
2078
2079 MOVQ (SI),CX
2080 ADDQ $8,SI
2081 MOVQ CX,(DI)
2082 ADDQ $8,DI
2083
2084 MOVQ (SI),CX
2085 ADDQ $8,SI
2086 MOVQ CX,(DI)
2087 ADDQ $8,DI
2088
2089 MOVQ (SI),CX
2090 ADDQ $8,SI
2091 MOVQ CX,(DI)
2092 ADDQ $8,DI
2093
2094 MOVQ (SI),CX
2095 ADDQ $8,SI
2096 MOVQ CX,(DI)
2097 ADDQ $8,DI
2098
2099 MOVQ (SI),CX
2100 ADDQ $8,SI
2101 MOVQ CX,(DI)
2102 ADDQ $8,DI
2103
2104 MOVQ (SI),CX
2105 ADDQ $8,SI
2106 MOVQ CX,(DI)
2107 ADDQ $8,DI
2108
2109 MOVQ (SI),CX
2110 ADDQ $8,SI
2111 MOVQ CX,(DI)
2112 ADDQ $8,DI
2113
2114 MOVQ (SI),CX
2115 ADDQ $8,SI
2116 MOVQ CX,(DI)
2117 ADDQ $8,DI
2118
2119 MOVQ (SI),CX
2120 ADDQ $8,SI
2121 MOVQ CX,(DI)
2122 ADDQ $8,DI
2123
2124 MOVQ (SI),CX
2125 ADDQ $8,SI
2126 MOVQ CX,(DI)
2127 ADDQ $8,DI
2128
2129 MOVQ (SI),CX
2130 ADDQ $8,SI
2131 MOVQ CX,(DI)
2132 ADDQ $8,DI
2133
2134 MOVQ (SI),CX
2135 ADDQ $8,SI
2136 MOVQ CX,(DI)
2137 ADDQ $8,DI
2138
2139 MOVQ (SI),CX
2140 ADDQ $8,SI
2141 MOVQ CX,(DI)
2142 ADDQ $8,DI
2143
2144 MOVQ (SI),CX
2145 ADDQ $8,SI
2146 MOVQ CX,(DI)
2147 ADDQ $8,DI
2148
2149 MOVQ (SI),CX
2150 ADDQ $8,SI
2151 MOVQ CX,(DI)
2152 ADDQ $8,DI
2153
2154 MOVQ (SI),CX
2155 ADDQ $8,SI
2156 MOVQ CX,(DI)
2157 ADDQ $8,DI
2158
2159 MOVQ (SI),CX
2160 ADDQ $8,SI
2161 MOVQ CX,(DI)
2162 ADDQ $8,DI
2163
2164 MOVQ (SI),CX
2165 ADDQ $8,SI
2166 MOVQ CX,(DI)
2167 ADDQ $8,DI
2168
2169 MOVQ (SI),CX
2170 ADDQ $8,SI
2171 MOVQ CX,(DI)
2172 ADDQ $8,DI
2173
2174 MOVQ (SI),CX
2175 ADDQ $8,SI
2176 MOVQ CX,(DI)
2177 ADDQ $8,DI
2178
2179 MOVQ (SI),CX
2180 ADDQ $8,SI
2181 MOVQ CX,(DI)
2182 ADDQ $8,DI
2183
2184 MOVQ (SI),CX
2185 ADDQ $8,SI
2186 MOVQ CX,(DI)
2187 ADDQ $8,DI
2188
2189 MOVQ (SI),CX
2190 ADDQ $8,SI
2191 MOVQ CX,(DI)
2192 ADDQ $8,DI
2193
2194 MOVQ (SI),CX
2195 ADDQ $8,SI
2196 MOVQ CX,(DI)
2197 ADDQ $8,DI
2198
2199 MOVQ (SI),CX
2200 ADDQ $8,SI
2201 MOVQ CX,(DI)
2202 ADDQ $8,DI
2203
2204 MOVQ (SI),CX
2205 ADDQ $8,SI
2206 MOVQ CX,(DI)
2207 ADDQ $8,DI
2208
2209 MOVQ (SI),CX
2210 ADDQ $8,SI
2211 MOVQ CX,(DI)
2212 ADDQ $8,DI
2213
2214 MOVQ (SI),CX
2215 ADDQ $8,SI
2216 MOVQ CX,(DI)
2217 ADDQ $8,DI
2218
2219 MOVQ (SI),CX
2220 ADDQ $8,SI
2221 MOVQ CX,(DI)
2222 ADDQ $8,DI
2223
2224 MOVQ (SI),CX
2225 ADDQ $8,SI
2226 MOVQ CX,(DI)
2227 ADDQ $8,DI
2228
2229 MOVQ (SI),CX
2230 ADDQ $8,SI
2231 MOVQ CX,(DI)
2232 ADDQ $8,DI
2233
2234 MOVQ (SI),CX
2235 ADDQ $8,SI
2236 MOVQ CX,(DI)
2237 ADDQ $8,DI
2238
2239 MOVQ (SI),CX
2240 ADDQ $8,SI
2241 MOVQ CX,(DI)
2242 ADDQ $8,DI
2243
2244 MOVQ (SI),CX
2245 ADDQ $8,SI
2246 MOVQ CX,(DI)
2247 ADDQ $8,DI
2248
2249 MOVQ (SI),CX
2250 ADDQ $8,SI
2251 MOVQ CX,(DI)
2252 ADDQ $8,DI
2253
2254 MOVQ (SI),CX
2255 ADDQ $8,SI
2256 MOVQ CX,(DI)
2257 ADDQ $8,DI
2258
2259 MOVQ (SI),CX
2260 ADDQ $8,SI
2261 MOVQ CX,(DI)
2262 ADDQ $8,DI
2263
2264 MOVQ (SI),CX
2265 ADDQ $8,SI
2266 MOVQ CX,(DI)
2267 ADDQ $8,DI
2268
2269 MOVQ (SI),CX
2270 ADDQ $8,SI
2271 MOVQ CX,(DI)
2272 ADDQ $8,DI
2273
2274 MOVQ (SI),CX
2275 ADDQ $8,SI
2276 MOVQ CX,(DI)
2277 ADDQ $8,DI
2278
2279 MOVQ (SI),CX
2280 ADDQ $8,SI
2281 MOVQ CX,(DI)
2282 ADDQ $8,DI
2283
2284 MOVQ (SI),CX
2285 ADDQ $8,SI
2286 MOVQ CX,(DI)
2287 ADDQ $8,DI
2288
2289 MOVQ (SI),CX
2290 ADDQ $8,SI
2291 MOVQ CX,(DI)
2292 ADDQ $8,DI
2293
2294 MOVQ (SI),CX
2295 ADDQ $8,SI
2296 MOVQ CX,(DI)
2297 ADDQ $8,DI
2298
2299 MOVQ (SI),CX
2300 ADDQ $8,SI
2301 MOVQ CX,(DI)
2302 ADDQ $8,DI
2303
2304 MOVQ (SI),CX
2305 ADDQ $8,SI
2306 MOVQ CX,(DI)
2307 ADDQ $8,DI
2308
2309 MOVQ (SI),CX
2310 ADDQ $8,SI
2311 MOVQ CX,(DI)
2312 ADDQ $8,DI
2313
2314 MOVQ (SI),CX
2315 ADDQ $8,SI
2316 MOVQ CX,(DI)
2317 ADDQ $8,DI
2318
2319 MOVQ (SI),CX
2320 ADDQ $8,SI
2321 MOVQ CX,(DI)
2322 ADDQ $8,DI
2323
2324 MOVQ (SI),CX
2325 ADDQ $8,SI
2326 MOVQ CX,(DI)
2327 ADDQ $8,DI
2328
2329 MOVQ (SI),CX
2330 ADDQ $8,SI
2331 MOVQ CX,(DI)
2332 ADDQ $8,DI
2333
2334 MOVQ (SI),CX
2335 ADDQ $8,SI
2336 MOVQ CX,(DI)
2337 ADDQ $8,DI
2338
2339 RET
Dmitriy Vyukov350a8fc2014-05-02 17:32:42 +01002340
2341TEXT runtime·timenow(SB), NOSPLIT, $0-0
2342 JMP time·now(SB)
Keith Randall0c6b55e2014-07-16 14:16:19 -07002343
Keith Randall3306d112014-09-02 14:33:33 -07002344TEXT runtime·fastrand1(SB), NOSPLIT, $0-4
Keith Randall0c6b55e2014-07-16 14:16:19 -07002345 get_tls(CX)
2346 MOVQ g(CX), AX
2347 MOVQ g_m(AX), AX
2348 MOVL m_fastrand(AX), DX
2349 ADDL DX, DX
2350 MOVL DX, BX
2351 XORL $0x88888eef, DX
2352 CMOVLMI BX, DX
2353 MOVL DX, m_fastrand(AX)
2354 MOVL DX, ret+0(FP)
2355 RET