rvsim-core 2.0.0

A cycle-level RISC-V 64-bit system simulator.
//! Arithmetic Logic Unit (ALU).
//!
//! This module implements the integer ALU used in the Execute stage.
//! It handles standard arithmetic, logical operations, and shifts
//! for both 32-bit and 64-bit operands. It also implements the
//! Multiply/Divide (M) and Bit-Manipulation (B) extension operations.
//!
//! Operations are organized into submodules by category:
//! - [`arithmetic`]: Add, Sub, Mul, Mulh, Mulhsu, Mulhu, Div, Divu, Rem, Remu
//! - [`logic`]:      Or, And, Xor, Slt, Sltu
//! - [`shifts`]:     Sll, Srl, Sra
//! - [`bitmanip`]:   Zba (address gen), Zbb (basic bitmanip), Zbc (clmul), Zbs (single-bit)

pub mod arithmetic;

pub mod bitmanip;

pub mod logic;

pub mod shifts;

use crate::isa::op::AluOp;

/// Executes an integer ALU operation.
///
/// Dispatches to the appropriate submodule based on the operation type.
/// Supports both 32-bit and 64-bit operations based on the `is32` flag.
///
/// # Arguments
///
/// * `op`   - The ALU operation to perform
/// * `a`    - First operand (64-bit value)
/// * `b`    - Second operand (64-bit value, also used as shift amount)
/// * `_c`   - Third operand (currently unused, reserved for future use)
/// * `is32` - If true, perform 32-bit operation (RV32 mode)
///
/// # Returns
///
/// The 64-bit result of the ALU operation. For 32-bit operations,
/// the result is sign-extended to 64 bits.
pub const fn execute(op: AluOp, a: u64, b: u64, _c: u64, is32: bool) -> u64 {
    match op {
        AluOp::Add
        | AluOp::Sub
        | AluOp::Mul
        | AluOp::Mulh
        | AluOp::Mulhsu
        | AluOp::Mulhu
        | AluOp::Div
        | AluOp::Divu
        | AluOp::Rem
        | AluOp::Remu => arithmetic::execute(op, a, b, is32),

        AluOp::Or | AluOp::And | AluOp::Xor | AluOp::Slt | AluOp::Sltu => {
            logic::execute(op, a, b, is32)
        }

        AluOp::Sll | AluOp::Srl | AluOp::Sra => shifts::execute(op, a, b, is32),

        AluOp::Sh1Add
        | AluOp::Sh2Add
        | AluOp::Sh3Add
        | AluOp::AddUw
        | AluOp::Sh1AddUw
        | AluOp::Sh2AddUw
        | AluOp::Sh3AddUw
        | AluOp::SlliUw
        | AluOp::Andn
        | AluOp::Orn
        | AluOp::Xnor
        | AluOp::Clz
        | AluOp::Ctz
        | AluOp::Cpop
        | AluOp::Max
        | AluOp::Maxu
        | AluOp::Min
        | AluOp::Minu
        | AluOp::SextB
        | AluOp::SextH
        | AluOp::Rol
        | AluOp::Ror
        | AluOp::OrcB
        | AluOp::Rev8
        | AluOp::Clmul
        | AluOp::Clmulh
        | AluOp::Clmulr
        | AluOp::Bclr
        | AluOp::Bext
        | AluOp::Binv
        | AluOp::Bset
        | AluOp::Brev8
        | AluOp::Pack
        | AluOp::Packh
        | AluOp::Packw
        | AluOp::Xperm4
        | AluOp::Xperm8 => bitmanip::execute(op, a, b, is32),

        _ => 0,
    }
}