diff options
| author | taitep <taitep@taitep.se> | 2025-12-26 16:06:30 +0100 |
|---|---|---|
| committer | taitep <taitep@taitep.se> | 2025-12-26 16:06:30 +0100 |
| commit | 75e843f5f9220e1de4dde34d70e5077e092b5016 (patch) | |
| tree | b9a3b0563018f81440dda554f0bf745f6a3b796a /src | |
| parent | 528b519ce98c21049705526442cbde1672495b49 (diff) | |
Make branches macros and implement all of them
Diffstat (limited to 'src')
| -rw-r--r-- | src/instructions.rs | 1 | ||||
| -rw-r--r-- | src/instructions/rvi.rs | 75 |
2 files changed, 27 insertions, 49 deletions
diff --git a/src/instructions.rs b/src/instructions.rs index 5e3f39c..c7af5ec 100644 --- a/src/instructions.rs +++ b/src/instructions.rs @@ -69,6 +69,7 @@ pub(crate) fn find_and_exec(instr: Instruction, core: &mut Core) -> Result<(), E 0b000 => rvi::beq(core, instr), 0b001 => rvi::bne(core, instr), 0b100 => rvi::blt(core, instr), + 0b101 => rvi::bge(core, instr), 0b110 => rvi::bltu(core, instr), 0b111 => rvi::bgeu(core, instr), _ => Err(IllegalInstruction), diff --git a/src/instructions/rvi.rs b/src/instructions/rvi.rs index d8439fa..a348596 100644 --- a/src/instructions/rvi.rs +++ b/src/instructions/rvi.rs @@ -106,52 +106,29 @@ pub fn jalr(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { Ok(()) } -pub fn beq(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { - if core.reg_read(instr.rs1()) == core.reg_read(instr.rs2()) { - core.pc = core.pc.wrapping_add(instr.imm_b()); - } else { - core.advance_pc(); - } - - Ok(()) -} - -pub fn bne(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { - if core.reg_read(instr.rs1()) != core.reg_read(instr.rs2()) { - core.pc = core.pc.wrapping_add(instr.imm_b()); - } else { - core.advance_pc(); - } - - Ok(()) -} - -pub fn blt(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { - if (core.reg_read(instr.rs1()) as i64) < (core.reg_read(instr.rs2()) as i64) { - core.pc = core.pc.wrapping_add(instr.imm_b()); - } else { - core.advance_pc(); - } - - Ok(()) -} - -pub fn bgeu(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { - if core.reg_read(instr.rs1()) >= core.reg_read(instr.rs2()) { - core.pc = core.pc.wrapping_add(instr.imm_b()); - } else { - core.advance_pc(); - } - - Ok(()) -} - -pub fn bltu(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { - if core.reg_read(instr.rs1()) < core.reg_read(instr.rs2()) { - core.pc = core.pc.wrapping_add(instr.imm_b()); - } else { - core.advance_pc(); - } - - Ok(()) -} +macro_rules! instr_branch { + ($name:ident, $cond:expr) => { + pub fn $name(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { + let a = core.reg_read(instr.rs1()); + let b = core.reg_read(instr.rs2()); + if $cond(a, b) { + core.pc = core.pc.wrapping_add(instr.imm_b()); + } else { + core.advance_pc(); + } + Ok(()) + } + }; +} +macro_rules! instr_branch_signed { + ($name:ident, $cond:expr) => { + instr_branch!($name, |a, b| $cond((a as i64), (b as i64))); + }; +} + +instr_branch!(beq, |a, b| a == b); +instr_branch!(bne, |a, b| a != b); +instr_branch!(bltu, |a, b| a < b); +instr_branch!(bgeu, |a, b| a >= b); +instr_branch_signed!(blt, |a, b| a < b); +instr_branch_signed!(bge, |a, b| a >= b); |
