Termination instruction

soft-float
Erin 2023-08-09 01:24:13 +02:00
parent 4530ff049e
commit eadf9e0a1f
6 changed files with 122 additions and 115 deletions

View File

@ -33,7 +33,7 @@ pub struct Assembler {
impl Default for Assembler {
fn default() -> Self {
Self {
buf: vec![0; 3],
buf: vec![0; 4],
sub: Default::default(),
}
}

View File

@ -13,15 +13,15 @@
static_assert(CHAR_BIT == 8, "Cursed architectures are not supported");
enum hbbc_Opcode: uint8_t {
hbbc_Op_NOP , hbbc_Op_ADD , hbbc_Op_SUB , hbbc_Op_MUL , hbbc_Op_AND , hbbc_Op_OR ,
hbbc_Op_XOR , hbbc_Op_SL , hbbc_Op_SR , hbbc_Op_SRS , hbbc_Op_CMP , hbbc_Op_CMPU ,
hbbc_Op_DIR , hbbc_Op_NEG , hbbc_Op_NOT , hbbc_Op_ADDI , hbbc_Op_MULI , hbbc_Op_ANDI ,
hbbc_Op_ORI , hbbc_Op_XORI , hbbc_Op_SLI , hbbc_Op_SRI , hbbc_Op_SRSI , hbbc_Op_CMPI ,
hbbc_Op_CMPUI , hbbc_Op_CP , hbbc_Op_SWA , hbbc_Op_LI , hbbc_Op_LD , hbbc_Op_ST ,
hbbc_Op_BMC , hbbc_Op_BRC , hbbc_Op_JMP , hbbc_Op_JEQ , hbbc_Op_JNE , hbbc_Op_JLT ,
hbbc_Op_JGT , hbbc_Op_JLTU , hbbc_Op_JGTU , hbbc_Op_ECALL , hbbc_Op_ADDF , hbbc_Op_SUBF ,
hbbc_Op_MULF , hbbc_Op_DIRF , hbbc_Op_FMAF , hbbc_Op_NEGF , hbbc_Op_ITF , hbbc_Op_FTI ,
hbbc_Op_ADDFI , hbbc_Op_MULFI ,
hbbc_Op_UN , hbbc_Op_TX , hbbc_Op_NOP , hbbc_Op_ADD , hbbc_Op_SUB , hbbc_Op_MUL ,
hbbc_Op_AND , hbbc_Op_OR , hbbc_Op_XOR , hbbc_Op_SL , hbbc_Op_SR , hbbc_Op_SRS ,
hbbc_Op_CMP , hbbc_Op_CMPU , hbbc_Op_DIR , hbbc_Op_NEG , hbbc_Op_NOT , hbbc_Op_ADDI ,
hbbc_Op_MULI , hbbc_Op_ANDI , hbbc_Op_ORI , hbbc_Op_XORI , hbbc_Op_SLI , hbbc_Op_SRI ,
hbbc_Op_SRSI , hbbc_Op_CMPI , hbbc_Op_CMPUI , hbbc_Op_CP , hbbc_Op_SWA , hbbc_Op_LI ,
hbbc_Op_LD , hbbc_Op_ST , hbbc_Op_BMC , hbbc_Op_BRC , hbbc_Op_JMP , hbbc_Op_JEQ ,
hbbc_Op_JNE , hbbc_Op_JLT , hbbc_Op_JGT , hbbc_Op_JLTU , hbbc_Op_JGTU , hbbc_Op_ECALL ,
hbbc_Op_ADDF , hbbc_Op_SUBF , hbbc_Op_MULF , hbbc_Op_DIRF , hbbc_Op_FMAF , hbbc_Op_NEGF ,
hbbc_Op_ITF , hbbc_Op_FTI , hbbc_Op_ADDFI , hbbc_Op_MULFI ,
} typedef hbbc_Opcode;
static_assert(sizeof(hbbc_Opcode) == 1);

View File

@ -62,7 +62,7 @@ macro_rules! invoke_with_def {
bd(p0: R, p1: I)
=> [LI],
n()
=> [UN, NOP, ECALL],
=> [UN, TX, NOP, ECALL],
);
};
}
@ -73,62 +73,63 @@ constmod!(pub opcode(u8) {
//! Opcode constant module
UN = 0, "N; Raises a trap";
NOP = 1, "N; Do nothing";
TX = 1, "N; Terminate execution";
NOP = 2, "N; Do nothing";
ADD = 2, "BBB; #0 ← #1 + #2";
SUB = 3, "BBB; #0 ← #1 - #2";
MUL = 4, "BBB; #0 ← #1 × #2";
AND = 5, "BBB; #0 ← #1 & #2";
OR = 6, "BBB; #0 ← #1 | #2";
XOR = 7, "BBB; #0 ← #1 ^ #2";
SL = 8, "BBB; #0 ← #1 « #2";
SR = 9, "BBB; #0 ← #1 » #2";
SRS = 10, "BBB; #0 ← #1 » #2 (signed)";
CMP = 11, "BBB; #0 ← #1 <=> #2";
CMPU = 12, "BBB; #0 ← #1 <=> #2 (unsigned)";
DIR = 13, "BBBB; #0 ← #2 / #3, #1 ← #2 % #3";
NEG = 14, "BB; #0 ← -#1";
NOT = 15, "BB; #0 ← !#1";
ADD = 3, "BBB; #0 ← #1 + #2";
SUB = 4, "BBB; #0 ← #1 - #2";
MUL = 5, "BBB; #0 ← #1 × #2";
AND = 6, "BBB; #0 ← #1 & #2";
OR = 7, "BBB; #0 ← #1 | #2";
XOR = 8, "BBB; #0 ← #1 ^ #2";
SL = 9, "BBB; #0 ← #1 « #2";
SR = 10, "BBB; #0 ← #1 » #2";
SRS = 11, "BBB; #0 ← #1 » #2 (signed)";
CMP = 12, "BBB; #0 ← #1 <=> #2";
CMPU = 13, "BBB; #0 ← #1 <=> #2 (unsigned)";
DIR = 14, "BBBB; #0 ← #2 / #3, #1 ← #2 % #3";
NEG = 15, "BB; #0 ← -#1";
NOT = 16, "BB; #0 ← !#1";
ADDI = 16, "BBD; #0 ← #1 + imm #2";
MULI = 17, "BBD; #0 ← #1 × imm #2";
ANDI = 18, "BBD; #0 ← #1 & imm #2";
ORI = 19, "BBD; #0 ← #1 | imm #2";
XORI = 20, "BBD; #0 ← #1 ^ imm #2";
SLI = 21, "BBW; #0 ← #1 « imm #2";
SRI = 22, "BBW; #0 ← #1 » imm #2";
SRSI = 23, "BBW; #0 ← #1 » imm #2 (signed)";
CMPI = 24, "BBD; #0 ← #1 <=> imm #2";
CMPUI = 25, "BBD; #0 ← #1 <=> imm #2 (unsigned)";
ADDI = 17, "BBD; #0 ← #1 + imm #2";
MULI = 18, "BBD; #0 ← #1 × imm #2";
ANDI = 19, "BBD; #0 ← #1 & imm #2";
ORI = 20, "BBD; #0 ← #1 | imm #2";
XORI = 21, "BBD; #0 ← #1 ^ imm #2";
SLI = 22, "BBW; #0 ← #1 « imm #2";
SRI = 23, "BBW; #0 ← #1 » imm #2";
SRSI = 24, "BBW; #0 ← #1 » imm #2 (signed)";
CMPI = 25, "BBD; #0 ← #1 <=> imm #2";
CMPUI = 26, "BBD; #0 ← #1 <=> imm #2 (unsigned)";
CP = 26, "BB; Copy #0 ← #1";
SWA = 27, "BB; Swap #0 and #1";
LI = 28, "BD; #0 ← imm #1";
LD = 29, "BBDB; #0 ← [#1 + imm #3], imm #4 bytes, overflowing";
ST = 30, "BBDB; [#1 + imm #3] ← #0, imm #4 bytes, overflowing";
BMC = 31, "BBD; [#0] ← [#1], imm #2 bytes";
BRC = 32, "BBB; #0 ← #1, imm #2 registers";
CP = 27, "BB; Copy #0 ← #1";
SWA = 28, "BB; Swap #0 and #1";
LI = 29, "BD; #0 ← imm #1";
LD = 30, "BBDB; #0 ← [#1 + imm #3], imm #4 bytes, overflowing";
ST = 31, "BBDB; [#1 + imm #3] ← #0, imm #4 bytes, overflowing";
BMC = 32, "BBD; [#0] ← [#1], imm #2 bytes";
BRC = 33, "BBB; #0 ← #1, imm #2 registers";
JAL = 33, "BD; Copy PC to #0 and unconditional jump [#1 + imm #2]";
JEQ = 34, "BBD; if #0 = #1 → jump imm #2";
JNE = 35, "BBD; if #0 ≠ #1 → jump imm #2";
JLT = 36, "BBD; if #0 < #1 → jump imm #2";
JGT = 37, "BBD; if #0 > #1 → jump imm #2";
JLTU = 38, "BBD; if #0 < #1 → jump imm #2 (unsigned)";
JGTU = 39, "BBD; if #0 > #1 → jump imm #2 (unsigned)";
ECALL = 40, "N; Issue system call";
JAL = 34, "BD; Copy PC to #0 and unconditional jump [#1 + imm #2]";
JEQ = 35, "BBD; if #0 = #1 → jump imm #2";
JNE = 36, "BBD; if #0 ≠ #1 → jump imm #2";
JLT = 37, "BBD; if #0 < #1 → jump imm #2";
JGT = 38, "BBD; if #0 > #1 → jump imm #2";
JLTU = 39, "BBD; if #0 < #1 → jump imm #2 (unsigned)";
JGTU = 40, "BBD; if #0 > #1 → jump imm #2 (unsigned)";
ECALL = 41, "N; Issue system call";
ADDF = 41, "BBB; #0 ← #1 +. #2";
SUBF = 42, "BBB; #0 ← #1 -. #2";
MULF = 43, "BBB; #0 ← #1 +. #2";
DIRF = 44, "BBBB; #0 ← #2 / #3, #1 ← #2 % #3";
FMAF = 45, "BBBB; #0 ← (#1 * #2) + #3";
NEGF = 46, "BB; #0 ← -#1";
ITF = 47, "BB; #0 ← #1 as float";
FTI = 48, "BB; #0 ← #1 as int";
ADDF = 42, "BBB; #0 ← #1 +. #2";
SUBF = 43, "BBB; #0 ← #1 -. #2";
MULF = 44, "BBB; #0 ← #1 +. #2";
DIRF = 45, "BBBB; #0 ← #2 / #3, #1 ← #2 % #3";
FMAF = 46, "BBBB; #0 ← (#1 * #2) + #3";
NEGF = 47, "BB; #0 ← -#1";
ITF = 48, "BB; #0 ← #1 as float";
FTI = 49, "BB; #0 ← #1 as int";
ADDFI = 49, "BBD; #0 ← #1 +. imm #2";
MULFI = 50, "BBD; #0 ← #1 *. imm #2";
ADDFI = 50, "BBD; #0 ← #1 +. imm #2";
MULFI = 51, "BBD; #0 ← #1 *. imm #2";
});
#[repr(packed)]

