Files
rasp/vm.md
2020-01-25 21:02:32 -05:00

2.5 KiB

VM

This is an outline of the VM that drives this language.

Primitives

  • Numbers may be big endian (BE) or little endian (LE) at the byte level. This guide will use LE.
  • Addresses point to single bytes.
Type Size (bits)
Address 64
Word 64
Halfword 32
Byte 8

Registers

CPU registers are addressed by a value between 0-63 (6 bits). All registers are 64 bits wide.

  • IP - Instruction pointer
  • SP - Stack pointer
  • FP - Frame pointer
  • FLAGS - CPU flags
  • (10 unused registers)
  • R0-R49

CPU Flags

CPU flags are addressed by bit index, going from right to left.

  • 00 - Halt flag
  • 01 - Compare flag

Flag ideas

  • "Trace" flag - halts the CPU when certain conditions are met that may be causing undesired behavior - for debugging
    • Overwriting a register without its value being used
    • Mixing arithmetic with bit twiddling on the same target

Instructions

Arithmetic

Arithmetic instructions store their result in the last register specified.

  • Add
    • Params: REG1, REG2
    • REG2 = REG1 + REG2
  • Mul
    • Params: REG1, REG2
    • REG2 = REG1 * REG2
  • Div
    • Params: REG1, REG2
    • REG2 = REG1 / REG2
  • Neg
    • Params: REG1
    • REG1 = REG1 * -1
  • And
    • Params: REG1, REG2
    • REG2 = REG1 & REG2
  • Or
    • Params: REG1, REG2
    • REG2 = REG1 | REG2
  • Xor
    • Params: REG1, REG2
    • REG2 = REG1 ^ REG2
  • Shl
    • Params: REG1, REG2
    • REG1 = REG1 << REG2
  • Shr
    • Params: REG1, REG2
    • REG1 = REG1 >> REG2

Control flow

  • CmpEq
    • Params: REG1, REG2
    •   if REG1 == REG2 {
            FLAGS[1] = 1;
        } else {
            FLAGS[1] = 0;
        }
      
  • CmpLt
    • Params: REG1, REG2
    •   if REG1 < REG2 {
            FLAGS[1] = 1;
        } else {
            FLAGS[1] = 0;
        }
      
  • Jz
    • Params: REG1
    •   if FLAGS[0] == 0 {
            IP = REG1;
        }
      
  • Jnz
    • Params: REG1
    •   if FLAGS[0] != 0 {
            IP = REG1;
        }
      
    
    

Data movement

  • Load
    • Params: REG1, REG2
    REG1 = MEM[REG2];
  • Store
    • Params: REG1, REG2
    MEM[REG2] = REG1;
  • StoreImm32
    • (hw = half word)
    • Params: REG1, IMM_HW
    • REG1 = IMM_HW
  • MemCopy
    • Params: REG1, REG2
    • MEM[REG1] = MEM[REG2]
  • RegCopy
    • Params: REG1, REG2
    • REG1 = REG2