Files
wazero/internal/asm/impl.go
Takeshi Yoneda ecb35e2b94 asm: complete arm64 instruction encodings for homemade assembler (#431)
This commit implements all the arm64 instruction encodings necessary
for our JIT compiler and replaces the golang-asm assembler with our
handmade assembler on arm64 platform. Notably, this allows us to do
concurrent compilations.

This closes #233 combined with #406.

Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
Co-authored-by: Adrian Cole <adrian@tetrate.io>
2022-04-12 09:13:27 +09:00

46 lines
1.7 KiB
Go

package asm
import (
"encoding/binary"
"fmt"
)
// BaseAssemblerImpl includes code common to all architectures.
//
// Note: When possible, add code here instead of in architecture-specific files to reduce drift:
// As this is internal, exporting symbols only to reduce duplication is ok.
type BaseAssemblerImpl struct {
// SetBranchTargetOnNextNodes holds branch kind instructions (BR, conditional BR, etc.)
// where we want to set the next coming instruction as the destination of these BR instructions.
SetBranchTargetOnNextNodes []Node
// OnGenerateCallbacks holds the callbacks which are called after generating native code.
OnGenerateCallbacks []func(code []byte) error
}
// SetJumpTargetOnNext implements AssemblerBase.SetJumpTargetOnNext
func (a *BaseAssemblerImpl) SetJumpTargetOnNext(nodes ...Node) {
a.SetBranchTargetOnNextNodes = append(a.SetBranchTargetOnNextNodes, nodes...)
}
// AddOnGenerateCallBack implements AssemblerBase.AddOnGenerateCallBack
func (a *BaseAssemblerImpl) AddOnGenerateCallBack(cb func([]byte) error) {
a.OnGenerateCallbacks = append(a.OnGenerateCallbacks, cb)
}
// BuildJumpTable implements AssemblerBase.BuildJumpTable
func (a *BaseAssemblerImpl) BuildJumpTable(table []byte, labelInitialInstructions []Node) {
a.AddOnGenerateCallBack(func(code []byte) error {
// Build the offset table for each target.
base := labelInitialInstructions[0].OffsetInBinary()
for i, nop := range labelInitialInstructions {
if uint64(nop.OffsetInBinary())-uint64(base) >= JumpTableMaximumOffset {
return fmt.Errorf("too large br_table")
}
// We store the offset from the beginning of the L0's initial instruction.
binary.LittleEndian.PutUint32(table[i*4:(i+1)*4], uint32(nop.OffsetInBinary())-uint32(base))
}
return nil
})
}