Updated flots
This commit is contained in:
parent
387d4c7ce7
commit
7d17f48562
|
@ -62,7 +62,8 @@ tokendef![
|
|||
"nop", "add", "sub", "mul", "and", "or", "xor", "sl", "sr", "srs", "cmp", "cmpu",
|
||||
"dir", "neg", "not", "addi", "muli", "andi", "ori", "xori", "sli", "sri", "srsi",
|
||||
"cmpi", "cmpui", "cp", "swa", "li", "ld", "st", "bmc", "brc", "jmp", "jeq", "jne",
|
||||
"jlt", "jgt", "jltu", "jgtu", "ecall", "addf", "mulf", "dirf", "addfi", "mulfi",
|
||||
"jlt", "jgt", "jltu", "jgtu", "ecall", "addf", "subf", "mulf", "dirf", "fma", "negf",
|
||||
"itf", "fti", "addfi", "mulfi",
|
||||
];
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
|
@ -161,7 +162,7 @@ pub fn assembly(code: &str, buf: &mut Vec<u8>) -> Result<(), Error> {
|
|||
]);
|
||||
Ok(())
|
||||
}
|
||||
NEG..=NOT | CP..=SWA => {
|
||||
NEG..=NOT | CP..=SWA | NEGF..=FTI => {
|
||||
expect_matches!(
|
||||
self,
|
||||
Token::Register(r0),
|
||||
|
|
|
@ -10,13 +10,15 @@
|
|||
static_assert(CHAR_BIT == 8, "Cursed architectures are not supported");
|
||||
|
||||
enum hbbc_Opcode: uint8_t {
|
||||
hbbc_Op_NOP, hbbc_Op_ADD, 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_MULF,
|
||||
hbbc_Op_DIRF, hbbc_Op_ADDFI, hbbc_Op_MULFI,
|
||||
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_FMA , hbbc_Op_NEGF , hbbc_Op_ITF , hbbc_Op_FTI ,
|
||||
hbbc_Op_ADDFI , hbbc_Op_MULFI ,
|
||||
} typedef hbbc_Opcode;
|
||||
|
||||
static_assert(sizeof(hbbc_Opcode) == 1);
|
||||
|
|
|
@ -32,7 +32,7 @@ constmod!(pub opcode(u8) {
|
|||
CMP = 10, "BBB; #0 ← #1 <=> #2";
|
||||
CMPU = 11, "BBB; #0 ← #1 <=> #2 (unsigned)";
|
||||
DIR = 12, "BBBB; #0 ← #2 / #3, #1 ← #2 % #3";
|
||||
NEG = 13, "BB; #0 ← ~#1";
|
||||
NEG = 13, "BB; #0 ← -#1";
|
||||
NOT = 14, "BB; #0 ← !#1";
|
||||
|
||||
ADDI = 15, "BBD; #0 ← #1 + imm #2";
|
||||
|
@ -63,12 +63,17 @@ constmod!(pub opcode(u8) {
|
|||
JGTU = 38, "BBD; if #0 > #1 → jump imm #2 (unsigned)";
|
||||
ECALL = 39, "N; Issue system call";
|
||||
|
||||
ADDF = 40, "BBB; #0 ← #1 +. #2";
|
||||
MULF = 41, "BBB; #0 ← #1 +. #2";
|
||||
DIRF = 42, "BBBB; #0 ← #2 / #3, #1 ← #2 % #3";
|
||||
ADDF = 40, "BBB; #0 ← #1 +. #2";
|
||||
SUBF = 41, "BBB; #0 ← #1 -. #2";
|
||||
MULF = 42, "BBB; #0 ← #1 +. #2";
|
||||
DIRF = 43, "BBBB; #0 ← #2 / #3, #1 ← #2 % #3";
|
||||
FMA = 44, "BBBB; #0 ← (#1 * #2) + #3";
|
||||
NEGF = 45, "BB; #0 ← -#1";
|
||||
ITF = 46, "BB; #0 ← #1 as float";
|
||||
FTI = 47, "BB; #0 ← #1 as int";
|
||||
|
||||
ADDFI = 43, "BBD; #0 ← #1 +. imm #2";
|
||||
MULFI = 44, "BBD; #0 ← #1 *. imm #2";
|
||||
ADDFI = 48, "BBD; #0 ← #1 +. imm #2";
|
||||
MULFI = 49, "BBD; #0 ← #1 *. imm #2";
|
||||
});
|
||||
|
||||
#[repr(packed)]
|
||||
|
|
|
@ -15,7 +15,7 @@ pub enum ErrorKind {
|
|||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub struct Error {
|
||||
/// Kind
|
||||
pub kind: ErrorKind,
|
||||
pub kind: ErrorKind,
|
||||
/// Location in bytecode
|
||||
pub index: usize,
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ pub fn validate(mut program: &[u8]) -> Result<(), Error> {
|
|||
if usize::from(*reg) * 8 + usize::from(*count) > 2048 =>
|
||||
{
|
||||
return Err(Error {
|
||||
kind: ErrorKind::RegisterArrayOverflow,
|
||||
kind: ErrorKind::RegisterArrayOverflow,
|
||||
index: (program.as_ptr() as usize) - (start.as_ptr() as usize),
|
||||
})
|
||||
}
|
||||
|
@ -42,20 +42,20 @@ pub fn validate(mut program: &[u8]) -> Result<(), Error> {
|
|||
if src.checked_add(*count).is_none() || dst.checked_add(*count).is_none() =>
|
||||
{
|
||||
return Err(Error {
|
||||
kind: ErrorKind::RegisterArrayOverflow,
|
||||
kind: ErrorKind::RegisterArrayOverflow,
|
||||
index: (program.as_ptr() as usize) - (start.as_ptr() as usize),
|
||||
})
|
||||
}
|
||||
[NOP | ECALL, rest @ ..]
|
||||
| [DIR | DIRF, _, _, _, _, rest @ ..]
|
||||
| [ADD..=CMPU | BRC | ADDF..=MULF, _, _, _, rest @ ..]
|
||||
| [NEG..=NOT | CP..=SWA, _, _, rest @ ..]
|
||||
| [NEG..=NOT | CP..=SWA | NEGF..=FTI, _, _, rest @ ..]
|
||||
| [LI | JMP, _, _, _, _, _, _, _, _, _, rest @ ..]
|
||||
| [ADDI..=CMPUI | BMC | JEQ..=JGTU | ADDFI..=MULFI, _, _, _, _, _, _, _, _, _, _, rest @ ..]
|
||||
| [LD..=ST, _, _, _, _, _, _, _, _, _, _, _, _, rest @ ..] => rest,
|
||||
_ => {
|
||||
return Err(Error {
|
||||
kind: ErrorKind::InvalidInstruction,
|
||||
kind: ErrorKind::InvalidInstruction,
|
||||
index: (program.as_ptr() as usize) - (start.as_ptr() as usize),
|
||||
})
|
||||
}
|
||||
|
|
|
@ -50,8 +50,7 @@ macro_rules! binary_op {
|
|||
$handler(
|
||||
Value::$ty(&$self.read_reg(a0)),
|
||||
Value::$ty(&$self.read_reg(a1)),
|
||||
)
|
||||
.into(),
|
||||
),
|
||||
);
|
||||
}};
|
||||
}
|
||||
|
@ -62,7 +61,7 @@ macro_rules! binary_op_imm {
|
|||
let ParamBBD(tg, a0, imm) = param!($self, ParamBBD);
|
||||
$self.write_reg(
|
||||
tg,
|
||||
$handler(Value::$ty(&$self.read_reg(a0)), Value::$ty(&imm.into())).into(),
|
||||
$handler(Value::$ty(&$self.read_reg(a0)), Value::$ty(&imm.into())),
|
||||
);
|
||||
}};
|
||||
}
|
||||
|
@ -148,21 +147,19 @@ impl<'a, T: HandleTrap> Vm<'a, T> {
|
|||
let ParamBBB(tg, a0, a1) = param!(self, ParamBBB);
|
||||
self.write_reg(
|
||||
tg,
|
||||
(self.read_reg(a0).as_i64().cmp(&self.read_reg(a1).as_i64()) as i64)
|
||||
.into(),
|
||||
self.read_reg(a0).as_i64().cmp(&self.read_reg(a1).as_i64()) as i64,
|
||||
);
|
||||
}
|
||||
CMPU => {
|
||||
let ParamBBB(tg, a0, a1) = param!(self, ParamBBB);
|
||||
self.write_reg(
|
||||
tg,
|
||||
(self.read_reg(a0).as_u64().cmp(&self.read_reg(a1).as_u64()) as i64)
|
||||
.into(),
|
||||
self.read_reg(a0).as_u64().cmp(&self.read_reg(a1).as_u64()) as i64,
|
||||
);
|
||||
}
|
||||
NOT => {
|
||||
let param = param!(self, ParamBB);
|
||||
self.write_reg(param.0, (!self.read_reg(param.1).as_u64()).into());
|
||||
self.write_reg(param.0, !self.read_reg(param.1).as_u64());
|
||||
}
|
||||
NEG => {
|
||||
let param = param!(self, ParamBB);
|
||||
|
@ -171,16 +168,15 @@ impl<'a, T: HandleTrap> Vm<'a, T> {
|
|||
match self.read_reg(param.1).as_u64() {
|
||||
0 => 1_u64,
|
||||
_ => 0,
|
||||
}
|
||||
.into(),
|
||||
},
|
||||
);
|
||||
}
|
||||
DIR => {
|
||||
let ParamBBBB(dt, rt, a0, a1) = param!(self, ParamBBBB);
|
||||
let a0 = self.read_reg(a0).as_u64();
|
||||
let a1 = self.read_reg(a1).as_u64();
|
||||
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(dt, a0.checked_div(a1).unwrap_or(u64::MAX));
|
||||
self.write_reg(rt, a0.checked_rem(a1).unwrap_or(u64::MAX));
|
||||
}
|
||||
ADDI => binary_op_imm!(self, as_u64, ops::Add::add),
|
||||
MULI => binary_op_imm!(self, as_u64, ops::Mul::mul),
|
||||
|
@ -194,13 +190,12 @@ impl<'a, T: HandleTrap> Vm<'a, T> {
|
|||
let ParamBBD(tg, a0, imm) = param!(self, ParamBBD);
|
||||
self.write_reg(
|
||||
tg,
|
||||
(self.read_reg(a0).as_i64().cmp(&Value::from(imm).as_i64()) as i64)
|
||||
.into(),
|
||||
self.read_reg(a0).as_i64().cmp(&Value::from(imm).as_i64()) as i64,
|
||||
);
|
||||
}
|
||||
CMPUI => {
|
||||
let ParamBBD(tg, a0, imm) = param!(self, ParamBBD);
|
||||
self.write_reg(tg, (self.read_reg(a0).as_u64().cmp(&imm) as i64).into());
|
||||
self.write_reg(tg, self.read_reg(a0).as_u64().cmp(&imm) as i64);
|
||||
}
|
||||
CP => {
|
||||
let param = param!(self, ParamBB);
|
||||
|
@ -217,7 +212,7 @@ impl<'a, T: HandleTrap> Vm<'a, T> {
|
|||
}
|
||||
LI => {
|
||||
let param = param!(self, ParamBD);
|
||||
self.write_reg(param.0, param.1.into());
|
||||
self.write_reg(param.0, param.1);
|
||||
}
|
||||
LD => {
|
||||
let ParamBBDH(dst, base, off, count) = param!(self, ParamBBDH);
|
||||
|
@ -280,13 +275,34 @@ impl<'a, T: HandleTrap> Vm<'a, T> {
|
|||
.ecall(&mut self.registers, &mut self.pc, &mut self.memory);
|
||||
}
|
||||
ADDF => binary_op!(self, as_f64, ops::Add::add),
|
||||
SUBF => binary_op!(self, as_f64, ops::Sub::sub),
|
||||
MULF => binary_op!(self, as_f64, ops::Mul::mul),
|
||||
DIRF => {
|
||||
let ParamBBBB(dt, rt, a0, a1) = param!(self, ParamBBBB);
|
||||
let a0 = self.read_reg(a0).as_f64();
|
||||
let a1 = self.read_reg(a1).as_f64();
|
||||
self.write_reg(dt, (a0 / a1).into());
|
||||
self.write_reg(rt, (a0 % a1).into());
|
||||
self.write_reg(dt, a0 / a1);
|
||||
self.write_reg(rt, a0 % a1);
|
||||
}
|
||||
FMA => {
|
||||
let ParamBBBB(dt, a0, a1, a2) = param!(self, ParamBBBB);
|
||||
self.write_reg(
|
||||
dt,
|
||||
self.read_reg(a0).as_f64() * self.read_reg(a1).as_f64()
|
||||
+ self.read_reg(a2).as_f64(),
|
||||
);
|
||||
}
|
||||
NEGF => {
|
||||
let ParamBB(dt, a0) = param!(self, ParamBB);
|
||||
self.write_reg(dt, -self.read_reg(a0).as_f64());
|
||||
}
|
||||
ITF => {
|
||||
let ParamBB(dt, a0) = param!(self, ParamBB);
|
||||
self.write_reg(dt, self.read_reg(a0).as_i64() as f64);
|
||||
}
|
||||
FTI => {
|
||||
let ParamBB(dt, a0) = param!(self, ParamBB);
|
||||
self.write_reg(dt, self.read_reg(a0).as_f64() as i64);
|
||||
}
|
||||
ADDFI => binary_op_imm!(self, as_f64, ops::Add::add),
|
||||
MULFI => binary_op_imm!(self, as_f64, ops::Mul::mul),
|
||||
|
@ -314,9 +330,9 @@ impl<'a, T: HandleTrap> Vm<'a, T> {
|
|||
/// Write a register.
|
||||
/// Writing to register 0 is no-op.
|
||||
#[inline]
|
||||
unsafe fn write_reg(&mut self, n: u8, value: Value) {
|
||||
unsafe fn write_reg(&mut self, n: u8, value: impl Into<Value>) {
|
||||
if n != 0 {
|
||||
*self.registers.get_unchecked_mut(n as usize) = value;
|
||||
*self.registers.get_unchecked_mut(n as usize) = value.into();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
hex_literal_case = "Upper"
|
||||
imports_granularity = "One"
|
||||
struct_field_align_threshold = 5
|
||||
enum_discrim_align_threshold = 5
|
36
spec.md
36
spec.md
|
@ -199,14 +199,38 @@
|
|||
| Opcode | Name | Action |
|
||||
|:------:|:----:|:--------------:|
|
||||
| 40 | ADDF | Addition |
|
||||
| 41 | MULF | Multiplication |
|
||||
| 41 | SUBF | Subtraction |
|
||||
| 42 | MULF | Multiplication |
|
||||
|
||||
### Division-remainder
|
||||
- Type BBBB
|
||||
|
||||
| Opcode | Name | Action |
|
||||
|:------:|:----:|:--------------------------------------:|
|
||||
| 42 | DIRF | Same flow applies as for integer `DIR` |
|
||||
| Opcode | Name | Action |
|
||||
|:------:|:----:|:-------------------------:|
|
||||
| 43 | DIRF | Same as for integer `DIR` |
|
||||
|
||||
### Fused Multiply-Add
|
||||
- Type BBBB
|
||||
|
||||
| Opcode | Name | Action |
|
||||
|:------:|:----:|:---------------------:|
|
||||
| 44 | FMA | `#0 ← (#1 * #2) + #3` |
|
||||
|
||||
### Negation
|
||||
- Type BB
|
||||
| Opcode | Name | Action |
|
||||
|:------:|:----:|:----------:|
|
||||
| 45 | NEGF | `#0 ← -#1` |
|
||||
|
||||
### Conversion
|
||||
- Type BB
|
||||
- Signed
|
||||
- `#0 ← #1 as _`
|
||||
|
||||
| Opcode | Name | Action |
|
||||
|:------:|:----:|:------------:|
|
||||
| 46 | ITF | Int to Float |
|
||||
| 47 | FTI | Float to Int |
|
||||
|
||||
## Floating point immediate operations
|
||||
- Type BBD
|
||||
|
@ -214,8 +238,8 @@
|
|||
|
||||
| Opcode | Name | Action |
|
||||
|:------:|:-----:|:--------------:|
|
||||
| 43 | ADDFI | Addition |
|
||||
| 44 | MULFI | Multiplication |
|
||||
| 48 | ADDFI | Addition |
|
||||
| 49 | MULFI | Multiplication |
|
||||
|
||||
# Registers
|
||||
- There is 255 registers + one zero register (with index 0)
|
||||
|
|
Loading…
Reference in a new issue