kraid/isa: Emit TryFrom<DataType> for all data-type-like enums

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/41841>
This commit is contained in:
Faith Ekstrand 2026-05-28 17:20:28 -04:00 committed by Marge Bot
parent ac4d8d31ab
commit d5a92e5322
3 changed files with 70 additions and 5 deletions

View file

@ -42,6 +42,7 @@ pub enum DataType {
None,
F16,
F32,
F64,
I8,
I16,
I24,

View file

@ -832,12 +832,22 @@ impl ToTokens for InstrEnc {
let mut v_idents = Vec::new();
if let Some(ve_ident) = &self.srcs.variants {
let mut vars_ts = TokenStream2::new();
let mut is_data_type = true;
let mut dt_cases_ts = TokenStream2::new();
for v_name in self.variants.keys() {
let v_camel_name = to_camel_case(v_name.as_ref().unwrap());
let v_ident = Ident::new(&v_camel_name, Span::call_site());
vars_ts.extend(quote! {
#v_ident,
});
if v_name.as_ref().is_some_and(|s| is_data_type_name(s)) {
dt_cases_ts.extend(quote! {
DataType::#v_ident => Ok(#ve_ident::#v_ident),
});
} else {
is_data_type = false;
}
v_idents.push(v_ident);
}
@ -847,6 +857,23 @@ impl ToTokens for InstrEnc {
#vars_ts
}
});
if is_data_type {
let err = format!("Unsupported {} variant", self.name);
ts.extend(quote! {
impl TryFrom<DataType> for #ve_ident {
type Error = &'static str;
fn try_from(
dt: DataType
) -> Result<#ve_ident, &'static str> {
match dt {
#dt_cases_ts
_ => Err(#err),
}
}
}
});
}
assert_eq!(v_idents.len(), self.variants.len());
} else {
assert_eq!(self.variants.len(), 1);
@ -1013,6 +1040,7 @@ pub fn gen_encoder(
let mut ts = quote! {
use crate::isa::*;
use crate::bitview::*;
use crate::data_type::DataType;
use compiler::bitset::ConstBitSet;
pub type EncodedSrc = super::EncodedSrc<SrcSwizzle>;
@ -1059,7 +1087,7 @@ pub fn gen_encoder(
)
.expect("Failed to create sample_position meta-enum");
isa.enums.declare(&mut ts);
isa.enums.declare(&mut ts, true);
let mut instrs: BTreeMap<_, InstrEnc> = Default::default();
for i in isa.instrs {

View file

@ -57,6 +57,7 @@ pub struct Enum {
pub arch: ArchSet,
pub has_none: bool,
pub is_bool: bool,
pub is_data_type: bool,
pub values: BTreeMap<String, EnumValue>,
meta: OnceCell<String>,
}
@ -77,12 +78,19 @@ impl Enum {
let camel_name = to_camel_case(&name);
let ident = Ident::new(&camel_name, Span::call_site());
// ls_multi_sr_count_m looks like a data type enum but isn't one.
// Or at least, our data type enum doesn't have enough integer types
// to satisfy it.
let may_be_data_type =
xml.children.len() > 0 && name != "ls_multi_sr_count_m";
let mut e = Enum {
name,
ident,
arch: xml.get_arch(arch.clone()).into(),
has_none: false,
is_bool: xml.children.len() == 2,
is_data_type: may_be_data_type,
values: Default::default(),
meta: Default::default(),
};
@ -100,6 +108,10 @@ impl Enum {
e.is_bool = false;
}
if !is_data_type_name(v.name.as_str()) {
e.is_data_type = false;
}
if !v.arch.is_empty() {
e.values.insert(v.name.clone(), v);
}
@ -113,6 +125,7 @@ impl Enum {
self.arch |= other.arch;
self.has_none |= other.has_none;
self.is_bool &= other.is_bool;
self.is_data_type &= other.is_data_type;
for (name, value) in other.values.into_iter() {
use btree_map::Entry;
@ -127,7 +140,7 @@ impl Enum {
}
}
pub fn declare(&self, ts: &mut TokenStream2) {
pub fn declare(&self, ts: &mut TokenStream2, data_type_casts: bool) {
let mut unique_values = true;
let mut all_same_arch = true;
let mut max_value = 0_u8;
@ -223,6 +236,30 @@ impl Enum {
});
}
let err = format!("Unsupported {e_ident}");
if self.is_data_type && data_type_casts {
let mut cases_ts = TokenStream2::new();
for EnumValue { ident, .. } in self.values.values() {
cases_ts.extend(quote! {
DataType::#ident => Ok(#e_ident::#ident),
});
}
ts.extend(quote! {
impl TryFrom<DataType> for #e_ident {
type Error = &'static str;
fn try_from(
dt: DataType
) -> Result<#e_ident, &'static str> {
match dt {
#cases_ts
_ => Err(#err),
}
}
}
});
}
if self.name == "ls_multi_sr_count_m" {
let mut sr_cases_ts = TokenStream2::new();
for EnumValue { ident, name, .. } in self.values.values() {
@ -329,7 +366,6 @@ impl Enum {
// Implement [Try]Encode
let err = format!("Unsupported {e_ident}");
if all_same_arch {
let encode_impl = if unique_values {
quote! {
@ -685,9 +721,9 @@ impl EnumSet {
Ok(())
}
pub fn declare(&self, ts: &mut TokenStream2) {
pub fn declare(&self, ts: &mut TokenStream2, data_type_casts: bool) {
for e in self.enums.values() {
e.declare(ts);
e.declare(ts, data_type_casts);
}
for me in self.meta_enums.values() {