Termination instruction

replace/247b2c6614ab81925e96744398632e3b7bb8b7ad
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 { impl Default for Assembler {
fn default() -> Self { fn default() -> Self {
Self { Self {
buf: vec![0; 3], buf: vec![0; 4],
sub: Default::default(), sub: Default::default(),
} }
} }

View File

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

View File

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

View File

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

View File

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

107
spec.md
View File

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