remedyvm

A toy RISC virtual machine inspired by Bell Lab's `dis' and Tsoding's `bm'
git clone git://git.ethandl.dev/remedyvm
Log | Files | Refs

specs.ms (6540B)


      1 \" Document specific macros:
      2 .de AL
      3 .   IP
      4 .   B1
      5 .   KS
      6 .   CW
      7 .\" Instruction syntax as $1:
      8 .\" <INST> <CND> <DEST> <TEMP> <TEMP>
      9     \\$1
     10 .   sp 0
     11 .\" Example Usage as $2:
     12 .\" mul <CND> z x y
     13     \\$2
     14 .\" Representative psuedocode as $3:
     15 .\" ; z <- CND ? x * y
     16 .   I "; \\$3"
     17 .   KE
     18 .   B2
     19 .   R
     20 ..
     21 
     22 \" Actual Document start:
     23 .TL
     24 RemedyVM Specifications
     25 
     26 .AU
     27 Ethan Long
     28 
     29 .AI
     30 Australian National University
     31 
     32 .AB
     33 RemedyVM is a memory machine (MM) inspired by the
     34 .CW dis
     35 virtual machine by Bell Labs, and Tsoding's
     36 .CW bm .
     37 The instruction set is close to machine code to allow for easy just-in-time (JIT) and ahead-of-time (AOT) compilation.
     38 .AE
     39 
     40 .NH 1
     41 Instructions & Syntax
     42 .PP
     43 All instructions follow the following general pattern:
     44 .DS I
     45 .CW
     46 inst.<CND> <DST> <SRC>
     47 .DE
     48 Where
     49 .CW <CND>
     50 is the condition for the execution of the instruction (see conditionals for more details),
     51 .CW <DST>
     52 is the destination temporary, and
     53 .CW <SRC>
     54 is the source temporary.
     55 
     56 Comments are started with
     57 .CW ; ' `
     58 and span to the end of the line, anything past this comment will be ignored by any assembler.
     59 
     60 .NH 2
     61 Conditionals
     62 .PP
     63 All instructions support conditionals.
     64 The list of valid conditionals is as follows:
     65 .TS
     66 center doublebox;
     67 c | c
     68 =   =
     69 r | l
     70 -   -
     71 r | l.
     72 T{
     73 .B Conditional
     74 T}	T{
     75 .B Description
     76 T}
     77 T{
     78 .CW eq
     79 T}	If the previous comparison was equal, this condition is true and triggers.
     80 T{
     81 .CW neq
     82 T}	If the previous comparison was not equal, this condition is true and triggers.
     83 .TE
     84 
     85 .NH 2
     86 Memory
     87 
     88 .NH 3
     89 .CW move
     90 .PP
     91 The
     92 .CW move
     93 instruction copies/moves the value stored in one temporary to another temporary.
     94 .SH 4
     95 Usage
     96 .AL "move.<CND> <DST> <SRC>" "move.<CND> y x" "y :=.<CND> ? x : y"
     97 
     98 .NH 3
     99 .CW swap
    100 .PP
    101 The
    102 .CW swap
    103 instruction swaps the value stored in one temporary with the value in another temporary.
    104 .SH 4
    105 Usage
    106 .AL "swap.<CND> <TEMP1> <TEMP2>" "swap.<CND> x y" "if CND { (x, y) := (y, x) }"
    107 
    108 .NH 3
    109 .CW push
    110 .PP
    111 The
    112 .CW push
    113 instruction pushes the specified temporary onto the stack.
    114 .SH 4
    115 Usage
    116 .AL "push.<CND> <SRC>" "push.<CND> x" "if CND { sp := sp + size(x), stack := x : stack }"
    117 
    118 .NH 3
    119 .CW pop
    120 .PP
    121 The
    122 .CW pop
    123 instruction pops from the top of the stack into the specified temporary.
    124 .SH 4
    125 Usage
    126 .AL "pop.<CND> <DEST>" "pop.<CND> x" "if CND { sp := sp - size(x), (x, stack) := (x, xs) in stack(x:xs) }"
    127 
    128 .NH 3
    129 .CW peek
    130 .PP
    131 The
    132 .CW peek
    133 instruction peeks at the top of the stack, copying the value on the top of the stack into the specified temporary.
    134 This is essentially a pop without lowering the stack.
    135 .SH 4
    136 Usage
    137 .AL "peek.<CND> <DEST>" "peek.<CND> x" "x := CND ? head(stack)"
    138 
    139 .NH 3
    140 .CW load
    141 .PP
    142 The
    143 .CW load
    144 instruction loads data from the memory pointed to by
    145 .CW <MEMADDR>
    146 into the specified
    147 .CW <TEMP> .
    148 .SH 4
    149 Usage
    150 .AL "load.<CND> <TEMP> <MEMADDR>" "store.<CND> y x" "CND ? y := Mem(x)"
    151 
    152 .NH 3
    153 .CW store
    154 .PP
    155 The
    156 .CW store
    157 instruction stores the data from the temporary
    158 .CW <TEMP>
    159 into the memory pointed to by
    160 .CW <MEMADDR> .
    161 .SH 4
    162 Usage
    163 .AL "store.<CND> <TEMP> <MEMADDR>" "store.<CND> y x" "CND ? Mem(x) := y"
    164 .B NOTE:
    165 the order of the store instruction is reversed to the regular load & other typical instructions.
    166 
    167 
    168 .NH 2
    169 Arithmetic
    170 
    171 .NH 3
    172 .CW add
    173 .PP
    174 The
    175 .CW add
    176 instruction adds two temporaries and puts the result in a third.
    177 .SH 4
    178 Usage
    179 .AL "add.<CND> <DEST> <TEMP> <TEMP>" "add.<CND> z x y" "z := CND ? x + y"
    180 
    181 .NH 3
    182 .CW sub
    183 .PP
    184 The
    185 .CW sub
    186 instruction subtracts
    187 .CW <TEMP1>
    188 from
    189 .CW <TEMP2>
    190 and puts the result in
    191 .CW <DEST> .
    192 .SH 4
    193 Usage
    194 .AL "sub.<CND> <DEST> <TEMP1> <TEMP2>" "sub.<CND> z x y" "z := CND ? x - y"
    195 
    196 .NH 3
    197 .CW mul
    198 .PP
    199 The
    200 .CW mul
    201 instruction multiplies two temporaries together, putting the result in
    202 .CW <DEST> .
    203 .SH 4
    204 Usage
    205 .AL "mul.<CND> <DEST> <TEMP> <TEMP>" "mul.<CND> z x y" "z := CND ? x * y"
    206 
    207 .NH 3
    208 .CW div
    209 .PP
    210 The
    211 .CW div
    212 instruction divides
    213 .CW <TEMP1>
    214 from
    215 .CW <TEMP2>
    216 and puts the result in
    217 .CW <DEST> .
    218 .SH 4
    219 Usage
    220 .AL "div.<CND> <DEST> <TEMP1> <TEMP2>" "div.<CND> z x y" "z := (CND && y != 0) ? x / y"
    221 .B NOTE:
    222 if
    223 .CW <TEMP2>
    224 is 0, the instruction will act as a
    225 .CW nop ,
    226 as well as set the
    227 .CW dz
    228 condition.
    229 This will need to be checked against at runtime after any division with unknown divisor.
    230 
    231 
    232 .NH 2
    233 Bit Manipulation & Logical Operations
    234 
    235 .NH 3
    236 .CW shiftl
    237 .PP
    238 The
    239 .CW shiftl
    240 instruction shifts a temporary
    241 .CW <TEMP1>
    242 left by
    243 .CW <TEMP2>
    244 into the temporary
    245 .CW <DEST> .
    246 .SH 4
    247 Usage
    248 .AL "shiftl.<CND> <DEST> <TEMP1> <TEMP2>" "shiftl.<CND> z x y" "z := CND ? x << y"
    249 
    250 .NH 3
    251 .CW shiftr(T)
    252 .PP
    253 The
    254 .CW shiftr(T)
    255 instruction shifts a temporary
    256 .CW <TEMP1>
    257 right by
    258 .CW <TEMP2>
    259 into the temporary
    260 .CW <DEST> .
    261 
    262 The
    263 .CW T
    264 parameter takes either
    265 .CW l
    266 (logical), or
    267 .CW a
    268 (arithmetic), and determines whether or not the instruction is an arithmetic or logical shift right.
    269 .SH 4
    270 Usage
    271 .AL "shiftr(T).<CND> <DEST> <TEMP1> <TEMP2>" "shiftr(l).<CND> z x y" "z := CND ? x >> y"
    272 .AL "shiftr(T).<CND> <DEST> <TEMP1> <TEMP2>" "shiftr(a).<CND> z x y" "z := CND ? x \(ti>> y"
    273 
    274 .NH 3
    275 .CW and
    276 .PP
    277 The
    278 .CW and
    279 instruction performs a bitwise AND on
    280 .CW <TEMP1>
    281 and
    282 .CW <TEMP2>
    283 and puts the result in
    284 .CW <DEST> .
    285 .SH 4
    286 Usage
    287 .AL "and.<CND> <DEST> <TEMP1> <TEMP2>" "and.<CND> z x y" "z := CND ? x & y"
    288 
    289 .NH 3
    290 .CW or
    291 .PP
    292 The
    293 .CW or
    294 instruction performs a bitwise OR on
    295 .CW <TEMP1>
    296 and
    297 .CW <TEMP2>
    298 and puts the result in
    299 .CW <DEST> .
    300 .SH 4
    301 Usage
    302 .AL "or.<CND> <DEST> <TEMP1> <TEMP2>" "and.<CND> z x y" "z := CND ? x | y"
    303 
    304 .NH 3
    305 .CW xor
    306 .PP
    307 The
    308 .CW xor
    309 instruction performs a bitwise XOR (eXclusive OR) on
    310 .CW <TEMP1>
    311 and
    312 .CW <TEMP2>
    313 and puts the result in
    314 .CW <DEST> .
    315 .SH 4
    316 Usage
    317 .AL "xor.<CND> <DEST> <TEMP1> <TEMP2>" "xor.<CND> z x y" "z := CND ? x ^ y"
    318 
    319 .NH 3
    320 .CW not
    321 .PP
    322 The
    323 .CW not
    324 instruction performs a bitwise NOT on
    325 .CW <SRC>
    326 and puts the result in
    327 .CW <DEST> .
    328 .SH 4
    329 Usage
    330 .AL "not.<CND> <DEST> <SRC>" "xor.<CND> y x" "y := CND ? !x"
    331 
    332 .NH 2
    333 Control Flow
    334 
    335 .NH 3
    336 .CW jump
    337 .PP
    338 The
    339 .CW jump
    340 instruction perfoms a jump to
    341 .CW <LOCATION> ,
    342 changing the program counter to point to that location.
    343 .SH 4
    344 Usage
    345 .AL "jump.<CND> <LOCATION>" "jump.<CND> x" "if CND { goto x; }"
    346 
    347 .NH 3
    348 .CW call
    349 .PP
    350 The
    351 .CW call
    352 instruction performs a jump to
    353 .CW <LOCATION> ,
    354 pushing the current program counter to the stack so that the callee can return to the caller.
    355 .PP
    356 .B NOTE:
    357 All
    358 .CW call s
    359 should always be
    360 .CW return ed
    361 to, as a
    362 .CW call
    363 pushes to a stack.
    364 .SH 4
    365 Usage
    366 .AL "call.<CND> <LOCATION>" "call.<CND> x" "if CND {x(<ARGS>)}"
    367 
    368 .NH 3
    369 .CW return
    370 .PP
    371 The
    372 .CW return
    373 instruction performs a jump back to wherever the last
    374 .CW call
    375 was.
    376 .SH 4
    377 Usage
    378 .AL "return.<CND>" "return.<CND>" "if CND { return }"