Skip to content

Commit 8438fb5

Browse files
feat: added the XML intrinsic parser for x86
1 parent b74725b commit 8438fb5

File tree

3 files changed

+91
-0
lines changed

3 files changed

+91
-0
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
use crate::common::constraint::Constraint;
2+
3+
pub fn map_constraints(imm_type: &String) -> Option<Constraint> {
4+
match imm_type.as_str() {
5+
"_MM_FROUND" => Some(Constraint::Range(0..4)),
6+
"_MM_INDEX_SCALE" => Some(Constraint::Set(vec![1, 2, 4, 8])),
7+
"_MM_CMPINT" => Some(Constraint::Range(0..8)),
8+
"_MM_REDUCE" => Some(Constraint::Range(0..8)),
9+
"_MM_FROUND_SAE" => Some(Constraint::Range(0..8)),
10+
"_MM_MANTISSA_NORM" => Some(Constraint::Range(0..4)),
11+
"_MM_MANTISSA_NORM_ENUM" => Some(Constraint::Range(0..4)),
12+
"_MM_MANTISSA_SIGN" => Some(Constraint::Range(0..3)),
13+
"_MM_PERM" => Some(Constraint::Range(0..256)),
14+
"_MM_PERM_ENUM" => Some(Constraint::Range(0..256)),
15+
"_MM_CMPINT_ENUM" => Some(Constraint::Range(0..8)),
16+
"_MM_ROUND_MODE" => Some(Constraint::Set(vec![0, 0x2000, 0x4000, 0x6000])),
17+
"_CMP_" => Some(Constraint::Range(0..32)),
18+
_ => None,
19+
}
20+
}

crates/intrinsic-test/src/x86/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
mod constraint;
12
mod intrinsic;
23
mod types;
34
mod xml_parser;

crates/intrinsic-test/src/x86/xml_parser.rs

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
1+
use crate::common::argument::{Argument, ArgumentList};
2+
use crate::common::intrinsic::Intrinsic;
3+
use crate::common::intrinsic_helpers::TypeKind;
4+
use crate::x86::constraint::map_constraints;
5+
16
use serde::{Deserialize, Deserializer};
7+
use std::path::Path;
28

9+
use super::intrinsic::X86IntrinsicType;
310

411
// Custom deserializer function to convert strings to u32
512
fn string_to_u32<'de, D>(deserializer: D) -> Result<u32, D::Error>
@@ -43,3 +50,66 @@ pub struct Parameter {
4350
#[serde(rename = "@immtype", default)]
4451
pub imm_type: String,
4552
}
53+
54+
pub fn get_xml_intrinsics(
55+
filename: &Path,
56+
) -> Result<Vec<Intrinsic<X86IntrinsicType>>, Box<dyn std::error::Error>> {
57+
let file = std::fs::File::open(filename)?;
58+
let reader = std::io::BufReader::new(file);
59+
let data: Data =
60+
quick_xml::de::from_reader(reader).expect("failed to deserialize the source XML file");
61+
62+
let parsed_intrinsics: Vec<Intrinsic<X86IntrinsicType>> = data
63+
.intrinsics
64+
.into_iter()
65+
.filter_map(|intr| {
66+
// Some(xml_to_intrinsic(intr, target).expect("Couldn't parse XML properly!"))
67+
xml_to_intrinsic(intr).ok()
68+
})
69+
.collect();
70+
71+
Ok(parsed_intrinsics)
72+
}
73+
74+
fn xml_to_intrinsic(
75+
intr: XMLIntrinsic,
76+
) -> Result<Intrinsic<X86IntrinsicType>, Box<dyn std::error::Error>> {
77+
let name = intr.name;
78+
let result = X86IntrinsicType::from_param(&intr.return_data);
79+
let args_check = intr.parameters.into_iter().enumerate().map(|(i, param)| {
80+
let ty = X86IntrinsicType::from_param(&param);
81+
if ty.is_err() {
82+
None
83+
} else {
84+
let constraint = map_constraints(&param.imm_type);
85+
let arg = Argument::<X86IntrinsicType>::new(
86+
i,
87+
param.var_name.clone(),
88+
ty.unwrap(),
89+
constraint,
90+
);
91+
Some(arg)
92+
}
93+
});
94+
95+
let args = args_check.collect::<Vec<_>>();
96+
if args.iter().any(|elem| elem.is_none()) {
97+
return Err(Box::from("intrinsic isn't fully supported in this test!"));
98+
}
99+
let args = args
100+
.into_iter()
101+
.map(|e| e.unwrap())
102+
.filter(|arg| arg.ty.ptr || arg.ty.kind != TypeKind::Void)
103+
.collect::<Vec<_>>();
104+
let arguments = ArgumentList::<X86IntrinsicType> { args };
105+
106+
if let Err(message) = result {
107+
return Err(Box::from(message));
108+
}
109+
Ok(Intrinsic {
110+
name,
111+
arguments,
112+
results: result.unwrap(),
113+
arch_tags: intr.cpuid,
114+
})
115+
}

0 commit comments

Comments
 (0)