diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 03:57:31 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 03:57:31 +0000 |
commit | dc0db358abe19481e475e10c32149b53370f1a1c (patch) | |
tree | ab8ce99c4b255ce46f99ef402c27916055b899ee /library/stdarch/crates/intrinsic-test/src/json_parser.rs | |
parent | Releasing progress-linux version 1.71.1+dfsg1-2~progress7.99u1. (diff) | |
download | rustc-dc0db358abe19481e475e10c32149b53370f1a1c.tar.xz rustc-dc0db358abe19481e475e10c32149b53370f1a1c.zip |
Merging upstream version 1.72.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'library/stdarch/crates/intrinsic-test/src/json_parser.rs')
-rw-r--r-- | library/stdarch/crates/intrinsic-test/src/json_parser.rs | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/library/stdarch/crates/intrinsic-test/src/json_parser.rs b/library/stdarch/crates/intrinsic-test/src/json_parser.rs new file mode 100644 index 000000000..bc6fa4a9e --- /dev/null +++ b/library/stdarch/crates/intrinsic-test/src/json_parser.rs @@ -0,0 +1,97 @@ +use std::collections::HashMap; + +use serde::Deserialize; + +use crate::argument::{Argument, ArgumentList}; +use crate::intrinsic::Intrinsic; +use crate::types::IntrinsicType; + +#[derive(Deserialize, Debug)] +#[serde(deny_unknown_fields)] +struct ReturnType { + value: String, +} + +#[derive(Deserialize, Debug)] +#[serde(untagged, deny_unknown_fields)] +pub enum ArgPrep { + Register { + #[serde(rename = "register")] + reg: String, + }, + Immediate { + #[serde(rename = "minimum")] + min: i64, + #[serde(rename = "maximum")] + max: i64, + }, + Nothing {}, +} + +#[derive(Deserialize, Debug)] +struct JsonIntrinsic { + #[serde(rename = "SIMD_ISA")] + simd_isa: String, + name: String, + arguments: Vec<String>, + return_type: ReturnType, + #[serde(rename = "Arguments_Preparation")] + args_prep: Option<HashMap<String, ArgPrep>>, + #[serde(rename = "Architectures")] + architectures: Vec<String>, +} + +pub fn get_neon_intrinsics(filename: &str) -> Result<Vec<Intrinsic>, Box<dyn std::error::Error>> { + let file = std::fs::File::open(filename)?; + let reader = std::io::BufReader::new(file); + let json: Vec<JsonIntrinsic> = serde_json::from_reader(reader).expect("Couldn't parse JSON"); + + let parsed = json + .into_iter() + .filter_map(|intr| { + if intr.simd_isa == "Neon" { + Some(json_to_intrinsic(intr).expect("Couldn't parse JSON")) + } else { + None + } + }) + .collect(); + Ok(parsed) +} + +fn json_to_intrinsic(mut intr: JsonIntrinsic) -> Result<Intrinsic, Box<dyn std::error::Error>> { + let name = intr.name.replace(['[', ']'], ""); + + let results = IntrinsicType::from_c(&intr.return_type.value)?; + + let mut args_prep = intr.args_prep.as_mut(); + let args = intr + .arguments + .into_iter() + .enumerate() + .map(|(i, arg)| { + let arg_name = Argument::type_and_name_from_c(&arg).1; + let arg_prep = args_prep.as_mut().and_then(|a| a.remove(arg_name)); + let mut arg = Argument::from_c(i, &arg, arg_prep); + // The JSON doesn't list immediates as const + if let IntrinsicType::Type { + ref mut constant, .. + } = arg.ty + { + if arg.name.starts_with("imm") { + *constant = true + } + } + arg + }) + .collect(); + + let arguments = ArgumentList { args }; + + Ok(Intrinsic { + name, + arguments, + results, + a64_only: intr.architectures == vec!["A64".to_string()], + }) +} |