mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-16 02:33:28 +00:00
arm: support softfloat in GOARM environment variable
This adds softfloat support to GOARM, as proposed here: https://github.com/golang/go/issues/61588 This is similar to https://github.com/tinygo-org/tinygo/pull/4189 but with a few differences: * It is based on the work to support MIPS softfloat. * It fixes the issue that the default changed to softfloat everywhere. This PR defaults to softfloat on ARMv5 and hardfloat on ARMv6 and ARMv7. * It also compiles the C libraries (compiler-rt, musl) using the same soft/hard floating point support. This is important because otherwise a GOARM=7,softfloat binary could still contain hardware floating point instructions.
This commit is contained in:
committed by
Ron Evans
parent
a35b983a5d
commit
4dc07d6cc3
@@ -53,9 +53,12 @@ func TestClangAttributes(t *testing.T) {
|
|||||||
for _, options := range []*compileopts.Options{
|
for _, options := range []*compileopts.Options{
|
||||||
{GOOS: "linux", GOARCH: "386"},
|
{GOOS: "linux", GOARCH: "386"},
|
||||||
{GOOS: "linux", GOARCH: "amd64"},
|
{GOOS: "linux", GOARCH: "amd64"},
|
||||||
{GOOS: "linux", GOARCH: "arm", GOARM: "5"},
|
{GOOS: "linux", GOARCH: "arm", GOARM: "5,softfloat"},
|
||||||
{GOOS: "linux", GOARCH: "arm", GOARM: "6"},
|
{GOOS: "linux", GOARCH: "arm", GOARM: "6,softfloat"},
|
||||||
{GOOS: "linux", GOARCH: "arm", GOARM: "7"},
|
{GOOS: "linux", GOARCH: "arm", GOARM: "7,softfloat"},
|
||||||
|
{GOOS: "linux", GOARCH: "arm", GOARM: "5,hardfloat"},
|
||||||
|
{GOOS: "linux", GOARCH: "arm", GOARM: "6,hardfloat"},
|
||||||
|
{GOOS: "linux", GOARCH: "arm", GOARM: "7,hardfloat"},
|
||||||
{GOOS: "linux", GOARCH: "arm64"},
|
{GOOS: "linux", GOARCH: "arm64"},
|
||||||
{GOOS: "linux", GOARCH: "mips", GOMIPS: "hardfloat"},
|
{GOOS: "linux", GOARCH: "mips", GOMIPS: "hardfloat"},
|
||||||
{GOOS: "linux", GOARCH: "mipsle", GOMIPS: "hardfloat"},
|
{GOOS: "linux", GOARCH: "mipsle", GOMIPS: "hardfloat"},
|
||||||
|
|||||||
@@ -173,6 +173,13 @@ func (l *Library) load(config *compileopts.Config, tmpdir string) (job *compileJ
|
|||||||
// Use softfloat instead of floating point instructions. This is
|
// Use softfloat instead of floating point instructions. This is
|
||||||
// supported on many architectures.
|
// supported on many architectures.
|
||||||
args = append(args, "-msoft-float")
|
args = append(args, "-msoft-float")
|
||||||
|
} else {
|
||||||
|
if strings.HasPrefix(target, "armv5") {
|
||||||
|
// On ARMv5 we need to explicitly enable hardware floating point
|
||||||
|
// instructions: Clang appears to assume the hardware doesn't have a
|
||||||
|
// FPU otherwise.
|
||||||
|
args = append(args, "-mfpu=vfpv2")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var once sync.Once
|
var once sync.Once
|
||||||
|
|||||||
+47
-5
@@ -267,18 +267,60 @@ func defaultTarget(options *Options) (*TargetSpec, error) {
|
|||||||
case "arm":
|
case "arm":
|
||||||
spec.CPU = "generic"
|
spec.CPU = "generic"
|
||||||
spec.CFlags = append(spec.CFlags, "-fno-unwind-tables", "-fno-asynchronous-unwind-tables")
|
spec.CFlags = append(spec.CFlags, "-fno-unwind-tables", "-fno-asynchronous-unwind-tables")
|
||||||
switch options.GOARM {
|
subarch := strings.Split(options.GOARM, ",")
|
||||||
|
if len(subarch) > 2 {
|
||||||
|
return nil, fmt.Errorf("invalid GOARM=%s, must be of form <num>,[hardfloat|softfloat]", options.GOARM)
|
||||||
|
}
|
||||||
|
archLevel := subarch[0]
|
||||||
|
var fpu string
|
||||||
|
if len(subarch) >= 2 {
|
||||||
|
fpu = subarch[1]
|
||||||
|
} else {
|
||||||
|
// Pick the default fpu value: softfloat for armv5 and hardfloat
|
||||||
|
// above that.
|
||||||
|
if archLevel == "5" {
|
||||||
|
fpu = "softfloat"
|
||||||
|
} else {
|
||||||
|
fpu = "hardfloat"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch fpu {
|
||||||
|
case "softfloat":
|
||||||
|
spec.CFlags = append(spec.CFlags, "-msoft-float")
|
||||||
|
spec.SoftFloat = true
|
||||||
|
case "hardfloat":
|
||||||
|
// Hardware floating point support is the default everywhere except
|
||||||
|
// on ARMv5 where it needs to be enabled explicitly.
|
||||||
|
if archLevel == "5" {
|
||||||
|
spec.CFlags = append(spec.CFlags, "-mfpu=vfpv2")
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("invalid extension GOARM=%s, must be softfloat or hardfloat", options.GOARM)
|
||||||
|
}
|
||||||
|
switch archLevel {
|
||||||
case "5":
|
case "5":
|
||||||
llvmarch = "armv5"
|
llvmarch = "armv5"
|
||||||
spec.Features = "+armv5t,+strict-align,-aes,-bf16,-d32,-dotprod,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-mve.fp,-neon,-sha2,-thumb-mode,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp"
|
if spec.SoftFloat {
|
||||||
|
spec.Features = "+armv5t,+soft-float,+strict-align,-aes,-bf16,-d32,-dotprod,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-mve,-mve.fp,-neon,-sha2,-thumb-mode,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp"
|
||||||
|
} else {
|
||||||
|
spec.Features = "+armv5t,+fp64,+strict-align,+vfp2,+vfp2sp,-aes,-d32,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fullfp16,-neon,-sha2,-thumb-mode,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp"
|
||||||
|
}
|
||||||
case "6":
|
case "6":
|
||||||
llvmarch = "armv6"
|
llvmarch = "armv6"
|
||||||
spec.Features = "+armv6,+dsp,+fp64,+strict-align,+vfp2,+vfp2sp,-aes,-d32,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fullfp16,-neon,-sha2,-thumb-mode,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp"
|
if spec.SoftFloat {
|
||||||
|
spec.Features = "+armv6,+dsp,+soft-float,+strict-align,-aes,-bf16,-d32,-dotprod,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-mve,-mve.fp,-neon,-sha2,-thumb-mode,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp"
|
||||||
|
} else {
|
||||||
|
spec.Features = "+armv6,+dsp,+fp64,+strict-align,+vfp2,+vfp2sp,-aes,-d32,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fullfp16,-neon,-sha2,-thumb-mode,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp"
|
||||||
|
}
|
||||||
case "7":
|
case "7":
|
||||||
llvmarch = "armv7"
|
llvmarch = "armv7"
|
||||||
spec.Features = "+armv7-a,+d32,+dsp,+fp64,+neon,+vfp2,+vfp2sp,+vfp3,+vfp3d16,+vfp3d16sp,+vfp3sp,-aes,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fullfp16,-sha2,-thumb-mode,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp"
|
if spec.SoftFloat {
|
||||||
|
spec.Features = "+armv7-a,+dsp,+soft-float,-aes,-bf16,-d32,-dotprod,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-mve,-mve.fp,-neon,-sha2,-thumb-mode,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp"
|
||||||
|
} else {
|
||||||
|
spec.Features = "+armv7-a,+d32,+dsp,+fp64,+neon,+vfp2,+vfp2sp,+vfp3,+vfp3d16,+vfp3d16sp,+vfp3sp,-aes,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fullfp16,-sha2,-thumb-mode,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp"
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("invalid GOARM=%s, must be 5, 6, or 7", options.GOARM)
|
return nil, fmt.Errorf("invalid GOARM=%s, must be of form <num>,[hardfloat|softfloat] where num is 5, 6, or 7", options.GOARM)
|
||||||
}
|
}
|
||||||
case "arm64":
|
case "arm64":
|
||||||
spec.CPU = "generic"
|
spec.CPU = "generic"
|
||||||
|
|||||||
Reference in New Issue
Block a user