View File

@ -100,7 +100,7 @@ where
loop {
// Check instruction boundary
if self.pc >= self.program_len {
return Ok(VmRunOk::End);
return Err(VmRunError::AddrOutOfBounds);
}
// Big match
@ -128,6 +128,10 @@ where
self.decode::<()>();
return Err(VmRunError::Unreachable);
}
TX => {
self.decode::<()>();
return Ok(VmRunOk::End);
}
NOP => self.decode::<()>(),
ADD => self.binary_op(u64::wrapping_add),
SUB => self.binary_op(u64::wrapping_sub),

View File

@ -10,6 +10,7 @@ use {
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut prog = vec![];
stdin().read_to_end(&mut prog)?;
println!("{prog:?}");
if let Err(e) = validate(&prog) {
eprintln!("Program validation error: {e:?}");

107
spec.md
View File

@ -34,13 +34,14 @@
- `P ← V`: Set register P to value V
- `[x]`: Address x
## No-op
## Program execution control
- N type
| Opcode | Name | Action |
|:------:|:----:|:-----------------------------:|
| 0 | UN | Trigger unreachable code trap |
| 1 | NOP | Do nothing |
| 1 | TX | Terminate execution |
| 2 | NOP | Do nothing |
## Integer binary ops.
- BBB type
@ -48,21 +49,21 @@
| Opcode | Name | Action |
|:------:|:----:|:-----------------------:|
| 2 | ADD | Wrapping addition |
| 3 | SUB | Wrapping subtraction |
| 4 | MUL | Wrapping multiplication |
| 5 | AND | Bitand |
| 6 | OR | Bitor |
| 7 | XOR | Bitxor |
| 8 | SL | Unsigned left bitshift |
| 9 | SR | Unsigned right bitshift |
| 10 | SRS | Signed right bitshift |
| 3 | ADD | Wrapping addition |
| 4 | SUB | Wrapping subtraction |
| 5 | MUL | Wrapping multiplication |
| 6 | AND | Bitand |
| 7 | OR | Bitor |
| 8 | XOR | Bitxor |
| 9 | SL | Unsigned left bitshift |
| 10 | SR | Unsigned right bitshift |
| 11 | SRS | Signed right bitshift |
### Comparsion
| Opcode | Name | Action |
|:------:|:----:|:-------------------:|
| 11 | CMP | Signed comparsion |
| 12 | CMPU | Unsigned comparsion |
| 12 | CMP | Signed comparsion |
| 13 | CMPU | Unsigned comparsion |
#### Comparsion table
| #1 *op* #2 | Result |
@ -79,7 +80,7 @@
| Opcode | Name | Action |
|:------:|:----:|:-------------------------------:|
| 13 | DIR | Divide and remainder combinated |
| 14 | DIR | Divide and remainder combinated |
### Negations
- Type BB
@ -87,36 +88,36 @@
| Opcode | Name | Action |
|:------:|:----:|:----------------:|
| 14 | NEG | Bit negation |
| 15 | NOT | Logical negation |
| 15 | NEG | Bit negation |
| 16 | NOT | Logical negation |
## Integer immediate binary ops.
- Type BBD
- `#0 ← #1 <op> imm #2`
| Opcode | Name | Action |
|:------:|:----:|:-----------------------:|
| 16 | ADDI | Wrapping addition |
| 17 | MULI | Wrapping subtraction |
| 18 | ANDI | Bitand |
| 19 | ORI | Bitor |
| 20 | XORI | Bitxor |
| Opcode | Name | Action |
|:------:|:----:|:--------------------:|
| 17 | ADDI | Wrapping addition |
| 18 | MULI | Wrapping subtraction |
| 19 | ANDI | Bitand |
| 20 | ORI | Bitor |
| 21 | XORI | Bitxor |
### Bitshifts
- Type BBW
| Opcode | Name | Action |
|:------:|:----:|:-----------------------:|
| 21 | SLI | Unsigned left bitshift |
| 22 | SRI | Unsigned right bitshift |
| 23 | SRSI | Signed right bitshift |
| 22 | SLI | Unsigned left bitshift |
| 23 | SRI | Unsigned right bitshift |
| 24 | SRSI | Signed right bitshift |
### Comparsion
- Comparsion is the same as when RRR type
| Opcode | Name | Action |
|:------:|:-----:|:-------------------:|
| 24 | CMPI | Signed comparsion |
| 25 | CMPUI | Unsigned comparsion |
| 25 | CMPI | Signed comparsion |
| 26 | CMPUI | Unsigned comparsion |
## Register value set / copy
@ -126,7 +127,7 @@
| Opcode | Name | Action |
|:------:|:----:|:------:|
| 26 | CP | Copy |
| 27 | CP | Copy |
### Swap
- Type BB
@ -137,7 +138,7 @@
| Opcode | Name | Action |
|:------:|:----:|:------:|
| 27 | SWA | Swap |
| 28 | SWA | Swap |
### Load immediate
- Type BD
@ -145,7 +146,7 @@
| Opcode | Name | Action |
|:------:|:----:|:--------------:|
| 28 | LI | Load immediate |
| 29 | LI | Load immediate |
## Memory operations
- Type BBDH
@ -154,8 +155,8 @@
### Load / Store
| Opcode | Name | Action |
|:------:|:----:|:---------------------------------------:|
| 29 | LD | `#0 ← [#1 + imm #3], copy imm #4 bytes` |
| 30 | ST | `[#1 + imm #3] ← #0, copy imm #4 bytes` |
| 30 | LD | `#0 ← [#1 + imm #3], copy imm #4 bytes` |
| 31 | ST | `[#1 + imm #3] ← #0, copy imm #4 bytes` |
## Block copy
- Block copy source and target can overlap
@ -165,7 +166,7 @@
| Opcode | Name | Action |
|:------:|:----:|:--------------------------------:|
| 31 | BMC | `[#1] ← [#0], copy imm #2 bytes` |
| 32 | BMC | `[#1] ← [#0], copy imm #2 bytes` |
### Register copy
- Type BBB
@ -173,7 +174,7 @@
| Opcode | Name | Action |
|:------:|:----:|:--------------------------------:|
| 32 | BRC | `#1 ← #0, copy imm #2 registers` |
| 33 | BRC | `#1 ← #0, copy imm #2 registers` |
## Control flow
@ -182,7 +183,7 @@
| Opcode | Name | Action |
|:------:|:----:|:--------------------------------------------------:|
| 33 | JAL | Save PC past JAL to `#0` and jump at `#1 + imm #2` |
| 34 | JAL | Save PC past JAL to `#0` and jump at `#1 + imm #2` |
### Conditional jumps
- Type BBD
@ -190,19 +191,19 @@
| Opcode | Name | Comparsion |
|:------:|:----:|:------------:|
| 34 | JEQ | = |
| 35 | JNE | ≠ |
| 36 | JLT | < (signed) |
| 37 | JGT | > (signed) |
| 38 | JLTU | < (unsigned) |
| 39 | JGTU | > (unsigned) |
| 35 | JEQ | = |
| 36 | JNE | ≠ |
| 37 | JLT | < (signed) |
| 38 | JGT | > (signed) |
| 39 | JLTU | < (unsigned) |
| 40 | JGTU | > (unsigned) |
### Environment call
- Type N
| Opcode | Name | Action |
|:------:|:-----:|:-------------------------------------:|
| 40 | ECALL | Cause an trap to the host environment |
| 41 | ECALL | Cause an trap to the host environment |
## Floating point operations
- Type BBB
@ -210,29 +211,29 @@
| Opcode | Name | Action |
|:------:|:----:|:--------------:|
| 41 | ADDF | Addition |
| 42 | SUBF | Subtraction |
| 43 | MULF | Multiplication |
| 42 | ADDF | Addition |
| 43 | SUBF | Subtraction |
| 44 | MULF | Multiplication |
### Division-remainder
- Type BBBB
| Opcode | Name | Action |
|:------:|:----:|:-------------------------:|
| 44 | DIRF | Same as for integer `DIR` |
| 45 | DIRF | Same as for integer `DIR` |
### Fused Multiply-Add
- Type BBBB
| Opcode | Name | Action |
|:------:|:----:|:---------------------:|
| 45 | FMAF | `#0 ← (#1 * #2) + #3` |
| 46 | FMAF | `#0 ← (#1 * #2) + #3` |
### Negation
- Type BB
| Opcode | Name | Action |
|:------:|:----:|:----------:|
| 46 | NEGF | `#0 ← -#1` |
| 47 | NEGF | `#0 ← -#1` |
### Conversion
- Type BB
@ -241,8 +242,8 @@
| Opcode | Name | Action |
|:------:|:----:|:------------:|
| 47 | ITF | Int to Float |
| 48 | FTI | Float to Int |
| 48 | ITF | Int to Float |
| 49 | FTI | Float to Int |
## Floating point immediate operations
- Type BBD
@ -250,8 +251,8 @@
| Opcode | Name | Action |
|:------:|:-----:|:--------------:|
| 49 | ADDFI | Addition |
| 50 | MULFI | Multiplication |
| 50 | ADDFI | Addition |
| 51 | MULFI | Multiplication |
# Registers
- There is 255 registers + one zero register (with index 0)