Skip to content

Commit 7b73a49

Browse files
committed
arm: support softfloat in GOARM environment variable
This adds softfloat support to GOARM, as proposed here: golang/go#61588 This is similar to #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.
1 parent dbcdac1 commit 7b73a49

File tree

3 files changed

+60
-8
lines changed

3 files changed

+60
-8
lines changed

builder/builder_test.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,12 @@ func TestClangAttributes(t *testing.T) {
5353
for _, options := range []*compileopts.Options{
5454
{GOOS: "linux", GOARCH: "386"},
5555
{GOOS: "linux", GOARCH: "amd64"},
56-
{GOOS: "linux", GOARCH: "arm", GOARM: "5"},
57-
{GOOS: "linux", GOARCH: "arm", GOARM: "6"},
58-
{GOOS: "linux", GOARCH: "arm", GOARM: "7"},
56+
{GOOS: "linux", GOARCH: "arm", GOARM: "5,softfloat"},
57+
{GOOS: "linux", GOARCH: "arm", GOARM: "6,softfloat"},
58+
{GOOS: "linux", GOARCH: "arm", GOARM: "7,softfloat"},
59+
{GOOS: "linux", GOARCH: "arm", GOARM: "5,hardfloat"},
60+
{GOOS: "linux", GOARCH: "arm", GOARM: "6,hardfloat"},
61+
{GOOS: "linux", GOARCH: "arm", GOARM: "7,hardfloat"},
5962
{GOOS: "linux", GOARCH: "arm64"},
6063
{GOOS: "linux", GOARCH: "mips", GOMIPS: "hardfloat"},
6164
{GOOS: "linux", GOARCH: "mipsle", GOMIPS: "hardfloat"},

builder/library.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,13 @@ func (l *Library) load(config *compileopts.Config, tmpdir string) (job *compileJ
173173
// Use softfloat instead of floating point instructions. This is
174174
// supported on many architectures.
175175
args = append(args, "-msoft-float")
176+
} else {
177+
if strings.HasPrefix(target, "armv5") {
178+
// On ARMv5 we need to explicitly enable hardware floating point
179+
// instructions: Clang appears to assume the hardware doesn't have a
180+
// FPU otherwise.
181+
args = append(args, "-mfpu=vfpv2")
182+
}
176183
}
177184

178185
var once sync.Once

compileopts/target.go

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -267,18 +267,60 @@ func defaultTarget(options *Options) (*TargetSpec, error) {
267267
case "arm":
268268
spec.CPU = "generic"
269269
spec.CFlags = append(spec.CFlags, "-fno-unwind-tables", "-fno-asynchronous-unwind-tables")
270-
switch options.GOARM {
270+
subarch := strings.Split(options.GOARM, ",")
271+
if len(subarch) > 2 {
272+
return nil, fmt.Errorf("invalid GOARM=%s, must be of form <num>,[hardfloat|softfloat]", options.GOARM)
273+
}
274+
archLevel := subarch[0]
275+
var fpu string
276+
if len(subarch) >= 2 {
277+
fpu = subarch[1]
278+
} else {
279+
// Pick the default fpu value: softfloat for armv5 and hardfloat
280+
// above that.
281+
if archLevel == "5" {
282+
fpu = "softfloat"
283+
} else {
284+
fpu = "hardfloat"
285+
}
286+
}
287+
switch fpu {
288+
case "softfloat":
289+
spec.CFlags = append(spec.CFlags, "-msoft-float")
290+
spec.SoftFloat = true
291+
case "hardfloat":
292+
// Hardware floating point support is the default everywhere except
293+
// on ARMv5 where it needs to be enabled explicitly.
294+
if archLevel == "5" {
295+
spec.CFlags = append(spec.CFlags, "-mfpu=vfpv2")
296+
}
297+
default:
298+
return nil, fmt.Errorf("invalid extension GOARM=%s, must be softfloat or hardfloat", options.GOARM)
299+
}
300+
switch archLevel {
271301
case "5":
272302
llvmarch = "armv5"
273-
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"
303+
if spec.SoftFloat {
304+
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"
305+
} else {
306+
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"
307+
}
274308
case "6":
275309
llvmarch = "armv6"
276-
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"
310+
if spec.SoftFloat {
311+
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"
312+
} else {
313+
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"
314+
}
277315
case "7":
278316
llvmarch = "armv7"
279-
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"
317+
if spec.SoftFloat {
318+
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"
319+
} else {
320+
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"
321+
}
280322
default:
281-
return nil, fmt.Errorf("invalid GOARM=%s, must be 5, 6, or 7", options.GOARM)
323+
return nil, fmt.Errorf("invalid GOARM=%s, must be of form <num>,[hardfloat|softfloat] where num is 5, 6, or 7", options.GOARM)
282324
}
283325
case "arm64":
284326
spec.CPU = "generic"

0 commit comments

Comments
 (0)