Files
wazero/internal/engine/compiler/arch_arm64.go
Takeshi Yoneda ef8e12a575 compiler: bitmask for tracking used registers (#1323)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2023-03-31 12:28:20 +09:00

71 lines
2.4 KiB
Go

package compiler
import (
"math"
"github.com/tetratelabs/wazero/internal/asm"
"github.com/tetratelabs/wazero/internal/asm/arm64"
)
// init initializes variables for the arm64 architecture
func init() {
newArchContext = newArchContextImpl
registerNameFn = arm64.RegisterName
unreservedGeneralPurposeRegisters = arm64UnreservedGeneralPurposeRegisters
unreservedVectorRegisters = arm64UnreservedVectorRegisters
}
// archContext is embedded in callEngine in order to store architecture-specific data.
type archContext struct {
// compilerCallReturnAddress holds the absolute return address for nativecall.
// The value is set whenever nativecall is executed and done in compiler_arm64.s
// Native code can return to the ce.execWasmFunction's main loop back by
// executing "ret" instruction with this value. See arm64Compiler.exit.
// Note: this is only used by Compiler code so mark this as nolint.
compilerCallReturnAddress uint64 //nolint
// Loading large constants in arm64 is a bit costly, so we place the following
// consts on callEngine struct so that we can quickly access them during various operations.
// minimum32BitSignedInt is used for overflow check for 32-bit signed division.
// Note: this can be obtained by moving $1 and doing left-shift with 31, but it is
// slower than directly loading from this location.
minimum32BitSignedInt int32
// Note: this can be obtained by moving $1 and doing left-shift with 63, but it is
// slower than directly loading from this location.
// minimum64BitSignedInt is used for overflow check for 64-bit signed division.
minimum64BitSignedInt int64
}
// newArchContextImpl implements newArchContext for amd64 architecture.
func newArchContextImpl() archContext {
return archContext{
minimum32BitSignedInt: math.MinInt32,
minimum64BitSignedInt: math.MinInt64,
}
}
// newCompiler returns a new compiler interface which can be used to compile the given function instance.
// Note: ir param can be nil for host functions.
func newCompiler() compiler {
return newArm64Compiler()
}
func registerMaskShift(r asm.Register) (ret int) {
ret = int(r - arm64.RegR0)
if r > arm64.RegSP {
// Skips arm64.RegSP which is not a real register.
ret--
}
return
}
func registerFromMaskShift(s int) asm.Register {
if s < 32 {
return arm64.RegR0 + asm.Register(s)
} else {
// Skips arm64.RegSP which is not a real register.
return arm64.RegR0 + asm.Register(s) + 1
}
}