github.com/wasilibs/wazerox@v0.0.0-20240124024944-4923be63ab5f/internal/engine/wazevo/backend/isa/arm64/util_test.go (about) 1 package arm64 2 3 import ( 4 "context" 5 "strings" 6 7 "github.com/wasilibs/wazerox/internal/engine/wazevo/backend" 8 "github.com/wasilibs/wazerox/internal/engine/wazevo/backend/regalloc" 9 "github.com/wasilibs/wazerox/internal/engine/wazevo/ssa" 10 ) 11 12 func getPendingInstr(m *machine) *instruction { 13 return m.pendingInstructions[0] 14 } 15 16 func formatEmittedInstructionsInCurrentBlock(m *machine) string { 17 m.FlushPendingInstructions() 18 var strs []string 19 for cur := m.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) SSABuilder() ssa.Builder { panic("TODO") } 65 66 func (m *mockCompiler) LoopNestingForestRoots() []ssa.BasicBlock { panic("TODO") } 67 68 func (m *mockCompiler) SourceOffsetInfo() []backend.SourceOffsetInfo { return nil } 69 70 func (m *mockCompiler) AddSourceOffsetInfo(int64, ssa.SourceOffset) {} 71 72 func (m *mockCompiler) AddRelocationInfo(funcRef ssa.FuncRef) { 73 m.relocs = append(m.relocs, backend.RelocationInfo{FuncRef: funcRef, Offset: int64(len(m.buf))}) 74 } 75 76 func (m *mockCompiler) Emit4Bytes(b uint32) { 77 m.buf = append(m.buf, byte(b), byte(b>>8), byte(b>>16), byte(b>>24)) 78 } 79 80 func (m *mockCompiler) Encode() {} 81 func (m *mockCompiler) Buf() []byte { return m.buf } 82 func (m *mockCompiler) TypeOf(v regalloc.VReg) (ret ssa.Type) { 83 return m.typeOf[v.ID()] 84 } 85 func (m *mockCompiler) Finalize() {} 86 func (m *mockCompiler) RegAlloc() {} 87 func (m *mockCompiler) Lower() {} 88 func (m *mockCompiler) Format() string { return "" } 89 func (m *mockCompiler) Init() {} 90 91 func newMockCompilationContext() *mockCompiler { 92 return &mockCompiler{ 93 vRegMap: make(map[ssa.Value]regalloc.VReg), 94 definitions: make(map[ssa.Value]*backend.SSAValueDefinition), 95 typeOf: map[regalloc.VRegID]ssa.Type{}, 96 } 97 } 98 99 // ResolveSignature implements backend.Compiler. 100 func (m *mockCompiler) ResolveSignature(id ssa.SignatureID) *ssa.Signature { 101 return m.sigs[id] 102 } 103 104 // AllocateVReg implements backend.Compiler. 105 func (m *mockCompiler) AllocateVReg(typ ssa.Type) regalloc.VReg { 106 m.vRegCounter++ 107 regType := regalloc.RegTypeOf(typ) 108 ret := regalloc.VReg(m.vRegCounter).SetRegType(regType) 109 m.typeOf[ret.ID()] = typ 110 return ret 111 } 112 113 // ValueDefinition implements backend.Compiler. 114 func (m *mockCompiler) ValueDefinition(value ssa.Value) *backend.SSAValueDefinition { 115 definition, exists := m.definitions[value] 116 if !exists { 117 return nil 118 } 119 return definition 120 } 121 122 // VRegOf implements backend.Compiler. 123 func (m *mockCompiler) VRegOf(value ssa.Value) regalloc.VReg { 124 vReg, exists := m.vRegMap[value] 125 if !exists { 126 panic("Value does not exist") 127 } 128 return vReg 129 } 130 131 // MatchInstr implements backend.Compiler. 132 func (m *mockCompiler) MatchInstr(def *backend.SSAValueDefinition, opcode ssa.Opcode) bool { 133 instr := def.Instr 134 return def.IsFromInstr() && 135 instr.Opcode() == opcode && 136 instr.GroupID() == m.currentGID && 137 def.RefCount < 2 138 } 139 140 // MatchInstrOneOf implements backend.Compiler. 141 func (m *mockCompiler) MatchInstrOneOf(def *backend.SSAValueDefinition, opcodes []ssa.Opcode) ssa.Opcode { 142 for _, opcode := range opcodes { 143 if m.MatchInstr(def, opcode) { 144 return opcode 145 } 146 } 147 return ssa.OpcodeInvalid 148 } 149 150 // Compile implements backend.Compiler. 151 func (m *mockCompiler) Compile(context.Context) (_ []byte, _ []backend.RelocationInfo, _ error) { 152 return 153 }