135 lines
3.4 KiB
Plaintext
135 lines
3.4 KiB
Plaintext
#+TITLE Project Specification
|
|
|
|
* Binary interface
|
|
|
|
The VM does not use floating point numbers, it instead uses fixed point numbers.
|
|
|
|
This is for portability reasons as some devices might not have a FPU in them
|
|
|
|
especially microcontrollers and some retro game systems like the PS1.
|
|
|
|
** Numbers
|
|
| type | size (bytes) | description |
|
|
|------+--------------+---------------------------------------|
|
|
| u8 | 1 | unsigned 8bit, alias =char= and =byte= |
|
|
| bool | 1 | unsigned 8bit, =false= or =true= |
|
|
| i8 | 1 | signed 8bit for interop |
|
|
| u16 | 2 | unsigned 16bit for interop |
|
|
| i16 | 2 | signed 16bit for interop |
|
|
| u32 | 4 | unsigned 32bit, alias =nat= |
|
|
| i32 | 4 | signed 32bit, alias =int= |
|
|
| f32 | 4 | signed 32bit fixed number, alias =real= |
|
|
|
|
* Memory
|
|
|
|
Uses a harvard style archecture, meaning the code and ram memory
|
|
are split up into two seperate blocks.
|
|
|
|
In the C version you can see these are two seperate arrays 'code' and 'mem'.
|
|
|
|
During compilation constants and local variables are put onto 'mem'
|
|
|
|
* Opcodes
|
|
|
|
| 2^n | count |
|
|
|----+-------|
|
|
| 2^3 | 8 |
|
|
| 2^4 | 16 |
|
|
| 2^5 | 32 |
|
|
| 2^6 | 64 |
|
|
| 2^8 | 128 |
|
|
|
|
** could be encoded
|
|
- op type [this is to maximize jump immidate and load immidate size]
|
|
- memory location
|
|
- local value / register
|
|
- local value type
|
|
|
|
*** Simplest
|
|
[opcode][dest][src1][src2]
|
|
[8][8][8][8]
|
|
|
|
*** Maximize inline jump and load-immidate
|
|
[0 0 0 0 0 0 0 0][0 0 0 0 0 0 0 0][0 0 0 0 0 0 0 0][0 0 0 0 0 0 0 0]
|
|
|
|
[0 0 0 | 0 0 0 0 0][0 0 0 | 0 0 0 0 0][0 0 0 | 0 0 0 0 0][0 0 0 | 0 0 0 | 0 0 ] noop
|
|
[0 0 0 | 0 0 0 0 0][0 0 0 | 0 0 0 0 0][0 0 0 | 0 0 0 0 0][0 0 0 | 0 0 1 | 0 0 ] call
|
|
[0 0 0 | 0 0 0 0 0][0 0 0 | 0 0 0 0 0][0 0 0 | 0 0 0 0 0][0 0 0 | 0 1 0 | 0 0 ] return
|
|
[0 0 0 | 0 0 0 0 0][0 0 0 | 0 0 0 0 0][0 0 0 | 0 0 0 0 0][0 0 0 | 0 1 1 | 0 0 ] syscall?
|
|
[0 0 0 | 0 0 0 0 0][0 0 0 | 0 0 0 0 0][0 0 0 | 0 0 0 0 1][0 0 0 | 1 0 0 | 0 0 ] exit
|
|
|
|
[0 0 0 0 0 0 0 0][0 0 0 0 0 0 0 0][0 0 0 0 0 0 0 0][0 0 0 0 0 0 | 0 1 ] jump ~1GB range
|
|
[0 0 0 0 0 0 0 0][0 0 0 0 0 0 0 0][0 0 0 0 0 0 0 0][0 0 0 0 0 0 | 1 0 ] load-immidate 2^30 max
|
|
|
|
*** multibyte ops
|
|
- ones that would be easier if they were multibyte
|
|
- jump
|
|
- load immidate
|
|
- syscall
|
|
- call
|
|
|
|
|
|
0 0 - system, lowest because lower opcodes are faster
|
|
0 1 - memory
|
|
1 0 - math
|
|
1 1 - jump
|
|
|
|
[0 0][0 0 0 0 0 0] = [system][no op]
|
|
[0 0][1 0 0 0 0 0] = [system][loadimm]
|
|
[0 0][0 0 0 0 0 0] = [system][return]
|
|
|
|
|
|
[0 0 0 | r r r r r][0 0 0 | r r r r r][0 0 0 | r r r r r][b b | t | o o o | 1 1] [math][add][f][8]
|
|
[0 0 0 | 0 0 0 0 0][0 0 0 | 0 0 0 0 0][0 0 0 | 0 0 0 0 0][0 0 | 1 | 0 0 1 | 1 1] [math][add][f][8]
|
|
|
|
[0 1][0 0 1][0][0 0] = [math][sub][f][16]
|
|
[0 1][0 1 0][0][0 0] = [math][mul][f][32]
|
|
[0 1][0 1 1][0][0 0] = [math][div][f][?]
|
|
[0 1][1 0 0][0][0 0] = [math][and][f][?]
|
|
|
|
[1 1][0][0 0][0 0] = [jmp][u][eq]
|
|
[1 1][0][0 0][0 0] = [jmp][u][ne]
|
|
[1 1][0][0 0][0 0] = [jmp][u][lt]
|
|
[1 1][0][0 0][0 0] = [jmp][u][gt]
|
|
|
|
[1 1][1][0 0 0][0 0] = [jmp][s][le]
|
|
[1 1][1][0 0 0][0 0] = [jmp][s][ge]
|
|
[1 1][1][0 0 0][0 0] = [jmp][s][]
|
|
[1 1][1][0 0 0][0 0] = [jmp][s][]
|
|
|
|
|
|
|
|
|
|
3 2 2 1
|
|
[...] i 32 0
|
|
|
|
3 1 3 1
|
|
[...] u rl j
|
|
[...] u ab j
|
|
[...] u eq j
|
|
[...] u nq j
|
|
[...] u lt j
|
|
[...] u le j
|
|
[...] u gt j
|
|
[...] u ge j
|
|
|
|
[jmp][dest][18]
|
|
[lli][dest][2]
|
|
|
|
|
|
|
|
int 3
|
|
|
|
add
|
|
sub
|
|
mul
|
|
div
|
|
|
|
jeq
|
|
jne
|
|
|
|
jlt
|
|
jle
|
|
jgt
|
|
jge
|