use crate::abi::Abi;
use crate::register_descriptors::RegisterDescriptor;
use crate::registers_meta::IntRegisterConversionError;
use super::RegisterIterator;
pub trait Register: PartialEq + PartialOrd + Default {
#[must_use]
fn as_index(&self) -> usize;
#[must_use]
fn count() -> usize;
#[must_use]
fn iter() -> RegisterIterator<Self> {
RegisterIterator::new()
}
fn try_from_u32(value: u32) -> Result<Self, IntRegisterConversionError>;
#[must_use]
fn descriptor_array() -> &'static [RegisterDescriptor];
#[must_use]
fn get_descriptor(&self) -> &'static RegisterDescriptor {
&Self::descriptor_array()[self.as_index()]
}
#[must_use]
fn name_numeric(&self) -> &'static str {
self.get_descriptor().name_numeric()
}
#[must_use]
fn name_abi(&self, abi: Abi, strip_dollar: bool) -> &'static str {
self.get_descriptor().name_abi(abi, strip_dollar)
}
#[must_use]
fn either_name(&self, abi: Abi, use_named: bool, strip_dollar: bool) -> &'static str {
if use_named {
self.name_abi(abi, strip_dollar)
} else {
self.name_numeric()
}
}
#[must_use]
fn is_clobbered_by_func_call(&self, _abi: Abi) -> bool {
self.get_descriptor().is_clobbered_by_func_call()
}
#[must_use]
fn is_reserved(&self, _abi: Abi) -> bool {
self.get_descriptor().is_reserved()
}
#[must_use]
fn is_kernel(&self, _abi: Abi) -> bool {
self.get_descriptor().is_kernel()
}
#[must_use]
fn is_zero(&self, _abi: Abi) -> bool {
self.get_descriptor().is_zero()
}
#[must_use]
fn is_assembler_temp(&self, _abi: Abi) -> bool {
self.get_descriptor().is_assembler_temp()
}
#[must_use]
fn holds_return_value(&self, _abi: Abi) -> bool {
self.get_descriptor().holds_return_value()
}
#[must_use]
fn holds_return_address(&self, _abi: Abi) -> bool {
self.get_descriptor().holds_return_address()
}
#[must_use]
fn is_stack_pointer(&self, _abi: Abi) -> bool {
self.get_descriptor().is_stack_pointer()
}
#[must_use]
fn is_global_pointer(&self, _abi: Abi) -> bool {
self.get_descriptor().is_global_pointer()
}
#[must_use]
fn is_saved(&self, _abi: Abi) -> bool {
self.get_descriptor().is_saved()
}
#[must_use]
fn is_temp(&self, _abi: Abi) -> bool {
self.get_descriptor().is_temp()
}
#[must_use]
fn is_arg(&self, _abi: Abi) -> bool {
self.get_descriptor().is_arg()
}
#[must_use]
#[cfg(feature = "encoder")]
#[cfg_attr(docsrs, doc(cfg(feature = "encoder")))]
fn from_name(name: &str, abi: Abi, allow_dollarless: bool) -> Option<Self> {
let allow_dollarless = allow_dollarless && !name.starts_with('$');
for descriptor in Self::descriptor_array() {
let found = descriptor.name_abi(abi, false) == name
|| (allow_dollarless && descriptor.name_abi(abi, true) == name)
|| descriptor.name_numeric() == name;
if found {
let reg_value = descriptor.value().into();
let reg = Self::try_from_u32(reg_value).expect("The value returned by the descriptor should always be a valid value for the try_from_u32 method");
return Some(reg);
}
}
None
}
}
#[cfg(feature = "R4000ALLEGREX")]
pub(crate) trait R4000AllegrexVectorRegister: Register {}