aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/asm/internal
diff options
context:
space:
mode:
authorPaul E. Murphy <murp@ibm.com>2021-03-09 16:55:22 -0600
committerPaul Murphy <murp@ibm.com>2023-02-28 15:06:46 +0000
commit72301a9863fb43ff26e9779a086e02cf02031ceb (patch)
treeb7e140db740e0b104df15ba90f1de8a74b930d69 /src/cmd/asm/internal
parente8fbad5de87f34d2e7632f94cac418c7436174ce (diff)
downloadgo-72301a9863fb43ff26e9779a086e02cf02031ceb.tar.xz
cmd/internal/obj: use prefix insn in MOV* opcodes for GOPPC64=power10
As background, Power10 adds prefixed load, store, and add immediate instructions which encode 34b signed displacements. Likewise, they also give the option to compute addresses against the PC. This enables using simpler PC relative (PC-rel) relocations instead of maintaining a dedicated pointer (the TOC) to the code/data blob on PPC64/linux. Similary, there are several Go opcodes where it can be advantageous to use prefixed instructions instead of composite sequences like oris/ori/add to implement "MOVD <big const>, Rx" or "ADD <big const>, Rx, Ry", or large offset load/stores like "MOVD <big constant>(Rx), Ry" using the same framework which dynamically configures optab. When selecting prefixed instruction forms, the assembler must also use new relocations. These new relocations are always PC-rel by design, thus code assembled as such has no implicit requirement to maintain a TOC pointer when assembling shared objects. Thus, we can safely avoid situations where some Go objects use a TOC pointer, and some do not. This greatly simplifies linking Go objects. For more details about the challenges of linking TOC and PC-rel compiled code, see the PPC64 ELFv2 ABI. The TOC pointer in R2 is still maintained in those build configurations which previously required it (e.x buildmode=pie). However, Go code built with PC-rel relocations does not require the TOC pointer. A future change could remove the overhead of maintaining a TOC pointer in those build configurations. This is enabled only for power10/ppc64le/linux. A final noteworthy difference between the prefixed and regular load/store instruction forms is the removal of the DS/DQ form restrictions. That is, the immediate operand does not need to be aligned. Updates #44549 Change-Id: If59c216d203c3eed963bfa08855e21771e6ed669 Reviewed-on: https://go-review.googlesource.com/c/go/+/355150 Reviewed-by: Michael Pratt <mpratt@google.com> Reviewed-by: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Lynn Boger <laboger@linux.vnet.ibm.com> Run-TryBot: Paul Murphy <murp@ibm.com>
Diffstat (limited to 'src/cmd/asm/internal')
-rw-r--r--src/cmd/asm/internal/asm/endtoend_test.go12
-rw-r--r--src/cmd/asm/internal/asm/testdata/ppc64.s27
2 files changed, 24 insertions, 15 deletions
diff --git a/src/cmd/asm/internal/asm/endtoend_test.go b/src/cmd/asm/internal/asm/endtoend_test.go
index 3928e364ab..ef41667c8e 100644
--- a/src/cmd/asm/internal/asm/endtoend_test.go
+++ b/src/cmd/asm/internal/asm/endtoend_test.go
@@ -457,10 +457,14 @@ func TestLOONG64Encoder(t *testing.T) {
}
func TestPPC64EndToEnd(t *testing.T) {
- testEndToEnd(t, "ppc64", "ppc64")
-
- // The assembler accepts all instructions irrespective of the GOPPC64 value.
- testEndToEnd(t, "ppc64", "ppc64_p10")
+ defer func(old int) { buildcfg.GOPPC64 = old }(buildcfg.GOPPC64)
+ for _, goppc64 := range []int{8, 9, 10} {
+ t.Logf("GOPPC64=power%d", goppc64)
+ buildcfg.GOPPC64 = goppc64
+ // Some pseudo-ops may assemble differently depending on GOPPC64
+ testEndToEnd(t, "ppc64", "ppc64")
+ testEndToEnd(t, "ppc64", "ppc64_p10")
+ }
}
func TestRISCVEndToEnd(t *testing.T) {
diff --git a/src/cmd/asm/internal/asm/testdata/ppc64.s b/src/cmd/asm/internal/asm/testdata/ppc64.s
index 367d7b77db..72ae796018 100644
--- a/src/cmd/asm/internal/asm/testdata/ppc64.s
+++ b/src/cmd/asm/internal/asm/testdata/ppc64.s
@@ -20,19 +20,19 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0
MOVD $65536, R6 // 64060001
MOVD $-32767, R5 // 38a08001
MOVD $-32768, R6 // 38c08000
- MOVD $1234567, R5 // 6405001260a5d687
+ MOVD $1234567, R5 // 6405001260a5d687 or 0600001238a0d687
MOVW $1, R3 // 38600001
MOVW $-1, R4 // 3880ffff
MOVW $65535, R5 // 6005ffff
MOVW $65536, R6 // 64060001
MOVW $-32767, R5 // 38a08001
MOVW $-32768, R6 // 38c08000
- MOVW $1234567, R5 // 6405001260a5d687
+ MOVW $1234567, R5 // 6405001260a5d687 or 0600001238a0d687
// Hex constant 0x80000001
- MOVW $2147483649, R5 // 6405800060a50001
- MOVD $2147483649, R5 // 6405800060a50001
+ MOVW $2147483649, R5 // 6405800060a50001 or 0600800038a00001
+ MOVD $2147483649, R5 // 6405800060a50001 or 0600800038a00001
// Hex constant 0xFFFFFFFF80000001
- MOVD $-2147483647, R5 // 3ca0800060a50001
+ MOVD $-2147483647, R5 // 3ca0800060a50001 or 0603800038a00001
MOVD 8(R3), R4 // e8830008
MOVD (R3)(R4), R5 // 7ca4182a
MOVD (R3)(R0), R5 // 7ca0182a
@@ -71,8 +71,8 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0
MOVHBR (R3)(R4), R5 // 7ca41e2c
MOVHBR (R3)(R0), R5 // 7ca01e2c
MOVHBR (R3), R5 // 7ca01e2c
- MOVD $foo+4009806848(FP), R5 // 3ca1ef0138a5cc40
- MOVD $foo(SB), R5 // 3ca0000038a50000
+ MOVD $foo+4009806848(FP), R5 // 3ca1ef0138a5cc40 or 0600ef0038a1cc40
+ MOVD $foo(SB), R5 // 3ca0000038a50000 or 0610000038a00000
MOVDU 8(R3), R4 // e8830009
MOVDU (R3)(R4), R5 // 7ca4186a
@@ -156,16 +156,21 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0
ADD $1, R3, R4 // 38830001
ADD $-1, R4 // 3884ffff
ADD $-1, R4, R5 // 38a4ffff
- ADD $65535, R5 // 601fffff7cbf2a14
- ADD $65535, R5, R6 // 601fffff7cdf2a14
+ ADD $65535, R5 // 601fffff7cbf2a14 or 0600000038a5ffff
+ ADD $65535, R5, R6 // 601fffff7cdf2a14 or 0600000038c5ffff
ADD $65536, R6 // 3cc60001
ADD $65536, R6, R7 // 3ce60001
ADD $-32767, R5 // 38a58001
ADD $-32767, R5, R4 // 38858001
ADD $-32768, R6 // 38c68000
ADD $-32768, R6, R5 // 38a68000
- ADD $1234567, R5 // 641f001263ffd6877cbf2a14
- ADD $1234567, R5, R6 // 641f001263ffd6877cdf2a14
+
+ //TODO: this compiles to add r5,r6,r0. It should be addi r5,r6,0.
+ // this is OK since r0 == $0, but the latter is preferred.
+ ADD $0, R6, R5 // 7ca60214
+
+ ADD $1234567, R5 // 641f001263ffd6877cbf2a14 or 0600001238a5d687
+ ADD $1234567, R5, R6 // 641f001263ffd6877cdf2a14 or 0600001238c5d687
ADDEX R3, R5, $3, R6 // 7cc32f54
ADDEX R3, $3, R5, R6 // 7cc32f54
ADDIS $8, R3 // 3c630008