blob: fdea05366e1cc520a10f8871838ec617b0faf6f8 [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
Dmitry Vyukov6e70fdd2015-02-17 14:25:49 +030033
34 // Figure out how to serialize RDTSC.
35 // On Intel processors LFENCE is enough. AMD requires MFENCE.
36 // Don't know about the rest, so let's do MFENCE.
37 CMPL BX, $0x756E6547 // "Genu"
38 JNE notintel
39 CMPL DX, $0x49656E69 // "ineI"
40 JNE notintel
41 CMPL CX, $0x6C65746E // "ntel"
42 JNE notintel
43 MOVB $1, runtime·lfenceBeforeRdtsc(SB)
44notintel:
45
Keith Randalla5d40242013-03-12 10:47:44 -070046 MOVQ $1, AX
47 CPUID
48 MOVL CX, runtime·cpuid_ecx(SB)
49 MOVL DX, runtime·cpuid_edx(SB)
50nocpuinfo:
51
Russ Coxf8d49b52013-02-28 16:24:38 -050052 // if there is an _cgo_init, call it.
53 MOVQ _cgo_init(SB), AX
Ian Lance Taylora4f8d362010-04-09 14:15:15 -070054 TESTQ AX, AX
Russ Coxe473f422010-08-04 17:50:22 -070055 JZ needtls
Alex Brainman8d6958f2012-01-20 12:59:44 +110056 // g0 already in DI
57 MOVQ DI, CX // Win64 uses CX for first parameter
Russ Cox89f185f2014-06-26 11:54:39 -040058 MOVQ $setg_gcc<>(SB), SI
Alex Brainman8d6958f2012-01-20 12:59:44 +110059 CALL AX
Russ Cox15b76ad2014-09-09 13:39:57 -040060
Dmitriy Vyukovf5becf42013-06-03 12:28:24 +040061 // update stackguard after _cgo_init
62 MOVQ $runtime·g0(SB), CX
Russ Cox15b76ad2014-09-09 13:39:57 -040063 MOVQ (g_stack+stack_lo)(CX), AX
Russ Cox15ced2d2014-11-11 17:06:22 -050064 ADDQ $const__StackGuard, AX
Russ Coxe6d35112015-01-05 16:29:21 +000065 MOVQ AX, g_stackguard0(CX)
66 MOVQ AX, g_stackguard1(CX)
Russ Cox15b76ad2014-09-09 13:39:57 -040067
Wei Guangjing9f636592011-07-19 10:47:33 -040068 CMPL runtime·iswindows(SB), $0
69 JEQ ok
Russ Coxe473f422010-08-04 17:50:22 -070070needtls:
Akshat Kumara72bebf2012-08-31 13:21:13 -040071 // skip TLS setup on Plan 9
72 CMPL runtime·isplan9(SB), $1
73 JEQ ok
Aram Hăvărneanua46b4342014-01-17 17:58:10 +130074 // skip TLS setup on Solaris
75 CMPL runtime·issolaris(SB), $1
76 JEQ ok
Akshat Kumara72bebf2012-08-31 13:21:13 -040077
Russ Cox68b42552010-11-04 14:00:19 -040078 LEAQ runtime·tls0(SB), DI
79 CALL runtime·settls(SB)
Russ Coxe473f422010-08-04 17:50:22 -070080
81 // store through it, to make sure it works
82 get_tls(BX)
83 MOVQ $0x123, g(BX)
Russ Cox68b42552010-11-04 14:00:19 -040084 MOVQ runtime·tls0(SB), AX
Russ Coxe473f422010-08-04 17:50:22 -070085 CMPQ AX, $0x123
86 JEQ 2(PC)
87 MOVL AX, 0 // abort
88ok:
89 // set the per-goroutine and per-mach "registers"
90 get_tls(BX)
Russ Cox68b42552010-11-04 14:00:19 -040091 LEAQ runtime·g0(SB), CX
Russ Coxe473f422010-08-04 17:50:22 -070092 MOVQ CX, g(BX)
Russ Cox68b42552010-11-04 14:00:19 -040093 LEAQ runtime·m0(SB), AX
Russ Coxe473f422010-08-04 17:50:22 -070094
95 // save m->g0 = g0
96 MOVQ CX, m_g0(AX)
Russ Cox89f185f2014-06-26 11:54:39 -040097 // save m0 to g0->m
98 MOVQ AX, g_m(CX)
Rob Pike8e82a672008-06-30 11:50:36 -070099
Ken Thompson8f53bc02008-12-15 15:07:35 -0800100 CLD // convention is D is always left cleared
Russ Cox68b42552010-11-04 14:00:19 -0400101 CALL runtime·check(SB)
Rob Pike8e82a672008-06-30 11:50:36 -0700102
Rob Pike8e82a672008-06-30 11:50:36 -0700103 MOVL 16(SP), AX // copy argc
104 MOVL AX, 0(SP)
105 MOVQ 24(SP), AX // copy argv
106 MOVQ AX, 8(SP)
Russ Cox68b42552010-11-04 14:00:19 -0400107 CALL runtime·args(SB)
108 CALL runtime·osinit(SB)
109 CALL runtime·schedinit(SB)
Russ Coxf7f63292008-08-05 14:21:42 -0700110
Ken Thompson751ce3a2008-07-11 19:16:39 -0700111 // create a new goroutine to start program
Michael Hudson-Doylef78dc1d2015-03-29 23:38:20 +0000112 MOVQ $runtime·mainPC(SB), AX // entry
Austin Clements20a6ff72015-01-27 18:29:02 -0500113 PUSHQ AX
Russ Cox7343e032009-06-17 15:12:16 -0700114 PUSHQ $0 // arg size
Russ Cox68b42552010-11-04 14:00:19 -0400115 CALL runtime·newproc(SB)
Russ Coxebd1eef2008-09-22 13:47:59 -0700116 POPQ AX
117 POPQ AX
Russ Cox79e1db22008-12-04 08:30:54 -0800118
Russ Coxebd1eef2008-09-22 13:47:59 -0700119 // start this M
Russ Cox68b42552010-11-04 14:00:19 -0400120 CALL runtime·mstart(SB)
Rob Pike8e82a672008-06-30 11:50:36 -0700121
Russ Cox36aa7d42012-03-08 14:03:56 -0500122 MOVL $0xf1, 0xf1 // crash
Rob Pike8e82a672008-06-30 11:50:36 -0700123 RET
124
Michael Hudson-Doylef78dc1d2015-03-29 23:38:20 +0000125DATA runtime·mainPC+0(SB)/8,$runtime·main(SB)
126GLOBL runtime·mainPC(SB),RODATA,$8
Russ Cox1903ad72013-02-21 17:01:13 -0500127
Keith Randall5a546962013-08-07 10:23:24 -0700128TEXT runtime·breakpoint(SB),NOSPLIT,$0-0
Ken Thompson751ce3a2008-07-11 19:16:39 -0700129 BYTE $0xcc
Rob Pike8e82a672008-06-30 11:50:36 -0700130 RET
131
Keith Randall5a546962013-08-07 10:23:24 -0700132TEXT runtime·asminit(SB),NOSPLIT,$0-0
Russ Cox1707a992012-02-14 01:23:15 -0500133 // No per-thread init.
134 RET
135
Ken Thompson751ce3a2008-07-11 19:16:39 -0700136/*
137 * go-routine
138 */
Rob Piked3204ef2008-06-30 14:39:47 -0700139
Russ Coxf9ca3b52011-03-07 10:37:42 -0500140// void gosave(Gobuf*)
Russ Cox7343e032009-06-17 15:12:16 -0700141// save state in Gobuf; setjmp
Keith Randall5a546962013-08-07 10:23:24 -0700142TEXT runtime·gosave(SB), NOSPLIT, $0-8
Russ Cox25f6b022014-08-27 11:32:17 -0400143 MOVQ buf+0(FP), AX // gobuf
144 LEAQ buf+0(FP), BX // caller's SP
Russ Cox7343e032009-06-17 15:12:16 -0700145 MOVQ BX, gobuf_sp(AX)
146 MOVQ 0(SP), BX // caller's PC
147 MOVQ BX, gobuf_pc(AX)
Russ Coxd67e7e32013-06-12 15:22:26 -0400148 MOVQ $0, gobuf_ret(AX)
149 MOVQ $0, gobuf_ctxt(AX)
Austin Clements3c0fee12015-01-14 11:09:50 -0500150 MOVQ BP, gobuf_bp(AX)
Russ Coxe473f422010-08-04 17:50:22 -0700151 get_tls(CX)
152 MOVQ g(CX), BX
153 MOVQ BX, gobuf_g(AX)
Ken Thompson751ce3a2008-07-11 19:16:39 -0700154 RET
155
Ian Lance Taylor06272482013-06-12 15:05:10 -0700156// void gogo(Gobuf*)
Russ Cox7343e032009-06-17 15:12:16 -0700157// restore state from Gobuf; longjmp
Keith Randall5a546962013-08-07 10:23:24 -0700158TEXT runtime·gogo(SB), NOSPLIT, $0-8
Russ Cox25f6b022014-08-27 11:32:17 -0400159 MOVQ buf+0(FP), BX // gobuf
Russ Coxe473f422010-08-04 17:50:22 -0700160 MOVQ gobuf_g(BX), DX
161 MOVQ 0(DX), CX // make sure g != nil
162 get_tls(CX)
163 MOVQ DX, g(CX)
Russ Cox7343e032009-06-17 15:12:16 -0700164 MOVQ gobuf_sp(BX), SP // restore SP
Russ Coxd67e7e32013-06-12 15:22:26 -0400165 MOVQ gobuf_ret(BX), AX
166 MOVQ gobuf_ctxt(BX), DX
Austin Clements3c0fee12015-01-14 11:09:50 -0500167 MOVQ gobuf_bp(BX), BP
Russ Coxd67e7e32013-06-12 15:22:26 -0400168 MOVQ $0, gobuf_sp(BX) // clear to help garbage collector
169 MOVQ $0, gobuf_ret(BX)
170 MOVQ $0, gobuf_ctxt(BX)
Austin Clements3c0fee12015-01-14 11:09:50 -0500171 MOVQ $0, gobuf_bp(BX)
Russ Cox7343e032009-06-17 15:12:16 -0700172 MOVQ gobuf_pc(BX), BX
173 JMP BX
174
Russ Cox012ceed2014-09-03 11:35:22 -0400175// func mcall(fn func(*g))
Russ Coxf9ca3b52011-03-07 10:37:42 -0500176// Switch to m->g0's stack, call fn(g).
Russ Cox370276a2011-04-27 23:21:12 -0400177// Fn must never return. It should gogo(&g->sched)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500178// to keep running g.
Keith Randall5a546962013-08-07 10:23:24 -0700179TEXT runtime·mcall(SB), NOSPLIT, $0-8
Russ Coxf9ca3b52011-03-07 10:37:42 -0500180 MOVQ fn+0(FP), DI
181
182 get_tls(CX)
Russ Cox528534c2013-06-05 07:16:53 -0400183 MOVQ g(CX), AX // save state in g->sched
Russ Coxf9ca3b52011-03-07 10:37:42 -0500184 MOVQ 0(SP), BX // caller's PC
185 MOVQ BX, (g_sched+gobuf_pc)(AX)
Russ Cox25f6b022014-08-27 11:32:17 -0400186 LEAQ fn+0(FP), BX // caller's SP
Russ Coxf9ca3b52011-03-07 10:37:42 -0500187 MOVQ BX, (g_sched+gobuf_sp)(AX)
188 MOVQ AX, (g_sched+gobuf_g)(AX)
Austin Clements3c0fee12015-01-14 11:09:50 -0500189 MOVQ BP, (g_sched+gobuf_bp)(AX)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500190
191 // switch to m->g0 & its stack, call fn
Russ Cox89f185f2014-06-26 11:54:39 -0400192 MOVQ g(CX), BX
193 MOVQ g_m(BX), BX
Russ Coxf9ca3b52011-03-07 10:37:42 -0500194 MOVQ m_g0(BX), SI
195 CMPQ SI, AX // if g == m->g0 call badmcall
Russ Cox9ddfb642013-07-16 16:24:09 -0400196 JNE 3(PC)
Keith Randall32b770b2013-08-29 15:53:34 -0700197 MOVQ $runtime·badmcall(SB), AX
198 JMP AX
Russ Coxf9ca3b52011-03-07 10:37:42 -0500199 MOVQ SI, g(CX) // g = m->g0
Russ Cox528534c2013-06-05 07:16:53 -0400200 MOVQ (g_sched+gobuf_sp)(SI), SP // sp = m->g0->sched.sp
Russ Coxf9ca3b52011-03-07 10:37:42 -0500201 PUSHQ AX
Russ Cox012ceed2014-09-03 11:35:22 -0400202 MOVQ DI, DX
203 MOVQ 0(DI), DI
Russ Coxf9ca3b52011-03-07 10:37:42 -0500204 CALL DI
205 POPQ AX
Keith Randall32b770b2013-08-29 15:53:34 -0700206 MOVQ $runtime·badmcall2(SB), AX
207 JMP AX
Russ Coxf9ca3b52011-03-07 10:37:42 -0500208 RET
209
Russ Cox656be312014-11-12 14:54:31 -0500210// systemstack_switch is a dummy routine that systemstack leaves at the bottom
Keith Randall4aa50432014-07-30 09:01:52 -0700211// of the G stack. We need to distinguish the routine that
212// lives at the bottom of the G stack from the one that lives
Russ Cox656be312014-11-12 14:54:31 -0500213// at the top of the system stack because the one at the top of
214// the system stack terminates the stack walk (see topofstack()).
215TEXT runtime·systemstack_switch(SB), NOSPLIT, $0-0
Keith Randall4aa50432014-07-30 09:01:52 -0700216 RET
217
Russ Cox656be312014-11-12 14:54:31 -0500218// func systemstack(fn func())
219TEXT runtime·systemstack(SB), NOSPLIT, $0-8
220 MOVQ fn+0(FP), DI // DI = fn
Russ Cox1d550b82014-09-11 12:08:30 -0400221 get_tls(CX)
222 MOVQ g(CX), AX // AX = g
223 MOVQ g_m(AX), BX // BX = m
Russ Cox656be312014-11-12 14:54:31 -0500224
Russ Cox1d550b82014-09-11 12:08:30 -0400225 MOVQ m_gsignal(BX), DX // DX = gsignal
226 CMPQ AX, DX
Russ Cox656be312014-11-12 14:54:31 -0500227 JEQ noswitch
Russ Cox32ecf572014-09-04 00:10:10 -0400228
Keith Randall4aa50432014-07-30 09:01:52 -0700229 MOVQ m_g0(BX), DX // DX = g0
230 CMPQ AX, DX
Russ Cox656be312014-11-12 14:54:31 -0500231 JEQ noswitch
Keith Randall4aa50432014-07-30 09:01:52 -0700232
Austin Clements20a6ff72015-01-27 18:29:02 -0500233 MOVQ m_curg(BX), R8
234 CMPQ AX, R8
Russ Cox656be312014-11-12 14:54:31 -0500235 JEQ switch
Russ Cox32ecf572014-09-04 00:10:10 -0400236
Russ Cox656be312014-11-12 14:54:31 -0500237 // Bad: g is not gsignal, not g0, not curg. What is it?
238 MOVQ $runtime·badsystemstack(SB), AX
Russ Cox32ecf572014-09-04 00:10:10 -0400239 CALL AX
240
Russ Cox656be312014-11-12 14:54:31 -0500241switch:
Keith Randall4aa50432014-07-30 09:01:52 -0700242 // save our state in g->sched. Pretend to
Russ Cox656be312014-11-12 14:54:31 -0500243 // be systemstack_switch if the G stack is scanned.
Austin Clements20a6ff72015-01-27 18:29:02 -0500244 MOVQ $runtime·systemstack_switch(SB), SI
245 MOVQ SI, (g_sched+gobuf_pc)(AX)
Keith Randall4aa50432014-07-30 09:01:52 -0700246 MOVQ SP, (g_sched+gobuf_sp)(AX)
247 MOVQ AX, (g_sched+gobuf_g)(AX)
Austin Clements3c0fee12015-01-14 11:09:50 -0500248 MOVQ BP, (g_sched+gobuf_bp)(AX)
Keith Randall4aa50432014-07-30 09:01:52 -0700249
250 // switch to g0
251 MOVQ DX, g(CX)
Russ Coxd16a2ad2014-09-04 22:48:08 -0400252 MOVQ (g_sched+gobuf_sp)(DX), BX
Russ Cox656be312014-11-12 14:54:31 -0500253 // make it look like mstart called systemstack on g0, to stop traceback
Russ Coxd16a2ad2014-09-04 22:48:08 -0400254 SUBQ $8, BX
255 MOVQ $runtime·mstart(SB), DX
256 MOVQ DX, 0(BX)
257 MOVQ BX, SP
Keith Randall4aa50432014-07-30 09:01:52 -0700258
259 // call target function
Russ Cox012ceed2014-09-03 11:35:22 -0400260 MOVQ DI, DX
261 MOVQ 0(DI), DI
Keith Randall4aa50432014-07-30 09:01:52 -0700262 CALL DI
263
264 // switch back to g
265 get_tls(CX)
266 MOVQ g(CX), AX
267 MOVQ g_m(AX), BX
268 MOVQ m_curg(BX), AX
269 MOVQ AX, g(CX)
270 MOVQ (g_sched+gobuf_sp)(AX), SP
271 MOVQ $0, (g_sched+gobuf_sp)(AX)
272 RET
273
Russ Cox656be312014-11-12 14:54:31 -0500274noswitch:
Keith Randall4aa50432014-07-30 09:01:52 -0700275 // already on m stack, just call directly
Russ Cox012ceed2014-09-03 11:35:22 -0400276 MOVQ DI, DX
277 MOVQ 0(DI), DI
Keith Randall4aa50432014-07-30 09:01:52 -0700278 CALL DI
279 RET
280
Rob Pike2da97832008-07-12 11:30:53 -0700281/*
282 * support for morestack
283 */
284
Russ Cox7343e032009-06-17 15:12:16 -0700285// Called during function prolog when more stack is needed.
Russ Cox58f12ff2013-07-18 16:53:45 -0400286//
287// The traceback routines see morestack on a g0 as being
288// the top of a stack (for example, morestack calling newstack
289// calling the scheduler calling newm calling gc), so we must
290// record an argument size. For that purpose, it has no arguments.
Keith Randall5a546962013-08-07 10:23:24 -0700291TEXT runtime·morestack(SB),NOSPLIT,$0-0
Russ Coxe473f422010-08-04 17:50:22 -0700292 // Cannot grow scheduler stack (m->g0).
Anthony Martin2302b212014-09-10 06:25:05 -0700293 get_tls(CX)
Russ Cox15b76ad2014-09-09 13:39:57 -0400294 MOVQ g(CX), BX
295 MOVQ g_m(BX), BX
Russ Coxe473f422010-08-04 17:50:22 -0700296 MOVQ m_g0(BX), SI
297 CMPQ g(CX), SI
298 JNE 2(PC)
299 INT $3
300
Russ Coxf8f630f2014-09-05 16:51:45 -0400301 // Cannot grow signal stack (m->gsignal).
302 MOVQ m_gsignal(BX), SI
303 CMPQ g(CX), SI
304 JNE 2(PC)
305 INT $3
306
Russ Cox7343e032009-06-17 15:12:16 -0700307 // Called from f.
308 // Set m->morebuf to f's caller.
309 MOVQ 8(SP), AX // f's caller's PC
Russ Coxe473f422010-08-04 17:50:22 -0700310 MOVQ AX, (m_morebuf+gobuf_pc)(BX)
Russ Cox7343e032009-06-17 15:12:16 -0700311 LEAQ 16(SP), AX // f's caller's SP
Russ Coxe473f422010-08-04 17:50:22 -0700312 MOVQ AX, (m_morebuf+gobuf_sp)(BX)
Russ Coxe473f422010-08-04 17:50:22 -0700313 get_tls(CX)
314 MOVQ g(CX), SI
315 MOVQ SI, (m_morebuf+gobuf_g)(BX)
Russ Cox7343e032009-06-17 15:12:16 -0700316
Russ Cox6fa3c892013-06-27 11:32:01 -0400317 // Set g->sched to context in f.
318 MOVQ 0(SP), AX // f's PC
319 MOVQ AX, (g_sched+gobuf_pc)(SI)
320 MOVQ SI, (g_sched+gobuf_g)(SI)
321 LEAQ 8(SP), AX // f's SP
322 MOVQ AX, (g_sched+gobuf_sp)(SI)
323 MOVQ DX, (g_sched+gobuf_ctxt)(SI)
Austin Clements3c0fee12015-01-14 11:09:50 -0500324 MOVQ BP, (g_sched+gobuf_bp)(SI)
Russ Cox7343e032009-06-17 15:12:16 -0700325
Russ Coxf9ca3b52011-03-07 10:37:42 -0500326 // Call newstack on m->g0's stack.
Austin Clements20a6ff72015-01-27 18:29:02 -0500327 MOVQ m_g0(BX), BX
328 MOVQ BX, g(CX)
329 MOVQ (g_sched+gobuf_sp)(BX), SP
Russ Cox68b42552010-11-04 14:00:19 -0400330 CALL runtime·newstack(SB)
Russ Cox7343e032009-06-17 15:12:16 -0700331 MOVQ $0, 0x1003 // crash if newstack returns
332 RET
333
Russ Cox15b76ad2014-09-09 13:39:57 -0400334// morestack but not preserving ctxt.
335TEXT runtime·morestack_noctxt(SB),NOSPLIT,$0
336 MOVL $0, DX
337 JMP runtime·morestack(SB)
338
Keith Randall52631982014-09-08 10:14:41 -0700339// reflectcall: call a function with the given argument list
Russ Coxdf027ac2014-12-30 13:59:55 -0500340// func call(argtype *_type, f *FuncVal, arg *byte, argsize, retoffset uint32).
Keith Randall9cd57062013-08-02 13:03:14 -0700341// we don't have variable-sized frames, so we use a small number
342// of constant-sized-frame functions to encode a few bits of size in the pc.
343// Caution: ugly multiline assembly macros in your future!
344
345#define DISPATCH(NAME,MAXSIZE) \
346 CMPQ CX, $MAXSIZE; \
347 JA 3(PC); \
Russ Coxcb6f5ac2014-10-15 13:12:16 -0400348 MOVQ $NAME(SB), AX; \
Keith Randall9cd57062013-08-02 13:03:14 -0700349 JMP AX
Rob Pikeaff78832014-07-30 10:11:44 -0700350// Note: can't just "JMP NAME(SB)" - bad inlining results.
Keith Randall9cd57062013-08-02 13:03:14 -0700351
Russ Cox7a524a12014-12-22 13:27:53 -0500352TEXT reflect·call(SB), NOSPLIT, $0-0
353 JMP ·reflectcall(SB)
354
Russ Coxdf027ac2014-12-30 13:59:55 -0500355TEXT ·reflectcall(SB), NOSPLIT, $0-32
356 MOVLQZX argsize+24(FP), CX
357 // NOTE(rsc): No call16, because CALLFN needs four words
358 // of argument space to invoke callwritebarrier.
Rob Pikeaff78832014-07-30 10:11:44 -0700359 DISPATCH(runtime·call32, 32)
360 DISPATCH(runtime·call64, 64)
361 DISPATCH(runtime·call128, 128)
362 DISPATCH(runtime·call256, 256)
363 DISPATCH(runtime·call512, 512)
364 DISPATCH(runtime·call1024, 1024)
365 DISPATCH(runtime·call2048, 2048)
366 DISPATCH(runtime·call4096, 4096)
367 DISPATCH(runtime·call8192, 8192)
368 DISPATCH(runtime·call16384, 16384)
369 DISPATCH(runtime·call32768, 32768)
370 DISPATCH(runtime·call65536, 65536)
371 DISPATCH(runtime·call131072, 131072)
372 DISPATCH(runtime·call262144, 262144)
373 DISPATCH(runtime·call524288, 524288)
374 DISPATCH(runtime·call1048576, 1048576)
375 DISPATCH(runtime·call2097152, 2097152)
376 DISPATCH(runtime·call4194304, 4194304)
377 DISPATCH(runtime·call8388608, 8388608)
378 DISPATCH(runtime·call16777216, 16777216)
379 DISPATCH(runtime·call33554432, 33554432)
380 DISPATCH(runtime·call67108864, 67108864)
381 DISPATCH(runtime·call134217728, 134217728)
382 DISPATCH(runtime·call268435456, 268435456)
383 DISPATCH(runtime·call536870912, 536870912)
384 DISPATCH(runtime·call1073741824, 1073741824)
Keith Randall9cd57062013-08-02 13:03:14 -0700385 MOVQ $runtime·badreflectcall(SB), AX
386 JMP AX
387
Keith Randall12e46e42013-08-06 14:33:55 -0700388#define CALLFN(NAME,MAXSIZE) \
Russ Coxdf027ac2014-12-30 13:59:55 -0500389TEXT NAME(SB), WRAPPER, $MAXSIZE-32; \
Russ Coxcb6f5ac2014-10-15 13:12:16 -0400390 NO_LOCAL_POINTERS; \
Keith Randall9cd57062013-08-02 13:03:14 -0700391 /* copy arguments to stack */ \
Russ Coxdf027ac2014-12-30 13:59:55 -0500392 MOVQ argptr+16(FP), SI; \
393 MOVLQZX argsize+24(FP), CX; \
Keith Randall9cd57062013-08-02 13:03:14 -0700394 MOVQ SP, DI; \
395 REP;MOVSB; \
396 /* call function */ \
Russ Coxdf027ac2014-12-30 13:59:55 -0500397 MOVQ f+8(FP), DX; \
Keith Randallcee8bca2014-05-21 14:28:34 -0700398 PCDATA $PCDATA_StackMapIndex, $0; \
Keith Randall9cd57062013-08-02 13:03:14 -0700399 CALL (DX); \
400 /* copy return values back */ \
Russ Coxdf027ac2014-12-30 13:59:55 -0500401 MOVQ argptr+16(FP), DI; \
402 MOVLQZX argsize+24(FP), CX; \
403 MOVLQZX retoffset+28(FP), BX; \
Keith Randall9cd57062013-08-02 13:03:14 -0700404 MOVQ SP, SI; \
Russ Cox72c5d5e2014-04-08 11:11:35 -0400405 ADDQ BX, DI; \
406 ADDQ BX, SI; \
407 SUBQ BX, CX; \
Keith Randall9cd57062013-08-02 13:03:14 -0700408 REP;MOVSB; \
Russ Coxdf027ac2014-12-30 13:59:55 -0500409 /* execute write barrier updates */ \
410 MOVQ argtype+0(FP), DX; \
411 MOVQ argptr+16(FP), DI; \
412 MOVLQZX argsize+24(FP), CX; \
413 MOVLQZX retoffset+28(FP), BX; \
414 MOVQ DX, 0(SP); \
415 MOVQ DI, 8(SP); \
416 MOVQ CX, 16(SP); \
417 MOVQ BX, 24(SP); \
418 CALL runtime·callwritebarrier(SB); \
Keith Randall9cd57062013-08-02 13:03:14 -0700419 RET
420
Russ Coxcb6f5ac2014-10-15 13:12:16 -0400421CALLFN(·call32, 32)
422CALLFN(·call64, 64)
423CALLFN(·call128, 128)
424CALLFN(·call256, 256)
425CALLFN(·call512, 512)
426CALLFN(·call1024, 1024)
427CALLFN(·call2048, 2048)
428CALLFN(·call4096, 4096)
429CALLFN(·call8192, 8192)
430CALLFN(·call16384, 16384)
431CALLFN(·call32768, 32768)
432CALLFN(·call65536, 65536)
433CALLFN(·call131072, 131072)
434CALLFN(·call262144, 262144)
435CALLFN(·call524288, 524288)
436CALLFN(·call1048576, 1048576)
437CALLFN(·call2097152, 2097152)
438CALLFN(·call4194304, 4194304)
439CALLFN(·call8388608, 8388608)
440CALLFN(·call16777216, 16777216)
441CALLFN(·call33554432, 33554432)
442CALLFN(·call67108864, 67108864)
443CALLFN(·call134217728, 134217728)
444CALLFN(·call268435456, 268435456)
445CALLFN(·call536870912, 536870912)
446CALLFN(·call1073741824, 1073741824)
Keith Randall9cd57062013-08-02 13:03:14 -0700447
Russ Coxd28acc42008-08-04 16:43:49 -0700448// bool cas(int32 *val, int32 old, int32 new)
449// Atomically:
450// if(*val == old){
451// *val = new;
452// return 1;
Ken Thompson1e1cc4e2009-01-27 12:03:53 -0800453// } else
Russ Coxd28acc42008-08-04 16:43:49 -0700454// return 0;
Russ Cox25f6b022014-08-27 11:32:17 -0400455TEXT runtime·cas(SB), NOSPLIT, $0-17
456 MOVQ ptr+0(FP), BX
457 MOVL old+8(FP), AX
458 MOVL new+12(FP), CX
Russ Coxd28acc42008-08-04 16:43:49 -0700459 LOCK
460 CMPXCHGL CX, 0(BX)
Josh Bleecher Snyderf7e43f12015-01-07 14:24:18 -0800461 SETEQ ret+16(FP)
Russ Coxd28acc42008-08-04 16:43:49 -0700462 RET
Ken Thompson1e1cc4e2009-01-27 12:03:53 -0800463
Russ Cox9ddfb642013-07-16 16:24:09 -0400464// bool runtime·cas64(uint64 *val, uint64 old, uint64 new)
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400465// Atomically:
466// if(*val == *old){
467// *val = new;
468// return 1;
469// } else {
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400470// return 0;
471// }
Russ Cox25f6b022014-08-27 11:32:17 -0400472TEXT runtime·cas64(SB), NOSPLIT, $0-25
473 MOVQ ptr+0(FP), BX
474 MOVQ old+8(FP), AX
475 MOVQ new+16(FP), CX
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400476 LOCK
477 CMPXCHGQ CX, 0(BX)
Josh Bleecher Snyderf7e43f12015-01-07 14:24:18 -0800478 SETEQ ret+24(FP)
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400479 RET
Russ Coxd21638b2014-08-27 21:59:49 -0400480
481TEXT runtime·casuintptr(SB), NOSPLIT, $0-25
482 JMP runtime·cas64(SB)
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400483
Russ Cox3a7f6642014-08-29 16:20:48 -0400484TEXT runtime·atomicloaduintptr(SB), NOSPLIT, $0-16
485 JMP runtime·atomicload64(SB)
486
Keith Randall47d6af22014-08-30 11:03:28 -0700487TEXT runtime·atomicloaduint(SB), NOSPLIT, $0-16
488 JMP runtime·atomicload64(SB)
489
Russ Cox2b1659b2014-10-07 23:27:25 -0400490TEXT runtime·atomicstoreuintptr(SB), NOSPLIT, $0-16
491 JMP runtime·atomicstore64(SB)
492
Russ Cox67793502011-02-16 13:21:13 -0500493// bool casp(void **val, void *old, void *new)
494// Atomically:
495// if(*val == old){
496// *val = new;
497// return 1;
498// } else
499// return 0;
Russ Cox15ced2d2014-11-11 17:06:22 -0500500TEXT runtime·casp1(SB), NOSPLIT, $0-25
Russ Cox25f6b022014-08-27 11:32:17 -0400501 MOVQ ptr+0(FP), BX
502 MOVQ old+8(FP), AX
503 MOVQ new+16(FP), CX
Russ Cox67793502011-02-16 13:21:13 -0500504 LOCK
505 CMPXCHGQ CX, 0(BX)
Josh Bleecher Snyderf7e43f12015-01-07 14:24:18 -0800506 SETEQ ret+24(FP)
Russ Cox67793502011-02-16 13:21:13 -0500507 RET
508
Dmitriy Vyukov491aa152011-07-15 11:27:16 -0400509// uint32 xadd(uint32 volatile *val, int32 delta)
510// Atomically:
511// *val += delta;
512// return *val;
Russ Cox25f6b022014-08-27 11:32:17 -0400513TEXT runtime·xadd(SB), NOSPLIT, $0-20
514 MOVQ ptr+0(FP), BX
515 MOVL delta+8(FP), AX
Dmitriy Vyukov491aa152011-07-15 11:27:16 -0400516 MOVL AX, CX
517 LOCK
518 XADDL AX, 0(BX)
519 ADDL CX, AX
Russ Cox25f6b022014-08-27 11:32:17 -0400520 MOVL AX, ret+16(FP)
Dmitriy Vyukov491aa152011-07-15 11:27:16 -0400521 RET
522
Russ Cox25f6b022014-08-27 11:32:17 -0400523TEXT runtime·xadd64(SB), NOSPLIT, $0-24
524 MOVQ ptr+0(FP), BX
525 MOVQ delta+8(FP), AX
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400526 MOVQ AX, CX
527 LOCK
528 XADDQ AX, 0(BX)
529 ADDQ CX, AX
Russ Cox25f6b022014-08-27 11:32:17 -0400530 MOVQ AX, ret+16(FP)
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400531 RET
532
Russ Cox25f6b022014-08-27 11:32:17 -0400533TEXT runtime·xchg(SB), NOSPLIT, $0-20
534 MOVQ ptr+0(FP), BX
535 MOVL new+8(FP), AX
Dmitriy Vyukov4e5086b2011-07-29 12:44:06 -0400536 XCHGL AX, 0(BX)
Russ Cox25f6b022014-08-27 11:32:17 -0400537 MOVL AX, ret+16(FP)
Dmitriy Vyukov4e5086b2011-07-29 12:44:06 -0400538 RET
539
Russ Cox25f6b022014-08-27 11:32:17 -0400540TEXT runtime·xchg64(SB), NOSPLIT, $0-24
541 MOVQ ptr+0(FP), BX
542 MOVQ new+8(FP), AX
Dmitriy Vyukovadd33492013-03-05 09:46:52 +0200543 XCHGQ AX, 0(BX)
Russ Cox25f6b022014-08-27 11:32:17 -0400544 MOVQ AX, ret+16(FP)
Dmitriy Vyukovadd33492013-03-05 09:46:52 +0200545 RET
546
Russ Cox15ced2d2014-11-11 17:06:22 -0500547TEXT runtime·xchgp1(SB), NOSPLIT, $0-24
Russ Cox25f6b022014-08-27 11:32:17 -0400548 MOVQ ptr+0(FP), BX
549 MOVQ new+8(FP), AX
Dmitriy Vyukov9cbd2fb2014-01-22 11:27:16 +0400550 XCHGQ AX, 0(BX)
Russ Cox25f6b022014-08-27 11:32:17 -0400551 MOVQ AX, ret+16(FP)
Dmitriy Vyukov9cbd2fb2014-01-22 11:27:16 +0400552 RET
553
Dmitriy Vyukov91a670d2014-09-04 10:04:04 +0400554TEXT runtime·xchguintptr(SB), NOSPLIT, $0-24
555 JMP runtime·xchg64(SB)
556
Keith Randall5a546962013-08-07 10:23:24 -0700557TEXT runtime·procyield(SB),NOSPLIT,$0-0
Russ Cox25f6b022014-08-27 11:32:17 -0400558 MOVL cycles+0(FP), AX
Dmitriy Vyukov4e5086b2011-07-29 12:44:06 -0400559again:
560 PAUSE
561 SUBL $1, AX
562 JNZ again
563 RET
564
Russ Cox15ced2d2014-11-11 17:06:22 -0500565TEXT runtime·atomicstorep1(SB), NOSPLIT, $0-16
Russ Cox25f6b022014-08-27 11:32:17 -0400566 MOVQ ptr+0(FP), BX
567 MOVQ val+8(FP), AX
Dmitriy Vyukov86a659c2011-07-13 11:22:41 -0700568 XCHGQ AX, 0(BX)
569 RET
570
Keith Randall5a546962013-08-07 10:23:24 -0700571TEXT runtime·atomicstore(SB), NOSPLIT, $0-12
Russ Cox25f6b022014-08-27 11:32:17 -0400572 MOVQ ptr+0(FP), BX
573 MOVL val+8(FP), AX
Dmitriy Vyukov91f0f182011-07-29 13:47:24 -0400574 XCHGL AX, 0(BX)
575 RET
576
Keith Randall5a546962013-08-07 10:23:24 -0700577TEXT runtime·atomicstore64(SB), NOSPLIT, $0-16
Russ Cox25f6b022014-08-27 11:32:17 -0400578 MOVQ ptr+0(FP), BX
579 MOVQ val+8(FP), AX
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400580 XCHGQ AX, 0(BX)
581 RET
582
Dmitriy Vyukovff3fa1b2014-08-19 17:38:00 +0400583// void runtime·atomicor8(byte volatile*, byte);
Russ Cox25f6b022014-08-27 11:32:17 -0400584TEXT runtime·atomicor8(SB), NOSPLIT, $0-9
Dmitriy Vyukovff3fa1b2014-08-19 17:38:00 +0400585 MOVQ ptr+0(FP), AX
586 MOVB val+8(FP), BX
587 LOCK
588 ORB BX, (AX)
589 RET
590
Russ Cox631d6a32015-03-19 19:42:16 -0400591// void runtime·atomicand8(byte volatile*, byte);
592TEXT runtime·atomicand8(SB), NOSPLIT, $0-9
593 MOVQ ptr+0(FP), AX
594 MOVB val+8(FP), BX
595 LOCK
596 ANDB BX, (AX)
597 RET
598
Russ Coxaa3222d82009-06-02 23:02:12 -0700599// void jmpdefer(fn, sp);
600// called from deferreturn.
Ken Thompson1e1cc4e2009-01-27 12:03:53 -0800601// 1. pop the caller
602// 2. sub 5 bytes from the callers return
603// 3. jmp to the argument
Keith Randalla97a91d2013-08-07 14:03:50 -0700604TEXT runtime·jmpdefer(SB), NOSPLIT, $0-16
Russ Cox25f6b022014-08-27 11:32:17 -0400605 MOVQ fv+0(FP), DX // fn
606 MOVQ argp+8(FP), BX // caller sp
Russ Coxaa3222d82009-06-02 23:02:12 -0700607 LEAQ -8(BX), SP // caller sp after CALL
608 SUBQ $5, (SP) // return to CALL again
Russ Cox6066fdc2013-02-22 10:47:54 -0500609 MOVQ 0(DX), BX
Russ Cox1903ad72013-02-21 17:01:13 -0500610 JMP BX // but first run the deferred function
Russ Cox133a1582009-10-03 10:37:12 -0700611
Russ Coxd67e7e32013-06-12 15:22:26 -0400612// Save state of caller into g->sched. Smashes R8, R9.
Keith Randall5a546962013-08-07 10:23:24 -0700613TEXT gosave<>(SB),NOSPLIT,$0
Russ Coxd67e7e32013-06-12 15:22:26 -0400614 get_tls(R8)
615 MOVQ g(R8), R8
616 MOVQ 0(SP), R9
617 MOVQ R9, (g_sched+gobuf_pc)(R8)
618 LEAQ 8(SP), R9
619 MOVQ R9, (g_sched+gobuf_sp)(R8)
620 MOVQ $0, (g_sched+gobuf_ret)(R8)
621 MOVQ $0, (g_sched+gobuf_ctxt)(R8)
Austin Clements3c0fee12015-01-14 11:09:50 -0500622 MOVQ BP, (g_sched+gobuf_bp)(R8)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500623 RET
624
625// asmcgocall(void(*fn)(void*), void *arg)
Russ Coxadd89dd2009-10-12 10:26:38 -0700626// Call fn(arg) on the scheduler stack,
627// aligned appropriately for the gcc ABI.
Russ Coxf9ca3b52011-03-07 10:37:42 -0500628// See cgocall.c for more details.
Russ Cox653fb6d2014-09-16 17:39:55 -0400629TEXT ·asmcgocall(SB),NOSPLIT,$0-16
Russ Cox54138e12014-09-03 11:36:14 -0400630 MOVQ fn+0(FP), AX
631 MOVQ arg+8(FP), BX
Russ Coxcb767242014-09-04 00:01:55 -0400632 CALL asmcgocall<>(SB)
Russ Cox54138e12014-09-03 11:36:14 -0400633 RET
634
Russ Cox653fb6d2014-09-16 17:39:55 -0400635TEXT ·asmcgocall_errno(SB),NOSPLIT,$0-20
Russ Coxf9ca3b52011-03-07 10:37:42 -0500636 MOVQ fn+0(FP), AX
637 MOVQ arg+8(FP), BX
Russ Coxcb767242014-09-04 00:01:55 -0400638 CALL asmcgocall<>(SB)
639 MOVL AX, ret+16(FP)
640 RET
641
642// asmcgocall common code. fn in AX, arg in BX. returns errno in AX.
643TEXT asmcgocall<>(SB),NOSPLIT,$0-0
Russ Coxf9ca3b52011-03-07 10:37:42 -0500644 MOVQ SP, DX
Russ Coxadd89dd2009-10-12 10:26:38 -0700645
646 // Figure out if we need to switch to m->g0 stack.
Russ Coxf9ca3b52011-03-07 10:37:42 -0500647 // We get called to create new OS threads too, and those
648 // come in on the m->g0 stack already.
649 get_tls(CX)
Austin Clements20a6ff72015-01-27 18:29:02 -0500650 MOVQ g(CX), R8
651 MOVQ g_m(R8), R8
652 MOVQ m_g0(R8), SI
Russ Coxf9ca3b52011-03-07 10:37:42 -0500653 MOVQ g(CX), DI
654 CMPQ SI, DI
Aram Hăvărneanua46b4342014-01-17 17:58:10 +1300655 JEQ nosave
Austin Clements20a6ff72015-01-27 18:29:02 -0500656 MOVQ m_gsignal(R8), SI
Aram Hăvărneanua46b4342014-01-17 17:58:10 +1300657 CMPQ SI, DI
658 JEQ nosave
659
Austin Clements20a6ff72015-01-27 18:29:02 -0500660 MOVQ m_g0(R8), SI
Russ Coxd67e7e32013-06-12 15:22:26 -0400661 CALL gosave<>(SB)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500662 MOVQ SI, g(CX)
663 MOVQ (g_sched+gobuf_sp)(SI), SP
Aram Hăvărneanua46b4342014-01-17 17:58:10 +1300664nosave:
Russ Coxadd89dd2009-10-12 10:26:38 -0700665
666 // Now on a scheduling stack (a pthread-created stack).
Alex Brainman7f075ec2012-09-03 12:12:51 +1000667 // Make sure we have enough room for 4 stack-backed fast-call
668 // registers as per windows amd64 calling convention.
669 SUBQ $64, SP
Russ Cox133a1582009-10-03 10:37:12 -0700670 ANDQ $~15, SP // alignment for gcc ABI
Alex Brainman7f075ec2012-09-03 12:12:51 +1000671 MOVQ DI, 48(SP) // save g
Keith Randall47f251c2014-09-11 20:36:23 -0700672 MOVQ (g_stack+stack_hi)(DI), DI
673 SUBQ DX, DI
674 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 -0500675 MOVQ BX, DI // DI = first argument in AMD64 ABI
Wei Guangjing9f636592011-07-19 10:47:33 -0400676 MOVQ BX, CX // CX = first argument in Win64
Russ Coxf9ca3b52011-03-07 10:37:42 -0500677 CALL AX
Russ Coxadd89dd2009-10-12 10:26:38 -0700678
Russ Coxe473f422010-08-04 17:50:22 -0700679 // Restore registers, g, stack pointer.
Russ Coxf9ca3b52011-03-07 10:37:42 -0500680 get_tls(CX)
Alex Brainman7f075ec2012-09-03 12:12:51 +1000681 MOVQ 48(SP), DI
Keith Randall47f251c2014-09-11 20:36:23 -0700682 MOVQ (g_stack+stack_hi)(DI), SI
683 SUBQ 40(SP), SI
Russ Coxf9ca3b52011-03-07 10:37:42 -0500684 MOVQ DI, g(CX)
Keith Randall47f251c2014-09-11 20:36:23 -0700685 MOVQ SI, SP
Russ Cox133a1582009-10-03 10:37:12 -0700686 RET
687
Russ Coxf9ca3b52011-03-07 10:37:42 -0500688// cgocallback(void (*fn)(void*), void *frame, uintptr framesize)
Russ Cox3d2dfc52013-02-22 16:08:56 -0500689// Turn the fn into a Go func (by taking its address) and call
690// cgocallback_gofunc.
Keith Randall5a546962013-08-07 10:23:24 -0700691TEXT runtime·cgocallback(SB),NOSPLIT,$24-24
Russ Cox3d2dfc52013-02-22 16:08:56 -0500692 LEAQ fn+0(FP), AX
693 MOVQ AX, 0(SP)
694 MOVQ frame+8(FP), AX
695 MOVQ AX, 8(SP)
696 MOVQ framesize+16(FP), AX
697 MOVQ AX, 16(SP)
698 MOVQ $runtime·cgocallback_gofunc(SB), AX
699 CALL AX
700 RET
701
702// cgocallback_gofunc(FuncVal*, void *frame, uintptr framesize)
703// See cgocall.c for more details.
Russ Cox653fb6d2014-09-16 17:39:55 -0400704TEXT ·cgocallback_gofunc(SB),NOSPLIT,$8-24
Russ Coxe844f532014-09-12 07:46:11 -0400705 NO_LOCAL_POINTERS
706
Russ Cox89f185f2014-06-26 11:54:39 -0400707 // If g is nil, Go did not create the current thread.
708 // Call needm to obtain one m for temporary use.
Russ Cox6c976392013-02-20 17:48:23 -0500709 // In this case, we're running on the thread stack, so there's
710 // lots of space, but the linker doesn't know. Hide the call from
711 // the linker analysis by using an indirect call through AX.
712 get_tls(CX)
713#ifdef GOOS_windows
Austin Clements20a6ff72015-01-27 18:29:02 -0500714 MOVL $0, BX
Russ Cox6c976392013-02-20 17:48:23 -0500715 CMPQ CX, $0
Russ Coxcefdb9c2013-07-23 22:59:32 -0400716 JEQ 2(PC)
Russ Cox6c976392013-02-20 17:48:23 -0500717#endif
Austin Clements20a6ff72015-01-27 18:29:02 -0500718 MOVQ g(CX), BX
719 CMPQ BX, $0
Russ Cox89f185f2014-06-26 11:54:39 -0400720 JEQ needm
Austin Clements20a6ff72015-01-27 18:29:02 -0500721 MOVQ g_m(BX), BX
722 MOVQ BX, R8 // holds oldm until end of function
Russ Cox89f185f2014-06-26 11:54:39 -0400723 JMP havem
Russ Cox6c976392013-02-20 17:48:23 -0500724needm:
Russ Cox89f185f2014-06-26 11:54:39 -0400725 MOVQ $0, 0(SP)
Russ Cox6c976392013-02-20 17:48:23 -0500726 MOVQ $runtime·needm(SB), AX
727 CALL AX
Russ Coxf0112822013-07-24 09:01:57 -0400728 MOVQ 0(SP), R8
Russ Coxe473f422010-08-04 17:50:22 -0700729 get_tls(CX)
Austin Clements20a6ff72015-01-27 18:29:02 -0500730 MOVQ g(CX), BX
731 MOVQ g_m(BX), BX
Russ Coxc4efaac2014-10-28 21:53:09 -0400732
733 // Set m->sched.sp = SP, so that if a panic happens
734 // during the function we are about to execute, it will
735 // have a valid SP to run on the g0 stack.
736 // The next few lines (after the havem label)
737 // will save this SP onto the stack and then write
738 // the same SP back to m->sched.sp. That seems redundant,
739 // but if an unrecovered panic happens, unwindm will
740 // restore the g->sched.sp from the stack location
Russ Cox656be312014-11-12 14:54:31 -0500741 // and then systemstack will try to use it. If we don't set it here,
Russ Coxc4efaac2014-10-28 21:53:09 -0400742 // that restored SP will be uninitialized (typically 0) and
743 // will not be usable.
Austin Clements20a6ff72015-01-27 18:29:02 -0500744 MOVQ m_g0(BX), SI
Russ Coxc4efaac2014-10-28 21:53:09 -0400745 MOVQ SP, (g_sched+gobuf_sp)(SI)
Russ Cox9b732382012-03-08 12:12:40 -0500746
Russ Cox6c976392013-02-20 17:48:23 -0500747havem:
748 // Now there's a valid m, and we're running on its m->g0.
749 // Save current m->g0->sched.sp on stack and then set it to SP.
750 // Save current sp in m->g0->sched.sp in preparation for
751 // switch back to m->curg stack.
Russ Coxdba623b2013-07-23 18:40:02 -0400752 // NOTE: unwindm knows that the saved g->sched.sp is at 0(SP).
Austin Clements20a6ff72015-01-27 18:29:02 -0500753 MOVQ m_g0(BX), SI
Russ Coxdba623b2013-07-23 18:40:02 -0400754 MOVQ (g_sched+gobuf_sp)(SI), AX
755 MOVQ AX, 0(SP)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500756 MOVQ SP, (g_sched+gobuf_sp)(SI)
Ian Lance Taylor2d0ff3f2010-04-09 13:30:11 -0700757
Russ Coxdba623b2013-07-23 18:40:02 -0400758 // Switch to m->curg stack and call runtime.cgocallbackg.
759 // Because we are taking over the execution of m->curg
760 // but *not* resuming what had been running, we need to
761 // save that information (m->curg->sched) so we can restore it.
Russ Cox528534c2013-06-05 07:16:53 -0400762 // We can restore m->curg->sched.sp easily, because calling
Alex Brainman72e83482011-08-18 12:17:09 -0400763 // runtime.cgocallbackg leaves SP unchanged upon return.
Russ Cox528534c2013-06-05 07:16:53 -0400764 // To save m->curg->sched.pc, we push it onto the stack.
Russ Coxf9ca3b52011-03-07 10:37:42 -0500765 // This has the added benefit that it looks to the traceback
Alex Brainman72e83482011-08-18 12:17:09 -0400766 // routine like cgocallbackg is going to return to that
Russ Coxdba623b2013-07-23 18:40:02 -0400767 // PC (because the frame we allocate below has the same
768 // size as cgocallback_gofunc's frame declared above)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500769 // so that the traceback will seamlessly trace back into
770 // the earlier calls.
Russ Coxdba623b2013-07-23 18:40:02 -0400771 //
Russ Coxf0112822013-07-24 09:01:57 -0400772 // In the new goroutine, 0(SP) holds the saved R8.
Austin Clements20a6ff72015-01-27 18:29:02 -0500773 MOVQ m_curg(BX), SI
Russ Coxf9ca3b52011-03-07 10:37:42 -0500774 MOVQ SI, g(CX)
775 MOVQ (g_sched+gobuf_sp)(SI), DI // prepare stack as DI
Austin Clements20a6ff72015-01-27 18:29:02 -0500776 MOVQ (g_sched+gobuf_pc)(SI), BX
777 MOVQ BX, -8(DI)
Austin Clements3c0fee12015-01-14 11:09:50 -0500778 // Compute the size of the frame, including return PC and, if
779 // GOEXPERIMENT=framepointer, the saved based pointer
Rob Pikec21f1d52015-02-19 13:44:06 -0800780 LEAQ fv+0(FP), AX
Austin Clements3c0fee12015-01-14 11:09:50 -0500781 SUBQ SP, AX
782 SUBQ AX, DI
783 MOVQ DI, SP
784
Russ Coxf0112822013-07-24 09:01:57 -0400785 MOVQ R8, 0(SP)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500786 CALL runtime·cgocallbackg(SB)
Russ Coxf0112822013-07-24 09:01:57 -0400787 MOVQ 0(SP), R8
Russ Coxf9ca3b52011-03-07 10:37:42 -0500788
Austin Clements3c0fee12015-01-14 11:09:50 -0500789 // Compute the size of the frame again. FP and SP have
790 // completely different values here than they did above,
791 // but only their difference matters.
Rob Pikec21f1d52015-02-19 13:44:06 -0800792 LEAQ fv+0(FP), AX
Austin Clements3c0fee12015-01-14 11:09:50 -0500793 SUBQ SP, AX
794
Russ Cox528534c2013-06-05 07:16:53 -0400795 // Restore g->sched (== m->curg->sched) from saved values.
Russ Coxe473f422010-08-04 17:50:22 -0700796 get_tls(CX)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500797 MOVQ g(CX), SI
Austin Clements3c0fee12015-01-14 11:09:50 -0500798 MOVQ SP, DI
799 ADDQ AX, DI
800 MOVQ -8(DI), BX
Austin Clements20a6ff72015-01-27 18:29:02 -0500801 MOVQ BX, (g_sched+gobuf_pc)(SI)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500802 MOVQ DI, (g_sched+gobuf_sp)(SI)
803
804 // Switch back to m->g0's stack and restore m->g0->sched.sp.
805 // (Unlike m->curg, the g0 goroutine never uses sched.pc,
806 // so we do not have to restore it.)
Austin Clements20a6ff72015-01-27 18:29:02 -0500807 MOVQ g(CX), BX
808 MOVQ g_m(BX), BX
809 MOVQ m_g0(BX), SI
Russ Coxf9ca3b52011-03-07 10:37:42 -0500810 MOVQ SI, g(CX)
811 MOVQ (g_sched+gobuf_sp)(SI), SP
Russ Coxdba623b2013-07-23 18:40:02 -0400812 MOVQ 0(SP), AX
813 MOVQ AX, (g_sched+gobuf_sp)(SI)
Russ Cox6c976392013-02-20 17:48:23 -0500814
815 // If the m on entry was nil, we called needm above to borrow an m
816 // for the duration of the call. Since the call is over, return it with dropm.
Russ Coxf0112822013-07-24 09:01:57 -0400817 CMPQ R8, $0
Russ Cox6c976392013-02-20 17:48:23 -0500818 JNE 3(PC)
819 MOVQ $runtime·dropm(SB), AX
820 CALL AX
Russ Coxf9ca3b52011-03-07 10:37:42 -0500821
822 // Done!
Ian Lance Taylor2d0ff3f2010-04-09 13:30:11 -0700823 RET
824
Russ Cox89f185f2014-06-26 11:54:39 -0400825// void setg(G*); set g. for use by needm.
Russ Cox25f6b022014-08-27 11:32:17 -0400826TEXT runtime·setg(SB), NOSPLIT, $0-8
Russ Cox89f185f2014-06-26 11:54:39 -0400827 MOVQ gg+0(FP), BX
Russ Cox6c976392013-02-20 17:48:23 -0500828#ifdef GOOS_windows
Russ Cox89f185f2014-06-26 11:54:39 -0400829 CMPQ BX, $0
Russ Cox6c976392013-02-20 17:48:23 -0500830 JNE settls
831 MOVQ $0, 0x28(GS)
832 RET
833settls:
Russ Cox89f185f2014-06-26 11:54:39 -0400834 MOVQ g_m(BX), AX
Russ Cox6c976392013-02-20 17:48:23 -0500835 LEAQ m_tls(AX), AX
836 MOVQ AX, 0x28(GS)
837#endif
838 get_tls(CX)
Russ Cox6c976392013-02-20 17:48:23 -0500839 MOVQ BX, g(CX)
840 RET
841
Russ Cox89f185f2014-06-26 11:54:39 -0400842// void setg_gcc(G*); set g called from gcc.
843TEXT setg_gcc<>(SB),NOSPLIT,$0
Russ Cox6a70f9d2013-03-25 18:14:02 -0400844 get_tls(AX)
Russ Cox89f185f2014-06-26 11:54:39 -0400845 MOVQ DI, g(AX)
Russ Cox6a70f9d2013-03-25 18:14:02 -0400846 RET
847
Russ Cox15b76ad2014-09-09 13:39:57 -0400848// check that SP is in range [g->stack.lo, g->stack.hi)
Keith Randall5a546962013-08-07 10:23:24 -0700849TEXT runtime·stackcheck(SB), NOSPLIT, $0-0
Russ Coxe473f422010-08-04 17:50:22 -0700850 get_tls(CX)
851 MOVQ g(CX), AX
Russ Cox15b76ad2014-09-09 13:39:57 -0400852 CMPQ (g_stack+stack_hi)(AX), SP
Russ Cox01eaf782010-03-30 10:53:16 -0700853 JHI 2(PC)
854 INT $3
Russ Cox15b76ad2014-09-09 13:39:57 -0400855 CMPQ SP, (g_stack+stack_lo)(AX)
Russ Cox01eaf782010-03-30 10:53:16 -0700856 JHI 2(PC)
857 INT $3
858 RET
859
Russ Cox25f6b022014-08-27 11:32:17 -0400860TEXT runtime·getcallerpc(SB),NOSPLIT,$0-16
861 MOVQ argp+0(FP),AX // addr of first arg
Russ Cox6c196012010-04-05 12:51:09 -0700862 MOVQ -8(AX),AX // get calling pc
Russ Cox25f6b022014-08-27 11:32:17 -0400863 MOVQ AX, ret+8(FP)
Russ Cox6c196012010-04-05 12:51:09 -0700864 RET
865
Keith Randall5a546962013-08-07 10:23:24 -0700866TEXT runtime·setcallerpc(SB),NOSPLIT,$0-16
Russ Cox25f6b022014-08-27 11:32:17 -0400867 MOVQ argp+0(FP),AX // addr of first arg
868 MOVQ pc+8(FP), BX
Russ Cox6c196012010-04-05 12:51:09 -0700869 MOVQ BX, -8(AX) // set calling pc
870 RET
871
Russ Cox25f6b022014-08-27 11:32:17 -0400872TEXT runtime·getcallersp(SB),NOSPLIT,$0-16
873 MOVQ argp+0(FP), AX
874 MOVQ AX, ret+8(FP)
Russ Cox6c196012010-04-05 12:51:09 -0700875 RET
876
Dmitry Vyukov6e70fdd2015-02-17 14:25:49 +0300877// func cputicks() int64
Keith Randall5a546962013-08-07 10:23:24 -0700878TEXT runtime·cputicks(SB),NOSPLIT,$0-0
Dmitry Vyukov6e70fdd2015-02-17 14:25:49 +0300879 CMPB runtime·lfenceBeforeRdtsc(SB), $1
880 JNE mfence
881 BYTE $0x0f; BYTE $0xae; BYTE $0xe8 // LFENCE
882 JMP done
883mfence:
884 BYTE $0x0f; BYTE $0xae; BYTE $0xf0 // MFENCE
885done:
Damian Gryski8e765da2012-02-02 14:09:27 -0500886 RDTSC
887 SHLQ $32, DX
888 ADDQ DX, AX
Russ Cox25f6b022014-08-27 11:32:17 -0400889 MOVQ AX, ret+0(FP)
Damian Gryski8e765da2012-02-02 14:09:27 -0500890 RET
891
Keith Randalld5e4c402015-01-06 16:42:48 -0800892// memhash_varlen(p unsafe.Pointer, h seed) uintptr
893// redirects to memhash(p, h, size) using the size
894// stored in the closure.
895TEXT runtime·memhash_varlen(SB),NOSPLIT,$32-24
896 GO_ARGS
897 NO_LOCAL_POINTERS
898 MOVQ p+0(FP), AX
899 MOVQ h+8(FP), BX
900 MOVQ 8(DX), CX
901 MOVQ AX, 0(SP)
902 MOVQ BX, 8(SP)
903 MOVQ CX, 16(SP)
904 CALL runtime·memhash(SB)
905 MOVQ 24(SP), AX
906 MOVQ AX, ret+16(FP)
907 RET
908
Keith Randalla5d40242013-03-12 10:47:44 -0700909// hash function using AES hardware instructions
Keith Randalla2a97682014-07-31 15:07:05 -0700910TEXT runtime·aeshash(SB),NOSPLIT,$0-32
911 MOVQ p+0(FP), AX // ptr to data
Keith Randalld5e4c402015-01-06 16:42:48 -0800912 MOVQ s+16(FP), CX // size
913 LEAQ ret+24(FP), DX
Keith Randalla5d40242013-03-12 10:47:44 -0700914 JMP runtime·aeshashbody(SB)
915
Keith Randalld5e4c402015-01-06 16:42:48 -0800916TEXT runtime·aeshashstr(SB),NOSPLIT,$0-24
Keith Randalla2a97682014-07-31 15:07:05 -0700917 MOVQ p+0(FP), AX // ptr to string struct
Keith Randalla5d40242013-03-12 10:47:44 -0700918 MOVQ 8(AX), CX // length of string
919 MOVQ (AX), AX // string data
Keith Randalld5e4c402015-01-06 16:42:48 -0800920 LEAQ ret+16(FP), DX
Keith Randalla5d40242013-03-12 10:47:44 -0700921 JMP runtime·aeshashbody(SB)
922
923// AX: data
924// CX: length
Keith Randalld5e4c402015-01-06 16:42:48 -0800925// DX: address to put return value
926TEXT runtime·aeshashbody(SB),NOSPLIT,$0-0
927 MOVQ h+8(FP), X6 // seed to low 64 bits of xmm6
Keith Randall7a4a64e2014-12-10 14:20:17 -0800928 PINSRQ $1, CX, X6 // size to high 64 bits of xmm6
929 PSHUFHW $0, X6, X6 // replace size with its low 2 bytes repeated 4 times
930 MOVO runtime·aeskeysched(SB), X7
Keith Randallee669722013-05-15 09:40:14 -0700931 CMPQ CX, $16
Keith Randall7a4a64e2014-12-10 14:20:17 -0800932 JB aes0to15
933 JE aes16
934 CMPQ CX, $32
935 JBE aes17to32
936 CMPQ CX, $64
937 JBE aes33to64
938 CMPQ CX, $128
939 JBE aes65to128
940 JMP aes129plus
Keith Randalla5d40242013-03-12 10:47:44 -0700941
Keith Randall7a4a64e2014-12-10 14:20:17 -0800942aes0to15:
943 TESTQ CX, CX
944 JE aes0
945
946 ADDQ $16, AX
947 TESTW $0xff0, AX
948 JE endofpage
Keith Randalla5d40242013-03-12 10:47:44 -0700949
Keith Randallee669722013-05-15 09:40:14 -0700950 // 16 bytes loaded at this address won't cross
951 // a page boundary, so we can load it directly.
Keith Randall7a4a64e2014-12-10 14:20:17 -0800952 MOVOU -16(AX), X0
Keith Randalla5d40242013-03-12 10:47:44 -0700953 ADDQ CX, CX
Austin Clements20a6ff72015-01-27 18:29:02 -0500954 MOVQ $masks<>(SB), AX
955 PAND (AX)(CX*8), X0
Keith Randall7a4a64e2014-12-10 14:20:17 -0800956
957 // scramble 3 times
958 AESENC X6, X0
959 AESENC X7, X0
960 AESENC X7, X0
Keith Randalld5e4c402015-01-06 16:42:48 -0800961 MOVQ X0, (DX)
Keith Randall7a4a64e2014-12-10 14:20:17 -0800962 RET
963
964endofpage:
Keith Randallee669722013-05-15 09:40:14 -0700965 // address ends in 1111xxxx. Might be up against
Keith Randalla5d40242013-03-12 10:47:44 -0700966 // a page boundary, so load ending at last byte.
967 // Then shift bytes down using pshufb.
Keith Randall7a4a64e2014-12-10 14:20:17 -0800968 MOVOU -32(AX)(CX*1), X0
Keith Randalla5d40242013-03-12 10:47:44 -0700969 ADDQ CX, CX
Austin Clements20a6ff72015-01-27 18:29:02 -0500970 MOVQ $shifts<>(SB), AX
971 PSHUFB (AX)(CX*8), X0
Keith Randall7a4a64e2014-12-10 14:20:17 -0800972 AESENC X6, X0
973 AESENC X7, X0
974 AESENC X7, X0
Keith Randalld5e4c402015-01-06 16:42:48 -0800975 MOVQ X0, (DX)
Keith Randalla5d40242013-03-12 10:47:44 -0700976 RET
977
Keith Randall7a4a64e2014-12-10 14:20:17 -0800978aes0:
979 // return input seed
Keith Randalld5e4c402015-01-06 16:42:48 -0800980 MOVQ h+8(FP), AX
981 MOVQ AX, (DX)
Keith Randall7a4a64e2014-12-10 14:20:17 -0800982 RET
983
984aes16:
985 MOVOU (AX), X0
986 AESENC X6, X0
987 AESENC X7, X0
988 AESENC X7, X0
Keith Randalld5e4c402015-01-06 16:42:48 -0800989 MOVQ X0, (DX)
Keith Randall7a4a64e2014-12-10 14:20:17 -0800990 RET
991
992aes17to32:
993 // load data to be hashed
994 MOVOU (AX), X0
995 MOVOU -16(AX)(CX*1), X1
996
997 // scramble 3 times
998 AESENC X6, X0
999 AESENC runtime·aeskeysched+16(SB), X1
1000 AESENC X7, X0
1001 AESENC X7, X1
1002 AESENC X7, X0
1003 AESENC X7, X1
1004
1005 // combine results
1006 PXOR X1, X0
Keith Randalld5e4c402015-01-06 16:42:48 -08001007 MOVQ X0, (DX)
Keith Randall7a4a64e2014-12-10 14:20:17 -08001008 RET
1009
1010aes33to64:
1011 MOVOU (AX), X0
1012 MOVOU 16(AX), X1
1013 MOVOU -32(AX)(CX*1), X2
1014 MOVOU -16(AX)(CX*1), X3
1015
1016 AESENC X6, X0
1017 AESENC runtime·aeskeysched+16(SB), X1
1018 AESENC runtime·aeskeysched+32(SB), X2
1019 AESENC runtime·aeskeysched+48(SB), X3
1020 AESENC X7, X0
1021 AESENC X7, X1
1022 AESENC X7, X2
1023 AESENC X7, X3
1024 AESENC X7, X0
1025 AESENC X7, X1
1026 AESENC X7, X2
1027 AESENC X7, X3
1028
1029 PXOR X2, X0
1030 PXOR X3, X1
1031 PXOR X1, X0
Keith Randalld5e4c402015-01-06 16:42:48 -08001032 MOVQ X0, (DX)
Keith Randall7a4a64e2014-12-10 14:20:17 -08001033 RET
1034
1035aes65to128:
1036 MOVOU (AX), X0
1037 MOVOU 16(AX), X1
1038 MOVOU 32(AX), X2
1039 MOVOU 48(AX), X3
1040 MOVOU -64(AX)(CX*1), X4
1041 MOVOU -48(AX)(CX*1), X5
1042 MOVOU -32(AX)(CX*1), X8
1043 MOVOU -16(AX)(CX*1), X9
1044
1045 AESENC X6, X0
1046 AESENC runtime·aeskeysched+16(SB), X1
1047 AESENC runtime·aeskeysched+32(SB), X2
1048 AESENC runtime·aeskeysched+48(SB), X3
1049 AESENC runtime·aeskeysched+64(SB), X4
1050 AESENC runtime·aeskeysched+80(SB), X5
1051 AESENC runtime·aeskeysched+96(SB), X8
1052 AESENC runtime·aeskeysched+112(SB), X9
1053 AESENC X7, X0
1054 AESENC X7, X1
1055 AESENC X7, X2
1056 AESENC X7, X3
1057 AESENC X7, X4
1058 AESENC X7, X5
1059 AESENC X7, X8
1060 AESENC X7, X9
1061 AESENC X7, X0
1062 AESENC X7, X1
1063 AESENC X7, X2
1064 AESENC X7, X3
1065 AESENC X7, X4
1066 AESENC X7, X5
1067 AESENC X7, X8
1068 AESENC X7, X9
1069
1070 PXOR X4, X0
1071 PXOR X5, X1
1072 PXOR X8, X2
1073 PXOR X9, X3
1074 PXOR X2, X0
1075 PXOR X3, X1
1076 PXOR X1, X0
Keith Randalld5e4c402015-01-06 16:42:48 -08001077 MOVQ X0, (DX)
Keith Randall7a4a64e2014-12-10 14:20:17 -08001078 RET
1079
1080aes129plus:
1081 // start with last (possibly overlapping) block
1082 MOVOU -128(AX)(CX*1), X0
1083 MOVOU -112(AX)(CX*1), X1
1084 MOVOU -96(AX)(CX*1), X2
1085 MOVOU -80(AX)(CX*1), X3
1086 MOVOU -64(AX)(CX*1), X4
1087 MOVOU -48(AX)(CX*1), X5
1088 MOVOU -32(AX)(CX*1), X8
1089 MOVOU -16(AX)(CX*1), X9
1090
1091 // scramble state once
1092 AESENC X6, X0
1093 AESENC runtime·aeskeysched+16(SB), X1
1094 AESENC runtime·aeskeysched+32(SB), X2
1095 AESENC runtime·aeskeysched+48(SB), X3
1096 AESENC runtime·aeskeysched+64(SB), X4
1097 AESENC runtime·aeskeysched+80(SB), X5
1098 AESENC runtime·aeskeysched+96(SB), X8
1099 AESENC runtime·aeskeysched+112(SB), X9
1100
1101 // compute number of remaining 128-byte blocks
1102 DECQ CX
1103 SHRQ $7, CX
1104
1105aesloop:
1106 // scramble state, xor in a block
1107 MOVOU (AX), X10
1108 MOVOU 16(AX), X11
1109 MOVOU 32(AX), X12
1110 MOVOU 48(AX), X13
1111 AESENC X10, X0
1112 AESENC X11, X1
1113 AESENC X12, X2
1114 AESENC X13, X3
1115 MOVOU 64(AX), X10
1116 MOVOU 80(AX), X11
1117 MOVOU 96(AX), X12
1118 MOVOU 112(AX), X13
1119 AESENC X10, X4
1120 AESENC X11, X5
1121 AESENC X12, X8
1122 AESENC X13, X9
1123
1124 // scramble state
1125 AESENC X7, X0
1126 AESENC X7, X1
1127 AESENC X7, X2
1128 AESENC X7, X3
1129 AESENC X7, X4
1130 AESENC X7, X5
1131 AESENC X7, X8
1132 AESENC X7, X9
1133
1134 ADDQ $128, AX
1135 DECQ CX
1136 JNE aesloop
1137
1138 // 2 more scrambles to finish
1139 AESENC X7, X0
1140 AESENC X7, X1
1141 AESENC X7, X2
1142 AESENC X7, X3
1143 AESENC X7, X4
1144 AESENC X7, X5
1145 AESENC X7, X8
1146 AESENC X7, X9
1147 AESENC X7, X0
1148 AESENC X7, X1
1149 AESENC X7, X2
1150 AESENC X7, X3
1151 AESENC X7, X4
1152 AESENC X7, X5
1153 AESENC X7, X8
1154 AESENC X7, X9
1155
1156 PXOR X4, X0
1157 PXOR X5, X1
1158 PXOR X8, X2
1159 PXOR X9, X3
1160 PXOR X2, X0
1161 PXOR X3, X1
1162 PXOR X1, X0
Keith Randalld5e4c402015-01-06 16:42:48 -08001163 MOVQ X0, (DX)
Keith Randall7a4a64e2014-12-10 14:20:17 -08001164 RET
1165
Keith Randalld5e4c402015-01-06 16:42:48 -08001166TEXT runtime·aeshash32(SB),NOSPLIT,$0-24
Keith Randalla2a97682014-07-31 15:07:05 -07001167 MOVQ p+0(FP), AX // ptr to data
Keith Randalld5e4c402015-01-06 16:42:48 -08001168 MOVQ h+8(FP), X0 // seed
Keith Randalla5d40242013-03-12 10:47:44 -07001169 PINSRD $2, (AX), X0 // data
Keith Randalldb53d972013-03-20 14:34:26 -07001170 AESENC runtime·aeskeysched+0(SB), X0
1171 AESENC runtime·aeskeysched+16(SB), X0
Keith Randall7a4a64e2014-12-10 14:20:17 -08001172 AESENC runtime·aeskeysched+32(SB), X0
Keith Randalld5e4c402015-01-06 16:42:48 -08001173 MOVQ X0, ret+16(FP)
Keith Randalla5d40242013-03-12 10:47:44 -07001174 RET
1175
Keith Randalld5e4c402015-01-06 16:42:48 -08001176TEXT runtime·aeshash64(SB),NOSPLIT,$0-24
Keith Randalla2a97682014-07-31 15:07:05 -07001177 MOVQ p+0(FP), AX // ptr to data
Keith Randalld5e4c402015-01-06 16:42:48 -08001178 MOVQ h+8(FP), X0 // seed
Keith Randalla5d40242013-03-12 10:47:44 -07001179 PINSRQ $1, (AX), X0 // data
Keith Randalldb53d972013-03-20 14:34:26 -07001180 AESENC runtime·aeskeysched+0(SB), X0
1181 AESENC runtime·aeskeysched+16(SB), X0
Keith Randall7a4a64e2014-12-10 14:20:17 -08001182 AESENC runtime·aeskeysched+32(SB), X0
Keith Randalld5e4c402015-01-06 16:42:48 -08001183 MOVQ X0, ret+16(FP)
Keith Randalla5d40242013-03-12 10:47:44 -07001184 RET
1185
1186// simple mask to get rid of data in the high part of the register.
Russ Cox9ddfb642013-07-16 16:24:09 -04001187DATA masks<>+0x00(SB)/8, $0x0000000000000000
1188DATA masks<>+0x08(SB)/8, $0x0000000000000000
1189DATA masks<>+0x10(SB)/8, $0x00000000000000ff
1190DATA masks<>+0x18(SB)/8, $0x0000000000000000
1191DATA masks<>+0x20(SB)/8, $0x000000000000ffff
1192DATA masks<>+0x28(SB)/8, $0x0000000000000000
1193DATA masks<>+0x30(SB)/8, $0x0000000000ffffff
1194DATA masks<>+0x38(SB)/8, $0x0000000000000000
1195DATA masks<>+0x40(SB)/8, $0x00000000ffffffff
1196DATA masks<>+0x48(SB)/8, $0x0000000000000000
1197DATA masks<>+0x50(SB)/8, $0x000000ffffffffff
1198DATA masks<>+0x58(SB)/8, $0x0000000000000000
1199DATA masks<>+0x60(SB)/8, $0x0000ffffffffffff
1200DATA masks<>+0x68(SB)/8, $0x0000000000000000
1201DATA masks<>+0x70(SB)/8, $0x00ffffffffffffff
1202DATA masks<>+0x78(SB)/8, $0x0000000000000000
1203DATA masks<>+0x80(SB)/8, $0xffffffffffffffff
1204DATA masks<>+0x88(SB)/8, $0x0000000000000000
1205DATA masks<>+0x90(SB)/8, $0xffffffffffffffff
1206DATA masks<>+0x98(SB)/8, $0x00000000000000ff
1207DATA masks<>+0xa0(SB)/8, $0xffffffffffffffff
1208DATA masks<>+0xa8(SB)/8, $0x000000000000ffff
1209DATA masks<>+0xb0(SB)/8, $0xffffffffffffffff
1210DATA masks<>+0xb8(SB)/8, $0x0000000000ffffff
1211DATA masks<>+0xc0(SB)/8, $0xffffffffffffffff
1212DATA masks<>+0xc8(SB)/8, $0x00000000ffffffff
1213DATA masks<>+0xd0(SB)/8, $0xffffffffffffffff
1214DATA masks<>+0xd8(SB)/8, $0x000000ffffffffff
1215DATA masks<>+0xe0(SB)/8, $0xffffffffffffffff
1216DATA masks<>+0xe8(SB)/8, $0x0000ffffffffffff
1217DATA masks<>+0xf0(SB)/8, $0xffffffffffffffff
1218DATA masks<>+0xf8(SB)/8, $0x00ffffffffffffff
Keith Randall5a546962013-08-07 10:23:24 -07001219GLOBL masks<>(SB),RODATA,$256
Keith Randalla5d40242013-03-12 10:47:44 -07001220
Russ Cox9ddfb642013-07-16 16:24:09 -04001221// these are arguments to pshufb. They move data down from
1222// the high bytes of the register to the low bytes of the register.
1223// index is how many bytes to move.
1224DATA shifts<>+0x00(SB)/8, $0x0000000000000000
1225DATA shifts<>+0x08(SB)/8, $0x0000000000000000
1226DATA shifts<>+0x10(SB)/8, $0xffffffffffffff0f
1227DATA shifts<>+0x18(SB)/8, $0xffffffffffffffff
1228DATA shifts<>+0x20(SB)/8, $0xffffffffffff0f0e
1229DATA shifts<>+0x28(SB)/8, $0xffffffffffffffff
1230DATA shifts<>+0x30(SB)/8, $0xffffffffff0f0e0d
1231DATA shifts<>+0x38(SB)/8, $0xffffffffffffffff
1232DATA shifts<>+0x40(SB)/8, $0xffffffff0f0e0d0c
1233DATA shifts<>+0x48(SB)/8, $0xffffffffffffffff
1234DATA shifts<>+0x50(SB)/8, $0xffffff0f0e0d0c0b
1235DATA shifts<>+0x58(SB)/8, $0xffffffffffffffff
1236DATA shifts<>+0x60(SB)/8, $0xffff0f0e0d0c0b0a
1237DATA shifts<>+0x68(SB)/8, $0xffffffffffffffff
1238DATA shifts<>+0x70(SB)/8, $0xff0f0e0d0c0b0a09
1239DATA shifts<>+0x78(SB)/8, $0xffffffffffffffff
1240DATA shifts<>+0x80(SB)/8, $0x0f0e0d0c0b0a0908
1241DATA shifts<>+0x88(SB)/8, $0xffffffffffffffff
1242DATA shifts<>+0x90(SB)/8, $0x0e0d0c0b0a090807
1243DATA shifts<>+0x98(SB)/8, $0xffffffffffffff0f
1244DATA shifts<>+0xa0(SB)/8, $0x0d0c0b0a09080706
1245DATA shifts<>+0xa8(SB)/8, $0xffffffffffff0f0e
1246DATA shifts<>+0xb0(SB)/8, $0x0c0b0a0908070605
1247DATA shifts<>+0xb8(SB)/8, $0xffffffffff0f0e0d
1248DATA shifts<>+0xc0(SB)/8, $0x0b0a090807060504
1249DATA shifts<>+0xc8(SB)/8, $0xffffffff0f0e0d0c
1250DATA shifts<>+0xd0(SB)/8, $0x0a09080706050403
1251DATA shifts<>+0xd8(SB)/8, $0xffffff0f0e0d0c0b
1252DATA shifts<>+0xe0(SB)/8, $0x0908070605040302
1253DATA shifts<>+0xe8(SB)/8, $0xffff0f0e0d0c0b0a
1254DATA shifts<>+0xf0(SB)/8, $0x0807060504030201
1255DATA shifts<>+0xf8(SB)/8, $0xff0f0e0d0c0b0a09
Keith Randall5a546962013-08-07 10:23:24 -07001256GLOBL shifts<>(SB),RODATA,$256
Keith Randall3d5daa22013-04-02 16:26:15 -07001257
Keith Randall7aa4e5a2014-08-07 14:52:55 -07001258TEXT runtime·memeq(SB),NOSPLIT,$0-25
Keith Randall0c6b55e2014-07-16 14:16:19 -07001259 MOVQ a+0(FP), SI
1260 MOVQ b+8(FP), DI
1261 MOVQ size+16(FP), BX
1262 CALL runtime·memeqbody(SB)
1263 MOVB AX, ret+24(FP)
1264 RET
1265
Keith Randalld5e4c402015-01-06 16:42:48 -08001266// memequal_varlen(a, b unsafe.Pointer) bool
1267TEXT runtime·memequal_varlen(SB),NOSPLIT,$0-17
1268 MOVQ a+0(FP), SI
1269 MOVQ b+8(FP), DI
1270 CMPQ SI, DI
1271 JEQ eq
1272 MOVQ 8(DX), BX // compiler stores size at offset 8 in the closure
1273 CALL runtime·memeqbody(SB)
1274 MOVB AX, ret+16(FP)
1275 RET
1276eq:
1277 MOVB $1, ret+16(FP)
1278 RET
1279
Keith Randallb36ed902014-06-16 21:00:37 -07001280// eqstring tests whether two strings are equal.
Josh Bleecher Snyder135ef492015-02-04 17:31:37 -08001281// The compiler guarantees that strings passed
1282// to eqstring have equal length.
Keith Randallb36ed902014-06-16 21:00:37 -07001283// See runtime_test.go:eqstring_generic for
Josh Bleecher Snyder339a24d2014-08-19 08:50:35 -07001284// equivalent Go code.
Keith Randallb36ed902014-06-16 21:00:37 -07001285TEXT runtime·eqstring(SB),NOSPLIT,$0-33
Keith Randallb36ed902014-06-16 21:00:37 -07001286 MOVQ s1str+0(FP), SI
1287 MOVQ s2str+16(FP), DI
1288 CMPQ SI, DI
Russ Coxb55791e2014-10-28 21:50:16 -04001289 JEQ eq
Josh Bleecher Snyder135ef492015-02-04 17:31:37 -08001290 MOVQ s1len+8(FP), BX
Keith Randallb36ed902014-06-16 21:00:37 -07001291 CALL runtime·memeqbody(SB)
1292 MOVB AX, v+32(FP)
1293 RET
Russ Coxb55791e2014-10-28 21:50:16 -04001294eq:
Keith Randallb36ed902014-06-16 21:00:37 -07001295 MOVB $1, v+32(FP)
1296 RET
Keith Randallb36ed902014-06-16 21:00:37 -07001297
Keith Randall3d5daa22013-04-02 16:26:15 -07001298// a in SI
1299// b in DI
1300// count in BX
Keith Randall5a546962013-08-07 10:23:24 -07001301TEXT runtime·memeqbody(SB),NOSPLIT,$0-0
Keith Randall3d5daa22013-04-02 16:26:15 -07001302 XORQ AX, AX
1303
1304 CMPQ BX, $8
1305 JB small
1306
1307 // 64 bytes at a time using xmm registers
1308hugeloop:
1309 CMPQ BX, $64
1310 JB bigloop
1311 MOVOU (SI), X0
1312 MOVOU (DI), X1
1313 MOVOU 16(SI), X2
1314 MOVOU 16(DI), X3
1315 MOVOU 32(SI), X4
1316 MOVOU 32(DI), X5
1317 MOVOU 48(SI), X6
1318 MOVOU 48(DI), X7
1319 PCMPEQB X1, X0
1320 PCMPEQB X3, X2
1321 PCMPEQB X5, X4
1322 PCMPEQB X7, X6
1323 PAND X2, X0
1324 PAND X6, X4
1325 PAND X4, X0
1326 PMOVMSKB X0, DX
1327 ADDQ $64, SI
1328 ADDQ $64, DI
1329 SUBQ $64, BX
1330 CMPL DX, $0xffff
1331 JEQ hugeloop
1332 RET
1333
1334 // 8 bytes at a time using 64-bit register
1335bigloop:
1336 CMPQ BX, $8
1337 JBE leftover
1338 MOVQ (SI), CX
1339 MOVQ (DI), DX
1340 ADDQ $8, SI
1341 ADDQ $8, DI
1342 SUBQ $8, BX
1343 CMPQ CX, DX
1344 JEQ bigloop
1345 RET
1346
1347 // remaining 0-8 bytes
1348leftover:
1349 MOVQ -8(SI)(BX*1), CX
1350 MOVQ -8(DI)(BX*1), DX
1351 CMPQ CX, DX
1352 SETEQ AX
1353 RET
1354
1355small:
1356 CMPQ BX, $0
1357 JEQ equal
1358
1359 LEAQ 0(BX*8), CX
1360 NEGQ CX
1361
1362 CMPB SI, $0xf8
1363 JA si_high
1364
1365 // load at SI won't cross a page boundary.
1366 MOVQ (SI), SI
1367 JMP si_finish
1368si_high:
1369 // address ends in 11111xxx. Load up to bytes we want, move to correct position.
1370 MOVQ -8(SI)(BX*1), SI
1371 SHRQ CX, SI
1372si_finish:
1373
1374 // same for DI.
1375 CMPB DI, $0xf8
1376 JA di_high
1377 MOVQ (DI), DI
1378 JMP di_finish
1379di_high:
1380 MOVQ -8(DI)(BX*1), DI
1381 SHRQ CX, DI
1382di_finish:
1383
1384 SUBQ SI, DI
1385 SHLQ CX, DI
1386equal:
1387 SETEQ AX
1388 RET
Keith Randallb3946dc2013-05-14 16:05:51 -07001389
Keith Randall5a546962013-08-07 10:23:24 -07001390TEXT runtime·cmpstring(SB),NOSPLIT,$0-40
Russ Cox25f6b022014-08-27 11:32:17 -04001391 MOVQ s1_base+0(FP), SI
1392 MOVQ s1_len+8(FP), BX
1393 MOVQ s2_base+16(FP), DI
1394 MOVQ s2_len+24(FP), DX
Keith Randallb3946dc2013-05-14 16:05:51 -07001395 CALL runtime·cmpbody(SB)
Russ Cox25f6b022014-08-27 11:32:17 -04001396 MOVQ AX, ret+32(FP)
Keith Randallb3946dc2013-05-14 16:05:51 -07001397 RET
1398
Russ Cox7a524a12014-12-22 13:27:53 -05001399TEXT bytes·Compare(SB),NOSPLIT,$0-56
Keith Randallb3946dc2013-05-14 16:05:51 -07001400 MOVQ s1+0(FP), SI
1401 MOVQ s1+8(FP), BX
1402 MOVQ s2+24(FP), DI
1403 MOVQ s2+32(FP), DX
1404 CALL runtime·cmpbody(SB)
1405 MOVQ AX, res+48(FP)
1406 RET
1407
1408// input:
1409// SI = a
1410// DI = b
1411// BX = alen
1412// DX = blen
1413// output:
1414// AX = 1/0/-1
Keith Randall5a546962013-08-07 10:23:24 -07001415TEXT runtime·cmpbody(SB),NOSPLIT,$0-0
Keith Randallb3946dc2013-05-14 16:05:51 -07001416 CMPQ SI, DI
Russ Coxb55791e2014-10-28 21:50:16 -04001417 JEQ allsame
Keith Randallb3946dc2013-05-14 16:05:51 -07001418 CMPQ BX, DX
Austin Clements20a6ff72015-01-27 18:29:02 -05001419 MOVQ DX, R8
1420 CMOVQLT BX, R8 // R8 = min(alen, blen) = # of bytes to compare
1421 CMPQ R8, $8
Russ Coxb55791e2014-10-28 21:50:16 -04001422 JB small
Keith Randallb3946dc2013-05-14 16:05:51 -07001423
Russ Coxb55791e2014-10-28 21:50:16 -04001424loop:
Austin Clements20a6ff72015-01-27 18:29:02 -05001425 CMPQ R8, $16
Russ Coxb55791e2014-10-28 21:50:16 -04001426 JBE _0through16
Keith Randallb3946dc2013-05-14 16:05:51 -07001427 MOVOU (SI), X0
1428 MOVOU (DI), X1
1429 PCMPEQB X0, X1
1430 PMOVMSKB X1, AX
1431 XORQ $0xffff, AX // convert EQ to NE
Russ Coxb55791e2014-10-28 21:50:16 -04001432 JNE diff16 // branch if at least one byte is not equal
Keith Randallb3946dc2013-05-14 16:05:51 -07001433 ADDQ $16, SI
1434 ADDQ $16, DI
Austin Clements20a6ff72015-01-27 18:29:02 -05001435 SUBQ $16, R8
Russ Coxb55791e2014-10-28 21:50:16 -04001436 JMP loop
Keith Randallb3946dc2013-05-14 16:05:51 -07001437
1438 // AX = bit mask of differences
Russ Coxb55791e2014-10-28 21:50:16 -04001439diff16:
Keith Randallb3946dc2013-05-14 16:05:51 -07001440 BSFQ AX, BX // index of first byte that differs
1441 XORQ AX, AX
1442 MOVB (SI)(BX*1), CX
1443 CMPB CX, (DI)(BX*1)
1444 SETHI AX
1445 LEAQ -1(AX*2), AX // convert 1/0 to +1/-1
1446 RET
1447
1448 // 0 through 16 bytes left, alen>=8, blen>=8
Russ Coxb55791e2014-10-28 21:50:16 -04001449_0through16:
Austin Clements20a6ff72015-01-27 18:29:02 -05001450 CMPQ R8, $8
Russ Coxb55791e2014-10-28 21:50:16 -04001451 JBE _0through8
Keith Randallb3946dc2013-05-14 16:05:51 -07001452 MOVQ (SI), AX
1453 MOVQ (DI), CX
1454 CMPQ AX, CX
Russ Coxb55791e2014-10-28 21:50:16 -04001455 JNE diff8
1456_0through8:
Austin Clements20a6ff72015-01-27 18:29:02 -05001457 MOVQ -8(SI)(R8*1), AX
1458 MOVQ -8(DI)(R8*1), CX
Keith Randallb3946dc2013-05-14 16:05:51 -07001459 CMPQ AX, CX
Russ Coxb55791e2014-10-28 21:50:16 -04001460 JEQ allsame
Keith Randallb3946dc2013-05-14 16:05:51 -07001461
1462 // AX and CX contain parts of a and b that differ.
Russ Coxb55791e2014-10-28 21:50:16 -04001463diff8:
Keith Randallb3946dc2013-05-14 16:05:51 -07001464 BSWAPQ AX // reverse order of bytes
1465 BSWAPQ CX
1466 XORQ AX, CX
1467 BSRQ CX, CX // index of highest bit difference
1468 SHRQ CX, AX // move a's bit to bottom
1469 ANDQ $1, AX // mask bit
1470 LEAQ -1(AX*2), AX // 1/0 => +1/-1
1471 RET
1472
1473 // 0-7 bytes in common
Russ Coxb55791e2014-10-28 21:50:16 -04001474small:
Austin Clements20a6ff72015-01-27 18:29:02 -05001475 LEAQ (R8*8), CX // bytes left -> bits left
Keith Randallb3946dc2013-05-14 16:05:51 -07001476 NEGQ CX // - bits lift (== 64 - bits left mod 64)
Russ Coxb55791e2014-10-28 21:50:16 -04001477 JEQ allsame
Keith Randallb3946dc2013-05-14 16:05:51 -07001478
1479 // load bytes of a into high bytes of AX
1480 CMPB SI, $0xf8
Russ Coxb55791e2014-10-28 21:50:16 -04001481 JA si_high
Keith Randallb3946dc2013-05-14 16:05:51 -07001482 MOVQ (SI), SI
Russ Coxb55791e2014-10-28 21:50:16 -04001483 JMP si_finish
1484si_high:
Austin Clements20a6ff72015-01-27 18:29:02 -05001485 MOVQ -8(SI)(R8*1), SI
Keith Randallb3946dc2013-05-14 16:05:51 -07001486 SHRQ CX, SI
Russ Coxb55791e2014-10-28 21:50:16 -04001487si_finish:
Keith Randallb3946dc2013-05-14 16:05:51 -07001488 SHLQ CX, SI
1489
1490 // load bytes of b in to high bytes of BX
1491 CMPB DI, $0xf8
Russ Coxb55791e2014-10-28 21:50:16 -04001492 JA di_high
Keith Randallb3946dc2013-05-14 16:05:51 -07001493 MOVQ (DI), DI
Russ Coxb55791e2014-10-28 21:50:16 -04001494 JMP di_finish
1495di_high:
Austin Clements20a6ff72015-01-27 18:29:02 -05001496 MOVQ -8(DI)(R8*1), DI
Keith Randallb3946dc2013-05-14 16:05:51 -07001497 SHRQ CX, DI
Russ Coxb55791e2014-10-28 21:50:16 -04001498di_finish:
Keith Randallb3946dc2013-05-14 16:05:51 -07001499 SHLQ CX, DI
1500
1501 BSWAPQ SI // reverse order of bytes
1502 BSWAPQ DI
1503 XORQ SI, DI // find bit differences
Russ Coxb55791e2014-10-28 21:50:16 -04001504 JEQ allsame
Keith Randallb3946dc2013-05-14 16:05:51 -07001505 BSRQ DI, CX // index of highest bit difference
1506 SHRQ CX, SI // move a's bit to bottom
1507 ANDQ $1, SI // mask bit
1508 LEAQ -1(SI*2), AX // 1/0 => +1/-1
1509 RET
1510
Russ Coxb55791e2014-10-28 21:50:16 -04001511allsame:
Keith Randallb3946dc2013-05-14 16:05:51 -07001512 XORQ AX, AX
1513 XORQ CX, CX
1514 CMPQ BX, DX
1515 SETGT AX // 1 if alen > blen
1516 SETEQ CX // 1 if alen == blen
1517 LEAQ -1(CX)(AX*2), AX // 1,0,-1 result
1518 RET
Brad Fitzpatricke2a1bd62013-08-01 16:11:19 -07001519
Shenghou Ma3b001972015-03-07 00:18:16 -05001520TEXT bytes·IndexByte(SB),NOSPLIT,$0-40
Brad Fitzpatricke2a1bd62013-08-01 16:11:19 -07001521 MOVQ s+0(FP), SI
1522 MOVQ s_len+8(FP), BX
1523 MOVB c+24(FP), AL
Brad Fitzpatrick598c7892013-08-05 15:04:05 -07001524 CALL runtime·indexbytebody(SB)
1525 MOVQ AX, ret+32(FP)
1526 RET
1527
Shenghou Ma3b001972015-03-07 00:18:16 -05001528TEXT strings·IndexByte(SB),NOSPLIT,$0-32
Brad Fitzpatrick598c7892013-08-05 15:04:05 -07001529 MOVQ s+0(FP), SI
1530 MOVQ s_len+8(FP), BX
1531 MOVB c+16(FP), AL
1532 CALL runtime·indexbytebody(SB)
1533 MOVQ AX, ret+24(FP)
1534 RET
1535
1536// input:
1537// SI: data
1538// BX: data len
1539// AL: byte sought
1540// output:
1541// AX
Keith Randall5a546962013-08-07 10:23:24 -07001542TEXT runtime·indexbytebody(SB),NOSPLIT,$0
Brad Fitzpatricke2a1bd62013-08-01 16:11:19 -07001543 MOVQ SI, DI
1544
1545 CMPQ BX, $16
Russ Coxb55791e2014-10-28 21:50:16 -04001546 JLT small
Brad Fitzpatricke2a1bd62013-08-01 16:11:19 -07001547
1548 // round up to first 16-byte boundary
1549 TESTQ $15, SI
1550 JZ aligned
1551 MOVQ SI, CX
1552 ANDQ $~15, CX
1553 ADDQ $16, CX
1554
1555 // search the beginning
1556 SUBQ SI, CX
1557 REPN; SCASB
1558 JZ success
1559
1560// DI is 16-byte aligned; get ready to search using SSE instructions
1561aligned:
1562 // round down to last 16-byte boundary
1563 MOVQ BX, R11
1564 ADDQ SI, R11
1565 ANDQ $~15, R11
1566
1567 // shuffle X0 around so that each byte contains c
1568 MOVD AX, X0
1569 PUNPCKLBW X0, X0
1570 PUNPCKLBW X0, X0
1571 PSHUFL $0, X0, X0
1572 JMP condition
1573
1574sse:
1575 // move the next 16-byte chunk of the buffer into X1
1576 MOVO (DI), X1
1577 // compare bytes in X0 to X1
1578 PCMPEQB X0, X1
1579 // take the top bit of each byte in X1 and put the result in DX
1580 PMOVMSKB X1, DX
1581 TESTL DX, DX
1582 JNZ ssesuccess
1583 ADDQ $16, DI
1584
1585condition:
1586 CMPQ DI, R11
1587 JLT sse
1588
1589 // search the end
1590 MOVQ SI, CX
1591 ADDQ BX, CX
1592 SUBQ R11, CX
1593 // if CX == 0, the zero flag will be set and we'll end up
1594 // returning a false success
1595 JZ failure
1596 REPN; SCASB
1597 JZ success
1598
1599failure:
Brad Fitzpatrick598c7892013-08-05 15:04:05 -07001600 MOVQ $-1, AX
Brad Fitzpatricke2a1bd62013-08-01 16:11:19 -07001601 RET
1602
1603// handle for lengths < 16
Russ Coxb55791e2014-10-28 21:50:16 -04001604small:
Brad Fitzpatricke2a1bd62013-08-01 16:11:19 -07001605 MOVQ BX, CX
1606 REPN; SCASB
1607 JZ success
Brad Fitzpatrick598c7892013-08-05 15:04:05 -07001608 MOVQ $-1, AX
Brad Fitzpatricke2a1bd62013-08-01 16:11:19 -07001609 RET
1610
1611// we've found the chunk containing the byte
1612// now just figure out which specific byte it is
1613ssesuccess:
1614 // get the index of the least significant set bit
1615 BSFW DX, DX
1616 SUBQ SI, DI
1617 ADDQ DI, DX
Brad Fitzpatrick598c7892013-08-05 15:04:05 -07001618 MOVQ DX, AX
Brad Fitzpatricke2a1bd62013-08-01 16:11:19 -07001619 RET
1620
1621success:
1622 SUBQ SI, DI
1623 SUBL $1, DI
Brad Fitzpatrick598c7892013-08-05 15:04:05 -07001624 MOVQ DI, AX
Brad Fitzpatricke2a1bd62013-08-01 16:11:19 -07001625 RET
1626
Keith Randall5a546962013-08-07 10:23:24 -07001627TEXT bytes·Equal(SB),NOSPLIT,$0-49
Brad Fitzpatricke2a1bd62013-08-01 16:11:19 -07001628 MOVQ a_len+8(FP), BX
1629 MOVQ b_len+32(FP), CX
1630 XORQ AX, AX
1631 CMPQ BX, CX
1632 JNE eqret
1633 MOVQ a+0(FP), SI
1634 MOVQ b+24(FP), DI
1635 CALL runtime·memeqbody(SB)
1636eqret:
1637 MOVB AX, ret+48(FP)
1638 RET
Keith Randall6c7cbf02014-04-01 12:51:02 -07001639
1640// A Duff's device for zeroing memory.
1641// The compiler jumps to computed addresses within
1642// this routine to zero chunks of memory. Do not
1643// change this code without also changing the code
1644// in ../../cmd/6g/ggen.c:clearfat.
1645// AX: zero
1646// DI: ptr to memory to be zeroed
1647// DI is updated as a side effect.
1648TEXT runtime·duffzero(SB), NOSPLIT, $0-0
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 STOSQ
1766 STOSQ
1767 STOSQ
1768 STOSQ
1769 STOSQ
1770 STOSQ
1771 STOSQ
1772 STOSQ
1773 STOSQ
1774 STOSQ
1775 STOSQ
1776 STOSQ
1777 RET
1778
1779// A Duff's device for copying memory.
1780// The compiler jumps to computed addresses within
1781// this routine to copy chunks of memory. Source
1782// and destination must not overlap. Do not
1783// change this code without also changing the code
1784// in ../../cmd/6g/cgen.c:sgen.
1785// SI: ptr to source memory
1786// DI: ptr to destination memory
1787// SI and DI are updated as a side effect.
1788
1789// NOTE: this is equivalent to a sequence of MOVSQ but
1790// for some reason that is 3.5x slower than this code.
1791// The STOSQ above seem fine, though.
1792TEXT runtime·duffcopy(SB), NOSPLIT, $0-0
1793 MOVQ (SI),CX
1794 ADDQ $8,SI
1795 MOVQ CX,(DI)
1796 ADDQ $8,DI
1797
1798 MOVQ (SI),CX
1799 ADDQ $8,SI
1800 MOVQ CX,(DI)
1801 ADDQ $8,DI
1802
1803 MOVQ (SI),CX
1804 ADDQ $8,SI
1805 MOVQ CX,(DI)
1806 ADDQ $8,DI
1807
1808 MOVQ (SI),CX
1809 ADDQ $8,SI
1810 MOVQ CX,(DI)
1811 ADDQ $8,DI
1812
1813 MOVQ (SI),CX
1814 ADDQ $8,SI
1815 MOVQ CX,(DI)
1816 ADDQ $8,DI
1817
1818 MOVQ (SI),CX
1819 ADDQ $8,SI
1820 MOVQ CX,(DI)
1821 ADDQ $8,DI
1822
1823 MOVQ (SI),CX
1824 ADDQ $8,SI
1825 MOVQ CX,(DI)
1826 ADDQ $8,DI
1827
1828 MOVQ (SI),CX
1829 ADDQ $8,SI
1830 MOVQ CX,(DI)
1831 ADDQ $8,DI
1832
1833 MOVQ (SI),CX
1834 ADDQ $8,SI
1835 MOVQ CX,(DI)
1836 ADDQ $8,DI
1837
1838 MOVQ (SI),CX
1839 ADDQ $8,SI
1840 MOVQ CX,(DI)
1841 ADDQ $8,DI
1842
1843 MOVQ (SI),CX
1844 ADDQ $8,SI
1845 MOVQ CX,(DI)
1846 ADDQ $8,DI
1847
1848 MOVQ (SI),CX
1849 ADDQ $8,SI
1850 MOVQ CX,(DI)
1851 ADDQ $8,DI
1852
1853 MOVQ (SI),CX
1854 ADDQ $8,SI
1855 MOVQ CX,(DI)
1856 ADDQ $8,DI
1857
1858 MOVQ (SI),CX
1859 ADDQ $8,SI
1860 MOVQ CX,(DI)
1861 ADDQ $8,DI
1862
1863 MOVQ (SI),CX
1864 ADDQ $8,SI
1865 MOVQ CX,(DI)
1866 ADDQ $8,DI
1867
1868 MOVQ (SI),CX
1869 ADDQ $8,SI
1870 MOVQ CX,(DI)
1871 ADDQ $8,DI
1872
1873 MOVQ (SI),CX
1874 ADDQ $8,SI
1875 MOVQ CX,(DI)
1876 ADDQ $8,DI
1877
1878 MOVQ (SI),CX
1879 ADDQ $8,SI
1880 MOVQ CX,(DI)
1881 ADDQ $8,DI
1882
1883 MOVQ (SI),CX
1884 ADDQ $8,SI
1885 MOVQ CX,(DI)
1886 ADDQ $8,DI
1887
1888 MOVQ (SI),CX
1889 ADDQ $8,SI
1890 MOVQ CX,(DI)
1891 ADDQ $8,DI
1892
1893 MOVQ (SI),CX
1894 ADDQ $8,SI
1895 MOVQ CX,(DI)
1896 ADDQ $8,DI
1897
1898 MOVQ (SI),CX
1899 ADDQ $8,SI
1900 MOVQ CX,(DI)
1901 ADDQ $8,DI
1902
1903 MOVQ (SI),CX
1904 ADDQ $8,SI
1905 MOVQ CX,(DI)
1906 ADDQ $8,DI
1907
1908 MOVQ (SI),CX
1909 ADDQ $8,SI
1910 MOVQ CX,(DI)
1911 ADDQ $8,DI
1912
1913 MOVQ (SI),CX
1914 ADDQ $8,SI
1915 MOVQ CX,(DI)
1916 ADDQ $8,DI
1917
1918 MOVQ (SI),CX
1919 ADDQ $8,SI
1920 MOVQ CX,(DI)
1921 ADDQ $8,DI
1922
1923 MOVQ (SI),CX
1924 ADDQ $8,SI
1925 MOVQ CX,(DI)
1926 ADDQ $8,DI
1927
1928 MOVQ (SI),CX
1929 ADDQ $8,SI
1930 MOVQ CX,(DI)
1931 ADDQ $8,DI
1932
1933 MOVQ (SI),CX
1934 ADDQ $8,SI
1935 MOVQ CX,(DI)
1936 ADDQ $8,DI
1937
1938 MOVQ (SI),CX
1939 ADDQ $8,SI
1940 MOVQ CX,(DI)
1941 ADDQ $8,DI
1942
1943 MOVQ (SI),CX
1944 ADDQ $8,SI
1945 MOVQ CX,(DI)
1946 ADDQ $8,DI
1947
1948 MOVQ (SI),CX
1949 ADDQ $8,SI
1950 MOVQ CX,(DI)
1951 ADDQ $8,DI
1952
1953 MOVQ (SI),CX
1954 ADDQ $8,SI
1955 MOVQ CX,(DI)
1956 ADDQ $8,DI
1957
1958 MOVQ (SI),CX
1959 ADDQ $8,SI
1960 MOVQ CX,(DI)
1961 ADDQ $8,DI
1962
1963 MOVQ (SI),CX
1964 ADDQ $8,SI
1965 MOVQ CX,(DI)
1966 ADDQ $8,DI
1967
1968 MOVQ (SI),CX
1969 ADDQ $8,SI
1970 MOVQ CX,(DI)
1971 ADDQ $8,DI
1972
1973 MOVQ (SI),CX
1974 ADDQ $8,SI
1975 MOVQ CX,(DI)
1976 ADDQ $8,DI
1977
1978 MOVQ (SI),CX
1979 ADDQ $8,SI
1980 MOVQ CX,(DI)
1981 ADDQ $8,DI
1982
1983 MOVQ (SI),CX
1984 ADDQ $8,SI
1985 MOVQ CX,(DI)
1986 ADDQ $8,DI
1987
1988 MOVQ (SI),CX
1989 ADDQ $8,SI
1990 MOVQ CX,(DI)
1991 ADDQ $8,DI
1992
1993 MOVQ (SI),CX
1994 ADDQ $8,SI
1995 MOVQ CX,(DI)
1996 ADDQ $8,DI
1997
1998 MOVQ (SI),CX
1999 ADDQ $8,SI
2000 MOVQ CX,(DI)
2001 ADDQ $8,DI
2002
2003 MOVQ (SI),CX
2004 ADDQ $8,SI
2005 MOVQ CX,(DI)
2006 ADDQ $8,DI
2007
2008 MOVQ (SI),CX
2009 ADDQ $8,SI
2010 MOVQ CX,(DI)
2011 ADDQ $8,DI
2012
2013 MOVQ (SI),CX
2014 ADDQ $8,SI
2015 MOVQ CX,(DI)
2016 ADDQ $8,DI
2017
2018 MOVQ (SI),CX
2019 ADDQ $8,SI
2020 MOVQ CX,(DI)
2021 ADDQ $8,DI
2022
2023 MOVQ (SI),CX
2024 ADDQ $8,SI
2025 MOVQ CX,(DI)
2026 ADDQ $8,DI
2027
2028 MOVQ (SI),CX
2029 ADDQ $8,SI
2030 MOVQ CX,(DI)
2031 ADDQ $8,DI
2032
2033 MOVQ (SI),CX
2034 ADDQ $8,SI
2035 MOVQ CX,(DI)
2036 ADDQ $8,DI
2037
2038 MOVQ (SI),CX
2039 ADDQ $8,SI
2040 MOVQ CX,(DI)
2041 ADDQ $8,DI
2042
2043 MOVQ (SI),CX
2044 ADDQ $8,SI
2045 MOVQ CX,(DI)
2046 ADDQ $8,DI
2047
2048 MOVQ (SI),CX
2049 ADDQ $8,SI
2050 MOVQ CX,(DI)
2051 ADDQ $8,DI
2052
2053 MOVQ (SI),CX
2054 ADDQ $8,SI
2055 MOVQ CX,(DI)
2056 ADDQ $8,DI
2057
2058 MOVQ (SI),CX
2059 ADDQ $8,SI
2060 MOVQ CX,(DI)
2061 ADDQ $8,DI
2062
2063 MOVQ (SI),CX
2064 ADDQ $8,SI
2065 MOVQ CX,(DI)
2066 ADDQ $8,DI
2067
2068 MOVQ (SI),CX
2069 ADDQ $8,SI
2070 MOVQ CX,(DI)
2071 ADDQ $8,DI
2072
2073 MOVQ (SI),CX
2074 ADDQ $8,SI
2075 MOVQ CX,(DI)
2076 ADDQ $8,DI
2077
2078 MOVQ (SI),CX
2079 ADDQ $8,SI
2080 MOVQ CX,(DI)
2081 ADDQ $8,DI
2082
2083 MOVQ (SI),CX
2084 ADDQ $8,SI
2085 MOVQ CX,(DI)
2086 ADDQ $8,DI
2087
2088 MOVQ (SI),CX
2089 ADDQ $8,SI
2090 MOVQ CX,(DI)
2091 ADDQ $8,DI
2092
2093 MOVQ (SI),CX
2094 ADDQ $8,SI
2095 MOVQ CX,(DI)
2096 ADDQ $8,DI
2097
2098 MOVQ (SI),CX
2099 ADDQ $8,SI
2100 MOVQ CX,(DI)
2101 ADDQ $8,DI
2102
2103 MOVQ (SI),CX
2104 ADDQ $8,SI
2105 MOVQ CX,(DI)
2106 ADDQ $8,DI
2107
2108 MOVQ (SI),CX
2109 ADDQ $8,SI
2110 MOVQ CX,(DI)
2111 ADDQ $8,DI
2112
2113 MOVQ (SI),CX
2114 ADDQ $8,SI
2115 MOVQ CX,(DI)
2116 ADDQ $8,DI
2117
2118 MOVQ (SI),CX
2119 ADDQ $8,SI
2120 MOVQ CX,(DI)
2121 ADDQ $8,DI
2122
2123 MOVQ (SI),CX
2124 ADDQ $8,SI
2125 MOVQ CX,(DI)
2126 ADDQ $8,DI
2127
2128 MOVQ (SI),CX
2129 ADDQ $8,SI
2130 MOVQ CX,(DI)
2131 ADDQ $8,DI
2132
2133 MOVQ (SI),CX
2134 ADDQ $8,SI
2135 MOVQ CX,(DI)
2136 ADDQ $8,DI
2137
2138 MOVQ (SI),CX
2139 ADDQ $8,SI
2140 MOVQ CX,(DI)
2141 ADDQ $8,DI
2142
2143 MOVQ (SI),CX
2144 ADDQ $8,SI
2145 MOVQ CX,(DI)
2146 ADDQ $8,DI
2147
2148 MOVQ (SI),CX
2149 ADDQ $8,SI
2150 MOVQ CX,(DI)
2151 ADDQ $8,DI
2152
2153 MOVQ (SI),CX
2154 ADDQ $8,SI
2155 MOVQ CX,(DI)
2156 ADDQ $8,DI
2157
2158 MOVQ (SI),CX
2159 ADDQ $8,SI
2160 MOVQ CX,(DI)
2161 ADDQ $8,DI
2162
2163 MOVQ (SI),CX
2164 ADDQ $8,SI
2165 MOVQ CX,(DI)
2166 ADDQ $8,DI
2167
2168 MOVQ (SI),CX
2169 ADDQ $8,SI
2170 MOVQ CX,(DI)
2171 ADDQ $8,DI
2172
2173 MOVQ (SI),CX
2174 ADDQ $8,SI
2175 MOVQ CX,(DI)
2176 ADDQ $8,DI
2177
2178 MOVQ (SI),CX
2179 ADDQ $8,SI
2180 MOVQ CX,(DI)
2181 ADDQ $8,DI
2182
2183 MOVQ (SI),CX
2184 ADDQ $8,SI
2185 MOVQ CX,(DI)
2186 ADDQ $8,DI
2187
2188 MOVQ (SI),CX
2189 ADDQ $8,SI
2190 MOVQ CX,(DI)
2191 ADDQ $8,DI
2192
2193 MOVQ (SI),CX
2194 ADDQ $8,SI
2195 MOVQ CX,(DI)
2196 ADDQ $8,DI
2197
2198 MOVQ (SI),CX
2199 ADDQ $8,SI
2200 MOVQ CX,(DI)
2201 ADDQ $8,DI
2202
2203 MOVQ (SI),CX
2204 ADDQ $8,SI
2205 MOVQ CX,(DI)
2206 ADDQ $8,DI
2207
2208 MOVQ (SI),CX
2209 ADDQ $8,SI
2210 MOVQ CX,(DI)
2211 ADDQ $8,DI
2212
2213 MOVQ (SI),CX
2214 ADDQ $8,SI
2215 MOVQ CX,(DI)
2216 ADDQ $8,DI
2217
2218 MOVQ (SI),CX
2219 ADDQ $8,SI
2220 MOVQ CX,(DI)
2221 ADDQ $8,DI
2222
2223 MOVQ (SI),CX
2224 ADDQ $8,SI
2225 MOVQ CX,(DI)
2226 ADDQ $8,DI
2227
2228 MOVQ (SI),CX
2229 ADDQ $8,SI
2230 MOVQ CX,(DI)
2231 ADDQ $8,DI
2232
2233 MOVQ (SI),CX
2234 ADDQ $8,SI
2235 MOVQ CX,(DI)
2236 ADDQ $8,DI
2237
2238 MOVQ (SI),CX
2239 ADDQ $8,SI
2240 MOVQ CX,(DI)
2241 ADDQ $8,DI
2242
2243 MOVQ (SI),CX
2244 ADDQ $8,SI
2245 MOVQ CX,(DI)
2246 ADDQ $8,DI
2247
2248 MOVQ (SI),CX
2249 ADDQ $8,SI
2250 MOVQ CX,(DI)
2251 ADDQ $8,DI
2252
2253 MOVQ (SI),CX
2254 ADDQ $8,SI
2255 MOVQ CX,(DI)
2256 ADDQ $8,DI
2257
2258 MOVQ (SI),CX
2259 ADDQ $8,SI
2260 MOVQ CX,(DI)
2261 ADDQ $8,DI
2262
2263 MOVQ (SI),CX
2264 ADDQ $8,SI
2265 MOVQ CX,(DI)
2266 ADDQ $8,DI
2267
2268 MOVQ (SI),CX
2269 ADDQ $8,SI
2270 MOVQ CX,(DI)
2271 ADDQ $8,DI
2272
2273 MOVQ (SI),CX
2274 ADDQ $8,SI
2275 MOVQ CX,(DI)
2276 ADDQ $8,DI
2277
2278 MOVQ (SI),CX
2279 ADDQ $8,SI
2280 MOVQ CX,(DI)
2281 ADDQ $8,DI
2282
2283 MOVQ (SI),CX
2284 ADDQ $8,SI
2285 MOVQ CX,(DI)
2286 ADDQ $8,DI
2287
2288 MOVQ (SI),CX
2289 ADDQ $8,SI
2290 MOVQ CX,(DI)
2291 ADDQ $8,DI
2292
2293 MOVQ (SI),CX
2294 ADDQ $8,SI
2295 MOVQ CX,(DI)
2296 ADDQ $8,DI
2297
2298 MOVQ (SI),CX
2299 ADDQ $8,SI
2300 MOVQ CX,(DI)
2301 ADDQ $8,DI
2302
2303 MOVQ (SI),CX
2304 ADDQ $8,SI
2305 MOVQ CX,(DI)
2306 ADDQ $8,DI
2307
2308 MOVQ (SI),CX
2309 ADDQ $8,SI
2310 MOVQ CX,(DI)
2311 ADDQ $8,DI
2312
2313 MOVQ (SI),CX
2314 ADDQ $8,SI
2315 MOVQ CX,(DI)
2316 ADDQ $8,DI
2317
2318 MOVQ (SI),CX
2319 ADDQ $8,SI
2320 MOVQ CX,(DI)
2321 ADDQ $8,DI
2322
2323 MOVQ (SI),CX
2324 ADDQ $8,SI
2325 MOVQ CX,(DI)
2326 ADDQ $8,DI
2327
2328 MOVQ (SI),CX
2329 ADDQ $8,SI
2330 MOVQ CX,(DI)
2331 ADDQ $8,DI
2332
2333 MOVQ (SI),CX
2334 ADDQ $8,SI
2335 MOVQ CX,(DI)
2336 ADDQ $8,DI
2337
2338 MOVQ (SI),CX
2339 ADDQ $8,SI
2340 MOVQ CX,(DI)
2341 ADDQ $8,DI
2342
2343 MOVQ (SI),CX
2344 ADDQ $8,SI
2345 MOVQ CX,(DI)
2346 ADDQ $8,DI
2347
2348 MOVQ (SI),CX
2349 ADDQ $8,SI
2350 MOVQ CX,(DI)
2351 ADDQ $8,DI
2352
2353 MOVQ (SI),CX
2354 ADDQ $8,SI
2355 MOVQ CX,(DI)
2356 ADDQ $8,DI
2357
2358 MOVQ (SI),CX
2359 ADDQ $8,SI
2360 MOVQ CX,(DI)
2361 ADDQ $8,DI
2362
2363 MOVQ (SI),CX
2364 ADDQ $8,SI
2365 MOVQ CX,(DI)
2366 ADDQ $8,DI
2367
2368 MOVQ (SI),CX
2369 ADDQ $8,SI
2370 MOVQ CX,(DI)
2371 ADDQ $8,DI
2372
2373 MOVQ (SI),CX
2374 ADDQ $8,SI
2375 MOVQ CX,(DI)
2376 ADDQ $8,DI
2377
2378 MOVQ (SI),CX
2379 ADDQ $8,SI
2380 MOVQ CX,(DI)
2381 ADDQ $8,DI
2382
2383 MOVQ (SI),CX
2384 ADDQ $8,SI
2385 MOVQ CX,(DI)
2386 ADDQ $8,DI
2387
2388 MOVQ (SI),CX
2389 ADDQ $8,SI
2390 MOVQ CX,(DI)
2391 ADDQ $8,DI
2392
2393 MOVQ (SI),CX
2394 ADDQ $8,SI
2395 MOVQ CX,(DI)
2396 ADDQ $8,DI
2397
2398 MOVQ (SI),CX
2399 ADDQ $8,SI
2400 MOVQ CX,(DI)
2401 ADDQ $8,DI
2402
2403 MOVQ (SI),CX
2404 ADDQ $8,SI
2405 MOVQ CX,(DI)
2406 ADDQ $8,DI
2407
2408 MOVQ (SI),CX
2409 ADDQ $8,SI
2410 MOVQ CX,(DI)
2411 ADDQ $8,DI
2412
2413 MOVQ (SI),CX
2414 ADDQ $8,SI
2415 MOVQ CX,(DI)
2416 ADDQ $8,DI
2417
2418 MOVQ (SI),CX
2419 ADDQ $8,SI
2420 MOVQ CX,(DI)
2421 ADDQ $8,DI
2422
2423 MOVQ (SI),CX
2424 ADDQ $8,SI
2425 MOVQ CX,(DI)
2426 ADDQ $8,DI
2427
2428 MOVQ (SI),CX
2429 ADDQ $8,SI
2430 MOVQ CX,(DI)
2431 ADDQ $8,DI
2432
2433 RET
Dmitriy Vyukov350a8fc2014-05-02 17:32:42 +01002434
Keith Randall3306d112014-09-02 14:33:33 -07002435TEXT runtime·fastrand1(SB), NOSPLIT, $0-4
Keith Randall0c6b55e2014-07-16 14:16:19 -07002436 get_tls(CX)
2437 MOVQ g(CX), AX
2438 MOVQ g_m(AX), AX
2439 MOVL m_fastrand(AX), DX
2440 ADDL DX, DX
2441 MOVL DX, BX
2442 XORL $0x88888eef, DX
2443 CMOVLMI BX, DX
2444 MOVL DX, m_fastrand(AX)
2445 MOVL DX, ret+0(FP)
2446 RET
Keith Randallf4407372014-09-03 08:49:43 -07002447
2448TEXT runtime·return0(SB), NOSPLIT, $0
2449 MOVL $0, AX
2450 RET
Keith Randall1b6807b2014-09-25 07:59:01 -07002451
2452
2453// Called from cgo wrappers, this function returns g->m->curg.stack.hi.
2454// Must obey the gcc calling convention.
Keith Randall1aa65fe2014-09-25 08:37:04 -07002455TEXT _cgo_topofstack(SB),NOSPLIT,$0
Keith Randall1b6807b2014-09-25 07:59:01 -07002456 get_tls(CX)
2457 MOVQ g(CX), AX
2458 MOVQ g_m(AX), AX
2459 MOVQ m_curg(AX), AX
2460 MOVQ (g_stack+stack_hi)(AX), AX
2461 RET
Russ Coxa5a07332014-10-29 20:37:44 -04002462
2463// The top-most function running on a goroutine
2464// returns to goexit+PCQuantum.
2465TEXT runtime·goexit(SB),NOSPLIT,$0-0
2466 BYTE $0x90 // NOP
2467 CALL runtime·goexit1(SB) // does not return
Dmitry Vyukov894024f2015-02-20 20:07:02 +03002468 // traceback from goexit1 must hit code range of goexit
2469 BYTE $0x90 // NOP
Russ Cox15ced2d2014-11-11 17:06:22 -05002470
2471TEXT runtime·getg(SB),NOSPLIT,$0-8
2472 get_tls(CX)
2473 MOVQ g(CX), AX
2474 MOVQ AX, ret+0(FP)
2475 RET
Russ Cox8c3f6402014-11-21 15:57:10 -05002476
2477TEXT runtime·prefetcht0(SB),NOSPLIT,$0-8
2478 MOVQ addr+0(FP), AX
2479 PREFETCHT0 (AX)
2480 RET
2481
2482TEXT runtime·prefetcht1(SB),NOSPLIT,$0-8
2483 MOVQ addr+0(FP), AX
2484 PREFETCHT1 (AX)
2485 RET
2486
2487TEXT runtime·prefetcht2(SB),NOSPLIT,$0-8
2488 MOVQ addr+0(FP), AX
2489 PREFETCHT2 (AX)
2490 RET
2491
2492TEXT runtime·prefetchnta(SB),NOSPLIT,$0-8
2493 MOVQ addr+0(FP), AX
2494 PREFETCHNTA (AX)
2495 RET