Skip to content

Commit

Permalink
compiler: require ARMv8.1
Browse files Browse the repository at this point in the history
Signed-off-by: Nuno Cruces <ncruces@users.noreply.github.com>
  • Loading branch information
ncruces committed Nov 19, 2024
1 parent d25ce10 commit 379f8be
Show file tree
Hide file tree
Showing 9 changed files with 117 additions and 8 deletions.
7 changes: 6 additions & 1 deletion config_supported.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@

package wazero

import "github.com/tetratelabs/wazero/internal/platform"

func newRuntimeConfig() RuntimeConfig {
return NewRuntimeConfigCompiler()
if platform.CompilerSupported() {
return NewRuntimeConfigCompiler()
}
return NewRuntimeConfigInterpreter()
}
5 changes: 5 additions & 0 deletions internal/platform/cpuid.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,8 @@ const (
CpuExtraFeatureAmd64ABM CpuFeature = 1 << 5
// Note: when adding new features, ensure that the feature is included in CpuFeatureFlags.Raw.
)

const (
// CpuFeatureArm64Atomic is the flag to query CpuFeatureFlags.Has for Large System Extensions capabilities on arm64
CpuFeatureArm64Atomic CpuFeature = 1 << 21
)
4 changes: 2 additions & 2 deletions internal/platform/cpuid_amd64.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//go:build amd64 && !tinygo
//go:build gc

package platform

Expand All @@ -12,7 +12,7 @@ type cpuFeatureFlags struct {
}

// cpuid exposes the CPUID instruction to the Go layer (https://www.amd.com/system/files/TechDocs/25481.pdf)
// implemented in impl_amd64.s
// implemented in cpuid_amd64.s
func cpuid(arg1, arg2 uint32) (eax, ebx, ecx, edx uint32)

// cpuidAsBitmap combines the result of invoking cpuid to uint64 bitmap.
Expand Down
4 changes: 3 additions & 1 deletion internal/platform/cpuid_amd64.s
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
//go:build gc

#include "textflag.h"

// lifted from github.com/intel-go/cpuid and src/internal/cpu/cpu_x86.s

// func cpuid(arg1, arg2 uint32) (eax, ebx, ecx, edx uint32)
TEXT ·cpuid(SB), NOSPLIT, $0-24
MOVL arg1+0(FP), AX
Expand All @@ -11,4 +14,3 @@ TEXT ·cpuid(SB), NOSPLIT, $0-24
MOVL CX, ecx+16(FP)
MOVL DX, edx+20(FP)
RET

76 changes: 76 additions & 0 deletions internal/platform/cpuid_arm64.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
//go:build gc

package platform

import "runtime"

// CpuFeatures exposes the capabilities for this CPU, queried via the Has, HasExtra methods.
var CpuFeatures = loadCpuFeatureFlags()

// cpuFeatureFlags implements CpuFeatureFlags interface.
type cpuFeatureFlags struct {
isar0 uint64
isar1 uint64
}

// implemented in cpuid_arm64.s
func getisar0() uint64

// implemented in cpuid_arm64.s
func getisar1() uint64

func loadCpuFeatureFlags() CpuFeatureFlags {
switch runtime.GOOS {
case "darwin", "windows":
// These OSes require ARMv8.1, which includes atomic instructions.
return &cpuFeatureFlags{
isar0: uint64(CpuFeatureArm64Atomic),
isar1: 0,
}
case "linux", "freebsd":
// These OSes allow reading the instruction set attribute registers.
return &cpuFeatureFlags{
isar0: getisar0(),
isar1: getisar1(),
}
default:
return &cpuFeatureFlags{}
}
}

// Has implements the same method on the CpuFeatureFlags interface.
func (f *cpuFeatureFlags) Has(cpuFeature CpuFeature) bool {
return (f.isar0 & uint64(cpuFeature)) != 0
}

// HasExtra implements the same method on the CpuFeatureFlags interface.
func (f *cpuFeatureFlags) HasExtra(cpuFeature CpuFeature) bool {
return (f.isar1 & uint64(cpuFeature)) != 0
}

// Raw implements the same method on the CpuFeatureFlags interface.
func (f *cpuFeatureFlags) Raw() uint64 {
// Below, we only set the first 4 bits for the features we care about,
// instead of setting all the unnecessary bits obtained from the CPUID instruction.
var ret uint64
switch runtime.GOARCH {
case "arm64":
if f.Has(CpuFeatureArm64Atomic) {
ret = 1 << 0
}
case "amd64":
if f.Has(CpuFeatureAmd64SSE3) {
ret = 1 << 0
}
if f.Has(CpuFeatureAmd64SSE4_1) {
ret |= 1 << 1
}
if f.Has(CpuFeatureAmd64SSE4_2) {
ret |= 1 << 2
}
if f.HasExtra(CpuExtraFeatureAmd64ABM) {
ret |= 1 << 3
}
}
return ret
}
21 changes: 21 additions & 0 deletions internal/platform/cpuid_arm64.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//go:build gc

#include "textflag.h"

// lifted from github.com/golang/sys and cpu/cpu_arm64.s

// func getisar0() uint64
TEXT ·getisar0(SB), NOSPLIT, $0-8
// get Instruction Set Attributes 0 into x0
// mrs x0, ID_AA64ISAR0_EL1 = d5380600
WORD $0xd5380600
MOVD R0, ret+0(FP)
RET

// func getisar1() uint64
TEXT ·getisar1(SB), NOSPLIT, $0-8
// get Instruction Set Attributes 1 into x0
// mrs x0, ID_AA64ISAR1_EL1 = d5380620
WORD $0xd5380620
MOVD R0, ret+0(FP)
RET
2 changes: 1 addition & 1 deletion internal/platform/cpuid_unsupported.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//go:build !amd64 || tinygo
//go:build !(amd64 || arm64) || !gc

package platform

Expand Down
2 changes: 1 addition & 1 deletion internal/platform/platform.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
// archRequirementsVerified is set by platform-specific init to true if the platform is supported
var archRequirementsVerified bool

// CompilerSupported is exported for tests and includes constraints here and also the assembler.
// CompilerSupported includes constraints here and also the assembler.
func CompilerSupported() bool {
switch runtime.GOOS {
case "linux", "darwin", "freebsd", "netbsd", "dragonfly", "windows":
Expand Down
4 changes: 2 additions & 2 deletions internal/platform/platform_arm64.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ package platform

// init verifies that the current CPU supports the required ARM64 features
func init() {
// No further checks currently needed.
archRequirementsVerified = true
// Ensure atomic instructions are supported.
archRequirementsVerified = CpuFeatures.Has(CpuFeatureArm64Atomic)
}

0 comments on commit 379f8be

Please sign in to comment.