Skip to content

Commit 6efc6d2

Browse files
aykevldeadprogram
authored andcommitted
compileopts: refactor defaultTarget function
Move triple calculation into defaultTarget. It was separate for historic reasons that no longer apply. Merging the code makes future changes easier (in particular, softfloat support). The new code is actually shorter than the old code even though it has more comments.
1 parent d6e73b4 commit 6efc6d2

File tree

2 files changed

+83
-92
lines changed

2 files changed

+83
-92
lines changed

builder/builder_test.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@ func TestClangAttributes(t *testing.T) {
6464
{GOOS: "windows", GOARCH: "amd64"},
6565
{GOOS: "windows", GOARCH: "arm64"},
6666
{GOOS: "wasip1", GOARCH: "wasm"},
67-
{GOOS: "wasip2", GOARCH: "wasm"},
6867
} {
6968
name := "GOOS=" + options.GOOS + ",GOARCH=" + options.GOARCH
7069
if options.GOARCH == "arm" {

compileopts/target.go

Lines changed: 83 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -172,63 +172,7 @@ func (spec *TargetSpec) resolveInherits() error {
172172
// Load a target specification.
173173
func LoadTarget(options *Options) (*TargetSpec, error) {
174174
if options.Target == "" {
175-
// Configure based on GOOS/GOARCH environment variables (falling back to
176-
// runtime.GOOS/runtime.GOARCH), and generate a LLVM target based on it.
177-
var llvmarch string
178-
switch options.GOARCH {
179-
case "386":
180-
llvmarch = "i386"
181-
case "amd64":
182-
llvmarch = "x86_64"
183-
case "arm64":
184-
llvmarch = "aarch64"
185-
case "arm":
186-
switch options.GOARM {
187-
case "5":
188-
llvmarch = "armv5"
189-
case "6":
190-
llvmarch = "armv6"
191-
case "7":
192-
llvmarch = "armv7"
193-
default:
194-
return nil, fmt.Errorf("invalid GOARM=%s, must be 5, 6, or 7", options.GOARM)
195-
}
196-
case "mips":
197-
llvmarch = "mips"
198-
case "mipsle":
199-
llvmarch = "mipsel"
200-
case "wasm":
201-
llvmarch = "wasm32"
202-
default:
203-
llvmarch = options.GOARCH
204-
}
205-
llvmvendor := "unknown"
206-
llvmos := options.GOOS
207-
switch llvmos {
208-
case "darwin":
209-
// Use macosx* instead of darwin, otherwise darwin/arm64 will refer
210-
// to iOS!
211-
llvmos = "macosx10.12.0"
212-
if llvmarch == "aarch64" {
213-
// Looks like Apple prefers to call this architecture ARM64
214-
// instead of AArch64.
215-
llvmarch = "arm64"
216-
llvmos = "macosx11.0.0"
217-
}
218-
llvmvendor = "apple"
219-
case "wasip1":
220-
llvmos = "wasi"
221-
}
222-
// Target triples (which actually have four components, but are called
223-
// triples for historical reasons) have the form:
224-
// arch-vendor-os-environment
225-
target := llvmarch + "-" + llvmvendor + "-" + llvmos
226-
if options.GOOS == "windows" {
227-
target += "-gnu"
228-
} else if options.GOARCH == "arm" {
229-
target += "-gnueabihf"
230-
}
231-
return defaultTarget(options.GOOS, options.GOARCH, target)
175+
return defaultTarget(options)
232176
}
233177

234178
// See whether there is a target specification for this target (e.g.
@@ -289,44 +233,57 @@ func GetTargetSpecs() (map[string]*TargetSpec, error) {
289233
return maps, nil
290234
}
291235

292-
func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) {
293-
// No target spec available. Use the default one, useful on most systems
294-
// with a regular OS.
236+
// Load a target from environment variables (which default to
237+
// runtime.GOOS/runtime.GOARCH).
238+
func defaultTarget(options *Options) (*TargetSpec, error) {
295239
spec := TargetSpec{
296-
Triple: triple,
297-
GOOS: goos,
298-
GOARCH: goarch,
299-
BuildTags: []string{goos, goarch},
240+
GOOS: options.GOOS,
241+
GOARCH: options.GOARCH,
242+
BuildTags: []string{options.GOOS, options.GOARCH},
300243
GC: "precise",
301244
Scheduler: "tasks",
302245
Linker: "cc",
303246
DefaultStackSize: 1024 * 64, // 64kB
304247
GDB: []string{"gdb"},
305248
PortReset: "false",
306249
}
307-
switch goarch {
250+
251+
// Configure target based on GOARCH.
252+
var llvmarch string
253+
switch options.GOARCH {
308254
case "386":
255+
llvmarch = "i386"
309256
spec.CPU = "pentium4"
310257
spec.Features = "+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87"
311258
case "amd64":
259+
llvmarch = "x86_64"
312260
spec.CPU = "x86-64"
313261
spec.Features = "+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87"
314262
case "arm":
315263
spec.CPU = "generic"
316264
spec.CFlags = append(spec.CFlags, "-fno-unwind-tables", "-fno-asynchronous-unwind-tables")
317-
switch strings.Split(triple, "-")[0] {
318-
case "armv5":
265+
switch options.GOARM {
266+
case "5":
267+
llvmarch = "armv5"
319268
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"
320-
case "armv6":
269+
case "6":
270+
llvmarch = "armv6"
321271
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"
322-
case "armv7":
272+
case "7":
273+
llvmarch = "armv7"
323274
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"
275+
default:
276+
return nil, fmt.Errorf("invalid GOARM=%s, must be 5, 6, or 7", options.GOARM)
324277
}
325278
case "arm64":
326279
spec.CPU = "generic"
327-
if goos == "darwin" {
280+
llvmarch = "aarch64"
281+
if options.GOOS == "darwin" {
328282
spec.Features = "+fp-armv8,+neon"
329-
} else if goos == "windows" {
283+
// Looks like Apple prefers to call this architecture ARM64
284+
// instead of AArch64.
285+
llvmarch = "arm64"
286+
} else if options.GOOS == "windows" {
330287
spec.Features = "+fp-armv8,+neon,-fmv"
331288
} else { // linux
332289
spec.Features = "+fp-armv8,+neon,-fmv,-outline-atomics"
@@ -335,7 +292,13 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) {
335292
spec.CPU = "mips32r2"
336293
spec.Features = "+fpxx,+mips32r2,+nooddspreg,-noabicalls"
337294
spec.CFlags = append(spec.CFlags, "-fno-pic")
295+
if options.GOOS == "mips" {
296+
llvmarch = "mips" // big endian
297+
} else {
298+
llvmarch = "mipsel" // little endian
299+
}
338300
case "wasm":
301+
llvmarch = "wasm32"
339302
spec.CPU = "generic"
340303
spec.Features = "+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext"
341304
spec.BuildTags = append(spec.BuildTags, "tinygo.wasm")
@@ -344,24 +307,37 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) {
344307
"-mnontrapping-fptoint",
345308
"-msign-ext",
346309
)
310+
default:
311+
return nil, fmt.Errorf("unknown GOARCH=%s", options.GOARCH)
347312
}
348-
if goos == "darwin" {
313+
314+
// Configure target based on GOOS.
315+
llvmos := options.GOOS
316+
llvmvendor := "unknown"
317+
switch options.GOOS {
318+
case "darwin":
319+
platformVersion := "10.12.0"
320+
if options.GOARCH == "arm64" {
321+
platformVersion = "11.0.0" // first macosx platform with arm64 support
322+
}
323+
llvmvendor = "apple"
349324
spec.Linker = "ld.lld"
350325
spec.Libc = "darwin-libSystem"
351-
arch := strings.Split(triple, "-")[0]
352-
platformVersion := strings.TrimPrefix(strings.Split(triple, "-")[2], "macosx")
326+
// Use macosx* instead of darwin, otherwise darwin/arm64 will refer to
327+
// iOS!
328+
llvmos = "macosx" + platformVersion
353329
spec.LDFlags = append(spec.LDFlags,
354330
"-flavor", "darwin",
355331
"-dead_strip",
356-
"-arch", arch,
332+
"-arch", llvmarch,
357333
"-platform_version", "macos", platformVersion, platformVersion,
358334
)
359-
} else if goos == "linux" {
335+
case "linux":
360336
spec.Linker = "ld.lld"
361337
spec.RTLib = "compiler-rt"
362338
spec.Libc = "musl"
363339
spec.LDFlags = append(spec.LDFlags, "--gc-sections")
364-
if goarch == "arm64" {
340+
if options.GOARCH == "arm64" {
365341
// Disable outline atomics. For details, see:
366342
// https://cpufun.substack.com/p/atomics-in-aarch64
367343
// A better way would be to fully support outline atomics, which
@@ -375,7 +351,7 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) {
375351
// proper threading.
376352
spec.CFlags = append(spec.CFlags, "-mno-outline-atomics")
377353
}
378-
} else if goos == "windows" {
354+
case "windows":
379355
spec.Linker = "ld.lld"
380356
spec.Libc = "mingw-w64"
381357
// Note: using a medium code model, low image base and no ASLR
@@ -384,7 +360,7 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) {
384360
// normally present in Go (without explicitly opting in).
385361
// For more discussion:
386362
// https://groups.google.com/g/Golang-nuts/c/Jd9tlNc6jUE/m/Zo-7zIP_m3MJ?pli=1
387-
switch goarch {
363+
switch options.GOARCH {
388364
case "amd64":
389365
spec.LDFlags = append(spec.LDFlags,
390366
"-m", "i386pep",
@@ -401,7 +377,7 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) {
401377
"--no-insert-timestamp",
402378
"--no-dynamicbase",
403379
)
404-
} else if goos == "wasip1" {
380+
case "wasip1":
405381
spec.GC = "" // use default GC
406382
spec.Scheduler = "asyncify"
407383
spec.Linker = "wasm-ld"
@@ -417,28 +393,43 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) {
417393
"src/runtime/asm_tinygowasm.S",
418394
"src/internal/task/task_asyncify_wasm.S",
419395
)
420-
} else {
421-
spec.LDFlags = append(spec.LDFlags, "-no-pie", "-Wl,--gc-sections") // WARNING: clang < 5.0 requires -nopie
396+
llvmos = "wasi"
397+
default:
398+
return nil, fmt.Errorf("unknown GOOS=%s", options.GOOS)
422399
}
423-
if goarch != "wasm" {
400+
401+
// Target triples (which actually have four components, but are called
402+
// triples for historical reasons) have the form:
403+
// arch-vendor-os-environment
404+
spec.Triple = llvmarch + "-" + llvmvendor + "-" + llvmos
405+
if options.GOOS == "windows" {
406+
spec.Triple += "-gnu"
407+
} else if options.GOARCH == "arm" {
408+
spec.Triple += "-gnueabihf"
409+
}
410+
411+
// Add extra assembly files (needed for the scheduler etc).
412+
if options.GOARCH != "wasm" {
424413
suffix := ""
425-
if goos == "windows" && goarch == "amd64" {
414+
if options.GOOS == "windows" && options.GOARCH == "amd64" {
426415
// Windows uses a different calling convention on amd64 from other
427416
// operating systems so we need separate assembly files.
428417
suffix = "_windows"
429418
}
430-
asmGoarch := goarch
431-
if goarch == "mips" || goarch == "mipsle" {
419+
asmGoarch := options.GOARCH
420+
if options.GOARCH == "mips" || options.GOARCH == "mipsle" {
432421
asmGoarch = "mipsx"
433422
}
434423
spec.ExtraFiles = append(spec.ExtraFiles, "src/runtime/asm_"+asmGoarch+suffix+".S")
435424
spec.ExtraFiles = append(spec.ExtraFiles, "src/internal/task/task_stack_"+asmGoarch+suffix+".S")
436425
}
437-
if goarch != runtime.GOARCH {
426+
427+
// Configure the emulator.
428+
if options.GOARCH != runtime.GOARCH {
438429
// Some educated guesses as to how to invoke helper programs.
439430
spec.GDB = []string{"gdb-multiarch"}
440-
if goos == "linux" {
441-
switch goarch {
431+
if options.GOOS == "linux" {
432+
switch options.GOARCH {
442433
case "386":
443434
// amd64 can _usually_ run 32-bit programs, so skip the emulator in that case.
444435
if runtime.GOARCH != "amd64" {
@@ -457,11 +448,12 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) {
457448
}
458449
}
459450
}
460-
if goos != runtime.GOOS {
461-
if goos == "windows" {
451+
if options.GOOS != runtime.GOOS {
452+
if options.GOOS == "windows" {
462453
spec.Emulator = "wine {}"
463454
}
464455
}
456+
465457
return &spec, nil
466458
}
467459

0 commit comments

Comments
 (0)