1// Copyright 2019 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.file "gcc_aix_ppc64.S"
6
7/*
8 * void crosscall_ppc64(void (*fn)(void), void *g)
9 *
10 * Calling into the gc tool chain, where all registers are caller save.
11 * Called from standard ppc64 C ABI, where r2, r14-r31, f14-f31 are
12 * callee-save, so they must be saved explicitly.
13 * AIX has a special assembly syntax and keywords that can be mixed with
14 * Linux assembly.
15 */
16  .toc
17  .csect .text[PR]
18  .globl crosscall_ppc64
19  .globl .crosscall_ppc64
20  .csect crosscall_ppc64[DS]
21crosscall_ppc64:
22  .llong .crosscall_ppc64, TOC[tc0], 0
23  .csect .text[PR]
24.crosscall_ppc64:
25	// Start with standard C stack frame layout and linkage
26	mflr	0
27	std	0, 16(1)	// Save LR in caller's frame
28	std	2, 40(1)	// Save TOC in caller's frame
29	bl	saveregs
30	stdu	1, -296(1)
31
32	// Set up Go ABI constant registers
33	// Must match _cgo_reginit in runtime package.
34	xor 0, 0, 0
35
36	// Restore g pointer (r30 in Go ABI, which may have been clobbered by C)
37	mr	30, 4
38
39	// Call fn
40	mr	12, 3
41	mtctr	12
42	bctrl
43
44	addi	1, 1, 296
45	bl	restoreregs
46	ld	2, 40(1)
47	ld	0, 16(1)
48	mtlr	0
49	blr
50
51saveregs:
52	// Save callee-save registers
53	// O=-288; for R in {14..31}; do echo "\tstd\t$R, $O(1)"; ((O+=8)); done; for F in f{14..31}; do echo "\tstfd\t$F, $O(1)"; ((O+=8)); done
54	std	14, -288(1)
55	std	15, -280(1)
56	std	16, -272(1)
57	std	17, -264(1)
58	std	18, -256(1)
59	std	19, -248(1)
60	std	20, -240(1)
61	std	21, -232(1)
62	std	22, -224(1)
63	std	23, -216(1)
64	std	24, -208(1)
65	std	25, -200(1)
66	std	26, -192(1)
67	std	27, -184(1)
68	std	28, -176(1)
69	std	29, -168(1)
70	std	30, -160(1)
71	std	31, -152(1)
72	stfd	14, -144(1)
73	stfd	15, -136(1)
74	stfd	16, -128(1)
75	stfd	17, -120(1)
76	stfd	18, -112(1)
77	stfd	19, -104(1)
78	stfd	20, -96(1)
79	stfd	21, -88(1)
80	stfd	22, -80(1)
81	stfd	23, -72(1)
82	stfd	24, -64(1)
83	stfd	25, -56(1)
84	stfd	26, -48(1)
85	stfd	27, -40(1)
86	stfd	28, -32(1)
87	stfd	29, -24(1)
88	stfd	30, -16(1)
89	stfd	31, -8(1)
90
91	blr
92
93restoreregs:
94	// O=-288; for R in {14..31}; do echo "\tld\t$R, $O(1)"; ((O+=8)); done; for F in {14..31}; do echo "\tlfd\t$F, $O(1)"; ((O+=8)); done
95	ld	14, -288(1)
96	ld	15, -280(1)
97	ld	16, -272(1)
98	ld	17, -264(1)
99	ld	18, -256(1)
100	ld	19, -248(1)
101	ld	20, -240(1)
102	ld	21, -232(1)
103	ld	22, -224(1)
104	ld	23, -216(1)
105	ld	24, -208(1)
106	ld	25, -200(1)
107	ld	26, -192(1)
108	ld	27, -184(1)
109	ld	28, -176(1)
110	ld	29, -168(1)
111	ld	30, -160(1)
112	ld	31, -152(1)
113	lfd	14, -144(1)
114	lfd	15, -136(1)
115	lfd	16, -128(1)
116	lfd	17, -120(1)
117	lfd	18, -112(1)
118	lfd	19, -104(1)
119	lfd	20, -96(1)
120	lfd	21, -88(1)
121	lfd	22, -80(1)
122	lfd	23, -72(1)
123	lfd	24, -64(1)
124	lfd	25, -56(1)
125	lfd	26, -48(1)
126	lfd	27, -40(1)
127	lfd	28, -32(1)
128	lfd	29, -24(1)
129	lfd	30, -16(1)
130	lfd	31, -8(1)
131
132	blr
133