diff options
Diffstat (limited to 'library/stdarch/crates/intrinsic-test/src/arm/constraint.rs')
| -rw-r--r-- | library/stdarch/crates/intrinsic-test/src/arm/constraint.rs | 60 |
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(()) + } + } +} |
