Skip to content

Commit d92ce71

Browse files
Sharpening the parsing logic:
1. filtered any intrinsic arguments where the only parameter is of type "void" 2. Better parsing for intrinsic return type 3. Filtering intrinsics that are difficult to test (void returns) 4. Reduced the variants in TypeKind (which differed only in bit_len)
1 parent 2934899 commit d92ce71

File tree

5 files changed

+165
-55
lines changed

5 files changed

+165
-55
lines changed

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

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,10 @@ use super::values::value_for_array;
1212
pub enum TypeKind {
1313
BFloat,
1414
Float,
15-
Double,
1615

1716
// if signed, then the inner value is true
1817
Int(bool),
1918
Char(bool),
20-
Short(bool),
2119
Poly,
2220
Void,
2321
}
@@ -29,9 +27,8 @@ impl FromStr for TypeKind {
2927
match s {
3028
"bfloat" => Ok(Self::BFloat),
3129
"float" => Ok(Self::Float),
32-
"double" => Ok(Self::Double),
33-
"int" | "long" => Ok(Self::Int(true)),
34-
"short" => Ok(Self::Short(true)),
30+
"double" => Ok(Self::Float),
31+
"int" | "long" | "short" => Ok(Self::Int(true)),
3532
"poly" => Ok(Self::Poly),
3633
"char" => Ok(Self::Char(true)),
3734
"uint" | "unsigned" => Ok(Self::Int(false)),
@@ -49,15 +46,12 @@ impl fmt::Display for TypeKind {
4946
match self {
5047
Self::BFloat => "bfloat",
5148
Self::Float => "float",
52-
Self::Double => "double",
5349
Self::Int(true) => "int",
5450
Self::Int(false) => "uint",
5551
Self::Poly => "poly",
5652
Self::Void => "void",
5753
Self::Char(true) => "char",
5854
Self::Char(false) => "unsigned char",
59-
Self::Short(true) => "short",
60-
Self::Short(false) => "unsigned short",
6155
}
6256
)
6357
}
@@ -72,7 +66,6 @@ impl TypeKind {
7266
Self::Int(false) => "uint",
7367
Self::Poly => "poly",
7468
Self::Char(true) => "char",
75-
Self::Double => "double",
7669
_ => unreachable!("Not used: {:#?}", self),
7770
}
7871
}
@@ -126,7 +119,7 @@ impl IntrinsicType {
126119
if let Some(bl) = self.bit_len {
127120
bl
128121
} else {
129-
unreachable!("")
122+
unreachable!("{}", self.kind)
130123
}
131124
}
132125

@@ -159,11 +152,17 @@ impl IntrinsicType {
159152
}
160153

161154
pub fn c_scalar_type(&self) -> String {
162-
format!(
163-
"{prefix}{bits}_t",
164-
prefix = self.kind().c_prefix(),
165-
bits = self.inner_size()
166-
)
155+
match self {
156+
IntrinsicType {
157+
kind: TypeKind::Char(_),
158+
..
159+
} => String::from("char"),
160+
_ => format!(
161+
"{prefix}{bits}_t",
162+
prefix = self.kind().c_prefix(),
163+
bits = self.inner_size()
164+
),
165+
}
167166
}
168167

169168
pub fn rust_scalar_type(&self) -> String {
@@ -198,6 +197,21 @@ impl IntrinsicType {
198197
128 => "",
199198
_ => panic!("invalid bit_len"),
200199
},
200+
IntrinsicType {
201+
kind: TypeKind::Float,
202+
bit_len: Some(bit_len),
203+
..
204+
} => match bit_len {
205+
16 => "(float16_t)",
206+
32 => "(float)",
207+
64 => "(double)",
208+
128 => "",
209+
_ => panic!("invalid bit_len"),
210+
},
211+
IntrinsicType {
212+
kind: TypeKind::Char(_),
213+
..
214+
} => "(char)",
201215
_ => "",
202216
}
203217
}

crates/intrinsic-test/src/x86/intrinsic.rs

Lines changed: 65 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::common::argument::ArgumentList;
22
use crate::common::indentation::Indentation;
33
use crate::common::intrinsic::{Intrinsic, IntrinsicDefinition};
4-
use crate::common::intrinsic_helpers::IntrinsicType;
4+
use crate::common::intrinsic_helpers::{IntrinsicType, IntrinsicTypeDefinition, TypeKind};
55
use std::ops::{Deref, DerefMut};
66

