From b83ccb98186c9e1a76a9a1f4f37bf55b85205bb2 Mon Sep 17 00:00:00 2001 From: Keith Randall Date: Thu, 14 Dec 2023 16:29:50 -0800 Subject: [PATCH] cmd/asm: for arm, rewrite argument shifted right by 0 to left by 0. Right shift by 0 has bad semantics. Make sure if we try to right shift by 0, do a left shift by 0 instead. CL 549955 handled full instructions with this strange no-op encoding. This CL handles the shift done to instruction register inputs. (The former is implemented using the latter, but not until deep inside the assembler.) Update #64715 Change-Id: Ibfabb4b13e2595551e58b977162fe005aaaa0ad1 Reviewed-on: https://go-review.googlesource.com/c/go/+/550335 Run-TryBot: Cherry Mui TryBot-Result: Gopher Robot Reviewed-by: Cherry Mui LUCI-TryBot-Result: Go LUCI Reviewed-by: Keith Randall --- src/cmd/asm/internal/asm/testdata/arm.s | 14 ++++++++++++++ src/cmd/internal/obj/arm/asm5.go | 18 ++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/src/cmd/asm/internal/asm/testdata/arm.s b/src/cmd/asm/internal/asm/testdata/arm.s index 2b8cadbed8bbe..93edc8854ead4 100644 --- a/src/cmd/asm/internal/asm/testdata/arm.s +++ b/src/cmd/asm/internal/asm/testdata/arm.s @@ -943,6 +943,20 @@ jmp_label_3: SLL R5, R7 // 1775a0e1 SLL.S R5, R7 // 1775b0e1 +// Ops with zero shifts should encode as left shifts + ADD R0<<0, R1, R2 // 002081e0 + ADD R0>>0, R1, R2 // 002081e0 + ADD R0->0, R1, R2 // 002081e0 + ADD R0@>0, R1, R2 // 002081e0 + MOVW R0<<0(R1), R2 // 002091e7 + MOVW R0>>0(R1), R2 // 002091e7 + MOVW R0->0(R1), R2 // 002091e7 + MOVW R0@>0(R1), R2 // 002091e7 + MOVW R0, R1<<0(R2) // 010082e7 + MOVW R0, R1>>0(R2) // 010082e7 + MOVW R0, R1->0(R2) // 010082e7 + MOVW R0, R1@>0(R2) // 010082e7 + // MULA / MULS MULAWT R1, R2, R3, R4 // c23124e1 MULAWB R1, R2, R3, R4 // 823124e1 diff --git a/src/cmd/internal/obj/arm/asm5.go b/src/cmd/internal/obj/arm/asm5.go index 9731bd4151403..4e6eff9e17ca8 100644 --- a/src/cmd/internal/obj/arm/asm5.go +++ b/src/cmd/internal/obj/arm/asm5.go @@ -1106,6 +1106,24 @@ func (c *ctxt5) oplook(p *obj.Prog) *Optab { // TODO: rotate by 0? Not currently supported, but if we ever do then include it here. p.As = ASLL } + if p.As != AMOVB && p.As != AMOVBS && p.As != AMOVBU && p.As != AMOVH && p.As != AMOVHS && p.As != AMOVHU && p.As != AXTAB && p.As != AXTABU && p.As != AXTAH && p.As != AXTAHU { + // Same here, but for shifts encoded in Addrs. + // Don't do it for the extension ops, which + // need to keep their RR shifts. + fixShift := func(a *obj.Addr) { + if a.Type == obj.TYPE_SHIFT { + typ := a.Offset & SHIFT_RR + isConst := a.Offset&(1<<4) == 0 + amount := a.Offset >> 7 & 0x1f + if isConst && amount == 0 && (typ == SHIFT_LR || typ == SHIFT_AR || typ == SHIFT_RR) { + a.Offset -= typ + a.Offset += SHIFT_LL + } + } + } + fixShift(&p.From) + fixShift(&p.To) + } ops := oprange[p.As&obj.AMask] c1 := &xcmp[a1]