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