.. index:: single: tVM single: t-Code Virtual Machine *t*-Code Virtual Machine - Instruction set and operation manual =============================================================== This page describes *t*\ VM, a virtual machine that runs *t*-code, which is a low level 3-address code. Is is called *t*-code because the virtual machine has a very simple set of instructions and thus it is necessary to use a lot of *t*\ emporal registers to store intermediate results. This document describes the instructions that the VM can process, as well as how to execute a program on it. Executing a program in *t*\ VM ------------------------------ To execute a program, just run the VM with the name of the program file as an argument :: ./tvm myprogram.t You can add the flag ``--debug`` to get details about the machine status while it executes your program. :: ./tvm myprogram.t --debug *t*\ VM program structure ------------------------- A program for *t*\ VM is just a list of functions. Exactly one of the functions must be named ``main`` :: function main ;;; this is the main program ... endfunction function f1 ;;; another function ... endfunction ... etc The string ``;;;`` starts a comment that will last until the end of the line. Comments can appear anywhere. Function structure ------------------ Each function has three sections: - Section ``params`` is optional, and declares the parameters the function expects to find in the stack. - Each parameter is declared with its name and type. If the parameter is an array, its name and element type, followed by the keyword ``array``. Array parameters are always passed by reference. - Parameters are declared in the order they must be pushed. - Parameters must be pushed by the caller. - Function ``main`` can not have ``params`` section. - All parameters use exactly one memory position. - Section ``vars`` is optional, and lists the function local variables, with their types. If the variable is an array, the type of its elements plus the number of elements is listed. - Finally, there is the function body which is a list of instructions. The execution of the function ends when a ``return`` instruction is found. Example function: :: function f1 params p1 integer p2 float a1 integer array endparams vars v1 integer a2 character 10 endvars ... instructions go here ... return endfunction Memory usage, variables and temporal registers ---------------------------------------------- - *t*\ VM functions handle only parameters and local variables. All of them are stored in the stack. - Function result value is handled as an additional parameter, that has to be pushed and popped by the caller. - Function parameters use one memory position (32 bits). - Variables can use any number of memory positions. - Variables of sizes larger than 1 can be used as array base addresses and accessed with indexing instructions. - Apart from stack memory, *t*\ VM has temporal registers, identified as ``%1``, ``%2``, ``%3``, ... - There is no limit to the number of used temporal registers. - Temporal registers are local to each function activation, and saved automatically by the VM between calls. Instruction set --------------- Flow control instructions ^^^^^^^^^^^^^^^^^^^^^^^^^ +----------------------------------+-----------------------------------------------------+ | *Instruction* | *Effect* | +==================================+=====================================================+ | ``label label-name :`` | Define a label in this position, to be jumped to. | +----------------------------------+-----------------------------------------------------+ | ``goto label-name`` | Continue execution at given label. | +----------------------------------+-----------------------------------------------------+ | ``ifFalse addr goto label-name`` | If the content of variable/temporal ``addr`` | | | is zero continue execution at given label. | +----------------------------------+-----------------------------------------------------+ All labels are local to functions. No jumps between functions are allowed. Assignment instructions ^^^^^^^^^^^^^^^^^^^^^^^ +-------------------+-----------------------------------------------------+ | *Instruction* | *Effect* | +===================+=====================================================+ | ``addr = 99`` | Load integer value into variable/temporal ``addr``. | +-------------------+-----------------------------------------------------+ | ``addr = 9.99`` | Load float value into variable/temporal ``addr``. | +-------------------+-----------------------------------------------------+ | ``addr = 'A'`` | Load char value into variable/temporal ``addr``. | | | Escaped chars ``'\t'`` and ``'\n'`` are allowed. | +-------------------+-----------------------------------------------------+ | ``addr1 = addr2`` | Copy value from variable/temporal ``addr2`` to | | | variable/temporal ``addr1``. | +-------------------+-----------------------------------------------------+ Aritmetic/relational/logical binary instructions ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +----------------------------------+-------------------------------------------------------+ | *Instruction* | *Effect* | +==================================+=======================================================+ |``addr1 = addr2 operation addr3`` | Perform ``operation`` with variables/temporals | | | ``addr2`` and ``addr3`` and store result in | | | variable/temporal ``addr1``. | +----------------------------------+-------------------------------------------------------+ +----------------------------------+-------------------------------------------------------------------------+ | *Valid operations are:* | | +----------------------------------+-------------------------------------------------------------------------+ | ``+`` ``-`` ``*`` ``/`` | Aritmetic operations with integer operands and integer result. | +----------------------------------+-------------------------------------------------------------------------+ | ``+.`` ``-.`` ``*.`` ``/.`` | Aritmetic operations with float operands and float result. | +----------------------------------+-------------------------------------------------------------------------+ | ``==`` ``<=`` ``<`` | Comparison operators with integer operands and integer (0/1) result. | +----------------------------------+-------------------------------------------------------------------------+ | ``==.`` ``<=.`` ``<.`` | Comparison operators with float operands and integer (0/1) result. | +----------------------------------+-------------------------------------------------------------------------+ | ``and`` ``or`` | Logical operators with integer (0/1) operands and integer (0/1) result. | +----------------------------------+-------------------------------------------------------------------------+ Aritmetic/logical unary instructions ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +-----------------------------+------------------------------------------------------------+ | *Instruction* | *Effect* | +=============================+============================================================+ | ``addr1 = operation addr2`` | Perform unary ``operation`` on variable/temporal ``addr2`` | | | and store result in variable/temporal ``addr1``. | +-----------------------------+------------------------------------------------------------+ +-------------------------+-----------------------------------------------------------------------+ | *Valid operations are:* | | +-------------------------+-----------------------------------------------------------------------+ | ``-`` | Sign change with integer operands and integer result. | +-------------------------+-----------------------------------------------------------------------+ | ``-.`` | Sign change with float operands and float result. | +-------------------------+-----------------------------------------------------------------------+ | ``not`` | Logical negation with integer (0/1) operands and integer (0/1) result.| +-------------------------+-----------------------------------------------------------------------+ | ``float`` | Integer to float conversion with integer operand and float result. | +-------------------------+-----------------------------------------------------------------------+ Assignment instructions with indirections or indexing ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +--------------------------+----------------------------------------------------------+ | *Instruction* | *Effect* | +==========================+==========================================================+ | ``addr1[addr2] = addr3`` | Copy content of variable/temporal ``addr3`` to | | | ``addr2`` positions after ``addr1`` memory address. | | | If ``addr1`` is a variable or parameter, its address is | | | used. If it is a temporal, it is assumed to contain a | | | pointer to the base address to be used. | +--------------------------+----------------------------------------------------------+ | ``addr1 = addr2[addr3]`` | Copy to variable/temporal ``addr1`` the content of | | | ``addr3`` positions after ``addr2`` memory address. | | | If ``addr2`` is a variable or parameter, its address is | | | used. If it is a temporal, it is assumed to contain a | | | pointer to the base address to be used. | +--------------------------+----------------------------------------------------------+ | ``temp = &var`` | Copy to temporal ``temp`` the memory address of ``var``. | +--------------------------+----------------------------------------------------------+ | ``addr1 = *temp`` | Copy to variable/temporal ``addr1`` the content of | | | memory address contained in temporal ``temp``. | +--------------------------+----------------------------------------------------------+ | ``*temp = addr1`` | Copy the content of variable/temporal ``addr1`` | | | to the memory address contained in temporal ``temp``. | +--------------------------+----------------------------------------------------------+ Stack instructions ^^^^^^^^^^^^^^^^^^ ========================== ====================================== *Instruction* *Effect* ========================== ====================================== ``pushparam addr1`` Push content of variable/temporal ``addr1`` into the stack. ``pushparam`` Push a zero into the stack (typically to reserve space, e.g. for a function result). ``popparam addr1`` Get content of stack top into ``addr1`` and pop it from the stack. ``popparam`` Pop top of the stack, ignoring its value. ========================== ====================================== Function calling instructions ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ================== ============================================== *Instruction* *Effect* ================== ============================================== ``call fname`` Execute function ``fname``. ``return`` End function execution and return control to caller. ================== ============================================== Input/output instructions ^^^^^^^^^^^^^^^^^^^^^^^^^ ========================== ============================================== *Instruction* *Effect* ========================== ============================================== ``readi addr1`` Read an integer value and store it in ``addr1``. ``readf addr1`` Read an float value and store it in ``addr1``. ``readc addr1`` Read an character value and store it in ``addr1``. ``writei addr1`` Write content of variable/temporal ``addr1`` as integer. ``writef addr1`` Write content of variable/temporal ``addr1`` as float. ``writec addr1`` Write content of variable/temporal ``addr1`` as character. ``writes "somestring"`` Write a string literal. ``writeln`` Write a newline. ========================== ============================================== Example programs ================ Factorial --------- .. include:: ../../practica/tvm/examples/fact.t :literal: Example - Computing number *e* ------------------------------ .. include:: ../../practica/tvm/examples/floats.t :literal: Example - Reversing a vector ---------------------------- .. include:: ../../practica/tvm/examples/array.t :literal: Example - Passing arrays per reference -------------------------------------- .. include:: ../../practica/tvm/examples/refparam.t :literal: