blob: f31508de186b3d9a86bb46f710667b7987a7c564 [file] [log] [blame]
Rob Pike8e82a672008-06-30 11:50:36 -07001// Copyright 2009 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
Russ Cox55889402011-12-19 15:51:13 -05005#include "zasm_GOOS_GOARCH.h"
Rob Pike8e82a672008-06-30 11:50:36 -07006
Russ Cox68b42552010-11-04 14:00:19 -04007TEXT _rt0_amd64(SB),7,$-8
Rob Pike8e82a672008-06-30 11:50:36 -07008 // copy arguments forward on an even stack
Russ Cox36b414f2013-03-06 15:03:04 -05009 MOVQ DI, AX // argc
10 MOVQ SI, BX // argv
Rob Pike8e82a672008-06-30 11:50:36 -070011 SUBQ $(4*8+7), SP // 2args 2auto
Ian Lance Taylora4f8d362010-04-09 14:15:15 -070012 ANDQ $~15, SP
Rob Pike8e82a672008-06-30 11:50:36 -070013 MOVQ AX, 16(SP)
14 MOVQ BX, 24(SP)
Dmitriy Vyukov428062d2011-12-07 16:53:17 +030015
16 // create istack out of the given (operating system) stack.
Russ Coxf8d49b52013-02-28 16:24:38 -050017 // _cgo_init may update stackguard.
Dmitriy Vyukov428062d2011-12-07 16:53:17 +030018 MOVQ $runtime·g0(SB), DI
Alex Brainman8d6958f2012-01-20 12:59:44 +110019 LEAQ (-64*1024+104)(SP), BX
Dmitriy Vyukov428062d2011-12-07 16:53:17 +030020 MOVQ BX, g_stackguard(DI)
21 MOVQ SP, g_stackbase(DI)
Rob Pike8e82a672008-06-30 11:50:36 -070022
Keith Randalla5d40242013-03-12 10:47:44 -070023 // find out information about the processor we're on
24 MOVQ $0, AX
25 CPUID
26 CMPQ AX, $0
27 JE nocpuinfo
28 MOVQ $1, AX
29 CPUID
30 MOVL CX, runtime·cpuid_ecx(SB)
31 MOVL DX, runtime·cpuid_edx(SB)
32nocpuinfo:
33
Russ Coxf8d49b52013-02-28 16:24:38 -050034 // if there is an _cgo_init, call it.
35 MOVQ _cgo_init(SB), AX
Ian Lance Taylora4f8d362010-04-09 14:15:15 -070036 TESTQ AX, AX
Russ Coxe473f422010-08-04 17:50:22 -070037 JZ needtls
Alex Brainman8d6958f2012-01-20 12:59:44 +110038 // g0 already in DI
39 MOVQ DI, CX // Win64 uses CX for first parameter
40 CALL AX
Wei Guangjing9f636592011-07-19 10:47:33 -040041 CMPL runtime·iswindows(SB), $0
42 JEQ ok
Ian Lance Taylora4f8d362010-04-09 14:15:15 -070043
Russ Coxe473f422010-08-04 17:50:22 -070044needtls:
Akshat Kumara72bebf2012-08-31 13:21:13 -040045 // skip TLS setup on Plan 9
46 CMPL runtime·isplan9(SB), $1
47 JEQ ok
48
Russ Cox68b42552010-11-04 14:00:19 -040049 LEAQ runtime·tls0(SB), DI
50 CALL runtime·settls(SB)
Russ Coxe473f422010-08-04 17:50:22 -070051
52 // store through it, to make sure it works
53 get_tls(BX)
54 MOVQ $0x123, g(BX)
Russ Cox68b42552010-11-04 14:00:19 -040055 MOVQ runtime·tls0(SB), AX
Russ Coxe473f422010-08-04 17:50:22 -070056 CMPQ AX, $0x123
57 JEQ 2(PC)
58 MOVL AX, 0 // abort
59ok:
60 // set the per-goroutine and per-mach "registers"
61 get_tls(BX)
Russ Cox68b42552010-11-04 14:00:19 -040062 LEAQ runtime·g0(SB), CX
Russ Coxe473f422010-08-04 17:50:22 -070063 MOVQ CX, g(BX)
Russ Cox68b42552010-11-04 14:00:19 -040064 LEAQ runtime·m0(SB), AX
Russ Coxe473f422010-08-04 17:50:22 -070065 MOVQ AX, m(BX)
66
67 // save m->g0 = g0
68 MOVQ CX, m_g0(AX)
Rob Pike8e82a672008-06-30 11:50:36 -070069
Ken Thompson8f53bc02008-12-15 15:07:35 -080070 CLD // convention is D is always left cleared
Russ Cox68b42552010-11-04 14:00:19 -040071 CALL runtime·check(SB)
Rob Pike8e82a672008-06-30 11:50:36 -070072
Rob Pike8e82a672008-06-30 11:50:36 -070073 MOVL 16(SP), AX // copy argc
74 MOVL AX, 0(SP)
75 MOVQ 24(SP), AX // copy argv
76 MOVQ AX, 8(SP)
Russ Cox68b42552010-11-04 14:00:19 -040077 CALL runtime·args(SB)
78 CALL runtime·osinit(SB)
Keith Randalla5d40242013-03-12 10:47:44 -070079 CALL runtime·hashinit(SB)
Russ Cox68b42552010-11-04 14:00:19 -040080 CALL runtime·schedinit(SB)
Russ Coxf7f63292008-08-05 14:21:42 -070081
Ken Thompson751ce3a2008-07-11 19:16:39 -070082 // create a new goroutine to start program
Russ Cox1903ad72013-02-21 17:01:13 -050083 PUSHQ $runtime·main·f(SB) // entry
Russ Cox7343e032009-06-17 15:12:16 -070084 PUSHQ $0 // arg size
Russ Cox68b42552010-11-04 14:00:19 -040085 CALL runtime·newproc(SB)
Russ Coxebd1eef2008-09-22 13:47:59 -070086 POPQ AX
87 POPQ AX
Russ Cox79e1db22008-12-04 08:30:54 -080088
Russ Coxebd1eef2008-09-22 13:47:59 -070089 // start this M
Russ Cox68b42552010-11-04 14:00:19 -040090 CALL runtime·mstart(SB)
Rob Pike8e82a672008-06-30 11:50:36 -070091
Russ Cox36aa7d42012-03-08 14:03:56 -050092 MOVL $0xf1, 0xf1 // crash
Rob Pike8e82a672008-06-30 11:50:36 -070093 RET
94
Russ Cox1903ad72013-02-21 17:01:13 -050095DATA runtime·main·f+0(SB)/8,$runtime·main(SB)
96GLOBL runtime·main·f(SB),8,$8
97
Russ Cox68b42552010-11-04 14:00:19 -040098TEXT runtime·breakpoint(SB),7,$0
Ken Thompson751ce3a2008-07-11 19:16:39 -070099 BYTE $0xcc
Rob Pike8e82a672008-06-30 11:50:36 -0700100 RET
101
Russ Cox1707a992012-02-14 01:23:15 -0500102TEXT runtime·asminit(SB),7,$0
103 // No per-thread init.
104 RET
105
Ken Thompson751ce3a2008-07-11 19:16:39 -0700106/*
107 * go-routine
108 */
Rob Piked3204ef2008-06-30 14:39:47 -0700109
Russ Coxf9ca3b52011-03-07 10:37:42 -0500110// void gosave(Gobuf*)
Russ Cox7343e032009-06-17 15:12:16 -0700111// save state in Gobuf; setjmp
Russ Cox68b42552010-11-04 14:00:19 -0400112TEXT runtime·gosave(SB), 7, $0
Ken Thompson751ce3a2008-07-11 19:16:39 -0700113 MOVQ 8(SP), AX // gobuf
Russ Cox7343e032009-06-17 15:12:16 -0700114 LEAQ 8(SP), BX // caller's SP
115 MOVQ BX, gobuf_sp(AX)
116 MOVQ 0(SP), BX // caller's PC
117 MOVQ BX, gobuf_pc(AX)
Russ Coxe473f422010-08-04 17:50:22 -0700118 get_tls(CX)
119 MOVQ g(CX), BX
120 MOVQ BX, gobuf_g(AX)
Ken Thompson751ce3a2008-07-11 19:16:39 -0700121 RET
122
Russ Cox7343e032009-06-17 15:12:16 -0700123// void gogo(Gobuf*, uintptr)
124// restore state from Gobuf; longjmp
Russ Cox68b42552010-11-04 14:00:19 -0400125TEXT runtime·gogo(SB), 7, $0
Russ Cox7343e032009-06-17 15:12:16 -0700126 MOVQ 16(SP), AX // return 2nd arg
127 MOVQ 8(SP), BX // gobuf
Russ Coxe473f422010-08-04 17:50:22 -0700128 MOVQ gobuf_g(BX), DX
129 MOVQ 0(DX), CX // make sure g != nil
130 get_tls(CX)
131 MOVQ DX, g(CX)
Russ Cox7343e032009-06-17 15:12:16 -0700132 MOVQ gobuf_sp(BX), SP // restore SP
133 MOVQ gobuf_pc(BX), BX
134 JMP BX
135
Russ Cox6066fdc2013-02-22 10:47:54 -0500136// void gogocall(Gobuf*, void (*fn)(void), uintptr r0)
Russ Cox7343e032009-06-17 15:12:16 -0700137// restore state from Gobuf but then call fn.
138// (call fn, returning to state in Gobuf)
Russ Cox68b42552010-11-04 14:00:19 -0400139TEXT runtime·gogocall(SB), 7, $0
Russ Cox6066fdc2013-02-22 10:47:54 -0500140 MOVQ 24(SP), DX // context
Russ Cox7343e032009-06-17 15:12:16 -0700141 MOVQ 16(SP), AX // fn
142 MOVQ 8(SP), BX // gobuf
Russ Cox6066fdc2013-02-22 10:47:54 -0500143 MOVQ gobuf_g(BX), DI
Russ Coxe473f422010-08-04 17:50:22 -0700144 get_tls(CX)
Russ Cox6066fdc2013-02-22 10:47:54 -0500145 MOVQ DI, g(CX)
146 MOVQ 0(DI), CX // make sure g != nil
Russ Cox7343e032009-06-17 15:12:16 -0700147 MOVQ gobuf_sp(BX), SP // restore SP
148 MOVQ gobuf_pc(BX), BX
149 PUSHQ BX
150 JMP AX
151 POPQ BX // not reached
152
Russ Cox1903ad72013-02-21 17:01:13 -0500153// void gogocallfn(Gobuf*, FuncVal*)
154// restore state from Gobuf but then call fn.
155// (call fn, returning to state in Gobuf)
156TEXT runtime·gogocallfn(SB), 7, $0
Russ Cox6066fdc2013-02-22 10:47:54 -0500157 MOVQ 16(SP), DX // fn
Russ Cox1903ad72013-02-21 17:01:13 -0500158 MOVQ 8(SP), BX // gobuf
Russ Cox6066fdc2013-02-22 10:47:54 -0500159 MOVQ gobuf_g(BX), AX
Russ Cox1903ad72013-02-21 17:01:13 -0500160 get_tls(CX)
Russ Cox6066fdc2013-02-22 10:47:54 -0500161 MOVQ AX, g(CX)
162 MOVQ 0(AX), CX // make sure g != nil
Russ Cox1903ad72013-02-21 17:01:13 -0500163 MOVQ gobuf_sp(BX), SP // restore SP
164 MOVQ gobuf_pc(BX), BX
165 PUSHQ BX
Russ Cox6066fdc2013-02-22 10:47:54 -0500166 MOVQ 0(DX), BX
Russ Cox1903ad72013-02-21 17:01:13 -0500167 JMP BX
168 POPQ BX // not reached
169
Russ Coxf9ca3b52011-03-07 10:37:42 -0500170// void mcall(void (*fn)(G*))
171// Switch to m->g0's stack, call fn(g).
Russ Cox370276a2011-04-27 23:21:12 -0400172// Fn must never return. It should gogo(&g->sched)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500173// to keep running g.
174TEXT runtime·mcall(SB), 7, $0
175 MOVQ fn+0(FP), DI
176
177 get_tls(CX)
178 MOVQ g(CX), AX // save state in g->gobuf
179 MOVQ 0(SP), BX // caller's PC
180 MOVQ BX, (g_sched+gobuf_pc)(AX)
181 LEAQ 8(SP), BX // caller's SP
182 MOVQ BX, (g_sched+gobuf_sp)(AX)
183 MOVQ AX, (g_sched+gobuf_g)(AX)
184
185 // switch to m->g0 & its stack, call fn
186 MOVQ m(CX), BX
187 MOVQ m_g0(BX), SI
188 CMPQ SI, AX // if g == m->g0 call badmcall
189 JNE 2(PC)
190 CALL runtime·badmcall(SB)
191 MOVQ SI, g(CX) // g = m->g0
192 MOVQ (g_sched+gobuf_sp)(SI), SP // sp = m->g0->gobuf.sp
193 PUSHQ AX
194 CALL DI
195 POPQ AX
196 CALL runtime·badmcall2(SB)
197 RET
198
Rob Pike2da97832008-07-12 11:30:53 -0700199/*
200 * support for morestack
201 */
202
Russ Cox7343e032009-06-17 15:12:16 -0700203// Called during function prolog when more stack is needed.
Russ Coxe473f422010-08-04 17:50:22 -0700204// Caller has already done get_tls(CX); MOVQ m(CX), BX.
Russ Cox68b42552010-11-04 14:00:19 -0400205TEXT runtime·morestack(SB),7,$0
Russ Coxe473f422010-08-04 17:50:22 -0700206 // Cannot grow scheduler stack (m->g0).
207 MOVQ m_g0(BX), SI
208 CMPQ g(CX), SI
209 JNE 2(PC)
210 INT $3
Russ Cox6066fdc2013-02-22 10:47:54 -0500211
212 MOVQ DX, m_cret(BX)
Russ Coxe473f422010-08-04 17:50:22 -0700213
Russ Cox7343e032009-06-17 15:12:16 -0700214 // Called from f.
215 // Set m->morebuf to f's caller.
216 MOVQ 8(SP), AX // f's caller's PC
Russ Coxe473f422010-08-04 17:50:22 -0700217 MOVQ AX, (m_morebuf+gobuf_pc)(BX)
Russ Cox7343e032009-06-17 15:12:16 -0700218 LEAQ 16(SP), AX // f's caller's SP
Russ Coxe473f422010-08-04 17:50:22 -0700219 MOVQ AX, (m_morebuf+gobuf_sp)(BX)
Russ Cox141a4a12011-01-14 14:05:20 -0500220 MOVQ AX, m_moreargp(BX)
Russ Coxe473f422010-08-04 17:50:22 -0700221 get_tls(CX)
222 MOVQ g(CX), SI
223 MOVQ SI, (m_morebuf+gobuf_g)(BX)
Russ Cox7343e032009-06-17 15:12:16 -0700224
225 // Set m->morepc to f's PC.
226 MOVQ 0(SP), AX
Russ Coxe473f422010-08-04 17:50:22 -0700227 MOVQ AX, m_morepc(BX)
Russ Cox7343e032009-06-17 15:12:16 -0700228
Russ Coxf9ca3b52011-03-07 10:37:42 -0500229 // Call newstack on m->g0's stack.
Russ Coxe473f422010-08-04 17:50:22 -0700230 MOVQ m_g0(BX), BP
231 MOVQ BP, g(CX)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500232 MOVQ (g_sched+gobuf_sp)(BP), SP
Russ Cox68b42552010-11-04 14:00:19 -0400233 CALL runtime·newstack(SB)
Russ Cox7343e032009-06-17 15:12:16 -0700234 MOVQ $0, 0x1003 // crash if newstack returns
235 RET
236
Russ Coxbba278a2009-07-08 18:16:09 -0700237// Called from reflection library. Mimics morestack,
238// reuses stack growth code to create a frame
239// with the desired args running the desired function.
240//
241// func call(fn *byte, arg *byte, argsize uint32).
242TEXT reflect·call(SB), 7, $0
Russ Coxe473f422010-08-04 17:50:22 -0700243 get_tls(CX)
244 MOVQ m(CX), BX
245
Russ Coxbba278a2009-07-08 18:16:09 -0700246 // Save our caller's state as the PC and SP to
247 // restore when returning from f.
248 MOVQ 0(SP), AX // our caller's PC
Russ Coxe473f422010-08-04 17:50:22 -0700249 MOVQ AX, (m_morebuf+gobuf_pc)(BX)
Russ Coxbba278a2009-07-08 18:16:09 -0700250 LEAQ 8(SP), AX // our caller's SP
Russ Coxe473f422010-08-04 17:50:22 -0700251 MOVQ AX, (m_morebuf+gobuf_sp)(BX)
252 MOVQ g(CX), AX
253 MOVQ AX, (m_morebuf+gobuf_g)(BX)
Russ Coxbba278a2009-07-08 18:16:09 -0700254
255 // Set up morestack arguments to call f on a new stack.
Russ Cox83727cc2010-03-29 21:48:22 -0700256 // We set f's frame size to 1, as a hint to newstack
257 // that this is a call from reflect·call.
258 // If it turns out that f needs a larger frame than
259 // the default stack, f's usual stack growth prolog will
260 // allocate a new segment (and recopy the arguments).
Russ Coxbba278a2009-07-08 18:16:09 -0700261 MOVQ 8(SP), AX // fn
Russ Coxe473f422010-08-04 17:50:22 -0700262 MOVQ 16(SP), DX // arg frame
Russ Coxbba278a2009-07-08 18:16:09 -0700263 MOVL 24(SP), CX // arg size
264
Russ Coxe473f422010-08-04 17:50:22 -0700265 MOVQ AX, m_morepc(BX) // f's PC
Russ Cox141a4a12011-01-14 14:05:20 -0500266 MOVQ DX, m_moreargp(BX) // argument frame pointer
267 MOVL CX, m_moreargsize(BX) // f's argument size
268 MOVL $1, m_moreframesize(BX) // f's frame size
Russ Coxbba278a2009-07-08 18:16:09 -0700269
Russ Coxf9ca3b52011-03-07 10:37:42 -0500270 // Call newstack on m->g0's stack.
Russ Coxe473f422010-08-04 17:50:22 -0700271 MOVQ m_g0(BX), BP
272 get_tls(CX)
273 MOVQ BP, g(CX)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500274 MOVQ (g_sched+gobuf_sp)(BP), SP
Russ Cox68b42552010-11-04 14:00:19 -0400275 CALL runtime·newstack(SB)
Russ Coxbba278a2009-07-08 18:16:09 -0700276 MOVQ $0, 0x1103 // crash if newstack returns
277 RET
278
Russ Cox7343e032009-06-17 15:12:16 -0700279// Return point when leaving stack.
Russ Cox68b42552010-11-04 14:00:19 -0400280TEXT runtime·lessstack(SB), 7, $0
Russ Cox7343e032009-06-17 15:12:16 -0700281 // Save return value in m->cret
Russ Coxe473f422010-08-04 17:50:22 -0700282 get_tls(CX)
283 MOVQ m(CX), BX
284 MOVQ AX, m_cret(BX)
Russ Cox7343e032009-06-17 15:12:16 -0700285
Russ Coxf9ca3b52011-03-07 10:37:42 -0500286 // Call oldstack on m->g0's stack.
287 MOVQ m_g0(BX), BP
288 MOVQ BP, g(CX)
289 MOVQ (g_sched+gobuf_sp)(BP), SP
Russ Cox68b42552010-11-04 14:00:19 -0400290 CALL runtime·oldstack(SB)
Russ Cox7343e032009-06-17 15:12:16 -0700291 MOVQ $0, 0x1004 // crash if oldstack returns
292 RET
293
Ken Thompson1ed7f182009-05-01 18:07:33 -0700294// morestack trampolines
Russ Cox68b42552010-11-04 14:00:19 -0400295TEXT runtime·morestack00(SB),7,$0
Russ Coxe473f422010-08-04 17:50:22 -0700296 get_tls(CX)
297 MOVQ m(CX), BX
Ken Thompson1ed7f182009-05-01 18:07:33 -0700298 MOVQ $0, AX
Russ Cox141a4a12011-01-14 14:05:20 -0500299 MOVQ AX, m_moreframesize(BX)
Russ Cox68b42552010-11-04 14:00:19 -0400300 MOVQ $runtime·morestack(SB), AX
Ken Thompson1ed7f182009-05-01 18:07:33 -0700301 JMP AX
302
Russ Cox68b42552010-11-04 14:00:19 -0400303TEXT runtime·morestack01(SB),7,$0
Russ Coxe473f422010-08-04 17:50:22 -0700304 get_tls(CX)
305 MOVQ m(CX), BX
Ken Thompson1ed7f182009-05-01 18:07:33 -0700306 SHLQ $32, AX
Russ Cox141a4a12011-01-14 14:05:20 -0500307 MOVQ AX, m_moreframesize(BX)
Russ Cox68b42552010-11-04 14:00:19 -0400308 MOVQ $runtime·morestack(SB), AX
Ken Thompson1ed7f182009-05-01 18:07:33 -0700309 JMP AX
310
Russ Cox68b42552010-11-04 14:00:19 -0400311TEXT runtime·morestack10(SB),7,$0
Russ Coxe473f422010-08-04 17:50:22 -0700312 get_tls(CX)
313 MOVQ m(CX), BX
Ken Thompson1ed7f182009-05-01 18:07:33 -0700314 MOVLQZX AX, AX
Russ Cox141a4a12011-01-14 14:05:20 -0500315 MOVQ AX, m_moreframesize(BX)
Russ Cox68b42552010-11-04 14:00:19 -0400316 MOVQ $runtime·morestack(SB), AX
Ken Thompson1ed7f182009-05-01 18:07:33 -0700317 JMP AX
318
Russ Cox68b42552010-11-04 14:00:19 -0400319TEXT runtime·morestack11(SB),7,$0
Russ Coxe473f422010-08-04 17:50:22 -0700320 get_tls(CX)
321 MOVQ m(CX), BX
Russ Cox141a4a12011-01-14 14:05:20 -0500322 MOVQ AX, m_moreframesize(BX)
Russ Cox68b42552010-11-04 14:00:19 -0400323 MOVQ $runtime·morestack(SB), AX
Ken Thompson1ed7f182009-05-01 18:07:33 -0700324 JMP AX
325
Ken Thompson5963f592009-05-03 19:09:14 -0700326// subcases of morestack01
327// with const of 8,16,...48
Russ Cox68b42552010-11-04 14:00:19 -0400328TEXT runtime·morestack8(SB),7,$0
Ken Thompson5963f592009-05-03 19:09:14 -0700329 PUSHQ $1
Russ Cox68b42552010-11-04 14:00:19 -0400330 MOVQ $morestack<>(SB), AX
Ken Thompson5963f592009-05-03 19:09:14 -0700331 JMP AX
332
Russ Cox68b42552010-11-04 14:00:19 -0400333TEXT runtime·morestack16(SB),7,$0
Ken Thompson5963f592009-05-03 19:09:14 -0700334 PUSHQ $2
Russ Cox68b42552010-11-04 14:00:19 -0400335 MOVQ $morestack<>(SB), AX
Ken Thompson5963f592009-05-03 19:09:14 -0700336 JMP AX
337
Russ Cox68b42552010-11-04 14:00:19 -0400338TEXT runtime·morestack24(SB),7,$0
Ken Thompson5963f592009-05-03 19:09:14 -0700339 PUSHQ $3
Russ Cox68b42552010-11-04 14:00:19 -0400340 MOVQ $morestack<>(SB), AX
Ken Thompson5963f592009-05-03 19:09:14 -0700341 JMP AX
342
Russ Cox68b42552010-11-04 14:00:19 -0400343TEXT runtime·morestack32(SB),7,$0
Ken Thompson5963f592009-05-03 19:09:14 -0700344 PUSHQ $4
Russ Cox68b42552010-11-04 14:00:19 -0400345 MOVQ $morestack<>(SB), AX
Ken Thompson5963f592009-05-03 19:09:14 -0700346 JMP AX
347
Russ Cox68b42552010-11-04 14:00:19 -0400348TEXT runtime·morestack40(SB),7,$0
Ken Thompson5963f592009-05-03 19:09:14 -0700349 PUSHQ $5
Russ Cox68b42552010-11-04 14:00:19 -0400350 MOVQ $morestack<>(SB), AX
Ken Thompson5963f592009-05-03 19:09:14 -0700351 JMP AX
352
Russ Cox68b42552010-11-04 14:00:19 -0400353TEXT runtime·morestack48(SB),7,$0
Ken Thompson5963f592009-05-03 19:09:14 -0700354 PUSHQ $6
Russ Cox68b42552010-11-04 14:00:19 -0400355 MOVQ $morestack<>(SB), AX
Ken Thompson5963f592009-05-03 19:09:14 -0700356 JMP AX
357
Russ Cox68b42552010-11-04 14:00:19 -0400358TEXT morestack<>(SB),7,$0
Russ Coxe473f422010-08-04 17:50:22 -0700359 get_tls(CX)
360 MOVQ m(CX), BX
Russ Cox7343e032009-06-17 15:12:16 -0700361 POPQ AX
362 SHLQ $35, AX
Russ Cox141a4a12011-01-14 14:05:20 -0500363 MOVQ AX, m_moreframesize(BX)
Russ Cox68b42552010-11-04 14:00:19 -0400364 MOVQ $runtime·morestack(SB), AX
Rob Pike2da97832008-07-12 11:30:53 -0700365 JMP AX
366
Russ Coxd28acc42008-08-04 16:43:49 -0700367// bool cas(int32 *val, int32 old, int32 new)
368// Atomically:
369// if(*val == old){
370// *val = new;
371// return 1;
Ken Thompson1e1cc4e2009-01-27 12:03:53 -0800372// } else
Russ Coxd28acc42008-08-04 16:43:49 -0700373// return 0;
Russ Cox68b42552010-11-04 14:00:19 -0400374TEXT runtime·cas(SB), 7, $0
Russ Coxd28acc42008-08-04 16:43:49 -0700375 MOVQ 8(SP), BX
376 MOVL 16(SP), AX
377 MOVL 20(SP), CX
378 LOCK
379 CMPXCHGL CX, 0(BX)
380 JZ 3(PC)
381 MOVL $0, AX
382 RET
383 MOVL $1, AX
384 RET
Ken Thompson1e1cc4e2009-01-27 12:03:53 -0800385
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400386// bool runtime·cas64(uint64 *val, uint64 *old, uint64 new)
387// Atomically:
388// if(*val == *old){
389// *val = new;
390// return 1;
391// } else {
392// *old = *val
393// return 0;
394// }
395TEXT runtime·cas64(SB), 7, $0
396 MOVQ 8(SP), BX
397 MOVQ 16(SP), BP
398 MOVQ 0(BP), AX
399 MOVQ 24(SP), CX
400 LOCK
401 CMPXCHGQ CX, 0(BX)
402 JNZ cas64_fail
403 MOVL $1, AX
404 RET
405cas64_fail:
406 MOVQ AX, 0(BP)
407 MOVL $0, AX
408 RET
409
Russ Cox67793502011-02-16 13:21:13 -0500410// bool casp(void **val, void *old, void *new)
411// Atomically:
412// if(*val == old){
413// *val = new;
414// return 1;
415// } else
416// return 0;
417TEXT runtime·casp(SB), 7, $0
418 MOVQ 8(SP), BX
419 MOVQ 16(SP), AX
420 MOVQ 24(SP), CX
421 LOCK
422 CMPXCHGQ CX, 0(BX)
423 JZ 3(PC)
424 MOVL $0, AX
425 RET
426 MOVL $1, AX
427 RET
428
Dmitriy Vyukov491aa152011-07-15 11:27:16 -0400429// uint32 xadd(uint32 volatile *val, int32 delta)
430// Atomically:
431// *val += delta;
432// return *val;
433TEXT runtime·xadd(SB), 7, $0
434 MOVQ 8(SP), BX
435 MOVL 16(SP), AX
436 MOVL AX, CX
437 LOCK
438 XADDL AX, 0(BX)
439 ADDL CX, AX
440 RET
441
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400442TEXT runtime·xadd64(SB), 7, $0
443 MOVQ 8(SP), BX
444 MOVQ 16(SP), AX
445 MOVQ AX, CX
446 LOCK
447 XADDQ AX, 0(BX)
448 ADDQ CX, AX
449 RET
450
Dmitriy Vyukov4e5086b2011-07-29 12:44:06 -0400451TEXT runtime·xchg(SB), 7, $0
452 MOVQ 8(SP), BX
453 MOVL 16(SP), AX
454 XCHGL AX, 0(BX)
455 RET
456
Dmitriy Vyukovadd33492013-03-05 09:46:52 +0200457TEXT runtime·xchg64(SB), 7, $0
458 MOVQ 8(SP), BX
459 MOVQ 16(SP), AX
460 XCHGQ AX, 0(BX)
461 RET
462
Dmitriy Vyukov4e5086b2011-07-29 12:44:06 -0400463TEXT runtime·procyield(SB),7,$0
464 MOVL 8(SP), AX
465again:
466 PAUSE
467 SUBL $1, AX
468 JNZ again
469 RET
470
Dmitriy Vyukov86a659c2011-07-13 11:22:41 -0700471TEXT runtime·atomicstorep(SB), 7, $0
472 MOVQ 8(SP), BX
473 MOVQ 16(SP), AX
474 XCHGQ AX, 0(BX)
475 RET
476
Dmitriy Vyukov91f0f182011-07-29 13:47:24 -0400477TEXT runtime·atomicstore(SB), 7, $0
478 MOVQ 8(SP), BX
479 MOVL 16(SP), AX
480 XCHGL AX, 0(BX)
481 RET
482
Dmitriy Vyukov46675712012-04-05 18:47:43 +0400483TEXT runtime·atomicstore64(SB), 7, $0
484 MOVQ 8(SP), BX
485 MOVQ 16(SP), AX
486 XCHGQ AX, 0(BX)
487 RET
488
Russ Coxaa3222d82009-06-02 23:02:12 -0700489// void jmpdefer(fn, sp);
490// called from deferreturn.
Ken Thompson1e1cc4e2009-01-27 12:03:53 -0800491// 1. pop the caller
492// 2. sub 5 bytes from the callers return
493// 3. jmp to the argument
Russ Cox68b42552010-11-04 14:00:19 -0400494TEXT runtime·jmpdefer(SB), 7, $0
Russ Cox6066fdc2013-02-22 10:47:54 -0500495 MOVQ 8(SP), DX // fn
Russ Coxaa3222d82009-06-02 23:02:12 -0700496 MOVQ 16(SP), BX // caller sp
497 LEAQ -8(BX), SP // caller sp after CALL
498 SUBQ $5, (SP) // return to CALL again
Russ Cox6066fdc2013-02-22 10:47:54 -0500499 MOVQ 0(DX), BX
Russ Cox1903ad72013-02-21 17:01:13 -0500500 JMP BX // but first run the deferred function
Russ Cox133a1582009-10-03 10:37:12 -0700501
Russ Coxf9ca3b52011-03-07 10:37:42 -0500502// Dummy function to use in saved gobuf.PC,
503// to match SP pointing at a return address.
504// The gobuf.PC is unused by the contortions here
505// but setting it to return will make the traceback code work.
506TEXT return<>(SB),7,$0
507 RET
508
509// asmcgocall(void(*fn)(void*), void *arg)
Russ Coxadd89dd2009-10-12 10:26:38 -0700510// Call fn(arg) on the scheduler stack,
511// aligned appropriately for the gcc ABI.
Russ Coxf9ca3b52011-03-07 10:37:42 -0500512// See cgocall.c for more details.
513TEXT runtime·asmcgocall(SB),7,$0
514 MOVQ fn+0(FP), AX
515 MOVQ arg+8(FP), BX
516 MOVQ SP, DX
Russ Coxadd89dd2009-10-12 10:26:38 -0700517
518 // Figure out if we need to switch to m->g0 stack.
Russ Coxf9ca3b52011-03-07 10:37:42 -0500519 // We get called to create new OS threads too, and those
520 // come in on the m->g0 stack already.
521 get_tls(CX)
522 MOVQ m(CX), BP
523 MOVQ m_g0(BP), SI
524 MOVQ g(CX), DI
525 CMPQ SI, DI
526 JEQ 6(PC)
527 MOVQ SP, (g_sched+gobuf_sp)(DI)
528 MOVQ $return<>(SB), (g_sched+gobuf_pc)(DI)
529 MOVQ DI, (g_sched+gobuf_g)(DI)
530 MOVQ SI, g(CX)
531 MOVQ (g_sched+gobuf_sp)(SI), SP
Russ Coxadd89dd2009-10-12 10:26:38 -0700532
533 // Now on a scheduling stack (a pthread-created stack).
Alex Brainman7f075ec2012-09-03 12:12:51 +1000534 // Make sure we have enough room for 4 stack-backed fast-call
535 // registers as per windows amd64 calling convention.
536 SUBQ $64, SP
Russ Cox133a1582009-10-03 10:37:12 -0700537 ANDQ $~15, SP // alignment for gcc ABI
Alex Brainman7f075ec2012-09-03 12:12:51 +1000538 MOVQ DI, 48(SP) // save g
539 MOVQ DX, 40(SP) // save SP
Russ Coxf9ca3b52011-03-07 10:37:42 -0500540 MOVQ BX, DI // DI = first argument in AMD64 ABI
Wei Guangjing9f636592011-07-19 10:47:33 -0400541 MOVQ BX, CX // CX = first argument in Win64
Russ Coxf9ca3b52011-03-07 10:37:42 -0500542 CALL AX
Russ Coxadd89dd2009-10-12 10:26:38 -0700543
Russ Coxe473f422010-08-04 17:50:22 -0700544 // Restore registers, g, stack pointer.
Russ Coxf9ca3b52011-03-07 10:37:42 -0500545 get_tls(CX)
Alex Brainman7f075ec2012-09-03 12:12:51 +1000546 MOVQ 48(SP), DI
Russ Coxf9ca3b52011-03-07 10:37:42 -0500547 MOVQ DI, g(CX)
Alex Brainman7f075ec2012-09-03 12:12:51 +1000548 MOVQ 40(SP), SP
Russ Cox133a1582009-10-03 10:37:12 -0700549 RET
550
Russ Coxf9ca3b52011-03-07 10:37:42 -0500551// cgocallback(void (*fn)(void*), void *frame, uintptr framesize)
Russ Cox3d2dfc52013-02-22 16:08:56 -0500552// Turn the fn into a Go func (by taking its address) and call
553// cgocallback_gofunc.
Russ Coxf9ca3b52011-03-07 10:37:42 -0500554TEXT runtime·cgocallback(SB),7,$24
Russ Cox3d2dfc52013-02-22 16:08:56 -0500555 LEAQ fn+0(FP), AX
556 MOVQ AX, 0(SP)
557 MOVQ frame+8(FP), AX
558 MOVQ AX, 8(SP)
559 MOVQ framesize+16(FP), AX
560 MOVQ AX, 16(SP)
561 MOVQ $runtime·cgocallback_gofunc(SB), AX
562 CALL AX
563 RET
564
565// cgocallback_gofunc(FuncVal*, void *frame, uintptr framesize)
566// See cgocall.c for more details.
567TEXT runtime·cgocallback_gofunc(SB),7,$24
Russ Cox6c976392013-02-20 17:48:23 -0500568 // If m is nil, Go did not create the current thread.
569 // Call needm to obtain one for temporary use.
570 // In this case, we're running on the thread stack, so there's
571 // lots of space, but the linker doesn't know. Hide the call from
572 // the linker analysis by using an indirect call through AX.
573 get_tls(CX)
574#ifdef GOOS_windows
575 CMPQ CX, $0
576 JNE 3(PC)
577 PUSHQ $0
578 JMP needm
579#endif
580 MOVQ m(CX), BP
581 PUSHQ BP
582 CMPQ BP, $0
583 JNE havem
584needm:
585 MOVQ $runtime·needm(SB), AX
586 CALL AX
Russ Coxe473f422010-08-04 17:50:22 -0700587 get_tls(CX)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500588 MOVQ m(CX), BP
Russ Cox9b732382012-03-08 12:12:40 -0500589
Russ Cox6c976392013-02-20 17:48:23 -0500590havem:
591 // Now there's a valid m, and we're running on its m->g0.
592 // Save current m->g0->sched.sp on stack and then set it to SP.
593 // Save current sp in m->g0->sched.sp in preparation for
594 // switch back to m->curg stack.
Russ Coxf9ca3b52011-03-07 10:37:42 -0500595 MOVQ m_g0(BP), SI
596 PUSHQ (g_sched+gobuf_sp)(SI)
597 MOVQ SP, (g_sched+gobuf_sp)(SI)
Ian Lance Taylor2d0ff3f2010-04-09 13:30:11 -0700598
Alex Brainman72e83482011-08-18 12:17:09 -0400599 // Switch to m->curg stack and call runtime.cgocallbackg
Russ Coxf9ca3b52011-03-07 10:37:42 -0500600 // with the three arguments. Because we are taking over
601 // the execution of m->curg but *not* resuming what had
602 // been running, we need to save that information (m->curg->gobuf)
603 // so that we can restore it when we're done.
604 // We can restore m->curg->gobuf.sp easily, because calling
Alex Brainman72e83482011-08-18 12:17:09 -0400605 // runtime.cgocallbackg leaves SP unchanged upon return.
Russ Coxf9ca3b52011-03-07 10:37:42 -0500606 // To save m->curg->gobuf.pc, we push it onto the stack.
607 // This has the added benefit that it looks to the traceback
Alex Brainman72e83482011-08-18 12:17:09 -0400608 // routine like cgocallbackg is going to return to that
609 // PC (because we defined cgocallbackg to have
Russ Coxf9ca3b52011-03-07 10:37:42 -0500610 // a frame size of 24, the same amount that we use below),
611 // so that the traceback will seamlessly trace back into
612 // the earlier calls.
Russ Cox6c976392013-02-20 17:48:23 -0500613 MOVQ fn+0(FP), AX
614 MOVQ frame+8(FP), BX
615 MOVQ framesize+16(FP), DX
616
Russ Coxf9ca3b52011-03-07 10:37:42 -0500617 MOVQ m_curg(BP), SI
618 MOVQ SI, g(CX)
619 MOVQ (g_sched+gobuf_sp)(SI), DI // prepare stack as DI
Ian Lance Taylor2d0ff3f2010-04-09 13:30:11 -0700620
Russ Coxf9ca3b52011-03-07 10:37:42 -0500621 // Push gobuf.pc
622 MOVQ (g_sched+gobuf_pc)(SI), BP
623 SUBQ $8, DI
624 MOVQ BP, 0(DI)
625
626 // Push arguments to cgocallbackg.
627 // Frame size here must match the frame size above
628 // to trick traceback routines into doing the right thing.
629 SUBQ $24, DI
630 MOVQ AX, 0(DI)
631 MOVQ BX, 8(DI)
632 MOVQ DX, 16(DI)
633
634 // Switch stack and make the call.
635 MOVQ DI, SP
636 CALL runtime·cgocallbackg(SB)
637
638 // Restore g->gobuf (== m->curg->gobuf) from saved values.
Russ Coxe473f422010-08-04 17:50:22 -0700639 get_tls(CX)
Russ Coxf9ca3b52011-03-07 10:37:42 -0500640 MOVQ g(CX), SI
641 MOVQ 24(SP), BP
642 MOVQ BP, (g_sched+gobuf_pc)(SI)
643 LEAQ (24+8)(SP), DI
644 MOVQ DI, (g_sched+gobuf_sp)(SI)
645
646 // Switch back to m->g0's stack and restore m->g0->sched.sp.
647 // (Unlike m->curg, the g0 goroutine never uses sched.pc,
648 // so we do not have to restore it.)
649 MOVQ m(CX), BP
650 MOVQ m_g0(BP), SI
651 MOVQ SI, g(CX)
652 MOVQ (g_sched+gobuf_sp)(SI), SP
653 POPQ (g_sched+gobuf_sp)(SI)
Russ Cox6c976392013-02-20 17:48:23 -0500654
655 // If the m on entry was nil, we called needm above to borrow an m
656 // for the duration of the call. Since the call is over, return it with dropm.
657 POPQ BP
658 CMPQ BP, $0
659 JNE 3(PC)
660 MOVQ $runtime·dropm(SB), AX
661 CALL AX
Russ Coxf9ca3b52011-03-07 10:37:42 -0500662
663 // Done!
Ian Lance Taylor2d0ff3f2010-04-09 13:30:11 -0700664 RET
665
Russ Cox6c976392013-02-20 17:48:23 -0500666// void setmg(M*, G*); set m and g. for use by needm.
667TEXT runtime·setmg(SB), 7, $0
668 MOVQ mm+0(FP), AX
669#ifdef GOOS_windows
670 CMPQ AX, $0
671 JNE settls
672 MOVQ $0, 0x28(GS)
673 RET
674settls:
675 LEAQ m_tls(AX), AX
676 MOVQ AX, 0x28(GS)
677#endif
678 get_tls(CX)
679 MOVQ mm+0(FP), AX
680 MOVQ AX, m(CX)
681 MOVQ gg+8(FP), BX
682 MOVQ BX, g(CX)
683 RET
684
Devon H. O'Dell5a4a08f2009-12-08 18:19:30 -0800685// check that SP is in range [g->stackbase, g->stackguard)
Russ Cox68b42552010-11-04 14:00:19 -0400686TEXT runtime·stackcheck(SB), 7, $0
Russ Coxe473f422010-08-04 17:50:22 -0700687 get_tls(CX)
688 MOVQ g(CX), AX
689 CMPQ g_stackbase(AX), SP
Russ Cox01eaf782010-03-30 10:53:16 -0700690 JHI 2(PC)
691 INT $3
Russ Coxe473f422010-08-04 17:50:22 -0700692 CMPQ SP, g_stackguard(AX)
Russ Cox01eaf782010-03-30 10:53:16 -0700693 JHI 2(PC)
694 INT $3
695 RET
696
Russ Cox68b42552010-11-04 14:00:19 -0400697TEXT runtime·memclr(SB),7,$0
Russ Cox6c196012010-04-05 12:51:09 -0700698 MOVQ 8(SP), DI // arg 1 addr
Russ Coxafc69282011-01-25 16:35:36 -0500699 MOVQ 16(SP), CX // arg 2 count
Quan Yong Zhai47410a22011-07-23 15:46:58 -0400700 MOVQ CX, BX
701 ANDQ $7, BX
Russ Coxafc69282011-01-25 16:35:36 -0500702 SHRQ $3, CX
Russ Cox6c196012010-04-05 12:51:09 -0700703 MOVQ $0, AX
704 CLD
705 REP
706 STOSQ
Quan Yong Zhai47410a22011-07-23 15:46:58 -0400707 MOVQ BX, CX
708 REP
709 STOSB
Russ Cox6c196012010-04-05 12:51:09 -0700710 RET
711
Russ Cox68b42552010-11-04 14:00:19 -0400712TEXT runtime·getcallerpc(SB),7,$0
Russ Cox6c196012010-04-05 12:51:09 -0700713 MOVQ x+0(FP),AX // addr of first arg
714 MOVQ -8(AX),AX // get calling pc
715 RET
716
Russ Cox68b42552010-11-04 14:00:19 -0400717TEXT runtime·setcallerpc(SB),7,$0
Russ Cox6c196012010-04-05 12:51:09 -0700718 MOVQ x+0(FP),AX // addr of first arg
719 MOVQ x+8(FP), BX
720 MOVQ BX, -8(AX) // set calling pc
721 RET
722
Russ Cox68b42552010-11-04 14:00:19 -0400723TEXT runtime·getcallersp(SB),7,$0
Russ Cox6c196012010-04-05 12:51:09 -0700724 MOVQ sp+0(FP), AX
725 RET
726
Damian Gryski8e765da2012-02-02 14:09:27 -0500727// int64 runtime·cputicks(void)
728TEXT runtime·cputicks(SB),7,$0
729 RDTSC
730 SHLQ $32, DX
731 ADDQ DX, AX
732 RET
733
Russ Cox9e5db8c2012-03-15 15:22:30 -0400734TEXT runtime·stackguard(SB),7,$0
735 MOVQ SP, DX
736 MOVQ DX, sp+0(FP)
737 get_tls(CX)
738 MOVQ g(CX), BX
739 MOVQ g_stackguard(BX), DX
740 MOVQ DX, guard+8(FP)
741 RET
742
Russ Cox68b42552010-11-04 14:00:19 -0400743GLOBL runtime·tls0(SB), $64
Keith Randalla5d40242013-03-12 10:47:44 -0700744
745// hash function using AES hardware instructions
746TEXT runtime·aeshash(SB),7,$0
747 MOVQ 8(SP), DX // ptr to hash value
748 MOVQ 16(SP), CX // size
749 MOVQ 24(SP), AX // ptr to data
750 JMP runtime·aeshashbody(SB)
751
752TEXT runtime·aeshashstr(SB),7,$0
753 MOVQ 8(SP), DX // ptr to hash value
754 MOVQ 24(SP), AX // ptr to string struct
755 MOVQ 8(AX), CX // length of string
756 MOVQ (AX), AX // string data
757 JMP runtime·aeshashbody(SB)
758
759// AX: data
760// CX: length
761// DX: ptr to seed input / hash output
762TEXT runtime·aeshashbody(SB),7,$0
763 MOVQ (DX), X0 // seed to low 64 bits of xmm0
764 PINSRQ $1, CX, X0 // size to high 64 bits of xmm0
765 MOVOU runtime·aeskeysched+0(SB), X2
766 MOVOU runtime·aeskeysched+16(SB), X3
767aesloop:
768 CMPQ CX, $16
769 JB aesloopend
770 MOVOU (AX), X1
771 AESENC X2, X0
772 AESENC X1, X0
773 SUBQ $16, CX
774 ADDQ $16, AX
775 JMP aesloop
776aesloopend:
777 TESTQ CX, CX
778 JE finalize // no partial block
779
780 TESTQ $16, AX
781 JNE highpartial
782
783 // address ends in 0xxxx. 16 bytes loaded
784 // at this address won't cross a page boundary, so
785 // we can load it directly.
786 MOVOU (AX), X1
787 ADDQ CX, CX
788 PAND masks(SB)(CX*8), X1
789 JMP partial
790highpartial:
791 // address ends in 1xxxx. Might be up against
792 // a page boundary, so load ending at last byte.
793 // Then shift bytes down using pshufb.
794 MOVOU -16(AX)(CX*1), X1
795 ADDQ CX, CX
796 PSHUFB shifts(SB)(CX*8), X1
797partial:
798 // incorporate partial block into hash
799 AESENC X3, X0
800 AESENC X1, X0
801finalize:
802 // finalize hash
803 AESENC X2, X0
804 AESENC X3, X0
805 AESENC X2, X0
806 MOVQ X0, (DX)
807 RET
808
809TEXT runtime·aeshash32(SB),7,$0
810 MOVQ 8(SP), DX // ptr to hash value
811 MOVQ 24(SP), AX // ptr to data
812 MOVQ (DX), X0 // seed
813 PINSRD $2, (AX), X0 // data
814 MOVOU runtime·aeskeysched+0(SB), X2
815 MOVOU runtime·aeskeysched+16(SB), X3
816 AESENC X2, X0
817 AESENC X3, X0
818 AESENC X2, X0
819 MOVQ X0, (DX)
820 RET
821
822TEXT runtime·aeshash64(SB),7,$0
823 MOVQ 8(SP), DX // ptr to hash value
824 MOVQ 24(SP), AX // ptr to data
825 MOVQ (DX), X0 // seed
826 PINSRQ $1, (AX), X0 // data
827 MOVOU runtime·aeskeysched+0(SB), X2
828 MOVOU runtime·aeskeysched+16(SB), X3
829 AESENC X2, X0
830 AESENC X3, X0
831 AESENC X2, X0
832 MOVQ X0, (DX)
833 RET
834
835// simple mask to get rid of data in the high part of the register.
836TEXT masks(SB),7,$0
837 QUAD $0x0000000000000000
838 QUAD $0x0000000000000000
839 QUAD $0x00000000000000ff
840 QUAD $0x0000000000000000
841 QUAD $0x000000000000ffff
842 QUAD $0x0000000000000000
843 QUAD $0x0000000000ffffff
844 QUAD $0x0000000000000000
845 QUAD $0x00000000ffffffff
846 QUAD $0x0000000000000000
847 QUAD $0x000000ffffffffff
848 QUAD $0x0000000000000000
849 QUAD $0x0000ffffffffffff
850 QUAD $0x0000000000000000
851 QUAD $0x00ffffffffffffff
852 QUAD $0x0000000000000000
853 QUAD $0xffffffffffffffff
854 QUAD $0x0000000000000000
855 QUAD $0xffffffffffffffff
856 QUAD $0x00000000000000ff
857 QUAD $0xffffffffffffffff
858 QUAD $0x000000000000ffff
859 QUAD $0xffffffffffffffff
860 QUAD $0x0000000000ffffff
861 QUAD $0xffffffffffffffff
862 QUAD $0x00000000ffffffff
863 QUAD $0xffffffffffffffff
864 QUAD $0x000000ffffffffff
865 QUAD $0xffffffffffffffff
866 QUAD $0x0000ffffffffffff
867 QUAD $0xffffffffffffffff
868 QUAD $0x00ffffffffffffff
869
870 // these are arguments to pshufb. They move data down from
871 // the high bytes of the register to the low bytes of the register.
872 // index is how many bytes to move.
873TEXT shifts(SB),7,$0
874 QUAD $0x0000000000000000
875 QUAD $0x0000000000000000
876 QUAD $0xffffffffffffff0f
877 QUAD $0xffffffffffffffff
878 QUAD $0xffffffffffff0f0e
879 QUAD $0xffffffffffffffff
880 QUAD $0xffffffffff0f0e0d
881 QUAD $0xffffffffffffffff
882 QUAD $0xffffffff0f0e0d0c
883 QUAD $0xffffffffffffffff
884 QUAD $0xffffff0f0e0d0c0b
885 QUAD $0xffffffffffffffff
886 QUAD $0xffff0f0e0d0c0b0a
887 QUAD $0xffffffffffffffff
888 QUAD $0xff0f0e0d0c0b0a09
889 QUAD $0xffffffffffffffff
890 QUAD $0x0f0e0d0c0b0a0908
891 QUAD $0xffffffffffffffff
892 QUAD $0x0e0d0c0b0a090807
893 QUAD $0xffffffffffffff0f
894 QUAD $0x0d0c0b0a09080706
895 QUAD $0xffffffffffff0f0e
896 QUAD $0x0c0b0a0908070605
897 QUAD $0xffffffffff0f0e0d
898 QUAD $0x0b0a090807060504
899 QUAD $0xffffffff0f0e0d0c
900 QUAD $0x0a09080706050403
901 QUAD $0xffffff0f0e0d0c0b
902 QUAD $0x0908070605040302
903 QUAD $0xffff0f0e0d0c0b0a
904 QUAD $0x0807060504030201
905 QUAD $0xff0f0e0d0c0b0a09