blob: f09e5ae250e16d4843310385da3b6b3b59b5a1ab [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 Cox15ced2d2014-11-11 17:06:22 -05005#include "go_asm.h"
6#include "go_tls.h"
Russ Cox9ddfb642013-07-16 16:24:09 -04007#include "funcdata.h"
Russ Coxcb040d52014-09-04 23:05:18 -04008#include "textflag.h"
Rob Pike8e82a672008-06-30 11:50:36 -07009
Russ Cox7ba41e92014-09-03 11:11:16 -040010TEXT runtime·rt0_go(SB),NOSPLIT,$0
Rob Pike8e82a672008-06-30 11:50:36 -070011 // copy arguments forward on an even stack
Russ Cox36b414f2013-03-06 15:03:04 -050012 MOVQ DI, AX // argc
13 MOVQ SI, BX // argv
Rob Pike8e82a672008-06-30 11:50:36 -070014 SUBQ $(4*8+7), SP // 2args 2auto
Ian Lance Taylora4f8d362010-04-09 14:15:15 -070015 ANDQ $~15, SP
Rob Pike8e82a672008-06-30 11:50:36 -070016 MOVQ AX, 16(SP)
17 MOVQ BX, 24(SP)
Dmitriy Vyukov428062d2011-12-07 16:53:17 +030018
19 // create istack out of the given (operating system) stack.
Russ Coxf8d49b52013-02-28 16:24:38 -050020 // _cgo_init may update stackguard.
Dmitriy Vyukov428062d2011-12-07 16:53:17 +030021 MOVQ $runtime·g0(SB), DI
Alex Brainman8d6958f2012-01-20 12:59:44 +110022 LEAQ (-64*1024+104)(SP), BX
Russ Coxe6d35112015-01-05 16:29:21 +000023 MOVQ BX, g_stackguard0(DI)
24 MOVQ BX, g_stackguard1(DI)
Russ Cox15b76ad2014-09-09 13:39:57 -040025 MOVQ BX, (g_stack+stack_lo)(DI)
26 MOVQ SP, (g_stack+stack_hi)(DI)
Rob Pike8e82a672008-06-30 11:50:36 -070027
Keith Randalla5d40242013-03-12 10:47:44 -070028 // find out information about the processor we're on
29 MOVQ $0, AX
30 CPUID
31 CMPQ AX, $0
32 JE nocpuinfo
33 MOVQ $1, AX
34 CPUID
35 MOVL CX, runtime·cpuid_ecx(SB)
36 MOVL DX, runtime·cpuid_edx(SB)
37nocpuinfo:
38
Russ Coxf8d49b52013-02-28 16:24:38 -050039 // if there is an _cgo_init, call it.
40 MOVQ _cgo_init(SB), AX
Ian Lance Taylora4f8d362010-04-09 14:15:15 -070041 TESTQ AX, AX
Russ Coxe473f422010-08-04 17:50:22 -070042 JZ needtls
Alex Brainman8d6958f2012-01-20 12:59:44 +110043 // g0 already in DI
44 MOVQ DI, CX // Win64 uses CX for first parameter
Russ Cox89f185f2014-06-26 11:54:39 -040045 MOVQ $setg_gcc<>(SB), SI
Alex Brainman8d6958f2012-01-20 12:59:44 +110046 CALL AX
Russ Cox15b76ad2014-09-09 13:39:57 -040047
Dmitriy Vyukovf5becf42013-06-03 12:28:24 +040048 // update stackguard after _cgo_init
49 MOVQ $runtime·g0(SB), CX
Russ Cox15b76ad2014-09-09 13:39:57 -040050 MOVQ (g_stack+stack_lo)(CX), AX
Russ Cox15ced2d2014-11-11 17:06:22 -050051 ADDQ $const__StackGuard, AX
Russ Coxe6d35112015-01-05 16:29:21 +000052 MOVQ AX, g_stackguard0(CX)
53 MOVQ AX, g_stackguard1(CX)
Russ Cox15b76ad2014-09-09 13:39:57 -040054
Wei Guangjing9f636592011-07-19 10:47:33 -040055 CMPL runtime·iswindows(SB), $0
56 JEQ ok
Russ Coxe473f422010-08-04 17:50:22 -070057needtls:
Akshat Kumara72bebf2012-08-31 13:21:13 -040058 // skip TLS setup on Plan 9
59 CMPL runtime·isplan9(SB), $1
60 JEQ ok
Aram Hăvărneanua46b4342014-01-17 17:58:10 +130061 // skip TLS setup on Solaris
62 CMPL runtime·issolaris(SB), $1
63 JEQ ok
Akshat Kumara72bebf2012-08-31 13:21:13 -040064
Russ Cox68b42552010-11-04 14:00:19 -040065 LEAQ runtime·tls0(SB), DI
66 CALL runtime·settls(SB)
Russ Coxe473f422010-08-04 17:50:22 -070067
68 // store through it, to make sure it works
69 get_tls(BX)
70 MOVQ $0x123, g(BX)
Russ Cox68b42552010-11-04 14:00:19 -040071 MOVQ runtime·tls0(SB), AX
Russ Coxe473f422010-08-04 17:50:22 -070072 CMPQ AX, $0x123
73 JEQ 2(PC)
74 MOVL AX, 0 // abort
75ok:
76 // set the per-goroutine and per-mach "registers"
77 get_tls(BX)
Russ Cox68b42552010-11-04 14:00:19 -040078 LEAQ runtime·g0(SB), CX
Russ Coxe473f422010-08-04 17:50:22 -070079 MOVQ CX, g(BX)
Russ Cox68b42552010-11-04 14:00:19 -040080 LEAQ runtime·m0(SB), AX
Russ Coxe473f422010-08-04 17:50:22 -070081
82 // save m->g0 = g0
83 MOVQ CX, m_g0(AX)
Russ Cox89f185f2014-06-26 11:54:39 -040084 // save m0 to g0->m
85 MOVQ AX, g_m(CX)
Rob Pike8e82a672008-06-30 11:50:36 -070086
Ken Thompson8f53bc02008-12-15 15:07:35 -080087 CLD // convention is D is always left cleared
Russ Cox68b42552010-11-04 14:00:19 -040088 CALL runtime·check(SB)
Rob Pike8e82a672008-06-30 11:50:36 -070089
Rob Pike8e82a672008-06-30 11:50:36 -070090 MOVL 16(SP), AX // copy argc
91 MOVL AX, 0(SP)
92 MOVQ 24(SP), AX // copy argv
93 MOVQ AX, 8(SP)
Russ Cox68b42552010-11-04 14:00:19 -040094 CALL runtime·args(SB)
95 CALL runtime·osinit(SB)
96 CALL runtime·schedinit(SB)
Russ Coxf7f63292008-08-05 14:21:42 -070097
Ken Thompson751ce3a2008-07-11 19:16:39 -070098 // create a new goroutine to start program
Austin Clements20a6ff72015-01-27 18:29:02 -050099 MOVQ $runtime·main·f(SB), AX // entry
100 PUSHQ AX
Russ Cox7343e032009-06-17 15:12:16 -0700101 PUSHQ $0 // arg size
Russ Cox68b42552010-11-04 14:00:19 -0400102 CALL runtime·newproc(SB)
Russ Coxebd1eef2008-09-22 13:47:59 -0700103 POPQ AX
104 POPQ AX
Russ Cox79e1db22008-12-04 08:30:54 -0800105
Russ Coxebd1eef2008-09-22 13:47:59 -0700106 // start this M
Russ Cox68b42552010-11-04 14:00:19 -0400107 CALL runtime·mstart(SB)
Rob Pike8e82a672008-06-30 11:50:36 -0700108
Russ Cox36aa7d42012-03-08 14:03:56 -0500109 MOVL $0xf1, 0xf1 // crash
Rob Pike8e82a672008-06-30 11:50:36 -0700110 RET
111
Russ Cox1903ad72013-02-21 17:01:13 -0500112DATA runtime·main·f+0(SB)/8,$runtime·main(SB)
Keith Randall5a546962013-08-07 10:23:24 -0700113GLOBL runtime·main·f(SB),RODATA,$8
Russ Cox1903ad72013-02-21 17:01:13 -0500114
Keith Randall5a546962013-08-07 10:23:24 -0700115TEXT runtime·breakpoint(SB),NOSPLIT,$0-0
Ken Thompson751ce3a2008-07-11 19:16:39 -0700116 BYTE $0xcc
Rob Pike8e82a672008-06-30 11:50:36 -0700117 RET
118
Keith Randall5a546962013-08-07 10:23:24 -0700119TEXT runtime·asminit(SB),NOSPLIT,$0-0
Russ Cox1707a992012-02-14 01:23:15 -0500120 // No per-thread init.
121 RET
122
Ken Thompson751ce3a2008-07-11 19:16:39 -0700123/*
124 * go-routine
125 */
Rob Piked3204ef2008-06-30 14:39:47 -0700126
Russ Coxf9ca3b52011-03-07 10:37:42 -0500127// void gosave(Gobuf*)
Russ Cox7343e032009-06-17 15:12:16 -0700128// save state in Gobuf; setjmp
Keith Randall5a546962013-08-07 10:23:24 -0700129TEXT runtime·gosave(SB), NOSPLIT, $0-8
Russ Cox25f6b022014-08-27 11:32:17 -0400130 MOVQ buf+0(FP), AX // gobuf
131 LEAQ buf+0(FP), BX // caller's SP
Russ Cox7343e032009-06-17 15:12:16 -0700132 MOVQ BX, gobuf_sp(AX)
133 MOVQ 0(SP), BX // caller's PC
134 MOVQ BX, gobuf_pc(AX)
Russ Coxd67e7e32013-06-12 15:22:26 -0400135 MOVQ $0, gobuf_ret(AX)
136 MOVQ $0, gobuf_ctxt(AX)
Austin Clements3c0fee12015-01-14 11:09:50 -0500137 MOVQ BP, gobuf_bp(AX)
Russ Coxe473f422010-08-04 17:50:22 -0700138 get_tls(CX)
139 MOVQ g(CX), BX
140 MOVQ BX, gobuf_g(AX)
Ken Thompson751ce3a2008-07-11 19:16:39 -0700141 RET
142
Ian Lance Taylor06272482013-06-12 15:05:10 -0700143// void gogo(Gobuf*)
Russ Cox7343e032009-06-17 15:12:16 -0700144// restore state from Gobuf; longjmp
Keith Randall5a546962013-08-07 10:23:24 -0700145TEXT runtime·gogo(SB), NOSPLIT, $0-8
Russ Cox25f6b022014-08-27 11:32:17 -0400146 MOVQ buf+0(FP), BX // gobuf
Russ Coxe473f422010-08-04 17:50:22 -0700147 MOVQ gobuf_g(BX), DX
148 MOVQ 0(DX), CX // make sure g != nil
149 get_tls(CX)
150 MOVQ DX, g(CX)
Russ Cox7343e032009-06-17 15:12:16 -0700151 MOVQ gobuf_sp(BX), SP // restore SP
Russ Coxd67e7e32013-06-12 15:22:26 -0400152 MOVQ gobuf_ret(BX), AX
153 MOVQ gobuf_ctxt(BX), DX
Austin Clements3c0fee12015-01-14 11:09:50 -0500154 MOVQ gobuf_bp(BX), BP
Russ Coxd67e7e32013-06-12 15:22:26 -0400155 MOVQ $0, gobuf_sp(BX) // clear to help garbage collector
156 MOVQ $0, gobuf_ret(BX)
157 MOVQ $0, gobuf_ctxt(BX)
Austin Clements3c0fee12015-01-14 11:09:50 -0500158 MOVQ $0, gobuf_bp(BX)
Russ Cox7343e032009-06-17 15:12:16 -0700159 MOVQ gobuf_pc(BX), BX
160 JMP BX
161
Russ Cox012ceed2014-09-03 11:35:22 -0400162// func mcall(fn func(*g))
Russ Coxf9ca3b52011-03-07 10:37:42 -0500163// Switch to m->g0's stack, call fn(g).
Russ Cox370276a2011-04-27 23:21:12 -0400164// Fn must never return. It should gogo(&g->sched)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500165// to keep running g.
Keith Randall5a546962013-08-07 10:23:24 -0700166TEXT runtime·mcall(SB), NOSPLIT, $0-8
Russ Coxf9ca3b52011-03-07 10:37:42 -0500167 MOVQ fn+0(FP), DI
168
169 get_tls(CX)
Russ Cox528534c2013-06-05 07:16:53 -0400170 MOVQ g(CX), AX // save state in g->sched
Russ Coxf9ca3b52011-03-07 10:37:42 -0500171 MOVQ 0(SP), BX // caller's PC
172 MOVQ BX, (g_sched+gobuf_pc)(AX)
Russ Cox25f6b022014-08-27 11:32:17 -0400173 LEAQ fn+0(FP), BX // caller's SP
Russ Coxf9ca3b52011-03-07 10:37:42 -0500174 MOVQ BX, (g_sched+gobuf_sp)(AX)
175 MOVQ AX, (g_sched+gobuf_g)(AX)
Austin Clements3c0fee12015-01-14 11:09:50 -0500176 MOVQ BP, (g_sched+gobuf_bp)(AX)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500177
178 // switch to m->g0 & its stack, call fn
Russ Cox89f185f2014-06-26 11:54:39 -0400179 MOVQ g(CX), BX
180 MOVQ g_m(BX), BX
Russ Coxf9ca3b52011-03-07 10:37:42 -0500181 MOVQ m_g0(BX), SI
182 CMPQ SI, AX // if g == m->g0 call badmcall
Russ Cox9ddfb642013-07-16 16:24:09 -0400183 JNE 3(PC)
Keith Randall32b770b2013-08-29 15:53:34 -0700184 MOVQ $runtime·badmcall(SB), AX
185 JMP AX
Russ Coxf9ca3b52011-03-07 10:37:42 -0500186 MOVQ SI, g(CX) // g = m->g0
Russ Cox528534c2013-06-05 07:16:53 -0400187 MOVQ (g_sched+gobuf_sp)(SI), SP // sp = m->g0->sched.sp
Russ Coxf9ca3b52011-03-07 10:37:42 -0500188 PUSHQ AX
Russ Cox012ceed2014-09-03 11:35:22 -0400189 MOVQ DI, DX
190 MOVQ 0(DI), DI
Russ Coxf9ca3b52011-03-07 10:37:42 -0500191 CALL DI
192 POPQ AX
Keith Randall32b770b2013-08-29 15:53:34 -0700193 MOVQ $runtime·badmcall2(SB), AX
194 JMP AX
Russ Coxf9ca3b52011-03-07 10:37:42 -0500195 RET
196
Russ Cox656be312014-11-12 14:54:31 -0500197// systemstack_switch is a dummy routine that systemstack leaves at the bottom
Keith Randall4aa50432014-07-30 09:01:52 -0700198// of the G stack. We need to distinguish the routine that
199// lives at the bottom of the G stack from the one that lives
Russ Cox656be312014-11-12 14:54:31 -0500200// at the top of the system stack because the one at the top of
201// the system stack terminates the stack walk (see topofstack()).
202TEXT runtime·systemstack_switch(SB), NOSPLIT, $0-0
Keith Randall4aa50432014-07-30 09:01:52 -0700203 RET
204
Russ Cox656be312014-11-12 14:54:31 -0500205// func systemstack(fn func())
206TEXT runtime·systemstack(SB), NOSPLIT, $0-8
207 MOVQ fn+0(FP), DI // DI = fn
Russ Cox1d550b82014-09-11 12:08:30 -0400208 get_tls(CX)
209 MOVQ g(CX), AX // AX = g
210 MOVQ g_m(AX), BX // BX = m
Russ Cox656be312014-11-12 14:54:31 -0500211
Russ Cox1d550b82014-09-11 12:08:30 -0400212 MOVQ m_gsignal(BX), DX // DX = gsignal
213 CMPQ AX, DX
Russ Cox656be312014-11-12 14:54:31 -0500214 JEQ noswitch
Russ Cox32ecf572014-09-04 00:10:10 -0400215
Keith Randall4aa50432014-07-30 09:01:52 -0700216 MOVQ m_g0(BX), DX // DX = g0
217 CMPQ AX, DX
Russ Cox656be312014-11-12 14:54:31 -0500218 JEQ noswitch
Keith Randall4aa50432014-07-30 09:01:52 -0700219
Austin Clements20a6ff72015-01-27 18:29:02 -0500220 MOVQ m_curg(BX), R8
221 CMPQ AX, R8
Russ Cox656be312014-11-12 14:54:31 -0500222 JEQ switch
Russ Cox32ecf572014-09-04 00:10:10 -0400223
Russ Cox656be312014-11-12 14:54:31 -0500224 // Bad: g is not gsignal, not g0, not curg. What is it?
225 MOVQ $runtime·badsystemstack(SB), AX
Russ Cox32ecf572014-09-04 00:10:10 -0400226 CALL AX
227
Russ Cox656be312014-11-12 14:54:31 -0500228switch:
Keith Randall4aa50432014-07-30 09:01:52 -0700229 // save our state in g->sched. Pretend to
Russ Cox656be312014-11-12 14:54:31 -0500230 // be systemstack_switch if the G stack is scanned.
Austin Clements20a6ff72015-01-27 18:29:02 -0500231 MOVQ $runtime·systemstack_switch(SB), SI
232 MOVQ SI, (g_sched+gobuf_pc)(AX)
Keith Randall4aa50432014-07-30 09:01:52 -0700233 MOVQ SP, (g_sched+gobuf_sp)(AX)
234 MOVQ AX, (g_sched+gobuf_g)(AX)
Austin Clements3c0fee12015-01-14 11:09:50 -0500235 MOVQ BP, (g_sched+gobuf_bp)(AX)
Keith Randall4aa50432014-07-30 09:01:52 -0700236
237 // switch to g0
238 MOVQ DX, g(CX)
Russ Coxd16a2ad2014-09-04 22:48:08 -0400239 MOVQ (g_sched+gobuf_sp)(DX), BX
Russ Cox656be312014-11-12 14:54:31 -0500240 // make it look like mstart called systemstack on g0, to stop traceback
Russ Coxd16a2ad2014-09-04 22:48:08 -0400241 SUBQ $8, BX
242 MOVQ $runtime·mstart(SB), DX
243 MOVQ DX, 0(BX)
244 MOVQ BX, SP
Keith Randall4aa50432014-07-30 09:01:52 -0700245
246 // call target function
Russ Cox012ceed2014-09-03 11:35:22 -0400247 MOVQ DI, DX
248 MOVQ 0(DI), DI
Keith Randall4aa50432014-07-30 09:01:52 -0700249 CALL DI
250
251 // switch back to g
252 get_tls(CX)
253 MOVQ g(CX), AX
254 MOVQ g_m(AX), BX
255 MOVQ m_curg(BX), AX
256 MOVQ AX, g(CX)
257 MOVQ (g_sched+gobuf_sp)(AX), SP
258 MOVQ $0, (g_sched+gobuf_sp)(AX)
259 RET
260
Russ Cox656be312014-11-12 14:54:31 -0500261noswitch:
Keith Randall4aa50432014-07-30 09:01:52 -0700262 // already on m stack, just call directly
Russ Cox012ceed2014-09-03 11:35:22 -0400263 MOVQ DI, DX
264 MOVQ 0(DI), DI
Keith Randall4aa50432014-07-30 09:01:52 -0700265 CALL DI
266 RET
267
Rob Pike2da97832008-07-12 11:30:53 -0700268/*
269 * support for morestack
270 */
271
Russ Cox7343e032009-06-17 15:12:16 -0700272// Called during function prolog when more stack is needed.
Russ Cox58f12ff2013-07-18 16:53:45 -0400273//
274// The traceback routines see morestack on a g0 as being
275// the top of a stack (for example, morestack calling newstack
276// calling the scheduler calling newm calling gc), so we must
277// record an argument size. For that purpose, it has no arguments.
Keith Randall5a546962013-08-07 10:23:24 -0700278TEXT runtime·morestack(SB),NOSPLIT,$0-0
Russ Coxe473f422010-08-04 17:50:22 -0700279 // Cannot grow scheduler stack (m->g0).
Anthony Martin2302b212014-09-10 06:25:05 -0700280 get_tls(CX)
Russ Cox15b76ad2014-09-09 13:39:57 -0400281 MOVQ g(CX), BX
282 MOVQ g_m(BX), BX
Russ Coxe473f422010-08-04 17:50:22 -0700283 MOVQ m_g0(BX), SI
284 CMPQ g(CX), SI
285 JNE 2(PC)
286 INT $3
287
Russ Coxf8f630f2014-09-05 16:51:45 -0400288 // Cannot grow signal stack (m->gsignal).
289 MOVQ m_gsignal(BX), SI
290 CMPQ g(CX), SI
291 JNE 2(PC)
292 INT $3
293
Russ Cox7343e032009-06-17 15:12:16 -0700294 // Called from f.
295 // Set m->morebuf to f's caller.
296 MOVQ 8(SP), AX // f's caller's PC
Russ Coxe473f422010-08-04 17:50:22 -0700297 MOVQ AX, (m_morebuf+gobuf_pc)(BX)
Russ Cox7343e032009-06-17 15:12:16 -0700298 LEAQ 16(SP), AX // f's caller's SP
Russ Coxe473f422010-08-04 17:50:22 -0700299 MOVQ AX, (m_morebuf+gobuf_sp)(BX)
Russ Coxe473f422010-08-04 17:50:22 -0700300 get_tls(CX)
301 MOVQ g(CX), SI
302 MOVQ SI, (m_morebuf+gobuf_g)(BX)
Russ Cox7343e032009-06-17 15:12:16 -0700303
Russ Cox6fa3c892013-06-27 11:32:01 -0400304 // Set g->sched to context in f.
305 MOVQ 0(SP), AX // f's PC
306 MOVQ AX, (g_sched+gobuf_pc)(SI)
307 MOVQ SI, (g_sched+gobuf_g)(SI)
308 LEAQ 8(SP), AX // f's SP
309 MOVQ AX, (g_sched+gobuf_sp)(SI)
310 MOVQ DX, (g_sched+gobuf_ctxt)(SI)
Austin Clements3c0fee12015-01-14 11:09:50 -0500311 MOVQ BP, (g_sched+gobuf_bp)(SI)
Russ Cox7343e032009-06-17 15:12:16 -0700312
Russ Coxf9ca3b52011-03-07 10:37:42 -0500313 // Call newstack on m->g0's stack.
Austin Clements20a6ff72015-01-27 18:29:02 -0500314 MOVQ m_g0(BX), BX
315 MOVQ BX, g(CX)
316 MOVQ (g_sched+gobuf_sp)(BX), SP
Russ Cox68b42552010-11-04 14:00:19 -0400317 CALL runtime·newstack(SB)
Russ Cox7343e032009-06-17 15:12:16 -0700318 MOVQ $0, 0x1003 // crash if newstack returns
319 RET
320
Russ Cox15b76ad2014-09-09 13:39:57 -0400321// morestack but not preserving ctxt.
322TEXT runtime·morestack_noctxt(SB),NOSPLIT,$0
323 MOVL $0, DX
324 JMP runtime·morestack(SB)
325
Keith Randall52631982014-09-08 10:14:41 -0700326// reflectcall: call a function with the given argument list
Russ Coxdf027ac2014-12-30 13:59:55 -0500327// func call(argtype *_type, f *FuncVal, arg *byte, argsize, retoffset uint32).
Keith Randall9cd57062013-08-02 13:03:14 -0700328// we don't have variable-sized frames, so we use a small number
329// of constant-sized-frame functions to encode a few bits of size in the pc.
330// Caution: ugly multiline assembly macros in your future!
331
332#define DISPATCH(NAME,MAXSIZE) \
333 CMPQ CX, $MAXSIZE; \
334 JA 3(PC); \
Russ Coxcb6f5ac2014-10-15 13:12:16 -0400335 MOVQ $NAME(SB), AX; \
Keith Randall9cd57062013-08-02 13:03:14 -0700336 JMP AX
Rob Pikeaff78832014-07-30 10:11:44 -0700337// Note: can't just "JMP NAME(SB)" - bad inlining results.
Keith Randall9cd57062013-08-02 13:03:14 -0700338
Russ Cox7a524a12014-12-22 13:27:53 -0500339TEXT reflect·call(SB), NOSPLIT, $0-0
340 JMP ·reflectcall(SB)
341
Russ Coxdf027ac2014-12-30 13:59:55 -0500342TEXT ·reflectcall(SB), NOSPLIT, $0-32
343 MOVLQZX argsize+24(FP), CX
344 // NOTE(rsc): No call16, because CALLFN needs four words
345 // of argument space to invoke callwritebarrier.
Rob Pikeaff78832014-07-30 10:11:44 -0700346 DISPATCH(runtime·call32, 32)
347 DISPATCH(runtime·call64, 64)
348 DISPATCH(runtime·call128, 128)
349 DISPATCH(runtime·call256, 256)
350 DISPATCH(runtime·call512, 512)
351 DISPATCH(runtime·call1024, 1024)
352 DISPATCH(runtime·call2048, 2048)
353 DISPATCH(runtime·call4096, 4096)
354 DISPATCH(runtime·call8192, 8192)
355 DISPATCH(runtime·call16384, 16384)
356 DISPATCH(runtime·call32768, 32768)
357 DISPATCH(runtime·call65536, 65536)
358 DISPATCH(runtime·call131072, 131072)
359 DISPATCH(runtime·call262144, 262144)
360 DISPATCH(runtime·call524288, 524288)
361 DISPATCH(runtime·call1048576, 1048576)
362 DISPATCH(runtime·call2097152, 2097152)
363 DISPATCH(runtime·call4194304, 4194304)
364 DISPATCH(runtime·call8388608, 8388608)
365 DISPATCH(runtime·call16777216, 16777216)
366 DISPATCH(runtime·call33554432, 33554432)
367 DISPATCH(runtime·call67108864, 67108864)
368 DISPATCH(runtime·call134217728, 134217728)
369 DISPATCH(runtime·call268435456, 268435456)
370 DISPATCH(runtime·call536870912, 536870912)
371 DISPATCH(runtime·call1073741824, 1073741824)
Keith Randall9cd57062013-08-02 13:03:14 -0700372 MOVQ $runtime·badreflectcall(SB), AX
373 JMP AX
374
Keith Randall12e46e42013-08-06 14:33:55 -0700375#define CALLFN(NAME,MAXSIZE) \
Russ Coxdf027ac2014-12-30 13:59:55 -0500376TEXT NAME(SB), WRAPPER, $MAXSIZE-32; \
Russ Coxcb6f5ac2014-10-15 13:12:16 -0400377 NO_LOCAL_POINTERS; \
Keith Randall9cd57062013-08-02 13:03:14 -0700378 /* copy arguments to stack */ \
Russ Coxdf027ac2014-12-30 13:59:55 -0500379 MOVQ argptr+16(FP), SI; \
380 MOVLQZX argsize+24(FP), CX; \
Keith Randall9cd57062013-08-02 13:03:14 -0700381 MOVQ SP, DI; \
382 REP;MOVSB; \
383 /* call function */ \
Russ Coxdf027ac2014-12-30 13:59:55 -0500384 MOVQ f+8(FP), DX; \
Keith Randallcee8bca2014-05-21 14:28:34 -0700385 PCDATA $PCDATA_StackMapIndex, $0; \
Keith Randall9cd57062013-08-02 13:03:14 -0700386 CALL (DX); \
387 /* copy return values back */ \
Russ Coxdf027ac2014-12-30 13:59:55 -0500388 MOVQ argptr+16(FP), DI; \
389 MOVLQZX argsize+24(FP), CX; \
390 MOVLQZX retoffset+28(FP), BX; \
Keith Randall9cd57062013-08-02 13:03:14 -0700391 MOVQ SP, SI; \
Russ Cox72c5d5e2014-04-08 11:11:35 -0400392 ADDQ BX, DI; \
393 ADDQ BX, SI; \
394 SUBQ BX, CX; \
Keith Randall9cd57062013-08-02 13:03:14 -0700395 REP;MOVSB; \
Russ Coxdf027ac2014-12-30 13:59:55 -0500396 /* execute write barrier updates */ \
397 MOVQ argtype+0(FP), DX; \
398 MOVQ argptr+16(FP), DI; \
399 MOVLQZX argsize+24(FP), CX; \
400 MOVLQZX retoffset+28(FP), BX; \
401 MOVQ DX, 0(SP); \
402 MOVQ DI, 8(SP); \
403 MOVQ CX, 16(SP); \
404 MOVQ BX, 24(SP); \
405 CALL runtime·callwritebarrier(SB); \
Keith Randall9cd57062013-08-02 13:03:14 -0700406 RET
407
Russ Coxcb6f5ac2014-10-15 13:12:16 -0400408CALLFN(·call32, 32)
409CALLFN(·call64, 64)
410CALLFN(·call128, 128)
411CALLFN(·call256, 256)
412CALLFN(·call512, 512)
413CALLFN(·call1024, 1024)
414CALLFN(·call2048, 2048)
415CALLFN(·call4096, 4096)
416CALLFN(·call8192, 8192)
417CALLFN(·call16384, 16384)
418CALLFN(·call32768, 32768)
419CALLFN(·call65536, 65536)
420CALLFN(·call131072, 131072)
421CALLFN(·call262144, 262144)
422CALLFN(·call524288, 524288)
423CALLFN(·call1048576, 1048576)
424CALLFN(·call2097152, 2097152)
425CALLFN(·call4194304, 4194304)
426CALLFN(·call8388608, 8388608)
427CALLFN(·call16777216, 16777216)
428CALLFN(·call33554432, 33554432)
429CALLFN(·call67108864, 67108864)
430CALLFN(·call134217728, 134217728)
431CALLFN(·call268435456, 268435456)
432CALLFN(·call536870912, 536870912)
433CALLFN(·call1073741824, 1073741824)
Keith Randall9cd57062013-08-02 13:03:14 -0700434
Russ Coxd28acc42008-08-04 16:43:49 -0700435// bool cas(int32 *val, int32 old, int32 new)
436// Atomically:
437// if(*val == old){
438// *val = new;
439// return 1;
Ken Thompson1e1cc4e2009-01-27 12:03:53 -0800440// } else
Russ Coxd28acc42008-08-04 16:43:49 -0700441// return 0;
Russ Cox25f6b022014-08-27 11:32:17 -0400442TEXT runtime·cas(SB), NOSPLIT, $0-17
443 MOVQ ptr+0(FP), BX
444 MOVL old+8(FP), AX
445 MOVL new+12(FP), CX
Russ Coxd28acc42008-08-04 16:43:49 -0700446 LOCK
447 CMPXCHGL CX, 0(BX)
Josh Bleecher Snyderf7e43f12015-01-07 14:24:18 -0800448 SETEQ ret+16(FP)
Russ Coxd28acc42008-08-04 16:43:49 -0700449 RET
Ken Thompson1e1cc4e2009-01-27 12:03:53 -0800450
Russ Cox9ddfb642013-07-16 16:24:09 -0400451// bool runtime·cas64(uint64 *val, uint64 old, uint64 new)
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400452// Atomically:
453// if(*val == *old){
454// *val = new;
455// return 1;
456// } else {
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400457// return 0;
458// }
Russ Cox25f6b022014-08-27 11:32:17 -0400459TEXT runtime·cas64(SB), NOSPLIT, $0-25
460 MOVQ ptr+0(FP), BX
461 MOVQ old+8(FP), AX
462 MOVQ new+16(FP), CX
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400463 LOCK
464 CMPXCHGQ CX, 0(BX)
Josh Bleecher Snyderf7e43f12015-01-07 14:24:18 -0800465 SETEQ ret+24(FP)
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400466 RET
Russ Coxd21638b2014-08-27 21:59:49 -0400467
468TEXT runtime·casuintptr(SB), NOSPLIT, $0-25
469 JMP runtime·cas64(SB)
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400470
Russ Cox3a7f6642014-08-29 16:20:48 -0400471TEXT runtime·atomicloaduintptr(SB), NOSPLIT, $0-16
472 JMP runtime·atomicload64(SB)
473
Keith Randall47d6af22014-08-30 11:03:28 -0700474TEXT runtime·atomicloaduint(SB), NOSPLIT, $0-16
475 JMP runtime·atomicload64(SB)
476
Russ Cox2b1659b2014-10-07 23:27:25 -0400477TEXT runtime·atomicstoreuintptr(SB), NOSPLIT, $0-16
478 JMP runtime·atomicstore64(SB)
479
Russ Cox67793502011-02-16 13:21:13 -0500480// bool casp(void **val, void *old, void *new)
481// Atomically:
482// if(*val == old){
483// *val = new;
484// return 1;
485// } else
486// return 0;
Russ Cox15ced2d2014-11-11 17:06:22 -0500487TEXT runtime·casp1(SB), NOSPLIT, $0-25
Russ Cox25f6b022014-08-27 11:32:17 -0400488 MOVQ ptr+0(FP), BX
489 MOVQ old+8(FP), AX
490 MOVQ new+16(FP), CX
Russ Cox67793502011-02-16 13:21:13 -0500491 LOCK
492 CMPXCHGQ CX, 0(BX)
Josh Bleecher Snyderf7e43f12015-01-07 14:24:18 -0800493 SETEQ ret+24(FP)
Russ Cox67793502011-02-16 13:21:13 -0500494 RET
495
Dmitriy Vyukov491aa152011-07-15 11:27:16 -0400496// uint32 xadd(uint32 volatile *val, int32 delta)
497// Atomically:
498// *val += delta;
499// return *val;
Russ Cox25f6b022014-08-27 11:32:17 -0400500TEXT runtime·xadd(SB), NOSPLIT, $0-20
501 MOVQ ptr+0(FP), BX
502 MOVL delta+8(FP), AX
Dmitriy Vyukov491aa152011-07-15 11:27:16 -0400503 MOVL AX, CX
504 LOCK
505 XADDL AX, 0(BX)
506 ADDL CX, AX
Russ Cox25f6b022014-08-27 11:32:17 -0400507 MOVL AX, ret+16(FP)
Dmitriy Vyukov491aa152011-07-15 11:27:16 -0400508 RET
509
Russ Cox25f6b022014-08-27 11:32:17 -0400510TEXT runtime·xadd64(SB), NOSPLIT, $0-24
511 MOVQ ptr+0(FP), BX
512 MOVQ delta+8(FP), AX
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400513 MOVQ AX, CX
514 LOCK
515 XADDQ AX, 0(BX)
516 ADDQ CX, AX
Russ Cox25f6b022014-08-27 11:32:17 -0400517 MOVQ AX, ret+16(FP)
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400518 RET
519
Russ Cox25f6b022014-08-27 11:32:17 -0400520TEXT runtime·xchg(SB), NOSPLIT, $0-20
521 MOVQ ptr+0(FP), BX
522 MOVL new+8(FP), AX
Dmitriy Vyukov4e5086b2011-07-29 12:44:06 -0400523 XCHGL AX, 0(BX)
Russ Cox25f6b022014-08-27 11:32:17 -0400524 MOVL AX, ret+16(FP)
Dmitriy Vyukov4e5086b2011-07-29 12:44:06 -0400525 RET
526
Russ Cox25f6b022014-08-27 11:32:17 -0400527TEXT runtime·xchg64(SB), NOSPLIT, $0-24
528 MOVQ ptr+0(FP), BX
529 MOVQ new+8(FP), AX
Dmitriy Vyukovadd33492013-03-05 09:46:52 +0200530 XCHGQ AX, 0(BX)
Russ Cox25f6b022014-08-27 11:32:17 -0400531 MOVQ AX, ret+16(FP)
Dmitriy Vyukovadd33492013-03-05 09:46:52 +0200532 RET
533
Russ Cox15ced2d2014-11-11 17:06:22 -0500534TEXT runtime·xchgp1(SB), NOSPLIT, $0-24
Russ Cox25f6b022014-08-27 11:32:17 -0400535 MOVQ ptr+0(FP), BX
536 MOVQ new+8(FP), AX
Dmitriy Vyukov9cbd2fb2014-01-22 11:27:16 +0400537 XCHGQ AX, 0(BX)
Russ Cox25f6b022014-08-27 11:32:17 -0400538 MOVQ AX, ret+16(FP)
Dmitriy Vyukov9cbd2fb2014-01-22 11:27:16 +0400539 RET
540
Dmitriy Vyukov91a670d2014-09-04 10:04:04 +0400541TEXT runtime·xchguintptr(SB), NOSPLIT, $0-24
542 JMP runtime·xchg64(SB)
543
Keith Randall5a546962013-08-07 10:23:24 -0700544TEXT runtime·procyield(SB),NOSPLIT,$0-0
Russ Cox25f6b022014-08-27 11:32:17 -0400545 MOVL cycles+0(FP), AX
Dmitriy Vyukov4e5086b2011-07-29 12:44:06 -0400546again:
547 PAUSE
548 SUBL $1, AX
549 JNZ again
550 RET
551
Russ Cox15ced2d2014-11-11 17:06:22 -0500552TEXT runtime·atomicstorep1(SB), NOSPLIT, $0-16
Russ Cox25f6b022014-08-27 11:32:17 -0400553 MOVQ ptr+0(FP), BX
554 MOVQ val+8(FP), AX
Dmitriy Vyukov86a659c2011-07-13 11:22:41 -0700555 XCHGQ AX, 0(BX)
556 RET
557
Keith Randall5a546962013-08-07 10:23:24 -0700558TEXT runtime·atomicstore(SB), NOSPLIT, $0-12
Russ Cox25f6b022014-08-27 11:32:17 -0400559 MOVQ ptr+0(FP), BX
560 MOVL val+8(FP), AX
Dmitriy Vyukov91f0f182011-07-29 13:47:24 -0400561 XCHGL AX, 0(BX)
562 RET
563
Keith Randall5a546962013-08-07 10:23:24 -0700564TEXT runtime·atomicstore64(SB), NOSPLIT, $0-16
Russ Cox25f6b022014-08-27 11:32:17 -0400565 MOVQ ptr+0(FP), BX
566 MOVQ val+8(FP), AX
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400567 XCHGQ AX, 0(BX)
568 RET
569
Dmitriy Vyukovff3fa1b2014-08-19 17:38:00 +0400570// void runtime·atomicor8(byte volatile*, byte);
Russ Cox25f6b022014-08-27 11:32:17 -0400571TEXT runtime·atomicor8(SB), NOSPLIT, $0-9
Dmitriy Vyukovff3fa1b2014-08-19 17:38:00 +0400572 MOVQ ptr+0(FP), AX
573 MOVB val+8(FP), BX
574 LOCK
575 ORB BX, (AX)
576 RET
577
Russ Coxaa3222d82009-06-02 23:02:12 -0700578// void jmpdefer(fn, sp);
579// called from deferreturn.
Ken Thompson1e1cc4e2009-01-27 12:03:53 -0800580// 1. pop the caller
581// 2. sub 5 bytes from the callers return
582// 3. jmp to the argument
Keith Randalla97a91d2013-08-07 14:03:50 -0700583TEXT runtime·jmpdefer(SB), NOSPLIT, $0-16
Russ Cox25f6b022014-08-27 11:32:17 -0400584 MOVQ fv+0(FP), DX // fn
585 MOVQ argp+8(FP), BX // caller sp
Russ Coxaa3222d82009-06-02 23:02:12 -0700586 LEAQ -8(BX), SP // caller sp after CALL
587 SUBQ $5, (SP) // return to CALL again
Russ Cox6066fdc2013-02-22 10:47:54 -0500588 MOVQ 0(DX), BX
Russ Cox1903ad72013-02-21 17:01:13 -0500589 JMP BX // but first run the deferred function
Russ Cox133a1582009-10-03 10:37:12 -0700590
Russ Coxd67e7e32013-06-12 15:22:26 -0400591// Save state of caller into g->sched. Smashes R8, R9.
Keith Randall5a546962013-08-07 10:23:24 -0700592TEXT gosave<>(SB),NOSPLIT,$0
Russ Coxd67e7e32013-06-12 15:22:26 -0400593 get_tls(R8)
594 MOVQ g(R8), R8
595 MOVQ 0(SP), R9
596 MOVQ R9, (g_sched+gobuf_pc)(R8)
597 LEAQ 8(SP), R9
598 MOVQ R9, (g_sched+gobuf_sp)(R8)
599 MOVQ $0, (g_sched+gobuf_ret)(R8)
600 MOVQ $0, (g_sched+gobuf_ctxt)(R8)
Austin Clements3c0fee12015-01-14 11:09:50 -0500601 MOVQ BP, (g_sched+gobuf_bp)(R8)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500602 RET
603
604// asmcgocall(void(*fn)(void*), void *arg)
Russ Coxadd89dd2009-10-12 10:26:38 -0700605// Call fn(arg) on the scheduler stack,
606// aligned appropriately for the gcc ABI.
Russ Coxf9ca3b52011-03-07 10:37:42 -0500607// See cgocall.c for more details.
Russ Cox653fb6d2014-09-16 17:39:55 -0400608TEXT ·asmcgocall(SB),NOSPLIT,$0-16
Russ Cox54138e12014-09-03 11:36:14 -0400609 MOVQ fn+0(FP), AX
610 MOVQ arg+8(FP), BX
Russ Coxcb767242014-09-04 00:01:55 -0400611 CALL asmcgocall<>(SB)
Russ Cox54138e12014-09-03 11:36:14 -0400612 RET
613
Russ Cox653fb6d2014-09-16 17:39:55 -0400614TEXT ·asmcgocall_errno(SB),NOSPLIT,$0-20
Russ Coxf9ca3b52011-03-07 10:37:42 -0500615 MOVQ fn+0(FP), AX
616 MOVQ arg+8(FP), BX
Russ Coxcb767242014-09-04 00:01:55 -0400617 CALL asmcgocall<>(SB)
618 MOVL AX, ret+16(FP)
619 RET
620
621// asmcgocall common code. fn in AX, arg in BX. returns errno in AX.
622TEXT asmcgocall<>(SB),NOSPLIT,$0-0
Russ Coxf9ca3b52011-03-07 10:37:42 -0500623 MOVQ SP, DX
Russ Coxadd89dd2009-10-12 10:26:38 -0700624
625 // Figure out if we need to switch to m->g0 stack.
Russ Coxf9ca3b52011-03-07 10:37:42 -0500626 // We get called to create new OS threads too, and those
627 // come in on the m->g0 stack already.
628 get_tls(CX)
Austin Clements20a6ff72015-01-27 18:29:02 -0500629 MOVQ g(CX), R8
630 MOVQ g_m(R8), R8
631 MOVQ m_g0(R8), SI
Russ Coxf9ca3b52011-03-07 10:37:42 -0500632 MOVQ g(CX), DI
633 CMPQ SI, DI
Aram Hăvărneanua46b4342014-01-17 17:58:10 +1300634 JEQ nosave
Austin Clements20a6ff72015-01-27 18:29:02 -0500635 MOVQ m_gsignal(R8), SI
Aram Hăvărneanua46b4342014-01-17 17:58:10 +1300636 CMPQ SI, DI
637 JEQ nosave
638
Austin Clements20a6ff72015-01-27 18:29:02 -0500639 MOVQ m_g0(R8), SI
Russ Coxd67e7e32013-06-12 15:22:26 -0400640 CALL gosave<>(SB)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500641 MOVQ SI, g(CX)
642 MOVQ (g_sched+gobuf_sp)(SI), SP
Aram Hăvărneanua46b4342014-01-17 17:58:10 +1300643nosave:
Russ Coxadd89dd2009-10-12 10:26:38 -0700644
645 // Now on a scheduling stack (a pthread-created stack).
Alex Brainman7f075ec2012-09-03 12:12:51 +1000646 // Make sure we have enough room for 4 stack-backed fast-call
647 // registers as per windows amd64 calling convention.
648 SUBQ $64, SP
Russ Cox133a1582009-10-03 10:37:12 -0700649 ANDQ $~15, SP // alignment for gcc ABI
Alex Brainman7f075ec2012-09-03 12:12:51 +1000650 MOVQ DI, 48(SP) // save g
Keith Randall47f251c2014-09-11 20:36:23 -0700651 MOVQ (g_stack+stack_hi)(DI), DI
652 SUBQ DX, DI
653 MOVQ DI, 40(SP) // save depth in stack (can't just save SP, as stack might be copied during a callback)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500654 MOVQ BX, DI // DI = first argument in AMD64 ABI
Wei Guangjing9f636592011-07-19 10:47:33 -0400655 MOVQ BX, CX // CX = first argument in Win64
Russ Coxf9ca3b52011-03-07 10:37:42 -0500656 CALL AX
Russ Coxadd89dd2009-10-12 10:26:38 -0700657
Russ Coxe473f422010-08-04 17:50:22 -0700658 // Restore registers, g, stack pointer.
Russ Coxf9ca3b52011-03-07 10:37:42 -0500659 get_tls(CX)
Alex Brainman7f075ec2012-09-03 12:12:51 +1000660 MOVQ 48(SP), DI
Keith Randall47f251c2014-09-11 20:36:23 -0700661 MOVQ (g_stack+stack_hi)(DI), SI
662 SUBQ 40(SP), SI
Russ Coxf9ca3b52011-03-07 10:37:42 -0500663 MOVQ DI, g(CX)
Keith Randall47f251c2014-09-11 20:36:23 -0700664 MOVQ SI, SP
Russ Cox133a1582009-10-03 10:37:12 -0700665 RET
666
Russ Coxf9ca3b52011-03-07 10:37:42 -0500667// cgocallback(void (*fn)(void*), void *frame, uintptr framesize)
Russ Cox3d2dfc52013-02-22 16:08:56 -0500668// Turn the fn into a Go func (by taking its address) and call
669// cgocallback_gofunc.
Keith Randall5a546962013-08-07 10:23:24 -0700670TEXT runtime·cgocallback(SB),NOSPLIT,$24-24
Russ Cox3d2dfc52013-02-22 16:08:56 -0500671 LEAQ fn+0(FP), AX
672 MOVQ AX, 0(SP)
673 MOVQ frame+8(FP), AX
674 MOVQ AX, 8(SP)
675 MOVQ framesize+16(FP), AX
676 MOVQ AX, 16(SP)
677 MOVQ $runtime·cgocallback_gofunc(SB), AX
678 CALL AX
679 RET
680
681// cgocallback_gofunc(FuncVal*, void *frame, uintptr framesize)
682// See cgocall.c for more details.
Russ Cox653fb6d2014-09-16 17:39:55 -0400683TEXT ·cgocallback_gofunc(SB),NOSPLIT,$8-24
Russ Coxe844f532014-09-12 07:46:11 -0400684 NO_LOCAL_POINTERS
685
Russ Cox89f185f2014-06-26 11:54:39 -0400686 // If g is nil, Go did not create the current thread.
687 // Call needm to obtain one m for temporary use.
Russ Cox6c976392013-02-20 17:48:23 -0500688 // In this case, we're running on the thread stack, so there's
689 // lots of space, but the linker doesn't know. Hide the call from
690 // the linker analysis by using an indirect call through AX.
691 get_tls(CX)
692#ifdef GOOS_windows
Austin Clements20a6ff72015-01-27 18:29:02 -0500693 MOVL $0, BX
Russ Cox6c976392013-02-20 17:48:23 -0500694 CMPQ CX, $0
Russ Coxcefdb9c2013-07-23 22:59:32 -0400695 JEQ 2(PC)
Russ Cox6c976392013-02-20 17:48:23 -0500696#endif
Austin Clements20a6ff72015-01-27 18:29:02 -0500697 MOVQ g(CX), BX
698 CMPQ BX, $0
Russ Cox89f185f2014-06-26 11:54:39 -0400699 JEQ needm
Austin Clements20a6ff72015-01-27 18:29:02 -0500700 MOVQ g_m(BX), BX
701 MOVQ BX, R8 // holds oldm until end of function
Russ Cox89f185f2014-06-26 11:54:39 -0400702 JMP havem
Russ Cox6c976392013-02-20 17:48:23 -0500703needm:
Russ Cox89f185f2014-06-26 11:54:39 -0400704 MOVQ $0, 0(SP)
Russ Cox6c976392013-02-20 17:48:23 -0500705 MOVQ $runtime·needm(SB), AX
706 CALL AX
Russ Coxf0112822013-07-24 09:01:57 -0400707 MOVQ 0(SP), R8
Russ Coxe473f422010-08-04 17:50:22 -0700708 get_tls(CX)
Austin Clements20a6ff72015-01-27 18:29:02 -0500709 MOVQ g(CX), BX
710 MOVQ g_m(BX), BX
Russ Coxc4efaac2014-10-28 21:53:09 -0400711
712 // Set m->sched.sp = SP, so that if a panic happens
713 // during the function we are about to execute, it will
714 // have a valid SP to run on the g0 stack.
715 // The next few lines (after the havem label)
716 // will save this SP onto the stack and then write
717 // the same SP back to m->sched.sp. That seems redundant,
718 // but if an unrecovered panic happens, unwindm will
719 // restore the g->sched.sp from the stack location
Russ Cox656be312014-11-12 14:54:31 -0500720 // and then systemstack will try to use it. If we don't set it here,
Russ Coxc4efaac2014-10-28 21:53:09 -0400721 // that restored SP will be uninitialized (typically 0) and
722 // will not be usable.
Austin Clements20a6ff72015-01-27 18:29:02 -0500723 MOVQ m_g0(BX), SI
Russ Coxc4efaac2014-10-28 21:53:09 -0400724 MOVQ SP, (g_sched+gobuf_sp)(SI)
Russ Cox9b732382012-03-08 12:12:40 -0500725
Russ Cox6c976392013-02-20 17:48:23 -0500726havem:
727 // Now there's a valid m, and we're running on its m->g0.
728 // Save current m->g0->sched.sp on stack and then set it to SP.
729 // Save current sp in m->g0->sched.sp in preparation for
730 // switch back to m->curg stack.
Russ Coxdba623b2013-07-23 18:40:02 -0400731 // NOTE: unwindm knows that the saved g->sched.sp is at 0(SP).
Austin Clements20a6ff72015-01-27 18:29:02 -0500732 MOVQ m_g0(BX), SI
Russ Coxdba623b2013-07-23 18:40:02 -0400733 MOVQ (g_sched+gobuf_sp)(SI), AX
734 MOVQ AX, 0(SP)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500735 MOVQ SP, (g_sched+gobuf_sp)(SI)
Ian Lance Taylor2d0ff3f2010-04-09 13:30:11 -0700736
Russ Coxdba623b2013-07-23 18:40:02 -0400737 // Switch to m->curg stack and call runtime.cgocallbackg.
738 // Because we are taking over the execution of m->curg
739 // but *not* resuming what had been running, we need to
740 // save that information (m->curg->sched) so we can restore it.
Russ Cox528534c2013-06-05 07:16:53 -0400741 // We can restore m->curg->sched.sp easily, because calling
Alex Brainman72e83482011-08-18 12:17:09 -0400742 // runtime.cgocallbackg leaves SP unchanged upon return.
Russ Cox528534c2013-06-05 07:16:53 -0400743 // To save m->curg->sched.pc, we push it onto the stack.
Russ Coxf9ca3b52011-03-07 10:37:42 -0500744 // This has the added benefit that it looks to the traceback
Alex Brainman72e83482011-08-18 12:17:09 -0400745 // routine like cgocallbackg is going to return to that
Russ Coxdba623b2013-07-23 18:40:02 -0400746 // PC (because the frame we allocate below has the same
747 // size as cgocallback_gofunc's frame declared above)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500748 // so that the traceback will seamlessly trace back into
749 // the earlier calls.
Russ Coxdba623b2013-07-23 18:40:02 -0400750 //
Russ Coxf0112822013-07-24 09:01:57 -0400751 // In the new goroutine, 0(SP) holds the saved R8.
Austin Clements20a6ff72015-01-27 18:29:02 -0500752 MOVQ m_curg(BX), SI
Russ Coxf9ca3b52011-03-07 10:37:42 -0500753 MOVQ SI, g(CX)
754 MOVQ (g_sched+gobuf_sp)(SI), DI // prepare stack as DI
Austin Clements20a6ff72015-01-27 18:29:02 -0500755 MOVQ (g_sched+gobuf_pc)(SI), BX
756 MOVQ BX, -8(DI)
Austin Clements3c0fee12015-01-14 11:09:50 -0500757 // Compute the size of the frame, including return PC and, if
758 // GOEXPERIMENT=framepointer, the saved based pointer
759 LEAQ x+0(FP), AX
760 SUBQ SP, AX
761 SUBQ AX, DI
762 MOVQ DI, SP
763
Russ Coxf0112822013-07-24 09:01:57 -0400764 MOVQ R8, 0(SP)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500765 CALL runtime·cgocallbackg(SB)
Russ Coxf0112822013-07-24 09:01:57 -0400766 MOVQ 0(SP), R8
Russ Coxf9ca3b52011-03-07 10:37:42 -0500767
Austin Clements3c0fee12015-01-14 11:09:50 -0500768 // Compute the size of the frame again. FP and SP have
769 // completely different values here than they did above,
770 // but only their difference matters.
771 LEAQ x+0(FP), AX
772 SUBQ SP, AX
773
Russ Cox528534c2013-06-05 07:16:53 -0400774 // Restore g->sched (== m->curg->sched) from saved values.
Russ Coxe473f422010-08-04 17:50:22 -0700775 get_tls(CX)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500776 MOVQ g(CX), SI
Austin Clements3c0fee12015-01-14 11:09:50 -0500777 MOVQ SP, DI
778 ADDQ AX, DI
779 MOVQ -8(DI), BX
Austin Clements20a6ff72015-01-27 18:29:02 -0500780 MOVQ BX, (g_sched+gobuf_pc)(SI)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500781 MOVQ DI, (g_sched+gobuf_sp)(SI)
782
783 // Switch back to m->g0's stack and restore m->g0->sched.sp.
784 // (Unlike m->curg, the g0 goroutine never uses sched.pc,
785 // so we do not have to restore it.)
Austin Clements20a6ff72015-01-27 18:29:02 -0500786 MOVQ g(CX), BX
787 MOVQ g_m(BX), BX
788 MOVQ m_g0(BX), SI
Russ Coxf9ca3b52011-03-07 10:37:42 -0500789 MOVQ SI, g(CX)
790 MOVQ (g_sched+gobuf_sp)(SI), SP
Russ Coxdba623b2013-07-23 18:40:02 -0400791 MOVQ 0(SP), AX
792 MOVQ AX, (g_sched+gobuf_sp)(SI)
Russ Cox6c976392013-02-20 17:48:23 -0500793
794 // If the m on entry was nil, we called needm above to borrow an m
795 // for the duration of the call. Since the call is over, return it with dropm.
Russ Coxf0112822013-07-24 09:01:57 -0400796 CMPQ R8, $0
Russ Cox6c976392013-02-20 17:48:23 -0500797 JNE 3(PC)
798 MOVQ $runtime·dropm(SB), AX
799 CALL AX
Russ Coxf9ca3b52011-03-07 10:37:42 -0500800
801 // Done!
Ian Lance Taylor2d0ff3f2010-04-09 13:30:11 -0700802 RET
803
Russ Cox89f185f2014-06-26 11:54:39 -0400804// void setg(G*); set g. for use by needm.
Russ Cox25f6b022014-08-27 11:32:17 -0400805TEXT runtime·setg(SB), NOSPLIT, $0-8
Russ Cox89f185f2014-06-26 11:54:39 -0400806 MOVQ gg+0(FP), BX
Russ Cox6c976392013-02-20 17:48:23 -0500807#ifdef GOOS_windows
Russ Cox89f185f2014-06-26 11:54:39 -0400808 CMPQ BX, $0
Russ Cox6c976392013-02-20 17:48:23 -0500809 JNE settls
810 MOVQ $0, 0x28(GS)
811 RET
812settls:
Russ Cox89f185f2014-06-26 11:54:39 -0400813 MOVQ g_m(BX), AX
Russ Cox6c976392013-02-20 17:48:23 -0500814 LEAQ m_tls(AX), AX
815 MOVQ AX, 0x28(GS)
816#endif
817 get_tls(CX)
Russ Cox6c976392013-02-20 17:48:23 -0500818 MOVQ BX, g(CX)
819 RET
820
Russ Cox89f185f2014-06-26 11:54:39 -0400821// void setg_gcc(G*); set g called from gcc.
822TEXT setg_gcc<>(SB),NOSPLIT,$0
Russ Cox6a70f9d2013-03-25 18:14:02 -0400823 get_tls(AX)
Russ Cox89f185f2014-06-26 11:54:39 -0400824 MOVQ DI, g(AX)
Russ Cox6a70f9d2013-03-25 18:14:02 -0400825 RET
826
Russ Cox15b76ad2014-09-09 13:39:57 -0400827// check that SP is in range [g->stack.lo, g->stack.hi)
Keith Randall5a546962013-08-07 10:23:24 -0700828TEXT runtime·stackcheck(SB), NOSPLIT, $0-0
Russ Coxe473f422010-08-04 17:50:22 -0700829 get_tls(CX)
830 MOVQ g(CX), AX
Russ Cox15b76ad2014-09-09 13:39:57 -0400831 CMPQ (g_stack+stack_hi)(AX), SP
Russ Cox01eaf782010-03-30 10:53:16 -0700832 JHI 2(PC)
833 INT $3
Russ Cox15b76ad2014-09-09 13:39:57 -0400834 CMPQ SP, (g_stack+stack_lo)(AX)
Russ Cox01eaf782010-03-30 10:53:16 -0700835 JHI 2(PC)
836 INT $3
837 RET
838
Russ Cox25f6b022014-08-27 11:32:17 -0400839TEXT runtime·getcallerpc(SB),NOSPLIT,$0-16
840 MOVQ argp+0(FP),AX // addr of first arg
Russ Cox6c196012010-04-05 12:51:09 -0700841 MOVQ -8(AX),AX // get calling pc
Russ Cox25f6b022014-08-27 11:32:17 -0400842 MOVQ AX, ret+8(FP)
Russ Cox6c196012010-04-05 12:51:09 -0700843 RET
844
Keith Randall14c81432014-06-17 21:59:50 -0700845TEXT runtime·gogetcallerpc(SB),NOSPLIT,$0-16
846 MOVQ p+0(FP),AX // addr of first arg
Keith Randall61dca942014-06-16 23:03:03 -0700847 MOVQ -8(AX),AX // get calling pc
Keith Randall14c81432014-06-17 21:59:50 -0700848 MOVQ AX,ret+8(FP)
Keith Randall61dca942014-06-16 23:03:03 -0700849 RET
850
Keith Randall5a546962013-08-07 10:23:24 -0700851TEXT runtime·setcallerpc(SB),NOSPLIT,$0-16
Russ Cox25f6b022014-08-27 11:32:17 -0400852 MOVQ argp+0(FP),AX // addr of first arg
853 MOVQ pc+8(FP), BX
Russ Cox6c196012010-04-05 12:51:09 -0700854 MOVQ BX, -8(AX) // set calling pc
855 RET
856
Russ Cox25f6b022014-08-27 11:32:17 -0400857TEXT runtime·getcallersp(SB),NOSPLIT,$0-16
858 MOVQ argp+0(FP), AX
859 MOVQ AX, ret+8(FP)
Russ Cox6c196012010-04-05 12:51:09 -0700860 RET
861
Rémy Oudompheng39ffa8b2014-08-26 08:34:46 +0200862// func gogetcallersp(p unsafe.Pointer) uintptr
863TEXT runtime·gogetcallersp(SB),NOSPLIT,$0-16
864 MOVQ p+0(FP),AX // addr of first arg
865 MOVQ AX, ret+8(FP)
866 RET
867
Damian Gryski8e765da2012-02-02 14:09:27 -0500868// int64 runtime·cputicks(void)
Keith Randall5a546962013-08-07 10:23:24 -0700869TEXT runtime·cputicks(SB),NOSPLIT,$0-0
Damian Gryski8e765da2012-02-02 14:09:27 -0500870 RDTSC
871 SHLQ $32, DX
872 ADDQ DX, AX
Russ Cox25f6b022014-08-27 11:32:17 -0400873 MOVQ AX, ret+0(FP)
Damian Gryski8e765da2012-02-02 14:09:27 -0500874 RET
875
Keith Randalld5e4c402015-01-06 16:42:48 -0800876// memhash_varlen(p unsafe.Pointer, h seed) uintptr
877// redirects to memhash(p, h, size) using the size
878// stored in the closure.
879TEXT runtime·memhash_varlen(SB),NOSPLIT,$32-24
880 GO_ARGS
881 NO_LOCAL_POINTERS
882 MOVQ p+0(FP), AX
883 MOVQ h+8(FP), BX
884 MOVQ 8(DX), CX
885 MOVQ AX, 0(SP)
886 MOVQ BX, 8(SP)
887 MOVQ CX, 16(SP)
888 CALL runtime·memhash(SB)
889 MOVQ 24(SP), AX
890 MOVQ AX, ret+16(FP)
891 RET
892
Keith Randalla5d40242013-03-12 10:47:44 -0700893// hash function using AES hardware instructions
Keith Randalla2a97682014-07-31 15:07:05 -0700894TEXT runtime·aeshash(SB),NOSPLIT,$0-32
895 MOVQ p+0(FP), AX // ptr to data
Keith Randalld5e4c402015-01-06 16:42:48 -0800896 MOVQ s+16(FP), CX // size
897 LEAQ ret+24(FP), DX
Keith Randalla5d40242013-03-12 10:47:44 -0700898 JMP runtime·aeshashbody(SB)
899
Keith Randalld5e4c402015-01-06 16:42:48 -0800900TEXT runtime·aeshashstr(SB),NOSPLIT,$0-24
Keith Randalla2a97682014-07-31 15:07:05 -0700901 MOVQ p+0(FP), AX // ptr to string struct
Keith Randalla5d40242013-03-12 10:47:44 -0700902 MOVQ 8(AX), CX // length of string
903 MOVQ (AX), AX // string data
Keith Randalld5e4c402015-01-06 16:42:48 -0800904 LEAQ ret+16(FP), DX
Keith Randalla5d40242013-03-12 10:47:44 -0700905 JMP runtime·aeshashbody(SB)
906
907// AX: data
908// CX: length
Keith Randalld5e4c402015-01-06 16:42:48 -0800909// DX: address to put return value
910TEXT runtime·aeshashbody(SB),NOSPLIT,$0-0
911 MOVQ h+8(FP), X6 // seed to low 64 bits of xmm6
Keith Randall7a4a64e2014-12-10 14:20:17 -0800912 PINSRQ $1, CX, X6 // size to high 64 bits of xmm6
913 PSHUFHW $0, X6, X6 // replace size with its low 2 bytes repeated 4 times
914 MOVO runtime·aeskeysched(SB), X7
Keith Randallee669722013-05-15 09:40:14 -0700915 CMPQ CX, $16
Keith Randall7a4a64e2014-12-10 14:20:17 -0800916 JB aes0to15
917 JE aes16
918 CMPQ CX, $32
919 JBE aes17to32
920 CMPQ CX, $64
921 JBE aes33to64
922 CMPQ CX, $128
923 JBE aes65to128
924 JMP aes129plus
Keith Randalla5d40242013-03-12 10:47:44 -0700925
Keith Randall7a4a64e2014-12-10 14:20:17 -0800926aes0to15:
927 TESTQ CX, CX
928 JE aes0
929
930 ADDQ $16, AX
931 TESTW $0xff0, AX
932 JE endofpage
Keith Randalla5d40242013-03-12 10:47:44 -0700933
Keith Randallee669722013-05-15 09:40:14 -0700934 // 16 bytes loaded at this address won't cross
935 // a page boundary, so we can load it directly.
Keith Randall7a4a64e2014-12-10 14:20:17 -0800936 MOVOU -16(AX), X0
Keith Randalla5d40242013-03-12 10:47:44 -0700937 ADDQ CX, CX
Austin Clements20a6ff72015-01-27 18:29:02 -0500938 MOVQ $masks<>(SB), AX
939 PAND (AX)(CX*8), X0
Keith Randall7a4a64e2014-12-10 14:20:17 -0800940
941 // scramble 3 times
942 AESENC X6, X0
943 AESENC X7, X0
944 AESENC X7, X0
Keith Randalld5e4c402015-01-06 16:42:48 -0800945 MOVQ X0, (DX)
Keith Randall7a4a64e2014-12-10 14:20:17 -0800946 RET
947
948endofpage:
Keith Randallee669722013-05-15 09:40:14 -0700949 // address ends in 1111xxxx. Might be up against
Keith Randalla5d40242013-03-12 10:47:44 -0700950 // a page boundary, so load ending at last byte.
951 // Then shift bytes down using pshufb.
Keith Randall7a4a64e2014-12-10 14:20:17 -0800952 MOVOU -32(AX)(CX*1), X0
Keith Randalla5d40242013-03-12 10:47:44 -0700953 ADDQ CX, CX
Austin Clements20a6ff72015-01-27 18:29:02 -0500954 MOVQ $shifts<>(SB), AX
955 PSHUFB (AX)(CX*8), X0
Keith Randall7a4a64e2014-12-10 14:20:17 -0800956 AESENC X6, X0
957 AESENC X7, X0
958 AESENC X7, X0
Keith Randalld5e4c402015-01-06 16:42:48 -0800959 MOVQ X0, (DX)
Keith Randalla5d40242013-03-12 10:47:44 -0700960 RET
961
Keith Randall7a4a64e2014-12-10 14:20:17 -0800962aes0:
963 // return input seed
Keith Randalld5e4c402015-01-06 16:42:48 -0800964 MOVQ h+8(FP), AX
965 MOVQ AX, (DX)
Keith Randall7a4a64e2014-12-10 14:20:17 -0800966 RET
967
968aes16:
969 MOVOU (AX), X0
970 AESENC X6, X0
971 AESENC X7, X0
972 AESENC X7, X0
Keith Randalld5e4c402015-01-06 16:42:48 -0800973 MOVQ X0, (DX)
Keith Randall7a4a64e2014-12-10 14:20:17 -0800974 RET
975
976aes17to32:
977 // load data to be hashed
978 MOVOU (AX), X0
979 MOVOU -16(AX)(CX*1), X1
980
981 // scramble 3 times
982 AESENC X6, X0
983 AESENC runtime·aeskeysched+16(SB), X1
984 AESENC X7, X0
985 AESENC X7, X1
986 AESENC X7, X0
987 AESENC X7, X1
988
989 // combine results
990 PXOR X1, X0
Keith Randalld5e4c402015-01-06 16:42:48 -0800991 MOVQ X0, (DX)
Keith Randall7a4a64e2014-12-10 14:20:17 -0800992 RET
993
994aes33to64:
995 MOVOU (AX), X0
996 MOVOU 16(AX), X1
997 MOVOU -32(AX)(CX*1), X2
998 MOVOU -16(AX)(CX*1), X3
999
1000 AESENC X6, X0
1001 AESENC runtime·aeskeysched+16(SB), X1
1002 AESENC runtime·aeskeysched+32(SB), X2
1003 AESENC runtime·aeskeysched+48(SB), X3
1004 AESENC X7, X0
1005 AESENC X7, X1
1006 AESENC X7, X2
1007 AESENC X7, X3
1008 AESENC X7, X0
1009 AESENC X7, X1
1010 AESENC X7, X2
1011 AESENC X7, X3
1012
1013 PXOR X2, X0
1014 PXOR X3, X1
1015 PXOR X1, X0
Keith Randalld5e4c402015-01-06 16:42:48 -08001016 MOVQ X0, (DX)
Keith Randall7a4a64e2014-12-10 14:20:17 -08001017 RET
1018
1019aes65to128:
1020 MOVOU (AX), X0
1021 MOVOU 16(AX), X1
1022 MOVOU 32(AX), X2
1023 MOVOU 48(AX), X3
1024 MOVOU -64(AX)(CX*1), X4
1025 MOVOU -48(AX)(CX*1), X5
1026 MOVOU -32(AX)(CX*1), X8
1027 MOVOU -16(AX)(CX*1), X9
1028
1029 AESENC X6, X0
1030 AESENC runtime·aeskeysched+16(SB), X1
1031 AESENC runtime·aeskeysched+32(SB), X2
1032 AESENC runtime·aeskeysched+48(SB), X3
1033 AESENC runtime·aeskeysched+64(SB), X4
1034 AESENC runtime·aeskeysched+80(SB), X5
1035 AESENC runtime·aeskeysched+96(SB), X8
1036 AESENC runtime·aeskeysched+112(SB), X9
1037 AESENC X7, X0
1038 AESENC X7, X1
1039 AESENC X7, X2
1040 AESENC X7, X3
1041 AESENC X7, X4
1042 AESENC X7, X5
1043 AESENC X7, X8
1044 AESENC X7, X9
1045 AESENC X7, X0
1046 AESENC X7, X1
1047 AESENC X7, X2
1048 AESENC X7, X3
1049 AESENC X7, X4
1050 AESENC X7, X5
1051 AESENC X7, X8
1052 AESENC X7, X9
1053
1054 PXOR X4, X0
1055 PXOR X5, X1
1056 PXOR X8, X2
1057 PXOR X9, X3
1058 PXOR X2, X0
1059 PXOR X3, X1
1060 PXOR X1, X0
Keith Randalld5e4c402015-01-06 16:42:48 -08001061 MOVQ X0, (DX)
Keith Randall7a4a64e2014-12-10 14:20:17 -08001062 RET
1063
1064aes129plus:
1065 // start with last (possibly overlapping) block
1066 MOVOU -128(AX)(CX*1), X0
1067 MOVOU -112(AX)(CX*1), X1
1068 MOVOU -96(AX)(CX*1), X2
1069 MOVOU -80(AX)(CX*1), X3
1070 MOVOU -64(AX)(CX*1), X4
1071 MOVOU -48(AX)(CX*1), X5
1072 MOVOU -32(AX)(CX*1), X8
1073 MOVOU -16(AX)(CX*1), X9
1074
1075 // scramble state once
1076 AESENC X6, X0
1077 AESENC runtime·aeskeysched+16(SB), X1
1078 AESENC runtime·aeskeysched+32(SB), X2
1079 AESENC runtime·aeskeysched+48(SB), X3
1080 AESENC runtime·aeskeysched+64(SB), X4
1081 AESENC runtime·aeskeysched+80(SB), X5
1082 AESENC runtime·aeskeysched+96(SB), X8
1083 AESENC runtime·aeskeysched+112(SB), X9
1084
1085 // compute number of remaining 128-byte blocks
1086 DECQ CX
1087 SHRQ $7, CX
1088
1089aesloop:
1090 // scramble state, xor in a block
1091 MOVOU (AX), X10
1092 MOVOU 16(AX), X11
1093 MOVOU 32(AX), X12
1094 MOVOU 48(AX), X13
1095 AESENC X10, X0
1096 AESENC X11, X1
1097 AESENC X12, X2
1098 AESENC X13, X3
1099 MOVOU 64(AX), X10
1100 MOVOU 80(AX), X11
1101 MOVOU 96(AX), X12
1102 MOVOU 112(AX), X13
1103 AESENC X10, X4
1104 AESENC X11, X5
1105 AESENC X12, X8
1106 AESENC X13, X9
1107
1108 // scramble state
1109 AESENC X7, X0
1110 AESENC X7, X1
1111 AESENC X7, X2
1112 AESENC X7, X3
1113 AESENC X7, X4
1114 AESENC X7, X5
1115 AESENC X7, X8
1116 AESENC X7, X9
1117
1118 ADDQ $128, AX
1119 DECQ CX
1120 JNE aesloop
1121
1122 // 2 more scrambles to finish
1123 AESENC X7, X0
1124 AESENC X7, X1
1125 AESENC X7, X2
1126 AESENC X7, X3
1127 AESENC X7, X4
1128 AESENC X7, X5
1129 AESENC X7, X8
1130 AESENC X7, X9
1131 AESENC X7, X0
1132 AESENC X7, X1
1133 AESENC X7, X2
1134 AESENC X7, X3
1135 AESENC X7, X4
1136 AESENC X7, X5
1137 AESENC X7, X8
1138 AESENC X7, X9
1139
1140 PXOR X4, X0
1141 PXOR X5, X1
1142 PXOR X8, X2
1143 PXOR X9, X3
1144 PXOR X2, X0
1145 PXOR X3, X1
1146 PXOR X1, X0
Keith Randalld5e4c402015-01-06 16:42:48 -08001147 MOVQ X0, (DX)
Keith Randall7a4a64e2014-12-10 14:20:17 -08001148 RET
1149
Keith Randalld5e4c402015-01-06 16:42:48 -08001150TEXT runtime·aeshash32(SB),NOSPLIT,$0-24
Keith Randalla2a97682014-07-31 15:07:05 -07001151 MOVQ p+0(FP), AX // ptr to data
Keith Randalld5e4c402015-01-06 16:42:48 -08001152 MOVQ h+8(FP), X0 // seed
Keith Randalla5d40242013-03-12 10:47:44 -07001153 PINSRD $2, (AX), X0 // data
Keith Randalldb53d972013-03-20 14:34:26 -07001154 AESENC runtime·aeskeysched+0(SB), X0
1155 AESENC runtime·aeskeysched+16(SB), X0
Keith Randall7a4a64e2014-12-10 14:20:17 -08001156 AESENC runtime·aeskeysched+32(SB), X0
Keith Randalld5e4c402015-01-06 16:42:48 -08001157 MOVQ X0, ret+16(FP)
Keith Randalla5d40242013-03-12 10:47:44 -07001158 RET
1159
Keith Randalld5e4c402015-01-06 16:42:48 -08001160TEXT runtime·aeshash64(SB),NOSPLIT,$0-24
Keith Randalla2a97682014-07-31 15:07:05 -07001161 MOVQ p+0(FP), AX // ptr to data
Keith Randalld5e4c402015-01-06 16:42:48 -08001162 MOVQ h+8(FP), X0 // seed
Keith Randalla5d40242013-03-12 10:47:44 -07001163 PINSRQ $1, (AX), X0 // data
Keith Randalldb53d972013-03-20 14:34:26 -07001164 AESENC runtime·aeskeysched+0(SB), X0
1165 AESENC runtime·aeskeysched+16(SB), X0
Keith Randall7a4a64e2014-12-10 14:20:17 -08001166 AESENC runtime·aeskeysched+32(SB), X0
Keith Randalld5e4c402015-01-06 16:42:48 -08001167 MOVQ X0, ret+16(FP)
Keith Randalla5d40242013-03-12 10:47:44 -07001168 RET
1169
1170// simple mask to get rid of data in the high part of the register.
Russ Cox9ddfb642013-07-16 16:24:09 -04001171DATA masks<>+0x00(SB)/8, $0x0000000000000000
1172DATA masks<>+0x08(SB)/8, $0x0000000000000000
1173DATA masks<>+0x10(SB)/8, $0x00000000000000ff
1174DATA masks<>+0x18(SB)/8, $0x0000000000000000
1175DATA masks<>+0x20(SB)/8, $0x000000000000ffff
1176DATA masks<>+0x28(SB)/8, $0x0000000000000000
1177DATA masks<>+0x30(SB)/8, $0x0000000000ffffff
1178DATA masks<>+0x38(SB)/8, $0x0000000000000000
1179DATA masks<>+0x40(SB)/8, $0x00000000ffffffff
1180DATA masks<>+0x48(SB)/8, $0x0000000000000000
1181DATA masks<>+0x50(SB)/8, $0x000000ffffffffff
1182DATA masks<>+0x58(SB)/8, $0x0000000000000000
1183DATA masks<>+0x60(SB)/8, $0x0000ffffffffffff
1184DATA masks<>+0x68(SB)/8, $0x0000000000000000
1185DATA masks<>+0x70(SB)/8, $0x00ffffffffffffff
1186DATA masks<>+0x78(SB)/8, $0x0000000000000000
1187DATA masks<>+0x80(SB)/8, $0xffffffffffffffff
1188DATA masks<>+0x88(SB)/8, $0x0000000000000000
1189DATA masks<>+0x90(SB)/8, $0xffffffffffffffff
1190DATA masks<>+0x98(SB)/8, $0x00000000000000ff
1191DATA masks<>+0xa0(SB)/8, $0xffffffffffffffff
1192DATA masks<>+0xa8(SB)/8, $0x000000000000ffff
1193DATA masks<>+0xb0(SB)/8, $0xffffffffffffffff
1194DATA masks<>+0xb8(SB)/8, $0x0000000000ffffff
1195DATA masks<>+0xc0(SB)/8, $0xffffffffffffffff
1196DATA masks<>+0xc8(SB)/8, $0x00000000ffffffff
1197DATA masks<>+0xd0(SB)/8, $0xffffffffffffffff
1198DATA masks<>+0xd8(SB)/8, $0x000000ffffffffff
1199DATA masks<>+0xe0(SB)/8, $0xffffffffffffffff
1200DATA masks<>+0xe8(SB)/8, $0x0000ffffffffffff
1201DATA masks<>+0xf0(SB)/8, $0xffffffffffffffff
1202DATA masks<>+0xf8(SB)/8, $0x00ffffffffffffff
Keith Randall5a546962013-08-07 10:23:24 -07001203GLOBL masks<>(SB),RODATA,$256
Keith Randalla5d40242013-03-12 10:47:44 -07001204
Russ Cox9ddfb642013-07-16 16:24:09 -04001205// these are arguments to pshufb. They move data down from
1206// the high bytes of the register to the low bytes of the register.
1207// index is how many bytes to move.
1208DATA shifts<>+0x00(SB)/8, $0x0000000000000000
1209DATA shifts<>+0x08(SB)/8, $0x0000000000000000
1210DATA shifts<>+0x10(SB)/8, $0xffffffffffffff0f
1211DATA shifts<>+0x18(SB)/8, $0xffffffffffffffff
1212DATA shifts<>+0x20(SB)/8, $0xffffffffffff0f0e
1213DATA shifts<>+0x28(SB)/8, $0xffffffffffffffff
1214DATA shifts<>+0x30(SB)/8, $0xffffffffff0f0e0d
1215DATA shifts<>+0x38(SB)/8, $0xffffffffffffffff
1216DATA shifts<>+0x40(SB)/8, $0xffffffff0f0e0d0c
1217DATA shifts<>+0x48(SB)/8, $0xffffffffffffffff
1218DATA shifts<>+0x50(SB)/8, $0xffffff0f0e0d0c0b
1219DATA shifts<>+0x58(SB)/8, $0xffffffffffffffff
1220DATA shifts<>+0x60(SB)/8, $0xffff0f0e0d0c0b0a
1221DATA shifts<>+0x68(SB)/8, $0xffffffffffffffff
1222DATA shifts<>+0x70(SB)/8, $0xff0f0e0d0c0b0a09
1223DATA shifts<>+0x78(SB)/8, $0xffffffffffffffff
1224DATA shifts<>+0x80(SB)/8, $0x0f0e0d0c0b0a0908
1225DATA shifts<>+0x88(SB)/8, $0xffffffffffffffff
1226DATA shifts<>+0x90(SB)/8, $0x0e0d0c0b0a090807
1227DATA shifts<>+0x98(SB)/8, $0xffffffffffffff0f
1228DATA shifts<>+0xa0(SB)/8, $0x0d0c0b0a09080706
1229DATA shifts<>+0xa8(SB)/8, $0xffffffffffff0f0e
1230DATA shifts<>+0xb0(SB)/8, $0x0c0b0a0908070605
1231DATA shifts<>+0xb8(SB)/8, $0xffffffffff0f0e0d
1232DATA shifts<>+0xc0(SB)/8, $0x0b0a090807060504
1233DATA shifts<>+0xc8(SB)/8, $0xffffffff0f0e0d0c
1234DATA shifts<>+0xd0(SB)/8, $0x0a09080706050403
1235DATA shifts<>+0xd8(SB)/8, $0xffffff0f0e0d0c0b
1236DATA shifts<>+0xe0(SB)/8, $0x0908070605040302
1237DATA shifts<>+0xe8(SB)/8, $0xffff0f0e0d0c0b0a
1238DATA shifts<>+0xf0(SB)/8, $0x0807060504030201
1239DATA shifts<>+0xf8(SB)/8, $0xff0f0e0d0c0b0a09
Keith Randall5a546962013-08-07 10:23:24 -07001240GLOBL shifts<>(SB),RODATA,$256
Keith Randall3d5daa22013-04-02 16:26:15 -07001241
Keith Randall7aa4e5a2014-08-07 14:52:55 -07001242TEXT runtime·memeq(SB),NOSPLIT,$0-25
Keith Randall0c6b55e2014-07-16 14:16:19 -07001243 MOVQ a+0(FP), SI
1244 MOVQ b+8(FP), DI
1245 MOVQ size+16(FP), BX
1246 CALL runtime·memeqbody(SB)
1247 MOVB AX, ret+24(FP)
1248 RET
1249
Keith Randalld5e4c402015-01-06 16:42:48 -08001250// memequal_varlen(a, b unsafe.Pointer) bool
1251TEXT runtime·memequal_varlen(SB),NOSPLIT,$0-17
1252 MOVQ a+0(FP), SI
1253 MOVQ b+8(FP), DI
1254 CMPQ SI, DI
1255 JEQ eq
1256 MOVQ 8(DX), BX // compiler stores size at offset 8 in the closure
1257 CALL runtime·memeqbody(SB)
1258 MOVB AX, ret+16(FP)
1259 RET
1260eq:
1261 MOVB $1, ret+16(FP)
1262 RET
1263
Keith Randallb36ed902014-06-16 21:00:37 -07001264// eqstring tests whether two strings are equal.
1265// See runtime_test.go:eqstring_generic for
Josh Bleecher Snyder339a24d2014-08-19 08:50:35 -07001266// equivalent Go code.
Keith Randallb36ed902014-06-16 21:00:37 -07001267TEXT runtime·eqstring(SB),NOSPLIT,$0-33
1268 MOVQ s1len+8(FP), AX
1269 MOVQ s2len+24(FP), BX
1270 CMPQ AX, BX
Russ Coxb55791e2014-10-28 21:50:16 -04001271 JNE noteq
Keith Randallb36ed902014-06-16 21:00:37 -07001272 MOVQ s1str+0(FP), SI
1273 MOVQ s2str+16(FP), DI
1274 CMPQ SI, DI
Russ Coxb55791e2014-10-28 21:50:16 -04001275 JEQ eq
Keith Randallb36ed902014-06-16 21:00:37 -07001276 CALL runtime·memeqbody(SB)
1277 MOVB AX, v+32(FP)
1278 RET
Russ Coxb55791e2014-10-28 21:50:16 -04001279eq:
Keith Randallb36ed902014-06-16 21:00:37 -07001280 MOVB $1, v+32(FP)
1281 RET
Russ Coxb55791e2014-10-28 21:50:16 -04001282noteq:
Keith Randallb36ed902014-06-16 21:00:37 -07001283 MOVB $0, v+32(FP)
1284 RET
1285
Keith Randall3d5daa22013-04-02 16:26:15 -07001286// a in SI
1287// b in DI
1288// count in BX
Keith Randall5a546962013-08-07 10:23:24 -07001289TEXT runtime·memeqbody(SB),NOSPLIT,$0-0
Keith Randall3d5daa22013-04-02 16:26:15 -07001290 XORQ AX, AX
1291
1292 CMPQ BX, $8
1293 JB small
1294
1295 // 64 bytes at a time using xmm registers
1296hugeloop:
1297 CMPQ BX, $64
1298 JB bigloop
1299 MOVOU (SI), X0
1300 MOVOU (DI), X1
1301 MOVOU 16(SI), X2
1302 MOVOU 16(DI), X3
1303 MOVOU 32(SI), X4
1304 MOVOU 32(DI), X5
1305 MOVOU 48(SI), X6
1306 MOVOU 48(DI), X7
1307 PCMPEQB X1, X0
1308 PCMPEQB X3, X2
1309 PCMPEQB X5, X4
1310 PCMPEQB X7, X6
1311 PAND X2, X0
1312 PAND X6, X4
1313 PAND X4, X0
1314 PMOVMSKB X0, DX
1315 ADDQ $64, SI
1316 ADDQ $64, DI
1317 SUBQ $64, BX
1318 CMPL DX, $0xffff
1319 JEQ hugeloop
1320 RET
1321
1322 // 8 bytes at a time using 64-bit register
1323bigloop:
1324 CMPQ BX, $8
1325 JBE leftover
1326 MOVQ (SI), CX
1327 MOVQ (DI), DX
1328 ADDQ $8, SI
1329 ADDQ $8, DI
1330 SUBQ $8, BX
1331 CMPQ CX, DX
1332 JEQ bigloop
1333 RET
1334
1335 // remaining 0-8 bytes
1336leftover:
1337 MOVQ -8(SI)(BX*1), CX
1338 MOVQ -8(DI)(BX*1), DX
1339 CMPQ CX, DX
1340 SETEQ AX
1341 RET
1342
1343small:
1344 CMPQ BX, $0
1345 JEQ equal
1346
1347 LEAQ 0(BX*8), CX
1348 NEGQ CX
1349
1350 CMPB SI, $0xf8
1351 JA si_high
1352
1353 // load at SI won't cross a page boundary.
1354 MOVQ (SI), SI
1355 JMP si_finish
1356si_high:
1357 // address ends in 11111xxx. Load up to bytes we want, move to correct position.
1358 MOVQ -8(SI)(BX*1), SI
1359 SHRQ CX, SI
1360si_finish:
1361
1362 // same for DI.
1363 CMPB DI, $0xf8
1364 JA di_high
1365 MOVQ (DI), DI
1366 JMP di_finish
1367di_high:
1368 MOVQ -8(DI)(BX*1), DI
1369 SHRQ CX, DI
1370di_finish:
1371
1372 SUBQ SI, DI
1373 SHLQ CX, DI
1374equal:
1375 SETEQ AX
1376 RET
Keith Randallb3946dc2013-05-14 16:05:51 -07001377
Keith Randall5a546962013-08-07 10:23:24 -07001378TEXT runtime·cmpstring(SB),NOSPLIT,$0-40
Russ Cox25f6b022014-08-27 11:32:17 -04001379 MOVQ s1_base+0(FP), SI
1380 MOVQ s1_len+8(FP), BX
1381 MOVQ s2_base+16(FP), DI
1382 MOVQ s2_len+24(FP), DX
Keith Randallb3946dc2013-05-14 16:05:51 -07001383 CALL runtime·cmpbody(SB)
Russ Cox25f6b022014-08-27 11:32:17 -04001384 MOVQ AX, ret+32(FP)
Keith Randallb3946dc2013-05-14 16:05:51 -07001385 RET
1386
Russ Cox7a524a12014-12-22 13:27:53 -05001387TEXT bytes·Compare(SB),NOSPLIT,$0-56
Keith Randallb3946dc2013-05-14 16:05:51 -07001388 MOVQ s1+0(FP), SI
1389 MOVQ s1+8(FP), BX
1390 MOVQ s2+24(FP), DI
1391 MOVQ s2+32(FP), DX
1392 CALL runtime·cmpbody(SB)
1393 MOVQ AX, res+48(FP)
1394 RET
1395
1396// input:
1397// SI = a
1398// DI = b
1399// BX = alen
1400// DX = blen
1401// output:
1402// AX = 1/0/-1
Keith Randall5a546962013-08-07 10:23:24 -07001403TEXT runtime·cmpbody(SB),NOSPLIT,$0-0
Keith Randallb3946dc2013-05-14 16:05:51 -07001404 CMPQ SI, DI
Russ Coxb55791e2014-10-28 21:50:16 -04001405 JEQ allsame
Keith Randallb3946dc2013-05-14 16:05:51 -07001406 CMPQ BX, DX
Austin Clements20a6ff72015-01-27 18:29:02 -05001407 MOVQ DX, R8
1408 CMOVQLT BX, R8 // R8 = min(alen, blen) = # of bytes to compare
1409 CMPQ R8, $8
Russ Coxb55791e2014-10-28 21:50:16 -04001410 JB small
Keith Randallb3946dc2013-05-14 16:05:51 -07001411
Russ Coxb55791e2014-10-28 21:50:16 -04001412loop:
Austin Clements20a6ff72015-01-27 18:29:02 -05001413 CMPQ R8, $16
Russ Coxb55791e2014-10-28 21:50:16 -04001414 JBE _0through16
Keith Randallb3946dc2013-05-14 16:05:51 -07001415 MOVOU (SI), X0
1416 MOVOU (DI), X1
1417 PCMPEQB X0, X1
1418 PMOVMSKB X1, AX
1419 XORQ $0xffff, AX // convert EQ to NE
Russ Coxb55791e2014-10-28 21:50:16 -04001420 JNE diff16 // branch if at least one byte is not equal
Keith Randallb3946dc2013-05-14 16:05:51 -07001421 ADDQ $16, SI
1422 ADDQ $16, DI
Austin Clements20a6ff72015-01-27 18:29:02 -05001423 SUBQ $16, R8
Russ Coxb55791e2014-10-28 21:50:16 -04001424 JMP loop
Keith Randallb3946dc2013-05-14 16:05:51 -07001425
1426 // AX = bit mask of differences
Russ Coxb55791e2014-10-28 21:50:16 -04001427diff16:
Keith Randallb3946dc2013-05-14 16:05:51 -07001428 BSFQ AX, BX // index of first byte that differs
1429 XORQ AX, AX
1430 MOVB (SI)(BX*1), CX
1431 CMPB CX, (DI)(BX*1)
1432 SETHI AX
1433 LEAQ -1(AX*2), AX // convert 1/0 to +1/-1
1434 RET
1435
1436 // 0 through 16 bytes left, alen>=8, blen>=8
Russ Coxb55791e2014-10-28 21:50:16 -04001437_0through16:
Austin Clements20a6ff72015-01-27 18:29:02 -05001438 CMPQ R8, $8
Russ Coxb55791e2014-10-28 21:50:16 -04001439 JBE _0through8
Keith Randallb3946dc2013-05-14 16:05:51 -07001440 MOVQ (SI), AX
1441 MOVQ (DI), CX
1442 CMPQ AX, CX
Russ Coxb55791e2014-10-28 21:50:16 -04001443 JNE diff8
1444_0through8:
Austin Clements20a6ff72015-01-27 18:29:02 -05001445 MOVQ -8(SI)(R8*1), AX
1446 MOVQ -8(DI)(R8*1), CX
Keith Randallb3946dc2013-05-14 16:05:51 -07001447 CMPQ AX, CX
Russ Coxb55791e2014-10-28 21:50:16 -04001448 JEQ allsame
Keith Randallb3946dc2013-05-14 16:05:51 -07001449
1450 // AX and CX contain parts of a and b that differ.
Russ Coxb55791e2014-10-28 21:50:16 -04001451diff8:
Keith Randallb3946dc2013-05-14 16:05:51 -07001452 BSWAPQ AX // reverse order of bytes
1453 BSWAPQ CX
1454 XORQ AX, CX
1455 BSRQ CX, CX // index of highest bit difference
1456 SHRQ CX, AX // move a's bit to bottom
1457 ANDQ $1, AX // mask bit
1458 LEAQ -1(AX*2), AX // 1/0 => +1/-1
1459 RET
1460
1461 // 0-7 bytes in common
Russ Coxb55791e2014-10-28 21:50:16 -04001462small:
Austin Clements20a6ff72015-01-27 18:29:02 -05001463 LEAQ (R8*8), CX // bytes left -> bits left
Keith Randallb3946dc2013-05-14 16:05:51 -07001464 NEGQ CX // - bits lift (== 64 - bits left mod 64)
Russ Coxb55791e2014-10-28 21:50:16 -04001465 JEQ allsame
Keith Randallb3946dc2013-05-14 16:05:51 -07001466
1467 // load bytes of a into high bytes of AX
1468 CMPB SI, $0xf8
Russ Coxb55791e2014-10-28 21:50:16 -04001469 JA si_high
Keith Randallb3946dc2013-05-14 16:05:51 -07001470 MOVQ (SI), SI
Russ Coxb55791e2014-10-28 21:50:16 -04001471 JMP si_finish
1472si_high:
Austin Clements20a6ff72015-01-27 18:29:02 -05001473 MOVQ -8(SI)(R8*1), SI
Keith Randallb3946dc2013-05-14 16:05:51 -07001474 SHRQ CX, SI
Russ Coxb55791e2014-10-28 21:50:16 -04001475si_finish:
Keith Randallb3946dc2013-05-14 16:05:51 -07001476 SHLQ CX, SI
1477
1478 // load bytes of b in to high bytes of BX
1479 CMPB DI, $0xf8
Russ Coxb55791e2014-10-28 21:50:16 -04001480 JA di_high
Keith Randallb3946dc2013-05-14 16:05:51 -07001481 MOVQ (DI), DI
Russ Coxb55791e2014-10-28 21:50:16 -04001482 JMP di_finish
1483di_high:
Austin Clements20a6ff72015-01-27 18:29:02 -05001484 MOVQ -8(DI)(R8*1), DI
Keith Randallb3946dc2013-05-14 16:05:51 -07001485 SHRQ CX, DI
Russ Coxb55791e2014-10-28 21:50:16 -04001486di_finish:
Keith Randallb3946dc2013-05-14 16:05:51 -07001487 SHLQ CX, DI
1488
1489 BSWAPQ SI // reverse order of bytes
1490 BSWAPQ DI
1491 XORQ SI, DI // find bit differences
Russ Coxb55791e2014-10-28 21:50:16 -04001492 JEQ allsame
Keith Randallb3946dc2013-05-14 16:05:51 -07001493 BSRQ DI, CX // index of highest bit difference
1494 SHRQ CX, SI // move a's bit to bottom
1495 ANDQ $1, SI // mask bit
1496 LEAQ -1(SI*2), AX // 1/0 => +1/-1
1497 RET
1498
Russ Coxb55791e2014-10-28 21:50:16 -04001499allsame:
Keith Randallb3946dc2013-05-14 16:05:51 -07001500 XORQ AX, AX
1501 XORQ CX, CX
1502 CMPQ BX, DX
1503 SETGT AX // 1 if alen > blen
1504 SETEQ CX // 1 if alen == blen
1505 LEAQ -1(CX)(AX*2), AX // 1,0,-1 result
1506 RET
Brad Fitzpatricke2a1bd62013-08-01 16:11:19 -07001507
Keith Randall5a546962013-08-07 10:23:24 -07001508TEXT bytes·IndexByte(SB),NOSPLIT,$0
Brad Fitzpatricke2a1bd62013-08-01 16:11:19 -07001509 MOVQ s+0(FP), SI
1510 MOVQ s_len+8(FP), BX
1511 MOVB c+24(FP), AL
Brad Fitzpatrick598c7892013-08-05 15:04:05 -07001512 CALL runtime·indexbytebody(SB)
1513 MOVQ AX, ret+32(FP)
1514 RET
1515
Keith Randall5a546962013-08-07 10:23:24 -07001516TEXT strings·IndexByte(SB),NOSPLIT,$0
Brad Fitzpatrick598c7892013-08-05 15:04:05 -07001517 MOVQ s+0(FP), SI
1518 MOVQ s_len+8(FP), BX
1519 MOVB c+16(FP), AL
1520 CALL runtime·indexbytebody(SB)
1521 MOVQ AX, ret+24(FP)
1522 RET
1523
1524// input:
1525// SI: data
1526// BX: data len
1527// AL: byte sought
1528// output:
1529// AX
Keith Randall5a546962013-08-07 10:23:24 -07001530TEXT runtime·indexbytebody(SB),NOSPLIT,$0
Brad Fitzpatricke2a1bd62013-08-01 16:11:19 -07001531 MOVQ SI, DI
1532
1533 CMPQ BX, $16
Russ Coxb55791e2014-10-28 21:50:16 -04001534 JLT small
Brad Fitzpatricke2a1bd62013-08-01 16:11:19 -07001535
1536 // round up to first 16-byte boundary
1537 TESTQ $15, SI
1538 JZ aligned
1539 MOVQ SI, CX
1540 ANDQ $~15, CX
1541 ADDQ $16, CX
1542
1543 // search the beginning
1544 SUBQ SI, CX
1545 REPN; SCASB
1546 JZ success
1547
1548// DI is 16-byte aligned; get ready to search using SSE instructions
1549aligned:
1550 // round down to last 16-byte boundary
1551 MOVQ BX, R11
1552 ADDQ SI, R11
1553 ANDQ $~15, R11
1554
1555 // shuffle X0 around so that each byte contains c
1556 MOVD AX, X0
1557 PUNPCKLBW X0, X0
1558 PUNPCKLBW X0, X0
1559 PSHUFL $0, X0, X0
1560 JMP condition
1561
1562sse:
1563 // move the next 16-byte chunk of the buffer into X1
1564 MOVO (DI), X1
1565 // compare bytes in X0 to X1
1566 PCMPEQB X0, X1
1567 // take the top bit of each byte in X1 and put the result in DX
1568 PMOVMSKB X1, DX
1569 TESTL DX, DX
1570 JNZ ssesuccess
1571 ADDQ $16, DI
1572
1573condition:
1574 CMPQ DI, R11
1575 JLT sse
1576
1577 // search the end
1578 MOVQ SI, CX
1579 ADDQ BX, CX
1580 SUBQ R11, CX
1581 // if CX == 0, the zero flag will be set and we'll end up
1582 // returning a false success
1583 JZ failure
1584 REPN; SCASB
1585 JZ success
1586
1587failure:
Brad Fitzpatrick598c7892013-08-05 15:04:05 -07001588 MOVQ $-1, AX
Brad Fitzpatricke2a1bd62013-08-01 16:11:19 -07001589 RET
1590
1591// handle for lengths < 16
Russ Coxb55791e2014-10-28 21:50:16 -04001592small:
Brad Fitzpatricke2a1bd62013-08-01 16:11:19 -07001593 MOVQ BX, CX
1594 REPN; SCASB
1595 JZ success
Brad Fitzpatrick598c7892013-08-05 15:04:05 -07001596 MOVQ $-1, AX
Brad Fitzpatricke2a1bd62013-08-01 16:11:19 -07001597 RET
1598
1599// we've found the chunk containing the byte
1600// now just figure out which specific byte it is
1601ssesuccess:
1602 // get the index of the least significant set bit
1603 BSFW DX, DX
1604 SUBQ SI, DI
1605 ADDQ DI, DX
Brad Fitzpatrick598c7892013-08-05 15:04:05 -07001606 MOVQ DX, AX
Brad Fitzpatricke2a1bd62013-08-01 16:11:19 -07001607 RET
1608
1609success:
1610 SUBQ SI, DI
1611 SUBL $1, DI
Brad Fitzpatrick598c7892013-08-05 15:04:05 -07001612 MOVQ DI, AX
Brad Fitzpatricke2a1bd62013-08-01 16:11:19 -07001613 RET
1614
Keith Randall5a546962013-08-07 10:23:24 -07001615TEXT bytes·Equal(SB),NOSPLIT,$0-49
Brad Fitzpatricke2a1bd62013-08-01 16:11:19 -07001616 MOVQ a_len+8(FP), BX
1617 MOVQ b_len+32(FP), CX
1618 XORQ AX, AX
1619 CMPQ BX, CX
1620 JNE eqret
1621 MOVQ a+0(FP), SI
1622 MOVQ b+24(FP), DI
1623 CALL runtime·memeqbody(SB)
1624eqret:
1625 MOVB AX, ret+48(FP)
1626 RET
Keith Randall6c7cbf02014-04-01 12:51:02 -07001627
1628// A Duff's device for zeroing memory.
1629// The compiler jumps to computed addresses within
1630// this routine to zero chunks of memory. Do not
1631// change this code without also changing the code
1632// in ../../cmd/6g/ggen.c:clearfat.
1633// AX: zero
1634// DI: ptr to memory to be zeroed
1635// DI is updated as a side effect.
1636TEXT runtime·duffzero(SB), NOSPLIT, $0-0
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 STOSQ
1684 STOSQ
1685 STOSQ
1686 STOSQ
1687 STOSQ
1688 STOSQ
1689 STOSQ
1690 STOSQ
1691 STOSQ
1692 STOSQ
1693 STOSQ
1694 STOSQ
1695 STOSQ
1696 STOSQ
1697 STOSQ
1698 STOSQ
1699 STOSQ
1700 STOSQ
1701 STOSQ
1702 STOSQ
1703 STOSQ
1704 STOSQ
1705 STOSQ
1706 STOSQ
1707 STOSQ
1708 STOSQ
1709 STOSQ
1710 STOSQ
1711 STOSQ
1712 STOSQ
1713 STOSQ
1714 STOSQ
1715 STOSQ
1716 STOSQ
1717 STOSQ
1718 STOSQ
1719 STOSQ
1720 STOSQ
1721 STOSQ
1722 STOSQ
1723 STOSQ
1724 STOSQ
1725 STOSQ
1726 STOSQ
1727 STOSQ
1728 STOSQ
1729 STOSQ
1730 STOSQ
1731 STOSQ
1732 STOSQ
1733 STOSQ
1734 STOSQ
1735 STOSQ
1736 STOSQ
1737 STOSQ
1738 STOSQ
1739 STOSQ
1740 STOSQ
1741 STOSQ
1742 STOSQ
1743 STOSQ
1744 STOSQ
1745 STOSQ
1746 STOSQ
1747 STOSQ
1748 STOSQ
1749 STOSQ
1750 STOSQ
1751 STOSQ
1752 STOSQ
1753 STOSQ
1754 STOSQ
1755 STOSQ
1756 STOSQ
1757 STOSQ
1758 STOSQ
1759 STOSQ
1760 STOSQ
1761 STOSQ
1762 STOSQ
1763 STOSQ
1764 STOSQ
1765 RET
1766
1767// A Duff's device for copying memory.
1768// The compiler jumps to computed addresses within
1769// this routine to copy chunks of memory. Source
1770// and destination must not overlap. Do not
1771// change this code without also changing the code
1772// in ../../cmd/6g/cgen.c:sgen.
1773// SI: ptr to source memory
1774// DI: ptr to destination memory
1775// SI and DI are updated as a side effect.
1776
1777// NOTE: this is equivalent to a sequence of MOVSQ but
1778// for some reason that is 3.5x slower than this code.
1779// The STOSQ above seem fine, though.
1780TEXT runtime·duffcopy(SB), NOSPLIT, $0-0
1781 MOVQ (SI),CX
1782 ADDQ $8,SI
1783 MOVQ CX,(DI)
1784 ADDQ $8,DI
1785
1786 MOVQ (SI),CX
1787 ADDQ $8,SI
1788 MOVQ CX,(DI)
1789 ADDQ $8,DI
1790
1791 MOVQ (SI),CX
1792 ADDQ $8,SI
1793 MOVQ CX,(DI)
1794 ADDQ $8,DI
1795
1796 MOVQ (SI),CX
1797 ADDQ $8,SI
1798 MOVQ CX,(DI)
1799 ADDQ $8,DI
1800
1801 MOVQ (SI),CX
1802 ADDQ $8,SI
1803 MOVQ CX,(DI)
1804 ADDQ $8,DI
1805
1806 MOVQ (SI),CX
1807 ADDQ $8,SI
1808 MOVQ CX,(DI)
1809 ADDQ $8,DI
1810
1811 MOVQ (SI),CX
1812 ADDQ $8,SI
1813 MOVQ CX,(DI)
1814 ADDQ $8,DI
1815
1816 MOVQ (SI),CX
1817 ADDQ $8,SI
1818 MOVQ CX,(DI)
1819 ADDQ $8,DI
1820
1821 MOVQ (SI),CX
1822 ADDQ $8,SI
1823 MOVQ CX,(DI)
1824 ADDQ $8,DI
1825
1826 MOVQ (SI),CX
1827 ADDQ $8,SI
1828 MOVQ CX,(DI)
1829 ADDQ $8,DI
1830
1831 MOVQ (SI),CX
1832 ADDQ $8,SI
1833 MOVQ CX,(DI)
1834 ADDQ $8,DI
1835
1836 MOVQ (SI),CX
1837 ADDQ $8,SI
1838 MOVQ CX,(DI)
1839 ADDQ $8,DI
1840
1841 MOVQ (SI),CX
1842 ADDQ $8,SI
1843 MOVQ CX,(DI)
1844 ADDQ $8,DI
1845
1846 MOVQ (SI),CX
1847 ADDQ $8,SI
1848 MOVQ CX,(DI)
1849 ADDQ $8,DI
1850
1851 MOVQ (SI),CX
1852 ADDQ $8,SI
1853 MOVQ CX,(DI)
1854 ADDQ $8,DI
1855
1856 MOVQ (SI),CX
1857 ADDQ $8,SI
1858 MOVQ CX,(DI)
1859 ADDQ $8,DI
1860
1861 MOVQ (SI),CX
1862 ADDQ $8,SI
1863 MOVQ CX,(DI)
1864 ADDQ $8,DI
1865
1866 MOVQ (SI),CX
1867 ADDQ $8,SI
1868 MOVQ CX,(DI)
1869 ADDQ $8,DI
1870
1871 MOVQ (SI),CX
1872 ADDQ $8,SI
1873 MOVQ CX,(DI)
1874 ADDQ $8,DI
1875
1876 MOVQ (SI),CX
1877 ADDQ $8,SI
1878 MOVQ CX,(DI)
1879 ADDQ $8,DI
1880
1881 MOVQ (SI),CX
1882 ADDQ $8,SI
1883 MOVQ CX,(DI)
1884 ADDQ $8,DI
1885
1886 MOVQ (SI),CX
1887 ADDQ $8,SI
1888 MOVQ CX,(DI)
1889 ADDQ $8,DI
1890
1891 MOVQ (SI),CX
1892 ADDQ $8,SI
1893 MOVQ CX,(DI)
1894 ADDQ $8,DI
1895
1896 MOVQ (SI),CX
1897 ADDQ $8,SI
1898 MOVQ CX,(DI)
1899 ADDQ $8,DI
1900
1901 MOVQ (SI),CX
1902 ADDQ $8,SI
1903 MOVQ CX,(DI)
1904 ADDQ $8,DI
1905
1906 MOVQ (SI),CX
1907 ADDQ $8,SI
1908 MOVQ CX,(DI)
1909 ADDQ $8,DI
1910
1911 MOVQ (SI),CX
1912 ADDQ $8,SI
1913 MOVQ CX,(DI)
1914 ADDQ $8,DI
1915
1916 MOVQ (SI),CX
1917 ADDQ $8,SI
1918 MOVQ CX,(DI)
1919 ADDQ $8,DI
1920
1921 MOVQ (SI),CX
1922 ADDQ $8,SI
1923 MOVQ CX,(DI)
1924 ADDQ $8,DI
1925
1926 MOVQ (SI),CX
1927 ADDQ $8,SI
1928 MOVQ CX,(DI)
1929 ADDQ $8,DI
1930
1931 MOVQ (SI),CX
1932 ADDQ $8,SI
1933 MOVQ CX,(DI)
1934 ADDQ $8,DI
1935
1936 MOVQ (SI),CX
1937 ADDQ $8,SI
1938 MOVQ CX,(DI)
1939 ADDQ $8,DI
1940
1941 MOVQ (SI),CX
1942 ADDQ $8,SI
1943 MOVQ CX,(DI)
1944 ADDQ $8,DI
1945
1946 MOVQ (SI),CX
1947 ADDQ $8,SI
1948 MOVQ CX,(DI)
1949 ADDQ $8,DI
1950
1951 MOVQ (SI),CX
1952 ADDQ $8,SI
1953 MOVQ CX,(DI)
1954 ADDQ $8,DI
1955
1956 MOVQ (SI),CX
1957 ADDQ $8,SI
1958 MOVQ CX,(DI)
1959 ADDQ $8,DI
1960
1961 MOVQ (SI),CX
1962 ADDQ $8,SI
1963 MOVQ CX,(DI)
1964 ADDQ $8,DI
1965
1966 MOVQ (SI),CX
1967 ADDQ $8,SI
1968 MOVQ CX,(DI)
1969 ADDQ $8,DI
1970
1971 MOVQ (SI),CX
1972 ADDQ $8,SI
1973 MOVQ CX,(DI)
1974 ADDQ $8,DI
1975
1976 MOVQ (SI),CX
1977 ADDQ $8,SI
1978 MOVQ CX,(DI)
1979 ADDQ $8,DI
1980
1981 MOVQ (SI),CX
1982 ADDQ $8,SI
1983 MOVQ CX,(DI)
1984 ADDQ $8,DI
1985
1986 MOVQ (SI),CX
1987 ADDQ $8,SI
1988 MOVQ CX,(DI)
1989 ADDQ $8,DI
1990
1991 MOVQ (SI),CX
1992 ADDQ $8,SI
1993 MOVQ CX,(DI)
1994 ADDQ $8,DI
1995
1996 MOVQ (SI),CX
1997 ADDQ $8,SI
1998 MOVQ CX,(DI)
1999 ADDQ $8,DI
2000
2001 MOVQ (SI),CX
2002 ADDQ $8,SI
2003 MOVQ CX,(DI)
2004 ADDQ $8,DI
2005
2006 MOVQ (SI),CX
2007 ADDQ $8,SI
2008 MOVQ CX,(DI)
2009 ADDQ $8,DI
2010
2011 MOVQ (SI),CX
2012 ADDQ $8,SI
2013 MOVQ CX,(DI)
2014 ADDQ $8,DI
2015
2016 MOVQ (SI),CX
2017 ADDQ $8,SI
2018 MOVQ CX,(DI)
2019 ADDQ $8,DI
2020
2021 MOVQ (SI),CX
2022 ADDQ $8,SI
2023 MOVQ CX,(DI)
2024 ADDQ $8,DI
2025
2026 MOVQ (SI),CX
2027 ADDQ $8,SI
2028 MOVQ CX,(DI)
2029 ADDQ $8,DI
2030
2031 MOVQ (SI),CX
2032 ADDQ $8,SI
2033 MOVQ CX,(DI)
2034 ADDQ $8,DI
2035
2036 MOVQ (SI),CX
2037 ADDQ $8,SI
2038 MOVQ CX,(DI)
2039 ADDQ $8,DI
2040
2041 MOVQ (SI),CX
2042 ADDQ $8,SI
2043 MOVQ CX,(DI)
2044 ADDQ $8,DI
2045
2046 MOVQ (SI),CX
2047 ADDQ $8,SI
2048 MOVQ CX,(DI)
2049 ADDQ $8,DI
2050
2051 MOVQ (SI),CX
2052 ADDQ $8,SI
2053 MOVQ CX,(DI)
2054 ADDQ $8,DI
2055
2056 MOVQ (SI),CX
2057 ADDQ $8,SI
2058 MOVQ CX,(DI)
2059 ADDQ $8,DI
2060
2061 MOVQ (SI),CX
2062 ADDQ $8,SI
2063 MOVQ CX,(DI)
2064 ADDQ $8,DI
2065
2066 MOVQ (SI),CX
2067 ADDQ $8,SI
2068 MOVQ CX,(DI)
2069 ADDQ $8,DI
2070
2071 MOVQ (SI),CX
2072 ADDQ $8,SI
2073 MOVQ CX,(DI)
2074 ADDQ $8,DI
2075
2076 MOVQ (SI),CX
2077 ADDQ $8,SI
2078 MOVQ CX,(DI)
2079 ADDQ $8,DI
2080
2081 MOVQ (SI),CX
2082 ADDQ $8,SI
2083 MOVQ CX,(DI)
2084 ADDQ $8,DI
2085
2086 MOVQ (SI),CX
2087 ADDQ $8,SI
2088 MOVQ CX,(DI)
2089 ADDQ $8,DI
2090
2091 MOVQ (SI),CX
2092 ADDQ $8,SI
2093 MOVQ CX,(DI)
2094 ADDQ $8,DI
2095
2096 MOVQ (SI),CX
2097 ADDQ $8,SI
2098 MOVQ CX,(DI)
2099 ADDQ $8,DI
2100
2101 MOVQ (SI),CX
2102 ADDQ $8,SI
2103 MOVQ CX,(DI)
2104 ADDQ $8,DI
2105
2106 MOVQ (SI),CX
2107 ADDQ $8,SI
2108 MOVQ CX,(DI)
2109 ADDQ $8,DI
2110
2111 MOVQ (SI),CX
2112 ADDQ $8,SI
2113 MOVQ CX,(DI)
2114 ADDQ $8,DI
2115
2116 MOVQ (SI),CX
2117 ADDQ $8,SI
2118 MOVQ CX,(DI)
2119 ADDQ $8,DI
2120
2121 MOVQ (SI),CX
2122 ADDQ $8,SI
2123 MOVQ CX,(DI)
2124 ADDQ $8,DI
2125
2126 MOVQ (SI),CX
2127 ADDQ $8,SI
2128 MOVQ CX,(DI)
2129 ADDQ $8,DI
2130
2131 MOVQ (SI),CX
2132 ADDQ $8,SI
2133 MOVQ CX,(DI)
2134 ADDQ $8,DI
2135
2136 MOVQ (SI),CX
2137 ADDQ $8,SI
2138 MOVQ CX,(DI)
2139 ADDQ $8,DI
2140
2141 MOVQ (SI),CX
2142 ADDQ $8,SI
2143 MOVQ CX,(DI)
2144 ADDQ $8,DI
2145
2146 MOVQ (SI),CX
2147 ADDQ $8,SI
2148 MOVQ CX,(DI)
2149 ADDQ $8,DI
2150
2151 MOVQ (SI),CX
2152 ADDQ $8,SI
2153 MOVQ CX,(DI)
2154 ADDQ $8,DI
2155
2156 MOVQ (SI),CX
2157 ADDQ $8,SI
2158 MOVQ CX,(DI)
2159 ADDQ $8,DI
2160
2161 MOVQ (SI),CX
2162 ADDQ $8,SI
2163 MOVQ CX,(DI)
2164 ADDQ $8,DI
2165
2166 MOVQ (SI),CX
2167 ADDQ $8,SI
2168 MOVQ CX,(DI)
2169 ADDQ $8,DI
2170
2171 MOVQ (SI),CX
2172 ADDQ $8,SI
2173 MOVQ CX,(DI)
2174 ADDQ $8,DI
2175
2176 MOVQ (SI),CX
2177 ADDQ $8,SI
2178 MOVQ CX,(DI)
2179 ADDQ $8,DI
2180
2181 MOVQ (SI),CX
2182 ADDQ $8,SI
2183 MOVQ CX,(DI)
2184 ADDQ $8,DI
2185
2186 MOVQ (SI),CX
2187 ADDQ $8,SI
2188 MOVQ CX,(DI)
2189 ADDQ $8,DI
2190
2191 MOVQ (SI),CX
2192 ADDQ $8,SI
2193 MOVQ CX,(DI)
2194 ADDQ $8,DI
2195
2196 MOVQ (SI),CX
2197 ADDQ $8,SI
2198 MOVQ CX,(DI)
2199 ADDQ $8,DI
2200
2201 MOVQ (SI),CX
2202 ADDQ $8,SI
2203 MOVQ CX,(DI)
2204 ADDQ $8,DI
2205
2206 MOVQ (SI),CX
2207 ADDQ $8,SI
2208 MOVQ CX,(DI)
2209 ADDQ $8,DI
2210
2211 MOVQ (SI),CX
2212 ADDQ $8,SI
2213 MOVQ CX,(DI)
2214 ADDQ $8,DI
2215
2216 MOVQ (SI),CX
2217 ADDQ $8,SI
2218 MOVQ CX,(DI)
2219 ADDQ $8,DI
2220
2221 MOVQ (SI),CX
2222 ADDQ $8,SI
2223 MOVQ CX,(DI)
2224 ADDQ $8,DI
2225
2226 MOVQ (SI),CX
2227 ADDQ $8,SI
2228 MOVQ CX,(DI)
2229 ADDQ $8,DI
2230
2231 MOVQ (SI),CX
2232 ADDQ $8,SI
2233 MOVQ CX,(DI)
2234 ADDQ $8,DI
2235
2236 MOVQ (SI),CX
2237 ADDQ $8,SI
2238 MOVQ CX,(DI)
2239 ADDQ $8,DI
2240
2241 MOVQ (SI),CX
2242 ADDQ $8,SI
2243 MOVQ CX,(DI)
2244 ADDQ $8,DI
2245
2246 MOVQ (SI),CX
2247 ADDQ $8,SI
2248 MOVQ CX,(DI)
2249 ADDQ $8,DI
2250
2251 MOVQ (SI),CX
2252 ADDQ $8,SI
2253 MOVQ CX,(DI)
2254 ADDQ $8,DI
2255
2256 MOVQ (SI),CX
2257 ADDQ $8,SI
2258 MOVQ CX,(DI)
2259 ADDQ $8,DI
2260
2261 MOVQ (SI),CX
2262 ADDQ $8,SI
2263 MOVQ CX,(DI)
2264 ADDQ $8,DI
2265
2266 MOVQ (SI),CX
2267 ADDQ $8,SI
2268 MOVQ CX,(DI)
2269 ADDQ $8,DI
2270
2271 MOVQ (SI),CX
2272 ADDQ $8,SI
2273 MOVQ CX,(DI)
2274 ADDQ $8,DI
2275
2276 MOVQ (SI),CX
2277 ADDQ $8,SI
2278 MOVQ CX,(DI)
2279 ADDQ $8,DI
2280
2281 MOVQ (SI),CX
2282 ADDQ $8,SI
2283 MOVQ CX,(DI)
2284 ADDQ $8,DI
2285
2286 MOVQ (SI),CX
2287 ADDQ $8,SI
2288 MOVQ CX,(DI)
2289 ADDQ $8,DI
2290
2291 MOVQ (SI),CX
2292 ADDQ $8,SI
2293 MOVQ CX,(DI)
2294 ADDQ $8,DI
2295
2296 MOVQ (SI),CX
2297 ADDQ $8,SI
2298 MOVQ CX,(DI)
2299 ADDQ $8,DI
2300
2301 MOVQ (SI),CX
2302 ADDQ $8,SI
2303 MOVQ CX,(DI)
2304 ADDQ $8,DI
2305
2306 MOVQ (SI),CX
2307 ADDQ $8,SI
2308 MOVQ CX,(DI)
2309 ADDQ $8,DI
2310
2311 MOVQ (SI),CX
2312 ADDQ $8,SI
2313 MOVQ CX,(DI)
2314 ADDQ $8,DI
2315
2316 MOVQ (SI),CX
2317 ADDQ $8,SI
2318 MOVQ CX,(DI)
2319 ADDQ $8,DI
2320
2321 MOVQ (SI),CX
2322 ADDQ $8,SI
2323 MOVQ CX,(DI)
2324 ADDQ $8,DI
2325
2326 MOVQ (SI),CX
2327 ADDQ $8,SI
2328 MOVQ CX,(DI)
2329 ADDQ $8,DI
2330
2331 MOVQ (SI),CX
2332 ADDQ $8,SI
2333 MOVQ CX,(DI)
2334 ADDQ $8,DI
2335
2336 MOVQ (SI),CX
2337 ADDQ $8,SI
2338 MOVQ CX,(DI)
2339 ADDQ $8,DI
2340
2341 MOVQ (SI),CX
2342 ADDQ $8,SI
2343 MOVQ CX,(DI)
2344 ADDQ $8,DI
2345
2346 MOVQ (SI),CX
2347 ADDQ $8,SI
2348 MOVQ CX,(DI)
2349 ADDQ $8,DI
2350
2351 MOVQ (SI),CX
2352 ADDQ $8,SI
2353 MOVQ CX,(DI)
2354 ADDQ $8,DI
2355
2356 MOVQ (SI),CX
2357 ADDQ $8,SI
2358 MOVQ CX,(DI)
2359 ADDQ $8,DI
2360
2361 MOVQ (SI),CX
2362 ADDQ $8,SI
2363 MOVQ CX,(DI)
2364 ADDQ $8,DI
2365
2366 MOVQ (SI),CX
2367 ADDQ $8,SI
2368 MOVQ CX,(DI)
2369 ADDQ $8,DI
2370
2371 MOVQ (SI),CX
2372 ADDQ $8,SI
2373 MOVQ CX,(DI)
2374 ADDQ $8,DI
2375
2376 MOVQ (SI),CX
2377 ADDQ $8,SI
2378 MOVQ CX,(DI)
2379 ADDQ $8,DI
2380
2381 MOVQ (SI),CX
2382 ADDQ $8,SI
2383 MOVQ CX,(DI)
2384 ADDQ $8,DI
2385
2386 MOVQ (SI),CX
2387 ADDQ $8,SI
2388 MOVQ CX,(DI)
2389 ADDQ $8,DI
2390
2391 MOVQ (SI),CX
2392 ADDQ $8,SI
2393 MOVQ CX,(DI)
2394 ADDQ $8,DI
2395
2396 MOVQ (SI),CX
2397 ADDQ $8,SI
2398 MOVQ CX,(DI)
2399 ADDQ $8,DI
2400
2401 MOVQ (SI),CX
2402 ADDQ $8,SI
2403 MOVQ CX,(DI)
2404 ADDQ $8,DI
2405
2406 MOVQ (SI),CX
2407 ADDQ $8,SI
2408 MOVQ CX,(DI)
2409 ADDQ $8,DI
2410
2411 MOVQ (SI),CX
2412 ADDQ $8,SI
2413 MOVQ CX,(DI)
2414 ADDQ $8,DI
2415
2416 MOVQ (SI),CX
2417 ADDQ $8,SI
2418 MOVQ CX,(DI)
2419 ADDQ $8,DI
2420
2421 RET
Dmitriy Vyukov350a8fc2014-05-02 17:32:42 +01002422
Keith Randall3306d112014-09-02 14:33:33 -07002423TEXT runtime·fastrand1(SB), NOSPLIT, $0-4
Keith Randall0c6b55e2014-07-16 14:16:19 -07002424 get_tls(CX)
2425 MOVQ g(CX), AX
2426 MOVQ g_m(AX), AX
2427 MOVL m_fastrand(AX), DX
2428 ADDL DX, DX
2429 MOVL DX, BX
2430 XORL $0x88888eef, DX
2431 CMOVLMI BX, DX
2432 MOVL DX, m_fastrand(AX)
2433 MOVL DX, ret+0(FP)
2434 RET
Keith Randallf4407372014-09-03 08:49:43 -07002435
2436TEXT runtime·return0(SB), NOSPLIT, $0
2437 MOVL $0, AX
2438 RET
Keith Randall1b6807b2014-09-25 07:59:01 -07002439
2440
2441// Called from cgo wrappers, this function returns g->m->curg.stack.hi.
2442// Must obey the gcc calling convention.
Keith Randall1aa65fe2014-09-25 08:37:04 -07002443TEXT _cgo_topofstack(SB),NOSPLIT,$0
Keith Randall1b6807b2014-09-25 07:59:01 -07002444 get_tls(CX)
2445 MOVQ g(CX), AX
2446 MOVQ g_m(AX), AX
2447 MOVQ m_curg(AX), AX
2448 MOVQ (g_stack+stack_hi)(AX), AX
2449 RET
Russ Coxa5a07332014-10-29 20:37:44 -04002450
2451// The top-most function running on a goroutine
2452// returns to goexit+PCQuantum.
2453TEXT runtime·goexit(SB),NOSPLIT,$0-0
2454 BYTE $0x90 // NOP
2455 CALL runtime·goexit1(SB) // does not return
Russ Cox15ced2d2014-11-11 17:06:22 -05002456
2457TEXT runtime·getg(SB),NOSPLIT,$0-8
2458 get_tls(CX)
2459 MOVQ g(CX), AX
2460 MOVQ AX, ret+0(FP)
2461 RET
Russ Cox8c3f6402014-11-21 15:57:10 -05002462
2463TEXT runtime·prefetcht0(SB),NOSPLIT,$0-8
2464 MOVQ addr+0(FP), AX
2465 PREFETCHT0 (AX)
2466 RET
2467
2468TEXT runtime·prefetcht1(SB),NOSPLIT,$0-8
2469 MOVQ addr+0(FP), AX
2470 PREFETCHT1 (AX)
2471 RET
2472
2473TEXT runtime·prefetcht2(SB),NOSPLIT,$0-8
2474 MOVQ addr+0(FP), AX
2475 PREFETCHT2 (AX)
2476 RET
2477
2478TEXT runtime·prefetchnta(SB),NOSPLIT,$0-8
2479 MOVQ addr+0(FP), AX
2480 PREFETCHNTA (AX)
2481 RET