summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortaitep <taitep@taitep.se>2025-12-26 16:06:30 +0100
committertaitep <taitep@taitep.se>2025-12-26 16:06:30 +0100
commit75e843f5f9220e1de4dde34d70e5077e092b5016 (patch)
treeb9a3b0563018f81440dda554f0bf745f6a3b796a /src
parent528b519ce98c21049705526442cbde1672495b49 (diff)
Make branches macros and implement all of them
Diffstat (limited to 'src')
-rw-r--r--src/instructions.rs1
-rw-r--r--src/instructions/rvi.rs75
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);