Files
rasp/vm.md
Alek Ratzloff df950c6f63 Fix arithmetic instruction specs
Originally, arithmetic instructions were in the form of

    REG2 = REG1 (OP) REG2

but then I started storing the result in REG1 (both in implementation,
and later defs of the arth instructions). So I'm updating it to match
what was actually in my head.

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-01-26 10:52:26 -05:00

2.6 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 first register specified.

  • Add
    • Params: REG1, REG2
    • REG1 = REG1 + REG2
  • Mul
    • Params: REG1, REG2
    • REG1 = REG1 * REG2
  • Div
    • Params: REG1, REG2
    • REG1 = REG1 / REG2
  • Mod
    • Params: REG1, REG2
    • REG1 = REG1 % REG2 (exact semantics TBD)
  • Neg
    • Params: REG1
    • REG1 = REG1 * -1
  • And
    • Params: REG1, REG2
    • REG1 = REG1 & REG2
  • Or
    • Params: REG1, REG2
    • REG1 = REG1 | REG2
  • Xor
    • Params: REG1, REG2
    • REG1 = 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
    • Params: REG1, IMM_32
    • REG1 = IMM_32
  • MemCopy
    • Params: REG1, REG2
    • MEM[REG1] = MEM[REG2]
  • RegCopy
    • Params: REG1, REG2
    • REG1 = REG2