summaryrefslogtreecommitdiffstats
path: root/library/stdarch/crates/intrinsic-test/src/json_parser.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 03:57:31 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 03:57:31 +0000
commitdc0db358abe19481e475e10c32149b53370f1a1c (patch)
treeab8ce99c4b255ce46f99ef402c27916055b899ee /library/stdarch/crates/intrinsic-test/src/json_parser.rs
parentReleasing progress-linux version 1.71.1+dfsg1-2~progress7.99u1. (diff)
downloadrustc-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.rs97
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()],
+ })
+}