blob: 773dabf4d75b19985a9fdc7b46bcb6bc229d2300 [file] [log] [blame]
use crate::common::argument::ArgumentList;
use crate::common::indentation::Indentation;
use crate::common::intrinsic::{Intrinsic, IntrinsicDefinition};
use crate::common::intrinsic_helpers::{IntrinsicType, IntrinsicTypeDefinition, TypeKind};
use std::ops::Deref;
#[derive(Debug, Clone, PartialEq)]
pub struct ArmIntrinsicType(pub IntrinsicType);
impl Deref for ArmIntrinsicType {
type Target = IntrinsicType;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl IntrinsicDefinition<ArmIntrinsicType> for Intrinsic<ArmIntrinsicType> {
fn arguments(&self) -> ArgumentList<ArmIntrinsicType> {
self.arguments.clone()
}
fn results(&self) -> ArmIntrinsicType {
self.results.clone()
}
fn name(&self) -> String {
self.name.clone()
}
/// 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 {
let lanes = if self.results().num_vectors() > 1 {
(0..self.results().num_vectors())
.map(|vector| {
format!(
r#""{ty}(" << {lanes} << ")""#,
ty = self.results().c_single_vector_type(),
lanes = (0..self.results().num_lanes())
.map(move |idx| -> std::string::String {
format!(
"{cast}{lane_fn}(__return_value.val[{vector}], {lane})",
cast = self.results().c_promotion(),
lane_fn = self.results().get_lane_function(),
lane = idx,
vector = vector,
)
})
.collect::<Vec<_>>()
.join(r#" << ", " << "#)
)
})
.collect::<Vec<_>>()
.join(r#" << ", " << "#)
} else if self.results().num_lanes() > 1 {
(0..self.results().num_lanes())
.map(|idx| -> std::string::String {
format!(
"{cast}{lane_fn}(__return_value, {lane})",
cast = self.results().c_promotion(),
lane_fn = self.results().get_lane_function(),
lane = idx
)
})
.collect::<Vec<_>>()
.join(r#" << ", " << "#)
} else {
format!(
"{promote}cast<{cast}>(__return_value)",
cast = match self.results.kind() {
TypeKind::Float if self.results().inner_size() == 16 => "float16_t".to_string(),
TypeKind::Float if self.results().inner_size() == 32 => "float".to_string(),
TypeKind::Float if self.results().inner_size() == 64 => "double".to_string(),
TypeKind::Int => format!("int{}_t", self.results().inner_size()),
TypeKind::UInt => format!("uint{}_t", self.results().inner_size()),
TypeKind::Poly => format!("poly{}_t", self.results().inner_size()),
ty => todo!("print_result_c - Unknown type: {:#?}", ty),
},
promote = self.results().c_promotion(),
)
};
format!(
r#"{indentation}std::cout << "Result {additional}-" << i+1 << ": {ty}" << std::fixed << std::setprecision(150) << {lanes} << "{close}" << std::endl;"#,
ty = if self.results().is_simd() {
format!("{}(", self.results().c_type())
} else {
String::from("")
},
close = if self.results.is_simd() { ")" } else { "" },
)
}
}