aboutsummaryrefslogtreecommitdiff
path: root/src/cmd
diff options
context:
space:
mode:
authorCherry Zhang <cherryyz@google.com>2017-04-06 10:01:36 -0400
committerCherry Zhang <cherryyz@google.com>2017-04-06 17:59:39 +0000
commit0bae9b083bdbf4d15d65fe175eaa98e4a83d22ea (patch)
tree5cc3b30c54441aa6b03748bc693313f112bede38 /src/cmd
parent257b01f8f47ace2ddd75efe37d8a0353888bce14 (diff)
downloadgo-0bae9b083bdbf4d15d65fe175eaa98e4a83d22ea.tar.xz
cmd/internal/obj/arm64: fix encoding of AND MBCON
When a constant is both MOVCON (can fit into a MOV instruction) and BITCON (can fit into a logical instruction), the assembler chooses to use the MOVCON encoding, which is actually longer for logical instructions. We add MBCON rules explicitly to make sure it uses the BITCON encoding. Updates #19857. Change-Id: Ib9881be363cbc491ac2a0792b36b87e74eff34a8 Reviewed-on: https://go-review.googlesource.com/39652 Run-TryBot: Cherry Zhang <cherryyz@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: David Chase <drchase@google.com>
Diffstat (limited to 'src/cmd')
-rw-r--r--src/cmd/asm/internal/asm/testdata/arm64.s9
-rw-r--r--src/cmd/internal/obj/arm64/a.out.go9
-rw-r--r--src/cmd/internal/obj/arm64/asm7.go4
3 files changed, 19 insertions, 3 deletions
diff --git a/src/cmd/asm/internal/asm/testdata/arm64.s b/src/cmd/asm/internal/asm/testdata/arm64.s
index 9ca6f2f166..28b34e3d72 100644
--- a/src/cmd/asm/internal/asm/testdata/arm64.s
+++ b/src/cmd/asm/internal/asm/testdata/arm64.s
@@ -45,6 +45,15 @@ TEXT foo(SB), 7, $-8
ADD R1->33, R2
AND R1@>33, R2
+// logical ops
+// make sure constants get encoded into an instruction when it could
+ AND $(1<<63), R1 // AND $-9223372036854775808, R1 // 21004192
+ AND $(1<<63-1), R1 // AND $9223372036854775807, R1 // 21f84092
+ ORR $(1<<63), R1 // ORR $-9223372036854775808, R1 // 210041b2
+ ORR $(1<<63-1), R1 // ORR $9223372036854775807, R1 // 21f840b2
+ EOR $(1<<63), R1 // EOR $-9223372036854775808, R1 // 210041d2
+ EOR $(1<<63-1), R1 // EOR $9223372036854775807, R1 // 21f840d2
+
//
// CLS
//
diff --git a/src/cmd/internal/obj/arm64/a.out.go b/src/cmd/internal/obj/arm64/a.out.go
index bed129d891..f192a51b0a 100644
--- a/src/cmd/internal/obj/arm64/a.out.go
+++ b/src/cmd/internal/obj/arm64/a.out.go
@@ -254,6 +254,9 @@ const (
)
const (
+ // optab is sorted based on the order of these constants
+ // and the first match is chosen.
+ // The more specific class needs to come earlier.
C_NONE = iota
C_REG // R0..R30
C_RSP // R0..R30, RSP
@@ -266,13 +269,13 @@ const (
C_COND // EQ, NE, etc
C_ZCON // $0 or ZR
+ C_ABCON0 // could be C_ADDCON0 or C_BITCON
C_ADDCON0 // 12-bit unsigned, unshifted
+ C_ABCON // could be C_ADDCON or C_BITCON
C_ADDCON // 12-bit unsigned, shifted left by 0 or 12
+ C_MBCON // could be C_MOVCON or C_BITCON
C_MOVCON // generated by a 16-bit constant, optionally inverted and/or shifted by multiple of 16
C_BITCON // bitfield and logical immediate masks
- C_ABCON0 // could be C_ADDCON0 or C_BITCON
- C_ABCON // could be C_ADDCON or C_BITCON
- C_MBCON // could be C_MOVCON or C_BITCON
C_LCON // 32-bit constant
C_VCON // 64-bit constant
C_FCON // floating-point constant
diff --git a/src/cmd/internal/obj/arm64/asm7.go b/src/cmd/internal/obj/arm64/asm7.go
index 66a324943d..c0a19d2d2a 100644
--- a/src/cmd/internal/obj/arm64/asm7.go
+++ b/src/cmd/internal/obj/arm64/asm7.go
@@ -190,6 +190,10 @@ var optab = []Optab{
{AAND, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0},
{ABIC, C_REG, C_REG, C_REG, 1, 4, 0, 0, 0},
{ABIC, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0},
+ {AAND, C_MBCON, C_REG, C_REG, 53, 4, 0, 0, 0},
+ {AAND, C_MBCON, C_NONE, C_REG, 53, 4, 0, 0, 0},
+ {ABIC, C_MBCON, C_REG, C_REG, 53, 4, 0, 0, 0},
+ {ABIC, C_MBCON, C_NONE, C_REG, 53, 4, 0, 0, 0},
{AAND, C_BITCON, C_REG, C_REG, 53, 4, 0, 0, 0},
{AAND, C_BITCON, C_NONE, C_REG, 53, 4, 0, 0, 0},
{ABIC, C_BITCON, C_REG, C_REG, 53, 4, 0, 0, 0},