From 916e682d5167faad1bb961ec28cac74f05f145f7 Mon Sep 17 00:00:00 2001 From: Xiaolin Zhao Date: Wed, 24 Sep 2025 17:21:40 +0800 Subject: [PATCH] cmd/internal/obj, cmd/asm: reclassify the offset of memory access operations on loong64 This CL also fixes the encoding error of LL/SC[V] instruction and adds the handling of offset greater than 16 bits in MOV{W/V}P instructions. Change-Id: I7a8fab4b68a6839da81c5e59af1f42289d00ef61 Reviewed-on: https://go-review.googlesource.com/c/go/+/706435 Reviewed-by: David Chase Reviewed-by: Meidan Li LUCI-TryBot-Result: Go LUCI Reviewed-by: abner chenc Reviewed-by: Michael Knyszek --- src/cmd/asm/internal/asm/endtoend_test.go | 1 + .../asm/internal/asm/testdata/loong64enc1.s | 12 +- .../asm/internal/asm/testdata/loong64enc3.s | 21 +- .../asm/internal/asm/testdata/loong64enc6.s | 12 + .../asm/internal/asm/testdata/loong64error.s | 5 + src/cmd/internal/obj/loong64/a.out.go | 22 +- src/cmd/internal/obj/loong64/asm.go | 206 ++++++++++++------ 7 files changed, 195 insertions(+), 84 deletions(-) create mode 100644 src/cmd/asm/internal/asm/testdata/loong64enc6.s diff --git a/src/cmd/asm/internal/asm/endtoend_test.go b/src/cmd/asm/internal/asm/endtoend_test.go index afaf02815f..9571afc326 100644 --- a/src/cmd/asm/internal/asm/endtoend_test.go +++ b/src/cmd/asm/internal/asm/endtoend_test.go @@ -467,6 +467,7 @@ func TestLOONG64Encoder(t *testing.T) { testEndToEnd(t, "loong64", "loong64enc3") testEndToEnd(t, "loong64", "loong64enc4") testEndToEnd(t, "loong64", "loong64enc5") + testEndToEnd(t, "loong64", "loong64enc6") testEndToEnd(t, "loong64", "loong64") } diff --git a/src/cmd/asm/internal/asm/testdata/loong64enc1.s b/src/cmd/asm/internal/asm/testdata/loong64enc1.s index fd86db7a4f..6e2a86969d 100644 --- a/src/cmd/asm/internal/asm/testdata/loong64enc1.s +++ b/src/cmd/asm/internal/asm/testdata/loong64enc1.s @@ -93,8 +93,8 @@ lable2: MOVV R4, 1(R5) // a404c029 MOVB R4, 1(R5) // a4040029 MOVBU R4, 1(R5) // a4040029 - SC R4, 1(R5) // a4040021 - SCV R4, 1(R5) // a4040023 + SC R4, 4096(R5) // a4001021 + SCV R4, 4096(R5) // a4001023 MOVW y+8(FP), R4 // 64408028 MOVWU y+8(FP), R4 // 6440802a MOVV y+8(FP), R4 // 6440c028 @@ -105,8 +105,8 @@ lable2: MOVV 1(R5), R4 // a404c028 MOVB 1(R5), R4 // a4040028 MOVBU 1(R5), R4 // a404002a - LL 1(R5), R4 // a4040020 - LLV 1(R5), R4 // a4040022 + LL 4096(R5), R4 // a4001020 + LLV 4096(R5), R4 // a4001022 MOVW $4(R4), R5 // 8510c002 MOVV $4(R4), R5 // 8510c002 MOVW $-1, R4 // 04fcff02 @@ -261,22 +261,18 @@ lable2: MOVV R4, FCC0 // 80d81401 // LDPTR.{W/D} and STPTR.{W/D} instructions - MOVWP R5, -32768(R4) // 85008025 MOVWP R5, 32764(R4) // 85fc7f25 MOVWP R5, 32(R4) // 85200025 MOVWP R5, 4(R4) // 85040025 MOVWP R5, (R4) // 85000025 - MOVVP R5, -32768(R4) // 85008027 MOVVP R5, 32764(R4) // 85fc7f27 MOVVP R5, 32(R4) // 85200027 MOVVP R5, 4(R4) // 85040027 MOVVP R5, (R4) // 85000027 - MOVWP -32768(R5), R4 // a4008024 MOVWP 32764(R5), R4 // a4fc7f24 MOVWP 32(R5), R4 // a4200024 MOVWP 4(R5), R4 // a4040024 MOVWP (R5), R4 // a4000024 - MOVVP -32768(R5), R4 // a4008026 MOVVP 32764(R5), R4 // a4fc7f26 MOVVP 32(R5), R4 // a4200026 MOVVP 4(R5), R4 // a4040026 diff --git a/src/cmd/asm/internal/asm/testdata/loong64enc3.s b/src/cmd/asm/internal/asm/testdata/loong64enc3.s index 2d83bd719a..2dc6529dcb 100644 --- a/src/cmd/asm/internal/asm/testdata/loong64enc3.s +++ b/src/cmd/asm/internal/asm/testdata/loong64enc3.s @@ -42,8 +42,10 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0 MOVB R4, 4096(R5) // 3e000014de971000c4030029 MOVBU R4, 65536(R5) // 1e020014de971000c4030029 MOVBU R4, 4096(R5) // 3e000014de971000c4030029 - SC R4, 65536(R5) // 1e020014de971000c4030021 - SC R4, 4096(R5) // 3e000014de971000c4030021 + SC R4, 65536(R5) // 1e040010de971000c4030021 + SCV R4, 65536(R5) // 1e040010de971000c4030023 + LL 65536(R5), R4 // 1e040010de971000c4030020 + LLV 65536(R5), R4 // 1e040010de971000c4030022 MOVW y+65540(FP), R4 // 1e020014de8f1000c4338028 MOVWU y+65540(FP), R4 // 1e020014de8f1000c433802a MOVV y+65540(FP), R4 // 1e020014de8f1000c433c028 @@ -122,6 +124,21 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0 XOR $4097, R4 // 3e000014de07800384f81500 XOR $4097, R4, R5 // 3e000014de07800385f81500 + MOVWP R5, -32768(R4) // 1efcff13de931000c5038025 + MOVWP R5, 32768(R4) // 1e000010de931000c5038025 + MOVWP R5, 65536(R4) // 1e040010de931000c5030025 + MOVWP R5, 1048576(R4) // 1e400010de931000c5030025 + MOVVP R5, -32768(R4) // 1efcff13de931000c5038027 + MOVVP R5, 65536(R4) // 1e040010de931000c5030027 + MOVVP R5, 1048576(R4) // 1e400010de931000c5030027 + MOVWP -32768(R5), R4 // 1efcff13de971000c4038024 + MOVWP 2229248(R5), R4 // 1e880010de971000c4030424 + MOVWP -2145518592(R5), R4 // 1e740012de971000c403fc24 + MOVVP -32768(R5), R4 // 1efcff13de971000c4038026 + MOVVP 2229248(R5), R4 // 1e880010de971000c4030426 + MOVVP -2145518592(R5), R4 // 1e740012de971000c403fc26 + + // MOVV C_DCON32_12S, r MOVV $0x27312345fffff800, R4 // MOVV $2824077224892692480, R4 // 0400a002a468241684cc0903 MOVV $0xf7312345fffff800, R4 // MOVV $-634687288927848448, R4 // 0400a002a468241684cc3d03 diff --git a/src/cmd/asm/internal/asm/testdata/loong64enc6.s b/src/cmd/asm/internal/asm/testdata/loong64enc6.s new file mode 100644 index 0000000000..bd19ea7601 --- /dev/null +++ b/src/cmd/asm/internal/asm/testdata/loong64enc6.s @@ -0,0 +1,12 @@ +// Copyright 2025 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. + +#include "../../../../../runtime/textflag.h" + +TEXT asmtest(SB),DUPOK|NOSPLIT,$0 + // MOVWP LOREG_64(Rx), Ry + MOVWP 81985529216486896(R4), R5 // 9e571315dec3b703feac6816de4b000384f8100085000025 + MOVWP -81985529216486896(R4), R5 // 7ea8ec14de4388031e539717deb73f0384f8100085000025 + MOVWP R4, 81985529216486896(R5) // 9e571315dec3b703feac6816de4b0003a5f81000a4000025 + MOVWP R4, -81985529216486896(R5) // 7ea8ec14de4388031e539717deb73f03a5f81000a4000025 diff --git a/src/cmd/asm/internal/asm/testdata/loong64error.s b/src/cmd/asm/internal/asm/testdata/loong64error.s index 2dcd34bf61..1bc0ddea55 100644 --- a/src/cmd/asm/internal/asm/testdata/loong64error.s +++ b/src/cmd/asm/internal/asm/testdata/loong64error.s @@ -7,3 +7,8 @@ TEXT errors(SB),$0 XVSHUF4IV $16, X1, X2 // ERROR "operand out of range 0 to 15" ADDV16 $1, R4, R5 // ERROR "the constant must be a multiple of 65536." ADDV16 $65535, R4, R5 // ERROR "the constant must be a multiple of 65536." + SC R4, 1(R5) // ERROR "offset must be a multiple of 4." + SCV R4, 1(R5) // ERROR "offset must be a multiple of 4." + LL 1(R5), R4 // ERROR "offset must be a multiple of 4." + LLV 1(R5), R4 // ERROR "offset must be a multiple of 4." + diff --git a/src/cmd/internal/obj/loong64/a.out.go b/src/cmd/internal/obj/loong64/a.out.go index 3cdbeb12a3..3a676db922 100644 --- a/src/cmd/internal/obj/loong64/a.out.go +++ b/src/cmd/internal/obj/loong64/a.out.go @@ -249,7 +249,13 @@ func init() { } const ( - BIG = 2046 + BIG_8 = 128 - 2 // FIXME (not sure if -2 is appropriate) + BIG_9 = 256 - 2 + BIG_10 = 512 - 2 + BIG_11 = 1024 - 2 + BIG_12 = 2046 + BIG_16 = 32768 - 2 + BIG_32 = 2147483648 - 2 ) const ( @@ -397,10 +403,16 @@ const ( C_BRAN C_SAUTO C_LAUTO - C_ZOREG - C_SOREG - C_LOREG - C_ROFF // register offset + C_ZOREG // An $0+reg memory op + C_SOREG_8 // An $n+reg memory arg where n is a 8 bit signed offset + C_SOREG_9 // An $n+reg memory arg where n is a 9 bit signed offset + C_SOREG_10 // An $n+reg memory arg where n is a 10 bit signed offset + C_SOREG_11 // An $n+reg memory arg where n is a 11 bit signed offset + C_SOREG_12 // An $n+reg memory arg where n is a 12 bit signed offset + C_SOREG_16 // An $n+reg memory arg where n is a 16 bit signed offset + C_LOREG_32 // An $n+reg memory arg where n is a 32 bit signed offset + C_LOREG_64 // An $n+reg memory arg where n is a 64 bit signed offset + C_ROFF // register offset C_ADDR C_TLS_LE C_TLS_IE diff --git a/src/cmd/internal/obj/loong64/asm.go b/src/cmd/internal/obj/loong64/asm.go index 5a61acac87..7eb5668d82 100644 --- a/src/cmd/internal/obj/loong64/asm.go +++ b/src/cmd/internal/obj/loong64/asm.go @@ -162,46 +162,41 @@ var optab = []Optab{ {AMOVV, C_REG, C_NONE, C_NONE, C_SAUTO, C_NONE, 7, 4, REGSP, 0}, {AMOVB, C_REG, C_NONE, C_NONE, C_SAUTO, C_NONE, 7, 4, REGSP, 0}, {AMOVBU, C_REG, C_NONE, C_NONE, C_SAUTO, C_NONE, 7, 4, REGSP, 0}, - {AMOVW, C_REG, C_NONE, C_NONE, C_SOREG, C_NONE, 7, 4, REGZERO, 0}, - {AMOVWU, C_REG, C_NONE, C_NONE, C_SOREG, C_NONE, 7, 4, REGZERO, 0}, - {AMOVV, C_REG, C_NONE, C_NONE, C_SOREG, C_NONE, 7, 4, REGZERO, 0}, - {AMOVB, C_REG, C_NONE, C_NONE, C_SOREG, C_NONE, 7, 4, REGZERO, 0}, - {AMOVBU, C_REG, C_NONE, C_NONE, C_SOREG, C_NONE, 7, 4, REGZERO, 0}, - {AVMOVQ, C_VREG, C_NONE, C_NONE, C_SOREG, C_NONE, 7, 4, REGZERO, 0}, - {AXVMOVQ, C_XREG, C_NONE, C_NONE, C_SOREG, C_NONE, 7, 4, REGZERO, 0}, + {AMOVW, C_REG, C_NONE, C_NONE, C_SOREG_12, C_NONE, 7, 4, REGZERO, 0}, + {AMOVWU, C_REG, C_NONE, C_NONE, C_SOREG_12, C_NONE, 7, 4, REGZERO, 0}, + {AMOVV, C_REG, C_NONE, C_NONE, C_SOREG_12, C_NONE, 7, 4, REGZERO, 0}, + {AMOVB, C_REG, C_NONE, C_NONE, C_SOREG_12, C_NONE, 7, 4, REGZERO, 0}, + {AMOVBU, C_REG, C_NONE, C_NONE, C_SOREG_12, C_NONE, 7, 4, REGZERO, 0}, + {AVMOVQ, C_VREG, C_NONE, C_NONE, C_SOREG_12, C_NONE, 7, 4, REGZERO, 0}, + {AXVMOVQ, C_XREG, C_NONE, C_NONE, C_SOREG_12, C_NONE, 7, 4, REGZERO, 0}, {AVMOVQ, C_VREG, C_NONE, C_NONE, C_SAUTO, C_NONE, 7, 4, REGZERO, 0}, {AXVMOVQ, C_XREG, C_NONE, C_NONE, C_SAUTO, C_NONE, 7, 4, REGZERO, 0}, - {ASC, C_REG, C_NONE, C_NONE, C_SOREG, C_NONE, 7, 4, REGZERO, 0}, - {ASCV, C_REG, C_NONE, C_NONE, C_SOREG, C_NONE, 7, 4, REGZERO, 0}, {AMOVW, C_SAUTO, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGSP, 0}, {AMOVWU, C_SAUTO, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGSP, 0}, {AMOVV, C_SAUTO, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGSP, 0}, {AMOVB, C_SAUTO, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGSP, 0}, {AMOVBU, C_SAUTO, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGSP, 0}, - {AMOVW, C_SOREG, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGZERO, 0}, - {AMOVWU, C_SOREG, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGZERO, 0}, - {AMOVV, C_SOREG, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGZERO, 0}, - {AMOVB, C_SOREG, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGZERO, 0}, - {AMOVBU, C_SOREG, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGZERO, 0}, - {AVMOVQ, C_SOREG, C_NONE, C_NONE, C_VREG, C_NONE, 8, 4, REGZERO, 0}, - {AXVMOVQ, C_SOREG, C_NONE, C_NONE, C_XREG, C_NONE, 8, 4, REGZERO, 0}, + {AMOVW, C_SOREG_12, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGZERO, 0}, + {AMOVWU, C_SOREG_12, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGZERO, 0}, + {AMOVV, C_SOREG_12, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGZERO, 0}, + {AMOVB, C_SOREG_12, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGZERO, 0}, + {AMOVBU, C_SOREG_12, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGZERO, 0}, + {AVMOVQ, C_SOREG_12, C_NONE, C_NONE, C_VREG, C_NONE, 8, 4, REGZERO, 0}, + {AXVMOVQ, C_SOREG_12, C_NONE, C_NONE, C_XREG, C_NONE, 8, 4, REGZERO, 0}, {AVMOVQ, C_SAUTO, C_NONE, C_NONE, C_VREG, C_NONE, 8, 4, REGZERO, 0}, {AXVMOVQ, C_SAUTO, C_NONE, C_NONE, C_XREG, C_NONE, 8, 4, REGZERO, 0}, - {ALL, C_SOREG, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGZERO, 0}, - {ALLV, C_SOREG, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGZERO, 0}, {AMOVW, C_REG, C_NONE, C_NONE, C_LAUTO, C_NONE, 35, 12, REGSP, 0}, {AMOVWU, C_REG, C_NONE, C_NONE, C_LAUTO, C_NONE, 35, 12, REGSP, 0}, {AMOVV, C_REG, C_NONE, C_NONE, C_LAUTO, C_NONE, 35, 12, REGSP, 0}, {AMOVB, C_REG, C_NONE, C_NONE, C_LAUTO, C_NONE, 35, 12, REGSP, 0}, {AMOVBU, C_REG, C_NONE, C_NONE, C_LAUTO, C_NONE, 35, 12, REGSP, 0}, - {AMOVW, C_REG, C_NONE, C_NONE, C_LOREG, C_NONE, 35, 12, REGZERO, 0}, - {AMOVWU, C_REG, C_NONE, C_NONE, C_LOREG, C_NONE, 35, 12, REGZERO, 0}, - {AMOVV, C_REG, C_NONE, C_NONE, C_LOREG, C_NONE, 35, 12, REGZERO, 0}, - {AMOVB, C_REG, C_NONE, C_NONE, C_LOREG, C_NONE, 35, 12, REGZERO, 0}, - {AMOVBU, C_REG, C_NONE, C_NONE, C_LOREG, C_NONE, 35, 12, REGZERO, 0}, - {ASC, C_REG, C_NONE, C_NONE, C_LOREG, C_NONE, 35, 12, REGZERO, 0}, + {AMOVW, C_REG, C_NONE, C_NONE, C_LOREG_32, C_NONE, 35, 12, REGZERO, 0}, + {AMOVWU, C_REG, C_NONE, C_NONE, C_LOREG_32, C_NONE, 35, 12, REGZERO, 0}, + {AMOVV, C_REG, C_NONE, C_NONE, C_LOREG_32, C_NONE, 35, 12, REGZERO, 0}, + {AMOVB, C_REG, C_NONE, C_NONE, C_LOREG_32, C_NONE, 35, 12, REGZERO, 0}, + {AMOVBU, C_REG, C_NONE, C_NONE, C_LOREG_32, C_NONE, 35, 12, REGZERO, 0}, {AMOVW, C_REG, C_NONE, C_NONE, C_ADDR, C_NONE, 50, 8, 0, 0}, {AMOVWU, C_REG, C_NONE, C_NONE, C_ADDR, C_NONE, 50, 8, 0, 0}, {AMOVV, C_REG, C_NONE, C_NONE, C_ADDR, C_NONE, 50, 8, 0, 0}, @@ -212,19 +207,20 @@ var optab = []Optab{ {AMOVV, C_REG, C_NONE, C_NONE, C_TLS_LE, C_NONE, 53, 16, 0, 0}, {AMOVB, C_REG, C_NONE, C_NONE, C_TLS_LE, C_NONE, 53, 16, 0, 0}, {AMOVBU, C_REG, C_NONE, C_NONE, C_TLS_LE, C_NONE, 53, 16, 0, 0}, - {AMOVWP, C_REG, C_NONE, C_NONE, C_SOREG, C_NONE, 73, 4, 0, 0}, - {AMOVWP, C_REG, C_NONE, C_NONE, C_LOREG, C_NONE, 73, 4, 0, 0}, + {AMOVWP, C_REG, C_NONE, C_NONE, C_SOREG_16, C_NONE, 73, 4, 0, 0}, + {AMOVWP, C_REG, C_NONE, C_NONE, C_LOREG_32, C_NONE, 73, 12, 0, 0}, + {AMOVWP, C_REG, C_NONE, C_NONE, C_LOREG_64, C_NONE, 73, 24, 0, 0}, {AMOVW, C_LAUTO, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGSP, 0}, {AMOVWU, C_LAUTO, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGSP, 0}, {AMOVV, C_LAUTO, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGSP, 0}, {AMOVB, C_LAUTO, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGSP, 0}, {AMOVBU, C_LAUTO, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGSP, 0}, - {AMOVW, C_LOREG, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGZERO, 0}, - {AMOVWU, C_LOREG, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGZERO, 0}, - {AMOVV, C_LOREG, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGZERO, 0}, - {AMOVB, C_LOREG, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGZERO, 0}, - {AMOVBU, C_LOREG, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGZERO, 0}, + {AMOVW, C_LOREG_32, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGZERO, 0}, + {AMOVWU, C_LOREG_32, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGZERO, 0}, + {AMOVV, C_LOREG_32, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGZERO, 0}, + {AMOVB, C_LOREG_32, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGZERO, 0}, + {AMOVBU, C_LOREG_32, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGZERO, 0}, {AMOVW, C_ADDR, C_NONE, C_NONE, C_REG, C_NONE, 51, 8, 0, 0}, {AMOVWU, C_ADDR, C_NONE, C_NONE, C_REG, C_NONE, 51, 8, 0, 0}, {AMOVV, C_ADDR, C_NONE, C_NONE, C_REG, C_NONE, 51, 8, 0, 0}, @@ -235,8 +231,9 @@ var optab = []Optab{ {AMOVV, C_TLS_LE, C_NONE, C_NONE, C_REG, C_NONE, 54, 16, 0, 0}, {AMOVB, C_TLS_LE, C_NONE, C_NONE, C_REG, C_NONE, 54, 16, 0, 0}, {AMOVBU, C_TLS_LE, C_NONE, C_NONE, C_REG, C_NONE, 54, 16, 0, 0}, - {AMOVWP, C_SOREG, C_NONE, C_NONE, C_REG, C_NONE, 74, 4, 0, 0}, - {AMOVWP, C_LOREG, C_NONE, C_NONE, C_REG, C_NONE, 74, 4, 0, 0}, + {AMOVWP, C_SOREG_16, C_NONE, C_NONE, C_REG, C_NONE, 74, 4, 0, 0}, + {AMOVWP, C_LOREG_32, C_NONE, C_NONE, C_REG, C_NONE, 74, 12, 0, 0}, + {AMOVWP, C_LOREG_64, C_NONE, C_NONE, C_REG, C_NONE, 74, 24, 0, 0}, {AMOVW, C_SACON, C_NONE, C_NONE, C_REG, C_NONE, 3, 4, REGSP, 0}, {AMOVV, C_SACON, C_NONE, C_NONE, C_REG, C_NONE, 3, 4, REGSP, 0}, @@ -333,25 +330,25 @@ var optab = []Optab{ {AMOVF, C_SAUTO, C_NONE, C_NONE, C_FREG, C_NONE, 28, 4, REGSP, 0}, {AMOVD, C_SAUTO, C_NONE, C_NONE, C_FREG, C_NONE, 28, 4, REGSP, 0}, - {AMOVF, C_SOREG, C_NONE, C_NONE, C_FREG, C_NONE, 28, 4, REGZERO, 0}, - {AMOVD, C_SOREG, C_NONE, C_NONE, C_FREG, C_NONE, 28, 4, REGZERO, 0}, + {AMOVF, C_SOREG_12, C_NONE, C_NONE, C_FREG, C_NONE, 28, 4, REGZERO, 0}, + {AMOVD, C_SOREG_12, C_NONE, C_NONE, C_FREG, C_NONE, 28, 4, REGZERO, 0}, {AMOVF, C_LAUTO, C_NONE, C_NONE, C_FREG, C_NONE, 28, 12, REGSP, 0}, {AMOVD, C_LAUTO, C_NONE, C_NONE, C_FREG, C_NONE, 28, 12, REGSP, 0}, - {AMOVF, C_LOREG, C_NONE, C_NONE, C_FREG, C_NONE, 28, 12, REGZERO, 0}, - {AMOVD, C_LOREG, C_NONE, C_NONE, C_FREG, C_NONE, 28, 12, REGZERO, 0}, + {AMOVF, C_LOREG_32, C_NONE, C_NONE, C_FREG, C_NONE, 28, 12, REGZERO, 0}, + {AMOVD, C_LOREG_32, C_NONE, C_NONE, C_FREG, C_NONE, 28, 12, REGZERO, 0}, {AMOVF, C_ADDR, C_NONE, C_NONE, C_FREG, C_NONE, 51, 8, 0, 0}, {AMOVD, C_ADDR, C_NONE, C_NONE, C_FREG, C_NONE, 51, 8, 0, 0}, {AMOVF, C_FREG, C_NONE, C_NONE, C_SAUTO, C_NONE, 29, 4, REGSP, 0}, {AMOVD, C_FREG, C_NONE, C_NONE, C_SAUTO, C_NONE, 29, 4, REGSP, 0}, - {AMOVF, C_FREG, C_NONE, C_NONE, C_SOREG, C_NONE, 29, 4, REGZERO, 0}, - {AMOVD, C_FREG, C_NONE, C_NONE, C_SOREG, C_NONE, 29, 4, REGZERO, 0}, + {AMOVF, C_FREG, C_NONE, C_NONE, C_SOREG_12, C_NONE, 29, 4, REGZERO, 0}, + {AMOVD, C_FREG, C_NONE, C_NONE, C_SOREG_12, C_NONE, 29, 4, REGZERO, 0}, {AMOVF, C_FREG, C_NONE, C_NONE, C_LAUTO, C_NONE, 29, 12, REGSP, 0}, {AMOVD, C_FREG, C_NONE, C_NONE, C_LAUTO, C_NONE, 29, 12, REGSP, 0}, - {AMOVF, C_FREG, C_NONE, C_NONE, C_LOREG, C_NONE, 29, 12, REGZERO, 0}, - {AMOVD, C_FREG, C_NONE, C_NONE, C_LOREG, C_NONE, 29, 12, REGZERO, 0}, + {AMOVF, C_FREG, C_NONE, C_NONE, C_LOREG_32, C_NONE, 29, 12, REGZERO, 0}, + {AMOVD, C_FREG, C_NONE, C_NONE, C_LOREG_32, C_NONE, 29, 12, REGZERO, 0}, {AMOVF, C_FREG, C_NONE, C_NONE, C_ADDR, C_NONE, 50, 8, 0, 0}, {AMOVD, C_FREG, C_NONE, C_NONE, C_ADDR, C_NONE, 50, 8, 0, 0}, @@ -426,11 +423,11 @@ var optab = []Optab{ {AVMOVQ, C_ELEM, C_NONE, C_NONE, C_ARNG, C_NONE, 45, 4, 0, 0}, - {AVMOVQ, C_SOREG, C_NONE, C_NONE, C_ARNG, C_NONE, 46, 4, 0, 0}, - {AXVMOVQ, C_SOREG, C_NONE, C_NONE, C_ARNG, C_NONE, 46, 4, 0, 0}, + {AVMOVQ, C_SOREG_12, C_NONE, C_NONE, C_ARNG, C_NONE, 46, 4, 0, 0}, + {AXVMOVQ, C_SOREG_12, C_NONE, C_NONE, C_ARNG, C_NONE, 46, 4, 0, 0}, - {APRELD, C_SOREG, C_U5CON, C_NONE, C_NONE, C_NONE, 47, 4, 0, 0}, - {APRELDX, C_SOREG, C_DCON, C_U5CON, C_NONE, C_NONE, 48, 20, 0, 0}, + {APRELD, C_SOREG_12, C_U5CON, C_NONE, C_NONE, C_NONE, 47, 4, 0, 0}, + {APRELDX, C_SOREG_16, C_DCON, C_U5CON, C_NONE, C_NONE, 48, 20, 0, 0}, {AALSLV, C_U3CON, C_REG, C_REG, C_REG, C_NONE, 64, 4, 0, 0}, @@ -678,7 +675,7 @@ func span0(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { bp := c.cursym.P var i int32 - var out [5]uint32 + var out [6]uint32 for p := c.cursym.Func().Text.Link; p != nil; p = p.Link { c.pc = p.Pc o = c.oplook(p) @@ -778,7 +775,7 @@ func (c *ctxt0) aclass(a *obj.Addr) int { a.Reg = obj.REG_NONE } c.instoffset = int64(c.autosize) + a.Offset - if c.instoffset >= -BIG && c.instoffset < BIG { + if c.instoffset >= -BIG_12 && c.instoffset < BIG_12 { return C_SAUTO } return C_LAUTO @@ -790,7 +787,7 @@ func (c *ctxt0) aclass(a *obj.Addr) int { a.Reg = obj.REG_NONE } c.instoffset = int64(c.autosize) + a.Offset + c.ctxt.Arch.FixedFrameSize - if c.instoffset >= -BIG && c.instoffset < BIG { + if c.instoffset >= -BIG_12 && c.instoffset < BIG_12 { return C_SAUTO } return C_LAUTO @@ -808,10 +805,23 @@ func (c *ctxt0) aclass(a *obj.Addr) int { if c.instoffset == 0 { return C_ZOREG } - if c.instoffset >= -BIG && c.instoffset < BIG { - return C_SOREG + if c.instoffset >= -BIG_8 && c.instoffset < BIG_8 { + return C_SOREG_8 + } else if c.instoffset >= -BIG_9 && c.instoffset < BIG_9 { + return C_SOREG_9 + } else if c.instoffset >= -BIG_10 && c.instoffset < BIG_10 { + return C_SOREG_10 + } else if c.instoffset >= -BIG_11 && c.instoffset < BIG_11 { + return C_SOREG_11 + } else if c.instoffset >= -BIG_12 && c.instoffset < BIG_12 { + return C_SOREG_12 + } else if c.instoffset >= -BIG_16 && c.instoffset < BIG_16 { + return C_SOREG_16 + } else if c.instoffset >= -BIG_32 && c.instoffset < BIG_32 { + return C_LOREG_32 + } else { + return C_LOREG_64 } - return C_LOREG case obj.NAME_GOTREF: return C_GOTADDR @@ -828,7 +838,7 @@ func (c *ctxt0) aclass(a *obj.Addr) int { case obj.NAME_NONE: c.instoffset = a.Offset if a.Reg != 0 { - if -BIG <= c.instoffset && c.instoffset <= BIG { + if -BIG_12 <= c.instoffset && c.instoffset <= BIG_12 { return C_SACON } if isint32(c.instoffset) { @@ -857,7 +867,7 @@ func (c *ctxt0) aclass(a *obj.Addr) int { a.Reg = obj.REG_NONE } c.instoffset = int64(c.autosize) + a.Offset - if c.instoffset >= -BIG && c.instoffset < BIG { + if c.instoffset >= -BIG_12 && c.instoffset < BIG_12 { return C_SACON } return C_LACON @@ -869,7 +879,7 @@ func (c *ctxt0) aclass(a *obj.Addr) int { a.Reg = obj.REG_NONE } c.instoffset = int64(c.autosize) + a.Offset + c.ctxt.Arch.FixedFrameSize - if c.instoffset >= -BIG && c.instoffset < BIG { + if c.instoffset >= -BIG_12 && c.instoffset < BIG_12 { return C_SACON } return C_LACON @@ -1271,10 +1281,33 @@ func cmp(a int, b int) bool { case C_REG: return b == C_ZCON - case C_LOREG: - return b == C_ZOREG || b == C_SOREG + case C_LOREG_64: + if b == C_ZOREG || b == C_SOREG_8 || + b == C_SOREG_9 || b == C_SOREG_10 || + b == C_SOREG_11 || b == C_SOREG_12 || + b == C_SOREG_16 || b == C_LOREG_32 { + return true + } + + case C_LOREG_32: + return cmp(C_SOREG_16, b) + + case C_SOREG_16: + return cmp(C_SOREG_12, b) + + case C_SOREG_12: + return cmp(C_SOREG_11, b) + + case C_SOREG_11: + return cmp(C_SOREG_10, b) + + case C_SOREG_10: + return cmp(C_SOREG_9, b) - case C_SOREG: + case C_SOREG_9: + return cmp(C_SOREG_8, b) + + case C_SOREG_8: return b == C_ZOREG } @@ -1453,6 +1486,10 @@ func buildop(ctxt *obj.Link) { case AMOVWP: opset(AMOVVP, r0) + opset(ASC, r0) + opset(ASCV, r0) + opset(ALL, r0) + opset(ALLV, r0) case AMUL: opset(AMULU, r0) @@ -1522,10 +1559,6 @@ func buildop(ctxt *obj.Link) { AMOVWU, AVMOVQ, AXVMOVQ, - ALL, - ALLV, - ASC, - ASCV, ANEGW, ANEGV, AWORD, @@ -2051,6 +2084,7 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) { o3 := uint32(0) o4 := uint32(0) o5 := uint32(0) + o6 := uint32(0) add := AADDU add = AADDVU @@ -2955,18 +2989,51 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) { o4 = OP_RRR(c.oprrr(p.As), uint32(REGTMP), uint32(r), uint32(p.To.Reg)) case 73: - v := c.regoff(&p.To) + v := c.vregoff(&p.To) + r := p.To.Reg if v&3 != 0 { c.ctxt.Diag("%v: offset must be a multiple of 4.\n", p) } - o1 = OP_14IRR(c.opirr(p.As), uint32(v>>2), uint32(p.To.Reg), uint32(p.From.Reg)) + + switch o.size { + case 4: // 16 bit + o1 = OP_14IRR(c.opirr(p.As), uint32(v>>2), uint32(r), uint32(p.From.Reg)) + case 12: // 32 bit + o1 = OP_16IRR(c.opirr(AADDV16), uint32(v>>16), uint32(REG_R0), uint32(REGTMP)) + o2 = OP_RRR(c.oprrr(add), uint32(r), uint32(REGTMP), uint32(REGTMP)) + o3 = OP_14IRR(c.opirr(p.As), uint32(v>>2), uint32(REGTMP), uint32(p.From.Reg)) + case 24: // 64 bit + o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(REGTMP)) + o2 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(REGTMP), uint32(REGTMP)) + o3 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(REGTMP)) + o4 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(REGTMP), uint32(REGTMP)) + o5 = OP_RRR(c.oprrr(add), uint32(REGTMP), uint32(r), uint32(r)) + o6 = OP_14IRR(c.opirr(p.As), uint32(0), uint32(r), uint32(p.From.Reg)) + } case 74: - v := c.regoff(&p.From) + v := c.vregoff(&p.From) + r := p.From.Reg if v&3 != 0 { c.ctxt.Diag("%v: offset must be a multiple of 4.\n", p) } - o1 = OP_14IRR(c.opirr(-p.As), uint32(v>>2), uint32(p.From.Reg), uint32(p.To.Reg)) + + switch o.size { + case 4: // 16 bit + o1 = OP_14IRR(c.opirr(-p.As), uint32(v>>2), uint32(r), uint32(p.To.Reg)) + case 12: // 32 bit + o1 = OP_16IRR(c.opirr(AADDV16), uint32(v>>16), uint32(REG_R0), uint32(REGTMP)) + o2 = OP_RRR(c.oprrr(add), uint32(r), uint32(REGTMP), uint32(REGTMP)) + o3 = OP_14IRR(c.opirr(-p.As), uint32(v>>2), uint32(REGTMP), uint32(p.To.Reg)) + case 24: // 64 bit + o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(REGTMP)) + o2 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(REGTMP), uint32(REGTMP)) + o3 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(REGTMP)) + o4 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(REGTMP), uint32(REGTMP)) + o5 = OP_RRR(c.oprrr(add), uint32(REGTMP), uint32(r), uint32(r)) + o6 = OP_14IRR(c.opirr(p.As), uint32(0), uint32(r), uint32(p.To.Reg)) + } + } out[0] = o1 @@ -2974,6 +3041,7 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) { out[2] = o3 out[3] = o4 out[4] = o5 + out[5] = o6 } // checkoperand checks if operand >= 0 && operand <= maxoperand @@ -4143,13 +4211,13 @@ func (c *ctxt0) opirr(a obj.As) uint32 { case AROTRV: return 0x004d << 16 case -ALL: - return 0x020 << 24 + return 0x020 << 24 // ll.w case -ALLV: - return 0x022 << 24 + return 0x022 << 24 // ll.d case ASC: - return 0x021 << 24 + return 0x021 << 24 // sc.w case ASCV: - return 0x023 << 24 + return 0x023 << 24 // sc.d case AVANDB: return 0x1CF4 << 18 // vandi.b case AVORB: -- 2.52.0