77
#[derive(Debug, Clone, PartialEq)]
@@ -38,7 +38,69 @@ impl IntrinsicDefinition<X86IntrinsicType> for Intrinsic<X86IntrinsicType> {
3838
/// Generates a std::cout for the intrinsics results that will match the
3939
/// rust debug output format for the return type. The generated line assumes
4040
/// there is an int i in scope which is the current pass number.
41-
fn print_result_c(&self, _indentation: Indentation, _additional: &str) -> String {
42-
todo!("print_result_c in Intrinsic<X86IntrinsicType> needs to be implemented!");
41+
fn print_result_c(&self, indentation: Indentation, additional: &str) -> String {
42+
let lanes = if self.results().num_vectors() > 1 {
43+
(0..self.results().num_vectors())
44+
.map(|vector| {
45+
format!(
46+
r#""{ty}(" << {lanes} << ")""#,
47+
ty = self.results().c_single_vector_type(),
48+
lanes = (0..self.results().num_lanes())
49+
.map(move |idx| -> std::string::String {
50+
format!(
51+
"{cast}{lane_fn}(__return_value.val[{vector}], {lane})",
52+
cast = self.results().c_promotion(),
53+
lane_fn = self.results().get_lane_function(),
54+
lane = idx,
55+
vector = vector,
56+
)
57+
})
58+
.collect::<Vec<_>>()
59+
.join(r#" << ", " << "#)
60+
)
61+
})
62+
.collect::<Vec<_>>()
63+
.join(r#" << ", " << "#)
64+
} else if self.results().num_lanes() > 1 {
65+
(0..self.results().num_lanes())
66+
.map(|idx| -> std::string::String {
67+
format!(
68+
"{cast}{lane_fn}(__return_value, {lane})",
69+
cast = self.results().c_promotion(),
70+
lane_fn = self.results().get_lane_function(),
71+
lane = idx
72+
)
73+
})
74+
.collect::<Vec<_>>()
75+
.join(r#" << ", " << "#)
76+
} else {
77+
format!(
78+
"{promote}cast<{cast}>(__return_value)",
79+
cast = match self.results.kind() {
80+
TypeKind::Void => "void".to_string(),
81+
TypeKind::Float if self.results().inner_size() == 64 => "double".to_string(),
82+
TypeKind::Float if self.results().inner_size() == 32 => "float".to_string(),
83+
// TypeKind::Float if self.results().inner_size() == 16 => "float16_t".to_string(),
84+
// TypeKind::Int(true) if self.results().inner_size() == 64 => "long".to_string(),
85+
// TypeKind::Int(false) if self.results().inner_size() == 64 => "unsigned long".to_string(),
86+
// TypeKind::Int(true) if self.results().inner_size() == 32 => "int".to_string(),
87+
// TypeKind::Int(false) if self.results().inner_size() == 32 => "unsigned int".to_string(),
88+
// TypeKind::Int(true) if self.results().inner_size() == 16 => "short".to_string(),
89+
// TypeKind::Int(false) if self.results().inner_size() == 16 => "unsigned short".to_string(),
90+
_ => self.results.c_scalar_type(),
91+
},
92+
promote = self.results().c_promotion(),
93+
)
94+
};
95+
96+
format!(
97+
r#"{indentation}std::cout << "Result {additional}-" << i+1 << ": {ty}" << std::fixed << std::setprecision(150) << {lanes} << "{close}" << std::endl;"#,
98+
ty = if self.results().is_simd() {
99+
format!("{}(", self.results().c_type())
100+
} else {
101+
String::from("")
102+
},
103+
close = if self.results.is_simd() { ")" } else { "" },
104+
)
43105
}
44106
}

crates/intrinsic-test/src/x86/mod.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ mod xml_parser;
66
use crate::common::SupportedArchitectureTest;
77
use crate::common::cli::ProcessedCli;
88
use crate::common::intrinsic::{Intrinsic, IntrinsicDefinition};
9+
use crate::common::intrinsic_helpers::TypeKind;
910
use crate::common::write_file::{write_c_testfiles, write_rust_testfiles};
1011
use config::build_notices;
1112
use intrinsic::X86IntrinsicType;
@@ -18,9 +19,24 @@ pub struct X86ArchitectureTest {
1819

1920
impl SupportedArchitectureTest for X86ArchitectureTest {
2021
fn create(cli_options: ProcessedCli) -> Box<Self> {
21-
let intrinsics = get_xml_intrinsics(&cli_options.filename, &cli_options.target)
22+
let mut intrinsics = get_xml_intrinsics(&cli_options.filename, &cli_options.target)
2223
.expect("Error parsing input file");
2324

25+
intrinsics.sort_by(|a, b| a.name.cmp(&b.name));
26+
let intrinsics = intrinsics
27+
.into_iter()
28+
// Not sure how we would compare intrinsic that returns void.
29+
.filter(|i| i.results.kind() != TypeKind::Void)
30+
.filter(|i| i.results.kind() != TypeKind::BFloat)
31+
.filter(|i| i.arguments().args.len() > 0)
32+
.filter(|i| !i.arguments.iter().any(|a| a.ty.kind() == TypeKind::BFloat))
33+
// Skip pointers for now, we would probably need to look at the return
34+
// type to work out how many elements we need to point to.
35+
.filter(|i| !i.arguments.iter().any(|a| a.is_ptr()))
36+
.filter(|i| !i.arguments.iter().any(|a| a.ty.inner_size() == 128))
37+
.filter(|i| !cli_options.skip.contains(&i.name))
38+
.collect::<Vec<_>>();
39+
2440
Box::new(Self {
2541
intrinsics: intrinsics,
2642
cli_options: cli_options,

crates/intrinsic-test/src/x86/types.rs

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,9 @@ impl IntrinsicTypeDefinition for X86IntrinsicType {
1111
let part_1 = match self.kind {
1212
TypeKind::Int(false) => "unsigned int",
1313
TypeKind::Char(false) => "unsigned char",
14-
TypeKind::Short(false) => "unsigned short",
15-
TypeKind::Short(true) => "short",
1614
_ => self.kind.c_prefix(),
1715
};
18-
let part_2 = if self.ptr {
19-
if self.ptr_constant { "* const" } else { "*" }
20-
} else {
21-
""
22-
};
16+
let part_2 = if self.ptr { "*" } else { "" };
2317

2418
String::from(vec![part_0, part_1, part_2].join(" ").trim())
2519
}
@@ -59,23 +53,30 @@ impl IntrinsicTypeDefinition for X86IntrinsicType {
5953
// functionality below this line.
6054
// Currently all the intrinsics that have an "_"
6155
// is ignored.
62-
if let Some(_) = s.matches("_").next() {
56+
if s.matches("_").next().is_some() {
6357
return Err(String::from("This functionality needs to be implemented"));
6458
};
6559

6660
// TODO: make the unwrapping safe
6761
let kind = TypeKind::from_str(s_split.unwrap()).expect("Unable to parse type!");
68-
let mut ptr_constant = false;
62+
63+
let kind = if s.find("unsigned").is_some() {
64+
match kind {
65+
TypeKind::Int(_) => TypeKind::Int(false),
66+
TypeKind::Char(_) => TypeKind::Char(false),
67+
a => a,
68+
}
69+
} else {
70+
kind
71+
};
72+
let ptr_constant = false;
6973
let mut constant = false;
7074
let mut ptr = false;
7175

72-
if let Some(_) = s.matches("const*").next() {
73-
ptr_constant = true;
74-
};
75-
if let Some(_) = s.matches("const").next() {
76+
if s.matches("const").next().is_some() {
7677
constant = true;
7778
};
78-
if let Some(_) = s.matches("*").next() {
79+
if s.matches("*").next().is_some() {
7980
ptr = true;
8081
};
8182

crates/intrinsic-test/src/x86/xml_parser.rs

Lines changed: 39 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::common::argument::{Argument, ArgumentList};
22
use crate::common::intrinsic::Intrinsic;
3-
use crate::common::intrinsic_helpers::{IntrinsicType, IntrinsicTypeDefinition};
3+
use crate::common::intrinsic_helpers::{IntrinsicType, IntrinsicTypeDefinition, TypeKind};
44

55
use serde::{Deserialize, Deserializer};
66
use std::path::Path;
@@ -38,7 +38,7 @@ struct Data {
3838
#[derive(Deserialize)]
3939
struct XMLIntrinsic {
4040
#[serde(rename = "return")]
41-
return_data: Return,
41+
return_data: Parameter,
4242
#[serde(rename = "@name")]
4343
name: String,
4444
#[serde(rename = "@tech")]
@@ -65,12 +65,6 @@ struct Parameter {
6565
var_name: String,
6666
}
6767

68-
#[derive(Deserialize)]
69-
struct Return {
70-
#[serde(rename = "@type", default)]
71-
type_data: String,
72-
}
73-
7468
#[derive(Deserialize, Debug)]
7569
struct Instruction {
7670
#[serde(rename = "@name")]
@@ -86,7 +80,6 @@ pub fn get_xml_intrinsics(
8680
let data: Data =
8781
quick_xml::de::from_reader(reader).expect("failed to deserialize the source XML file");
8882

89-
// println!("{} intrinsics found", data.intrinsics.len());
9083
let parsed_intrinsics: Vec<Intrinsic<X86IntrinsicType>> = data
9184
.intrinsics
9285
.into_iter()
@@ -99,26 +92,43 @@ pub fn get_xml_intrinsics(
9992
Ok(parsed_intrinsics)
10093
}
10194

95+
fn parse_observable(param: &Parameter, target: &String) -> Result<X86IntrinsicType, String> {
96+
let ty = X86IntrinsicType::from_c(param.type_data.as_str(), target);
97+
98+
if let Err(_) = ty {
99+
return ty;
100+
}
101+
let mut ty_bit_len = param.etype.clone();
102+
ty_bit_len.retain(|c| c.is_numeric());
103+
let ty_bit_len = str::parse::<u32>(ty_bit_len.as_str()).ok();
104+
let mut ty = ty.unwrap();
105+
let ty_bit_len = match ty_bit_len {
106+
None => match ty.kind {
107+
TypeKind::Int(_) => Some(32),
108+
TypeKind::Float => Some(32),
109+
TypeKind::BFloat => Some(16),
110+
TypeKind::Void => Some(param.memwidth as u32),
111+
_ => None,
112+
},
113+
ty => ty,
114+
};
115+
ty.set_bit_len(ty_bit_len);
116+
Ok(ty)
117+
}
118+
102119
fn xml_to_intrinsic(
103120
intr: XMLIntrinsic,
104121
target: &String,
105122
) -> Result<Intrinsic<X86IntrinsicType>, Box<dyn std::error::Error>> {
106123
let name = intr.name;
107-
let results = X86IntrinsicType::from_c(&intr.return_data.type_data, target)?;
108-
124+
let result = parse_observable(&intr.return_data, target);
109125
let args_check = intr.parameters.into_iter().enumerate().map(|(i, param)| {
110-
let constraint = None;
111-
let ty = X86IntrinsicType::from_c(param.type_data.as_str(), target);
112-
126+
let ty = parse_observable(&param, target);
113127
if let Err(_) = ty {
114128
return None;
115129
}
116-
let mut ty_bit_len = param.etype.clone();
117-
ty_bit_len.retain(|c| c.is_numeric());
118-
let ty_bit_len = str::parse::<u32>(ty_bit_len.as_str()).ok();
119-
let mut ty = ty.unwrap();
120-
ty.set_bit_len(ty_bit_len);
121-
let mut arg = Argument::<X86IntrinsicType>::new(i, param.var_name, ty, constraint);
130+
let constraint = None;
131+
let mut arg = Argument::<X86IntrinsicType>::new(i, param.var_name, ty.unwrap(), constraint);
122132
let IntrinsicType {
123133
ref mut constant, ..
124134
} = arg.ty.0;
@@ -132,13 +142,20 @@ fn xml_to_intrinsic(
132142
if args.iter().any(|elem| elem.is_none()) {
133143
return Err(Box::from("intrinsic isn't fully supported in this test!"));
134144
}
135-
let args = args.into_iter().map(|e| e.unwrap()).collect::<Vec<_>>();
145+
let args = args
146+
.into_iter()
147+
.map(|e| e.unwrap())
148+
.filter(|arg| arg.ty.ptr || arg.ty.kind != TypeKind::Void)
149+
.collect::<Vec<_>>();
136150
let arguments = ArgumentList::<X86IntrinsicType> { args };
137151

152+
if let Err(message) = result {
153+
return Err(Box::from(message));
154+
}
138155
Ok(Intrinsic {
139156
name,
140157
arguments,
141-
results: results,
158+
results: result.unwrap(),
142159
arch_tags: intr.cpuid,
143160
})
144161
}

0 commit comments

Comments
 (0)