about summary refs log tree commit diff
path: root/library/stdarch/crates/intrinsic-test/src/arm/json_parser.rs
diff options
context:
space:
mode:
authorMadhav Madhusoodanan <f20200049@pilani.bits-pilani.ac.in>2025-03-25 13:32:33 +0400
committerAmanieu d'Antras <amanieu@gmail.com>2025-05-27 23:27:38 +0000
commitd7edb3ea7c9b813b8794e62a2c1c5078e881e1cb (patch)
tree283c644b485a2bee83d6b03f4a6d1e7c45831e7f /library/stdarch/crates/intrinsic-test/src/arm/json_parser.rs
parent08484b5e7a93181c49f4ce8654270dfa47dd6ebb (diff)
downloadrust-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.rs99
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()],
+    })
+}