common: start writing encoding routines (todo!)
This commit is contained in:
+51
-40
@@ -154,6 +154,8 @@ impl std::fmt::Display for Register {
|
||||
}
|
||||
}
|
||||
|
||||
/// TODO: Turn argument tuples into simple structs like `TwoReg`, `TwoRegAndOff`
|
||||
/// etc just to make code a little cleaner.
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[repr(u8)]
|
||||
pub enum Instruction {
|
||||
@@ -212,6 +214,7 @@ pub enum Instruction {
|
||||
Halt = 0x24,
|
||||
}
|
||||
|
||||
#[expect(clippy::missing_const_for_fn)]
|
||||
impl Instruction {
|
||||
/// Returns the opcode of an instruction.
|
||||
///
|
||||
@@ -226,48 +229,56 @@ impl Instruction {
|
||||
#[must_use]
|
||||
#[allow(unused)]
|
||||
pub fn encode(&self) -> u32 {
|
||||
match self {
|
||||
Self::Nop => todo!(),
|
||||
Self::Mov(src, dst) => todo!(),
|
||||
Self::MovSigned(register, register1) => todo!(),
|
||||
Self::LoadByte(register, _, register1) => todo!(),
|
||||
Self::LoadByteSigned(register, _, register1) => todo!(),
|
||||
Self::LoadHalfword(register, _, register1) => todo!(),
|
||||
Self::LoadHalfwordSigned(register, _, register1) => todo!(),
|
||||
Self::LoadWord(register, _, register1) => todo!(),
|
||||
Self::StoreByte(register, _, register1) => todo!(),
|
||||
Self::StoreHalfword(register, _, register1) => todo!(),
|
||||
Self::StoreWord(register, _, register1) => todo!(),
|
||||
Self::LoadLowerImmediate(register, _) => todo!(),
|
||||
Self::LoadUpperImmediate(register, _) => todo!(),
|
||||
Self::Jump(register, _) => todo!(),
|
||||
Self::JumpEq(register, _) => todo!(),
|
||||
Self::JumpNeq(register, _) => todo!(),
|
||||
Self::JumpGt(register, _) => todo!(),
|
||||
Self::JumpGe(register, _) => todo!(),
|
||||
Self::JumpLt(register, _) => todo!(),
|
||||
Self::JumpLe(register, _) => todo!(),
|
||||
Self::Compare(register, register1) => todo!(),
|
||||
Self::Add(register, register1, register2) => todo!(),
|
||||
Self::Sub(register, register1, register2) => todo!(),
|
||||
Self::Increment(register) => todo!(),
|
||||
Self::Decrement(register) => todo!(),
|
||||
Self::ShiftLeft(register, register1, _) => todo!(),
|
||||
Self::ShiftRight(register, register1, _) => todo!(),
|
||||
Self::And(register, register1, register2) => todo!(),
|
||||
Self::Or(register, register1, register2) => todo!(),
|
||||
Self::Not(register, register1) => todo!(),
|
||||
Self::Xor(register, register1, register2) => todo!(),
|
||||
Self::Nand(register, register1, register2) => todo!(),
|
||||
Self::Nor(register, register1, register2) => todo!(),
|
||||
Self::Xnor(register, register1, register2) => todo!(),
|
||||
Self::Interrupt(interrupt) => todo!(),
|
||||
Self::IntReturn => todo!(),
|
||||
Self::Halt => todo!(),
|
||||
}
|
||||
// match self {
|
||||
// _ => todo!(),
|
||||
// }
|
||||
|
||||
// Note to Harry, I will finish this encode/decode shit in a few hours.
|
||||
|
||||
21
|
||||
}
|
||||
|
||||
const fn _encode_mov() {}
|
||||
/// Encodes an R-type instruction from its fields. These must have unused high-order
|
||||
/// bits set to 0 else the bit shifting logic is fucked.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// - `shamt`: The amount to shift value (used only in shift instructions, otherwise 0).
|
||||
#[must_use]
|
||||
pub const fn encode_r_type(opcode: u8, sr1: u8, sr2: u8, dr: u8, shamt: u8) -> u32 {
|
||||
let opcode = opcode as u32;
|
||||
let sr1 = sr1 as u32;
|
||||
let sr2 = sr2 as u32;
|
||||
let dr = dr as u32;
|
||||
let shamt = shamt as u32;
|
||||
|
||||
(opcode << 26) | (sr1 << 21) | (sr2 << 16) | (dr << 11) | (shamt << 6)
|
||||
}
|
||||
|
||||
/// Encodes an I-type instruction from its fields. These must have some unused high-order
|
||||
/// bits set to 0 else the bit shifting logic gets fucked.
|
||||
#[must_use]
|
||||
pub const fn encode_i_type(opcode: u8, sr1: u8, dr: u8, immediate: u16) -> u32 {
|
||||
let opcode = opcode as u32;
|
||||
let sr1 = sr1 as u32;
|
||||
let dr = dr as u32;
|
||||
let immediate = immediate as u32;
|
||||
|
||||
(opcode << 26) | (sr1 << 21) | (dr << 16) | immediate
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
#[deprecated = "I am a little confused as to whether we keep these around for jumps."]
|
||||
/// Encodes a J-type instruction from its fields. These must have some unused high-order
|
||||
/// bits set to 0 else the bit shifting logic gets fucked.
|
||||
///
|
||||
/// Note: the address argument is passed as-is, caller is responsible for resolving this
|
||||
/// address properly.
|
||||
pub const fn _encode_j_type(opcode: u8, addr: u32) -> u32 {
|
||||
let opcode = opcode as u32;
|
||||
|
||||
(opcode << 26) | addr
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn decode(_data: u32) -> Self {
|
||||
|
||||
Reference in New Issue
Block a user