forked from koniifer/ableos
Updated flots
This commit is contained in:
parent
3919aa8100
commit
2d34ed61d0
|
@ -62,7 +62,8 @@ tokendef![
|
||||||
"nop", "add", "sub", "mul", "and", "or", "xor", "sl", "sr", "srs", "cmp", "cmpu",
|
"nop", "add", "sub", "mul", "and", "or", "xor", "sl", "sr", "srs", "cmp", "cmpu",
|
||||||
"dir", "neg", "not", "addi", "muli", "andi", "ori", "xori", "sli", "sri", "srsi",
|
"dir", "neg", "not", "addi", "muli", "andi", "ori", "xori", "sli", "sri", "srsi",
|
||||||
"cmpi", "cmpui", "cp", "swa", "li", "ld", "st", "bmc", "brc", "jmp", "jeq", "jne",
|
"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)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||||
|
@ -161,7 +162,7 @@ pub fn assembly(code: &str, buf: &mut Vec<u8>) -> Result<(), Error> {
|
||||||
]);
|
]);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
NEG..=NOT | CP..=SWA => {
|
NEG..=NOT | CP..=SWA | NEGF..=FTI => {
|
||||||
expect_matches!(
|
expect_matches!(
|
||||||
self,
|
self,
|
||||||
Token::Register(r0),
|
Token::Register(r0),
|
||||||
|
|
|
@ -10,13 +10,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_MUL, hbbc_Op_AND, hbbc_Op_OR, hbbc_Op_XOR, hbbc_Op_SL,
|
hbbc_Op_NOP , hbbc_Op_ADD , hbbc_Op_SUB , hbbc_Op_MUL , hbbc_Op_AND , hbbc_Op_OR ,
|
||||||
hbbc_Op_SR, hbbc_Op_SRS, hbbc_Op_CMP, hbbc_Op_CMPU, hbbc_Op_DIR, hbbc_Op_NEG, hbbc_Op_NOT,
|
hbbc_Op_XOR , hbbc_Op_SL , hbbc_Op_SR , hbbc_Op_SRS , hbbc_Op_CMP , hbbc_Op_CMPU ,
|
||||||
hbbc_Op_ADDI, hbbc_Op_MULI, hbbc_Op_ANDI, hbbc_Op_ORI, hbbc_Op_XORI, hbbc_Op_SLI, hbbc_Op_SRI,
|
hbbc_Op_DIR , hbbc_Op_NEG , hbbc_Op_NOT , hbbc_Op_ADDI , hbbc_Op_MULI , hbbc_Op_ANDI ,
|
||||||
hbbc_Op_SRSI, hbbc_Op_CMPI, hbbc_Op_CMPUI, hbbc_Op_CP, hbbc_Op_SWA, hbbc_Op_LI, hbbc_Op_LD,
|
hbbc_Op_ORI , hbbc_Op_XORI , hbbc_Op_SLI , hbbc_Op_SRI , hbbc_Op_SRSI , hbbc_Op_CMPI ,
|
||||||
hbbc_Op_ST, hbbc_Op_BMC, hbbc_Op_BRC, hbbc_Op_JMP, hbbc_Op_JEQ, hbbc_Op_JNE, hbbc_Op_JLT,
|
hbbc_Op_CMPUI , hbbc_Op_CP , hbbc_Op_SWA , hbbc_Op_LI , hbbc_Op_LD , hbbc_Op_ST ,
|
||||||
hbbc_Op_JGT, hbbc_Op_JLTU, hbbc_Op_JGTU, hbbc_Op_ECALL, hbbc_Op_ADDF, hbbc_Op_MULF,
|
hbbc_Op_BMC , hbbc_Op_BRC , hbbc_Op_JMP , hbbc_Op_JEQ , hbbc_Op_JNE , hbbc_Op_JLT ,
|
||||||
hbbc_Op_DIRF, hbbc_Op_ADDFI, hbbc_Op_MULFI,
|
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;
|
} typedef hbbc_Opcode;
|
||||||
|
|
||||||
static_assert(sizeof(hbbc_Opcode) == 1);
|
static_assert(sizeof(hbbc_Opcode) == 1);
|
||||||
|
|
|
@ -32,7 +32,7 @@ constmod!(pub opcode(u8) {
|
||||||
CMP = 10, "BBB; #0 ← #1 <=> #2";
|
CMP = 10, "BBB; #0 ← #1 <=> #2";
|
||||||
CMPU = 11, "BBB; #0 ← #1 <=> #2 (unsigned)";
|
CMPU = 11, "BBB; #0 ← #1 <=> #2 (unsigned)";
|
||||||
DIR = 12, "BBBB; #0 ← #2 / #3, #1 ← #2 % #3";
|
DIR = 12, "BBBB; #0 ← #2 / #3, #1 ← #2 % #3";
|
||||||
NEG = 13, "BB; #0 ← ~#1";
|
NEG = 13, "BB; #0 ← -#1";
|
||||||
NOT = 14, "BB; #0 ← !#1";
|
NOT = 14, "BB; #0 ← !#1";
|
||||||
|
|
||||||
ADDI = 15, "BBD; #0 ← #1 + imm #2";
|
ADDI = 15, "BBD; #0 ← #1 + imm #2";
|
||||||
|
@ -64,11 +64,16 @@ constmod!(pub opcode(u8) {
|
||||||
ECALL = 39, "N; Issue system call";
|
ECALL = 39, "N; Issue system call";
|
||||||
|
|
||||||
ADDF = 40, "BBB; #0 ← #1 +. #2";
|
ADDF = 40, "BBB; #0 ← #1 +. #2";
|
||||||
MULF = 41, "BBB; #0 ← #1 +. #2";
|
SUBF = 41, "BBB; #0 ← #1 -. #2";
|
||||||
DIRF = 42, "BBBB; #0 ← #2 / #3, #1 ← #2 % #3";
|
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";
|
ADDFI = 48, "BBD; #0 ← #1 +. imm #2";
|
||||||
MULFI = 44, "BBD; #0 ← #1 *. imm #2";
|
MULFI = 49, "BBD; #0 ← #1 *. imm #2";
|
||||||
});
|
});
|
||||||
|
|
||||||
#[repr(packed)]
|
#[repr(packed)]
|
||||||
|
|
|
@ -49,7 +49,7 @@ pub fn validate(mut program: &[u8]) -> Result<(), Error> {
|
||||||
[NOP | ECALL, rest @ ..]
|
[NOP | ECALL, rest @ ..]
|
||||||
| [DIR | DIRF, _, _, _, _, rest @ ..]
|
| [DIR | DIRF, _, _, _, _, rest @ ..]
|
||||||
| [ADD..=CMPU | BRC | ADDF..=MULF, _, _, _, rest @ ..]
|
| [ADD..=CMPU | BRC | ADDF..=MULF, _, _, _, rest @ ..]
|
||||||
| [NEG..=NOT | CP..=SWA, _, _, rest @ ..]
|
| [NEG..=NOT | CP..=SWA | NEGF..=FTI, _, _, rest @ ..]
|
||||||
| [LI | JMP, _, _, _, _, _, _, _, _, _, rest @ ..]
|
| [LI | JMP, _, _, _, _, _, _, _, _, _, rest @ ..]
|
||||||
| [ADDI..=CMPUI | BMC | JEQ..=JGTU | ADDFI..=MULFI, _, _, _, _, _, _, _, _, _, _, rest @ ..]
|
| [ADDI..=CMPUI | BMC | JEQ..=JGTU | ADDFI..=MULFI, _, _, _, _, _, _, _, _, _, _, rest @ ..]
|
||||||
| [LD..=ST, _, _, _, _, _, _, _, _, _, _, _, _, rest @ ..] => rest,
|
| [LD..=ST, _, _, _, _, _, _, _, _, _, _, _, _, rest @ ..] => rest,
|
||||||
|
|
|
@ -50,8 +50,7 @@ macro_rules! binary_op {
|
||||||
$handler(
|
$handler(
|
||||||
Value::$ty(&$self.read_reg(a0)),
|
Value::$ty(&$self.read_reg(a0)),
|
||||||
Value::$ty(&$self.read_reg(a1)),
|
Value::$ty(&$self.read_reg(a1)),
|
||||||
)
|
),
|
||||||
.into(),
|
|
||||||
);
|
);
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
@ -62,7 +61,7 @@ macro_rules! binary_op_imm {
|
||||||
let ParamBBD(tg, a0, imm) = param!($self, ParamBBD);
|
let ParamBBD(tg, a0, imm) = param!($self, ParamBBD);
|
||||||
$self.write_reg(
|
$self.write_reg(
|
||||||
tg,
|
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);
|
let ParamBBB(tg, a0, a1) = param!(self, ParamBBB);
|
||||||
self.write_reg(
|
self.write_reg(
|
||||||
tg,
|
tg,
|
||||||
(self.read_reg(a0).as_i64().cmp(&self.read_reg(a1).as_i64()) as i64)
|
self.read_reg(a0).as_i64().cmp(&self.read_reg(a1).as_i64()) as i64,
|
||||||
.into(),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
CMPU => {
|
CMPU => {
|
||||||
let ParamBBB(tg, a0, a1) = param!(self, ParamBBB);
|
let ParamBBB(tg, a0, a1) = param!(self, ParamBBB);
|
||||||
self.write_reg(
|
self.write_reg(
|
||||||
tg,
|
tg,
|
||||||
(self.read_reg(a0).as_u64().cmp(&self.read_reg(a1).as_u64()) as i64)
|
self.read_reg(a0).as_u64().cmp(&self.read_reg(a1).as_u64()) as i64,
|
||||||
.into(),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
NOT => {
|
NOT => {
|
||||||
let param = param!(self, ParamBB);
|
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 => {
|
NEG => {
|
||||||
let param = param!(self, ParamBB);
|
let param = param!(self, ParamBB);
|
||||||
|
@ -171,16 +168,15 @@ impl<'a, T: HandleTrap> Vm<'a, T> {
|
||||||
match self.read_reg(param.1).as_u64() {
|
match self.read_reg(param.1).as_u64() {
|
||||||
0 => 1_u64,
|
0 => 1_u64,
|
||||||
_ => 0,
|
_ => 0,
|
||||||
}
|
},
|
||||||
.into(),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
DIR => {
|
DIR => {
|
||||||
let ParamBBBB(dt, rt, a0, a1) = param!(self, ParamBBBB);
|
let ParamBBBB(dt, rt, a0, a1) = param!(self, ParamBBBB);
|
||||||
let a0 = self.read_reg(a0).as_u64();
|
let a0 = self.read_reg(a0).as_u64();
|
||||||
let a1 = self.read_reg(a1).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(dt, a0.checked_div(a1).unwrap_or(u64::MAX));
|
||||||
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));
|
||||||
}
|
}
|
||||||
ADDI => binary_op_imm!(self, as_u64, ops::Add::add),
|
ADDI => binary_op_imm!(self, as_u64, ops::Add::add),
|
||||||
MULI => binary_op_imm!(self, as_u64, ops::Mul::mul),
|
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);
|
let ParamBBD(tg, a0, imm) = param!(self, ParamBBD);
|
||||||
self.write_reg(
|
self.write_reg(
|
||||||
tg,
|
tg,
|
||||||
(self.read_reg(a0).as_i64().cmp(&Value::from(imm).as_i64()) as i64)
|
self.read_reg(a0).as_i64().cmp(&Value::from(imm).as_i64()) as i64,
|
||||||
.into(),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
CMPUI => {
|
CMPUI => {
|
||||||
let ParamBBD(tg, a0, imm) = param!(self, ParamBBD);
|
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 => {
|
CP => {
|
||||||
let param = param!(self, ParamBB);
|
let param = param!(self, ParamBB);
|
||||||
|
@ -217,7 +212,7 @@ impl<'a, T: HandleTrap> Vm<'a, T> {
|
||||||
}
|
}
|
||||||
LI => {
|
LI => {
|
||||||
let param = param!(self, ParamBD);
|
let param = param!(self, ParamBD);
|
||||||
self.write_reg(param.0, param.1.into());
|
self.write_reg(param.0, param.1);
|
||||||
}
|
}
|
||||||
LD => {
|
LD => {
|
||||||
let ParamBBDH(dst, base, off, count) = param!(self, ParamBBDH);
|
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);
|
.ecall(&mut self.registers, &mut self.pc, &mut self.memory);
|
||||||
}
|
}
|
||||||
ADDF => binary_op!(self, as_f64, ops::Add::add),
|
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),
|
MULF => binary_op!(self, as_f64, ops::Mul::mul),
|
||||||
DIRF => {
|
DIRF => {
|
||||||
let ParamBBBB(dt, rt, a0, a1) = param!(self, ParamBBBB);
|
let ParamBBBB(dt, rt, a0, a1) = param!(self, ParamBBBB);
|
||||||
let a0 = self.read_reg(a0).as_f64();
|
let a0 = self.read_reg(a0).as_f64();
|
||||||
let a1 = self.read_reg(a1).as_f64();
|
let a1 = self.read_reg(a1).as_f64();
|
||||||
self.write_reg(dt, (a0 / a1).into());
|
self.write_reg(dt, a0 / a1);
|
||||||
self.write_reg(rt, (a0 % a1).into());
|
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),
|
ADDFI => binary_op_imm!(self, as_f64, ops::Add::add),
|
||||||
MULFI => binary_op_imm!(self, as_f64, ops::Mul::mul),
|
MULFI => binary_op_imm!(self, as_f64, ops::Mul::mul),
|
||||||
|
@ -314,9 +330,9 @@ impl<'a, T: HandleTrap> Vm<'a, T> {
|
||||||
/// Write a register.
|
/// Write a register.
|
||||||
/// Writing to register 0 is no-op.
|
/// Writing to register 0 is no-op.
|
||||||
#[inline]
|
#[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 {
|
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"
|
hex_literal_case = "Upper"
|
||||||
imports_granularity = "One"
|
imports_granularity = "One"
|
||||||
struct_field_align_threshold = 5
|
struct_field_align_threshold = 5
|
||||||
|
enum_discrim_align_threshold = 5
|
34
spec.md
34
spec.md
|
@ -199,14 +199,38 @@
|
||||||
| Opcode | Name | Action |
|
| Opcode | Name | Action |
|
||||||
|:------:|:----:|:--------------:|
|
|:------:|:----:|:--------------:|
|
||||||
| 40 | ADDF | Addition |
|
| 40 | ADDF | Addition |
|
||||||
| 41 | MULF | Multiplication |
|
| 41 | SUBF | Subtraction |
|
||||||
|
| 42 | MULF | Multiplication |
|
||||||
|
|
||||||
### Division-remainder
|
### Division-remainder
|
||||||
- Type BBBB
|
- Type BBBB
|
||||||
|
|
||||||
| Opcode | Name | Action |
|
| Opcode | Name | Action |
|
||||||
|:------:|:----:|:--------------------------------------:|
|
|:------:|:----:|:-------------------------:|
|
||||||
| 42 | DIRF | Same flow applies as for integer `DIR` |
|
| 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
|
## Floating point immediate operations
|
||||||
- Type BBD
|
- Type BBD
|
||||||
|
@ -214,8 +238,8 @@
|
||||||
|
|
||||||
| Opcode | Name | Action |
|
| Opcode | Name | Action |
|
||||||
|:------:|:-----:|:--------------:|
|
|:------:|:-----:|:--------------:|
|
||||||
| 43 | ADDFI | Addition |
|
| 48 | ADDFI | Addition |
|
||||||
| 44 | MULFI | Multiplication |
|
| 49 | MULFI | Multiplication |
|
||||||
|
|
||||||
# Registers
|
# Registers
|
||||||
- There is 255 registers + one zero register (with index 0)
|
- There is 255 registers + one zero register (with index 0)
|
||||||
|
|
Loading…
Reference in a new issue