internal/inst: doc exported symbols (#9)
This commit is contained in:
@@ -3,6 +3,8 @@ package inst
|
|||||||
//go:generate avogen -bootstrap -data ../data -output ztable.go godata
|
//go:generate avogen -bootstrap -data ../data -output ztable.go godata
|
||||||
//go:generate avogen -bootstrap -data ../data -output ztable_test.go godatatest
|
//go:generate avogen -bootstrap -data ../data -output ztable_test.go godatatest
|
||||||
|
|
||||||
|
// Lookup returns the instruction with the given opcode. Boolean return value
|
||||||
|
// indicates whether the instruction was found.
|
||||||
func Lookup(opcode string) (Instruction, bool) {
|
func Lookup(opcode string) (Instruction, bool) {
|
||||||
for _, i := range Instructions {
|
for _, i := range Instructions {
|
||||||
if i.Opcode == opcode {
|
if i.Opcode == opcode {
|
||||||
|
|||||||
@@ -5,18 +5,22 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Instruction represents an x86 instruction.
|
||||||
type Instruction struct {
|
type Instruction struct {
|
||||||
Opcode string
|
Opcode string // Golang assembly mnemonic
|
||||||
AliasOf string
|
AliasOf string // Opcode of instruction that this is an alias for
|
||||||
Summary string
|
Summary string // Description of the instruction
|
||||||
Forms []Form
|
Forms []Form // Accepted operand forms
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsTerminal reports whether the instruction exits a function.
|
||||||
func (i Instruction) IsTerminal() bool {
|
func (i Instruction) IsTerminal() bool {
|
||||||
// TODO(mbm): how about the RETF* instructions
|
// TODO(mbm): how about the RETF* instructions
|
||||||
return i.Opcode == "RET"
|
return i.Opcode == "RET"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsBranch reports whether the instruction is a branch; that is, if it can
|
||||||
|
// cause control flow to jump to another location.
|
||||||
func (i Instruction) IsBranch() bool {
|
func (i Instruction) IsBranch() bool {
|
||||||
if i.Opcode == "CALL" {
|
if i.Opcode == "CALL" {
|
||||||
return false
|
return false
|
||||||
@@ -31,10 +35,12 @@ func (i Instruction) IsBranch() bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsConditionalBranch reports whether the instruction branches dependent on some condition.
|
||||||
func (i Instruction) IsConditionalBranch() bool {
|
func (i Instruction) IsConditionalBranch() bool {
|
||||||
return i.IsBranch() && i.Opcode != "JMP"
|
return i.IsBranch() && i.Opcode != "JMP"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Arities returns the unique arities among the instruction forms.
|
||||||
func (i Instruction) Arities() []int {
|
func (i Instruction) Arities() []int {
|
||||||
s := map[int]bool{}
|
s := map[int]bool{}
|
||||||
for _, f := range i.Forms {
|
for _, f := range i.Forms {
|
||||||
@@ -48,6 +54,8 @@ func (i Instruction) Arities() []int {
|
|||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Arity is a convenience for returning the unique instruction arity when you
|
||||||
|
// know it is not variadic. Panics for a variadic instruction.
|
||||||
func (i Instruction) Arity() int {
|
func (i Instruction) Arity() int {
|
||||||
if i.IsVariadic() {
|
if i.IsVariadic() {
|
||||||
panic("variadic")
|
panic("variadic")
|
||||||
@@ -56,25 +64,33 @@ func (i Instruction) Arity() int {
|
|||||||
return a[0]
|
return a[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsVariadic reports whether the instruction has more than one arity.
|
||||||
func (i Instruction) IsVariadic() bool {
|
func (i Instruction) IsVariadic() bool {
|
||||||
return len(i.Arities()) > 1
|
return len(i.Arities()) > 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsNiladic reports whether the instruction takes no operands.
|
||||||
func (i Instruction) IsNiladic() bool {
|
func (i Instruction) IsNiladic() bool {
|
||||||
a := i.Arities()
|
a := i.Arities()
|
||||||
return len(a) == 1 && a[0] == 0
|
return len(a) == 1 && a[0] == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Form specifies one accepted set of operands for an instruction.
|
||||||
type Form struct {
|
type Form struct {
|
||||||
|
// Instruction sets this instruction form requires.
|
||||||
ISA []string
|
ISA []string
|
||||||
|
// Operands required for this form.
|
||||||
Operands []Operand
|
Operands []Operand
|
||||||
|
// Registers read or written but not explicitly passed to the instruction.
|
||||||
ImplicitOperands []ImplicitOperand
|
ImplicitOperands []ImplicitOperand
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Arity returns the number of operands this form expects.
|
||||||
func (f Form) Arity() int {
|
func (f Form) Arity() int {
|
||||||
return len(f.Operands)
|
return len(f.Operands)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Signature returns the list of operand types.
|
||||||
func (f Form) Signature() []string {
|
func (f Form) Signature() []string {
|
||||||
s := make([]string, f.Arity())
|
s := make([]string, f.Arity())
|
||||||
for i, op := range f.Operands {
|
for i, op := range f.Operands {
|
||||||
@@ -83,24 +99,29 @@ func (f Form) Signature() []string {
|
|||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Operand is an operand to an instruction, describing the expected type and read/write action.
|
||||||
type Operand struct {
|
type Operand struct {
|
||||||
Type string
|
Type string
|
||||||
Action Action
|
Action Action
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ImplicitOperand describes a register that is implicitly read/written by an instruction.
|
||||||
type ImplicitOperand struct {
|
type ImplicitOperand struct {
|
||||||
Register string
|
Register string
|
||||||
Action Action
|
Action Action
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Action specifies the read/write operation of an instruction on an operand.
|
||||||
type Action uint8
|
type Action uint8
|
||||||
|
|
||||||
|
// Possible Action types.
|
||||||
const (
|
const (
|
||||||
R Action = 0x1
|
R Action = 0x1
|
||||||
W Action = 0x2
|
W Action = 0x2
|
||||||
RW Action = R | W
|
RW Action = R | W
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ActionFromReadWrite builds an Action from boolean flags.
|
||||||
func ActionFromReadWrite(r, w bool) Action {
|
func ActionFromReadWrite(r, w bool) Action {
|
||||||
var a Action
|
var a Action
|
||||||
if r {
|
if r {
|
||||||
@@ -112,18 +133,22 @@ func ActionFromReadWrite(r, w bool) Action {
|
|||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Contains reports whether a supports all actions in s.
|
||||||
func (a Action) Contains(s Action) bool {
|
func (a Action) Contains(s Action) bool {
|
||||||
return (a & s) == s
|
return (a & s) == s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Read reports whether a supports read.
|
||||||
func (a Action) Read() bool {
|
func (a Action) Read() bool {
|
||||||
return a.Contains(R)
|
return a.Contains(R)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Write reports whether a supports write.
|
||||||
func (a Action) Write() bool {
|
func (a Action) Write() bool {
|
||||||
return a.Contains(W)
|
return a.Contains(W)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// String represents a as a human-readable string.
|
||||||
func (a Action) String() string {
|
func (a Action) String() string {
|
||||||
s := ""
|
s := ""
|
||||||
if a.Read() {
|
if a.Read() {
|
||||||
|
|||||||
Reference in New Issue
Block a user