summaryrefslogtreecommitdiffstats
path: root/src/runtime/cgo/gcc_aix_ppc64.S
blob: a00fae24d219e05d2f2047d5c4eb0e71426b7b41 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build ppc64
// +build aix

/*
 * void crosscall_ppc64(void (*fn)(void), void *g)
 *
 * Calling into the gc tool chain, where all registers are caller save.
 * Called from standard ppc64 C ABI, where r2, r14-r31, f14-f31 are
 * callee-save, so they must be saved explicitly.
 * AIX has a special assembly syntax and keywords that can be mixed with
 * Linux assembly.
 */
  .toc
  .csect .text[PR]
  .globl crosscall_ppc64
  .globl .crosscall_ppc64
  .csect crosscall_ppc64[DS]
crosscall_ppc64:
  .llong .crosscall_ppc64, TOC[tc0], 0
  .csect .text[PR]
.crosscall_ppc64:
	// Start with standard C stack frame layout and linkage
	mflr	0
	std	0, 16(1)	// Save LR in caller's frame
	std	2, 40(1)	// Save TOC in caller's frame
	bl	saveregs
	stdu	1, -296(1)

	// Set up Go ABI constant registers
	// Must match _cgo_reginit in runtime package.
	xor 0, 0, 0

	// Restore g pointer (r30 in Go ABI, which may have been clobbered by C)
	mr	30, 4

	// Call fn
	mr	12, 3
	mtctr	12
	bctrl

	addi	1, 1, 296
	bl	restoreregs
	ld	2, 40(1)
	ld	0, 16(1)
	mtlr	0
	blr

saveregs:
	// Save callee-save registers
	// 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
	std	14, -288(1)
	std	15, -280(1)
	std	16, -272(1)
	std	17, -264(1)
	std	18, -256(1)
	std	19, -248(1)
	std	20, -240(1)
	std	21, -232(1)
	std	22, -224(1)
	std	23, -216(1)
	std	24, -208(1)
	std	25, -200(1)
	std	26, -192(1)
	std	27, -184(1)
	std	28, -176(1)
	std	29, -168(1)
	std	30, -160(1)
	std	31, -152(1)
	stfd	14, -144(1)
	stfd	15, -136(1)
	stfd	16, -128(1)
	stfd	17, -120(1)
	stfd	18, -112(1)
	stfd	19, -104(1)
	stfd	20, -96(1)
	stfd	21, -88(1)
	stfd	22, -80(1)
	stfd	23, -72(1)
	stfd	24, -64(1)
	stfd	25, -56(1)
	stfd	26, -48(1)
	stfd	27, -40(1)
	stfd	28, -32(1)
	stfd	29, -24(1)
	stfd	30, -16(1)
	stfd	31, -8(1)

	blr

restoreregs:
	// 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
	ld	14, -288(1)
	ld	15, -280(1)
	ld	16, -272(1)
	ld	17, -264(1)
	ld	18, -256(1)
	ld	19, -248(1)
	ld	20, -240(1)
	ld	21, -232(1)
	ld	22, -224(1)
	ld	23, -216(1)
	ld	24, -208(1)
	ld	25, -200(1)
	ld	26, -192(1)
	ld	27, -184(1)
	ld	28, -176(1)
	ld	29, -168(1)
	ld	30, -160(1)
	ld	31, -152(1)
	lfd	14, -144(1)
	lfd	15, -136(1)
	lfd	16, -128(1)
	lfd	17, -120(1)
	lfd	18, -112(1)
	lfd	19, -104(1)
	lfd	20, -96(1)
	lfd	21, -88(1)
	lfd	22, -80(1)
	lfd	23, -72(1)
	lfd	24, -64(1)
	lfd	25, -56(1)
	lfd	26, -48(1)
	lfd	27, -40(1)
	lfd	28, -32(1)
	lfd	29, -24(1)
	lfd	30, -16(1)
	lfd	31, -8(1)

	blr