diff --git a/doc/asm.html b/doc/asm.html
index c954079b669..f2f8fad5766 100644
--- a/doc/asm.html
+++ b/doc/asm.html
@@ -939,6 +939,12 @@ The value of GOMIPS
environment variable (hardfloat
or
GOMIPS_hardfloat
or GOMIPS_softfloat
.
+
+The value of GOMIPS64
environment variable (hardfloat
or
+softfloat
) is made available to assembly code by predefining either
+GOMIPS64_hardfloat
or GOMIPS64_softfloat
.
+
+
Unsupported opcodes
diff --git a/src/cmd/compile/internal/mips64/galign.go b/src/cmd/compile/internal/mips64/galign.go
index 910230f4f45..5252719e8ea 100644
--- a/src/cmd/compile/internal/mips64/galign.go
+++ b/src/cmd/compile/internal/mips64/galign.go
@@ -18,7 +18,7 @@ func Init(arch *gc.Arch) {
}
arch.REGSP = mips.REGSP
arch.MAXWIDTH = 1 << 50
-
+ arch.SoftFloat = objabi.GOMIPS64 == "softfloat"
arch.ZeroRange = zerorange
arch.ZeroAuto = zeroAuto
arch.Ginsnop = ginsnop
diff --git a/src/cmd/dist/build.go b/src/cmd/dist/build.go
index d570aa1a84d..163fdae1198 100644
--- a/src/cmd/dist/build.go
+++ b/src/cmd/dist/build.go
@@ -31,6 +31,7 @@ var (
goarm string
go386 string
gomips string
+ gomips64 string
goroot string
goroot_final string
goextlinkenabled string
@@ -145,6 +146,12 @@ func xinit() {
}
gomips = b
+ b = os.Getenv("GOMIPS64")
+ if b == "" {
+ b = "hardfloat"
+ }
+ gomips64 = b
+
if p := pathf("%s/src/all.bash", goroot); !isfile(p) {
fatalf("$GOROOT is not set correctly or not exported\n"+
"\tGOROOT=%s\n"+
@@ -202,6 +209,7 @@ func xinit() {
os.Setenv("GOHOSTOS", gohostos)
os.Setenv("GOOS", goos)
os.Setenv("GOMIPS", gomips)
+ os.Setenv("GOMIPS64", gomips64)
os.Setenv("GOROOT", goroot)
os.Setenv("GOROOT_FINAL", goroot_final)
@@ -822,6 +830,11 @@ func runInstall(dir string, ch chan struct{}) {
compile = append(compile, "-D", "GOMIPS_"+gomips)
}
+ if goarch == "mips64" || goarch == "mipsle64" {
+ // Define GOMIPS64_value from gomips64.
+ compile = append(compile, "-D", "GOMIPS64_"+gomips64)
+ }
+
doclean := true
b := pathf("%s/%s", workdir, filepath.Base(p))
@@ -1063,6 +1076,9 @@ func cmdenv() {
if goarch == "mips" || goarch == "mipsle" {
xprintf(format, "GOMIPS", gomips)
}
+ if goarch == "mips64" || goarch == "mips64le" {
+ xprintf(format, "GOMIPS64", gomips64)
+ }
if *path {
sep := ":"
diff --git a/src/cmd/dist/buildruntime.go b/src/cmd/dist/buildruntime.go
index 5cbcd8191b9..acf2230cb49 100644
--- a/src/cmd/dist/buildruntime.go
+++ b/src/cmd/dist/buildruntime.go
@@ -44,6 +44,7 @@ func mkzversion(dir, file string) {
// const defaultGO386 =
// const defaultGOARM =
// const defaultGOMIPS =
+// const defaultGOMIPS64 =
// const defaultGOOS = runtime.GOOS
// const defaultGOARCH = runtime.GOARCH
// const defaultGO_EXTLINK_ENABLED =
@@ -71,6 +72,7 @@ func mkzbootstrap(file string) {
fmt.Fprintf(&buf, "const defaultGO386 = `%s`\n", go386)
fmt.Fprintf(&buf, "const defaultGOARM = `%s`\n", goarm)
fmt.Fprintf(&buf, "const defaultGOMIPS = `%s`\n", gomips)
+ fmt.Fprintf(&buf, "const defaultGOMIPS64 = `%s`\n", gomips64)
fmt.Fprintf(&buf, "const defaultGOOS = runtime.GOOS\n")
fmt.Fprintf(&buf, "const defaultGOARCH = runtime.GOARCH\n")
fmt.Fprintf(&buf, "const defaultGO_EXTLINK_ENABLED = `%s`\n", goextlinkenabled)
diff --git a/src/cmd/go/alldocs.go b/src/cmd/go/alldocs.go
index 371f8ceb950..fa8c02cc4bb 100644
--- a/src/cmd/go/alldocs.go
+++ b/src/cmd/go/alldocs.go
@@ -1094,6 +1094,9 @@
// GOMIPS
// For GOARCH=mips{,le}, whether to use floating point instructions.
// Valid values are hardfloat (default), softfloat.
+// GOMIPS64
+// For GOARCH=mips64{,le}, whether to use floating point instructions.
+// Valid values are hardfloat (default), softfloat.
//
// Special-purpose environment variables:
//
diff --git a/src/cmd/go/internal/cfg/cfg.go b/src/cmd/go/internal/cfg/cfg.go
index 1de4f0dc791..85494e34f0f 100644
--- a/src/cmd/go/internal/cfg/cfg.go
+++ b/src/cmd/go/internal/cfg/cfg.go
@@ -84,9 +84,10 @@ var (
GOROOT_FINAL = findGOROOT_FINAL()
// Used in envcmd.MkEnv and build ID computations.
- GOARM = fmt.Sprint(objabi.GOARM)
- GO386 = objabi.GO386
- GOMIPS = objabi.GOMIPS
+ GOARM = fmt.Sprint(objabi.GOARM)
+ GO386 = objabi.GO386
+ GOMIPS = objabi.GOMIPS
+ GOMIPS64 = objabi.GOMIPS64
)
// Update build context to use our computed GOROOT.
diff --git a/src/cmd/go/internal/envcmd/env.go b/src/cmd/go/internal/envcmd/env.go
index 603f7b5060c..f682c3a7891 100644
--- a/src/cmd/go/internal/envcmd/env.go
+++ b/src/cmd/go/internal/envcmd/env.go
@@ -78,6 +78,8 @@ func MkEnv() []cfg.EnvVar {
env = append(env, cfg.EnvVar{Name: "GO386", Value: cfg.GO386})
case "mips", "mipsle":
env = append(env, cfg.EnvVar{Name: "GOMIPS", Value: cfg.GOMIPS})
+ case "mips64", "mips64le":
+ env = append(env, cfg.EnvVar{Name: "GOMIPS64", Value: cfg.GOMIPS64})
}
cc := cfg.DefaultCC(cfg.Goos, cfg.Goarch)
diff --git a/src/cmd/go/internal/help/helpdoc.go b/src/cmd/go/internal/help/helpdoc.go
index f7ec839f02f..60c1346e1d0 100644
--- a/src/cmd/go/internal/help/helpdoc.go
+++ b/src/cmd/go/internal/help/helpdoc.go
@@ -527,6 +527,9 @@ Architecture-specific environment variables:
GOMIPS
For GOARCH=mips{,le}, whether to use floating point instructions.
Valid values are hardfloat (default), softfloat.
+ GOMIPS64
+ For GOARCH=mips64{,le}, whether to use floating point instructions.
+ Valid values are hardfloat (default), softfloat.
Special-purpose environment variables:
diff --git a/src/cmd/go/internal/work/gc.go b/src/cmd/go/internal/work/gc.go
index 04fabd995ec..88efe8b757b 100644
--- a/src/cmd/go/internal/work/gc.go
+++ b/src/cmd/go/internal/work/gc.go
@@ -233,6 +233,11 @@ func (gcToolchain) asm(b *Builder, a *Action, sfiles []string) ([]string, error)
args = append(args, "-D", "GOMIPS_"+cfg.GOMIPS)
}
+ if cfg.Goarch == "mips64" || cfg.Goarch == "mips64le" {
+ // Define GOMIPS64_value from cfg.GOMIPS64.
+ args = append(args, "-D", "GOMIPS64_"+cfg.GOMIPS64)
+ }
+
var ofiles []string
for _, sfile := range sfiles {
ofile := a.Objdir + sfile[:len(sfile)-len(".s")] + ".o"
diff --git a/src/cmd/internal/objabi/util.go b/src/cmd/internal/objabi/util.go
index eafef6bfa71..0553231dee0 100644
--- a/src/cmd/internal/objabi/util.go
+++ b/src/cmd/internal/objabi/util.go
@@ -21,13 +21,14 @@ func envOr(key, value string) string {
var (
defaultGOROOT string // set by linker
- GOROOT = envOr("GOROOT", defaultGOROOT)
- GOARCH = envOr("GOARCH", defaultGOARCH)
- GOOS = envOr("GOOS", defaultGOOS)
- GO386 = envOr("GO386", defaultGO386)
- GOARM = goarm()
- GOMIPS = gomips()
- Version = version
+ GOROOT = envOr("GOROOT", defaultGOROOT)
+ GOARCH = envOr("GOARCH", defaultGOARCH)
+ GOOS = envOr("GOOS", defaultGOOS)
+ GO386 = envOr("GO386", defaultGO386)
+ GOARM = goarm()
+ GOMIPS = gomips()
+ GOMIPS64 = gomips64()
+ Version = version
)
func goarm() int {
@@ -53,6 +54,15 @@ func gomips() string {
panic("unreachable")
}
+func gomips64() string {
+ switch v := envOr("GOMIPS64", defaultGOMIPS64); v {
+ case "hardfloat", "softfloat":
+ return v
+ }
+ log.Fatalf("Invalid GOMIPS64 value. Must be hardfloat or softfloat.")
+ panic("unreachable")
+}
+
func Getgoextlinkenabled() string {
return envOr("GO_EXTLINK_ENABLED", defaultGO_EXTLINK_ENABLED)
}
diff --git a/src/runtime/cgo/asm_mips64x.s b/src/runtime/cgo/asm_mips64x.s
index e928ff4792d..1235852dbe4 100644
--- a/src/runtime/cgo/asm_mips64x.s
+++ b/src/runtime/cgo/asm_mips64x.s
@@ -17,7 +17,11 @@ TEXT crosscall2(SB),NOSPLIT|NOFRAME,$0
* Also note that at procedure entry in gc world, 8(R29) will be the
* first arg.
*/
+#ifndef GOMIPS64_softfloat
ADDV $(-8*23), R29
+#else
+ ADDV $(-8*15), R29
+#endif
MOVV R5, (8*1)(R29) // void*
MOVW R6, (8*2)(R29) // int32
MOVV R7, (8*3)(R29) // uintptr
@@ -32,6 +36,7 @@ TEXT crosscall2(SB),NOSPLIT|NOFRAME,$0
MOVV RSB, (8*12)(R29)
MOVV g, (8*13)(R29)
MOVV R31, (8*14)(R29)
+#ifndef GOMIPS64_softfloat
MOVD F24, (8*15)(R29)
MOVD F25, (8*16)(R29)
MOVD F26, (8*17)(R29)
@@ -40,7 +45,7 @@ TEXT crosscall2(SB),NOSPLIT|NOFRAME,$0
MOVD F29, (8*20)(R29)
MOVD F30, (8*21)(R29)
MOVD F31, (8*22)(R29)
-
+#endif
// Initialize Go ABI environment
// prepare SB register = PC & 0xffffffff00000000
BGEZAL R0, 1(PC)
@@ -60,6 +65,7 @@ TEXT crosscall2(SB),NOSPLIT|NOFRAME,$0
MOVV (8*12)(R29), RSB
MOVV (8*13)(R29), g
MOVV (8*14)(R29), R31
+#ifndef GOMIPS64_softfloat
MOVD (8*15)(R29), F24
MOVD (8*16)(R29), F25
MOVD (8*17)(R29), F26
@@ -69,4 +75,7 @@ TEXT crosscall2(SB),NOSPLIT|NOFRAME,$0
MOVD (8*21)(R29), F30
MOVD (8*22)(R29), F31
ADDV $(8*23), R29
+#else
+ ADDV $(8*15), R29
+#endif
RET
diff --git a/src/runtime/cgo/gcc_mips64x.S b/src/runtime/cgo/gcc_mips64x.S
index a7ef0061a4f..908dd2135c8 100644
--- a/src/runtime/cgo/gcc_mips64x.S
+++ b/src/runtime/cgo/gcc_mips64x.S
@@ -14,7 +14,11 @@
.globl crosscall1
.set noat
crosscall1:
+#ifndef __mips_soft_float
daddiu $29, $29, -160
+#else
+ daddiu $29, $29, -96 // For soft-float, no need to make room for FP registers
+#endif
sd $31, 0($29)
sd $16, 8($29)
sd $17, 16($29)
@@ -26,6 +30,7 @@ crosscall1:
sd $23, 64($29)
sd $28, 72($29)
sd $30, 80($29)
+#ifndef __mips_soft_float
sdc1 $f24, 88($29)
sdc1 $f25, 96($29)
sdc1 $f26, 104($29)
@@ -34,6 +39,7 @@ crosscall1:
sdc1 $f29, 128($29)
sdc1 $f30, 136($29)
sdc1 $f31, 144($29)
+#endif
// prepare SB register = pc & 0xffffffff00000000
bal 1f
@@ -56,6 +62,7 @@ crosscall1:
ld $23, 64($29)
ld $28, 72($29)
ld $30, 80($29)
+#ifndef __mips_soft_float
ldc1 $f24, 88($29)
ldc1 $f25, 96($29)
ldc1 $f26, 104($29)
@@ -64,9 +71,13 @@ crosscall1:
ldc1 $f29, 128($29)
ldc1 $f30, 136($29)
ldc1 $f31, 144($29)
+#endif
ld $31, 0($29)
-
+#ifndef __mips_soft_float
daddiu $29, $29, 160
+#else
+ daddiu $29, $29, 96
+#endif
jr $31
.set at
diff --git a/test/codegen/math.go b/test/codegen/math.go
index f73321200be..1ecba26847a 100644
--- a/test/codegen/math.go
+++ b/test/codegen/math.go
@@ -40,7 +40,8 @@ func sqrt(x float64) float64 {
// 386/387:"FSQRT" 386/sse2:"SQRTSD"
// arm64:"FSQRTD"
// arm/7:"SQRTD"
- // mips/hardfloat:"SQRTD" mips64:"SQRTD"
+ // mips/hardfloat:"SQRTD" mips/softfloat:-"SQRTD"
+ // mips64/hardfloat:"SQRTD" mips64/softfloat:-"SQRTD"
return math.Sqrt(x)
}
diff --git a/test/run.go b/test/run.go
index 0914b742abc..93139e183e9 100644
--- a/test/run.go
+++ b/test/run.go
@@ -1301,7 +1301,7 @@ var (
"arm": {"GOARM", "5", "6", "7"},
"arm64": {},
"mips": {"GOMIPS", "hardfloat", "softfloat"},
- "mips64": {},
+ "mips64": {"GOMIPS64", "hardfloat", "softfloat"},
"ppc64": {},
"ppc64le": {},
"s390x": {},