diff options
| author | Paul E. Murphy <murp@ibm.com> | 2021-03-09 16:55:22 -0600 |
|---|---|---|
| committer | Paul Murphy <murp@ibm.com> | 2023-02-28 15:06:46 +0000 |
| commit | 72301a9863fb43ff26e9779a086e02cf02031ceb (patch) | |
| tree | b7e140db740e0b104df15ba90f1de8a74b930d69 /src/cmd/asm | |
| parent | e8fbad5de87f34d2e7632f94cac418c7436174ce (diff) | |
| download | go-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')
| -rw-r--r-- | src/cmd/asm/internal/asm/endtoend_test.go | 12 | ||||
| -rw-r--r-- | src/cmd/asm/internal/asm/testdata/ppc64.s | 27 |
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 |
