cmd/internal/obj/arm64: fix encoding of 32-bit negated logical instructions

32-bit negated logical instructions (BICW, ORNW, EONW) with
constants were mis-encoded, because they were missing in the
cases where we handle 32-bit logical instructions. This CL
adds the missing cases.

Fixes #28548

Change-Id: I3d6acde7d3b72bb7d3d5d00a9df698a72c806ad5
Reviewed-on: https://go-review.googlesource.com/c/147077
Run-TryBot: Cherry Zhang <cherryyz@google.com>
Run-TryBot: Ben Shi <powerman1st@163.com>
Reviewed-by: Ben Shi <powerman1st@163.com>
diff --git a/src/cmd/asm/internal/asm/testdata/arm64.s b/src/cmd/asm/internal/asm/testdata/arm64.s
index 12c7adb..b851ba4 100644
--- a/src/cmd/asm/internal/asm/testdata/arm64.s
+++ b/src/cmd/asm/internal/asm/testdata/arm64.s
@@ -222,6 +222,13 @@
 	EOR	$(1<<63), R1   // EOR	$-9223372036854775808, R1 // 210041d2
 	EOR	$(1<<63-1), R1 // EOR	$9223372036854775807, R1  // 21f840d2
 
+	ANDW	$0x3ff00000, R2 // ANDW	$1072693248, R2 // 42240c12
+	BICW	$0x3ff00000, R2 // BICW	$1072693248, R2 // 42540212
+	ORRW	$0x3ff00000, R2 // ORRW	$1072693248, R2 // 42240c32
+	ORNW	$0x3ff00000, R2 // ORNW	$1072693248, R2 // 42540232
+	EORW	$0x3ff00000, R2 // EORW	$1072693248, R2 // 42240c52
+	EONW	$0x3ff00000, R2 // EONW	$1072693248, R2 // 42540252
+
 	AND	$0x22220000, R3, R4   // AND $572653568, R3, R4   // 5b44a4d264001b8a
 	ORR	$0x22220000, R3, R4   // ORR $572653568, R3, R4   // 5b44a4d264001baa
 	EOR	$0x22220000, R3, R4   // EOR $572653568, R3, R4   // 5b44a4d264001bca
diff --git a/src/cmd/internal/obj/arm64/asm7.go b/src/cmd/internal/obj/arm64/asm7.go
index 6a6e818..770b4b6 100644
--- a/src/cmd/internal/obj/arm64/asm7.go
+++ b/src/cmd/internal/obj/arm64/asm7.go
@@ -1689,21 +1689,14 @@
 				a1 = ra0 + 1
 				p.From.Class = int8(a1)
 			}
-			if isANDWop(p.As) {
-				switch p.As {
-				case AANDW, AORRW, AEORW, AANDSW, ATSTW:
-					// For 32-bit logical instruction with constant,
-					// rewrite the high 32-bit to be a copy of the low
-					// 32-bit, so that the BITCON test can be shared
-					// for both 32-bit and 64-bit.
-					if a0 == C_BITCON {
-						break
-					}
-					fallthrough
-				default:
-					a1 = c.con32class(&p.From) + 1
-					p.From.Class = int8(a1)
-				}
+			if isANDWop(p.As) && a0 != C_BITCON {
+				// For 32-bit logical instruction with constant,
+				// the BITCON test is special in that it looks at
+				// the 64-bit which has the high 32-bit as a copy
+				// of the low 32-bit. We have handled that and
+				// don't pass it to con32class.
+				a1 = c.con32class(&p.From) + 1
+				p.From.Class = int8(a1)
 			}
 		}
 	}
diff --git a/src/cmd/internal/obj/arm64/obj7.go b/src/cmd/internal/obj/arm64/obj7.go
index 4476dad..d0e354e 100644
--- a/src/cmd/internal/obj/arm64/obj7.go
+++ b/src/cmd/internal/obj/arm64/obj7.go
@@ -311,12 +311,9 @@
 	// shared for both 32-bit and 64-bit. 32-bit ops
 	// will zero the high 32-bit of the destination
 	// register anyway.
-	switch p.As {
-	case AANDW, AORRW, AEORW, AANDSW, ATSTW:
-		if p.From.Type == obj.TYPE_CONST {
-			v := p.From.Offset & 0xffffffff
-			p.From.Offset = v | v<<32
-		}
+	if isANDWop(p.As) && p.From.Type == obj.TYPE_CONST {
+		v := p.From.Offset & 0xffffffff
+		p.From.Offset = v | v<<32
 	}
 
 	if c.ctxt.Flag_dynlink {