Skip to content

Commit

Permalink
refine what we think MIR does.
Browse files Browse the repository at this point in the history
  • Loading branch information
Lokathor committed Dec 31, 2024
1 parent 9bdd7e0 commit 3c0d540
Show file tree
Hide file tree
Showing 8 changed files with 324 additions and 259 deletions.
246 changes: 0 additions & 246 deletions src/asm/mod.rs
Original file line number Diff line number Diff line change
@@ -1,251 +1,5 @@
use super::*;

/// Performs math using the A register along with some other value.
#[derive(Debug, Clone, Copy)]
pub enum BinaryOp {
/// `adc`
AddCarry,

/// `add`
Add,

/// `and`
BitAnd,

/// `cp`
Compare,

/// `or`
BitOr,

/// `sbc`
SubCarry,

/// `sub`
Sub,

/// `xor`
BitXor,
}
impl core::fmt::Display for BinaryOp {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
match self {
BinaryOp::AddCarry => "adc",
BinaryOp::Add => "add",
BinaryOp::BitAnd => "and",
BinaryOp::Compare => "cp",
BinaryOp::BitOr => "or",
BinaryOp::SubCarry => "sbc",
BinaryOp::Sub => "sub",
BinaryOp::BitXor => "xor",
}
)
}
}

/// Manipulates the bits of a single value
#[derive(Debug, Clone, Copy)]
pub enum UnaryOp {
/// `bit n,`
Test(u8),

/// `set n,`
Set(u8),

/// `res n,`
Clear(u8),

/// `swap`
Swap,

/// `rl`
RotateLeft,

/// `rlc`
RotateLeftCarryless,

/// `rr`
RotateRight,

/// `rlc`
RotateRightCarryless,

/// `sla`
///
/// shift left, signed or unsigned
ShiftLeftArithmetic,

/// `sra`
///
/// shift right signed
ShiftRightArithmetic,

/// `srl`
///
/// shift right unsigned
ShiftRightLogical,
}
impl core::fmt::Display for UnaryOp {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
match self {
UnaryOp::Test(0) => "bit 0,",
UnaryOp::Test(1) => "bit 1,",
UnaryOp::Test(2) => "bit 2,",
UnaryOp::Test(3) => "bit 3,",
UnaryOp::Test(4) => "bit 4,",
UnaryOp::Test(5) => "bit 5,",
UnaryOp::Test(6) => "bit 6,",
UnaryOp::Test(7) => "bit 7,",
UnaryOp::Set(0) => "set 0,",
UnaryOp::Set(1) => "set 1,",
UnaryOp::Set(2) => "set 2,",
UnaryOp::Set(3) => "set 3,",
UnaryOp::Set(4) => "set 4,",
UnaryOp::Set(5) => "set 5,",
UnaryOp::Set(6) => "set 6,",
UnaryOp::Set(7) => "set 7,",
UnaryOp::Clear(0) => "res 0,",
UnaryOp::Clear(1) => "res 1,",
UnaryOp::Clear(2) => "res 2,",
UnaryOp::Clear(3) => "res 3,",
UnaryOp::Clear(4) => "res 4,",
UnaryOp::Clear(5) => "res 5,",
UnaryOp::Clear(6) => "res 6,",
UnaryOp::Clear(7) => "res 7,",
UnaryOp::Swap => "swap",
UnaryOp::RotateLeft => "rl",
UnaryOp::RotateLeftCarryless => "rlc",
UnaryOp::RotateRight => "rr",
UnaryOp::RotateRightCarryless => "rlc",
UnaryOp::ShiftLeftArithmetic => "sla",
UnaryOp::ShiftRightArithmetic => "sra",
UnaryOp::ShiftRightLogical => "srl",
_ => unimplemented!(),
}
)
}
}

