mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-06-09 23:08:18 +02:00
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:
parent
ac4d8d31ab
commit
d5a92e5322
3 changed files with 70 additions and 5 deletions
|
|
@ -42,6 +42,7 @@ pub enum DataType {
|
|||
None,
|
||||
F16,
|
||||
F32,
|
||||
F64,
|
||||
I8,
|
||||
I16,
|
||||
I24,
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue