Skip to content

Commit 72301a9

Browse files
committed
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 <[email protected]> Reviewed-by: Matthew Dempsky <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Lynn Boger <[email protected]> Run-TryBot: Paul Murphy <[email protected]>
1 parent e8fbad5 commit 72301a9

File tree

4 files changed

+293
-71
lines changed

4 files changed

+293
-71
lines changed

src/cmd/asm/internal/asm/endtoend_test.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -457,10 +457,14 @@ func TestLOONG64Encoder(t *testing.T) {
457457
}
458458

459459
func TestPPC64EndToEnd(t *testing.T) {
460-
testEndToEnd(t, "ppc64", "ppc64")
461-
462-
// The assembler accepts all instructions irrespective of the GOPPC64 value.
463-
testEndToEnd(t, "ppc64", "ppc64_p10")
460+
defer func(old int) { buildcfg.GOPPC64 = old }(buildcfg.GOPPC64)
461+
for _, goppc64 := range []int{8, 9, 10} {
462+
t.Logf("GOPPC64=power%d", goppc64)
463+
buildcfg.GOPPC64 = goppc64
464+
// Some pseudo-ops may assemble differently depending on GOPPC64
465+
testEndToEnd(t, "ppc64", "ppc64")
466+
testEndToEnd(t, "ppc64", "ppc64_p10")
467+
}
464468
}
465469

466470
func TestRISCVEndToEnd(t *testing.T) {

src/cmd/asm/internal/asm/testdata/ppc64.s

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,19 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0
2020
MOVD $65536, R6 // 64060001
2121
MOVD $-32767, R5 // 38a08001
2222
MOVD $-32768, R6 // 38c08000
23-
MOVD $1234567, R5 // 6405001260a5d687
23+
MOVD $1234567, R5 // 6405001260a5d687 or 0600001238a0d687
2424
MOVW $1, R3 // 38600001
2525
MOVW $-1, R4 // 3880ffff
2626
MOVW $65535, R5 // 6005ffff
2727
MOVW $65536, R6 // 64060001
2828
MOVW $-32767, R5 // 38a08001
2929
MOVW $-32768, R6 // 38c08000
30-
MOVW $1234567, R5 // 6405001260a5d687
30+
MOVW $1234567, R5 // 6405001260a5d687 or 0600001238a0d687
3131
// Hex constant 0x80000001
32-
MOVW $2147483649, R5 // 6405800060a50001
33-
MOVD $2147483649, R5 // 6405800060a50001
32+
MOVW $2147483649, R5 // 6405800060a50001 or 0600800038a00001
33+
MOVD $2147483649, R5 // 6405800060a50001 or 0600800038a00001
3434
// Hex constant 0xFFFFFFFF80000001
35-
MOVD $-2147483647, R5 // 3ca0800060a50001
35+
MOVD $-2147483647, R5 // 3ca0800060a50001 or 0603800038a00001
3636
MOVD 8(R3), R4 // e8830008
3737
MOVD (R3)(R4), R5 // 7ca4182a
3838
MOVD (R3)(R0), R5 // 7ca0182a
@@ -71,8 +71,8 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0
7171
MOVHBR (R3)(R4), R5 // 7ca41e2c
7272
MOVHBR (R3)(R0), R5 // 7ca01e2c
7373
MOVHBR (R3), R5 // 7ca01e2c
74-
MOVD $foo+4009806848(FP), R5 // 3ca1ef0138a5cc40
75-
MOVD $foo(SB), R5 // 3ca0000038a50000
74+
MOVD $foo+4009806848(FP), R5 // 3ca1ef0138a5cc40 or 0600ef0038a1cc40
75+
MOVD $foo(SB), R5 // 3ca0000038a50000 or 0610000038a00000
7676

7777
MOVDU 8(R3), R4 // e8830009
7878
MOVDU (R3)(R4), R5 // 7ca4186a
@@ -156,16 +156,21 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0
156156
ADD $1, R3, R4 // 38830001
157157
ADD $-1, R4 // 3884ffff
158158
ADD $-1, R4, R5 // 38a4ffff
159-
ADD $65535, R5 // 601fffff7cbf2a14
160-
ADD $65535, R5, R6 // 601fffff7cdf2a14
159+
ADD $65535, R5 // 601fffff7cbf2a14 or 0600000038a5ffff
160+
ADD $65535, R5, R6 // 601fffff7cdf2a14 or 0600000038c5ffff
161161
ADD $65536, R6 // 3cc60001
162162
ADD $65536, R6, R7 // 3ce60001
163163
ADD $-32767, R5 // 38a58001
164164
ADD $-32767, R5, R4 // 38858001
165165
ADD $-32768, R6 // 38c68000
166166
ADD $-32768, R6, R5 // 38a68000
167-
ADD $1234567, R5 // 641f001263ffd6877cbf2a14
168-
ADD $1234567, R5, R6 // 641f001263ffd6877cdf2a14
167+
168+
//TODO: this compiles to add r5,r6,r0. It should be addi r5,r6,0.
169+
// this is OK since r0 == $0, but the latter is preferred.
170+
ADD $0, R6, R5 // 7ca60214
171+
172+
ADD $1234567, R5 // 641f001263ffd6877cbf2a14 or 0600001238a5d687
173+
ADD $1234567, R5, R6 // 641f001263ffd6877cdf2a14 or 0600001238c5d687
169174
ADDEX R3, R5, $3, R6 // 7cc32f54
170175
ADDEX R3, $3, R5, R6 // 7cc32f54
171176
ADDIS $8, R3 // 3c630008

0 commit comments

Comments
 (0)