Skip to content

Commit e57c4bf

Browse files
feat: added memsize and rust_type implementation
Notes: 1. rust_type deinition may need future work for accuracy
1 parent e947072 commit e57c4bf

File tree

2 files changed

+93
-22
lines changed

2 files changed

+93
-22
lines changed

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

Lines changed: 82 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,73 @@ impl IntrinsicTypeDefinition for X86IntrinsicType {
2323
// matches __m128, __m256 and similar types
2424
let re = Regex::new(r"\__m\d+\").unwrap();
2525
match self.metadata.get("type") {
26-
Some(type_data) if re.is_match(type_data) => type_data.to_string(),
26+
Some(type_data) if re.is_match(type_data) => type_data.to_string(),
2727
_ => unreachable!("Shouldn't be called on this type"),
2828
}
2929
}
3030

3131
fn rust_type(&self) -> String {
32-
todo!("rust_type for X86IntrinsicType needs to be implemented!");
32+
// handling edge cases first
33+
// the general handling is implemented below
34+
if let Some(val) = self.metadata.get("type") {
35+
match val.as_str() {
36+
"__m128 const *" => {
37+
return "&__m128".to_string();
38+
}
39+
"__m128d const *" => {
40+
return "&__m128d".to_string();
41+
}
42+
"const void*" => {
43+
return "&__m128d".to_string();
44+
}
45+
_ => {}
46+
}
47+
}
48+
49+
if self.kind() == TypeKind::Void && self.ptr {
50+
// this has been handled by default settings in
51+
// the from_param function of X86IntrinsicType
52+
unreachable!()
53+
}
54+
55+
// general handling cases
56+
let core_part = if self.kind() == TypeKind::Mask {
57+
// all types of __mmask<int> are handled here
58+
format!("__mask{}", self.bit_len.unwrap())
59+
} else if self.simd_len.is_some() {
60+
// all types of __m<int> vector types are handled here
61+
let re = Regex::new(r"\__m\d+[a-z]*").unwrap();
62+
let rust_type = self
63+
.metadata
64+
.get("type")
65+
.map(|val| re.find(val).unwrap().as_str());
66+
rust_type.unwrap().to_string()
67+
} else {
68+
format!(
69+
"{}{}",
70+
self.kind.rust_prefix().to_string(),
71+
self.bit_len.unwrap()
72+
)
73+
};
74+
75+
// extracting "memsize" so that even vector types can be involved
76+
let memwidth = self
77+
.metadata
78+
.get("memwidth")
79+
.map(|n| str::parse::<u32>(n).unwrap());
80+
let prefix_part = if self.ptr && self.constant && self.bit_len.eq(&memwidth) {
81+
"&"
82+
} else if self.ptr && self.bit_len.eq(&memwidth) {
83+
"&mut "
84+
} else if self.ptr && self.constant {
85+
"*const "
86+
} else if self.ptr {
87+
"*mut "
88+
} else {
89+
""
90+
};
91+
92+
return prefix_part.to_string() + core_part.as_str();
3393
}
3494

3595
/// Determines the load function for this type.
@@ -124,6 +184,7 @@ impl X86IntrinsicType {
124184
// The assumption is that the parameter of type void may have param.type
125185
// as "__m128i", "__mmask8" and the like.
126186
ret.set_metadata("etype".to_string(), param.etype.clone());
187+
ret.set_metadata("memwidth".to_string(), param.memwidth.to_string());
127188
if !param.etype.is_empty() {
128189
match TypeKind::from_str(param.etype.as_str()) {
129190
Ok(value) => {
@@ -155,16 +216,26 @@ impl X86IntrinsicType {
155216

156217
// then check the param.type and extract numeric part if there are double
157218
// underscores. divide this number with bit-len and set this as simd-len.
219+
// Only __m<int> types can have a simd-len.
220+
if param.type_data.matches("__m").next().is_some()
221+
&& param.type_data.matches("__mmask").next().is_none()
222+
{
223+
let mut type_processed = param.type_data.clone();
224+
type_processed.retain(|c| c.is_numeric());
225+
ret.vec_len = match str::parse::<u32>(type_processed.as_str()) {
226+
// If bit_len is None, vec_len will be None.
227+
// Else vec_len will be (num_bits / bit_len).
228+
Ok(num_bits) => ret.bit_len.and(Some(num_bits / ret.bit_len.unwrap())),
229+
Err(_) => None,
230+
};
231+
}
158232

159-
let mut type_processed = param.type_data.clone();
160-
type_processed.retain(|c| c.is_numeric());
161-
162-
ret.vec_len = match str::parse::<u32>(type_processed.as_str()) {
163-
// If bit_len is None, vec_len will be None.
164-
// Else vec_len will be (num_bits / bit_len).
165-
Ok(num_bits) => ret.bit_len.and(Some(num_bits / ret.bit_len.unwrap())),
166-
Err(_) => None,
167-
};
233+
// default settings for "void *" parameters
234+
// often used by intrinsics to denote memory address or so.
235+
if ret.kind == TypeKind::Void && ret.ptr {
236+
ret.kind = TypeKind::Int(Sign::Unsigned);
237+
ret.bit_len = Some(8);
238+
}
168239

169240
// if param.etype == IMM, then it is a constant.
170241
// else it stays unchanged.

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

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,19 @@ use crate::common::argument::{Argument, ArgumentList};
22
use crate::common::intrinsic::Intrinsic;
33
use crate::common::intrinsic_helpers::TypeKind;
44

5-
use serde::Deserialize;
5+
use serde::{Deserialize, Deserializer};
66
use std::path::Path;
77

88
use super::intrinsic::X86IntrinsicType;
99

10-
// Custom deserializer function to convert strings to u16
11-
// fn string_to_u16<'de, D>(deserializer: D) -> Result<u16, D::Error>
12-
// where
13-
// D: Deserializer<'de>,
14-
// {
15-
// let s = String::deserialize(deserializer)?;
16-
// return Ok(s.as_str().parse::<u16>().unwrap_or(0u16));
17-
// }
10+
// Custom deserializer function to convert strings to u32
11+
fn string_to_u32<'de, D>(deserializer: D) -> Result<u32, D::Error>
12+
where
13+
D: Deserializer<'de>,
14+
{
15+
let s = String::deserialize(deserializer)?;
16+
return s.as_str().parse::<u32>().or(Ok(0u16));
17+
}
1818

1919
#[derive(Deserialize)]
2020
struct Data {
@@ -42,8 +42,8 @@ pub struct Parameter {
4242
pub type_data: String,
4343
#[serde(rename = "@etype", default)]
4444
pub etype: String,
45-
// #[serde(rename = "@memwidth", default, deserialize_with = "string_to_u16")]
46-
// pub memwidth: u16,
45+
#[serde(rename = "@memwidth", default, deserialize_with = "string_to_u32")]
46+
pub memwidth: u32,
4747
#[serde(rename = "@varname", default)]
4848
pub var_name: String,
4949
}

0 commit comments

Comments
 (0)