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