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`
|
||||
/// etc just to make code a little cleaner.
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
@@ -163,50 +185,50 @@ pub enum Instruction {
|
||||
Nop = 0x0,
|
||||
|
||||
// Data transfer instructions
|
||||
Mov(Register, Register) = 0x1,
|
||||
MovSigned(Register, Register) = 0x2,
|
||||
Mov(RTypeArgs) = 0x1,
|
||||
MovSigned(RTypeArgs) = 0x2,
|
||||
|
||||
LoadByte(Register, Offset, Register) = 0x3,
|
||||
LoadByteSigned(Register, Offset, Register) = 0x4,
|
||||
LoadHalfword(Register, Offset, Register) = 0x5,
|
||||
LoadHalfwordSigned(Register, Offset, Register) = 0x6,
|
||||
LoadWord(Register, Offset, Register) = 0x7,
|
||||
LoadByte(ITypeArgs) = 0x3,
|
||||
LoadByteSigned(ITypeArgs) = 0x4,
|
||||
LoadHalfword(ITypeArgs) = 0x5,
|
||||
LoadHalfwordSigned(ITypeArgs) = 0x6,
|
||||
LoadWord(ITypeArgs) = 0x7,
|
||||
|
||||
StoreByte(Register, Offset, Register) = 0x8,
|
||||
StoreHalfword(Register, Offset, Register) = 0x9,
|
||||
StoreWord(Register, Offset, Register) = 0xA,
|
||||
StoreByte(ITypeArgs) = 0x8,
|
||||
StoreHalfword(ITypeArgs) = 0x9,
|
||||
StoreWord(ITypeArgs) = 0xA,
|
||||
|
||||
LoadLowerImmediate(Register, Immediate) = 0xB,
|
||||
LoadUpperImmediate(Register, Immediate) = 0xC,
|
||||
LoadLowerImmediate(ITypeArgs) = 0xB,
|
||||
LoadUpperImmediate(ITypeArgs) = 0xC,
|
||||
|
||||
// Jump Instructions
|
||||
Jump(Register, Offset) = 0xD,
|
||||
JumpEq(Register, Offset) = 0xE,
|
||||
JumpNeq(Register, Offset) = 0xF,
|
||||
JumpGt(Register, Offset) = 0x10,
|
||||
JumpGe(Register, Offset) = 0x11,
|
||||
JumpLt(Register, Offset) = 0x12,
|
||||
JumpLe(Register, Offset) = 0x13,
|
||||
Jump(ITypeArgs) = 0xD,
|
||||
JumpEq(ITypeArgs) = 0xE,
|
||||
JumpNeq(ITypeArgs) = 0xF,
|
||||
JumpGt(ITypeArgs) = 0x10,
|
||||
JumpGe(ITypeArgs) = 0x11,
|
||||
JumpLt(ITypeArgs) = 0x12,
|
||||
JumpLe(ITypeArgs) = 0x13,
|
||||
|
||||
// Comparison
|
||||
Compare(Register, Register) = 0x14,
|
||||
Compare(RTypeArgs) = 0x14,
|
||||
|
||||
// Arithmetic
|
||||
Add(Register, Register, Register) = 0x19,
|
||||
Sub(Register, Register, Register) = 0x1A,
|
||||
Increment(Register) = 0x15,
|
||||
Decrement(Register) = 0x16,
|
||||
ShiftLeft(Register, Register, Immediate) = 0x17,
|
||||
ShiftRight(Register, Register, Immediate) = 0x18,
|
||||
Add(RTypeArgs) = 0x19,
|
||||
Sub(RTypeArgs) = 0x1A,
|
||||
Increment(RTypeArgs) = 0x15,
|
||||
Decrement(RTypeArgs) = 0x16,
|
||||
ShiftLeft(RTypeArgs) = 0x17,
|
||||
ShiftRight(RTypeArgs) = 0x18,
|
||||
|
||||
// Logical
|
||||
And(Register, Register, Register) = 0x1B,
|
||||
Or(Register, Register, Register) = 0x1C,
|
||||
Not(Register, Register) = 0x1D,
|
||||
Xor(Register, Register, Register) = 0x1E,
|
||||
Nand(Register, Register, Register) = 0x1F,
|
||||
Nor(Register, Register, Register) = 0x20,
|
||||
Xnor(Register, Register, Register) = 0x21,
|
||||
And(RTypeArgs) = 0x1B,
|
||||
Or(RTypeArgs) = 0x1C,
|
||||
Not(RTypeArgs) = 0x1D,
|
||||
Xor(RTypeArgs) = 0x1E,
|
||||
Nand(RTypeArgs) = 0x1F,
|
||||
Nor(RTypeArgs) = 0x20,
|
||||
Xnor(RTypeArgs) = 0x21,
|
||||
|
||||
// Misc
|
||||
Interrupt(Interrupt) = 0x22,
|
||||
@@ -290,46 +312,57 @@ impl Instruction {
|
||||
impl std::fmt::Display for Instruction {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::Nop => write!(f, "No Operation"),
|
||||
Self::Mov(a, b) => write!(f, "MOV {a}, {b}"),
|
||||
Self::MovSigned(a, b) => write!(f, "MOVS {a}, {b}"),
|
||||
Self::LoadByte(a, b, c) => write!(f, "LDB {a}, {b}, {c}"),
|
||||
Self::LoadByteSigned(a, b, c) => write!(f, "LDBS {a}, {b}, {c}"),
|
||||
Self::LoadHalfword(a, b, c) => write!(f, "LDH {a}, {b}, {c}"),
|
||||
Self::LoadHalfwordSigned(a, b, c) => write!(f, "LDHS {a}, {b}, {c}"),
|
||||
Self::LoadWord(a, b, c) => write!(f, "LDW {a}, {b}, {c}"),
|
||||
Self::Nop => write!(f, "NOP"),
|
||||
Self::Mov(args) => write!(f, "MOV {}, {}", args.sr1, args.dr),
|
||||
Self::MovSigned(args) => write!(f, "MOVS {}, {}", args.sr1, args.dr),
|
||||
Self::LoadByte(args) => write!(f, "LDB {:x}({}), {}", args.immediate, args.r1, args.r2),
|
||||
Self::LoadByteSigned(args) => {
|
||||
write!(f, "LDBS {:x}({}), {}", args.immediate, args.r1, args.r2)
|
||||
}
|
||||
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::StoreHalfword(a, b, c) => write!(f, "STH {a}, {b}, {c}"),
|
||||
Self::StoreWord(a, b, c) => write!(f, "STW {a}, {b}, {c}"),
|
||||
Self::LoadLowerImmediate(args) => write!(f, "LLI {}, {}", args.r1, args.r2),
|
||||
Self::LoadUpperImmediate(args) => write!(f, "LUI {}, {}", args.r1, args.r2),
|
||||
|
||||
Self::LoadLowerImmediate(a, b) => write!(f, "LLI {a}, {b}"),
|
||||
Self::LoadUpperImmediate(a, b) => write!(f, "LUI {a}, {b}"),
|
||||
Self::Jump(args) => write!(f, "JMP ({:x}){}", args.immediate, args.r1),
|
||||
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::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(args) => write!(f, "CMP {}, {}", args.sr1, args.sr2),
|
||||
|
||||
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::Sub(a, b, c) => write!(f, "SUB {a}, {b}, {c}"),
|
||||
Self::Increment(a) => write!(f, "INC {a}"),
|
||||
Self::Decrement(a) => write!(f, "DEC {a}"),
|
||||
Self::ShiftLeft(a, b, c) => write!(f, "SHL {a}, {b}, {c}"),
|
||||
Self::ShiftRight(a, b, c) => write!(f, "SHR {a}, {b}, {c}"),
|
||||
|
||||
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::And(args) => write!(f, "AND {}, {}, {}", args.sr1, args.sr2, args.dr),
|
||||
Self::Or(args) => write!(f, "OR {}, {}, {}", args.sr1, args.sr2, args.dr),
|
||||
Self::Not(args) => write!(f, "NOT {}, {}", args.sr1, args.sr2),
|
||||
Self::Xor(args) => write!(f, "XOR {}, {}, {}", args.sr1, args.sr2, args.dr),
|
||||
Self::Nand(args) => write!(f, "NAND {}, {}, {}", args.sr1, args.sr2, args.dr),
|
||||
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::Interrupt(a) => write!(f, "INT {}", a.as_u8()),
|
||||
Self::IntReturn => write!(f, "INTR"),
|
||||
|
||||
Reference in New Issue
Block a user