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:
parent
2eca0b1e16
commit
02482a546f
3
src/cmd/asm/internal/asm/testdata/arm64.s
vendored
3
src/cmd/asm/internal/asm/testdata/arm64.s
vendored
@ -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
|
||||
|
2
src/cmd/asm/internal/asm/testdata/arm64enc.s
vendored
2
src/cmd/asm/internal/asm/testdata/arm64enc.s
vendored
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user