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