/// The standard 8-bit registers
#[derive(Debug, Clone, Copy)]
pub enum Reg8 {
A,
B,
C,
D,
E,
H,
L,
}
impl TryFrom<Register> for Reg8 {
type Error = ();
#[inline]
fn try_from(value: Register) -> Result<Self, Self::Error> {
Ok(match value {
Register::A => Reg8::A,
Register::B => Reg8::B,
Register::C => Reg8::C,
Register::D => Reg8::D,
Register::E => Reg8::E,
Register::H => Reg8::H,
Register::L => Reg8::L,
_ => return Err(()),
})
}
}
impl core::fmt::Display for Reg8 {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
match self {
Reg8::A => "a",
Reg8::B => "b",
Reg8::C => "c",
Reg8::D => "d",
Reg8::E => "e",
Reg8::H => "h",
Reg8::L => "l",
}
)
}
}

/// The standard 16-bit register pairs
///
/// * Importantly, this **excludes** `af` and `sp`.
#[derive(Debug, Clone, Copy)]
pub enum Reg16 {
BC,
DE,
HL,
}
impl TryFrom<Register> for Reg16 {
type Error = ();
#[inline]
fn try_from(value: Register) -> Result<Self, Self::Error> {
Ok(match value {
Register::BC => Reg16::BC,
Register::DE => Reg16::DE,
Register::HL => Reg16::HL,
_ => return Err(()),
})
}
}
impl core::fmt::Display for Reg16 {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
match self {
Reg16::BC => "bc",
Reg16::DE => "de",
Reg16::HL => "hl",
}
)
}
}

/// The conditions for calls and jumps
#[derive(Debug, Clone, Copy)]
pub enum Condition {
/// `c,`
Carry,

/// `nc,`
NoCarry,

/// `z,`
Zero,

/// `nz,`
NonZero,

/// nothing is written for the "always" condition.
Always,
}
impl core::fmt::Display for Condition {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
match self {
Condition::Carry => "c, ",
Condition::NoCarry => "nc, ",
Condition::Zero => "z, ",
Condition::NonZero => "nz, ",
Condition::Always => "",
}
)
}
}

/// A value that can be expressed in a single line of assembly.
///
/// * Parts ending in `t` use that as the target. Eg: "Hlt" is "HL target",
Expand Down
6 changes: 5 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
//! package.
use crate::{
asm::{Asm, BinaryOp, Condition, Reg16, Reg8, UnaryOp},
asm::Asm,
ast::data::{
Call, Const, Expression, Function, IfElse, Item, Loop, Register, Statement,
Static, Token, Token::*, TokenTree, TokenTree::*,
Expand All @@ -29,6 +29,10 @@ use crate::{
file_span::FileSpan,
file_spanned::FileSpanned,
internal_iterator_mut::InternalIteratorMut,
mir::{
binary_op::BinaryOp, condition::Condition, reg16::Reg16, reg8::Reg8,
unary_op::UnaryOp,
},
src_file::{SrcFile, SrcID},
str_id::StrID,
};
Expand Down
47 changes: 47 additions & 0 deletions src/mir/binary_op.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
use super::*;

/// Performs math using the A register along with some other value.
#[derive(Debug, Clone, Copy)]
pub enum BinaryOp {
/// `adc`
AddCarry,

/// `add`
Add,

/// `and`
BitAnd,

/// `cp`
Compare,

/// `or`
BitOr,

/// `sbc`
SubCarry,

/// `sub`
Sub,

/// `xor`
BitXor,
}
impl core::fmt::Display for BinaryOp {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
match self {
BinaryOp::AddCarry => "adc",
BinaryOp::Add => "add",
BinaryOp::BitAnd => "and",
BinaryOp::Compare => "cp",
BinaryOp::BitOr => "or",
BinaryOp::SubCarry => "sbc",
BinaryOp::Sub => "sub",
BinaryOp::BitXor => "xor",
}
)
}
}
35 changes: 35 additions & 0 deletions src/mir/condition.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
use super::*;

/// The conditions for calls and jumps
#[derive(Debug, Clone, Copy)]
pub enum Condition {
/// `c,`
Carry,

/// `nc,`
NoCarry,

/// `z,`
Zero,

/// `nz,`
NonZero,

/// The "always" condition doesn't get written down in assembly output.
Always,
}
impl core::fmt::Display for Condition {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
match self {
Condition::Carry => "c, ",
Condition::NoCarry => "nc, ",
Condition::Zero => "z, ",
Condition::NonZero => "nz, ",
Condition::Always => "",
}
)
}
}
Loading

0 comments on commit 3c0d540

Please sign in to comment.