common: update Instruction tuples to hold common structs

This commit is contained in:
2025-06-15 11:58:03 +01:00
parent 5494ff5803
commit e52093f9cd
+101 -68
View File
@@ -154,6 +154,28 @@ impl std::fmt::Display for Register {
} }
} }
/// Used by instructions with no arguments.
struct NoArgs {}
#[derive(Debug, Clone, Copy)]
/// Used by instructions with 2 registers and an immediate argument.
struct ITypeArgs {
immediate: u16,
r1: Register,
/// May not actually be used by some instructions taking an immediate e.g. LUI. This is solved by making the constructor take Options.
r2: Register,
}
/// Used by instructions not using immediates (besides 5 bit shift values).
#[derive(Debug, Clone, Copy)]
struct RTypeArgs {
sr1: Register,
sr2: Register,
dr: Register,
/// 5 bit shift amount.
shamt: u8,
}
/// TODO: Turn argument tuples into simple structs like `TwoReg`, `TwoRegAndOff` /// TODO: Turn argument tuples into simple structs like `TwoReg`, `TwoRegAndOff`
/// etc just to make code a little cleaner. /// etc just to make code a little cleaner.
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
@@ -163,50 +185,50 @@ pub enum Instruction {
Nop = 0x0, Nop = 0x0,
// Data transfer instructions // Data transfer instructions
Mov(Register, Register) = 0x1, Mov(RTypeArgs) = 0x1,
MovSigned(Register, Register) = 0x2, MovSigned(RTypeArgs) = 0x2,
LoadByte(Register, Offset, Register) = 0x3, LoadByte(ITypeArgs) = 0x3,
LoadByteSigned(Register, Offset, Register) = 0x4, LoadByteSigned(ITypeArgs) = 0x4,
LoadHalfword(Register, Offset, Register) = 0x5, LoadHalfword(ITypeArgs) = 0x5,
LoadHalfwordSigned(Register, Offset, Register) = 0x6, LoadHalfwordSigned(ITypeArgs) = 0x6,
LoadWord(Register, Offset, Register) = 0x7, LoadWord(ITypeArgs) = 0x7,
StoreByte(Register, Offset, Register) = 0x8, StoreByte(ITypeArgs) = 0x8,
StoreHalfword(Register, Offset, Register) = 0x9, StoreHalfword(ITypeArgs) = 0x9,
StoreWord(Register, Offset, Register) = 0xA, StoreWord(ITypeArgs) = 0xA,
LoadLowerImmediate(Register, Immediate) = 0xB, LoadLowerImmediate(ITypeArgs) = 0xB,
LoadUpperImmediate(Register, Immediate) = 0xC, LoadUpperImmediate(ITypeArgs) = 0xC,
// Jump Instructions // Jump Instructions
Jump(Register, Offset) = 0xD, Jump(ITypeArgs) = 0xD,
JumpEq(Register, Offset) = 0xE, JumpEq(ITypeArgs) = 0xE,
JumpNeq(Register, Offset) = 0xF, JumpNeq(ITypeArgs) = 0xF,
JumpGt(Register, Offset) = 0x10, JumpGt(ITypeArgs) = 0x10,
JumpGe(Register, Offset) = 0x11, JumpGe(ITypeArgs) = 0x11,
JumpLt(Register, Offset) = 0x12, JumpLt(ITypeArgs) = 0x12,
JumpLe(Register, Offset) = 0x13, JumpLe(ITypeArgs) = 0x13,
// Comparison // Comparison
Compare(Register, Register) = 0x14, Compare(RTypeArgs) = 0x14,
// Arithmetic // Arithmetic
Add(Register, Register, Register) = 0x19, Add(RTypeArgs) = 0x19,
Sub(Register, Register, Register) = 0x1A, Sub(RTypeArgs) = 0x1A,
Increment(Register) = 0x15, Increment(RTypeArgs) = 0x15,
Decrement(Register) = 0x16, Decrement(RTypeArgs) = 0x16,
ShiftLeft(Register, Register, Immediate) = 0x17, ShiftLeft(RTypeArgs) = 0x17,
ShiftRight(Register, Register, Immediate) = 0x18, ShiftRight(RTypeArgs) = 0x18,
// Logical // Logical
And(Register, Register, Register) = 0x1B, And(RTypeArgs) = 0x1B,
Or(Register, Register, Register) = 0x1C, Or(RTypeArgs) = 0x1C,
Not(Register, Register) = 0x1D, Not(RTypeArgs) = 0x1D,
Xor(Register, Register, Register) = 0x1E, Xor(RTypeArgs) = 0x1E,
Nand(Register, Register, Register) = 0x1F, Nand(RTypeArgs) = 0x1F,
Nor(Register, Register, Register) = 0x20, Nor(RTypeArgs) = 0x20,
Xnor(Register, Register, Register) = 0x21, Xnor(RTypeArgs) = 0x21,
// Misc // Misc
Interrupt(Interrupt) = 0x22, Interrupt(Interrupt) = 0x22,
@@ -290,46 +312,57 @@ impl Instruction {
impl std::fmt::Display for Instruction { impl std::fmt::Display for Instruction {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { match self {
Self::Nop => write!(f, "No Operation"), Self::Nop => write!(f, "NOP"),
Self::Mov(a, b) => write!(f, "MOV {a}, {b}"), Self::Mov(args) => write!(f, "MOV {}, {}", args.sr1, args.dr),
Self::MovSigned(a, b) => write!(f, "MOVS {a}, {b}"), Self::MovSigned(args) => write!(f, "MOVS {}, {}", args.sr1, args.dr),
Self::LoadByte(a, b, c) => write!(f, "LDB {a}, {b}, {c}"), Self::LoadByte(args) => write!(f, "LDB {:x}({}), {}", args.immediate, args.r1, args.r2),
Self::LoadByteSigned(a, b, c) => write!(f, "LDBS {a}, {b}, {c}"), Self::LoadByteSigned(args) => {
Self::LoadHalfword(a, b, c) => write!(f, "LDH {a}, {b}, {c}"), write!(f, "LDBS {:x}({}), {}", args.immediate, args.r1, args.r2)
Self::LoadHalfwordSigned(a, b, c) => write!(f, "LDHS {a}, {b}, {c}"), }
Self::LoadWord(a, b, c) => write!(f, "LDW {a}, {b}, {c}"), Self::LoadHalfword(args) => {
write!(f, "LDH {:x}({}), {}", args.immediate, args.r1, args.r2)
}
Self::LoadHalfwordSigned(args) => {
write!(f, "LDHS {:x}({}), {}", args.immediate, args.r1, args.r2)
}
Self::LoadWord(args) => write!(f, "LDW {:x}({}), {}", args.immediate, args.r1, args.r2),
Self::StoreByte(args) => {
write!(f, "STB {:x}({}), {}", args.immediate, args.r1, args.r2)
}
Self::StoreHalfword(args) => {
write!(f, "STH {:x}({}), {}", args.immediate, args.r1, args.r2)
}
Self::StoreWord(args) => {
write!(f, "STW {:x}({}), {}", args.immediate, args.r1, args.r2)
}
Self::StoreByte(a, b, c) => write!(f, "STB {a}, {b}, {c}"), Self::LoadLowerImmediate(args) => write!(f, "LLI {}, {}", args.r1, args.r2),
Self::StoreHalfword(a, b, c) => write!(f, "STH {a}, {b}, {c}"), Self::LoadUpperImmediate(args) => write!(f, "LUI {}, {}", args.r1, args.r2),
Self::StoreWord(a, b, c) => write!(f, "STW {a}, {b}, {c}"),
Self::LoadLowerImmediate(a, b) => write!(f, "LLI {a}, {b}"), Self::Jump(args) => write!(f, "JMP ({:x}){}", args.immediate, args.r1),
Self::LoadUpperImmediate(a, b) => write!(f, "LUI {a}, {b}"), Self::JumpEq(args) => write!(f, "JEQ ({:x}){}", args.immediate, args.r1),
Self::JumpNeq(args) => write!(f, "JNEQ ({:x}){}", args.immediate, args.r1),
Self::JumpGt(args) => write!(f, "JGT {:x}({})", args.immediate, args.r1),
Self::JumpGe(args) => write!(f, "JGE {:x}({})", args.immediate, args.r1),
Self::JumpLt(args) => write!(f, "JLT {:x}({})", args.immediate, args.r1),
Self::JumpLe(args) => write!(f, "JLE {:x}({})", args.immediate, args.r1),
Self::Jump(a, b) => write!(f, "JMP {a}, {b}"), Self::Compare(args) => write!(f, "CMP {}, {}", args.sr1, args.sr2),
Self::JumpEq(a, b) => write!(f, "JEQ {a}, {b}"),
Self::JumpNeq(a, b) => write!(f, "JNEQ {a}, {b}"),
Self::JumpGt(a, b) => write!(f, "JGT {a}, {b}"),
Self::JumpGe(a, b) => write!(f, "JGE {a}, {b}"),
Self::JumpLt(a, b) => write!(f, "JLT {a}, {b}"),
Self::JumpLe(a, b) => write!(f, "JLE {a}, {b}"),
Self::Compare(a, b) => write!(f, "CMP {a}, {b}"), Self::Add(args) => write!(f, "ADD {}, {}, {}", args.sr1, args.sr2, args.dr),
Self::Sub(args) => write!(f, "SUB {}, {}, {}", args.sr1, args.sr2, args.dr),
Self::Increment(a) => write!(f, "INC {}", a.dr),
Self::Decrement(a) => write!(f, "DEC {}", a.dr),
Self::ShiftLeft(args) => write!(f, "SHL {}, {}, {}", args.sr1, args.sr2, args.dr),
Self::ShiftRight(args) => write!(f, "SHR {}, {}, {}", args.sr1, args.sr2, args.dr),
Self::Add(a, b, c) => write!(f, "ADD {a}, {b}, {c}"), Self::And(args) => write!(f, "AND {}, {}, {}", args.sr1, args.sr2, args.dr),
Self::Sub(a, b, c) => write!(f, "SUB {a}, {b}, {c}"), Self::Or(args) => write!(f, "OR {}, {}, {}", args.sr1, args.sr2, args.dr),
Self::Increment(a) => write!(f, "INC {a}"), Self::Not(args) => write!(f, "NOT {}, {}", args.sr1, args.sr2),
Self::Decrement(a) => write!(f, "DEC {a}"), Self::Xor(args) => write!(f, "XOR {}, {}, {}", args.sr1, args.sr2, args.dr),
Self::ShiftLeft(a, b, c) => write!(f, "SHL {a}, {b}, {c}"), Self::Nand(args) => write!(f, "NAND {}, {}, {}", args.sr1, args.sr2, args.dr),
Self::ShiftRight(a, b, c) => write!(f, "SHR {a}, {b}, {c}"), Self::Nor(args) => write!(f, "NOR {}, {}, {}", args.sr1, args.sr2, args.dr),
Self::Xnor(args) => write!(f, "XNOR {}, {}, {}", args.sr1, args.sr2, args.dr),
Self::And(a, b, c) => write!(f, "AND {a}, {b}, {c}"),
Self::Or(a, b, c) => write!(f, "OR {a}, {b}, {c}"),
Self::Not(a, b) => write!(f, "NOT {a}, {b}"),
Self::Xor(a, b, c) => write!(f, "XOR {a}, {b}, {c}"),
Self::Nand(a, b, c) => write!(f, "NAND {a}, {b}, {c}"),
Self::Nor(a, b, c) => write!(f, "NOR {a}, {b}, {c}"),
Self::Xnor(a, b, c) => write!(f, "XNOR {a}, {b}, {c}"),
Self::Interrupt(a) => write!(f, "INT {}", a.as_u8()), Self::Interrupt(a) => write!(f, "INT {}", a.as_u8()),
Self::IntReturn => write!(f, "INTR"), Self::IntReturn => write!(f, "INTR"),