mirror of
https://github.com/golang/go
synced 2024-11-26 04:47:57 -07:00
cmd/compile: add softfloat support to mips64{,le}
mips64 softfloat support is based on mips implementation and introduces new enviroment variable GOMIPS64. GOMIPS64 is a GOARCH=mips64{,le} specific option, for a choice between hard-float and soft-float. Valid values are 'hardfloat' (default) and 'softfloat'. It is passed to the assembler as 'GOMIPS64_{hardfloat,softfloat}'. Change-Id: I7f73078627f7cb37c588a38fb5c997fe09c56134 Reviewed-on: https://go-review.googlesource.com/108475 Reviewed-by: Cherry Zhang <cherryyz@google.com> Run-TryBot: Cherry Zhang <cherryyz@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
62adf6fc2d
commit
2959128dc5
@ -939,6 +939,12 @@ The value of <code>GOMIPS</code> environment variable (<code>hardfloat</code> or
|
|||||||
<code>GOMIPS_hardfloat</code> or <code>GOMIPS_softfloat</code>.
|
<code>GOMIPS_hardfloat</code> or <code>GOMIPS_softfloat</code>.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The value of <code>GOMIPS64</code> environment variable (<code>hardfloat</code> or
|
||||||
|
<code>softfloat</code>) is made available to assembly code by predefining either
|
||||||
|
<code>GOMIPS64_hardfloat</code> or <code>GOMIPS64_softfloat</code>.
|
||||||
|
</p>
|
||||||
|
|
||||||
<h3 id="unsupported_opcodes">Unsupported opcodes</h3>
|
<h3 id="unsupported_opcodes">Unsupported opcodes</h3>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
@ -18,7 +18,7 @@ func Init(arch *gc.Arch) {
|
|||||||
}
|
}
|
||||||
arch.REGSP = mips.REGSP
|
arch.REGSP = mips.REGSP
|
||||||
arch.MAXWIDTH = 1 << 50
|
arch.MAXWIDTH = 1 << 50
|
||||||
|
arch.SoftFloat = objabi.GOMIPS64 == "softfloat"
|
||||||
arch.ZeroRange = zerorange
|
arch.ZeroRange = zerorange
|
||||||
arch.ZeroAuto = zeroAuto
|
arch.ZeroAuto = zeroAuto
|
||||||
arch.Ginsnop = ginsnop
|
arch.Ginsnop = ginsnop
|
||||||
|
16
src/cmd/dist/build.go
vendored
16
src/cmd/dist/build.go
vendored
@ -31,6 +31,7 @@ var (
|
|||||||
goarm string
|
goarm string
|
||||||
go386 string
|
go386 string
|
||||||
gomips string
|
gomips string
|
||||||
|
gomips64 string
|
||||||
goroot string
|
goroot string
|
||||||
goroot_final string
|
goroot_final string
|
||||||
goextlinkenabled string
|
goextlinkenabled string
|
||||||
@ -145,6 +146,12 @@ func xinit() {
|
|||||||
}
|
}
|
||||||
gomips = b
|
gomips = b
|
||||||
|
|
||||||
|
b = os.Getenv("GOMIPS64")
|
||||||
|
if b == "" {
|
||||||
|
b = "hardfloat"
|
||||||
|
}
|
||||||
|
gomips64 = b
|
||||||
|
|
||||||
if p := pathf("%s/src/all.bash", goroot); !isfile(p) {
|
if p := pathf("%s/src/all.bash", goroot); !isfile(p) {
|
||||||
fatalf("$GOROOT is not set correctly or not exported\n"+
|
fatalf("$GOROOT is not set correctly or not exported\n"+
|
||||||
"\tGOROOT=%s\n"+
|
"\tGOROOT=%s\n"+
|
||||||
@ -202,6 +209,7 @@ func xinit() {
|
|||||||
os.Setenv("GOHOSTOS", gohostos)
|
os.Setenv("GOHOSTOS", gohostos)
|
||||||
os.Setenv("GOOS", goos)
|
os.Setenv("GOOS", goos)
|
||||||
os.Setenv("GOMIPS", gomips)
|
os.Setenv("GOMIPS", gomips)
|
||||||
|
os.Setenv("GOMIPS64", gomips64)
|
||||||
os.Setenv("GOROOT", goroot)
|
os.Setenv("GOROOT", goroot)
|
||||||
os.Setenv("GOROOT_FINAL", goroot_final)
|
os.Setenv("GOROOT_FINAL", goroot_final)
|
||||||
|
|
||||||
@ -822,6 +830,11 @@ func runInstall(dir string, ch chan struct{}) {
|
|||||||
compile = append(compile, "-D", "GOMIPS_"+gomips)
|
compile = append(compile, "-D", "GOMIPS_"+gomips)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if goarch == "mips64" || goarch == "mipsle64" {
|
||||||
|
// Define GOMIPS64_value from gomips64.
|
||||||
|
compile = append(compile, "-D", "GOMIPS64_"+gomips64)
|
||||||
|
}
|
||||||
|
|
||||||
doclean := true
|
doclean := true
|
||||||
b := pathf("%s/%s", workdir, filepath.Base(p))
|
b := pathf("%s/%s", workdir, filepath.Base(p))
|
||||||
|
|
||||||
@ -1063,6 +1076,9 @@ func cmdenv() {
|
|||||||
if goarch == "mips" || goarch == "mipsle" {
|
if goarch == "mips" || goarch == "mipsle" {
|
||||||
xprintf(format, "GOMIPS", gomips)
|
xprintf(format, "GOMIPS", gomips)
|
||||||
}
|
}
|
||||||
|
if goarch == "mips64" || goarch == "mips64le" {
|
||||||
|
xprintf(format, "GOMIPS64", gomips64)
|
||||||
|
}
|
||||||
|
|
||||||
if *path {
|
if *path {
|
||||||
sep := ":"
|
sep := ":"
|
||||||
|
2
src/cmd/dist/buildruntime.go
vendored
2
src/cmd/dist/buildruntime.go
vendored
@ -44,6 +44,7 @@ func mkzversion(dir, file string) {
|
|||||||
// const defaultGO386 = <go386>
|
// const defaultGO386 = <go386>
|
||||||
// const defaultGOARM = <goarm>
|
// const defaultGOARM = <goarm>
|
||||||
// const defaultGOMIPS = <gomips>
|
// const defaultGOMIPS = <gomips>
|
||||||
|
// const defaultGOMIPS64 = <gomips64>
|
||||||
// const defaultGOOS = runtime.GOOS
|
// const defaultGOOS = runtime.GOOS
|
||||||
// const defaultGOARCH = runtime.GOARCH
|
// const defaultGOARCH = runtime.GOARCH
|
||||||
// const defaultGO_EXTLINK_ENABLED = <goextlinkenabled>
|
// const defaultGO_EXTLINK_ENABLED = <goextlinkenabled>
|
||||||
@ -71,6 +72,7 @@ func mkzbootstrap(file string) {
|
|||||||
fmt.Fprintf(&buf, "const defaultGO386 = `%s`\n", go386)
|
fmt.Fprintf(&buf, "const defaultGO386 = `%s`\n", go386)
|
||||||
fmt.Fprintf(&buf, "const defaultGOARM = `%s`\n", goarm)
|
fmt.Fprintf(&buf, "const defaultGOARM = `%s`\n", goarm)
|
||||||
fmt.Fprintf(&buf, "const defaultGOMIPS = `%s`\n", gomips)
|
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 defaultGOOS = runtime.GOOS\n")
|
||||||
fmt.Fprintf(&buf, "const defaultGOARCH = runtime.GOARCH\n")
|
fmt.Fprintf(&buf, "const defaultGOARCH = runtime.GOARCH\n")
|
||||||
fmt.Fprintf(&buf, "const defaultGO_EXTLINK_ENABLED = `%s`\n", goextlinkenabled)
|
fmt.Fprintf(&buf, "const defaultGO_EXTLINK_ENABLED = `%s`\n", goextlinkenabled)
|
||||||
|
@ -1094,6 +1094,9 @@
|
|||||||
// GOMIPS
|
// GOMIPS
|
||||||
// For GOARCH=mips{,le}, whether to use floating point instructions.
|
// For GOARCH=mips{,le}, whether to use floating point instructions.
|
||||||
// Valid values are hardfloat (default), softfloat.
|
// 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:
|
// Special-purpose environment variables:
|
||||||
//
|
//
|
||||||
|
@ -84,9 +84,10 @@ var (
|
|||||||
GOROOT_FINAL = findGOROOT_FINAL()
|
GOROOT_FINAL = findGOROOT_FINAL()
|
||||||
|
|
||||||
// Used in envcmd.MkEnv and build ID computations.
|
// Used in envcmd.MkEnv and build ID computations.
|
||||||
GOARM = fmt.Sprint(objabi.GOARM)
|
GOARM = fmt.Sprint(objabi.GOARM)
|
||||||
GO386 = objabi.GO386
|
GO386 = objabi.GO386
|
||||||
GOMIPS = objabi.GOMIPS
|
GOMIPS = objabi.GOMIPS
|
||||||
|
GOMIPS64 = objabi.GOMIPS64
|
||||||
)
|
)
|
||||||
|
|
||||||
// Update build context to use our computed GOROOT.
|
// Update build context to use our computed GOROOT.
|
||||||
|
@ -78,6 +78,8 @@ func MkEnv() []cfg.EnvVar {
|
|||||||
env = append(env, cfg.EnvVar{Name: "GO386", Value: cfg.GO386})
|
env = append(env, cfg.EnvVar{Name: "GO386", Value: cfg.GO386})
|
||||||
case "mips", "mipsle":
|
case "mips", "mipsle":
|
||||||
env = append(env, cfg.EnvVar{Name: "GOMIPS", Value: cfg.GOMIPS})
|
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)
|
cc := cfg.DefaultCC(cfg.Goos, cfg.Goarch)
|
||||||
|
@ -527,6 +527,9 @@ Architecture-specific environment variables:
|
|||||||
GOMIPS
|
GOMIPS
|
||||||
For GOARCH=mips{,le}, whether to use floating point instructions.
|
For GOARCH=mips{,le}, whether to use floating point instructions.
|
||||||
Valid values are hardfloat (default), softfloat.
|
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:
|
Special-purpose environment variables:
|
||||||
|
|
||||||
|
@ -233,6 +233,11 @@ func (gcToolchain) asm(b *Builder, a *Action, sfiles []string) ([]string, error)
|
|||||||
args = append(args, "-D", "GOMIPS_"+cfg.GOMIPS)
|
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
|
var ofiles []string
|
||||||
for _, sfile := range sfiles {
|
for _, sfile := range sfiles {
|
||||||
ofile := a.Objdir + sfile[:len(sfile)-len(".s")] + ".o"
|
ofile := a.Objdir + sfile[:len(sfile)-len(".s")] + ".o"
|
||||||
|
@ -21,13 +21,14 @@ func envOr(key, value string) string {
|
|||||||
var (
|
var (
|
||||||
defaultGOROOT string // set by linker
|
defaultGOROOT string // set by linker
|
||||||
|
|
||||||
GOROOT = envOr("GOROOT", defaultGOROOT)
|
GOROOT = envOr("GOROOT", defaultGOROOT)
|
||||||
GOARCH = envOr("GOARCH", defaultGOARCH)
|
GOARCH = envOr("GOARCH", defaultGOARCH)
|
||||||
GOOS = envOr("GOOS", defaultGOOS)
|
GOOS = envOr("GOOS", defaultGOOS)
|
||||||
GO386 = envOr("GO386", defaultGO386)
|
GO386 = envOr("GO386", defaultGO386)
|
||||||
GOARM = goarm()
|
GOARM = goarm()
|
||||||
GOMIPS = gomips()
|
GOMIPS = gomips()
|
||||||
Version = version
|
GOMIPS64 = gomips64()
|
||||||
|
Version = version
|
||||||
)
|
)
|
||||||
|
|
||||||
func goarm() int {
|
func goarm() int {
|
||||||
@ -53,6 +54,15 @@ func gomips() string {
|
|||||||
panic("unreachable")
|
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 {
|
func Getgoextlinkenabled() string {
|
||||||
return envOr("GO_EXTLINK_ENABLED", defaultGO_EXTLINK_ENABLED)
|
return envOr("GO_EXTLINK_ENABLED", defaultGO_EXTLINK_ENABLED)
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,11 @@ TEXT crosscall2(SB),NOSPLIT|NOFRAME,$0
|
|||||||
* Also note that at procedure entry in gc world, 8(R29) will be the
|
* Also note that at procedure entry in gc world, 8(R29) will be the
|
||||||
* first arg.
|
* first arg.
|
||||||
*/
|
*/
|
||||||
|
#ifndef GOMIPS64_softfloat
|
||||||
ADDV $(-8*23), R29
|
ADDV $(-8*23), R29
|
||||||
|
#else
|
||||||
|
ADDV $(-8*15), R29
|
||||||
|
#endif
|
||||||
MOVV R5, (8*1)(R29) // void*
|
MOVV R5, (8*1)(R29) // void*
|
||||||
MOVW R6, (8*2)(R29) // int32
|
MOVW R6, (8*2)(R29) // int32
|
||||||
MOVV R7, (8*3)(R29) // uintptr
|
MOVV R7, (8*3)(R29) // uintptr
|
||||||
@ -32,6 +36,7 @@ TEXT crosscall2(SB),NOSPLIT|NOFRAME,$0
|
|||||||
MOVV RSB, (8*12)(R29)
|
MOVV RSB, (8*12)(R29)
|
||||||
MOVV g, (8*13)(R29)
|
MOVV g, (8*13)(R29)
|
||||||
MOVV R31, (8*14)(R29)
|
MOVV R31, (8*14)(R29)
|
||||||
|
#ifndef GOMIPS64_softfloat
|
||||||
MOVD F24, (8*15)(R29)
|
MOVD F24, (8*15)(R29)
|
||||||
MOVD F25, (8*16)(R29)
|
MOVD F25, (8*16)(R29)
|
||||||
MOVD F26, (8*17)(R29)
|
MOVD F26, (8*17)(R29)
|
||||||
@ -40,7 +45,7 @@ TEXT crosscall2(SB),NOSPLIT|NOFRAME,$0
|
|||||||
MOVD F29, (8*20)(R29)
|
MOVD F29, (8*20)(R29)
|
||||||
MOVD F30, (8*21)(R29)
|
MOVD F30, (8*21)(R29)
|
||||||
MOVD F31, (8*22)(R29)
|
MOVD F31, (8*22)(R29)
|
||||||
|
#endif
|
||||||
// Initialize Go ABI environment
|
// Initialize Go ABI environment
|
||||||
// prepare SB register = PC & 0xffffffff00000000
|
// prepare SB register = PC & 0xffffffff00000000
|
||||||
BGEZAL R0, 1(PC)
|
BGEZAL R0, 1(PC)
|
||||||
@ -60,6 +65,7 @@ TEXT crosscall2(SB),NOSPLIT|NOFRAME,$0
|
|||||||
MOVV (8*12)(R29), RSB
|
MOVV (8*12)(R29), RSB
|
||||||
MOVV (8*13)(R29), g
|
MOVV (8*13)(R29), g
|
||||||
MOVV (8*14)(R29), R31
|
MOVV (8*14)(R29), R31
|
||||||
|
#ifndef GOMIPS64_softfloat
|
||||||
MOVD (8*15)(R29), F24
|
MOVD (8*15)(R29), F24
|
||||||
MOVD (8*16)(R29), F25
|
MOVD (8*16)(R29), F25
|
||||||
MOVD (8*17)(R29), F26
|
MOVD (8*17)(R29), F26
|
||||||
@ -69,4 +75,7 @@ TEXT crosscall2(SB),NOSPLIT|NOFRAME,$0
|
|||||||
MOVD (8*21)(R29), F30
|
MOVD (8*21)(R29), F30
|
||||||
MOVD (8*22)(R29), F31
|
MOVD (8*22)(R29), F31
|
||||||
ADDV $(8*23), R29
|
ADDV $(8*23), R29
|
||||||
|
#else
|
||||||
|
ADDV $(8*15), R29
|
||||||
|
#endif
|
||||||
RET
|
RET
|
||||||
|
@ -14,7 +14,11 @@
|
|||||||
.globl crosscall1
|
.globl crosscall1
|
||||||
.set noat
|
.set noat
|
||||||
crosscall1:
|
crosscall1:
|
||||||
|
#ifndef __mips_soft_float
|
||||||
daddiu $29, $29, -160
|
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 $31, 0($29)
|
||||||
sd $16, 8($29)
|
sd $16, 8($29)
|
||||||
sd $17, 16($29)
|
sd $17, 16($29)
|
||||||
@ -26,6 +30,7 @@ crosscall1:
|
|||||||
sd $23, 64($29)
|
sd $23, 64($29)
|
||||||
sd $28, 72($29)
|
sd $28, 72($29)
|
||||||
sd $30, 80($29)
|
sd $30, 80($29)
|
||||||
|
#ifndef __mips_soft_float
|
||||||
sdc1 $f24, 88($29)
|
sdc1 $f24, 88($29)
|
||||||
sdc1 $f25, 96($29)
|
sdc1 $f25, 96($29)
|
||||||
sdc1 $f26, 104($29)
|
sdc1 $f26, 104($29)
|
||||||
@ -34,6 +39,7 @@ crosscall1:
|
|||||||
sdc1 $f29, 128($29)
|
sdc1 $f29, 128($29)
|
||||||
sdc1 $f30, 136($29)
|
sdc1 $f30, 136($29)
|
||||||
sdc1 $f31, 144($29)
|
sdc1 $f31, 144($29)
|
||||||
|
#endif
|
||||||
|
|
||||||
// prepare SB register = pc & 0xffffffff00000000
|
// prepare SB register = pc & 0xffffffff00000000
|
||||||
bal 1f
|
bal 1f
|
||||||
@ -56,6 +62,7 @@ crosscall1:
|
|||||||
ld $23, 64($29)
|
ld $23, 64($29)
|
||||||
ld $28, 72($29)
|
ld $28, 72($29)
|
||||||
ld $30, 80($29)
|
ld $30, 80($29)
|
||||||
|
#ifndef __mips_soft_float
|
||||||
ldc1 $f24, 88($29)
|
ldc1 $f24, 88($29)
|
||||||
ldc1 $f25, 96($29)
|
ldc1 $f25, 96($29)
|
||||||
ldc1 $f26, 104($29)
|
ldc1 $f26, 104($29)
|
||||||
@ -64,9 +71,13 @@ crosscall1:
|
|||||||
ldc1 $f29, 128($29)
|
ldc1 $f29, 128($29)
|
||||||
ldc1 $f30, 136($29)
|
ldc1 $f30, 136($29)
|
||||||
ldc1 $f31, 144($29)
|
ldc1 $f31, 144($29)
|
||||||
|
#endif
|
||||||
ld $31, 0($29)
|
ld $31, 0($29)
|
||||||
|
#ifndef __mips_soft_float
|
||||||
daddiu $29, $29, 160
|
daddiu $29, $29, 160
|
||||||
|
#else
|
||||||
|
daddiu $29, $29, 96
|
||||||
|
#endif
|
||||||
jr $31
|
jr $31
|
||||||
|
|
||||||
.set at
|
.set at
|
||||||
|
@ -40,7 +40,8 @@ func sqrt(x float64) float64 {
|
|||||||
// 386/387:"FSQRT" 386/sse2:"SQRTSD"
|
// 386/387:"FSQRT" 386/sse2:"SQRTSD"
|
||||||
// arm64:"FSQRTD"
|
// arm64:"FSQRTD"
|
||||||
// arm/7:"SQRTD"
|
// arm/7:"SQRTD"
|
||||||
// mips/hardfloat:"SQRTD" mips64:"SQRTD"
|
// mips/hardfloat:"SQRTD" mips/softfloat:-"SQRTD"
|
||||||
|
// mips64/hardfloat:"SQRTD" mips64/softfloat:-"SQRTD"
|
||||||
return math.Sqrt(x)
|
return math.Sqrt(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1301,7 +1301,7 @@ var (
|
|||||||
"arm": {"GOARM", "5", "6", "7"},
|
"arm": {"GOARM", "5", "6", "7"},
|
||||||
"arm64": {},
|
"arm64": {},
|
||||||
"mips": {"GOMIPS", "hardfloat", "softfloat"},
|
"mips": {"GOMIPS", "hardfloat", "softfloat"},
|
||||||
"mips64": {},
|
"mips64": {"GOMIPS64", "hardfloat", "softfloat"},
|
||||||
"ppc64": {},
|
"ppc64": {},
|
||||||
"ppc64le": {},
|
"ppc64le": {},
|
||||||
"s390x": {},
|
"s390x": {},
|
||||||
|
Loading…
Reference in New Issue
Block a user