// Copyright (C) 2024 Intel Corporation.
// Author(s): Zhao Liu <zhao1.liu@intel.com>
// SPDX-License-Identifier: GPL-2.0-or-later

//! This module provides bit operation extensions to integer types.
//! It is usually included via the `qemu_api` prelude.

use std::ops::{
    Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, DivAssign,
    Mul, MulAssign, Not, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign,
};

/// Trait for extensions to integer types
pub trait IntegerExt:
    Add<Self, Output = Self> + AddAssign<Self> +
    BitAnd<Self, Output = Self> + BitAndAssign<Self> +
    BitOr<Self, Output = Self> + BitOrAssign<Self> +
    BitXor<Self, Output = Self> + BitXorAssign<Self> +
    Copy +
    Div<Self, Output = Self> + DivAssign<Self> +
    Eq +
    Mul<Self, Output = Self> + MulAssign<Self> +
    Not<Output = Self> + Ord + PartialOrd +
    Rem<Self, Output = Self> + RemAssign<Self> +
    Shl<Self, Output = Self> + ShlAssign<Self> +
    Shl<u32, Output = Self> + ShlAssign<u32> + // add more as needed
    Shr<Self, Output = Self> + ShrAssign<Self> +
    Shr<u32, Output = Self> + ShrAssign<u32> // add more as needed
{
    const BITS: u32;
    const MAX: Self;
    const MIN: Self;
    const ONE: Self;
    const ZERO: Self;

    #[inline]
    #[must_use]
    fn bit(start: u32) -> Self
    {
        debug_assert!(start < Self::BITS);

        Self::ONE << start
    }

    #[inline]
    #[must_use]
    fn mask(start: u32, length: u32) -> Self
    {
        /* FIXME: Implement a more elegant check with error handling support? */
        debug_assert!(start < Self::BITS && length > 0 && length <= Self::BITS - start);

        (Self::MAX >> (Self::BITS - length)) << start
    }

    #[inline]
    #[must_use]
    fn deposit<U: IntegerExt>(self, start: u32, length: u32,
                          fieldval: U) -> Self
        where Self: From<U>
    {
        debug_assert!(length <= U::BITS);

        let mask = Self::mask(start, length);
        (self & !mask) | ((Self::from(fieldval) << start) & mask)
    }

    #[inline]
    #[must_use]
    fn extract(self, start: u32, length: u32) -> Self
    {
        let mask = Self::mask(start, length);
        (self & mask) >> start
    }
}

macro_rules! impl_num_ext {
    ($type:ty) => {
        impl IntegerExt for $type {
            const BITS: u32 = <$type>::BITS;
            const MAX: Self = <$type>::MAX;
            const MIN: Self = <$type>::MIN;
            const ONE: Self = 1;
            const ZERO: Self = 0;
        }
    };
}

impl_num_ext!(u8);
impl_num_ext!(u16);
impl_num_ext!(u32);
impl_num_ext!(u64);

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_deposit() {
        assert_eq!(15u32.deposit(8, 8, 1u32), 256 + 15);
        assert_eq!(15u32.deposit(8, 1, 255u8), 256 + 15);
    }

    #[test]
    fn test_extract() {
        assert_eq!(15u32.extract(2, 4), 3);
    }

    #[test]
    fn test_bit() {
        assert_eq!(u8::bit(7), 128);
        assert_eq!(u32::bit(16), 0x10000);
    }

    #[test]
    fn test_mask() {
        assert_eq!(u8::mask(7, 1), 128);
        assert_eq!(u32::mask(8, 8), 0xff00);
    }
}
