Text file
src/runtime/asm_mips64x.s
1 // Copyright 2015 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
5 //go:build mips64 || mips64le
6
7 #include "go_asm.h"
8 #include "go_tls.h"
9 #include "funcdata.h"
10 #include "textflag.h"
11
12 #define REGCTXT R22
13
14 TEXT runtime·rt0_go(SB),NOSPLIT|TOPFRAME,$0
15 // R29 = stack; R4 = argc; R5 = argv
16
17 ADDV $-24, R29
18 MOVW R4, 8(R29) // argc
19 MOVV R5, 16(R29) // argv
20
21 // create istack out of the given (operating system) stack.
22 // _cgo_init may update stackguard.
23 MOVV $runtime·g0(SB), g
24 MOVV $(-64*1024), R23
25 ADDV R23, R29, R1
26 MOVV R1, g_stackguard0(g)
27 MOVV R1, g_stackguard1(g)
28 MOVV R1, (g_stack+stack_lo)(g)
29 MOVV R29, (g_stack+stack_hi)(g)
30
31 // if there is a _cgo_init, call it using the gcc ABI.
32 MOVV _cgo_init(SB), R25
33 BEQ R25, nocgo
34
35 MOVV R0, R7 // arg 3: not used
36 MOVV R0, R6 // arg 2: not used
37 MOVV $setg_gcc<>(SB), R5 // arg 1: setg
38 MOVV g, R4 // arg 0: G
39 JAL (R25)
40
41 nocgo:
42 // update stackguard after _cgo_init
43 MOVV (g_stack+stack_lo)(g), R1
44 ADDV $const__StackGuard, R1
45 MOVV R1, g_stackguard0(g)
46 MOVV R1, g_stackguard1(g)
47
48 // set the per-goroutine and per-mach "registers"
49 MOVV $runtime·m0(SB), R1
50
51 // save m->g0 = g0
52 MOVV g, m_g0(R1)
53 // save m0 to g0->m
54 MOVV R1, g_m(g)
55
56 JAL runtime·check(SB)
57
58 // args are already prepared
59 JAL runtime·args(SB)
60 JAL runtime·osinit(SB)
61 JAL runtime·schedinit(SB)
62
63 // create a new goroutine to start program
64 MOVV $runtime·mainPC(SB), R1 // entry
65 ADDV $-16, R29
66 MOVV R1, 8(R29)
67 MOVV R0, 0(R29)
68 JAL runtime·newproc(SB)
69 ADDV $16, R29
70
71 // start this M
72 JAL runtime·mstart(SB)
73
74 MOVV R0, 1(R0)
75 RET
76
77 DATA runtime·mainPC+0(SB)/8,$runtime·main(SB)
78 GLOBL runtime·mainPC(SB),RODATA,$8
79
80 TEXT runtime·breakpoint(SB),NOSPLIT|NOFRAME,$0-0
81 MOVV R0, 2(R0) // TODO: TD
82 RET
83
84 TEXT runtime·asminit(SB),NOSPLIT|NOFRAME,$0-0
85 RET
86
87 TEXT runtime·mstart(SB),NOSPLIT|TOPFRAME,$0
88 JAL runtime·mstart0(SB)
89 RET // not reached
90
91 /*
92 * go-routine
93 */
94
95 // void gogo(Gobuf*)
96 // restore state from Gobuf; longjmp
97 TEXT runtime·gogo(SB), NOSPLIT|NOFRAME, $0-8
98 MOVV buf+0(FP), R3
99 MOVV gobuf_g(R3), R4
100 MOVV 0(R4), R0 // make sure g != nil
101 JMP gogo<>(SB)
102
103 TEXT gogo<>(SB), NOSPLIT|NOFRAME, $0
104 MOVV R4, g
105 JAL runtime·save_g(SB)
106
107 MOVV 0(g), R2
108 MOVV gobuf_sp(R3), R29
109 MOVV gobuf_lr(R3), R31
110 MOVV gobuf_ret(R3), R1
111 MOVV gobuf_ctxt(R3), REGCTXT
112 MOVV R0, gobuf_sp(R3)
113 MOVV R0, gobuf_ret(R3)
114 MOVV R0, gobuf_lr(R3)
115 MOVV R0, gobuf_ctxt(R3)
116 MOVV gobuf_pc(R3), R4
117 JMP (R4)
118
119 // void mcall(fn func(*g))
120 // Switch to m->g0's stack, call fn(g).
121 // Fn must never return. It should gogo(&g->sched)
122 // to keep running g.
123 TEXT runtime·mcall(SB), NOSPLIT|NOFRAME, $0-8
124 // Save caller state in g->sched
125 MOVV R29, (g_sched+gobuf_sp)(g)
126 MOVV R31, (g_sched+gobuf_pc)(g)
127 MOVV R0, (g_sched+gobuf_lr)(g)
128
129 // Switch to m->g0 & its stack, call fn.
130 MOVV g, R1
131 MOVV g_m(g), R3
132 MOVV m_g0(R3), g
133 JAL runtime·save_g(SB)
134 BNE g, R1, 2(PC)
135 JMP runtime·badmcall(SB)
136 MOVV fn+0(FP), REGCTXT // context
137 MOVV 0(REGCTXT), R4 // code pointer
138 MOVV (g_sched+gobuf_sp)(g), R29 // sp = m->g0->sched.sp
139 ADDV $-16, R29
140 MOVV R1, 8(R29)
141 MOVV R0, 0(R29)
142 JAL (R4)
143 JMP runtime·badmcall2(SB)
144
145 // systemstack_switch is a dummy routine that systemstack leaves at the bottom
146 // of the G stack. We need to distinguish the routine that
147 // lives at the bottom of the G stack from the one that lives
148 // at the top of the system stack because the one at the top of
149 // the system stack terminates the stack walk (see topofstack()).
150 TEXT runtime·systemstack_switch(SB), NOSPLIT, $0-0
151 UNDEF
152 JAL (R31) // make sure this function is not leaf
153 RET
154
155 // func systemstack(fn func())
156 TEXT runtime·systemstack(SB), NOSPLIT, $0-8
157 MOVV fn+0(FP), R1 // R1 = fn
158 MOVV R1, REGCTXT // context
159 MOVV g_m(g), R2 // R2 = m
160
161 MOVV m_gsignal(R2), R3 // R3 = gsignal
162 BEQ g, R3, noswitch
163
164 MOVV m_g0(R2), R3 // R3 = g0
165 BEQ g, R3, noswitch
166
167 MOVV m_curg(R2), R4
168 BEQ g, R4, switch
169
170 // Bad: g is not gsignal, not g0, not curg. What is it?
171 // Hide call from linker nosplit analysis.
172 MOVV $runtime·badsystemstack(SB), R4
173 JAL (R4)
174 JAL runtime·abort(SB)
175
176 switch:
177 // save our state in g->sched. Pretend to
178 // be systemstack_switch if the G stack is scanned.
179 JAL gosave_systemstack_switch<>(SB)
180
181 // switch to g0
182 MOVV R3, g
183 JAL runtime·save_g(SB)
184 MOVV (g_sched+gobuf_sp)(g), R1
185 MOVV R1, R29
186
187 // call target function
188 MOVV 0(REGCTXT), R4 // code pointer
189 JAL (R4)
190
191 // switch back to g
192 MOVV g_m(g), R1
193 MOVV m_curg(R1), g
194 JAL runtime·save_g(SB)
195 MOVV (g_sched+gobuf_sp)(g), R29
196 MOVV R0, (g_sched+gobuf_sp)(g)
197 RET
198
199 noswitch:
200 // already on m stack, just call directly
201 // Using a tail call here cleans up tracebacks since we won't stop
202 // at an intermediate systemstack.
203 MOVV 0(REGCTXT), R4 // code pointer
204 MOVV 0(R29), R31 // restore LR
205 ADDV $8, R29
206 JMP (R4)
207
208 /*
209 * support for morestack
210 */
211
212 // Called during function prolog when more stack is needed.
213 // Caller has already loaded:
214 // R1: framesize, R2: argsize, R3: LR
215 //
216 // The traceback routines see morestack on a g0 as being
217 // the top of a stack (for example, morestack calling newstack
218 // calling the scheduler calling newm calling gc), so we must
219 // record an argument size. For that purpose, it has no arguments.
220 TEXT runtime·morestack(SB),NOSPLIT|NOFRAME,$0-0
221 // Cannot grow scheduler stack (m->g0).
222 MOVV g_m(g), R7
223 MOVV m_g0(R7), R8
224 BNE g, R8, 3(PC)
225 JAL runtime·badmorestackg0(SB)
226 JAL runtime·abort(SB)
227
228 // Cannot grow signal stack (m->gsignal).
229 MOVV m_gsignal(R7), R8
230 BNE g, R8, 3(PC)
231 JAL runtime·badmorestackgsignal(SB)
232 JAL runtime·abort(SB)
233
234 // Called from f.
235 // Set g->sched to context in f.
236 MOVV R29, (g_sched+gobuf_sp)(g)
237 MOVV R31, (g_sched+gobuf_pc)(g)
238 MOVV R3, (g_sched+gobuf_lr)(g)
239 MOVV REGCTXT, (g_sched+gobuf_ctxt)(g)
240
241 // Called from f.
242 // Set m->morebuf to f's caller.
243 MOVV R3, (m_morebuf+gobuf_pc)(R7) // f's caller's PC
244 MOVV R29, (m_morebuf+gobuf_sp)(R7) // f's caller's SP
245 MOVV g, (m_morebuf+gobuf_g)(R7)
246
247 // Call newstack on m->g0's stack.
248 MOVV m_g0(R7), g
249 JAL runtime·save_g(SB)
250 MOVV (g_sched+gobuf_sp)(g), R29
251 // Create a stack frame on g0 to call newstack.
252 MOVV R0, -8(R29) // Zero saved LR in frame
253 ADDV $-8, R29
254 JAL runtime·newstack(SB)
255
256 // Not reached, but make sure the return PC from the call to newstack
257 // is still in this function, and not the beginning of the next.
258 UNDEF
259
260 TEXT runtime·morestack_noctxt(SB),NOSPLIT|NOFRAME,$0-0
261 MOVV R0, REGCTXT
262 JMP runtime·morestack(SB)
263
264 // reflectcall: call a function with the given argument list
265 // func call(stackArgsType *_type, f *FuncVal, stackArgs *byte, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs).
266 // we don't have variable-sized frames, so we use a small number
267 // of constant-sized-frame functions to encode a few bits of size in the pc.
268 // Caution: ugly multiline assembly macros in your future!
269
270 #define DISPATCH(NAME,MAXSIZE) \
271 MOVV $MAXSIZE, R23; \
272 SGTU R1, R23, R23; \
273 BNE R23, 3(PC); \
274 MOVV $NAME(SB), R4; \
275 JMP (R4)
276 // Note: can't just "BR NAME(SB)" - bad inlining results.
277
278 TEXT ·reflectcall(SB), NOSPLIT|NOFRAME, $0-48
279 MOVWU frameSize+32(FP), R1
280 DISPATCH(runtime·call16, 16)
281 DISPATCH(runtime·call32, 32)
282 DISPATCH(runtime·call64, 64)
283 DISPATCH(runtime·call128, 128)
284 DISPATCH(runtime·call256, 256)
285 DISPATCH(runtime·call512, 512)
286 DISPATCH(runtime·call1024, 1024)
287 DISPATCH(runtime·call2048, 2048)
288 DISPATCH(runtime·call4096, 4096)
289 DISPATCH(runtime·call8192, 8192)
290 DISPATCH(runtime·call16384, 16384)
291 DISPATCH(runtime·call32768, 32768)
292 DISPATCH(runtime·call65536, 65536)
293 DISPATCH(runtime·call131072, 131072)
294 DISPATCH(runtime·call262144, 262144)
295 DISPATCH(runtime·call524288, 524288)
296 DISPATCH(runtime·call1048576, 1048576)
297 DISPATCH(runtime·call2097152, 2097152)
298 DISPATCH(runtime·call4194304, 4194304)
299 DISPATCH(runtime·call8388608, 8388608)
300 DISPATCH(runtime·call16777216, 16777216)
301 DISPATCH(runtime·call33554432, 33554432)
302 DISPATCH(runtime·call67108864, 67108864)
303 DISPATCH(runtime·call134217728, 134217728)
304 DISPATCH(runtime·call268435456, 268435456)
305 DISPATCH(runtime·call536870912, 536870912)
306 DISPATCH(runtime·call1073741824, 1073741824)
307 MOVV $runtime·badreflectcall(SB), R4
308 JMP (R4)
309
310 #define CALLFN(NAME,MAXSIZE) \
311 TEXT NAME(SB), WRAPPER, $MAXSIZE-48; \
312 NO_LOCAL_POINTERS; \
313 /* copy arguments to stack */ \
314 MOVV stackArgs+16(FP), R1; \
315 MOVWU stackArgsSize+24(FP), R2; \
316 MOVV R29, R3; \
317 ADDV $8, R3; \
318 ADDV R3, R2; \
319 BEQ R3, R2, 6(PC); \
320 MOVBU (R1), R4; \
321 ADDV $1, R1; \
322 MOVBU R4, (R3); \
323 ADDV $1, R3; \
324 JMP -5(PC); \
325 /* call function */ \
326 MOVV f+8(FP), REGCTXT; \
327 MOVV (REGCTXT), R4; \
328 PCDATA $PCDATA_StackMapIndex, $0; \
329 JAL (R4); \
330 /* copy return values back */ \
331 MOVV stackArgsType+0(FP), R5; \
332 MOVV stackArgs+16(FP), R1; \
333 MOVWU stackArgsSize+24(FP), R2; \
334 MOVWU stackRetOffset+28(FP), R4; \
335 ADDV $8, R29, R3; \
336 ADDV R4, R3; \
337 ADDV R4, R1; \
338 SUBVU R4, R2; \
339 JAL callRet<>(SB); \
340 RET
341
342 // callRet copies return values back at the end of call*. This is a
343 // separate function so it can allocate stack space for the arguments
344 // to reflectcallmove. It does not follow the Go ABI; it expects its
345 // arguments in registers.
346 TEXT callRet<>(SB), NOSPLIT, $40-0
347 MOVV R5, 8(R29)
348 MOVV R1, 16(R29)
349 MOVV R3, 24(R29)
350 MOVV R2, 32(R29)
351 MOVV $0, 40(R29)
352 JAL runtime·reflectcallmove(SB)
353 RET
354
355 CALLFN(·call16, 16)
356 CALLFN(·call32, 32)
357 CALLFN(·call64, 64)
358 CALLFN(·call128, 128)
359 CALLFN(·call256, 256)
360 CALLFN(·call512, 512)
361 CALLFN(·call1024, 1024)
362 CALLFN(·call2048, 2048)
363 CALLFN(·call4096, 4096)
364 CALLFN(·call8192, 8192)
365 CALLFN(·call16384, 16384)
366 CALLFN(·call32768, 32768)
367 CALLFN(·call65536, 65536)
368 CALLFN(·call131072, 131072)
369 CALLFN(·call262144, 262144)
370 CALLFN(·call524288, 524288)
371 CALLFN(·call1048576, 1048576)
372 CALLFN(·call2097152, 2097152)
373 CALLFN(·call4194304, 4194304)
374 CALLFN(·call8388608, 8388608)
375 CALLFN(·call16777216, 16777216)
376 CALLFN(·call33554432, 33554432)
377 CALLFN(·call67108864, 67108864)
378 CALLFN(·call134217728, 134217728)
379 CALLFN(·call268435456, 268435456)
380 CALLFN(·call536870912, 536870912)
381 CALLFN(·call1073741824, 1073741824)
382
383 TEXT runtime·procyield(SB),NOSPLIT,$0-0
384 RET
385
386 // Save state of caller into g->sched,
387 // but using fake PC from systemstack_switch.
388 // Must only be called from functions with no locals ($0)
389 // or else unwinding from systemstack_switch is incorrect.
390 // Smashes R1.
391 TEXT gosave_systemstack_switch<>(SB),NOSPLIT|NOFRAME,$0
392 MOVV $runtime·systemstack_switch(SB), R1
393 ADDV $8, R1 // get past prologue
394 MOVV R1, (g_sched+gobuf_pc)(g)
395 MOVV R29, (g_sched+gobuf_sp)(g)
396 MOVV R0, (g_sched+gobuf_lr)(g)
397 MOVV R0, (g_sched+gobuf_ret)(g)
398 // Assert ctxt is zero. See func save.
399 MOVV (g_sched+gobuf_ctxt)(g), R1
400 BEQ R1, 2(PC)
401 JAL runtime·abort(SB)
402 RET
403
404 // func asmcgocall_no_g(fn, arg unsafe.Pointer)
405 // Call fn(arg) aligned appropriately for the gcc ABI.
406 // Called on a system stack, and there may be no g yet (during needm).
407 TEXT ·asmcgocall_no_g(SB),NOSPLIT,$0-16
408 MOVV fn+0(FP), R25
409 MOVV arg+8(FP), R4
410 JAL (R25)
411 RET
412
413 // func asmcgocall(fn, arg unsafe.Pointer) int32
414 // Call fn(arg) on the scheduler stack,
415 // aligned appropriately for the gcc ABI.
416 // See cgocall.go for more details.
417 TEXT ·asmcgocall(SB),NOSPLIT,$0-20
418 MOVV fn+0(FP), R25
419 MOVV arg+8(FP), R4
420
421 MOVV R29, R3 // save original stack pointer
422 MOVV g, R2
423
424 // Figure out if we need to switch to m->g0 stack.
425 // We get called to create new OS threads too, and those
426 // come in on the m->g0 stack already. Or we might already
427 // be on the m->gsignal stack.
428 MOVV g_m(g), R5
429 MOVV m_gsignal(R5), R6
430 BEQ R6, g, g0
431 MOVV m_g0(R5), R6
432 BEQ R6, g, g0
433
434 JAL gosave_systemstack_switch<>(SB)
435 MOVV R6, g
436 JAL runtime·save_g(SB)
437 MOVV (g_sched+gobuf_sp)(g), R29
438
439 // Now on a scheduling stack (a pthread-created stack).
440 g0:
441 // Save room for two of our pointers.
442 ADDV $-16, R29
443 MOVV R2, 0(R29) // save old g on stack
444 MOVV (g_stack+stack_hi)(R2), R2
445 SUBVU R3, R2
446 MOVV R2, 8(R29) // save depth in old g stack (can't just save SP, as stack might be copied during a callback)
447 JAL (R25)
448
449 // Restore g, stack pointer. R2 is return value.
450 MOVV 0(R29), g
451 JAL runtime·save_g(SB)
452 MOVV (g_stack+stack_hi)(g), R5
453 MOVV 8(R29), R6
454 SUBVU R6, R5
455 MOVV R5, R29
456
457 MOVW R2, ret+16(FP)
458 RET
459
460 // func cgocallback(fn, frame unsafe.Pointer, ctxt uintptr)
461 // See cgocall.go for more details.
462 TEXT ·cgocallback(SB),NOSPLIT,$24-24
463 NO_LOCAL_POINTERS
464
465 // Load m and g from thread-local storage.
466 MOVB runtime·iscgo(SB), R1
467 BEQ R1, nocgo
468 JAL runtime·load_g(SB)
469 nocgo:
470
471 // If g is nil, Go did not create the current thread.
472 // Call needm to obtain one for temporary use.
473 // In this case, we're running on the thread stack, so there's
474 // lots of space, but the linker doesn't know. Hide the call from
475 // the linker analysis by using an indirect call.
476 BEQ g, needm
477
478 MOVV g_m(g), R3
479 MOVV R3, savedm-8(SP)
480 JMP havem
481
482 needm:
483 MOVV g, savedm-8(SP) // g is zero, so is m.
484 MOVV $runtime·needm(SB), R4
485 JAL (R4)
486
487 // Set m->sched.sp = SP, so that if a panic happens
488 // during the function we are about to execute, it will
489 // have a valid SP to run on the g0 stack.
490 // The next few lines (after the havem label)
491 // will save this SP onto the stack and then write
492 // the same SP back to m->sched.sp. That seems redundant,
493 // but if an unrecovered panic happens, unwindm will
494 // restore the g->sched.sp from the stack location
495 // and then systemstack will try to use it. If we don't set it here,
496 // that restored SP will be uninitialized (typically 0) and
497 // will not be usable.
498 MOVV g_m(g), R3
499 MOVV m_g0(R3), R1
500 MOVV R29, (g_sched+gobuf_sp)(R1)
501
502 havem:
503 // Now there's a valid m, and we're running on its m->g0.
504 // Save current m->g0->sched.sp on stack and then set it to SP.
505 // Save current sp in m->g0->sched.sp in preparation for
506 // switch back to m->curg stack.
507 // NOTE: unwindm knows that the saved g->sched.sp is at 8(R29) aka savedsp-16(SP).
508 MOVV m_g0(R3), R1
509 MOVV (g_sched+gobuf_sp)(R1), R2
510 MOVV R2, savedsp-24(SP) // must match frame size
511 MOVV R29, (g_sched+gobuf_sp)(R1)
512
513 // Switch to m->curg stack and call runtime.cgocallbackg.
514 // Because we are taking over the execution of m->curg
515 // but *not* resuming what had been running, we need to
516 // save that information (m->curg->sched) so we can restore it.
517 // We can restore m->curg->sched.sp easily, because calling
518 // runtime.cgocallbackg leaves SP unchanged upon return.
519 // To save m->curg->sched.pc, we push it onto the curg stack and
520 // open a frame the same size as cgocallback's g0 frame.
521 // Once we switch to the curg stack, the pushed PC will appear
522 // to be the return PC of cgocallback, so that the traceback
523 // will seamlessly trace back into the earlier calls.
524 MOVV m_curg(R3), g
525 JAL runtime·save_g(SB)
526 MOVV (g_sched+gobuf_sp)(g), R2 // prepare stack as R2
527 MOVV (g_sched+gobuf_pc)(g), R4
528 MOVV R4, -(24+8)(R2) // "saved LR"; must match frame size
529 // Gather our arguments into registers.
530 MOVV fn+0(FP), R5
531 MOVV frame+8(FP), R6
532 MOVV ctxt+16(FP), R7
533 MOVV $-(24+8)(R2), R29 // switch stack; must match frame size
534 MOVV R5, 8(R29)
535 MOVV R6, 16(R29)
536 MOVV R7, 24(R29)
537 JAL runtime·cgocallbackg(SB)
538
539 // Restore g->sched (== m->curg->sched) from saved values.
540 MOVV 0(R29), R4
541 MOVV R4, (g_sched+gobuf_pc)(g)
542 MOVV $(24+8)(R29), R2 // must match frame size
543 MOVV R2, (g_sched+gobuf_sp)(g)
544
545 // Switch back to m->g0's stack and restore m->g0->sched.sp.
546 // (Unlike m->curg, the g0 goroutine never uses sched.pc,
547 // so we do not have to restore it.)
548 MOVV g_m(g), R3
549 MOVV m_g0(R3), g
550 JAL runtime·save_g(SB)
551 MOVV (g_sched+gobuf_sp)(g), R29
552 MOVV savedsp-24(SP), R2 // must match frame size
553 MOVV R2, (g_sched+gobuf_sp)(g)
554
555 // If the m on entry was nil, we called needm above to borrow an m
556 // for the duration of the call. Since the call is over, return it with dropm.
557 MOVV savedm-8(SP), R3
558 BNE R3, droppedm
559 MOVV $runtime·dropm(SB), R4
560 JAL (R4)
561 droppedm:
562
563 // Done!
564 RET
565
566 // void setg(G*); set g. for use by needm.
567 TEXT runtime·setg(SB), NOSPLIT, $0-8
568 MOVV gg+0(FP), g
569 // This only happens if iscgo, so jump straight to save_g
570 JAL runtime·save_g(SB)
571 RET
572
573 // void setg_gcc(G*); set g called from gcc with g in R1
574 TEXT setg_gcc<>(SB),NOSPLIT,$0-0
575 MOVV R1, g
576 JAL runtime·save_g(SB)
577 RET
578
579 TEXT runtime·abort(SB),NOSPLIT|NOFRAME,$0-0
580 MOVW (R0), R0
581 UNDEF
582
583 // AES hashing not implemented for mips64
584 TEXT runtime·memhash(SB),NOSPLIT|NOFRAME,$0-32
585 JMP runtime·memhashFallback(SB)
586 TEXT runtime·strhash(SB),NOSPLIT|NOFRAME,$0-24
587 JMP runtime·strhashFallback(SB)
588 TEXT runtime·memhash32(SB),NOSPLIT|NOFRAME,$0-24
589 JMP runtime·memhash32Fallback(SB)
590 TEXT runtime·memhash64(SB),NOSPLIT|NOFRAME,$0-24
591 JMP runtime·memhash64Fallback(SB)
592
593 TEXT runtime·return0(SB), NOSPLIT, $0
594 MOVW $0, R1
595 RET
596
597 // Called from cgo wrappers, this function returns g->m->curg.stack.hi.
598 // Must obey the gcc calling convention.
599 TEXT _cgo_topofstack(SB),NOSPLIT,$16
600 // g (R30) and REGTMP (R23) might be clobbered by load_g. They
601 // are callee-save in the gcc calling convention, so save them.
602 MOVV R23, savedR23-16(SP)
603 MOVV g, savedG-8(SP)
604
605 JAL runtime·load_g(SB)
606 MOVV g_m(g), R1
607 MOVV m_curg(R1), R1
608 MOVV (g_stack+stack_hi)(R1), R2 // return value in R2
609
610 MOVV savedG-8(SP), g
611 MOVV savedR23-16(SP), R23
612 RET
613
614 // The top-most function running on a goroutine
615 // returns to goexit+PCQuantum.
616 TEXT runtime·goexit(SB),NOSPLIT|NOFRAME|TOPFRAME,$0-0
617 NOR R0, R0 // NOP
618 JAL runtime·goexit1(SB) // does not return
619 // traceback from goexit1 must hit code range of goexit
620 NOR R0, R0 // NOP
621
622 TEXT ·checkASM(SB),NOSPLIT,$0-1
623 MOVW $1, R1
624 MOVB R1, ret+0(FP)
625 RET
626
627 // gcWriteBarrier performs a heap pointer write and informs the GC.
628 //
629 // gcWriteBarrier does NOT follow the Go ABI. It takes two arguments:
630 // - R20 is the destination of the write
631 // - R21 is the value being written at R20.
632 // It clobbers R23 (the linker temp register).
633 // The act of CALLing gcWriteBarrier will clobber R31 (LR).
634 // It does not clobber any other general-purpose registers,
635 // but may clobber others (e.g., floating point registers).
636 TEXT runtime·gcWriteBarrier(SB),NOSPLIT,$192
637 // Save the registers clobbered by the fast path.
638 MOVV R1, 184(R29)
639 MOVV R2, 192(R29)
640 MOVV g_m(g), R1
641 MOVV m_p(R1), R1
642 MOVV (p_wbBuf+wbBuf_next)(R1), R2
643 // Increment wbBuf.next position.
644 ADDV $16, R2
645 MOVV R2, (p_wbBuf+wbBuf_next)(R1)
646 MOVV (p_wbBuf+wbBuf_end)(R1), R1
647 MOVV R1, R23 // R23 is linker temp register
648 // Record the write.
649 MOVV R21, -16(R2) // Record value
650 MOVV (R20), R1 // TODO: This turns bad writes into bad reads.
651 MOVV R1, -8(R2) // Record *slot
652 // Is the buffer full?
653 BEQ R2, R23, flush
654 ret:
655 MOVV 184(R29), R1
656 MOVV 192(R29), R2
657 // Do the write.
658 MOVV R21, (R20)
659 RET
660
661 flush:
662 // Save all general purpose registers since these could be
663 // clobbered by wbBufFlush and were not saved by the caller.
664 MOVV R20, 8(R29) // Also first argument to wbBufFlush
665 MOVV R21, 16(R29) // Also second argument to wbBufFlush
666 // R1 already saved
667 // R2 already saved
668 MOVV R3, 24(R29)
669 MOVV R4, 32(R29)
670 MOVV R5, 40(R29)
671 MOVV R6, 48(R29)
672 MOVV R7, 56(R29)
673 MOVV R8, 64(R29)
674 MOVV R9, 72(R29)
675 MOVV R10, 80(R29)
676 MOVV R11, 88(R29)
677 MOVV R12, 96(R29)
678 MOVV R13, 104(R29)
679 MOVV R14, 112(R29)
680 MOVV R15, 120(R29)
681 MOVV R16, 128(R29)
682 MOVV R17, 136(R29)
683 MOVV R18, 144(R29)
684 MOVV R19, 152(R29)
685 // R20 already saved
686 // R21 already saved.
687 MOVV R22, 160(R29)
688 // R23 is tmp register.
689 MOVV R24, 168(R29)
690 MOVV R25, 176(R29)
691 // R26 is reserved by kernel.
692 // R27 is reserved by kernel.
693 // R28 is REGSB (not modified by Go code).
694 // R29 is SP.
695 // R30 is g.
696 // R31 is LR, which was saved by the prologue.
697
698 // This takes arguments R20 and R21.
699 CALL runtime·wbBufFlush(SB)
700
701 MOVV 8(R29), R20
702 MOVV 16(R29), R21
703 MOVV 24(R29), R3
704 MOVV 32(R29), R4
705 MOVV 40(R29), R5
706 MOVV 48(R29), R6
707 MOVV 56(R29), R7
708 MOVV 64(R29), R8
709 MOVV 72(R29), R9
710 MOVV 80(R29), R10
711 MOVV 88(R29), R11
712 MOVV 96(R29), R12
713 MOVV 104(R29), R13
714 MOVV 112(R29), R14
715 MOVV 120(R29), R15
716 MOVV 128(R29), R16
717 MOVV 136(R29), R17
718 MOVV 144(R29), R18
719 MOVV 152(R29), R19
720 MOVV 160(R29), R22
721 MOVV 168(R29), R24
722 MOVV 176(R29), R25
723 JMP ret
724
725 // Note: these functions use a special calling convention to save generated code space.
726 // Arguments are passed in registers, but the space for those arguments are allocated
727 // in the caller's stack frame. These stubs write the args into that stack space and
728 // then tail call to the corresponding runtime handler.
729 // The tail call makes these stubs disappear in backtraces.
730 TEXT runtime·panicIndex(SB),NOSPLIT,$0-16
731 MOVV R1, x+0(FP)
732 MOVV R2, y+8(FP)
733 JMP runtime·goPanicIndex(SB)
734 TEXT runtime·panicIndexU(SB),NOSPLIT,$0-16
735 MOVV R1, x+0(FP)
736 MOVV R2, y+8(FP)
737 JMP runtime·goPanicIndexU(SB)
738 TEXT runtime·panicSliceAlen(SB),NOSPLIT,$0-16
739 MOVV R2, x+0(FP)
740 MOVV R3, y+8(FP)
741 JMP runtime·goPanicSliceAlen(SB)
742 TEXT runtime·panicSliceAlenU(SB),NOSPLIT,$0-16
743 MOVV R2, x+0(FP)
744 MOVV R3, y+8(FP)
745 JMP runtime·goPanicSliceAlenU(SB)
746 TEXT runtime·panicSliceAcap(SB),NOSPLIT,$0-16
747 MOVV R2, x+0(FP)
748 MOVV R3, y+8(FP)
749 JMP runtime·goPanicSliceAcap(SB)
750 TEXT runtime·panicSliceAcapU(SB),NOSPLIT,$0-16
751 MOVV R2, x+0(FP)
752 MOVV R3, y+8(FP)
753 JMP runtime·goPanicSliceAcapU(SB)
754 TEXT runtime·panicSliceB(SB),NOSPLIT,$0-16
755 MOVV R1, x+0(FP)
756 MOVV R2, y+8(FP)
757 JMP runtime·goPanicSliceB(SB)
758 TEXT runtime·panicSliceBU(SB),NOSPLIT,$0-16
759 MOVV R1, x+0(FP)
760 MOVV R2, y+8(FP)
761 JMP runtime·goPanicSliceBU(SB)
762 TEXT runtime·panicSlice3Alen(SB),NOSPLIT,$0-16
763 MOVV R3, x+0(FP)
764 MOVV R4, y+8(FP)
765 JMP runtime·goPanicSlice3Alen(SB)
766 TEXT runtime·panicSlice3AlenU(SB),NOSPLIT,$0-16
767 MOVV R3, x+0(FP)
768 MOVV R4, y+8(FP)
769 JMP runtime·goPanicSlice3AlenU(SB)
770 TEXT runtime·panicSlice3Acap(SB),NOSPLIT,$0-16
771 MOVV R3, x+0(FP)
772 MOVV R4, y+8(FP)
773 JMP runtime·goPanicSlice3Acap(SB)
774 TEXT runtime·panicSlice3AcapU(SB),NOSPLIT,$0-16
775 MOVV R3, x+0(FP)
776 MOVV R4, y+8(FP)
777 JMP runtime·goPanicSlice3AcapU(SB)
778 TEXT runtime·panicSlice3B(SB),NOSPLIT,$0-16
779 MOVV R2, x+0(FP)
780 MOVV R3, y+8(FP)
781 JMP runtime·goPanicSlice3B(SB)
782 TEXT runtime·panicSlice3BU(SB),NOSPLIT,$0-16
783 MOVV R2, x+0(FP)
784 MOVV R3, y+8(FP)
785 JMP runtime·goPanicSlice3BU(SB)
786 TEXT runtime·panicSlice3C(SB),NOSPLIT,$0-16
787 MOVV R1, x+0(FP)
788 MOVV R2, y+8(FP)
789 JMP runtime·goPanicSlice3C(SB)
790 TEXT runtime·panicSlice3CU(SB),NOSPLIT,$0-16
791 MOVV R1, x+0(FP)
792 MOVV R2, y+8(FP)
793 JMP runtime·goPanicSlice3CU(SB)
794 TEXT runtime·panicSliceConvert(SB),NOSPLIT,$0-16
795 MOVV R3, x+0(FP)
796 MOVV R4, y+8(FP)
797 JMP runtime·goPanicSliceConvert(SB)
798
View as plain text