package ssa
import (
"fmt"
"math"
"strings"
"github.com/tetratelabs/wazero/internal/engine/wazevo/wazevoapi"
)
type Opcode uint32
type Instruction struct {
id int
opcode Opcode
u1, u2 uint64
v Value
v2 Value
v3 Value
vs Values
typ Type
prev, next *Instruction
rValue Value
rValues Values
gid InstructionGroupID
sourceOffset SourceOffset
live bool
alreadyLowered bool
}
type SourceOffset int64
const sourceOffsetUnknown = -1
func (l SourceOffset ) Valid () bool {
return l != sourceOffsetUnknown
}
func (i *Instruction ) annotateSourceOffset (line SourceOffset ) {
i .sourceOffset = line
}
func (i *Instruction ) SourceOffset () SourceOffset {
return i .sourceOffset
}
func (i *Instruction ) Opcode () Opcode {
return i .opcode
}
func (i *Instruction ) GroupID () InstructionGroupID {
return i .gid
}
func (i *Instruction ) MarkLowered () {
i .alreadyLowered = true
}
func (i *Instruction ) Lowered () bool {
return i .alreadyLowered
}
func resetInstruction(i *Instruction ) {
*i = Instruction {}
i .v = ValueInvalid
i .v2 = ValueInvalid
i .v3 = ValueInvalid
i .rValue = ValueInvalid
i .typ = typeInvalid
i .vs = ValuesNil
i .sourceOffset = sourceOffsetUnknown
}
type InstructionGroupID uint32
func (i *Instruction ) Returns () (first Value , rest []Value ) {
if i .IsBranching () {
return ValueInvalid , nil
}
return i .rValue , i .rValues .View ()
}
func (i *Instruction ) Return () (first Value ) {
return i .rValue
}
func (i *Instruction ) Args () (v1 , v2 , v3 Value , vs []Value ) {
return i .v , i .v2 , i .v3 , i .vs .View ()
}
func (i *Instruction ) Arg () Value {
return i .v
}
func (i *Instruction ) Arg2 () (Value , Value ) {
return i .v , i .v2
}
func (i *Instruction ) ArgWithLane () (Value , VecLane ) {
return i .v , VecLane (i .u1 )
}
func (i *Instruction ) Arg2WithLane () (Value , Value , VecLane ) {
return i .v , i .v2 , VecLane (i .u1 )
}
func (i *Instruction ) ShuffleData () (v Value , v2 Value , lo uint64 , hi uint64 ) {
return i .v , i .v2 , i .u1 , i .u2
}
func (i *Instruction ) Arg3 () (Value , Value , Value ) {
return i .v , i .v2 , i .v3
}
func (i *Instruction ) Next () *Instruction {
return i .next
}
func (i *Instruction ) Prev () *Instruction {
return i .prev
}
func (i *Instruction ) IsBranching () bool {
switch i .opcode {
case OpcodeJump , OpcodeBrz , OpcodeBrnz , OpcodeBrTable :
return true
default :
return false
}
}
const (
OpcodeInvalid Opcode = iota
OpcodeUndefined
OpcodeJump
OpcodeBrz
OpcodeBrnz
OpcodeBrTable
OpcodeExitWithCode
OpcodeExitIfTrueWithCode
OpcodeReturn
OpcodeCall
OpcodeCallIndirect
OpcodeSplat
OpcodeSwizzle
OpcodeInsertlane
OpcodeExtractlane
OpcodeLoad
OpcodeStore
OpcodeUload8
OpcodeSload8
OpcodeIstore8
OpcodeUload16
OpcodeSload16
OpcodeIstore16
OpcodeUload32
OpcodeSload32
OpcodeIstore32
OpcodeLoadSplat
OpcodeVZeroExtLoad
OpcodeIconst
OpcodeF32const
OpcodeF64const
OpcodeVconst
OpcodeVbor
OpcodeVbxor
OpcodeVband
OpcodeVbandnot
OpcodeVbnot
OpcodeVbitselect
OpcodeShuffle
OpcodeSelect
OpcodeVanyTrue
OpcodeVallTrue
OpcodeVhighBits
OpcodeIcmp
OpcodeVIcmp
OpcodeIcmpImm
OpcodeIadd
OpcodeVIadd
OpcodeVSaddSat
OpcodeVUaddSat
OpcodeIsub
OpcodeVIsub
OpcodeVSsubSat
OpcodeVUsubSat
OpcodeVImin
OpcodeVUmin
OpcodeVImax
OpcodeVUmax
OpcodeVAvgRound
OpcodeVImul
OpcodeVIneg
OpcodeVIpopcnt
OpcodeVIabs
OpcodeVIshl
OpcodeVUshr
OpcodeVSshr
OpcodeVFabs
OpcodeVFmax
OpcodeVFmin
OpcodeVFneg
OpcodeVFadd
OpcodeVFsub
OpcodeVFmul
OpcodeVFdiv
OpcodeVFcmp
OpcodeVCeil
OpcodeVFloor
OpcodeVTrunc
OpcodeVNearest
OpcodeVMaxPseudo
OpcodeVMinPseudo
OpcodeVSqrt
OpcodeVFcvtToUintSat
OpcodeVFcvtToSintSat
OpcodeVFcvtFromUint
OpcodeVFcvtFromSint
OpcodeImul
OpcodeUdiv
OpcodeSdiv
OpcodeUrem
OpcodeSrem
OpcodeBand
OpcodeBor
OpcodeBxor
OpcodeBnot
OpcodeRotl
OpcodeRotr
OpcodeIshl
OpcodeUshr
OpcodeSshr
OpcodeClz
OpcodeCtz
OpcodePopcnt
OpcodeFcmp
OpcodeFadd
OpcodeFsub
OpcodeFmul
OpcodeSqmulRoundSat
OpcodeFdiv
OpcodeSqrt
OpcodeFneg
OpcodeFabs
OpcodeFcopysign
OpcodeFmin
OpcodeFmax
OpcodeCeil
OpcodeFloor
OpcodeTrunc
OpcodeNearest
OpcodeBitcast
OpcodeIreduce
OpcodeSnarrow
OpcodeUnarrow
OpcodeSwidenLow
OpcodeSwidenHigh
OpcodeUwidenLow
OpcodeUwidenHigh
OpcodeExtIaddPairwise
OpcodeWideningPairwiseDotProductS
OpcodeUExtend
OpcodeSExtend
OpcodeFpromote
OpcodeFvpromoteLow
OpcodeFdemote
OpcodeFvdemote
OpcodeFcvtToUint
OpcodeFcvtToSint
OpcodeFcvtToUintSat
OpcodeFcvtToSintSat
OpcodeFcvtFromUint
OpcodeFcvtFromSint
OpcodeAtomicRmw
OpcodeAtomicCas
OpcodeAtomicLoad
OpcodeAtomicStore
OpcodeFence
OpcodeTailCallReturnCall
OpcodeTailCallReturnCallIndirect
opcodeEnd
)
type AtomicRmwOp byte
const (
AtomicRmwOpAdd AtomicRmwOp = iota
AtomicRmwOpSub
AtomicRmwOpAnd
AtomicRmwOpOr
AtomicRmwOpXor
AtomicRmwOpXchg
)
func (op AtomicRmwOp ) String () string {
switch op {
case AtomicRmwOpAdd :
return "add"
case AtomicRmwOpSub :
return "sub"
case AtomicRmwOpAnd :
return "and"
case AtomicRmwOpOr :
return "or"
case AtomicRmwOpXor :
return "xor"
case AtomicRmwOpXchg :
return "xchg"
}
panic (fmt .Sprintf ("unknown AtomicRmwOp: %d" , op ))
}
type returnTypesFn func (b *builder , instr *Instruction ) (t1 Type , ts []Type )
var (
returnTypesFnNoReturns returnTypesFn = func (b *builder , instr *Instruction ) (t1 Type , ts []Type ) { return typeInvalid , nil }
returnTypesFnSingle = func (b *builder , instr *Instruction ) (t1 Type , ts []Type ) { return instr .typ , nil }
returnTypesFnI32 = func (b *builder , instr *Instruction ) (t1 Type , ts []Type ) { return TypeI32 , nil }
returnTypesFnF32 = func (b *builder , instr *Instruction ) (t1 Type , ts []Type ) { return TypeF32 , nil }
returnTypesFnF64 = func (b *builder , instr *Instruction ) (t1 Type , ts []Type ) { return TypeF64 , nil }
returnTypesFnV128 = func (b *builder , instr *Instruction ) (t1 Type , ts []Type ) { return TypeV128 , nil }
returnTypesFnCallIndirect = func (b *builder , instr *Instruction ) (t1 Type , ts []Type ) {
sigID := SignatureID (instr .u1 )
sig , ok := b .signatures [sigID ]
if !ok {
panic ("BUG" )
}
switch len (sig .Results ) {
case 0 :
t1 = typeInvalid
case 1 :
t1 = sig .Results [0 ]
default :
t1 , ts = sig .Results [0 ], sig .Results [1 :]
}
return
}
returnTypesFnCall = func (b *builder , instr *Instruction ) (t1 Type , ts []Type ) {
sigID := SignatureID (instr .u2 )
sig , ok := b .signatures [sigID ]
if !ok {
panic ("BUG" )
}
switch len (sig .Results ) {
case 0 :
t1 = typeInvalid
case 1 :
t1 = sig .Results [0 ]
default :
t1 , ts = sig .Results [0 ], sig .Results [1 :]
}
return
}
)
type sideEffect byte
const (
sideEffectUnknown sideEffect = iota
sideEffectStrict
sideEffectTraps
sideEffectNone
)
var instructionSideEffects = [opcodeEnd ]sideEffect {
OpcodeUndefined : sideEffectStrict ,
OpcodeJump : sideEffectStrict ,
OpcodeIconst : sideEffectNone ,
OpcodeCall : sideEffectStrict ,
OpcodeCallIndirect : sideEffectStrict ,
OpcodeIadd : sideEffectNone ,
OpcodeImul : sideEffectNone ,
OpcodeIsub : sideEffectNone ,
OpcodeIcmp : sideEffectNone ,
OpcodeExtractlane : sideEffectNone ,
OpcodeInsertlane : sideEffectNone ,
OpcodeBand : sideEffectNone ,
OpcodeBor : sideEffectNone ,
OpcodeBxor : sideEffectNone ,
OpcodeRotl : sideEffectNone ,
OpcodeRotr : sideEffectNone ,
OpcodeFcmp : sideEffectNone ,
OpcodeFadd : sideEffectNone ,
OpcodeClz : sideEffectNone ,
OpcodeCtz : sideEffectNone ,
OpcodePopcnt : sideEffectNone ,
OpcodeLoad : sideEffectNone ,
OpcodeLoadSplat : sideEffectNone ,
OpcodeUload8 : sideEffectNone ,
OpcodeUload16 : sideEffectNone ,
OpcodeUload32 : sideEffectNone ,
OpcodeSload8 : sideEffectNone ,
OpcodeSload16 : sideEffectNone ,
OpcodeSload32 : sideEffectNone ,
OpcodeSExtend : sideEffectNone ,
OpcodeUExtend : sideEffectNone ,
OpcodeSwidenLow : sideEffectNone ,
OpcodeUwidenLow : sideEffectNone ,
OpcodeSwidenHigh : sideEffectNone ,
OpcodeUwidenHigh : sideEffectNone ,
OpcodeSnarrow : sideEffectNone ,
OpcodeUnarrow : sideEffectNone ,
OpcodeSwizzle : sideEffectNone ,
OpcodeShuffle : sideEffectNone ,
OpcodeSplat : sideEffectNone ,
OpcodeFsub : sideEffectNone ,
OpcodeF32const : sideEffectNone ,
OpcodeF64const : sideEffectNone ,
OpcodeIshl : sideEffectNone ,
OpcodeSshr : sideEffectNone ,
OpcodeUshr : sideEffectNone ,
OpcodeStore : sideEffectStrict ,
OpcodeIstore8 : sideEffectStrict ,
OpcodeIstore16 : sideEffectStrict ,
OpcodeIstore32 : sideEffectStrict ,
OpcodeExitWithCode : sideEffectStrict ,
OpcodeExitIfTrueWithCode : sideEffectStrict ,
OpcodeReturn : sideEffectStrict ,
OpcodeBrz : sideEffectStrict ,
OpcodeBrnz : sideEffectStrict ,
OpcodeBrTable : sideEffectStrict ,
OpcodeFdiv : sideEffectNone ,
OpcodeFmul : sideEffectNone ,
OpcodeFmax : sideEffectNone ,
OpcodeSqmulRoundSat : sideEffectNone ,
OpcodeSelect : sideEffectNone ,
OpcodeFmin : sideEffectNone ,
OpcodeFneg : sideEffectNone ,
OpcodeFcvtToSint : sideEffectTraps ,
OpcodeFcvtToUint : sideEffectTraps ,
OpcodeFcvtFromSint : sideEffectNone ,
OpcodeFcvtFromUint : sideEffectNone ,
OpcodeFcvtToSintSat : sideEffectNone ,
OpcodeFcvtToUintSat : sideEffectNone ,
OpcodeVFcvtFromUint : sideEffectNone ,
OpcodeVFcvtFromSint : sideEffectNone ,
OpcodeFdemote : sideEffectNone ,
OpcodeFvpromoteLow : sideEffectNone ,
OpcodeFvdemote : sideEffectNone ,
OpcodeFpromote : sideEffectNone ,
OpcodeBitcast : sideEffectNone ,
OpcodeIreduce : sideEffectNone ,
OpcodeSqrt : sideEffectNone ,
OpcodeCeil : sideEffectNone ,
OpcodeFloor : sideEffectNone ,
OpcodeTrunc : sideEffectNone ,
OpcodeNearest : sideEffectNone ,
OpcodeSdiv : sideEffectTraps ,
OpcodeSrem : sideEffectTraps ,
OpcodeUdiv : sideEffectTraps ,
OpcodeUrem : sideEffectTraps ,
OpcodeFabs : sideEffectNone ,
OpcodeFcopysign : sideEffectNone ,
OpcodeExtIaddPairwise : sideEffectNone ,
OpcodeVconst : sideEffectNone ,
OpcodeVbor : sideEffectNone ,
OpcodeVbxor : sideEffectNone ,
OpcodeVband : sideEffectNone ,
OpcodeVbandnot : sideEffectNone ,
OpcodeVbnot : sideEffectNone ,
OpcodeVbitselect : sideEffectNone ,
OpcodeVanyTrue : sideEffectNone ,
OpcodeVallTrue : sideEffectNone ,
OpcodeVhighBits : sideEffectNone ,
OpcodeVIadd : sideEffectNone ,
OpcodeVSaddSat : sideEffectNone ,
OpcodeVUaddSat : sideEffectNone ,
OpcodeVIsub : sideEffectNone ,
OpcodeVSsubSat : sideEffectNone ,
OpcodeVUsubSat : sideEffectNone ,
OpcodeVIcmp : sideEffectNone ,
OpcodeVImin : sideEffectNone ,
OpcodeVUmin : sideEffectNone ,
OpcodeVImax : sideEffectNone ,
OpcodeVUmax : sideEffectNone ,
OpcodeVAvgRound : sideEffectNone ,
OpcodeVImul : sideEffectNone ,
OpcodeVIabs : sideEffectNone ,
OpcodeVIneg : sideEffectNone ,
OpcodeVIpopcnt : sideEffectNone ,
OpcodeVIshl : sideEffectNone ,
OpcodeVSshr : sideEffectNone ,
OpcodeVUshr : sideEffectNone ,
OpcodeVSqrt : sideEffectNone ,
OpcodeVFabs : sideEffectNone ,
OpcodeVFmin : sideEffectNone ,
OpcodeVFmax : sideEffectNone ,
OpcodeVFneg : sideEffectNone ,
OpcodeVFadd : sideEffectNone ,
OpcodeVFsub : sideEffectNone ,
OpcodeVFmul : sideEffectNone ,
OpcodeVFdiv : sideEffectNone ,
OpcodeVFcmp : sideEffectNone ,
OpcodeVCeil : sideEffectNone ,
OpcodeVFloor : sideEffectNone ,
OpcodeVTrunc : sideEffectNone ,
OpcodeVNearest : sideEffectNone ,
OpcodeVMaxPseudo : sideEffectNone ,
OpcodeVMinPseudo : sideEffectNone ,
OpcodeVFcvtToUintSat : sideEffectNone ,
OpcodeVFcvtToSintSat : sideEffectNone ,
OpcodeVZeroExtLoad : sideEffectNone ,
OpcodeAtomicRmw : sideEffectStrict ,
OpcodeAtomicLoad : sideEffectStrict ,
OpcodeAtomicStore : sideEffectStrict ,
OpcodeAtomicCas : sideEffectStrict ,
OpcodeFence : sideEffectStrict ,
OpcodeTailCallReturnCall : sideEffectStrict ,
OpcodeTailCallReturnCallIndirect : sideEffectStrict ,
OpcodeWideningPairwiseDotProductS : sideEffectNone ,
}
func (i *Instruction ) sideEffect () sideEffect {
if e := instructionSideEffects [i .opcode ]; e == sideEffectUnknown {
panic ("BUG: side effect info not registered for " + i .opcode .String ())
} else {
return e
}
}
var instructionReturnTypes = [opcodeEnd ]returnTypesFn {
OpcodeExtIaddPairwise : returnTypesFnV128 ,
OpcodeVbor : returnTypesFnV128 ,
OpcodeVbxor : returnTypesFnV128 ,
OpcodeVband : returnTypesFnV128 ,
OpcodeVbnot : returnTypesFnV128 ,
OpcodeVbandnot : returnTypesFnV128 ,
OpcodeVbitselect : returnTypesFnV128 ,
OpcodeVanyTrue : returnTypesFnI32 ,
OpcodeVallTrue : returnTypesFnI32 ,
OpcodeVhighBits : returnTypesFnI32 ,
OpcodeVIadd : returnTypesFnV128 ,
OpcodeVSaddSat : returnTypesFnV128 ,
OpcodeVUaddSat : returnTypesFnV128 ,
OpcodeVIsub : returnTypesFnV128 ,
OpcodeVSsubSat : returnTypesFnV128 ,
OpcodeVUsubSat : returnTypesFnV128 ,
OpcodeVIcmp : returnTypesFnV128 ,
OpcodeVImin : returnTypesFnV128 ,
OpcodeVUmin : returnTypesFnV128 ,
OpcodeVImax : returnTypesFnV128 ,
OpcodeVUmax : returnTypesFnV128 ,
OpcodeVImul : returnTypesFnV128 ,
OpcodeVAvgRound : returnTypesFnV128 ,
OpcodeVIabs : returnTypesFnV128 ,
OpcodeVIneg : returnTypesFnV128 ,
OpcodeVIpopcnt : returnTypesFnV128 ,
OpcodeVIshl : returnTypesFnV128 ,
OpcodeVSshr : returnTypesFnV128 ,
OpcodeVUshr : returnTypesFnV128 ,
OpcodeExtractlane : returnTypesFnSingle ,
OpcodeInsertlane : returnTypesFnV128 ,
OpcodeBand : returnTypesFnSingle ,
OpcodeFcopysign : returnTypesFnSingle ,
OpcodeBitcast : returnTypesFnSingle ,
OpcodeBor : returnTypesFnSingle ,
OpcodeBxor : returnTypesFnSingle ,
OpcodeRotl : returnTypesFnSingle ,
OpcodeRotr : returnTypesFnSingle ,
OpcodeIshl : returnTypesFnSingle ,
OpcodeSshr : returnTypesFnSingle ,
OpcodeSdiv : returnTypesFnSingle ,
OpcodeSrem : returnTypesFnSingle ,
OpcodeUdiv : returnTypesFnSingle ,
OpcodeUrem : returnTypesFnSingle ,
OpcodeUshr : returnTypesFnSingle ,
OpcodeJump : returnTypesFnNoReturns ,
OpcodeUndefined : returnTypesFnNoReturns ,
OpcodeIconst : returnTypesFnSingle ,
OpcodeSelect : returnTypesFnSingle ,
OpcodeSExtend : returnTypesFnSingle ,
OpcodeUExtend : returnTypesFnSingle ,
OpcodeSwidenLow : returnTypesFnV128 ,
OpcodeUwidenLow : returnTypesFnV128 ,
OpcodeSwidenHigh : returnTypesFnV128 ,
OpcodeUwidenHigh : returnTypesFnV128 ,
OpcodeSnarrow : returnTypesFnV128 ,
OpcodeUnarrow : returnTypesFnV128 ,
OpcodeSwizzle : returnTypesFnSingle ,
OpcodeShuffle : returnTypesFnV128 ,
OpcodeSplat : returnTypesFnV128 ,
OpcodeIreduce : returnTypesFnSingle ,
OpcodeFabs : returnTypesFnSingle ,
OpcodeSqrt : returnTypesFnSingle ,
OpcodeCeil : returnTypesFnSingle ,
OpcodeFloor : returnTypesFnSingle ,
OpcodeTrunc : returnTypesFnSingle ,
OpcodeNearest : returnTypesFnSingle ,
OpcodeCallIndirect : returnTypesFnCallIndirect ,
OpcodeCall : returnTypesFnCall ,
OpcodeLoad : returnTypesFnSingle ,
OpcodeVZeroExtLoad : returnTypesFnV128 ,
OpcodeLoadSplat : returnTypesFnV128 ,
OpcodeIadd : returnTypesFnSingle ,
OpcodeIsub : returnTypesFnSingle ,
OpcodeImul : returnTypesFnSingle ,
OpcodeIcmp : returnTypesFnI32 ,
OpcodeFcmp : returnTypesFnI32 ,
OpcodeFadd : returnTypesFnSingle ,
OpcodeFsub : returnTypesFnSingle ,
OpcodeFdiv : returnTypesFnSingle ,
OpcodeFmul : returnTypesFnSingle ,
OpcodeFmax : returnTypesFnSingle ,
OpcodeFmin : returnTypesFnSingle ,
OpcodeSqmulRoundSat : returnTypesFnV128 ,
OpcodeF32const : returnTypesFnF32 ,
OpcodeF64const : returnTypesFnF64 ,
OpcodeClz : returnTypesFnSingle ,
OpcodeCtz : returnTypesFnSingle ,
OpcodePopcnt : returnTypesFnSingle ,
OpcodeStore : returnTypesFnNoReturns ,
OpcodeIstore8 : returnTypesFnNoReturns ,
OpcodeIstore16 : returnTypesFnNoReturns ,
OpcodeIstore32 : returnTypesFnNoReturns ,
OpcodeExitWithCode : returnTypesFnNoReturns ,
OpcodeExitIfTrueWithCode : returnTypesFnNoReturns ,
OpcodeReturn : returnTypesFnNoReturns ,
OpcodeBrz : returnTypesFnNoReturns ,
OpcodeBrnz : returnTypesFnNoReturns ,
OpcodeBrTable : returnTypesFnNoReturns ,
OpcodeUload8 : returnTypesFnSingle ,
OpcodeUload16 : returnTypesFnSingle ,
OpcodeUload32 : returnTypesFnSingle ,
OpcodeSload8 : returnTypesFnSingle ,
OpcodeSload16 : returnTypesFnSingle ,
OpcodeSload32 : returnTypesFnSingle ,
OpcodeFcvtToSint : returnTypesFnSingle ,
OpcodeFcvtToUint : returnTypesFnSingle ,
OpcodeFcvtFromSint : returnTypesFnSingle ,
OpcodeFcvtFromUint : returnTypesFnSingle ,
OpcodeFcvtToSintSat : returnTypesFnSingle ,
OpcodeFcvtToUintSat : returnTypesFnSingle ,
OpcodeVFcvtFromUint : returnTypesFnV128 ,
OpcodeVFcvtFromSint : returnTypesFnV128 ,
OpcodeFneg : returnTypesFnSingle ,
OpcodeFdemote : returnTypesFnF32 ,
OpcodeFvdemote : returnTypesFnV128 ,
OpcodeFvpromoteLow : returnTypesFnV128 ,
OpcodeFpromote : returnTypesFnF64 ,
OpcodeVconst : returnTypesFnV128 ,
OpcodeVFabs : returnTypesFnV128 ,
OpcodeVSqrt : returnTypesFnV128 ,
OpcodeVFmax : returnTypesFnV128 ,
OpcodeVFmin : returnTypesFnV128 ,
OpcodeVFneg : returnTypesFnV128 ,
OpcodeVFadd : returnTypesFnV128 ,
OpcodeVFsub : returnTypesFnV128 ,
OpcodeVFmul : returnTypesFnV128 ,
OpcodeVFdiv : returnTypesFnV128 ,
OpcodeVFcmp : returnTypesFnV128 ,
OpcodeVCeil : returnTypesFnV128 ,
OpcodeVFloor : returnTypesFnV128 ,
OpcodeVTrunc : returnTypesFnV128 ,
OpcodeVNearest : returnTypesFnV128 ,
OpcodeVMaxPseudo : returnTypesFnV128 ,
OpcodeVMinPseudo : returnTypesFnV128 ,
OpcodeVFcvtToUintSat : returnTypesFnV128 ,
OpcodeVFcvtToSintSat : returnTypesFnV128 ,
OpcodeAtomicRmw : returnTypesFnSingle ,
OpcodeAtomicLoad : returnTypesFnSingle ,
OpcodeAtomicStore : returnTypesFnNoReturns ,
OpcodeAtomicCas : returnTypesFnSingle ,
OpcodeFence : returnTypesFnNoReturns ,
OpcodeTailCallReturnCallIndirect : returnTypesFnCallIndirect ,
OpcodeTailCallReturnCall : returnTypesFnCall ,
OpcodeWideningPairwiseDotProductS : returnTypesFnV128 ,
}
func (i *Instruction ) AsLoad (ptr Value , offset uint32 , typ Type ) *Instruction {
i .opcode = OpcodeLoad
i .v = ptr
i .u1 = uint64 (offset )
i .typ = typ
return i
}
func (i *Instruction ) AsExtLoad (op Opcode , ptr Value , offset uint32 , dst64bit bool ) *Instruction {
i .opcode = op
i .v = ptr
i .u1 = uint64 (offset )
if dst64bit {
i .typ = TypeI64
} else {
i .typ = TypeI32
}
return i
}
func (i *Instruction ) AsVZeroExtLoad (ptr Value , offset uint32 , scalarType Type ) *Instruction {
i .opcode = OpcodeVZeroExtLoad
i .v = ptr
i .u1 = uint64 (offset )
i .u2 = uint64 (scalarType )
i .typ = TypeV128
return i
}
func (i *Instruction ) VZeroExtLoadData () (ptr Value , offset uint32 , typ Type ) {
return i .v , uint32 (i .u1 ), Type (i .u2 )
}
func (i *Instruction ) AsLoadSplat (ptr Value , offset uint32 , lane VecLane ) *Instruction {
i .opcode = OpcodeLoadSplat
i .v = ptr
i .u1 = uint64 (offset )
i .u2 = uint64 (lane )
i .typ = TypeV128
return i
}
func (i *Instruction ) LoadData () (ptr Value , offset uint32 , typ Type ) {
return i .v , uint32 (i .u1 ), i .typ
}
func (i *Instruction ) LoadSplatData () (ptr Value , offset uint32 , lane VecLane ) {
return i .v , uint32 (i .u1 ), VecLane (i .u2 )
}
func (i *Instruction ) AsStore (storeOp Opcode , value , ptr Value , offset uint32 ) *Instruction {
i .opcode = storeOp
i .v = value
i .v2 = ptr
var dstSize uint64
switch storeOp {
case OpcodeStore :
dstSize = uint64 (value .Type ().Bits ())
case OpcodeIstore8 :
dstSize = 8
case OpcodeIstore16 :
dstSize = 16
case OpcodeIstore32 :
dstSize = 32
default :
panic ("invalid store opcode" + storeOp .String ())
}
i .u1 = uint64 (offset ) | dstSize <<32
return i
}
func (i *Instruction ) StoreData () (value , ptr Value , offset uint32 , storeSizeInBits byte ) {
return i .v , i .v2 , uint32 (i .u1 ), byte (i .u1 >> 32 )
}
func (i *Instruction ) AsIconst64 (v uint64 ) *Instruction {
i .opcode = OpcodeIconst
i .typ = TypeI64
i .u1 = v
return i
}
func (i *Instruction ) AsIconst32 (v uint32 ) *Instruction {
i .opcode = OpcodeIconst
i .typ = TypeI32
i .u1 = uint64 (v )
return i
}
func (i *Instruction ) AsIadd (x , y Value ) *Instruction {
i .opcode = OpcodeIadd
i .v = x
i .v2 = y
i .typ = x .Type ()
return i
}
func (i *Instruction ) AsVIadd (x , y Value , lane VecLane ) *Instruction {
i .opcode = OpcodeVIadd
i .v = x
i .v2 = y
i .u1 = uint64 (lane )
i .typ = TypeV128
return i
}
func (i *Instruction ) AsWideningPairwiseDotProductS (x , y Value ) *Instruction {
i .opcode = OpcodeWideningPairwiseDotProductS
i .v = x
i .v2 = y
i .typ = TypeV128
return i
}
func (i *Instruction ) AsExtIaddPairwise (x Value , srcLane VecLane , signed bool ) *Instruction {
i .opcode = OpcodeExtIaddPairwise
i .v = x
i .u1 = uint64 (srcLane )
if signed {
i .u2 = 1
}
i .typ = TypeV128
return i
}
func (i *Instruction ) ExtIaddPairwiseData () (x Value , srcLane VecLane , signed bool ) {
return i .v , VecLane (i .u1 ), i .u2 != 0
}
func (i *Instruction ) AsVSaddSat (x , y Value , lane VecLane ) *Instruction {
i .opcode = OpcodeVSaddSat
i .v = x
i .v2 = y
i .u1 = uint64 (lane )
i .typ = TypeV128
return i
}
func (i *Instruction ) AsVUaddSat (x , y Value , lane VecLane ) *Instruction {
i .opcode = OpcodeVUaddSat
i .v = x
i .v2 = y
i .u1 = uint64 (lane )
i .typ = TypeV128
return i
}
func (i *Instruction ) AsVIsub (x , y Value , lane VecLane ) *Instruction {
i .opcode = OpcodeVIsub
i .v = x
i .v2 = y
i .u1 = uint64 (lane )
i .typ = TypeV128
return i
}
func (i *Instruction ) AsVSsubSat (x , y Value , lane VecLane ) *Instruction {
i .opcode = OpcodeVSsubSat
i .v = x
i .v2 = y
i .u1 = uint64 (lane )
i .typ = TypeV128
return i
}
func (i *Instruction ) AsVUsubSat (x , y Value , lane VecLane ) *Instruction {
i .opcode = OpcodeVUsubSat
i .v = x
i .v2 = y
i .u1 = uint64 (lane )
i .typ = TypeV128
return i
}
func (i *Instruction ) AsVImin (x , y Value , lane VecLane ) *Instruction {
i .opcode = OpcodeVImin
i .v = x
i .v2 = y
i .u1 = uint64 (lane )
i .typ = TypeV128
return i
}
func (i *Instruction ) AsVUmin (x , y Value , lane VecLane ) *Instruction {
i .opcode = OpcodeVUmin
i .v = x
i .v2 = y
i .u1 = uint64 (lane )
i .typ = TypeV128
return i
}
func (i *Instruction ) AsVImax (x , y Value , lane VecLane ) *Instruction {
i .opcode = OpcodeVImax
i .v = x
i .v2 = y
i .u1 = uint64 (lane )
i .typ = TypeV128
return i
}
func (i *Instruction ) AsVUmax (x , y Value , lane VecLane ) *Instruction {
i .opcode = OpcodeVUmax
i .v = x
i .v2 = y
i .u1 = uint64 (lane )
i .typ = TypeV128
return i
}
func (i *Instruction ) AsVAvgRound (x , y Value , lane VecLane ) *Instruction {
i .opcode = OpcodeVAvgRound
i .v = x
i .v2 = y
i .u1 = uint64 (lane )
i .typ = TypeV128
return i
}
func (i *Instruction ) AsVImul (x , y Value , lane VecLane ) *Instruction {
i .opcode = OpcodeVImul
i .v = x
i .v2 = y
i .u1 = uint64 (lane )
i .typ = TypeV128
return i
}
func (i *Instruction ) AsSqmulRoundSat (x , y Value , lane VecLane ) *Instruction {
i .opcode = OpcodeSqmulRoundSat
i .v = x
i .v2 = y
i .u1 = uint64 (lane )
i .typ = TypeV128
return i
}
func (i *Instruction ) AsVIabs (x Value , lane VecLane ) *Instruction {
i .opcode = OpcodeVIabs
i .v = x
i .u1 = uint64 (lane )
i .typ = TypeV128
return i
}
func (i *Instruction ) AsVIneg (x Value , lane VecLane ) *Instruction {
i .opcode = OpcodeVIneg
i .v = x
i .u1 = uint64 (lane )
i .typ = TypeV128
return i
}
func (i *Instruction ) AsVIpopcnt (x Value , lane VecLane ) *Instruction {
if lane != VecLaneI8x16 {
panic ("Unsupported lane type " + lane .String ())
}
i .opcode = OpcodeVIpopcnt
i .v = x
i .u1 = uint64 (lane )
i .typ = TypeV128
return i
}
func (i *Instruction ) AsVSqrt (x Value , lane VecLane ) *Instruction {
i .opcode = OpcodeVSqrt
i .v = x
i .u1 = uint64 (lane )
i .typ = TypeV128
return i
}
func (i *Instruction ) AsVFabs (x Value , lane VecLane ) *Instruction {
i .opcode = OpcodeVFabs
i .v = x
i .u1 = uint64 (lane )
i .typ = TypeV128
return i
}
func (i *Instruction ) AsVFneg (x Value , lane VecLane ) *Instruction {
i .opcode = OpcodeVFneg
i .v = x
i .u1 = uint64 (lane )
i .typ = TypeV128
return i
}
func (i *Instruction ) AsVFmax (x , y Value , lane VecLane ) *Instruction {
i .opcode = OpcodeVFmax
i .v = x
i .v2 = y
i .u1 = uint64 (lane )
i .typ = TypeV128
return i
}
func (i *Instruction ) AsVFmin (x , y Value , lane VecLane ) *Instruction {
i .opcode = OpcodeVFmin
i .v = x
i .v2 = y
i .u1 = uint64 (lane )
i .typ = TypeV128
return i
}
func (i *Instruction ) AsVFadd (x , y Value , lane VecLane ) *Instruction {
i .opcode = OpcodeVFadd
i .v = x
i .v2 = y
i .u1 = uint64 (lane )
i .typ = TypeV128
return i
}
func (i *Instruction ) AsVFsub (x , y Value , lane VecLane ) *Instruction {
i .opcode = OpcodeVFsub
i .v = x
i .v2 = y
i .u1 = uint64 (lane )
i .typ = TypeV128
return i
}
func (i *Instruction ) AsVFmul (x , y Value , lane VecLane ) *Instruction {
i .opcode = OpcodeVFmul
i .v = x
i .v2 = y
i .u1 = uint64 (lane )
i .typ = TypeV128
return i
}
func (i *Instruction ) AsVFdiv (x , y Value , lane VecLane ) *Instruction {
i .opcode = OpcodeVFdiv
i .v = x
i .v2 = y
i .u1 = uint64 (lane )
i .typ = TypeV128
return i
}
func (i *Instruction ) AsImul (x , y Value ) *Instruction {
i .opcode = OpcodeImul
i .v = x
i .v2 = y
i .typ = x .Type ()
return i
}
func (i *Instruction ) Insert (b Builder ) *Instruction {
b .InsertInstruction (i )
return i
}
func (i *Instruction ) AsIsub (x , y Value ) *Instruction {
i .opcode = OpcodeIsub
i .v = x
i .v2 = y
i .typ = x .Type ()
return i
}
func (i *Instruction ) AsIcmp (x , y Value , c IntegerCmpCond ) *Instruction {
i .opcode = OpcodeIcmp
i .v = x
i .v2 = y
i .u1 = uint64 (c )
i .typ = TypeI32
return i
}
func (i *Instruction ) AsFcmp (x , y Value , c FloatCmpCond ) {
i .opcode = OpcodeFcmp
i .v = x
i .v2 = y
i .u1 = uint64 (c )
i .typ = TypeI32
}
func (i *Instruction ) AsVIcmp (x , y Value , c IntegerCmpCond , lane VecLane ) *Instruction {
i .opcode = OpcodeVIcmp
i .v = x
i .v2 = y
i .u1 = uint64 (c )
i .u2 = uint64 (lane )
i .typ = TypeV128
return i
}
func (i *Instruction ) AsVFcmp (x , y Value , c FloatCmpCond , lane VecLane ) *Instruction {
i .opcode = OpcodeVFcmp
i .v = x
i .v2 = y
i .u1 = uint64 (c )
i .typ = TypeV128
i .u2 = uint64 (lane )
return i
}
func (i *Instruction ) AsVCeil (x Value , lane VecLane ) *Instruction {
i .opcode = OpcodeVCeil
i .v = x
i .typ = x .Type ()
i .u1 = uint64 (lane )
return i
}
func (i *Instruction ) AsVFloor (x Value , lane VecLane ) *Instruction {
i .opcode = OpcodeVFloor
i .v = x
i .typ = x .Type ()
i .u1 = uint64 (lane )
return i
}
func (i *Instruction ) AsVTrunc (x Value , lane VecLane ) *Instruction {
i .opcode = OpcodeVTrunc
i .v = x
i .typ = x .Type ()
i .u1 = uint64 (lane )
return i
}
func (i *Instruction ) AsVNearest (x Value , lane VecLane ) *Instruction {
i .opcode = OpcodeVNearest
i .v = x
i .typ = x .Type ()
i .u1 = uint64 (lane )
return i
}
func (i *Instruction ) AsVMaxPseudo (x , y Value , lane VecLane ) *Instruction {
i .opcode = OpcodeVMaxPseudo
i .typ = x .Type ()
i .v = x
i .v2 = y
i .u1 = uint64 (lane )
return i
}
func (i *Instruction ) AsVMinPseudo (x , y Value , lane VecLane ) *Instruction {
i .opcode = OpcodeVMinPseudo
i .typ = x .Type ()
i .v = x
i .v2 = y
i .u1 = uint64 (lane )
return i
}
func (i *Instruction ) AsSDiv (x , y , ctx Value ) *Instruction {
i .opcode = OpcodeSdiv
i .v = x
i .v2 = y
i .v3 = ctx
i .typ = x .Type ()
return i
}
func (i *Instruction ) AsUDiv (x , y , ctx Value ) *Instruction {
i .opcode = OpcodeUdiv
i .v = x
i .v2 = y
i .v3 = ctx
i .typ = x .Type ()
return i
}
func (i *Instruction ) AsSRem (x , y , ctx Value ) *Instruction {
i .opcode = OpcodeSrem
i .v = x
i .v2 = y
i .v3 = ctx
i .typ = x .Type ()
return i
}
func (i *Instruction ) AsURem (x , y , ctx Value ) *Instruction {
i .opcode = OpcodeUrem
i .v = x
i .v2 = y
i .v3 = ctx
i .typ = x .Type ()
return i
}
func (i *Instruction ) AsBand (x , amount Value ) *Instruction {
i .opcode = OpcodeBand
i .v = x
i .v2 = amount
i .typ = x .Type ()
return i
}
func (i *Instruction ) AsBor (x , amount Value ) {
i .opcode = OpcodeBor
i .v = x
i .v2 = amount
i .typ = x .Type ()
}
func (i *Instruction ) AsBxor (x , amount Value ) {
i .opcode = OpcodeBxor
i .v = x
i .v2 = amount
i .typ = x .Type ()
}
func (i *Instruction ) AsIshl (x , amount Value ) *Instruction {
i .opcode = OpcodeIshl
i .v = x
i .v2 = amount
i .typ = x .Type ()
return i
}
func (i *Instruction ) AsVIshl (x , amount Value , lane VecLane ) *Instruction {
i .opcode = OpcodeVIshl
i .v = x
i .v2 = amount
i .u1 = uint64 (lane )
i .typ = x .Type ()
return i
}
func (i *Instruction ) AsUshr (x , amount Value ) *Instruction {
i .opcode = OpcodeUshr
i .v = x
i .v2 = amount
i .typ = x .Type ()
return i
}
func (i *Instruction ) AsVUshr (x , amount Value , lane VecLane ) *Instruction {
i .opcode = OpcodeVUshr
i .v = x
i .v2 = amount
i .u1 = uint64 (lane )
i .typ = x .Type ()
return i
}
func (i *Instruction ) AsSshr (x , amount Value ) *Instruction {
i .opcode = OpcodeSshr
i .v = x
i .v2 = amount
i .typ = x .Type ()
return i
}
func (i *Instruction ) AsVSshr (x , amount Value , lane VecLane ) *Instruction {
i .opcode = OpcodeVSshr
i .v = x
i .v2 = amount
i .u1 = uint64 (lane )
i .typ = x .Type ()
return i
}
func (i *Instruction ) AsExtractlane (x Value , index byte , lane VecLane , signed bool ) *Instruction {
i .opcode = OpcodeExtractlane
i .v = x
i .u1 = uint64 (index )
if signed {
i .u1 = i .u1 | 1 <<32
}
i .u2 = uint64 (lane )
switch lane {
case VecLaneI8x16 , VecLaneI16x8 , VecLaneI32x4 :
i .typ = TypeI32
case VecLaneI64x2 :
i .typ = TypeI64
case VecLaneF32x4 :
i .typ = TypeF32
case VecLaneF64x2 :
i .typ = TypeF64
}
return i
}
func (i *Instruction ) AsInsertlane (x , y Value , index byte , lane VecLane ) *Instruction {
i .opcode = OpcodeInsertlane
i .v = x
i .v2 = y
i .u1 = uint64 (index )
i .u2 = uint64 (lane )
i .typ = TypeV128
return i
}
func (i *Instruction ) AsShuffle (x , y Value , lane []byte ) *Instruction {
i .opcode = OpcodeShuffle
i .v = x
i .v2 = y
i .u1 = uint64 (lane [7 ])<<56 | uint64 (lane [6 ])<<48 | uint64 (lane [5 ])<<40 | uint64 (lane [4 ])<<32 | uint64 (lane [3 ])<<24 | uint64 (lane [2 ])<<16 | uint64 (lane [1 ])<<8 | uint64 (lane [0 ])
i .u2 = uint64 (lane [15 ])<<56 | uint64 (lane [14 ])<<48 | uint64 (lane [13 ])<<40 | uint64 (lane [12 ])<<32 | uint64 (lane [11 ])<<24 | uint64 (lane [10 ])<<16 | uint64 (lane [9 ])<<8 | uint64 (lane [8 ])
i .typ = TypeV128
return i
}
func (i *Instruction ) AsSwizzle (x , y Value , lane VecLane ) *Instruction {
i .opcode = OpcodeSwizzle
i .v = x
i .v2 = y
i .u1 = uint64 (lane )
i .typ = TypeV128
return i
}
func (i *Instruction ) AsSplat (x Value , lane VecLane ) *Instruction {
i .opcode = OpcodeSplat
i .v = x
i .u1 = uint64 (lane )
i .typ = TypeV128
return i
}
func (i *Instruction ) AsRotl (x , amount Value ) {
i .opcode = OpcodeRotl
i .v = x
i .v2 = amount
i .typ = x .Type ()
}
func (i *Instruction ) AsRotr (x , amount Value ) {
i .opcode = OpcodeRotr
i .v = x
i .v2 = amount
i .typ = x .Type ()
}
func (i *Instruction ) IcmpData () (x , y Value , c IntegerCmpCond ) {
return i .v , i .v2 , IntegerCmpCond (i .u1 )
}
func (i *Instruction ) FcmpData () (x , y Value , c FloatCmpCond ) {
return i .v , i .v2 , FloatCmpCond (i .u1 )
}
func (i *Instruction ) VIcmpData () (x , y Value , c IntegerCmpCond , l VecLane ) {
return i .v , i .v2 , IntegerCmpCond (i .u1 ), VecLane (i .u2 )
}
func (i *Instruction ) VFcmpData () (x , y Value , c FloatCmpCond , l VecLane ) {
return i .v , i .v2 , FloatCmpCond (i .u1 ), VecLane (i .u2 )
}
func (i *Instruction ) ExtractlaneData () (x Value , index byte , signed bool , l VecLane ) {
x = i .v
index = byte (0b00001111 & i .u1 )
signed = i .u1 >>32 != 0
l = VecLane (i .u2 )
return
}
func (i *Instruction ) InsertlaneData () (x , y Value , index byte , l VecLane ) {
x = i .v
y = i .v2
index = byte (i .u1 )
l = VecLane (i .u2 )
return
}
func (i *Instruction ) AsFadd (x , y Value ) {
i .opcode = OpcodeFadd
i .v = x
i .v2 = y
i .typ = x .Type ()
}
func (i *Instruction ) AsFsub (x , y Value ) {
i .opcode = OpcodeFsub
i .v = x
i .v2 = y
i .typ = x .Type ()
}
func (i *Instruction ) AsFmul (x , y Value ) {
i .opcode = OpcodeFmul
i .v = x
i .v2 = y
i .typ = x .Type ()
}
func (i *Instruction ) AsFdiv (x , y Value ) {
i .opcode = OpcodeFdiv
i .v = x
i .v2 = y
i .typ = x .Type ()
}
func (i *Instruction ) AsFmin (x , y Value ) {
i .opcode = OpcodeFmin
i .v = x
i .v2 = y
i .typ = x .Type ()
}
func (i *Instruction ) AsFmax (x , y Value ) {
i .opcode = OpcodeFmax
i .v = x
i .v2 = y
i .typ = x .Type ()
}
func (i *Instruction ) AsF32const (f float32 ) *Instruction {
i .opcode = OpcodeF32const
i .typ = TypeF64
i .u1 = uint64 (math .Float32bits (f ))
return i
}
func (i *Instruction ) AsF64const (f float64 ) *Instruction {
i .opcode = OpcodeF64const
i .typ = TypeF64
i .u1 = math .Float64bits (f )
return i
}
func (i *Instruction ) AsVconst (lo , hi uint64 ) *Instruction {
i .opcode = OpcodeVconst
i .typ = TypeV128
i .u1 = lo
i .u2 = hi
return i
}
func (i *Instruction ) AsVbnot (v Value ) *Instruction {
i .opcode = OpcodeVbnot
i .typ = TypeV128
i .v = v
return i
}
func (i *Instruction ) AsVband (x , y Value ) *Instruction {
i .opcode = OpcodeVband
i .typ = TypeV128
i .v = x
i .v2 = y
return i
}
func (i *Instruction ) AsVbor (x , y Value ) *Instruction {
i .opcode = OpcodeVbor
i .typ = TypeV128
i .v = x
i .v2 = y
return i
}
func (i *Instruction ) AsVbxor (x , y Value ) *Instruction {
i .opcode = OpcodeVbxor
i .typ = TypeV128
i .v = x
i .v2 = y
return i
}
func (i *Instruction ) AsVbandnot (x , y Value ) *Instruction {
i .opcode = OpcodeVbandnot
i .typ = TypeV128
i .v = x
i .v2 = y
return i
}
func (i *Instruction ) AsVbitselect (c , x , y Value ) *Instruction {
i .opcode = OpcodeVbitselect
i .typ = TypeV128
i .v = c
i .v2 = x
i .v3 = y
return i
}
func (i *Instruction ) AsVanyTrue (x Value ) *Instruction {
i .opcode = OpcodeVanyTrue
i .typ = TypeI32
i .v = x
return i
}
func (i *Instruction ) AsVallTrue (x Value , lane VecLane ) *Instruction {
i .opcode = OpcodeVallTrue
i .typ = TypeI32
i .v = x
i .u1 = uint64 (lane )
return i
}
func (i *Instruction ) AsVhighBits (x Value , lane VecLane ) *Instruction {
i .opcode = OpcodeVhighBits
i .typ = TypeI32
i .v = x
i .u1 = uint64 (lane )
return i
}
func (i *Instruction ) VconstData () (lo , hi uint64 ) {
return i .u1 , i .u2
}
func (i *Instruction ) AsReturn (vs wazevoapi .VarLength [Value ]) *Instruction {
i .opcode = OpcodeReturn
i .vs = vs
return i
}
func (i *Instruction ) AsIreduce (v Value , dstType Type ) *Instruction {
i .opcode = OpcodeIreduce
i .v = v
i .typ = dstType
return i
}
func (i *Instruction ) AsWiden (v Value , lane VecLane , signed , low bool ) *Instruction {
switch {
case signed && low :
i .opcode = OpcodeSwidenLow
case !signed && low :
i .opcode = OpcodeUwidenLow
case signed && !low :
i .opcode = OpcodeSwidenHigh
case !signed && !low :
i .opcode = OpcodeUwidenHigh
}
i .v = v
i .u1 = uint64 (lane )
return i
}
func (i *Instruction ) AsAtomicLoad (addr Value , size uint64 , typ Type ) *Instruction {
i .opcode = OpcodeAtomicLoad
i .u1 = size
i .v = addr
i .typ = typ
return i
}
func (i *Instruction ) AsAtomicStore (addr , val Value , size uint64 ) *Instruction {
i .opcode = OpcodeAtomicStore
i .u1 = size
i .v = addr
i .v2 = val
i .typ = val .Type ()
return i
}
func (i *Instruction ) AsAtomicRmw (op AtomicRmwOp , addr , val Value , size uint64 ) *Instruction {
i .opcode = OpcodeAtomicRmw
i .u1 = uint64 (op )
i .u2 = size
i .v = addr
i .v2 = val
i .typ = val .Type ()
return i
}
func (i *Instruction ) AsAtomicCas (addr , exp , repl Value , size uint64 ) *Instruction {
i .opcode = OpcodeAtomicCas
i .u1 = size
i .v = addr
i .v2 = exp
i .v3 = repl
i .typ = repl .Type ()
return i
}
func (i *Instruction ) AsFence (order byte ) *Instruction {
i .opcode = OpcodeFence
i .u1 = uint64 (order )
return i
}
func (i *Instruction ) AtomicRmwData () (op AtomicRmwOp , size uint64 ) {
return AtomicRmwOp (i .u1 ), i .u2
}
func (i *Instruction ) AtomicTargetSize () (size uint64 ) {
return i .u1
}
func (i *Instruction ) AsTailCallReturnCall (ref FuncRef , sig *Signature , args Values ) {
i .opcode = OpcodeTailCallReturnCall
i .u1 = uint64 (ref )
i .vs = args
i .u2 = uint64 (sig .ID )
sig .used = true
}
func (i *Instruction ) AsTailCallReturnCallIndirect (funcPtr Value , sig *Signature , args Values ) *Instruction {
i .opcode = OpcodeTailCallReturnCallIndirect
i .vs = args
i .v = funcPtr
i .u1 = uint64 (sig .ID )
sig .used = true
return i
}
func (i *Instruction ) ReturnVals () []Value {
return i .vs .View ()
}
func (i *Instruction ) AsExitWithCode (ctx Value , code wazevoapi .ExitCode ) {
i .opcode = OpcodeExitWithCode
i .v = ctx
i .u1 = uint64 (code )
}
func (i *Instruction ) AsExitIfTrueWithCode (ctx , c Value , code wazevoapi .ExitCode ) *Instruction {
i .opcode = OpcodeExitIfTrueWithCode
i .v = ctx
i .v2 = c
i .u1 = uint64 (code )
return i
}
func (i *Instruction ) ExitWithCodeData () (ctx Value , code wazevoapi .ExitCode ) {
return i .v , wazevoapi .ExitCode (i .u1 )
}
func (i *Instruction ) ExitIfTrueWithCodeData () (ctx , c Value , code wazevoapi .ExitCode ) {
return i .v , i .v2 , wazevoapi .ExitCode (i .u1 )
}
func (i *Instruction ) InvertBrx () {
switch i .opcode {
case OpcodeBrz :
i .opcode = OpcodeBrnz
case OpcodeBrnz :
i .opcode = OpcodeBrz
default :
panic ("BUG" )
}
}
func (i *Instruction ) BranchData () (condVal Value , blockArgs []Value , target BasicBlockID ) {
switch i .opcode {
case OpcodeJump :
condVal = ValueInvalid
case OpcodeBrz , OpcodeBrnz :
condVal = i .v
default :
panic ("BUG" )
}
blockArgs = i .vs .View ()
target = BasicBlockID (i .rValue )
return
}
func (i *Instruction ) BrTableData () (index Value , targets Values ) {
if i .opcode != OpcodeBrTable {
panic ("BUG: BrTableData only available for OpcodeBrTable" )
}
index = i .v
targets = i .rValues
return
}
func (i *Instruction ) AsJump (vs Values , target BasicBlock ) *Instruction {
i .opcode = OpcodeJump
i .vs = vs
i .rValue = Value (target .ID ())
return i
}
func (i *Instruction ) IsFallthroughJump () bool {
if i .opcode != OpcodeJump {
panic ("BUG: IsFallthrough only available for OpcodeJump" )
}
return i .opcode == OpcodeJump && i .u1 != 0
}
func (i *Instruction ) AsFallthroughJump () {
if i .opcode != OpcodeJump {
panic ("BUG: AsFallthroughJump only available for OpcodeJump" )
}
i .u1 = 1
}
func (i *Instruction ) AsBrz (v Value , args Values , target BasicBlock ) {
i .opcode = OpcodeBrz
i .v = v
i .vs = args
i .rValue = Value (target .ID ())
}
func (i *Instruction ) AsBrnz (v Value , args Values , target BasicBlock ) *Instruction {
i .opcode = OpcodeBrnz
i .v = v
i .vs = args
i .rValue = Value (target .ID ())
return i
}
func (i *Instruction ) AsBrTable (index Value , targets Values ) {
i .opcode = OpcodeBrTable
i .v = index
i .rValues = targets
}
func (i *Instruction ) AsCall (ref FuncRef , sig *Signature , args Values ) {
i .opcode = OpcodeCall
i .u1 = uint64 (ref )
i .vs = args
i .u2 = uint64 (sig .ID )
sig .used = true
}
func (i *Instruction ) CallData () (ref FuncRef , sigID SignatureID , args []Value ) {
if i .opcode != OpcodeCall && i .opcode != OpcodeTailCallReturnCall {
panic ("BUG: CallData only available for OpcodeCall" )
}
ref = FuncRef (i .u1 )
sigID = SignatureID (i .u2 )
args = i .vs .View ()
return
}
func (i *Instruction ) AsCallIndirect (funcPtr Value , sig *Signature , args Values ) *Instruction {
i .opcode = OpcodeCallIndirect
i .typ = TypeF64
i .vs = args
i .v = funcPtr
i .u1 = uint64 (sig .ID )
sig .used = true
return i
}
func (i *Instruction ) AsCallGoRuntimeMemmove (funcPtr Value , sig *Signature , args Values ) *Instruction {
i .AsCallIndirect (funcPtr , sig , args )
i .u2 = 1
return i
}
func (i *Instruction ) CallIndirectData () (funcPtr Value , sigID SignatureID , args []Value , isGoMemmove bool ) {
if i .opcode != OpcodeCallIndirect && i .opcode != OpcodeTailCallReturnCallIndirect {
panic ("BUG: CallIndirectData only available for OpcodeCallIndirect and OpcodeTailCallReturnCallIndirect" )
}
funcPtr = i .v
sigID = SignatureID (i .u1 )
args = i .vs .View ()
isGoMemmove = i .u2 == 1
return
}
func (i *Instruction ) AsClz (x Value ) {
i .opcode = OpcodeClz
i .v = x
i .typ = x .Type ()
}
func (i *Instruction ) AsCtz (x Value ) {
i .opcode = OpcodeCtz
i .v = x
i .typ = x .Type ()
}
func (i *Instruction ) AsPopcnt (x Value ) {
i .opcode = OpcodePopcnt
i .v = x
i .typ = x .Type ()
}
func (i *Instruction ) AsFneg (x Value ) *Instruction {
i .opcode = OpcodeFneg
i .v = x
i .typ = x .Type ()
return i
}
func (i *Instruction ) AsSqrt (x Value ) *Instruction {
i .opcode = OpcodeSqrt
i .v = x
i .typ = x .Type ()
return i
}
func (i *Instruction ) AsFabs (x Value ) *Instruction {
i .opcode = OpcodeFabs
i .v = x
i .typ = x .Type ()
return i
}
func (i *Instruction ) AsFcopysign (x , y Value ) *Instruction {
i .opcode = OpcodeFcopysign
i .v = x
i .v2 = y
i .typ = x .Type ()
return i
}
func (i *Instruction ) AsCeil (x Value ) *Instruction {
i .opcode = OpcodeCeil
i .v = x
i .typ = x .Type ()
return i
}
func (i *Instruction ) AsFloor (x Value ) *Instruction {
i .opcode = OpcodeFloor
i .v = x
i .typ = x .Type ()
return i
}
func (i *Instruction ) AsTrunc (x Value ) *Instruction {
i .opcode = OpcodeTrunc
i .v = x
i .typ = x .Type ()
return i
}
func (i *Instruction ) AsNearest (x Value ) *Instruction {
i .opcode = OpcodeNearest
i .v = x
i .typ = x .Type ()
return i
}
func (i *Instruction ) AsBitcast (x Value , dstType Type ) *Instruction {
i .opcode = OpcodeBitcast
i .v = x
i .typ = dstType
return i
}
func (i *Instruction ) BitcastData () (x Value , dstType Type ) {
return i .v , i .typ
}
func (i *Instruction ) AsFdemote (x Value ) {
i .opcode = OpcodeFdemote
i .v = x
i .typ = TypeF32
}
func (i *Instruction ) AsFpromote (x Value ) {
i .opcode = OpcodeFpromote
i .v = x
i .typ = TypeF64
}
func (i *Instruction ) AsFcvtFromInt (x Value , signed bool , dst64bit bool ) *Instruction {
if signed {
i .opcode = OpcodeFcvtFromSint
} else {
i .opcode = OpcodeFcvtFromUint
}
i .v = x
if dst64bit {
i .typ = TypeF64
} else {
i .typ = TypeF32
}
return i
}
func (i *Instruction ) AsFcvtToInt (x , ctx Value , signed bool , dst64bit bool , sat bool ) *Instruction {
switch {
case signed && !sat :
i .opcode = OpcodeFcvtToSint
case !signed && !sat :
i .opcode = OpcodeFcvtToUint
case signed && sat :
i .opcode = OpcodeFcvtToSintSat
case !signed && sat :
i .opcode = OpcodeFcvtToUintSat
}
i .v = x
i .v2 = ctx
if dst64bit {
i .typ = TypeI64
} else {
i .typ = TypeI32
}
return i
}
func (i *Instruction ) AsVFcvtToIntSat (x Value , lane VecLane , signed bool ) *Instruction {
if signed {
i .opcode = OpcodeVFcvtToSintSat
} else {
i .opcode = OpcodeVFcvtToUintSat
}
i .v = x
i .u1 = uint64 (lane )
return i
}
func (i *Instruction ) AsVFcvtFromInt (x Value , lane VecLane , signed bool ) *Instruction {
if signed {
i .opcode = OpcodeVFcvtFromSint
} else {
i .opcode = OpcodeVFcvtFromUint
}
i .v = x
i .u1 = uint64 (lane )
return i
}
func (i *Instruction ) AsNarrow (x , y Value , lane VecLane , signed bool ) *Instruction {
if signed {
i .opcode = OpcodeSnarrow
} else {
i .opcode = OpcodeUnarrow
}
i .v = x
i .v2 = y
i .u1 = uint64 (lane )
return i
}
func (i *Instruction ) AsFvpromoteLow (x Value , lane VecLane ) *Instruction {
i .opcode = OpcodeFvpromoteLow
i .v = x
i .u1 = uint64 (lane )
return i
}
func (i *Instruction ) AsFvdemote (x Value , lane VecLane ) *Instruction {
i .opcode = OpcodeFvdemote
i .v = x
i .u1 = uint64 (lane )
return i
}
func (i *Instruction ) AsSExtend (v Value , from , to byte ) *Instruction {
i .opcode = OpcodeSExtend
i .v = v
i .u1 = uint64 (from )<<8 | uint64 (to )
if to == 64 {
i .typ = TypeI64
} else {
i .typ = TypeI32
}
return i
}
func (i *Instruction ) AsUExtend (v Value , from , to byte ) *Instruction {
i .opcode = OpcodeUExtend
i .v = v
i .u1 = uint64 (from )<<8 | uint64 (to )
if to == 64 {
i .typ = TypeI64
} else {
i .typ = TypeI32
}
return i
}
func (i *Instruction ) ExtendData () (from , to byte , signed bool ) {
if i .opcode != OpcodeSExtend && i .opcode != OpcodeUExtend {
panic ("BUG: ExtendData only available for OpcodeSExtend and OpcodeUExtend" )
}
from = byte (i .u1 >> 8 )
to = byte (i .u1 )
signed = i .opcode == OpcodeSExtend
return
}
func (i *Instruction ) AsSelect (c , x , y Value ) *Instruction {
i .opcode = OpcodeSelect
i .v = c
i .v2 = x
i .v3 = y
i .typ = x .Type ()
return i
}
func (i *Instruction ) SelectData () (c , x , y Value ) {
c = i .v
x = i .v2
y = i .v3
return
}
func (i *Instruction ) ExtendFromToBits () (from , to byte ) {
from = byte (i .u1 >> 8 )
to = byte (i .u1 )
return
}
func (i *Instruction ) Format (b Builder ) string {
var instSuffix string
switch i .opcode {
case OpcodeExitWithCode :
instSuffix = fmt .Sprintf (" %s, %s" , i .v .Format (b ), wazevoapi .ExitCode (i .u1 ))
case OpcodeExitIfTrueWithCode :
instSuffix = fmt .Sprintf (" %s, %s, %s" , i .v2 .Format (b ), i .v .Format (b ), wazevoapi .ExitCode (i .u1 ))
case OpcodeIadd , OpcodeIsub , OpcodeImul , OpcodeFadd , OpcodeFsub , OpcodeFmin , OpcodeFmax , OpcodeFdiv , OpcodeFmul :
instSuffix = fmt .Sprintf (" %s, %s" , i .v .Format (b ), i .v2 .Format (b ))
case OpcodeIcmp :
instSuffix = fmt .Sprintf (" %s, %s, %s" , IntegerCmpCond (i .u1 ), i .v .Format (b ), i .v2 .Format (b ))
case OpcodeFcmp :
instSuffix = fmt .Sprintf (" %s, %s, %s" , FloatCmpCond (i .u1 ), i .v .Format (b ), i .v2 .Format (b ))
case OpcodeSExtend , OpcodeUExtend :
instSuffix = fmt .Sprintf (" %s, %d->%d" , i .v .Format (b ), i .u1 >>8 , i .u1 &0xff )
case OpcodeCall , OpcodeCallIndirect :
view := i .vs .View ()
vs := make ([]string , len (view ))
for idx := range vs {
vs [idx ] = view [idx ].Format (b )
}
if i .opcode == OpcodeCallIndirect {
instSuffix = fmt .Sprintf (" %s:%s, %s" , i .v .Format (b ), SignatureID (i .u1 ), strings .Join (vs , ", " ))
} else {
instSuffix = fmt .Sprintf (" %s:%s, %s" , FuncRef (i .u1 ), SignatureID (i .u2 ), strings .Join (vs , ", " ))
}
case OpcodeStore , OpcodeIstore8 , OpcodeIstore16 , OpcodeIstore32 :
instSuffix = fmt .Sprintf (" %s, %s, %#x" , i .v .Format (b ), i .v2 .Format (b ), uint32 (i .u1 ))
case OpcodeLoad , OpcodeVZeroExtLoad :
instSuffix = fmt .Sprintf (" %s, %#x" , i .v .Format (b ), int32 (i .u1 ))
case OpcodeLoadSplat :
instSuffix = fmt .Sprintf (".%s %s, %#x" , VecLane (i .u2 ), i .v .Format (b ), int32 (i .u1 ))
case OpcodeUload8 , OpcodeUload16 , OpcodeUload32 , OpcodeSload8 , OpcodeSload16 , OpcodeSload32 :
instSuffix = fmt .Sprintf (" %s, %#x" , i .v .Format (b ), int32 (i .u1 ))
case OpcodeSelect , OpcodeVbitselect :
instSuffix = fmt .Sprintf (" %s, %s, %s" , i .v .Format (b ), i .v2 .Format (b ), i .v3 .Format (b ))
case OpcodeIconst :
switch i .typ {
case TypeI32 :
instSuffix = fmt .Sprintf ("_32 %#x" , uint32 (i .u1 ))
case TypeI64 :
instSuffix = fmt .Sprintf ("_64 %#x" , i .u1 )
}
case OpcodeVconst :
instSuffix = fmt .Sprintf (" %016x %016x" , i .u1 , i .u2 )
case OpcodeF32const :
instSuffix = fmt .Sprintf (" %f" , math .Float32frombits (uint32 (i .u1 )))
case OpcodeF64const :
instSuffix = fmt .Sprintf (" %f" , math .Float64frombits (i .u1 ))
case OpcodeReturn :
view := i .vs .View ()
if len (view ) == 0 {
break
}
vs := make ([]string , len (view ))
for idx := range vs {
vs [idx ] = view [idx ].Format (b )
}
instSuffix = fmt .Sprintf (" %s" , strings .Join (vs , ", " ))
case OpcodeJump :
view := i .vs .View ()
vs := make ([]string , len (view )+1 )
if i .IsFallthroughJump () {
vs [0 ] = " fallthrough"
} else {
blockId := BasicBlockID (i .rValue )
vs [0 ] = " " + b .BasicBlock (blockId ).Name ()
}
for idx := range view {
vs [idx +1 ] = view [idx ].Format (b )
}
instSuffix = strings .Join (vs , ", " )
case OpcodeBrz , OpcodeBrnz :
view := i .vs .View ()
vs := make ([]string , len (view )+2 )
vs [0 ] = " " + i .v .Format (b )
blockId := BasicBlockID (i .rValue )
vs [1 ] = b .BasicBlock (blockId ).Name ()
for idx := range view {
vs [idx +2 ] = view [idx ].Format (b )
}
instSuffix = strings .Join (vs , ", " )
case OpcodeBrTable :
instSuffix = fmt .Sprintf (" %s" , i .v .Format (b ))
instSuffix += ", ["
for i , target := range i .rValues .View () {
blk := b .BasicBlock (BasicBlockID (target ))
if i == 0 {
instSuffix += blk .Name ()
} else {
instSuffix += ", " + blk .Name ()
}
}
instSuffix += "]"
case OpcodeBand , OpcodeBor , OpcodeBxor , OpcodeRotr , OpcodeRotl , OpcodeIshl , OpcodeSshr , OpcodeUshr ,
OpcodeSdiv , OpcodeUdiv , OpcodeFcopysign , OpcodeSrem , OpcodeUrem ,
OpcodeVbnot , OpcodeVbxor , OpcodeVbor , OpcodeVband , OpcodeVbandnot , OpcodeVIcmp , OpcodeVFcmp :
instSuffix = fmt .Sprintf (" %s, %s" , i .v .Format (b ), i .v2 .Format (b ))
case OpcodeUndefined :
case OpcodeClz , OpcodeCtz , OpcodePopcnt , OpcodeFneg , OpcodeFcvtToSint , OpcodeFcvtToUint , OpcodeFcvtFromSint ,
OpcodeFcvtFromUint , OpcodeFcvtToSintSat , OpcodeFcvtToUintSat , OpcodeFdemote , OpcodeFpromote , OpcodeIreduce , OpcodeBitcast , OpcodeSqrt , OpcodeFabs ,
OpcodeCeil , OpcodeFloor , OpcodeTrunc , OpcodeNearest :
instSuffix = " " + i .v .Format (b )
case OpcodeVIadd , OpcodeExtIaddPairwise , OpcodeVSaddSat , OpcodeVUaddSat , OpcodeVIsub , OpcodeVSsubSat , OpcodeVUsubSat ,
OpcodeVImin , OpcodeVUmin , OpcodeVImax , OpcodeVUmax , OpcodeVImul , OpcodeVAvgRound ,
OpcodeVFadd , OpcodeVFsub , OpcodeVFmul , OpcodeVFdiv ,
OpcodeVIshl , OpcodeVSshr , OpcodeVUshr ,
OpcodeVFmin , OpcodeVFmax , OpcodeVMinPseudo , OpcodeVMaxPseudo ,
OpcodeSnarrow , OpcodeUnarrow , OpcodeSwizzle , OpcodeSqmulRoundSat :
instSuffix = fmt .Sprintf (".%s %s, %s" , VecLane (i .u1 ), i .v .Format (b ), i .v2 .Format (b ))
case OpcodeVIabs , OpcodeVIneg , OpcodeVIpopcnt , OpcodeVhighBits , OpcodeVallTrue , OpcodeVanyTrue ,
OpcodeVFabs , OpcodeVFneg , OpcodeVSqrt , OpcodeVCeil , OpcodeVFloor , OpcodeVTrunc , OpcodeVNearest ,
OpcodeVFcvtToUintSat , OpcodeVFcvtToSintSat , OpcodeVFcvtFromUint , OpcodeVFcvtFromSint ,
OpcodeFvpromoteLow , OpcodeFvdemote , OpcodeSwidenLow , OpcodeUwidenLow , OpcodeSwidenHigh , OpcodeUwidenHigh ,
OpcodeSplat :
instSuffix = fmt .Sprintf (".%s %s" , VecLane (i .u1 ), i .v .Format (b ))
case OpcodeExtractlane :
var signedness string
if i .u1 != 0 {
signedness = "signed"
} else {
signedness = "unsigned"
}
instSuffix = fmt .Sprintf (".%s %d, %s (%s)" , VecLane (i .u2 ), 0x0000FFFF &i .u1 , i .v .Format (b ), signedness )
case OpcodeInsertlane :
instSuffix = fmt .Sprintf (".%s %d, %s, %s" , VecLane (i .u2 ), i .u1 , i .v .Format (b ), i .v2 .Format (b ))
case OpcodeShuffle :
lanes := make ([]byte , 16 )
for idx := 0 ; idx < 8 ; idx ++ {
lanes [idx ] = byte (i .u1 >> (8 * idx ))
}
for idx := 0 ; idx < 8 ; idx ++ {
lanes [idx +8 ] = byte (i .u2 >> (8 * idx ))
}
instSuffix = fmt .Sprintf (".%v %s, %s" , lanes , i .v .Format (b ), i .v2 .Format (b ))
case OpcodeAtomicRmw :
instSuffix = fmt .Sprintf (" %s_%d, %s, %s" , AtomicRmwOp (i .u1 ), 8 *i .u2 , i .v .Format (b ), i .v2 .Format (b ))
case OpcodeAtomicLoad :
instSuffix = fmt .Sprintf ("_%d, %s" , 8 *i .u1 , i .v .Format (b ))
case OpcodeAtomicStore :
instSuffix = fmt .Sprintf ("_%d, %s, %s" , 8 *i .u1 , i .v .Format (b ), i .v2 .Format (b ))
case OpcodeAtomicCas :
instSuffix = fmt .Sprintf ("_%d, %s, %s, %s" , 8 *i .u1 , i .v .Format (b ), i .v2 .Format (b ), i .v3 .Format (b ))
case OpcodeFence :
instSuffix = fmt .Sprintf (" %d" , i .u1 )
case OpcodeTailCallReturnCall , OpcodeTailCallReturnCallIndirect :
view := i .vs .View ()
vs := make ([]string , len (view ))
for idx := range vs {
vs [idx ] = view [idx ].Format (b )
}
if i .opcode == OpcodeCallIndirect {
instSuffix = fmt .Sprintf (" %s:%s, %s" , i .v .Format (b ), SignatureID (i .u1 ), strings .Join (vs , ", " ))
} else {
instSuffix = fmt .Sprintf (" %s:%s, %s" , FuncRef (i .u1 ), SignatureID (i .u2 ), strings .Join (vs , ", " ))
}
case OpcodeWideningPairwiseDotProductS :
instSuffix = fmt .Sprintf (" %s, %s" , i .v .Format (b ), i .v2 .Format (b ))
default :
panic (fmt .Sprintf ("TODO: format for %s" , i .opcode ))
}
instr := i .opcode .String () + instSuffix
var rvs []string
r1 , rs := i .Returns ()
if r1 .Valid () {
rvs = append (rvs , r1 .formatWithType (b ))
}
for _ , v := range rs {
rvs = append (rvs , v .formatWithType (b ))
}
if len (rvs ) > 0 {
return fmt .Sprintf ("%s = %s" , strings .Join (rvs , ", " ), instr )
} else {
return instr
}
}
func (i *Instruction ) addArgumentBranchInst (b *builder , v Value ) {
switch i .opcode {
case OpcodeJump , OpcodeBrz , OpcodeBrnz :
i .vs = i .vs .Append (&b .varLengthPool , v )
default :
panic ("BUG: " + i .opcode .String ())
}
}
func (i *Instruction ) Constant () bool {
switch i .opcode {
case OpcodeIconst , OpcodeF32const , OpcodeF64const :
return true
}
return false
}
func (i *Instruction ) ConstantVal () (ret uint64 ) {
switch i .opcode {
case OpcodeIconst , OpcodeF32const , OpcodeF64const :
ret = i .u1
default :
panic ("TODO" )
}
return
}
func (o Opcode ) String () (ret string ) {
switch o {
case OpcodeInvalid :
return "invalid"
case OpcodeUndefined :
return "Undefined"
case OpcodeJump :
return "Jump"
case OpcodeBrz :
return "Brz"
case OpcodeBrnz :
return "Brnz"
case OpcodeBrTable :
return "BrTable"
case OpcodeExitWithCode :
return "Exit"
case OpcodeExitIfTrueWithCode :
return "ExitIfTrue"
case OpcodeReturn :
return "Return"
case OpcodeCall :
return "Call"
case OpcodeCallIndirect :
return "CallIndirect"
case OpcodeSplat :
return "Splat"
case OpcodeSwizzle :
return "Swizzle"
case OpcodeInsertlane :
return "Insertlane"
case OpcodeExtractlane :
return "Extractlane"
case OpcodeLoad :
return "Load"
case OpcodeLoadSplat :
return "LoadSplat"
case OpcodeStore :
return "Store"
case OpcodeUload8 :
return "Uload8"
case OpcodeSload8 :
return "Sload8"
case OpcodeIstore8 :
return "Istore8"
case OpcodeUload16 :
return "Uload16"
case OpcodeSload16 :
return "Sload16"
case OpcodeIstore16 :
return "Istore16"
case OpcodeUload32 :
return "Uload32"
case OpcodeSload32 :
return "Sload32"
case OpcodeIstore32 :
return "Istore32"
case OpcodeIconst :
return "Iconst"
case OpcodeF32const :
return "F32const"
case OpcodeF64const :
return "F64const"
case OpcodeVconst :
return "Vconst"
case OpcodeShuffle :
return "Shuffle"
case OpcodeSelect :
return "Select"
case OpcodeVanyTrue :
return "VanyTrue"
case OpcodeVallTrue :
return "VallTrue"
case OpcodeVhighBits :
return "VhighBits"
case OpcodeIcmp :
return "Icmp"
case OpcodeIcmpImm :
return "IcmpImm"
case OpcodeVIcmp :
return "VIcmp"
case OpcodeIadd :
return "Iadd"
case OpcodeIsub :
return "Isub"
case OpcodeImul :
return "Imul"
case OpcodeUdiv :
return "Udiv"
case OpcodeSdiv :
return "Sdiv"
case OpcodeUrem :
return "Urem"
case OpcodeSrem :
return "Srem"
case OpcodeBand :
return "Band"
case OpcodeBor :
return "Bor"
case OpcodeBxor :
return "Bxor"
case OpcodeBnot :
return "Bnot"
case OpcodeRotl :
return "Rotl"
case OpcodeRotr :
return "Rotr"
case OpcodeIshl :
return "Ishl"
case OpcodeUshr :
return "Ushr"
case OpcodeSshr :
return "Sshr"
case OpcodeClz :
return "Clz"
case OpcodeCtz :
return "Ctz"
case OpcodePopcnt :
return "Popcnt"
case OpcodeFcmp :
return "Fcmp"
case OpcodeFadd :
return "Fadd"
case OpcodeFsub :
return "Fsub"
case OpcodeFmul :
return "Fmul"
case OpcodeFdiv :
return "Fdiv"
case OpcodeSqmulRoundSat :
return "SqmulRoundSat"
case OpcodeSqrt :
return "Sqrt"
case OpcodeFneg :
return "Fneg"
case OpcodeFabs :
return "Fabs"
case OpcodeFcopysign :
return "Fcopysign"
case OpcodeFmin :
return "Fmin"
case OpcodeFmax :
return "Fmax"
case OpcodeCeil :
return "Ceil"
case OpcodeFloor :
return "Floor"
case OpcodeTrunc :
return "Trunc"
case OpcodeNearest :
return "Nearest"
case OpcodeBitcast :
return "Bitcast"
case OpcodeIreduce :
return "Ireduce"
case OpcodeSnarrow :
return "Snarrow"
case OpcodeUnarrow :
return "Unarrow"
case OpcodeSwidenLow :
return "SwidenLow"
case OpcodeSwidenHigh :
return "SwidenHigh"
case OpcodeUwidenLow :
return "UwidenLow"
case OpcodeUwidenHigh :
return "UwidenHigh"
case OpcodeExtIaddPairwise :
return "IaddPairwise"
case OpcodeWideningPairwiseDotProductS :
return "WideningPairwiseDotProductS"
case OpcodeUExtend :
return "UExtend"
case OpcodeSExtend :
return "SExtend"
case OpcodeFpromote :
return "Fpromote"
case OpcodeFdemote :
return "Fdemote"
case OpcodeFvdemote :
return "Fvdemote"
case OpcodeFcvtToUint :
return "FcvtToUint"
case OpcodeFcvtToSint :
return "FcvtToSint"
case OpcodeFcvtToUintSat :
return "FcvtToUintSat"
case OpcodeFcvtToSintSat :
return "FcvtToSintSat"
case OpcodeFcvtFromUint :
return "FcvtFromUint"
case OpcodeFcvtFromSint :
return "FcvtFromSint"
case OpcodeAtomicRmw :
return "AtomicRmw"
case OpcodeAtomicCas :
return "AtomicCas"
case OpcodeAtomicLoad :
return "AtomicLoad"
case OpcodeAtomicStore :
return "AtomicStore"
case OpcodeFence :
return "Fence"
case OpcodeTailCallReturnCall :
return "ReturnCall"
case OpcodeTailCallReturnCallIndirect :
return "ReturnCallIndirect"
case OpcodeVbor :
return "Vbor"
case OpcodeVbxor :
return "Vbxor"
case OpcodeVband :
return "Vband"
case OpcodeVbandnot :
return "Vbandnot"
case OpcodeVbnot :
return "Vbnot"
case OpcodeVbitselect :
return "Vbitselect"
case OpcodeVIadd :
return "VIadd"
case OpcodeVSaddSat :
return "VSaddSat"
case OpcodeVUaddSat :
return "VUaddSat"
case OpcodeVSsubSat :
return "VSsubSat"
case OpcodeVUsubSat :
return "VUsubSat"
case OpcodeVAvgRound :
return "OpcodeVAvgRound"
case OpcodeVIsub :
return "VIsub"
case OpcodeVImin :
return "VImin"
case OpcodeVUmin :
return "VUmin"
case OpcodeVImax :
return "VImax"
case OpcodeVUmax :
return "VUmax"
case OpcodeVImul :
return "VImul"
case OpcodeVIabs :
return "VIabs"
case OpcodeVIneg :
return "VIneg"
case OpcodeVIpopcnt :
return "VIpopcnt"
case OpcodeVIshl :
return "VIshl"
case OpcodeVUshr :
return "VUshr"
case OpcodeVSshr :
return "VSshr"
case OpcodeVFabs :
return "VFabs"
case OpcodeVFmax :
return "VFmax"
case OpcodeVFmin :
return "VFmin"
case OpcodeVFneg :
return "VFneg"
case OpcodeVFadd :
return "VFadd"
case OpcodeVFsub :
return "VFsub"
case OpcodeVFmul :
return "VFmul"
case OpcodeVFdiv :
return "VFdiv"
case OpcodeVFcmp :
return "VFcmp"
case OpcodeVCeil :
return "VCeil"
case OpcodeVFloor :
return "VFloor"
case OpcodeVTrunc :
return "VTrunc"
case OpcodeVNearest :
return "VNearest"
case OpcodeVMaxPseudo :
return "VMaxPseudo"
case OpcodeVMinPseudo :
return "VMinPseudo"
case OpcodeVSqrt :
return "VSqrt"
case OpcodeVFcvtToUintSat :
return "VFcvtToUintSat"
case OpcodeVFcvtToSintSat :
return "VFcvtToSintSat"
case OpcodeVFcvtFromUint :
return "VFcvtFromUint"
case OpcodeVFcvtFromSint :
return "VFcvtFromSint"
case OpcodeFvpromoteLow :
return "FvpromoteLow"
case OpcodeVZeroExtLoad :
return "VZeroExtLoad"
}
panic (fmt .Sprintf ("unknown opcode %d" , o ))
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .