Skip to content

Commit 39425f3

Browse files
chore: vector types cannot be the type of an individual element in an
array. Extra: 1. Added better load fuctions 2. Added an update_simd_len() function to support cases where the bit_len of the element need to be inferred from its partner arguments before calculating the simd_len
1 parent 1e56470 commit 39425f3

File tree

1 file changed

+77
-36
lines changed

1 file changed

+77
-36
lines changed

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

Lines changed: 77 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,10 @@ impl IntrinsicTypeDefinition for X86IntrinsicType {
115115
// if "type" starts with __m<num>{h/i/<null>},
116116
// then use either _mm_set1_epi64,
117117
// _mm256_set1_epi64 or _mm512_set1_epi64
118+
if type_value.contains("__m64") {
119+
return String::from("*(__m64*)");
120+
}
121+
118122
let type_val_filtered = type_value
119123
.chars()
120124
.filter(|c| c.is_numeric())
@@ -126,12 +130,11 @@ impl IntrinsicTypeDefinition for X86IntrinsicType {
126130
(Some(bit_len @ (8 | 16 | 32 | 64)), TypeKind::Int(_)) => {
127131
format!("epi{bit_len}")
128132
}
133+
(Some(bit_len), TypeKind::Mask) => format!("epi{bit_len}"),
129134
(Some(16), TypeKind::Float) => format!("ph"),
130135
(Some(32), TypeKind::Float) => format!("ps"),
131136
(Some(64), TypeKind::Float) => format!("pd"),
132-
(Some(128), TypeKind::Vector) => format!("si128"),
133-
(Some(256), TypeKind::Vector) => format!("si256"),
134-
(Some(512), TypeKind::Vector) => format!("si512"),
137+
(Some(128 | 256 | 512), TypeKind::Vector) => format!("epi32"),
135138
_ => unreachable!("Invalid element type for a vector type! {:?}", self.param),
136139
};
137140
format!("_mm{type_val_filtered}_loadu_{suffix}")
@@ -252,17 +255,18 @@ impl IntrinsicTypeDefinition for X86IntrinsicType {
252255
}
253256

254257
fn rust_scalar_type(&self) -> String {
255-
let re = Regex::new(r"\__m\d+[a-z]*").unwrap();
256-
if let Some(match_type) = re.find(self.param.type_data.as_str()) {
257-
match_type.as_str().to_string()
258-
} else {
259-
let prefix = match self.data.kind {
260-
TypeKind::Mask => String::from("__mmask"),
261-
_ => self.kind().rust_prefix().to_string(),
262-
};
258+
let prefix = match self.data.kind {
259+
TypeKind::Mask => String::from("__mmask"),
260+
TypeKind::Vector => String::from("i"),
261+
_ => self.kind().rust_prefix().to_string(),
262+
};
263263

264-
format!("{prefix}{bits}", bits = self.inner_size())
265-
}
264+
let bits = if self.inner_size() >= 128 {
265+
32
266+
} else {
267+
self.inner_size()
268+
};
269+
format!("{prefix}{bits}")
266270
}
267271
}
268272

@@ -311,6 +315,26 @@ impl X86IntrinsicType {
311315
})
312316
}
313317

318+
pub fn update_simd_len(&mut self) {
319+
let mut type_processed = self.param.type_data.clone();
320+
type_processed.retain(|c| c.is_numeric());
321+
322+
// check the param.type and extract numeric part if there are double
323+
// underscores. divide this number with bit-len and set this as simd-len.
324+
// Only __m<int> types can have a simd-len.
325+
if self.param.type_data.contains("__m") && !self.param.type_data.contains("__mmask") {
326+
self.data.simd_len = match str::parse::<u32>(type_processed.as_str()) {
327+
// If bit_len is None, simd_len will be None.
328+
// Else simd_len will be (num_bits / bit_len).
329+
Ok(num_bits) => self
330+
.data
331+
.bit_len
332+
.and_then(|bit_len| Some(num_bits / bit_len)),
333+
Err(_) => None,
334+
};
335+
}
336+
}
337+
314338
pub fn from_param(param: &Parameter) -> Result<Self, String> {
315339
match Self::from_c(param.type_data.as_str()) {
316340
Err(message) => Err(message),
@@ -350,22 +374,26 @@ impl X86IntrinsicType {
350374
}
351375
}
352376

353-
if param.type_data.matches("__mmask").next().is_some() {
377+
if param.type_data.contains("__mmask") {
354378
data.bit_len = str::parse::<u32>(type_processed.as_str()).ok();
355379
}
356380

357-
// then check the param.type and extract numeric part if there are double
358-
// underscores. divide this number with bit-len and set this as simd-len.
359-
// Only __m<int> types can have a simd-len.
360-
if param.type_data.matches("__m").next().is_some()
361-
&& param.type_data.matches("__mmask").next().is_none()
362-
{
363-
data.simd_len = match str::parse::<u32>(type_processed.as_str()) {
364-
// If bit_len is None, simd_len will be None.
365-
// Else simd_len will be (num_bits / bit_len).
366-
Ok(num_bits) => data.bit_len.and_then(|bit_len| Some(num_bits / bit_len)),
367-
Err(_) => None,
368-
};
381+
if vec!["M512", "M256", "M128"].contains(&param.etype.as_str()) {
382+
match param.type_data.chars().last() {
383+
Some('i') => {
384+
data.kind = TypeKind::Int(Sign::Signed);
385+
data.bit_len = Some(32);
386+
}
387+
Some('h') => {
388+
data.kind = TypeKind::Float;
389+
data.bit_len = Some(16);
390+
}
391+
Some('d') => {
392+
data.kind = TypeKind::Float;
393+
data.bit_len = Some(64);
394+
}
395+
_ => (),
396+
}
369397
}
370398

371399
// default settings for "void *" parameters
@@ -381,22 +409,35 @@ impl X86IntrinsicType {
381409
data.bit_len = Some(32);
382410
}
383411

384-
// default settings for IMM parameters
385-
if param.etype == "IMM" && param.imm_width > 0 {
386-
data.bit_len = Some(param.imm_width);
387-
}
388-
389412
if param.etype == "IMM" || param.imm_width > 0 || param.imm_type.len() > 0 {
413+
data.kind = TypeKind::Int(Sign::Unsigned);
390414
data.constant = true;
391415
}
392416

393-
// if param.etype == IMM, then it is a constant.
394-
// else it stays unchanged.
395-
data.constant |= param.etype == "IMM";
396-
Ok(X86IntrinsicType {
417+
// Rust defaults to signed variants, unless they are explicitly mentioned
418+
// the `type` field are C++ types.
419+
if data.kind == TypeKind::Int(Sign::Unsigned)
420+
&& !(param.type_data.contains("unsigned") || param.type_data.contains("uint"))
421+
{
422+
data.kind = TypeKind::Int(Sign::Signed)
423+
}
424+
425+
// default settings for IMM parameters
426+
if param.etype == "IMM" {
427+
data.bit_len = if param.imm_width > 0 {
428+
Some(param.imm_width)
429+
} else {
430+
Some(8)
431+
}
432+
}
433+
434+
let mut result = X86IntrinsicType {
397435
data,
398436
param: param.clone(),
399-
})
437+
};
438+
439+
result.update_simd_len();
440+
Ok(result)
400441
}
401442
}
402443
// Tile types won't currently reach here, since the intrinsic that involve them

0 commit comments

Comments
 (0)