From 9594ba4fe58e9d790ba8dbaa452132d5c4034fd3 Mon Sep 17 00:00:00 2001 From: Ben Shi Date: Wed, 1 Aug 2018 06:38:54 +0000 Subject: [PATCH] cmd/internal/obj/arm64: fix incorrect rejection of legal instructions "BFI $0, R1, $7, R2" is expected to copy bit 0~6 from R1 to R2, and left R2's other bits unchanged. But the assembler rejects it with error "illegal bit number", and BFIW/SBFIZ/SBFIZW/UBFIZ/UBFIZW have the same problem. This CL fixes that issue and adds corresponding test cases. fixes #26736 Change-Id: Ie0090a0faa38a49dd9b096a0f435987849800b76 Reviewed-on: https://go-review.googlesource.com/127159 Run-TryBot: Ben Shi Reviewed-by: Cherry Zhang --- src/cmd/asm/internal/asm/testdata/arm64.s | 8 ++++++ src/cmd/internal/obj/arm64/asm7.go | 30 ++++++++++++++++++----- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/src/cmd/asm/internal/asm/testdata/arm64.s b/src/cmd/asm/internal/asm/testdata/arm64.s index 859f71a26b..3a4410f10b 100644 --- a/src/cmd/asm/internal/asm/testdata/arm64.s +++ b/src/cmd/asm/internal/asm/testdata/arm64.s @@ -716,6 +716,14 @@ again: STPW (R3, R4), x(SB) STPW (R3, R4), x+8(SB) +// bit field operation + BFI $0, R1, $1, R2 // 220040b3 + BFIW $0, R1, $1, R2 // 22000033 + SBFIZ $0, R1, $1, R2 // 22004093 + SBFIZW $0, R1, $1, R2 // 22000013 + UBFIZ $0, R1, $1, R2 // 220040d3 + UBFIZW $0, R1, $1, R2 // 22000053 + // END // // LTYPEE comma diff --git a/src/cmd/internal/obj/arm64/asm7.go b/src/cmd/internal/obj/arm64/asm7.go index ff4b1d7ec1..e3bcce8265 100644 --- a/src/cmd/internal/obj/arm64/asm7.go +++ b/src/cmd/internal/obj/arm64/asm7.go @@ -3264,10 +3264,16 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) { } switch p.As { case ABFI: - o1 = c.opbfm(p, ABFM, 64-r, s-1, rf, rt) + if r != 0 { + r = 64 - r + } + o1 = c.opbfm(p, ABFM, r, s-1, rf, rt) case ABFIW: - o1 = c.opbfm(p, ABFMW, 32-r, s-1, rf, rt) + if r != 0 { + r = 32 - r + } + o1 = c.opbfm(p, ABFMW, r, s-1, rf, rt) case ABFXIL: o1 = c.opbfm(p, ABFM, r, r+s-1, rf, rt) @@ -3276,10 +3282,16 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) { o1 = c.opbfm(p, ABFMW, r, r+s-1, rf, rt) case ASBFIZ: - o1 = c.opbfm(p, ASBFM, 64-r, s-1, rf, rt) + if r != 0 { + r = 64 - r + } + o1 = c.opbfm(p, ASBFM, r, s-1, rf, rt) case ASBFIZW: - o1 = c.opbfm(p, ASBFMW, 32-r, s-1, rf, rt) + if r != 0 { + r = 32 - r + } + o1 = c.opbfm(p, ASBFMW, r, s-1, rf, rt) case ASBFX: o1 = c.opbfm(p, ASBFM, r, r+s-1, rf, rt) @@ -3288,10 +3300,16 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) { o1 = c.opbfm(p, ASBFMW, r, r+s-1, rf, rt) case AUBFIZ: - o1 = c.opbfm(p, AUBFM, 64-r, s-1, rf, rt) + if r != 0 { + r = 64 - r + } + o1 = c.opbfm(p, AUBFM, r, s-1, rf, rt) case AUBFIZW: - o1 = c.opbfm(p, AUBFMW, 32-r, s-1, rf, rt) + if r != 0 { + r = 32 - r + } + o1 = c.opbfm(p, AUBFMW, r, s-1, rf, rt) case AUBFX: o1 = c.opbfm(p, AUBFM, r, r+s-1, rf, rt)