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 <drchase@google.com>
Reviewed-by: Meidan Li <limeidan@loongson.cn>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: abner chenc <chenguoqi@loongson.cn>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
This commit is contained in:
Xiaolin Zhao 2025-09-24 17:21:40 +08:00 committed by abner chenc
parent 2835b994fb
commit 916e682d51
7 changed files with 195 additions and 84 deletions

View file

@ -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")
}

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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."

View file

@ -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

View file

@ -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_SOREG:
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_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: