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