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>
diff --git a/src/cmd/asm/internal/asm/testdata/arm64.s b/src/cmd/asm/internal/asm/testdata/arm64.s
index 859f71a..3a4410f 100644
--- a/src/cmd/asm/internal/asm/testdata/arm64.s
+++ b/src/cmd/asm/internal/asm/testdata/arm64.s
@@ -716,6 +716,14 @@
 	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 ff4b1d7..e3bcce8 100644
--- a/src/cmd/internal/obj/arm64/asm7.go
+++ b/src/cmd/internal/obj/arm64/asm7.go
@@ -3264,10 +3264,16 @@
 		}
 		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 @@
 			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 @@
 			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)