Ludi Rehak has uploaded this change for review.
all: add GOARMFP env var for ARM floating point mode
This change introduces a new environment variable, GOARMFP,
which controls the floating point mode on ARM targets. The
GOARMFP flag can be set to 'hard' (default) or 'soft', to
select whether to use hardware instructions or software
emulation for floating point computations, respectively.
Previously, software floating point support was limited to
GOARM=5. With the introduction of GOARMFP, software floating
point is now extended to all ARM versions, including GOARM=6
and 7. This avoids the need to downgrade to the ARMv5
instruction set on ARMv7 chips without hardware FPUs.
When GOARM=5, only soft floating point is used, regardless of
the GOARMFP value.
For #61588
Change-Id: I23dc86fbd0733b262004a2ed001e1032cf371e94
---
M src/cmd/compile/internal/arm/galign.go
M src/cmd/dist/build.go
M src/cmd/dist/buildruntime.go
M src/cmd/dist/util.go
M src/cmd/go/alldocs.go
M src/cmd/go/internal/cfg/cfg.go
M src/cmd/go/internal/help/helpdoc.go
M src/cmd/internal/obj/arm/asm5.go
M src/cmd/internal/testdir/testdir_test.go
M src/cmd/link/internal/ld/lib.go
M src/internal/buildcfg/cfg.go
M src/internal/cfg/cfg.go
M src/math/rand/rand_test.go
M src/runtime/asm_arm.s
M src/runtime/cgo/asm_arm.s
M src/runtime/mkpreempt.go
M src/runtime/os_freebsd_arm.go
M src/runtime/os_linux_arm.go
M src/runtime/preempt_arm.s
M src/runtime/runtime2.go
20 files changed, 90 insertions(+), 44 deletions(-)
diff --git a/src/cmd/compile/internal/arm/galign.go b/src/cmd/compile/internal/arm/galign.go
index 23e52ba..ea82f73 100644
--- a/src/cmd/compile/internal/arm/galign.go
+++ b/src/cmd/compile/internal/arm/galign.go
@@ -15,7 +15,7 @@
arch.LinkArch = &arm.Linkarm
arch.REGSP = arm.REGSP
arch.MAXWIDTH = (1 << 32) - 1
- arch.SoftFloat = buildcfg.GOARM == 5
+ arch.SoftFloat = buildcfg.GOARM == 5 || buildcfg.GOARMFP == "soft"
arch.ZeroRange = zerorange
arch.Ginsnop = ginsnop
diff --git a/src/cmd/dist/build.go b/src/cmd/dist/build.go
index 0afa5f0..87ae031 100644
--- a/src/cmd/dist/build.go
+++ b/src/cmd/dist/build.go
@@ -33,6 +33,7 @@
gohostos string
goos string
goarm string
+ goarmfp string
go386 string
goamd64 string
gomips string
@@ -147,6 +148,12 @@
}
goarm = b
+ b = os.Getenv("GOARMFP")
+ if b == "" {
+ b = "hard"
+ }
+ goarmfp = b
+
b = os.Getenv("GO386")
if b == "" {
b = "sse2"
@@ -230,6 +237,7 @@
os.Setenv("GOAMD64", goamd64)
os.Setenv("GOARCH", goarch)
os.Setenv("GOARM", goarm)
+ os.Setenv("GOARMFP", goarmfp)
os.Setenv("GOHOSTARCH", gohostarch)
os.Setenv("GOHOSTOS", gohostos)
os.Setenv("GOOS", goos)
@@ -1226,6 +1234,7 @@
xprintf(format, "GOTOOLDIR", tooldir)
if goarch == "arm" {
xprintf(format, "GOARM", goarm)
+ xprintf(format, "GOARMFP", goarmfp)
}
if goarch == "386" {
xprintf(format, "GO386", go386)
diff --git a/src/cmd/dist/buildruntime.go b/src/cmd/dist/buildruntime.go
index 1de78f0..16c0975 100644
--- a/src/cmd/dist/buildruntime.go
+++ b/src/cmd/dist/buildruntime.go
@@ -54,6 +54,7 @@
fmt.Fprintf(&buf, "const defaultGO386 = `%s`\n", go386)
fmt.Fprintf(&buf, "const defaultGOAMD64 = `%s`\n", goamd64)
fmt.Fprintf(&buf, "const defaultGOARM = `%s`\n", goarm)
+ fmt.Fprintf(&buf, "const defaultGOARMFP = `%s`\n", goarmfp)
fmt.Fprintf(&buf, "const defaultGOMIPS = `%s`\n", gomips)
fmt.Fprintf(&buf, "const defaultGOMIPS64 = `%s`\n", gomips64)
fmt.Fprintf(&buf, "const defaultGOPPC64 = `%s`\n", goppc64)
diff --git a/src/cmd/dist/util.go b/src/cmd/dist/util.go
index 2eeab18..b2a04ee 100644
--- a/src/cmd/dist/util.go
+++ b/src/cmd/dist/util.go
@@ -373,6 +373,7 @@
}
func xgetgoarm() string {
+ // todo: replace with uname -p to determine GOARM version, then run this code to determine GOARMFP value
// If we're building on an actual arm system, and not building
// a cross-compiling toolchain, try to exec ourselves
// to detect whether VFP is supported and set the default GOARM.
diff --git a/src/cmd/go/alldocs.go b/src/cmd/go/alldocs.go
index 45de1cc..c8f9df1 100644
--- a/src/cmd/go/alldocs.go
+++ b/src/cmd/go/alldocs.go
@@ -2281,6 +2281,9 @@
// GOARM
// For GOARCH=arm, the ARM architecture for which to compile.
// Valid values are 5, 6, 7.
+// GOARMFP
+// For GOARCH=arm, whether to use floating point instructions.
+// Valid values are hard (default), soft. Ignored when GOARM=5.
// GO386
// For GOARCH=386, how to implement floating point instructions.
// Valid values are sse2 (default), softfloat.
diff --git a/src/cmd/go/internal/cfg/cfg.go b/src/cmd/go/internal/cfg/cfg.go
index 8a82e55..0a25a5c 100644
--- a/src/cmd/go/internal/cfg/cfg.go
+++ b/src/cmd/go/internal/cfg/cfg.go
@@ -410,6 +410,7 @@
// Used in envcmd.MkEnv and build ID computations.
GOARM = envOr("GOARM", fmt.Sprint(buildcfg.GOARM))
+ GOARMFP = envOr("GOARMFP", buildcfg.GOARMFP)
GO386 = envOr("GO386", buildcfg.GO386)
GOAMD64 = envOr("GOAMD64", fmt.Sprintf("%s%d", "v", buildcfg.GOAMD64))
GOMIPS = envOr("GOMIPS", buildcfg.GOMIPS)
@@ -435,7 +436,7 @@
func GetArchEnv() (key, val string) {
switch Goarch {
case "arm":
- return "GOARM", GOARM
+ return "GOARM", GOARM // todo: handle GOARMFP flag
case "386":
return "GO386", GO386
case "amd64":
diff --git a/src/cmd/go/internal/help/helpdoc.go b/src/cmd/go/internal/help/helpdoc.go
index 68ac4d2..9f3402b 100644
--- a/src/cmd/go/internal/help/helpdoc.go
+++ b/src/cmd/go/internal/help/helpdoc.go
@@ -601,6 +601,9 @@
GOARM
For GOARCH=arm, the ARM architecture for which to compile.
Valid values are 5, 6, 7.
+ GOARMFP
+ For GOARCH=arm, whether to use floating point instructions.
+ Valid values are hard (default), soft. Ignored when GOARM=5.
GO386
For GOARCH=386, how to implement floating point instructions.
Valid values are sse2 (default), softfloat.
diff --git a/src/cmd/internal/obj/arm/asm5.go b/src/cmd/internal/obj/arm/asm5.go
index 177ffd9..4c858c3 100644
--- a/src/cmd/internal/obj/arm/asm5.go
+++ b/src/cmd/internal/obj/arm/asm5.go
@@ -3044,16 +3044,16 @@
}
func (c *ctxt5) chipzero5(e float64) int {
- // We use GOARM=7 to gate the use of VFPv3 vmov (imm) instructions.
- if buildcfg.GOARM < 7 || math.Float64bits(e) != 0 {
+ // We use GOARM=7 and GOARMFP!=soft to gate the use of VFPv3 vmov (imm) instructions.
+ if buildcfg.GOARM < 7 || buildcfg.GOARMFP == "soft" || math.Float64bits(e) != 0 {
return -1
}
return 0
}
func (c *ctxt5) chipfloat5(e float64) int {
- // We use GOARM=7 to gate the use of VFPv3 vmov (imm) instructions.
- if buildcfg.GOARM < 7 {
+ // We use GOARM=7 and GOARMFP!=soft to gate the use of VFPv3 vmov (imm) instructions.
+ if buildcfg.GOARM < 7 || buildcfg.GOARMFP == "soft" {
return -1
}
diff --git a/src/cmd/internal/testdir/testdir_test.go b/src/cmd/internal/testdir/testdir_test.go
index bd77859..c491bcf 100644
--- a/src/cmd/internal/testdir/testdir_test.go
+++ b/src/cmd/internal/testdir/testdir_test.go
@@ -1454,7 +1454,7 @@
archVariants = map[string][]string{
"386": {"GO386", "sse2", "softfloat"},
"amd64": {"GOAMD64", "v1", "v2", "v3", "v4"},
- "arm": {"GOARM", "5", "6", "7"},
+ "arm": {"GOARM", "5", "6", "7"}, // todo: change this to capture soft or hard float
"arm64": {},
"loong64": {},
"mips": {"GOMIPS", "hardfloat", "softfloat"},
diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go
index de0a54d..c25a52b 100644
--- a/src/cmd/link/internal/ld/lib.go
+++ b/src/cmd/link/internal/ld/lib.go
@@ -872,13 +872,23 @@
mdsb.SetSize(0)
// In addition, on ARM, the runtime depends on the linker
- // recording the value of GOARM.
+ // recording the value of GOARM and GOARMFP.
if ctxt.Arch.Family == sys.ARM {
goarm := ctxt.loader.LookupOrCreateSym("runtime.goarm", 0)
sb := ctxt.loader.MakeSymbolUpdater(goarm)
sb.SetType(sym.SDATA)
sb.SetSize(0)
sb.AddUint8(uint8(buildcfg.GOARM))
+
+ goarmsoftfp := ctxt.loader.LookupOrCreateSym("runtime.goarmsoftfp", 0)
+ sb2 := ctxt.loader.MakeSymbolUpdater(goarmsoftfp)
+ sb2.SetType(sym.SDATA)
+ sb2.SetSize(0)
+ if buildcfg.GOARMFP == "soft" || buildcfg.GOARM == 5 {
+ sb2.AddUint8(1)
+ } else {
+ sb2.AddUint8(0)
+ }
}
// Set runtime.disableMemoryProfiling bool if
diff --git a/src/internal/buildcfg/cfg.go b/src/internal/buildcfg/cfg.go
index b97b9c1..3b9ff76 100644
--- a/src/internal/buildcfg/cfg.go
+++ b/src/internal/buildcfg/cfg.go
@@ -27,6 +27,7 @@
GO386 = envOr("GO386", defaultGO386)
GOAMD64 = goamd64()
GOARM = goarm()
+ GOARMFP = goarmfp()
GOMIPS = gomips()
GOMIPS64 = gomips64()
GOPPC64 = goppc64()
@@ -87,6 +88,15 @@
return int(def[0] - '0')
}
+func goarmfp() string {
+ switch v := envOr("GOARMFP", defaultGOARMFP); v {
+ case "hard", "soft":
+ return v
+ }
+ Error = fmt.Errorf("invalid GOARMFP: must be hard, soft")
+ return defaultGOARMFP
+}
+
func gomips() string {
switch v := envOr("GOMIPS", defaultGOMIPS); v {
case "hardfloat", "softfloat":
@@ -206,6 +216,7 @@
}
return list
case "arm":
+ // todo: add GOARMFP variants
var list []string
for i := 5; i <= GOARM; i++ {
list = append(list, fmt.Sprintf("%s.%d", GOARCH, i))
diff --git a/src/internal/cfg/cfg.go b/src/internal/cfg/cfg.go
index 2af0ec7..2e02d09 100644
--- a/src/internal/cfg/cfg.go
+++ b/src/internal/cfg/cfg.go
@@ -36,6 +36,7 @@
GOAMD64
GOARCH
GOARM
+ GOARMFP
GOBIN
GOCACHE
GOCACHEPROG
diff --git a/src/math/rand/rand_test.go b/src/math/rand/rand_test.go
index 7eba1dc..ac3ab76 100644
--- a/src/math/rand/rand_test.go
+++ b/src/math/rand/rand_test.go
@@ -338,7 +338,7 @@
func hasSlowFloatingPoint() bool {
switch runtime.GOARCH {
case "arm":
- return os.Getenv("GOARM") == "5"
+ return os.Getenv("GOARM") == "5" || os.Getenv("GOARMFP") == "soft"
case "mips", "mipsle", "mips64", "mips64le":
// Be conservative and assume that all mips boards
// have emulated floating point.
diff --git a/src/runtime/asm_arm.s b/src/runtime/asm_arm.s
index e3206a1..31a0584 100644
--- a/src/runtime/asm_arm.s
+++ b/src/runtime/asm_arm.s
@@ -39,10 +39,10 @@
MOVW g, 32(R13)
MOVW R11, 36(R13)
- // Skip floating point registers on GOARM < 6.
- MOVB runtime·goarm(SB), R11
- CMP $6, R11
- BLT skipfpsave
+ // Skip floating point registers on goarmsoftfp != 0.
+ MOVB runtime·goarmsoftfp(SB), R11
+ CMP $0, R11
+ BNE skipfpsave
MOVD F8, (40+8*0)(R13)
MOVD F9, (40+8*1)(R13)
MOVD F10, (40+8*2)(R13)
@@ -77,9 +77,9 @@
BL runtime·newosproc0(SB)
rr:
// Restore callee-save registers and return.
- MOVB runtime·goarm(SB), R11
- CMP $6, R11
- BLT skipfprest
+ MOVB runtime·goarmsoftfp(SB), R11
+ CMP $0, R11
+ BNE skipfprest
MOVD (40+8*0)(R13), F8
MOVD (40+8*1)(R13), F9
MOVD (40+8*2)(R13), F10
@@ -197,10 +197,10 @@
RET
TEXT runtime·asminit(SB),NOSPLIT,$0-0
- // disable runfast (flush-to-zero) mode of vfp if runtime.goarm > 5
- MOVB runtime·goarm(SB), R11
- CMP $5, R11
- BLE 4(PC)
+ // disable runfast (flush-to-zero) mode of vfp if runtime.goarmsoftfp == 0
+ MOVB runtime·goarmsoftfp(SB), R11
+ CMP $0, R11
+ BNE 4(PC)
WORD $0xeef1ba10 // vmrs r11, fpscr
BIC $(1<<24), R11
WORD $0xeee1ba10 // vmsr fpscr, r11
diff --git a/src/runtime/cgo/asm_arm.s b/src/runtime/cgo/asm_arm.s
index f7f9977..d9b88a3 100644
--- a/src/runtime/cgo/asm_arm.s
+++ b/src/runtime/cgo/asm_arm.s
@@ -27,10 +27,10 @@
// starting at 4(R13).
MOVW.W R14, -4(R13)
- // Skip floating point registers on GOARM < 6.
- MOVB runtime·goarm(SB), R11
- CMP $6, R11
- BLT skipfpsave
+ // Skip floating point registers if goarmsoftfp!=0.
+ MOVB runtime·goarmsoftfp(SB), R11
+ CMP $0, R11
+ BNE skipfpsave
MOVD F8, (13*4+8*1)(R13)
MOVD F9, (13*4+8*2)(R13)
MOVD F10, (13*4+8*3)(R13)
@@ -45,9 +45,9 @@
// We set up the arguments to cgocallback when saving registers above.
BL runtime·cgocallback(SB)
- MOVB runtime·goarm(SB), R11
- CMP $6, R11
- BLT skipfprest
+ MOVB runtime·goarmsoftfp(SB), R11
+ CMP $0, R11
+ BNE skipfprest
MOVD (13*4+8*1)(R13), F8
MOVD (13*4+8*2)(R13), F9
MOVD (13*4+8*3)(R13), F10
diff --git a/src/runtime/mkpreempt.go b/src/runtime/mkpreempt.go
index 0bfbd379..15b0fad 100644
--- a/src/runtime/mkpreempt.go
+++ b/src/runtime/mkpreempt.go
@@ -317,11 +317,11 @@
p("MOVW.W R14, -%d(R13)", lfp.stack) // allocate frame, save LR
l.save()
- p("MOVB ·goarm(SB), R0\nCMP $6, R0\nBLT nofp") // test goarm, and skip FP registers if goarm=5.
+ p("MOVB ·goarmsoftfp(SB), R0\nCMP $0, R0\nBNE nofp") // test goarmsoftfp, and skip FP registers if goarmsoftfp!=0.
lfp.save()
label("nofp:")
p("CALL ·asyncPreempt2(SB)")
- p("MOVB ·goarm(SB), R0\nCMP $6, R0\nBLT nofp2") // test goarm, and skip FP registers if goarm=5.
+ p("MOVB ·goarmsoftfp(SB), R0\nCMP $0, R0\nBNE nofp2") // test goarmsoftfp, and skip FP registers if goarmsoftfp!=0.
lfp.restore()
label("nofp2:")
l.restore()
diff --git a/src/runtime/os_freebsd_arm.go b/src/runtime/os_freebsd_arm.go
index 3feaa5e..e3eb2e4 100644
--- a/src/runtime/os_freebsd_arm.go
+++ b/src/runtime/os_freebsd_arm.go
@@ -12,14 +12,16 @@
)
func checkgoarm() {
- if goarm > 5 && cpu.HWCap&_HWCAP_VFP == 0 {
+ if goarm > 5 && cpu.HWCap&_HWCAP_VFP == 0 && goarmsoftfp == 0 {
print("runtime: this CPU has no floating point hardware, so it cannot run\n")
- print("this GOARM=", goarm, " binary. Recompile using GOARM=5.\n")
+ print("this GOARM=", goarm, " binary with hard floating point. Recompile\n")
+ print("using GOARMFP=soft to use soft floating point.\n")
exit(1)
}
- if goarm > 6 && cpu.HWCap&_HWCAP_VFPv3 == 0 {
+ if goarm > 6 && cpu.HWCap&_HWCAP_VFPv3 == 0 && goarmsoftfp == 0 {
print("runtime: this CPU has no VFPv3 floating point hardware, so it cannot run\n")
- print("this GOARM=", goarm, " binary. Recompile using GOARM=5 or GOARM=6.\n")
+ print("this GOARM=", goarm, " binary with hard floating point. Recompile\n")
+ print("using GOARMFP=soft to use soft floating point.\n")
exit(1)
}
diff --git a/src/runtime/os_linux_arm.go b/src/runtime/os_linux_arm.go
index bd3ab44..445ae7b 100644
--- a/src/runtime/os_linux_arm.go
+++ b/src/runtime/os_linux_arm.go
@@ -20,14 +20,16 @@
if GOOS == "android" {
return
}
- if goarm > 5 && cpu.HWCap&_HWCAP_VFP == 0 {
+ if goarm > 5 && cpu.HWCap&_HWCAP_VFP == 0 && goarmsoftfp == 0 {
print("runtime: this CPU has no floating point hardware, so it cannot run\n")
- print("this GOARM=", goarm, " binary. Recompile using GOARM=5.\n")
+ print("this GOARM=", goarm, " binary with hard floating point. Recompile\n")
+ print("using GOARMFP=soft to use soft floating point.\n")
exit(1)
}
- if goarm > 6 && cpu.HWCap&_HWCAP_VFPv3 == 0 {
+ if goarm > 6 && cpu.HWCap&_HWCAP_VFPv3 == 0 && goarmsoftfp == 0 {
print("runtime: this CPU has no VFPv3 floating point hardware, so it cannot run\n")
- print("this GOARM=", goarm, " binary. Recompile using GOARM=5 or GOARM=6.\n")
+ print("this GOARM=", goarm, " binary. Recompile using GOARMFP=soft to use soft\n")
+ print("floating point.\n")
exit(1)
}
}
diff --git a/src/runtime/preempt_arm.s b/src/runtime/preempt_arm.s
index 8f243c0..b68df5d 100644
--- a/src/runtime/preempt_arm.s
+++ b/src/runtime/preempt_arm.s
@@ -19,9 +19,9 @@
MOVW R12, 48(R13)
MOVW CPSR, R0
MOVW R0, 52(R13)
- MOVB ·goarm(SB), R0
- CMP $6, R0
- BLT nofp
+ MOVB ·goarmsoftfp(SB), R0
+ CMP $0, R0
+ BNE nofp
MOVW FPCR, R0
MOVW R0, 56(R13)
MOVD F0, 60(R13)
@@ -42,9 +42,9 @@
MOVD F15, 180(R13)
nofp:
CALL ·asyncPreempt2(SB)
- MOVB ·goarm(SB), R0
- CMP $6, R0
- BLT nofp2
+ MOVB ·goarmsoftfp(SB), R0
+ CMP $0, R0
+ BNE nofp2
MOVD 180(R13), F15
MOVD 172(R13), F14
MOVD 164(R13), F13
diff --git a/src/runtime/runtime2.go b/src/runtime/runtime2.go
index 75f00938..f876ba0 100644
--- a/src/runtime/runtime2.go
+++ b/src/runtime/runtime2.go
@@ -1187,7 +1187,9 @@
processorVersionInfo uint32
isIntel bool
- goarm uint8 // set by cmd/link on arm systems
+ // set by cmd/link on arm systems
+ goarm uint8
+ goarmsoftfp uint8
)
// Set by the linker so the runtime can determine the buildmode.
To view, visit change 514907. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Ian Lance Taylor, Keith Randall, Michael Pratt.
Ludi Rehak uploaded patch set #2 to this change.
all: add floating point option for ARM targets
This change introduces new options to set the floating point
mode on ARM targets. The GOARM version number can optionally
be followed by ',hardfloat' or ',softfloat' to select whether
to use hardware instructions or software emulation for
floating point computations, respectively. For example,
GOARM=7,softfloat.
Previously, software floating point support was limited to
GOARM=5. With these options, software floating point is now
extended to all ARM versions, including GOARM=6 and 7. This
avoids the need to downgrade to the ARMv5 instruction set on
ARMv7 chips without hardware FPUs.
When GOARM=5, only soft floating point is permitted.
For #61588
Change-Id: I23dc86fbd0733b262004a2ed001e1032cf371e94
---
M src/cmd/asm/internal/asm/endtoend_test.go
M src/cmd/compile/internal/arm/galign.go
M src/cmd/compile/internal/arm/ssa.go
M src/cmd/compile/internal/ssa/_gen/ARM.rules
M src/cmd/compile/internal/ssa/rewriteARM.go
M src/cmd/dist/util.go
M src/cmd/go/alldocs.go
M src/cmd/go/internal/help/helpdoc.go
M src/cmd/internal/obj/arm/asm5.go
M src/cmd/internal/obj/arm/obj5.go
M src/cmd/internal/testdir/testdir_test.go
M src/cmd/link/internal/ld/lib.go
M src/internal/buildcfg/cfg.go
M src/internal/cfg/cfg.go
M src/math/rand/rand_test.go
M src/runtime/asm_arm.s
M src/runtime/cgo/asm_arm.s
M src/runtime/mkpreempt.go
M src/runtime/os_freebsd_arm.go
M src/runtime/os_linux_arm.go
M src/runtime/preempt_arm.s
M src/runtime/runtime2.go
22 files changed, 228 insertions(+), 153 deletions(-)
To view, visit change 514907. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Ian Lance Taylor, Keith Randall, Michael Pratt.
Ludi Rehak uploaded patch set #3 to this change.
M src/math/rand/rand_test.go
M src/runtime/asm_arm.s
M src/runtime/cgo/asm_arm.s
M src/runtime/mkpreempt.go
M src/runtime/os_freebsd_arm.go
M src/runtime/os_linux_arm.go
M src/runtime/preempt_arm.s
M src/runtime/runtime2.go
21 files changed, 226 insertions(+), 152 deletions(-)
To view, visit change 514907. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Ian Lance Taylor, Keith Randall, Michael Pratt.
Ludi Rehak uploaded patch set #4 to this change.
21 files changed, 223 insertions(+), 152 deletions(-)
To view, visit change 514907. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Ian Lance Taylor, Keith Randall, Michael Pratt.
Ludi Rehak uploaded patch set #5 to this change.
all: add floating point option for ARM targets
This change introduces new options to set the floating point
mode on ARM targets. The GOARM version number can optionally be
followed by ',hardfloat' or ',softfloat' to select whether to
use hardware instructions or software emulation for floating
point computations, respectively. For example,
GOARM=7,softfloat.
Previously, software floating point support was limited to
GOARM=5. With these options, software floating point is now
extended to all ARM versions, including GOARM=6 and 7. This
change also extends hardware floating point to GOARM=5.
GOARM=5 defaults to softfloat and GOARM=6 and 7 default to
hardfloat.
Attention is currently required from: Ian Lance Taylor, Ludi Rehak, Michael Pratt.
7 comments:
File src/cmd/go/alldocs.go:
Patch Set #5, Line 2288: Values can be followed by option for floating point instructions.
The value can be followed by an option specifying how to implement floating point instructions.
File src/cmd/go/internal/help/helpdoc.go:
Patch Set #5, Line 604: Values can be followed by option for floating point instructions.
Same here.
File src/internal/buildcfg/cfg.go:
Patch Set #5, Line 126: fmt.Errorf("invalid GOARM: option must be either %q or %q", hardFloatOpt, softFloatOpt)
This would be kind of a weird error if you just had junk as your GOARM that happened to be the right length.
Patch Set #5, Line 132: return
I would reorganize this to strip the option off first, then run the old code.
floatSpecified := false
if strings.HasSuffix(v, softFloatOpt) {
g.SoftFloat = true
floatSpecified = true
v = v[:len(v)-len(softFloatOpt)]
}
... same for hard ...
Then do the old code. Then do:
// 5 defaults to softfloat. 6 and 7 default to hardfloat.
if !floatSpecified && g.Version == 5 {
g.SoftFloat = true
}
File src/runtime/os_freebsd_arm.go:
Patch Set #5, Line 18: ,softfloat to use soft floating point
this CPU has no floating point hardware, so it cannot run a
binary compiled for hard floating point. Recompile adding ,softfloat to GOARM.
Patch Set #5, Line 24: print("using GOARM=", goarm, ",softfloat to use soft floating point or GOARM=6 to\n")
Similar here.
File src/runtime/os_linux_arm.go:
Patch Set #5, Line 25: print("this GOARM=", goarm, " binary with hard floating point. Recompile\n")
Similar here.
To view, visit change 514907. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Ian Lance Taylor, Ludi Rehak, Michael Pratt.
Ludi Rehak uploaded patch set #6 to this change.
all: add floating point option for ARM targets
This change introduces new options to set the floating point
mode on ARM targets. The GOARM version number can optionally be
followed by ',hardfloat' or ',softfloat' to select whether to
use hardware instructions or software emulation for floating
point computations, respectively. For example,
GOARM=7,softfloat.
Previously, software floating point support was limited to
GOARM=5. With these options, software floating point is now
extended to all ARM versions, including GOARM=6 and 7. This
change also extends hardware floating point to GOARM=5.
GOARM=5 defaults to softfloat and GOARM=6 and 7 default to
hardfloat.
For #61588
Change-Id: I23dc86fbd0733b262004a2ed001e1032cf371e94
---
M src/cmd/asm/internal/asm/endtoend_test.go
M src/cmd/compile/internal/arm/galign.go
M src/cmd/compile/internal/arm/ssa.go
M src/cmd/compile/internal/ssa/_gen/ARM.rules
M src/cmd/compile/internal/ssa/rewriteARM.go
M src/cmd/dist/util.go
M src/cmd/go/alldocs.go
M src/cmd/go/internal/help/helpdoc.go
M src/cmd/internal/obj/arm/asm5.go
M src/cmd/internal/obj/arm/obj5.go
M src/cmd/internal/testdir/testdir_test.go
M src/cmd/link/internal/ld/lib.go
M src/internal/buildcfg/cfg.go
M src/math/rand/rand_test.go
M src/runtime/asm_arm.s
M src/runtime/cgo/asm_arm.s
M src/runtime/mkpreempt.go
M src/runtime/os_freebsd_arm.go
M src/runtime/os_linux_arm.go
M src/runtime/preempt_arm.s
M src/runtime/runtime2.go
21 files changed, 215 insertions(+), 152 deletions(-)
To view, visit change 514907. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Ian Lance Taylor, Keith Randall, Michael Pratt.
7 comments:
File src/cmd/go/alldocs.go:
Patch Set #5, Line 2288: Values can be followed by option for floating point instructions.
The value can be followed by an option specifying how to implement floating point instructions.
Done
File src/cmd/go/internal/help/helpdoc.go:
Patch Set #5, Line 604: Values can be followed by option for floating point instructions.
Same here.
Done
File src/internal/buildcfg/cfg.go:
Patch Set #5, Line 126: fmt.Errorf("invalid GOARM: option must be either %q or %q", hardFloatOpt, softFloatOpt)
This would be kind of a weird error if you just had junk as your GOARM that happened to be the right […]
Done
Patch Set #5, Line 132: return
I would reorganize this to strip the option off first, then run the old code. […]
Done
File src/runtime/os_freebsd_arm.go:
Patch Set #5, Line 18: ,softfloat to use soft floating point
this CPU has no floating point hardware, so it cannot run a […]
Done
I also removed the `if goarm > 5` statement, since `goarm = 5` no longer implies soft float.
Patch Set #5, Line 24: print("using GOARM=", goarm, ",softfloat to use soft floating point or GOARM=6 to\n")
Similar here.
Done
File src/runtime/os_linux_arm.go:
Patch Set #5, Line 25: print("this GOARM=", goarm, " binary with hard floating point. Recompile\n")
Similar here.
Done
To view, visit change 514907. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Ian Lance Taylor, Keith Randall, Michael Pratt.
1 comment:
Patchset:
Here are the remaining todos. I need some guidance on how to proceed (hopefully in time for the go1.22 release):
1) `TestARMEndToEnd()` in https://go-review.googlesource.com/c/go/+/514907/6/src/cmd/asm/internal/asm/endtoend_test.go
2) `xgetgoarm()`: https://go-review.googlesource.com/c/go/+/514907/6/src/cmd/dist/util.go
3) `var archVariants` https://go-review.googlesource.com/c/go/+/514907/6/src/cmd/internal/testdir/testdir_test.go
4) `gogoarchTags()`: https://go-review.googlesource.com/c/go/+/514907/6/src/internal/buildcfg/cfg.go
To view, visit change 514907. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Ian Lance Taylor, Ludi Rehak, Michael Pratt.
2 comments:
Patchset:
Code looks good. I think the only thing that still needs addressing is point 3.
Here are the remaining todos. I need some guidance on how to proceed (hopefully in time for the go1. […]
1) should not be an issue. That's just testing that the assembler works correctly. The assembler doesn't care what the float setting is (even if it is softfloat, the assembler will generate hardfloat instructions just fine).
2) is not much of an issue. That's just for detecting a default goarm, which I think shouldn't matter. I guess if you were building on a v7-nohardfloat machine, it would autodetect to v5. But you can always override with explicitly setting GOARM=v7,softfloat.
3) This is which archs we run tests on. I would add "v7,softfloat" to that list and see what happens on a v7 machine. There might be a codegen test or two to fix up, but it should otherwise work.
4) This has to do with build tags, and I don't think we're adding build tags for this option? (Just assembly macros, which don't count.)
To view, visit change 514907. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Ian Lance Taylor, Ludi Rehak, Michael Pratt.
Ludi Rehak uploaded patch set #7 to this change.
all: add floating point option for ARM targets
This change introduces new options to set the floating point
mode on ARM targets. The GOARM version number can optionally be
followed by ',hardfloat' or ',softfloat' to select whether to
use hardware instructions or software emulation for floating
point computations, respectively. For example,
GOARM=7,softfloat.
Previously, software floating point support was limited to
GOARM=5. With these options, software floating point is now
extended to all ARM versions, including GOARM=6 and 7. This
change also extends hardware floating point to GOARM=5.
GOARM=5 defaults to softfloat and GOARM=6 and 7 default to
hardfloat.
For #61588
Change-Id: I23dc86fbd0733b262004a2ed001e1032cf371e94
---
M src/cmd/asm/internal/asm/endtoend_test.go
M src/cmd/compile/internal/arm/galign.go
M src/cmd/compile/internal/arm/ssa.go
M src/cmd/compile/internal/ssa/_gen/ARM.rules
M src/cmd/compile/internal/ssa/rewriteARM.go
M src/cmd/go/alldocs.go
M src/cmd/go/internal/help/helpdoc.go
M src/cmd/internal/obj/arm/asm5.go
M src/cmd/internal/obj/arm/obj5.go
M src/cmd/internal/testdir/testdir_test.go
M src/cmd/link/internal/ld/lib.go
M src/internal/buildcfg/cfg.go
M src/math/rand/rand_test.go
M src/runtime/asm_arm.s
M src/runtime/cgo/asm_arm.s
M src/runtime/mkpreempt.go
M src/runtime/os_freebsd_arm.go
M src/runtime/os_linux_arm.go
M src/runtime/preempt_arm.s
M src/runtime/runtime2.go
20 files changed, 212 insertions(+), 152 deletions(-)
To view, visit change 514907. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Ian Lance Taylor, Keith Randall, Michael Pratt.
1 comment:
Patchset:
1) should not be an issue. That's just testing that the assembler works correctly. […]
Thank you Keith.
For point 3, I've added `7,softfloat` to the list. How do I go about testing on a v7 machine?
To view, visit change 514907. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Ian Lance Taylor, Keith Randall, Michael Pratt.
1 comment:
Patchset:
Thank you Keith. […]
I think I figured out what to do.
1. Build go from source, with this CL applied, on an armv7 machine.
```
root@raspberrypi:/home/pi/goroot/src/cmd/internal/testdir# go version
go version devel go1.22-2944abde96 Fri Nov 17 14:37:10 2023 -0800 linux/arm
```
2. Run the codegen unit tests.
```
root@raspberrypi:/home/pi/goroot/src/cmd/internal/testdir# go test -run Test/codegen testdir_test.go
ok command-line-arguments 4.898s
```
They all pass.
To view, visit change 514907. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Ian Lance Taylor, Ludi Rehak, Michael Pratt.
Patch set 7:Auto-Submit +1Code-Review +2Commit-Queue +1
1 comment:
Patchset:
I think I figured out what to do. […]
I think all.bash should run that test as well.
I always do (from GOROOT/src)
../bin/go test cmd/internal/testdir --all_codegen
But I think your incantation probably works also.
To view, visit change 514907. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Ian Lance Taylor, Ludi Rehak, Michael Pratt.
Patch set 7:Code-Review +1
Attention is currently required from: Ian Lance Taylor, Ludi Rehak, Michael Pratt.
Patch set 8:Code-Review +2Commit-Queue +1
Attention is currently required from: Ian Lance Taylor, Michael Pratt.
1 comment:
Patchset:
I think all.bash should run that test as well. […]
Acknowledged
To view, visit change 514907. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Ian Lance Taylor, Michael Pratt.
Michael Knyszek removed a vote from this change.
To view, visit change 514907. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Ian Lance Taylor, Ludi Rehak, Michael Pratt.
Patch set 8:Run-TryBot +1Auto-Submit +1Code-Review +1
1 comment:
Patchset:
TRY=linux-arm
To view, visit change 514907. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Ian Lance Taylor, Ludi Rehak, Michael Pratt.
1 comment:
Patchset:
Q: should the Go command ToolTags support take this into account? For example for MIPS this is how things are handled:
```
$ GOARCH=mips64 GOMIPS=hardfloat go list -f '{{context.ToolTags}}'
[goexperiment.coverageredesign goexperiment.allocheaders mips64.hardfloat]
```
Do we want the same for ARM? E.g. what should be printed for this cmd?
```
$ GOARCH=arm GOARM=6,softfloat go list -f '{{context.ToolTags}}'
```
To view, visit change 514907. To unsubscribe, or for help writing mail filters, visit settings.
Gopher Robot submitted this change.
all: add floating point option for ARM targets
This change introduces new options to set the floating point
mode on ARM targets. The GOARM version number can optionally be
followed by ',hardfloat' or ',softfloat' to select whether to
use hardware instructions or software emulation for floating
point computations, respectively. For example,
GOARM=7,softfloat.
Previously, software floating point support was limited to
GOARM=5. With these options, software floating point is now
extended to all ARM versions, including GOARM=6 and 7. This
change also extends hardware floating point to GOARM=5.
GOARM=5 defaults to softfloat and GOARM=6 and 7 default to
hardfloat.
For #61588
Change-Id: I23dc86fbd0733b262004a2ed001e1032cf371e94
Reviewed-on: https://go-review.googlesource.com/c/go/+/514907
Run-TryBot: Michael Knyszek <mkny...@google.com>
Reviewed-by: Michael Knyszek <mkny...@google.com>
Reviewed-by: Keith Randall <k...@golang.org>
TryBot-Result: Gopher Robot <go...@golang.org>
Reviewed-by: Keith Randall <k...@google.com>
Auto-Submit: Michael Knyszek <mkny...@google.com>
---
M src/cmd/asm/internal/asm/endtoend_test.go
M src/cmd/compile/internal/arm/galign.go
M src/cmd/compile/internal/arm/ssa.go
M src/cmd/compile/internal/ssa/_gen/ARM.rules
M src/cmd/compile/internal/ssa/rewriteARM.go
M src/cmd/go/alldocs.go
M src/cmd/go/internal/help/helpdoc.go
M src/cmd/internal/obj/arm/asm5.go
M src/cmd/internal/obj/arm/obj5.go
M src/cmd/internal/testdir/testdir_test.go
M src/cmd/link/internal/ld/lib.go
M src/internal/buildcfg/cfg.go
M src/math/rand/rand_test.go
M src/runtime/asm_arm.s
M src/runtime/cgo/asm_arm.s
M src/runtime/mkpreempt.go
M src/runtime/os_freebsd_arm.go
M src/runtime/os_linux_arm.go
M src/runtime/preempt_arm.s
M src/runtime/runtime2.go
20 files changed, 212 insertions(+), 152 deletions(-)
diff --git a/src/cmd/asm/internal/asm/endtoend_test.go b/src/cmd/asm/internal/asm/endtoend_test.go
index a2de636..592d7b4 100644
--- a/src/cmd/asm/internal/asm/endtoend_test.go
+++ b/src/cmd/asm/internal/asm/endtoend_test.go
@@ -372,10 +372,10 @@
}
func TestARMEndToEnd(t *testing.T) {
- defer func(old int) { buildcfg.GOARM = old }(buildcfg.GOARM)
+ defer func(old int) { buildcfg.GOARM.Version = old }(buildcfg.GOARM.Version)
for _, goarm := range []int{5, 6, 7} {
t.Logf("GOARM=%d", goarm)
- buildcfg.GOARM = goarm
+ buildcfg.GOARM.Version = goarm
testEndToEnd(t, "arm", "arm")
if goarm == 6 {
testEndToEnd(t, "arm", "armv6")
diff --git a/src/cmd/compile/internal/arm/galign.go b/src/cmd/compile/internal/arm/galign.go
index 23e52ba..43d8118 100644
--- a/src/cmd/compile/internal/arm/galign.go
+++ b/src/cmd/compile/internal/arm/galign.go
@@ -15,7 +15,7 @@
arch.LinkArch = &arm.Linkarm
arch.REGSP = arm.REGSP
arch.MAXWIDTH = (1 << 32) - 1
- arch.SoftFloat = buildcfg.GOARM == 5
+ arch.SoftFloat = buildcfg.GOARM.SoftFloat
arch.ZeroRange = zerorange
arch.Ginsnop = ginsnop
diff --git a/src/cmd/compile/internal/arm/ssa.go b/src/cmd/compile/internal/arm/ssa.go
index 7fcbb4d..638ed3e 100644
--- a/src/cmd/compile/internal/arm/ssa.go
+++ b/src/cmd/compile/internal/arm/ssa.go
@@ -289,7 +289,7 @@
case ssa.OpARMANDconst, ssa.OpARMBICconst:
// try to optimize ANDconst and BICconst to BFC, which saves bytes and ticks
// BFC is only available on ARMv7, and its result and source are in the same register
- if buildcfg.GOARM == 7 && v.Reg() == v.Args[0].Reg() {
+ if buildcfg.GOARM.Version == 7 && v.Reg() == v.Args[0].Reg() {
var val uint32
if v.Op == ssa.OpARMANDconst {
val = ^uint32(v.AuxInt)
@@ -646,7 +646,7 @@
default:
}
}
- if buildcfg.GOARM >= 6 {
+ if buildcfg.GOARM.Version >= 6 {
// generate more efficient "MOVB/MOVBU/MOVH/MOVHU Reg@>0, Reg" on ARMv6 & ARMv7
genshift(s, v, v.Op.Asm(), 0, v.Args[0].Reg(), v.Reg(), arm.SHIFT_RR, 0)
return
diff --git a/src/cmd/compile/internal/ssa/_gen/ARM.rules b/src/cmd/compile/internal/ssa/_gen/ARM.rules
index a60afb0..ed0ed80 100644
--- a/src/cmd/compile/internal/ssa/_gen/ARM.rules
+++ b/src/cmd/compile/internal/ssa/_gen/ARM.rules
@@ -66,17 +66,17 @@
// count trailing zero for ARMv5 and ARMv6
// 32 - CLZ(x&-x - 1)
-(Ctz32 <t> x) && buildcfg.GOARM<=6 =>
+(Ctz32 <t> x) && buildcfg.GOARM.Version<=6 =>
(RSBconst [32] (CLZ <t> (SUBconst <t> (AND <t> x (RSBconst <t> [0] x)) [1])))
-(Ctz16 <t> x) && buildcfg.GOARM<=6 =>
+(Ctz16 <t> x) && buildcfg.GOARM.Version<=6 =>
(RSBconst [32] (CLZ <t> (SUBconst <typ.UInt32> (AND <typ.UInt32> (ORconst <typ.UInt32> [0x10000] x) (RSBconst <typ.UInt32> [0] (ORconst <typ.UInt32> [0x10000] x))) [1])))
-(Ctz8 <t> x) && buildcfg.GOARM<=6 =>
+(Ctz8 <t> x) && buildcfg.GOARM.Version<=6 =>
(RSBconst [32] (CLZ <t> (SUBconst <typ.UInt32> (AND <typ.UInt32> (ORconst <typ.UInt32> [0x100] x) (RSBconst <typ.UInt32> [0] (ORconst <typ.UInt32> [0x100] x))) [1])))
// count trailing zero for ARMv7
-(Ctz32 <t> x) && buildcfg.GOARM==7 => (CLZ <t> (RBIT <t> x))
-(Ctz16 <t> x) && buildcfg.GOARM==7 => (CLZ <t> (RBIT <typ.UInt32> (ORconst <typ.UInt32> [0x10000] x)))
-(Ctz8 <t> x) && buildcfg.GOARM==7 => (CLZ <t> (RBIT <typ.UInt32> (ORconst <typ.UInt32> [0x100] x)))
+(Ctz32 <t> x) && buildcfg.GOARM.Version==7 => (CLZ <t> (RBIT <t> x))
+(Ctz16 <t> x) && buildcfg.GOARM.Version==7 => (CLZ <t> (RBIT <typ.UInt32> (ORconst <typ.UInt32> [0x10000] x)))
+(Ctz8 <t> x) && buildcfg.GOARM.Version==7 => (CLZ <t> (RBIT <typ.UInt32> (ORconst <typ.UInt32> [0x100] x)))
// bit length
(BitLen32 <t> x) => (RSBconst [32] (CLZ <t> x))
@@ -90,13 +90,13 @@
// t5 = x right rotate 8 bits -- (d, a, b, c )
// result = t4 ^ t5 -- (d, c, b, a )
// using shifted ops this can be done in 4 instructions.
-(Bswap32 <t> x) && buildcfg.GOARM==5 =>
+(Bswap32 <t> x) && buildcfg.GOARM.Version==5 =>
(XOR <t>
(SRLconst <t> (BICconst <t> (XOR <t> x (SRRconst <t> [16] x)) [0xff0000]) [8])
(SRRconst <t> x [8]))
// byte swap for ARMv6 and above
-(Bswap32 x) && buildcfg.GOARM>=6 => (REV x)
+(Bswap32 x) && buildcfg.GOARM.Version>=6 => (REV x)
// boolean ops -- booleans are represented with 0=false, 1=true
(AndB ...) => (AND ...)
@@ -741,10 +741,10 @@
(SUBconst [c] x) && !isARMImmRot(uint32(c)) && isARMImmRot(uint32(-c)) => (ADDconst [-c] x)
(ANDconst [c] x) && !isARMImmRot(uint32(c)) && isARMImmRot(^uint32(c)) => (BICconst [int32(^uint32(c))] x)
(BICconst [c] x) && !isARMImmRot(uint32(c)) && isARMImmRot(^uint32(c)) => (ANDconst [int32(^uint32(c))] x)
-(ADDconst [c] x) && buildcfg.GOARM==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && uint32(-c)<=0xffff => (SUBconst [-c] x)
-(SUBconst [c] x) && buildcfg.GOARM==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && uint32(-c)<=0xffff => (ADDconst [-c] x)
-(ANDconst [c] x) && buildcfg.GOARM==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && ^uint32(c)<=0xffff => (BICconst [int32(^uint32(c))] x)
-(BICconst [c] x) && buildcfg.GOARM==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && ^uint32(c)<=0xffff => (ANDconst [int32(^uint32(c))] x)
+(ADDconst [c] x) && buildcfg.GOARM.Version==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && uint32(-c)<=0xffff => (SUBconst [-c] x)
+(SUBconst [c] x) && buildcfg.GOARM.Version==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && uint32(-c)<=0xffff => (ADDconst [-c] x)
+(ANDconst [c] x) && buildcfg.GOARM.Version==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && ^uint32(c)<=0xffff => (BICconst [int32(^uint32(c))] x)
+(BICconst [c] x) && buildcfg.GOARM.Version==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && ^uint32(c)<=0xffff => (ANDconst [int32(^uint32(c))] x)
(ADDconst [c] (MOVWconst [d])) => (MOVWconst [c+d])
(ADDconst [c] (ADDconst [d] x)) => (ADDconst [c+d] x)
(ADDconst [c] (SUBconst [d] x)) => (ADDconst [c-d] x)
@@ -1139,7 +1139,7 @@
// UBFX instruction is supported by ARMv6T2, ARMv7 and above versions, REV16 is supported by
// ARMv6 and above versions. So for ARMv6, we need to match SLLconst, SRLconst and ORshiftLL.
((ADDshiftLL|ORshiftLL|XORshiftLL) <typ.UInt16> [8] (BFXU <typ.UInt16> [int32(armBFAuxInt(8, 8))] x) x) => (REV16 x)
-((ADDshiftLL|ORshiftLL|XORshiftLL) <typ.UInt16> [8] (SRLconst <typ.UInt16> [24] (SLLconst [16] x)) x) && buildcfg.GOARM>=6 => (REV16 x)
+((ADDshiftLL|ORshiftLL|XORshiftLL) <typ.UInt16> [8] (SRLconst <typ.UInt16> [24] (SLLconst [16] x)) x) && buildcfg.GOARM.Version>=6 => (REV16 x)
// use indexed loads and stores
(MOVWload [0] {sym} (ADD ptr idx) mem) && sym == nil => (MOVWloadidx ptr idx mem)
@@ -1209,25 +1209,25 @@
(BIC x x) => (MOVWconst [0])
(ADD (MUL x y) a) => (MULA x y a)
-(SUB a (MUL x y)) && buildcfg.GOARM == 7 => (MULS x y a)
-(RSB (MUL x y) a) && buildcfg.GOARM == 7 => (MULS x y a)
+(SUB a (MUL x y)) && buildcfg.GOARM.Version == 7 => (MULS x y a)
+(RSB (MUL x y) a) && buildcfg.GOARM.Version == 7 => (MULS x y a)
-(NEGF (MULF x y)) && buildcfg.GOARM >= 6 => (NMULF x y)
-(NEGD (MULD x y)) && buildcfg.GOARM >= 6 => (NMULD x y)
-(MULF (NEGF x) y) && buildcfg.GOARM >= 6 => (NMULF x y)
-(MULD (NEGD x) y) && buildcfg.GOARM >= 6 => (NMULD x y)
+(NEGF (MULF x y)) && buildcfg.GOARM.Version >= 6 => (NMULF x y)
+(NEGD (MULD x y)) && buildcfg.GOARM.Version >= 6 => (NMULD x y)
+(MULF (NEGF x) y) && buildcfg.GOARM.Version >= 6 => (NMULF x y)
+(MULD (NEGD x) y) && buildcfg.GOARM.Version >= 6 => (NMULD x y)
(NMULF (NEGF x) y) => (MULF x y)
(NMULD (NEGD x) y) => (MULD x y)
// the result will overwrite the addend, since they are in the same register
-(ADDF a (MULF x y)) && a.Uses == 1 && buildcfg.GOARM >= 6 => (MULAF a x y)
-(ADDF a (NMULF x y)) && a.Uses == 1 && buildcfg.GOARM >= 6 => (MULSF a x y)
-(ADDD a (MULD x y)) && a.Uses == 1 && buildcfg.GOARM >= 6 => (MULAD a x y)
-(ADDD a (NMULD x y)) && a.Uses == 1 && buildcfg.GOARM >= 6 => (MULSD a x y)
-(SUBF a (MULF x y)) && a.Uses == 1 && buildcfg.GOARM >= 6 => (MULSF a x y)
-(SUBF a (NMULF x y)) && a.Uses == 1 && buildcfg.GOARM >= 6 => (MULAF a x y)
-(SUBD a (MULD x y)) && a.Uses == 1 && buildcfg.GOARM >= 6 => (MULSD a x y)
-(SUBD a (NMULD x y)) && a.Uses == 1 && buildcfg.GOARM >= 6 => (MULAD a x y)
+(ADDF a (MULF x y)) && a.Uses == 1 && buildcfg.GOARM.Version >= 6 => (MULAF a x y)
+(ADDF a (NMULF x y)) && a.Uses == 1 && buildcfg.GOARM.Version >= 6 => (MULSF a x y)
+(ADDD a (MULD x y)) && a.Uses == 1 && buildcfg.GOARM.Version >= 6 => (MULAD a x y)
+(ADDD a (NMULD x y)) && a.Uses == 1 && buildcfg.GOARM.Version >= 6 => (MULSD a x y)
+(SUBF a (MULF x y)) && a.Uses == 1 && buildcfg.GOARM.Version >= 6 => (MULSF a x y)
+(SUBF a (NMULF x y)) && a.Uses == 1 && buildcfg.GOARM.Version >= 6 => (MULAF a x y)
+(SUBD a (MULD x y)) && a.Uses == 1 && buildcfg.GOARM.Version >= 6 => (MULSD a x y)
+(SUBD a (NMULD x y)) && a.Uses == 1 && buildcfg.GOARM.Version >= 6 => (MULAD a x y)
(AND x (MVN y)) => (BIC x y)
@@ -1259,8 +1259,8 @@
(CMPD x (MOVDconst [0])) => (CMPD0 x)
// bit extraction
-(SRAconst (SLLconst x [c]) [d]) && buildcfg.GOARM==7 && uint64(d)>=uint64(c) && uint64(d)<=31 => (BFX [(d-c)|(32-d)<<8] x)
-(SRLconst (SLLconst x [c]) [d]) && buildcfg.GOARM==7 && uint64(d)>=uint64(c) && uint64(d)<=31 => (BFXU [(d-c)|(32-d)<<8] x)
+(SRAconst (SLLconst x [c]) [d]) && buildcfg.GOARM.Version==7 && uint64(d)>=uint64(c) && uint64(d)<=31 => (BFX [(d-c)|(32-d)<<8] x)
+(SRLconst (SLLconst x [c]) [d]) && buildcfg.GOARM.Version==7 && uint64(d)>=uint64(c) && uint64(d)<=31 => (BFXU [(d-c)|(32-d)<<8] x)
// comparison simplification
((EQ|NE) (CMP x (RSBconst [0] y))) => ((EQ|NE) (CMN x y)) // sense of carry bit not preserved; see also #50854
diff --git a/src/cmd/compile/internal/ssa/rewriteARM.go b/src/cmd/compile/internal/ssa/rewriteARM.go
index 70cacb9..971c9a5 100644
--- a/src/cmd/compile/internal/ssa/rewriteARM.go
+++ b/src/cmd/compile/internal/ssa/rewriteARM.go
@@ -1496,7 +1496,7 @@
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (ADDD a (MULD x y))
- // cond: a.Uses == 1 && buildcfg.GOARM >= 6
+ // cond: a.Uses == 1 && buildcfg.GOARM.Version >= 6
// result: (MULAD a x y)
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
@@ -1506,7 +1506,7 @@
}
y := v_1.Args[1]
x := v_1.Args[0]
- if !(a.Uses == 1 && buildcfg.GOARM >= 6) {
+ if !(a.Uses == 1 && buildcfg.GOARM.Version >= 6) {
continue
}
v.reset(OpARMMULAD)
@@ -1516,7 +1516,7 @@
break
}
// match: (ADDD a (NMULD x y))
- // cond: a.Uses == 1 && buildcfg.GOARM >= 6
+ // cond: a.Uses == 1 && buildcfg.GOARM.Version >= 6
// result: (MULSD a x y)
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
@@ -1526,7 +1526,7 @@
}
y := v_1.Args[1]
x := v_1.Args[0]
- if !(a.Uses == 1 && buildcfg.GOARM >= 6) {
+ if !(a.Uses == 1 && buildcfg.GOARM.Version >= 6) {
continue
}
v.reset(OpARMMULSD)
@@ -1541,7 +1541,7 @@
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (ADDF a (MULF x y))
- // cond: a.Uses == 1 && buildcfg.GOARM >= 6
+ // cond: a.Uses == 1 && buildcfg.GOARM.Version >= 6
// result: (MULAF a x y)
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
@@ -1551,7 +1551,7 @@
}
y := v_1.Args[1]
x := v_1.Args[0]
- if !(a.Uses == 1 && buildcfg.GOARM >= 6) {
+ if !(a.Uses == 1 && buildcfg.GOARM.Version >= 6) {
continue
}
v.reset(OpARMMULAF)
@@ -1561,7 +1561,7 @@
break
}
// match: (ADDF a (NMULF x y))
- // cond: a.Uses == 1 && buildcfg.GOARM >= 6
+ // cond: a.Uses == 1 && buildcfg.GOARM.Version >= 6
// result: (MULSF a x y)
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
@@ -1571,7 +1571,7 @@
}
y := v_1.Args[1]
x := v_1.Args[0]
- if !(a.Uses == 1 && buildcfg.GOARM >= 6) {
+ if !(a.Uses == 1 && buildcfg.GOARM.Version >= 6) {
continue
}
v.reset(OpARMMULSF)
@@ -1979,12 +1979,12 @@
return true
}
// match: (ADDconst [c] x)
- // cond: buildcfg.GOARM==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && uint32(-c)<=0xffff
+ // cond: buildcfg.GOARM.Version==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && uint32(-c)<=0xffff
// result: (SUBconst [-c] x)
for {
c := auxIntToInt32(v.AuxInt)
x := v_0
- if !(buildcfg.GOARM == 7 && !isARMImmRot(uint32(c)) && uint32(c) > 0xffff && uint32(-c) <= 0xffff) {
+ if !(buildcfg.GOARM.Version == 7 && !isARMImmRot(uint32(c)) && uint32(c) > 0xffff && uint32(-c) <= 0xffff) {
break
}
v.reset(OpARMSUBconst)
@@ -2099,7 +2099,7 @@
return true
}
// match: (ADDshiftLL <typ.UInt16> [8] (SRLconst <typ.UInt16> [24] (SLLconst [16] x)) x)
- // cond: buildcfg.GOARM>=6
+ // cond: buildcfg.GOARM.Version>=6
// result: (REV16 x)
for {
if v.Type != typ.UInt16 || auxIntToInt32(v.AuxInt) != 8 || v_0.Op != OpARMSRLconst || v_0.Type != typ.UInt16 || auxIntToInt32(v_0.AuxInt) != 24 {
@@ -2110,7 +2110,7 @@
break
}
x := v_0_0.Args[0]
- if x != v_1 || !(buildcfg.GOARM >= 6) {
+ if x != v_1 || !(buildcfg.GOARM.Version >= 6) {
break
}
v.reset(OpARMREV16)
@@ -2551,12 +2551,12 @@
return true
}
// match: (ANDconst [c] x)
- // cond: buildcfg.GOARM==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && ^uint32(c)<=0xffff
+ // cond: buildcfg.GOARM.Version==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && ^uint32(c)<=0xffff
// result: (BICconst [int32(^uint32(c))] x)
for {
c := auxIntToInt32(v.AuxInt)
x := v_0
- if !(buildcfg.GOARM == 7 && !isARMImmRot(uint32(c)) && uint32(c) > 0xffff && ^uint32(c) <= 0xffff) {
+ if !(buildcfg.GOARM.Version == 7 && !isARMImmRot(uint32(c)) && uint32(c) > 0xffff && ^uint32(c) <= 0xffff) {
break
}
v.reset(OpARMBICconst)
@@ -3052,12 +3052,12 @@
return true
}
// match: (BICconst [c] x)
- // cond: buildcfg.GOARM==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && ^uint32(c)<=0xffff
+ // cond: buildcfg.GOARM.Version==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && ^uint32(c)<=0xffff
// result: (ANDconst [int32(^uint32(c))] x)
for {
c := auxIntToInt32(v.AuxInt)
x := v_0
- if !(buildcfg.GOARM == 7 && !isARMImmRot(uint32(c)) && uint32(c) > 0xffff && ^uint32(c) <= 0xffff) {
+ if !(buildcfg.GOARM.Version == 7 && !isARMImmRot(uint32(c)) && uint32(c) > 0xffff && ^uint32(c) <= 0xffff) {
break
}
v.reset(OpARMANDconst)
@@ -7590,7 +7590,7 @@
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (MULD (NEGD x) y)
- // cond: buildcfg.GOARM >= 6
+ // cond: buildcfg.GOARM.Version >= 6
// result: (NMULD x y)
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
@@ -7599,7 +7599,7 @@
}
x := v_0.Args[0]
y := v_1
- if !(buildcfg.GOARM >= 6) {
+ if !(buildcfg.GOARM.Version >= 6) {
continue
}
v.reset(OpARMNMULD)
@@ -7614,7 +7614,7 @@
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (MULF (NEGF x) y)
- // cond: buildcfg.GOARM >= 6
+ // cond: buildcfg.GOARM.Version >= 6
// result: (NMULF x y)
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
@@ -7623,7 +7623,7 @@
}
x := v_0.Args[0]
y := v_1
- if !(buildcfg.GOARM >= 6) {
+ if !(buildcfg.GOARM.Version >= 6) {
continue
}
v.reset(OpARMNMULF)
@@ -8247,7 +8247,7 @@
func rewriteValueARM_OpARMNEGD(v *Value) bool {
v_0 := v.Args[0]
// match: (NEGD (MULD x y))
- // cond: buildcfg.GOARM >= 6
+ // cond: buildcfg.GOARM.Version >= 6
// result: (NMULD x y)
for {
if v_0.Op != OpARMMULD {
@@ -8255,7 +8255,7 @@
}
y := v_0.Args[1]
x := v_0.Args[0]
- if !(buildcfg.GOARM >= 6) {
+ if !(buildcfg.GOARM.Version >= 6) {
break
}
v.reset(OpARMNMULD)
@@ -8267,7 +8267,7 @@
func rewriteValueARM_OpARMNEGF(v *Value) bool {
v_0 := v.Args[0]
// match: (NEGF (MULF x y))
- // cond: buildcfg.GOARM >= 6
+ // cond: buildcfg.GOARM.Version >= 6
// result: (NMULF x y)
for {
if v_0.Op != OpARMMULF {
@@ -8275,7 +8275,7 @@
}
y := v_0.Args[1]
x := v_0.Args[0]
- if !(buildcfg.GOARM >= 6) {
+ if !(buildcfg.GOARM.Version >= 6) {
break
}
v.reset(OpARMNMULF)
@@ -8583,7 +8583,7 @@
return true
}
// match: (ORshiftLL <typ.UInt16> [8] (SRLconst <typ.UInt16> [24] (SLLconst [16] x)) x)
- // cond: buildcfg.GOARM>=6
+ // cond: buildcfg.GOARM.Version>=6
// result: (REV16 x)
for {
if v.Type != typ.UInt16 || auxIntToInt32(v.AuxInt) != 8 || v_0.Op != OpARMSRLconst || v_0.Type != typ.UInt16 || auxIntToInt32(v_0.AuxInt) != 24 {
@@ -8594,7 +8594,7 @@
break
}
x := v_0_0.Args[0]
- if x != v_1 || !(buildcfg.GOARM >= 6) {
+ if x != v_1 || !(buildcfg.GOARM.Version >= 6) {
break
}
v.reset(OpARMREV16)
@@ -9048,7 +9048,7 @@
return true
}
// match: (RSB (MUL x y) a)
- // cond: buildcfg.GOARM == 7
+ // cond: buildcfg.GOARM.Version == 7
// result: (MULS x y a)
for {
if v_0.Op != OpARMMUL {
@@ -9057,7 +9057,7 @@
y := v_0.Args[1]
x := v_0.Args[0]
a := v_1
- if !(buildcfg.GOARM == 7) {
+ if !(buildcfg.GOARM.Version == 7) {
break
}
v.reset(OpARMMULS)
@@ -10534,7 +10534,7 @@
return true
}
// match: (SRAconst (SLLconst x [c]) [d])
- // cond: buildcfg.GOARM==7 && uint64(d)>=uint64(c) && uint64(d)<=31
+ // cond: buildcfg.GOARM.Version==7 && uint64(d)>=uint64(c) && uint64(d)<=31
// result: (BFX [(d-c)|(32-d)<<8] x)
for {
d := auxIntToInt32(v.AuxInt)
@@ -10543,7 +10543,7 @@
}
c := auxIntToInt32(v_0.AuxInt)
x := v_0.Args[0]
- if !(buildcfg.GOARM == 7 && uint64(d) >= uint64(c) && uint64(d) <= 31) {
+ if !(buildcfg.GOARM.Version == 7 && uint64(d) >= uint64(c) && uint64(d) <= 31) {
break
}
v.reset(OpARMBFX)
@@ -10590,7 +10590,7 @@
return true
}
// match: (SRLconst (SLLconst x [c]) [d])
- // cond: buildcfg.GOARM==7 && uint64(d)>=uint64(c) && uint64(d)<=31
+ // cond: buildcfg.GOARM.Version==7 && uint64(d)>=uint64(c) && uint64(d)<=31
// result: (BFXU [(d-c)|(32-d)<<8] x)
for {
d := auxIntToInt32(v.AuxInt)
@@ -10599,7 +10599,7 @@
}
c := auxIntToInt32(v_0.AuxInt)
x := v_0.Args[0]
- if !(buildcfg.GOARM == 7 && uint64(d) >= uint64(c) && uint64(d) <= 31) {
+ if !(buildcfg.GOARM.Version == 7 && uint64(d) >= uint64(c) && uint64(d) <= 31) {
break
}
v.reset(OpARMBFXU)
@@ -10830,7 +10830,7 @@
return true
}
// match: (SUB a (MUL x y))
- // cond: buildcfg.GOARM == 7
+ // cond: buildcfg.GOARM.Version == 7
// result: (MULS x y a)
for {
a := v_0
@@ -10839,7 +10839,7 @@
}
y := v_1.Args[1]
x := v_1.Args[0]
- if !(buildcfg.GOARM == 7) {
+ if !(buildcfg.GOARM.Version == 7) {
break
}
v.reset(OpARMMULS)
@@ -10852,7 +10852,7 @@
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (SUBD a (MULD x y))
- // cond: a.Uses == 1 && buildcfg.GOARM >= 6
+ // cond: a.Uses == 1 && buildcfg.GOARM.Version >= 6
// result: (MULSD a x y)
for {
a := v_0
@@ -10861,7 +10861,7 @@
}
y := v_1.Args[1]
x := v_1.Args[0]
- if !(a.Uses == 1 && buildcfg.GOARM >= 6) {
+ if !(a.Uses == 1 && buildcfg.GOARM.Version >= 6) {
break
}
v.reset(OpARMMULSD)
@@ -10869,7 +10869,7 @@
return true
}
// match: (SUBD a (NMULD x y))
- // cond: a.Uses == 1 && buildcfg.GOARM >= 6
+ // cond: a.Uses == 1 && buildcfg.GOARM.Version >= 6
// result: (MULAD a x y)
for {
a := v_0
@@ -10878,7 +10878,7 @@
}
y := v_1.Args[1]
x := v_1.Args[0]
- if !(a.Uses == 1 && buildcfg.GOARM >= 6) {
+ if !(a.Uses == 1 && buildcfg.GOARM.Version >= 6) {
break
}
v.reset(OpARMMULAD)
@@ -10891,7 +10891,7 @@
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (SUBF a (MULF x y))
- // cond: a.Uses == 1 && buildcfg.GOARM >= 6
+ // cond: a.Uses == 1 && buildcfg.GOARM.Version >= 6
// result: (MULSF a x y)
for {
a := v_0
@@ -10900,7 +10900,7 @@
}
y := v_1.Args[1]
x := v_1.Args[0]
- if !(a.Uses == 1 && buildcfg.GOARM >= 6) {
+ if !(a.Uses == 1 && buildcfg.GOARM.Version >= 6) {
break
}
v.reset(OpARMMULSF)
@@ -10908,7 +10908,7 @@
return true
}
// match: (SUBF a (NMULF x y))
- // cond: a.Uses == 1 && buildcfg.GOARM >= 6
+ // cond: a.Uses == 1 && buildcfg.GOARM.Version >= 6
// result: (MULAF a x y)
for {
a := v_0
@@ -10917,7 +10917,7 @@
}
y := v_1.Args[1]
x := v_1.Args[0]
- if !(a.Uses == 1 && buildcfg.GOARM >= 6) {
+ if !(a.Uses == 1 && buildcfg.GOARM.Version >= 6) {
break
}
v.reset(OpARMMULAF)
@@ -11383,12 +11383,12 @@
return true
}
// match: (SUBconst [c] x)
- // cond: buildcfg.GOARM==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && uint32(-c)<=0xffff
+ // cond: buildcfg.GOARM.Version==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && uint32(-c)<=0xffff
// result: (ADDconst [-c] x)
for {
c := auxIntToInt32(v.AuxInt)
x := v_0
- if !(buildcfg.GOARM == 7 && !isARMImmRot(uint32(c)) && uint32(c) > 0xffff && uint32(-c) <= 0xffff) {
+ if !(buildcfg.GOARM.Version == 7 && !isARMImmRot(uint32(c)) && uint32(c) > 0xffff && uint32(-c) <= 0xffff) {
break
}
v.reset(OpARMADDconst)
@@ -12710,7 +12710,7 @@
return true
}
// match: (XORshiftLL <typ.UInt16> [8] (SRLconst <typ.UInt16> [24] (SLLconst [16] x)) x)
- // cond: buildcfg.GOARM>=6
+ // cond: buildcfg.GOARM.Version>=6
// result: (REV16 x)
for {
if v.Type != typ.UInt16 || auxIntToInt32(v.AuxInt) != 8 || v_0.Op != OpARMSRLconst || v_0.Type != typ.UInt16 || auxIntToInt32(v_0.AuxInt) != 24 {
@@ -12721,7 +12721,7 @@
break
}
x := v_0_0.Args[0]
- if x != v_1 || !(buildcfg.GOARM >= 6) {
+ if x != v_1 || !(buildcfg.GOARM.Version >= 6) {
break
}
v.reset(OpARMREV16)
@@ -13062,12 +13062,12 @@
v_0 := v.Args[0]
b := v.Block
// match: (Bswap32 <t> x)
- // cond: buildcfg.GOARM==5
+ // cond: buildcfg.GOARM.Version==5
// result: (XOR <t> (SRLconst <t> (BICconst <t> (XOR <t> x (SRRconst <t> [16] x)) [0xff0000]) [8]) (SRRconst <t> x [8]))
for {
t := v.Type
x := v_0
- if !(buildcfg.GOARM == 5) {
+ if !(buildcfg.GOARM.Version == 5) {
break
}
v.reset(OpARMXOR)
@@ -13090,11 +13090,11 @@
return true
}
// match: (Bswap32 x)
- // cond: buildcfg.GOARM>=6
+ // cond: buildcfg.GOARM.Version>=6
// result: (REV x)
for {
x := v_0
- if !(buildcfg.GOARM >= 6) {
+ if !(buildcfg.GOARM.Version >= 6) {
break
}
v.reset(OpARMREV)
@@ -13177,12 +13177,12 @@
b := v.Block
typ := &b.Func.Config.Types
// match: (Ctz16 <t> x)
- // cond: buildcfg.GOARM<=6
+ // cond: buildcfg.GOARM.Version<=6
// result: (RSBconst [32] (CLZ <t> (SUBconst <typ.UInt32> (AND <typ.UInt32> (ORconst <typ.UInt32> [0x10000] x) (RSBconst <typ.UInt32> [0] (ORconst <typ.UInt32> [0x10000] x))) [1])))
for {
t := v.Type
x := v_0
- if !(buildcfg.GOARM <= 6) {
+ if !(buildcfg.GOARM.Version <= 6) {
break
}
v.reset(OpARMRSBconst)
@@ -13204,12 +13204,12 @@
return true
}
// match: (Ctz16 <t> x)
- // cond: buildcfg.GOARM==7
+ // cond: buildcfg.GOARM.Version==7
// result: (CLZ <t> (RBIT <typ.UInt32> (ORconst <typ.UInt32> [0x10000] x)))
for {
t := v.Type
x := v_0
- if !(buildcfg.GOARM == 7) {
+ if !(buildcfg.GOARM.Version == 7) {
break
}
v.reset(OpARMCLZ)
@@ -13228,12 +13228,12 @@
v_0 := v.Args[0]
b := v.Block
// match: (Ctz32 <t> x)
- // cond: buildcfg.GOARM<=6
+ // cond: buildcfg.GOARM.Version<=6
// result: (RSBconst [32] (CLZ <t> (SUBconst <t> (AND <t> x (RSBconst <t> [0] x)) [1])))
for {
t := v.Type
x := v_0
- if !(buildcfg.GOARM <= 6) {
+ if !(buildcfg.GOARM.Version <= 6) {
break
}
v.reset(OpARMRSBconst)
@@ -13252,12 +13252,12 @@
return true
}
// match: (Ctz32 <t> x)
- // cond: buildcfg.GOARM==7
+ // cond: buildcfg.GOARM.Version==7
// result: (CLZ <t> (RBIT <t> x))
for {
t := v.Type
x := v_0
- if !(buildcfg.GOARM == 7) {
+ if !(buildcfg.GOARM.Version == 7) {
break
}
v.reset(OpARMCLZ)
@@ -13274,12 +13274,12 @@
b := v.Block
typ := &b.Func.Config.Types
// match: (Ctz8 <t> x)
- // cond: buildcfg.GOARM<=6
+ // cond: buildcfg.GOARM.Version<=6
// result: (RSBconst [32] (CLZ <t> (SUBconst <typ.UInt32> (AND <typ.UInt32> (ORconst <typ.UInt32> [0x100] x) (RSBconst <typ.UInt32> [0] (ORconst <typ.UInt32> [0x100] x))) [1])))
for {
t := v.Type
x := v_0
- if !(buildcfg.GOARM <= 6) {
+ if !(buildcfg.GOARM.Version <= 6) {
break
}
v.reset(OpARMRSBconst)
@@ -13301,12 +13301,12 @@
return true
}
// match: (Ctz8 <t> x)
- // cond: buildcfg.GOARM==7
+ // cond: buildcfg.GOARM.Version==7
// result: (CLZ <t> (RBIT <typ.UInt32> (ORconst <typ.UInt32> [0x100] x)))
for {
t := v.Type
x := v_0
- if !(buildcfg.GOARM == 7) {
+ if !(buildcfg.GOARM.Version == 7) {
break
}
v.reset(OpARMCLZ)
diff --git a/src/cmd/go/alldocs.go b/src/cmd/go/alldocs.go
index a5148ad..a40d055 100644
--- a/src/cmd/go/alldocs.go
+++ b/src/cmd/go/alldocs.go
@@ -2285,6 +2285,8 @@
// GOARM
// For GOARCH=arm, the ARM architecture for which to compile.
// Valid values are 5, 6, 7.
+// The value can be followed by an option specifying how to implement floating point instructions.
+// Valid options are ,softfloat (default for 5) and ,hardfloat (default for 6 and 7).
// GO386
// For GOARCH=386, how to implement floating point instructions.
// Valid values are sse2 (default), softfloat.
diff --git a/src/cmd/go/internal/help/helpdoc.go b/src/cmd/go/internal/help/helpdoc.go
index 93613ac..c5d1e2a 100644
--- a/src/cmd/go/internal/help/helpdoc.go
+++ b/src/cmd/go/internal/help/helpdoc.go
@@ -601,6 +601,8 @@
GOARM
For GOARCH=arm, the ARM architecture for which to compile.
Valid values are 5, 6, 7.
+ The value can be followed by an option specifying how to implement floating point instructions.
+ Valid options are ,softfloat (default for 5) and ,hardfloat (default for 6 and 7).
GO386
For GOARCH=386, how to implement floating point instructions.
Valid values are sse2 (default), softfloat.
diff --git a/src/cmd/internal/obj/arm/asm5.go b/src/cmd/internal/obj/arm/asm5.go
index 177ffd9..24b9bdd 100644
--- a/src/cmd/internal/obj/arm/asm5.go
+++ b/src/cmd/internal/obj/arm/asm5.go
@@ -979,7 +979,7 @@
if immrot(^uint32(c.instoffset)) != 0 {
return C_NCON
}
- if uint32(c.instoffset) <= 0xffff && buildcfg.GOARM == 7 {
+ if uint32(c.instoffset) <= 0xffff && buildcfg.GOARM.Version == 7 {
return C_SCON
}
if x, y := immrot2a(uint32(c.instoffset)); x != 0 && y != 0 {
@@ -3044,16 +3044,16 @@
}
func (c *ctxt5) chipzero5(e float64) int {
- // We use GOARM=7 to gate the use of VFPv3 vmov (imm) instructions.
- if buildcfg.GOARM < 7 || math.Float64bits(e) != 0 {
+ // We use GOARM.Version=7 and !GOARM.SoftFloat to gate the use of VFPv3 vmov (imm) instructions.
+ if buildcfg.GOARM.Version < 7 || buildcfg.GOARM.SoftFloat || math.Float64bits(e) != 0 {
return -1
}
return 0
}
func (c *ctxt5) chipfloat5(e float64) int {
- // We use GOARM=7 to gate the use of VFPv3 vmov (imm) instructions.
- if buildcfg.GOARM < 7 {
+ // We use GOARM.Version=7 and !GOARM.SoftFloat to gate the use of VFPv3 vmov (imm) instructions.
+ if buildcfg.GOARM.Version < 7 || buildcfg.GOARM.SoftFloat {
return -1
}
diff --git a/src/cmd/internal/obj/arm/obj5.go b/src/cmd/internal/obj/arm/obj5.go
index fb7c260..def4f52 100644
--- a/src/cmd/internal/obj/arm/obj5.go
+++ b/src/cmd/internal/obj/arm/obj5.go
@@ -66,7 +66,7 @@
ctxt.Diag("%v: TLS MRC instruction must write to R0 as it might get translated into a BL instruction", p.Line())
}
- if buildcfg.GOARM < 7 {
+ if buildcfg.GOARM.Version < 7 {
// Replace it with BL runtime.read_tls_fallback(SB) for ARM CPUs that lack the tls extension.
if progedit_tlsfallback == nil {
progedit_tlsfallback = ctxt.Lookup("runtime.read_tls_fallback")
diff --git a/src/cmd/internal/testdir/testdir_test.go b/src/cmd/internal/testdir/testdir_test.go
index 1b91dbe..0fb56e6 100644
--- a/src/cmd/internal/testdir/testdir_test.go
+++ b/src/cmd/internal/testdir/testdir_test.go
@@ -1458,7 +1458,7 @@
archVariants = map[string][]string{
"386": {"GO386", "sse2", "softfloat"},
"amd64": {"GOAMD64", "v1", "v2", "v3", "v4"},
- "arm": {"GOARM", "5", "6", "7"},
+ "arm": {"GOARM", "5", "6", "7", "7,softfloat"},
"arm64": {},
"loong64": {},
"mips": {"GOMIPS", "hardfloat", "softfloat"},
diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go
index b603fba..eab74dc 100644
--- a/src/cmd/link/internal/ld/lib.go
+++ b/src/cmd/link/internal/ld/lib.go
@@ -878,7 +878,17 @@
sb := ctxt.loader.MakeSymbolUpdater(goarm)
sb.SetType(sym.SDATA)
sb.SetSize(0)
- sb.AddUint8(uint8(buildcfg.GOARM))
+ sb.AddUint8(uint8(buildcfg.GOARM.Version))
+
+ goarmsoftfp := ctxt.loader.LookupOrCreateSym("runtime.goarmsoftfp", 0)
+ sb2 := ctxt.loader.MakeSymbolUpdater(goarmsoftfp)
+ sb2.SetType(sym.SDATA)
+ sb2.SetSize(0)
+ if buildcfg.GOARM.SoftFloat {
+ sb2.AddUint8(1)
+ } else {
+ sb2.AddUint8(0)
+ }
}
// Set runtime.disableMemoryProfiling bool if
diff --git a/src/internal/buildcfg/cfg.go b/src/internal/buildcfg/cfg.go
index b97b9c1..8b97a65 100644
--- a/src/internal/buildcfg/cfg.go
+++ b/src/internal/buildcfg/cfg.go
@@ -69,22 +69,61 @@
return int(defaultGOAMD64[len("v")] - '0')
}
-func goarm() int {
+type goarmFeatures struct {
+ Version int
+ SoftFloat bool
+}
+
+func (g goarmFeatures) String() string {
+ armStr := strconv.Itoa(g.Version)
+ if g.SoftFloat {
+ armStr += ",softfloat"
+ } else {
+ armStr += ",hardfloat"
+ }
+ return armStr
+}
+
+func goarm() (g goarmFeatures) {
+ const (
+ softFloatOpt = ",softfloat"
+ hardFloatOpt = ",hardfloat"
+ )
def := defaultGOARM
if GOOS == "android" && GOARCH == "arm" {
// Android arm devices always support GOARM=7.
def = "7"
}
- switch v := envOr("GOARM", def); v {
- case "5":
- return 5
- case "6":
- return 6
- case "7":
- return 7
+ v := envOr("GOARM", def)
+
+ floatSpecified := false
+ if strings.HasSuffix(v, softFloatOpt) {
+ g.SoftFloat = true
+ floatSpecified = true
+ v = v[:len(v)-len(softFloatOpt)]
}
- Error = fmt.Errorf("invalid GOARM: must be 5, 6, 7")
- return int(def[0] - '0')
+ if strings.HasSuffix(v, hardFloatOpt) {
+ floatSpecified = true
+ v = v[:len(v)-len(hardFloatOpt)]
+ }
+
+ switch v {
+ case "5":
+ g.Version = 5
+ case "6":
+ g.Version = 6
+ case "7":
+ g.Version = 7
+ default:
+ Error = fmt.Errorf("invalid GOARM: must start with 5, 6, or 7, and may optionally end in either %q or %q", hardFloatOpt, softFloatOpt)
+ g.Version = int(def[0] - '0')
+ }
+
+ // 5 defaults to softfloat. 6 and 7 default to hardfloat.
+ if !floatSpecified && g.Version == 5 {
+ g.SoftFloat = true
+ }
+ return
}
func gomips() string {
@@ -182,7 +221,7 @@
case "amd64":
return "GOAMD64", fmt.Sprintf("v%d", GOAMD64)
case "arm":
- return "GOARM", strconv.Itoa(GOARM)
+ return "GOARM", GOARM.String()
case "mips", "mipsle":
return "GOMIPS", GOMIPS
case "mips64", "mips64le":
@@ -207,7 +246,7 @@
return list
case "arm":
var list []string
- for i := 5; i <= GOARM; i++ {
+ for i := 5; i <= GOARM.Version; i++ {
list = append(list, fmt.Sprintf("%s.%d", GOARCH, i))
}
return list
diff --git a/src/math/rand/rand_test.go b/src/math/rand/rand_test.go
index 4ad2ae2..9f074fe 100644
--- a/src/math/rand/rand_test.go
+++ b/src/math/rand/rand_test.go
@@ -14,6 +14,7 @@
. "math/rand"
"os"
"runtime"
+ "strings"
"sync"
"testing"
"testing/iotest"
@@ -331,7 +332,7 @@
func hasSlowFloatingPoint() bool {
switch runtime.GOARCH {
case "arm":
- return os.Getenv("GOARM") == "5"
+ return os.Getenv("GOARM") == "5" || strings.HasSuffix(os.Getenv("GOARM"), ",softfloat")index 095e9c0..425899e 100644
--- a/src/runtime/cgo/asm_arm.s
+++ b/src/runtime/cgo/asm_arm.s
@@ -32,10 +32,10 @@
// starting at 4(R13).
MOVW.W R14, -4(R13)
- // Skip floating point registers on GOARM < 6.
- MOVB runtime·goarm(SB), R11
- CMP $6, R11
- BLT skipfpsave
+ // Skip floating point registers if goarmsoftfp!=0.
+ MOVB runtime·goarmsoftfp(SB), R11
+ CMP $0, R11
+ BNE skipfpsave
MOVD F8, (13*4+8*1)(R13)
MOVD F9, (13*4+8*2)(R13)
MOVD F10, (13*4+8*3)(R13)
@@ -50,9 +50,9 @@
// We set up the arguments to cgocallback when saving registers above.
BL runtime·cgocallback(SB)
- MOVB runtime·goarm(SB), R11
- CMP $6, R11
- BLT skipfprest
+ MOVB runtime·goarmsoftfp(SB), R11
+ CMP $0, R11
+ BNE skipfprest
MOVD (13*4+8*1)(R13), F8
MOVD (13*4+8*2)(R13), F9
MOVD (13*4+8*3)(R13), F10
diff --git a/src/runtime/mkpreempt.go b/src/runtime/mkpreempt.go
index a96ae59..17544d6 100644
--- a/src/runtime/mkpreempt.go
+++ b/src/runtime/mkpreempt.go
@@ -317,11 +317,11 @@
p("MOVW.W R14, -%d(R13)", lfp.stack) // allocate frame, save LR
l.save()
- p("MOVB ·goarm(SB), R0\nCMP $6, R0\nBLT nofp") // test goarm, and skip FP registers if goarm=5.
+ p("MOVB ·goarmsoftfp(SB), R0\nCMP $0, R0\nBNE nofp") // test goarmsoftfp, and skip FP registers if goarmsoftfp!=0.
lfp.save()
label("nofp:")
p("CALL ·asyncPreempt2(SB)")
- p("MOVB ·goarm(SB), R0\nCMP $6, R0\nBLT nofp2") // test goarm, and skip FP registers if goarm=5.
+ p("MOVB ·goarmsoftfp(SB), R0\nCMP $0, R0\nBNE nofp2") // test goarmsoftfp, and skip FP registers if goarmsoftfp!=0.
lfp.restore()
label("nofp2:")
l.restore()
diff --git a/src/runtime/os_freebsd_arm.go b/src/runtime/os_freebsd_arm.go
index df8c709..ae80119 100644
--- a/src/runtime/os_freebsd_arm.go
+++ b/src/runtime/os_freebsd_arm.go
@@ -15,14 +15,16 @@
)
func checkgoarm() {
- if goarm > 5 && cpu.HWCap&_HWCAP_VFP == 0 {
+ if cpu.HWCap&_HWCAP_VFP == 0 && goarmsoftfp == 0 {
print("runtime: this CPU has no floating point hardware, so it cannot run\n")
- print("this GOARM=", goarm, " binary. Recompile using GOARM=5.\n")
+ print("a binary compiled for hard floating point. Recompile adding ,softfloat\n")
+ print("to GOARM.\n")
exit(1)
}
- if goarm > 6 && cpu.HWCap&_HWCAP_VFPv3 == 0 {
+ if goarm > 6 && cpu.HWCap&_HWCAP_VFPv3 == 0 && goarmsoftfp == 0 {
print("runtime: this CPU has no VFPv3 floating point hardware, so it cannot run\n")
- print("this GOARM=", goarm, " binary. Recompile using GOARM=5 or GOARM=6.\n")
+ print("a binary compiled for VFPv3 hard floating point. Recompile adding ,softfloat\n")
+ print("to GOARM or changing GOARM to 6.\n")
exit(1)
}
diff --git a/src/runtime/os_linux_arm.go b/src/runtime/os_linux_arm.go
index 6e0c729..b977915 100644
--- a/src/runtime/os_linux_arm.go
+++ b/src/runtime/os_linux_arm.go
@@ -23,14 +23,16 @@
if GOOS == "android" {
return
}
- if goarm > 5 && cpu.HWCap&_HWCAP_VFP == 0 {
+ if cpu.HWCap&_HWCAP_VFP == 0 && goarmsoftfp == 0 {
print("runtime: this CPU has no floating point hardware, so it cannot run\n")
- print("this GOARM=", goarm, " binary. Recompile using GOARM=5.\n")
+ print("a binary compiled for hard floating point. Recompile adding ,softfloat\n")
+ print("to GOARM.\n")
exit(1)
}
- if goarm > 6 && cpu.HWCap&_HWCAP_VFPv3 == 0 {
+ if goarm > 6 && cpu.HWCap&_HWCAP_VFPv3 == 0 && goarmsoftfp == 0 {
print("runtime: this CPU has no VFPv3 floating point hardware, so it cannot run\n")
- print("this GOARM=", goarm, " binary. Recompile using GOARM=5 or GOARM=6.\n")
+ print("a binary compiled for VFPv3 hard floating point. Recompile adding ,softfloat\n")
+ print("to GOARM or changing GOARM to 6.\n")
index e64c3c5..fb283a3 100644
--- a/src/runtime/runtime2.go
+++ b/src/runtime/runtime2.go
@@ -1230,7 +1230,9 @@
processorVersionInfo uint32
isIntel bool
- goarm uint8 // set by cmd/link on arm systems
+ // set by cmd/link on arm systems
+ goarm uint8
+ goarmsoftfp uint8
)
// Set by the linker so the runtime can determine the buildmode.
To view, visit change 514907. To unsubscribe, or for help writing mail filters, visit settings.