VIUA-OPS(7) Viua VM Manual VIUA-OPS(7)
NAME
viua-ops - Viua VM opcodes and instructions
SYNOPSIS
The following style is used in the instruction descriptions:
┌────────┬─────────────────┬──────────────────────────────────────────┐
│ symbol │ example │ meaning │
├────────┼─────────────────┼──────────────────────────────────────────┤
│ op │ move │ an instruction │
├────────┼─────────────────┼──────────────────────────────────────────┤
│ void │ │ the special register void │
├────────┼─────────────────┼──────────────────────────────────────────┤
│ zero │ │ the special register zero │
├────────┼─────────────────┼──────────────────────────────────────────┤
│ $reg │ $0.a │ a general-purpose register │
├────────┼─────────────────┼──────────────────────────────────────────┤
│ $reg.x │ $1.p │ a general-purpose register in a specific │
│ │ │ register set │
├────────┼─────────────────┼──────────────────────────────────────────┤
│ imm │ -1, 42u, 3.14 │ an immediate value of an arithmetic type │
├────────┼─────────────────┼──────────────────────────────────────────┤
│ "str" │ "Hello, World!" │ an immediate value of a string type │
└────────┴─────────────────┴──────────────────────────────────────────┘
DESCRIPTION
In Viua VM's ISA design the emphasis is put on reliability of the pro‐
grams, performance begin a secondary consideration--the guiding idea
being that an answer delivered quickly is useless if it is wrong; or
that a program that runs fast but crashes often is less useful than one
that works correctly.
ENVIRONMENT
The instructions controlling the execution environment.
noop
No operation. The instruction does nothing at all.
halt
Halt the process. The instruction stops execution immediately.
ebreak
Environment break. By default dumps the state of the process.
earithmeticwidth $dst|void, $src|zeroearithmeticwidth $dst, void
Manipulates the earw (arithmetic width) environment register.
Stores its current value in $dst (if not void), and replaces it
with the value from $src.
If void is supplied instead of $src, the current value is not re‐
placed.
If zero is supplied instead of $src, the current value is set to
the default value.
REGISTER MANAGEMENT
These instructions allow direct management of register contents.
copy $dst, $src
Copy bits from $src to $dst, preserving $src.
move $dst, $srcmove void, $src
Move bits from $src to $dst, preserving $src.
swap $dst, $src
Swap bits between $src and $dst.
delete $dst (pseudoinstruction)
Erase the $dst register.
ARITHMETIC
Instructions marked with [.native] accept style flags; instructions not
marked so do not accept style flags. The .native flag can be stated ex‐
plicitly, but is the implicit default in the absence of any other style
flag.
Style flags are explained in Arithmetic styles.
Base arithmetic instructions
For base arithmetic instructions the type of the output value depends
on the type of the value in the $lhs register, and so neither zero nor
void can be used for the $lhs operand.
add[.native] $dst, $lhs, $rhs
Add $rhs to $lhs, and store the output in $dst.
sub[.native] $dst, $lhs, $rhs
Subtract $rhs from $lhs, and store the output in $dst.
mul[.native] $dst, $lhs, $rhs
Multiply $lhs by $rhs, and store the output in $dst.
div[.native] $dst, $lhs, $rhs
Divide $lhs by $rhs, and store the output in $dst.
mod dst, lhs, rhs
Calculate ($lhs modulo $rhs), and store the output in $dst.
Arithmetic with an immediate value
These instructions are similar to the base arithmetic instructions, but
instead of $rhs they take an immediate value; and they can take a zero
as the $lhs value, while the base instructions could not.
If zero is used instead of $lhs the output type is the same as the type
of the immediate operand. For example:
addiu $2.l, zero, 0 luiu $2.l, 0
creates an unsigned integer (note the u after the number zero), because
the immediate operand is unsigned; while
addi $2.l, zero, 0 lui $2.l, 0
creates a signed integer.
The unsigned versions are not directly available to programmers,
though, and must be accessed through the pseudoinstructions that infer
the desired sign of the output from the sign of the immediate. A few
examples to show the idea:
addi $2.l, zero, 1
addi $2.l, zero, 1u
In general, all of the above should be handed off to the assembler and
the programmers should only rely on the li pseudoinstruction.
lui $dst, immediate
Create a signed integer with its highest 32 bits set to immediate,
and store the result in $dst.
Use addi or addiu to fill the lower 32 bits.
luiu $dst, immediate
Create an usigned integer with its highest 32 bits set to immedi‐ate, and store the result in $dst.
Use addi or addiu to fill the lower 32 bits.
addi $dst, $lhs|zero, immediate
Add immediate to $lhs (or zero), and store the output in $dst.
subi $dst, $lhs|zero, immediate
Subtract immediate from $lhs (or zero), and store the output in
$dst.
muli $dst, $lhs|zero, immediate
Multiply $lhs (or zero) by immediate, and store the output in $dst.
Using zero in place of $lhs does not make much sense, but is legal.
divi $dst, $lhs|zero, immediate
Divide $lhs (or zero) by immediate, and store the output in $dst.
Using zero in place of $lhs does not make much sense, but is legal.
Arithmetic styles
Viua offers several styles of arithmetic:
┌────────────┬────────────────────────────────────────────────────────┐
│ style flag │ style description │
├────────────┼────────────────────────────────────────────────────────┤
│ .native │ fast, works on floating point and integer types │
├────────────┼────────────────────────────────────────────────────────┤
│ .wrap │ wraps on overflow, only works on integer types │
├────────────┼────────────────────────────────────────────────────────┤
│ .trap │ traps on overflow, only works on integer types │
├────────────┼────────────────────────────────────────────────────────┤
│ .saturate │ saturates on overflow, only works on integer types │
└────────────┴────────────────────────────────────────────────────────┘
A style flag can be appended to an arithmetic instruction to enable the
specific style. For example, to execute saturating addition one would
write:
add.saturate $4.l, $2.l, $3.l
Styles other than .native take into account the state of the earw envi‐
ronment register (manipulated using the earithmeticwidth instruction),
and can be made to work on integers of specific width; eg, on 8-bit or
42-bit integers (the width does not have to be a multiple of 8).
Floating-point constructorsdouble $reg
Use the unsigned integer in $reg as offset into the strings table,
load a double, and store the result back in $reg.
float $dst, immediate
Store the immediate of type float in $dst.
LOGIC
Logic instructions.
eq $dst, $lhs, $rhs
Compare $lhs with $rhs; store 1 in $dst if both values are equal,
store 0 otherwise.
If the value in $rhs cannot be interpreted as a value of the type
of $lhs the instruction aborts execution. Output is always a signed
integer.
lt $dst, $lhs, $rhs
Compare $lhs less-than $rhs; store 1 in $dst if the comparison is
true, store 0 otherwise.
If the value in $rhs cannot be interpreted as a value of the type
of $lhs the instruction aborts execution. Output is always a signed
integer.
gt $dst, $lhs, $rhs
Compare $lhs greater-than $rhs; store 1 in $dst if the comparison
is true, store 0 otherwise.
If the value in $rhs cannot be interpreted as a value of the type
of $lhs the instruction aborts execution. Output is always a signed
integer.
cmp $dst, $lhs, $rhs
Compare $lhs with $rhs, and store result in $dst according to the
following table:
If the value in $rhs cannot be interpreted as a value of the type
of $lhs the instruction aborts execution. Output is always a signed
integer.
┌──────┬────────────────────────┐
│ $dst │ condition │
├──────┼────────────────────────┤
│ -1 │ left-hand < right-hand │
├──────┼────────────────────────┤
│ 0 │ left-hand = right-hand │
├──────┼────────────────────────┤
│ 1 │ left-hand > right-hand │
└──────┴────────────────────────┘
and $dst, $lhs, $rhs
Execute $lhs logical-and $rhs, and store the result in $dst.
Inputs are interpreted as the bool type by the instruction. Output
is always an unsigned integer.
or $dst, $lhs, $rhs
Execute $lhs logical-or $rhs, and store the result in $dst.
Inputs are interpreted as the bool type by the instruction. Output
is always an unsigned integer.
not $dst, $src
Store the logical negation of $src in $dst.
Inputs are interpreted as the bool type by the instruction. Output
is always an unsigned integer.
BIT ARITHMETIC
Bitwise operations require an unsigned integer value in their $src or
$lhs operands, and will attempt to cast the value in $shift or $rhs to
an unsigned integer. The instructions will abort execution unless both
of the aforementioned conditions are satisified.
NOTE: The earw register has no effect on the bit arithmetic instruc‐
tions; they always work on full-width values.
Shiftsbitshl $dst, $src, $shift
Shift the value from $src left by $shift bits, and store the result
in $dst. The result is filled with zeroes on the right.
bitshr $dst, $src, $shift
Shift the value from $src right by $shift bits, and store the re‐
sult in $dst. The result is filled with zeroes on the left.
bitashr $dst, $src, $shift
Shift the value from $src right by $shift bits, and store the re‐
sult in $dst. The result is filled with the highest bit of the in‐
put on the left; bitashr is the arithmetic right bit shift ie, it
preserves the sign of the input.
Rotationsbitrol $dst, $src, $shift
Rotate the value from $src to the left by $shift bits, and store
the result in $dst. The bits "shifted out" from the input ie, its
highest bits, are "shifted in" as the lowest bits of the output.
For example, if bitrol was applied to 0b1100'0100 with a shift
value of 2, the result would be 0b0001'0011.
bitror $dst, $src, $shift
Rotate the value from $src to the right by $shift bits, and store
the result in $dst. The bits "shifted out" from the input ie, its
lowest bits, are "shifted in" as the highest bits of the output.
For example, if bitror was applied to 0b1100'0100 with a shift
value of 2, the result would be 0b0011'0001.
Masksbitand $dst, $lhs, $rhs
Perform $lhs bitwise-and $rhs, and store the result in $dst.
bitor $dst, $lhs, $rhs
Perform $lhs bitwise-or $rhs, and store the result in $dst.
bitxor $dst, $lhs, $rhs
Perform $lhs bitwise-xor $rhs, and store the result in $dst.
bitnot $dst, $src
Invert the bits of $src, and store the result in $dst.
CONTROL FLOW
Control flow instructions.
if $condition|void, $address
Jump to $address if the $condition is true; perform an uncondi‐
tional jump if the operand is the void register.
If the $condition operand is non-void, the operation will attempt
to cast it as a boolean value. The operation aborts execution if
this is not possible.
See the description of the atxtp instruction to learn how to create
a pointer usable as the $address operand.
frame $argcount.a
frame $argcount.l
Allocate a frame.
If the $argcount.a form is used ie, the count is taken as-if from
the arguments register set, the number of allocated argument/para‐
meter registers (see the REGISTERS chapter of viua-isa(7) for the
distinction) is equal to the argcount value, as if it were an imme‐
diate value.
If the $argcount.l form is used ie, the count is taken from the lo‐
cal register set, the number of allocated argument/parameter regis‐
ters is equal to the value in $argcount.l register. That value must
be an unsigned integer, or the operation will abort execution.
call $retval|void, $address
Use a previously allocated frame (see the description of the frame
instruction above) to perform a call to the address.
After control returns from the callee, the result of the call is
stored in $retval (or discarded if the operand was void).
If a non-void $retval operand is provided and the callee does re‐
turn a value, the operation aborts execution. Execution is aborted
after the call finishes, not before.
The callee receives a fresh local register set, and has no access
to the caller's frame.
The only fully open communication channel between the caller and
the callee are the registers in the arguments/parameters register
set, and the value moved from the callee to the caller with the re‐turn instruction. See the MEMORY chapter of viua-isa(7) to learn
about the restrictions on memory access between frames.
See the description of the atxtp instruction to learn how to create
a pointer usable as the $address operand.
return $retval|void
Return control to the caller frame. If the current frame is the
only frame on the stack, the execution of the whole actor ends. If
the current actor was the only one, the execution of the whole pro‐
gram ends.
If the $retval operand is a non-void register, return the value
contained in it.
The operation aborts execution if a non-void register is supplied
that is empty. Return nothing requires explicitly supplying the
void register for the $retval operand.
MEMORY
The unit operand of memory instructions is not symbolic, but given as
the number of bits the 1u value should be shifted left.
Its legal range is 0 (a byte) to 7 (a duotrigesimal-word).
The effective address is the result of the following calculation:
$addr + (offset * (1u << unit))
For example, if the unit is 2 (a word), the offset 42 the effective ad‐
dress would be:
$addr + (42 * (1u << 2)) =
$addr + (42 * 4) =
$addr + 168
For an extended discussion about loads and stores, refer to the M-FOR‐MAT chapter of viua-isa(7).
Constructors
The "current module" used in the descriptions of constructor instruc‐
tions means the module at which the program counter is pointing.
This can usually be thought of as a static-linked ELF emitted by an in‐
vocation of viua-ld(1). In case of dynamic linking, the .got must be
used to get pointers to objects in other modules.
arodp $dst, offset
Create a pointer pointing at offset bytes into the .rodata section
of the current module, and store the result in $dst.
If the offset is invalid the operation aborts execution.
atxtp $dst, offset
Create a pointer pointing at offset bytes into the .text section of
the current module, and store the result in $dst.
If the offset is invalid the operation aborts execution.
atom $reg
Use the unsigned integer in $reg as offset into the strings table,
load an atom, and store the result back in $reg.
cast $reg, type
Interpret an undefined value contained in $reg as type.
Refer to chapter FUNDAMENTAL TYPES of viua-isa(7) to learn what
symbols are available for the type operand.
Loads and stores
For lm and sm instructions only unit values up to 4 (a quad-word) are
useful, since Viua registers can only hold 128 bits.
lm unit, $reg, $addr, offset
Load a unit of memory eg, a word, from the effectiveaddress into
$reg.
sm unit, $reg, $addr, offset
Store a unit of memory eg, a word, from $reg at the effectivead‐dress.
Allocation
For aa and ad instructions all unit values are useful.
aa unit, $ptr, $count
Allocate an amount of automatic (stack) memory equal to $count
times unit.
ad unit, $ptr, $count (!!! NOT IMPLEMENTED !!!)
Allocate an amount of dynamic (heap) memory equal to $count times
unit.
PSEUDOINSTRUCTIONSatom $dst, atom
Store the atom in $dst.
double $dst, immediate
Store the immediate of type double in $dst.
lb $reg, $addr, offsetlh $reg, $addr, offsetlw $reg, $addr, offsetld $reg, $addr, offsetlq $reg, $addr, offset
Load a value from memory and into $reg. See discussion of the lm
instruction for more detailed information.
sb $reg, $addr, offsetsh $reg, $addr, offsetsw $reg, $addr, offsetsd $reg, $addr, offsetsq $reg, $addr, offset
Store a value from $reg in memory. See discussion of the lm in‐
struction for more detailed information.
amba $ptr, $size, 0
amha $ptr, $size, 0
amwa $ptr, $size, 0
amda $ptr, $size, 0
amqa $ptr, $size, 0
amoa $ptr, $size, 0
amxa $ptr, $size, 0
amua $ptr, $size, 0
Allocate automatic memory. See discussion of the aa instruction for
more detailed information.
call $retval|void, symbol
Call a symbol defined by a .symbol directive. See discussion of the
call instruction for more detailed information.
if $condition, label
Jump to a label defined by a .label directive. See discussion of
the if instruction for more detailed information.
li $reg, immediate
Load an immediate integer value into $reg. The immediate must be
representable on 64 bits, and its signedness is inferred by the as‐
sembler.
By default, signed integers are loaded:
li $2.l, 1
Use the u suffix may be used to force unsigned integers:
li $3.l, 1u
Use the special -1u case to load maximal value of an unsigned inte‐
ger:
li #4.l, -1u
SEE ALSOviua-asm(5), viua-isa(7).
Patterson, David A. and Waterman, Andrew. TheRISC-VReader. Strawberry
Canyon LLC, 2017.
ISBN 978-09-9924-911-6
Web site
‹https://viuavm.org›
Source code repository
‹https://git.sr.ht/~maelkum/viuavm›
VIUA VM
Part of the viua(1) toolchain.