~maelkum/viuavm

Remove buffer- and struct-related instructions

They are (or, rather, will be) possible to implement in terms of memory
instructions - AA, SM, LM, etc. It will be a compiler's job to translate
high-level concepts to VM's lower-level instructions.
Report values of frame pointer and stack break in ebreak output
Basic implementation for AA instruction

It does not check if enough memory is allocated and blindly creates the
pointer. The check is a TODO.
Fix operand fetches in arithmetic instructions

They were fetching values from 0th local register instead of using
default zero when they had void as input operand.
Abort compilation if invalid unit is found in memory instruction

It's better to crash and burn then emit invalid code.
Make get_value() and get_proxy() public

They are still an implementation detail of viua::vm::ins namespace, but
since some instructions' implementations may be stored in separate
files, having private linkage no longer makes sense for get_value() and
get_proxy().
Save and restore memory registers

The memory registers are:

 - frame pointer ie, the first address allocated for the frame
 - stack break ie, the first unallocated address on the stack

These are saved during a CALL instruction, and restored during RETURN.
The information is saved in the caller's frame, but the VM does it
automatically - neither caller nor callee have to do anything to ensure
correct operation.
Rename allocation pseudoinstructions from A* to AM*

The instruction for dynamically allocating a double-world was named ADD
in the old scheme, which conflicted with arithmetic ADD instruction. The
new scheme uses a better prefix: AM - Allocate Memory.
Assemble and disassemble AA and AD instructions

The semantics described in commit
241b755da0ee740d9a08c6423d8094bc4eb463ab need to be amended. The
alignment of the memory area is now described by the unit specified in
the pseudoinstructions name:

 - abx: allocate bytes
 - ahx: allocate half-words
 - awx: allocate words
 - adx: allocate double-words
 - aqx: allocate quad-words

The same rule is used for AA and AD instructions. In source code, they
will appear like this:

    aha $ptr, $size, 0
    aa  16, $ptr, $size, 0

The last parameter MUST be zero; otherwise, the source is rejected and
compilation is aborted.

The design for PTR instruction should be revisited.
Add AA, AD, and PTR instructions

They will be used to create pointers and allocate memory.

AA - Allocate Automatic

    aa $ptr, $size, <align>

Allocates memory with automatic duration (ie, on stack) and returns
pointer to the allocated memory area. The VM automatically finds a
suitable address to allocate the memory, including requesting a new page
if necessary.

The address parameter (2nd one) is used to specify the requested size.

The offset parameter (3rd one) is used to specify alignment. Alignment
of zero means the most stringent alignment is chosen.

AD - Allocate Dynamic

    ad $ptr, $size, <align>

Allocates memory with dynamic duration (ie, on heap) and returns pointer
to the allocated memory area. The memory is reclaimed automatically
unless the ownership of the pointer is passed to the caller.

The parameters' meaning is the same as for AA.

PTR - PoinTeR

    ptr $ptr, $area, <offset>

Create a pointer to an inside of a memory area allocated by AA or AD.
This makes it easier to address subobjects. However, the since the
offset is only 16 bits wide, the instruction is only able to address the
first 16 KiB of memory in the $area.

ADDIU and ADD instructions can be used to increase the address (the VM
will automatically enforce bounds check to ensure that memory outside
the original area cannot be accessed this way). To facilitate this
analysis put the greedy prefix on PTR instruction and use the arithmetic
instruction immediately afterwards:

    g.ptr $ptr, $area, 0xffff
    addiu $ptr, $ptr, 0x42

Otherwise the pointer arithmetic will be rejected.
Shorten dispatch code using macros

Or rather "shorten". The code stays the same, it is just easier to
write.
Use get_value() for all kinds of general purpose registers

All instructions should use the get_value() wrapper instead of accessing
registers directly. This will make it possible to use local, argument,
and parameter registers in all operands.
Highlight the opcode token in the error message

The error line looks better this way, and makes it immediately obvious
why an integer was expected.
Improve aside notes

They are still not as versatile as they should be, but now they can be
attached to non-main lexemes on an error line. Error messages spread out
over several lines are still a feature for the future (ha!).
Increase preemption threshold

Executing only two instructions at a time doesn't make much sense.
Add a type to hold memory pages allocated to a process

The backing array is aligned to 8-byte boundary to be able to act as a
backing store for arbitrary types.
Fix implementations of SM and LM instructions

The addresses need to be checked by the VM to prevent badly written, or
just malicious, programs from trashing VM's memory.
Load memory dumps into ebreak data inside test suite

The *.ebreak files for test cases can now request tests of memory
contents and fail if they do not match expected values.
Ensure that numbers are displayed in decimal when outputting perf data

After recent patches they were displayed in hex, which broke the test
suite.
Dump memory when showing frame in REPL
Next