From 851c5adf05dd07a9a3a4d2d52ce910fd8ddcdfa7 Mon Sep 17 00:00:00 2001
From: Clement <clement.chigot@atos.net>
Date: Fri, 25 Jan 2019 10:49:45 -0600
Subject: [PATCH 21/37] runtime/cgo: add port for aix/ppc64 and big-endian
 ppc64

---
 src/runtime/cgo/asm_ppc64x.s                  |  13 +-
 src/runtime/cgo/gcc_aix_ppc64.S               | 133 ++++++++++++++++++
 src/runtime/cgo/gcc_context.c                 |   2 +-
 src/runtime/cgo/gcc_fatalf.c                  |   2 +-
 src/runtime/cgo/gcc_libinit.c                 |   2 +-
 .../cgo/{gcc_ppc64x.S => gcc_linux_ppc64x.S}  |   1 +
 .../cgo/{gcc_linux_ppc64x.c => gcc_ppc64x.c}  |   0
 src/runtime/cgo/gcc_setenv.c                  |   2 +-
 src/runtime/cgo/setenv.go                     |   2 +-
 9 files changed, 148 insertions(+), 9 deletions(-)
 create mode 100644 src/runtime/cgo/gcc_aix_ppc64.S
 rename src/runtime/cgo/{gcc_ppc64x.S => gcc_linux_ppc64x.S} (99%)
 rename src/runtime/cgo/{gcc_linux_ppc64x.c => gcc_ppc64x.c} (100%)

diff --git a/src/runtime/cgo/asm_ppc64x.s b/src/runtime/cgo/asm_ppc64x.s
index 1cf27ddc96..3876f9389c 100644
--- a/src/runtime/cgo/asm_ppc64x.s
+++ b/src/runtime/cgo/asm_ppc64x.s
@@ -11,8 +11,6 @@
 // func crosscall2(fn func(a unsafe.Pointer, n int32, ctxt uintptr), a unsafe.Pointer, n int32, ctxt uintptr)
 // Saves C callee-saved registers and calls fn with three arguments.
 TEXT crosscall2(SB),NOSPLIT|NOFRAME,$0
-	// TODO(austin): ABI v1 (fn is probably a function descriptor)
-
 	// Start with standard C stack frame layout and linkage
 	MOVD	LR, R0
 	MOVD	R0, 16(R1)	// Save LR in caller's frame
@@ -29,9 +27,16 @@ TEXT crosscall2(SB),NOSPLIT|NOFRAME,$0
 	BL	runtime·load_g(SB)
 
 	MOVD	R3, R12
-	MOVD	R3, CTR
+#ifdef GOARCH_ppc64
+	// ppc64 use elf ABI v1. we must get the real entry address from
+	// first slot of the function descriptor before call.
+	// Same for AIX.
+	MOVD	8(R12), R2
+	MOVD	(R12), R12
+#endif
+	MOVD	R12, CTR
 	MOVD	R4, FIXED_FRAME+0(R1)
-	MOVD	R5, FIXED_FRAME+8(R1)
+	MOVW	R5, FIXED_FRAME+8(R1)
 	MOVD	R6, FIXED_FRAME+16(R1)
 	BL	(CTR)
 
diff --git a/src/runtime/cgo/gcc_aix_ppc64.S b/src/runtime/cgo/gcc_aix_ppc64.S
new file mode 100644
index 0000000000..ea1e4ceaaa
--- /dev/null
+++ b/src/runtime/cgo/gcc_aix_ppc64.S
@@ -0,0 +1,133 @@
+// Copyright 2014 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
+	bl	._cgo_reginit
+	nop
+
+	// 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
diff --git a/src/runtime/cgo/gcc_context.c b/src/runtime/cgo/gcc_context.c
index b46b6040d2..5fc0abb8bc 100644
--- a/src/runtime/cgo/gcc_context.c
+++ b/src/runtime/cgo/gcc_context.c
@@ -3,7 +3,7 @@
 // license that can be found in the LICENSE file.
 
 // +build cgo
-// +build darwin dragonfly freebsd linux netbsd openbsd solaris windows
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows
 
 #include "libcgo.h"
 
diff --git a/src/runtime/cgo/gcc_fatalf.c b/src/runtime/cgo/gcc_fatalf.c
index fdcf6f5e52..597e750f12 100644
--- a/src/runtime/cgo/gcc_fatalf.c
+++ b/src/runtime/cgo/gcc_fatalf.c
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !android,linux freebsd
+// +build aix !android,linux freebsd
 
 #include <stdarg.h>
 #include <stdio.h>
diff --git a/src/runtime/cgo/gcc_libinit.c b/src/runtime/cgo/gcc_libinit.c
index 3dafd10b7b..d35726d953 100644
--- a/src/runtime/cgo/gcc_libinit.c
+++ b/src/runtime/cgo/gcc_libinit.c
@@ -3,7 +3,7 @@
 // license that can be found in the LICENSE file.
 
 // +build cgo
-// +build darwin dragonfly freebsd linux netbsd openbsd solaris
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 #include <pthread.h>
 #include <errno.h>
diff --git a/src/runtime/cgo/gcc_ppc64x.S b/src/runtime/cgo/gcc_linux_ppc64x.S
similarity index 99%
rename from src/runtime/cgo/gcc_ppc64x.S
rename to src/runtime/cgo/gcc_linux_ppc64x.S
index 5f37a8bfc1..595eb38460 100644
--- a/src/runtime/cgo/gcc_ppc64x.S
+++ b/src/runtime/cgo/gcc_linux_ppc64x.S
@@ -3,6 +3,7 @@
 // license that can be found in the LICENSE file.
 
 // +build ppc64 ppc64le
+// +build linux
 
 /*
  * Apple still insists on underscore prefixes for C function names.
diff --git a/src/runtime/cgo/gcc_linux_ppc64x.c b/src/runtime/cgo/gcc_ppc64x.c
similarity index 100%
rename from src/runtime/cgo/gcc_linux_ppc64x.c
rename to src/runtime/cgo/gcc_ppc64x.c
diff --git a/src/runtime/cgo/gcc_setenv.c b/src/runtime/cgo/gcc_setenv.c
index ed5d203fb0..88e92bfd8a 100644
--- a/src/runtime/cgo/gcc_setenv.c
+++ b/src/runtime/cgo/gcc_setenv.c
@@ -3,7 +3,7 @@
 // license that can be found in the LICENSE file.
 
 // +build cgo
-// +build darwin dragonfly freebsd linux netbsd openbsd solaris
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 #include "libcgo.h"
 
diff --git a/src/runtime/cgo/setenv.go b/src/runtime/cgo/setenv.go
index fab43399e2..6495fcb5f8 100644
--- a/src/runtime/cgo/setenv.go
+++ b/src/runtime/cgo/setenv.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build darwin dragonfly freebsd linux netbsd openbsd solaris
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package cgo
 
-- 
2.21.0

