diff --git a/.gitignore b/.gitignore index ea8c4bf..27791bc 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,4 @@ /target +/hbbytecode/src/opcode.rs +/hbbytecode/src/ops.rs +/hblang/src/instrs.rs diff --git a/Cargo.lock b/Cargo.lock index 1c70201..742f4aa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -196,10 +196,6 @@ dependencies = [ [[package]] name = "hbbytecode" version = "0.1.0" -dependencies = [ - "paste", - "with_builtin_macros", -] [[package]] name = "hblang" diff --git a/hbbytecode/Cargo.toml b/hbbytecode/Cargo.toml index 4c19884..1b50f51 100644 --- a/hbbytecode/Cargo.toml +++ b/hbbytecode/Cargo.toml @@ -2,7 +2,3 @@ name = "hbbytecode" version = "0.1.0" edition = "2018" - -[dependencies] -paste = "1.0.14" -with_builtin_macros = "0.0.3" diff --git a/hbbytecode/build.rs b/hbbytecode/build.rs new file mode 100644 index 0000000..9ac45d2 --- /dev/null +++ b/hbbytecode/build.rs @@ -0,0 +1,58 @@ +#![feature(iter_next_chunk)] + +fn main() -> Result<(), Box> { + println!("cargo:rerun-if-changed=build.rs"); + println!("cargo:rerun-if-changed=instructions.in"); + + let mut generated = String::new(); + gen_op_structs(&mut generated)?; + std::fs::write("src/ops.rs", generated)?; + + let mut generated = String::new(); + gen_op_codes(&mut generated)?; + std::fs::write("src/opcode.rs", generated)?; + + Ok(()) +} + +fn gen_op_structs(generated: &mut String) -> std::fmt::Result { + use std::fmt::Write; + let mut seen = std::collections::HashSet::new(); + writeln!(generated, "use crate::*;")?; + for [.., args, _] in instructions() { + if !seen.insert(args) { + continue; + } + + writeln!(generated, "#[derive(Clone, Copy, Debug)]")?; + writeln!(generated, "#[repr(packed)]")?; + write!(generated, "pub struct Ops{args}(")?; + let mut first = true; + for ch in args.chars().filter(|&ch| ch != 'N') { + if !std::mem::take(&mut first) { + write!(generated, ",")?; + } + write!(generated, "pub Op{ch}")?; + } + writeln!(generated, ");")?; + writeln!(generated, "unsafe impl BytecodeItem for Ops{args} {{}}")?; + } + + Ok(()) +} + +fn gen_op_codes(generated: &mut String) -> std::fmt::Result { + use std::fmt::Write; + for [op, name, _, comment] in instructions() { + writeln!(generated, "#[doc = {comment}]")?; + writeln!(generated, "pub const {name}: u8 = {op};")?; + } + Ok(()) +} + +fn instructions() -> impl Iterator { + include_str!("../hbbytecode/instructions.in") + .lines() + .map(|line| line.strip_suffix(';').unwrap()) + .map(|line| line.splitn(4, ',').map(str::trim).next_chunk().unwrap()) +} diff --git a/hbbytecode/src/generated.rs b/hbbytecode/src/generated.rs new file mode 100644 index 0000000..30b24dd --- /dev/null +++ b/hbbytecode/src/generated.rs @@ -0,0 +1,466 @@ +pub struct OpsN( +pub OpN +pub struct OpsN( +pub OpN +pub struct OpsN( +pub OpN +pub struct OpsRRR( +pub OpR +,pub OpR +,pub OpR +pub struct OpsRRR( +pub OpR +,pub OpR +,pub OpR +pub struct OpsRRR( +pub OpR +,pub OpR +,pub OpR +pub struct OpsRRR( +pub OpR +,pub OpR +,pub OpR +pub struct OpsRRR( +pub OpR +,pub OpR +,pub OpR +pub struct OpsRRR( +pub OpR +,pub OpR +,pub OpR +pub struct OpsRRR( +pub OpR +,pub OpR +,pub OpR +pub struct OpsRRR( +pub OpR +,pub OpR +,pub OpR +pub struct OpsRRR( +pub OpR +,pub OpR +,pub OpR +pub struct OpsRRR( +pub OpR +,pub OpR +,pub OpR +pub struct OpsRRR( +pub OpR +,pub OpR +,pub OpR +pub struct OpsRRR( +pub OpR +,pub OpR +,pub OpR +pub struct OpsRRR( +pub OpR +,pub OpR +,pub OpR +pub struct OpsRRR( +pub OpR +,pub OpR +,pub OpR +pub struct OpsRRR( +pub OpR +,pub OpR +,pub OpR +pub struct OpsRRR( +pub OpR +,pub OpR +,pub OpR +pub struct OpsRRR( +pub OpR +,pub OpR +,pub OpR +pub struct OpsRRR( +pub OpR +,pub OpR +,pub OpR +pub struct OpsRRR( +pub OpR +,pub OpR +,pub OpR +pub struct OpsRRR( +pub OpR +,pub OpR +,pub OpR +pub struct OpsRRR( +pub OpR +,pub OpR +,pub OpR +pub struct OpsRRR( +pub OpR +,pub OpR +,pub OpR +pub struct OpsRRR( +pub OpR +,pub OpR +,pub OpR +pub struct OpsRRR( +pub OpR +,pub OpR +,pub OpR +pub struct OpsRRR( +pub OpR +,pub OpR +,pub OpR +pub struct OpsRRR( +pub OpR +,pub OpR +,pub OpR +pub struct OpsRRR( +pub OpR +,pub OpR +,pub OpR +pub struct OpsRRR( +pub OpR +,pub OpR +,pub OpR +pub struct OpsRRR( +pub OpR +,pub OpR +,pub OpR +pub struct OpsRRRR( +pub OpR +,pub OpR +,pub OpR +,pub OpR +pub struct OpsRRRR( +pub OpR +,pub OpR +,pub OpR +,pub OpR +pub struct OpsRRRR( +pub OpR +,pub OpR +,pub OpR +,pub OpR +pub struct OpsRRRR( +pub OpR +,pub OpR +,pub OpR +,pub OpR +pub struct OpsRRRR( +pub OpR +,pub OpR +,pub OpR +,pub OpR +pub struct OpsRRRR( +pub OpR +,pub OpR +,pub OpR +,pub OpR +pub struct OpsRRRR( +pub OpR +,pub OpR +,pub OpR +,pub OpR +pub struct OpsRRRR( +pub OpR +,pub OpR +,pub OpR +,pub OpR +pub struct OpsRR( +pub OpR +,pub OpR +pub struct OpsRR( +pub OpR +,pub OpR +pub struct OpsRR( +pub OpR +,pub OpR +pub struct OpsRR( +pub OpR +,pub OpR +pub struct OpsRR( +pub OpR +,pub OpR +pub struct OpsRRB( +pub OpR +,pub OpR +,pub OpB +pub struct OpsRRH( +pub OpR +,pub OpR +,pub OpH +pub struct OpsRRW( +pub OpR +,pub OpR +,pub OpW +pub struct OpsRRD( +pub OpR +,pub OpR +,pub OpD +pub struct OpsRRB( +pub OpR +,pub OpR +,pub OpB +pub struct OpsRRH( +pub OpR +,pub OpR +,pub OpH +pub struct OpsRRW( +pub OpR +,pub OpR +,pub OpW +pub struct OpsRRD( +pub OpR +,pub OpR +,pub OpD +pub struct OpsRRD( +pub OpR +,pub OpR +,pub OpD +pub struct OpsRRD( +pub OpR +,pub OpR +,pub OpD +pub struct OpsRRD( +pub OpR +,pub OpR +,pub OpD +pub struct OpsRRB( +pub OpR +,pub OpR +,pub OpB +pub struct OpsRRB( +pub OpR +,pub OpR +,pub OpB +pub struct OpsRRB( +pub OpR +,pub OpR +,pub OpB +pub struct OpsRRB( +pub OpR +,pub OpR +,pub OpB +pub struct OpsRRB( +pub OpR +,pub OpR +,pub OpB +pub struct OpsRRB( +pub OpR +,pub OpR +,pub OpB +pub struct OpsRRB( +pub OpR +,pub OpR +,pub OpB +pub struct OpsRRB( +pub OpR +,pub OpR +,pub OpB +pub struct OpsRRB( +pub OpR +,pub OpR +,pub OpB +pub struct OpsRRB( +pub OpR +,pub OpR +,pub OpB +pub struct OpsRRB( +pub OpR +,pub OpR +,pub OpB +pub struct OpsRRB( +pub OpR +,pub OpR +,pub OpB +pub struct OpsRRD( +pub OpR +,pub OpR +,pub OpD +pub struct OpsRRD( +pub OpR +,pub OpR +,pub OpD +pub struct OpsRR( +pub OpR +,pub OpR +pub struct OpsRR( +pub OpR +,pub OpR +pub struct OpsRB( +pub OpR +,pub OpB +pub struct OpsRH( +pub OpR +,pub OpH +pub struct OpsRW( +pub OpR +,pub OpW +pub struct OpsRD( +pub OpR +,pub OpD +pub struct OpsRRO( +pub OpR +,pub OpR +,pub OpO +pub struct OpsRRAH( +pub OpR +,pub OpR +,pub OpA +,pub OpH +pub struct OpsRRAH( +pub OpR +,pub OpR +,pub OpA +,pub OpH +pub struct OpsRROH( +pub OpR +,pub OpR +,pub OpO +,pub OpH +pub struct OpsRROH( +pub OpR +,pub OpR +,pub OpO +,pub OpH +pub struct OpsRRH( +pub OpR +,pub OpR +,pub OpH +pub struct OpsRRB( +pub OpR +,pub OpR +,pub OpB +pub struct OpsO( +pub OpO +pub struct OpsRRO( +pub OpR +,pub OpR +,pub OpO +pub struct OpsRRA( +pub OpR +,pub OpR +,pub OpA +pub struct OpsRRP( +pub OpR +,pub OpR +,pub OpP +pub struct OpsRRP( +pub OpR +,pub OpR +,pub OpP +pub struct OpsRRP( +pub OpR +,pub OpR +,pub OpP +pub struct OpsRRP( +pub OpR +,pub OpR +,pub OpP +pub struct OpsRRP( +pub OpR +,pub OpR +,pub OpP +pub struct OpsRRP( +pub OpR +,pub OpR +,pub OpP +pub struct OpsN( +pub OpN +pub struct OpsN( +pub OpN +pub struct OpsRRR( +pub OpR +,pub OpR +,pub OpR +pub struct OpsRRR( +pub OpR +,pub OpR +,pub OpR +pub struct OpsRRR( +pub OpR +,pub OpR +,pub OpR +pub struct OpsRRR( +pub OpR +,pub OpR +,pub OpR +pub struct OpsRRR( +pub OpR +,pub OpR +,pub OpR +pub struct OpsRRR( +pub OpR +,pub OpR +,pub OpR +pub struct OpsRRR( +pub OpR +,pub OpR +,pub OpR +pub struct OpsRRR( +pub OpR +,pub OpR +,pub OpR +pub struct OpsRRRR( +pub OpR +,pub OpR +,pub OpR +,pub OpR +pub struct OpsRRRR( +pub OpR +,pub OpR +,pub OpR +,pub OpR +pub struct OpsRR( +pub OpR +,pub OpR +pub struct OpsRR( +pub OpR +,pub OpR +pub struct OpsRRR( +pub OpR +,pub OpR +,pub OpR +pub struct OpsRRR( +pub OpR +,pub OpR +,pub OpR +pub struct OpsRRR( +pub OpR +,pub OpR +,pub OpR +pub struct OpsRRR( +pub OpR +,pub OpR +,pub OpR +pub struct OpsRR( +pub OpR +,pub OpR +pub struct OpsRR( +pub OpR +,pub OpR +pub struct OpsRRB( +pub OpR +,pub OpR +,pub OpB +pub struct OpsRRB( +pub OpR +,pub OpR +,pub OpB +pub struct OpsRR( +pub OpR +,pub OpR +pub struct OpsRRB( +pub OpR +,pub OpR +,pub OpB +pub struct OpsRRP( +pub OpR +,pub OpR +,pub OpP +pub struct OpsRRPH( +pub OpR +,pub OpR +,pub OpP +,pub OpH +pub struct OpsRRPH( +pub OpR +,pub OpR +,pub OpP +,pub OpH +pub struct OpsP( +pub OpP diff --git a/hbbytecode/src/lib.rs b/hbbytecode/src/lib.rs index fcd3103..1d260c1 100644 --- a/hbbytecode/src/lib.rs +++ b/hbbytecode/src/lib.rs @@ -1,7 +1,11 @@ #![no_std] +pub use crate::ops::*; use core::convert::TryFrom; +pub mod opcode; +mod ops; + type OpR = u8; type OpA = u64; @@ -16,152 +20,8 @@ type OpD = u64; /// # Safety /// Has to be valid to be decoded from bytecode. pub unsafe trait BytecodeItem {} -macro_rules! define_items { - ($($name:ident ($($nm:ident: $item:ident),* $(,)?)),* $(,)?) => { - $( - #[derive(Clone, Copy, Debug)] - #[repr(packed)] - pub struct $name($(pub $item),*); - unsafe impl BytecodeItem for $name {} - - impl Encodable for $name { - fn encode(self, _buffer: &mut impl Buffer) { - let Self($($nm),*) = self; - $( - for byte in $nm.to_le_bytes() { - unsafe { _buffer.write(byte) }; - } - )* - } - - fn encode_len(self) -> usize { - core::mem::size_of::() - } - } - )* - }; -} - -define_items! { - OpsRR (a: OpR, b: OpR ), - OpsRRR (a: OpR, b: OpR, c: OpR ), - OpsRRRR (a: OpR, b: OpR, c: OpR, d: OpR), - OpsRRB (a: OpR, b: OpR, c: OpB ), - OpsRRH (a: OpR, b: OpR, c: OpH ), - OpsRRW (a: OpR, b: OpR, c: OpW ), - OpsRRD (a: OpR, b: OpR, c: OpD ), - OpsRB (a: OpR, b: OpB ), - OpsRH (a: OpR, b: OpH ), - OpsRW (a: OpR, b: OpW ), - OpsRD (a: OpR, b: OpD ), - OpsRRA (a: OpR, b: OpR, c: OpA ), - OpsRRAH (a: OpR, b: OpR, c: OpA, d: OpH), - OpsRROH (a: OpR, b: OpR, c: OpO, d: OpH), - OpsRRPH (a: OpR, b: OpR, c: OpP, d: OpH), - OpsRRO (a: OpR, b: OpR, c: OpO ), - OpsRRP (a: OpR, b: OpR, c: OpP ), - OpsO (a: OpO, ), - OpsP (a: OpP, ), - OpsN ( ), -} - unsafe impl BytecodeItem for u8 {} -::with_builtin_macros::with_builtin! { - let $spec = include_from_root!("instructions.in") in { - /// Invoke macro with bytecode definition - /// - /// # Format - /// ```text - /// Opcode, Mnemonic, Type, Docstring; - /// ``` - /// - /// # Type - /// ```text - /// Types consist of letters meaning a single field - /// | Type | Size (B) | Meaning | - /// |:-----|:---------|:------------------------| - /// | N | 0 | Empty | - /// | R | 1 | Register | - /// | A | 8 | Absolute address | - /// | O | 4 | Relative address offset | - /// | P | 2 | Relative address offset | - /// | B | 1 | Immediate | - /// | H | 2 | Immediate | - /// | W | 4 | Immediate | - /// | D | 8 | Immediate | - /// ``` - #[macro_export] - macro_rules! invoke_with_def { - ($($macro:tt)*) => { - $($macro)*! { $spec } - }; - } - } -} - -pub trait Buffer { - fn reserve(&mut self, bytes: usize); - /// # Safety - /// Reserve needs to be called before this function, and only reserved amount can be written. - unsafe fn write(&mut self, byte: u8); -} - -pub trait Encodable { - fn encode(self, buffer: &mut impl Buffer); - fn encode_len(self) -> usize; -} - -macro_rules! gen_opcodes { - ($($opcode:expr, $mnemonic:ident, $ty:ident, $doc:literal;)*) => { - pub mod opcode { - $( - #[doc = $doc] - pub const $mnemonic: u8 = $opcode; - )* - - paste::paste! { - #[derive(Clone, Copy, Debug)] - #[repr(u8)] - pub enum Op { $( - [< $mnemonic:lower:camel >](super::[]), - )* } - - impl Op { - pub fn size(&self) -> usize { - (match self { - $(Self::[<$mnemonic:lower:camel>] { .. } => core::mem::size_of::]>(),)* - }) + 1 - } - } - - impl crate::Encodable for Op { - fn encode(self, buffer: &mut impl crate::Buffer) { - match self { - $( - Self::[< $mnemonic:lower:camel >](op) => { - unsafe { buffer.write($opcode) }; - op.encode(buffer); - } - )* - } - } - - fn encode_len(self) -> usize { - match self { - $( - Self::[< $mnemonic:lower:camel >](op) => { - 1 + crate::Encodable::encode_len(op) - } - )* - } - } - } - } - } - }; -} - /// Rounding mode #[derive(Clone, Copy, Debug, PartialEq, Eq)] #[repr(u8)] @@ -181,5 +41,3 @@ impl TryFrom for RoundingMode { .ok_or(()) } } - -invoke_with_def!(gen_opcodes); diff --git a/hblang/Cargo.toml b/hblang/Cargo.toml index d2d7742..ee487b4 100644 --- a/hblang/Cargo.toml +++ b/hblang/Cargo.toml @@ -8,6 +8,4 @@ name = "hbc" path = "src/main.rs" [dependencies] - -[dev-dependencies] hbvm = { path = "../hbvm", features = ["nightly"] } diff --git a/hblang/src/codegen.rs b/hblang/src/codegen.rs index 12d6855..cf2c8a8 100644 --- a/hblang/src/codegen.rs +++ b/hblang/src/codegen.rs @@ -471,6 +471,12 @@ impl<'a> std::fmt::Display for TypeDisplay<'a> { } } +struct Global { + id: Ident, + offset: u64, + ty: Type, +} + #[derive(Default)] pub struct Codegen<'a> { path: &'a str, @@ -486,6 +492,7 @@ pub struct Codegen<'a> { loops: Vec, records: Vec, pointers: Vec, + globals: Vec, main: Option, } @@ -495,28 +502,35 @@ impl<'a> Codegen<'a> { self.input = input; for expr in exprs { - match expr { - E::BinOp { - left: E::Ident { id, .. }, - op: T::Decl, - right: E::Closure { args, ret, .. }, - } => { + let E::BinOp { + left: &E::Ident { id, name, .. }, + op: T::Decl, + right, + } = expr + else { + self.report(expr.pos(), format_args!("expected declaration")); + }; + + match right { + E::Closure { args, ret, .. } => { let args = args.iter().map(|arg| self.ty(&arg.ty)).collect::>(); let ret = self.ty(ret); - self.declare_fn_label(*id, args, ret); + self.declare_fn_label(id, args, ret); } - E::BinOp { - left: E::Ident { id, name, .. }, - op: T::Decl, - right: E::Struct { .. }, - } => { + E::Struct { .. } => { self.records.push(Struct { - id: *id, - name: (*name).into(), + id, + name: (*name).into(), fields: Rc::from([]), }); } - _ => self.report(expr.pos(), "expected declaration"), + _ => { + self.globals.push(Global { + id, + offset: 0, + ty: bt::NEVER, + }); + } } } @@ -580,7 +594,7 @@ impl<'a> Codegen<'a> { self.ret(); self.sa.borrow_mut().clear(); } - _ => unreachable!(), + value => todo!(), } } } diff --git a/hblang/src/instrs.rs b/hblang/src/instrs.rs deleted file mode 100644 index 934258f..0000000 --- a/hblang/src/instrs.rs +++ /dev/null @@ -1,623 +0,0 @@ -pub const MAX_SIZE: usize = 13; -/// Cause an unreachable code trap -pub fn un() -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(N(0x00, )) } -} -/// Termiante execution -pub fn tx() -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(N(0x01, )) } -} -/// Do nothing -pub fn nop() -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(N(0x02, )) } -} -/// Addition (8b) -pub fn add8(reg0: u8, reg1: u8, reg2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRR(0x03, reg0, reg1, reg2)) } -} -/// Addition (16b) -pub fn add16(reg0: u8, reg1: u8, reg2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRR(0x04, reg0, reg1, reg2)) } -} -/// Addition (32b) -pub fn add32(reg0: u8, reg1: u8, reg2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRR(0x05, reg0, reg1, reg2)) } -} -/// Addition (64b) -pub fn add64(reg0: u8, reg1: u8, reg2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRR(0x06, reg0, reg1, reg2)) } -} -/// Subtraction (8b) -pub fn sub8(reg0: u8, reg1: u8, reg2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRR(0x07, reg0, reg1, reg2)) } -} -/// Subtraction (16b) -pub fn sub16(reg0: u8, reg1: u8, reg2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRR(0x08, reg0, reg1, reg2)) } -} -/// Subtraction (32b) -pub fn sub32(reg0: u8, reg1: u8, reg2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRR(0x09, reg0, reg1, reg2)) } -} -/// Subtraction (64b) -pub fn sub64(reg0: u8, reg1: u8, reg2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRR(0x0A, reg0, reg1, reg2)) } -} -/// Multiplication (8b) -pub fn mul8(reg0: u8, reg1: u8, reg2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRR(0x0B, reg0, reg1, reg2)) } -} -/// Multiplication (16b) -pub fn mul16(reg0: u8, reg1: u8, reg2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRR(0x0C, reg0, reg1, reg2)) } -} -/// Multiplication (32b) -pub fn mul32(reg0: u8, reg1: u8, reg2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRR(0x0D, reg0, reg1, reg2)) } -} -/// Multiplication (64b) -pub fn mul64(reg0: u8, reg1: u8, reg2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRR(0x0E, reg0, reg1, reg2)) } -} -/// Bitand -pub fn and(reg0: u8, reg1: u8, reg2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRR(0x0F, reg0, reg1, reg2)) } -} -/// Bitor -pub fn or(reg0: u8, reg1: u8, reg2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRR(0x10, reg0, reg1, reg2)) } -} -/// Bitxor -pub fn xor(reg0: u8, reg1: u8, reg2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRR(0x11, reg0, reg1, reg2)) } -} -/// Unsigned left bitshift (8b) -pub fn slu8(reg0: u8, reg1: u8, reg2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRR(0x12, reg0, reg1, reg2)) } -} -/// Unsigned left bitshift (16b) -pub fn slu16(reg0: u8, reg1: u8, reg2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRR(0x13, reg0, reg1, reg2)) } -} -/// Unsigned left bitshift (32b) -pub fn slu32(reg0: u8, reg1: u8, reg2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRR(0x14, reg0, reg1, reg2)) } -} -/// Unsigned left bitshift (64b) -pub fn slu64(reg0: u8, reg1: u8, reg2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRR(0x15, reg0, reg1, reg2)) } -} -/// Unsigned right bitshift (8b) -pub fn sru8(reg0: u8, reg1: u8, reg2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRR(0x16, reg0, reg1, reg2)) } -} -/// Unsigned right bitshift (16b) -pub fn sru16(reg0: u8, reg1: u8, reg2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRR(0x17, reg0, reg1, reg2)) } -} -/// Unsigned right bitshift (32b) -pub fn sru32(reg0: u8, reg1: u8, reg2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRR(0x18, reg0, reg1, reg2)) } -} -/// Unsigned right bitshift (64b) -pub fn sru64(reg0: u8, reg1: u8, reg2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRR(0x19, reg0, reg1, reg2)) } -} -/// Signed right bitshift (8b) -pub fn srs8(reg0: u8, reg1: u8, reg2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRR(0x1A, reg0, reg1, reg2)) } -} -/// Signed right bitshift (16b) -pub fn srs16(reg0: u8, reg1: u8, reg2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRR(0x1B, reg0, reg1, reg2)) } -} -/// Signed right bitshift (32b) -pub fn srs32(reg0: u8, reg1: u8, reg2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRR(0x1C, reg0, reg1, reg2)) } -} -/// Signed right bitshift (64b) -pub fn srs64(reg0: u8, reg1: u8, reg2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRR(0x1D, reg0, reg1, reg2)) } -} -/// Unsigned comparsion -pub fn cmpu(reg0: u8, reg1: u8, reg2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRR(0x1E, reg0, reg1, reg2)) } -} -/// Signed comparsion -pub fn cmps(reg0: u8, reg1: u8, reg2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRR(0x1F, reg0, reg1, reg2)) } -} -/// Merged divide-remainder (unsigned 8b) -pub fn diru8(reg0: u8, reg1: u8, reg2: u8, reg3: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRRR(0x20, reg0, reg1, reg2, reg3)) } -} -/// Merged divide-remainder (unsigned 16b) -pub fn diru16(reg0: u8, reg1: u8, reg2: u8, reg3: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRRR(0x21, reg0, reg1, reg2, reg3)) } -} -/// Merged divide-remainder (unsigned 32b) -pub fn diru32(reg0: u8, reg1: u8, reg2: u8, reg3: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRRR(0x22, reg0, reg1, reg2, reg3)) } -} -/// Merged divide-remainder (unsigned 64b) -pub fn diru64(reg0: u8, reg1: u8, reg2: u8, reg3: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRRR(0x23, reg0, reg1, reg2, reg3)) } -} -/// Merged divide-remainder (signed 8b) -pub fn dirs8(reg0: u8, reg1: u8, reg2: u8, reg3: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRRR(0x24, reg0, reg1, reg2, reg3)) } -} -/// Merged divide-remainder (signed 16b) -pub fn dirs16(reg0: u8, reg1: u8, reg2: u8, reg3: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRRR(0x25, reg0, reg1, reg2, reg3)) } -} -/// Merged divide-remainder (signed 32b) -pub fn dirs32(reg0: u8, reg1: u8, reg2: u8, reg3: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRRR(0x26, reg0, reg1, reg2, reg3)) } -} -/// Merged divide-remainder (signed 64b) -pub fn dirs64(reg0: u8, reg1: u8, reg2: u8, reg3: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRRR(0x27, reg0, reg1, reg2, reg3)) } -} -/// Bit negation -pub fn neg(reg0: u8, reg1: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RR(0x28, reg0, reg1)) } -} -/// Logical negation -pub fn not(reg0: u8, reg1: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RR(0x29, reg0, reg1)) } -} -/// Sign extend 8b to 64b -pub fn sxt8(reg0: u8, reg1: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RR(0x2A, reg0, reg1)) } -} -/// Sign extend 16b to 64b -pub fn sxt16(reg0: u8, reg1: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RR(0x2B, reg0, reg1)) } -} -/// Sign extend 32b to 64b -pub fn sxt32(reg0: u8, reg1: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RR(0x2C, reg0, reg1)) } -} -/// Addition with immediate (8b) -pub fn addi8(reg0: u8, reg1: u8, imm2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRB(0x2D, reg0, reg1, imm2)) } -} -/// Addition with immediate (16b) -pub fn addi16(reg0: u8, reg1: u8, imm2: u16) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRH(0x2E, reg0, reg1, imm2)) } -} -/// Addition with immediate (32b) -pub fn addi32(reg0: u8, reg1: u8, imm2: u32) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRW(0x2F, reg0, reg1, imm2)) } -} -/// Addition with immediate (64b) -pub fn addi64(reg0: u8, reg1: u8, imm2: u64) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRD(0x30, reg0, reg1, imm2)) } -} -/// Multiplication with immediate (8b) -pub fn muli8(reg0: u8, reg1: u8, imm2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRB(0x31, reg0, reg1, imm2)) } -} -/// Multiplication with immediate (16b) -pub fn muli16(reg0: u8, reg1: u8, imm2: u16) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRH(0x32, reg0, reg1, imm2)) } -} -/// Multiplication with immediate (32b) -pub fn muli32(reg0: u8, reg1: u8, imm2: u32) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRW(0x33, reg0, reg1, imm2)) } -} -/// Multiplication with immediate (64b) -pub fn muli64(reg0: u8, reg1: u8, imm2: u64) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRD(0x34, reg0, reg1, imm2)) } -} -/// Bitand with immediate -pub fn andi(reg0: u8, reg1: u8, imm2: u64) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRD(0x35, reg0, reg1, imm2)) } -} -/// Bitor with immediate -pub fn ori(reg0: u8, reg1: u8, imm2: u64) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRD(0x36, reg0, reg1, imm2)) } -} -/// Bitxor with immediate -pub fn xori(reg0: u8, reg1: u8, imm2: u64) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRD(0x37, reg0, reg1, imm2)) } -} -/// Unsigned left bitshift with immedidate (8b) -pub fn slui8(reg0: u8, reg1: u8, imm2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRB(0x38, reg0, reg1, imm2)) } -} -/// Unsigned left bitshift with immedidate (16b) -pub fn slui16(reg0: u8, reg1: u8, imm2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRB(0x39, reg0, reg1, imm2)) } -} -/// Unsigned left bitshift with immedidate (32b) -pub fn slui32(reg0: u8, reg1: u8, imm2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRB(0x3A, reg0, reg1, imm2)) } -} -/// Unsigned left bitshift with immedidate (64b) -pub fn slui64(reg0: u8, reg1: u8, imm2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRB(0x3B, reg0, reg1, imm2)) } -} -/// Unsigned right bitshift with immediate (8b) -pub fn srui8(reg0: u8, reg1: u8, imm2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRB(0x3C, reg0, reg1, imm2)) } -} -/// Unsigned right bitshift with immediate (16b) -pub fn srui16(reg0: u8, reg1: u8, imm2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRB(0x3D, reg0, reg1, imm2)) } -} -/// Unsigned right bitshift with immediate (32b) -pub fn srui32(reg0: u8, reg1: u8, imm2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRB(0x3E, reg0, reg1, imm2)) } -} -/// Unsigned right bitshift with immediate (64b) -pub fn srui64(reg0: u8, reg1: u8, imm2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRB(0x3F, reg0, reg1, imm2)) } -} -/// Signed right bitshift with immediate -pub fn srsi8(reg0: u8, reg1: u8, imm2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRB(0x40, reg0, reg1, imm2)) } -} -/// Signed right bitshift with immediate -pub fn srsi16(reg0: u8, reg1: u8, imm2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRB(0x41, reg0, reg1, imm2)) } -} -/// Signed right bitshift with immediate -pub fn srsi32(reg0: u8, reg1: u8, imm2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRB(0x42, reg0, reg1, imm2)) } -} -/// Signed right bitshift with immediate -pub fn srsi64(reg0: u8, reg1: u8, imm2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRB(0x43, reg0, reg1, imm2)) } -} -/// Unsigned compare with immediate -pub fn cmpui(reg0: u8, reg1: u8, imm2: u64) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRD(0x44, reg0, reg1, imm2)) } -} -/// Signed compare with immediate -pub fn cmpsi(reg0: u8, reg1: u8, imm2: u64) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRD(0x45, reg0, reg1, imm2)) } -} -/// Copy register -pub fn cp(reg0: u8, reg1: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RR(0x46, reg0, reg1)) } -} -/// Swap registers -pub fn swa(reg0: u8, reg1: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RR(0x47, reg0, reg1)) } -} -/// Load immediate (8b) -pub fn li8(reg0: u8, imm1: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RB(0x48, reg0, imm1)) } -} -/// Load immediate (16b) -pub fn li16(reg0: u8, imm1: u16) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RH(0x49, reg0, imm1)) } -} -/// Load immediate (32b) -pub fn li32(reg0: u8, imm1: u32) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RW(0x4A, reg0, imm1)) } -} -/// Load immediate (64b) -pub fn li64(reg0: u8, imm1: u64) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RD(0x4B, reg0, imm1)) } -} -/// Load relative address -pub fn lra(reg0: u8, reg1: u8, offset2: i32) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRO(0x4C, reg0, reg1, offset2)) } -} -/// Load from absolute address -pub fn ld(reg0: u8, reg1: u8, addr2: u64, imm3: u16) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRAH(0x4D, reg0, reg1, addr2, imm3)) } -} -/// Store to absolute address -pub fn st(reg0: u8, reg1: u8, addr2: u64, imm3: u16) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRAH(0x4E, reg0, reg1, addr2, imm3)) } -} -/// Load from relative address -pub fn ldr(reg0: u8, reg1: u8, offset2: i32, imm3: u16) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RROH(0x4F, reg0, reg1, offset2, imm3)) } -} -/// Store to relative address -pub fn str(reg0: u8, reg1: u8, offset2: i32, imm3: u16) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RROH(0x50, reg0, reg1, offset2, imm3)) } -} -/// Copy block of memory -pub fn bmc(reg0: u8, reg1: u8, imm2: u16) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRH(0x51, reg0, reg1, imm2)) } -} -/// Copy register block -pub fn brc(reg0: u8, reg1: u8, imm2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRB(0x52, reg0, reg1, imm2)) } -} -/// Relative jump -pub fn jmp(offset0: i32) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(O(0x53, offset0)) } -} -/// Linking relative jump -pub fn jal(reg0: u8, reg1: u8, offset2: i32) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRO(0x54, reg0, reg1, offset2)) } -} -/// Linking absolute jump -pub fn jala(reg0: u8, reg1: u8, addr2: u64) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRA(0x55, reg0, reg1, addr2)) } -} -/// Branch on equal -pub fn jeq(reg0: u8, reg1: u8, offset2: i16) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRP(0x56, reg0, reg1, offset2)) } -} -/// Branch on nonequal -pub fn jne(reg0: u8, reg1: u8, offset2: i16) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRP(0x57, reg0, reg1, offset2)) } -} -/// Branch on lesser-than (unsigned) -pub fn jltu(reg0: u8, reg1: u8, offset2: i16) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRP(0x58, reg0, reg1, offset2)) } -} -/// Branch on greater-than (unsigned) -pub fn jgtu(reg0: u8, reg1: u8, offset2: i16) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRP(0x59, reg0, reg1, offset2)) } -} -/// Branch on lesser-than (signed) -pub fn jlts(reg0: u8, reg1: u8, offset2: i16) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRP(0x5A, reg0, reg1, offset2)) } -} -/// Branch on greater-than (signed) -pub fn jgts(reg0: u8, reg1: u8, offset2: i16) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRP(0x5B, reg0, reg1, offset2)) } -} -/// Environment call trap -pub fn eca() -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(N(0x5C, )) } -} -/// Environment breakpoint -pub fn ebp() -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(N(0x5D, )) } -} -/// Floating point addition (32b) -pub fn fadd32(reg0: u8, reg1: u8, reg2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRR(0x5E, reg0, reg1, reg2)) } -} -/// Floating point addition (64b) -pub fn fadd64(reg0: u8, reg1: u8, reg2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRR(0x5F, reg0, reg1, reg2)) } -} -/// Floating point subtraction (32b) -pub fn fsub32(reg0: u8, reg1: u8, reg2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRR(0x60, reg0, reg1, reg2)) } -} -/// Floating point subtraction (64b) -pub fn fsub64(reg0: u8, reg1: u8, reg2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRR(0x61, reg0, reg1, reg2)) } -} -/// Floating point multiply (32b) -pub fn fmul32(reg0: u8, reg1: u8, reg2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRR(0x62, reg0, reg1, reg2)) } -} -/// Floating point multiply (64b) -pub fn fmul64(reg0: u8, reg1: u8, reg2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRR(0x63, reg0, reg1, reg2)) } -} -/// Floating point division (32b) -pub fn fdiv32(reg0: u8, reg1: u8, reg2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRR(0x64, reg0, reg1, reg2)) } -} -/// Floating point division (64b) -pub fn fdiv64(reg0: u8, reg1: u8, reg2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRR(0x65, reg0, reg1, reg2)) } -} -/// Float fused multiply-add (32b) -pub fn fma32(reg0: u8, reg1: u8, reg2: u8, reg3: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRRR(0x66, reg0, reg1, reg2, reg3)) } -} -/// Float fused multiply-add (64b) -pub fn fma64(reg0: u8, reg1: u8, reg2: u8, reg3: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRRR(0x67, reg0, reg1, reg2, reg3)) } -} -/// Float reciprocal (32b) -pub fn finv32(reg0: u8, reg1: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RR(0x68, reg0, reg1)) } -} -/// Float reciprocal (64b) -pub fn finv64(reg0: u8, reg1: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RR(0x69, reg0, reg1)) } -} -/// Flaot compare less than (32b) -pub fn fcmplt32(reg0: u8, reg1: u8, reg2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRR(0x6A, reg0, reg1, reg2)) } -} -/// Flaot compare less than (64b) -pub fn fcmplt64(reg0: u8, reg1: u8, reg2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRR(0x6B, reg0, reg1, reg2)) } -} -/// Flaot compare greater than (32b) -pub fn fcmpgt32(reg0: u8, reg1: u8, reg2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRR(0x6C, reg0, reg1, reg2)) } -} -/// Flaot compare greater than (64b) -pub fn fcmpgt64(reg0: u8, reg1: u8, reg2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRR(0x6D, reg0, reg1, reg2)) } -} -/// Int to 32 bit float -pub fn itf32(reg0: u8, reg1: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RR(0x6E, reg0, reg1)) } -} -/// Int to 64 bit float -pub fn itf64(reg0: u8, reg1: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RR(0x6F, reg0, reg1)) } -} -/// Float 32 to int -pub fn fti32(reg0: u8, reg1: u8, imm2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRB(0x70, reg0, reg1, imm2)) } -} -/// Float 64 to int -pub fn fti64(reg0: u8, reg1: u8, imm2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRB(0x71, reg0, reg1, imm2)) } -} -/// Float 64 to Float 32 -pub fn fc32t64(reg0: u8, reg1: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RR(0x72, reg0, reg1)) } -} -/// Float 32 to Float 64 -pub fn fc64t32(reg0: u8, reg1: u8, imm2: u8) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRB(0x73, reg0, reg1, imm2)) } -} -/// Load relative immediate (16 bit) -pub fn lra16(reg0: u8, reg1: u8, offset2: i16) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRP(0x74, reg0, reg1, offset2)) } -} -/// Load from relative address (16 bit) -pub fn ldr16(reg0: u8, reg1: u8, offset2: i16, imm3: u16) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRPH(0x75, reg0, reg1, offset2, imm3)) } -} -/// Store to relative address (16 bit) -pub fn str16(reg0: u8, reg1: u8, offset2: i16, imm3: u16) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(RRPH(0x76, reg0, reg1, offset2, imm3)) } -} -/// Relative jump (16 bit) -pub fn jmp16(offset0: i16) -> (usize, [u8; MAX_SIZE]) { - unsafe { crate::encode(P(0x77, offset0)) } -} -#[repr(packed)] pub struct N(u8, ); -#[repr(packed)] pub struct RRR(u8, u8, u8, u8); -#[repr(packed)] pub struct RRRR(u8, u8, u8, u8, u8); -#[repr(packed)] pub struct RR(u8, u8, u8); -#[repr(packed)] pub struct RRB(u8, u8, u8, u8); -#[repr(packed)] pub struct RRH(u8, u8, u8, u16); -#[repr(packed)] pub struct RRW(u8, u8, u8, u32); -#[repr(packed)] pub struct RRD(u8, u8, u8, u64); -#[repr(packed)] pub struct RB(u8, u8, u8); -#[repr(packed)] pub struct RH(u8, u8, u16); -#[repr(packed)] pub struct RW(u8, u8, u32); -#[repr(packed)] pub struct RD(u8, u8, u64); -#[repr(packed)] pub struct RRO(u8, u8, u8, i32); -#[repr(packed)] pub struct RRAH(u8, u8, u8, u64, u16); -#[repr(packed)] pub struct RROH(u8, u8, u8, i32, u16); -#[repr(packed)] pub struct O(u8, i32); -#[repr(packed)] pub struct RRA(u8, u8, u8, u64); -#[repr(packed)] pub struct RRP(u8, u8, u8, i16); -#[repr(packed)] pub struct RRPH(u8, u8, u8, i16, u16); -#[repr(packed)] pub struct P(u8, i16); -pub const NAMES: [&str; 120] = [ - "un", - "tx", - "nop", - "add8", - "add16", - "add32", - "add64", - "sub8", - "sub16", - "sub32", - "sub64", - "mul8", - "mul16", - "mul32", - "mul64", - "and", - "or", - "xor", - "slu8", - "slu16", - "slu32", - "slu64", - "sru8", - "sru16", - "sru32", - "sru64", - "srs8", - "srs16", - "srs32", - "srs64", - "cmpu", - "cmps", - "diru8", - "diru16", - "diru32", - "diru64", - "dirs8", - "dirs16", - "dirs32", - "dirs64", - "neg", - "not", - "sxt8", - "sxt16", - "sxt32", - "addi8", - "addi16", - "addi32", - "addi64", - "muli8", - "muli16", - "muli32", - "muli64", - "andi", - "ori", - "xori", - "slui8", - "slui16", - "slui32", - "slui64", - "srui8", - "srui16", - "srui32", - "srui64", - "srsi8", - "srsi16", - "srsi32", - "srsi64", - "cmpui", - "cmpsi", - "cp", - "swa", - "li8", - "li16", - "li32", - "li64", - "lra", - "ld", - "st", - "ldr", - "str", - "bmc", - "brc", - "jmp", - "jal", - "jala", - "jeq", - "jne", - "jltu", - "jgtu", - "jlts", - "jgts", - "eca", - "ebp", - "fadd32", - "fadd64", - "fsub32", - "fsub64", - "fmul32", - "fmul64", - "fdiv32", - "fdiv64", - "fma32", - "fma64", - "finv32", - "finv64", - "fcmplt32", - "fcmplt64", - "fcmpgt32", - "fcmpgt64", - "itf32", - "itf64", - "fti32", - "fti64", - "fc32t64", - "fc64t32", - "lra16", - "ldr16", - "str16", - "jmp16", -]; diff --git a/hblang/src/lib.rs b/hblang/src/lib.rs index f41aa95..51e417e 100644 --- a/hblang/src/lib.rs +++ b/hblang/src/lib.rs @@ -1,7 +1,6 @@ #![feature(noop_waker)] #![feature(macro_metavar_expr)] #![feature(let_chains)] -#![feature(non_null_convenience)] #![allow(dead_code)] #![feature(const_mut_refs)] diff --git a/hblang/src/parser.rs b/hblang/src/parser.rs index ef1c0b6..a3ec118 100644 --- a/hblang/src/parser.rs +++ b/hblang/src/parser.rs @@ -497,8 +497,34 @@ impl<'a> std::fmt::Display for Expr<'a> { write!(f, "{end}") } + macro_rules! impl_parenter { + ($($name:ident => $pat:pat,)*) => { + $( + struct $name<'a>(&'a Expr<'a>); + + impl<'a> std::fmt::Display for $name<'a> { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + if matches!(self.0, $pat) { + write!(f, "({})", self.0) + } else { + write!(f, "{}", self.0) + } + } + } + )* + }; + } + + impl_parenter! { + Unary => Expr::BinOp { .. }, + Postfix => Expr::UnOp { .. } | Expr::BinOp { .. }, + Consecutive => Expr::UnOp { .. }, + } + match *self { - Self::Field { target, field } => write!(f, "{target}.{field}"), + Self::Field { target, field } => { + write!(f, "{}.{field}", Postfix(target)) + } Self::Directive { name, args, .. } => { write!(f, "@{name}(")?; fmt_list(f, ")", args, std::fmt::Display::fmt) @@ -515,7 +541,7 @@ impl<'a> std::fmt::Display for Expr<'a> { }; if let Some(ty) = ty { - write!(f, "{ty}")?; + write!(f, "{}", Unary(ty))?; } write!(f, ".{left}")?; let first = &mut true; @@ -530,13 +556,13 @@ impl<'a> std::fmt::Display for Expr<'a> { } write!(f, "{rith}") } - Self::UnOp { op, val, .. } => write!(f, "{op}{val}"), + Self::UnOp { op, val, .. } => write!(f, "{op}{}", Unary(val)), Self::Break { .. } => write!(f, "break;"), Self::Continue { .. } => write!(f, "continue;"), Self::If { cond, then, else_, .. } => { - write!(f, "if {cond} {then}")?; + write!(f, "if {cond} {}", Consecutive(then))?; if let Some(else_) = else_ { write!(f, " else {else_}")?; } @@ -551,7 +577,7 @@ impl<'a> std::fmt::Display for Expr<'a> { write!(f, "): {ret} {body}") } Self::Call { func, args } => { - write!(f, "{func}(")?; + write!(f, "{}(", Postfix(func))?; fmt_list(f, ")", args, std::fmt::Display::fmt) } Self::Return { val: Some(val), .. } => write!(f, "return {val};"),