forked from AbleOS/holey-bytes
spec
This commit is contained in:
parent
9ee9d6e266
commit
bdb596befb
|
@ -52,11 +52,11 @@ macro_rules! tokendef {
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
tokendef![
|
tokendef![
|
||||||
"nop", "add", "sub", "mul", "and", "or", "xor", "sl", "sr", "srs", "cmp", "cmpu", "not",
|
"nop", "add", "sub", "mul", "and", "or", "xor", "sl", "sr", "srs", "cmp", "cmpu", "not", "neg",
|
||||||
"dir", "addf", "subf", "mulf", "dirf", "addi", "muli", "andi", "ori",
|
"dir", "addf", "mulf", "dirf", "addi", "muli", "andi", "ori",
|
||||||
"xori", "sli", "sri", "srsi", "cmpi", "cmpui", "addfi", "mulfi", "cp", "li", "lb",
|
"xori", "sli", "sri", "srsi", "cmpi", "cmpui", "addfi", "mulfi", "cp", "li", "lb",
|
||||||
"ld", "lq", "lo", "sb", "sd", "sq", "so", "jmp", "jeq", "jne", "jlt", "jgt",
|
"ld", "lq", "lo", "sb", "sd", "sq", "so", "jmp", "jeq", "jne", "jlt", "jgt",
|
||||||
"jltu", "jgtu", "ret", "ecall",
|
"jltu", "jgtu", "ecall",
|
||||||
];
|
];
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||||
|
@ -112,12 +112,12 @@ pub fn assembly(code: &str, buf: &mut Vec<u8>) -> Result<(), Error> {
|
||||||
Some(Ok(Token::OpCode(op))) => {
|
Some(Ok(Token::OpCode(op))) => {
|
||||||
self.buf.push(op);
|
self.buf.push(op);
|
||||||
match op {
|
match op {
|
||||||
NOP | RET | ECALL => Ok(()),
|
NOP | ECALL => Ok(()),
|
||||||
DIR | DIRF => self.rrrr(),
|
DIR | DIRF => self.rrrr(),
|
||||||
ADD..=CMPU | ADDF..=MULF => self.rrr(),
|
ADD..=CMPU | ADDF..=MULF => self.rrr(),
|
||||||
NOT | CP => self.rr(),
|
NOT | CP => self.rr(),
|
||||||
LI | JMP => self.ri(),
|
LI | JMP => self.ri(),
|
||||||
ADDI..=MULFI | LB..=SO | JEQ..=JGTU => self.rri(),
|
ADDI..=CMPUI | ADDFI..=MULFI | LB..=SO | JEQ..=JGTU => self.rri(),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}?;
|
}?;
|
||||||
match self.next() {
|
match self.next() {
|
||||||
|
|
|
@ -32,46 +32,46 @@ constmod!(pub opcode(u8) {
|
||||||
CMP = 10, "RRR; #0 ← #1 <=> #2";
|
CMP = 10, "RRR; #0 ← #1 <=> #2";
|
||||||
CMPU = 11, "RRR; #0 ← #1 <=> #2 (unsigned)";
|
CMPU = 11, "RRR; #0 ← #1 <=> #2 (unsigned)";
|
||||||
DIR = 12, "RRRR; #0 ← #2 / #3, #1 ← #2 % #3";
|
DIR = 12, "RRRR; #0 ← #2 / #3, #1 ← #2 % #3";
|
||||||
NOT = 13, "RR; #0 ← !#1";
|
NEG = 13, "RR; #0 ← ~#1";
|
||||||
|
NOT = 14, "RR; #0 ← !#1";
|
||||||
|
|
||||||
ADDF = 14, "RRR; #0 ← #1 +. #2";
|
ADDI = 18, "RRI; #0 ← #1 + imm #2";
|
||||||
SUBF = 15, "RRR; #0 ← #1 +. #2";
|
MULI = 19, "RRI; #0 ← #1 × imm #2";
|
||||||
MULF = 16, "RRR; #0 ← #1 +. #2";
|
ANDI = 20, "RRI; #0 ← #1 & imm #2";
|
||||||
ADDI = 17, "RRI; #0 ← #1 + imm #2";
|
ORI = 21, "RRI; #0 ← #1 | imm #2";
|
||||||
MULI = 18, "RRI; #0 ← #1 × imm #2";
|
XORI = 22, "RRI; #0 ← #1 ^ imm #2";
|
||||||
ANDI = 19, "RRI; #0 ← #1 & imm #2";
|
SLI = 23, "RRI; #0 ← #1 « imm #2";
|
||||||
ORI = 20, "RRI; #0 ← #1 | imm #2";
|
SRI = 24, "RRI; #0 ← #1 » imm #2";
|
||||||
XORI = 21, "RRI; #0 ← #1 ^ imm #2";
|
SRSI = 25, "RRI; #0 ← #1 » imm #2 (signed)";
|
||||||
SLI = 22, "RRI; #0 ← #1 « imm #2";
|
CMPI = 26, "RRI; #0 ← #1 <=> imm #2";
|
||||||
SRI = 23, "RRI; #0 ← #1 » imm #2";
|
CMPUI = 27, "RRI; #0 ← #1 <=> imm #2 (unsigned)";
|
||||||
SRSI = 24, "RRI; #0 ← #1 » imm #2 (signed)";
|
|
||||||
CMPI = 25, "RRI; #0 ← #1 <=> imm #2";
|
|
||||||
CMPUI = 26, "RRI; #0 ← #1 <=> imm #2 (unsigned)";
|
|
||||||
DIRF = 27, "RRRR; #0 ← #2 / #3, #1 ← #2 % #3";
|
|
||||||
|
|
||||||
ADDFI = 28, "RRI; #0 ← #1 +. imm #2";
|
CP = 28, "RR; Copy #0 ← #1";
|
||||||
MULFI = 29, "RRI; #0 ← #1 *. imm #2";
|
LI = 29, "RI; Load immediate, #0 ← imm #1";
|
||||||
|
LB = 30, "RRI; Load byte (8 bits), #0 ← [#1 + imm #2]";
|
||||||
|
LD = 31, "RRI; Load doublet (16 bits)";
|
||||||
|
LQ = 32, "RRI; Load quadlet (32 bits)";
|
||||||
|
LO = 33, "RRI; Load octlet (64 bits)";
|
||||||
|
SB = 34, "RRI; Store byte, [#1 + imm #2] ← #0";
|
||||||
|
SD = 35, "RRI; Store doublet";
|
||||||
|
SQ = 36, "RRI; Store quadlet";
|
||||||
|
SO = 37, "RRI; Store octlet";
|
||||||
|
|
||||||
CP = 30, "RR; Copy #0 ← #1";
|
JMP = 38, "RI; Unconditional jump [#0 + imm #1]";
|
||||||
LI = 31, "RI; Load immediate, #0 ← imm #1";
|
JEQ = 39, "RRI; if #0 = #1 → jump imm #2";
|
||||||
LB = 32, "RRI; Load byte (8 bits), #0 ← [#1 + imm #2]";
|
JNE = 40, "RRI; if #0 ≠ #1 → jump imm #2";
|
||||||
LD = 33, "RRI; Load doublet (16 bits)";
|
JLT = 41, "RRI; if #0 < #1 → jump imm #2";
|
||||||
LQ = 34, "RRI; Load quadlet (32 bits)";
|
JGT = 42, "RRI; if #0 > #1 → jump imm #2";
|
||||||
LO = 35, "RRI; Load octlet (64 bits)";
|
JLTU = 43, "RRI; if #0 < #1 → jump imm #2 (unsigned)";
|
||||||
SB = 36, "RRI; Store byte, [#1 + imm #2] ← #0";
|
JGTU = 44, "RRI; if #0 > #1 → jump imm #2 (unsigned)";
|
||||||
SD = 37, "RRI; Store doublet";
|
ECALL = 45, "N; Issue system call";
|
||||||
SQ = 38, "RRI; Store quadlet";
|
|
||||||
SO = 39, "RRI; Store octlet";
|
|
||||||
|
|
||||||
JMP = 40, "RI; Unconditional jump [#0 + imm #1]";
|
ADDF = 46, "RRR; #0 ← #1 +. #2";
|
||||||
JEQ = 41, "RRI; if #0 = #1 → jump imm #2";
|
MULF = 47, "RRR; #0 ← #1 +. #2";
|
||||||
JNE = 42, "RRI; if #0 ≠ #1 → jump imm #2";
|
DIRF = 48, "RRRR; #0 ← #2 / #3, #1 ← #2 % #3";
|
||||||
JLT = 43, "RRI; if #0 < #1 → jump imm #2";
|
|
||||||
JGT = 44, "RRI; if #0 > #1 → jump imm #2";
|
ADDFI = 49, "RRI; #0 ← #1 +. imm #2";
|
||||||
JLTU = 45, "RRI; if #0 < #1 → jump imm #2 (unsigned)";
|
MULFI = 50, "RRI; #0 ← #1 *. imm #2";
|
||||||
JGTU = 46, "RRI; if #0 > #1 → jump imm #2 (unsigned)";
|
|
||||||
RET = 47, "N; Return";
|
|
||||||
ECALL = 48, "N; Issue system call";
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ pub fn validate(mut program: &[u8]) -> Result<(), Error> {
|
||||||
program = match program {
|
program = match program {
|
||||||
[] => return Ok(()),
|
[] => return Ok(()),
|
||||||
// N
|
// N
|
||||||
[NOP | RET | ECALL, rest @ ..] => rest,
|
[NOP | ECALL, rest @ ..] => rest,
|
||||||
// RRRR
|
// RRRR
|
||||||
[DIR | DIRF, _, _, _, _, rest @ ..] => {
|
[DIR | DIRF, _, _, _, _, rest @ ..] => {
|
||||||
if let Some(n) = reg(&program[1..=4]) {
|
if let Some(n) = reg(&program[1..=4]) {
|
||||||
|
@ -69,7 +69,8 @@ pub fn validate(mut program: &[u8]) -> Result<(), Error> {
|
||||||
rest
|
rest
|
||||||
}
|
}
|
||||||
// RRI
|
// RRI
|
||||||
[ADDI..=MULFI | LB..=SO | JEQ..=JGTU, _, _, _, _, _, _, _, _, _, _, rest @ ..] => {
|
[ADDI..=CMPUI | ADDFI..=MULFI | LB..=SO | JEQ..=JGTU, _, _, _, _, _, _, _, _, _, _, rest @ ..] =>
|
||||||
|
{
|
||||||
if let Some(n) = reg(&program[1..=2]) {
|
if let Some(n) = reg(&program[1..=2]) {
|
||||||
bail!(InvalidRegister, start, program, n + 1);
|
bail!(InvalidRegister, start, program, n + 1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -162,6 +162,17 @@ impl<'a> Vm<'a> {
|
||||||
let param = param!(self, ParamRR);
|
let param = param!(self, ParamRR);
|
||||||
self.write_reg(param.0, (!self.read_reg(param.1).int()).into());
|
self.write_reg(param.0, (!self.read_reg(param.1).int()).into());
|
||||||
}
|
}
|
||||||
|
NEG => {
|
||||||
|
let param = param!(self, ParamRR);
|
||||||
|
self.write_reg(
|
||||||
|
param.0,
|
||||||
|
match self.read_reg(param.1).int() {
|
||||||
|
0 => 1_u64,
|
||||||
|
_ => 0,
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
);
|
||||||
|
}
|
||||||
DIR => {
|
DIR => {
|
||||||
let ParamRRRR(dt, rt, a0, a1) = param!(self, ParamRRRR);
|
let ParamRRRR(dt, rt, a0, a1) = param!(self, ParamRRRR);
|
||||||
let a0 = self.read_reg(a0).int();
|
let a0 = self.read_reg(a0).int();
|
||||||
|
@ -169,16 +180,6 @@ impl<'a> Vm<'a> {
|
||||||
self.write_reg(dt, (a0.checked_div(a1).unwrap_or(u64::MAX)).into());
|
self.write_reg(dt, (a0.checked_div(a1).unwrap_or(u64::MAX)).into());
|
||||||
self.write_reg(rt, (a0.checked_rem(a1).unwrap_or(u64::MAX)).into());
|
self.write_reg(rt, (a0.checked_rem(a1).unwrap_or(u64::MAX)).into());
|
||||||
}
|
}
|
||||||
ADDF => binary_op!(self, float, ops::Add::add),
|
|
||||||
SUBF => binary_op!(self, float, ops::Sub::sub),
|
|
||||||
MULF => binary_op!(self, float, ops::Mul::mul),
|
|
||||||
DIRF => {
|
|
||||||
let ParamRRRR(dt, rt, a0, a1) = param!(self, ParamRRRR);
|
|
||||||
let a0 = self.read_reg(a0).float();
|
|
||||||
let a1 = self.read_reg(a1).float();
|
|
||||||
self.write_reg(dt, (a0 / a1).into());
|
|
||||||
self.write_reg(rt, (a0 % a1).into());
|
|
||||||
}
|
|
||||||
ADDI => binary_op_imm!(self, int, ops::Add::add),
|
ADDI => binary_op_imm!(self, int, ops::Add::add),
|
||||||
MULI => binary_op_imm!(self, int, ops::Mul::mul),
|
MULI => binary_op_imm!(self, int, ops::Mul::mul),
|
||||||
ANDI => binary_op_imm!(self, int, ops::BitAnd::bitand),
|
ANDI => binary_op_imm!(self, int, ops::BitAnd::bitand),
|
||||||
|
@ -187,8 +188,6 @@ impl<'a> Vm<'a> {
|
||||||
SLI => binary_op_imm!(self, int, ops::Shl::shl),
|
SLI => binary_op_imm!(self, int, ops::Shl::shl),
|
||||||
SRI => binary_op_imm!(self, int, ops::Shr::shr),
|
SRI => binary_op_imm!(self, int, ops::Shr::shr),
|
||||||
SRSI => binary_op_imm!(self, sint, ops::Shr::shr),
|
SRSI => binary_op_imm!(self, sint, ops::Shr::shr),
|
||||||
ADDFI => binary_op_imm!(self, float, ops::Add::add),
|
|
||||||
MULFI => binary_op_imm!(self, float, ops::Mul::mul),
|
|
||||||
CMPI => {
|
CMPI => {
|
||||||
let ParamRRI(tg, a0, imm) = param!(self, ParamRRI);
|
let ParamRRI(tg, a0, imm) = param!(self, ParamRRI);
|
||||||
self.write_reg(
|
self.write_reg(
|
||||||
|
@ -235,6 +234,17 @@ impl<'a> Vm<'a> {
|
||||||
param!(self, ());
|
param!(self, ());
|
||||||
return HaltReason::Ecall;
|
return HaltReason::Ecall;
|
||||||
}
|
}
|
||||||
|
ADDF => binary_op!(self, float, ops::Add::add),
|
||||||
|
MULF => binary_op!(self, float, ops::Mul::mul),
|
||||||
|
DIRF => {
|
||||||
|
let ParamRRRR(dt, rt, a0, a1) = param!(self, ParamRRRR);
|
||||||
|
let a0 = self.read_reg(a0).float();
|
||||||
|
let a1 = self.read_reg(a1).float();
|
||||||
|
self.write_reg(dt, (a0 / a1).into());
|
||||||
|
self.write_reg(rt, (a0 % a1).into());
|
||||||
|
}
|
||||||
|
ADDFI => binary_op_imm!(self, float, ops::Add::add),
|
||||||
|
MULFI => binary_op_imm!(self, float, ops::Mul::mul),
|
||||||
_ => core::hint::unreachable_unchecked(),
|
_ => core::hint::unreachable_unchecked(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
240
spec.md
240
spec.md
|
@ -1 +1,241 @@
|
||||||
# HoleyBytes ISA Specification
|
# HoleyBytes ISA Specification
|
||||||
|
|
||||||
|
# Bytecode format
|
||||||
|
- All numbers are encoded little-endian
|
||||||
|
- There is 60 registers (0 – 59), they are represented by a byte
|
||||||
|
- Immediate values are 64 bit
|
||||||
|
|
||||||
|
### Instruction encoding
|
||||||
|
- Instruction parameters are packed (no alignment)
|
||||||
|
- [opcode, …parameters…]
|
||||||
|
|
||||||
|
### Instruction parameter types
|
||||||
|
- R = Register
|
||||||
|
- I = Immediate
|
||||||
|
|
||||||
|
| Name | Size |
|
||||||
|
|:----:|:--------|
|
||||||
|
| RRRR | 32 bits |
|
||||||
|
| RRR | 24 bits |
|
||||||
|
| RRI | 80 bits |
|
||||||
|
| RR | 16 bits |
|
||||||
|
| RI | 72 bits |
|
||||||
|
| I | 64 bits |
|
||||||
|
| N | 0 bits |
|
||||||
|
|
||||||
|
# Instructions
|
||||||
|
- `#n`: register in parameter *n*
|
||||||
|
- `imm #n`: for immediate in parameter *n*
|
||||||
|
- `P ← V`: Set register P to value V
|
||||||
|
- `[x]`: Address x
|
||||||
|
|
||||||
|
## No-op
|
||||||
|
- N type
|
||||||
|
|
||||||
|
| Opcode | Name | Action |
|
||||||
|
|:------:|:----:|:----------:|
|
||||||
|
| 0 | NOP | Do nothing |
|
||||||
|
|
||||||
|
## Integer binary ops.
|
||||||
|
- RRR type
|
||||||
|
- `#0 ← #1 <op> #2`
|
||||||
|
|
||||||
|
| Opcode | Name | Action |
|
||||||
|
|:------:|:----:|:-----------------------:|
|
||||||
|
| 1 | ADD | Wrapping addition |
|
||||||
|
| 2 | SUB | Wrapping subtraction |
|
||||||
|
| 3 | MUL | Wrapping multiplication |
|
||||||
|
| 4 | AND | Bitand |
|
||||||
|
| 5 | OR | Bitor |
|
||||||
|
| 6 | XOR | Bitxor |
|
||||||
|
| 7 | SL | Unsigned left bitshift |
|
||||||
|
| 8 | SR | Unsigned right bitshift |
|
||||||
|
| 9 | SRS | Signed right bitshift |
|
||||||
|
|
||||||
|
### Comparsion
|
||||||
|
| Opcode | Name | Action |
|
||||||
|
|:------:|:----:|:-------------------:|
|
||||||
|
| 10 | CMP | Signed comparsion |
|
||||||
|
| 11 | CMPU | Unsigned comparsion |
|
||||||
|
|
||||||
|
#### Comparsion table
|
||||||
|
| #1 *op* #2 | Result |
|
||||||
|
|:----------:|:------:|
|
||||||
|
| < | -1 |
|
||||||
|
| = | 0 |
|
||||||
|
| > | 1 |
|
||||||
|
|
||||||
|
### Division-remainder
|
||||||
|
- Type RRRR
|
||||||
|
- In case of `#3` is zero, the resulting value is all-ones
|
||||||
|
- `#0 ← #2 ÷ #3`
|
||||||
|
- `#1 ← #2 % #3`
|
||||||
|
|
||||||
|
| Opcode | Name | Action |
|
||||||
|
|:------:|:----:|:-------------------------------:|
|
||||||
|
| 12 | DIR | Divide and remainder combinated |
|
||||||
|
|
||||||
|
### Negations
|
||||||
|
- Type RR
|
||||||
|
- `#0 ← #1 <op> #2`
|
||||||
|
|
||||||
|
| Opcode | Name | Action |
|
||||||
|
|:------:|:----:|:----------------:|
|
||||||
|
| 13 | NEG | Bit negation |
|
||||||
|
| 14 | NOT | Logical negation |
|
||||||
|
|
||||||
|
## Integer immediate binary ops.
|
||||||
|
- Type RRI
|
||||||
|
- `#0 ← #1 <op> imm #2`
|
||||||
|
|
||||||
|
| Opcode | Name | Action |
|
||||||
|
|:------:|:----:|:-----------------------:|
|
||||||
|
| 18 | ADDI | Wrapping addition |
|
||||||
|
| 19 | MULI | Wrapping subtraction |
|
||||||
|
| 20 | ANDI | Bitand |
|
||||||
|
| 21 | ORI | Bitor |
|
||||||
|
| 22 | XORI | Bitxor |
|
||||||
|
| 23 | SLI | Unsigned left bitshift |
|
||||||
|
| 24 | SRI | Unsigned right bitshift |
|
||||||
|
| 25 | SRSI | Signed right bitshift |
|
||||||
|
|
||||||
|
### Comparsion
|
||||||
|
- Comparsion is the same as when RRR type
|
||||||
|
|
||||||
|
| Opcode | Name | Action |
|
||||||
|
|:------:|:-----:|:-------------------:|
|
||||||
|
| 26 | CMPI | Signed comparsion |
|
||||||
|
| 27 | CMPUI | Unsigned comparsion |
|
||||||
|
|
||||||
|
## Register value set / copy
|
||||||
|
|
||||||
|
### Copy
|
||||||
|
- Type RR
|
||||||
|
- `#0 ← #1`
|
||||||
|
|
||||||
|
| Opcode | Name | Action |
|
||||||
|
|:------:|:----:|:------:|
|
||||||
|
| 28 | CP | Copy |
|
||||||
|
|
||||||
|
### Load immediate
|
||||||
|
- Type RI
|
||||||
|
- `#0 ← #1`
|
||||||
|
|
||||||
|
| Opcode | Name | Action |
|
||||||
|
|:------:|:----:|:--------------:|
|
||||||
|
| 29 | LI | Load immediate |
|
||||||
|
|
||||||
|
## Memory operations
|
||||||
|
- Type RRI
|
||||||
|
|
||||||
|
### Load
|
||||||
|
- `#0 ← [#1 + imm #2]`
|
||||||
|
|
||||||
|
| Opcode | Name | Action |
|
||||||
|
|:------:|:----:|:----------------------:|
|
||||||
|
| 30 | LB | Load byte (8 bits) |
|
||||||
|
| 31 | LD | Load doublet (16 bits) |
|
||||||
|
| 32 | LQ | Load quadlet (32 bits) |
|
||||||
|
| 33 | LO | Load octlet (64 bits) |
|
||||||
|
|
||||||
|
### Store
|
||||||
|
- `[#1 + imm #2] ← #0`
|
||||||
|
|
||||||
|
| Opcode | Name | Action |
|
||||||
|
|:------:|:----:|:-----------------------:|
|
||||||
|
| 34 | SB | Store byte (8 bits) |
|
||||||
|
| 35 | SD | Store doublet (16 bits) |
|
||||||
|
| 36 | SQ | Store quadlet (32 bits) |
|
||||||
|
| 37 | SO | Store octlet (64 bits) |
|
||||||
|
|
||||||
|
## Control flow
|
||||||
|
|
||||||
|
### Unconditional jump
|
||||||
|
- Type RI
|
||||||
|
|
||||||
|
| Opcode | Name | Action |
|
||||||
|
|:------:|:----:|:---------------------:|
|
||||||
|
| 38 | JMP | Jump at `#0 + imm #1` |
|
||||||
|
|
||||||
|
### Conditional jumps
|
||||||
|
- Type RRI
|
||||||
|
- Jump at `imm #2` if `#0 <op> #1`
|
||||||
|
|
||||||
|
| Opcode | Name | Comparsion |
|
||||||
|
|:------:|:----:|:------------:|
|
||||||
|
| 39 | JEQ | = |
|
||||||
|
| 40 | JNE | ≠ |
|
||||||
|
| 41 | JLT | < (signed) |
|
||||||
|
| 42 | JGT | > (signed) |
|
||||||
|
| 43 | JLTU | < (unsigned) |
|
||||||
|
| 44 | JGTU | > (unsigned) |
|
||||||
|
|
||||||
|
### Environment call
|
||||||
|
- Type N
|
||||||
|
|
||||||
|
| Opcode | Name | Action |
|
||||||
|
|:------:|:-----:|:-------------------------------------:|
|
||||||
|
| 45 | ECALL | Cause an trap to the host environment |
|
||||||
|
|
||||||
|
## Floating point operations
|
||||||
|
- Type RRR
|
||||||
|
- `#0 ← #1 <op> #2`
|
||||||
|
|
||||||
|
| Opcode | Name | Action |
|
||||||
|
|:------:|:----:|:--------------:|
|
||||||
|
| 46 | ADDF | Addition |
|
||||||
|
| 47 | MULF | Multiplication |
|
||||||
|
|
||||||
|
### Division-remainder
|
||||||
|
- Type RRRR
|
||||||
|
|
||||||
|
| Opcode | Name | Action |
|
||||||
|
|:------:|:----:|:--------------------------------------:|
|
||||||
|
| 48 | DIRF | Same flow applies as for integer `DIR` |
|
||||||
|
|
||||||
|
## Floating point immediate operations
|
||||||
|
- Type RRI
|
||||||
|
- `#0 ← #1 <op> imm #2`
|
||||||
|
|
||||||
|
| Opcode | Name | Action |
|
||||||
|
|:------:|:-----:|:--------------:|
|
||||||
|
| 49 | ADDFI | Addition |
|
||||||
|
| 50 | MULFI | Multiplication |
|
||||||
|
|
||||||
|
# Registers
|
||||||
|
- There is 59 registers + one zero register (with index 0)
|
||||||
|
- Reading from zero register yields zero
|
||||||
|
- Writing to zero register is a no-op
|
||||||
|
|
||||||
|
# Memory
|
||||||
|
- Addresses are 64 bit
|
||||||
|
- Memory implementation is arbitrary
|
||||||
|
- In case of accessing invalid address:
|
||||||
|
- Program shall trap (LoadAccessEx, StoreAccessEx) with parameter of accessed address
|
||||||
|
- Value of register when trapped is undefined
|
||||||
|
|
||||||
|
## Recommendations
|
||||||
|
- Leave address `0x0` as invalid
|
||||||
|
- If paging used:
|
||||||
|
- Leave first page invalid
|
||||||
|
- Pages should be at least 4 KiB
|
||||||
|
|
||||||
|
# Program execution
|
||||||
|
- The way of program execution is implementation defined
|
||||||
|
- The order of instruction is arbitrary, as long all observable
|
||||||
|
effects are applied in the program's order
|
||||||
|
|
||||||
|
# Program validation
|
||||||
|
- Invalid program should cause runtime error:
|
||||||
|
- The form of error is arbitrary. Can be a trap or an interpreter-specified error
|
||||||
|
- It shall not be handleable from within the program
|
||||||
|
- Executing invalid opcode should trap
|
||||||
|
- Program can be validaded either before execution or when executing
|
||||||
|
|
||||||
|
# Traps
|
||||||
|
| Name | Parameters | Cause |
|
||||||
|
|:-------------:|:----------------:|:--------------------------:|
|
||||||
|
| LoadAccessEx | Accessed address | Loading invalid address |
|
||||||
|
| StoreAccessEx | Accessed address | Storing to invalid address |
|
||||||
|
| InvalidOpcode | Loaded opcode | Executing invalid opcode |
|
||||||
|
| Ecall | None | Ecall instruction |
|
||||||
|
|
Loading…
Reference in a new issue