]> Cypherpunks.ru repositories - gostls13.git/blob - src/runtime/asm_ppc64x.s
runtime/cgo: store M for C-created thread in pthread key
[gostls13.git] / 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
13 #ifdef GOOS_aix
14 #define cgoCalleeStackSize 48
15 #else
16 #define cgoCalleeStackSize 32
17 #endif
18
19 TEXT 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     R0, R12
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
67 nocgo:
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
102         MOVD    R0, 0(R0)
103         RET
104
105 DATA    runtime·mainPC+0(SB)/8,$runtime·main<ABIInternal>(SB)
106 GLOBL   runtime·mainPC(SB),RODATA,$8
107
108 TEXT runtime·breakpoint(SB),NOSPLIT|NOFRAME,$0-0
109         TW      $31, R0, R0
110         RET
111
112 TEXT runtime·asminit(SB),NOSPLIT|NOFRAME,$0-0
113         RET
114
115 // Any changes must be reflected to runtime/cgo/gcc_aix_ppc64.S:.crosscall_ppc64
116 TEXT _cgo_reginit(SB),NOSPLIT|NOFRAME,$0-0
117         // crosscall_ppc64 and crosscall2 need to reginit, but can't
118         // get at the 'runtime.reginit' symbol.
119         BR      runtime·reginit(SB)
120
121 TEXT runtime·reginit(SB),NOSPLIT|NOFRAME,$0-0
122         // set R0 to zero, it's expected by the toolchain
123         XOR R0, R0
124         RET
125
126 TEXT runtime·mstart(SB),NOSPLIT|TOPFRAME,$0
127         BL      runtime·mstart0(SB)
128         RET // not reached
129
130 /*
131  *  go-routine
132  */
133
134 // void gogo(Gobuf*)
135 // restore state from Gobuf; longjmp
136 TEXT runtime·gogo(SB), NOSPLIT|NOFRAME, $0-8
137         MOVD    buf+0(FP), R5
138         MOVD    gobuf_g(R5), R6
139         MOVD    0(R6), R4       // make sure g != nil
140         BR      gogo<>(SB)
141
142 TEXT gogo<>(SB), NOSPLIT|NOFRAME, $0
143         MOVD    R6, g
144         BL      runtime·save_g(SB)
145
146         MOVD    gobuf_sp(R5), R1
147         MOVD    gobuf_lr(R5), R31
148 #ifndef GOOS_aix
149         MOVD    24(R1), R2      // restore R2
150 #endif
151         MOVD    R31, LR
152         MOVD    gobuf_ret(R5), R3
153         MOVD    gobuf_ctxt(R5), R11
154         MOVD    R0, gobuf_sp(R5)
155         MOVD    R0, gobuf_ret(R5)
156         MOVD    R0, gobuf_lr(R5)
157         MOVD    R0, gobuf_ctxt(R5)
158         CMP     R0, R0 // set condition codes for == test, needed by stack split
159         MOVD    gobuf_pc(R5), R12
160         MOVD    R12, CTR
161         BR      (CTR)
162
163 // void mcall(fn func(*g))
164 // Switch to m->g0's stack, call fn(g).
165 // Fn must never return. It should gogo(&g->sched)
166 // to keep running g.
167 TEXT runtime·mcall<ABIInternal>(SB), NOSPLIT|NOFRAME, $0-8
168         // Save caller state in g->sched
169         // R11 should be safe across save_g??
170         MOVD    R3, R11
171         MOVD    R1, (g_sched+gobuf_sp)(g)
172         MOVD    LR, R31
173         MOVD    R31, (g_sched+gobuf_pc)(g)
174         MOVD    R0, (g_sched+gobuf_lr)(g)
175
176         // Switch to m->g0 & its stack, call fn.
177         MOVD    g, R3
178         MOVD    g_m(g), R8
179         MOVD    m_g0(R8), g
180         BL      runtime·save_g(SB)
181         CMP     g, R3
182         BNE     2(PC)
183         BR      runtime·badmcall(SB)
184         MOVD    0(R11), R12                     // code pointer
185         MOVD    R12, CTR
186         MOVD    (g_sched+gobuf_sp)(g), R1       // sp = m->g0->sched.sp
187         // Don't need to do anything special for regabiargs here
188         // R3 is g; stack is set anyway
189         MOVDU   R3, -8(R1)
190         MOVDU   R0, -8(R1)
191         MOVDU   R0, -8(R1)
192         MOVDU   R0, -8(R1)
193         MOVDU   R0, -8(R1)
194         BL      (CTR)
195         MOVD    24(R1), R2
196         BR      runtime·badmcall2(SB)
197
198 // systemstack_switch is a dummy routine that systemstack leaves at the bottom
199 // of the G stack. We need to distinguish the routine that
200 // lives at the bottom of the G stack from the one that lives
201 // at the top of the system stack because the one at the top of
202 // the system stack terminates the stack walk (see topofstack()).
203 TEXT runtime·systemstack_switch(SB), NOSPLIT, $0-0
204         // We have several undefs here so that 16 bytes past
205         // $runtime·systemstack_switch lies within them whether or not the
206         // instructions that derive r2 from r12 are there.
207         UNDEF
208         UNDEF
209         UNDEF
210         BL      (LR)    // make sure this function is not leaf
211         RET
212
213 // func systemstack(fn func())
214 TEXT runtime·systemstack(SB), NOSPLIT, $0-8
215         MOVD    fn+0(FP), R3    // R3 = fn
216         MOVD    R3, R11         // context
217         MOVD    g_m(g), R4      // R4 = m
218
219         MOVD    m_gsignal(R4), R5       // R5 = gsignal
220         CMP     g, R5
221         BEQ     noswitch
222
223         MOVD    m_g0(R4), R5    // R5 = g0
224         CMP     g, R5
225         BEQ     noswitch
226
227         MOVD    m_curg(R4), R6
228         CMP     g, R6
229         BEQ     switch
230
231         // Bad: g is not gsignal, not g0, not curg. What is it?
232         // Hide call from linker nosplit analysis.
233         MOVD    $runtime·badsystemstack(SB), R12
234         MOVD    R12, CTR
235         BL      (CTR)
236         BL      runtime·abort(SB)
237
238 switch:
239         // save our state in g->sched. Pretend to
240         // be systemstack_switch if the G stack is scanned.
241         BL      gosave_systemstack_switch<>(SB)
242
243         // switch to g0
244         MOVD    R5, g
245         BL      runtime·save_g(SB)
246         MOVD    (g_sched+gobuf_sp)(g), R1
247
248         // call target function
249         MOVD    0(R11), R12     // code pointer
250         MOVD    R12, CTR
251         BL      (CTR)
252
253         // restore TOC pointer. It seems unlikely that we will use systemstack
254         // to call a function defined in another module, but the results of
255         // doing so would be so confusing that it's worth doing this.
256         MOVD    g_m(g), R3
257         MOVD    m_curg(R3), g
258         MOVD    (g_sched+gobuf_sp)(g), R3
259 #ifndef GOOS_aix
260         MOVD    24(R3), R2
261 #endif
262         // switch back to g
263         MOVD    g_m(g), R3
264         MOVD    m_curg(R3), g
265         BL      runtime·save_g(SB)
266         MOVD    (g_sched+gobuf_sp)(g), R1
267         MOVD    R0, (g_sched+gobuf_sp)(g)
268         RET
269
270 noswitch:
271         // already on m stack, just call directly
272         // On other arches we do a tail call here, but it appears to be
273         // impossible to tail call a function pointer in shared mode on
274         // ppc64 because the caller is responsible for restoring the TOC.
275         MOVD    0(R11), R12     // code pointer
276         MOVD    R12, CTR
277         BL      (CTR)
278 #ifndef GOOS_aix
279         MOVD    24(R1), R2
280 #endif
281         RET
282
283 /*
284  * support for morestack
285  */
286
287 // Called during function prolog when more stack is needed.
288 // Caller has already loaded:
289 // R3: framesize, R4: argsize, R5: LR
290 //
291 // The traceback routines see morestack on a g0 as being
292 // the top of a stack (for example, morestack calling newstack
293 // calling the scheduler calling newm calling gc), so we must
294 // record an argument size. For that purpose, it has no arguments.
295 TEXT runtime·morestack(SB),NOSPLIT|NOFRAME,$0-0
296         // Cannot grow scheduler stack (m->g0).
297         MOVD    g_m(g), R7
298         MOVD    m_g0(R7), R8
299         CMP     g, R8
300         BNE     3(PC)
301         BL      runtime·badmorestackg0(SB)
302         BL      runtime·abort(SB)
303
304         // Cannot grow signal stack (m->gsignal).
305         MOVD    m_gsignal(R7), R8
306         CMP     g, R8
307         BNE     3(PC)
308         BL      runtime·badmorestackgsignal(SB)
309         BL      runtime·abort(SB)
310
311         // Called from f.
312         // Set g->sched to context in f.
313         MOVD    R1, (g_sched+gobuf_sp)(g)
314         MOVD    LR, R8
315         MOVD    R8, (g_sched+gobuf_pc)(g)
316         MOVD    R5, (g_sched+gobuf_lr)(g)
317         MOVD    R11, (g_sched+gobuf_ctxt)(g)
318
319         // Called from f.
320         // Set m->morebuf to f's caller.
321         MOVD    R5, (m_morebuf+gobuf_pc)(R7)    // f's caller's PC
322         MOVD    R1, (m_morebuf+gobuf_sp)(R7)    // f's caller's SP
323         MOVD    g, (m_morebuf+gobuf_g)(R7)
324
325         // Call newstack on m->g0's stack.
326         MOVD    m_g0(R7), g
327         BL      runtime·save_g(SB)
328         MOVD    (g_sched+gobuf_sp)(g), R1
329         MOVDU   R0, -(FIXED_FRAME+0)(R1)        // create a call frame on g0
330         BL      runtime·newstack(SB)
331
332         // Not reached, but make sure the return PC from the call to newstack
333         // is still in this function, and not the beginning of the next.
334         UNDEF
335
336 TEXT runtime·morestack_noctxt(SB),NOSPLIT|NOFRAME,$0-0
337         // Force SPWRITE. This function doesn't actually write SP,
338         // but it is called with a special calling convention where
339         // the caller doesn't save LR on stack but passes it as a
340         // register (R5), and the unwinder currently doesn't understand.
341         // Make it SPWRITE to stop unwinding. (See issue 54332)
342         // Use OR R0, R1 instead of MOVD R1, R1 as the MOVD instruction
343         // has a special affect on Power8,9,10 by lowering the thread 
344         // priority and causing a slowdown in execution time
345
346         OR      R0, R1
347         MOVD    R0, R11
348         BR      runtime·morestack(SB)
349
350 // reflectcall: call a function with the given argument list
351 // func call(stackArgsType *_type, f *FuncVal, stackArgs *byte, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs).
352 // we don't have variable-sized frames, so we use a small number
353 // of constant-sized-frame functions to encode a few bits of size in the pc.
354 // Caution: ugly multiline assembly macros in your future!
355
356 #define DISPATCH(NAME,MAXSIZE)          \
357         MOVD    $MAXSIZE, R31;          \
358         CMP     R3, R31;                \
359         BGT     4(PC);                  \
360         MOVD    $NAME(SB), R12;         \
361         MOVD    R12, CTR;               \
362         BR      (CTR)
363 // Note: can't just "BR NAME(SB)" - bad inlining results.
364
365 TEXT ·reflectcall(SB), NOSPLIT|NOFRAME, $0-48
366         MOVWZ   frameSize+32(FP), R3
367         DISPATCH(runtime·call16, 16)
368         DISPATCH(runtime·call32, 32)
369         DISPATCH(runtime·call64, 64)
370         DISPATCH(runtime·call128, 128)
371         DISPATCH(runtime·call256, 256)
372         DISPATCH(runtime·call512, 512)
373         DISPATCH(runtime·call1024, 1024)
374         DISPATCH(runtime·call2048, 2048)
375         DISPATCH(runtime·call4096, 4096)
376         DISPATCH(runtime·call8192, 8192)
377         DISPATCH(runtime·call16384, 16384)
378         DISPATCH(runtime·call32768, 32768)
379         DISPATCH(runtime·call65536, 65536)
380         DISPATCH(runtime·call131072, 131072)
381         DISPATCH(runtime·call262144, 262144)
382         DISPATCH(runtime·call524288, 524288)
383         DISPATCH(runtime·call1048576, 1048576)
384         DISPATCH(runtime·call2097152, 2097152)
385         DISPATCH(runtime·call4194304, 4194304)
386         DISPATCH(runtime·call8388608, 8388608)
387         DISPATCH(runtime·call16777216, 16777216)
388         DISPATCH(runtime·call33554432, 33554432)
389         DISPATCH(runtime·call67108864, 67108864)
390         DISPATCH(runtime·call134217728, 134217728)
391         DISPATCH(runtime·call268435456, 268435456)
392         DISPATCH(runtime·call536870912, 536870912)
393         DISPATCH(runtime·call1073741824, 1073741824)
394         MOVD    $runtime·badreflectcall(SB), R12
395         MOVD    R12, CTR
396         BR      (CTR)
397
398 #define CALLFN(NAME,MAXSIZE)                    \
399 TEXT NAME(SB), WRAPPER, $MAXSIZE-48;            \
400         NO_LOCAL_POINTERS;                      \
401         /* copy arguments to stack */           \
402         MOVD    stackArgs+16(FP), R3;                   \
403         MOVWZ   stackArgsSize+24(FP), R4;                       \
404         MOVD    R1, R5;                         \
405         CMP     R4, $8;                         \
406         BLT     tailsetup;                      \
407         /* copy 8 at a time if possible */      \
408         ADD     $(FIXED_FRAME-8), R5;                   \
409         SUB     $8, R3;                         \
410 top: \
411         MOVDU   8(R3), R7;                      \
412         MOVDU   R7, 8(R5);                      \
413         SUB     $8, R4;                         \
414         CMP     R4, $8;                         \
415         BGE     top;                            \
416         /* handle remaining bytes */    \
417         CMP     $0, R4;                 \
418         BEQ     callfn;                 \
419         ADD     $7, R3;                 \
420         ADD     $7, R5;                 \
421         BR      tail;                   \
422 tailsetup: \
423         CMP     $0, R4;                 \
424         BEQ     callfn;                 \
425         ADD     $(FIXED_FRAME-1), R5;   \
426         SUB     $1, R3;                 \
427 tail: \
428         MOVBU   1(R3), R6;              \
429         MOVBU   R6, 1(R5);              \
430         SUB     $1, R4;                 \
431         CMP     $0, R4;                 \
432         BGT     tail;                   \
433 callfn: \
434         /* call function */                     \
435         MOVD    f+8(FP), R11;                   \
436 #ifdef GOOS_aix                         \
437         /* AIX won't trigger a SIGSEGV if R11 = nil */  \
438         /* So it manually triggers it */        \
439         CMP     R0, R11                         \
440         BNE     2(PC)                           \
441         MOVD    R0, 0(R0)                       \
442 #endif                                          \
443         MOVD    regArgs+40(FP), R20;    \
444         BL      runtime·unspillArgs(SB);        \
445         MOVD    (R11), R12;                     \
446         MOVD    R12, CTR;                       \
447         PCDATA  $PCDATA_StackMapIndex, $0;      \
448         BL      (CTR);                          \
449 #ifndef GOOS_aix                                \
450         MOVD    24(R1), R2;                     \
451 #endif                                          \
452         /* copy return values back */           \
453         MOVD    regArgs+40(FP), R20;            \
454         BL      runtime·spillArgs(SB);                 \
455         MOVD    stackArgsType+0(FP), R7;                \
456         MOVD    stackArgs+16(FP), R3;                   \
457         MOVWZ   stackArgsSize+24(FP), R4;                       \
458         MOVWZ   stackRetOffset+28(FP), R6;              \
459         ADD     $FIXED_FRAME, R1, R5;           \
460         ADD     R6, R5;                         \
461         ADD     R6, R3;                         \
462         SUB     R6, R4;                         \
463         BL      callRet<>(SB);                  \
464         RET
465
466 // callRet copies return values back at the end of call*. This is a
467 // separate function so it can allocate stack space for the arguments
468 // to reflectcallmove. It does not follow the Go ABI; it expects its
469 // arguments in registers.
470 TEXT callRet<>(SB), NOSPLIT, $40-0
471         NO_LOCAL_POINTERS
472         MOVD    R7, FIXED_FRAME+0(R1)
473         MOVD    R3, FIXED_FRAME+8(R1)
474         MOVD    R5, FIXED_FRAME+16(R1)
475         MOVD    R4, FIXED_FRAME+24(R1)
476         MOVD    R20, FIXED_FRAME+32(R1)
477         BL      runtime·reflectcallmove(SB)
478         RET
479
480 CALLFN(·call16, 16)
481 CALLFN(·call32, 32)
482 CALLFN(·call64, 64)
483 CALLFN(·call128, 128)
484 CALLFN(·call256, 256)
485 CALLFN(·call512, 512)
486 CALLFN(·call1024, 1024)
487 CALLFN(·call2048, 2048)
488 CALLFN(·call4096, 4096)
489 CALLFN(·call8192, 8192)
490 CALLFN(·call16384, 16384)
491 CALLFN(·call32768, 32768)
492 CALLFN(·call65536, 65536)
493 CALLFN(·call131072, 131072)
494 CALLFN(·call262144, 262144)
495 CALLFN(·call524288, 524288)
496 CALLFN(·call1048576, 1048576)
497 CALLFN(·call2097152, 2097152)
498 CALLFN(·call4194304, 4194304)
499 CALLFN(·call8388608, 8388608)
500 CALLFN(·call16777216, 16777216)
501 CALLFN(·call33554432, 33554432)
502 CALLFN(·call67108864, 67108864)
503 CALLFN(·call134217728, 134217728)
504 CALLFN(·call268435456, 268435456)
505 CALLFN(·call536870912, 536870912)
506 CALLFN(·call1073741824, 1073741824)
507
508 TEXT runtime·procyield(SB),NOSPLIT|NOFRAME,$0-4
509         MOVW    cycles+0(FP), R7
510         // POWER does not have a pause/yield instruction equivalent.
511         // Instead, we can lower the program priority by setting the
512         // Program Priority Register prior to the wait loop and set it
513         // back to default afterwards. On Linux, the default priority is
514         // medium-low. For details, see page 837 of the ISA 3.0.
515         OR      R1, R1, R1      // Set PPR priority to low
516 again:
517         SUB     $1, R7
518         CMP     $0, R7
519         BNE     again
520         OR      R6, R6, R6      // Set PPR priority back to medium-low
521         RET
522
523 // Save state of caller into g->sched,
524 // but using fake PC from systemstack_switch.
525 // Must only be called from functions with no locals ($0)
526 // or else unwinding from systemstack_switch is incorrect.
527 // Smashes R31.
528 TEXT gosave_systemstack_switch<>(SB),NOSPLIT|NOFRAME,$0
529         MOVD    $runtime·systemstack_switch(SB), R31
530         ADD     $16, R31 // get past prologue (including r2-setting instructions when they're there)
531         MOVD    R31, (g_sched+gobuf_pc)(g)
532         MOVD    R1, (g_sched+gobuf_sp)(g)
533         MOVD    R0, (g_sched+gobuf_lr)(g)
534         MOVD    R0, (g_sched+gobuf_ret)(g)
535         // Assert ctxt is zero. See func save.
536         MOVD    (g_sched+gobuf_ctxt)(g), R31
537         CMP     R0, R31
538         BEQ     2(PC)
539         BL      runtime·abort(SB)
540         RET
541
542 #ifdef GOOS_aix
543 #define asmcgocallSaveOffset cgoCalleeStackSize + 8
544 #else
545 #define asmcgocallSaveOffset cgoCalleeStackSize
546 #endif
547
548 // func asmcgocall(fn, arg unsafe.Pointer) int32
549 // Call fn(arg) on the scheduler stack,
550 // aligned appropriately for the gcc ABI.
551 // See cgocall.go for more details.
552 TEXT ·asmcgocall(SB),NOSPLIT,$0-20
553         MOVD    fn+0(FP), R3
554         MOVD    arg+8(FP), R4
555
556         MOVD    R1, R7          // save original stack pointer
557         MOVD    g, R5
558
559         // Figure out if we need to switch to m->g0 stack.
560         // We get called to create new OS threads too, and those
561         // come in on the m->g0 stack already. Or we might already
562         // be on the m->gsignal stack.
563         MOVD    g_m(g), R8
564         MOVD    m_gsignal(R8), R6
565         CMP     R6, g
566         BEQ     g0
567         MOVD    m_g0(R8), R6
568         CMP     R6, g
569         BEQ     g0
570         BL      gosave_systemstack_switch<>(SB)
571         MOVD    R6, g
572         BL      runtime·save_g(SB)
573         MOVD    (g_sched+gobuf_sp)(g), R1
574
575         // Now on a scheduling stack (a pthread-created stack).
576 g0:
577 #ifdef GOOS_aix
578         // Create a fake LR to improve backtrace.
579         MOVD    $runtime·asmcgocall(SB), R6
580         MOVD    R6, 16(R1)
581         // AIX also save one argument on the stack.
582         SUB $8, R1
583 #endif
584         // Save room for two of our pointers, plus the callee
585         // save area that lives on the caller stack.
586         SUB     $(asmcgocallSaveOffset+16), R1
587         RLDCR   $0, R1, $~15, R1        // 16-byte alignment for gcc ABI
588         MOVD    R5, (asmcgocallSaveOffset+8)(R1)// save old g on stack
589         MOVD    (g_stack+stack_hi)(R5), R5
590         SUB     R7, R5
591         MOVD    R5, asmcgocallSaveOffset(R1)    // save depth in old g stack (can't just save SP, as stack might be copied during a callback)
592 #ifdef GOOS_aix
593         MOVD    R7, 0(R1)       // Save frame pointer to allow manual backtrace with gdb
594 #else
595         MOVD    R0, 0(R1)       // clear back chain pointer (TODO can we give it real back trace information?)
596 #endif
597         // This is a "global call", so put the global entry point in r12
598         MOVD    R3, R12
599
600 #ifdef GO_PPC64X_HAS_FUNCDESC
601         // Load the real entry address from the first slot of the function descriptor.
602         MOVD    8(R12), R2
603         MOVD    (R12), R12
604 #endif
605         MOVD    R12, CTR
606         MOVD    R4, R3          // arg in r3
607         BL      (CTR)
608         // C code can clobber R0, so set it back to 0. F27-F31 are
609         // callee save, so we don't need to recover those.
610         XOR     R0, R0
611         // Restore g, stack pointer, toc pointer.
612         // R3 is errno, so don't touch it
613         MOVD    (asmcgocallSaveOffset+8)(R1), g
614         MOVD    (g_stack+stack_hi)(g), R5
615         MOVD    asmcgocallSaveOffset(R1), R6
616         SUB     R6, R5
617 #ifndef GOOS_aix
618         MOVD    24(R5), R2
619 #endif
620         MOVD    R5, R1
621         BL      runtime·save_g(SB)
622
623         MOVW    R3, ret+16(FP)
624         RET
625
626 // func cgocallback(fn, frame unsafe.Pointer, ctxt uintptr)
627 // See cgocall.go for more details.
628 TEXT ·cgocallback(SB),NOSPLIT,$24-24
629         NO_LOCAL_POINTERS
630
631         // Skip cgocallbackg, just dropm when fn is nil, and frame is the saved g.
632         // It is used to dropm while thread is exiting.
633         MOVD    fn+0(FP), R5
634         CMP     R5, $0
635         BNE     loadg
636         // Restore the g from frame.
637         MOVD    frame+8(FP), g
638         BR      dropm
639
640 loadg:
641         // Load m and g from thread-local storage.
642         MOVBZ   runtime·iscgo(SB), R3
643         CMP     R3, $0
644         BEQ     nocgo
645         BL      runtime·load_g(SB)
646 nocgo:
647
648         // If g is nil, Go did not create the current thread,
649         // or if this thread never called into Go on pthread platforms.
650         // Call needm to obtain one for temporary use.
651         // In this case, we're running on the thread stack, so there's
652         // lots of space, but the linker doesn't know. Hide the call from
653         // the linker analysis by using an indirect call.
654         CMP     g, $0
655         BEQ     needm
656
657         MOVD    g_m(g), R8
658         MOVD    R8, savedm-8(SP)
659         BR      havem
660
661 needm:
662         MOVD    g, savedm-8(SP) // g is zero, so is m.
663         MOVD    $runtime·needAndBindM(SB), R12
664         MOVD    R12, CTR
665         BL      (CTR)
666
667         // Set m->sched.sp = SP, so that if a panic happens
668         // during the function we are about to execute, it will
669         // have a valid SP to run on the g0 stack.
670         // The next few lines (after the havem label)
671         // will save this SP onto the stack and then write
672         // the same SP back to m->sched.sp. That seems redundant,
673         // but if an unrecovered panic happens, unwindm will
674         // restore the g->sched.sp from the stack location
675         // and then systemstack will try to use it. If we don't set it here,
676         // that restored SP will be uninitialized (typically 0) and
677         // will not be usable.
678         MOVD    g_m(g), R8
679         MOVD    m_g0(R8), R3
680         MOVD    R1, (g_sched+gobuf_sp)(R3)
681
682 havem:
683         // Now there's a valid m, and we're running on its m->g0.
684         // Save current m->g0->sched.sp on stack and then set it to SP.
685         // Save current sp in m->g0->sched.sp in preparation for
686         // switch back to m->curg stack.
687         // NOTE: unwindm knows that the saved g->sched.sp is at 8(R1) aka savedsp-16(SP).
688         MOVD    m_g0(R8), R3
689         MOVD    (g_sched+gobuf_sp)(R3), R4
690         MOVD    R4, savedsp-24(SP)      // must match frame size
691         MOVD    R1, (g_sched+gobuf_sp)(R3)
692
693         // Switch to m->curg stack and call runtime.cgocallbackg.
694         // Because we are taking over the execution of m->curg
695         // but *not* resuming what had been running, we need to
696         // save that information (m->curg->sched) so we can restore it.
697         // We can restore m->curg->sched.sp easily, because calling
698         // runtime.cgocallbackg leaves SP unchanged upon return.
699         // To save m->curg->sched.pc, we push it onto the curg stack and
700         // open a frame the same size as cgocallback's g0 frame.
701         // Once we switch to the curg stack, the pushed PC will appear
702         // to be the return PC of cgocallback, so that the traceback
703         // will seamlessly trace back into the earlier calls.
704         MOVD    m_curg(R8), g
705         BL      runtime·save_g(SB)
706         MOVD    (g_sched+gobuf_sp)(g), R4 // prepare stack as R4
707         MOVD    (g_sched+gobuf_pc)(g), R5
708         MOVD    R5, -(24+FIXED_FRAME)(R4)       // "saved LR"; must match frame size
709         // Gather our arguments into registers.
710         MOVD    fn+0(FP), R5
711         MOVD    frame+8(FP), R6
712         MOVD    ctxt+16(FP), R7
713         MOVD    $-(24+FIXED_FRAME)(R4), R1      // switch stack; must match frame size
714         MOVD    R5, FIXED_FRAME+0(R1)
715         MOVD    R6, FIXED_FRAME+8(R1)
716         MOVD    R7, FIXED_FRAME+16(R1)
717
718         MOVD    $runtime·cgocallbackg(SB), R12
719         MOVD    R12, CTR
720         CALL    (CTR) // indirect call to bypass nosplit check. We're on a different stack now.
721
722         // Restore g->sched (== m->curg->sched) from saved values.
723         MOVD    0(R1), R5
724         MOVD    R5, (g_sched+gobuf_pc)(g)
725         MOVD    $(24+FIXED_FRAME)(R1), R4       // must match frame size
726         MOVD    R4, (g_sched+gobuf_sp)(g)
727
728         // Switch back to m->g0's stack and restore m->g0->sched.sp.
729         // (Unlike m->curg, the g0 goroutine never uses sched.pc,
730         // so we do not have to restore it.)
731         MOVD    g_m(g), R8
732         MOVD    m_g0(R8), g
733         BL      runtime·save_g(SB)
734         MOVD    (g_sched+gobuf_sp)(g), R1
735         MOVD    savedsp-24(SP), R4      // must match frame size
736         MOVD    R4, (g_sched+gobuf_sp)(g)
737
738         // If the m on entry was nil, we called needm above to borrow an m,
739         // 1. for the duration of the call on non-pthread platforms,
740         // 2. or the duration of the C thread alive on pthread platforms.
741         // If the m on entry wasn't nil,
742         // 1. the thread might be a Go thread,
743         // 2. or it's wasn't the first call from a C thread on pthread platforms,
744         //    since the we skip dropm to resue the m in the first call.
745         MOVD    savedm-8(SP), R6
746         CMP     R6, $0
747         BNE     droppedm
748
749         // Skip dropm to reuse it in the next call, when a pthread key has been created.
750         MOVD    _cgo_pthread_key_created(SB), R6
751         // It means cgo is disabled when _cgo_pthread_key_created is a nil pointer, need dropm.
752         CMP     R6, $0
753         BEQ     dropm
754         MOVD    (R6), R6
755         CMP     R6, $0
756         BNE     droppedm
757
758 dropm:
759         MOVD    $runtime·dropm(SB), R12
760         MOVD    R12, CTR
761         BL      (CTR)
762 droppedm:
763
764         // Done!
765         RET
766
767 // void setg(G*); set g. for use by needm.
768 TEXT runtime·setg(SB), NOSPLIT, $0-8
769         MOVD    gg+0(FP), g
770         // This only happens if iscgo, so jump straight to save_g
771         BL      runtime·save_g(SB)
772         RET
773
774 #ifdef GOARCH_ppc64
775 #ifdef GOOS_aix
776 DATA    setg_gcc<>+0(SB)/8, $_setg_gcc<>(SB)
777 DATA    setg_gcc<>+8(SB)/8, $TOC(SB)
778 DATA    setg_gcc<>+16(SB)/8, $0
779 GLOBL   setg_gcc<>(SB), NOPTR, $24
780 #else
781 TEXT setg_gcc<>(SB),NOSPLIT|NOFRAME,$0-0
782         DWORD   $_setg_gcc<>(SB)
783         DWORD   $0
784         DWORD   $0
785 #endif
786 #endif
787
788 // void setg_gcc(G*); set g in C TLS.
789 // Must obey the gcc calling convention.
790 #ifdef GOARCH_ppc64le
791 TEXT setg_gcc<>(SB),NOSPLIT|NOFRAME,$0-0
792 #else
793 TEXT _setg_gcc<>(SB),NOSPLIT|NOFRAME,$0-0
794 #endif
795         // The standard prologue clobbers R31, which is callee-save in
796         // the C ABI, so we have to use $-8-0 and save LR ourselves.
797         MOVD    LR, R4
798         // Also save g and R31, since they're callee-save in C ABI
799         MOVD    R31, R5
800         MOVD    g, R6
801
802         MOVD    R3, g
803         BL      runtime·save_g(SB)
804
805         MOVD    R6, g
806         MOVD    R5, R31
807         MOVD    R4, LR
808         RET
809
810 TEXT runtime·abort(SB),NOSPLIT|NOFRAME,$0-0
811         MOVW    (R0), R0
812         UNDEF
813
814 #define TBR     268
815
816 // int64 runtime·cputicks(void)
817 TEXT runtime·cputicks(SB),NOSPLIT,$0-8
818         MOVD    SPR(TBR), R3
819         MOVD    R3, ret+0(FP)
820         RET
821
822 // spillArgs stores return values from registers to a *internal/abi.RegArgs in R20.
823 TEXT runtime·spillArgs(SB),NOSPLIT,$0-0
824         MOVD    R3, 0(R20)
825         MOVD    R4, 8(R20)
826         MOVD    R5, 16(R20)
827         MOVD    R6, 24(R20)
828         MOVD    R7, 32(R20)
829         MOVD    R8, 40(R20)
830         MOVD    R9, 48(R20)
831         MOVD    R10, 56(R20)
832         MOVD    R14, 64(R20)
833         MOVD    R15, 72(R20)
834         MOVD    R16, 80(R20)
835         MOVD    R17, 88(R20)
836         FMOVD   F1, 96(R20)
837         FMOVD   F2, 104(R20)
838         FMOVD   F3, 112(R20)
839         FMOVD   F4, 120(R20)
840         FMOVD   F5, 128(R20)
841         FMOVD   F6, 136(R20)
842         FMOVD   F7, 144(R20)
843         FMOVD   F8, 152(R20)
844         FMOVD   F9, 160(R20)
845         FMOVD   F10, 168(R20)
846         FMOVD   F11, 176(R20)
847         FMOVD   F12, 184(R20)
848         RET
849
850 // unspillArgs loads args into registers from a *internal/abi.RegArgs in R20.
851 TEXT runtime·unspillArgs(SB),NOSPLIT,$0-0
852         MOVD    0(R20), R3
853         MOVD    8(R20), R4
854         MOVD    16(R20), R5
855         MOVD    24(R20), R6
856         MOVD    32(R20), R7
857         MOVD    40(R20), R8
858         MOVD    48(R20), R9
859         MOVD    56(R20), R10
860         MOVD    64(R20), R14
861         MOVD    72(R20), R15
862         MOVD    80(R20), R16
863         MOVD    88(R20), R17
864         FMOVD   96(R20), F1
865         FMOVD   104(R20), F2
866         FMOVD   112(R20), F3
867         FMOVD   120(R20), F4
868         FMOVD   128(R20), F5
869         FMOVD   136(R20), F6
870         FMOVD   144(R20), F7
871         FMOVD   152(R20), F8
872         FMOVD   160(R20), F9
873         FMOVD   168(R20), F10
874         FMOVD   176(R20), F11
875         FMOVD   184(R20), F12
876         RET
877
878 // AES hashing not implemented for ppc64
879 TEXT runtime·memhash<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-32
880         JMP     runtime·memhashFallback<ABIInternal>(SB)
881 TEXT runtime·strhash<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-24
882         JMP     runtime·strhashFallback<ABIInternal>(SB)
883 TEXT runtime·memhash32<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-24
884         JMP     runtime·memhash32Fallback<ABIInternal>(SB)
885 TEXT runtime·memhash64<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-24
886         JMP     runtime·memhash64Fallback<ABIInternal>(SB)
887
888 TEXT runtime·return0(SB), NOSPLIT, $0
889         MOVW    $0, R3
890         RET
891
892 // Called from cgo wrappers, this function returns g->m->curg.stack.hi.
893 // Must obey the gcc calling convention.
894 #ifdef GOOS_aix
895 // On AIX, _cgo_topofstack is defined in runtime/cgo, because it must
896 // be a longcall in order to prevent trampolines from ld.
897 TEXT __cgo_topofstack(SB),NOSPLIT|NOFRAME,$0
898 #else
899 TEXT _cgo_topofstack(SB),NOSPLIT|NOFRAME,$0
900 #endif
901         // g (R30) and R31 are callee-save in the C ABI, so save them
902         MOVD    g, R4
903         MOVD    R31, R5
904         MOVD    LR, R6
905
906         BL      runtime·load_g(SB)     // clobbers g (R30), R31
907         MOVD    g_m(g), R3
908         MOVD    m_curg(R3), R3
909         MOVD    (g_stack+stack_hi)(R3), R3
910
911         MOVD    R4, g
912         MOVD    R5, R31
913         MOVD    R6, LR
914         RET
915
916 // The top-most function running on a goroutine
917 // returns to goexit+PCQuantum.
918 //
919 // When dynamically linking Go, it can be returned to from a function
920 // implemented in a different module and so needs to reload the TOC pointer
921 // from the stack (although this function declares that it does not set up x-a
922 // frame, newproc1 does in fact allocate one for goexit and saves the TOC
923 // pointer in the correct place).
924 // goexit+_PCQuantum is halfway through the usual global entry point prologue
925 // that derives r2 from r12 which is a bit silly, but not harmful.
926 TEXT runtime·goexit(SB),NOSPLIT|NOFRAME|TOPFRAME,$0-0
927         MOVD    24(R1), R2
928         BL      runtime·goexit1(SB)    // does not return
929         // traceback from goexit1 must hit code range of goexit
930         MOVD    R0, R0  // NOP
931
932 // prepGoExitFrame saves the current TOC pointer (i.e. the TOC pointer for the
933 // module containing runtime) to the frame that goexit will execute in when
934 // the goroutine exits. It's implemented in assembly mainly because that's the
935 // easiest way to get access to R2.
936 TEXT runtime·prepGoExitFrame(SB),NOSPLIT,$0-8
937         MOVD    sp+0(FP), R3
938         MOVD    R2, 24(R3)
939         RET
940
941 TEXT runtime·addmoduledata(SB),NOSPLIT|NOFRAME,$0-0
942         ADD     $-8, R1
943         MOVD    R31, 0(R1)
944         MOVD    runtime·lastmoduledatap(SB), R4
945         MOVD    R3, moduledata_next(R4)
946         MOVD    R3, runtime·lastmoduledatap(SB)
947         MOVD    0(R1), R31
948         ADD     $8, R1
949         RET
950
951 TEXT ·checkASM(SB),NOSPLIT,$0-1
952         MOVW    $1, R3
953         MOVB    R3, ret+0(FP)
954         RET
955
956 // gcWriteBarrier informs the GC about heap pointer writes.
957 //
958 // gcWriteBarrier does NOT follow the Go ABI. It accepts the
959 // number of bytes of buffer needed in R29, and returns a pointer
960 // to the buffer space in R29.
961 // It clobbers condition codes.
962 // It does not clobber R0 through R17 (except special registers),
963 // but may clobber any other register, *including* R31.
964 TEXT gcWriteBarrier<>(SB),NOSPLIT,$112
965         // The standard prologue clobbers R31.
966         // We use R18, R19, and R31 as scratch registers.
967 retry:
968         MOVD    g_m(g), R18
969         MOVD    m_p(R18), R18
970         MOVD    (p_wbBuf+wbBuf_next)(R18), R19
971         MOVD    (p_wbBuf+wbBuf_end)(R18), R31
972         // Increment wbBuf.next position.
973         ADD     R29, R19
974         // Is the buffer full?
975         CMPU    R31, R19
976         BLT     flush
977         // Commit to the larger buffer.
978         MOVD    R19, (p_wbBuf+wbBuf_next)(R18)
979         // Make return value (the original next position)
980         SUB     R29, R19, R29
981         RET
982
983 flush:
984         // Save registers R0 through R15 since these were not saved by the caller.
985         // We don't save all registers on ppc64 because it takes too much space.
986         MOVD    R20, (FIXED_FRAME+0)(R1)
987         MOVD    R21, (FIXED_FRAME+8)(R1)
988         // R0 is always 0, so no need to spill.
989         // R1 is SP.
990         // R2 is SB.
991         MOVD    R3, (FIXED_FRAME+16)(R1)
992         MOVD    R4, (FIXED_FRAME+24)(R1)
993         MOVD    R5, (FIXED_FRAME+32)(R1)
994         MOVD    R6, (FIXED_FRAME+40)(R1)
995         MOVD    R7, (FIXED_FRAME+48)(R1)
996         MOVD    R8, (FIXED_FRAME+56)(R1)
997         MOVD    R9, (FIXED_FRAME+64)(R1)
998         MOVD    R10, (FIXED_FRAME+72)(R1)
999         // R11, R12 may be clobbered by external-linker-inserted trampoline
1000         // R13 is REGTLS
1001         MOVD    R14, (FIXED_FRAME+80)(R1)
1002         MOVD    R15, (FIXED_FRAME+88)(R1)
1003         MOVD    R16, (FIXED_FRAME+96)(R1)
1004         MOVD    R17, (FIXED_FRAME+104)(R1)
1005
1006         CALL    runtime·wbBufFlush(SB)
1007
1008         MOVD    (FIXED_FRAME+0)(R1), R20
1009         MOVD    (FIXED_FRAME+8)(R1), R21
1010         MOVD    (FIXED_FRAME+16)(R1), R3
1011         MOVD    (FIXED_FRAME+24)(R1), R4
1012         MOVD    (FIXED_FRAME+32)(R1), R5
1013         MOVD    (FIXED_FRAME+40)(R1), R6
1014         MOVD    (FIXED_FRAME+48)(R1), R7
1015         MOVD    (FIXED_FRAME+56)(R1), R8
1016         MOVD    (FIXED_FRAME+64)(R1), R9
1017         MOVD    (FIXED_FRAME+72)(R1), R10
1018         MOVD    (FIXED_FRAME+80)(R1), R14
1019         MOVD    (FIXED_FRAME+88)(R1), R15
1020         MOVD    (FIXED_FRAME+96)(R1), R16
1021         MOVD    (FIXED_FRAME+104)(R1), R17
1022         JMP     retry
1023
1024 TEXT runtime·gcWriteBarrier1<ABIInternal>(SB),NOSPLIT,$0
1025         MOVD    $8, R29
1026         JMP     gcWriteBarrier<>(SB)
1027 TEXT runtime·gcWriteBarrier2<ABIInternal>(SB),NOSPLIT,$0
1028         MOVD    $16, R29
1029         JMP     gcWriteBarrier<>(SB)
1030 TEXT runtime·gcWriteBarrier3<ABIInternal>(SB),NOSPLIT,$0
1031         MOVD    $24, R29
1032         JMP     gcWriteBarrier<>(SB)
1033 TEXT runtime·gcWriteBarrier4<ABIInternal>(SB),NOSPLIT,$0
1034         MOVD    $32, R29
1035         JMP     gcWriteBarrier<>(SB)
1036 TEXT runtime·gcWriteBarrier5<ABIInternal>(SB),NOSPLIT,$0
1037         MOVD    $40, R29
1038         JMP     gcWriteBarrier<>(SB)
1039 TEXT runtime·gcWriteBarrier6<ABIInternal>(SB),NOSPLIT,$0
1040         MOVD    $48, R29
1041         JMP     gcWriteBarrier<>(SB)
1042 TEXT runtime·gcWriteBarrier7<ABIInternal>(SB),NOSPLIT,$0
1043         MOVD    $56, R29
1044         JMP     gcWriteBarrier<>(SB)
1045 TEXT runtime·gcWriteBarrier8<ABIInternal>(SB),NOSPLIT,$0
1046         MOVD    $64, R29
1047         JMP     gcWriteBarrier<>(SB)
1048
1049 // Note: these functions use a special calling convention to save generated code space.
1050 // Arguments are passed in registers, but the space for those arguments are allocated
1051 // in the caller's stack frame. These stubs write the args into that stack space and
1052 // then tail call to the corresponding runtime handler.
1053 // The tail call makes these stubs disappear in backtraces.
1054 TEXT runtime·panicIndex<ABIInternal>(SB),NOSPLIT,$0-16
1055         JMP     runtime·goPanicIndex<ABIInternal>(SB)
1056 TEXT runtime·panicIndexU<ABIInternal>(SB),NOSPLIT,$0-16
1057         JMP     runtime·goPanicIndexU<ABIInternal>(SB)
1058 TEXT runtime·panicSliceAlen<ABIInternal>(SB),NOSPLIT,$0-16
1059         MOVD    R4, R3
1060         MOVD    R5, R4
1061         JMP     runtime·goPanicSliceAlen<ABIInternal>(SB)
1062 TEXT runtime·panicSliceAlenU<ABIInternal>(SB),NOSPLIT,$0-16
1063         MOVD    R4, R3
1064         MOVD    R5, R4
1065         JMP     runtime·goPanicSliceAlenU<ABIInternal>(SB)
1066 TEXT runtime·panicSliceAcap<ABIInternal>(SB),NOSPLIT,$0-16
1067         MOVD    R4, R3
1068         MOVD    R5, R4
1069         JMP     runtime·goPanicSliceAcap<ABIInternal>(SB)
1070 TEXT runtime·panicSliceAcapU<ABIInternal>(SB),NOSPLIT,$0-16
1071         MOVD    R4, R3
1072         MOVD    R5, R4
1073         JMP     runtime·goPanicSliceAcapU<ABIInternal>(SB)
1074 TEXT runtime·panicSliceB<ABIInternal>(SB),NOSPLIT,$0-16
1075         JMP     runtime·goPanicSliceB<ABIInternal>(SB)
1076 TEXT runtime·panicSliceBU<ABIInternal>(SB),NOSPLIT,$0-16
1077         JMP     runtime·goPanicSliceBU<ABIInternal>(SB)
1078 TEXT runtime·panicSlice3Alen<ABIInternal>(SB),NOSPLIT,$0-16
1079         MOVD    R5, R3
1080         MOVD    R6, R4
1081         JMP     runtime·goPanicSlice3Alen<ABIInternal>(SB)
1082 TEXT runtime·panicSlice3AlenU<ABIInternal>(SB),NOSPLIT,$0-16
1083         MOVD    R5, R3
1084         MOVD    R6, R4
1085         JMP     runtime·goPanicSlice3AlenU<ABIInternal>(SB)
1086 TEXT runtime·panicSlice3Acap<ABIInternal>(SB),NOSPLIT,$0-16
1087         MOVD    R5, R3
1088         MOVD    R6, R4
1089         JMP     runtime·goPanicSlice3Acap<ABIInternal>(SB)
1090 TEXT runtime·panicSlice3AcapU<ABIInternal>(SB),NOSPLIT,$0-16
1091         MOVD    R5, R3
1092         MOVD    R6, R4
1093         JMP     runtime·goPanicSlice3AcapU<ABIInternal>(SB)
1094 TEXT runtime·panicSlice3B<ABIInternal>(SB),NOSPLIT,$0-16
1095         MOVD    R4, R3
1096         MOVD    R5, R4
1097         JMP     runtime·goPanicSlice3B<ABIInternal>(SB)
1098 TEXT runtime·panicSlice3BU<ABIInternal>(SB),NOSPLIT,$0-16
1099         MOVD    R4, R3
1100         MOVD    R5, R4
1101         JMP     runtime·goPanicSlice3BU<ABIInternal>(SB)
1102 TEXT runtime·panicSlice3C<ABIInternal>(SB),NOSPLIT,$0-16
1103         JMP     runtime·goPanicSlice3C<ABIInternal>(SB)
1104 TEXT runtime·panicSlice3CU<ABIInternal>(SB),NOSPLIT,$0-16
1105         JMP     runtime·goPanicSlice3CU<ABIInternal>(SB)
1106 TEXT runtime·panicSliceConvert<ABIInternal>(SB),NOSPLIT,$0-16
1107         MOVD    R5, R3
1108         MOVD    R6, R4
1109         JMP     runtime·goPanicSliceConvert<ABIInternal>(SB)
1110
1111 // These functions are used when internal linking cgo with external
1112 // objects compiled with the -Os on gcc. They reduce prologue/epilogue
1113 // size by deferring preservation of callee-save registers to a shared
1114 // function. These are defined in PPC64 ELFv2 2.3.3 (but also present
1115 // in ELFv1)
1116 //
1117 // These appear unused, but the linker will redirect calls to functions
1118 // like _savegpr0_14 or _restgpr1_14 to runtime.elf_savegpr0 or
1119 // runtime.elf_restgpr1 with an appropriate offset based on the number
1120 // register operations required when linking external objects which
1121 // make these calls. For GPR/FPR saves, the minimum register value is
1122 // 14, for VR it is 20.
1123 //
1124 // These are only used when linking such cgo code internally. Note, R12
1125 // and R0 may be used in different ways than regular ELF compliant
1126 // functions.
1127 TEXT runtime·elf_savegpr0(SB),NOSPLIT|NOFRAME,$0
1128         // R0 holds the LR of the caller's caller, R1 holds save location
1129         MOVD    R14, -144(R1)
1130         MOVD    R15, -136(R1)
1131         MOVD    R16, -128(R1)
1132         MOVD    R17, -120(R1)
1133         MOVD    R18, -112(R1)
1134         MOVD    R19, -104(R1)
1135         MOVD    R20, -96(R1)
1136         MOVD    R21, -88(R1)
1137         MOVD    R22, -80(R1)
1138         MOVD    R23, -72(R1)
1139         MOVD    R24, -64(R1)
1140         MOVD    R25, -56(R1)
1141         MOVD    R26, -48(R1)
1142         MOVD    R27, -40(R1)
1143         MOVD    R28, -32(R1)
1144         MOVD    R29, -24(R1)
1145         MOVD    g, -16(R1)
1146         MOVD    R31, -8(R1)
1147         MOVD    R0, 16(R1)
1148         RET
1149 TEXT runtime·elf_restgpr0(SB),NOSPLIT|NOFRAME,$0
1150         // R1 holds save location. This returns to the LR saved on stack (bypassing the caller)
1151         MOVD    -144(R1), R14
1152         MOVD    -136(R1), R15
1153         MOVD    -128(R1), R16
1154         MOVD    -120(R1), R17
1155         MOVD    -112(R1), R18
1156         MOVD    -104(R1), R19
1157         MOVD    -96(R1), R20
1158         MOVD    -88(R1), R21
1159         MOVD    -80(R1), R22
1160         MOVD    -72(R1), R23
1161         MOVD    -64(R1), R24
1162         MOVD    -56(R1), R25
1163         MOVD    -48(R1), R26
1164         MOVD    -40(R1), R27
1165         MOVD    -32(R1), R28
1166         MOVD    -24(R1), R29
1167         MOVD    -16(R1), g
1168         MOVD    -8(R1), R31
1169         MOVD    16(R1), R0      // Load and return to saved LR
1170         MOVD    R0, LR
1171         RET
1172 TEXT runtime·elf_savegpr1(SB),NOSPLIT|NOFRAME,$0
1173         // R12 holds the save location
1174         MOVD    R14, -144(R12)
1175         MOVD    R15, -136(R12)
1176         MOVD    R16, -128(R12)
1177         MOVD    R17, -120(R12)
1178         MOVD    R18, -112(R12)
1179         MOVD    R19, -104(R12)
1180         MOVD    R20, -96(R12)
1181         MOVD    R21, -88(R12)
1182         MOVD    R22, -80(R12)
1183         MOVD    R23, -72(R12)
1184         MOVD    R24, -64(R12)
1185         MOVD    R25, -56(R12)
1186         MOVD    R26, -48(R12)
1187         MOVD    R27, -40(R12)
1188         MOVD    R28, -32(R12)
1189         MOVD    R29, -24(R12)
1190         MOVD    g, -16(R12)
1191         MOVD    R31, -8(R12)
1192         RET
1193 TEXT runtime·elf_restgpr1(SB),NOSPLIT|NOFRAME,$0
1194         // R12 holds the save location
1195         MOVD    -144(R12), R14
1196         MOVD    -136(R12), R15
1197         MOVD    -128(R12), R16
1198         MOVD    -120(R12), R17
1199         MOVD    -112(R12), R18
1200         MOVD    -104(R12), R19
1201         MOVD    -96(R12), R20
1202         MOVD    -88(R12), R21
1203         MOVD    -80(R12), R22
1204         MOVD    -72(R12), R23
1205         MOVD    -64(R12), R24
1206         MOVD    -56(R12), R25
1207         MOVD    -48(R12), R26
1208         MOVD    -40(R12), R27
1209         MOVD    -32(R12), R28
1210         MOVD    -24(R12), R29
1211         MOVD    -16(R12), g
1212         MOVD    -8(R12), R31
1213         RET
1214 TEXT runtime·elf_savefpr(SB),NOSPLIT|NOFRAME,$0
1215         // R0 holds the LR of the caller's caller, R1 holds save location
1216         FMOVD   F14, -144(R1)
1217         FMOVD   F15, -136(R1)
1218         FMOVD   F16, -128(R1)
1219         FMOVD   F17, -120(R1)
1220         FMOVD   F18, -112(R1)
1221         FMOVD   F19, -104(R1)
1222         FMOVD   F20, -96(R1)
1223         FMOVD   F21, -88(R1)
1224         FMOVD   F22, -80(R1)
1225         FMOVD   F23, -72(R1)
1226         FMOVD   F24, -64(R1)
1227         FMOVD   F25, -56(R1)
1228         FMOVD   F26, -48(R1)
1229         FMOVD   F27, -40(R1)
1230         FMOVD   F28, -32(R1)
1231         FMOVD   F29, -24(R1)
1232         FMOVD   F30, -16(R1)
1233         FMOVD   F31, -8(R1)
1234         MOVD    R0, 16(R1)
1235         RET
1236 TEXT runtime·elf_restfpr(SB),NOSPLIT|NOFRAME,$0
1237         // R1 holds save location. This returns to the LR saved on stack (bypassing the caller)
1238         FMOVD   -144(R1), F14
1239         FMOVD   -136(R1), F15
1240         FMOVD   -128(R1), F16
1241         FMOVD   -120(R1), F17
1242         FMOVD   -112(R1), F18
1243         FMOVD   -104(R1), F19
1244         FMOVD   -96(R1), F20
1245         FMOVD   -88(R1), F21
1246         FMOVD   -80(R1), F22
1247         FMOVD   -72(R1), F23
1248         FMOVD   -64(R1), F24
1249         FMOVD   -56(R1), F25
1250         FMOVD   -48(R1), F26
1251         FMOVD   -40(R1), F27
1252         FMOVD   -32(R1), F28
1253         FMOVD   -24(R1), F29
1254         FMOVD   -16(R1), F30
1255         FMOVD   -8(R1), F31
1256         MOVD    16(R1), R0      // Load and return to saved LR
1257         MOVD    R0, LR
1258         RET
1259 TEXT runtime·elf_savevr(SB),NOSPLIT|NOFRAME,$0
1260         // R0 holds the save location, R12 is clobbered
1261         MOVD    $-192, R12
1262         STVX    V20, (R0+R12)
1263         MOVD    $-176, R12
1264         STVX    V21, (R0+R12)
1265         MOVD    $-160, R12
1266         STVX    V22, (R0+R12)
1267         MOVD    $-144, R12
1268         STVX    V23, (R0+R12)
1269         MOVD    $-128, R12
1270         STVX    V24, (R0+R12)
1271         MOVD    $-112, R12
1272         STVX    V25, (R0+R12)
1273         MOVD    $-96, R12
1274         STVX    V26, (R0+R12)
1275         MOVD    $-80, R12
1276         STVX    V27, (R0+R12)
1277         MOVD    $-64, R12
1278         STVX    V28, (R0+R12)
1279         MOVD    $-48, R12
1280         STVX    V29, (R0+R12)
1281         MOVD    $-32, R12
1282         STVX    V30, (R0+R12)
1283         MOVD    $-16, R12
1284         STVX    V31, (R0+R12)
1285         RET
1286 TEXT runtime·elf_restvr(SB),NOSPLIT|NOFRAME,$0
1287         // R0 holds the save location, R12 is clobbered
1288         MOVD    $-192, R12
1289         LVX     (R0+R12), V20
1290         MOVD    $-176, R12
1291         LVX     (R0+R12), V21
1292         MOVD    $-160, R12
1293         LVX     (R0+R12), V22
1294         MOVD    $-144, R12
1295         LVX     (R0+R12), V23
1296         MOVD    $-128, R12
1297         LVX     (R0+R12), V24
1298         MOVD    $-112, R12
1299         LVX     (R0+R12), V25
1300         MOVD    $-96, R12
1301         LVX     (R0+R12), V26
1302         MOVD    $-80, R12
1303         LVX     (R0+R12), V27
1304         MOVD    $-64, R12
1305         LVX     (R0+R12), V28
1306         MOVD    $-48, R12
1307         LVX     (R0+R12), V29
1308         MOVD    $-32, R12
1309         LVX     (R0+R12), V30
1310         MOVD    $-16, R12
1311         LVX     (R0+R12), V31
1312         RET