Files
avo/internal/inst/types.go

137 lines
1.9 KiB
Go
Raw Normal View History

2018-11-20 11:44:44 -06:00
package inst
2018-12-02 12:28:33 -08:00
import (
"sort"
"strings"
)
2018-11-25 18:25:51 -08:00
2018-11-20 11:44:44 -06:00
type Instruction struct {
2018-11-21 13:02:18 -06:00
Opcode string
2018-11-25 16:22:02 -08:00
AliasOf string
2018-11-21 13:02:18 -06:00
Summary string
Forms []Form
2018-11-20 11:44:44 -06:00
}
2018-12-02 12:28:33 -08:00
func (i Instruction) IsTerminal() bool {
// TODO(mbm): how about the RETF* instructions
return i.Opcode == "RET"
}
func (i Instruction) IsBranch() bool {
if i.Opcode == "CALL" {
return false
}
for _, f := range i.Forms {
for _, op := range f.Operands {
if strings.HasPrefix(op.Type, "rel") {
return true
}
}
}
return false
}
func (i Instruction) IsConditionalBranch() bool {
return i.IsBranch() && i.Opcode != "JMP"
}
2018-11-25 18:25:51 -08:00
func (i Instruction) Arities() []int {
s := map[int]bool{}
for _, f := range i.Forms {
2018-12-08 20:14:51 -08:00
s[f.Arity()] = true
2018-11-25 18:25:51 -08:00
}
a := make([]int, 0, len(s))
for n := range s {
a = append(a, n)
}
sort.Ints(a)
return a
}
2018-11-26 10:13:04 -08:00
func (i Instruction) Arity() int {
if i.IsVariadic() {
panic("variadic")
}
a := i.Arities()
return a[0]
}
func (i Instruction) IsVariadic() bool {
return len(i.Arities()) > 1
}
func (i Instruction) IsNiladic() bool {
a := i.Arities()
return len(a) == 1 && a[0] == 0
}
2018-11-20 11:44:44 -06:00
type Form struct {
2018-11-23 17:14:18 -06:00
ISA []string
Operands []Operand
2018-11-23 23:48:47 -08:00
ImplicitOperands []ImplicitOperand
2018-11-20 11:44:44 -06:00
}
2018-12-08 20:14:51 -08:00
func (f Form) Arity() int {
return len(f.Operands)
}
func (f Form) Signature() []string {
2018-12-08 20:14:51 -08:00
s := make([]string, f.Arity())
for i, op := range f.Operands {
s[i] = op.Type
}
return s
}
2018-11-20 11:44:44 -06:00
type Operand struct {
Type string
Action Action
}
2018-11-23 17:14:18 -06:00
type ImplicitOperand struct {
Register string
Action Action
}
2018-11-20 11:44:44 -06:00
type Action uint8
const (
R Action = 0x1
W Action = 0x2
RW Action = R | W
)
2018-11-21 13:02:18 -06:00
func ActionFromReadWrite(r, w bool) Action {
var a Action
if r {
a |= R
}
if w {
a |= W
}
return a
}
func (a Action) Contains(s Action) bool {
return (a & s) == s
}
2018-11-21 13:02:18 -06:00
func (a Action) Read() bool {
return a.Contains(R)
2018-11-21 13:02:18 -06:00
}
func (a Action) Write() bool {
return a.Contains(W)
2018-11-21 13:02:18 -06:00
}
func (a Action) String() string {
s := ""
if a.Read() {
s += "r"
}
if a.Write() {
s += "w"
}
return s
}