diff --git a/src/panfrost/compiler/kraid/proc/isa/mod.rs b/src/panfrost/compiler/kraid/proc/isa/mod.rs index 1ce61ecae84..57812bb129b 100644 --- a/src/panfrost/compiler/kraid/proc/isa/mod.rs +++ b/src/panfrost/compiler/kraid/proc/isa/mod.rs @@ -2,10 +2,12 @@ // SPDX-License-Identifier: MIT pub mod encoder; +mod xml; use proc_macro2::TokenStream as TokenStream2; use quote::ToTokens; use std::ops::Range; +use xml::XmlElement; #[macro_export] macro_rules! ident { @@ -163,7 +165,13 @@ pub struct ISA { } impl ISA { - pub fn from_xml_file(file: std::fs::File, arch: Range) -> Result { + fn from_xml(xml: XmlElement, arch: Range) -> Result { + assert_eq!(xml.name.local_name, "mali-isa"); + Ok(ISA { arch }) } + + pub fn from_xml_file(file: std::fs::File, arch: Range) -> Result { + ISA::from_xml(xml::XmlElement::from_xml_file(file)?, arch) + } } diff --git a/src/panfrost/compiler/kraid/proc/isa/xml.rs b/src/panfrost/compiler/kraid/proc/isa/xml.rs new file mode 100644 index 00000000000..ff54ca104b9 --- /dev/null +++ b/src/panfrost/compiler/kraid/proc/isa/xml.rs @@ -0,0 +1,94 @@ +// Copyright © 2026 Collabora, Ltd. +// SPDX-License-Identifier: MIT + +use std::collections::HashMap; +use std::ops::Range; +use xml::attribute::OwnedAttribute; +use xml::name::OwnedName; +use xml::reader::{EventReader, XmlEvent}; + +/// A very simpl DOM +pub struct XmlElement { + pub name: OwnedName, + pub attrs: HashMap, + pub children: Vec, +} + +impl XmlElement { + fn from_xml_event( + name: OwnedName, + attributes: Vec, + events: &mut impl Iterator>, + ) -> xml::reader::Result { + let mut elem = XmlElement { + name, + attrs: attributes + .into_iter() + .map(|a| (a.name.local_name, a.value)) + .collect(), + children: Default::default(), + }; + + while let Some(event) = events.next() { + match event? { + XmlEvent::StartElement { + name, attributes, .. + } => { + elem.children.push(XmlElement::from_xml_event( + name, attributes, events, + )?); + } + XmlEvent::EndElement { .. } => return Ok(elem), + _ => (), + } + } + + Err(xml::reader::ErrorKind::UnexpectedEof.into()) + } + + pub fn from_xml_file( + file: std::fs::File, + ) -> xml::reader::Result { + // Buffering is important for performance + let file = std::io::BufReader::new(file); + let mut events = EventReader::new(file).into_iter(); + + while let Some(event) = events.next() { + match event? { + XmlEvent::StartElement { + name, attributes, .. + } => { + return XmlElement::from_xml_event( + name, + attributes, + &mut events, + ) + } + _ => (), + } + } + + Err(xml::reader::ErrorKind::UnexpectedEof.into()) + } + + pub fn get_u8_attr(&self, name: &str) -> Option { + let s = self.attrs.get(name)?; + let u = u8::from_str_radix(s, 10).unwrap(); + Some(u) + } + + pub fn get_bool_attr(&self, name: &str) -> Option { + self.get_u8_attr(name).map(|u| u != 0) + } + + pub fn get_arch(&self, all_arch: Range) -> Range { + let mut range = all_arch; + if let Some(since) = self.get_u8_attr("since") { + range.start = range.start.max(since); + } + if let Some(until) = self.get_u8_attr("until") { + range.end = range.end.min(until + 1); + } + range + } +}