aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Shi <powerman1st@163.com>2018-08-01 06:38:54 +0000
committerCherry Zhang <cherryyz@google.com>2018-08-03 15:44:22 +0000
commit9594ba4fe58e9d790ba8dbaa452132d5c4034fd3 (patch)
tree4c66ab580fa1254b5d172b4424046f09a519b68a
parentac6d1564795e662b5b930c6b3d86f12351ff83d5 (diff)
downloadgo-9594ba4fe58e9d790ba8dbaa452132d5c4034fd3.tar.gz
go-9594ba4fe58e9d790ba8dbaa452132d5c4034fd3.zip
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 <powerman1st@163.com> Reviewed-by: Cherry Zhang <cherryyz@google.com>
-rw-r--r--src/cmd/asm/internal/asm/testdata/arm64.s8
-rw-r--r--src/cmd/internal/obj/arm64/asm7.go30
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)