aboutsummaryrefslogtreecommitdiffhomepage
path: root/compileopts
diff options
context:
space:
mode:
authorAyke van Laethem <[email protected]>2024-07-30 19:08:55 +0200
committerRon Evans <[email protected]>2024-08-12 13:23:32 +0200
commitf188eaf5f92618adc6422c2b55db8f822c6cc458 (patch)
tree835fb9b43034c92ff679d386500c7c9f66a98290 /compileopts
parent6efc6d2bb6489a9157c5bd964bdc072ed23f29d1 (diff)
downloadtinygo-f188eaf5f92618adc6422c2b55db8f822c6cc458.tar.gz
tinygo-f188eaf5f92618adc6422c2b55db8f822c6cc458.zip
mips: add GOMIPS=softfloat support
Previously, the compiler would default to hardfloat. This is not supported by some MIPS CPUs. This took me much longer than it should have because of a quirk in the LLVM Mips backend: if the target-features string is not set (like during LTO), the Mips backend picks the first function in the module and uses that. Unfortunately, in the case of TinyGo this first function is `llvm.dbg.value`, which is an LLVM intrinsic and doesn't have the target-features string. I fixed it by adding a `-mllvm -mattr=` flag to the linker.
Diffstat (limited to 'compileopts')
-rw-r--r--compileopts/config.go9
-rw-r--r--compileopts/options.go1
-rw-r--r--compileopts/target.go16
3 files changed, 25 insertions, 1 deletions
diff --git a/compileopts/config.go b/compileopts/config.go
index a5ab7cd8f..67c773de1 100644
--- a/compileopts/config.go
+++ b/compileopts/config.go
@@ -72,6 +72,12 @@ func (c *Config) GOARM() string {
return c.Options.GOARM
}
+// GOMIPS will return the GOMIPS environment variable given to the compiler when
+// building a program.
+func (c *Config) GOMIPS() string {
+ return c.Options.GOMIPS
+}
+
// BuildTags returns the complete list of build tags used during this build.
func (c *Config) BuildTags() []string {
tags := append([]string(nil), c.Target.BuildTags...) // copy slice (avoid a race)
@@ -240,6 +246,9 @@ func (c *Config) LibcPath(name string) (path string, precompiled bool) {
if c.ABI() != "" {
archname += "-" + c.ABI()
}
+ if c.Target.SoftFloat {
+ archname += "-softfloat"
+ }
// Try to load a precompiled library.
precompiledDir := filepath.Join(goenv.Get("TINYGOROOT"), "pkg", archname, name)
diff --git a/compileopts/options.go b/compileopts/options.go
index 8b0e2266d..9601ae322 100644
--- a/compileopts/options.go
+++ b/compileopts/options.go
@@ -23,6 +23,7 @@ type Options struct {
GOOS string // environment variable
GOARCH string // environment variable
GOARM string // environment variable (only used with GOARCH=arm)
+ GOMIPS string // environment variable (only used with GOARCH=mips and GOARCH=mipsle)
Directory string // working dir, leave it unset to use the current working dir
Target string
Opt string
diff --git a/compileopts/target.go b/compileopts/target.go
index ecbebd8b3..9388b8496 100644
--- a/compileopts/target.go
+++ b/compileopts/target.go
@@ -30,6 +30,7 @@ type TargetSpec struct {
Features string `json:"features,omitempty"`
GOOS string `json:"goos,omitempty"`
GOARCH string `json:"goarch,omitempty"`
+ SoftFloat bool // used for non-baremetal systems (GOMIPS=softfloat etc)
BuildTags []string `json:"build-tags,omitempty"`
GC string `json:"gc,omitempty"`
Scheduler string `json:"scheduler,omitempty"`
@@ -86,6 +87,10 @@ func (spec *TargetSpec) overrideProperties(child *TargetSpec) error {
if src.Uint() != 0 {
dst.Set(src)
}
+ case reflect.Bool:
+ if src.Bool() {
+ dst.Set(src)
+ }
case reflect.Ptr: // for pointers, copy if not nil
if !src.IsNil() {
dst.Set(src)
@@ -290,13 +295,22 @@ func defaultTarget(options *Options) (*TargetSpec, error) {
}
case "mips", "mipsle":
spec.CPU = "mips32r2"
- spec.Features = "+fpxx,+mips32r2,+nooddspreg,-noabicalls"
spec.CFlags = append(spec.CFlags, "-fno-pic")
if options.GOOS == "mips" {
llvmarch = "mips" // big endian
} else {
llvmarch = "mipsel" // little endian
}
+ switch options.GOMIPS {
+ case "hardfloat":
+ spec.Features = "+fpxx,+mips32r2,+nooddspreg,-noabicalls"
+ case "softfloat":
+ spec.SoftFloat = true
+ spec.Features = "+mips32r2,+soft-float,-noabicalls"
+ spec.CFlags = append(spec.CFlags, "-msoft-float")
+ default:
+ return nil, fmt.Errorf("invalid GOMIPS=%s: must be hardfloat or softfloat", options.GOMIPS)
+ }
case "wasm":
llvmarch = "wasm32"
spec.CPU = "generic"