diff options
| author | Madhav Madhusoodanan <f20200049@pilani.bits-pilani.ac.in> | 2025-03-25 13:32:33 +0400 |
|---|---|---|
| committer | Amanieu d'Antras <amanieu@gmail.com> | 2025-05-27 23:27:38 +0000 |
| commit | d7edb3ea7c9b813b8794e62a2c1c5078e881e1cb (patch) | |
| tree | 283c644b485a2bee83d6b03f4a6d1e7c45831e7f /library/stdarch/crates/intrinsic-test/src/arm/json_parser.rs | |
| parent | 08484b5e7a93181c49f4ce8654270dfa47dd6ebb (diff) | |
| download | rust-d7edb3ea7c9b813b8794e62a2c1c5078e881e1cb.tar.gz rust-d7edb3ea7c9b813b8794e62a2c1c5078e881e1cb.zip | |
Feat: Moved majority of the code to `arm` module.
Reasoning: 1. Majority of code assumes the usage of `Intrinsic` and related types, which is derived from the JSON structure of the ARM intrinsics JSON source file 2. Further commits will start with extracting common parts of the code (eg: Create C/Rust file, Build C/Rust file, etc)
Diffstat (limited to 'library/stdarch/crates/intrinsic-test/src/arm/json_parser.rs')
| -rw-r--r-- | library/stdarch/crates/intrinsic-test/src/arm/json_parser.rs | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/library/stdarch/crates/intrinsic-test/src/arm/json_parser.rs b/library/stdarch/crates/intrinsic-test/src/arm/json_parser.rs new file mode 100644 index 00000000000..32bb10e6f69 --- /dev/null +++ b/library/stdarch/crates/intrinsic-test/src/arm/json_parser.rs @@ -0,0 +1,99 @@ +use std::collections::HashMap; +use std::path::Path; + +use serde::Deserialize; + +use super::argument::{Argument, ArgumentList}; +use super::intrinsic::Intrinsic; +use super::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")] + #[allow(dead_code)] + 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: &Path) -> 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()], + }) +} |
