targets: add CPU property everywhere
This is for consistency with Clang, which always adds a CPU flag even if it's not specified in CFLAGS. This commit also adds some tests to make sure the Clang target-cpu matches the CPU property in the JSON files. This does have an effect on the generated binaries. The effect is very small though: on average just 0.2% increase in binary size, apparently because Cortex-M3 and Cortex-M4 are compiled a bit differently. However, when rebased on top of https://github.com/tinygo-org/tinygo/pull/2218 (minsize), the difference drops to -0.1% (a slight decrease on average).
Этот коммит содержится в:
родитель
c2165f74d8
коммит
29206cf0a4
21 изменённых файлов: 174 добавлений и 28 удалений
|
@ -119,7 +119,7 @@ commands:
|
|||
- lib/wasi-libc/sysroot
|
||||
- run:
|
||||
name: "Test TinyGo"
|
||||
command: go test -v -timeout=20m -tags=llvm<<parameters.llvm>> ./cgo ./compileopts ./compiler ./interp ./transform .
|
||||
command: go test -v -timeout=20m -tags=llvm<<parameters.llvm>> ./builder ./cgo ./compileopts ./compiler ./interp ./transform .
|
||||
no_output_timeout: 20m
|
||||
- run: make gen-device -j4
|
||||
- run: make smoketest XTENSA=0
|
||||
|
|
141
builder/builder_test.go
Обычный файл
141
builder/builder_test.go
Обычный файл
|
@ -0,0 +1,141 @@
|
|||
package builder
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/tinygo-org/tinygo/compileopts"
|
||||
"github.com/tinygo-org/tinygo/goenv"
|
||||
"tinygo.org/x/go-llvm"
|
||||
)
|
||||
|
||||
// Test whether the Clang generated "target-cpu" attribute matches the CPU
|
||||
// property in TinyGo target files.
|
||||
func TestClangAttributes(t *testing.T) {
|
||||
var targetNames = []string{
|
||||
// Please keep this list sorted!
|
||||
"atmega328p",
|
||||
"atmega1280",
|
||||
"atmega1284p",
|
||||
"atmega2560",
|
||||
"attiny85",
|
||||
"cortex-m0",
|
||||
"cortex-m0plus",
|
||||
"cortex-m3",
|
||||
//"cortex-m33", // TODO: broken in LLVM 11, fixed in https://reviews.llvm.org/D90305
|
||||
"cortex-m4",
|
||||
"cortex-m7",
|
||||
"esp32c3",
|
||||
"fe310",
|
||||
"gameboy-advance",
|
||||
"k210",
|
||||
"nintendoswitch",
|
||||
"riscv-qemu",
|
||||
"wasi",
|
||||
"wasm",
|
||||
}
|
||||
if hasBuiltinTools {
|
||||
// hasBuiltinTools is set when TinyGo is statically linked with LLVM,
|
||||
// which also implies it was built with Xtensa support.
|
||||
targetNames = append(targetNames, "esp32", "esp8266")
|
||||
}
|
||||
for _, targetName := range targetNames {
|
||||
targetName := targetName
|
||||
t.Run(targetName, func(t *testing.T) {
|
||||
testClangAttributes(t, &compileopts.Options{Target: targetName})
|
||||
})
|
||||
}
|
||||
|
||||
for _, options := range []*compileopts.Options{
|
||||
{GOOS: "linux", GOARCH: "386"},
|
||||
{GOOS: "linux", GOARCH: "amd64"},
|
||||
{GOOS: "linux", GOARCH: "arm"},
|
||||
{GOOS: "linux", GOARCH: "arm64"},
|
||||
{GOOS: "darwin", GOARCH: "amd64"},
|
||||
{GOOS: "darwin", GOARCH: "arm64"},
|
||||
} {
|
||||
t.Run("GOOS="+options.GOOS+",GOARCH="+options.GOARCH, func(t *testing.T) {
|
||||
testClangAttributes(t, options)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func testClangAttributes(t *testing.T, options *compileopts.Options) {
|
||||
testDir := t.TempDir()
|
||||
clangHeaderPath := getClangHeaderPath(goenv.Get("TINYGOROOT"))
|
||||
|
||||
ctx := llvm.NewContext()
|
||||
defer ctx.Dispose()
|
||||
|
||||
target, err := compileopts.LoadTarget(options)
|
||||
if err != nil {
|
||||
t.Fatalf("could not load target: %s", err)
|
||||
}
|
||||
config := compileopts.Config{
|
||||
Options: options,
|
||||
Target: target,
|
||||
ClangHeaders: clangHeaderPath,
|
||||
}
|
||||
|
||||
// Create a very simple C input file.
|
||||
srcpath := filepath.Join(testDir, "test.c")
|
||||
err = ioutil.WriteFile(srcpath, []byte("int add(int a, int b) { return a + b; }"), 0o666)
|
||||
if err != nil {
|
||||
t.Fatalf("could not write target file %s: %s", srcpath, err)
|
||||
}
|
||||
|
||||
// Compile this file using Clang.
|
||||
outpath := filepath.Join(testDir, "test.bc")
|
||||
flags := append([]string{"-c", "-emit-llvm", "-o", outpath, srcpath}, config.CFlags()...)
|
||||
if config.GOOS() == "darwin" {
|
||||
// Silence some warnings that happen when testing GOOS=darwin on
|
||||
// something other than MacOS.
|
||||
flags = append(flags, "-Wno-missing-sysroot", "-Wno-incompatible-sysroot")
|
||||
}
|
||||
err = runCCompiler(flags...)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to compile %s: %s", srcpath, err)
|
||||
}
|
||||
|
||||
// Read the resulting LLVM bitcode.
|
||||
mod, err := ctx.ParseBitcodeFile(outpath)
|
||||
if err != nil {
|
||||
t.Fatalf("could not parse bitcode file %s: %s", outpath, err)
|
||||
}
|
||||
defer mod.Dispose()
|
||||
|
||||
// Check the "target-cpu" string attribute of the add function.
|
||||
add := mod.NamedFunction("add")
|
||||
var cpu string
|
||||
cpuAttr := add.GetStringAttributeAtIndex(-1, "target-cpu")
|
||||
if !cpuAttr.IsNil() {
|
||||
cpu = cpuAttr.GetStringValue()
|
||||
}
|
||||
if cpu != config.CPU() {
|
||||
t.Errorf("target has CPU %#v but Clang makes it CPU %#v", config.CPU(), cpu)
|
||||
}
|
||||
}
|
||||
|
||||
// This TestMain is necessary because TinyGo may also be invoked to run certain
|
||||
// LLVM tools in a separate process. Not capturing these invocations would lead
|
||||
// to recursive tests.
|
||||
func TestMain(m *testing.M) {
|
||||
if len(os.Args) >= 2 {
|
||||
switch os.Args[1] {
|
||||
case "clang", "ld.lld", "wasm-ld":
|
||||
// Invoke a specific tool.
|
||||
err := RunTool(os.Args[1], os.Args[2:]...)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
os.Exit(0)
|
||||
}
|
||||
}
|
||||
|
||||
// Run normal tests.
|
||||
os.Exit(m.Run())
|
||||
}
|
|
@ -220,6 +220,19 @@ func (c *Config) CFlags() []string {
|
|||
cflags = append(cflags, "-O"+c.Options.Opt)
|
||||
// Set the LLVM target triple.
|
||||
cflags = append(cflags, "--target="+c.Triple())
|
||||
// Set the -mcpu (or similar) flag.
|
||||
if c.Target.CPU != "" {
|
||||
if c.GOARCH() == "amd64" || c.GOARCH() == "386" {
|
||||
// x86 prefers the -march flag (-mcpu is deprecated there).
|
||||
cflags = append(cflags, "-march="+c.Target.CPU)
|
||||
} else if strings.HasPrefix(c.Triple(), "avr") {
|
||||
// AVR MCUs use -mmcu instead of -mcpu.
|
||||
cflags = append(cflags, "-mmcu="+c.Target.CPU)
|
||||
} else {
|
||||
// The rest just uses -mcpu.
|
||||
cflags = append(cflags, "-mcpu="+c.Target.CPU)
|
||||
}
|
||||
}
|
||||
return cflags
|
||||
}
|
||||
|
||||
|
|
|
@ -221,8 +221,15 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) {
|
|||
GDB: []string{"gdb"},
|
||||
PortReset: "false",
|
||||
}
|
||||
if goarch == "386" {
|
||||
switch goarch {
|
||||
case "386":
|
||||
spec.CPU = "pentium4"
|
||||
case "amd64":
|
||||
spec.CPU = "x86-64"
|
||||
case "arm":
|
||||
spec.CPU = "generic"
|
||||
case "arm64":
|
||||
spec.CPU = "generic"
|
||||
}
|
||||
if goos == "darwin" {
|
||||
spec.CFlags = append(spec.CFlags, "-isysroot", "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk")
|
||||
|
|
|
@ -3,9 +3,6 @@
|
|||
"cpu": "atmega1280",
|
||||
"build-tags": ["atmega1280", "atmega"],
|
||||
"serial": "uart",
|
||||
"cflags": [
|
||||
"-mmcu=atmega1280"
|
||||
],
|
||||
"ldflags": [
|
||||
"-mmcu=avr51",
|
||||
"-Wl,--defsym=_stack_size=512"
|
||||
|
|
|
@ -3,9 +3,6 @@
|
|||
"cpu": "atmega1284p",
|
||||
"build-tags": ["atmega1284p", "atmega"],
|
||||
"serial": "uart",
|
||||
"cflags": [
|
||||
"-mmcu=atmega1284p"
|
||||
],
|
||||
"ldflags": [
|
||||
"-mmcu=avr51",
|
||||
"-Wl,--defsym=_bootloader_size=0",
|
||||
|
|
|
@ -3,9 +3,6 @@
|
|||
"cpu": "atmega2560",
|
||||
"build-tags": ["atmega2560", "atmega"],
|
||||
"serial": "uart",
|
||||
"cflags": [
|
||||
"-mmcu=atmega2560"
|
||||
],
|
||||
"ldflags": [
|
||||
"-mmcu=avr6",
|
||||
"-Wl,--defsym=_stack_size=512"
|
||||
|
|
|
@ -3,9 +3,6 @@
|
|||
"cpu": "atmega328p",
|
||||
"build-tags": ["atmega328p", "atmega", "avr5"],
|
||||
"serial": "uart",
|
||||
"cflags": [
|
||||
"-mmcu=atmega328p"
|
||||
],
|
||||
"ldflags": [
|
||||
"-mmcu=avr5"
|
||||
],
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
"cpu": "attiny85",
|
||||
"build-tags": ["attiny85", "attiny", "avr2", "avr25"],
|
||||
"cflags": [
|
||||
"-mmcu=attiny85",
|
||||
"-D__AVR_ARCH__=25"
|
||||
],
|
||||
"ldflags": [
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
"inherits": ["cortex-m"],
|
||||
"llvm-target": "armv6m-unknown-unknown-eabi"
|
||||
"llvm-target": "armv6m-unknown-unknown-eabi",
|
||||
"cpu": "cortex-m0"
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
"inherits": ["cortex-m"],
|
||||
"llvm-target": "armv6m-unknown-unknown-eabi"
|
||||
"llvm-target": "armv6m-unknown-unknown-eabi",
|
||||
"cpu": "cortex-m0plus"
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
"inherits": ["cortex-m"],
|
||||
"llvm-target": "armv7m-unknown-unknown-eabi"
|
||||
"llvm-target": "armv7m-unknown-unknown-eabi",
|
||||
"cpu": "cortex-m3"
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
"inherits": ["cortex-m"],
|
||||
"llvm-target": "armv7em-unknown-unknown-eabi",
|
||||
"cpu": "cortex-m4",
|
||||
"cflags": [
|
||||
"-mfloat-abi=soft"
|
||||
]
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
"llvm-target": "armv7em-unknown-unknown-eabi",
|
||||
"cpu": "cortex-m7",
|
||||
"cflags": [
|
||||
"-mcpu=cortex-m7",
|
||||
"-mfloat-abi=soft"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -6,9 +6,6 @@
|
|||
"serial": "uart",
|
||||
"linker": "xtensa-esp32-elf-ld",
|
||||
"default-stack-size": 2048,
|
||||
"cflags": [
|
||||
"-mcpu=esp32"
|
||||
],
|
||||
"rtlib": "compiler-rt",
|
||||
"libc": "picolibc",
|
||||
"linkerscript": "targets/esp32.ld",
|
||||
|
|
|
@ -5,9 +5,6 @@
|
|||
"scheduler": "tasks",
|
||||
"linker": "xtensa-esp32-elf-ld",
|
||||
"default-stack-size": 2048,
|
||||
"cflags": [
|
||||
"-mcpu=esp8266"
|
||||
],
|
||||
"rtlib": "compiler-rt",
|
||||
"libc": "picolibc",
|
||||
"linkerscript": "targets/esp8266.ld",
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"inherits": ["riscv32"],
|
||||
"cpu": "sifive-e31",
|
||||
"features": ["+a", "+c", "+m"],
|
||||
"build-tags": ["fe310", "sifive"]
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
"rtlib": "compiler-rt",
|
||||
"libc": "picolibc",
|
||||
"cflags": [
|
||||
"-mcpu=arm7tdmi",
|
||||
"-Werror",
|
||||
"-fshort-enums",
|
||||
"-fomit-frame-pointer",
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"llvm-target": "aarch64",
|
||||
"cpu": "cortex-a57",
|
||||
"build-tags": ["nintendoswitch", "arm64"],
|
||||
"scheduler": "tasks",
|
||||
"goos": "linux",
|
||||
|
@ -9,11 +10,9 @@
|
|||
"libc": "picolibc",
|
||||
"gc": "conservative",
|
||||
"relocation-model": "pic",
|
||||
"cpu": "cortex-a57",
|
||||
"default-stack-size": 2048,
|
||||
"cflags": [
|
||||
"-target", "aarch64-unknown-none",
|
||||
"-mcpu=cortex-a57",
|
||||
"-fPIE",
|
||||
"-Werror",
|
||||
"-fshort-enums",
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"llvm-target": "wasm32-unknown-wasi",
|
||||
"cpu": "generic",
|
||||
"build-tags": ["tinygo.wasm", "wasi"],
|
||||
"goos": "linux",
|
||||
"goarch": "arm",
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"llvm-target": "wasm32-unknown-wasi",
|
||||
"cpu": "generic",
|
||||
"build-tags": ["tinygo.wasm"],
|
||||
"goos": "js",
|
||||
"goarch": "wasm",
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче