blob: bc46ccfbac40c8804a0b84771303609a3d5e8638 [file] [log] [blame]
use super::argument::ArgumentList;
use super::indentation::Indentation;
use super::intrinsic_helpers::{IntrinsicTypeDefinition, TypeKind};
/// An intrinsic
#[derive(Debug, PartialEq, Clone)]
pub struct Intrinsic<T: IntrinsicTypeDefinition> {
/// The function name of this intrinsic.
pub name: String,
/// Any arguments for this intrinsic.
pub arguments: ArgumentList<T>,
/// The return type of this intrinsic.
pub results: T,
/// Any architecture-specific tags.
pub arch_tags: Vec<String>,
}
pub trait IntrinsicDefinition<T>
where
T: IntrinsicTypeDefinition,
{
fn arguments(&self) -> ArgumentList<T>;
fn results(&self) -> T;
fn name(&self) -> String;
/// Generates a std::cout for the intrinsics results that will match the
/// rust debug output format for the return type. The generated line assumes
/// there is an int i in scope which is the current pass number.
fn print_result_c(&self, _indentation: Indentation, _additional: &str) -> String;
}
pub fn format_f16_return_value<T: IntrinsicTypeDefinition>(
intrinsic: &dyn IntrinsicDefinition<T>,
) -> String {
// the `intrinsic-test` crate compares the output of C and Rust intrinsics. Currently, It uses
// a string representation of the output value to compare. In C, f16 values are currently printed
// as hexadecimal integers. Since https://github.com/rust-lang/rust/pull/127013, rust does print
// them as decimal floating point values. To keep the intrinsics tests working, for now, format
// vectors containing f16 values like C prints them.
let return_value = match intrinsic.results().kind() {
TypeKind::Float if intrinsic.results().inner_size() == 16 => "debug_f16(__return_value)",
_ => "format_args!(\"{__return_value:.150?}\")",
};
String::from(return_value)
}