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