On 12/5/24 07:07, Zhao Liu wrote:
+pub fn deposit64(value: u64, start: usize, length: usize, fieldval: u64) -> u64 { + /* FIXME: Implement a more elegant check with error handling support? */ + assert!(length > 0 && length <= 64 - start); + + let mask = (u64::MAX >> (64 - length)) << start; + (value & !mask) | ((fieldval << start) & mask) +}
This should be more generic and implemented as a trait that is implemented by u8/u16/u32/u64. It's okay to rewrite these utility functions in Rust instead of relying on bindgen, because the way you'd like to use them is likely different from C. Something like: pub trait IntegerExt { fn deposit(self, start: u32, length: u32, fieldval: U) -> Self; } impl IntegerExt for u64 { fn deposit(self, start: usize, length: usize, fieldval: u64) -> u64 { /* FIXME: Implement a more elegant check with error handling support? */ assert!(length > 0 && length <= 64 - start); let mask = (u64::MAX >> (64 - length)) << start; (value & !mask) | ((fieldval << start) & mask) } } And we can add a "prelude" module so that you can do use qemu_api::prelude::*; and get all these useful traits at once. I will send a patch after fleshing the idea out a bit more. Paolo