ssa

package
v0.0.0-...-cfdb25a Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 9, 2021 License: BSD-3-Clause Imports: 38 Imported by: 0

README

Introduction to the Go compiler's SSA backend

This package contains the compiler's Static Single Assignment form component. If you're not familiar with SSA, its Wikipedia article is a good starting point.

It is recommended that you first read cmd/compile/README.md if you are not familiar with the Go compiler already. That document gives an overview of the compiler, and explains what is SSA's part and purpose in it.

Key concepts

The names described below may be loosely related to their Go counterparts, but note that they are not equivalent. For example, a Go block statement has a variable scope, yet SSA has no notion of variables nor variable scopes.

It may also be surprising that values and blocks are named after their unique sequential IDs. They rarely correspond to named entities in the original code, such as variables or function parameters. The sequential IDs also allow the compiler to avoid maps, and it is always possible to track back the values to Go code using debug and position information.

Values

Values are the basic building blocks of SSA. Per SSA's very definition, a value is defined exactly once, but it may be used any number of times. A value mainly consists of a unique identifier, an operator, a type, and some arguments.

An operator or Op describes the operation that computes the value. The semantics of each operator can be found in gen/*Ops.go. For example, OpAdd8 takes two value arguments holding 8-bit integers and results in their addition. Here is a possible SSA representation of the addition of two uint8 values:

// var c uint8 = a + b
v4 = Add8 <uint8> v2 v3

A value's type will usually be a Go type. For example, the value in the example above has a uint8 type, and a constant boolean value will have a bool type. However, certain types don't come from Go and are special; below we will cover memory, the most common of them.

See value.go for more information.

Memory types

memory represents the global memory state. An Op that takes a memory argument depends on that memory state, and an Op which has the memory type impacts the state of memory. This ensures that memory operations are kept in the right order. For example:

// *a = 3
// *b = *a
v10 = Store <mem> {int} v6 v8 v1
v14 = Store <mem> {int} v7 v8 v10

Here, Store stores its second argument (of type int) into the first argument (of type *int). The last argument is the memory state; since the second store depends on the memory value defined by the first store, the two stores cannot be reordered.

See cmd/compile/internal/types/type.go for more information.

Blocks

A block represents a basic block in the control flow graph of a function. It is, essentially, a list of values that define the operation of this block. Besides the list of values, blocks mainly consist of a unique identifier, a kind, and a list of successor blocks.

The simplest kind is a plain block; it simply hands the control flow to another block, thus its successors list contains one block.

Another common block kind is the exit block. These have a final value, called control value, which must return a memory state. This is necessary for functions to return some values, for example - the caller needs some memory state to depend on, to ensure that it receives those return values correctly.

The last important block kind we will mention is the if block. Its control value must be a boolean value, and it has exactly two successor blocks. The control flow is handed to the first successor if the bool is true, and to the second otherwise.

Here is a sample if-else control flow represented with basic blocks:

// func(b bool) int {
// 	if b {
// 		return 2
// 	}
// 	return 3
// }
b1:
  v1 = InitMem <mem>
  v2 = SP <uintptr>
  v5 = Addr <*int> {~r1} v2
  v6 = Arg <bool> {b}
  v8 = Const64 <int> [2]
  v12 = Const64 <int> [3]
  If v6 -> b2 b3
b2: <- b1
  v10 = VarDef <mem> {~r1} v1
  v11 = Store <mem> {int} v5 v8 v10
  Ret v11
b3: <- b1
  v14 = VarDef <mem> {~r1} v1
  v15 = Store <mem> {int} v5 v12 v14
  Ret v15

See block.go for more information.

Functions

A function represents a function declaration along with its body. It mainly consists of a name, a type (its signature), a list of blocks that form its body, and the entry block within said list.

When a function is called, the control flow is handed to its entry block. If the function terminates, the control flow will eventually reach an exit block, thus ending the function call.

Note that a function may have zero or multiple exit blocks, just like a Go function can have any number of return points, but it must have exactly one entry point block.

Also note that some SSA functions are autogenerated, such as the hash functions for each type used as a map key.

For example, this is what an empty function can look like in SSA, with a single exit block that returns an uninteresting memory state:

foo func()
  b1:
    v1 = InitMem <mem>
    Ret v1

See func.go for more information.

Compiler passes

Having a program in SSA form is not very useful on its own. Its advantage lies in how easy it is to write optimizations that modify the program to make it better. The way the Go compiler accomplishes this is via a list of passes.

Each pass transforms a SSA function in some way. For example, a dead code elimination pass will remove blocks and values that it can prove will never be executed, and a nil check elimination pass will remove nil checks which it can prove to be redundant.

Compiler passes work on one function at a time, and by default run sequentially and exactly once.

The lower pass is special; it converts the SSA representation from being machine-independent to being machine-dependent. That is, some abstract operators are replaced with their non-generic counterparts, potentially reducing or increasing the final number of values.

See the passes list defined in compile.go for more information.

Playing with SSA

A good way to see and get used to the compiler's SSA in action is via GOSSAFUNC. For example, to see func Foo's initial SSA form and final generated assembly, one can run:

GOSSAFUNC=Foo go build

The generated ssa.html file will also contain the SSA func at each of the compile passes, making it easy to see what each pass does to a particular program. You can also click on values and blocks to highlight them, to help follow the control flow and values.

Hacking on SSA

While most compiler passes are implemented directly in Go code, some others are code generated. This is currently done via rewrite rules, which have their own syntax and are maintained in gen/*.rules. Simpler optimizations can be written easily and quickly this way, but rewrite rules are not suitable for more complex optimizations.

To read more on rewrite rules, have a look at the top comments in gen/generic.rules and gen/rulegen.go.

Similarly, the code to manage operators is also code generated from gen/*Ops.go, as it is easier to maintain a few tables than a lot of code. After changing the rules or operators, see gen/README for instructions on how to generate the Go code again.

Documentation

Overview

Copyright 2017 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.

Index

Constants

View Source
const (
	BranchUnlikely = BranchPrediction(-1)
	BranchUnknown  = BranchPrediction(0)
	BranchLikely   = BranchPrediction(+1)
)
View Source
const (
	ScorePhi = iota // towards top of block
	ScoreArg
	ScoreNilCheck
	ScoreReadTuple
	ScoreVarDef
	ScoreMemory
	ScoreReadFlags
	ScoreDefault
	ScoreFlags
	ScoreControl // towards bottom of block
)
View Source
const (
	// When used to lookup up definitions in a sparse tree,
	// these adjustments to a block's entry (+adjust) and
	// exit (-adjust) numbers allow a distinction to be made
	// between assignments (typically branch-dependent
	// conditionals) occurring "before" the block (e.g., as inputs
	// to the block and its phi functions), "within" the block,
	// and "after" the block.
	AdjustBefore = -1 // defined before phi
	AdjustWithin = 0  // defined by phi
	AdjustAfter  = 1  // defined within block
)
View Source
const MaxStruct = 4

MaxStruct is the maximum number of fields a struct can have and still be SSAable.

Variables

View Source
var BlockEnd = &Value{
	ID:  -20000,
	Op:  OpInvalid,
	Aux: "BlockEnd",
}
View Source
var BlockStart = &Value{
	ID:  -10000,
	Op:  OpInvalid,
	Aux: "BlockStart",
}
View Source
var BuildDebug int
View Source
var BuildDump string // name of function to dump after initial build of ssa
View Source
var BuildStats int
View Source
var BuildTest int
View Source
var IntrinsicsDebug int

Debug output

View Source
var IntrinsicsDisable bool

Functions

func Compile

func Compile(f *Func)

Compile is the main entry point for this package. Compile modifies f so that on return:

· all Values in f map to 0 or 1 assembly instructions of the target architecture
· the order of f.Blocks is the order to emit the Blocks
· the order of b.Values is the order to emit the Values in each Block
· f has a non-nil regAlloc field

func DebugNameMatch

func DebugNameMatch(evname, name string) bool

func IsGlobalAddr

func IsGlobalAddr(v *Value) bool

IsGlobalAddr reports whether v is known to be an address of a global.

func IsNewObject

func IsNewObject(v *Value, mem *Value) bool

IsNewObject reports whether v is a pointer to a freshly allocated & zeroed object at memory state mem. TODO: Be more precise. We really want "IsNilPointer" for the particular field in question. Right now, we can only detect a new object before any writes have been done to it. We could ignore non-pointer writes, writes to offsets which are known not to overlap the write in question, etc.

func IsReadOnlyGlobalAddr

func IsReadOnlyGlobalAddr(v *Value) bool

IsReadOnlyGlobalAddr reports whether v is known to be an address of a read-only global.

func IsSanitizerSafeAddr

func IsSanitizerSafeAddr(v *Value) bool

IsSanitizerSafeAddr reports whether v is known to be an address that doesn't need instrumentation.

func IsStackAddr

func IsStackAddr(v *Value) bool

IsStackAddr reports whether v is known to be an address of a stack slot.

func LosesStmtMark

func LosesStmtMark(as obj.As) bool

LosesStmtMark reports whether a prog with op as loses its statement mark on the way to DWARF. The attributes from some opcodes are lost in translation. TODO: this is an artifact of how funcpctab combines information for instructions at a single PC. Should try to fix it there.

func NeedsFixUp

func NeedsFixUp(v *Value) bool

NeedsFixUp reports whether the division needs fix-up code.

func PhaseOption

func PhaseOption(phase, flag string, val int, valString string) string

PhaseOption sets the specified flag in the specified ssa phase, returning empty string if this was successful or a string explaining the error if it was not. A version of the phase name with "_" replaced by " " is also checked for a match. If the phase name begins a '~' then the rest of the underscores-replaced-with-blanks version is used as a regular expression to match the phase name(s).

Special cases that have turned out to be useful:

ssa/check/on enables checking after each phase
ssa/all/time enables time reporting for all phases

See gc/lex.go for dissection of the option string. Example uses:

GO_GCFLAGS=-d=ssa/generic_cse/time,ssa/generic_cse/stats,ssa/generic_cse/debug=3 ./make.bash

BOOT_GO_GCFLAGS=-d='ssa/~^.*scc$/off' GO_GCFLAGS='-d=ssa/~^.*scc$/off' ./make.bash

func ReachableBlocks

func ReachableBlocks(f *Func) []bool

ReachableBlocks returns the reachable blocks in f.

Types

type Block

type Block struct {
	// A unique identifier for the block. The system will attempt to allocate
	// these IDs densely, but no guarantees.
	ID ID

	// Source position for block's control operation
	Pos src.XPos

	// The kind of block this is.
	Kind BlockKind

	// Likely direction for branches.
	// If BranchLikely, Succs[0] is the most likely branch taken.
	// If BranchUnlikely, Succs[1] is the most likely branch taken.
	// Ignored if len(Succs) < 2.
	// Fatal if not BranchUnknown and len(Succs) > 2.
	Likely BranchPrediction

	// After flagalloc, records whether flags are live at the end of the block.
	FlagsLiveAtEnd bool

	// Subsequent blocks, if any. The number and order depend on the block kind.
	Succs []Edge

	// Inverse of successors.
	// The order is significant to Phi nodes in the block.
	// TODO: predecessors is a pain to maintain. Can we somehow order phi
	// arguments by block id and have this field computed explicitly when needed?
	Preds []Edge

	// A value that determines how the block is exited. Its value depends on the kind
	// of the block. For instance, a BlockIf has a boolean control value and BlockExit
	// has a memory control value.
	Control *Value

	// Auxiliary info for the block. Its value depends on the Kind.
	Aux interface{}

	// The unordered set of Values that define the operation of this block.
	// The list must include the control value, if any. (TODO: need this last condition?)
	// After the scheduling pass, this list is ordered.
	Values []*Value

	// The containing function
	Func *Func
	// contains filtered or unexported fields
}

Block represents a basic block in the control flow graph of a function.

func (*Block) AddEdgeTo

func (b *Block) AddEdgeTo(c *Block)

AddEdgeTo adds an edge from block b to block c. Used during building of the SSA graph; do not use on an already-completed SSA graph.

func (*Block) Fatalf

func (b *Block) Fatalf(msg string, args ...interface{})

func (*Block) HTML

func (b *Block) HTML() string

func (*Block) LackingPos

func (b *Block) LackingPos() bool

LackingPos indicates whether b is a block whose position should be inherited from its successors. This is true if all the values within it have unreliable positions and if it is "plain", meaning that there is no control flow that is also very likely to correspond to a well-understood source position.

func (*Block) Log

func (b *Block) Log() bool

func (*Block) Logf

func (b *Block) Logf(msg string, args ...interface{})

func (*Block) LongHTML

func (b *Block) LongHTML() string

func (*Block) LongString

func (b *Block) LongString() string

long form print

func (*Block) NewValue0

func (b *Block) NewValue0(pos src.XPos, op Op, t *types.Type) *Value

NewValue0 returns a new value in the block with no arguments and zero aux values.

func (*Block) NewValue0A

func (b *Block) NewValue0A(pos src.XPos, op Op, t *types.Type, aux interface{}) *Value

NewValue returns a new value in the block with no arguments and an aux value.

func (*Block) NewValue0I

func (b *Block) NewValue0I(pos src.XPos, op Op, t *types.Type, auxint int64) *Value

NewValue returns a new value in the block with no arguments and an auxint value.

func (*Block) NewValue0IA

func (b *Block) NewValue0IA(pos src.XPos, op Op, t *types.Type, auxint int64, aux interface{}) *Value

NewValue returns a new value in the block with no arguments and both an auxint and aux values.

func (*Block) NewValue1

func (b *Block) NewValue1(pos src.XPos, op Op, t *types.Type, arg *Value) *Value

NewValue1 returns a new value in the block with one argument and zero aux values.

func (*Block) NewValue1A

func (b *Block) NewValue1A(pos src.XPos, op Op, t *types.Type, aux interface{}, arg *Value) *Value

NewValue1A returns a new value in the block with one argument and an aux value.

func (*Block) NewValue1I

func (b *Block) NewValue1I(pos src.XPos, op Op, t *types.Type, auxint int64, arg *Value) *Value

NewValue1I returns a new value in the block with one argument and an auxint value.

func (*Block) NewValue1IA

func (b *Block) NewValue1IA(pos src.XPos, op Op, t *types.Type, auxint int64, aux interface{}, arg *Value) *Value

NewValue1IA returns a new value in the block with one argument and both an auxint and aux values.

func (*Block) NewValue2

func (b *Block) NewValue2(pos src.XPos, op Op, t *types.Type, arg0, arg1 *Value) *Value

NewValue2 returns a new value in the block with two arguments and zero aux values.

func (*Block) NewValue2A

func (b *Block) NewValue2A(pos src.XPos, op Op, t *types.Type, aux interface{}, arg0, arg1 *Value) *Value

NewValue2A returns a new value in the block with two arguments and one aux values.

func (*Block) NewValue2I

func (b *Block) NewValue2I(pos src.XPos, op Op, t *types.Type, auxint int64, arg0, arg1 *Value) *Value

NewValue2I returns a new value in the block with two arguments and an auxint value.

func (*Block) NewValue2IA

func (b *Block) NewValue2IA(pos src.XPos, op Op, t *types.Type, auxint int64, aux interface{}, arg0, arg1 *Value) *Value

NewValue2IA returns a new value in the block with two arguments and both an auxint and aux values.

func (*Block) NewValue3

func (b *Block) NewValue3(pos src.XPos, op Op, t *types.Type, arg0, arg1, arg2 *Value) *Value

NewValue3 returns a new value in the block with three arguments and zero aux values.

func (*Block) NewValue3A

func (b *Block) NewValue3A(pos src.XPos, op Op, t *types.Type, aux interface{}, arg0, arg1, arg2 *Value) *Value

NewValue3A returns a new value in the block with three argument and an aux value.

func (*Block) NewValue3I

func (b *Block) NewValue3I(pos src.XPos, op Op, t *types.Type, auxint int64, arg0, arg1, arg2 *Value) *Value

NewValue3I returns a new value in the block with three arguments and an auxint value.

func (*Block) NewValue4

func (b *Block) NewValue4(pos src.XPos, op Op, t *types.Type, arg0, arg1, arg2, arg3 *Value) *Value

NewValue4 returns a new value in the block with four arguments and zero aux values.

func (*Block) SetControl

func (b *Block) SetControl(v *Value)

func (*Block) String

func (b *Block) String() string

short form print

type BlockDebug

type BlockDebug struct {
	// contains filtered or unexported fields
}

type BlockKind

type BlockKind int8
kind           control    successors

------------------------------------------

 Exit        return mem                []
Plain               nil            [next]
   If   a boolean Value      [then, else]
Defer               mem  [nopanic, panic]  (control opcode should be OpStaticCall to runtime.deferproc)
const (
	BlockInvalid BlockKind = iota

	Block386EQ
	Block386NE
	Block386LT
	Block386LE
	Block386GT
	Block386GE
	Block386OS
	Block386OC
	Block386ULT
	Block386ULE
	Block386UGT
	Block386UGE
	Block386EQF
	Block386NEF
	Block386ORD
	Block386NAN

	BlockAMD64EQ
	BlockAMD64NE
	BlockAMD64LT
	BlockAMD64LE
	BlockAMD64GT
	BlockAMD64GE
	BlockAMD64OS
	BlockAMD64OC
	BlockAMD64ULT
	BlockAMD64ULE
	BlockAMD64UGT
	BlockAMD64UGE
	BlockAMD64EQF
	BlockAMD64NEF
	BlockAMD64ORD
	BlockAMD64NAN

	BlockARMEQ
	BlockARMNE
	BlockARMLT
	BlockARMLE
	BlockARMGT
	BlockARMGE
	BlockARMULT
	BlockARMULE
	BlockARMUGT
	BlockARMUGE

	BlockARM64EQ
	BlockARM64NE
	BlockARM64LT
	BlockARM64LE
	BlockARM64GT
	BlockARM64GE
	BlockARM64ULT
	BlockARM64ULE
	BlockARM64UGT
	BlockARM64UGE
	BlockARM64Z
	BlockARM64NZ
	BlockARM64ZW
	BlockARM64NZW
	BlockARM64TBZ
	BlockARM64TBNZ

	BlockMIPSEQ
	BlockMIPSNE
	BlockMIPSLTZ
	BlockMIPSLEZ
	BlockMIPSGTZ
	BlockMIPSGEZ
	BlockMIPSFPT
	BlockMIPSFPF

	BlockMIPS64EQ
	BlockMIPS64NE
	BlockMIPS64LTZ
	BlockMIPS64LEZ
	BlockMIPS64GTZ
	BlockMIPS64GEZ
	BlockMIPS64FPT
	BlockMIPS64FPF

	BlockPPC64EQ
	BlockPPC64NE
	BlockPPC64LT
	BlockPPC64LE
	BlockPPC64GT
	BlockPPC64GE
	BlockPPC64FLT
	BlockPPC64FLE
	BlockPPC64FGT
	BlockPPC64FGE

	BlockS390XEQ
	BlockS390XNE
	BlockS390XLT
	BlockS390XLE
	BlockS390XGT
	BlockS390XGE
	BlockS390XGTF
	BlockS390XGEF

	BlockPlain
	BlockIf
	BlockDefer
	BlockRet
	BlockRetJmp
	BlockExit
	BlockFirst
)

func (BlockKind) String

func (k BlockKind) String() string

type BranchPrediction

type BranchPrediction int8

type ByTopo

type ByTopo []*FuncLines

ByTopo sorts topologically: target function is on top, followed by inlined functions sorted by filename and line numbers.

func (ByTopo) Len

func (x ByTopo) Len() int

func (ByTopo) Less

func (x ByTopo) Less(i, j int) bool

func (ByTopo) Swap

func (x ByTopo) Swap(i, j int)

type Cache

type Cache struct {
	ValueToProgAfter []*obj.Prog

	Liveness interface{} // *gc.livenessFuncCache
	// contains filtered or unexported fields
}

A Cache holds reusable compiler state. It is intended to be re-used for multiple Func compilations.

func (*Cache) Reset

func (c *Cache) Reset()

type Config

type Config struct {
	PtrSize int64 // 4 or 8; copy of cmd/internal/sys.Arch.PtrSize
	RegSize int64 // 4 or 8; copy of cmd/internal/sys.Arch.RegSize
	Types   Types

	GCRegMap []*Register // garbage collector register map, by GC register index
	FPReg    int8        // register number of frame pointer, -1 if not used
	LinkReg  int8        // register number of link register if it is a general purpose register, -1 if not used

	SoftFloat      bool //
	Race           bool // race detector enabled
	NeedsFpScratch bool // No direct move between GP and FP register sets
	BigEndian      bool //
	// contains filtered or unexported fields
}

A Config holds readonly compilation information. It is created once, early during compilation, and shared across all compilations.

func NewConfig

func NewConfig(arch string, types Types, ctxt *obj.Link, optimize bool) *Config

NewConfig returns a new configuration object for the given architecture.

func (*Config) Ctxt

func (c *Config) Ctxt() *obj.Link

func (*Config) Set387

func (c *Config) Set387(b bool)

type Edge

type Edge struct {
	// contains filtered or unexported fields
}

Edge represents a CFG edge. Example edges for b branching to either c or d. (c and d have other predecessors.)

b.Succs = [{c,3}, {d,1}]
c.Preds = [?, ?, ?, {b,0}]
d.Preds = [?, {b,1}, ?]

These indexes allow us to edit the CFG in constant time. In addition, it informs phi ops in degenerate cases like: b:

if k then c else c

c:

v = Phi(x, y)

Then the indexes tell you whether x is chosen from the if or else branch from b.

b.Succs = [{c,0},{c,1}]
c.Preds = [{b,0},{b,1}]

means x is chosen if k is true.

func (Edge) Block

func (e Edge) Block() *Block

func (Edge) Index

func (e Edge) Index() int

type Frontend

type Frontend interface {
	CanSSA(t *types.Type) bool

	Logger

	// StringData returns a symbol pointing to the given string's contents.
	StringData(string) interface{} // returns *gc.Sym

	// Auto returns a Node for an auto variable of the given type.
	// The SSA compiler uses this function to allocate space for spills.
	Auto(src.XPos, *types.Type) GCNode

	// Given the name for a compound type, returns the name we should use
	// for the parts of that compound type.
	SplitString(LocalSlot) (LocalSlot, LocalSlot)
	SplitInterface(LocalSlot) (LocalSlot, LocalSlot)
	SplitSlice(LocalSlot) (LocalSlot, LocalSlot, LocalSlot)
	SplitComplex(LocalSlot) (LocalSlot, LocalSlot)
	SplitStruct(LocalSlot, int) LocalSlot
	SplitArray(LocalSlot) LocalSlot              // array must be length 1
	SplitInt64(LocalSlot) (LocalSlot, LocalSlot) // returns (hi, lo)

	// DerefItab dereferences an itab function
	// entry, given the symbol of the itab and
	// the byte offset of the function pointer.
	// It may return nil.
	DerefItab(sym *obj.LSym, offset int64) *obj.LSym

	// Line returns a string describing the given position.
	Line(src.XPos) string

	// AllocFrame assigns frame offsets to all live auto variables.
	AllocFrame(f *Func)

	// Syslook returns a symbol of the runtime function/variable with the
	// given name.
	Syslook(string) *obj.LSym

	// UseWriteBarrier reports whether write barrier is enabled
	UseWriteBarrier() bool

	// SetWBPos indicates that a write barrier has been inserted
	// in this function at position pos.
	SetWBPos(pos src.XPos)
}

type Func

type Func struct {
	Config *Config // architecture information
	Cache  *Cache  // re-usable cache

	Name   string      // e.g. NewFunc or (*Func).NumBlocks (no package prefix)
	Type   *types.Type // type signature of the function.
	Blocks []*Block    // unordered set of all basic blocks (note: not indexable by ID)
	Entry  *Block      // the entry basic block

	HTMLWriter     *HTMLWriter // html writer, for debugging
	DebugTest      bool        // default true unless $GOSSAHASH != ""; as a debugging aid, make new code conditional on this and use GOSSAHASH to binary search for failing cases
	PrintOrHtmlSSA bool        // true if GOSSAFUNC matches, true even if fe.Log() (spew phase results to stdout) is false.

	NoSplit bool // true if function is marked as nosplit.  Used by schedule check pass.

	// when register allocation is done, maps value ids to locations
	RegAlloc []Location

	// map from LocalSlot to set of Values that we want to store in that slot.
	NamedValues map[LocalSlot][]*Value
	// Names is a copy of NamedValues.Keys. We keep a separate list
	// of keys to make iteration order deterministic.
	Names []LocalSlot

	// WBLoads is a list of Blocks that branch on the write
	// barrier flag. Safe-points are disabled from the OpLoad that
	// reads the write-barrier flag until the control flow rejoins
	// below the two successors of this block.
	WBLoads []*Block
	// contains filtered or unexported fields
}

A Func represents a Go func declaration (or function literal) and its body. This package compiles each Func independently. Funcs are single-use; a new Func must be created for every compiled function.

func NewFunc

func NewFunc(fe Frontend) *Func

NewFunc returns a new, empty function object. Caller must set f.Config and f.Cache before using f.

func (*Func) ConstBool

func (f *Func) ConstBool(t *types.Type, c bool) *Value

ConstInt returns an int constant representing its argument.

func (*Func) ConstEmptyString

func (f *Func) ConstEmptyString(t *types.Type) *Value

func (*Func) ConstFloat32

func (f *Func) ConstFloat32(t *types.Type, c float64) *Value

func (*Func) ConstFloat64

func (f *Func) ConstFloat64(t *types.Type, c float64) *Value

func (*Func) ConstInt16

func (f *Func) ConstInt16(t *types.Type, c int16) *Value

func (*Func) ConstInt32

func (f *Func) ConstInt32(t *types.Type, c int32) *Value

func (*Func) ConstInt64

func (f *Func) ConstInt64(t *types.Type, c int64) *Value

func (*Func) ConstInt8

func (f *Func) ConstInt8(t *types.Type, c int8) *Value

func (*Func) ConstInterface

func (f *Func) ConstInterface(t *types.Type) *Value

func (*Func) ConstNil

func (f *Func) ConstNil(t *types.Type) *Value

func (*Func) ConstOffPtrSP

func (f *Func) ConstOffPtrSP(t *types.Type, c int64, sp *Value) *Value

func (*Func) ConstSlice

func (f *Func) ConstSlice(t *types.Type) *Value

func (*Func) DebugHashMatch

func (f *Func) DebugHashMatch(evname, name string) bool

DebugHashMatch reports whether environment variable evname

  1. is empty (this is a special more-quickly implemented case of 3)
  2. is "y" or "Y"
  3. is a suffix of the sha1 hash of name
  4. is a suffix of the environment variable fmt.Sprintf("%s%d", evname, n) provided that all such variables are nonempty for 0 <= i <= n

Otherwise it returns false. When true is returned the message

"%s triggered %s\n", evname, name

is printed on the file named in environment variable

GSHS_LOGFILE

or standard out if that is empty or there is an error opening the file.

func (*Func) Fatalf

func (f *Func) Fatalf(msg string, args ...interface{})

func (*Func) Frontend

func (f *Func) Frontend() Frontend

func (*Func) HTML

func (f *Func) HTML(phase string, dot *dotWriter) string

func (*Func) Idom

func (f *Func) Idom() []*Block

Idom returns a map from block ID to the immediate dominator of that block. f.Entry.ID maps to nil. Unreachable blocks map to nil as well.

func (*Func) Log

func (f *Func) Log() bool

func (*Func) LogStat

func (f *Func) LogStat(key string, args ...interface{})

logPassStat writes a string key and int value as a warning in a tab-separated format easily handled by spreadsheets or awk. file names, lines, and function names are included to provide enough (?) context to allow item-by-item comparisons across runs. For example: awk 'BEGIN {FS="\t"} $3~/TIME/{sum+=$4} END{print "t(ns)=",sum}' t.log

func (*Func) Logf

func (f *Func) Logf(msg string, args ...interface{})

func (*Func) NewBlock

func (f *Func) NewBlock(kind BlockKind) *Block

newBlock allocates a new Block of the given kind and places it at the end of f.Blocks.

func (*Func) NumBlocks

func (f *Func) NumBlocks() int

NumBlocks returns an integer larger than the id of any Block in the Func.

func (*Func) NumValues

func (f *Func) NumValues() int

NumValues returns an integer larger than the id of any Value in the Func.

func (*Func) Postorder

func (f *Func) Postorder() []*Block

func (*Func) String

func (f *Func) String() string

func (*Func) Warnl

func (f *Func) Warnl(pos src.XPos, msg string, args ...interface{})

type FuncDebug

type FuncDebug struct {
	// Slots is all the slots used in the debug info, indexed by their SlotID.
	Slots []LocalSlot
	// The user variables, indexed by VarID.
	Vars []GCNode
	// The slots that make up each variable, indexed by VarID.
	VarSlots [][]SlotID
	// The location list data, indexed by VarID. Must be processed by PutLocationList.
	LocationLists [][]byte

	// Filled in by the user. Translates Block and Value ID to PC.
	GetPC func(ID, ID) int64
}

A FuncDebug contains all the debug information for the variables in a function. Variables are identified by their LocalSlot, which may be the result of decomposing a larger variable.

func BuildFuncDebug

func BuildFuncDebug(ctxt *obj.Link, f *Func, loggingEnabled bool, stackOffset func(LocalSlot) int32) *FuncDebug

BuildFuncDebug returns debug information for f. f must be fully processed, so that each Value is where it will be when machine code is emitted.

func (*FuncDebug) PutLocationList

func (debugInfo *FuncDebug) PutLocationList(list []byte, ctxt *obj.Link, listSym, startPC *obj.LSym)

PutLocationList adds list (a location list in its intermediate representation) to listSym.

type FuncLines

type FuncLines struct {
	Filename    string
	StartLineno uint
	Lines       []string
}

FuncLines contains source code for a function to be displayed in sources column.

type GCNode

type GCNode interface {
	Typ() *types.Type
	String() string
	IsSynthetic() bool
	IsAutoTmp() bool
	StorageClass() StorageClass
}

interface used to hold a *gc.Node (a stack variable). We'd use *gc.Node directly but that would lead to an import cycle.

type HTMLWriter

type HTMLWriter struct {
	Logger
	// contains filtered or unexported fields
}

func NewHTMLWriter

func NewHTMLWriter(path string, logger Logger, funcname, cfgMask string) *HTMLWriter

func (*HTMLWriter) Close

func (w *HTMLWriter) Close()

func (*HTMLWriter) Printf

func (w *HTMLWriter) Printf(msg string, v ...interface{})

func (*HTMLWriter) WriteAST

func (w *HTMLWriter) WriteAST(phase string, buf *bytes.Buffer)

func (*HTMLWriter) WriteColumn

func (w *HTMLWriter) WriteColumn(phase, title, class, html string)

WriteColumn writes raw HTML in a column headed by title. It is intended for pre- and post-compilation log output.

func (*HTMLWriter) WriteFunc

func (w *HTMLWriter) WriteFunc(phase, title string, f *Func)

WriteFunc writes f in a column headed by title. phase is used for collapsing columns and should be unique across the table.

func (*HTMLWriter) WriteSources

func (w *HTMLWriter) WriteSources(phase string, all []*FuncLines)

WriteSources writes lines as source code in a column headed by title. phase is used for collapsing columns and should be unique across the table.

func (*HTMLWriter) WriteString

func (w *HTMLWriter) WriteString(s string)

type ID

type ID int32

type LocPair

type LocPair [2]Location

func (LocPair) String

func (t LocPair) String() string

type LocalSlot

type LocalSlot struct {
	N    GCNode      // an ONAME *gc.Node representing a stack location.
	Type *types.Type // type of slot
	Off  int64       // offset of slot in N

	SplitOf     *LocalSlot // slot is a decomposition of SplitOf
	SplitOffset int64      // .. at this offset.
}

A LocalSlot is a location in the stack frame, which identifies and stores part or all of a PPARAM, PPARAMOUT, or PAUTO ONAME node. It can represent a whole variable, part of a larger stack slot, or part of a variable that has been decomposed into multiple stack slots. As an example, a string could have the following configurations:

stack layout              LocalSlots

Optimizations are disabled. s is on the stack and represented in its entirety. [ ------- s string ---- ] { N: s, Type: string, Off: 0 }

s was not decomposed, but the SSA operates on its parts individually, so there is a LocalSlot for each of its fields that points into the single stack slot. [ ------- s string ---- ] { N: s, Type: *uint8, Off: 0 }, {N: s, Type: int, Off: 8}

s was decomposed. Each of its fields is in its own stack slot and has its own LocalSLot. [ ptr *uint8 ] [ len int] { N: ptr, Type: *uint8, Off: 0, SplitOf: parent, SplitOffset: 0},

{ N: len, Type: int, Off: 0, SplitOf: parent, SplitOffset: 8}
parent = &{N: s, Type: string}

func (LocalSlot) String

func (s LocalSlot) String() string

type Location

type Location interface {
	String() string // name to use in assembly templates: AX, 16(SP), ...
}

A place that an ssa variable can reside.

type Logger

type Logger interface {
	// Logf logs a message from the compiler.
	Logf(string, ...interface{})

	// Log reports whether logging is not a no-op
	// some logging calls account for more than a few heap allocations.
	Log() bool

	// Fatal reports a compiler error and exits.
	Fatalf(pos src.XPos, msg string, args ...interface{})

	// Warnl writes compiler messages in the form expected by "errorcheck" tests
	Warnl(pos src.XPos, fmt_ string, args ...interface{})

	// Forwards the Debug flags from gc
	Debug_checknil() bool
}

type Op

type Op int32

An Op encodes the specific operation that a Value performs. Opcodes' semantics can be modified by the type and aux fields of the Value. For instance, OpAdd can be 32 or 64 bit, signed or unsigned, float or complex, depending on Value.Type. Semantics of each op are described in the opcode files in gen/*Ops.go. There is one file for generic (architecture-independent) ops and one file for each architecture.

const (
	OpInvalid Op = iota

	Op386ADDSS
	Op386ADDSD
	Op386SUBSS
	Op386SUBSD
	Op386MULSS
	Op386MULSD
	Op386DIVSS
	Op386DIVSD
	Op386MOVSSload
	Op386MOVSDload
	Op386MOVSSconst
	Op386MOVSDconst
	Op386MOVSSloadidx1
	Op386MOVSSloadidx4
	Op386MOVSDloadidx1
	Op386MOVSDloadidx8
	Op386MOVSSstore
	Op386MOVSDstore
	Op386MOVSSstoreidx1
	Op386MOVSSstoreidx4
	Op386MOVSDstoreidx1
	Op386MOVSDstoreidx8
	Op386ADDSSload
	Op386ADDSDload
	Op386SUBSSload
	Op386SUBSDload
	Op386MULSSload
	Op386MULSDload
	Op386DIVSSload
	Op386DIVSDload
	Op386ADDL
	Op386ADDLconst
	Op386ADDLcarry
	Op386ADDLconstcarry
	Op386ADCL
	Op386ADCLconst
	Op386SUBL
	Op386SUBLconst
	Op386SUBLcarry
	Op386SUBLconstcarry
	Op386SBBL
	Op386SBBLconst
	Op386MULL
	Op386MULLconst
	Op386MULLU
	Op386HMULL
	Op386HMULLU
	Op386MULLQU
	Op386AVGLU
	Op386DIVL
	Op386DIVW
	Op386DIVLU
	Op386DIVWU
	Op386MODL
	Op386MODW
	Op386MODLU
	Op386MODWU
	Op386ANDL
	Op386ANDLconst
	Op386ORL
	Op386ORLconst
	Op386XORL
	Op386XORLconst
	Op386CMPL
	Op386CMPW
	Op386CMPB
	Op386CMPLconst
	Op386CMPWconst
	Op386CMPBconst
	Op386CMPLload
	Op386CMPWload
	Op386CMPBload
	Op386CMPLconstload
	Op386CMPWconstload
	Op386CMPBconstload
	Op386UCOMISS
	Op386UCOMISD
	Op386TESTL
	Op386TESTW
	Op386TESTB
	Op386TESTLconst
	Op386TESTWconst
	Op386TESTBconst
	Op386SHLL
	Op386SHLLconst
	Op386SHRL
	Op386SHRW
	Op386SHRB
	Op386SHRLconst
	Op386SHRWconst
	Op386SHRBconst
	Op386SARL
	Op386SARW
	Op386SARB
	Op386SARLconst
	Op386SARWconst
	Op386SARBconst
	Op386ROLLconst
	Op386ROLWconst
	Op386ROLBconst
	Op386ADDLload
	Op386SUBLload
	Op386MULLload
	Op386ANDLload
	Op386ORLload
	Op386XORLload
	Op386ADDLloadidx4
	Op386SUBLloadidx4
	Op386MULLloadidx4
	Op386ANDLloadidx4
	Op386ORLloadidx4
	Op386XORLloadidx4
	Op386NEGL
	Op386NOTL
	Op386BSFL
	Op386BSFW
	Op386BSRL
	Op386BSRW
	Op386BSWAPL
	Op386SQRTSD
	Op386SBBLcarrymask
	Op386SETEQ
	Op386SETNE
	Op386SETL
	Op386SETLE
	Op386SETG
	Op386SETGE
	Op386SETB
	Op386SETBE
	Op386SETA
	Op386SETAE
	Op386SETO
	Op386SETEQF
	Op386SETNEF
	Op386SETORD
	Op386SETNAN
	Op386SETGF
	Op386SETGEF
	Op386MOVBLSX
	Op386MOVBLZX
	Op386MOVWLSX
	Op386MOVWLZX
	Op386MOVLconst
	Op386CVTTSD2SL
	Op386CVTTSS2SL
	Op386CVTSL2SS
	Op386CVTSL2SD
	Op386CVTSD2SS
	Op386CVTSS2SD
	Op386PXOR
	Op386LEAL
	Op386LEAL1
	Op386LEAL2
	Op386LEAL4
	Op386LEAL8
	Op386MOVBload
	Op386MOVBLSXload
	Op386MOVWload
	Op386MOVWLSXload
	Op386MOVLload
	Op386MOVBstore
	Op386MOVWstore
	Op386MOVLstore
	Op386ADDLmodify
	Op386SUBLmodify
	Op386ANDLmodify
	Op386ORLmodify
	Op386XORLmodify
	Op386ADDLmodifyidx4
	Op386SUBLmodifyidx4
	Op386ANDLmodifyidx4
	Op386ORLmodifyidx4
	Op386XORLmodifyidx4
	Op386ADDLconstmodify
	Op386ANDLconstmodify
	Op386ORLconstmodify
	Op386XORLconstmodify
	Op386ADDLconstmodifyidx4
	Op386ANDLconstmodifyidx4
	Op386ORLconstmodifyidx4
	Op386XORLconstmodifyidx4
	Op386MOVBloadidx1
	Op386MOVWloadidx1
	Op386MOVWloadidx2
	Op386MOVLloadidx1
	Op386MOVLloadidx4
	Op386MOVBstoreidx1
	Op386MOVWstoreidx1
	Op386MOVWstoreidx2
	Op386MOVLstoreidx1
	Op386MOVLstoreidx4
	Op386MOVBstoreconst
	Op386MOVWstoreconst
	Op386MOVLstoreconst
	Op386MOVBstoreconstidx1
	Op386MOVWstoreconstidx1
	Op386MOVWstoreconstidx2
	Op386MOVLstoreconstidx1
	Op386MOVLstoreconstidx4
	Op386DUFFZERO
	Op386REPSTOSL
	Op386CALLstatic
	Op386CALLclosure
	Op386CALLinter
	Op386DUFFCOPY
	Op386REPMOVSL
	Op386InvertFlags
	Op386LoweredGetG
	Op386LoweredGetClosurePtr
	Op386LoweredGetCallerPC
	Op386LoweredGetCallerSP
	Op386LoweredNilCheck
	Op386LoweredWB
	Op386FlagEQ
	Op386FlagLT_ULT
	Op386FlagLT_UGT
	Op386FlagGT_UGT
	Op386FlagGT_ULT
	Op386FCHS
	Op386MOVSSconst1
	Op386MOVSDconst1
	Op386MOVSSconst2
	Op386MOVSDconst2

	OpAMD64ADDSS
	OpAMD64ADDSD
	OpAMD64SUBSS
	OpAMD64SUBSD
	OpAMD64MULSS
	OpAMD64MULSD
	OpAMD64DIVSS
	OpAMD64DIVSD
	OpAMD64MOVSSload
	OpAMD64MOVSDload
	OpAMD64MOVSSconst
	OpAMD64MOVSDconst
	OpAMD64MOVSSloadidx1
	OpAMD64MOVSSloadidx4
	OpAMD64MOVSDloadidx1
	OpAMD64MOVSDloadidx8
	OpAMD64MOVSSstore
	OpAMD64MOVSDstore
	OpAMD64MOVSSstoreidx1
	OpAMD64MOVSSstoreidx4
	OpAMD64MOVSDstoreidx1
	OpAMD64MOVSDstoreidx8
	OpAMD64ADDSSload
	OpAMD64ADDSDload
	OpAMD64SUBSSload
	OpAMD64SUBSDload
	OpAMD64MULSSload
	OpAMD64MULSDload
	OpAMD64DIVSSload
	OpAMD64DIVSDload
	OpAMD64ADDQ
	OpAMD64ADDL
	OpAMD64ADDQconst
	OpAMD64ADDLconst
	OpAMD64ADDQconstmodify
	OpAMD64ADDLconstmodify
	OpAMD64SUBQ
	OpAMD64SUBL
	OpAMD64SUBQconst
	OpAMD64SUBLconst
	OpAMD64MULQ
	OpAMD64MULL
	OpAMD64MULQconst
	OpAMD64MULLconst
	OpAMD64MULLU
	OpAMD64MULQU
	OpAMD64HMULQ
	OpAMD64HMULL
	OpAMD64HMULQU
	OpAMD64HMULLU
	OpAMD64AVGQU
	OpAMD64DIVQ
	OpAMD64DIVL
	OpAMD64DIVW
	OpAMD64DIVQU
	OpAMD64DIVLU
	OpAMD64DIVWU
	OpAMD64NEGLflags
	OpAMD64ADDQcarry
	OpAMD64ADCQ
	OpAMD64ADDQconstcarry
	OpAMD64ADCQconst
	OpAMD64SUBQborrow
	OpAMD64SBBQ
	OpAMD64SUBQconstborrow
	OpAMD64SBBQconst
	OpAMD64MULQU2
	OpAMD64DIVQU2
	OpAMD64ANDQ
	OpAMD64ANDL
	OpAMD64ANDQconst
	OpAMD64ANDLconst
	OpAMD64ANDQconstmodify
	OpAMD64ANDLconstmodify
	OpAMD64ORQ
	OpAMD64ORL
	OpAMD64ORQconst
	OpAMD64ORLconst
	OpAMD64ORQconstmodify
	OpAMD64ORLconstmodify
	OpAMD64XORQ
	OpAMD64XORL
	OpAMD64XORQconst
	OpAMD64XORLconst
	OpAMD64XORQconstmodify
	OpAMD64XORLconstmodify
	OpAMD64CMPQ
	OpAMD64CMPL
	OpAMD64CMPW
	OpAMD64CMPB
	OpAMD64CMPQconst
	OpAMD64CMPLconst
	OpAMD64CMPWconst
	OpAMD64CMPBconst
	OpAMD64CMPQload
	OpAMD64CMPLload
	OpAMD64CMPWload
	OpAMD64CMPBload
	OpAMD64CMPQconstload
	OpAMD64CMPLconstload
	OpAMD64CMPWconstload
	OpAMD64CMPBconstload
	OpAMD64UCOMISS
	OpAMD64UCOMISD
	OpAMD64BTL
	OpAMD64BTQ
	OpAMD64BTCL
	OpAMD64BTCQ
	OpAMD64BTRL
	OpAMD64BTRQ
	OpAMD64BTSL
	OpAMD64BTSQ
	OpAMD64BTLconst
	OpAMD64BTQconst
	OpAMD64BTCLconst
	OpAMD64BTCQconst
	OpAMD64BTRLconst
	OpAMD64BTRQconst
	OpAMD64BTSLconst
	OpAMD64BTSQconst
	OpAMD64BTCQmodify
	OpAMD64BTCLmodify
	OpAMD64BTSQmodify
	OpAMD64BTSLmodify
	OpAMD64BTRQmodify
	OpAMD64BTRLmodify
	OpAMD64BTCQconstmodify
	OpAMD64BTCLconstmodify
	OpAMD64BTSQconstmodify
	OpAMD64BTSLconstmodify
	OpAMD64BTRQconstmodify
	OpAMD64BTRLconstmodify
	OpAMD64TESTQ
	OpAMD64TESTL
	OpAMD64TESTW
	OpAMD64TESTB
	OpAMD64TESTQconst
	OpAMD64TESTLconst
	OpAMD64TESTWconst
	OpAMD64TESTBconst
	OpAMD64SHLQ
	OpAMD64SHLL
	OpAMD64SHLQconst
	OpAMD64SHLLconst
	OpAMD64SHRQ
	OpAMD64SHRL
	OpAMD64SHRW
	OpAMD64SHRB
	OpAMD64SHRQconst
	OpAMD64SHRLconst
	OpAMD64SHRWconst
	OpAMD64SHRBconst
	OpAMD64SARQ
	OpAMD64SARL
	OpAMD64SARW
	OpAMD64SARB
	OpAMD64SARQconst
	OpAMD64SARLconst
	OpAMD64SARWconst
	OpAMD64SARBconst
	OpAMD64ROLQ
	OpAMD64ROLL
	OpAMD64ROLW
	OpAMD64ROLB
	OpAMD64RORQ
	OpAMD64RORL
	OpAMD64RORW
	OpAMD64RORB
	OpAMD64ROLQconst
	OpAMD64ROLLconst
	OpAMD64ROLWconst
	OpAMD64ROLBconst
	OpAMD64ADDLload
	OpAMD64ADDQload
	OpAMD64SUBQload
	OpAMD64SUBLload
	OpAMD64ANDLload
	OpAMD64ANDQload
	OpAMD64ORQload
	OpAMD64ORLload
	OpAMD64XORQload
	OpAMD64XORLload
	OpAMD64ADDQmodify
	OpAMD64SUBQmodify
	OpAMD64ANDQmodify
	OpAMD64ORQmodify
	OpAMD64XORQmodify
	OpAMD64ADDLmodify
	OpAMD64SUBLmodify
	OpAMD64ANDLmodify
	OpAMD64ORLmodify
	OpAMD64XORLmodify
	OpAMD64NEGQ
	OpAMD64NEGL
	OpAMD64NOTQ
	OpAMD64NOTL
	OpAMD64BSFQ
	OpAMD64BSFL
	OpAMD64BSRQ
	OpAMD64BSRL
	OpAMD64CMOVQEQ
	OpAMD64CMOVQNE
	OpAMD64CMOVQLT
	OpAMD64CMOVQGT
	OpAMD64CMOVQLE
	OpAMD64CMOVQGE
	OpAMD64CMOVQLS
	OpAMD64CMOVQHI
	OpAMD64CMOVQCC
	OpAMD64CMOVQCS
	OpAMD64CMOVLEQ
	OpAMD64CMOVLNE
	OpAMD64CMOVLLT
	OpAMD64CMOVLGT
	OpAMD64CMOVLLE
	OpAMD64CMOVLGE
	OpAMD64CMOVLLS
	OpAMD64CMOVLHI
	OpAMD64CMOVLCC
	OpAMD64CMOVLCS
	OpAMD64CMOVWEQ
	OpAMD64CMOVWNE
	OpAMD64CMOVWLT
	OpAMD64CMOVWGT
	OpAMD64CMOVWLE
	OpAMD64CMOVWGE
	OpAMD64CMOVWLS
	OpAMD64CMOVWHI
	OpAMD64CMOVWCC
	OpAMD64CMOVWCS
	OpAMD64CMOVQEQF
	OpAMD64CMOVQNEF
	OpAMD64CMOVQGTF
	OpAMD64CMOVQGEF
	OpAMD64CMOVLEQF
	OpAMD64CMOVLNEF
	OpAMD64CMOVLGTF
	OpAMD64CMOVLGEF
	OpAMD64CMOVWEQF
	OpAMD64CMOVWNEF
	OpAMD64CMOVWGTF
	OpAMD64CMOVWGEF
	OpAMD64BSWAPQ
	OpAMD64BSWAPL
	OpAMD64POPCNTQ
	OpAMD64POPCNTL
	OpAMD64SQRTSD
	OpAMD64ROUNDSD
	OpAMD64SBBQcarrymask
	OpAMD64SBBLcarrymask
	OpAMD64SETEQ
	OpAMD64SETNE
	OpAMD64SETL
	OpAMD64SETLE
	OpAMD64SETG
	OpAMD64SETGE
	OpAMD64SETB
	OpAMD64SETBE
	OpAMD64SETA
	OpAMD64SETAE
	OpAMD64SETO
	OpAMD64SETEQstore
	OpAMD64SETNEstore
	OpAMD64SETLstore
	OpAMD64SETLEstore
	OpAMD64SETGstore
	OpAMD64SETGEstore
	OpAMD64SETBstore
	OpAMD64SETBEstore
	OpAMD64SETAstore
	OpAMD64SETAEstore
	OpAMD64SETEQF
	OpAMD64SETNEF
	OpAMD64SETORD
	OpAMD64SETNAN
	OpAMD64SETGF
	OpAMD64SETGEF
	OpAMD64MOVBQSX
	OpAMD64MOVBQZX
	OpAMD64MOVWQSX
	OpAMD64MOVWQZX
	OpAMD64MOVLQSX
	OpAMD64MOVLQZX
	OpAMD64MOVLconst
	OpAMD64MOVQconst
	OpAMD64CVTTSD2SL
	OpAMD64CVTTSD2SQ
	OpAMD64CVTTSS2SL
	OpAMD64CVTTSS2SQ
	OpAMD64CVTSL2SS
	OpAMD64CVTSL2SD
	OpAMD64CVTSQ2SS
	OpAMD64CVTSQ2SD
	OpAMD64CVTSD2SS
	OpAMD64CVTSS2SD
	OpAMD64MOVQi2f
	OpAMD64MOVQf2i
	OpAMD64MOVLi2f
	OpAMD64MOVLf2i
	OpAMD64PXOR
	OpAMD64LEAQ
	OpAMD64LEAL
	OpAMD64LEAW
	OpAMD64LEAQ1
	OpAMD64LEAL1
	OpAMD64LEAW1
	OpAMD64LEAQ2
	OpAMD64LEAL2
	OpAMD64LEAW2
	OpAMD64LEAQ4
	OpAMD64LEAL4
	OpAMD64LEAW4
	OpAMD64LEAQ8
	OpAMD64LEAL8
	OpAMD64LEAW8
	OpAMD64MOVBload
	OpAMD64MOVBQSXload
	OpAMD64MOVWload
	OpAMD64MOVWQSXload
	OpAMD64MOVLload
	OpAMD64MOVLQSXload
	OpAMD64MOVQload
	OpAMD64MOVBstore
	OpAMD64MOVWstore
	OpAMD64MOVLstore
	OpAMD64MOVQstore
	OpAMD64MOVOload
	OpAMD64MOVOstore
	OpAMD64MOVBloadidx1
	OpAMD64MOVWloadidx1
	OpAMD64MOVWloadidx2
	OpAMD64MOVLloadidx1
	OpAMD64MOVLloadidx4
	OpAMD64MOVLloadidx8
	OpAMD64MOVQloadidx1
	OpAMD64MOVQloadidx8
	OpAMD64MOVBstoreidx1
	OpAMD64MOVWstoreidx1
	OpAMD64MOVWstoreidx2
	OpAMD64MOVLstoreidx1
	OpAMD64MOVLstoreidx4
	OpAMD64MOVLstoreidx8
	OpAMD64MOVQstoreidx1
	OpAMD64MOVQstoreidx8
	OpAMD64MOVBstoreconst
	OpAMD64MOVWstoreconst
	OpAMD64MOVLstoreconst
	OpAMD64MOVQstoreconst
	OpAMD64MOVBstoreconstidx1
	OpAMD64MOVWstoreconstidx1
	OpAMD64MOVWstoreconstidx2
	OpAMD64MOVLstoreconstidx1
	OpAMD64MOVLstoreconstidx4
	OpAMD64MOVQstoreconstidx1
	OpAMD64MOVQstoreconstidx8
	OpAMD64DUFFZERO
	OpAMD64MOVOconst
	OpAMD64REPSTOSQ
	OpAMD64CALLstatic
	OpAMD64CALLclosure
	OpAMD64CALLinter
	OpAMD64DUFFCOPY
	OpAMD64REPMOVSQ
	OpAMD64InvertFlags
	OpAMD64LoweredGetG
	OpAMD64LoweredGetClosurePtr
	OpAMD64LoweredGetCallerPC
	OpAMD64LoweredGetCallerSP
	OpAMD64LoweredNilCheck
	OpAMD64LoweredWB
	OpAMD64FlagEQ
	OpAMD64FlagLT_ULT
	OpAMD64FlagLT_UGT
	OpAMD64FlagGT_UGT
	OpAMD64FlagGT_ULT
	OpAMD64MOVLatomicload
	OpAMD64MOVQatomicload
	OpAMD64XCHGL
	OpAMD64XCHGQ
	OpAMD64XADDLlock
	OpAMD64XADDQlock
	OpAMD64AddTupleFirst32
	OpAMD64AddTupleFirst64
	OpAMD64CMPXCHGLlock
	OpAMD64CMPXCHGQlock
	OpAMD64ANDBlock
	OpAMD64ORBlock

	OpARMADD
	OpARMADDconst
	OpARMSUB
	OpARMSUBconst
	OpARMRSB
	OpARMRSBconst
	OpARMMUL
	OpARMHMUL
	OpARMHMULU
	OpARMCALLudiv
	OpARMADDS
	OpARMADDSconst
	OpARMADC
	OpARMADCconst
	OpARMSUBS
	OpARMSUBSconst
	OpARMRSBSconst
	OpARMSBC
	OpARMSBCconst
	OpARMRSCconst
	OpARMMULLU
	OpARMMULA
	OpARMMULS
	OpARMADDF
	OpARMADDD
	OpARMSUBF
	OpARMSUBD
	OpARMMULF
	OpARMMULD
	OpARMNMULF
	OpARMNMULD
	OpARMDIVF
	OpARMDIVD
	OpARMMULAF
	OpARMMULAD
	OpARMMULSF
	OpARMMULSD
	OpARMAND
	OpARMANDconst
	OpARMOR
	OpARMORconst
	OpARMXOR
	OpARMXORconst
	OpARMBIC
	OpARMBICconst
	OpARMBFX
	OpARMBFXU
	OpARMMVN
	OpARMNEGF
	OpARMNEGD
	OpARMSQRTD
	OpARMCLZ
	OpARMREV
	OpARMRBIT
	OpARMSLL
	OpARMSLLconst
	OpARMSRL
	OpARMSRLconst
	OpARMSRA
	OpARMSRAconst
	OpARMSRRconst
	OpARMADDshiftLL
	OpARMADDshiftRL
	OpARMADDshiftRA
	OpARMSUBshiftLL
	OpARMSUBshiftRL
	OpARMSUBshiftRA
	OpARMRSBshiftLL
	OpARMRSBshiftRL
	OpARMRSBshiftRA
	OpARMANDshiftLL
	OpARMANDshiftRL
	OpARMANDshiftRA
	OpARMORshiftLL
	OpARMORshiftRL
	OpARMORshiftRA
	OpARMXORshiftLL
	OpARMXORshiftRL
	OpARMXORshiftRA
	OpARMXORshiftRR
	OpARMBICshiftLL
	OpARMBICshiftRL
	OpARMBICshiftRA
	OpARMMVNshiftLL
	OpARMMVNshiftRL
	OpARMMVNshiftRA
	OpARMADCshiftLL
	OpARMADCshiftRL
	OpARMADCshiftRA
	OpARMSBCshiftLL
	OpARMSBCshiftRL
	OpARMSBCshiftRA
	OpARMRSCshiftLL
	OpARMRSCshiftRL
	OpARMRSCshiftRA
	OpARMADDSshiftLL
	OpARMADDSshiftRL
	OpARMADDSshiftRA
	OpARMSUBSshiftLL
	OpARMSUBSshiftRL
	OpARMSUBSshiftRA
	OpARMRSBSshiftLL
	OpARMRSBSshiftRL
	OpARMRSBSshiftRA
	OpARMADDshiftLLreg
	OpARMADDshiftRLreg
	OpARMADDshiftRAreg
	OpARMSUBshiftLLreg
	OpARMSUBshiftRLreg
	OpARMSUBshiftRAreg
	OpARMRSBshiftLLreg
	OpARMRSBshiftRLreg
	OpARMRSBshiftRAreg
	OpARMANDshiftLLreg
	OpARMANDshiftRLreg
	OpARMANDshiftRAreg
	OpARMORshiftLLreg
	OpARMORshiftRLreg
	OpARMORshiftRAreg
	OpARMXORshiftLLreg
	OpARMXORshiftRLreg
	OpARMXORshiftRAreg
	OpARMBICshiftLLreg
	OpARMBICshiftRLreg
	OpARMBICshiftRAreg
	OpARMMVNshiftLLreg
	OpARMMVNshiftRLreg
	OpARMMVNshiftRAreg
	OpARMADCshiftLLreg
	OpARMADCshiftRLreg
	OpARMADCshiftRAreg
	OpARMSBCshiftLLreg
	OpARMSBCshiftRLreg
	OpARMSBCshiftRAreg
	OpARMRSCshiftLLreg
	OpARMRSCshiftRLreg
	OpARMRSCshiftRAreg
	OpARMADDSshiftLLreg
	OpARMADDSshiftRLreg
	OpARMADDSshiftRAreg
	OpARMSUBSshiftLLreg
	OpARMSUBSshiftRLreg
	OpARMSUBSshiftRAreg
	OpARMRSBSshiftLLreg
	OpARMRSBSshiftRLreg
	OpARMRSBSshiftRAreg
	OpARMCMP
	OpARMCMPconst
	OpARMCMN
	OpARMCMNconst
	OpARMTST
	OpARMTSTconst
	OpARMTEQ
	OpARMTEQconst
	OpARMCMPF
	OpARMCMPD
	OpARMCMPshiftLL
	OpARMCMPshiftRL
	OpARMCMPshiftRA
	OpARMCMNshiftLL
	OpARMCMNshiftRL
	OpARMCMNshiftRA
	OpARMTSTshiftLL
	OpARMTSTshiftRL
	OpARMTSTshiftRA
	OpARMTEQshiftLL
	OpARMTEQshiftRL
	OpARMTEQshiftRA
	OpARMCMPshiftLLreg
	OpARMCMPshiftRLreg
	OpARMCMPshiftRAreg
	OpARMCMNshiftLLreg
	OpARMCMNshiftRLreg
	OpARMCMNshiftRAreg
	OpARMTSTshiftLLreg
	OpARMTSTshiftRLreg
	OpARMTSTshiftRAreg
	OpARMTEQshiftLLreg
	OpARMTEQshiftRLreg
	OpARMTEQshiftRAreg
	OpARMCMPF0
	OpARMCMPD0
	OpARMMOVWconst
	OpARMMOVFconst
	OpARMMOVDconst
	OpARMMOVWaddr
	OpARMMOVBload
	OpARMMOVBUload
	OpARMMOVHload
	OpARMMOVHUload
	OpARMMOVWload
	OpARMMOVFload
	OpARMMOVDload
	OpARMMOVBstore
	OpARMMOVHstore
	OpARMMOVWstore
	OpARMMOVFstore
	OpARMMOVDstore
	OpARMMOVWloadidx
	OpARMMOVWloadshiftLL
	OpARMMOVWloadshiftRL
	OpARMMOVWloadshiftRA
	OpARMMOVBUloadidx
	OpARMMOVBloadidx
	OpARMMOVHUloadidx
	OpARMMOVHloadidx
	OpARMMOVWstoreidx
	OpARMMOVWstoreshiftLL
	OpARMMOVWstoreshiftRL
	OpARMMOVWstoreshiftRA
	OpARMMOVBstoreidx
	OpARMMOVHstoreidx
	OpARMMOVBreg
	OpARMMOVBUreg
	OpARMMOVHreg
	OpARMMOVHUreg
	OpARMMOVWreg
	OpARMMOVWnop
	OpARMMOVWF
	OpARMMOVWD
	OpARMMOVWUF
	OpARMMOVWUD
	OpARMMOVFW
	OpARMMOVDW
	OpARMMOVFWU
	OpARMMOVDWU
	OpARMMOVFD
	OpARMMOVDF
	OpARMCMOVWHSconst
	OpARMCMOVWLSconst
	OpARMSRAcond
	OpARMCALLstatic
	OpARMCALLclosure
	OpARMCALLinter
	OpARMLoweredNilCheck
	OpARMEqual
	OpARMNotEqual
	OpARMLessThan
	OpARMLessEqual
	OpARMGreaterThan
	OpARMGreaterEqual
	OpARMLessThanU
	OpARMLessEqualU
	OpARMGreaterThanU
	OpARMGreaterEqualU
	OpARMDUFFZERO
	OpARMDUFFCOPY
	OpARMLoweredZero
	OpARMLoweredMove
	OpARMLoweredGetClosurePtr
	OpARMLoweredGetCallerSP
	OpARMLoweredGetCallerPC
	OpARMFlagEQ
	OpARMFlagLT_ULT
	OpARMFlagLT_UGT
	OpARMFlagGT_UGT
	OpARMFlagGT_ULT
	OpARMInvertFlags
	OpARMLoweredWB

	OpARM64ADD
	OpARM64ADDconst
	OpARM64SUB
	OpARM64SUBconst
	OpARM64MUL
	OpARM64MULW
	OpARM64MNEG
	OpARM64MNEGW
	OpARM64MULH
	OpARM64UMULH
	OpARM64MULL
	OpARM64UMULL
	OpARM64DIV
	OpARM64UDIV
	OpARM64DIVW
	OpARM64UDIVW
	OpARM64MOD
	OpARM64UMOD
	OpARM64MODW
	OpARM64UMODW
	OpARM64FADDS
	OpARM64FADDD
	OpARM64FSUBS
	OpARM64FSUBD
	OpARM64FMULS
	OpARM64FMULD
	OpARM64FNMULS
	OpARM64FNMULD
	OpARM64FDIVS
	OpARM64FDIVD
	OpARM64AND
	OpARM64ANDconst
	OpARM64OR
	OpARM64ORconst
	OpARM64XOR
	OpARM64XORconst
	OpARM64BIC
	OpARM64EON
	OpARM64ORN
	OpARM64LoweredMuluhilo
	OpARM64MVN
	OpARM64NEG
	OpARM64FABSD
	OpARM64FNEGS
	OpARM64FNEGD
	OpARM64FSQRTD
	OpARM64REV
	OpARM64REVW
	OpARM64REV16W
	OpARM64RBIT
	OpARM64RBITW
	OpARM64CLZ
	OpARM64CLZW
	OpARM64VCNT
	OpARM64VUADDLV
	OpARM64LoweredRound32F
	OpARM64LoweredRound64F
	OpARM64FMADDS
	OpARM64FMADDD
	OpARM64FNMADDS
	OpARM64FNMADDD
	OpARM64FMSUBS
	OpARM64FMSUBD
	OpARM64FNMSUBS
	OpARM64FNMSUBD
	OpARM64MADD
	OpARM64MADDW
	OpARM64MSUB
	OpARM64MSUBW
	OpARM64SLL
	OpARM64SLLconst
	OpARM64SRL
	OpARM64SRLconst
	OpARM64SRA
	OpARM64SRAconst
	OpARM64ROR
	OpARM64RORW
	OpARM64RORconst
	OpARM64RORWconst
	OpARM64EXTRconst
	OpARM64EXTRWconst
	OpARM64CMP
	OpARM64CMPconst
	OpARM64CMPW
	OpARM64CMPWconst
	OpARM64CMN
	OpARM64CMNconst
	OpARM64CMNW
	OpARM64CMNWconst
	OpARM64TST
	OpARM64TSTconst
	OpARM64TSTW
	OpARM64TSTWconst
	OpARM64FCMPS
	OpARM64FCMPD
	OpARM64MVNshiftLL
	OpARM64MVNshiftRL
	OpARM64MVNshiftRA
	OpARM64NEGshiftLL
	OpARM64NEGshiftRL
	OpARM64NEGshiftRA
	OpARM64ADDshiftLL
	OpARM64ADDshiftRL
	OpARM64ADDshiftRA
	OpARM64SUBshiftLL
	OpARM64SUBshiftRL
	OpARM64SUBshiftRA
	OpARM64ANDshiftLL
	OpARM64ANDshiftRL
	OpARM64ANDshiftRA
	OpARM64ORshiftLL
	OpARM64ORshiftRL
	OpARM64ORshiftRA
	OpARM64XORshiftLL
	OpARM64XORshiftRL
	OpARM64XORshiftRA
	OpARM64BICshiftLL
	OpARM64BICshiftRL
	OpARM64BICshiftRA
	OpARM64EONshiftLL
	OpARM64EONshiftRL
	OpARM64EONshiftRA
	OpARM64ORNshiftLL
	OpARM64ORNshiftRL
	OpARM64ORNshiftRA
	OpARM64CMPshiftLL
	OpARM64CMPshiftRL
	OpARM64CMPshiftRA
	OpARM64CMNshiftLL
	OpARM64CMNshiftRL
	OpARM64CMNshiftRA
	OpARM64TSTshiftLL
	OpARM64TSTshiftRL
	OpARM64TSTshiftRA
	OpARM64BFI
	OpARM64BFXIL
	OpARM64SBFIZ
	OpARM64SBFX
	OpARM64UBFIZ
	OpARM64UBFX
	OpARM64MOVDconst
	OpARM64FMOVSconst
	OpARM64FMOVDconst
	OpARM64MOVDaddr
	OpARM64MOVBload
	OpARM64MOVBUload
	OpARM64MOVHload
	OpARM64MOVHUload
	OpARM64MOVWload
	OpARM64MOVWUload
	OpARM64MOVDload
	OpARM64FMOVSload
	OpARM64FMOVDload
	OpARM64MOVDloadidx
	OpARM64MOVWloadidx
	OpARM64MOVWUloadidx
	OpARM64MOVHloadidx
	OpARM64MOVHUloadidx
	OpARM64MOVBloadidx
	OpARM64MOVBUloadidx
	OpARM64FMOVSloadidx
	OpARM64FMOVDloadidx
	OpARM64MOVHloadidx2
	OpARM64MOVHUloadidx2
	OpARM64MOVWloadidx4
	OpARM64MOVWUloadidx4
	OpARM64MOVDloadidx8
	OpARM64MOVBstore
	OpARM64MOVHstore
	OpARM64MOVWstore
	OpARM64MOVDstore
	OpARM64STP
	OpARM64FMOVSstore
	OpARM64FMOVDstore
	OpARM64MOVBstoreidx
	OpARM64MOVHstoreidx
	OpARM64MOVWstoreidx
	OpARM64MOVDstoreidx
	OpARM64FMOVSstoreidx
	OpARM64FMOVDstoreidx
	OpARM64MOVHstoreidx2
	OpARM64MOVWstoreidx4
	OpARM64MOVDstoreidx8
	OpARM64MOVBstorezero
	OpARM64MOVHstorezero
	OpARM64MOVWstorezero
	OpARM64MOVDstorezero
	OpARM64MOVQstorezero
	OpARM64MOVBstorezeroidx
	OpARM64MOVHstorezeroidx
	OpARM64MOVWstorezeroidx
	OpARM64MOVDstorezeroidx
	OpARM64MOVHstorezeroidx2
	OpARM64MOVWstorezeroidx4
	OpARM64MOVDstorezeroidx8
	OpARM64FMOVDgpfp
	OpARM64FMOVDfpgp
	OpARM64FMOVSgpfp
	OpARM64FMOVSfpgp
	OpARM64MOVBreg
	OpARM64MOVBUreg
	OpARM64MOVHreg
	OpARM64MOVHUreg
	OpARM64MOVWreg
	OpARM64MOVWUreg
	OpARM64MOVDreg
	OpARM64MOVDnop
	OpARM64SCVTFWS
	OpARM64SCVTFWD
	OpARM64UCVTFWS
	OpARM64UCVTFWD
	OpARM64SCVTFS
	OpARM64SCVTFD
	OpARM64UCVTFS
	OpARM64UCVTFD
	OpARM64FCVTZSSW
	OpARM64FCVTZSDW
	OpARM64FCVTZUSW
	OpARM64FCVTZUDW
	OpARM64FCVTZSS
	OpARM64FCVTZSD
	OpARM64FCVTZUS
	OpARM64FCVTZUD
	OpARM64FCVTSD
	OpARM64FCVTDS
	OpARM64FRINTAD
	OpARM64FRINTMD
	OpARM64FRINTND
	OpARM64FRINTPD
	OpARM64FRINTZD
	OpARM64CSEL
	OpARM64CSEL0
	OpARM64CALLstatic
	OpARM64CALLclosure
	OpARM64CALLinter
	OpARM64LoweredNilCheck
	OpARM64Equal
	OpARM64NotEqual
	OpARM64LessThan
	OpARM64LessEqual
	OpARM64GreaterThan
	OpARM64GreaterEqual
	OpARM64LessThanU
	OpARM64LessEqualU
	OpARM64GreaterThanU
	OpARM64GreaterEqualU
	OpARM64DUFFZERO
	OpARM64LoweredZero
	OpARM64DUFFCOPY
	OpARM64LoweredMove
	OpARM64LoweredGetClosurePtr
	OpARM64LoweredGetCallerSP
	OpARM64LoweredGetCallerPC
	OpARM64FlagEQ
	OpARM64FlagLT_ULT
	OpARM64FlagLT_UGT
	OpARM64FlagGT_UGT
	OpARM64FlagGT_ULT
	OpARM64InvertFlags
	OpARM64LDAR
	OpARM64LDARW
	OpARM64STLR
	OpARM64STLRW
	OpARM64LoweredAtomicExchange64
	OpARM64LoweredAtomicExchange32
	OpARM64LoweredAtomicAdd64
	OpARM64LoweredAtomicAdd32
	OpARM64LoweredAtomicAdd64Variant
	OpARM64LoweredAtomicAdd32Variant
	OpARM64LoweredAtomicCas64
	OpARM64LoweredAtomicCas32
	OpARM64LoweredAtomicAnd8
	OpARM64LoweredAtomicOr8
	OpARM64LoweredWB

	OpMIPSADD
	OpMIPSADDconst
	OpMIPSSUB
	OpMIPSSUBconst
	OpMIPSMUL
	OpMIPSMULT
	OpMIPSMULTU
	OpMIPSDIV
	OpMIPSDIVU
	OpMIPSADDF
	OpMIPSADDD
	OpMIPSSUBF
	OpMIPSSUBD
	OpMIPSMULF
	OpMIPSMULD
	OpMIPSDIVF
	OpMIPSDIVD
	OpMIPSAND
	OpMIPSANDconst
	OpMIPSOR
	OpMIPSORconst
	OpMIPSXOR
	OpMIPSXORconst
	OpMIPSNOR
	OpMIPSNORconst
	OpMIPSNEG
	OpMIPSNEGF
	OpMIPSNEGD
	OpMIPSSQRTD
	OpMIPSSLL
	OpMIPSSLLconst
	OpMIPSSRL
	OpMIPSSRLconst
	OpMIPSSRA
	OpMIPSSRAconst
	OpMIPSCLZ
	OpMIPSSGT
	OpMIPSSGTconst
	OpMIPSSGTzero
	OpMIPSSGTU
	OpMIPSSGTUconst
	OpMIPSSGTUzero
	OpMIPSCMPEQF
	OpMIPSCMPEQD
	OpMIPSCMPGEF
	OpMIPSCMPGED
	OpMIPSCMPGTF
	OpMIPSCMPGTD
	OpMIPSMOVWconst
	OpMIPSMOVFconst
	OpMIPSMOVDconst
	OpMIPSMOVWaddr
	OpMIPSMOVBload
	OpMIPSMOVBUload
	OpMIPSMOVHload
	OpMIPSMOVHUload
	OpMIPSMOVWload
	OpMIPSMOVFload
	OpMIPSMOVDload
	OpMIPSMOVBstore
	OpMIPSMOVHstore
	OpMIPSMOVWstore
	OpMIPSMOVFstore
	OpMIPSMOVDstore
	OpMIPSMOVBstorezero
	OpMIPSMOVHstorezero
	OpMIPSMOVWstorezero
	OpMIPSMOVBreg
	OpMIPSMOVBUreg
	OpMIPSMOVHreg
	OpMIPSMOVHUreg
	OpMIPSMOVWreg
	OpMIPSMOVWnop
	OpMIPSCMOVZ
	OpMIPSCMOVZzero
	OpMIPSMOVWF
	OpMIPSMOVWD
	OpMIPSTRUNCFW
	OpMIPSTRUNCDW
	OpMIPSMOVFD
	OpMIPSMOVDF
	OpMIPSCALLstatic
	OpMIPSCALLclosure
	OpMIPSCALLinter
	OpMIPSLoweredAtomicLoad
	OpMIPSLoweredAtomicStore
	OpMIPSLoweredAtomicStorezero
	OpMIPSLoweredAtomicExchange
	OpMIPSLoweredAtomicAdd
	OpMIPSLoweredAtomicAddconst
	OpMIPSLoweredAtomicCas
	OpMIPSLoweredAtomicAnd
	OpMIPSLoweredAtomicOr
	OpMIPSLoweredZero
	OpMIPSLoweredMove
	OpMIPSLoweredNilCheck
	OpMIPSFPFlagTrue
	OpMIPSFPFlagFalse
	OpMIPSLoweredGetClosurePtr
	OpMIPSLoweredGetCallerSP
	OpMIPSLoweredGetCallerPC
	OpMIPSLoweredWB

	OpMIPS64ADDV
	OpMIPS64ADDVconst
	OpMIPS64SUBV
	OpMIPS64SUBVconst
	OpMIPS64MULV
	OpMIPS64MULVU
	OpMIPS64DIVV
	OpMIPS64DIVVU
	OpMIPS64ADDF
	OpMIPS64ADDD
	OpMIPS64SUBF
	OpMIPS64SUBD
	OpMIPS64MULF
	OpMIPS64MULD
	OpMIPS64DIVF
	OpMIPS64DIVD
	OpMIPS64AND
	OpMIPS64ANDconst
	OpMIPS64OR
	OpMIPS64ORconst
	OpMIPS64XOR
	OpMIPS64XORconst
	OpMIPS64NOR
	OpMIPS64NORconst
	OpMIPS64NEGV
	OpMIPS64NEGF
	OpMIPS64NEGD
	OpMIPS64SQRTD
	OpMIPS64SLLV
	OpMIPS64SLLVconst
	OpMIPS64SRLV
	OpMIPS64SRLVconst
	OpMIPS64SRAV
	OpMIPS64SRAVconst
	OpMIPS64SGT
	OpMIPS64SGTconst
	OpMIPS64SGTU
	OpMIPS64SGTUconst
	OpMIPS64CMPEQF
	OpMIPS64CMPEQD
	OpMIPS64CMPGEF
	OpMIPS64CMPGED
	OpMIPS64CMPGTF
	OpMIPS64CMPGTD
	OpMIPS64MOVVconst
	OpMIPS64MOVFconst
	OpMIPS64MOVDconst
	OpMIPS64MOVVaddr
	OpMIPS64MOVBload
	OpMIPS64MOVBUload
	OpMIPS64MOVHload
	OpMIPS64MOVHUload
	OpMIPS64MOVWload
	OpMIPS64MOVWUload
	OpMIPS64MOVVload
	OpMIPS64MOVFload
	OpMIPS64MOVDload
	OpMIPS64MOVBstore
	OpMIPS64MOVHstore
	OpMIPS64MOVWstore
	OpMIPS64MOVVstore
	OpMIPS64MOVFstore
	OpMIPS64MOVDstore
	OpMIPS64MOVBstorezero
	OpMIPS64MOVHstorezero
	OpMIPS64MOVWstorezero
	OpMIPS64MOVVstorezero
	OpMIPS64MOVBreg
	OpMIPS64MOVBUreg
	OpMIPS64MOVHreg
	OpMIPS64MOVHUreg
	OpMIPS64MOVWreg
	OpMIPS64MOVWUreg
	OpMIPS64MOVVreg
	OpMIPS64MOVVnop
	OpMIPS64MOVWF
	OpMIPS64MOVWD
	OpMIPS64MOVVF
	OpMIPS64MOVVD
	OpMIPS64TRUNCFW
	OpMIPS64TRUNCDW
	OpMIPS64TRUNCFV
	OpMIPS64TRUNCDV
	OpMIPS64MOVFD
	OpMIPS64MOVDF
	OpMIPS64CALLstatic
	OpMIPS64CALLclosure
	OpMIPS64CALLinter
	OpMIPS64DUFFZERO
	OpMIPS64LoweredZero
	OpMIPS64LoweredMove
	OpMIPS64LoweredAtomicLoad32
	OpMIPS64LoweredAtomicLoad64
	OpMIPS64LoweredAtomicStore32
	OpMIPS64LoweredAtomicStore64
	OpMIPS64LoweredAtomicStorezero32
	OpMIPS64LoweredAtomicStorezero64
	OpMIPS64LoweredAtomicExchange32
	OpMIPS64LoweredAtomicExchange64
	OpMIPS64LoweredAtomicAdd32
	OpMIPS64LoweredAtomicAdd64
	OpMIPS64LoweredAtomicAddconst32
	OpMIPS64LoweredAtomicAddconst64
	OpMIPS64LoweredAtomicCas32
	OpMIPS64LoweredAtomicCas64
	OpMIPS64LoweredNilCheck
	OpMIPS64FPFlagTrue
	OpMIPS64FPFlagFalse
	OpMIPS64LoweredGetClosurePtr
	OpMIPS64LoweredGetCallerSP
	OpMIPS64LoweredGetCallerPC
	OpMIPS64LoweredWB

	OpPPC64ADD
	OpPPC64ADDconst
	OpPPC64FADD
	OpPPC64FADDS
	OpPPC64SUB
	OpPPC64FSUB
	OpPPC64FSUBS
	OpPPC64MULLD
	OpPPC64MULLW
	OpPPC64MULHD
	OpPPC64MULHW
	OpPPC64MULHDU
	OpPPC64MULHWU
	OpPPC64LoweredMuluhilo
	OpPPC64FMUL
	OpPPC64FMULS
	OpPPC64FMADD
	OpPPC64FMADDS
	OpPPC64FMSUB
	OpPPC64FMSUBS
	OpPPC64SRAD
	OpPPC64SRAW
	OpPPC64SRD
	OpPPC64SRW
	OpPPC64SLD
	OpPPC64SLW
	OpPPC64ROTL
	OpPPC64ROTLW
	OpPPC64ADDconstForCarry
	OpPPC64MaskIfNotCarry
	OpPPC64SRADconst
	OpPPC64SRAWconst
	OpPPC64SRDconst
	OpPPC64SRWconst
	OpPPC64SLDconst
	OpPPC64SLWconst
	OpPPC64ROTLconst
	OpPPC64ROTLWconst
	OpPPC64CNTLZD
	OpPPC64CNTLZW
	OpPPC64POPCNTD
	OpPPC64POPCNTW
	OpPPC64POPCNTB
	OpPPC64FDIV
	OpPPC64FDIVS
	OpPPC64DIVD
	OpPPC64DIVW
	OpPPC64DIVDU
	OpPPC64DIVWU
	OpPPC64FCTIDZ
	OpPPC64FCTIWZ
	OpPPC64FCFID
	OpPPC64FCFIDS
	OpPPC64FRSP
	OpPPC64MFVSRD
	OpPPC64MTVSRD
	OpPPC64AND
	OpPPC64ANDN
	OpPPC64ANDCC
	OpPPC64OR
	OpPPC64ORN
	OpPPC64ORCC
	OpPPC64NOR
	OpPPC64XOR
	OpPPC64XORCC
	OpPPC64EQV
	OpPPC64NEG
	OpPPC64FNEG
	OpPPC64FSQRT
	OpPPC64FSQRTS
	OpPPC64FFLOOR
	OpPPC64FCEIL
	OpPPC64FTRUNC
	OpPPC64FROUND
	OpPPC64FABS
	OpPPC64FNABS
	OpPPC64FCPSGN
	OpPPC64ORconst
	OpPPC64XORconst
	OpPPC64ANDconst
	OpPPC64ANDCCconst
	OpPPC64MOVBreg
	OpPPC64MOVBZreg
	OpPPC64MOVHreg
	OpPPC64MOVHZreg
	OpPPC64MOVWreg
	OpPPC64MOVWZreg
	OpPPC64MOVBZload
	OpPPC64MOVHload
	OpPPC64MOVHZload
	OpPPC64MOVWload
	OpPPC64MOVWZload
	OpPPC64MOVDload
	OpPPC64MOVDBRload
	OpPPC64MOVWBRload
	OpPPC64MOVHBRload
	OpPPC64MOVBZloadidx
	OpPPC64MOVHloadidx
	OpPPC64MOVHZloadidx
	OpPPC64MOVWloadidx
	OpPPC64MOVWZloadidx
	OpPPC64MOVDloadidx
	OpPPC64MOVHBRloadidx
	OpPPC64MOVWBRloadidx
	OpPPC64MOVDBRloadidx
	OpPPC64FMOVDloadidx
	OpPPC64FMOVSloadidx
	OpPPC64MOVDBRstore
	OpPPC64MOVWBRstore
	OpPPC64MOVHBRstore
	OpPPC64FMOVDload
	OpPPC64FMOVSload
	OpPPC64MOVBstore
	OpPPC64MOVHstore
	OpPPC64MOVWstore
	OpPPC64MOVDstore
	OpPPC64FMOVDstore
	OpPPC64FMOVSstore
	OpPPC64MOVBstoreidx
	OpPPC64MOVHstoreidx
	OpPPC64MOVWstoreidx
	OpPPC64MOVDstoreidx
	OpPPC64FMOVDstoreidx
	OpPPC64FMOVSstoreidx
	OpPPC64MOVHBRstoreidx
	OpPPC64MOVWBRstoreidx
	OpPPC64MOVDBRstoreidx
	OpPPC64MOVBstorezero
	OpPPC64MOVHstorezero
	OpPPC64MOVWstorezero
	OpPPC64MOVDstorezero
	OpPPC64MOVDaddr
	OpPPC64MOVDconst
	OpPPC64FMOVDconst
	OpPPC64FMOVSconst
	OpPPC64FCMPU
	OpPPC64CMP
	OpPPC64CMPU
	OpPPC64CMPW
	OpPPC64CMPWU
	OpPPC64CMPconst
	OpPPC64CMPUconst
	OpPPC64CMPWconst
	OpPPC64CMPWUconst
	OpPPC64Equal
	OpPPC64NotEqual
	OpPPC64LessThan
	OpPPC64FLessThan
	OpPPC64LessEqual
	OpPPC64FLessEqual
	OpPPC64GreaterThan
	OpPPC64FGreaterThan
	OpPPC64GreaterEqual
	OpPPC64FGreaterEqual
	OpPPC64LoweredGetClosurePtr
	OpPPC64LoweredGetCallerSP
	OpPPC64LoweredGetCallerPC
	OpPPC64LoweredNilCheck
	OpPPC64LoweredRound32F
	OpPPC64LoweredRound64F
	OpPPC64CALLstatic
	OpPPC64CALLclosure
	OpPPC64CALLinter
	OpPPC64LoweredZero
	OpPPC64LoweredMove
	OpPPC64LoweredAtomicStore32
	OpPPC64LoweredAtomicStore64
	OpPPC64LoweredAtomicLoad32
	OpPPC64LoweredAtomicLoad64
	OpPPC64LoweredAtomicLoadPtr
	OpPPC64LoweredAtomicAdd32
	OpPPC64LoweredAtomicAdd64
	OpPPC64LoweredAtomicExchange32
	OpPPC64LoweredAtomicExchange64
	OpPPC64LoweredAtomicCas64
	OpPPC64LoweredAtomicCas32
	OpPPC64LoweredAtomicAnd8
	OpPPC64LoweredAtomicOr8
	OpPPC64LoweredWB
	OpPPC64InvertFlags
	OpPPC64FlagEQ
	OpPPC64FlagLT
	OpPPC64FlagGT

	OpS390XFADDS
	OpS390XFADD
	OpS390XFSUBS
	OpS390XFSUB
	OpS390XFMULS
	OpS390XFMUL
	OpS390XFDIVS
	OpS390XFDIV
	OpS390XFNEGS
	OpS390XFNEG
	OpS390XFMADDS
	OpS390XFMADD
	OpS390XFMSUBS
	OpS390XFMSUB
	OpS390XLPDFR
	OpS390XLNDFR
	OpS390XCPSDR
	OpS390XFIDBR
	OpS390XFMOVSload
	OpS390XFMOVDload
	OpS390XFMOVSconst
	OpS390XFMOVDconst
	OpS390XFMOVSloadidx
	OpS390XFMOVDloadidx
	OpS390XFMOVSstore
	OpS390XFMOVDstore
	OpS390XFMOVSstoreidx
	OpS390XFMOVDstoreidx
	OpS390XADD
	OpS390XADDW
	OpS390XADDconst
	OpS390XADDWconst
	OpS390XADDload
	OpS390XADDWload
	OpS390XSUB
	OpS390XSUBW
	OpS390XSUBconst
	OpS390XSUBWconst
	OpS390XSUBload
	OpS390XSUBWload
	OpS390XMULLD
	OpS390XMULLW
	OpS390XMULLDconst
	OpS390XMULLWconst
	OpS390XMULLDload
	OpS390XMULLWload
	OpS390XMULHD
	OpS390XMULHDU
	OpS390XDIVD
	OpS390XDIVW
	OpS390XDIVDU
	OpS390XDIVWU
	OpS390XMODD
	OpS390XMODW
	OpS390XMODDU
	OpS390XMODWU
	OpS390XAND
	OpS390XANDW
	OpS390XANDconst
	OpS390XANDWconst
	OpS390XANDload
	OpS390XANDWload
	OpS390XOR
	OpS390XORW
	OpS390XORconst
	OpS390XORWconst
	OpS390XORload
	OpS390XORWload
	OpS390XXOR
	OpS390XXORW
	OpS390XXORconst
	OpS390XXORWconst
	OpS390XXORload
	OpS390XXORWload
	OpS390XCMP
	OpS390XCMPW
	OpS390XCMPU
	OpS390XCMPWU
	OpS390XCMPconst
	OpS390XCMPWconst
	OpS390XCMPUconst
	OpS390XCMPWUconst
	OpS390XFCMPS
	OpS390XFCMP
	OpS390XSLD
	OpS390XSLW
	OpS390XSLDconst
	OpS390XSLWconst
	OpS390XSRD
	OpS390XSRW
	OpS390XSRDconst
	OpS390XSRWconst
	OpS390XSRAD
	OpS390XSRAW
	OpS390XSRADconst
	OpS390XSRAWconst
	OpS390XRLLG
	OpS390XRLL
	OpS390XRLLGconst
	OpS390XRLLconst
	OpS390XNEG
	OpS390XNEGW
	OpS390XNOT
	OpS390XNOTW
	OpS390XFSQRT
	OpS390XMOVDEQ
	OpS390XMOVDNE
	OpS390XMOVDLT
	OpS390XMOVDLE
	OpS390XMOVDGT
	OpS390XMOVDGE
	OpS390XMOVDGTnoinv
	OpS390XMOVDGEnoinv
	OpS390XMOVBreg
	OpS390XMOVBZreg
	OpS390XMOVHreg
	OpS390XMOVHZreg
	OpS390XMOVWreg
	OpS390XMOVWZreg
	OpS390XMOVDreg
	OpS390XMOVDnop
	OpS390XMOVDconst
	OpS390XLDGR
	OpS390XLGDR
	OpS390XCFDBRA
	OpS390XCGDBRA
	OpS390XCFEBRA
	OpS390XCGEBRA
	OpS390XCEFBRA
	OpS390XCDFBRA
	OpS390XCEGBRA
	OpS390XCDGBRA
	OpS390XLEDBR
	OpS390XLDEBR
	OpS390XMOVDaddr
	OpS390XMOVDaddridx
	OpS390XMOVBZload
	OpS390XMOVBload
	OpS390XMOVHZload
	OpS390XMOVHload
	OpS390XMOVWZload
	OpS390XMOVWload
	OpS390XMOVDload
	OpS390XMOVWBR
	OpS390XMOVDBR
	OpS390XMOVHBRload
	OpS390XMOVWBRload
	OpS390XMOVDBRload
	OpS390XMOVBstore
	OpS390XMOVHstore
	OpS390XMOVWstore
	OpS390XMOVDstore
	OpS390XMOVHBRstore
	OpS390XMOVWBRstore
	OpS390XMOVDBRstore
	OpS390XMVC
	OpS390XMOVBZloadidx
	OpS390XMOVBloadidx
	OpS390XMOVHZloadidx
	OpS390XMOVHloadidx
	OpS390XMOVWZloadidx
	OpS390XMOVWloadidx
	OpS390XMOVDloadidx
	OpS390XMOVHBRloadidx
	OpS390XMOVWBRloadidx
	OpS390XMOVDBRloadidx
	OpS390XMOVBstoreidx
	OpS390XMOVHstoreidx
	OpS390XMOVWstoreidx
	OpS390XMOVDstoreidx
	OpS390XMOVHBRstoreidx
	OpS390XMOVWBRstoreidx
	OpS390XMOVDBRstoreidx
	OpS390XMOVBstoreconst
	OpS390XMOVHstoreconst
	OpS390XMOVWstoreconst
	OpS390XMOVDstoreconst
	OpS390XCLEAR
	OpS390XCALLstatic
	OpS390XCALLclosure
	OpS390XCALLinter
	OpS390XInvertFlags
	OpS390XLoweredGetG
	OpS390XLoweredGetClosurePtr
	OpS390XLoweredGetCallerSP
	OpS390XLoweredGetCallerPC
	OpS390XLoweredNilCheck
	OpS390XLoweredRound32F
	OpS390XLoweredRound64F
	OpS390XLoweredWB
	OpS390XFlagEQ
	OpS390XFlagLT
	OpS390XFlagGT
	OpS390XMOVWZatomicload
	OpS390XMOVDatomicload
	OpS390XMOVWatomicstore
	OpS390XMOVDatomicstore
	OpS390XLAA
	OpS390XLAAG
	OpS390XAddTupleFirst32
	OpS390XAddTupleFirst64
	OpS390XLoweredAtomicCas32
	OpS390XLoweredAtomicCas64
	OpS390XLoweredAtomicExchange32
	OpS390XLoweredAtomicExchange64
	OpS390XFLOGR
	OpS390XPOPCNT
	OpS390XSumBytes2
	OpS390XSumBytes4
	OpS390XSumBytes8
	OpS390XSTMG2
	OpS390XSTMG3
	OpS390XSTMG4
	OpS390XSTM2
	OpS390XSTM3
	OpS390XSTM4
	OpS390XLoweredMove
	OpS390XLoweredZero

	OpWasmLoweredStaticCall
	OpWasmLoweredClosureCall
	OpWasmLoweredInterCall
	OpWasmLoweredAddr
	OpWasmLoweredMove
	OpWasmLoweredZero
	OpWasmLoweredGetClosurePtr
	OpWasmLoweredGetCallerPC
	OpWasmLoweredGetCallerSP
	OpWasmLoweredNilCheck
	OpWasmLoweredWB
	OpWasmLoweredRound32F
	OpWasmLoweredConvert
	OpWasmSelect
	OpWasmI64Load8U
	OpWasmI64Load8S
	OpWasmI64Load16U
	OpWasmI64Load16S
	OpWasmI64Load32U
	OpWasmI64Load32S
	OpWasmI64Load
	OpWasmI64Store8
	OpWasmI64Store16
	OpWasmI64Store32
	OpWasmI64Store
	OpWasmF32Load
	OpWasmF64Load
	OpWasmF32Store
	OpWasmF64Store
	OpWasmI64Const
	OpWasmF64Const
	OpWasmI64Eqz
	OpWasmI64Eq
	OpWasmI64Ne
	OpWasmI64LtS
	OpWasmI64LtU
	OpWasmI64GtS
	OpWasmI64GtU
	OpWasmI64LeS
	OpWasmI64LeU
	OpWasmI64GeS
	OpWasmI64GeU
	OpWasmF64Eq
	OpWasmF64Ne
	OpWasmF64Lt
	OpWasmF64Gt
	OpWasmF64Le
	OpWasmF64Ge
	OpWasmI64Add
	OpWasmI64AddConst
	OpWasmI64Sub
	OpWasmI64Mul
	OpWasmI64DivS
	OpWasmI64DivU
	OpWasmI64RemS
	OpWasmI64RemU
	OpWasmI64And
	OpWasmI64Or
	OpWasmI64Xor
	OpWasmI64Shl
	OpWasmI64ShrS
	OpWasmI64ShrU
	OpWasmF64Neg
	OpWasmF64Add
	OpWasmF64Sub
	OpWasmF64Mul
	OpWasmF64Div
	OpWasmI64TruncSF64
	OpWasmI64TruncUF64
	OpWasmF64ConvertSI64
	OpWasmF64ConvertUI64

	OpAdd8
	OpAdd16
	OpAdd32
	OpAdd64
	OpAddPtr
	OpAdd32F
	OpAdd64F
	OpSub8
	OpSub16
	OpSub32
	OpSub64
	OpSubPtr
	OpSub32F
	OpSub64F
	OpMul8
	OpMul16
	OpMul32
	OpMul64
	OpMul32F
	OpMul64F
	OpDiv32F
	OpDiv64F
	OpHmul32
	OpHmul32u
	OpHmul64
	OpHmul64u
	OpMul32uhilo
	OpMul64uhilo
	OpMul32uover
	OpMul64uover
	OpAvg32u
	OpAvg64u
	OpDiv8
	OpDiv8u
	OpDiv16
	OpDiv16u
	OpDiv32
	OpDiv32u
	OpDiv64
	OpDiv64u
	OpDiv128u
	OpMod8
	OpMod8u
	OpMod16
	OpMod16u
	OpMod32
	OpMod32u
	OpMod64
	OpMod64u
	OpAnd8
	OpAnd16
	OpAnd32
	OpAnd64
	OpOr8
	OpOr16
	OpOr32
	OpOr64
	OpXor8
	OpXor16
	OpXor32
	OpXor64
	OpLsh8x8
	OpLsh8x16
	OpLsh8x32
	OpLsh8x64
	OpLsh16x8
	OpLsh16x16
	OpLsh16x32
	OpLsh16x64
	OpLsh32x8
	OpLsh32x16
	OpLsh32x32
	OpLsh32x64
	OpLsh64x8
	OpLsh64x16
	OpLsh64x32
	OpLsh64x64
	OpRsh8x8
	OpRsh8x16
	OpRsh8x32
	OpRsh8x64
	OpRsh16x8
	OpRsh16x16
	OpRsh16x32
	OpRsh16x64
	OpRsh32x8
	OpRsh32x16
	OpRsh32x32
	OpRsh32x64
	OpRsh64x8
	OpRsh64x16
	OpRsh64x32
	OpRsh64x64
	OpRsh8Ux8
	OpRsh8Ux16
	OpRsh8Ux32
	OpRsh8Ux64
	OpRsh16Ux8
	OpRsh16Ux16
	OpRsh16Ux32
	OpRsh16Ux64
	OpRsh32Ux8
	OpRsh32Ux16
	OpRsh32Ux32
	OpRsh32Ux64
	OpRsh64Ux8
	OpRsh64Ux16
	OpRsh64Ux32
	OpRsh64Ux64
	OpEq8
	OpEq16
	OpEq32
	OpEq64
	OpEqPtr
	OpEqInter
	OpEqSlice
	OpEq32F
	OpEq64F
	OpNeq8
	OpNeq16
	OpNeq32
	OpNeq64
	OpNeqPtr
	OpNeqInter
	OpNeqSlice
	OpNeq32F
	OpNeq64F
	OpLess8
	OpLess8U
	OpLess16
	OpLess16U
	OpLess32
	OpLess32U
	OpLess64
	OpLess64U
	OpLess32F
	OpLess64F
	OpLeq8
	OpLeq8U
	OpLeq16
	OpLeq16U
	OpLeq32
	OpLeq32U
	OpLeq64
	OpLeq64U
	OpLeq32F
	OpLeq64F
	OpGreater8
	OpGreater8U
	OpGreater16
	OpGreater16U
	OpGreater32
	OpGreater32U
	OpGreater64
	OpGreater64U
	OpGreater32F
	OpGreater64F
	OpGeq8
	OpGeq8U
	OpGeq16
	OpGeq16U
	OpGeq32
	OpGeq32U
	OpGeq64
	OpGeq64U
	OpGeq32F
	OpGeq64F
	OpCondSelect
	OpAndB
	OpOrB
	OpEqB
	OpNeqB
	OpNot
	OpNeg8
	OpNeg16
	OpNeg32
	OpNeg64
	OpNeg32F
	OpNeg64F
	OpCom8
	OpCom16
	OpCom32
	OpCom64
	OpCtz8
	OpCtz16
	OpCtz32
	OpCtz64
	OpCtz8NonZero
	OpCtz16NonZero
	OpCtz32NonZero
	OpCtz64NonZero
	OpBitLen8
	OpBitLen16
	OpBitLen32
	OpBitLen64
	OpBswap32
	OpBswap64
	OpBitRev8
	OpBitRev16
	OpBitRev32
	OpBitRev64
	OpPopCount8
	OpPopCount16
	OpPopCount32
	OpPopCount64
	OpRotateLeft8
	OpRotateLeft16
	OpRotateLeft32
	OpRotateLeft64
	OpSqrt
	OpFloor
	OpCeil
	OpTrunc
	OpRound
	OpRoundToEven
	OpAbs
	OpCopysign
	OpPhi
	OpCopy
	OpConvert
	OpConstBool
	OpConstString
	OpConstNil
	OpConst8
	OpConst16
	OpConst32
	OpConst64
	OpConst32F
	OpConst64F
	OpConstInterface
	OpConstSlice
	OpInitMem
	OpArg
	OpAddr
	OpLocalAddr
	OpSP
	OpSB
	OpLoad
	OpStore
	OpMove
	OpZero
	OpStoreWB
	OpMoveWB
	OpZeroWB
	OpWB
	OpClosureCall
	OpStaticCall
	OpInterCall
	OpSignExt8to16
	OpSignExt8to32
	OpSignExt8to64
	OpSignExt16to32
	OpSignExt16to64
	OpSignExt32to64
	OpZeroExt8to16
	OpZeroExt8to32
	OpZeroExt8to64
	OpZeroExt16to32
	OpZeroExt16to64
	OpZeroExt32to64
	OpTrunc16to8
	OpTrunc32to8
	OpTrunc32to16
	OpTrunc64to8
	OpTrunc64to16
	OpTrunc64to32
	OpCvt32to32F
	OpCvt32to64F
	OpCvt64to32F
	OpCvt64to64F
	OpCvt32Fto32
	OpCvt32Fto64
	OpCvt64Fto32
	OpCvt64Fto64
	OpCvt32Fto64F
	OpCvt64Fto32F
	OpRound32F
	OpRound64F
	OpIsNonNil
	OpIsInBounds
	OpIsSliceInBounds
	OpNilCheck
	OpGetG
	OpGetClosurePtr
	OpGetCallerPC
	OpGetCallerSP
	OpPtrIndex
	OpOffPtr
	OpSliceMake
	OpSlicePtr
	OpSliceLen
	OpSliceCap
	OpComplexMake
	OpComplexReal
	OpComplexImag
	OpStringMake
	OpStringPtr
	OpStringLen
	OpIMake
	OpITab
	OpIData
	OpStructMake0
	OpStructMake1
	OpStructMake2
	OpStructMake3
	OpStructMake4
	OpStructSelect
	OpArrayMake0
	OpArrayMake1
	OpArraySelect
	OpStoreReg
	OpLoadReg
	OpFwdRef
	OpUnknown
	OpVarDef
	OpVarKill
	OpVarLive
	OpKeepAlive
	OpInlMark
	OpInt64Make
	OpInt64Hi
	OpInt64Lo
	OpAdd32carry
	OpAdd32withcarry
	OpSub32carry
	OpSub32withcarry
	OpAdd64carry
	OpSub64borrow
	OpSignmask
	OpZeromask
	OpSlicemask
	OpCvt32Uto32F
	OpCvt32Uto64F
	OpCvt32Fto32U
	OpCvt64Fto32U
	OpCvt64Uto32F
	OpCvt64Uto64F
	OpCvt32Fto64U
	OpCvt64Fto64U
	OpSelect0
	OpSelect1
	OpAtomicLoad32
	OpAtomicLoad64
	OpAtomicLoadPtr
	OpAtomicLoadAcq32
	OpAtomicStore32
	OpAtomicStore64
	OpAtomicStorePtrNoWB
	OpAtomicStoreRel32
	OpAtomicExchange32
	OpAtomicExchange64
	OpAtomicAdd32
	OpAtomicAdd64
	OpAtomicCompareAndSwap32
	OpAtomicCompareAndSwap64
	OpAtomicCompareAndSwapRel32
	OpAtomicAnd8
	OpAtomicOr8
	OpAtomicAdd32Variant
	OpAtomicAdd64Variant
	OpClobber
)

func StructMakeOp

func StructMakeOp(nf int) Op

StructMakeOp returns the opcode to construct a struct with the given number of fields.

func (Op) Asm

func (o Op) Asm() obj.As

func (Op) IsCall

func (o Op) IsCall() bool

func (Op) String

func (o Op) String() string

func (Op) SymEffect

func (o Op) SymEffect() SymEffect

func (Op) UsesScratch

func (o Op) UsesScratch() bool

type RBTint32

type RBTint32 struct {
	// contains filtered or unexported fields
}

RBTint32 is a red-black tree with data stored at internal nodes, following Tarjan, Data Structures and Network Algorithms, pp 48-52, using explicit rank instead of red and black. Deletion is not yet implemented because it is not yet needed. Extra operations glb, lub, glbEq, lubEq are provided for use in sparse lookup algorithms.

func (*RBTint32) Find

func (t *RBTint32) Find(key int32) interface{}

Find returns the data associated with key in the tree, or nil if key is not in the tree.

func (*RBTint32) Glb

func (t *RBTint32) Glb(x int32) (k int32, d interface{})

Glb returns the greatest-lower-bound-exclusive of x and its associated data. If x has no glb in the tree, then (0, nil) is returned.

func (*RBTint32) GlbEq

func (t *RBTint32) GlbEq(x int32) (k int32, d interface{})

GlbEq returns the greatest-lower-bound-inclusive of x and its associated data. If x has no glbEQ in the tree, then (0, nil) is returned.

func (*RBTint32) Insert

func (t *RBTint32) Insert(key int32, data interface{}) interface{}

Insert adds key to the tree and associates key with data. If key was already in the tree, it updates the associated data. Insert returns the previous data associated with key, or nil if key was not present. Insert panics if data is nil.

func (*RBTint32) IsEmpty

func (t *RBTint32) IsEmpty() bool

IsEmpty reports whether t is empty.

func (*RBTint32) IsSingle

func (t *RBTint32) IsSingle() bool

IsSingle reports whether t is a singleton (leaf).

func (*RBTint32) Lub

func (t *RBTint32) Lub(x int32) (k int32, d interface{})

Lub returns the least-upper-bound-exclusive of x and its associated data. If x has no lub in the tree, then (0, nil) is returned.

func (*RBTint32) LubEq

func (t *RBTint32) LubEq(x int32) (k int32, d interface{})

LubEq returns the least-upper-bound-inclusive of x and its associated data. If x has no lubEq in the tree, then (0, nil) is returned.

func (*RBTint32) Max

func (t *RBTint32) Max() (k int32, d interface{})

Max returns the maximum element of t and its associated data. If t is empty, then (0, nil) is returned.

func (*RBTint32) Min

func (t *RBTint32) Min() (k int32, d interface{})

Min returns the minimum element of t and its associated data. If t is empty, then (0, nil) is returned.

func (*RBTint32) String

func (t *RBTint32) String() string

func (*RBTint32) VisitInOrder

func (t *RBTint32) VisitInOrder(f func(int32, interface{}))

VisitInOrder applies f to the key and data pairs in t, with keys ordered from smallest to largest.

type Register

type Register struct {
	// contains filtered or unexported fields
}

A Register is a machine register, like AX. They are numbered densely from 0 (for each architecture).

func (*Register) GCNum

func (r *Register) GCNum() int16

GCNum returns the runtime GC register index of r, or -1 if this register can't contain pointers.

func (*Register) ObjNum

func (r *Register) ObjNum() int16

ObjNum returns the register number from cmd/internal/obj/$ARCH that corresponds to this register.

func (*Register) String

func (r *Register) String() string

type RegisterSet

type RegisterSet uint64

RegisterSet is a bitmap of registers, indexed by Register.num.

type SlotID

type SlotID int32

type SparseTree

type SparseTree []SparseTreeNode

A SparseTree is a tree of Blocks. It allows rapid ancestor queries, such as whether one block dominates another.

func (SparseTree) Child

func (t SparseTree) Child(x *Block) *Block

Child returns a child of x in the dominator tree, or nil if there are none. The choice of first child is arbitrary but repeatable.

func (SparseTree) Sibling

func (t SparseTree) Sibling(x *Block) *Block

Sibling returns a sibling of x in the dominator tree (i.e., a node with the same immediate dominator) or nil if there are no remaining siblings in the arbitrary but repeatable order chosen. Because the Child-Sibling order is used to assign entry and exit numbers in the treewalk, those numbers are also consistent with this order (i.e., Sibling(x) has entry number larger than x's exit number).

type SparseTreeHelper

type SparseTreeHelper struct {
	Sdom   []SparseTreeNode // indexed by block.ID
	Po     []*Block         // exported data; the blocks, in a post-order
	Dom    []*Block         // exported data; the dominator of this block.
	Ponums []int32          // exported data; Po[Ponums[b.ID]] == b; the index of b in Po
}

A SparseTreeHelper contains indexing and allocation data structures common to a collection of SparseTreeMaps, as well as exposing some useful control-flow-related data to other packages, such as gc.

func NewSparseTreeHelper

func NewSparseTreeHelper(f *Func) *SparseTreeHelper

NewSparseTreeHelper returns a SparseTreeHelper for use in the gc package, for example in phi-function placement.

func (*SparseTreeHelper) NewTree

func (h *SparseTreeHelper) NewTree() *SparseTreeMap

type SparseTreeMap

type SparseTreeMap RBTint32

A SparseTreeMap encodes a subset of nodes within a tree used for sparse-ancestor queries.

Combined with a SparseTreeHelper, this supports an Insert to add a tree node to the set and a Find operation to locate the nearest tree ancestor of a given node such that the ancestor is also in the set.

Given a set of blocks {B1, B2, B3} within the dominator tree, established by stm.Insert()ing B1, B2, B3, etc, a query at block B (performed with stm.Find(stm, B, adjust, helper)) will return the member of the set that is the nearest strict ancestor of B within the dominator tree, or nil if none exists. The expected complexity of this operation is the log of the size the set, given certain assumptions about sparsity (the log complexity could be guaranteed with additional data structures whose constant- factor overhead has not yet been justified.)

The adjust parameter allows positioning of the insertion and lookup points within a block -- one of AdjustBefore, AdjustWithin, AdjustAfter, where lookups at AdjustWithin can find insertions at AdjustBefore in the same block, and lookups at AdjustAfter can find insertions at either AdjustBefore or AdjustWithin in the same block. (Note that this assumes a gappy numbering such that exit number or exit number is separated from its nearest neighbor by at least 3).

The Sparse Tree lookup algorithm is described by Paul F. Dietz. Maintaining order in a linked list. In Proceedings of the Fourteenth Annual ACM Symposium on Theory of Computing, pages 122–127, May 1982. and by Ben Wegbreit. Faster retrieval from context trees. Communications of the ACM, 19(9):526–529, September 1976.

func (*SparseTreeMap) Find

func (m *SparseTreeMap) Find(b *Block, adjust int32, helper *SparseTreeHelper) interface{}

Find returns the definition visible from block b, or nil if none can be found. Adjust indicates where the block should be searched. AdjustBefore searches before the phi functions of b. AdjustWithin searches starting at the phi functions of b. AdjustAfter searches starting at the exit from the block, including normal within-block definitions.

Note that Finds are properly nested with Inserts: m.Insert(b, a) followed by m.Find(b, a) will not return the result of the insert, but m.Insert(b, AdjustBefore) followed by m.Find(b, AdjustWithin) will.

Another way to think of this is that Find searches for inputs, Insert defines outputs.

func (*SparseTreeMap) Insert

func (m *SparseTreeMap) Insert(b *Block, adjust int32, x interface{}, helper *SparseTreeHelper)

Insert creates a definition within b with data x. adjust indicates where in the block should be inserted: AdjustBefore means defined at a phi function (visible Within or After in the same block) AdjustWithin means defined within the block (visible After in the same block) AdjustAfter means after the block (visible within child blocks)

func (*SparseTreeMap) String

func (m *SparseTreeMap) String() string

type SparseTreeNode

type SparseTreeNode struct {
	// contains filtered or unexported fields
}

func (*SparseTreeNode) Entry

func (s *SparseTreeNode) Entry() int32

func (*SparseTreeNode) Exit

func (s *SparseTreeNode) Exit() int32

func (*SparseTreeNode) String

func (s *SparseTreeNode) String() string

type StackOffset

type StackOffset int32

StackOffset encodes whether a value is on the stack and if so, where. It is a 31-bit integer followed by a presence flag at the low-order bit.

type StorageClass

type StorageClass uint8
const (
	ClassAuto     StorageClass = iota // local stack variable
	ClassParam                        // argument
	ClassParamOut                     // return value
)

type SymEffect

type SymEffect int8

A SymEffect describes the effect that an SSA Value has on the variable identified by the symbol in its Aux field.

const (
	SymRead SymEffect = 1 << iota
	SymWrite
	SymAddr

	SymRdWr = SymRead | SymWrite

	SymNone SymEffect = 0
)

type Types

type Types struct {
	Bool       *types.Type
	Int8       *types.Type
	Int16      *types.Type
	Int32      *types.Type
	Int64      *types.Type
	UInt8      *types.Type
	UInt16     *types.Type
	UInt32     *types.Type
	UInt64     *types.Type
	Int        *types.Type
	Float32    *types.Type
	Float64    *types.Type
	UInt       *types.Type
	Uintptr    *types.Type
	String     *types.Type
	BytePtr    *types.Type // TODO: use unsafe.Pointer instead?
	Int32Ptr   *types.Type
	UInt32Ptr  *types.Type
	IntPtr     *types.Type
	UintptrPtr *types.Type
	Float32Ptr *types.Type
	Float64Ptr *types.Type
	BytePtrPtr *types.Type
}

func NewTypes

func NewTypes() *Types

NewTypes creates and populates a Types.

func (*Types) SetTypPtrs

func (t *Types) SetTypPtrs()

SetTypPtrs populates t.

type ValAndOff

type ValAndOff int64

A ValAndOff is used by the several opcodes. It holds both a value and a pointer offset. A ValAndOff is intended to be encoded into an AuxInt field. The zero ValAndOff encodes a value of 0 and an offset of 0. The high 32 bits hold a value. The low 32 bits hold a pointer offset.

func (ValAndOff) Int64

func (x ValAndOff) Int64() int64

func (ValAndOff) Off

func (x ValAndOff) Off() int64

func (ValAndOff) String

func (x ValAndOff) String() string

func (ValAndOff) Val

func (x ValAndOff) Val() int64

type ValHeap

type ValHeap struct {
	// contains filtered or unexported fields
}

func (ValHeap) Len

func (h ValHeap) Len() int

func (ValHeap) Less

func (h ValHeap) Less(i, j int) bool

func (*ValHeap) Pop

func (h *ValHeap) Pop() interface{}

func (*ValHeap) Push

func (h *ValHeap) Push(x interface{})

func (ValHeap) Swap

func (h ValHeap) Swap(i, j int)

type Value

type Value struct {
	// A unique identifier for the value. For performance we allocate these IDs
	// densely starting at 1.  There is no guarantee that there won't be occasional holes, though.
	ID ID

	// The operation that computes this value. See op.go.
	Op Op

	// The type of this value. Normally this will be a Go type, but there
	// are a few other pseudo-types, see ../types/type.go.
	Type *types.Type

	// Auxiliary info for this value. The type of this information depends on the opcode and type.
	// AuxInt is used for integer values, Aux is used for other values.
	// Floats are stored in AuxInt using math.Float64bits(f).
	// Unused portions of AuxInt are filled by sign-extending the used portion,
	// even if the represented value is unsigned.
	// Users of AuxInt which interpret AuxInt as unsigned (e.g. shifts) must be careful.
	// Use Value.AuxUnsigned to get the zero-extended value of AuxInt.
	AuxInt int64
	Aux    interface{}

	// Arguments of this value
	Args []*Value

	// Containing basic block
	Block *Block

	// Source position
	Pos src.XPos

	// Use count. Each appearance in Value.Args and Block.Control counts once.
	Uses int32

	// wasm: Value stays on the WebAssembly stack. This value will not get a "register" (WebAssembly variable)
	// nor a slot on Go stack, and the generation of this value is delayed to its use time.
	OnWasmStack bool
	// contains filtered or unexported fields
}

A Value represents a value in the SSA representation of the program. The ID and Type fields must not be modified. The remainder may be modified if they preserve the value of the Value (e.g. changing a (mul 2 x) to an (add x x)).

func (*Value) AddArg

func (v *Value) AddArg(w *Value)

If/when midstack inlining is enabled (-l=4), the compiler gets both larger and slower. Not-inlining this method is a help (*Value.reset and *Block.NewValue0 are similar).

func (*Value) AddArgs

func (v *Value) AddArgs(a ...*Value)

func (*Value) AuxFloat

func (v *Value) AuxFloat() float64

func (*Value) AuxInt16

func (v *Value) AuxInt16() int16

func (*Value) AuxInt32

func (v *Value) AuxInt32() int32

func (*Value) AuxInt8

func (v *Value) AuxInt8() int8

func (*Value) AuxUnsigned

func (v *Value) AuxUnsigned() uint64

AuxUnsigned returns v.AuxInt as an unsigned value for OpConst*. v.AuxInt is always sign-extended to 64 bits, even if the represented value is unsigned. This undoes that sign extension.

func (*Value) AuxValAndOff

func (v *Value) AuxValAndOff() ValAndOff

func (*Value) Fatalf

func (v *Value) Fatalf(msg string, args ...interface{})

func (*Value) HTML

func (v *Value) HTML() string

func (*Value) LackingPos

func (v *Value) LackingPos() bool

LackingPos indicates whether v is a value that is unlikely to have a correct position assigned to it. Ignoring such values leads to more user-friendly positions assigned to nearby values and the blocks containing them.

func (*Value) Log

func (v *Value) Log() bool

func (*Value) Logf

func (v *Value) Logf(msg string, args ...interface{})

func (*Value) LongHTML

func (v *Value) LongHTML() string

func (*Value) LongString

func (v *Value) LongString() string

long form print. v# = opcode <type> [aux] args [: reg] (names)

func (*Value) MemoryArg

func (v *Value) MemoryArg() *Value

MemoryArg returns the memory argument for the Value. The returned value, if non-nil, will be memory-typed (or a tuple with a memory-typed second part). Otherwise, nil is returned.

func (*Value) Reg

func (v *Value) Reg() int16

Reg returns the register assigned to v, in cmd/internal/obj/$ARCH numbering.

func (*Value) Reg0

func (v *Value) Reg0() int16

Reg0 returns the register assigned to the first output of v, in cmd/internal/obj/$ARCH numbering.

func (*Value) Reg1

func (v *Value) Reg1() int16

Reg1 returns the register assigned to the second output of v, in cmd/internal/obj/$ARCH numbering.

func (*Value) RegName

func (v *Value) RegName() string

func (*Value) RemoveArg

func (v *Value) RemoveArg(i int)

func (*Value) SetArg

func (v *Value) SetArg(i int, w *Value)

func (*Value) SetArgs1

func (v *Value) SetArgs1(a *Value)

func (*Value) SetArgs2

func (v *Value) SetArgs2(a *Value, b *Value)

func (*Value) String

func (v *Value) String() string

short form print. Just v#.

type VarID

type VarID int32

type VarLoc

type VarLoc struct {
	// The registers this variable is available in. There can be more than
	// one in various situations, e.g. it's being moved between registers.
	Registers RegisterSet

	StackOffset
}

A VarLoc describes the storage for part of a user variable.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL