Text file
src/runtime/asm_loong64.s
1 // Copyright 2022 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 #include "go_asm.h"
6 #include "go_tls.h"
7 #include "funcdata.h"
8 #include "textflag.h"
9 #include "cgo/abi_loong64.h"
10
11 // When building with -buildmode=c-shared, this symbol is called when the shared
12 // library is loaded.
13 TEXT _rt0_loong64_lib(SB),NOSPLIT,$168
14 // Preserve callee-save registers.
15 SAVE_R22_TO_R31(3*8)
16 SAVE_F24_TO_F31(13*8)
17
18 // Initialize g as nil in case of using g later e.g. sigaction in cgo_sigaction.go
19 MOVV R0, g
20
21 MOVV R4, _rt0_loong64_lib_argc<>(SB)
22 MOVV R5, _rt0_loong64_lib_argv<>(SB)
23
24 MOVV $runtime·libInit(SB), R19
25 JAL (R19)
26
27 // Restore callee-save registers.
28 RESTORE_R22_TO_R31(3*8)
29 RESTORE_F24_TO_F31(13*8)
30 RET
31
32 TEXT runtime·rt0_lib_go<ABIInternal>(SB),NOSPLIT,$0
33 MOVV _rt0_loong64_lib_argc<>(SB), R4
34 MOVV _rt0_loong64_lib_argv<>(SB), R5
35 MOVV $runtime·rt0_go(SB),R19
36 JMP (R19)
37
38 DATA _rt0_loong64_lib_argc<>(SB)/8, $0
39 GLOBL _rt0_loong64_lib_argc<>(SB),NOPTR, $8
40 DATA _rt0_loong64_lib_argv<>(SB)/8, $0
41 GLOBL _rt0_loong64_lib_argv<>(SB),NOPTR, $8
42
43 #define REGCTXT R29
44
45 TEXT runtime·rt0_go(SB),NOSPLIT|TOPFRAME,$0
46 // R3 = stack; R4 = argc; R5 = argv
47
48 ADDV $-24, R3
49 MOVW R4, 8(R3) // argc
50 MOVV R5, 16(R3) // argv
51
52 // create istack out of the given (operating system) stack.
53 // _cgo_init may update stackguard.
54 MOVV $runtime·g0(SB), g
55 MOVV $(-64*1024), R30
56 ADDV R30, R3, R19
57 MOVV R19, g_stackguard0(g)
58 MOVV R19, g_stackguard1(g)
59 MOVV R19, (g_stack+stack_lo)(g)
60 MOVV R3, (g_stack+stack_hi)(g)
61
62 // if there is a _cgo_init, call it using the gcc ABI.
63 MOVV _cgo_init(SB), R25
64 BEQ R25, nocgo
65
66 MOVV R0, R7 // arg 3: not used
67 MOVV R0, R6 // arg 2: not used
68 MOVV $setg_gcc<>(SB), R5 // arg 1: setg
69 MOVV g, R4 // arg 0: G
70 JAL (R25)
71
72 nocgo:
73 JAL runtime·save_g(SB)
74 // update stackguard after _cgo_init
75 MOVV (g_stack+stack_lo)(g), R19
76 ADDV $const_stackGuard, R19
77 MOVV R19, g_stackguard0(g)
78 MOVV R19, g_stackguard1(g)
79
80 // set the per-goroutine and per-mach "registers"
81 MOVV $runtime·m0(SB), R19
82
83 // save m->g0 = g0
84 MOVV g, m_g0(R19)
85 // save m0 to g0->m
86 MOVV R19, g_m(g)
87
88 JAL runtime·check(SB)
89
90 // args are already prepared
91 JAL runtime·args(SB)
92 JAL runtime·osinit(SB)
93 JAL runtime·schedinit(SB)
94
95 // create a new goroutine to start program
96 MOVV $runtime·mainPC(SB), R19 // entry
97 ADDV $-16, R3
98 MOVV R19, 8(R3)
99 MOVV R0, 0(R3)
100 JAL runtime·newproc(SB)
101 ADDV $16, R3
102
103 // start this M
104 JAL runtime·mstart(SB)
105
106 // Prevent dead-code elimination of debugCallV2 and debugPinnerV1, which are
107 // intended to be called by debuggers.
108 MOVV $runtime·debugPinnerV1<ABIInternal>(SB), R0
109 MOVV $runtime·debugCallV2<ABIInternal>(SB), R0
110
111 MOVV R0, 1(R0)
112 RET
113
114 DATA runtime·mainPC+0(SB)/8,$runtime·main<ABIInternal>(SB)
115 GLOBL runtime·mainPC(SB),RODATA,$8
116
117 TEXT runtime·breakpoint(SB),NOSPLIT|NOFRAME,$0-0
118 BREAK
119 RET
120
121 TEXT runtime·asminit(SB),NOSPLIT|NOFRAME,$0-0
122 RET
123
124 TEXT runtime·mstart(SB),NOSPLIT|TOPFRAME,$0
125 JAL runtime·mstart0(SB)
126 RET // not reached
127
128 // func cputicks() int64
129 TEXT runtime·cputicks<ABIInternal>(SB),NOSPLIT,$0-8
130 RDTIMED R0, R4
131 RET
132
133 /*
134 * go-routine
135 */
136
137 // void gogo(Gobuf*)
138 // restore state from Gobuf; longjmp
139 TEXT runtime·gogo(SB), NOSPLIT|NOFRAME, $0-8
140 MOVV buf+0(FP), R4
141 MOVV gobuf_g(R4), R5
142 MOVV 0(R5), R0 // make sure g != nil
143 JMP gogo<>(SB)
144
145 TEXT gogo<>(SB), NOSPLIT|NOFRAME, $0
146 MOVV R5, g
147 JAL runtime·save_g(SB)
148
149 MOVV gobuf_sp(R4), R3
150 MOVV gobuf_lr(R4), R1
151 MOVV gobuf_ctxt(R4), REGCTXT
152 MOVV R0, gobuf_sp(R4)
153 MOVV R0, gobuf_lr(R4)
154 MOVV R0, gobuf_ctxt(R4)
155 MOVV gobuf_pc(R4), R6
156 JMP (R6)
157
158 // void mcall(fn func(*g))
159 // Switch to m->g0's stack, call fn(g).
160 // Fn must never return. It should gogo(&g->sched)
161 // to keep running g.
162 TEXT runtime·mcall<ABIInternal>(SB), NOSPLIT|NOFRAME, $0-8
163 MOVV R4, REGCTXT
164 // Save caller state in g->sched
165 MOVV R3, (g_sched+gobuf_sp)(g)
166 MOVV R1, (g_sched+gobuf_pc)(g)
167 MOVV R0, (g_sched+gobuf_lr)(g)
168
169 // Switch to m->g0 & its stack, call fn.
170 MOVV g, R4 // arg = g
171 MOVV g_m(g), R20
172 MOVV m_g0(R20), g
173 JAL runtime·save_g(SB)
174 BNE g, R4, 2(PC)
175 JMP runtime·badmcall(SB)
176 MOVV 0(REGCTXT), R20 // code pointer
177 MOVV (g_sched+gobuf_sp)(g), R3 // sp = m->g0->sched.sp
178 ADDV $-16, R3
179 MOVV R4, 8(R3)
180 MOVV R0, 0(R3)
181 JAL (R20)
182 JMP runtime·badmcall2(SB)
183
184 // systemstack_switch is a dummy routine that systemstack leaves at the bottom
185 // of the G stack. We need to distinguish the routine that
186 // lives at the bottom of the G stack from the one that lives
187 // at the top of the system stack because the one at the top of
188 // the system stack terminates the stack walk (see topofstack()).
189 TEXT runtime·systemstack_switch(SB), NOSPLIT, $0-0
190 UNDEF
191 JAL (R1) // make sure this function is not leaf
192 RET
193
194 // func systemstack(fn func())
195 TEXT runtime·systemstack(SB), NOSPLIT, $0-8
196 MOVV fn+0(FP), R19 // R19 = fn
197 MOVV R19, REGCTXT // context
198 MOVV g_m(g), R4 // R4 = m
199
200 MOVV m_gsignal(R4), R5 // R5 = gsignal
201 BEQ g, R5, noswitch
202
203 MOVV m_g0(R4), R5 // R5 = g0
204 BEQ g, R5, noswitch
205
206 MOVV m_curg(R4), R6
207 BEQ g, R6, switch
208
209 // Bad: g is not gsignal, not g0, not curg. What is it?
210 // Hide call from linker nosplit analysis.
211 MOVV $runtime·badsystemstack(SB), R7
212 JAL (R7)
213 JAL runtime·abort(SB)
214
215 switch:
216 // save our state in g->sched. Pretend to
217 // be systemstack_switch if the G stack is scanned.
218 JAL gosave_systemstack_switch<>(SB)
219
220 // switch to g0
221 MOVV R5, g
222 JAL runtime·save_g(SB)
223 MOVV (g_sched+gobuf_sp)(g), R19
224 MOVV R19, R3
225
226 // call target function
227 MOVV 0(REGCTXT), R6 // code pointer
228 JAL (R6)
229
230 // switch back to g
231 MOVV g_m(g), R4
232 MOVV m_curg(R4), g
233 JAL runtime·save_g(SB)
234 MOVV (g_sched+gobuf_sp)(g), R3
235 MOVV R0, (g_sched+gobuf_sp)(g)
236 RET
237
238 noswitch:
239 // already on m stack, just call directly
240 // Using a tail call here cleans up tracebacks since we won't stop
241 // at an intermediate systemstack.
242 MOVV 0(REGCTXT), R4 // code pointer
243 MOVV 0(R3), R1 // restore LR
244 ADDV $8, R3
245 JMP (R4)
246
247 // func switchToCrashStack0(fn func())
248 TEXT runtime·switchToCrashStack0<ABIInternal>(SB),NOSPLIT,$0-8
249 MOVV R4, REGCTXT // context register
250 MOVV g_m(g), R5 // curm
251
252 // set g to gcrash
253 MOVV $runtime·gcrash(SB), g // g = &gcrash
254 JAL runtime·save_g(SB)
255 MOVV R5, g_m(g) // g.m = curm
256 MOVV g, m_g0(R5) // curm.g0 = g
257
258 // switch to crashstack
259 MOVV (g_stack+stack_hi)(g), R5
260 ADDV $(-4*8), R5, R3
261
262 // call target function
263 MOVV 0(REGCTXT), R6
264 JAL (R6)
265
266 // should never return
267 JAL runtime·abort(SB)
268 UNDEF
269
270 /*
271 * support for morestack
272 */
273
274 // Called during function prolog when more stack is needed.
275 // Caller has already loaded:
276 // loong64: R31: LR
277 //
278 // The traceback routines see morestack on a g0 as being
279 // the top of a stack (for example, morestack calling newstack
280 // calling the scheduler calling newm calling gc), so we must
281 // record an argument size. For that purpose, it has no arguments.
282 TEXT runtime·morestack(SB),NOSPLIT|NOFRAME,$0-0
283 // Called from f.
284 // Set g->sched to context in f.
285 MOVV R3, (g_sched+gobuf_sp)(g)
286 MOVV R1, (g_sched+gobuf_pc)(g)
287 MOVV R31, (g_sched+gobuf_lr)(g)
288 MOVV REGCTXT, (g_sched+gobuf_ctxt)(g)
289
290 // Cannot grow scheduler stack (m->g0).
291 MOVV g_m(g), R7
292 MOVV m_g0(R7), R8
293 BNE g, R8, 3(PC)
294 JAL runtime·badmorestackg0(SB)
295 JAL runtime·abort(SB)
296
297 // Cannot grow signal stack (m->gsignal).
298 MOVV m_gsignal(R7), R8
299 BNE g, R8, 3(PC)
300 JAL runtime·badmorestackgsignal(SB)
301 JAL runtime·abort(SB)
302
303 // Called from f.
304 // Set m->morebuf to f's caller.
305 MOVV R31, (m_morebuf+gobuf_pc)(R7) // f's caller's PC
306 MOVV R3, (m_morebuf+gobuf_sp)(R7) // f's caller's SP
307 MOVV g, (m_morebuf+gobuf_g)(R7)
308
309 // Call newstack on m->g0's stack.
310 MOVV m_g0(R7), g
311 JAL runtime·save_g(SB)
312 MOVV (g_sched+gobuf_sp)(g), R3
313 // Create a stack frame on g0 to call newstack.
314 MOVV R0, -8(R3) // Zero saved LR in frame
315 ADDV $-8, R3
316 JAL runtime·newstack(SB)
317
318 // Not reached, but make sure the return PC from the call to newstack
319 // is still in this function, and not the beginning of the next.
320 UNDEF
321
322 TEXT runtime·morestack_noctxt(SB),NOSPLIT|NOFRAME,$0-0
323 // Force SPWRITE. This function doesn't actually write SP,
324 // but it is called with a special calling convention where
325 // the caller doesn't save LR on stack but passes it as a
326 // register (R5), and the unwinder currently doesn't understand.
327 // Make it SPWRITE to stop unwinding. (See issue 54332)
328 MOVV R3, R3
329
330 MOVV R0, REGCTXT
331 JMP runtime·morestack(SB)
332
333 // reflectcall: call a function with the given argument list
334 // func call(stackArgsType *_type, f *FuncVal, stackArgs *byte, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs).
335 // we don't have variable-sized frames, so we use a small number
336 // of constant-sized-frame functions to encode a few bits of size in the pc.
337 // Caution: ugly multiline assembly macros in your future!
338
339 #define DISPATCH(NAME,MAXSIZE) \
340 MOVV $MAXSIZE, R30; \
341 SGTU R19, R30, R30; \
342 BNE R30, 3(PC); \
343 MOVV $NAME(SB), R4; \
344 JMP (R4)
345 // Note: can't just "BR NAME(SB)" - bad inlining results.
346
347 TEXT ·reflectcall(SB), NOSPLIT|NOFRAME, $0-48
348 MOVWU frameSize+32(FP), R19
349 DISPATCH(runtime·call32, 32)
350 DISPATCH(runtime·call64, 64)
351 DISPATCH(runtime·call128, 128)
352 DISPATCH(runtime·call256, 256)
353 DISPATCH(runtime·call512, 512)
354 DISPATCH(runtime·call1024, 1024)
355 DISPATCH(runtime·call2048, 2048)
356 DISPATCH(runtime·call4096, 4096)
357 DISPATCH(runtime·call8192, 8192)
358 DISPATCH(runtime·call16384, 16384)
359 DISPATCH(runtime·call32768, 32768)
360 DISPATCH(runtime·call65536, 65536)
361 DISPATCH(runtime·call131072, 131072)
362 DISPATCH(runtime·call262144, 262144)
363 DISPATCH(runtime·call524288, 524288)
364 DISPATCH(runtime·call1048576, 1048576)
365 DISPATCH(runtime·call2097152, 2097152)
366 DISPATCH(runtime·call4194304, 4194304)
367 DISPATCH(runtime·call8388608, 8388608)
368 DISPATCH(runtime·call16777216, 16777216)
369 DISPATCH(runtime·call33554432, 33554432)
370 DISPATCH(runtime·call67108864, 67108864)
371 DISPATCH(runtime·call134217728, 134217728)
372 DISPATCH(runtime·call268435456, 268435456)
373 DISPATCH(runtime·call536870912, 536870912)
374 DISPATCH(runtime·call1073741824, 1073741824)
375 MOVV $runtime·badreflectcall(SB), R4
376 JMP (R4)
377
378 #define CALLFN(NAME,MAXSIZE) \
379 TEXT NAME(SB), WRAPPER, $MAXSIZE-48; \
380 NO_LOCAL_POINTERS; \
381 /* copy arguments to stack */ \
382 MOVV arg+16(FP), R4; \
383 MOVWU argsize+24(FP), R5; \
384 MOVV R3, R12; \
385 MOVV $16, R13; \
386 ADDV $8, R12; \
387 BLT R5, R13, check8; \
388 /* copy 16 bytes a time */ \
389 MOVBU internal∕cpu·Loong64+const_offsetLOONG64HasLSX(SB), R16; \
390 BEQ R16, copy16_again; \
391 loop16:; \
392 VMOVQ (R4), V0; \
393 ADDV $16, R4; \
394 ADDV $-16, R5; \
395 VMOVQ V0, (R12); \
396 ADDV $16, R12; \
397 BGE R5, R13, loop16; \
398 JMP check8; \
399 copy16_again:; \
400 MOVV (R4), R14; \
401 MOVV 8(R4), R15; \
402 ADDV $16, R4; \
403 ADDV $-16, R5; \
404 MOVV R14, (R12); \
405 MOVV R15, 8(R12); \
406 ADDV $16, R12; \
407 BGE R5, R13, copy16_again; \
408 check8:; \
409 /* R13 = 8 */; \
410 SRLV $1, R13; \
411 BLT R5, R13, 6(PC); \
412 /* copy 8 bytes a time */ \
413 MOVV (R4), R14; \
414 ADDV $8, R4; \
415 ADDV $-8, R5; \
416 MOVV R14, (R12); \
417 ADDV $8, R12; \
418 BEQ R5, R0, 7(PC); \
419 /* copy 1 byte a time for the rest */ \
420 MOVBU (R4), R14; \
421 ADDV $1, R4; \
422 ADDV $-1, R5; \
423 MOVBU R14, (R12); \
424 ADDV $1, R12; \
425 JMP -6(PC); \
426 /* set up argument registers */ \
427 MOVV regArgs+40(FP), R25; \
428 JAL ·unspillArgs(SB); \
429 /* call function */ \
430 MOVV f+8(FP), REGCTXT; \
431 MOVV (REGCTXT), R25; \
432 PCDATA $PCDATA_StackMapIndex, $0; \
433 JAL (R25); \
434 /* copy return values back */ \
435 MOVV regArgs+40(FP), R25; \
436 JAL ·spillArgs(SB); \
437 MOVV argtype+0(FP), R7; \
438 MOVV arg+16(FP), R4; \
439 MOVWU n+24(FP), R5; \
440 MOVWU retoffset+28(FP), R6; \
441 ADDV $8, R3, R12; \
442 ADDV R6, R12; \
443 ADDV R6, R4; \
444 SUBVU R6, R5; \
445 JAL callRet<>(SB); \
446 RET
447
448 // callRet copies return values back at the end of call*. This is a
449 // separate function so it can allocate stack space for the arguments
450 // to reflectcallmove. It does not follow the Go ABI; it expects its
451 // arguments in registers.
452 TEXT callRet<>(SB), NOSPLIT, $40-0
453 NO_LOCAL_POINTERS
454 MOVV R7, 8(R3)
455 MOVV R4, 16(R3)
456 MOVV R12, 24(R3)
457 MOVV R5, 32(R3)
458 MOVV R25, 40(R3)
459 JAL runtime·reflectcallmove(SB)
460 RET
461
462 CALLFN(·call16, 16)
463 CALLFN(·call32, 32)
464 CALLFN(·call64, 64)
465 CALLFN(·call128, 128)
466 CALLFN(·call256, 256)
467 CALLFN(·call512, 512)
468 CALLFN(·call1024, 1024)
469 CALLFN(·call2048, 2048)
470 CALLFN(·call4096, 4096)
471 CALLFN(·call8192, 8192)
472 CALLFN(·call16384, 16384)
473 CALLFN(·call32768, 32768)
474 CALLFN(·call65536, 65536)
475 CALLFN(·call131072, 131072)
476 CALLFN(·call262144, 262144)
477 CALLFN(·call524288, 524288)
478 CALLFN(·call1048576, 1048576)
479 CALLFN(·call2097152, 2097152)
480 CALLFN(·call4194304, 4194304)
481 CALLFN(·call8388608, 8388608)
482 CALLFN(·call16777216, 16777216)
483 CALLFN(·call33554432, 33554432)
484 CALLFN(·call67108864, 67108864)
485 CALLFN(·call134217728, 134217728)
486 CALLFN(·call268435456, 268435456)
487 CALLFN(·call536870912, 536870912)
488 CALLFN(·call1073741824, 1073741824)
489
490 TEXT runtime·procyieldAsm(SB),NOSPLIT,$0-0
491 RET
492
493 // Save state of caller into g->sched.
494 // but using fake PC from systemstack_switch.
495 // Must only be called from functions with no locals ($0)
496 // or else unwinding from systemstack_switch is incorrect.
497 // Smashes R19.
498 TEXT gosave_systemstack_switch<>(SB),NOSPLIT|NOFRAME,$0
499 MOVV $runtime·systemstack_switch(SB), R19
500 ADDV $8, R19
501 MOVV R19, (g_sched+gobuf_pc)(g)
502 MOVV R3, (g_sched+gobuf_sp)(g)
503 MOVV R0, (g_sched+gobuf_lr)(g)
504 // Assert ctxt is zero. See func save.
505 MOVV (g_sched+gobuf_ctxt)(g), R19
506 BEQ R19, 2(PC)
507 JAL runtime·abort(SB)
508 RET
509
510 // func asmcgocall(fn, arg unsafe.Pointer) int32
511 // Call fn(arg) on the scheduler stack,
512 // aligned appropriately for the gcc ABI.
513 // See cgocall.go for more details.
514 TEXT ·asmcgocall(SB),NOSPLIT,$0-20
515 MOVV fn+0(FP), R25
516 MOVV arg+8(FP), R4
517
518 MOVV R3, R12 // save original stack pointer
519 MOVV g, R13
520
521 // Figure out if we need to switch to m->g0 stack.
522 // We get called to create new OS threads too, and those
523 // come in on the m->g0 stack already.
524 BEQ g, R0, nosave
525 MOVV g_m(g), R5
526 MOVV m_gsignal(R5), R6
527 BEQ R6, g, g0
528 MOVV m_g0(R5), R6
529 BEQ R6, g, g0
530
531 JAL gosave_systemstack_switch<>(SB)
532 MOVV R6, g
533 JAL runtime·save_g(SB)
534 MOVV (g_sched+gobuf_sp)(g), R3
535
536 // Now on a scheduling stack (a pthread-created stack).
537 g0:
538 // Save room for two of our pointers.
539 ADDV $-16, R3
540 MOVV R13, 0(R3) // save old g on stack
541 MOVV (g_stack+stack_hi)(R13), R13
542 SUBVU R12, R13
543 MOVV R13, 8(R3) // save depth in old g stack (can't just save SP, as stack might be copied during a callback)
544 JAL (R25)
545
546 // Restore g, stack pointer. R4 is return value.
547 MOVV 0(R3), g
548 JAL runtime·save_g(SB)
549 MOVV (g_stack+stack_hi)(g), R5
550 MOVV 8(R3), R6
551 SUBVU R6, R5
552 MOVV R5, R3
553
554 MOVW R4, ret+16(FP)
555 RET
556
557 nosave:
558 // Running on a system stack, perhaps even without a g.
559 // Having no g can happen during thread creation or thread teardown.
560 MOVV fn+0(FP), R25
561 MOVV arg+8(FP), R4
562 MOVV R3, R12
563 ADDV $-16, R3
564 MOVV R0, 0(R3) // Where above code stores g, in case someone looks during debugging.
565 MOVV R12, 8(R3) // Save original stack pointer.
566 JAL (R25)
567 MOVV 8(R3), R3 // Restore stack pointer.
568 MOVW R4, ret+16(FP)
569 RET
570
571 // func asmcgocall_no_g(fn, arg unsafe.Pointer)
572 // Call fn(arg) aligned appropriately for the gcc ABI.
573 // Called on a system stack, and there may be no g yet.
574 TEXT ·asmcgocall_no_g(SB),NOSPLIT,$0-16
575 MOVV fn+0(FP), R25
576 MOVV arg+8(FP), R4
577 JAL (R25)
578 RET
579
580 // func cgocallback(fn, frame unsafe.Pointer, ctxt uintptr)
581 // See cgocall.go for more details.
582 TEXT ·cgocallback(SB),NOSPLIT,$24-24
583 NO_LOCAL_POINTERS
584
585 // Skip cgocallbackg, just dropm when fn is nil, and frame is the saved g.
586 // It is used to dropm while thread is exiting.
587 MOVV fn+0(FP), R5
588 BNE R5, loadg
589 // Restore the g from frame.
590 MOVV frame+8(FP), g
591 JMP dropm
592
593 loadg:
594 // Load m and g from thread-local storage.
595 MOVB runtime·iscgo(SB), R19
596 BEQ R19, nocgo
597 JAL runtime·load_g(SB)
598 nocgo:
599
600 // If g is nil, Go did not create the current thread,
601 // or if this thread never called into Go on pthread platforms.
602 // Call needm to obtain one for temporary use.
603 // In this case, we're running on the thread stack, so there's
604 // lots of space, but the linker doesn't know. Hide the call from
605 // the linker analysis by using an indirect call.
606 BEQ g, needm
607
608 MOVV g_m(g), R12
609 MOVV R12, savedm-8(SP)
610 JMP havem
611
612 needm:
613 MOVV g, savedm-8(SP) // g is zero, so is m.
614 MOVV $runtime·needAndBindM(SB), R4
615 JAL (R4)
616
617 // Set m->sched.sp = SP, so that if a panic happens
618 // during the function we are about to execute, it will
619 // have a valid SP to run on the g0 stack.
620 // The next few lines (after the havem label)
621 // will save this SP onto the stack and then write
622 // the same SP back to m->sched.sp. That seems redundant,
623 // but if an unrecovered panic happens, unwindm will
624 // restore the g->sched.sp from the stack location
625 // and then systemstack will try to use it. If we don't set it here,
626 // that restored SP will be uninitialized (typically 0) and
627 // will not be usable.
628 MOVV g_m(g), R12
629 MOVV m_g0(R12), R19
630 MOVV R3, (g_sched+gobuf_sp)(R19)
631
632 havem:
633 // Now there's a valid m, and we're running on its m->g0.
634 // Save current m->g0->sched.sp on stack and then set it to SP.
635 // Save current sp in m->g0->sched.sp in preparation for
636 // switch back to m->curg stack.
637 // NOTE: unwindm knows that the saved g->sched.sp is at 8(R29) aka savedsp-16(SP).
638 MOVV m_g0(R12), R19
639 MOVV (g_sched+gobuf_sp)(R19), R13
640 MOVV R13, savedsp-24(SP) // must match frame size
641 MOVV R3, (g_sched+gobuf_sp)(R19)
642
643 // Switch to m->curg stack and call runtime.cgocallbackg.
644 // Because we are taking over the execution of m->curg
645 // but *not* resuming what had been running, we need to
646 // save that information (m->curg->sched) so we can restore it.
647 // We can restore m->curg->sched.sp easily, because calling
648 // runtime.cgocallbackg leaves SP unchanged upon return.
649 // To save m->curg->sched.pc, we push it onto the stack.
650 // This has the added benefit that it looks to the traceback
651 // routine like cgocallbackg is going to return to that
652 // PC (because the frame we allocate below has the same
653 // size as cgocallback_gofunc's frame declared above)
654 // so that the traceback will seamlessly trace back into
655 // the earlier calls.
656 MOVV m_curg(R12), g
657 JAL runtime·save_g(SB)
658 MOVV (g_sched+gobuf_sp)(g), R13 // prepare stack as R13
659 MOVV (g_sched+gobuf_pc)(g), R4
660 MOVV R4, -(24+8)(R13) // "saved LR"; must match frame size
661 MOVV fn+0(FP), R5
662 MOVV frame+8(FP), R6
663 MOVV ctxt+16(FP), R7
664 MOVV $-(24+8)(R13), R3
665 MOVV R5, 8(R3)
666 MOVV R6, 16(R3)
667 MOVV R7, 24(R3)
668 JAL runtime·cgocallbackg(SB)
669
670 // Restore g->sched (== m->curg->sched) from saved values.
671 MOVV 0(R3), R4
672 MOVV R4, (g_sched+gobuf_pc)(g)
673 MOVV $(24+8)(R3), R13 // must match frame size
674 MOVV R13, (g_sched+gobuf_sp)(g)
675
676 // Switch back to m->g0's stack and restore m->g0->sched.sp.
677 // (Unlike m->curg, the g0 goroutine never uses sched.pc,
678 // so we do not have to restore it.)
679 MOVV g_m(g), R12
680 MOVV m_g0(R12), g
681 JAL runtime·save_g(SB)
682 MOVV (g_sched+gobuf_sp)(g), R3
683 MOVV savedsp-24(SP), R13 // must match frame size
684 MOVV R13, (g_sched+gobuf_sp)(g)
685
686 // If the m on entry was nil, we called needm above to borrow an m,
687 // 1. for the duration of the call on non-pthread platforms,
688 // 2. or the duration of the C thread alive on pthread platforms.
689 // If the m on entry wasn't nil,
690 // 1. the thread might be a Go thread,
691 // 2. or it wasn't the first call from a C thread on pthread platforms,
692 // since then we skip dropm to resue the m in the first call.
693 MOVV savedm-8(SP), R12
694 BNE R12, droppedm
695
696 // Skip dropm to reuse it in the next call, when a pthread key has been created.
697 MOVV _cgo_pthread_key_created(SB), R12
698 // It means cgo is disabled when _cgo_pthread_key_created is a nil pointer, need dropm.
699 BEQ R12, dropm
700 MOVV (R12), R12
701 BNE R12, droppedm
702
703 dropm:
704 MOVV $runtime·dropm(SB), R4
705 JAL (R4)
706 droppedm:
707
708 // Done!
709 RET
710
711 // void setg(G*); set g. for use by needm.
712 TEXT runtime·setg(SB), NOSPLIT, $0-8
713 MOVV gg+0(FP), g
714 // This only happens if iscgo, so jump straight to save_g
715 JAL runtime·save_g(SB)
716 RET
717
718 // void setg_gcc(G*); set g called from gcc with g in R4
719 TEXT setg_gcc<>(SB),NOSPLIT,$0-0
720 MOVV R4, g
721 JAL runtime·save_g(SB)
722 RET
723
724 TEXT runtime·abort(SB),NOSPLIT|NOFRAME,$0-0
725 MOVW (R0), R0
726 UNDEF
727
728 // AES hashing not implemented for loong64
729 TEXT runtime·memhash<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-32
730 JMP runtime·memhashFallback<ABIInternal>(SB)
731 TEXT runtime·strhash<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-24
732 JMP runtime·strhashFallback<ABIInternal>(SB)
733 TEXT runtime·memhash32<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-24
734 JMP runtime·memhash32Fallback<ABIInternal>(SB)
735 TEXT runtime·memhash64<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-24
736 JMP runtime·memhash64Fallback<ABIInternal>(SB)
737
738 // Called from cgo wrappers, this function returns g->m->curg.stack.hi.
739 // Must obey the gcc calling convention.
740 TEXT _cgo_topofstack(SB),NOSPLIT,$16
741 // g (R22) and REGTMP (R30) might be clobbered by load_g. They
742 // are callee-save in the gcc calling convention, so save them.
743 MOVV R30, savedREGTMP-16(SP)
744 MOVV g, savedG-8(SP)
745
746 JAL runtime·load_g(SB)
747 MOVV g_m(g), R19
748 MOVV m_curg(R19), R19
749 MOVV (g_stack+stack_hi)(R19), R4 // return value in R4
750
751 MOVV savedG-8(SP), g
752 MOVV savedREGTMP-16(SP), R30
753 RET
754
755 // The top-most function running on a goroutine
756 // returns to goexit+PCQuantum.
757 TEXT runtime·goexit(SB),NOSPLIT|NOFRAME|TOPFRAME,$0-0
758 NOOP
759 JAL runtime·goexit1(SB) // does not return
760 // traceback from goexit1 must hit code range of goexit
761 NOOP
762
763 // This is called from .init_array and follows the platform, not Go, ABI.
764 TEXT runtime·addmoduledata(SB),NOSPLIT,$0-0
765 ADDV $-0x10, R3
766 MOVV R30, 8(R3) // The access to global variables below implicitly uses R30, which is callee-save
767 MOVV runtime·lastmoduledatap(SB), R12
768 MOVV R4, moduledata_next(R12)
769 MOVV R4, runtime·lastmoduledatap(SB)
770 MOVV 8(R3), R30
771 ADDV $0x10, R3
772 RET
773
774 TEXT ·checkASM(SB),NOSPLIT,$0-1
775 MOVW $1, R19
776 MOVB R19, ret+0(FP)
777 RET
778
779 // spillArgs stores return values from registers to a *internal/abi.RegArgs in R25.
780 TEXT ·spillArgs(SB),NOSPLIT,$0-0
781 MOVV R4, (0*8)(R25)
782 MOVV R5, (1*8)(R25)
783 MOVV R6, (2*8)(R25)
784 MOVV R7, (3*8)(R25)
785 MOVV R8, (4*8)(R25)
786 MOVV R9, (5*8)(R25)
787 MOVV R10, (6*8)(R25)
788 MOVV R11, (7*8)(R25)
789 MOVV R12, (8*8)(R25)
790 MOVV R13, (9*8)(R25)
791 MOVV R14, (10*8)(R25)
792 MOVV R15, (11*8)(R25)
793 MOVV R16, (12*8)(R25)
794 MOVV R17, (13*8)(R25)
795 MOVV R18, (14*8)(R25)
796 MOVV R19, (15*8)(R25)
797 MOVD F0, (16*8)(R25)
798 MOVD F1, (17*8)(R25)
799 MOVD F2, (18*8)(R25)
800 MOVD F3, (19*8)(R25)
801 MOVD F4, (20*8)(R25)
802 MOVD F5, (21*8)(R25)
803 MOVD F6, (22*8)(R25)
804 MOVD F7, (23*8)(R25)
805 MOVD F8, (24*8)(R25)
806 MOVD F9, (25*8)(R25)
807 MOVD F10, (26*8)(R25)
808 MOVD F11, (27*8)(R25)
809 MOVD F12, (28*8)(R25)
810 MOVD F13, (29*8)(R25)
811 MOVD F14, (30*8)(R25)
812 MOVD F15, (31*8)(R25)
813 RET
814
815 // unspillArgs loads args into registers from a *internal/abi.RegArgs in R25.
816 TEXT ·unspillArgs(SB),NOSPLIT,$0-0
817 MOVV (0*8)(R25), R4
818 MOVV (1*8)(R25), R5
819 MOVV (2*8)(R25), R6
820 MOVV (3*8)(R25), R7
821 MOVV (4*8)(R25), R8
822 MOVV (5*8)(R25), R9
823 MOVV (6*8)(R25), R10
824 MOVV (7*8)(R25), R11
825 MOVV (8*8)(R25), R12
826 MOVV (9*8)(R25), R13
827 MOVV (10*8)(R25), R14
828 MOVV (11*8)(R25), R15
829 MOVV (12*8)(R25), R16
830 MOVV (13*8)(R25), R17
831 MOVV (14*8)(R25), R18
832 MOVV (15*8)(R25), R19
833 MOVD (16*8)(R25), F0
834 MOVD (17*8)(R25), F1
835 MOVD (18*8)(R25), F2
836 MOVD (19*8)(R25), F3
837 MOVD (20*8)(R25), F4
838 MOVD (21*8)(R25), F5
839 MOVD (22*8)(R25), F6
840 MOVD (23*8)(R25), F7
841 MOVD (24*8)(R25), F8
842 MOVD (25*8)(R25), F9
843 MOVD (26*8)(R25), F10
844 MOVD (27*8)(R25), F11
845 MOVD (28*8)(R25), F12
846 MOVD (29*8)(R25), F13
847 MOVD (30*8)(R25), F14
848 MOVD (31*8)(R25), F15
849 RET
850
851 // gcWriteBarrier informs the GC about heap pointer writes.
852 //
853 // gcWriteBarrier does NOT follow the Go ABI. It accepts the
854 // number of bytes of buffer needed in R29, and returns a pointer
855 // to the buffer space in R29.
856 // It clobbers R30 (the linker temp register).
857 // The act of CALLing gcWriteBarrier will clobber R1 (LR).
858 // It does not clobber any other general-purpose registers,
859 // but may clobber others (e.g., floating point registers).
860 TEXT gcWriteBarrier<>(SB),NOSPLIT,$216
861 // Save the registers clobbered by the fast path.
862 MOVV R19, 208(R3)
863 MOVV R13, 216(R3)
864 retry:
865 MOVV g_m(g), R19
866 MOVV m_p(R19), R19
867 MOVV (p_wbBuf+wbBuf_next)(R19), R13
868 MOVV (p_wbBuf+wbBuf_end)(R19), R30 // R30 is linker temp register
869 // Increment wbBuf.next position.
870 ADDV R29, R13
871 // Is the buffer full?
872 BLTU R30, R13, flush
873 // Commit to the larger buffer.
874 MOVV R13, (p_wbBuf+wbBuf_next)(R19)
875 // Make return value (the original next position)
876 SUBV R29, R13, R29
877 // Restore registers.
878 MOVV 208(R3), R19
879 MOVV 216(R3), R13
880 RET
881
882 flush:
883 // Save all general purpose registers since these could be
884 // clobbered by wbBufFlush and were not saved by the caller.
885 MOVV R27, 8(R3)
886 MOVV R28, 16(R3)
887 // R1 is LR, which was saved by the prologue.
888 MOVV R2, 24(R3)
889 // R3 is SP.
890 MOVV R4, 32(R3)
891 MOVV R5, 40(R3)
892 MOVV R6, 48(R3)
893 MOVV R7, 56(R3)
894 MOVV R8, 64(R3)
895 MOVV R9, 72(R3)
896 MOVV R10, 80(R3)
897 MOVV R11, 88(R3)
898 MOVV R12, 96(R3)
899 // R13 already saved
900 MOVV R14, 104(R3)
901 MOVV R15, 112(R3)
902 MOVV R16, 120(R3)
903 MOVV R17, 128(R3)
904 MOVV R18, 136(R3)
905 // R19 already saved
906 MOVV R20, 144(R3)
907 MOVV R21, 152(R3)
908 // R22 is g.
909 MOVV R23, 160(R3)
910 MOVV R24, 168(R3)
911 MOVV R25, 176(R3)
912 MOVV R26, 184(R3)
913 // R27 already saved
914 // R28 already saved.
915 MOVV R29, 192(R3)
916 // R30 is tmp register.
917 MOVV R31, 200(R3)
918
919 CALL runtime·wbBufFlush(SB)
920
921 MOVV 8(R3), R27
922 MOVV 16(R3), R28
923 MOVV 24(R3), R2
924 MOVV 32(R3), R4
925 MOVV 40(R3), R5
926 MOVV 48(R3), R6
927 MOVV 56(R3), R7
928 MOVV 64(R3), R8
929 MOVV 72(R3), R9
930 MOVV 80(R3), R10
931 MOVV 88(R3), R11
932 MOVV 96(R3), R12
933 MOVV 104(R3), R14
934 MOVV 112(R3), R15
935 MOVV 120(R3), R16
936 MOVV 128(R3), R17
937 MOVV 136(R3), R18
938 MOVV 144(R3), R20
939 MOVV 152(R3), R21
940 MOVV 160(R3), R23
941 MOVV 168(R3), R24
942 MOVV 176(R3), R25
943 MOVV 184(R3), R26
944 MOVV 192(R3), R29
945 MOVV 200(R3), R31
946 JMP retry
947
948 TEXT runtime·gcWriteBarrier1<ABIInternal>(SB),NOSPLIT,$0
949 MOVV $8, R29
950 JMP gcWriteBarrier<>(SB)
951 TEXT runtime·gcWriteBarrier2<ABIInternal>(SB),NOSPLIT,$0
952 MOVV $16, R29
953 JMP gcWriteBarrier<>(SB)
954 TEXT runtime·gcWriteBarrier3<ABIInternal>(SB),NOSPLIT,$0
955 MOVV $24, R29
956 JMP gcWriteBarrier<>(SB)
957 TEXT runtime·gcWriteBarrier4<ABIInternal>(SB),NOSPLIT,$0
958 MOVV $32, R29
959 JMP gcWriteBarrier<>(SB)
960 TEXT runtime·gcWriteBarrier5<ABIInternal>(SB),NOSPLIT,$0
961 MOVV $40, R29
962 JMP gcWriteBarrier<>(SB)
963 TEXT runtime·gcWriteBarrier6<ABIInternal>(SB),NOSPLIT,$0
964 MOVV $48, R29
965 JMP gcWriteBarrier<>(SB)
966 TEXT runtime·gcWriteBarrier7<ABIInternal>(SB),NOSPLIT,$0
967 MOVV $56, R29
968 JMP gcWriteBarrier<>(SB)
969 TEXT runtime·gcWriteBarrier8<ABIInternal>(SB),NOSPLIT,$0
970 MOVV $64, R29
971 JMP gcWriteBarrier<>(SB)
972
973 DATA debugCallFrameTooLarge<>+0x00(SB)/20, $"call frame too large"
974 GLOBL debugCallFrameTooLarge<>(SB), RODATA, $20 // Size duplicated below
975
976 // debugCallV2 is the entry point for debugger-injected function
977 // calls on running goroutines. It informs the runtime that a
978 // debug call has been injected and creates a call frame for the
979 // debugger to fill in.
980 //
981 // To inject a function call, a debugger should:
982 // 1. Check that the goroutine is in state _Grunning and that
983 // there are at least 280 bytes free on the stack.
984 // 2. Set SP as SP-8.
985 // 3. Store the current LR in (SP) (using the SP after step 2).
986 // 4. Store the current PC in the LR register.
987 // 5. Write the desired argument frame size at SP-8
988 // 6. Save all machine registers so they can be restored later by the debugger.
989 // 7. Set the PC to debugCallV2 and resume execution.
990 //
991 // If the goroutine is in state _Grunnable, then it's not generally
992 // safe to inject a call because it may return out via other runtime
993 // operations. Instead, the debugger should unwind the stack to find
994 // the return to non-runtime code, add a temporary breakpoint there,
995 // and inject the call once that breakpoint is hit.
996 //
997 // If the goroutine is in any other state, it's not safe to inject a call.
998 //
999 // This function communicates back to the debugger by setting R19 and
1000 // invoking BREAK to raise a breakpoint signal. Note that the signal PC of
1001 // the signal triggered by the BREAK instruction is the PC where the signal
1002 // is trapped, not the next PC, so to resume execution, the debugger needs
1003 // to set the signal PC to PC+4. See the comments in the implementation for
1004 // the protocol the debugger is expected to follow. InjectDebugCall in the
1005 // runtime tests demonstrates this protocol.
1006 //
1007 // The debugger must ensure that any pointers passed to the function
1008 // obey escape analysis requirements. Specifically, it must not pass
1009 // a stack pointer to an escaping argument. debugCallV2 cannot check
1010 // this invariant.
1011 //
1012 // This is ABIInternal because Go code injects its PC directly into new
1013 // goroutine stacks.
1014 TEXT runtime·debugCallV2<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-0
1015 MOVV R1, -272(R3)
1016 ADDV $-272, R3
1017
1018 // We can't do anything that might clobber any of these
1019 // registers before this.
1020 MOVV R2, (4*8)(R3)
1021 MOVV R4, (5*8)(R3)
1022 MOVV R5, (6*8)(R3)
1023 MOVV R6, (7*8)(R3)
1024 MOVV R7, (8*8)(R3)
1025 MOVV R8, (9*8)(R3)
1026 MOVV R9, (10*8)(R3)
1027 MOVV R10, (11*8)(R3)
1028 MOVV R11, (12*8)(R3)
1029 MOVV R12, (13*8)(R3)
1030 MOVV R13, (14*8)(R3)
1031 MOVV R14, (15*8)(R3)
1032 MOVV R15, (16*8)(R3)
1033 MOVV R16, (17*8)(R3)
1034 MOVV R17, (18*8)(R3)
1035 MOVV R18, (19*8)(R3)
1036 MOVV R19, (20*8)(R3)
1037 MOVV R20, (21*8)(R3)
1038 MOVV R21, (22*8)(R3)
1039 MOVV g, (23*8)(R3)
1040 MOVV R23, (24*8)(R3)
1041 MOVV R24, (25*8)(R3)
1042 MOVV R25, (26*8)(R3)
1043 MOVV R26, (27*8)(R3)
1044 MOVV R27, (28*8)(R3)
1045 MOVV R28, (29*8)(R3)
1046 MOVV R29, (30*8)(R3)
1047 MOVV R30, (31*8)(R3)
1048 MOVV R31, (32*8)(R3)
1049
1050 // Perform a safe-point check.
1051 MOVV R1, 8(R3)
1052 CALL runtime·debugCallCheck(SB)
1053 MOVV 16(R3), R30
1054 BEQ R30, good
1055
1056 // The safety check failed. Put the reason string at the top
1057 // of the stack.
1058 MOVV R30, 8(R3)
1059
1060 MOVV 24(R3), R30
1061 MOVV R30, 16(R3)
1062
1063 MOVV $8, R19
1064 BREAK
1065 JMP restore
1066
1067 good:
1068 // Registers are saved and it's safe to make a call.
1069 // Open up a call frame, moving the stack if necessary.
1070 //
1071 // Once the frame is allocated, this will set R19 to 0 and
1072 // invoke BREAK. The debugger should write the argument
1073 // frame for the call at SP+8, set up argument registers,
1074 // set the LR as the signal PC + 4, set the PC to the function
1075 // to call, set R29 to point to the closure (if a closure call),
1076 // and resume execution.
1077 //
1078 // If the function returns, this will set R19 to 1 and invoke
1079 // BREAK. The debugger can then inspect any return value saved
1080 // on the stack at SP+8 and in registers. To resume execution,
1081 // the debugger should restore the LR from (SP).
1082 //
1083 // If the function panics, this will set R19 to 2 and invoke BREAK.
1084 // The interface{} value of the panic will be at SP+8. The debugger
1085 // can inspect the panic value and resume execution again.
1086 #define DEBUG_CALL_DISPATCH(NAME,MAXSIZE) \
1087 MOVV $MAXSIZE, R27; \
1088 BLT R27, R30, 5(PC); \
1089 MOVV $NAME(SB), R28; \
1090 MOVV R28, 8(R3); \
1091 CALL runtime·debugCallWrap(SB); \
1092 JMP restore
1093
1094 MOVV 264(R3), R30 // the argument frame size
1095 DEBUG_CALL_DISPATCH(debugCall32<>, 32)
1096 DEBUG_CALL_DISPATCH(debugCall64<>, 64)
1097 DEBUG_CALL_DISPATCH(debugCall128<>, 128)
1098 DEBUG_CALL_DISPATCH(debugCall256<>, 256)
1099 DEBUG_CALL_DISPATCH(debugCall512<>, 512)
1100 DEBUG_CALL_DISPATCH(debugCall1024<>, 1024)
1101 DEBUG_CALL_DISPATCH(debugCall2048<>, 2048)
1102 DEBUG_CALL_DISPATCH(debugCall4096<>, 4096)
1103 DEBUG_CALL_DISPATCH(debugCall8192<>, 8192)
1104 DEBUG_CALL_DISPATCH(debugCall16384<>, 16384)
1105 DEBUG_CALL_DISPATCH(debugCall32768<>, 32768)
1106 DEBUG_CALL_DISPATCH(debugCall65536<>, 65536)
1107 // The frame size is too large. Report the error.
1108 MOVV $debugCallFrameTooLarge<>(SB), R30
1109 MOVV R30, 8(R3)
1110 MOVV $20, R30
1111 MOVV R30, 16(R3) // length of debugCallFrameTooLarge string
1112 MOVV $8, R19
1113 BREAK
1114 JMP restore
1115
1116 restore:
1117 // Calls and failures resume here.
1118 //
1119 // Set R19 to 16 and invoke BREAK. The debugger should restore
1120 // all registers except for PC and SP and resume execution.
1121 MOVV $16, R19
1122 BREAK
1123 // We must not modify flags after this point.
1124
1125 // Restore pointer-containing registers, which may have been
1126 // modified from the debugger's copy by stack copying.
1127 MOVV (4*8)(R3), R2
1128 MOVV (5*8)(R3), R4
1129 MOVV (6*8)(R3), R5
1130 MOVV (7*8)(R3), R6
1131 MOVV (8*8)(R3), R7
1132 MOVV (9*8)(R3), R8
1133 MOVV (10*8)(R3), R9
1134 MOVV (11*8)(R3), R10
1135 MOVV (12*8)(R3), R11
1136 MOVV (13*8)(R3), R12
1137 MOVV (14*8)(R3), R13
1138 MOVV (15*8)(R3), R14
1139 MOVV (16*8)(R3), R15
1140 MOVV (17*8)(R3), R16
1141 MOVV (18*8)(R3), R17
1142 MOVV (19*8)(R3), R18
1143 MOVV (20*8)(R3), R19
1144 MOVV (21*8)(R3), R20
1145 MOVV (22*8)(R3), R21
1146 MOVV (23*8)(R3), g
1147 MOVV (24*8)(R3), R23
1148 MOVV (25*8)(R3), R24
1149 MOVV (26*8)(R3), R25
1150 MOVV (27*8)(R3), R26
1151 MOVV (28*8)(R3), R27
1152 MOVV (29*8)(R3), R28
1153 MOVV (30*8)(R3), R29
1154 MOVV (31*8)(R3), R30
1155 MOVV (32*8)(R3), R31
1156
1157 MOVV 0(R3), R30
1158 ADDV $280, R3 // Add 8 more bytes, see saveSigContext
1159 MOVV -8(R3), R1
1160 JMP (R30)
1161
1162 // runtime.debugCallCheck assumes that functions defined with the
1163 // DEBUG_CALL_FN macro are safe points to inject calls.
1164 #define DEBUG_CALL_FN(NAME,MAXSIZE) \
1165 TEXT NAME(SB),WRAPPER,$MAXSIZE-0; \
1166 NO_LOCAL_POINTERS; \
1167 MOVV $0, R19; \
1168 BREAK; \
1169 MOVV $1, R19; \
1170 BREAK; \
1171 RET
1172 DEBUG_CALL_FN(debugCall32<>, 32)
1173 DEBUG_CALL_FN(debugCall64<>, 64)
1174 DEBUG_CALL_FN(debugCall128<>, 128)
1175 DEBUG_CALL_FN(debugCall256<>, 256)
1176 DEBUG_CALL_FN(debugCall512<>, 512)
1177 DEBUG_CALL_FN(debugCall1024<>, 1024)
1178 DEBUG_CALL_FN(debugCall2048<>, 2048)
1179 DEBUG_CALL_FN(debugCall4096<>, 4096)
1180 DEBUG_CALL_FN(debugCall8192<>, 8192)
1181 DEBUG_CALL_FN(debugCall16384<>, 16384)
1182 DEBUG_CALL_FN(debugCall32768<>, 32768)
1183 DEBUG_CALL_FN(debugCall65536<>, 65536)
1184
1185 // func debugCallPanicked(val interface{})
1186 TEXT runtime·debugCallPanicked(SB),NOSPLIT,$16-16
1187 // Copy the panic value to the top of stack at SP+8.
1188 MOVV val_type+0(FP), R30
1189 MOVV R30, 8(R3)
1190 MOVV val_data+8(FP), R30
1191 MOVV R30, 16(R3)
1192 MOVV $2, R19
1193 BREAK
1194 RET
1195
1196 TEXT runtime·panicBounds<ABIInternal>(SB),NOSPLIT,$144-0
1197 NO_LOCAL_POINTERS
1198 // Save all 16 int registers that could have an index in them.
1199 // They may be pointers, but if they are they are dead.
1200 // Skip R0 aka ZERO, R1 aka LR, R2 aka thread pointer, R3 aka SP.
1201 MOVV R4, 24(R3)
1202 MOVV R5, 32(R3)
1203 MOVV R6, 40(R3)
1204 MOVV R7, 48(R3)
1205 MOVV R8, 56(R3)
1206 MOVV R9, 64(R3)
1207 MOVV R10, 72(R3)
1208 MOVV R11, 80(R3)
1209 MOVV R12, 88(R3)
1210 MOVV R13, 96(R3)
1211 MOVV R14, 104(R3)
1212 MOVV R15, 112(R3)
1213 MOVV R16, 120(R3)
1214 MOVV R17, 128(R3)
1215 MOVV R18, 136(R3)
1216 MOVV R19, 144(R3)
1217
1218 MOVV R1, R4 // PC immediately after call to panicBounds
1219 ADDV $24, R3, R5 // pointer to save area
1220 CALL runtime·panicBounds64<ABIInternal>(SB)
1221 RET
1222
View as plain text