added target field within IntrinsicType to perform target level checking cleanly

This commit is contained in:
Madhav Madhusoodanan 2025-04-14 06:10:27 +05:30 committed by Amanieu d'Antras
parent 9927915e58
commit 9d3c09ed53
4 changed files with 26 additions and 12 deletions

View file

@ -79,10 +79,10 @@ impl Argument {
}
// ARM-specific
pub fn from_c(pos: usize, arg: &str, arg_prep: Option<ArgPrep>) -> Argument {
pub fn from_c(pos: usize, arg: &str, arg_prep: Option<ArgPrep>, target: &String) -> Argument {
let (ty, var_name) = Self::type_and_name_from_c(arg);
let ty = IntrinsicType::from_c(ty)
let ty = IntrinsicType::from_c(ty, target)
.unwrap_or_else(|_| panic!("Failed to parse argument '{arg}'"));
let constraint = arg_prep.and_then(|a| a.try_into().ok());

View file

@ -41,7 +41,10 @@ struct JsonIntrinsic {
architectures: Vec<String>,
}
pub fn get_neon_intrinsics(filename: &Path) -> Result<Vec<Intrinsic>, Box<dyn std::error::Error>> {
pub fn get_neon_intrinsics(
filename: &Path,
target: &String,
) -> Result<Vec<Intrinsic>, Box<dyn std::error::Error>> {
let file = std::fs::File::open(filename)?;
let reader = std::io::BufReader::new(file);
let json: Vec<JsonIntrinsic> = serde_json::from_reader(reader).expect("Couldn't parse JSON");
@ -50,7 +53,7 @@ pub fn get_neon_intrinsics(filename: &Path) -> Result<Vec<Intrinsic>, Box<dyn st
.into_iter()
.filter_map(|intr| {
if intr.simd_isa == "Neon" {
Some(json_to_intrinsic(intr).expect("Couldn't parse JSON"))
Some(json_to_intrinsic(intr, target).expect("Couldn't parse JSON"))
} else {
None
}
@ -59,10 +62,13 @@ pub fn get_neon_intrinsics(filename: &Path) -> Result<Vec<Intrinsic>, Box<dyn st
Ok(parsed)
}
fn json_to_intrinsic(mut intr: JsonIntrinsic) -> Result<Intrinsic, Box<dyn std::error::Error>> {
fn json_to_intrinsic(
mut intr: JsonIntrinsic,
target: &String,
) -> Result<Intrinsic, Box<dyn std::error::Error>> {
let name = intr.name.replace(['[', ']'], "");
let results = IntrinsicType::from_c(&intr.return_type.value)?;
let results = IntrinsicType::from_c(&intr.return_type.value, target)?;
let mut args_prep = intr.args_prep.as_mut();
let args = intr
@ -72,7 +78,7 @@ fn json_to_intrinsic(mut intr: JsonIntrinsic) -> Result<Intrinsic, Box<dyn std::
.map(|(i, arg)| {
let arg_name = Argument::type_and_name_from_c(&arg).1;
let arg_prep = args_prep.as_mut().and_then(|a| a.remove(arg_name));
let mut arg = Argument::from_c(i, &arg, arg_prep);
let mut arg = Argument::from_c(i, &arg, arg_prep, target);
// The JSON doesn't list immediates as const
if let IntrinsicType::Type {
ref mut constant, ..

View file

@ -22,8 +22,8 @@ pub struct ArmArchitectureTest {
impl SupportedArchitectureTest for ArmArchitectureTest {
fn create(cli_options: ProcessedCli) -> Self {
let a32 = cli_options.target.contains("v7");
let mut intrinsics =
get_neon_intrinsics(&cli_options.filename).expect("Error parsing input file");
let mut intrinsics = get_neon_intrinsics(&cli_options.filename, &cli_options.target)
.expect("Error parsing input file");
intrinsics.sort_by(|a, b| a.name.cmp(&b.name));

View file

@ -97,6 +97,8 @@ pub enum IntrinsicType {
/// rows encoded in the type (e.g. uint8x8_t).
/// A value of `None` can be assumed to be 1 though.
vec_len: Option<u32>,
target: String,
},
}
@ -393,6 +395,7 @@ impl IntrinsicType {
bit_len: Some(bl),
simd_len,
vec_len,
target,
..
} => {
let quad = if simd_len.unwrap_or(1) * bl > 64 {
@ -400,6 +403,8 @@ impl IntrinsicType {
} else {
""
};
let choose_workaround = language == Language::C && target.contains("v7");
format!(
"vld{len}{quad}_{type}{size}",
type = match k {
@ -407,7 +412,8 @@ impl IntrinsicType {
TypeKind::Int => "s",
TypeKind::Float => "f",
// The ACLE doesn't support 64-bit polynomial loads on Armv7
TypeKind::Poly => if language == Language::C && *bl == 64 {"s"} else {"p"},
// if armv7 and bl == 64, use "s", else "p"
TypeKind::Poly => if choose_workaround && *bl == 64 {"s"} else {"p"},
x => todo!("get_load_function TypeKind: {:#?}", x),
},
size = bl,
@ -462,7 +468,7 @@ impl IntrinsicType {
}
/// ARM-specific
pub fn from_c(s: &str) -> Result<IntrinsicType, String> {
pub fn from_c(s: &str, target: &String) -> Result<IntrinsicType, String> {
const CONST_STR: &str = "const";
if let Some(s) = s.strip_suffix('*') {
let (s, constant) = match s.trim().strip_suffix(CONST_STR) {
@ -472,7 +478,7 @@ impl IntrinsicType {
let s = s.trim_end();
Ok(IntrinsicType::Ptr {
constant,
child: Box::new(IntrinsicType::from_c(s)?),
child: Box::new(IntrinsicType::from_c(s, target)?),
})
} else {
// [const ]TYPE[{bitlen}[x{simdlen}[x{vec_len}]]][_t]
@ -507,6 +513,7 @@ impl IntrinsicType {
bit_len: Some(bit_len),
simd_len,
vec_len,
target: target.to_string(),
})
} else {
let kind = start.parse::<TypeKind>()?;
@ -520,6 +527,7 @@ impl IntrinsicType {
bit_len,
simd_len: None,
vec_len: None,
target: target.to_string(),
})
}
}