@@ -190,11 +190,99 @@ fn generate_rust_program(notices: &str, intrinsic: &Intrinsic, target: &str) ->
190190 . filter ( |i| i. has_constraint ( ) )
191191 . collect_vec ( ) ;
192192
193+ // Format f16 values (and vectors containing them) in a way that is consistent with C.
194+ let f16_formatting = r#"
195+ /// Used to continue `Debug`ging SIMD types as `MySimd(1, 2, 3, 4)`, as they
196+ /// were before moving to array-based simd.
197+ #[inline]
198+ fn debug_simd_finish<T: core::fmt::Debug, const N: usize>(
199+ formatter: &mut core::fmt::Formatter<'_>,
200+ type_name: &str,
201+ array: &[T; N],
202+ ) -> core::fmt::Result {
203+ core::fmt::Formatter::debug_tuple_fields_finish(
204+ formatter,
205+ type_name,
206+ &core::array::from_fn::<&dyn core::fmt::Debug, N, _>(|i| &array[i]),
207+ )
208+ }
209+
210+ #[repr(transparent)]
211+ struct Hex<T>(T);
212+
213+ impl<T: DebugHexF16> core::fmt::Debug for Hex<T> {
214+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
215+ <T as DebugHexF16>::fmt(&self.0, f)
216+ }
217+ }
218+
219+ fn debug_f16<T: DebugHexF16>(x: T) -> impl core::fmt::Debug {
220+ Hex(x)
221+ }
222+
223+ trait DebugHexF16 {
224+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result;
225+ }
226+
227+ impl DebugHexF16 for f16 {
228+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
229+ write!(f, "{:#06x?}", self.to_bits())
230+ }
231+ }
232+
233+ impl DebugHexF16 for float16x4_t {
234+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
235+ let array = unsafe { core::mem::transmute::<_, [Hex<f16>; 4]>(*self) };
236+ debug_simd_finish(f, "float16x4_t", &array)
237+ }
238+ }
239+
240+ impl DebugHexF16 for float16x8_t {
241+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
242+ let array = unsafe { core::mem::transmute::<_, [Hex<f16>; 8]>(*self) };
243+ debug_simd_finish(f, "float16x8_t", &array)
244+ }
245+ }
246+
247+ impl DebugHexF16 for float16x4x2_t {
248+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
249+ debug_simd_finish(f, "float16x4x2_t", &[Hex(self.0), Hex(self.1)])
250+ }
251+ }
252+ impl DebugHexF16 for float16x4x3_t {
253+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
254+ debug_simd_finish(f, "float16x4x3_t", &[Hex(self.0), Hex(self.1), Hex(self.2)])
255+ }
256+ }
257+ impl DebugHexF16 for float16x4x4_t {
258+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
259+ debug_simd_finish(f, "float16x4x4_t", &[Hex(self.0), Hex(self.1), Hex(self.2), Hex(self.3)])
260+ }
261+ }
262+
263+ impl DebugHexF16 for float16x8x2_t {
264+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
265+ debug_simd_finish(f, "float16x8x2_t", &[Hex(self.0), Hex(self.1)])
266+ }
267+ }
268+ impl DebugHexF16 for float16x8x3_t {
269+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
270+ debug_simd_finish(f, "float16x8x3_t", &[Hex(self.0), Hex(self.1), Hex(self.2)])
271+ }
272+ }
273+ impl DebugHexF16 for float16x8x4_t {
274+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
275+ debug_simd_finish(f, "float16x8x4_t", &[Hex(self.0), Hex(self.1), Hex(self.2), Hex(self.3)])
276+ }
277+ }
278+ "# ;
279+
193280 let indentation = Indentation :: default ( ) ;
194281 format ! (
195282 r#"{notices}#![feature(simd_ffi)]
196283#![feature(link_llvm_intrinsics)]
197284#![feature(f16)]
285+ #![feature(fmt_helpers_for_derive)]
198286#![cfg_attr(target_arch = "arm", feature(stdarch_arm_neon_intrinsics))]
199287#![cfg_attr(target_arch = "arm", feature(stdarch_aarch32_crc32))]
200288#![cfg_attr(any(target_arch = "aarch64", target_arch = "arm64ec"), feature(stdarch_neon_fcma))]
@@ -207,6 +295,8 @@ fn generate_rust_program(notices: &str, intrinsic: &Intrinsic, target: &str) ->
207295#![allow(non_upper_case_globals)]
208296use core_arch::arch::{target_arch}::*;
209297
298+ {f16_formatting}
299+
210300fn main() {{
211301{arglists}
212302{passes}
0 commit comments