Text file
src/runtime/asm_ppc64x.s
Documentation: runtime
1// Copyright 2014 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5//go:build ppc64 || ppc64le
6
7#include "go_asm.h"
8#include "go_tls.h"
9#include "funcdata.h"
10#include "textflag.h"
11#include "asm_ppc64x.h"
12
13#ifdef GOOS_aix
14#define cgoCalleeStackSize 48
15#else
16#define cgoCalleeStackSize 32
17#endif
18
19TEXT runtime·rt0_go(SB),NOSPLIT|TOPFRAME,$0
20 // R1 = stack; R3 = argc; R4 = argv; R13 = C TLS base pointer
21
22 // initialize essential registers
23 BL runtime·reginit(SB)
24
25 SUB $(FIXED_FRAME+16), R1
26 MOVD R2, 24(R1) // stash the TOC pointer away again now we've created a new frame
27 MOVW R3, FIXED_FRAME+0(R1) // argc
28 MOVD R4, FIXED_FRAME+8(R1) // argv
29
30 // create istack out of the given (operating system) stack.
31 // _cgo_init may update stackguard.
32 MOVD $runtime·g0(SB), g
33 BL runtime·save_g(SB)
34 MOVD $(-64*1024), R31
35 ADD R31, R1, R3
36 MOVD R3, g_stackguard0(g)
37 MOVD R3, g_stackguard1(g)
38 MOVD R3, (g_stack+stack_lo)(g)
39 MOVD R1, (g_stack+stack_hi)(g)
40
41 // If there is a _cgo_init, call it using the gcc ABI.
42 MOVD _cgo_init(SB), R12
43 CMP R12, $0
44 BEQ nocgo
45
46#ifdef GO_PPC64X_HAS_FUNCDESC
47 // Load the real entry address from the first slot of the function descriptor.
48 MOVD 8(R12), R2
49 MOVD (R12), R12
50#endif
51 MOVD R12, CTR // r12 = "global function entry point"
52 MOVD R13, R5 // arg 2: TLS base pointer
53 MOVD $setg_gcc<>(SB), R4 // arg 1: setg
54 MOVD g, R3 // arg 0: G
55 // C functions expect 32 (48 for AIX) bytes of space on caller
56 // stack frame and a 16-byte aligned R1
57 MOVD R1, R14 // save current stack
58 SUB $cgoCalleeStackSize, R1 // reserve the callee area
59 RLDCR $0, R1, $~15, R1 // 16-byte align
60 BL (CTR) // may clobber R0, R3-R12
61 MOVD R14, R1 // restore stack
62#ifndef GOOS_aix
63 MOVD 24(R1), R2
64#endif
65 XOR R0, R0 // fix R0
66
67nocgo:
68 // update stackguard after _cgo_init
69 MOVD (g_stack+stack_lo)(g), R3
70 ADD $const_stackGuard, R3
71 MOVD R3, g_stackguard0(g)
72 MOVD R3, g_stackguard1(g)
73
74 // set the per-goroutine and per-mach "registers"
75 MOVD $runtime·m0(SB), R3
76
77 // save m->g0 = g0
78 MOVD g, m_g0(R3)
79 // save m0 to g0->m
80 MOVD R3, g_m(g)
81
82 BL runtime·check(SB)
83
84 // args are already prepared
85 BL runtime·args(SB)
86 BL runtime·osinit(SB)
87 BL runtime·schedinit(SB)
88
89 // create a new goroutine to start program
90 MOVD $runtime·mainPC(SB), R3 // entry
91 MOVDU R3, -8(R1)
92 MOVDU R0, -8(R1)
93 MOVDU R0, -8(R1)
94 MOVDU R0, -8(R1)
95 MOVDU R0, -8(R1)
96 BL runtime·newproc(SB)
97 ADD $(8+FIXED_FRAME), R1
98
99 // start this M
100 BL runtime·mstart(SB)
101 // Prevent dead-code elimination of debugCallV2 and debugPinnerV1, which are
102 // intended to be called by debuggers.
103#ifdef GOARCH_ppc64le
104 MOVD $runtime·debugPinnerV1<ABIInternal>(SB), R31
105 MOVD $runtime·debugCallV2<ABIInternal>(SB), R31
106#endif
107 MOVD R0, 0(R0)
108 RET
109
110DATA runtime·mainPC+0(SB)/8,$runtime·main<ABIInternal>(SB)
111GLOBL runtime·mainPC(SB),RODATA,$8
112
113TEXT runtime·breakpoint(SB),NOSPLIT|NOFRAME,$0-0
114 TW $31, R0, R0
115 RET
116
117TEXT runtime·asminit(SB),NOSPLIT|NOFRAME,$0-0
118 RET
119
120// Any changes must be reflected to runtime/cgo/gcc_aix_ppc64.S:.crosscall_ppc64
121TEXT _cgo_reginit(SB),NOSPLIT|NOFRAME,$0-0
122 // crosscall_ppc64 and crosscall2 need to reginit, but can't
123 // get at the 'runtime.reginit' symbol.
124 BR runtime·reginit(SB)
125
126TEXT runtime·reginit(SB),NOSPLIT|NOFRAME,$0-0
127 // set R0 to zero, it's expected by the toolchain
128 XOR R0, R0
129 RET
130
131TEXT runtime·mstart(SB),NOSPLIT|TOPFRAME,$0
132 BL runtime·mstart0(SB)
133 RET // not reached
134
135/*
136 * go-routine
137 */
138
139// void gogo(Gobuf*)
140// restore state from Gobuf; longjmp
141TEXT runtime·gogo(SB), NOSPLIT|NOFRAME, $0-8
142 MOVD buf+0(FP), R5
143 MOVD gobuf_g(R5), R6
144 MOVD 0(R6), R4 // make sure g != nil
145 BR gogo<>(SB)
146
147TEXT gogo<>(SB), NOSPLIT|NOFRAME, $0
148 MOVD R6, g
149 BL runtime·save_g(SB)
150
151 MOVD gobuf_sp(R5), R1
152 MOVD gobuf_lr(R5), R31
153#ifndef GOOS_aix
154 MOVD 24(R1), R2 // restore R2
155#endif
156 MOVD R31, LR
157 MOVD gobuf_ret(R5), R3
158 MOVD gobuf_ctxt(R5), R11
159 MOVD R0, gobuf_sp(R5)
160 MOVD R0, gobuf_ret(R5)
161 MOVD R0, gobuf_lr(R5)
162 MOVD R0, gobuf_ctxt(R5)
163 CMP R0, R0 // set condition codes for == test, needed by stack split
164 MOVD gobuf_pc(R5), R12
165 MOVD R12, CTR
166 BR (CTR)
167
168// void mcall(fn func(*g))
169// Switch to m->g0's stack, call fn(g).
170// Fn must never return. It should gogo(&g->sched)
171// to keep running g.
172TEXT runtime·mcall<ABIInternal>(SB), NOSPLIT|NOFRAME, $0-8
173 // Save caller state in g->sched
174 // R11 should be safe across save_g??
175 MOVD R3, R11
176 MOVD R1, (g_sched+gobuf_sp)(g)
177 MOVD LR, R31
178 MOVD R31, (g_sched+gobuf_pc)(g)
179 MOVD R0, (g_sched+gobuf_lr)(g)
180
181 // Switch to m->g0 & its stack, call fn.
182 MOVD g, R3
183 MOVD g_m(g), R8
184 MOVD m_g0(R8), g
185 BL runtime·save_g(SB)
186 CMP g, R3
187 BNE 2(PC)
188 BR runtime·badmcall(SB)
189 MOVD 0(R11), R12 // code pointer
190 MOVD R12, CTR
191 MOVD (g_sched+gobuf_sp)(g), R1 // sp = m->g0->sched.sp
192 // Don't need to do anything special for regabiargs here
193 // R3 is g; stack is set anyway
194 MOVDU R3, -8(R1)
195 MOVDU R0, -8(R1)
196 MOVDU R0, -8(R1)
197 MOVDU R0, -8(R1)
198 MOVDU R0, -8(R1)
199 BL (CTR)
200 MOVD 24(R1), R2
201 BR runtime·badmcall2(SB)
202
203// systemstack_switch is a dummy routine that systemstack leaves at the bottom
204// of the G stack. We need to distinguish the routine that
205// lives at the bottom of the G stack from the one that lives
206// at the top of the system stack because the one at the top of
207// the system stack terminates the stack walk (see topofstack()).
208TEXT runtime·systemstack_switch(SB), NOSPLIT, $0-0
209 // We have several undefs here so that 16 bytes past
210 // $runtime·systemstack_switch lies within them whether or not the
211 // instructions that derive r2 from r12 are there.
212 UNDEF
213 UNDEF
214 UNDEF
215 BL (LR) // make sure this function is not leaf
216 RET
217
218// func systemstack(fn func())
219TEXT runtime·systemstack(SB), NOSPLIT, $0-8
220 MOVD fn+0(FP), R3 // R3 = fn
221 MOVD R3, R11 // context
222 MOVD g_m(g), R4 // R4 = m
223
224 MOVD m_gsignal(R4), R5 // R5 = gsignal
225 CMP g, R5
226 BEQ noswitch
227
228 MOVD m_g0(R4), R5 // R5 = g0
229 CMP g, R5
230 BEQ noswitch
231
232 MOVD m_curg(R4), R6
233 CMP g, R6
234 BEQ switch
235
236 // Bad: g is not gsignal, not g0, not curg. What is it?
237 // Hide call from linker nosplit analysis.
238 MOVD $runtime·badsystemstack(SB), R12
239 MOVD R12, CTR
240 BL (CTR)
241 BL runtime·abort(SB)
242
243switch:
244 // save our state in g->sched. Pretend to
245 // be systemstack_switch if the G stack is scanned.
246 BL gosave_systemstack_switch<>(SB)
247
248 // switch to g0
249 MOVD R5, g
250 BL runtime·save_g(SB)
251 MOVD (g_sched+gobuf_sp)(g), R1
252
253 // call target function
254 MOVD 0(R11), R12 // code pointer
255 MOVD R12, CTR
256 BL (CTR)
257
258 // restore TOC pointer. It seems unlikely that we will use systemstack
259 // to call a function defined in another module, but the results of
260 // doing so would be so confusing that it's worth doing this.
261 MOVD g_m(g), R3
262 MOVD m_curg(R3), g
263 MOVD (g_sched+gobuf_sp)(g), R3
264#ifndef GOOS_aix
265 MOVD 24(R3), R2
266#endif
267 // switch back to g
268 MOVD g_m(g), R3
269 MOVD m_curg(R3), g
270 BL runtime·save_g(SB)
271 MOVD (g_sched+gobuf_sp)(g), R1
272 MOVD R0, (g_sched+gobuf_sp)(g)
273 RET
274
275noswitch:
276 // already on m stack, just call directly
277 // On other arches we do a tail call here, but it appears to be
278 // impossible to tail call a function pointer in shared mode on
279 // ppc64 because the caller is responsible for restoring the TOC.
280 MOVD 0(R11), R12 // code pointer
281 MOVD R12, CTR
282 BL (CTR)
283#ifndef GOOS_aix
284 MOVD 24(R1), R2
285#endif
286 RET
287
288// func switchToCrashStack0(fn func())
289TEXT runtime·switchToCrashStack0<ABIInternal>(SB), NOSPLIT, $0-8
290 MOVD R3, R11 // context register
291 MOVD g_m(g), R3 // curm
292
293 // set g to gcrash
294 MOVD $runtime·gcrash(SB), g // g = &gcrash
295 CALL runtime·save_g(SB) // clobbers R31
296 MOVD R3, g_m(g) // g.m = curm
297 MOVD g, m_g0(R3) // curm.g0 = g
298
299 // switch to crashstack
300 MOVD (g_stack+stack_hi)(g), R3
301 SUB $(4*8), R3
302 MOVD R3, R1
303
304 // call target function
305 MOVD 0(R11), R12 // code pointer
306 MOVD R12, CTR
307 BL (CTR)
308
309 // should never return
310 CALL runtime·abort(SB)
311 UNDEF
312
313/*
314 * support for morestack
315 */
316
317// Called during function prolog when more stack is needed.
318// Caller has already loaded:
319// R3: framesize, R4: argsize, R5: LR
320//
321// The traceback routines see morestack on a g0 as being
322// the top of a stack (for example, morestack calling newstack
323// calling the scheduler calling newm calling gc), so we must
324// record an argument size. For that purpose, it has no arguments.
325TEXT runtime·morestack(SB),NOSPLIT|NOFRAME,$0-0
326 // Called from f.
327 // Set g->sched to context in f.
328 MOVD R1, (g_sched+gobuf_sp)(g)
329 MOVD LR, R8
330 MOVD R8, (g_sched+gobuf_pc)(g)
331 MOVD R5, (g_sched+gobuf_lr)(g)
332 MOVD R11, (g_sched+gobuf_ctxt)(g)
333
334 // Cannot grow scheduler stack (m->g0).
335 MOVD g_m(g), R7
336 MOVD m_g0(R7), R8
337 CMP g, R8
338 BNE 3(PC)
339 BL runtime·badmorestackg0(SB)
340 BL runtime·abort(SB)
341
342 // Cannot grow signal stack (m->gsignal).
343 MOVD m_gsignal(R7), R8
344 CMP g, R8
345 BNE 3(PC)
346 BL runtime·badmorestackgsignal(SB)
347 BL runtime·abort(SB)
348
349 // Called from f.
350 // Set m->morebuf to f's caller.
351 MOVD R5, (m_morebuf+gobuf_pc)(R7) // f's caller's PC
352 MOVD R1, (m_morebuf+gobuf_sp)(R7) // f's caller's SP
353 MOVD g, (m_morebuf+gobuf_g)(R7)
354
355 // Call newstack on m->g0's stack.
356 MOVD m_g0(R7), g
357 BL runtime·save_g(SB)
358 MOVD (g_sched+gobuf_sp)(g), R1
359 MOVDU R0, -(FIXED_FRAME+0)(R1) // create a call frame on g0
360 BL runtime·newstack(SB)
361
362 // Not reached, but make sure the return PC from the call to newstack
363 // is still in this function, and not the beginning of the next.
364 UNDEF
365
366TEXT runtime·morestack_noctxt(SB),NOSPLIT|NOFRAME,$0-0
367 // Force SPWRITE. This function doesn't actually write SP,
368 // but it is called with a special calling convention where
369 // the caller doesn't save LR on stack but passes it as a
370 // register (R5), and the unwinder currently doesn't understand.
371 // Make it SPWRITE to stop unwinding. (See issue 54332)
372 // Use OR R0, R1 instead of MOVD R1, R1 as the MOVD instruction
373 // has a special affect on Power8,9,10 by lowering the thread
374 // priority and causing a slowdown in execution time
375
376 OR R0, R1
377 MOVD R0, R11
378 BR runtime·morestack(SB)
379
380// reflectcall: call a function with the given argument list
381// func call(stackArgsType *_type, f *FuncVal, stackArgs *byte, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs).
382// we don't have variable-sized frames, so we use a small number
383// of constant-sized-frame functions to encode a few bits of size in the pc.
384// Caution: ugly multiline assembly macros in your future!
385
386#define DISPATCH(NAME,MAXSIZE) \
387 MOVD $MAXSIZE, R31; \
388 CMP R3, R31; \
389 BGT 4(PC); \
390 MOVD $NAME(SB), R12; \
391 MOVD R12, CTR; \
392 BR (CTR)
393// Note: can't just "BR NAME(SB)" - bad inlining results.
394
395TEXT ·reflectcall(SB), NOSPLIT|NOFRAME, $0-48
396 MOVWZ frameSize+32(FP), R3
397 DISPATCH(runtime·call16, 16)
398 DISPATCH(runtime·call32, 32)
399 DISPATCH(runtime·call64, 64)
400 DISPATCH(runtime·call128, 128)
401 DISPATCH(runtime·call256, 256)
402 DISPATCH(runtime·call512, 512)
403 DISPATCH(runtime·call1024, 1024)
404 DISPATCH(runtime·call2048, 2048)
405 DISPATCH(runtime·call4096, 4096)
406 DISPATCH(runtime·call8192, 8192)
407 DISPATCH(runtime·call16384, 16384)
408 DISPATCH(runtime·call32768, 32768)
409 DISPATCH(runtime·call65536, 65536)
410 DISPATCH(runtime·call131072, 131072)
411 DISPATCH(runtime·call262144, 262144)
412 DISPATCH(runtime·call524288, 524288)
413 DISPATCH(runtime·call1048576, 1048576)
414 DISPATCH(runtime·call2097152, 2097152)
415 DISPATCH(runtime·call4194304, 4194304)
416 DISPATCH(runtime·call8388608, 8388608)
417 DISPATCH(runtime·call16777216, 16777216)
418 DISPATCH(runtime·call33554432, 33554432)
419 DISPATCH(runtime·call67108864, 67108864)
420 DISPATCH(runtime·call134217728, 134217728)
421 DISPATCH(runtime·call268435456, 268435456)
422 DISPATCH(runtime·call536870912, 536870912)
423 DISPATCH(runtime·call1073741824, 1073741824)
424 MOVD $runtime·badreflectcall(SB), R12
425 MOVD R12, CTR
426 BR (CTR)
427
428#define CALLFN(NAME,MAXSIZE) \
429TEXT NAME(SB), WRAPPER, $MAXSIZE-48; \
430 NO_LOCAL_POINTERS; \
431 /* copy arguments to stack */ \
432 MOVD stackArgs+16(FP), R3; \
433 MOVWZ stackArgsSize+24(FP), R4; \
434 MOVD R1, R5; \
435 CMP R4, $8; \
436 BLT tailsetup; \
437 /* copy 8 at a time if possible */ \
438 ADD $(FIXED_FRAME-8), R5; \
439 SUB $8, R3; \
440top: \
441 MOVDU 8(R3), R7; \
442 MOVDU R7, 8(R5); \
443 SUB $8, R4; \
444 CMP R4, $8; \
445 BGE top; \
446 /* handle remaining bytes */ \
447 CMP $0, R4; \
448 BEQ callfn; \
449 ADD $7, R3; \
450 ADD $7, R5; \
451 BR tail; \
452tailsetup: \
453 CMP $0, R4; \
454 BEQ callfn; \
455 ADD $(FIXED_FRAME-1), R5; \
456 SUB $1, R3; \
457tail: \
458 MOVBU 1(R3), R6; \
459 MOVBU R6, 1(R5); \
460 SUB $1, R4; \
461 CMP $0, R4; \
462 BGT tail; \
463callfn: \
464 /* call function */ \
465 MOVD f+8(FP), R11; \
466#ifdef GOOS_aix \
467 /* AIX won't trigger a SIGSEGV if R11 = nil */ \
468 /* So it manually triggers it */ \
469 CMP R11, $0 \
470 BNE 2(PC) \
471 MOVD R0, 0(R0) \
472#endif \
473 MOVD regArgs+40(FP), R20; \
474 BL runtime·unspillArgs(SB); \
475 MOVD (R11), R12; \
476 MOVD R12, CTR; \
477 PCDATA $PCDATA_StackMapIndex, $0; \
478 BL (CTR); \
479#ifndef GOOS_aix \
480 MOVD 24(R1), R2; \
481#endif \
482 /* copy return values back */ \
483 MOVD regArgs+40(FP), R20; \
484 BL runtime·spillArgs(SB); \
485 MOVD stackArgsType+0(FP), R7; \
486 MOVD stackArgs+16(FP), R3; \
487 MOVWZ stackArgsSize+24(FP), R4; \
488 MOVWZ stackRetOffset+28(FP), R6; \
489 ADD $FIXED_FRAME, R1, R5; \
490 ADD R6, R5; \
491 ADD R6, R3; \
492 SUB R6, R4; \
493 BL callRet<>(SB); \
494 RET
495
496// callRet copies return values back at the end of call*. This is a
497// separate function so it can allocate stack space for the arguments
498// to reflectcallmove. It does not follow the Go ABI; it expects its
499// arguments in registers.
500TEXT callRet<>(SB), NOSPLIT, $40-0
501 NO_LOCAL_POINTERS
502 MOVD R7, FIXED_FRAME+0(R1)
503 MOVD R3, FIXED_FRAME+8(R1)
504 MOVD R5, FIXED_FRAME+16(R1)
505 MOVD R4, FIXED_FRAME+24(R1)
506 MOVD R20, FIXED_FRAME+32(R1)
507 BL runtime·reflectcallmove(SB)
508 RET
509
510CALLFN(·call16, 16)
511CALLFN(·call32, 32)
512CALLFN(·call64, 64)
513CALLFN(·call128, 128)
514CALLFN(·call256, 256)
515CALLFN(·call512, 512)
516CALLFN(·call1024, 1024)
517CALLFN(·call2048, 2048)
518CALLFN(·call4096, 4096)
519CALLFN(·call8192, 8192)
520CALLFN(·call16384, 16384)
521CALLFN(·call32768, 32768)
522CALLFN(·call65536, 65536)
523CALLFN(·call131072, 131072)
524CALLFN(·call262144, 262144)
525CALLFN(·call524288, 524288)
526CALLFN(·call1048576, 1048576)
527CALLFN(·call2097152, 2097152)
528CALLFN(·call4194304, 4194304)
529CALLFN(·call8388608, 8388608)
530CALLFN(·call16777216, 16777216)
531CALLFN(·call33554432, 33554432)
532CALLFN(·call67108864, 67108864)
533CALLFN(·call134217728, 134217728)
534CALLFN(·call268435456, 268435456)
535CALLFN(·call536870912, 536870912)
536CALLFN(·call1073741824, 1073741824)
537
538TEXT runtime·procyield(SB),NOSPLIT|NOFRAME,$0-4
539 MOVW cycles+0(FP), R7
540 // POWER does not have a pause/yield instruction equivalent.
541 // Instead, we can lower the program priority by setting the
542 // Program Priority Register prior to the wait loop and set it
543 // back to default afterwards. On Linux, the default priority is
544 // medium-low. For details, see page 837 of the ISA 3.0.
545 OR R1, R1, R1 // Set PPR priority to low
546again:
547 SUB $1, R7
548 CMP $0, R7
549 BNE again
550 OR R6, R6, R6 // Set PPR priority back to medium-low
551 RET
552
553// Save state of caller into g->sched,
554// but using fake PC from systemstack_switch.
555// Must only be called from functions with no locals ($0)
556// or else unwinding from systemstack_switch is incorrect.
557// Smashes R31.
558TEXT gosave_systemstack_switch<>(SB),NOSPLIT|NOFRAME,$0
559 MOVD $runtime·systemstack_switch(SB), R31
560 ADD $16, R31 // get past prologue (including r2-setting instructions when they're there)
561 MOVD R31, (g_sched+gobuf_pc)(g)
562 MOVD R1, (g_sched+gobuf_sp)(g)
563 MOVD R0, (g_sched+gobuf_lr)(g)
564 MOVD R0, (g_sched+gobuf_ret)(g)
565 // Assert ctxt is zero. See func save.
566 MOVD (g_sched+gobuf_ctxt)(g), R31
567 CMP R31, $0
568 BEQ 2(PC)
569 BL runtime·abort(SB)
570 RET
571
572#ifdef GOOS_aix
573#define asmcgocallSaveOffset cgoCalleeStackSize + 8
574#else
575#define asmcgocallSaveOffset cgoCalleeStackSize
576#endif
577
578// func asmcgocall_no_g(fn, arg unsafe.Pointer)
579// Call fn(arg) aligned appropriately for the gcc ABI.
580// Called on a system stack, and there may be no g yet (during needm).
581TEXT ·asmcgocall_no_g(SB),NOSPLIT,$0-16
582 MOVD fn+0(FP), R3
583 MOVD arg+8(FP), R4
584
585 MOVD R1, R15
586 SUB $(asmcgocallSaveOffset+8), R1
587 RLDCR $0, R1, $~15, R1 // 16-byte alignment for gcc ABI
588 MOVD R15, asmcgocallSaveOffset(R1)
589
590 MOVD R0, 0(R1) // clear back chain pointer (TODO can we give it real back trace information?)
591
592 // This is a "global call", so put the global entry point in r12
593 MOVD R3, R12
594
595#ifdef GO_PPC64X_HAS_FUNCDESC
596 // Load the real entry address from the first slot of the function descriptor.
597 MOVD 8(R12), R2
598 MOVD (R12), R12
599#endif
600 MOVD R12, CTR
601 MOVD R4, R3 // arg in r3
602 BL (CTR)
603
604 // C code can clobber R0, so set it back to 0. F27-F31 are
605 // callee save, so we don't need to recover those.
606 XOR R0, R0
607
608 MOVD asmcgocallSaveOffset(R1), R1 // Restore stack pointer.
609#ifndef GOOS_aix
610 MOVD 24(R1), R2
611#endif
612
613 RET
614
615// func asmcgocall(fn, arg unsafe.Pointer) int32
616// Call fn(arg) on the scheduler stack,
617// aligned appropriately for the gcc ABI.
618// See cgocall.go for more details.
619TEXT ·asmcgocall<ABIInternal>(SB),NOSPLIT,$0-20
620 // R3 = fn
621 // R4 = arg
622
623 MOVD R1, R7 // save original stack pointer
624 CMP $0, g
625 BEQ nosave
626 MOVD g, R5
627
628 // Figure out if we need to switch to m->g0 stack.
629 // We get called to create new OS threads too, and those
630 // come in on the m->g0 stack already. Or we might already
631 // be on the m->gsignal stack.
632 MOVD g_m(g), R8
633 MOVD m_gsignal(R8), R6
634 CMP R6, g
635 BEQ nosave
636 MOVD m_g0(R8), R6
637 CMP R6, g
638 BEQ nosave
639
640 BL gosave_systemstack_switch<>(SB)
641 MOVD R6, g
642 BL runtime·save_g(SB)
643 MOVD (g_sched+gobuf_sp)(g), R1
644
645 // Now on a scheduling stack (a pthread-created stack).
646#ifdef GOOS_aix
647 // Create a fake LR to improve backtrace.
648 MOVD $runtime·asmcgocall(SB), R6
649 MOVD R6, 16(R1)
650 // AIX also saves one argument on the stack.
651 SUB $8, R1
652#endif
653 // Save room for two of our pointers, plus the callee
654 // save area that lives on the caller stack.
655 // Do arithmetics in R10 to hide from the assembler
656 // counting it as SP delta, which is irrelevant as we are
657 // on the system stack.
658 SUB $(asmcgocallSaveOffset+16), R1, R10
659 RLDCR $0, R10, $~15, R1 // 16-byte alignment for gcc ABI
660 MOVD R5, (asmcgocallSaveOffset+8)(R1) // save old g on stack
661 MOVD (g_stack+stack_hi)(R5), R5
662 SUB R7, R5
663 MOVD R5, asmcgocallSaveOffset(R1) // save depth in old g stack (can't just save SP, as stack might be copied during a callback)
664#ifdef GOOS_aix
665 MOVD R7, 0(R1) // Save frame pointer to allow manual backtrace with gdb
666#else
667 MOVD R0, 0(R1) // clear back chain pointer (TODO can we give it real back trace information?)
668#endif
669 // This is a "global call", so put the global entry point in r12
670 MOVD R3, R12
671
672#ifdef GO_PPC64X_HAS_FUNCDESC
673 // Load the real entry address from the first slot of the function descriptor.
674 MOVD 8(R12), R2
675 MOVD (R12), R12
676#endif
677 MOVD R12, CTR
678 MOVD R4, R3 // arg in r3
679 BL (CTR)
680
681 // Reinitialise zero value register.
682 XOR R0, R0
683
684 // Restore g, stack pointer, toc pointer.
685 // R3 is errno, so don't touch it
686 MOVD (asmcgocallSaveOffset+8)(R1), g
687 MOVD (g_stack+stack_hi)(g), R5
688 MOVD asmcgocallSaveOffset(R1), R6
689 SUB R6, R5
690#ifndef GOOS_aix
691 MOVD 24(R5), R2
692#endif
693 MOVD R5, R1
694 BL runtime·save_g(SB)
695
696 // ret = R3
697 RET
698
699nosave:
700 // Running on a system stack, perhaps even without a g.
701 // Having no g can happen during thread creation or thread teardown.
702 // This code is like the above sequence but without saving/restoring g
703 // and without worrying about the stack moving out from under us
704 // (because we're on a system stack, not a goroutine stack).
705 // The above code could be used directly if already on a system stack,
706 // but then the only path through this code would be a rare case.
707 // Using this code for all "already on system stack" calls exercises it more,
708 // which should help keep it correct.
709
710 SUB $(asmcgocallSaveOffset+8), R1, R10
711 RLDCR $0, R10, $~15, R1 // 16-byte alignment for gcc ABI
712 MOVD R7, asmcgocallSaveOffset(R1) // Save original stack pointer.
713
714 MOVD R3, R12 // fn
715#ifdef GO_PPC64X_HAS_FUNCDESC
716 // Load the real entry address from the first slot of the function descriptor.
717 MOVD 8(R12), R2
718 MOVD (R12), R12
719#endif
720 MOVD R12, CTR
721 MOVD R4, R3 // arg
722 BL (CTR)
723
724 // Reinitialise zero value register.
725 XOR R0, R0
726
727 MOVD asmcgocallSaveOffset(R1), R1 // Restore stack pointer.
728#ifndef GOOS_aix
729 MOVD 24(R1), R2
730#endif
731 // ret = R3
732 RET
733
734// func cgocallback(fn, frame unsafe.Pointer, ctxt uintptr)
735// See cgocall.go for more details.
736TEXT ·cgocallback(SB),NOSPLIT,$24-24
737 NO_LOCAL_POINTERS
738
739 // Skip cgocallbackg, just dropm when fn is nil, and frame is the saved g.
740 // It is used to dropm while thread is exiting.
741 MOVD fn+0(FP), R5
742 CMP R5, $0
743 BNE loadg
744 // Restore the g from frame.
745 MOVD frame+8(FP), g
746 BR dropm
747
748loadg:
749 // Load m and g from thread-local storage.
750#ifndef GOOS_openbsd
751 MOVBZ runtime·iscgo(SB), R3
752 CMP R3, $0
753 BEQ nocgo
754#endif
755 BL runtime·load_g(SB)
756nocgo:
757
758 // If g is nil, Go did not create the current thread,
759 // or if this thread never called into Go on pthread platforms.
760 // Call needm to obtain one for temporary use.
761 // In this case, we're running on the thread stack, so there's
762 // lots of space, but the linker doesn't know. Hide the call from
763 // the linker analysis by using an indirect call.
764 CMP g, $0
765 BEQ needm
766
767 MOVD g_m(g), R8
768 MOVD R8, savedm-8(SP)
769 BR havem
770
771needm:
772 MOVD g, savedm-8(SP) // g is zero, so is m.
773 MOVD $runtime·needAndBindM(SB), R12
774 MOVD R12, CTR
775 BL (CTR)
776
777 // Set m->sched.sp = SP, so that if a panic happens
778 // during the function we are about to execute, it will
779 // have a valid SP to run on the g0 stack.
780 // The next few lines (after the havem label)
781 // will save this SP onto the stack and then write
782 // the same SP back to m->sched.sp. That seems redundant,
783 // but if an unrecovered panic happens, unwindm will
784 // restore the g->sched.sp from the stack location
785 // and then systemstack will try to use it. If we don't set it here,
786 // that restored SP will be uninitialized (typically 0) and
787 // will not be usable.
788 MOVD g_m(g), R8
789 MOVD m_g0(R8), R3
790 MOVD R1, (g_sched+gobuf_sp)(R3)
791
792havem:
793 // Now there's a valid m, and we're running on its m->g0.
794 // Save current m->g0->sched.sp on stack and then set it to SP.
795 // Save current sp in m->g0->sched.sp in preparation for
796 // switch back to m->curg stack.
797 // NOTE: unwindm knows that the saved g->sched.sp is at 8(R1) aka savedsp-16(SP).
798 MOVD m_g0(R8), R3
799 MOVD (g_sched+gobuf_sp)(R3), R4
800 MOVD R4, savedsp-24(SP) // must match frame size
801 MOVD R1, (g_sched+gobuf_sp)(R3)
802
803 // Switch to m->curg stack and call runtime.cgocallbackg.
804 // Because we are taking over the execution of m->curg
805 // but *not* resuming what had been running, we need to
806 // save that information (m->curg->sched) so we can restore it.
807 // We can restore m->curg->sched.sp easily, because calling
808 // runtime.cgocallbackg leaves SP unchanged upon return.
809 // To save m->curg->sched.pc, we push it onto the curg stack and
810 // open a frame the same size as cgocallback's g0 frame.
811 // Once we switch to the curg stack, the pushed PC will appear
812 // to be the return PC of cgocallback, so that the traceback
813 // will seamlessly trace back into the earlier calls.
814 MOVD m_curg(R8), g
815 BL runtime·save_g(SB)
816 MOVD (g_sched+gobuf_sp)(g), R4 // prepare stack as R4
817 MOVD (g_sched+gobuf_pc)(g), R5
818 MOVD R5, -(24+FIXED_FRAME)(R4) // "saved LR"; must match frame size
819 // Gather our arguments into registers.
820 MOVD fn+0(FP), R5
821 MOVD frame+8(FP), R6
822 MOVD ctxt+16(FP), R7
823 MOVD $-(24+FIXED_FRAME)(R4), R1 // switch stack; must match frame size
824 MOVD R5, FIXED_FRAME+0(R1)
825 MOVD R6, FIXED_FRAME+8(R1)
826 MOVD R7, FIXED_FRAME+16(R1)
827
828 MOVD $runtime·cgocallbackg(SB), R12
829 MOVD R12, CTR
830 CALL (CTR) // indirect call to bypass nosplit check. We're on a different stack now.
831
832 // Restore g->sched (== m->curg->sched) from saved values.
833 MOVD 0(R1), R5
834 MOVD R5, (g_sched+gobuf_pc)(g)
835 MOVD $(24+FIXED_FRAME)(R1), R4 // must match frame size
836 MOVD R4, (g_sched+gobuf_sp)(g)
837
838 // Switch back to m->g0's stack and restore m->g0->sched.sp.
839 // (Unlike m->curg, the g0 goroutine never uses sched.pc,
840 // so we do not have to restore it.)
841 MOVD g_m(g), R8
842 MOVD m_g0(R8), g
843 BL runtime·save_g(SB)
844 MOVD (g_sched+gobuf_sp)(g), R1
845 MOVD savedsp-24(SP), R4 // must match frame size
846 MOVD R4, (g_sched+gobuf_sp)(g)
847
848 // If the m on entry was nil, we called needm above to borrow an m,
849 // 1. for the duration of the call on non-pthread platforms,
850 // 2. or the duration of the C thread alive on pthread platforms.
851 // If the m on entry wasn't nil,
852 // 1. the thread might be a Go thread,
853 // 2. or it wasn't the first call from a C thread on pthread platforms,
854 // since then we skip dropm to reuse the m in the first call.
855 MOVD savedm-8(SP), R6
856 CMP R6, $0
857 BNE droppedm
858
859 // Skip dropm to reuse it in the next call, when a pthread key has been created.
860 MOVD _cgo_pthread_key_created(SB), R6
861 // It means cgo is disabled when _cgo_pthread_key_created is a nil pointer, need dropm.
862 CMP R6, $0
863 BEQ dropm
864 MOVD (R6), R6
865 CMP R6, $0
866 BNE droppedm
867
868dropm:
869 MOVD $runtime·dropm(SB), R12
870 MOVD R12, CTR
871 BL (CTR)
872droppedm:
873
874 // Done!
875 RET
876
877// void setg(G*); set g. for use by needm.
878TEXT runtime·setg(SB), NOSPLIT, $0-8
879 MOVD gg+0(FP), g
880 // This only happens if iscgo, so jump straight to save_g
881 BL runtime·save_g(SB)
882 RET
883
884#ifdef GO_PPC64X_HAS_FUNCDESC
885DEFINE_PPC64X_FUNCDESC(setg_gcc<>, _setg_gcc<>)
886TEXT _setg_gcc<>(SB),NOSPLIT|NOFRAME,$0-0
887#else
888TEXT setg_gcc<>(SB),NOSPLIT|NOFRAME,$0-0
889#endif
890 // The standard prologue clobbers R31, which is callee-save in
891 // the C ABI, so we have to use $-8-0 and save LR ourselves.
892 MOVD LR, R4
893 // Also save g and R31, since they're callee-save in C ABI
894 MOVD R31, R5
895 MOVD g, R6
896
897 MOVD R3, g
898 BL runtime·save_g(SB)
899
900 MOVD R6, g
901 MOVD R5, R31
902 MOVD R4, LR
903 RET
904
905TEXT runtime·abort(SB),NOSPLIT|NOFRAME,$0-0
906 MOVW (R0), R0
907 UNDEF
908
909#define TBR 268
910
911// int64 runtime·cputicks(void)
912TEXT runtime·cputicks(SB),NOSPLIT,$0-8
913 MOVD SPR(TBR), R3
914 MOVD R3, ret+0(FP)
915 RET
916
917// spillArgs stores return values from registers to a *internal/abi.RegArgs in R20.
918TEXT runtime·spillArgs(SB),NOSPLIT,$0-0
919 MOVD R3, 0(R20)
920 MOVD R4, 8(R20)
921 MOVD R5, 16(R20)
922 MOVD R6, 24(R20)
923 MOVD R7, 32(R20)
924 MOVD R8, 40(R20)
925 MOVD R9, 48(R20)
926 MOVD R10, 56(R20)
927 MOVD R14, 64(R20)
928 MOVD R15, 72(R20)
929 MOVD R16, 80(R20)
930 MOVD R17, 88(R20)
931 FMOVD F1, 96(R20)
932 FMOVD F2, 104(R20)
933 FMOVD F3, 112(R20)
934 FMOVD F4, 120(R20)
935 FMOVD F5, 128(R20)
936 FMOVD F6, 136(R20)
937 FMOVD F7, 144(R20)
938 FMOVD F8, 152(R20)
939 FMOVD F9, 160(R20)
940 FMOVD F10, 168(R20)
941 FMOVD F11, 176(R20)
942 FMOVD F12, 184(R20)
943 RET
944
945// unspillArgs loads args into registers from a *internal/abi.RegArgs in R20.
946TEXT runtime·unspillArgs(SB),NOSPLIT,$0-0
947 MOVD 0(R20), R3
948 MOVD 8(R20), R4
949 MOVD 16(R20), R5
950 MOVD 24(R20), R6
951 MOVD 32(R20), R7
952 MOVD 40(R20), R8
953 MOVD 48(R20), R9
954 MOVD 56(R20), R10
955 MOVD 64(R20), R14
956 MOVD 72(R20), R15
957 MOVD 80(R20), R16
958 MOVD 88(R20), R17
959 FMOVD 96(R20), F1
960 FMOVD 104(R20), F2
961 FMOVD 112(R20), F3
962 FMOVD 120(R20), F4
963 FMOVD 128(R20), F5
964 FMOVD 136(R20), F6
965 FMOVD 144(R20), F7
966 FMOVD 152(R20), F8
967 FMOVD 160(R20), F9
968 FMOVD 168(R20), F10
969 FMOVD 176(R20), F11
970 FMOVD 184(R20), F12
971 RET
972
973// AES hashing not implemented for ppc64
974TEXT runtime·memhash<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-32
975 JMP runtime·memhashFallback<ABIInternal>(SB)
976TEXT runtime·strhash<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-24
977 JMP runtime·strhashFallback<ABIInternal>(SB)
978TEXT runtime·memhash32<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-24
979 JMP runtime·memhash32Fallback<ABIInternal>(SB)
980TEXT runtime·memhash64<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-24
981 JMP runtime·memhash64Fallback<ABIInternal>(SB)
982
983TEXT runtime·return0(SB), NOSPLIT, $0
984 MOVW $0, R3
985 RET
986
987// Called from cgo wrappers, this function returns g->m->curg.stack.hi.
988// Must obey the gcc calling convention.
989#ifdef GOOS_aix
990// On AIX, _cgo_topofstack is defined in runtime/cgo, because it must
991// be a longcall in order to prevent trampolines from ld.
992TEXT __cgo_topofstack(SB),NOSPLIT|NOFRAME,$0
993#else
994TEXT _cgo_topofstack(SB),NOSPLIT|NOFRAME,$0
995#endif
996 // g (R30) and R31 are callee-save in the C ABI, so save them
997 MOVD g, R4
998 MOVD R31, R5
999 MOVD LR, R6
1000
1001 BL runtime·load_g(SB) // clobbers g (R30), R31
1002 MOVD g_m(g), R3
1003 MOVD m_curg(R3), R3
1004 MOVD (g_stack+stack_hi)(R3), R3
1005
1006 MOVD R4, g
1007 MOVD R5, R31
1008 MOVD R6, LR
1009 RET
1010
1011// The top-most function running on a goroutine
1012// returns to goexit+PCQuantum.
1013//
1014// When dynamically linking Go, it can be returned to from a function
1015// implemented in a different module and so needs to reload the TOC pointer
1016// from the stack (although this function declares that it does not set up x-a
1017// frame, newproc1 does in fact allocate one for goexit and saves the TOC
1018// pointer in the correct place).
1019// goexit+_PCQuantum is halfway through the usual global entry point prologue
1020// that derives r2 from r12 which is a bit silly, but not harmful.
1021TEXT runtime·goexit(SB),NOSPLIT|NOFRAME|TOPFRAME,$0-0
1022 MOVD 24(R1), R2
1023 BL runtime·goexit1(SB) // does not return
1024 // traceback from goexit1 must hit code range of goexit
1025 MOVD R0, R0 // NOP
1026
1027// prepGoExitFrame saves the current TOC pointer (i.e. the TOC pointer for the
1028// module containing runtime) to the frame that goexit will execute in when
1029// the goroutine exits. It's implemented in assembly mainly because that's the
1030// easiest way to get access to R2.
1031TEXT runtime·prepGoExitFrame(SB),NOSPLIT,$0-8
1032 MOVD sp+0(FP), R3
1033 MOVD R2, 24(R3)
1034 RET
1035
1036TEXT runtime·addmoduledata(SB),NOSPLIT|NOFRAME,$0-0
1037 ADD $-8, R1
1038 MOVD R31, 0(R1)
1039 MOVD runtime·lastmoduledatap(SB), R4
1040 MOVD R3, moduledata_next(R4)
1041 MOVD R3, runtime·lastmoduledatap(SB)
1042 MOVD 0(R1), R31
1043 ADD $8, R1
1044 RET
1045
1046TEXT ·checkASM(SB),NOSPLIT,$0-1
1047 MOVW $1, R3
1048 MOVB R3, ret+0(FP)
1049 RET
1050
1051// gcWriteBarrier informs the GC about heap pointer writes.
1052//
1053// gcWriteBarrier does NOT follow the Go ABI. It accepts the
1054// number of bytes of buffer needed in R29, and returns a pointer
1055// to the buffer space in R29.
1056// It clobbers condition codes.
1057// It does not clobber R0 through R17 (except special registers),
1058// but may clobber any other register, *including* R31.
1059TEXT gcWriteBarrier<>(SB),NOSPLIT,$120
1060 // The standard prologue clobbers R31.
1061 // We use R18, R19, and R31 as scratch registers.
1062retry:
1063 MOVD g_m(g), R18
1064 MOVD m_p(R18), R18
1065 MOVD (p_wbBuf+wbBuf_next)(R18), R19
1066 MOVD (p_wbBuf+wbBuf_end)(R18), R31
1067 // Increment wbBuf.next position.
1068 ADD R29, R19
1069 // Is the buffer full?
1070 CMPU R31, R19
1071 BLT flush
1072 // Commit to the larger buffer.
1073 MOVD R19, (p_wbBuf+wbBuf_next)(R18)
1074 // Make return value (the original next position)
1075 SUB R29, R19, R29
1076 RET
1077
1078flush:
1079 // Save registers R0 through R15 since these were not saved by the caller.
1080 // We don't save all registers on ppc64 because it takes too much space.
1081 MOVD R20, (FIXED_FRAME+0)(R1)
1082 MOVD R21, (FIXED_FRAME+8)(R1)
1083 // R0 is always 0, so no need to spill.
1084 // R1 is SP.
1085 // R2 is SB.
1086 MOVD R3, (FIXED_FRAME+16)(R1)
1087 MOVD R4, (FIXED_FRAME+24)(R1)
1088 MOVD R5, (FIXED_FRAME+32)(R1)
1089 MOVD R6, (FIXED_FRAME+40)(R1)
1090 MOVD R7, (FIXED_FRAME+48)(R1)
1091 MOVD R8, (FIXED_FRAME+56)(R1)
1092 MOVD R9, (FIXED_FRAME+64)(R1)
1093 MOVD R10, (FIXED_FRAME+72)(R1)
1094 // R11, R12 may be clobbered by external-linker-inserted trampoline
1095 // R13 is REGTLS
1096 MOVD R14, (FIXED_FRAME+80)(R1)
1097 MOVD R15, (FIXED_FRAME+88)(R1)
1098 MOVD R16, (FIXED_FRAME+96)(R1)
1099 MOVD R17, (FIXED_FRAME+104)(R1)
1100 MOVD R29, (FIXED_FRAME+112)(R1)
1101
1102 CALL runtime·wbBufFlush(SB)
1103
1104 MOVD (FIXED_FRAME+0)(R1), R20
1105 MOVD (FIXED_FRAME+8)(R1), R21
1106 MOVD (FIXED_FRAME+16)(R1), R3
1107 MOVD (FIXED_FRAME+24)(R1), R4
1108 MOVD (FIXED_FRAME+32)(R1), R5
1109 MOVD (FIXED_FRAME+40)(R1), R6
1110 MOVD (FIXED_FRAME+48)(R1), R7
1111 MOVD (FIXED_FRAME+56)(R1), R8
1112 MOVD (FIXED_FRAME+64)(R1), R9
1113 MOVD (FIXED_FRAME+72)(R1), R10
1114 MOVD (FIXED_FRAME+80)(R1), R14
1115 MOVD (FIXED_FRAME+88)(R1), R15
1116 MOVD (FIXED_FRAME+96)(R1), R16
1117 MOVD (FIXED_FRAME+104)(R1), R17
1118 MOVD (FIXED_FRAME+112)(R1), R29
1119 JMP retry
1120
1121TEXT runtime·gcWriteBarrier1<ABIInternal>(SB),NOSPLIT,$0
1122 MOVD $8, R29
1123 JMP gcWriteBarrier<>(SB)
1124TEXT runtime·gcWriteBarrier2<ABIInternal>(SB),NOSPLIT,$0
1125 MOVD $16, R29
1126 JMP gcWriteBarrier<>(SB)
1127TEXT runtime·gcWriteBarrier3<ABIInternal>(SB),NOSPLIT,$0
1128 MOVD $24, R29
1129 JMP gcWriteBarrier<>(SB)
1130TEXT runtime·gcWriteBarrier4<ABIInternal>(SB),NOSPLIT,$0
1131 MOVD $32, R29
1132 JMP gcWriteBarrier<>(SB)
1133TEXT runtime·gcWriteBarrier5<ABIInternal>(SB),NOSPLIT,$0
1134 MOVD $40, R29
1135 JMP gcWriteBarrier<>(SB)
1136TEXT runtime·gcWriteBarrier6<ABIInternal>(SB),NOSPLIT,$0
1137 MOVD $48, R29
1138 JMP gcWriteBarrier<>(SB)
1139TEXT runtime·gcWriteBarrier7<ABIInternal>(SB),NOSPLIT,$0
1140 MOVD $56, R29
1141 JMP gcWriteBarrier<>(SB)
1142TEXT runtime·gcWriteBarrier8<ABIInternal>(SB),NOSPLIT,$0
1143 MOVD $64, R29
1144 JMP gcWriteBarrier<>(SB)
1145
1146DATA debugCallFrameTooLarge<>+0x00(SB)/20, $"call frame too large"
1147GLOBL debugCallFrameTooLarge<>(SB), RODATA, $20 // Size duplicated below
1148
1149// debugCallV2 is the entry point for debugger-injected function
1150// calls on running goroutines. It informs the runtime that a
1151// debug call has been injected and creates a call frame for the
1152// debugger to fill in.
1153//
1154// To inject a function call, a debugger should:
1155// 1. Check that the goroutine is in state _Grunning and that
1156// there are at least 320 bytes free on the stack.
1157// 2. Set SP as SP-32.
1158// 3. Store the current LR in (SP) (using the SP after step 2).
1159// 4. Store the current PC in the LR register.
1160// 5. Write the desired argument frame size at SP-32
1161// 6. Save all machine registers (including flags and floating point registers)
1162// so they can be restored later by the debugger.
1163// 7. Set the PC to debugCallV2 and resume execution.
1164//
1165// If the goroutine is in state _Grunnable, then it's not generally
1166// safe to inject a call because it may return out via other runtime
1167// operations. Instead, the debugger should unwind the stack to find
1168// the return to non-runtime code, add a temporary breakpoint there,
1169// and inject the call once that breakpoint is hit.
1170//
1171// If the goroutine is in any other state, it's not safe to inject a call.
1172//
1173// This function communicates back to the debugger by setting R20 and
1174// invoking TW to raise a breakpoint signal. Note that the signal PC of
1175// the signal triggered by the TW instruction is the PC where the signal
1176// is trapped, not the next PC, so to resume execution, the debugger needs
1177// to set the signal PC to PC+4. See the comments in the implementation for
1178// the protocol the debugger is expected to follow. InjectDebugCall in the
1179// runtime tests demonstrates this protocol.
1180// The debugger must ensure that any pointers passed to the function
1181// obey escape analysis requirements. Specifically, it must not pass
1182// a stack pointer to an escaping argument. debugCallV2 cannot check
1183// this invariant.
1184//
1185// This is ABIInternal because Go code injects its PC directly into new
1186// goroutine stacks.
1187#ifdef GOARCH_ppc64le
1188TEXT runtime·debugCallV2<ABIInternal>(SB), NOSPLIT|NOFRAME, $0-0
1189 // save scratch register R31 first
1190 MOVD R31, -184(R1)
1191 MOVD 0(R1), R31
1192 // save caller LR
1193 MOVD R31, -304(R1)
1194 MOVD -32(R1), R31
1195 // save argument frame size
1196 MOVD R31, -192(R1)
1197 MOVD LR, R31
1198 MOVD R31, -320(R1)
1199 ADD $-320, R1
1200 // save all registers that can contain pointers
1201 // and the CR register
1202 MOVW CR, R31
1203 MOVD R31, 8(R1)
1204 MOVD R2, 24(R1)
1205 MOVD R3, 56(R1)
1206 MOVD R4, 64(R1)
1207 MOVD R5, 72(R1)
1208 MOVD R6, 80(R1)
1209 MOVD R7, 88(R1)
1210 MOVD R8, 96(R1)
1211 MOVD R9, 104(R1)
1212 MOVD R10, 112(R1)
1213 MOVD R11, 120(R1)
1214 MOVD R12, 144(R1)
1215 MOVD R13, 152(R1)
1216 MOVD R14, 160(R1)
1217 MOVD R15, 168(R1)
1218 MOVD R16, 176(R1)
1219 MOVD R17, 184(R1)
1220 MOVD R18, 192(R1)
1221 MOVD R19, 200(R1)
1222 MOVD R20, 208(R1)
1223 MOVD R21, 216(R1)
1224 MOVD R22, 224(R1)
1225 MOVD R23, 232(R1)
1226 MOVD R24, 240(R1)
1227 MOVD R25, 248(R1)
1228 MOVD R26, 256(R1)
1229 MOVD R27, 264(R1)
1230 MOVD R28, 272(R1)
1231 MOVD R29, 280(R1)
1232 MOVD g, 288(R1)
1233 MOVD LR, R31
1234 MOVD R31, 32(R1)
1235 CALL runtime·debugCallCheck(SB)
1236 MOVD 40(R1), R22
1237 XOR R0, R0
1238 CMP R22, $0
1239 BEQ good
1240 MOVD 48(R1), R22
1241 MOVD $8, R20
1242 TW $31, R0, R0
1243
1244 BR restore
1245
1246good:
1247#define DEBUG_CALL_DISPATCH(NAME,MAXSIZE) \
1248 MOVD $MAXSIZE, R23; \
1249 CMP R26, R23; \
1250 BGT 5(PC); \
1251 MOVD $NAME(SB), R26; \
1252 MOVD R26, 32(R1); \
1253 CALL runtime·debugCallWrap(SB); \
1254 BR restore
1255
1256 // the argument frame size
1257 MOVD 128(R1), R26
1258
1259 DEBUG_CALL_DISPATCH(debugCall32<>, 32)
1260 DEBUG_CALL_DISPATCH(debugCall64<>, 64)
1261 DEBUG_CALL_DISPATCH(debugCall128<>, 128)
1262 DEBUG_CALL_DISPATCH(debugCall256<>, 256)
1263 DEBUG_CALL_DISPATCH(debugCall512<>, 512)
1264 DEBUG_CALL_DISPATCH(debugCall1024<>, 1024)
1265 DEBUG_CALL_DISPATCH(debugCall2048<>, 2048)
1266 DEBUG_CALL_DISPATCH(debugCall4096<>, 4096)
1267 DEBUG_CALL_DISPATCH(debugCall8192<>, 8192)
1268 DEBUG_CALL_DISPATCH(debugCall16384<>, 16384)
1269 DEBUG_CALL_DISPATCH(debugCall32768<>, 32768)
1270 DEBUG_CALL_DISPATCH(debugCall65536<>, 65536)
1271 // The frame size is too large. Report the error.
1272 MOVD $debugCallFrameTooLarge<>(SB), R22
1273 MOVD R22, 32(R1)
1274 MOVD $20, R22
1275 // length of debugCallFrameTooLarge string
1276 MOVD R22, 40(R1)
1277 MOVD $8, R20
1278 TW $31, R0, R0
1279 BR restore
1280restore:
1281 MOVD $16, R20
1282 TW $31, R0, R0
1283 // restore all registers that can contain
1284 // pointers including CR
1285 MOVD 8(R1), R31
1286 MOVW R31, CR
1287 MOVD 24(R1), R2
1288 MOVD 56(R1), R3
1289 MOVD 64(R1), R4
1290 MOVD 72(R1), R5
1291 MOVD 80(R1), R6
1292 MOVD 88(R1), R7
1293 MOVD 96(R1), R8
1294 MOVD 104(R1), R9
1295 MOVD 112(R1), R10
1296 MOVD 120(R1), R11
1297 MOVD 144(R1), R12
1298 MOVD 152(R1), R13
1299 MOVD 160(R1), R14
1300 MOVD 168(R1), R15
1301 MOVD 176(R1), R16
1302 MOVD 184(R1), R17
1303 MOVD 192(R1), R18
1304 MOVD 200(R1), R19
1305 MOVD 208(R1), R20
1306 MOVD 216(R1), R21
1307 MOVD 224(R1), R22
1308 MOVD 232(R1), R23
1309 MOVD 240(R1), R24
1310 MOVD 248(R1), R25
1311 MOVD 256(R1), R26
1312 MOVD 264(R1), R27
1313 MOVD 272(R1), R28
1314 MOVD 280(R1), R29
1315 MOVD 288(R1), g
1316 MOVD 16(R1), R31
1317 // restore old LR
1318 MOVD R31, LR
1319 // restore caller PC
1320 MOVD 0(R1), CTR
1321 MOVD 136(R1), R31
1322 // Add 32 bytes more to compensate for SP change in saveSigContext
1323 ADD $352, R1
1324 JMP (CTR)
1325#endif
1326#define DEBUG_CALL_FN(NAME,MAXSIZE) \
1327TEXT NAME(SB),WRAPPER,$MAXSIZE-0; \
1328 NO_LOCAL_POINTERS; \
1329 MOVD $0, R20; \
1330 TW $31, R0, R0 \
1331 MOVD $1, R20; \
1332 TW $31, R0, R0 \
1333 RET
1334DEBUG_CALL_FN(debugCall32<>, 32)
1335DEBUG_CALL_FN(debugCall64<>, 64)
1336DEBUG_CALL_FN(debugCall128<>, 128)
1337DEBUG_CALL_FN(debugCall256<>, 256)
1338DEBUG_CALL_FN(debugCall512<>, 512)
1339DEBUG_CALL_FN(debugCall1024<>, 1024)
1340DEBUG_CALL_FN(debugCall2048<>, 2048)
1341DEBUG_CALL_FN(debugCall4096<>, 4096)
1342DEBUG_CALL_FN(debugCall8192<>, 8192)
1343DEBUG_CALL_FN(debugCall16384<>, 16384)
1344DEBUG_CALL_FN(debugCall32768<>, 32768)
1345DEBUG_CALL_FN(debugCall65536<>, 65536)
1346
1347#ifdef GOARCH_ppc64le
1348// func debugCallPanicked(val interface{})
1349TEXT runtime·debugCallPanicked(SB),NOSPLIT,$32-16
1350 // Copy the panic value to the top of stack at SP+32.
1351 MOVD val_type+0(FP), R31
1352 MOVD R31, 32(R1)
1353 MOVD val_data+8(FP), R31
1354 MOVD R31, 40(R1)
1355 MOVD $2, R20
1356 TW $31, R0, R0
1357 RET
1358#endif
1359// Note: these functions use a special calling convention to save generated code space.
1360// Arguments are passed in registers, but the space for those arguments are allocated
1361// in the caller's stack frame. These stubs write the args into that stack space and
1362// then tail call to the corresponding runtime handler.
1363// The tail call makes these stubs disappear in backtraces.
1364TEXT runtime·panicIndex<ABIInternal>(SB),NOSPLIT,$0-16
1365 JMP runtime·goPanicIndex<ABIInternal>(SB)
1366TEXT runtime·panicIndexU<ABIInternal>(SB),NOSPLIT,$0-16
1367 JMP runtime·goPanicIndexU<ABIInternal>(SB)
1368TEXT runtime·panicSliceAlen<ABIInternal>(SB),NOSPLIT,$0-16
1369 MOVD R4, R3
1370 MOVD R5, R4
1371 JMP runtime·goPanicSliceAlen<ABIInternal>(SB)
1372TEXT runtime·panicSliceAlenU<ABIInternal>(SB),NOSPLIT,$0-16
1373 MOVD R4, R3
1374 MOVD R5, R4
1375 JMP runtime·goPanicSliceAlenU<ABIInternal>(SB)
1376TEXT runtime·panicSliceAcap<ABIInternal>(SB),NOSPLIT,$0-16
1377 MOVD R4, R3
1378 MOVD R5, R4
1379 JMP runtime·goPanicSliceAcap<ABIInternal>(SB)
1380TEXT runtime·panicSliceAcapU<ABIInternal>(SB),NOSPLIT,$0-16
1381 MOVD R4, R3
1382 MOVD R5, R4
1383 JMP runtime·goPanicSliceAcapU<ABIInternal>(SB)
1384TEXT runtime·panicSliceB<ABIInternal>(SB),NOSPLIT,$0-16
1385 JMP runtime·goPanicSliceB<ABIInternal>(SB)
1386TEXT runtime·panicSliceBU<ABIInternal>(SB),NOSPLIT,$0-16
1387 JMP runtime·goPanicSliceBU<ABIInternal>(SB)
1388TEXT runtime·panicSlice3Alen<ABIInternal>(SB),NOSPLIT,$0-16
1389 MOVD R5, R3
1390 MOVD R6, R4
1391 JMP runtime·goPanicSlice3Alen<ABIInternal>(SB)
1392TEXT runtime·panicSlice3AlenU<ABIInternal>(SB),NOSPLIT,$0-16
1393 MOVD R5, R3
1394 MOVD R6, R4
1395 JMP runtime·goPanicSlice3AlenU<ABIInternal>(SB)
1396TEXT runtime·panicSlice3Acap<ABIInternal>(SB),NOSPLIT,$0-16
1397 MOVD R5, R3
1398 MOVD R6, R4
1399 JMP runtime·goPanicSlice3Acap<ABIInternal>(SB)
1400TEXT runtime·panicSlice3AcapU<ABIInternal>(SB),NOSPLIT,$0-16
1401 MOVD R5, R3
1402 MOVD R6, R4
1403 JMP runtime·goPanicSlice3AcapU<ABIInternal>(SB)
1404TEXT runtime·panicSlice3B<ABIInternal>(SB),NOSPLIT,$0-16
1405 MOVD R4, R3
1406 MOVD R5, R4
1407 JMP runtime·goPanicSlice3B<ABIInternal>(SB)
1408TEXT runtime·panicSlice3BU<ABIInternal>(SB),NOSPLIT,$0-16
1409 MOVD R4, R3
1410 MOVD R5, R4
1411 JMP runtime·goPanicSlice3BU<ABIInternal>(SB)
1412TEXT runtime·panicSlice3C<ABIInternal>(SB),NOSPLIT,$0-16
1413 JMP runtime·goPanicSlice3C<ABIInternal>(SB)
1414TEXT runtime·panicSlice3CU<ABIInternal>(SB),NOSPLIT,$0-16
1415 JMP runtime·goPanicSlice3CU<ABIInternal>(SB)
1416TEXT runtime·panicSliceConvert<ABIInternal>(SB),NOSPLIT,$0-16
1417 MOVD R5, R3
1418 MOVD R6, R4
1419 JMP runtime·goPanicSliceConvert<ABIInternal>(SB)
1420
1421// These functions are used when internal linking cgo with external
1422// objects compiled with the -Os on gcc. They reduce prologue/epilogue
1423// size by deferring preservation of callee-save registers to a shared
1424// function. These are defined in PPC64 ELFv2 2.3.3 (but also present
1425// in ELFv1)
1426//
1427// These appear unused, but the linker will redirect calls to functions
1428// like _savegpr0_14 or _restgpr1_14 to runtime.elf_savegpr0 or
1429// runtime.elf_restgpr1 with an appropriate offset based on the number
1430// register operations required when linking external objects which
1431// make these calls. For GPR/FPR saves, the minimum register value is
1432// 14, for VR it is 20.
1433//
1434// These are only used when linking such cgo code internally. Note, R12
1435// and R0 may be used in different ways than regular ELF compliant
1436// functions.
1437TEXT runtime·elf_savegpr0(SB),NOSPLIT|NOFRAME,$0
1438 // R0 holds the LR of the caller's caller, R1 holds save location
1439 MOVD R14, -144(R1)
1440 MOVD R15, -136(R1)
1441 MOVD R16, -128(R1)
1442 MOVD R17, -120(R1)
1443 MOVD R18, -112(R1)
1444 MOVD R19, -104(R1)
1445 MOVD R20, -96(R1)
1446 MOVD R21, -88(R1)
1447 MOVD R22, -80(R1)
1448 MOVD R23, -72(R1)
1449 MOVD R24, -64(R1)
1450 MOVD R25, -56(R1)
1451 MOVD R26, -48(R1)
1452 MOVD R27, -40(R1)
1453 MOVD R28, -32(R1)
1454 MOVD R29, -24(R1)
1455 MOVD g, -16(R1)
1456 MOVD R31, -8(R1)
1457 MOVD R0, 16(R1)
1458 RET
1459TEXT runtime·elf_restgpr0(SB),NOSPLIT|NOFRAME,$0
1460 // R1 holds save location. This returns to the LR saved on stack (bypassing the caller)
1461 MOVD -144(R1), R14
1462 MOVD -136(R1), R15
1463 MOVD -128(R1), R16
1464 MOVD -120(R1), R17
1465 MOVD -112(R1), R18
1466 MOVD -104(R1), R19
1467 MOVD -96(R1), R20
1468 MOVD -88(R1), R21
1469 MOVD -80(R1), R22
1470 MOVD -72(R1), R23
1471 MOVD -64(R1), R24
1472 MOVD -56(R1), R25
1473 MOVD -48(R1), R26
1474 MOVD -40(R1), R27
1475 MOVD -32(R1), R28
1476 MOVD -24(R1), R29
1477 MOVD -16(R1), g
1478 MOVD -8(R1), R31
1479 MOVD 16(R1), R0 // Load and return to saved LR
1480 MOVD R0, LR
1481 RET
1482TEXT runtime·elf_savegpr1(SB),NOSPLIT|NOFRAME,$0
1483 // R12 holds the save location
1484 MOVD R14, -144(R12)
1485 MOVD R15, -136(R12)
1486 MOVD R16, -128(R12)
1487 MOVD R17, -120(R12)
1488 MOVD R18, -112(R12)
1489 MOVD R19, -104(R12)
1490 MOVD R20, -96(R12)
1491 MOVD R21, -88(R12)
1492 MOVD R22, -80(R12)
1493 MOVD R23, -72(R12)
1494 MOVD R24, -64(R12)
1495 MOVD R25, -56(R12)
1496 MOVD R26, -48(R12)
1497 MOVD R27, -40(R12)
1498 MOVD R28, -32(R12)
1499 MOVD R29, -24(R12)
1500 MOVD g, -16(R12)
1501 MOVD R31, -8(R12)
1502 RET
1503TEXT runtime·elf_restgpr1(SB),NOSPLIT|NOFRAME,$0
1504 // R12 holds the save location
1505 MOVD -144(R12), R14
1506 MOVD -136(R12), R15
1507 MOVD -128(R12), R16
1508 MOVD -120(R12), R17
1509 MOVD -112(R12), R18
1510 MOVD -104(R12), R19
1511 MOVD -96(R12), R20
1512 MOVD -88(R12), R21
1513 MOVD -80(R12), R22
1514 MOVD -72(R12), R23
1515 MOVD -64(R12), R24
1516 MOVD -56(R12), R25
1517 MOVD -48(R12), R26
1518 MOVD -40(R12), R27
1519 MOVD -32(R12), R28
1520 MOVD -24(R12), R29
1521 MOVD -16(R12), g
1522 MOVD -8(R12), R31
1523 RET
1524TEXT runtime·elf_savefpr(SB),NOSPLIT|NOFRAME,$0
1525 // R0 holds the LR of the caller's caller, R1 holds save location
1526 FMOVD F14, -144(R1)
1527 FMOVD F15, -136(R1)
1528 FMOVD F16, -128(R1)
1529 FMOVD F17, -120(R1)
1530 FMOVD F18, -112(R1)
1531 FMOVD F19, -104(R1)
1532 FMOVD F20, -96(R1)
1533 FMOVD F21, -88(R1)
1534 FMOVD F22, -80(R1)
1535 FMOVD F23, -72(R1)
1536 FMOVD F24, -64(R1)
1537 FMOVD F25, -56(R1)
1538 FMOVD F26, -48(R1)
1539 FMOVD F27, -40(R1)
1540 FMOVD F28, -32(R1)
1541 FMOVD F29, -24(R1)
1542 FMOVD F30, -16(R1)
1543 FMOVD F31, -8(R1)
1544 MOVD R0, 16(R1)
1545 RET
1546TEXT runtime·elf_restfpr(SB),NOSPLIT|NOFRAME,$0
1547 // R1 holds save location. This returns to the LR saved on stack (bypassing the caller)
1548 FMOVD -144(R1), F14
1549 FMOVD -136(R1), F15
1550 FMOVD -128(R1), F16
1551 FMOVD -120(R1), F17
1552 FMOVD -112(R1), F18
1553 FMOVD -104(R1), F19
1554 FMOVD -96(R1), F20
1555 FMOVD -88(R1), F21
1556 FMOVD -80(R1), F22
1557 FMOVD -72(R1), F23
1558 FMOVD -64(R1), F24
1559 FMOVD -56(R1), F25
1560 FMOVD -48(R1), F26
1561 FMOVD -40(R1), F27
1562 FMOVD -32(R1), F28
1563 FMOVD -24(R1), F29
1564 FMOVD -16(R1), F30
1565 FMOVD -8(R1), F31
1566 MOVD 16(R1), R0 // Load and return to saved LR
1567 MOVD R0, LR
1568 RET
1569TEXT runtime·elf_savevr(SB),NOSPLIT|NOFRAME,$0
1570 // R0 holds the save location, R12 is clobbered
1571 MOVD $-192, R12
1572 STVX V20, (R0+R12)
1573 MOVD $-176, R12
1574 STVX V21, (R0+R12)
1575 MOVD $-160, R12
1576 STVX V22, (R0+R12)
1577 MOVD $-144, R12
1578 STVX V23, (R0+R12)
1579 MOVD $-128, R12
1580 STVX V24, (R0+R12)
1581 MOVD $-112, R12
1582 STVX V25, (R0+R12)
1583 MOVD $-96, R12
1584 STVX V26, (R0+R12)
1585 MOVD $-80, R12
1586 STVX V27, (R0+R12)
1587 MOVD $-64, R12
1588 STVX V28, (R0+R12)
1589 MOVD $-48, R12
1590 STVX V29, (R0+R12)
1591 MOVD $-32, R12
1592 STVX V30, (R0+R12)
1593 MOVD $-16, R12
1594 STVX V31, (R0+R12)
1595 RET
1596TEXT runtime·elf_restvr(SB),NOSPLIT|NOFRAME,$0
1597 // R0 holds the save location, R12 is clobbered
1598 MOVD $-192, R12
1599 LVX (R0+R12), V20
1600 MOVD $-176, R12
1601 LVX (R0+R12), V21
1602 MOVD $-160, R12
1603 LVX (R0+R12), V22
1604 MOVD $-144, R12
1605 LVX (R0+R12), V23
1606 MOVD $-128, R12
1607 LVX (R0+R12), V24
1608 MOVD $-112, R12
1609 LVX (R0+R12), V25
1610 MOVD $-96, R12
1611 LVX (R0+R12), V26
1612 MOVD $-80, R12
1613 LVX (R0+R12), V27
1614 MOVD $-64, R12
1615 LVX (R0+R12), V28
1616 MOVD $-48, R12
1617 LVX (R0+R12), V29
1618 MOVD $-32, R12
1619 LVX (R0+R12), V30
1620 MOVD $-16, R12
1621 LVX (R0+R12), V31
1622 RET
View as plain text