Skip to content

Commit 4e0895e

Browse files
committed
intrinsic-test: add SVE-specific constraints
1 parent 3632439 commit 4e0895e

2 files changed

Lines changed: 50 additions & 12 deletions

File tree

crates/intrinsic-test/src/arm/json_parser.rs

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::arm::types::parse_intrinsic_type;
33
use crate::common::argument::{Argument, ArgumentList};
44
use crate::common::constraint::Constraint;
55
use crate::common::intrinsic::Intrinsic;
6-
use crate::common::intrinsic_helpers::IntrinsicType;
6+
use crate::common::intrinsic_helpers::{IntrinsicType, TypeKind};
77
use serde::Deserialize;
88
use serde_json::Value;
99
use std::collections::HashMap;
@@ -90,18 +90,37 @@ fn json_to_intrinsic(
9090
.enumerate()
9191
.map(|(i, arg)| {
9292
let (type_name, arg_name) = Argument::<ArmIntrinsicType>::type_and_name_from_c(&arg);
93+
94+
let arg_ty = parse_intrinsic_type(type_name)
95+
.unwrap_or_else(|_| panic!("Failed to parse argument '{arg}'"));
96+
9397
let metadata = intr.args_prep.as_mut();
9498
let metadata = metadata.and_then(|a| a.remove(arg_name));
9599
let arg_prep: Option<ArgPrep> = metadata.and_then(|a| a.try_into().ok());
96-
let constraint: Option<Constraint> = arg_prep.and_then(|a| a.try_into().ok());
97-
let arg_ty = ArmIntrinsicType(
98-
parse_intrinsic_type(type_name)
99-
.unwrap_or_else(|_| panic!("Failed to parse argument '{arg}'")),
100+
let constraint: Option<Constraint> =
101+
arg_prep.and_then(|a| a.try_into().ok()).or_else(|| {
102+
if arg_ty.kind() == TypeKind::SvPattern {
103+
Some(Constraint::SvPattern)
104+
} else if arg_ty.kind() == TypeKind::SvPrefetchOp {
105+
Some(Constraint::SvPrefetchOp)
106+
} else if arg_name == "imm_rotation" {
107+
if name.starts_with("svcadd_") || name.starts_with("svqcadd_") {
108+
Some(Constraint::SvImmRotationAdd)
109+
} else {
110+
Some(Constraint::SvImmRotation)
111+
}
112+
} else {
113+
None
114+
}
115+
});
116+
117+
let mut arg = Argument::<ArmIntrinsicType>::new(
118+
i,
119+
String::from(arg_name),
120+
ArmIntrinsicType(arg_ty),
121+
constraint,
100122
);
101123

102-
let mut arg =
103-
Argument::<ArmIntrinsicType>::new(i, String::from(arg_name), arg_ty, constraint);
104-
105124
// The JSON doesn't list immediates as const
106125
let IntrinsicType {
107126
ref mut constant, ..

crates/intrinsic-test/src/common/constraint.rs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,34 @@ pub enum Constraint {
1010
Range(Range<i64>),
1111
/// Test discrete values, e.g. `vec![1, 2, 4, 8]`.
1212
Set(Vec<i64>),
13+
/// Values of `core::arch::aarch64::svpattern`
14+
SvPattern,
15+
/// Values of `core::arch::aarch64::svprfop`
16+
SvPrefetchOp,
17+
// Values of the `imm_rotation` argument in SVE intrinsics where arguments contain complex
18+
// pairs and `imm_rotation` corresponds to the rotation.
19+
SvImmRotation,
20+
// Values of the `imm_rotation` argument in SVE intrinsics where arguments contain complex
21+
// pairs and `imm_rotation` corresponds to the rotation (this variant is specifically for
22+
// `svcadd` and `svqcadd` where only 90 and 270 are valid arguments).
23+
SvImmRotationAdd,
1324
}
1425

1526
impl Constraint {
1627
/// Iterate over the values of this constraint.
17-
pub fn iter<'a>(&'a self) -> impl Iterator<Item = i64> + 'a {
28+
pub fn iter(&self) -> Box<dyn Iterator<Item = i64> + '_> {
1829
match self {
19-
Constraint::Equal(i) => std::slice::Iter::default().copied().chain(*i..*i + 1),
20-
Constraint::Range(range) => std::slice::Iter::default().copied().chain(range.clone()),
21-
Constraint::Set(items) => items.iter().copied().chain(std::ops::Range::default()),
30+
Constraint::Equal(i) => Box::new(std::iter::once(*i)),
31+
Constraint::Range(range) => Box::new(range.clone()),
32+
Constraint::Set(items) => Box::new(items.iter().copied().chain(Range::default())),
33+
// These values are discriminants of the `svpattern` enum
34+
Constraint::SvPattern => Box::new((0..=13).chain(29..=31)),
35+
// These values are discriminants of the `svprfop` enum
36+
Constraint::SvPrefetchOp => Box::new((0..=5).chain(8..=14)),
37+
// Valid rotations for intrinsics operating on complex pairs: 0, 90, 180, 270
38+
Constraint::SvImmRotation => Box::new((0..=270).step_by(90)),
39+
// Valid rotations for `svcadd` and `svqcadd`: 0, 270
40+
Constraint::SvImmRotationAdd => Box::new((90..=270).step_by(180)),
2241
}
2342
}
2443
}

0 commit comments

Comments
 (0)