all: add target-features string to all targets
This makes sure that the LLVM target features match the one generated by Clang: - This fixes a bug introduced when setting the target CPU for all targets: Cortex-M4 would now start using floating point operations while they were disabled in C. - This will make it possible in the future to inline C functions in Go and vice versa. This will need some more work though. There is a code size impact. Cortex-M4 targets are increased slightly in binary size while Cortex-M0 targets tend to be reduced a little bit. Other than that, there is little impact.
Этот коммит содержится в:
родитель
af4d0fe191
коммит
78fec3719f
17 изменённых файлов: 53 добавлений и 30 удалений
|
@ -136,7 +136,6 @@ func Build(pkgName, outpath string, config *compileopts.Config, action func(Buil
|
||||||
DefaultStackSize: config.Target.DefaultStackSize,
|
DefaultStackSize: config.Target.DefaultStackSize,
|
||||||
NeedsStackObjects: config.NeedsStackObjects(),
|
NeedsStackObjects: config.NeedsStackObjects(),
|
||||||
Debug: true,
|
Debug: true,
|
||||||
LLVMFeatures: config.LLVMFeatures(),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load the target machine, which is the LLVM object that contains all
|
// Load the target machine, which is the LLVM object that contains all
|
||||||
|
|
|
@ -12,8 +12,8 @@ import (
|
||||||
"tinygo.org/x/go-llvm"
|
"tinygo.org/x/go-llvm"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Test whether the Clang generated "target-cpu" attribute matches the CPU
|
// Test whether the Clang generated "target-cpu" and "target-features"
|
||||||
// property in TinyGo target files.
|
// attributes match the CPU and Features property in TinyGo target files.
|
||||||
func TestClangAttributes(t *testing.T) {
|
func TestClangAttributes(t *testing.T) {
|
||||||
var targetNames = []string{
|
var targetNames = []string{
|
||||||
// Please keep this list sorted!
|
// Please keep this list sorted!
|
||||||
|
@ -112,16 +112,30 @@ func testClangAttributes(t *testing.T, options *compileopts.Options) {
|
||||||
t.Errorf("target has LLVM triple %#v but Clang makes it LLVM triple %#v", config.Triple(), mod.Target())
|
t.Errorf("target has LLVM triple %#v but Clang makes it LLVM triple %#v", config.Triple(), mod.Target())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check the "target-cpu" string attribute of the add function.
|
// Check the "target-cpu" and "target-features" string attribute of the add
|
||||||
|
// function.
|
||||||
add := mod.NamedFunction("add")
|
add := mod.NamedFunction("add")
|
||||||
var cpu string
|
var cpu, features string
|
||||||
cpuAttr := add.GetStringAttributeAtIndex(-1, "target-cpu")
|
cpuAttr := add.GetStringAttributeAtIndex(-1, "target-cpu")
|
||||||
|
featuresAttr := add.GetStringAttributeAtIndex(-1, "target-features")
|
||||||
if !cpuAttr.IsNil() {
|
if !cpuAttr.IsNil() {
|
||||||
cpu = cpuAttr.GetStringValue()
|
cpu = cpuAttr.GetStringValue()
|
||||||
}
|
}
|
||||||
|
if !featuresAttr.IsNil() {
|
||||||
|
features = featuresAttr.GetStringValue()
|
||||||
|
}
|
||||||
if cpu != config.CPU() {
|
if cpu != config.CPU() {
|
||||||
t.Errorf("target has CPU %#v but Clang makes it CPU %#v", config.CPU(), cpu)
|
t.Errorf("target has CPU %#v but Clang makes it CPU %#v", config.CPU(), cpu)
|
||||||
}
|
}
|
||||||
|
if features != config.Features() {
|
||||||
|
if llvm.Version != "11.0.0" {
|
||||||
|
// This needs to be removed once we switch to LLVM 12.
|
||||||
|
// LLVM 11.0.0 uses a different "target-features" string than LLVM
|
||||||
|
// 11.1.0 for Thumb targets. The Xtensa fork is still based on LLVM
|
||||||
|
// 11.0.0, so we need to skip this check on that version.
|
||||||
|
t.Errorf("target has LLVM features %#v but Clang makes it %#v", config.Features(), features)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This TestMain is necessary because TinyGo may also be invoked to run certain
|
// This TestMain is necessary because TinyGo may also be invoked to run certain
|
||||||
|
|
|
@ -34,10 +34,16 @@ func (c *Config) CPU() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Features returns a list of features this CPU supports. For example, for a
|
// Features returns a list of features this CPU supports. For example, for a
|
||||||
// RISC-V processor, that could be ["+a", "+c", "+m"]. For many targets, an
|
// RISC-V processor, that could be "+a,+c,+m". For many targets, an empty list
|
||||||
// empty list will be returned.
|
// will be returned.
|
||||||
func (c *Config) Features() []string {
|
func (c *Config) Features() string {
|
||||||
|
if c.Target.Features == "" {
|
||||||
|
return c.Options.LLVMFeatures
|
||||||
|
}
|
||||||
|
if c.Options.LLVMFeatures == "" {
|
||||||
return c.Target.Features
|
return c.Target.Features
|
||||||
|
}
|
||||||
|
return c.Target.Features + "," + c.Options.LLVMFeatures
|
||||||
}
|
}
|
||||||
|
|
||||||
// GOOS returns the GOOS of the target. This might not always be the actual OS:
|
// GOOS returns the GOOS of the target. This might not always be the actual OS:
|
||||||
|
@ -441,10 +447,6 @@ func (c *Config) WasmAbi() string {
|
||||||
return c.Target.WasmAbi
|
return c.Target.WasmAbi
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Config) LLVMFeatures() string {
|
|
||||||
return c.Options.LLVMFeatures
|
|
||||||
}
|
|
||||||
|
|
||||||
type TestConfig struct {
|
type TestConfig struct {
|
||||||
CompileTestBinary bool
|
CompileTestBinary bool
|
||||||
// TODO: Filter the test functions to run, include verbose flag, etc
|
// TODO: Filter the test functions to run, include verbose flag, etc
|
||||||
|
|
|
@ -25,7 +25,7 @@ type TargetSpec struct {
|
||||||
Inherits []string `json:"inherits"`
|
Inherits []string `json:"inherits"`
|
||||||
Triple string `json:"llvm-target"`
|
Triple string `json:"llvm-target"`
|
||||||
CPU string `json:"cpu"`
|
CPU string `json:"cpu"`
|
||||||
Features []string `json:"features"`
|
Features string `json:"features"`
|
||||||
GOOS string `json:"goos"`
|
GOOS string `json:"goos"`
|
||||||
GOARCH string `json:"goarch"`
|
GOARCH string `json:"goarch"`
|
||||||
BuildTags []string `json:"build-tags"`
|
BuildTags []string `json:"build-tags"`
|
||||||
|
@ -234,12 +234,16 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) {
|
||||||
switch goarch {
|
switch goarch {
|
||||||
case "386":
|
case "386":
|
||||||
spec.CPU = "pentium4"
|
spec.CPU = "pentium4"
|
||||||
|
spec.Features = "+cx8,+fxsr,+mmx,+sse,+sse2,+x87"
|
||||||
case "amd64":
|
case "amd64":
|
||||||
spec.CPU = "x86-64"
|
spec.CPU = "x86-64"
|
||||||
|
spec.Features = "+cx8,+fxsr,+mmx,+sse,+sse2,+x87"
|
||||||
case "arm":
|
case "arm":
|
||||||
spec.CPU = "generic"
|
spec.CPU = "generic"
|
||||||
|
spec.Features = "+armv7-a,+dsp,+fp64,+vfp2,+vfp2sp,+vfp3d16,+vfp3d16sp,-thumb-mode"
|
||||||
case "arm64":
|
case "arm64":
|
||||||
spec.CPU = "generic"
|
spec.CPU = "generic"
|
||||||
|
spec.Features = "+neon"
|
||||||
}
|
}
|
||||||
if goos == "darwin" {
|
if goos == "darwin" {
|
||||||
spec.CFlags = append(spec.CFlags, "-isysroot", "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk")
|
spec.CFlags = append(spec.CFlags, "-isysroot", "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk")
|
||||||
|
|
|
@ -43,7 +43,7 @@ type Config struct {
|
||||||
// Target and output information.
|
// Target and output information.
|
||||||
Triple string
|
Triple string
|
||||||
CPU string
|
CPU string
|
||||||
Features []string
|
Features string
|
||||||
GOOS string
|
GOOS string
|
||||||
GOARCH string
|
GOARCH string
|
||||||
CodeModel string
|
CodeModel string
|
||||||
|
@ -57,7 +57,6 @@ type Config struct {
|
||||||
DefaultStackSize uint64
|
DefaultStackSize uint64
|
||||||
NeedsStackObjects bool
|
NeedsStackObjects bool
|
||||||
Debug bool // Whether to emit debug information in the LLVM module.
|
Debug bool // Whether to emit debug information in the LLVM module.
|
||||||
LLVMFeatures string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// compilerContext contains function-independent data that should still be
|
// compilerContext contains function-independent data that should still be
|
||||||
|
@ -189,12 +188,6 @@ func NewTargetMachine(config *Config) (llvm.TargetMachine, error) {
|
||||||
return llvm.TargetMachine{}, err
|
return llvm.TargetMachine{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
feat := config.Features
|
|
||||||
if len(config.LLVMFeatures) > 0 {
|
|
||||||
feat = append(feat, config.LLVMFeatures)
|
|
||||||
}
|
|
||||||
features := strings.Join(feat, ",")
|
|
||||||
|
|
||||||
var codeModel llvm.CodeModel
|
var codeModel llvm.CodeModel
|
||||||
var relocationModel llvm.RelocMode
|
var relocationModel llvm.RelocMode
|
||||||
|
|
||||||
|
@ -222,7 +215,7 @@ func NewTargetMachine(config *Config) (llvm.TargetMachine, error) {
|
||||||
relocationModel = llvm.RelocDynamicNoPic
|
relocationModel = llvm.RelocDynamicNoPic
|
||||||
}
|
}
|
||||||
|
|
||||||
machine := target.CreateTargetMachine(config.Triple, config.CPU, features, llvm.CodeGenLevelDefault, relocationModel, codeModel)
|
machine := target.CreateTargetMachine(config.Triple, config.CPU, config.Features, llvm.CodeGenLevelDefault, relocationModel, codeModel)
|
||||||
return machine, nil
|
return machine, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
{
|
{
|
||||||
"inherits": ["cortex-m"],
|
"inherits": ["cortex-m"],
|
||||||
"llvm-target": "thumbv6m-unknown-unknown-eabi",
|
"llvm-target": "thumbv6m-unknown-unknown-eabi",
|
||||||
"cpu": "cortex-m0"
|
"cpu": "cortex-m0",
|
||||||
|
"features": "+armv6-m,+soft-float,+strict-align,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-d32,-dotprod,-dsp,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-hwdiv,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-ras,-sb,-sha2,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
{
|
{
|
||||||
"inherits": ["cortex-m"],
|
"inherits": ["cortex-m"],
|
||||||
"llvm-target": "thumbv6m-unknown-unknown-eabi",
|
"llvm-target": "thumbv6m-unknown-unknown-eabi",
|
||||||
"cpu": "cortex-m0plus"
|
"cpu": "cortex-m0plus",
|
||||||
|
"features": "+armv6-m,+soft-float,+strict-align,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-d32,-dotprod,-dsp,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-hwdiv,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-ras,-sb,-sha2,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
{
|
{
|
||||||
"inherits": ["cortex-m"],
|
"inherits": ["cortex-m"],
|
||||||
"llvm-target": "thumbv7m-unknown-unknown-eabi",
|
"llvm-target": "thumbv7m-unknown-unknown-eabi",
|
||||||
"cpu": "cortex-m3"
|
"cpu": "cortex-m3",
|
||||||
|
"features": "+armv7-m,+hwdiv,+soft-float,+strict-align,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-d32,-dotprod,-dsp,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-ras,-sb,-sha2,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp"
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
"inherits": ["cortex-m"],
|
"inherits": ["cortex-m"],
|
||||||
"llvm-target": "thumbv7em-unknown-unknown-eabi",
|
"llvm-target": "thumbv7em-unknown-unknown-eabi",
|
||||||
"cpu": "cortex-m4",
|
"cpu": "cortex-m4",
|
||||||
|
"features": "+armv7e-m,+dsp,+hwdiv,+soft-float,+strict-align,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-d32,-dotprod,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-ras,-sb,-sha2,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp",
|
||||||
"cflags": [
|
"cflags": [
|
||||||
"-mfloat-abi=soft"
|
"-mfloat-abi=soft"
|
||||||
]
|
]
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
"inherits": ["cortex-m"],
|
"inherits": ["cortex-m"],
|
||||||
"llvm-target": "thumbv7em-unknown-unknown-eabi",
|
"llvm-target": "thumbv7em-unknown-unknown-eabi",
|
||||||
"cpu": "cortex-m7",
|
"cpu": "cortex-m7",
|
||||||
|
"features": "+armv7e-m,+dsp,+hwdiv,+soft-float,+strict-align,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-d32,-dotprod,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-ras,-sb,-sha2,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp",
|
||||||
"cflags": [
|
"cflags": [
|
||||||
"-mfloat-abi=soft"
|
"-mfloat-abi=soft"
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
{
|
{
|
||||||
"inherits": ["riscv32"],
|
"inherits": ["riscv32"],
|
||||||
"features": ["+c", "+m"],
|
"features": "+c,+m,-relax,-save-restore",
|
||||||
"build-tags": ["esp32c3", "esp"],
|
"build-tags": ["esp32c3", "esp"],
|
||||||
"serial": "uart",
|
"serial": "uart",
|
||||||
"rtlib": "compiler-rt",
|
"rtlib": "compiler-rt",
|
||||||
"libc": "picolibc",
|
"libc": "picolibc",
|
||||||
|
"cflags": [
|
||||||
|
"-march=rv32imc"
|
||||||
|
],
|
||||||
"linkerscript": "targets/esp32c3.ld",
|
"linkerscript": "targets/esp32c3.ld",
|
||||||
"extra-files": [
|
"extra-files": [
|
||||||
"src/device/esp/esp32c3.S"
|
"src/device/esp/esp32c3.S"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"inherits": ["riscv32"],
|
"inherits": ["riscv32"],
|
||||||
"cpu": "sifive-e31",
|
"cpu": "sifive-e31",
|
||||||
"features": ["+a", "+c", "+m"],
|
"features": "+a,+c,+m,-64bit,-relax,-save-restore",
|
||||||
"build-tags": ["fe310", "sifive"]
|
"build-tags": ["fe310", "sifive"]
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
{
|
{
|
||||||
"llvm-target": "armv4t-unknown-unknown-eabi",
|
"llvm-target": "armv4t-unknown-unknown-eabi",
|
||||||
"cpu": "arm7tdmi",
|
"cpu": "arm7tdmi",
|
||||||
|
"features": "+armv4t,+soft-float,+strict-align,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-d32,-dotprod,-dsp,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-hwdiv,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-ras,-sb,-sha2,-thumb-mode,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp",
|
||||||
"build-tags": ["gameboyadvance", "arm7tdmi", "baremetal", "linux", "arm"],
|
"build-tags": ["gameboyadvance", "arm7tdmi", "baremetal", "linux", "arm"],
|
||||||
"goos": "linux",
|
"goos": "linux",
|
||||||
"goarch": "arm",
|
"goarch": "arm",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"inherits": ["riscv64"],
|
"inherits": ["riscv64"],
|
||||||
"features": ["+a", "+c", "+m", "+f", "+d"],
|
"features": "+a,+c,+d,+f,+m,-relax,-save-restore",
|
||||||
"build-tags": ["k210", "kendryte"],
|
"build-tags": ["k210", "kendryte"],
|
||||||
"code-model": "medium"
|
"code-model": "medium"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
{
|
{
|
||||||
"llvm-target": "aarch64",
|
"llvm-target": "aarch64",
|
||||||
"cpu": "cortex-a57",
|
"cpu": "cortex-a57",
|
||||||
|
"features": "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2",
|
||||||
"build-tags": ["nintendoswitch", "arm64"],
|
"build-tags": ["nintendoswitch", "arm64"],
|
||||||
"scheduler": "tasks",
|
"scheduler": "tasks",
|
||||||
"goos": "linux",
|
"goos": "linux",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"inherits": ["riscv32"],
|
"inherits": ["riscv32"],
|
||||||
"features": ["+a", "+c", "+m"],
|
"features": "+a,+c,+m,-relax,-save-restore",
|
||||||
"build-tags": ["virt", "qemu"],
|
"build-tags": ["virt", "qemu"],
|
||||||
"linkerscript": "targets/riscv-qemu.ld",
|
"linkerscript": "targets/riscv-qemu.ld",
|
||||||
"emulator": ["qemu-system-riscv32", "-machine", "virt", "-nographic", "-bios", "none", "-kernel"]
|
"emulator": ["qemu-system-riscv32", "-machine", "virt", "-nographic", "-bios", "none", "-kernel"]
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
"libc": "picolibc",
|
"libc": "picolibc",
|
||||||
"cflags": [
|
"cflags": [
|
||||||
"-Werror",
|
"-Werror",
|
||||||
|
"-mno-relax",
|
||||||
"-fno-exceptions", "-fno-unwind-tables",
|
"-fno-exceptions", "-fno-unwind-tables",
|
||||||
"-ffunction-sections", "-fdata-sections"
|
"-ffunction-sections", "-fdata-sections"
|
||||||
],
|
],
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче