OzVM - Preliminary Description of the Machine, Opcodes, and Instructions

OzVM is a simple register-based, RISC-style processor. The machine maintains 256 general-purpose 64-bit registers, one 32-bit instruction pointer, and a 32-bit addressable memory region. The specification defines 120 operations supporting 10 data types, covering 4 sizes of integers and 2 sizes of floating-point numbers. Any register may be used for either integer or floating-point calculations.

Memory access to the valid memory is enforced - access outside that memory results in undefined behavior. The specific amount of memory available to the machine is unspecified. Currently, available memory is fixed at load-time with no support for run-time memory allocation.

Absent from the machine specification is any native support for interrupts, exceptions, or multithreading. That includes no support for ALU and FPU exceptions such as overflow, underflow, etc.

Table 1. Register allocation convention
Registers Description
0-31 Integer / pointer
0 "Hardwired" to 0
1 Procedure return address
2 Stack pointer
3 Function return value
4-15 Scratch
16-31 Variables
32-63 Floating-point
32 Function return value
33-47 Scratch
48-63 Variables
64-65 Reserved for compiler
66-255 Unused

Each opcode is a 32-bit field describing the operation and the registers, possibly followed by a 32-bit immediate value.

Table 2. Machine code format
Mandatory Contingent
Bits 31-24 23-16 15-8 7-0
Field r3 r2 r1 op
Bits 31-0
Field imm

There are ten fundamental types. Each instruction supports some subset of these types.

Table 3. Fundamental types
Type Description ILP32 C-type
I1 8-bit signed integer char
I2 16-bit signed integer short
I4 32-bit signed integer int
I8 64-bit signed integer long long
F4 32-bit floating-point float
F8 64-bit floating-point double
U1 8-bit unsigned integer unsigned char
U2 16-bit unsigned integer unsigned short
U4 32-bit unsigned integer unsigned int
U8 64-bit unsigned integer unsigned long long

There are 120 unique opcodes, one for each type of instruction. Note, the copy to register instructions (C_R_...) on 8-bit and 16-bit types (I1, I2, U1, U2) always write a full 32-bits to the destination register, zero- or sign-extended as appropriate.

Table 4. Instruction list and description
Instruction Types Operation Description
Nop n/a none No operation
C_R_R I1, I2, U1, U2, U4, U8 REG(r1) = REG(r2) Copy to register from register
C_R_I I1, I2, U1, U2, U4 REG(r1) = imm Copy to register from immediate
C_R_MRI I1, I2, U1, U2, U4, U8 REG(r1) = MEM( REG(r2) + imm ) Copy to register from memory at register+immediate
C_R_MRR I1, I2, U1, U2, U4, U8 REG(r1) = MEM( REG(r2) + REG(r3) ) Copy to register from memory at register+register
C_MRI_R U1, U2, U4, U8 MEM( REG(r1) + imm ) = REG(r2) Copy to memory at register+immediate from register
C_MRR_R U1, U2, U4, U8 MEM( REG(r1) + REG(r2) ) = REG(r3) Copy to memory at register+register from register
Cvt_F4 F8, I4, I8, U4, U8 (F4)REG(r1) = (type)REG(r2) Convert to F4 from (type)
Cvt_F8 F4, I4, I8, U4, U8 (F8)REG(r1) = (type)REG(r2) Convert to F8 from (type)
Cvt_U4 F4, F8, U8 (U4)REG(r1) = (type)REG(r2) Convert to U4 from (type)
Cvt_U8 F4, F8, I4, U4 (U8)REG(r1) = (type)REG(r2) Convert to U8 from (type)
Add F4, F8, U4, U8 REG(r1) = REG(r2) + REG(r3) Add
Sub F4, F8, U4, U8 REG(r1) = REG(r2) - REG(r3) Subtract
Mul F4, F8, I4, I8, U4, U8 REG(r1) = REG(r2) * REG(r3) Multiply
Div F4, F8, I4, I8, U4, U8 REG(r1) = REG(r2) / REG(r3) Divide
Mod I4, I8, U4, U8 REG(r1) = REG(r2) % REG(r3) Modulo
Neg F4, F8, I4, I8 REG(r1) = - REG(r2) Negate
And U4, U8 REG(r1) = REG(r2) & REG(r3) Binary and
Or U4, U8 REG(r1) = REG(r2) | REG(r3) Binary or
Xor U4, U8 REG(r1) = REG(r2) ^ REG(r3) Binary exclusive-or
Com U4, U8 REG(r1) = ~ REG(r2) Binary compliment
Lsh U4, U8 REG(r1) = REG(r2) << REG(r3) Left-shift variable number of bits
Rsh I4, I8, U4, U8 REG(r1) = REG(r2) >> REG(r3) Right-shift variable number of bits
Lsh_C U4, U8 REG(r1) = REG(r2) << r3 Left-shift constant number of bits
Rsh_C I4, I8, U4, U8 REG(r1) = REG(r2) >> r3 Right-shift constant number of bits
Jump U4 IP = imm if r1 == 0
IP = REG(r1) otherwise
Load instruction pointer with new value
Link U4 REG(r2) = address of next instruction,
then execute Jump
Copy instruction pointer of next instruction, then jump
Beq F4, F8, U4, U8 if REG(r2) == REG(r3) then IP += imm Branch if equal
Bne F4, F8, U4, U8 if REG(r2) != REG(r3) then IP += imm Branch if not-equal
Ble F4, F8, I4, I8, U4, U8 if REG(r2) <= REG(r3) then IP += imm Branch if less-than or equal
Blt F4, F8, I4, I8, U4, U8 if REG(r2) < REG(r3) then IP += imm Branch if less-than
Trap U4 call system function REG(r1)
argument in REG(r2)
Trap, call system function

$Revision: 1.1.1.1 $
$Date: 2001/09/18 10:45:25 $