common: update Instruction tuples to hold common structs
This commit is contained in:
+101
-68
@@ -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"),
|
||||||
|
|||||||
Reference in New Issue
Block a user