...
1 package asm
2
3 import (
4 "encoding/binary"
5 "fmt"
6 )
7
8
9
10
11
12 type BaseAssemblerImpl struct {
13
14
15 SetBranchTargetOnNextNodes []Node
16
17
18 JumpTableEntries []JumpTableEntry
19 }
20
21
22
23 type JumpTableEntry struct {
24 t *StaticConst
25 labelInitialInstructions []Node
26 }
27
28
29 func (a *BaseAssemblerImpl) SetJumpTargetOnNext(node Node) {
30 a.SetBranchTargetOnNextNodes = append(a.SetBranchTargetOnNextNodes, node)
31 }
32
33
34 func (a *BaseAssemblerImpl) BuildJumpTable(table *StaticConst, labelInitialInstructions []Node) {
35 a.JumpTableEntries = append(a.JumpTableEntries, JumpTableEntry{
36 t: table,
37 labelInitialInstructions: labelInitialInstructions,
38 })
39 }
40
41
42 func (a *BaseAssemblerImpl) FinalizeJumpTableEntry(code []byte) (err error) {
43 for i := range a.JumpTableEntries {
44 ent := &a.JumpTableEntries[i]
45 labelInitialInstructions := ent.labelInitialInstructions
46 table := ent.t
47
48 base := labelInitialInstructions[0].OffsetInBinary()
49 for i, nop := range labelInitialInstructions {
50 if nop.OffsetInBinary()-base >= JumpTableMaximumOffset {
51 return fmt.Errorf("too large br_table")
52 }
53
54 binary.LittleEndian.PutUint32(code[table.OffsetInBinary+uint64(i*4):table.OffsetInBinary+uint64((i+1)*4)],
55 uint32(nop.OffsetInBinary())-uint32(base))
56 }
57 }
58 return
59 }
60
View as plain text