/
store.go
95 lines (84 loc) · 1.86 KB
/
store.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package intermediate
import (
"aletheiaware.com/flamego"
"aletheiaware.com/flamego/isa"
"encoding/binary"
)
var _ Addressable = (*Store)(nil)
var _ Emittable = (*Store)(nil)
var _ Linkable = (*Store)(nil)
type Store struct {
Statement
address flamego.Register
labelName string
constantName string
offset uint32
source flamego.Register
label *Label
constant *Data
}
func NewStoreWithLabel(a flamego.Register, l string, s flamego.Register, c string) *Store {
return &Store{
Statement: Statement{
comment: c,
},
address: a,
labelName: l,
source: s,
}
}
func NewStoreWithConstant(a flamego.Register, n string, s flamego.Register, c string) *Store {
return &Store{
Statement: Statement{
comment: c,
},
address: a,
constantName: n,
source: s,
}
}
func NewStoreWithOffset(a flamego.Register, o uint32, s flamego.Register, c string) *Store {
return &Store{
Statement: Statement{
comment: c,
},
address: a,
offset: o,
source: s,
}
}
func (a *Store) Link(l Linker) error {
if a.labelName != "" {
label, err := l.Label(a.labelName)
if err != nil {
return err
}
a.label = label
} else if a.constantName != "" {
constant, err := l.Constant(a.constantName)
if err != nil {
return err
}
a.constant = constant
}
return nil
}
func (a *Store) String() string {
return a.Instruction().String() + a.Statement.String()
}
func (a *Store) Emit() []byte {
buffer := make([]byte, 4)
binary.BigEndian.PutUint32(buffer, isa.Encode(a.Instruction()))
return buffer
}
func (a *Store) EmittedSize() uint32 {
return flamego.InstructionSize
}
func (a *Store) Instruction() flamego.Instruction {
if a.label != nil {
a.offset = uint32(a.label.AbsoluteAddress())
} else if a.constant != nil {
a.offset = uint32(a.constant.Value())
}
return isa.NewStore(a.address, a.offset, a.source)
}