|
1 | 1 | use std::fmt;
|
2 | 2 | use std::str::FromStr;
|
3 | 3 |
|
| 4 | +use itertools::Itertools as _; |
| 5 | + |
4 | 6 | use crate::values::value_for_array;
|
5 | 7 | use crate::Language;
|
6 | 8 |
|
@@ -288,82 +290,64 @@ impl IntrinsicType {
|
288 | 290 | }
|
289 | 291 | }
|
290 | 292 |
|
291 |
| - /// Generates a comma list of values that can be used to initialize the array that |
292 |
| - /// an argument for the intrinsic call is loaded from. |
| 293 | + /// Generates an initialiser for an array, which can be used to initialise an argument for the |
| 294 | + /// intrinsic call. |
| 295 | + /// |
293 | 296 | /// This is determistic based on the pass number.
|
294 | 297 | ///
|
295 | 298 | /// * `loads`: The number of values that need to be loaded from the argument array
|
296 | 299 | /// * e.g for argument type uint32x2, loads=2 results in a string representing 4 32-bit values
|
297 | 300 | ///
|
298 | 301 | /// Returns a string such as
|
299 |
| - /// * `0x1, 0x7F, 0xFF` if `language` is `Language::C` |
300 |
| - /// * `0x1 as _, 0x7F as _, 0xFF as _` if `language` is `Language::Rust` |
| 302 | + /// * `{0x1, 0x7F, 0xFF}` if `language` is `Language::C` |
| 303 | + /// * `[0x1 as _, 0x7F as _, 0xFF as _]` if `language` is `Language::Rust` |
301 | 304 | pub fn populate_random(&self, loads: u32, language: &Language) -> String {
|
302 | 305 | match self {
|
303 | 306 | IntrinsicType::Ptr { child, .. } => child.populate_random(loads, language),
|
304 | 307 | IntrinsicType::Type {
|
305 | 308 | bit_len: Some(bit_len),
|
306 |
| - kind, |
| 309 | + kind: TypeKind::Int | TypeKind::UInt | TypeKind::Poly, |
307 | 310 | simd_len,
|
308 | 311 | vec_len,
|
309 | 312 | ..
|
310 |
| - } if kind == &TypeKind::Int || kind == &TypeKind::UInt || kind == &TypeKind::Poly => (0 |
311 |
| - ..(simd_len.unwrap_or(1) * vec_len.unwrap_or(1) + loads - 1)) |
312 |
| - .map(|i| { |
313 |
| - format!( |
314 |
| - "{}{}", |
315 |
| - value_for_array(*bit_len, i), |
316 |
| - match language { |
317 |
| - &Language::Rust => format!(" as {ty} ", ty = self.rust_scalar_type()), |
318 |
| - &Language::C => String::from(""), |
319 |
| - } |
320 |
| - ) |
321 |
| - }) |
322 |
| - .collect::<Vec<_>>() |
323 |
| - .join(","), |
324 |
| - IntrinsicType::Type { |
325 |
| - kind: TypeKind::Float, |
326 |
| - bit_len: Some(32), |
327 |
| - simd_len, |
328 |
| - vec_len, |
329 |
| - .. |
330 |
| - } => (0..(simd_len.unwrap_or(1) * vec_len.unwrap_or(1) + loads - 1)) |
331 |
| - .map(|i| { |
332 |
| - format!( |
333 |
| - "{}({})", |
334 |
| - match language { |
335 |
| - &Language::Rust => "std::mem::transmute", |
336 |
| - &Language::C => "cast<float, uint32_t>", |
337 |
| - }, |
338 |
| - value_for_array(32, i), |
339 |
| - ) |
340 |
| - }) |
341 |
| - .collect::<Vec<_>>() |
342 |
| - .join(","), |
| 313 | + } => { |
| 314 | + let (prefix, as_type, suffix) = match language { |
| 315 | + &Language::Rust => ("[", format!(" as {}", self.rust_scalar_type()), "]"), |
| 316 | + &Language::C => ("{", "".into(), "}"), |
| 317 | + }; |
| 318 | + format!( |
| 319 | + "{prefix}{body}{suffix}", |
| 320 | + body = (0..(simd_len.unwrap_or(1) * vec_len.unwrap_or(1) + loads - 1)) |
| 321 | + .format_with(", ", |i, fmt| fmt(&format_args!( |
| 322 | + "{src}{as_type}", |
| 323 | + src = value_for_array(*bit_len, i) |
| 324 | + ))) |
| 325 | + ) |
| 326 | + } |
343 | 327 | IntrinsicType::Type {
|
344 | 328 | kind: TypeKind::Float,
|
345 |
| - bit_len: Some(64), |
| 329 | + bit_len: Some(bit_len @ (32 | 64)), |
346 | 330 | simd_len,
|
347 | 331 | vec_len,
|
348 | 332 | ..
|
349 |
| - } => (0..(simd_len.unwrap_or(1) * vec_len.unwrap_or(1) + loads - 1)) |
350 |
| - .map(|i| { |
351 |
| - format!( |
352 |
| - "{}({}{})", |
353 |
| - match language { |
354 |
| - &Language::Rust => "std::mem::transmute", |
355 |
| - &Language::C => "cast<double, uint64_t>", |
356 |
| - }, |
357 |
| - value_for_array(64, i), |
358 |
| - match language { |
359 |
| - &Language::Rust => " as u64", |
360 |
| - &Language::C => "", |
361 |
| - } |
362 |
| - ) |
363 |
| - }) |
364 |
| - .collect::<Vec<_>>() |
365 |
| - .join(","), |
366 |
| - _ => unreachable!("populate random: {:#?}", self), |
| 333 | + } => { |
| 334 | + let (prefix, cast_prefix, cast_suffix, suffix) = match (language, bit_len) { |
| 335 | + (&Language::Rust, 32) => ("[", "f32::from_bits(", ")", "]"), |
| 336 | + (&Language::Rust, 64) => ("[", "f64::from_bits(", ")", "]"), |
| 337 | + (&Language::C, 32) => ("{", "cast<float, uint32_t>(", ")", "}"), |
| 338 | + (&Language::C, 64) => ("{", "cast<double, uint64_t>(", ")", "}"), |
| 339 | + _ => unreachable!(), |
| 340 | + }; |
| 341 | + format!( |
| 342 | + "{prefix}{body}{suffix}", |
| 343 | + body = (0..(simd_len.unwrap_or(1) * vec_len.unwrap_or(1) + loads - 1)) |
| 344 | + .format_with(", ", |i, fmt| fmt(&format_args!( |
| 345 | + "{cast_prefix}{src}{cast_suffix}", |
| 346 | + src = value_for_array(*bit_len, i) |
| 347 | + ))) |
| 348 | + ) |
| 349 | + } |
| 350 | + _ => unimplemented!("populate random: {:#?}", self), |
367 | 351 | }
|
368 | 352 | }
|
369 | 353 |
|
|
0 commit comments