github.com/tetratelabs/wazero@v1.7.3-0.20240513003603-48f702e154b5/internal/engine/wazevo/backend/isa/arm64/util_test.go (about)

     1  package arm64
     2  
     3  import (
     4  	"context"
     5  	"strings"
     6  
     7  	"github.com/tetratelabs/wazero/internal/engine/wazevo/backend"
     8  	"github.com/tetratelabs/wazero/internal/engine/wazevo/backend/regalloc"
     9  	"github.com/tetratelabs/wazero/internal/engine/wazevo/ssa"
    10  )
    11  
    12  func getPendingInstr(m *machine) *instruction {
    13  	return m.executableContext.PendingInstructions[0]
    14  }
    15  
    16  func formatEmittedInstructionsInCurrentBlock(m *machine) string {
    17  	m.executableContext.FlushPendingInstructions()
    18  	var strs []string
    19  	for cur := m.executableContext.PerBlockHead; cur != nil; cur = cur.next {
    20  		strs = append(strs, cur.String())
    21  	}
    22  	return strings.Join(strs, "\n")
    23  }
    24  
    25  func newSetup() (ssa.Builder, *machine) {
    26  	m := NewBackend().(*machine)
    27  	ssaB := ssa.NewBuilder()
    28  	backend.NewCompiler(context.Background(), m, ssaB)
    29  	blk := ssaB.AllocateBasicBlock()
    30  	ssaB.SetCurrentBlock(blk)
    31  	return ssaB, m
    32  }
    33  
    34  func newSetupWithMockContext() (*mockCompiler, ssa.Builder, *machine) {
    35  	ctx := newMockCompilationContext()
    36  	m := NewBackend().(*machine)
    37  	m.SetCompiler(ctx)
    38  	ssaB := ssa.NewBuilder()
    39  	blk := ssaB.AllocateBasicBlock()
    40  	ssaB.SetCurrentBlock(blk)
    41  	return ctx, ssaB, m
    42  }
    43  
    44  func regToVReg(reg regalloc.RealReg) regalloc.VReg {
    45  	return regalloc.VReg(0).SetRealReg(reg).SetRegType(regalloc.RegTypeInt)
    46  }
    47  
    48  func intToVReg(i int) regalloc.VReg {
    49  	return regalloc.VReg(i).SetRegType(regalloc.RegTypeInt)
    50  }
    51  
    52  // mockCompiler implements backend.Compiler for testing.
    53  type mockCompiler struct {
    54  	currentGID  ssa.InstructionGroupID
    55  	vRegCounter int
    56  	vRegMap     map[ssa.Value]regalloc.VReg
    57  	definitions map[ssa.Value]*backend.SSAValueDefinition
    58  	sigs        map[ssa.SignatureID]*ssa.Signature
    59  	typeOf      map[regalloc.VRegID]ssa.Type
    60  	relocs      []backend.RelocationInfo
    61  	buf         []byte
    62  }
    63  
    64  func (m *mockCompiler) BufPtr() *[]byte { return &m.buf }
    65  
    66  func (m *mockCompiler) GetFunctionABI(sig *ssa.Signature) *backend.FunctionABI {
    67  	// TODO implement me
    68  	panic("implement me")
    69  }
    70  
    71  func (m *mockCompiler) SSABuilder() ssa.Builder { return nil }
    72  
    73  func (m *mockCompiler) LoopNestingForestRoots() []ssa.BasicBlock { panic("TODO") }
    74  
    75  func (m *mockCompiler) SourceOffsetInfo() []backend.SourceOffsetInfo { return nil }
    76  
    77  func (m *mockCompiler) AddSourceOffsetInfo(int64, ssa.SourceOffset) {}
    78  
    79  func (m *mockCompiler) AddRelocationInfo(funcRef ssa.FuncRef) {
    80  	m.relocs = append(m.relocs, backend.RelocationInfo{FuncRef: funcRef, Offset: int64(len(m.buf))})
    81  }
    82  
    83  func (m *mockCompiler) Emit4Bytes(b uint32) {
    84  	m.buf = append(m.buf, byte(b), byte(b>>8), byte(b>>16), byte(b>>24))
    85  }
    86  
    87  func (m *mockCompiler) EmitByte(b byte) {
    88  	m.buf = append(m.buf, b)
    89  }
    90  
    91  func (m *mockCompiler) Emit8Bytes(b uint64) {
    92  	m.buf = append(m.buf, byte(b), byte(b>>8), byte(b>>16), byte(b>>24), byte(b>>32), byte(b>>40), byte(b>>48), byte(b>>56))
    93  }
    94  
    95  func (m *mockCompiler) Encode()     {}
    96  func (m *mockCompiler) Buf() []byte { return m.buf }
    97  func (m *mockCompiler) TypeOf(v regalloc.VReg) (ret ssa.Type) {
    98  	return m.typeOf[v.ID()]
    99  }
   100  func (m *mockCompiler) Finalize(context.Context) (err error) { return }
   101  func (m *mockCompiler) RegAlloc()                            {}
   102  func (m *mockCompiler) Lower()                               {}
   103  func (m *mockCompiler) Format() string                       { return "" }
   104  func (m *mockCompiler) Init()                                {}
   105  
   106  func newMockCompilationContext() *mockCompiler {
   107  	return &mockCompiler{
   108  		vRegMap:     make(map[ssa.Value]regalloc.VReg),
   109  		definitions: make(map[ssa.Value]*backend.SSAValueDefinition),
   110  		typeOf:      map[regalloc.VRegID]ssa.Type{},
   111  	}
   112  }
   113  
   114  // ResolveSignature implements backend.Compiler.
   115  func (m *mockCompiler) ResolveSignature(id ssa.SignatureID) *ssa.Signature {
   116  	return m.sigs[id]
   117  }
   118  
   119  // AllocateVReg implements backend.Compiler.
   120  func (m *mockCompiler) AllocateVReg(typ ssa.Type) regalloc.VReg {
   121  	m.vRegCounter++
   122  	regType := regalloc.RegTypeOf(typ)
   123  	ret := regalloc.VReg(m.vRegCounter).SetRegType(regType)
   124  	m.typeOf[ret.ID()] = typ
   125  	return ret
   126  }
   127  
   128  // ValueDefinition implements backend.Compiler.
   129  func (m *mockCompiler) ValueDefinition(value ssa.Value) *backend.SSAValueDefinition {
   130  	definition, exists := m.definitions[value]
   131  	if !exists {
   132  		return nil
   133  	}
   134  	return definition
   135  }
   136  
   137  // VRegOf implements backend.Compiler.
   138  func (m *mockCompiler) VRegOf(value ssa.Value) regalloc.VReg {
   139  	vReg, exists := m.vRegMap[value]
   140  	if !exists {
   141  		panic("Value does not exist")
   142  	}
   143  	return vReg
   144  }
   145  
   146  // MatchInstr implements backend.Compiler.
   147  func (m *mockCompiler) MatchInstr(def *backend.SSAValueDefinition, opcode ssa.Opcode) bool {
   148  	instr := def.Instr
   149  	return def.IsFromInstr() &&
   150  		instr.Opcode() == opcode &&
   151  		instr.GroupID() == m.currentGID &&
   152  		def.RefCount < 2
   153  }
   154  
   155  // MatchInstrOneOf implements backend.Compiler.
   156  func (m *mockCompiler) MatchInstrOneOf(def *backend.SSAValueDefinition, opcodes []ssa.Opcode) ssa.Opcode {
   157  	for _, opcode := range opcodes {
   158  		if m.MatchInstr(def, opcode) {
   159  			return opcode
   160  		}
   161  	}
   162  	return ssa.OpcodeInvalid
   163  }
   164  
   165  // Compile implements backend.Compiler.
   166  func (m *mockCompiler) Compile(context.Context) (_ []byte, _ []backend.RelocationInfo, _ error) {
   167  	return
   168  }