removing deendence on macros with a simple build script
This commit is contained in:
parent
78f9eb6acc
commit
87ba7aa203
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1 +1,4 @@
|
|||
/target
|
||||
/hbbytecode/src/opcode.rs
|
||||
/hbbytecode/src/ops.rs
|
||||
/hblang/src/instrs.rs
|
||||
|
|
4
Cargo.lock
generated
4
Cargo.lock
generated
|
@ -196,10 +196,6 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "hbbytecode"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"paste",
|
||||
"with_builtin_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hblang"
|
||||
|
|
|
@ -2,7 +2,3 @@
|
|||
name = "hbbytecode"
|
||||
version = "0.1.0"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
paste = "1.0.14"
|
||||
with_builtin_macros = "0.0.3"
|
||||
|
|
58
hbbytecode/build.rs
Normal file
58
hbbytecode/build.rs
Normal file
|
@ -0,0 +1,58 @@
|
|||
#![feature(iter_next_chunk)]
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
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<Item = [&'static str; 4]> {
|
||||
include_str!("../hbbytecode/instructions.in")
|
||||
.lines()
|
||||
.map(|line| line.strip_suffix(';').unwrap())
|
||||
.map(|line| line.splitn(4, ',').map(str::trim).next_chunk().unwrap())
|
||||
}
|
466
hbbytecode/src/generated.rs
Normal file
466
hbbytecode/src/generated.rs
Normal file
|
@ -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
|
|
@ -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::<Self>()
|
||||
}
|
||||
}
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
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::[<Ops $ty>]),
|
||||
)* }
|
||||
|
||||
impl Op {
|
||||
pub fn size(&self) -> usize {
|
||||
(match self {
|
||||
$(Self::[<$mnemonic:lower:camel>] { .. } => core::mem::size_of::<super::[<Ops $ty>]>(),)*
|
||||
}) + 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<u8> for RoundingMode {
|
|||
.ok_or(())
|
||||
}
|
||||
}
|
||||
|
||||
invoke_with_def!(gen_opcodes);
|
||||
|
|
|
@ -8,6 +8,4 @@ name = "hbc"
|
|||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
|
||||
[dev-dependencies]
|
||||
hbvm = { path = "../hbvm", features = ["nightly"] }
|
||||
|
|
|
@ -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<Loop>,
|
||||
records: Vec<Struct>,
|
||||
pointers: Vec<Type>,
|
||||
globals: Vec<Global>,
|
||||
main: Option<LabelId>,
|
||||
}
|
||||
|
||||
|
@ -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::<Rc<[_]>>();
|
||||
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!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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",
|
||||
];
|
|
@ -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)]
|
||||
|
||||
|
|
|
@ -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};"),
|
||||
|
|
Loading…
Reference in a new issue