Documentation ¶
Overview ¶
Package aes implements AES encryption (formerly Rijndael), as defined in U.S. Federal Information Processing Standards Publication 197.
The AES operations in this package are not implemented using constant-time algorithms. An exception is when running on systems with enabled hardware support for AES that makes these operations constant-time. Examples include amd64 systems using AES-NI extensions and s390x systems using Message-Security-Assist extensions. On such systems, when the result of NewCipher is passed to cipher.NewGCM, the GHASH operation used by GCM is also constant-time.
Index ¶
- Constants
- Variables
- func AES_DEC_ROUND(state []uint32, key []uint32)
- func AES_ENC_ROUND(state []uint32, key []uint32)
- func ARRAY_TO_BIGENDIAN(input [4]uint32) (output [4]uint32)
- func CreateSuperScalarInstruction(sins *SuperScalarInstruction, gen *Blake2Generator, instruction_len int, ...)
- func MaskRegisterExponentMantissa(f float64, mode uint64) float64
- func Max(x, y int) int
- func ScheduleMop(mop *MacroOP, portbusy [][]int, cycle int, depcycle int, commit bool) int
- func ScheduleUop(uop ExecutionPort, portbusy [][]int, cycle int, commit bool) int
- type Blake2Generator
- type Config
- type DecoderType
- type ExecutionPort
- type Instruction
- type InstructionByteCode
- type MacroOP
- type MemoryRegisters
- type REG
- type REGISTER_FILE
- type Randomx_Cache
- type Register
- type SuperScalarInstruction
- func (sins *SuperScalarInstruction) FixSrcReg()
- func (sins *SuperScalarInstruction) Reset()
- func (sins *SuperScalarInstruction) SelectDestination(preAllocatedAvailableRegisters []int, cycle int, allowChainedMul bool, ...) bool
- func (sins *SuperScalarInstruction) SelectSource(preAllocatedAvailableRegisters []int, cycle int, Registers []Register, ...) bool
- func (sins SuperScalarInstruction) String() string
- type SuperScalarProgram
- type VM
- type VM_Instruction
- type VM_Instruction_Type
Constants ¶
const ( Null ExecutionPort = iota P0 = 1 P1 = 2 P5 = 4 P01 = P0 | P1 P05 = P0 | P5 P015 = P0 | P1 | P5 )
const ( S_INVALID int = -1 S_ISUB_R = 0 S_IXOR_R = 1 S_IADD_RS = 2 S_IMUL_R = 3 S_IROR_C = 4 S_IADD_C7 = 5 S_IXOR_C7 = 6 S_IADD_C8 = 7 S_IXOR_C8 = 8 S_IADD_C9 = 9 S_IXOR_C9 = 10 S_IMULH_R = 11 S_ISMULH_R = 12 S_IMUL_RCP = 13 )
const ArgonBlockSize uint32 = 1024
const ArgonSaltSize uint32 = 8 //sizeof("" RANDOMX_ARGON_SALT) - 1;
const CONDITIONMASK = ((1 << RANDOMX_JUMP_BITS) - 1)
const CONDITIONOFFSET = RANDOMX_JUMP_OFFSET
const CYCLE_MAP_SIZE int = RANDOMX_SUPERSCALAR_LATENCY + 4
const CacheLineAlignMask = (RANDOMX_DATASET_BASE_SIZE - 1) & (^(CacheLineSize - 1))
const CacheLineSize uint64 = RANDOMX_DATASET_ITEM_SIZE
const CacheSize uint64 = RANDOMX_ARGON_MEMORY * uint64(ArgonBlockSize)
const DATASETEXTRAITEMS = RANDOMX_DATASET_EXTRA_SIZE / RANDOMX_DATASET_ITEM_SIZE
const HIGH = 1
const LOOK_FORWARD_CYCLES int = 4
const LOW = 0
const MAX_THROWAWAY_COUNT int = 256
const Mask = CacheSize/CacheLineSize - 1
const RANDOMX_ARGON_ITERATIONS = 3
Number of Argon2d iterations for Cache initialization.
const RANDOMX_ARGON_LANES = 1
Number of parallel lanes for Cache initialization.
const RANDOMX_ARGON_MEMORY = 262144
see reference configuration.h Cache size in KiB. Must be a power of 2.
const RANDOMX_ARGON_SALT = "RandomX\x03"
Argon2d salt
const RANDOMX_CACHE_ACCESSES = 8
Number of random Cache accesses per Dataset item. Minimum is 2.
const RANDOMX_DATASET_BASE_SIZE = 2147483648
Dataset base size in bytes. Must be a power of 2.
const RANDOMX_DATASET_EXTRA_SIZE = 33554368
Dataset extra size. Must be divisible by 64.
const RANDOMX_DATASET_ITEM_SIZE uint64 = 64
const RANDOMX_FLAG_DEFAULT = 0
const RANDOMX_FLAG_JIT = 1
const RANDOMX_FLAG_LARGE_PAGES = 2
const RANDOMX_JUMP_BITS = 8
Jump condition mask size in bits.
const RANDOMX_JUMP_OFFSET = 8
Jump condition mask offset in bits. The sum of RANDOMX_JUMP_BITS and RANDOMX_JUMP_OFFSET must not exceed 16.
const RANDOMX_PROGRAM_COUNT = 8
Number of chained VM executions per hash.
const RANDOMX_PROGRAM_ITERATIONS = 2048
Number of iterations during VM execution.
const RANDOMX_PROGRAM_SIZE = 256
Number of instructions in a RandomX program. Must be divisible by 8.
const RANDOMX_SCRATCHPAD_L1 = 16384
Scratchpad L1 size in bytes. Must be a power of two (minimum 64) and less than or equal to RANDOMX_SCRATCHPAD_L2.
const RANDOMX_SCRATCHPAD_L2 = 262144
Scratchpad L2 size in bytes. Must be a power of two and less than or equal to RANDOMX_SCRATCHPAD_L3.
const RANDOMX_SCRATCHPAD_L3 = 2097152
Scratchpad L3 size in bytes. Must be a power of 2.
const RANDOMX_SUPERSCALAR_LATENCY = 170
Target latency for SuperscalarHash (in cycles of the reference CPU).
const REGISTERCOUNTFLT = 4
const REGISTERSCOUNT = 8
const RegisterNeedsDisplacement = 5
const RegisterNeedsSib = 4
const STOREL3CONDITION = 14
const ScratchpadL1 = RANDOMX_SCRATCHPAD_L1 / 8
const ScratchpadL1Mask = (ScratchpadL1 - 1) * 8
const ScratchpadL1Mask16 = (ScratchpadL1/2 - 1) * 16
const ScratchpadL2 = RANDOMX_SCRATCHPAD_L2 / 8
const ScratchpadL2Mask = (ScratchpadL2 - 1) * 8
const ScratchpadL2Mask16 = (ScratchpadL2/2 - 1) * 16
const ScratchpadL3 = RANDOMX_SCRATCHPAD_L3 / 8
const ScratchpadL3Mask = (ScratchpadL3 - 1) * 8
const ScratchpadL3Mask64 = (ScratchpadL3/8 - 1) * 64
const ScratchpadSize uint32 = RANDOMX_SCRATCHPAD_L3
const SuperscalarMaxSize int = 3*RANDOMX_SUPERSCALAR_LATENCY + 2
Variables ¶
var AES_GEN_1R_KEY0 = ARRAY_TO_BIGENDIAN([4]uint32{0xb4f44917, 0xdbb5552b, 0x62716609, 0x6daca553})
these keys are used to generate scratchpad
var AES_GEN_1R_KEY1 = ARRAY_TO_BIGENDIAN([4]uint32{0x0da1dc4e, 0x1725d378, 0x846a710d, 0x6d7caf07})
var AES_GEN_1R_KEY2 = ARRAY_TO_BIGENDIAN([4]uint32{0x3e20e345, 0xf4c0794f, 0x9f947ec6, 0x3f1262f1})
var AES_GEN_1R_KEY3 = ARRAY_TO_BIGENDIAN([4]uint32{0x49169154, 0x16314c88, 0xb1ba317c, 0x6aef8135})
var AES_GEN_4R_KEY0 = ARRAY_TO_BIGENDIAN([4]uint32{0x99e5d23f, 0x2f546d2b, 0xd1833ddb, 0x6421aadd})
these keys are used to used as per RandomX spec
var AES_GEN_4R_KEY1 = ARRAY_TO_BIGENDIAN([4]uint32{0xa5dfcde5, 0x06f79d53, 0xb6913f55, 0xb20e3450})
var AES_GEN_4R_KEY2 = ARRAY_TO_BIGENDIAN([4]uint32{0x171c02bf, 0x0aa4679f, 0x515e7baf, 0x5c3ed904})
var AES_GEN_4R_KEY3 = ARRAY_TO_BIGENDIAN([4]uint32{0xd8ded291, 0xcd673785, 0xe78f5d08, 0x85623763})
var AES_GEN_4R_KEY4 = ARRAY_TO_BIGENDIAN([4]uint32{0x229effb4, 0x3d518b6d, 0xe3d6a7a6, 0xb5826f73})
var AES_GEN_4R_KEY5 = ARRAY_TO_BIGENDIAN([4]uint32{0xb272b7d2, 0xe9024d4e, 0x9c10b3d9, 0xc7566bf3})
var AES_GEN_4R_KEY6 = ARRAY_TO_BIGENDIAN([4]uint32{0xf63befa7, 0x2ba9660a, 0xf765a38b, 0xf273c9e7})
var AES_GEN_4R_KEY7 = ARRAY_TO_BIGENDIAN([4]uint32{0xc0b0762d, 0x0c06d1fd, 0x915839de, 0x7a7cd609})
var AES_HASH_1R_STATE0 = ARRAY_TO_BIGENDIAN([4]uint32{0xd7983aad, 0xcc82db47, 0x9fa856de, 0x92b52c0d})
var AES_HASH_1R_STATE1 = ARRAY_TO_BIGENDIAN([4]uint32{0xace78057, 0xf59e125a, 0x15c7b798, 0x338d996e})
var AES_HASH_1R_STATE2 = ARRAY_TO_BIGENDIAN([4]uint32{0xe8a07ce4, 0x5079506b, 0xae62c7d0, 0x6a770017})
var AES_HASH_1R_STATE3 = ARRAY_TO_BIGENDIAN([4]uint32{0x7e994948, 0x79a10005, 0x07ad828d, 0x630a240c})
var AES_HASH_1R_XKEY0 = ARRAY_TO_BIGENDIAN([4]uint32{0x06890201, 0x90dc56bf, 0x8b24949f, 0xf6fa8389})
var AES_HASH_1R_XKEY1 = ARRAY_TO_BIGENDIAN([4]uint32{0xed18f99b, 0xee1043c6, 0x51f4e03c, 0x61b263d1})
var Decoder_To_Instruction_Length = [][]int{{4, 8, 4},
{7, 3, 3, 3},
{3, 7, 3, 3},
{4, 9, 3},
{4, 4, 4, 4},
{3, 3, 10}}
var IADD_C7 = Instruction{Name: "IADD_C7", Opcode: S_IADD_C7, UOP: M_Add_ri, SrcOP: -1}
var IADD_C8 = Instruction{Name: "IADD_C8", Opcode: S_IADD_C8, UOP: M_Add_ri, SrcOP: -1}
var IADD_C9 = Instruction{Name: "IADD_C9", Opcode: S_IADD_C9, UOP: M_Add_ri, SrcOP: -1}
var IADD_RS = Instruction{Name: "IADD_RS", Opcode: S_IADD_RS, UOP: M_Lea_SIB, SrcOP: 0}
var IMULH_R = Instruction{Name: "IMULH_R", Opcode: S_IMULH_R, UOP_Array: []MacroOP{M_Mov_rr, M_Mul_r, M_Mov_rr}, ResultOP: 1, DstOP: 0, SrcOP: 1}
var IMUL_R = Instruction{Name: "IMUL_R", Opcode: S_IMUL_R, UOP: M_Imul_rr, SrcOP: 0}
var IMUL_RCP = Instruction{Name: "IMUL_RCP", Opcode: S_IMUL_RCP, UOP_Array: []MacroOP{M_Mov_ri64, M_Imul_r_dependent}, ResultOP: 1, DstOP: 1, SrcOP: -1}
var INOP = Instruction{Name: "NOP", UOP: M_NOP}
var IROR_C = Instruction{Name: "IROR_C", Opcode: S_IROR_C, UOP: M_Ror_ri, SrcOP: -1}
var ISMULH_R = Instruction{Name: "ISMULH_R", Opcode: S_ISMULH_R, UOP_Array: []MacroOP{M_Mov_rr, M_Imul_r, M_Mov_rr}, ResultOP: 1, DstOP: 0, SrcOP: 1}
var ISUB_R = Instruction{Name: "ISUB_R", Opcode: S_ISUB_R, UOP: M_Sub_rr, SrcOP: 0}
SrcOP/DstOp are used to selected registers
var IXOR_C7 = Instruction{Name: "IXOR_C7", Opcode: S_IXOR_C7, UOP: M_Xor_ri, SrcOP: -1}
var IXOR_C8 = Instruction{Name: "IXOR_C8", Opcode: S_IXOR_C8, UOP: M_Xor_ri, SrcOP: -1}
var IXOR_C9 = Instruction{Name: "IXOR_C9", Opcode: S_IXOR_C9, UOP: M_Xor_ri, SrcOP: -1}
var IXOR_R = Instruction{Name: "IXOR_R", Opcode: S_IXOR_R, UOP: M_Xor_rr, SrcOP: 0}
var M_Add_ri = MacroOP{"add r,i", 7, 1, P015, Null, false}
Size: 7 bytes (can be optionally padded with nop to 8 or 9 bytes)
var M_Add_rr = MacroOP{"add r,r", 3, 1, P015, Null, false}
var M_Imul_r = MacroOP{"imul r", 3, 4, P1, P5, false}
var M_Imul_r_dependent = MacroOP{"imul r", 3, 3, P1, Null, true} // this is the dependent version where current instruction depends on previous instruction
latency is 1 lower
var M_Imul_rr = MacroOP{"imul r,r", 4, 3, P1, Null, false}
var M_Lea_SIB = MacroOP{"lea r,r+r*s", 4, 1, P01, Null, false}
Size: 4 bytes
var M_Mov_ri64 = MacroOP{"mov rax,i64", 10, 1, P015, Null, false}
Size: 10 bytes
var M_Mov_rr = MacroOP{"mov r,r", 3, 0, Null, Null, false}
var M_Mul_r = MacroOP{"mul r", 3, 4, P1, P5, false}
var M_NOP = MacroOP{"NOP", 0, 0, Null, Null, false}
3 byte instructions
var M_Ror_ri = MacroOP{"ror r,i", 4, 1, P05, Null, false}
var M_Sub_rr = MacroOP{"sub r,r", 3, 1, P015, Null, false}
var M_Xor_ri = MacroOP{"xor r,i", 7, 1, P015, Null, false}
var M_Xor_rr = MacroOP{"xor r,r", 3, 1, P015, Null, false}
var Names = map[VM_Instruction_Type]string{ VM_IADD_RS: "VM_IADD_RS", VM_IADD_M: "VM_IADD_M", VM_ISUB_R: "VM_ISUB_R", VM_ISUB_M: "VM_ISUB_M", VM_IMUL_R: "VM_IMUL_R", VM_IMUL_M: "VM_IMUL_M", VM_IMULH_R: "VM_IMULH_R", VM_IMULH_M: "VM_IMULH_M", VM_ISMULH_R: "VM_ISMULH_R", VM_ISMULH_M: "VM_ISMULH_M", VM_IMUL_RCP: "VM_IMUL_RCP", VM_INEG_R: "VM_INEG_R", VM_IXOR_R: "VM_IXOR_R", VM_IXOR_M: "VM_IXOR_M", VM_IROR_R: "VM_IROR_R", VM_IROL_R: "VM_IROL_R", VM_ISWAP_R: "VM_ISWAP_R", VM_FSWAP_R: "VM_FSWAP_R", VM_FADD_R: "VM_FADD_R", VM_FADD_M: "VM_FADD_M", VM_FSUB_R: "VM_FSUB_R", VM_FSUB_M: "VM_FSUB_M", VM_FSCAL_R: "VM_FSCAL_R", VM_FMUL_R: "VM_FMUL_R", VM_FDIV_M: "VM_FDIV_M", VM_FSQRT_R: "VM_FSQRT_R", VM_CBRANCH: "VM_CBRANCH", VM_CFROUND: "VM_CFROUND", VM_ISTORE: "VM_ISTORE", VM_NOP: "VM_NOP", }
var Opcode_To_String = map[int]string{S_INVALID: "INVALID", S_ISUB_R: "ISUB_R", S_IXOR_R: "IXOR_R", S_IADD_RS: "IADD_RS", S_IMUL_R: "IMUL_R", S_IROR_C: "IROR_C", S_IADD_C7: "IADD_C7", S_IXOR_C7: "IXOR_C7", S_IADD_C8: "IADD_C8", S_IXOR_C8: "IXOR_C8", S_IADD_C9: "IADD_C9", S_IXOR_C9: "IXOR_C9", S_IMULH_R: "IMULH_R", S_ISMULH_R: "ISMULH_R", S_IMUL_RCP: "IMUL_RCP", }
var Zero uint64 = 0
Functions ¶
func AES_DEC_ROUND ¶
func AES_ENC_ROUND ¶
func ARRAY_TO_BIGENDIAN ¶
reverses order of elements and also reverse byte order
func CreateSuperScalarInstruction ¶
func CreateSuperScalarInstruction(sins *SuperScalarInstruction, gen *Blake2Generator, instruction_len int, decoder_type int, islast, isfirst bool)
func ScheduleMop ¶
func ScheduleUop ¶
func ScheduleUop(uop ExecutionPort, portbusy [][]int, cycle int, commit bool) int
schedule the uop as early as possible
Types ¶
type Blake2Generator ¶
type Blake2Generator struct {
// contains filtered or unexported fields
}
func Init_Blake2Generator ¶
func Init_Blake2Generator(key []byte, nonce uint32) *Blake2Generator
func (*Blake2Generator) GetByte ¶
func (b *Blake2Generator) GetByte() byte
func (*Blake2Generator) GetUint32 ¶
func (b *Blake2Generator) GetUint32() uint32
type DecoderType ¶
type DecoderType int
const Decoder3310 DecoderType = 5
const Decoder3733 DecoderType = 2
const Decoder4444 DecoderType = 4
const Decoder484 DecoderType = 0
const Decoder493 DecoderType = 3
const Decoder7333 DecoderType = 1
func FetchNextDecoder ¶
func FetchNextDecoder(ins *Instruction, cycle int, mulcount int, gen *Blake2Generator) DecoderType
func (DecoderType) GetSize ¶
func (d DecoderType) GetSize() int
func (DecoderType) String ¶
func (d DecoderType) String() string
type ExecutionPort ¶
type ExecutionPort byte
type Instruction ¶
type Instruction struct { Name string Opcode byte UOP MacroOP SrcOP int ResultOP int DstOP int UOP_Array []MacroOP }
func (*Instruction) GetLatency ¶
func (ins *Instruction) GetLatency() int
func (*Instruction) GetSize ¶
func (ins *Instruction) GetSize() int
func (*Instruction) GetUOPCount ¶
func (ins *Instruction) GetUOPCount() int
func (*Instruction) IsSimple ¶
func (ins *Instruction) IsSimple() bool
type InstructionByteCode ¶
type InstructionByteCode struct { Opcode VM_Instruction_Type // contains filtered or unexported fields }
type MacroOP ¶
type MacroOP struct { Name string Size int Latency int UOP1 ExecutionPort UOP2 ExecutionPort Dependent bool }
func (*MacroOP) GetLatency ¶
func (*MacroOP) GetUOP1 ¶
func (m *MacroOP) GetUOP1() ExecutionPort
func (*MacroOP) GetUOP2 ¶
func (m *MacroOP) GetUOP2() ExecutionPort
func (*MacroOP) IsDependent ¶
func (*MacroOP) IsEliminated ¶
type MemoryRegisters ¶
type MemoryRegisters struct {
// contains filtered or unexported fields
}
type REGISTER_FILE ¶
type REGISTER_FILE struct {
// contains filtered or unexported fields
}
type Randomx_Cache ¶
type Randomx_Cache struct { Blocks []block Programs [RANDOMX_PROGRAM_COUNT]*SuperScalarProgram }
func Randomx_alloc_cache ¶
func Randomx_alloc_cache(flags uint64) *Randomx_Cache
func (*Randomx_Cache) GetBlock ¶
func (cache *Randomx_Cache) GetBlock(addr uint64, out []uint64)
fetch a 64 byte block in uint64 form
func (*Randomx_Cache) InitDatasetItem ¶
func (cache *Randomx_Cache) InitDatasetItem(out []uint64, itemnumber uint64)
func (*Randomx_Cache) Randomx_init_cache ¶
func (cache *Randomx_Cache) Randomx_init_cache(key []byte)
func (*Randomx_Cache) VM_Initialize ¶
func (cache *Randomx_Cache) VM_Initialize() *VM
type SuperScalarInstruction ¶
type SuperScalarInstruction struct { Opcode byte Dst_Reg int Src_Reg int Mod byte Imm32 uint32 Type int Name string OpGroup int OpGroupPar int GroupParIsSource int CanReuse bool // contains filtered or unexported fields }
superscalar program is built with superscalara instructions
func (*SuperScalarInstruction) FixSrcReg ¶
func (sins *SuperScalarInstruction) FixSrcReg()
func (*SuperScalarInstruction) Reset ¶
func (sins *SuperScalarInstruction) Reset()
func (*SuperScalarInstruction) SelectDestination ¶
func (sins *SuperScalarInstruction) SelectDestination(preAllocatedAvailableRegisters []int, cycle int, allowChainedMul bool, Registers []Register, gen *Blake2Generator) bool
func (*SuperScalarInstruction) SelectSource ¶
func (sins *SuperScalarInstruction) SelectSource(preAllocatedAvailableRegisters []int, cycle int, Registers []Register, gen *Blake2Generator) bool
func (SuperScalarInstruction) String ¶
func (sins SuperScalarInstruction) String() string
type SuperScalarProgram ¶
type SuperScalarProgram struct { Ins []SuperScalarInstruction // all instructions of program AddressReg int }
func Build_SuperScalar_Program ¶
func Build_SuperScalar_Program(gen *Blake2Generator) *SuperScalarProgram
type VM ¶
type VM struct { State_start [64]byte Prog []byte ScratchPad []byte ByteCode [RANDOMX_PROGRAM_SIZE]InstructionByteCode Cache *Randomx_Cache // randomx cache // contains filtered or unexported fields }
func (*VM) CalculateHash ¶
func (*VM) Compile_TO_Bytecode ¶
func (vm *VM) Compile_TO_Bytecode()
this will interpret single vm instruction reference https://github.com/tevador/RandomX/blob/master/doc/specs.md#52-integer-instructions
func (*VM) InterpretByteCode ¶
func (vm *VM) InterpretByteCode()
type VM_Instruction ¶
type VM_Instruction []byte // it is hardcode 8 bytes
since go does not have union, use byte array
func (VM_Instruction) Dst ¶
func (ins VM_Instruction) Dst() byte
func (VM_Instruction) IMM ¶
func (ins VM_Instruction) IMM() uint32
func (VM_Instruction) Mod ¶
func (ins VM_Instruction) Mod() byte
func (VM_Instruction) Opcode ¶
func (ins VM_Instruction) Opcode() byte
func (VM_Instruction) Src ¶
func (ins VM_Instruction) Src() byte
type VM_Instruction_Type ¶
type VM_Instruction_Type int
const ( VM_IADD_RS VM_Instruction_Type = 0 VM_IADD_M VM_Instruction_Type = 1 VM_ISUB_R VM_Instruction_Type = 2 VM_ISUB_M VM_Instruction_Type = 3 VM_IMUL_R VM_Instruction_Type = 4 VM_IMUL_M VM_Instruction_Type = 5 VM_IMULH_R VM_Instruction_Type = 6 VM_IMULH_M VM_Instruction_Type = 7 VM_ISMULH_R VM_Instruction_Type = 8 VM_ISMULH_M VM_Instruction_Type = 9 VM_IMUL_RCP VM_Instruction_Type = 10 VM_INEG_R VM_Instruction_Type = 11 VM_IXOR_R VM_Instruction_Type = 12 VM_IXOR_M VM_Instruction_Type = 13 VM_IROR_R VM_Instruction_Type = 14 VM_IROL_R VM_Instruction_Type = 15 VM_ISWAP_R VM_Instruction_Type = 16 VM_FSWAP_R VM_Instruction_Type = 17 VM_FADD_R VM_Instruction_Type = 18 VM_FADD_M VM_Instruction_Type = 19 VM_FSUB_R VM_Instruction_Type = 20 VM_FSUB_M VM_Instruction_Type = 21 VM_FSCAL_R VM_Instruction_Type = 22 VM_FMUL_R VM_Instruction_Type = 23 VM_FDIV_M VM_Instruction_Type = 24 VM_FSQRT_R VM_Instruction_Type = 25 VM_CBRANCH VM_Instruction_Type = 26 VM_CFROUND VM_Instruction_Type = 27 VM_ISTORE VM_Instruction_Type = 28 VM_NOP VM_Instruction_Type = 29 )