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/macros.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/macros.rs')
| -rw-r--r-- | src/instructions/macros.rs | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/src/instructions/macros.rs b/src/instructions/macros.rs new file mode 100644 index 0000000..c88114c --- /dev/null +++ b/src/instructions/macros.rs @@ -0,0 +1,64 @@ +// Copyright (c) 2025 taitep +// SPDX-License-Identifier: MIT +// +// This file is part of TRVE (https://gitea.taitep.se/taitep/trve) +// See LICENSE file in the project root for full license text. + +#[macro_export] +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_export] +macro_rules! instr_branch_signed { + ($name:ident, $cond:expr) => { + instr_branch!($name, |a, b| $cond((a as i64), (b as i64))); + }; +} + +#[macro_export] +macro_rules! instr_op_r { + ($name:ident, $op: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()); + let res = $op(a, b); + core.reg_write(instr.rd(), res); + core.advance_pc(); + Ok(()) + } + }; +} + +#[macro_export] +macro_rules! instr_op_i { + ($name:ident, $op:expr) => { + pub fn $name(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { + let a = core.reg_read(instr.rs1()); + let b = instr.imm_i(); + let res = $op(a, b); + core.reg_write(instr.rd(), res); + core.advance_pc(); + Ok(()) + } + }; +} + +#[macro_export] +macro_rules! instr_op { + ($name:ident, $name_imm:ident, $op:expr) => { + instr_op_r!($name, $op); + instr_op_i!($name_imm, $op); + }; +} |
