blob: 70e2225213810d414b1f27c3646f5489fc2600aa [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
Russ Cox25f6b022014-08-27 11:32:17 -0400128 MOVQ buf+0(FP), AX // gobuf
129 LEAQ buf+0(FP), BX // caller's SP
Russ Cox7343e032009-06-17 15:12:16 -0700130 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 Cox25f6b022014-08-27 11:32:17 -0400143 MOVQ buf+0(FP), 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)
Russ Cox25f6b022014-08-27 11:32:17 -0400168 LEAQ fn+0(FP), BX // caller's SP
Russ Coxf9ca3b52011-03-07 10:37:42 -0500169 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 Cox25f6b022014-08-27 11:32:17 -0400300 LEAQ fv+0(FP), 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 Cox25f6b022014-08-27 11:32:17 -0400317 MOVQ fv+0(FP), AX // fn
318 MOVQ addr+8(FP), DX // arg frame
319 MOVL size+16(FP), CX // arg size
Russ Coxbba278a2009-07-08 18:16:09 -0700320
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;
Russ Cox25f6b022014-08-27 11:32:17 -0400587TEXT runtime·cas(SB), NOSPLIT, $0-17
588 MOVQ ptr+0(FP), BX
589 MOVL old+8(FP), AX
590 MOVL new+12(FP), CX
Russ Coxd28acc42008-08-04 16:43:49 -0700591 LOCK
592 CMPXCHGL CX, 0(BX)
Russ Cox25f6b022014-08-27 11:32:17 -0400593 JZ 4(PC)
Russ Coxd28acc42008-08-04 16:43:49 -0700594 MOVL $0, AX
Russ Cox25f6b022014-08-27 11:32:17 -0400595 MOVB AX, ret+16(FP)
Russ Coxd28acc42008-08-04 16:43:49 -0700596 RET
597 MOVL $1, AX
Russ Cox25f6b022014-08-27 11:32:17 -0400598 MOVB AX, ret+16(FP)
Russ Coxd28acc42008-08-04 16:43:49 -0700599 RET
Ken Thompson1e1cc4e2009-01-27 12:03:53 -0800600
Russ Cox9ddfb642013-07-16 16:24:09 -0400601// bool runtime·cas64(uint64 *val, uint64 old, uint64 new)
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400602// Atomically:
603// if(*val == *old){
604// *val = new;
605// return 1;
606// } else {
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400607// return 0;
608// }
Russ Cox25f6b022014-08-27 11:32:17 -0400609TEXT runtime·cas64(SB), NOSPLIT, $0-25
610 MOVQ ptr+0(FP), BX
611 MOVQ old+8(FP), AX
612 MOVQ new+16(FP), CX
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400613 LOCK
614 CMPXCHGQ CX, 0(BX)
615 JNZ cas64_fail
616 MOVL $1, AX
Russ Cox25f6b022014-08-27 11:32:17 -0400617 MOVB AX, ret+24(FP)
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400618 RET
619cas64_fail:
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400620 MOVL $0, AX
Russ Cox25f6b022014-08-27 11:32:17 -0400621 MOVB AX, ret+24(FP)
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400622 RET
623
Russ Cox67793502011-02-16 13:21:13 -0500624// bool casp(void **val, void *old, void *new)
625// Atomically:
626// if(*val == old){
627// *val = new;
628// return 1;
629// } else
630// return 0;
Russ Cox25f6b022014-08-27 11:32:17 -0400631TEXT runtime·casp(SB), NOSPLIT, $0-25
632 MOVQ ptr+0(FP), BX
633 MOVQ old+8(FP), AX
634 MOVQ new+16(FP), CX
Russ Cox67793502011-02-16 13:21:13 -0500635 LOCK
636 CMPXCHGQ CX, 0(BX)
Russ Cox25f6b022014-08-27 11:32:17 -0400637 JZ 4(PC)
Russ Cox67793502011-02-16 13:21:13 -0500638 MOVL $0, AX
Russ Cox25f6b022014-08-27 11:32:17 -0400639 MOVB AX, ret+24(FP)
Russ Cox67793502011-02-16 13:21:13 -0500640 RET
641 MOVL $1, AX
Russ Cox25f6b022014-08-27 11:32:17 -0400642 MOVB AX, ret+24(FP)
Russ Cox67793502011-02-16 13:21:13 -0500643 RET
644
Dmitriy Vyukov491aa152011-07-15 11:27:16 -0400645// uint32 xadd(uint32 volatile *val, int32 delta)
646// Atomically:
647// *val += delta;
648// return *val;
Russ Cox25f6b022014-08-27 11:32:17 -0400649TEXT runtime·xadd(SB), NOSPLIT, $0-20
650 MOVQ ptr+0(FP), BX
651 MOVL delta+8(FP), AX
Dmitriy Vyukov491aa152011-07-15 11:27:16 -0400652 MOVL AX, CX
653 LOCK
654 XADDL AX, 0(BX)
655 ADDL CX, AX
Russ Cox25f6b022014-08-27 11:32:17 -0400656 MOVL AX, ret+16(FP)
Dmitriy Vyukov491aa152011-07-15 11:27:16 -0400657 RET
658
Russ Cox25f6b022014-08-27 11:32:17 -0400659TEXT runtime·xadd64(SB), NOSPLIT, $0-24
660 MOVQ ptr+0(FP), BX
661 MOVQ delta+8(FP), AX
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400662 MOVQ AX, CX
663 LOCK
664 XADDQ AX, 0(BX)
665 ADDQ CX, AX
Russ Cox25f6b022014-08-27 11:32:17 -0400666 MOVQ AX, ret+16(FP)
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400667 RET
668
Russ Cox25f6b022014-08-27 11:32:17 -0400669TEXT runtime·xchg(SB), NOSPLIT, $0-20
670 MOVQ ptr+0(FP), BX
671 MOVL new+8(FP), AX
Dmitriy Vyukov4e5086b2011-07-29 12:44:06 -0400672 XCHGL AX, 0(BX)
Russ Cox25f6b022014-08-27 11:32:17 -0400673 MOVL AX, ret+16(FP)
Dmitriy Vyukov4e5086b2011-07-29 12:44:06 -0400674 RET
675
Russ Cox25f6b022014-08-27 11:32:17 -0400676TEXT runtime·xchg64(SB), NOSPLIT, $0-24
677 MOVQ ptr+0(FP), BX
678 MOVQ new+8(FP), AX
Dmitriy Vyukovadd33492013-03-05 09:46:52 +0200679 XCHGQ AX, 0(BX)
Russ Cox25f6b022014-08-27 11:32:17 -0400680 MOVQ AX, ret+16(FP)
Dmitriy Vyukovadd33492013-03-05 09:46:52 +0200681 RET
682
Russ Cox25f6b022014-08-27 11:32:17 -0400683TEXT runtime·xchgp(SB), NOSPLIT, $0-24
684 MOVQ ptr+0(FP), BX
685 MOVQ new+8(FP), AX
Dmitriy Vyukov9cbd2fb2014-01-22 11:27:16 +0400686 XCHGQ AX, 0(BX)
Russ Cox25f6b022014-08-27 11:32:17 -0400687 MOVQ AX, ret+16(FP)
Dmitriy Vyukov9cbd2fb2014-01-22 11:27:16 +0400688 RET
689
Keith Randall5a546962013-08-07 10:23:24 -0700690TEXT runtime·procyield(SB),NOSPLIT,$0-0
Russ Cox25f6b022014-08-27 11:32:17 -0400691 MOVL cycles+0(FP), AX
Dmitriy Vyukov4e5086b2011-07-29 12:44:06 -0400692again:
693 PAUSE
694 SUBL $1, AX
695 JNZ again
696 RET
697
Keith Randall5a546962013-08-07 10:23:24 -0700698TEXT runtime·atomicstorep(SB), NOSPLIT, $0-16
Russ Cox25f6b022014-08-27 11:32:17 -0400699 MOVQ ptr+0(FP), BX
700 MOVQ val+8(FP), AX
Dmitriy Vyukov86a659c2011-07-13 11:22:41 -0700701 XCHGQ AX, 0(BX)
702 RET
703
Keith Randall5a546962013-08-07 10:23:24 -0700704TEXT runtime·atomicstore(SB), NOSPLIT, $0-12
Russ Cox25f6b022014-08-27 11:32:17 -0400705 MOVQ ptr+0(FP), BX
706 MOVL val+8(FP), AX
Dmitriy Vyukov91f0f182011-07-29 13:47:24 -0400707 XCHGL AX, 0(BX)
708 RET
709
Keith Randall5a546962013-08-07 10:23:24 -0700710TEXT runtime·atomicstore64(SB), NOSPLIT, $0-16
Russ Cox25f6b022014-08-27 11:32:17 -0400711 MOVQ ptr+0(FP), BX
712 MOVQ val+8(FP), AX
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400713 XCHGQ AX, 0(BX)
714 RET
715
Dmitriy Vyukovff3fa1b2014-08-19 17:38:00 +0400716// void runtime·atomicor8(byte volatile*, byte);
Russ Cox25f6b022014-08-27 11:32:17 -0400717TEXT runtime·atomicor8(SB), NOSPLIT, $0-9
Dmitriy Vyukovff3fa1b2014-08-19 17:38:00 +0400718 MOVQ ptr+0(FP), AX
719 MOVB val+8(FP), BX
720 LOCK
721 ORB BX, (AX)
722 RET
723
Russ Coxaa3222d82009-06-02 23:02:12 -0700724// void jmpdefer(fn, sp);
725// called from deferreturn.
Ken Thompson1e1cc4e2009-01-27 12:03:53 -0800726// 1. pop the caller
727// 2. sub 5 bytes from the callers return
728// 3. jmp to the argument
Keith Randalla97a91d2013-08-07 14:03:50 -0700729TEXT runtime·jmpdefer(SB), NOSPLIT, $0-16
Russ Cox25f6b022014-08-27 11:32:17 -0400730 MOVQ fv+0(FP), DX // fn
731 MOVQ argp+8(FP), BX // caller sp
Russ Coxaa3222d82009-06-02 23:02:12 -0700732 LEAQ -8(BX), SP // caller sp after CALL
733 SUBQ $5, (SP) // return to CALL again
Russ Cox6066fdc2013-02-22 10:47:54 -0500734 MOVQ 0(DX), BX
Russ Cox1903ad72013-02-21 17:01:13 -0500735 JMP BX // but first run the deferred function
Russ Cox133a1582009-10-03 10:37:12 -0700736
Russ Coxd67e7e32013-06-12 15:22:26 -0400737// Save state of caller into g->sched. Smashes R8, R9.
Keith Randall5a546962013-08-07 10:23:24 -0700738TEXT gosave<>(SB),NOSPLIT,$0
Russ Coxd67e7e32013-06-12 15:22:26 -0400739 get_tls(R8)
740 MOVQ g(R8), R8
741 MOVQ 0(SP), R9
742 MOVQ R9, (g_sched+gobuf_pc)(R8)
743 LEAQ 8(SP), R9
744 MOVQ R9, (g_sched+gobuf_sp)(R8)
745 MOVQ $0, (g_sched+gobuf_ret)(R8)
746 MOVQ $0, (g_sched+gobuf_ctxt)(R8)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500747 RET
748
749// asmcgocall(void(*fn)(void*), void *arg)
Russ Coxadd89dd2009-10-12 10:26:38 -0700750// Call fn(arg) on the scheduler stack,
751// aligned appropriately for the gcc ABI.
Russ Coxf9ca3b52011-03-07 10:37:42 -0500752// See cgocall.c for more details.
Keith Randall5a546962013-08-07 10:23:24 -0700753TEXT runtime·asmcgocall(SB),NOSPLIT,$0-16
Russ Coxf9ca3b52011-03-07 10:37:42 -0500754 MOVQ fn+0(FP), AX
755 MOVQ arg+8(FP), BX
756 MOVQ SP, DX
Russ Coxadd89dd2009-10-12 10:26:38 -0700757
758 // Figure out if we need to switch to m->g0 stack.
Russ Coxf9ca3b52011-03-07 10:37:42 -0500759 // We get called to create new OS threads too, and those
760 // come in on the m->g0 stack already.
761 get_tls(CX)
Russ Cox89f185f2014-06-26 11:54:39 -0400762 MOVQ g(CX), BP
763 MOVQ g_m(BP), BP
Russ Coxf9ca3b52011-03-07 10:37:42 -0500764 MOVQ m_g0(BP), SI
765 MOVQ g(CX), DI
766 CMPQ SI, DI
Aram Hăvărneanua46b4342014-01-17 17:58:10 +1300767 JEQ nosave
768 MOVQ m_gsignal(BP), SI
769 CMPQ SI, DI
770 JEQ nosave
771
772 MOVQ m_g0(BP), SI
Russ Coxd67e7e32013-06-12 15:22:26 -0400773 CALL gosave<>(SB)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500774 MOVQ SI, g(CX)
775 MOVQ (g_sched+gobuf_sp)(SI), SP
Aram Hăvărneanua46b4342014-01-17 17:58:10 +1300776nosave:
Russ Coxadd89dd2009-10-12 10:26:38 -0700777
778 // Now on a scheduling stack (a pthread-created stack).
Alex Brainman7f075ec2012-09-03 12:12:51 +1000779 // Make sure we have enough room for 4 stack-backed fast-call
780 // registers as per windows amd64 calling convention.
781 SUBQ $64, SP
Russ Cox133a1582009-10-03 10:37:12 -0700782 ANDQ $~15, SP // alignment for gcc ABI
Alex Brainman7f075ec2012-09-03 12:12:51 +1000783 MOVQ DI, 48(SP) // save g
784 MOVQ DX, 40(SP) // save SP
Russ Coxf9ca3b52011-03-07 10:37:42 -0500785 MOVQ BX, DI // DI = first argument in AMD64 ABI
Wei Guangjing9f636592011-07-19 10:47:33 -0400786 MOVQ BX, CX // CX = first argument in Win64
Russ Coxf9ca3b52011-03-07 10:37:42 -0500787 CALL AX
Russ Coxadd89dd2009-10-12 10:26:38 -0700788
Russ Coxe473f422010-08-04 17:50:22 -0700789 // Restore registers, g, stack pointer.
Russ Coxf9ca3b52011-03-07 10:37:42 -0500790 get_tls(CX)
Alex Brainman7f075ec2012-09-03 12:12:51 +1000791 MOVQ 48(SP), DI
Russ Coxf9ca3b52011-03-07 10:37:42 -0500792 MOVQ DI, g(CX)
Alex Brainman7f075ec2012-09-03 12:12:51 +1000793 MOVQ 40(SP), SP
Russ Cox133a1582009-10-03 10:37:12 -0700794 RET
795
Russ Coxf9ca3b52011-03-07 10:37:42 -0500796// cgocallback(void (*fn)(void*), void *frame, uintptr framesize)
Russ Cox3d2dfc52013-02-22 16:08:56 -0500797// Turn the fn into a Go func (by taking its address) and call
798// cgocallback_gofunc.
Keith Randall5a546962013-08-07 10:23:24 -0700799TEXT runtime·cgocallback(SB),NOSPLIT,$24-24
Russ Cox3d2dfc52013-02-22 16:08:56 -0500800 LEAQ fn+0(FP), AX
801 MOVQ AX, 0(SP)
802 MOVQ frame+8(FP), AX
803 MOVQ AX, 8(SP)
804 MOVQ framesize+16(FP), AX
805 MOVQ AX, 16(SP)
806 MOVQ $runtime·cgocallback_gofunc(SB), AX
807 CALL AX
808 RET
809
810// cgocallback_gofunc(FuncVal*, void *frame, uintptr framesize)
811// See cgocall.c for more details.
Keith Randall5a546962013-08-07 10:23:24 -0700812TEXT runtime·cgocallback_gofunc(SB),NOSPLIT,$8-24
Russ Cox89f185f2014-06-26 11:54:39 -0400813 // If g is nil, Go did not create the current thread.
814 // Call needm to obtain one m for temporary use.
Russ Cox6c976392013-02-20 17:48:23 -0500815 // In this case, we're running on the thread stack, so there's
816 // lots of space, but the linker doesn't know. Hide the call from
817 // the linker analysis by using an indirect call through AX.
818 get_tls(CX)
819#ifdef GOOS_windows
Russ Coxdba623b2013-07-23 18:40:02 -0400820 MOVL $0, BP
Russ Cox6c976392013-02-20 17:48:23 -0500821 CMPQ CX, $0
Russ Coxcefdb9c2013-07-23 22:59:32 -0400822 JEQ 2(PC)
Russ Cox6c976392013-02-20 17:48:23 -0500823#endif
Russ Cox89f185f2014-06-26 11:54:39 -0400824 MOVQ g(CX), BP
Russ Cox6c976392013-02-20 17:48:23 -0500825 CMPQ BP, $0
Russ Cox89f185f2014-06-26 11:54:39 -0400826 JEQ needm
827 MOVQ g_m(BP), BP
828 MOVQ BP, R8 // holds oldm until end of function
829 JMP havem
Russ Cox6c976392013-02-20 17:48:23 -0500830needm:
Russ Cox89f185f2014-06-26 11:54:39 -0400831 MOVQ $0, 0(SP)
Russ Cox6c976392013-02-20 17:48:23 -0500832 MOVQ $runtime·needm(SB), AX
833 CALL AX
Russ Coxf0112822013-07-24 09:01:57 -0400834 MOVQ 0(SP), R8
Russ Coxe473f422010-08-04 17:50:22 -0700835 get_tls(CX)
Russ Cox89f185f2014-06-26 11:54:39 -0400836 MOVQ g(CX), BP
837 MOVQ g_m(BP), BP
Russ Cox9b732382012-03-08 12:12:40 -0500838
Russ Cox6c976392013-02-20 17:48:23 -0500839havem:
840 // Now there's a valid m, and we're running on its m->g0.
841 // Save current m->g0->sched.sp on stack and then set it to SP.
842 // Save current sp in m->g0->sched.sp in preparation for
843 // switch back to m->curg stack.
Russ Coxdba623b2013-07-23 18:40:02 -0400844 // NOTE: unwindm knows that the saved g->sched.sp is at 0(SP).
Russ Coxf9ca3b52011-03-07 10:37:42 -0500845 MOVQ m_g0(BP), SI
Russ Coxdba623b2013-07-23 18:40:02 -0400846 MOVQ (g_sched+gobuf_sp)(SI), AX
847 MOVQ AX, 0(SP)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500848 MOVQ SP, (g_sched+gobuf_sp)(SI)
Ian Lance Taylor2d0ff3f2010-04-09 13:30:11 -0700849
Russ Coxdba623b2013-07-23 18:40:02 -0400850 // Switch to m->curg stack and call runtime.cgocallbackg.
851 // Because we are taking over the execution of m->curg
852 // but *not* resuming what had been running, we need to
853 // save that information (m->curg->sched) so we can restore it.
Russ Cox528534c2013-06-05 07:16:53 -0400854 // We can restore m->curg->sched.sp easily, because calling
Alex Brainman72e83482011-08-18 12:17:09 -0400855 // runtime.cgocallbackg leaves SP unchanged upon return.
Russ Cox528534c2013-06-05 07:16:53 -0400856 // To save m->curg->sched.pc, we push it onto the stack.
Russ Coxf9ca3b52011-03-07 10:37:42 -0500857 // This has the added benefit that it looks to the traceback
Alex Brainman72e83482011-08-18 12:17:09 -0400858 // routine like cgocallbackg is going to return to that
Russ Coxdba623b2013-07-23 18:40:02 -0400859 // PC (because the frame we allocate below has the same
860 // size as cgocallback_gofunc's frame declared above)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500861 // so that the traceback will seamlessly trace back into
862 // the earlier calls.
Russ Coxdba623b2013-07-23 18:40:02 -0400863 //
Russ Coxf0112822013-07-24 09:01:57 -0400864 // In the new goroutine, 0(SP) holds the saved R8.
Russ Coxf9ca3b52011-03-07 10:37:42 -0500865 MOVQ m_curg(BP), SI
866 MOVQ SI, g(CX)
867 MOVQ (g_sched+gobuf_sp)(SI), DI // prepare stack as DI
Russ Coxf9ca3b52011-03-07 10:37:42 -0500868 MOVQ (g_sched+gobuf_pc)(SI), BP
Russ Coxdba623b2013-07-23 18:40:02 -0400869 MOVQ BP, -8(DI)
Russ Coxf0112822013-07-24 09:01:57 -0400870 LEAQ -(8+8)(DI), SP
871 MOVQ R8, 0(SP)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500872 CALL runtime·cgocallbackg(SB)
Russ Coxf0112822013-07-24 09:01:57 -0400873 MOVQ 0(SP), R8
Russ Coxf9ca3b52011-03-07 10:37:42 -0500874
Russ Cox528534c2013-06-05 07:16:53 -0400875 // Restore g->sched (== m->curg->sched) from saved values.
Russ Coxe473f422010-08-04 17:50:22 -0700876 get_tls(CX)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500877 MOVQ g(CX), SI
Russ Coxf0112822013-07-24 09:01:57 -0400878 MOVQ 8(SP), BP
Russ Coxf9ca3b52011-03-07 10:37:42 -0500879 MOVQ BP, (g_sched+gobuf_pc)(SI)
Russ Coxf0112822013-07-24 09:01:57 -0400880 LEAQ (8+8)(SP), DI
Russ Coxf9ca3b52011-03-07 10:37:42 -0500881 MOVQ DI, (g_sched+gobuf_sp)(SI)
882
883 // Switch back to m->g0's stack and restore m->g0->sched.sp.
884 // (Unlike m->curg, the g0 goroutine never uses sched.pc,
885 // so we do not have to restore it.)
Russ Cox89f185f2014-06-26 11:54:39 -0400886 MOVQ g(CX), BP
887 MOVQ g_m(BP), BP
Russ Coxf9ca3b52011-03-07 10:37:42 -0500888 MOVQ m_g0(BP), SI
889 MOVQ SI, g(CX)
890 MOVQ (g_sched+gobuf_sp)(SI), SP
Russ Coxdba623b2013-07-23 18:40:02 -0400891 MOVQ 0(SP), AX
892 MOVQ AX, (g_sched+gobuf_sp)(SI)
Russ Cox6c976392013-02-20 17:48:23 -0500893
894 // If the m on entry was nil, we called needm above to borrow an m
895 // for the duration of the call. Since the call is over, return it with dropm.
Russ Coxf0112822013-07-24 09:01:57 -0400896 CMPQ R8, $0
Russ Cox6c976392013-02-20 17:48:23 -0500897 JNE 3(PC)
898 MOVQ $runtime·dropm(SB), AX
899 CALL AX
Russ Coxf9ca3b52011-03-07 10:37:42 -0500900
901 // Done!
Ian Lance Taylor2d0ff3f2010-04-09 13:30:11 -0700902 RET
903
Russ Cox89f185f2014-06-26 11:54:39 -0400904// void setg(G*); set g. for use by needm.
Russ Cox25f6b022014-08-27 11:32:17 -0400905TEXT runtime·setg(SB), NOSPLIT, $0-8
Russ Cox89f185f2014-06-26 11:54:39 -0400906 MOVQ gg+0(FP), BX
Russ Cox6c976392013-02-20 17:48:23 -0500907#ifdef GOOS_windows
Russ Cox89f185f2014-06-26 11:54:39 -0400908 CMPQ BX, $0
Russ Cox6c976392013-02-20 17:48:23 -0500909 JNE settls
910 MOVQ $0, 0x28(GS)
911 RET
912settls:
Russ Cox89f185f2014-06-26 11:54:39 -0400913 MOVQ g_m(BX), AX
Russ Cox6c976392013-02-20 17:48:23 -0500914 LEAQ m_tls(AX), AX
915 MOVQ AX, 0x28(GS)
916#endif
917 get_tls(CX)
Russ Cox6c976392013-02-20 17:48:23 -0500918 MOVQ BX, g(CX)
919 RET
920
Russ Cox89f185f2014-06-26 11:54:39 -0400921// void setg_gcc(G*); set g called from gcc.
922TEXT setg_gcc<>(SB),NOSPLIT,$0
Russ Cox6a70f9d2013-03-25 18:14:02 -0400923 get_tls(AX)
Russ Cox89f185f2014-06-26 11:54:39 -0400924 MOVQ DI, g(AX)
Russ Cox6a70f9d2013-03-25 18:14:02 -0400925 RET
926
Devon H. O'Dell5a4a08f2009-12-08 18:19:30 -0800927// check that SP is in range [g->stackbase, g->stackguard)
Keith Randall5a546962013-08-07 10:23:24 -0700928TEXT runtime·stackcheck(SB), NOSPLIT, $0-0
Russ Coxe473f422010-08-04 17:50:22 -0700929 get_tls(CX)
930 MOVQ g(CX), AX
931 CMPQ g_stackbase(AX), SP
Russ Cox01eaf782010-03-30 10:53:16 -0700932 JHI 2(PC)
933 INT $3
Russ Coxe473f422010-08-04 17:50:22 -0700934 CMPQ SP, g_stackguard(AX)
Russ Cox01eaf782010-03-30 10:53:16 -0700935 JHI 2(PC)
936 INT $3
937 RET
938
Russ Cox25f6b022014-08-27 11:32:17 -0400939TEXT runtime·getcallerpc(SB),NOSPLIT,$0-16
940 MOVQ argp+0(FP),AX // addr of first arg
Russ Cox6c196012010-04-05 12:51:09 -0700941 MOVQ -8(AX),AX // get calling pc
Russ Cox25f6b022014-08-27 11:32:17 -0400942 MOVQ AX, ret+8(FP)
Russ Cox6c196012010-04-05 12:51:09 -0700943 RET
944
Keith Randall14c81432014-06-17 21:59:50 -0700945TEXT runtime·gogetcallerpc(SB),NOSPLIT,$0-16
946 MOVQ p+0(FP),AX // addr of first arg
Keith Randall61dca942014-06-16 23:03:03 -0700947 MOVQ -8(AX),AX // get calling pc
Keith Randall14c81432014-06-17 21:59:50 -0700948 MOVQ AX,ret+8(FP)
Keith Randall61dca942014-06-16 23:03:03 -0700949 RET
950
Keith Randall5a546962013-08-07 10:23:24 -0700951TEXT runtime·setcallerpc(SB),NOSPLIT,$0-16
Russ Cox25f6b022014-08-27 11:32:17 -0400952 MOVQ argp+0(FP),AX // addr of first arg
953 MOVQ pc+8(FP), BX
Russ Cox6c196012010-04-05 12:51:09 -0700954 MOVQ BX, -8(AX) // set calling pc
955 RET
956
Russ Cox25f6b022014-08-27 11:32:17 -0400957TEXT runtime·getcallersp(SB),NOSPLIT,$0-16
958 MOVQ argp+0(FP), AX
959 MOVQ AX, ret+8(FP)
Russ Cox6c196012010-04-05 12:51:09 -0700960 RET
961
Rémy Oudompheng39ffa8b2014-08-26 08:34:46 +0200962// func gogetcallersp(p unsafe.Pointer) uintptr
963TEXT runtime·gogetcallersp(SB),NOSPLIT,$0-16
964 MOVQ p+0(FP),AX // addr of first arg
965 MOVQ AX, ret+8(FP)
966 RET
967
Damian Gryski8e765da2012-02-02 14:09:27 -0500968// int64 runtime·cputicks(void)
Keith Randall5a546962013-08-07 10:23:24 -0700969TEXT runtime·cputicks(SB),NOSPLIT,$0-0
Damian Gryski8e765da2012-02-02 14:09:27 -0500970 RDTSC
971 SHLQ $32, DX
972 ADDQ DX, AX
Russ Cox25f6b022014-08-27 11:32:17 -0400973 MOVQ AX, ret+0(FP)
Damian Gryski8e765da2012-02-02 14:09:27 -0500974 RET
975
Dmitriy Vyukov684de042014-08-21 20:41:09 +0400976TEXT runtime·gocputicks(SB),NOSPLIT,$0-8
977 RDTSC
Dmitriy Vyukovf4485782014-08-22 21:27:25 +0400978 SHLQ $32, DX
979 ADDQ DX, AX
980 MOVQ AX, ret+0(FP)
Dmitriy Vyukov684de042014-08-21 20:41:09 +0400981 RET
982
Keith Randall5a546962013-08-07 10:23:24 -0700983TEXT runtime·stackguard(SB),NOSPLIT,$0-16
Russ Cox9e5db8c2012-03-15 15:22:30 -0400984 MOVQ SP, DX
985 MOVQ DX, sp+0(FP)
986 get_tls(CX)
987 MOVQ g(CX), BX
988 MOVQ g_stackguard(BX), DX
Russ Cox07720b62013-03-22 12:57:55 -0400989 MOVQ DX, limit+8(FP)
Russ Cox9e5db8c2012-03-15 15:22:30 -0400990 RET
991
Russ Cox68b42552010-11-04 14:00:19 -0400992GLOBL runtime·tls0(SB), $64
Keith Randalla5d40242013-03-12 10:47:44 -0700993
994// hash function using AES hardware instructions
Keith Randalla2a97682014-07-31 15:07:05 -0700995TEXT runtime·aeshash(SB),NOSPLIT,$0-32
996 MOVQ p+0(FP), AX // ptr to data
997 MOVQ s+8(FP), CX // size
Keith Randalla5d40242013-03-12 10:47:44 -0700998 JMP runtime·aeshashbody(SB)
999
Keith Randalla2a97682014-07-31 15:07:05 -07001000TEXT runtime·aeshashstr(SB),NOSPLIT,$0-32
1001 MOVQ p+0(FP), AX // ptr to string struct
1002 // s+8(FP) is ignored, it is always sizeof(String)
Keith Randalla5d40242013-03-12 10:47:44 -07001003 MOVQ 8(AX), CX // length of string
1004 MOVQ (AX), AX // string data
1005 JMP runtime·aeshashbody(SB)
1006
1007// AX: data
1008// CX: length
Keith Randalla2a97682014-07-31 15:07:05 -07001009TEXT runtime·aeshashbody(SB),NOSPLIT,$0-32
1010 MOVQ h+16(FP), X0 // seed to low 64 bits of xmm0
Keith Randalla5d40242013-03-12 10:47:44 -07001011 PINSRQ $1, CX, X0 // size to high 64 bits of xmm0
Keith Randalldb53d972013-03-20 14:34:26 -07001012 MOVO runtime·aeskeysched+0(SB), X2
1013 MOVO runtime·aeskeysched+16(SB), X3
Keith Randallee669722013-05-15 09:40:14 -07001014 CMPQ CX, $16
1015 JB aessmall
Keith Randalla5d40242013-03-12 10:47:44 -07001016aesloop:
1017 CMPQ CX, $16
Keith Randallee669722013-05-15 09:40:14 -07001018 JBE aesloopend
Keith Randalla5d40242013-03-12 10:47:44 -07001019 MOVOU (AX), X1
1020 AESENC X2, X0
1021 AESENC X1, X0
1022 SUBQ $16, CX
1023 ADDQ $16, AX
1024 JMP aesloop
Keith Randallee669722013-05-15 09:40:14 -07001025// 1-16 bytes remaining
Keith Randalla5d40242013-03-12 10:47:44 -07001026aesloopend:
Keith Randallee669722013-05-15 09:40:14 -07001027 // This load may overlap with the previous load above.
1028 // We'll hash some bytes twice, but that's ok.
1029 MOVOU -16(AX)(CX*1), X1
1030 JMP partial
1031// 0-15 bytes
1032aessmall:
Keith Randalla5d40242013-03-12 10:47:44 -07001033 TESTQ CX, CX
Keith Randallee669722013-05-15 09:40:14 -07001034 JE finalize // 0 bytes
Keith Randalla5d40242013-03-12 10:47:44 -07001035
Keith Randallee669722013-05-15 09:40:14 -07001036 CMPB AX, $0xf0
1037 JA highpartial
Keith Randalla5d40242013-03-12 10:47:44 -07001038
Keith Randallee669722013-05-15 09:40:14 -07001039 // 16 bytes loaded at this address won't cross
1040 // a page boundary, so we can load it directly.
Keith Randalla5d40242013-03-12 10:47:44 -07001041 MOVOU (AX), X1
1042 ADDQ CX, CX
Russ Cox9aa1e9a2014-08-12 19:51:20 -04001043 MOVQ $masks<>(SB), BP
1044 PAND (BP)(CX*8), X1
Keith Randalla5d40242013-03-12 10:47:44 -07001045 JMP partial
1046highpartial:
Keith Randallee669722013-05-15 09:40:14 -07001047 // address ends in 1111xxxx. Might be up against
Keith Randalla5d40242013-03-12 10:47:44 -07001048 // a page boundary, so load ending at last byte.
1049 // Then shift bytes down using pshufb.
1050 MOVOU -16(AX)(CX*1), X1
1051 ADDQ CX, CX
Russ Cox9aa1e9a2014-08-12 19:51:20 -04001052 MOVQ $shifts<>(SB), BP
1053 PSHUFB (BP)(CX*8), X1
Keith Randalla5d40242013-03-12 10:47:44 -07001054partial:
1055 // incorporate partial block into hash
1056 AESENC X3, X0
1057 AESENC X1, X0
1058finalize:
1059 // finalize hash
1060 AESENC X2, X0
1061 AESENC X3, X0
1062 AESENC X2, X0
Keith Randalla2a97682014-07-31 15:07:05 -07001063 MOVQ X0, res+24(FP)
Keith Randalla5d40242013-03-12 10:47:44 -07001064 RET
1065
Keith Randalla2a97682014-07-31 15:07:05 -07001066TEXT runtime·aeshash32(SB),NOSPLIT,$0-32
1067 MOVQ p+0(FP), AX // ptr to data
1068 // s+8(FP) is ignored, it is always sizeof(int32)
1069 MOVQ h+16(FP), X0 // seed
Keith Randalla5d40242013-03-12 10:47:44 -07001070 PINSRD $2, (AX), X0 // data
Keith Randalldb53d972013-03-20 14:34:26 -07001071 AESENC runtime·aeskeysched+0(SB), X0
1072 AESENC runtime·aeskeysched+16(SB), X0
1073 AESENC runtime·aeskeysched+0(SB), X0
Russ Cox25f6b022014-08-27 11:32:17 -04001074 MOVQ X0, ret+24(FP)
Keith Randalla5d40242013-03-12 10:47:44 -07001075 RET
1076
Keith Randalla2a97682014-07-31 15:07:05 -07001077TEXT runtime·aeshash64(SB),NOSPLIT,$0-32
1078 MOVQ p+0(FP), AX // ptr to data
1079 // s+8(FP) is ignored, it is always sizeof(int64)
1080 MOVQ h+16(FP), X0 // seed
Keith Randalla5d40242013-03-12 10:47:44 -07001081 PINSRQ $1, (AX), X0 // data
Keith Randalldb53d972013-03-20 14:34:26 -07001082 AESENC runtime·aeskeysched+0(SB), X0
1083 AESENC runtime·aeskeysched+16(SB), X0
1084 AESENC runtime·aeskeysched+0(SB), X0
Russ Cox25f6b022014-08-27 11:32:17 -04001085 MOVQ X0, ret+24(FP)
Keith Randalla5d40242013-03-12 10:47:44 -07001086 RET
1087
1088// simple mask to get rid of data in the high part of the register.
Russ Cox9ddfb642013-07-16 16:24:09 -04001089DATA masks<>+0x00(SB)/8, $0x0000000000000000
1090DATA masks<>+0x08(SB)/8, $0x0000000000000000
1091DATA masks<>+0x10(SB)/8, $0x00000000000000ff
1092DATA masks<>+0x18(SB)/8, $0x0000000000000000
1093DATA masks<>+0x20(SB)/8, $0x000000000000ffff
1094DATA masks<>+0x28(SB)/8, $0x0000000000000000
1095DATA masks<>+0x30(SB)/8, $0x0000000000ffffff
1096DATA masks<>+0x38(SB)/8, $0x0000000000000000
1097DATA masks<>+0x40(SB)/8, $0x00000000ffffffff
1098DATA masks<>+0x48(SB)/8, $0x0000000000000000
1099DATA masks<>+0x50(SB)/8, $0x000000ffffffffff
1100DATA masks<>+0x58(SB)/8, $0x0000000000000000
1101DATA masks<>+0x60(SB)/8, $0x0000ffffffffffff
1102DATA masks<>+0x68(SB)/8, $0x0000000000000000
1103DATA masks<>+0x70(SB)/8, $0x00ffffffffffffff
1104DATA masks<>+0x78(SB)/8, $0x0000000000000000
1105DATA masks<>+0x80(SB)/8, $0xffffffffffffffff
1106DATA masks<>+0x88(SB)/8, $0x0000000000000000
1107DATA masks<>+0x90(SB)/8, $0xffffffffffffffff
1108DATA masks<>+0x98(SB)/8, $0x00000000000000ff
1109DATA masks<>+0xa0(SB)/8, $0xffffffffffffffff
1110DATA masks<>+0xa8(SB)/8, $0x000000000000ffff
1111DATA masks<>+0xb0(SB)/8, $0xffffffffffffffff
1112DATA masks<>+0xb8(SB)/8, $0x0000000000ffffff
1113DATA masks<>+0xc0(SB)/8, $0xffffffffffffffff
1114DATA masks<>+0xc8(SB)/8, $0x00000000ffffffff
1115DATA masks<>+0xd0(SB)/8, $0xffffffffffffffff
1116DATA masks<>+0xd8(SB)/8, $0x000000ffffffffff
1117DATA masks<>+0xe0(SB)/8, $0xffffffffffffffff
1118DATA masks<>+0xe8(SB)/8, $0x0000ffffffffffff
1119DATA masks<>+0xf0(SB)/8, $0xffffffffffffffff
1120DATA masks<>+0xf8(SB)/8, $0x00ffffffffffffff
Keith Randall5a546962013-08-07 10:23:24 -07001121GLOBL masks<>(SB),RODATA,$256
Keith Randalla5d40242013-03-12 10:47:44 -07001122
Russ Cox9ddfb642013-07-16 16:24:09 -04001123// these are arguments to pshufb. They move data down from
1124// the high bytes of the register to the low bytes of the register.
1125// index is how many bytes to move.
1126DATA shifts<>+0x00(SB)/8, $0x0000000000000000
1127DATA shifts<>+0x08(SB)/8, $0x0000000000000000
1128DATA shifts<>+0x10(SB)/8, $0xffffffffffffff0f
1129DATA shifts<>+0x18(SB)/8, $0xffffffffffffffff
1130DATA shifts<>+0x20(SB)/8, $0xffffffffffff0f0e
1131DATA shifts<>+0x28(SB)/8, $0xffffffffffffffff
1132DATA shifts<>+0x30(SB)/8, $0xffffffffff0f0e0d
1133DATA shifts<>+0x38(SB)/8, $0xffffffffffffffff
1134DATA shifts<>+0x40(SB)/8, $0xffffffff0f0e0d0c
1135DATA shifts<>+0x48(SB)/8, $0xffffffffffffffff
1136DATA shifts<>+0x50(SB)/8, $0xffffff0f0e0d0c0b
1137DATA shifts<>+0x58(SB)/8, $0xffffffffffffffff
1138DATA shifts<>+0x60(SB)/8, $0xffff0f0e0d0c0b0a
1139DATA shifts<>+0x68(SB)/8, $0xffffffffffffffff
1140DATA shifts<>+0x70(SB)/8, $0xff0f0e0d0c0b0a09
1141DATA shifts<>+0x78(SB)/8, $0xffffffffffffffff
1142DATA shifts<>+0x80(SB)/8, $0x0f0e0d0c0b0a0908
1143DATA shifts<>+0x88(SB)/8, $0xffffffffffffffff
1144DATA shifts<>+0x90(SB)/8, $0x0e0d0c0b0a090807
1145DATA shifts<>+0x98(SB)/8, $0xffffffffffffff0f
1146DATA shifts<>+0xa0(SB)/8, $0x0d0c0b0a09080706
1147DATA shifts<>+0xa8(SB)/8, $0xffffffffffff0f0e
1148DATA shifts<>+0xb0(SB)/8, $0x0c0b0a0908070605
1149DATA shifts<>+0xb8(SB)/8, $0xffffffffff0f0e0d
1150DATA shifts<>+0xc0(SB)/8, $0x0b0a090807060504
1151DATA shifts<>+0xc8(SB)/8, $0xffffffff0f0e0d0c
1152DATA shifts<>+0xd0(SB)/8, $0x0a09080706050403
1153DATA shifts<>+0xd8(SB)/8, $0xffffff0f0e0d0c0b
1154DATA shifts<>+0xe0(SB)/8, $0x0908070605040302
1155DATA shifts<>+0xe8(SB)/8, $0xffff0f0e0d0c0b0a
1156DATA shifts<>+0xf0(SB)/8, $0x0807060504030201
1157DATA shifts<>+0xf8(SB)/8, $0xff0f0e0d0c0b0a09
Keith Randall5a546962013-08-07 10:23:24 -07001158GLOBL shifts<>(SB),RODATA,$256
Keith Randall3d5daa22013-04-02 16:26:15 -07001159
Keith Randall7aa4e5a2014-08-07 14:52:55 -07001160TEXT runtime·memeq(SB),NOSPLIT,$0-25
Keith Randall0c6b55e2014-07-16 14:16:19 -07001161 MOVQ a+0(FP), SI
1162 MOVQ b+8(FP), DI
1163 MOVQ size+16(FP), BX
1164 CALL runtime·memeqbody(SB)
1165 MOVB AX, ret+24(FP)
1166 RET
1167
Keith Randallb36ed902014-06-16 21:00:37 -07001168// eqstring tests whether two strings are equal.
1169// See runtime_test.go:eqstring_generic for
Josh Bleecher Snyder339a24d2014-08-19 08:50:35 -07001170// equivalent Go code.
Keith Randallb36ed902014-06-16 21:00:37 -07001171TEXT runtime·eqstring(SB),NOSPLIT,$0-33
1172 MOVQ s1len+8(FP), AX
1173 MOVQ s2len+24(FP), BX
1174 CMPQ AX, BX
1175 JNE different
1176 MOVQ s1str+0(FP), SI
1177 MOVQ s2str+16(FP), DI
1178 CMPQ SI, DI
1179 JEQ same
1180 CALL runtime·memeqbody(SB)
1181 MOVB AX, v+32(FP)
1182 RET
1183same:
1184 MOVB $1, v+32(FP)
1185 RET
1186different:
1187 MOVB $0, v+32(FP)
1188 RET
1189
Keith Randall3d5daa22013-04-02 16:26:15 -07001190// a in SI
1191// b in DI
1192// count in BX
Keith Randall5a546962013-08-07 10:23:24 -07001193TEXT runtime·memeqbody(SB),NOSPLIT,$0-0
Keith Randall3d5daa22013-04-02 16:26:15 -07001194 XORQ AX, AX
1195
1196 CMPQ BX, $8
1197 JB small
1198
1199 // 64 bytes at a time using xmm registers
1200hugeloop:
1201 CMPQ BX, $64
1202 JB bigloop
1203 MOVOU (SI), X0
1204 MOVOU (DI), X1
1205 MOVOU 16(SI), X2
1206 MOVOU 16(DI), X3
1207 MOVOU 32(SI), X4
1208 MOVOU 32(DI), X5
1209 MOVOU 48(SI), X6
1210 MOVOU 48(DI), X7
1211 PCMPEQB X1, X0
1212 PCMPEQB X3, X2
1213 PCMPEQB X5, X4
1214 PCMPEQB X7, X6
1215 PAND X2, X0
1216 PAND X6, X4
1217 PAND X4, X0
1218 PMOVMSKB X0, DX
1219 ADDQ $64, SI
1220 ADDQ $64, DI
1221 SUBQ $64, BX
1222 CMPL DX, $0xffff
1223 JEQ hugeloop
1224 RET
1225
1226 // 8 bytes at a time using 64-bit register
1227bigloop:
1228 CMPQ BX, $8
1229 JBE leftover
1230 MOVQ (SI), CX
1231 MOVQ (DI), DX
1232 ADDQ $8, SI
1233 ADDQ $8, DI
1234 SUBQ $8, BX
1235 CMPQ CX, DX
1236 JEQ bigloop
1237 RET
1238
1239 // remaining 0-8 bytes
1240leftover:
1241 MOVQ -8(SI)(BX*1), CX
1242 MOVQ -8(DI)(BX*1), DX
1243 CMPQ CX, DX
1244 SETEQ AX
1245 RET
1246
1247small:
1248 CMPQ BX, $0
1249 JEQ equal
1250
1251 LEAQ 0(BX*8), CX
1252 NEGQ CX
1253
1254 CMPB SI, $0xf8
1255 JA si_high
1256
1257 // load at SI won't cross a page boundary.
1258 MOVQ (SI), SI
1259 JMP si_finish
1260si_high:
1261 // address ends in 11111xxx. Load up to bytes we want, move to correct position.
1262 MOVQ -8(SI)(BX*1), SI
1263 SHRQ CX, SI
1264si_finish:
1265
1266 // same for DI.
1267 CMPB DI, $0xf8
1268 JA di_high
1269 MOVQ (DI), DI
1270 JMP di_finish
1271di_high:
1272 MOVQ -8(DI)(BX*1), DI
1273 SHRQ CX, DI
1274di_finish:
1275
1276 SUBQ SI, DI
1277 SHLQ CX, DI
1278equal:
1279 SETEQ AX
1280 RET
Keith Randallb3946dc2013-05-14 16:05:51 -07001281
Keith Randall5a546962013-08-07 10:23:24 -07001282TEXT runtime·cmpstring(SB),NOSPLIT,$0-40
Russ Cox25f6b022014-08-27 11:32:17 -04001283 MOVQ s1_base+0(FP), SI
1284 MOVQ s1_len+8(FP), BX
1285 MOVQ s2_base+16(FP), DI
1286 MOVQ s2_len+24(FP), DX
Keith Randallb3946dc2013-05-14 16:05:51 -07001287 CALL runtime·cmpbody(SB)
Russ Cox25f6b022014-08-27 11:32:17 -04001288 MOVQ AX, ret+32(FP)
Keith Randallb3946dc2013-05-14 16:05:51 -07001289 RET
1290
Keith Randall5a546962013-08-07 10:23:24 -07001291TEXT bytes·Compare(SB),NOSPLIT,$0-56
Keith Randallb3946dc2013-05-14 16:05:51 -07001292 MOVQ s1+0(FP), SI
1293 MOVQ s1+8(FP), BX
1294 MOVQ s2+24(FP), DI
1295 MOVQ s2+32(FP), DX
1296 CALL runtime·cmpbody(SB)
1297 MOVQ AX, res+48(FP)
1298 RET
1299
1300// input:
1301// SI = a
1302// DI = b
1303// BX = alen
1304// DX = blen
1305// output:
1306// AX = 1/0/-1
Keith Randall5a546962013-08-07 10:23:24 -07001307TEXT runtime·cmpbody(SB),NOSPLIT,$0-0
Keith Randallb3946dc2013-05-14 16:05:51 -07001308 CMPQ SI, DI
1309 JEQ cmp_allsame
1310 CMPQ BX, DX
1311 MOVQ DX, BP
1312 CMOVQLT BX, BP // BP = min(alen, blen) = # of bytes to compare
1313 CMPQ BP, $8
1314 JB cmp_small
1315
1316cmp_loop:
1317 CMPQ BP, $16
1318 JBE cmp_0through16
1319 MOVOU (SI), X0
1320 MOVOU (DI), X1
1321 PCMPEQB X0, X1
1322 PMOVMSKB X1, AX
1323 XORQ $0xffff, AX // convert EQ to NE
1324 JNE cmp_diff16 // branch if at least one byte is not equal
1325 ADDQ $16, SI
1326 ADDQ $16, DI
1327 SUBQ $16, BP
1328 JMP cmp_loop
1329
1330 // AX = bit mask of differences
1331cmp_diff16:
1332 BSFQ AX, BX // index of first byte that differs
1333 XORQ AX, AX
1334 MOVB (SI)(BX*1), CX
1335 CMPB CX, (DI)(BX*1)
1336 SETHI AX
1337 LEAQ -1(AX*2), AX // convert 1/0 to +1/-1
1338 RET
1339
1340 // 0 through 16 bytes left, alen>=8, blen>=8
1341cmp_0through16:
1342 CMPQ BP, $8
1343 JBE cmp_0through8
1344 MOVQ (SI), AX
1345 MOVQ (DI), CX
1346 CMPQ AX, CX
1347 JNE cmp_diff8
1348cmp_0through8:
1349 MOVQ -8(SI)(BP*1), AX
1350 MOVQ -8(DI)(BP*1), CX
1351 CMPQ AX, CX
1352 JEQ cmp_allsame
1353
1354 // AX and CX contain parts of a and b that differ.
1355cmp_diff8:
1356 BSWAPQ AX // reverse order of bytes
1357 BSWAPQ CX
1358 XORQ AX, CX
1359 BSRQ CX, CX // index of highest bit difference
1360 SHRQ CX, AX // move a's bit to bottom
1361 ANDQ $1, AX // mask bit
1362 LEAQ -1(AX*2), AX // 1/0 => +1/-1
1363 RET
1364
1365 // 0-7 bytes in common
1366cmp_small:
1367 LEAQ (BP*8), CX // bytes left -> bits left
1368 NEGQ CX // - bits lift (== 64 - bits left mod 64)
1369 JEQ cmp_allsame
1370
1371 // load bytes of a into high bytes of AX
1372 CMPB SI, $0xf8
1373 JA cmp_si_high
1374 MOVQ (SI), SI
1375 JMP cmp_si_finish
1376cmp_si_high:
1377 MOVQ -8(SI)(BP*1), SI
1378 SHRQ CX, SI
1379cmp_si_finish:
1380 SHLQ CX, SI
1381
1382 // load bytes of b in to high bytes of BX
1383 CMPB DI, $0xf8
1384 JA cmp_di_high
1385 MOVQ (DI), DI
1386 JMP cmp_di_finish
1387cmp_di_high:
1388 MOVQ -8(DI)(BP*1), DI
1389 SHRQ CX, DI
1390cmp_di_finish:
1391 SHLQ CX, DI
1392
1393 BSWAPQ SI // reverse order of bytes
1394 BSWAPQ DI
1395 XORQ SI, DI // find bit differences
1396 JEQ cmp_allsame
1397 BSRQ DI, CX // index of highest bit difference
1398 SHRQ CX, SI // move a's bit to bottom
1399 ANDQ $1, SI // mask bit
1400 LEAQ -1(SI*2), AX // 1/0 => +1/-1
1401 RET
1402
1403cmp_allsame:
1404 XORQ AX, AX
1405 XORQ CX, CX
1406 CMPQ BX, DX
1407 SETGT AX // 1 if alen > blen
1408 SETEQ CX // 1 if alen == blen
1409 LEAQ -1(CX)(AX*2), AX // 1,0,-1 result
1410 RET
Brad Fitzpatricke2a1bd62013-08-01 16:11:19 -07001411
Keith Randall5a546962013-08-07 10:23:24 -07001412TEXT bytes·IndexByte(SB),NOSPLIT,$0
Brad Fitzpatricke2a1bd62013-08-01 16:11:19 -07001413 MOVQ s+0(FP), SI
1414 MOVQ s_len+8(FP), BX
1415 MOVB c+24(FP), AL
Brad Fitzpatrick598c7892013-08-05 15:04:05 -07001416 CALL runtime·indexbytebody(SB)
1417 MOVQ AX, ret+32(FP)
1418 RET
1419
Keith Randall5a546962013-08-07 10:23:24 -07001420TEXT strings·IndexByte(SB),NOSPLIT,$0
Brad Fitzpatrick598c7892013-08-05 15:04:05 -07001421 MOVQ s+0(FP), SI
1422 MOVQ s_len+8(FP), BX
1423 MOVB c+16(FP), AL
1424 CALL runtime·indexbytebody(SB)
1425 MOVQ AX, ret+24(FP)
1426 RET
1427
1428// input:
1429// SI: data
1430// BX: data len
1431// AL: byte sought
1432// output:
1433// AX
Keith Randall5a546962013-08-07 10:23:24 -07001434TEXT runtime·indexbytebody(SB),NOSPLIT,$0
Brad Fitzpatricke2a1bd62013-08-01 16:11:19 -07001435 MOVQ SI, DI
1436
1437 CMPQ BX, $16
1438 JLT indexbyte_small
1439
1440 // round up to first 16-byte boundary
1441 TESTQ $15, SI
1442 JZ aligned
1443 MOVQ SI, CX
1444 ANDQ $~15, CX
1445 ADDQ $16, CX
1446
1447 // search the beginning
1448 SUBQ SI, CX
1449 REPN; SCASB
1450 JZ success
1451
1452// DI is 16-byte aligned; get ready to search using SSE instructions
1453aligned:
1454 // round down to last 16-byte boundary
1455 MOVQ BX, R11
1456 ADDQ SI, R11
1457 ANDQ $~15, R11
1458
1459 // shuffle X0 around so that each byte contains c
1460 MOVD AX, X0
1461 PUNPCKLBW X0, X0
1462 PUNPCKLBW X0, X0
1463 PSHUFL $0, X0, X0
1464 JMP condition
1465
1466sse:
1467 // move the next 16-byte chunk of the buffer into X1
1468 MOVO (DI), X1
1469 // compare bytes in X0 to X1
1470 PCMPEQB X0, X1
1471 // take the top bit of each byte in X1 and put the result in DX
1472 PMOVMSKB X1, DX
1473 TESTL DX, DX
1474 JNZ ssesuccess
1475 ADDQ $16, DI
1476
1477condition:
1478 CMPQ DI, R11
1479 JLT sse
1480
1481 // search the end
1482 MOVQ SI, CX
1483 ADDQ BX, CX
1484 SUBQ R11, CX
1485 // if CX == 0, the zero flag will be set and we'll end up
1486 // returning a false success
1487 JZ failure
1488 REPN; SCASB
1489 JZ success
1490
1491failure:
Brad Fitzpatrick598c7892013-08-05 15:04:05 -07001492 MOVQ $-1, AX
Brad Fitzpatricke2a1bd62013-08-01 16:11:19 -07001493 RET
1494
1495// handle for lengths < 16
1496indexbyte_small:
1497 MOVQ BX, CX
1498 REPN; SCASB
1499 JZ success
Brad Fitzpatrick598c7892013-08-05 15:04:05 -07001500 MOVQ $-1, AX
Brad Fitzpatricke2a1bd62013-08-01 16:11:19 -07001501 RET
1502
1503// we've found the chunk containing the byte
1504// now just figure out which specific byte it is
1505ssesuccess:
1506 // get the index of the least significant set bit
1507 BSFW DX, DX
1508 SUBQ SI, DI
1509 ADDQ DI, DX
Brad Fitzpatrick598c7892013-08-05 15:04:05 -07001510 MOVQ DX, AX
Brad Fitzpatricke2a1bd62013-08-01 16:11:19 -07001511 RET
1512
1513success:
1514 SUBQ SI, DI
1515 SUBL $1, DI
Brad Fitzpatrick598c7892013-08-05 15:04:05 -07001516 MOVQ DI, AX
Brad Fitzpatricke2a1bd62013-08-01 16:11:19 -07001517 RET
1518
Keith Randall5a546962013-08-07 10:23:24 -07001519TEXT bytes·Equal(SB),NOSPLIT,$0-49
Brad Fitzpatricke2a1bd62013-08-01 16:11:19 -07001520 MOVQ a_len+8(FP), BX
1521 MOVQ b_len+32(FP), CX
1522 XORQ AX, AX
1523 CMPQ BX, CX
1524 JNE eqret
1525 MOVQ a+0(FP), SI
1526 MOVQ b+24(FP), DI
1527 CALL runtime·memeqbody(SB)
1528eqret:
1529 MOVB AX, ret+48(FP)
1530 RET
Keith Randall6c7cbf02014-04-01 12:51:02 -07001531
1532// A Duff's device for zeroing memory.
1533// The compiler jumps to computed addresses within
1534// this routine to zero chunks of memory. Do not
1535// change this code without also changing the code
1536// in ../../cmd/6g/ggen.c:clearfat.
1537// AX: zero
1538// DI: ptr to memory to be zeroed
1539// DI is updated as a side effect.
1540TEXT runtime·duffzero(SB), NOSPLIT, $0-0
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 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 RET
1670
1671// A Duff's device for copying memory.
1672// The compiler jumps to computed addresses within
1673// this routine to copy chunks of memory. Source
1674// and destination must not overlap. Do not
1675// change this code without also changing the code
1676// in ../../cmd/6g/cgen.c:sgen.
1677// SI: ptr to source memory
1678// DI: ptr to destination memory
1679// SI and DI are updated as a side effect.
1680
1681// NOTE: this is equivalent to a sequence of MOVSQ but
1682// for some reason that is 3.5x slower than this code.
1683// The STOSQ above seem fine, though.
1684TEXT runtime·duffcopy(SB), NOSPLIT, $0-0
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 MOVQ (SI),CX
2291 ADDQ $8,SI
2292 MOVQ CX,(DI)
2293 ADDQ $8,DI
2294
2295 MOVQ (SI),CX
2296 ADDQ $8,SI
2297 MOVQ CX,(DI)
2298 ADDQ $8,DI
2299
2300 MOVQ (SI),CX
2301 ADDQ $8,SI
2302 MOVQ CX,(DI)
2303 ADDQ $8,DI
2304
2305 MOVQ (SI),CX
2306 ADDQ $8,SI
2307 MOVQ CX,(DI)
2308 ADDQ $8,DI
2309
2310 MOVQ (SI),CX
2311 ADDQ $8,SI
2312 MOVQ CX,(DI)
2313 ADDQ $8,DI
2314
2315 MOVQ (SI),CX
2316 ADDQ $8,SI
2317 MOVQ CX,(DI)
2318 ADDQ $8,DI
2319
2320 MOVQ (SI),CX
2321 ADDQ $8,SI
2322 MOVQ CX,(DI)
2323 ADDQ $8,DI
2324
2325 RET
Dmitriy Vyukov350a8fc2014-05-02 17:32:42 +01002326
2327TEXT runtime·timenow(SB), NOSPLIT, $0-0
2328 JMP time·now(SB)
Keith Randall0c6b55e2014-07-16 14:16:19 -07002329
2330TEXT runtime·fastrand2(SB), NOSPLIT, $0-4
2331 get_tls(CX)
2332 MOVQ g(CX), AX
2333 MOVQ g_m(AX), AX
2334 MOVL m_fastrand(AX), DX
2335 ADDL DX, DX
2336 MOVL DX, BX
2337 XORL $0x88888eef, DX
2338 CMOVLMI BX, DX
2339 MOVL DX, m_fastrand(AX)
2340 MOVL DX, ret+0(FP)
2341 RET