1
0
mirror of https://github.com/golang/go synced 2024-11-17 04:44:46 -07:00

cmd/asm: Fix encoding error of register offset shifted by 0 on arm64

The following instruction is wrongly encoded on arm64:
MOVD (R2)(R3<<0), R1
It's incorrectly encoded as
MOVD (R2)(R3<<3), R1

The reason for the error is that we hard-coded the shift encoding to 6,
which is correct for the MOVB and MOVBU instructions because it only
allows a shift amount of 0, but it is wrong for the MOVD instruction
because it also allows other shift values.

For instructions MOVB, MOVBU and FMOVB, the extension amount must be 0,
encoded in "S" as 0 if omitted, or as 1 if present. But in Go, we don't
distinguish between Rn.<EXT> and Rn.<EXT><<0, so we encode it as that
does not present. This makes no difference to the function of the
instruction.

Change-Id: I2afe3498392cc9b2ecd524c7744f28b9d6d107b8
Reviewed-on: https://go-review.googlesource.com/c/go/+/510995
Reviewed-by: Heschi Kreinick <heschi@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Run-TryBot: Eric Fang <eric.fang@arm.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
eric fang 2023-07-18 06:50:49 +00:00 committed by Eric Fang
parent 2eca0b1e16
commit 02482a546f
3 changed files with 13 additions and 3 deletions

View File

@ -595,6 +595,7 @@ TEXT foo(SB), DUPOK|NOSPLIT, $-8
MOVD (R3)(R6*1), R5 // 656866f8
MOVD (R2)(R6), R4 // 446866f8
MOVWU (R19)(R20<<2), R20 // 747a74b8
MOVD (R2)(R3<<0), R1 // 416863f8
MOVD (R2)(R6<<3), R4 // 447866f8
MOVD (R3)(R7.SXTX<<3), R8 // 68f867f8
MOVWU (R5)(R4.UXTW), R10 // aa4864b8
@ -604,7 +605,7 @@ TEXT foo(SB), DUPOK|NOSPLIT, $-8
MOVHU (R1)(R2<<1), R5 // 25786278
MOVB (R9)(R3.UXTW), R6 // 2649a338
MOVB (R10)(R6), R15 // 4f69a638
MOVB (R29)(R30<<0), R14 // ae7bbe38
MOVB (R29)(R30<<0), R14 // ae6bbe38
MOVB (R29)(R30), R14 // ae6bbe38
MOVH (R5)(R7.SXTX<<1), R19 // b3f8a778
MOVH (R8)(R4<<1), R10 // 0a79a478

View File

@ -186,7 +186,7 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$-8
MOVBU.P 42(R2), R12 // 4ca44238
MOVBU.W -27(R2), R14 // 4e5c5e38
MOVBU 2916(R24), R3 // 03936d39
MOVBU (R19)(R14<<0), R23 // 777a6e38
MOVBU (R19)(R14<<0), R23 // 776a6e38
MOVBU (R2)(R8.SXTX), R19 // 53e86838
MOVBU (R27)(R23), R14 // 6e6b7738
MOVHU.P 107(R14), R13 // cdb54678

View File

@ -7601,6 +7601,11 @@ func (c *ctxt7) encRegShiftOrExt(p *obj.Prog, a *obj.Addr, r int16) uint32 {
case REG_UXTW <= r && r < REG_UXTX:
if a.Type == obj.TYPE_MEM {
if num == 0 {
// According to the arm64 specification, for instructions MOVB, MOVBU and FMOVB,
// the extension amount must be 0, encoded in "S" as 0 if omitted, or as 1 if present.
// But in Go, we don't distinguish between Rn.UXTW and Rn.UXTW<<0, so we encode it as
// that does not present. This makes no difference to the function of the instruction.
// This is also true for extensions LSL, SXTW and SXTX.
return roff(rm, 2, 2)
} else {
return roff(rm, 2, 6)
@ -7636,7 +7641,11 @@ func (c *ctxt7) encRegShiftOrExt(p *obj.Prog, a *obj.Addr, r int16) uint32 {
}
case REG_LSL <= r && r < REG_ARNG:
if a.Type == obj.TYPE_MEM { // (R1)(R2<<1)
return roff(rm, 3, 6)
if num == 0 {
return roff(rm, 3, 2)
} else {
return roff(rm, 3, 6)
}
} else if isADDWop(p.As) {
return roff(rm, 2, num)
}