about summary refs log tree commit diff
path: root/library/stdarch/crates/intrinsic-test/src/arm/constraint.rs
diff options
context:
space:
mode:
Diffstat (limited to 'library/stdarch/crates/intrinsic-test/src/arm/constraint.rs')
-rw-r--r--library/stdarch/crates/intrinsic-test/src/arm/constraint.rs60
1 files changed, 60 insertions, 0 deletions
diff --git a/library/stdarch/crates/intrinsic-test/src/arm/constraint.rs b/library/stdarch/crates/intrinsic-test/src/arm/constraint.rs
new file mode 100644
index 00000000000..777cbd0099a
--- /dev/null
+++ b/library/stdarch/crates/intrinsic-test/src/arm/constraint.rs
@@ -0,0 +1,60 @@
+use super::json_parser::ArgPrep;
+
+use crate::common::argument::MetadataDefinition;
+use serde::Deserialize;
+use serde_json::Value;
+use std::ops::Range;
+
+#[derive(Debug, PartialEq, Clone, Deserialize)]
+pub enum Constraint {
+    Equal(i64),
+    Range(Range<i64>),
+}
+
+impl Constraint {
+    pub fn to_range(&self) -> Range<i64> {
+        match self {
+            Constraint::Equal(eq) => *eq..*eq + 1,
+            Constraint::Range(range) => range.clone(),
+        }
+    }
+}
+
+impl MetadataDefinition for Constraint {
+    fn from_metadata(metadata: Option<Value>) -> Vec<Box<Self>> {
+        let arg_prep: Option<ArgPrep> = metadata.and_then(|a| {
+            if let Value::Object(_) = a {
+                a.try_into().ok()
+            } else {
+                None
+            }
+        });
+        let constraint: Option<Constraint> = arg_prep.and_then(|a| a.try_into().ok());
+        vec![constraint]
+            .into_iter()
+            .filter_map(|a| a)
+            .map(|a| Box::new(a))
+            .collect()
+    }
+}
+
+/// ARM-specific
+impl TryFrom<ArgPrep> for Constraint {
+    type Error = ();
+
+    fn try_from(prep: ArgPrep) -> Result<Self, Self::Error> {
+        let parsed_ints = match prep {
+            ArgPrep::Immediate { min, max } => Ok((min, max)),
+            _ => Err(()),
+        };
+        if let Ok((min, max)) = parsed_ints {
+            if min == max {
+                Ok(Constraint::Equal(min))
+            } else {
+                Ok(Constraint::Range(min..max + 1))
+            }
+        } else {
+            Err(())
+        }
+    }
+}