github.com/wasilibs/wazerox@v0.0.0-20240124024944-4923be63ab5f/internal/engine/compiler/arch_arm64.go (about) 1 package compiler 2 3 import ( 4 "math" 5 6 "github.com/wasilibs/wazerox/internal/asm" 7 "github.com/wasilibs/wazerox/internal/asm/arm64" 8 ) 9 10 // init initializes variables for the arm64 architecture 11 func init() { 12 newArchContext = newArchContextImpl 13 registerNameFn = arm64.RegisterName 14 unreservedGeneralPurposeRegisters = arm64UnreservedGeneralPurposeRegisters 15 unreservedVectorRegisters = arm64UnreservedVectorRegisters 16 } 17 18 // archContext is embedded in callEngine in order to store architecture-specific data. 19 type archContext struct { 20 // compilerCallReturnAddress holds the absolute return address for nativecall. 21 // The value is set whenever nativecall is executed and done in compiler_arm64.s 22 // Native code can return to the ce.execWasmFunction's main loop back by 23 // executing "ret" instruction with this value. See arm64Compiler.exit. 24 // Note: this is only used by Compiler code so mark this as nolint. 25 compilerCallReturnAddress uint64 //nolint 26 27 // Loading large constants in arm64 is a bit costly, so we place the following 28 // consts on callEngine struct so that we can quickly access them during various operations. 29 30 // minimum32BitSignedInt is used for overflow check for 32-bit signed division. 31 // Note: this can be obtained by moving $1 and doing left-shift with 31, but it is 32 // slower than directly loading from this location. 33 minimum32BitSignedInt int32 34 // Note: this can be obtained by moving $1 and doing left-shift with 63, but it is 35 // slower than directly loading from this location. 36 // minimum64BitSignedInt is used for overflow check for 64-bit signed division. 37 minimum64BitSignedInt int64 38 } 39 40 // newArchContextImpl implements newArchContext for amd64 architecture. 41 func newArchContextImpl() archContext { 42 return archContext{ 43 minimum32BitSignedInt: math.MinInt32, 44 minimum64BitSignedInt: math.MinInt64, 45 } 46 } 47 48 // newCompiler returns a new compiler interface which can be used to compile the given function instance. 49 // Note: ir param can be nil for host functions. 50 func newCompiler() compiler { 51 return newArm64Compiler() 52 } 53 54 func registerMaskShift(r asm.Register) (ret int) { 55 ret = int(r - arm64.RegR0) 56 if r > arm64.RegSP { 57 // Skips arm64.RegSP which is not a real register. 58 ret-- 59 } 60 return 61 } 62 63 func registerFromMaskShift(s int) asm.Register { 64 if s < 32 { 65 return arm64.RegR0 + asm.Register(s) 66 } else { 67 // Skips arm64.RegSP which is not a real register. 68 return arm64.RegR0 + asm.Register(s) + 1 69 } 70 }