diff options
| author | taitep <taitep@taitep.se> | 2025-12-26 18:14:32 +0100 |
|---|---|---|
| committer | taitep <taitep@taitep.se> | 2025-12-26 18:14:32 +0100 |
| commit | 34034dd5db07f71b0854de0f2bbb18e39aa3db69 (patch) | |
| tree | ea588631e7d88874e784c5d144505d1ba987e2cf /src/instructions/rvi.rs | |
| parent | 75e843f5f9220e1de4dde34d70e5077e092b5016 (diff) | |
Make macros for R/I-type operations and use them to implement basically every single one i think
Diffstat (limited to 'src/instructions/rvi.rs')
| -rw-r--r-- | src/instructions/rvi.rs | 131 |
1 files changed, 39 insertions, 92 deletions
diff --git a/src/instructions/rvi.rs b/src/instructions/rvi.rs index a348596..c35098f 100644 --- a/src/instructions/rvi.rs +++ b/src/instructions/rvi.rs @@ -4,83 +4,50 @@ // This file is part of TRVE (https://gitea.taitep.se/taitep/trve) // See LICENSE file in the project root for full license text. -use crate::{core::Core, decode::Instruction, exceptions::ExceptionType}; +use crate::{consts::RegValue, core::Core, decode::Instruction, exceptions::ExceptionType}; + +use std::ops::{BitAnd, BitOr, BitXor}; mod mem; pub use mem::*; -pub fn add(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { - core.reg_write( - instr.rd(), - core.reg_read(instr.rs1()) - .wrapping_add(core.reg_read(instr.rs2())), - ); - core.advance_pc(); - Ok(()) -} - -pub fn sub(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { - core.reg_write( - instr.rd(), - core.reg_read(instr.rs1()) - .wrapping_sub(core.reg_read(instr.rs2())), - ); - core.advance_pc(); - Ok(()) -} - -pub fn addi(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { - core.reg_write( - instr.rd(), - core.reg_read(instr.rs1()).wrapping_add(instr.imm_i()), - ); - core.advance_pc(); - Ok(()) -} - -pub fn addiw(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { - let res = core.reg_read(instr.rs1()).wrapping_add(instr.imm_i()) as i32; - core.reg_write(instr.rd(), res as i64 as u64); - core.advance_pc(); - Ok(()) -} - -pub fn and(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { - core.reg_write( - instr.rd(), - core.reg_read(instr.rs1()) & core.reg_read(instr.rs2()), - ); - core.advance_pc(); - Ok(()) -} - -pub fn andi(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { - core.reg_write(instr.rd(), core.reg_read(instr.rs1()) & instr.imm_i()); - core.advance_pc(); - Ok(()) -} - -pub fn or(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { - core.reg_write( - instr.rd(), - core.reg_read(instr.rs1()) | core.reg_read(instr.rs2()), - ); - core.advance_pc(); - Ok(()) -} - -pub fn slli(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { - core.reg_write(instr.rd(), core.reg_read(instr.rs1()) << instr.imm_shamt()); - core.advance_pc(); - Ok(()) -} - -pub fn srli(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { - core.reg_write(instr.rd(), core.reg_read(instr.rs1()) >> instr.imm_shamt()); - core.advance_pc(); - Ok(()) -} +instr_op!(add, addi, RegValue::wrapping_add); +instr_op!( + addw, + addiw, + |a, b| RegValue::wrapping_add(a, b) as i32 as i64 as RegValue +); +instr_op_r!(sub, RegValue::wrapping_sub); +instr_op_r!(subw, |a, b| RegValue::wrapping_sub(a, b) as i32 as i64 + as RegValue); + +instr_op!(and, andi, RegValue::bitand); +instr_op!(or, ori, RegValue::bitor); +instr_op!(xor, xori, RegValue::bitxor); + +instr_op!(sll, slli, |x, shamt| x << (shamt & 0b111111)); +instr_op!( + sllw, + slliw, + |x, shamt| (x << (shamt & 0b11111)) as i32 as i64 as RegValue +); +instr_op!(srl, srli, |x, shamt| x >> (shamt & 0b111111)); +instr_op!( + srlw, + srliw, + |x, shamt| (x >> (shamt & 0b11111)) as i32 as i64 as RegValue +); +instr_op!(sra, srai, |x, shamt| (x as i64 >> (shamt & 0b111111)) + as RegValue); +instr_op!( + sraw, + sraiw, + |x, shamt| (x as i32 >> (shamt & 0b11111)) as i64 as RegValue +); + +instr_op!(sltu, sltiu, |a, b| (a < b) as RegValue); +instr_op!(slt, slti, |a, b| ((a as i64) < (b as i64)) as RegValue); pub fn lui(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { core.reg_write(instr.rd(), instr.imm_u()); @@ -106,26 +73,6 @@ pub fn jalr(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { 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); |
