Skip to content

Commit 20ec01d

Browse files
feat: add formatting for __m128i, __m256i, __m512i types that is similar
to C++ version of the same.
1 parent 87e39a2 commit 20ec01d

File tree

5 files changed

+74
-18
lines changed

5 files changed

+74
-18
lines changed

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use std::process::Command;
44
use crate::common::intrinsic::Intrinsic;
55

66
use super::indentation::Indentation;
7-
use super::intrinsic::format_f16_return_value;
87
use super::intrinsic_helpers::IntrinsicTypeDefinition;
98

109
// The number of times each intrinsic will be called.
@@ -232,7 +231,6 @@ pub fn generate_rust_test_loop<T: IntrinsicTypeDefinition>(
232231
}
233232
}
234233

235-
let return_value = format_f16_return_value(intrinsic);
236234
let indentation2 = indentation.nested();
237235
let indentation3 = indentation2.nested();
238236
writeln!(
@@ -249,6 +247,7 @@ pub fn generate_rust_test_loop<T: IntrinsicTypeDefinition>(
249247
}}",
250248
loaded_args = intrinsic.arguments.load_values_rust(indentation3),
251249
args = intrinsic.arguments.as_call_param_rust(),
250+
return_value = intrinsic.results.print_result_rust(),
252251
)
253252
}
254253

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use super::argument::ArgumentList;
2-
use super::intrinsic_helpers::{IntrinsicTypeDefinition, TypeKind};
2+
use super::intrinsic_helpers::IntrinsicTypeDefinition;
33

44
/// An intrinsic
55
#[derive(Debug, PartialEq, Clone)]
@@ -16,17 +16,3 @@ pub struct Intrinsic<T: IntrinsicTypeDefinition> {
1616
/// Any architecture-specific tags.
1717
pub arch_tags: Vec<String>,
1818
}
19-
20-
pub fn format_f16_return_value<T: IntrinsicTypeDefinition>(intrinsic: &Intrinsic<T>) -> String {
21-
// the `intrinsic-test` crate compares the output of C and Rust intrinsics. Currently, It uses
22-
// a string representation of the output value to compare. In C, f16 values are currently printed
23-
// as hexadecimal integers. Since https://github.com/rust-lang/rust/pull/127013, rust does print
24-
// them as decimal floating point values. To keep the intrinsics tests working, for now, format
25-
// vectors containing f16 values like C prints them.
26-
let return_value = match intrinsic.results.kind() {
27-
TypeKind::Float if intrinsic.results.inner_size() == 16 => "debug_f16(__return_value)",
28-
_ => "format_args!(\"{__return_value:.150?}\")",
29-
};
30-
31-
String::from(return_value)
32-
}

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,23 @@ pub trait IntrinsicTypeDefinition: Deref<Target = IntrinsicType> {
365365
/// there is an int i in scope which is the current pass number.
366366
fn print_result_c(&self, indentation: Indentation, additional: &str) -> String;
367367

368+
/// Generates a std::cout for the intrinsics results that will match the
369+
/// rust debug output format for the return type. The generated line assumes
370+
/// there is an int i in scope which is the current pass number.
371+
fn print_result_rust(&self) -> String {
372+
// the `intrinsic-test` crate compares the output of C and Rust intrinsics. Currently, It uses
373+
// a string representation of the output value to compare. In C, f16 values are currently printed
374+
// as hexadecimal integers. Since https://github.com/rust-lang/rust/pull/127013, rust does print
375+
// them as decimal floating point values. To keep the intrinsics tests working, for now, format
376+
// vectors containing f16 values like C prints them.
377+
let return_value = match self.kind() {
378+
TypeKind::Float if self.inner_size() == 16 => "debug_f16(__return_value)",
379+
_ => "format_args!(\"{__return_value:.150?}\")",
380+
};
381+
382+
String::from(return_value)
383+
}
384+
368385
/// To enable architecture-specific logic
369386
fn rust_scalar_type(&self) -> String {
370387
format!(

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

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,49 @@ impl DebugHexF16 for __m512i {
206206
debug_simd_finish(f, "__m512i", &array)
207207
}
208208
}
209-
"#;
209+
210+
trait DebugI16 {
211+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result;
212+
}
213+
214+
impl DebugI16 for i16 {
215+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
216+
write!(f, "{}", self)
217+
}
218+
}
219+
220+
impl DebugI16 for __m128i {
221+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
222+
let array = unsafe { core::mem::transmute::<_, [i16; 8]>(*self) };
223+
debug_simd_finish(f, "__m128i", &array)
224+
}
225+
}
226+
227+
impl DebugI16 for __m256i {
228+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
229+
let array = unsafe { core::mem::transmute::<_, [i16; 16]>(*self) };
230+
debug_simd_finish(f, "__m256i", &array)
231+
}
232+
}
233+
234+
impl DebugI16 for __m512i {
235+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
236+
let array = unsafe { core::mem::transmute::<_, [i16; 32]>(*self) };
237+
debug_simd_finish(f, "__m512i", &array)
238+
}
239+
}
240+
241+
fn debug_i16<T: DebugI16>(x: T) -> impl core::fmt::Debug {
242+
struct DebugWrapper<T>(T);
243+
impl<T: DebugI16> core::fmt::Debug for DebugWrapper<T> {
244+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
245+
self.0.fmt(f)
246+
}
247+
}
248+
DebugWrapper(x)
249+
}
250+
251+
"#;
210252

211253
pub const PLATFORM_C_FORWARD_DECLARATIONS: &str = r#"
212254
#ifndef X86_DECLARATIONS

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,4 +468,16 @@ impl X86IntrinsicType {
468468
// often return "null" type. Such intrinsics are not tested in `intrinsic-test`
469469
// currently and are filtered out at `mod.rs`.
470470
}
471+
472+
fn print_result_rust(&self) -> String {
473+
let return_value = match self.kind() {
474+
TypeKind::Float if self.inner_size() == 16 => "debug_f16(__return_value)",
475+
_ if ["__m128i", "__m256i", "__m512i"].contains(&self.param.type_data.as_str()) => {
476+
"debug_i16(__return_value)"
477+
}
478+
_ => "format_args!(\"{__return_value:.150?}\")",
479+
};
480+
481+
String::from(return_value)
482+
}
471483
}

0 commit comments

Comments
 (0)