Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(100)

Delta Between Two Patch Sets: src/pkg/runtime/asm_386.s

Issue 9738047: code review 9738047: runtime: Add shared library support (linux/amd64)
Left Patch Set: diff -r 39a7093ee8db69539235d88e325df1dbabd82cc5 https://go.googlecode.com/hg/ Created 10 years, 9 months ago
Right Patch Set: diff -r 3833ddddde2b1a2741a396c4e965b04d525a133b https://go.googlecode.com/hg/ Created 10 years, 7 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « src/cmd/cgo/out.go ('k') | src/pkg/runtime/asm_amd64.s » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 // Copyright 2009 The Go Authors. All rights reserved. 1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style 2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file. 3 // license that can be found in the LICENSE file.
4 4
5 #include "zasm_GOOS_GOARCH.h" 5 #include "zasm_GOOS_GOARCH.h"
6 6 #include "funcdata.h"
7 TEXT _rt0_go(SB),7,$0 7 #include "../../cmd/ld/textflag.h"
8
9 TEXT _rt0_go(SB),NOSPLIT,$0
8 // copy arguments forward on an even stack 10 // copy arguments forward on an even stack
9 MOVL argc+0(FP), AX 11 MOVL argc+0(FP), AX
10 MOVL argv+4(FP), BX 12 MOVL argv+4(FP), BX
11 SUBL $128, SP // plenty of scratch 13 SUBL $128, SP // plenty of scratch
12 ANDL $~15, SP 14 ANDL $~15, SP
13 MOVL AX, 120(SP) // save argc, argv away 15 MOVL AX, 120(SP) // save argc, argv away
14 MOVL BX, 124(SP) 16 MOVL BX, 124(SP)
15 17
16 // set default stack bounds. 18 // set default stack bounds.
17 // _cgo_init may update stackguard. 19 // _cgo_init may update stackguard.
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 MOVL 124(SP), AX 90 MOVL 124(SP), AX
89 MOVL AX, 4(SP) 91 MOVL AX, 4(SP)
90 CALL runtime·args(SB) 92 CALL runtime·args(SB)
91 CALL runtime·osinit(SB) 93 CALL runtime·osinit(SB)
92 CALL runtime·hashinit(SB) 94 CALL runtime·hashinit(SB)
93 CALL runtime·schedinit(SB) 95 CALL runtime·schedinit(SB)
94 96
95 // create a new goroutine to start program 97 // create a new goroutine to start program
96 PUSHL $runtime·main·f(SB) // entry 98 PUSHL $runtime·main·f(SB) // entry
97 PUSHL $0 // arg size 99 PUSHL $0 // arg size
100 ARGSIZE(8)
98 CALL runtime·newproc(SB) 101 CALL runtime·newproc(SB)
102 ARGSIZE(-1)
99 POPL AX 103 POPL AX
100 POPL AX 104 POPL AX
101 105
102 // start this M 106 // start this M
103 CALL runtime·mstart(SB) 107 CALL runtime·mstart(SB)
104 108
105 INT $3 109 INT $3
106 RET 110 RET
107 111
108 DATA runtime·main·f+0(SB)/4,$runtime·main(SB) 112 DATA runtime·main·f+0(SB)/4,$runtime·main(SB)
109 GLOBL» runtime·main·f(SB),8,$4 113 GLOBL» runtime·main·f(SB),RODATA,$4
110 114
111 TEXT runtime·breakpoint(SB),7,$0 115 TEXT runtime·breakpoint(SB),NOSPLIT,$0-0
112 INT $3 116 INT $3
113 RET 117 RET
114 118
115 TEXT runtime·asminit(SB),7,$0 119 TEXT runtime·asminit(SB),NOSPLIT,$0-0
116 // Linux and MinGW start the FPU in extended double precision. 120 // Linux and MinGW start the FPU in extended double precision.
117 // Other operating systems use double precision. 121 // Other operating systems use double precision.
118 // Change to double precision to match them, 122 // Change to double precision to match them,
119 // and to match other hardware that only has double. 123 // and to match other hardware that only has double.
120 PUSHL $0x27F 124 PUSHL $0x27F
121 FLDCW 0(SP) 125 FLDCW 0(SP)
122 POPL AX 126 POPL AX
123 RET 127 RET
124 128
125 /* 129 /*
126 * go-routine 130 * go-routine
127 */ 131 */
128 132
129 // void gosave(Gobuf*) 133 // void gosave(Gobuf*)
130 // save state in Gobuf; setjmp 134 // save state in Gobuf; setjmp
131 TEXT runtime·gosave(SB), 7, $0 135 TEXT runtime·gosave(SB), NOSPLIT, $0-4
132 MOVL 4(SP), AX // gobuf 136 MOVL 4(SP), AX // gobuf
133 LEAL 4(SP), BX // caller's SP 137 LEAL 4(SP), BX // caller's SP
134 MOVL BX, gobuf_sp(AX) 138 MOVL BX, gobuf_sp(AX)
135 MOVL 0(SP), BX // caller's PC 139 MOVL 0(SP), BX // caller's PC
136 MOVL BX, gobuf_pc(AX) 140 MOVL BX, gobuf_pc(AX)
137 MOVL $0, gobuf_ret(AX) 141 MOVL $0, gobuf_ret(AX)
138 MOVL $0, gobuf_ctxt(AX) 142 MOVL $0, gobuf_ctxt(AX)
139 get_tls(CX) 143 get_tls(CX)
140 MOVL g(CX), BX 144 MOVL g(CX), BX
141 MOVL BX, gobuf_g(AX) 145 MOVL BX, gobuf_g(AX)
142 RET 146 RET
143 147
144 // void gogo(Gobuf*) 148 // void gogo(Gobuf*)
145 // restore state from Gobuf; longjmp 149 // restore state from Gobuf; longjmp
146 TEXT runtime·gogo(SB), 7, $0 150 TEXT runtime·gogo(SB), NOSPLIT, $0-4
147 MOVL 4(SP), BX // gobuf 151 MOVL 4(SP), BX // gobuf
148 MOVL gobuf_g(BX), DX 152 MOVL gobuf_g(BX), DX
149 MOVL 0(DX), CX // make sure g != nil 153 MOVL 0(DX), CX // make sure g != nil
150 get_tls(CX) 154 get_tls(CX)
151 MOVL DX, g(CX) 155 MOVL DX, g(CX)
152 MOVL gobuf_sp(BX), SP // restore SP 156 MOVL gobuf_sp(BX), SP // restore SP
153 MOVL gobuf_ret(BX), AX 157 MOVL gobuf_ret(BX), AX
154 MOVL gobuf_ctxt(BX), DX 158 MOVL gobuf_ctxt(BX), DX
155 MOVL $0, gobuf_sp(BX) // clear to help garbage collector 159 MOVL $0, gobuf_sp(BX) // clear to help garbage collector
156 MOVL $0, gobuf_ret(BX) 160 MOVL $0, gobuf_ret(BX)
157 MOVL $0, gobuf_ctxt(BX) 161 MOVL $0, gobuf_ctxt(BX)
158 MOVL gobuf_pc(BX), BX 162 MOVL gobuf_pc(BX), BX
159 JMP BX 163 JMP BX
160 164
161 // void mcall(void (*fn)(G*)) 165 // void mcall(void (*fn)(G*))
162 // Switch to m->g0's stack, call fn(g). 166 // Switch to m->g0's stack, call fn(g).
163 // Fn must never return. It should gogo(&g->sched) 167 // Fn must never return. It should gogo(&g->sched)
164 // to keep running g. 168 // to keep running g.
165 TEXT runtime·mcall(SB), 7, $0 169 TEXT runtime·mcall(SB), NOSPLIT, $0-4
166 MOVL fn+0(FP), DI 170 MOVL fn+0(FP), DI
167 ········ 171 ········
168 get_tls(CX) 172 get_tls(CX)
169 MOVL g(CX), AX // save state in g->sched 173 MOVL g(CX), AX // save state in g->sched
170 MOVL 0(SP), BX // caller's PC 174 MOVL 0(SP), BX // caller's PC
171 MOVL BX, (g_sched+gobuf_pc)(AX) 175 MOVL BX, (g_sched+gobuf_pc)(AX)
172 LEAL 4(SP), BX // caller's SP 176 LEAL 4(SP), BX // caller's SP
173 MOVL BX, (g_sched+gobuf_sp)(AX) 177 MOVL BX, (g_sched+gobuf_sp)(AX)
174 MOVL AX, (g_sched+gobuf_g)(AX) 178 MOVL AX, (g_sched+gobuf_g)(AX)
175 179
176 // switch to m->g0 & its stack, call fn 180 // switch to m->g0 & its stack, call fn
177 MOVL m(CX), BX 181 MOVL m(CX), BX
178 MOVL m_g0(BX), SI 182 MOVL m_g0(BX), SI
179 CMPL SI, AX // if g == m->g0 call badmcall 183 CMPL SI, AX // if g == m->g0 call badmcall
180 JNE 2(PC) 184 JNE 2(PC)
181 CALL runtime·badmcall(SB) 185 CALL runtime·badmcall(SB)
182 MOVL SI, g(CX) // g = m->g0 186 MOVL SI, g(CX) // g = m->g0
183 MOVL (g_sched+gobuf_sp)(SI), SP // sp = m->g0->sched.sp 187 MOVL (g_sched+gobuf_sp)(SI), SP // sp = m->g0->sched.sp
184 PUSHL AX 188 PUSHL AX
185 CALL DI 189 CALL DI
186 POPL AX 190 POPL AX
187 CALL runtime·badmcall2(SB) 191 CALL runtime·badmcall2(SB)
188 RET 192 RET
189 193
190 /* 194 /*
191 * support for morestack 195 * support for morestack
192 */ 196 */
193 197
194 // Called during function prolog when more stack is needed. 198 // Called during function prolog when more stack is needed.
195 TEXT runtime·morestack(SB),7,$0 199 //
200 // The traceback routines see morestack on a g0 as being
201 // the top of a stack (for example, morestack calling newstack
202 // calling the scheduler calling newm calling gc), so we must
203 // record an argument size. For that purpose, it has no arguments.
204 TEXT runtime·morestack(SB),NOSPLIT,$0-0
196 // Cannot grow scheduler stack (m->g0). 205 // Cannot grow scheduler stack (m->g0).
197 get_tls(CX) 206 get_tls(CX)
198 MOVL m(CX), BX 207 MOVL m(CX), BX
199 MOVL m_g0(BX), SI 208 MOVL m_g0(BX), SI
200 CMPL g(CX), SI 209 CMPL g(CX), SI
201 JNE 2(PC) 210 JNE 2(PC)
202 INT $3 211 INT $3
203 ········
204 MOVL DX, m_cret(BX)
205 212
206 // frame size in DI 213 // frame size in DI
207 // arg size in AX 214 // arg size in AX
208 // Save in m. 215 // Save in m.
209 MOVL DI, m_moreframesize(BX) 216 MOVL DI, m_moreframesize(BX)
210 MOVL AX, m_moreargsize(BX) 217 MOVL AX, m_moreargsize(BX)
211 218
212 // Called from f. 219 // Called from f.
213 // Set m->morebuf to f's caller. 220 // Set m->morebuf to f's caller.
214 MOVL 4(SP), DI // f's caller's PC 221 MOVL 4(SP), DI // f's caller's PC
215 MOVL DI, (m_morebuf+gobuf_pc)(BX) 222 MOVL DI, (m_morebuf+gobuf_pc)(BX)
216 LEAL 8(SP), CX // f's caller's SP 223 LEAL 8(SP), CX // f's caller's SP
217 MOVL CX, (m_morebuf+gobuf_sp)(BX) 224 MOVL CX, (m_morebuf+gobuf_sp)(BX)
218 MOVL CX, m_moreargp(BX) 225 MOVL CX, m_moreargp(BX)
219 get_tls(CX) 226 get_tls(CX)
220 MOVL g(CX), SI 227 MOVL g(CX), SI
221 MOVL SI, (m_morebuf+gobuf_g)(BX) 228 MOVL SI, (m_morebuf+gobuf_g)(BX)
222 229
223 » // Set m->morepc to f's PC. 230 » // Set g->sched to context in f.
224 » MOVL» 0(SP), AX 231 » MOVL» 0(SP), AX» // f's PC
225 » MOVL» AX, m_morepc(BX) 232 » MOVL» AX, (g_sched+gobuf_pc)(SI)
233 » MOVL» SI, (g_sched+gobuf_g)(SI)
234 » LEAL» 4(SP), AX» // f's SP
235 » MOVL» AX, (g_sched+gobuf_sp)(SI)
236 » MOVL» DX, (g_sched+gobuf_ctxt)(SI)
226 237
227 // Call newstack on m->g0's stack. 238 // Call newstack on m->g0's stack.
228 MOVL m_g0(BX), BP 239 MOVL m_g0(BX), BP
229 MOVL BP, g(CX) 240 MOVL BP, g(CX)
230 MOVL (g_sched+gobuf_sp)(BP), AX 241 MOVL (g_sched+gobuf_sp)(BP), AX
231 MOVL -4(AX), BX // fault if CALL would, before smashing SP 242 MOVL -4(AX), BX // fault if CALL would, before smashing SP
232 MOVL AX, SP 243 MOVL AX, SP
233 CALL runtime·newstack(SB) 244 CALL runtime·newstack(SB)
234 MOVL $0, 0x1003 // crash if newstack returns 245 MOVL $0, 0x1003 // crash if newstack returns
235 RET 246 RET
236 247
237 // Called from reflection library. Mimics morestack, 248 // Called from panic. Mimics morestack,
238 // reuses stack growth code to create a frame 249 // reuses stack growth code to create a frame
239 // with the desired args running the desired function. 250 // with the desired args running the desired function.
240 // 251 //
241 // func call(fn *byte, arg *byte, argsize uint32). 252 // func call(fn *byte, arg *byte, argsize uint32).
242 TEXT reflect·call(SB), 7, $0 253 TEXT runtime·newstackcall(SB), NOSPLIT, $0-12
243 get_tls(CX) 254 get_tls(CX)
244 MOVL m(CX), BX 255 MOVL m(CX), BX
245 256
246 // Save our caller's state as the PC and SP to 257 // Save our caller's state as the PC and SP to
247 // restore when returning from f. 258 // restore when returning from f.
248 MOVL 0(SP), AX // our caller's PC 259 MOVL 0(SP), AX // our caller's PC
249 MOVL AX, (m_morebuf+gobuf_pc)(BX) 260 MOVL AX, (m_morebuf+gobuf_pc)(BX)
250 LEAL 4(SP), AX // our caller's SP 261 LEAL 4(SP), AX // our caller's SP
251 MOVL AX, (m_morebuf+gobuf_sp)(BX) 262 MOVL AX, (m_morebuf+gobuf_sp)(BX)
252 MOVL g(CX), AX 263 MOVL g(CX), AX
253 MOVL AX, (m_morebuf+gobuf_g)(BX) 264 MOVL AX, (m_morebuf+gobuf_g)(BX)
254 265
266 // Save our own state as the PC and SP to restore
267 // if this goroutine needs to be restarted.
268 MOVL $runtime·newstackcall(SB), (g_sched+gobuf_pc)(AX)
269 MOVL SP, (g_sched+gobuf_sp)(AX)
270
255 // Set up morestack arguments to call f on a new stack. 271 // Set up morestack arguments to call f on a new stack.
256 // We set f's frame size to 1, as a hint to newstack 272 // We set f's frame size to 1, as a hint to newstack
257 » // that this is a call from reflect·call. 273 » // that this is a call from runtime·newstackcall.
258 // If it turns out that f needs a larger frame than 274 // If it turns out that f needs a larger frame than
259 // the default stack, f's usual stack growth prolog will 275 // the default stack, f's usual stack growth prolog will
260 // allocate a new segment (and recopy the arguments). 276 // allocate a new segment (and recopy the arguments).
261 MOVL 4(SP), AX // fn 277 MOVL 4(SP), AX // fn
262 MOVL 8(SP), DX // arg frame 278 MOVL 8(SP), DX // arg frame
263 MOVL 12(SP), CX // arg size 279 MOVL 12(SP), CX // arg size
264 280
265 » MOVL» AX, m_morepc(BX)» // f's PC 281 » MOVL» AX, m_cret(BX)» // f's PC
266 MOVL DX, m_moreargp(BX) // f's argument pointer 282 MOVL DX, m_moreargp(BX) // f's argument pointer
267 MOVL CX, m_moreargsize(BX) // f's argument size 283 MOVL CX, m_moreargsize(BX) // f's argument size
268 MOVL $1, m_moreframesize(BX) // f's frame size 284 MOVL $1, m_moreframesize(BX) // f's frame size
269 285
270 // Call newstack on m->g0's stack. 286 // Call newstack on m->g0's stack.
271 MOVL m_g0(BX), BP 287 MOVL m_g0(BX), BP
272 get_tls(CX) 288 get_tls(CX)
273 MOVL BP, g(CX) 289 MOVL BP, g(CX)
274 MOVL (g_sched+gobuf_sp)(BP), SP 290 MOVL (g_sched+gobuf_sp)(BP), SP
275 CALL runtime·newstack(SB) 291 CALL runtime·newstack(SB)
276 MOVL $0, 0x1103 // crash if newstack returns 292 MOVL $0, 0x1103 // crash if newstack returns
277 RET 293 RET
278 294
295 // reflect·call: call a function with the given argument list
296 // func call(f *FuncVal, arg *byte, argsize uint32).
297 // we don't have variable-sized frames, so we use a small number
298 // of constant-sized-frame functions to encode a few bits of size in the pc.
299 // Caution: ugly multiline assembly macros in your future!
300
301 #define DISPATCH(NAME,MAXSIZE) \
302 CMPL CX, $MAXSIZE; \
303 JA 3(PC); \
304 MOVL $runtime·NAME(SB), AX; \
305 JMP AX
306 // Note: can't just "JMP runtime·NAME(SB)" - bad inlining results.
307
308 TEXT reflect·call(SB), NOSPLIT, $0-12
309 MOVL argsize+8(FP), CX
310 DISPATCH(call16, 16)
311 DISPATCH(call32, 32)
312 DISPATCH(call64, 64)
313 DISPATCH(call128, 128)
314 DISPATCH(call256, 256)
315 DISPATCH(call512, 512)
316 DISPATCH(call1024, 1024)
317 DISPATCH(call2048, 2048)
318 DISPATCH(call4096, 4096)
319 DISPATCH(call8192, 8192)
320 DISPATCH(call16384, 16384)
321 DISPATCH(call32768, 32768)
322 DISPATCH(call65536, 65536)
323 DISPATCH(call131072, 131072)
324 DISPATCH(call262144, 262144)
325 DISPATCH(call524288, 524288)
326 DISPATCH(call1048576, 1048576)
327 DISPATCH(call2097152, 2097152)
328 DISPATCH(call4194304, 4194304)
329 DISPATCH(call8388608, 8388608)
330 DISPATCH(call16777216, 16777216)
331 DISPATCH(call33554432, 33554432)
332 DISPATCH(call67108864, 67108864)
333 DISPATCH(call134217728, 134217728)
334 DISPATCH(call268435456, 268435456)
335 DISPATCH(call536870912, 536870912)
336 DISPATCH(call1073741824, 1073741824)
337 MOVL $runtime·badreflectcall(SB), AX
338 JMP AX
339
340 #define CALLFN(NAME,MAXSIZE) \
341 TEXT runtime·NAME(SB), 0, $MAXSIZE-12; \
342 /* copy arguments to stack */ \
343 MOVL argptr+4(FP), SI; \
344 MOVL argsize+8(FP), CX; \
345 MOVL SP, DI; \
346 REP;MOVSB; \
347 /* call function */ \
348 MOVL f+0(FP), DX; \
349 CALL (DX); \
350 /* copy return values back */ \
351 MOVL argptr+4(FP), DI; \
352 MOVL argsize+8(FP), CX; \
353 MOVL SP, SI; \
354 REP;MOVSB; \
355 RET
356
357 CALLFN(call16, 16)
358 CALLFN(call32, 32)
359 CALLFN(call64, 64)
360 CALLFN(call128, 128)
361 CALLFN(call256, 256)
362 CALLFN(call512, 512)
363 CALLFN(call1024, 1024)
364 CALLFN(call2048, 2048)
365 CALLFN(call4096, 4096)
366 CALLFN(call8192, 8192)
367 CALLFN(call16384, 16384)
368 CALLFN(call32768, 32768)
369 CALLFN(call65536, 65536)
370 CALLFN(call131072, 131072)
371 CALLFN(call262144, 262144)
372 CALLFN(call524288, 524288)
373 CALLFN(call1048576, 1048576)
374 CALLFN(call2097152, 2097152)
375 CALLFN(call4194304, 4194304)
376 CALLFN(call8388608, 8388608)
377 CALLFN(call16777216, 16777216)
378 CALLFN(call33554432, 33554432)
379 CALLFN(call67108864, 67108864)
380 CALLFN(call134217728, 134217728)
381 CALLFN(call268435456, 268435456)
382 CALLFN(call536870912, 536870912)
383 CALLFN(call1073741824, 1073741824)
279 384
280 // Return point when leaving stack. 385 // Return point when leaving stack.
281 TEXT runtime·lessstack(SB), 7, $0 386 //
387 // Lessstack can appear in stack traces for the same reason
388 // as morestack; in that context, it has 0 arguments.
389 TEXT runtime·lessstack(SB), NOSPLIT, $0-0
282 // Save return value in m->cret 390 // Save return value in m->cret
283 get_tls(CX) 391 get_tls(CX)
284 MOVL m(CX), BX 392 MOVL m(CX), BX
285 MOVL AX, m_cret(BX) 393 MOVL AX, m_cret(BX)
286 394
287 // Call oldstack on m->g0's stack. 395 // Call oldstack on m->g0's stack.
288 MOVL m_g0(BX), BP 396 MOVL m_g0(BX), BP
289 MOVL BP, g(CX) 397 MOVL BP, g(CX)
290 MOVL (g_sched+gobuf_sp)(BP), SP 398 MOVL (g_sched+gobuf_sp)(BP), SP
291 CALL runtime·oldstack(SB) 399 CALL runtime·oldstack(SB)
292 MOVL $0, 0x1004 // crash if oldstack returns 400 MOVL $0, 0x1004 // crash if oldstack returns
293 RET 401 RET
294 402
295 403
296 // bool cas(int32 *val, int32 old, int32 new) 404 // bool cas(int32 *val, int32 old, int32 new)
297 // Atomically: 405 // Atomically:
298 // if(*val == old){ 406 // if(*val == old){
299 // *val = new; 407 // *val = new;
300 // return 1; 408 // return 1;
301 // }else 409 // }else
302 // return 0; 410 // return 0;
303 TEXT runtime·cas(SB), 7, $0 411 TEXT runtime·cas(SB), NOSPLIT, $0-12
304 MOVL 4(SP), BX 412 MOVL 4(SP), BX
305 MOVL 8(SP), AX 413 MOVL 8(SP), AX
306 MOVL 12(SP), CX 414 MOVL 12(SP), CX
307 LOCK 415 LOCK
308 CMPXCHGL CX, 0(BX) 416 CMPXCHGL CX, 0(BX)
309 JZ 3(PC) 417 JZ 3(PC)
310 MOVL $0, AX 418 MOVL $0, AX
311 RET 419 RET
312 MOVL $1, AX 420 MOVL $1, AX
313 RET 421 RET
314 422
315 // bool runtime·cas64(uint64 *val, uint64 *old, uint64 new) 423 // bool runtime·cas64(uint64 *val, uint64 old, uint64 new)
316 // Atomically: 424 // Atomically:
317 // if(*val == *old){ 425 // if(*val == *old){
318 // *val = new; 426 // *val = new;
319 // return 1; 427 // return 1;
320 // } else { 428 // } else {
321 // *old = *val
322 // return 0; 429 // return 0;
323 // } 430 // }
324 TEXT runtime·cas64(SB), 7, $0 431 TEXT runtime·cas64(SB), NOSPLIT, $0-20
325 MOVL 4(SP), BP 432 MOVL 4(SP), BP
326 » MOVL» 8(SP), SI 433 » MOVL» 8(SP), AX
327 » MOVL» 0(SI), AX 434 » MOVL» 12(SP), DX
328 » MOVL» 4(SI), DX 435 » MOVL» 16(SP), BX
329 » MOVL» 12(SP), BX 436 » MOVL» 20(SP), CX
330 » MOVL» 16(SP), CX
331 LOCK 437 LOCK
332 CMPXCHG8B 0(BP) 438 CMPXCHG8B 0(BP)
333 JNZ cas64_fail 439 JNZ cas64_fail
334 MOVL $1, AX 440 MOVL $1, AX
335 RET 441 RET
336 cas64_fail: 442 cas64_fail:
337 MOVL AX, 0(SI)
338 MOVL DX, 4(SI)
339 MOVL $0, AX 443 MOVL $0, AX
340 RET 444 RET
341 445
342 // bool casp(void **p, void *old, void *new) 446 // bool casp(void **p, void *old, void *new)
343 // Atomically: 447 // Atomically:
344 // if(*p == old){ 448 // if(*p == old){
345 // *p = new; 449 // *p = new;
346 // return 1; 450 // return 1;
347 // }else 451 // }else
348 // return 0; 452 // return 0;
349 TEXT runtime·casp(SB), 7, $0 453 TEXT runtime·casp(SB), NOSPLIT, $0-12
350 MOVL 4(SP), BX 454 MOVL 4(SP), BX
351 MOVL 8(SP), AX 455 MOVL 8(SP), AX
352 MOVL 12(SP), CX 456 MOVL 12(SP), CX
353 LOCK 457 LOCK
354 CMPXCHGL CX, 0(BX) 458 CMPXCHGL CX, 0(BX)
355 JZ 3(PC) 459 JZ 3(PC)
356 MOVL $0, AX 460 MOVL $0, AX
357 RET 461 RET
358 MOVL $1, AX 462 MOVL $1, AX
359 RET 463 RET
360 464
361 // uint32 xadd(uint32 volatile *val, int32 delta) 465 // uint32 xadd(uint32 volatile *val, int32 delta)
362 // Atomically: 466 // Atomically:
363 // *val += delta; 467 // *val += delta;
364 // return *val; 468 // return *val;
365 TEXT runtime·xadd(SB), 7, $0 469 TEXT runtime·xadd(SB), NOSPLIT, $0-8
366 MOVL 4(SP), BX 470 MOVL 4(SP), BX
367 MOVL 8(SP), AX 471 MOVL 8(SP), AX
368 MOVL AX, CX 472 MOVL AX, CX
369 LOCK 473 LOCK
370 XADDL AX, 0(BX) 474 XADDL AX, 0(BX)
371 ADDL CX, AX 475 ADDL CX, AX
372 RET 476 RET
373 477
374 TEXT runtime·xchg(SB), 7, $0 478 TEXT runtime·xchg(SB), NOSPLIT, $0-8
375 MOVL 4(SP), BX 479 MOVL 4(SP), BX
376 MOVL 8(SP), AX 480 MOVL 8(SP), AX
377 XCHGL AX, 0(BX) 481 XCHGL AX, 0(BX)
378 RET 482 RET
379 483
380 TEXT runtime·procyield(SB),7,$0 484 TEXT runtime·procyield(SB),NOSPLIT,$0-0
381 MOVL 4(SP), AX 485 MOVL 4(SP), AX
382 again: 486 again:
383 PAUSE 487 PAUSE
384 SUBL $1, AX 488 SUBL $1, AX
385 JNZ again 489 JNZ again
386 RET 490 RET
387 491
388 TEXT runtime·atomicstorep(SB), 7, $0 492 TEXT runtime·atomicstorep(SB), NOSPLIT, $0-8
389 MOVL 4(SP), BX 493 MOVL 4(SP), BX
390 MOVL 8(SP), AX 494 MOVL 8(SP), AX
391 XCHGL AX, 0(BX) 495 XCHGL AX, 0(BX)
392 RET 496 RET
393 497
394 TEXT runtime·atomicstore(SB), 7, $0 498 TEXT runtime·atomicstore(SB), NOSPLIT, $0-8
395 MOVL 4(SP), BX 499 MOVL 4(SP), BX
396 MOVL 8(SP), AX 500 MOVL 8(SP), AX
397 XCHGL AX, 0(BX) 501 XCHGL AX, 0(BX)
398 RET 502 RET
399 503
400 // uint64 atomicload64(uint64 volatile* addr); 504 // uint64 atomicload64(uint64 volatile* addr);
401 // so actually 505 // so actually
402 // void atomicload64(uint64 *res, uint64 volatile *addr); 506 // void atomicload64(uint64 *res, uint64 volatile *addr);
403 TEXT runtime·atomicload64(SB), 7, $0 507 TEXT runtime·atomicload64(SB), NOSPLIT, $0-8
404 » MOVL 4(SP), BX 508 » MOVL» 4(SP), BX
405 MOVL 8(SP), AX 509 MOVL 8(SP), AX
406 // MOVQ (%EAX), %MM0 510 // MOVQ (%EAX), %MM0
407 BYTE $0x0f; BYTE $0x6f; BYTE $0x00 511 BYTE $0x0f; BYTE $0x6f; BYTE $0x00
408 // MOVQ %MM0, 0(%EBX) 512 // MOVQ %MM0, 0(%EBX)
409 BYTE $0x0f; BYTE $0x7f; BYTE $0x03 513 BYTE $0x0f; BYTE $0x7f; BYTE $0x03
410 // EMMS 514 // EMMS
411 BYTE $0x0F; BYTE $0x77 515 BYTE $0x0F; BYTE $0x77
412 RET 516 RET
413 517
414 // void runtime·atomicstore64(uint64 volatile* addr, uint64 v); 518 // void runtime·atomicstore64(uint64 volatile* addr, uint64 v);
415 TEXT runtime·atomicstore64(SB), 7, $0 519 TEXT runtime·atomicstore64(SB), NOSPLIT, $0-12
416 MOVL 4(SP), AX 520 MOVL 4(SP), AX
417 // MOVQ and EMMS were introduced on the Pentium MMX. 521 // MOVQ and EMMS were introduced on the Pentium MMX.
418 // MOVQ 0x8(%ESP), %MM0 522 // MOVQ 0x8(%ESP), %MM0
419 BYTE $0x0f; BYTE $0x6f; BYTE $0x44; BYTE $0x24; BYTE $0x08 523 BYTE $0x0f; BYTE $0x6f; BYTE $0x44; BYTE $0x24; BYTE $0x08
420 // MOVQ %MM0, (%EAX) 524 // MOVQ %MM0, (%EAX)
421 BYTE $0x0f; BYTE $0x7f; BYTE $0x00· 525 BYTE $0x0f; BYTE $0x7f; BYTE $0x00·
422 // EMMS 526 // EMMS
423 BYTE $0x0F; BYTE $0x77 527 BYTE $0x0F; BYTE $0x77
424 // This is essentially a no-op, but it provides required memory fencing. 528 // This is essentially a no-op, but it provides required memory fencing.
425 // It can be replaced with MFENCE, but MFENCE was introduced only on the Pentium4 (SSE2). 529 // It can be replaced with MFENCE, but MFENCE was introduced only on the Pentium4 (SSE2).
426 MOVL $0, AX 530 MOVL $0, AX
427 LOCK 531 LOCK
428 XADDL AX, (SP) 532 XADDL AX, (SP)
429 RET 533 RET
430 534
431 // void jmpdefer(fn, sp); 535 // void jmpdefer(fn, sp);
432 // called from deferreturn. 536 // called from deferreturn.
433 // 1. pop the caller 537 // 1. pop the caller
434 // 2. sub 5 bytes from the callers return 538 // 2. sub 5 bytes from the callers return
435 // 3. jmp to the argument 539 // 3. jmp to the argument
436 TEXT runtime·jmpdefer(SB), 7, $0 540 TEXT runtime·jmpdefer(SB), NOSPLIT, $0-8
437 MOVL 4(SP), DX // fn 541 MOVL 4(SP), DX // fn
438 MOVL 8(SP), BX // caller sp 542 MOVL 8(SP), BX // caller sp
439 LEAL -4(BX), SP // caller sp after CALL 543 LEAL -4(BX), SP // caller sp after CALL
440 SUBL $5, (SP) // return to CALL again 544 SUBL $5, (SP) // return to CALL again
441 MOVL 0(DX), BX 545 MOVL 0(DX), BX
442 JMP BX // but first run the deferred function 546 JMP BX // but first run the deferred function
443 547
444 // Save state of caller into g->sched. 548 // Save state of caller into g->sched.
445 TEXT gosave<>(SB),7,$0 549 TEXT gosave<>(SB),NOSPLIT,$0
446 PUSHL AX 550 PUSHL AX
447 PUSHL BX 551 PUSHL BX
448 get_tls(BX) 552 get_tls(BX)
449 MOVL g(BX), BX 553 MOVL g(BX), BX
450 LEAL arg+0(FP), AX 554 LEAL arg+0(FP), AX
451 MOVL AX, (g_sched+gobuf_sp)(BX) 555 MOVL AX, (g_sched+gobuf_sp)(BX)
452 MOVL -4(AX), AX 556 MOVL -4(AX), AX
453 MOVL AX, (g_sched+gobuf_pc)(BX) 557 MOVL AX, (g_sched+gobuf_pc)(BX)
454 MOVL $0, (g_sched+gobuf_ret)(BX) 558 MOVL $0, (g_sched+gobuf_ret)(BX)
455 MOVL $0, (g_sched+gobuf_ctxt)(BX) 559 MOVL $0, (g_sched+gobuf_ctxt)(BX)
456 POPL BX 560 POPL BX
457 POPL AX 561 POPL AX
458 RET 562 RET
459 563
460 // asmcgocall(void(*fn)(void*), void *arg) 564 // asmcgocall(void(*fn)(void*), void *arg)
461 // Call fn(arg) on the scheduler stack, 565 // Call fn(arg) on the scheduler stack,
462 // aligned appropriately for the gcc ABI. 566 // aligned appropriately for the gcc ABI.
463 // See cgocall.c for more details. 567 // See cgocall.c for more details.
464 TEXT runtime·asmcgocall(SB),7,$0 568 TEXT runtime·asmcgocall(SB),NOSPLIT,$0-8
465 MOVL fn+0(FP), AX 569 MOVL fn+0(FP), AX
466 MOVL arg+4(FP), BX 570 MOVL arg+4(FP), BX
467 MOVL SP, DX 571 MOVL SP, DX
468 572
469 // Figure out if we need to switch to m->g0 stack. 573 // Figure out if we need to switch to m->g0 stack.
470 // We get called to create new OS threads too, and those 574 // We get called to create new OS threads too, and those
471 // come in on the m->g0 stack already. 575 // come in on the m->g0 stack already.
472 get_tls(CX) 576 get_tls(CX)
473 MOVL m(CX), BP 577 MOVL m(CX), BP
474 MOVL m_g0(BP), SI 578 MOVL m_g0(BP), SI
(...skipping 15 matching lines...) Expand all
490 // Restore registers, g, stack pointer. 594 // Restore registers, g, stack pointer.
491 get_tls(CX) 595 get_tls(CX)
492 MOVL 8(SP), DI 596 MOVL 8(SP), DI
493 MOVL DI, g(CX) 597 MOVL DI, g(CX)
494 MOVL 4(SP), SP 598 MOVL 4(SP), SP
495 RET 599 RET
496 600
497 // cgocallback(void (*fn)(void*), void *frame, uintptr framesize) 601 // cgocallback(void (*fn)(void*), void *frame, uintptr framesize)
498 // Turn the fn into a Go func (by taking its address) and call 602 // Turn the fn into a Go func (by taking its address) and call
499 // cgocallback_gofunc. 603 // cgocallback_gofunc.
500 TEXT runtime·cgocallback(SB),7,$12 604 TEXT runtime·cgocallback(SB),NOSPLIT,$12-12
501 LEAL fn+0(FP), AX 605 LEAL fn+0(FP), AX
502 MOVL AX, 0(SP) 606 MOVL AX, 0(SP)
503 MOVL frame+4(FP), AX 607 MOVL frame+4(FP), AX
504 MOVL AX, 4(SP) 608 MOVL AX, 4(SP)
505 MOVL framesize+8(FP), AX 609 MOVL framesize+8(FP), AX
506 MOVL AX, 8(SP) 610 MOVL AX, 8(SP)
507 MOVL $runtime·cgocallback_gofunc(SB), AX 611 MOVL $runtime·cgocallback_gofunc(SB), AX
508 CALL AX 612 CALL AX
509 RET 613 RET
510 614
511 // cgocallback_gofunc(FuncVal*, void *frame, uintptr framesize) 615 // cgocallback_gofunc(FuncVal*, void *frame, uintptr framesize)
512 // See cgocall.c for more details. 616 // See cgocall.c for more details.
513 TEXT runtime·cgocallback_gofunc(SB),7,$12 617 TEXT runtime·cgocallback_gofunc(SB),NOSPLIT,$12-12
514 // If m is nil, Go did not create the current thread. 618 // If m is nil, Go did not create the current thread.
515 // Call needm to obtain one for temporary use. 619 // Call needm to obtain one for temporary use.
516 // In this case, we're running on the thread stack, so there's 620 // In this case, we're running on the thread stack, so there's
517 // lots of space, but the linker doesn't know. Hide the call from 621 // lots of space, but the linker doesn't know. Hide the call from
518 // the linker analysis by using an indirect call through AX. 622 // the linker analysis by using an indirect call through AX.
519 get_tls(CX) 623 get_tls(CX)
520 #ifdef GOOS_windows 624 #ifdef GOOS_windows
625 MOVL $0, BP
521 CMPL CX, $0 626 CMPL CX, $0
522 » JNE» 3(PC) 627 » JEQ» 2(PC)
523 » PUSHL» $0
524 » JMP needm
525 #endif 628 #endif
526 MOVL m(CX), BP 629 MOVL m(CX), BP
527 » PUSHL» BP 630 » MOVL» BP, DX // saved copy of oldm
528 CMPL BP, $0 631 CMPL BP, $0
529 JNE havem 632 JNE havem
530 needm: 633 needm:
634 MOVL DX, 0(SP)
531 MOVL $runtime·needm(SB), AX 635 MOVL $runtime·needm(SB), AX
532 CALL AX 636 CALL AX
637 MOVL 0(SP), DX
533 get_tls(CX) 638 get_tls(CX)
534 MOVL m(CX), BP 639 MOVL m(CX), BP
535 640
536 havem: 641 havem:
537 // Now there's a valid m, and we're running on its m->g0. 642 // Now there's a valid m, and we're running on its m->g0.
538 // Save current m->g0->sched.sp on stack and then set it to SP. 643 // Save current m->g0->sched.sp on stack and then set it to SP.
539 // Save current sp in m->g0->sched.sp in preparation for 644 // Save current sp in m->g0->sched.sp in preparation for
540 // switch back to m->curg stack. 645 // switch back to m->curg stack.
646 // NOTE: unwindm knows that the saved g->sched.sp is at 0(SP).
647 // On Windows, the SEH is at 4(SP) and 8(SP).
541 MOVL m_g0(BP), SI 648 MOVL m_g0(BP), SI
542 » PUSHL» (g_sched+gobuf_sp)(SI) 649 » MOVL» (g_sched+gobuf_sp)(SI), AX
650 » MOVL» AX, 0(SP)
543 MOVL SP, (g_sched+gobuf_sp)(SI) 651 MOVL SP, (g_sched+gobuf_sp)(SI)
544 652
545 » // Switch to m->curg stack and call runtime.cgocallbackg 653 » // Switch to m->curg stack and call runtime.cgocallbackg.
546 » // with the three arguments. Because we are taking over 654 » // Because we are taking over the execution of m->curg
547 » // the execution of m->curg but *not* resuming what had 655 » // but *not* resuming what had been running, we need to
548 » // been running, we need to save that information (m->curg->sched) 656 » // save that information (m->curg->sched) so we can restore it.
549 » // so that we can restore it when we're done.
550 // We can restore m->curg->sched.sp easily, because calling 657 // We can restore m->curg->sched.sp easily, because calling
551 // runtime.cgocallbackg leaves SP unchanged upon return. 658 // runtime.cgocallbackg leaves SP unchanged upon return.
552 // To save m->curg->sched.pc, we push it onto the stack. 659 // To save m->curg->sched.pc, we push it onto the stack.
553 // This has the added benefit that it looks to the traceback 660 // This has the added benefit that it looks to the traceback
554 // routine like cgocallbackg is going to return to that 661 // routine like cgocallbackg is going to return to that
555 » // PC (because we defined cgocallbackg to have 662 » // PC (because the frame we allocate below has the same
556 » // a frame size of 12, the same amount that we use below), 663 » // size as cgocallback_gofunc's frame declared above)
557 // so that the traceback will seamlessly trace back into 664 // so that the traceback will seamlessly trace back into
558 // the earlier calls. 665 // the earlier calls.
559 » MOVL» fn+0(FP), AX 666 » //
560 » MOVL» frame+4(FP), BX 667 » // In the new goroutine, 0(SP) holds the saved oldm (DX) register.
561 » MOVL» framesize+8(FP), DX 668 » // 4(SP) and 8(SP) are unused.
562
563 MOVL m_curg(BP), SI 669 MOVL m_curg(BP), SI
564 MOVL SI, g(CX) 670 MOVL SI, g(CX)
565 » MOVL» (g_sched+gobuf_sp)(SI), DI // prepare stack as DI 671 » MOVL» (g_sched+gobuf_sp)(SI), DI // prepare stack as DI
566
567 » // Push gobuf.pc
568 MOVL (g_sched+gobuf_pc)(SI), BP 672 MOVL (g_sched+gobuf_pc)(SI), BP
569 » SUBL» $4, DI 673 » MOVL» BP, -4(DI)
570 » MOVL» BP, 0(DI) 674 » LEAL» -(4+12)(DI), SP
571 675 » MOVL» DX, 0(SP)
572 » // Push arguments to cgocallbackg.
573 » // Frame size here must match the frame size above
574 » // to trick traceback routines into doing the right thing.
575 » SUBL» $12, DI
576 » MOVL» AX, 0(DI)
577 » MOVL» BX, 4(DI)
578 » MOVL» DX, 8(DI)
579 »·······
580 » // Switch stack and make the call.
581 » MOVL» DI, SP
582 CALL runtime·cgocallbackg(SB) 676 CALL runtime·cgocallbackg(SB)
677 MOVL 0(SP), DX
583 678
584 // Restore g->sched (== m->curg->sched) from saved values. 679 // Restore g->sched (== m->curg->sched) from saved values.
585 get_tls(CX) 680 get_tls(CX)
586 MOVL g(CX), SI 681 MOVL g(CX), SI
587 MOVL 12(SP), BP 682 MOVL 12(SP), BP
588 MOVL BP, (g_sched+gobuf_pc)(SI) 683 MOVL BP, (g_sched+gobuf_pc)(SI)
589 LEAL (12+4)(SP), DI 684 LEAL (12+4)(SP), DI
590 MOVL DI, (g_sched+gobuf_sp)(SI) 685 MOVL DI, (g_sched+gobuf_sp)(SI)
591 686
592 // Switch back to m->g0's stack and restore m->g0->sched.sp. 687 // Switch back to m->g0's stack and restore m->g0->sched.sp.
593 // (Unlike m->curg, the g0 goroutine never uses sched.pc, 688 // (Unlike m->curg, the g0 goroutine never uses sched.pc,
594 // so we do not have to restore it.) 689 // so we do not have to restore it.)
595 MOVL m(CX), BP 690 MOVL m(CX), BP
596 MOVL m_g0(BP), SI 691 MOVL m_g0(BP), SI
597 MOVL SI, g(CX) 692 MOVL SI, g(CX)
598 MOVL (g_sched+gobuf_sp)(SI), SP 693 MOVL (g_sched+gobuf_sp)(SI), SP
599 » POPL» (g_sched+gobuf_sp)(SI) 694 » MOVL» 0(SP), AX
695 » MOVL» AX, (g_sched+gobuf_sp)(SI)
600 ········ 696 ········
601 // If the m on entry was nil, we called needm above to borrow an m 697 // If the m on entry was nil, we called needm above to borrow an m
602 // for the duration of the call. Since the call is over, return it with dropm. 698 // for the duration of the call. Since the call is over, return it with dropm.
603 » POPL» BP 699 » CMPL» DX, $0
604 » CMPL» BP, $0
605 JNE 3(PC) 700 JNE 3(PC)
606 MOVL $runtime·dropm(SB), AX 701 MOVL $runtime·dropm(SB), AX
607 CALL AX 702 CALL AX
608 703
609 // Done! 704 // Done!
610 RET 705 RET
611 706
612 // void setmg(M*, G*); set m and g. for use by needm. 707 // void setmg(M*, G*); set m and g. for use by needm.
613 TEXT runtime·setmg(SB), 7, $0 708 TEXT runtime·setmg(SB), NOSPLIT, $0-8
614 #ifdef GOOS_windows 709 #ifdef GOOS_windows
615 MOVL mm+0(FP), AX 710 MOVL mm+0(FP), AX
616 CMPL AX, $0 711 CMPL AX, $0
617 JNE settls 712 JNE settls
618 MOVL $0, 0x14(FS) 713 MOVL $0, 0x14(FS)
619 RET 714 RET
620 settls: 715 settls:
621 LEAL m_tls(AX), AX 716 LEAL m_tls(AX), AX
622 MOVL AX, 0x14(FS) 717 MOVL AX, 0x14(FS)
623 #endif 718 #endif
624 MOVL mm+0(FP), AX 719 MOVL mm+0(FP), AX
625 get_tls(CX) 720 get_tls(CX)
626 MOVL mm+0(FP), AX 721 MOVL mm+0(FP), AX
627 MOVL AX, m(CX) 722 MOVL AX, m(CX)
628 MOVL gg+4(FP), BX 723 MOVL gg+4(FP), BX
629 MOVL BX, g(CX) 724 MOVL BX, g(CX)
630 RET 725 RET
631 726
632 // void setmg_gcc(M*, G*); set m and g. for use by gcc 727 // void setmg_gcc(M*, G*); set m and g. for use by gcc
633 TEXT setmg_gcc<>(SB), 7, $0» 728 TEXT setmg_gcc<>(SB), NOSPLIT, $0
634 get_tls(AX) 729 get_tls(AX)
635 MOVL mm+0(FP), DX 730 MOVL mm+0(FP), DX
636 MOVL DX, m(AX) 731 MOVL DX, m(AX)
637 MOVL gg+4(FP), DX 732 MOVL gg+4(FP), DX
638 MOVL DX,g (AX) 733 MOVL DX,g (AX)
639 RET 734 RET
640 735
641 // check that SP is in range [g->stackbase, g->stackguard) 736 // check that SP is in range [g->stackbase, g->stackguard)
642 TEXT runtime·stackcheck(SB), 7, $0 737 TEXT runtime·stackcheck(SB), NOSPLIT, $0-0
643 get_tls(CX) 738 get_tls(CX)
644 MOVL g(CX), AX 739 MOVL g(CX), AX
645 CMPL g_stackbase(AX), SP 740 CMPL g_stackbase(AX), SP
646 JHI 2(PC) 741 JHI 2(PC)
647 INT $3 742 INT $3
648 CMPL SP, g_stackguard(AX) 743 CMPL SP, g_stackguard(AX)
649 JHI 2(PC) 744 JHI 2(PC)
650 INT $3 745 INT $3
651 RET 746 RET
652 747
653 TEXT runtime·memclr(SB),7,$0 748 TEXT runtime·memclr(SB),NOSPLIT,$0-8
654 MOVL 4(SP), DI // arg 1 addr 749 MOVL 4(SP), DI // arg 1 addr
655 MOVL 8(SP), CX // arg 2 count 750 MOVL 8(SP), CX // arg 2 count
656 MOVL CX, BX 751 MOVL CX, BX
657 ANDL $3, BX 752 ANDL $3, BX
658 SHRL $2, CX 753 SHRL $2, CX
659 MOVL $0, AX 754 MOVL $0, AX
660 CLD 755 CLD
661 REP 756 REP
662 STOSL 757 STOSL
663 MOVL BX, CX 758 MOVL BX, CX
664 REP 759 REP
665 STOSB 760 STOSB
666 RET 761 RET
667 762
668 TEXT runtime·getcallerpc(SB),7,$0 763 TEXT runtime·getcallerpc(SB),NOSPLIT,$0-4
669 MOVL x+0(FP),AX // addr of first arg 764 MOVL x+0(FP),AX // addr of first arg
670 MOVL -4(AX),AX // get calling pc 765 MOVL -4(AX),AX // get calling pc
671 RET 766 RET
672 767
673 TEXT runtime·setcallerpc(SB),7,$0 768 TEXT runtime·setcallerpc(SB),NOSPLIT,$0-8
674 MOVL x+0(FP),AX // addr of first arg 769 MOVL x+0(FP),AX // addr of first arg
675 MOVL x+4(FP), BX 770 MOVL x+4(FP), BX
676 MOVL BX, -4(AX) // set calling pc 771 MOVL BX, -4(AX) // set calling pc
677 RET 772 RET
678 773
679 TEXT runtime·getcallersp(SB), 7, $0 774 TEXT runtime·getcallersp(SB), NOSPLIT, $0-4
680 MOVL sp+0(FP), AX 775 MOVL sp+0(FP), AX
681 RET 776 RET
682 777
683 // int64 runtime·cputicks(void), so really 778 // int64 runtime·cputicks(void), so really
684 // void runtime·cputicks(int64 *ticks) 779 // void runtime·cputicks(int64 *ticks)
685 TEXT runtime·cputicks(SB),7,$0 780 TEXT runtime·cputicks(SB),NOSPLIT,$0-4
686 RDTSC 781 RDTSC
687 MOVL ret+0(FP), DI 782 MOVL ret+0(FP), DI
688 MOVL AX, 0(DI) 783 MOVL AX, 0(DI)
689 MOVL DX, 4(DI) 784 MOVL DX, 4(DI)
690 RET 785 RET
691 786
692 TEXT runtime·ldt0setup(SB),7,$16 787 TEXT runtime·ldt0setup(SB),NOSPLIT,$16-0
693 // set up ldt 7 to point at tls0 788 // set up ldt 7 to point at tls0
694 // ldt 1 would be fine on Linux, but on OS X, 7 is as low as we can go. 789 // ldt 1 would be fine on Linux, but on OS X, 7 is as low as we can go.
695 // the entry number is just a hint. setldt will set up GS with what it used. 790 // the entry number is just a hint. setldt will set up GS with what it used.
696 MOVL $7, 0(SP) 791 MOVL $7, 0(SP)
697 LEAL runtime·tls0(SB), AX 792 LEAL runtime·tls0(SB), AX
698 MOVL AX, 4(SP) 793 MOVL AX, 4(SP)
699 MOVL $32, 8(SP) // sizeof(tls array) 794 MOVL $32, 8(SP) // sizeof(tls array)
700 CALL runtime·setldt(SB) 795 CALL runtime·setldt(SB)
701 RET 796 RET
702 797
703 TEXT runtime·emptyfunc(SB),0,$0 798 TEXT runtime·emptyfunc(SB),0,$0-0
704 » RET 799 » RET
705 800
706 TEXT runtime·abort(SB),7,$0 801 TEXT runtime·abort(SB),NOSPLIT,$0-0
707 INT $0x3 802 INT $0x3
708 803
709 TEXT runtime·stackguard(SB),7,$0 804 TEXT runtime·stackguard(SB),NOSPLIT,$0-8
710 MOVL SP, DX 805 MOVL SP, DX
711 MOVL DX, sp+0(FP) 806 MOVL DX, sp+0(FP)
712 get_tls(CX) 807 get_tls(CX)
713 MOVL g(CX), BX 808 MOVL g(CX), BX
714 MOVL g_stackguard(BX), DX 809 MOVL g_stackguard(BX), DX
715 MOVL DX, limit+4(FP) 810 MOVL DX, limit+4(FP)
716 RET 811 RET
717 812
718 GLOBL runtime·tls0(SB), $32 813 GLOBL runtime·tls0(SB), $32
719 814
720 // hash function using AES hardware instructions 815 // hash function using AES hardware instructions
721 TEXT runtime·aeshash(SB),7,$0 816 TEXT runtime·aeshash(SB),NOSPLIT,$0-12
722 MOVL 4(SP), DX // ptr to hash value 817 MOVL 4(SP), DX // ptr to hash value
723 MOVL 8(SP), CX // size 818 MOVL 8(SP), CX // size
724 MOVL 12(SP), AX // ptr to data 819 MOVL 12(SP), AX // ptr to data
725 JMP runtime·aeshashbody(SB) 820 JMP runtime·aeshashbody(SB)
726 821
727 TEXT runtime·aeshashstr(SB),7,$0 822 TEXT runtime·aeshashstr(SB),NOSPLIT,$0-12
728 MOVL 4(SP), DX // ptr to hash value 823 MOVL 4(SP), DX // ptr to hash value
729 MOVL 12(SP), AX // ptr to string struct 824 MOVL 12(SP), AX // ptr to string struct
730 MOVL 4(AX), CX // length of string 825 MOVL 4(AX), CX // length of string
731 MOVL (AX), AX // string data 826 MOVL (AX), AX // string data
732 JMP runtime·aeshashbody(SB) 827 JMP runtime·aeshashbody(SB)
733 828
734 // AX: data 829 // AX: data
735 // CX: length 830 // CX: length
736 // DX: ptr to seed input / hash output 831 // DX: ptr to seed input / hash output
737 TEXT runtime·aeshashbody(SB),7,$0 832 TEXT runtime·aeshashbody(SB),NOSPLIT,$0-12
738 MOVL (DX), X0 // seed to low 32 bits of xmm0 833 MOVL (DX), X0 // seed to low 32 bits of xmm0
739 PINSRD $1, CX, X0 // size to next 32 bits of xmm0 834 PINSRD $1, CX, X0 // size to next 32 bits of xmm0
740 MOVO runtime·aeskeysched+0(SB), X2 835 MOVO runtime·aeskeysched+0(SB), X2
741 MOVO runtime·aeskeysched+16(SB), X3 836 MOVO runtime·aeskeysched+16(SB), X3
742 CMPL CX, $16 837 CMPL CX, $16
743 JB aessmall 838 JB aessmall
744 aesloop: 839 aesloop:
745 CMPL CX, $16 840 CMPL CX, $16
746 JBE aesloopend 841 JBE aesloopend
747 MOVOU (AX), X1 842 MOVOU (AX), X1
(...skipping 13 matching lines...) Expand all
761 TESTL CX, CX 856 TESTL CX, CX
762 JE finalize // 0 bytes 857 JE finalize // 0 bytes
763 858
764 CMPB AX, $0xf0 859 CMPB AX, $0xf0
765 JA highpartial 860 JA highpartial
766 861
767 // 16 bytes loaded at this address won't cross 862 // 16 bytes loaded at this address won't cross
768 // a page boundary, so we can load it directly. 863 // a page boundary, so we can load it directly.
769 MOVOU (AX), X1 864 MOVOU (AX), X1
770 ADDL CX, CX 865 ADDL CX, CX
771 » PAND» masks(SB)(CX*8), X1 866 » PAND» masks<>(SB)(CX*8), X1
772 JMP partial 867 JMP partial
773 highpartial: 868 highpartial:
774 // address ends in 1111xxxx. Might be up against 869 // address ends in 1111xxxx. Might be up against
775 // a page boundary, so load ending at last byte. 870 // a page boundary, so load ending at last byte.
776 // Then shift bytes down using pshufb. 871 // Then shift bytes down using pshufb.
777 MOVOU -16(AX)(CX*1), X1 872 MOVOU -16(AX)(CX*1), X1
778 ADDL CX, CX 873 ADDL CX, CX
779 » PSHUFB» shifts(SB)(CX*8), X1 874 » PSHUFB» shifts<>(SB)(CX*8), X1
780 partial: 875 partial:
781 // incorporate partial block into hash 876 // incorporate partial block into hash
782 AESENC X3, X0 877 AESENC X3, X0
783 AESENC X1, X0 878 AESENC X1, X0
784 finalize:······· 879 finalize:·······
785 // finalize hash 880 // finalize hash
786 AESENC X2, X0 881 AESENC X2, X0
787 AESENC X3, X0 882 AESENC X3, X0
788 AESENC X2, X0 883 AESENC X2, X0
789 MOVL X0, (DX) 884 MOVL X0, (DX)
790 RET 885 RET
791 886
792 TEXT runtime·aeshash32(SB),7,$0 887 TEXT runtime·aeshash32(SB),NOSPLIT,$0-12
793 MOVL 4(SP), DX // ptr to hash value 888 MOVL 4(SP), DX // ptr to hash value
794 MOVL 12(SP), AX // ptr to data 889 MOVL 12(SP), AX // ptr to data
795 MOVL (DX), X0 // seed 890 MOVL (DX), X0 // seed
796 PINSRD $1, (AX), X0 // data 891 PINSRD $1, (AX), X0 // data
797 AESENC runtime·aeskeysched+0(SB), X0 892 AESENC runtime·aeskeysched+0(SB), X0
798 AESENC runtime·aeskeysched+16(SB), X0 893 AESENC runtime·aeskeysched+16(SB), X0
799 AESENC runtime·aeskeysched+0(SB), X0 894 AESENC runtime·aeskeysched+0(SB), X0
800 MOVL X0, (DX) 895 MOVL X0, (DX)
801 RET 896 RET
802 897
803 TEXT runtime·aeshash64(SB),7,$0 898 TEXT runtime·aeshash64(SB),NOSPLIT,$0-12
804 MOVL 4(SP), DX // ptr to hash value 899 MOVL 4(SP), DX // ptr to hash value
805 MOVL 12(SP), AX // ptr to data 900 MOVL 12(SP), AX // ptr to data
806 MOVQ (AX), X0 // data 901 MOVQ (AX), X0 // data
807 PINSRD $2, (DX), X0 // seed 902 PINSRD $2, (DX), X0 // seed
808 AESENC runtime·aeskeysched+0(SB), X0 903 AESENC runtime·aeskeysched+0(SB), X0
809 AESENC runtime·aeskeysched+16(SB), X0 904 AESENC runtime·aeskeysched+16(SB), X0
810 AESENC runtime·aeskeysched+0(SB), X0 905 AESENC runtime·aeskeysched+0(SB), X0
811 MOVL X0, (DX) 906 MOVL X0, (DX)
812 RET 907 RET
813 908
814
815 // simple mask to get rid of data in the high part of the register. 909 // simple mask to get rid of data in the high part of the register.
816 TEXT masks(SB),7,$0 910 DATA masks<>+0x00(SB)/4, $0x00000000
817 » LONG $0x00000000 911 DATA masks<>+0x04(SB)/4, $0x00000000
818 » LONG $0x00000000 912 DATA masks<>+0x08(SB)/4, $0x00000000
819 » LONG $0x00000000 913 DATA masks<>+0x0c(SB)/4, $0x00000000
820 » LONG $0x00000000 914 »·······
821 »······· 915 DATA masks<>+0x10(SB)/4, $0x000000ff
822 » LONG $0x000000ff 916 DATA masks<>+0x14(SB)/4, $0x00000000
823 » LONG $0x00000000 917 DATA masks<>+0x18(SB)/4, $0x00000000
824 » LONG $0x00000000 918 DATA masks<>+0x1c(SB)/4, $0x00000000
825 » LONG $0x00000000 919 »·······
826 »······· 920 DATA masks<>+0x20(SB)/4, $0x0000ffff
827 » LONG $0x0000ffff 921 DATA masks<>+0x24(SB)/4, $0x00000000
828 » LONG $0x00000000 922 DATA masks<>+0x28(SB)/4, $0x00000000
829 » LONG $0x00000000 923 DATA masks<>+0x2c(SB)/4, $0x00000000
830 » LONG $0x00000000 924 »·······
831 »······· 925 DATA masks<>+0x30(SB)/4, $0x00ffffff
832 » LONG $0x00ffffff 926 DATA masks<>+0x34(SB)/4, $0x00000000
833 » LONG $0x00000000 927 DATA masks<>+0x38(SB)/4, $0x00000000
834 » LONG $0x00000000 928 DATA masks<>+0x3c(SB)/4, $0x00000000
835 » LONG $0x00000000 929 »·······
836 »······· 930 DATA masks<>+0x40(SB)/4, $0xffffffff
837 » LONG $0xffffffff 931 DATA masks<>+0x44(SB)/4, $0x00000000
838 » LONG $0x00000000 932 DATA masks<>+0x48(SB)/4, $0x00000000
839 » LONG $0x00000000 933 DATA masks<>+0x4c(SB)/4, $0x00000000
840 » LONG $0x00000000 934 »·······
841 »······· 935 DATA masks<>+0x50(SB)/4, $0xffffffff
842 » LONG $0xffffffff 936 DATA masks<>+0x54(SB)/4, $0x000000ff
843 » LONG $0x000000ff 937 DATA masks<>+0x58(SB)/4, $0x00000000
844 » LONG $0x00000000 938 DATA masks<>+0x5c(SB)/4, $0x00000000
845 » LONG $0x00000000 939 »·······
846 »······· 940 DATA masks<>+0x60(SB)/4, $0xffffffff
847 » LONG $0xffffffff 941 DATA masks<>+0x64(SB)/4, $0x0000ffff
848 » LONG $0x0000ffff 942 DATA masks<>+0x68(SB)/4, $0x00000000
849 » LONG $0x00000000 943 DATA masks<>+0x6c(SB)/4, $0x00000000
850 » LONG $0x00000000 944 »·······
851 »······· 945 DATA masks<>+0x70(SB)/4, $0xffffffff
852 » LONG $0xffffffff 946 DATA masks<>+0x74(SB)/4, $0x00ffffff
853 » LONG $0x00ffffff 947 DATA masks<>+0x78(SB)/4, $0x00000000
854 » LONG $0x00000000 948 DATA masks<>+0x7c(SB)/4, $0x00000000
855 » LONG $0x00000000 949 »·······
856 »······· 950 DATA masks<>+0x80(SB)/4, $0xffffffff
857 » LONG $0xffffffff 951 DATA masks<>+0x84(SB)/4, $0xffffffff
858 » LONG $0xffffffff 952 DATA masks<>+0x88(SB)/4, $0x00000000
859 » LONG $0x00000000 953 DATA masks<>+0x8c(SB)/4, $0x00000000
860 » LONG $0x00000000 954 »·······
861 »······· 955 DATA masks<>+0x90(SB)/4, $0xffffffff
862 » LONG $0xffffffff 956 DATA masks<>+0x94(SB)/4, $0xffffffff
863 » LONG $0xffffffff 957 DATA masks<>+0x98(SB)/4, $0x000000ff
864 » LONG $0x000000ff 958 DATA masks<>+0x9c(SB)/4, $0x00000000
865 » LONG $0x00000000 959 »·······
866 »······· 960 DATA masks<>+0xa0(SB)/4, $0xffffffff
867 » LONG $0xffffffff 961 DATA masks<>+0xa4(SB)/4, $0xffffffff
868 » LONG $0xffffffff 962 DATA masks<>+0xa8(SB)/4, $0x0000ffff
869 » LONG $0x0000ffff 963 DATA masks<>+0xac(SB)/4, $0x00000000
870 » LONG $0x00000000 964 »·······
871 »······· 965 DATA masks<>+0xb0(SB)/4, $0xffffffff
872 » LONG $0xffffffff 966 DATA masks<>+0xb4(SB)/4, $0xffffffff
873 » LONG $0xffffffff 967 DATA masks<>+0xb8(SB)/4, $0x00ffffff
874 » LONG $0x00ffffff 968 DATA masks<>+0xbc(SB)/4, $0x00000000
875 » LONG $0x00000000 969 »·······
876 »······· 970 DATA masks<>+0xc0(SB)/4, $0xffffffff
877 » LONG $0xffffffff 971 DATA masks<>+0xc4(SB)/4, $0xffffffff
878 » LONG $0xffffffff 972 DATA masks<>+0xc8(SB)/4, $0xffffffff
879 » LONG $0xffffffff 973 DATA masks<>+0xcc(SB)/4, $0x00000000
880 » LONG $0x00000000 974 »·······
881 »······· 975 DATA masks<>+0xd0(SB)/4, $0xffffffff
882 » LONG $0xffffffff 976 DATA masks<>+0xd4(SB)/4, $0xffffffff
883 » LONG $0xffffffff 977 DATA masks<>+0xd8(SB)/4, $0xffffffff
884 » LONG $0xffffffff 978 DATA masks<>+0xdc(SB)/4, $0x000000ff
885 » LONG $0x000000ff 979 »·······
886 »······· 980 DATA masks<>+0xe0(SB)/4, $0xffffffff
887 » LONG $0xffffffff 981 DATA masks<>+0xe4(SB)/4, $0xffffffff
888 » LONG $0xffffffff 982 DATA masks<>+0xe8(SB)/4, $0xffffffff
889 » LONG $0xffffffff 983 DATA masks<>+0xec(SB)/4, $0x0000ffff
890 » LONG $0x0000ffff 984 »·······
891 »······· 985 DATA masks<>+0xf0(SB)/4, $0xffffffff
892 » LONG $0xffffffff 986 DATA masks<>+0xf4(SB)/4, $0xffffffff
893 » LONG $0xffffffff 987 DATA masks<>+0xf8(SB)/4, $0xffffffff
894 » LONG $0xffffffff 988 DATA masks<>+0xfc(SB)/4, $0x00ffffff
895 » LONG $0x00ffffff 989
896 990 GLOBL masks<>(SB),RODATA,$256
897 » // these are arguments to pshufb. They move data down from 991
898 » // the high bytes of the register to the low bytes of the register. 992 // these are arguments to pshufb. They move data down from
899 » // index is how many bytes to move. 993 // the high bytes of the register to the low bytes of the register.
900 TEXT shifts(SB),7,$0 994 // index is how many bytes to move.
901 » LONG $0x00000000 995 DATA shifts<>+0x00(SB)/4, $0x00000000
902 » LONG $0x00000000 996 DATA shifts<>+0x04(SB)/4, $0x00000000
903 » LONG $0x00000000 997 DATA shifts<>+0x08(SB)/4, $0x00000000
904 » LONG $0x00000000 998 DATA shifts<>+0x0c(SB)/4, $0x00000000
905 »······· 999 »·······
906 » LONG $0xffffff0f 1000 DATA shifts<>+0x10(SB)/4, $0xffffff0f
907 » LONG $0xffffffff 1001 DATA shifts<>+0x14(SB)/4, $0xffffffff
908 » LONG $0xffffffff 1002 DATA shifts<>+0x18(SB)/4, $0xffffffff
909 » LONG $0xffffffff 1003 DATA shifts<>+0x1c(SB)/4, $0xffffffff
910 »······· 1004 »·······
911 » LONG $0xffff0f0e 1005 DATA shifts<>+0x20(SB)/4, $0xffff0f0e
912 » LONG $0xffffffff 1006 DATA shifts<>+0x24(SB)/4, $0xffffffff
913 » LONG $0xffffffff 1007 DATA shifts<>+0x28(SB)/4, $0xffffffff
914 » LONG $0xffffffff 1008 DATA shifts<>+0x2c(SB)/4, $0xffffffff
915 »······· 1009 »·······
916 » LONG $0xff0f0e0d 1010 DATA shifts<>+0x30(SB)/4, $0xff0f0e0d
917 » LONG $0xffffffff 1011 DATA shifts<>+0x34(SB)/4, $0xffffffff
918 » LONG $0xffffffff 1012 DATA shifts<>+0x38(SB)/4, $0xffffffff
919 » LONG $0xffffffff 1013 DATA shifts<>+0x3c(SB)/4, $0xffffffff
920 »······· 1014 »·······
921 » LONG $0x0f0e0d0c 1015 DATA shifts<>+0x40(SB)/4, $0x0f0e0d0c
922 » LONG $0xffffffff 1016 DATA shifts<>+0x44(SB)/4, $0xffffffff
923 » LONG $0xffffffff 1017 DATA shifts<>+0x48(SB)/4, $0xffffffff
924 » LONG $0xffffffff 1018 DATA shifts<>+0x4c(SB)/4, $0xffffffff
925 »······· 1019 »·······
926 » LONG $0x0e0d0c0b 1020 DATA shifts<>+0x50(SB)/4, $0x0e0d0c0b
927 » LONG $0xffffff0f 1021 DATA shifts<>+0x54(SB)/4, $0xffffff0f
928 » LONG $0xffffffff 1022 DATA shifts<>+0x58(SB)/4, $0xffffffff
929 » LONG $0xffffffff 1023 DATA shifts<>+0x5c(SB)/4, $0xffffffff
930 »······· 1024 »·······
931 » LONG $0x0d0c0b0a 1025 DATA shifts<>+0x60(SB)/4, $0x0d0c0b0a
932 » LONG $0xffff0f0e 1026 DATA shifts<>+0x64(SB)/4, $0xffff0f0e
933 » LONG $0xffffffff 1027 DATA shifts<>+0x68(SB)/4, $0xffffffff
934 » LONG $0xffffffff 1028 DATA shifts<>+0x6c(SB)/4, $0xffffffff
935 »······· 1029 »·······
936 » LONG $0x0c0b0a09 1030 DATA shifts<>+0x70(SB)/4, $0x0c0b0a09
937 » LONG $0xff0f0e0d 1031 DATA shifts<>+0x74(SB)/4, $0xff0f0e0d
938 » LONG $0xffffffff 1032 DATA shifts<>+0x78(SB)/4, $0xffffffff
939 » LONG $0xffffffff 1033 DATA shifts<>+0x7c(SB)/4, $0xffffffff
940 »······· 1034 »·······
941 » LONG $0x0b0a0908 1035 DATA shifts<>+0x80(SB)/4, $0x0b0a0908
942 » LONG $0x0f0e0d0c 1036 DATA shifts<>+0x84(SB)/4, $0x0f0e0d0c
943 » LONG $0xffffffff 1037 DATA shifts<>+0x88(SB)/4, $0xffffffff
944 » LONG $0xffffffff 1038 DATA shifts<>+0x8c(SB)/4, $0xffffffff
945 »······· 1039 »·······
946 » LONG $0x0a090807 1040 DATA shifts<>+0x90(SB)/4, $0x0a090807
947 » LONG $0x0e0d0c0b 1041 DATA shifts<>+0x94(SB)/4, $0x0e0d0c0b
948 » LONG $0xffffff0f 1042 DATA shifts<>+0x98(SB)/4, $0xffffff0f
949 » LONG $0xffffffff 1043 DATA shifts<>+0x9c(SB)/4, $0xffffffff
950 »······· 1044 »·······
951 » LONG $0x09080706 1045 DATA shifts<>+0xa0(SB)/4, $0x09080706
952 » LONG $0x0d0c0b0a 1046 DATA shifts<>+0xa4(SB)/4, $0x0d0c0b0a
953 » LONG $0xffff0f0e 1047 DATA shifts<>+0xa8(SB)/4, $0xffff0f0e
954 » LONG $0xffffffff 1048 DATA shifts<>+0xac(SB)/4, $0xffffffff
955 »······· 1049 »·······
956 » LONG $0x08070605 1050 DATA shifts<>+0xb0(SB)/4, $0x08070605
957 » LONG $0x0c0b0a09 1051 DATA shifts<>+0xb4(SB)/4, $0x0c0b0a09
958 » LONG $0xff0f0e0d 1052 DATA shifts<>+0xb8(SB)/4, $0xff0f0e0d
959 » LONG $0xffffffff 1053 DATA shifts<>+0xbc(SB)/4, $0xffffffff
960 »······· 1054 »·······
961 » LONG $0x07060504 1055 DATA shifts<>+0xc0(SB)/4, $0x07060504
962 » LONG $0x0b0a0908 1056 DATA shifts<>+0xc4(SB)/4, $0x0b0a0908
963 » LONG $0x0f0e0d0c 1057 DATA shifts<>+0xc8(SB)/4, $0x0f0e0d0c
964 » LONG $0xffffffff 1058 DATA shifts<>+0xcc(SB)/4, $0xffffffff
965 »······· 1059 »·······
966 » LONG $0x06050403 1060 DATA shifts<>+0xd0(SB)/4, $0x06050403
967 » LONG $0x0a090807 1061 DATA shifts<>+0xd4(SB)/4, $0x0a090807
968 » LONG $0x0e0d0c0b 1062 DATA shifts<>+0xd8(SB)/4, $0x0e0d0c0b
969 » LONG $0xffffff0f 1063 DATA shifts<>+0xdc(SB)/4, $0xffffff0f
970 »······· 1064 »·······
971 » LONG $0x05040302 1065 DATA shifts<>+0xe0(SB)/4, $0x05040302
972 » LONG $0x09080706 1066 DATA shifts<>+0xe4(SB)/4, $0x09080706
973 » LONG $0x0d0c0b0a 1067 DATA shifts<>+0xe8(SB)/4, $0x0d0c0b0a
974 » LONG $0xffff0f0e 1068 DATA shifts<>+0xec(SB)/4, $0xffff0f0e
975 »······· 1069 »·······
976 » LONG $0x04030201 1070 DATA shifts<>+0xf0(SB)/4, $0x04030201
977 » LONG $0x08070605 1071 DATA shifts<>+0xf4(SB)/4, $0x08070605
978 » LONG $0x0c0b0a09 1072 DATA shifts<>+0xf8(SB)/4, $0x0c0b0a09
979 » LONG $0xff0f0e0d 1073 DATA shifts<>+0xfc(SB)/4, $0xff0f0e0d
980 1074
981 TEXT runtime·memeq(SB),7,$0 1075 GLOBL shifts<>(SB),RODATA,$256
1076
1077 TEXT runtime·memeq(SB),NOSPLIT,$0-12
982 MOVL a+0(FP), SI 1078 MOVL a+0(FP), SI
983 MOVL b+4(FP), DI 1079 MOVL b+4(FP), DI
984 MOVL count+8(FP), BX 1080 MOVL count+8(FP), BX
985 JMP runtime·memeqbody(SB) 1081 JMP runtime·memeqbody(SB)
986 1082
987 1083 TEXT bytes·Equal(SB),NOSPLIT,$0-25
988 TEXT bytes·Equal(SB),7,$0
989 MOVL a_len+4(FP), BX 1084 MOVL a_len+4(FP), BX
990 MOVL b_len+16(FP), CX 1085 MOVL b_len+16(FP), CX
991 XORL AX, AX 1086 XORL AX, AX
992 CMPL BX, CX 1087 CMPL BX, CX
993 JNE eqret 1088 JNE eqret
994 MOVL a+0(FP), SI 1089 MOVL a+0(FP), SI
995 MOVL b+12(FP), DI 1090 MOVL b+12(FP), DI
996 CALL runtime·memeqbody(SB) 1091 CALL runtime·memeqbody(SB)
997 eqret: 1092 eqret:
998 MOVB AX, ret+24(FP) 1093 MOVB AX, ret+24(FP)
999 RET 1094 RET
1000 1095
1001 // a in SI 1096 // a in SI
1002 // b in DI 1097 // b in DI
1003 // count in BX 1098 // count in BX
1004 TEXT runtime·memeqbody(SB),7,$0 1099 TEXT runtime·memeqbody(SB),NOSPLIT,$0-0
1005 XORL AX, AX 1100 XORL AX, AX
1006 1101
1007 CMPL BX, $4 1102 CMPL BX, $4
1008 JB small 1103 JB small
1009 1104
1010 // 64 bytes at a time using xmm registers 1105 // 64 bytes at a time using xmm registers
1011 hugeloop: 1106 hugeloop:
1012 CMPL BX, $64 1107 CMPL BX, $64
1013 JB bigloop 1108 JB bigloop
1014 TESTL $0x4000000, runtime·cpuid_edx(SB) // check for sse2 1109 TESTL $0x4000000, runtime·cpuid_edx(SB) // check for sse2
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
1087 MOVL -4(DI)(BX*1), DI 1182 MOVL -4(DI)(BX*1), DI
1088 SHRL CX, DI 1183 SHRL CX, DI
1089 di_finish: 1184 di_finish:
1090 1185
1091 SUBL SI, DI 1186 SUBL SI, DI
1092 SHLL CX, DI 1187 SHLL CX, DI
1093 equal: 1188 equal:
1094 SETEQ AX 1189 SETEQ AX
1095 RET 1190 RET
1096 1191
1097 TEXT runtime·cmpstring(SB),7,$0 1192 TEXT runtime·cmpstring(SB),NOSPLIT,$0-20
1098 MOVL s1+0(FP), SI 1193 MOVL s1+0(FP), SI
1099 MOVL s1+4(FP), BX 1194 MOVL s1+4(FP), BX
1100 MOVL s2+8(FP), DI 1195 MOVL s2+8(FP), DI
1101 MOVL s2+12(FP), DX 1196 MOVL s2+12(FP), DX
1102 CALL runtime·cmpbody(SB) 1197 CALL runtime·cmpbody(SB)
1103 MOVL AX, res+16(FP) 1198 MOVL AX, res+16(FP)
1104 RET 1199 RET
1105 1200
1106 TEXT bytes·Compare(SB),7,$0 1201 TEXT bytes·Compare(SB),NOSPLIT,$0-28
1107 MOVL s1+0(FP), SI 1202 MOVL s1+0(FP), SI
1108 MOVL s1+4(FP), BX 1203 MOVL s1+4(FP), BX
1109 MOVL s2+12(FP), DI 1204 MOVL s2+12(FP), DI
1110 MOVL s2+16(FP), DX 1205 MOVL s2+16(FP), DX
1111 CALL runtime·cmpbody(SB) 1206 CALL runtime·cmpbody(SB)
1112 MOVL AX, res+24(FP) 1207 MOVL AX, res+24(FP)
1208 RET
1209
1210 TEXT bytes·IndexByte(SB),NOSPLIT,$0
1211 MOVL s+0(FP), SI
1212 MOVL s_len+4(FP), CX
1213 MOVB c+12(FP), AL
1214 MOVL SI, DI
1215 CLD; REPN; SCASB
1216 JZ 3(PC)
1217 MOVL $-1, ret+16(FP)
1218 RET
1219 SUBL SI, DI
1220 SUBL $1, DI
1221 MOVL DI, ret+16(FP)
1222 RET
1223
1224 TEXT strings·IndexByte(SB),NOSPLIT,$0
1225 MOVL s+0(FP), SI
1226 MOVL s_len+4(FP), CX
1227 MOVB c+8(FP), AL
1228 MOVL SI, DI
1229 CLD; REPN; SCASB
1230 JZ 3(PC)
1231 MOVL $-1, ret+12(FP)
1232 RET
1233 SUBL SI, DI
1234 SUBL $1, DI
1235 MOVL DI, ret+12(FP)
1113 RET 1236 RET
1114 1237
1115 // input: 1238 // input:
1116 // SI = a 1239 // SI = a
1117 // DI = b 1240 // DI = b
1118 // BX = alen 1241 // BX = alen
1119 // DX = blen 1242 // DX = blen
1120 // output: 1243 // output:
1121 // AX = 1/0/-1 1244 // AX = 1/0/-1
1122 TEXT runtime·cmpbody(SB),7,$0 1245 TEXT runtime·cmpbody(SB),NOSPLIT,$0-0
1123 CMPL SI, DI 1246 CMPL SI, DI
1124 JEQ cmp_allsame 1247 JEQ cmp_allsame
1125 CMPL BX, DX 1248 CMPL BX, DX
1126 MOVL DX, BP 1249 MOVL DX, BP
1127 CMOVLLT BX, BP // BP = min(alen, blen) 1250 CMOVLLT BX, BP // BP = min(alen, blen)
1128 CMPL BP, $4 1251 CMPL BP, $4
1129 JB cmp_small 1252 JB cmp_small
1130 TESTL $0x4000000, runtime·cpuid_edx(SB) // check for sse2 1253 TESTL $0x4000000, runtime·cpuid_edx(SB) // check for sse2
1131 JE cmp_mediumloop 1254 JE cmp_mediumloop
1132 cmp_largeloop: 1255 cmp_largeloop:
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
1223 cmp_allsame: 1346 cmp_allsame:
1224 XORL AX, AX 1347 XORL AX, AX
1225 XORL CX, CX 1348 XORL CX, CX
1226 CMPL BX, DX 1349 CMPL BX, DX
1227 SETGT AX // 1 if alen > blen 1350 SETGT AX // 1 if alen > blen
1228 SETEQ CX // 1 if alen == blen 1351 SETEQ CX // 1 if alen == blen
1229 LEAL -1(CX)(AX*2), AX // 1,0,-1 result 1352 LEAL -1(CX)(AX*2), AX // 1,0,-1 result
1230 RET 1353 RET
1231 1354
1232 // Not implemented on 386 yet 1355 // Not implemented on 386 yet
1233 TEXT runtime·lib_init(SB),7,$-4 1356 TEXT runtime·lib_init(SB),NOSPLIT,$-4
1234 MOVW $0, AX 1357 MOVW $0, AX
1235 MOVW (AX), AX 1358 MOVW (AX), AX
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b