Skip to content

Commit c009f9f

Browse files
Feat: started the skeleton for x86 module, added XML intrinsic parsing capabilities
1 parent a17a1b4 commit c009f9f

File tree

6 files changed

+217
-0
lines changed

6 files changed

+217
-0
lines changed

crates/intrinsic-test/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,5 @@ pretty_env_logger = "0.5.0"
2222
rayon = "1.5.0"
2323
diff = "0.1.12"
2424
itertools = "0.14.0"
25+
quick-xml = { version = "0.37.5", features = ["serialize", "overlapped-lists"] }
26+
serde-xml-rs = "0.8.0"

crates/intrinsic-test/src/main.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@ extern crate log;
33

44
mod arm;
55
mod common;
6+
mod x86;
67

78
use arm::ArmArchitectureTest;
89
use common::SupportedArchitectureTest;
910
use common::cli::{Cli, ProcessedCli};
11+
use x86::X86ArchitectureTest;
1012

1113
fn main() {
1214
pretty_env_logger::init();
@@ -21,6 +23,8 @@ fn main() {
2123
Some(ArmArchitectureTest::create(processed_cli_options))
2224
}
2325

26+
"x86_64-unknown-linux-gnu" => Some(X86ArchitectureTest::create(processed_cli_options)),
27+
2428
_ => None,
2529
};
2630

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
use crate::common::argument::ArgumentList;
2+
use crate::common::indentation::Indentation;
3+
use crate::common::intrinsic::{Intrinsic, IntrinsicDefinition};
4+
use crate::common::intrinsic_helpers::IntrinsicType;
5+
use std::ops::Deref;
6+
7+
#[derive(Debug, Clone, PartialEq)]
8+
pub struct X86IntrinsicType(pub IntrinsicType);
9+
10+
impl Deref for X86IntrinsicType {
11+
type Target = IntrinsicType;
12+
13+
fn deref(&self) -> &Self::Target {
14+
&self.0
15+
}
16+
}
17+
18+
impl IntrinsicDefinition<X86IntrinsicType> for Intrinsic<X86IntrinsicType> {
19+
fn arguments(&self) -> ArgumentList<X86IntrinsicType> {
20+
self.arguments.clone()
21+
}
22+
23+
fn results(&self) -> X86IntrinsicType {
24+
self.results.clone()
25+
}
26+
27+
fn name(&self) -> String {
28+
self.name.clone()
29+
}
30+
31+
/// Generates a std::cout for the intrinsics results that will match the
32+
/// rust debug output format for the return type. The generated line assumes
33+
/// there is an int i in scope which is the current pass number.
34+
fn print_result_c(&self, _indentation: Indentation, _additional: &str) -> String {
35+
todo!("print_result_c in Intrinsic<X86IntrinsicType> needs to be implemented!");
36+
}
37+
}

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

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
mod intrinsic;
2+
mod types;
3+
mod xml_parser;
4+
5+
use crate::common::SupportedArchitectureTest;
6+
use crate::common::cli::ProcessedCli;
7+
use crate::common::intrinsic::Intrinsic;
8+
use intrinsic::X86IntrinsicType;
9+
use xml_parser::get_xml_intrinsics;
10+
11+
pub struct X86ArchitectureTest {
12+
intrinsics: Vec<Intrinsic<X86IntrinsicType>>,
13+
cli_options: ProcessedCli,
14+
}
15+
16+
impl SupportedArchitectureTest for X86ArchitectureTest {
17+
fn create(cli_options: ProcessedCli) -> Box<Self> {
18+
let intrinsics = get_xml_intrinsics(&cli_options.filename, &cli_options.target)
19+
.expect("Error parsing input file");
20+
21+
Box::new(Self {
22+
intrinsics: intrinsics,
23+
cli_options: cli_options,
24+
})
25+
}
26+
27+
fn build_c_file(&self) -> bool {
28+
todo!("build_c_file in X86ArchitectureTest is not implemented")
29+
}
30+
31+
fn build_rust_file(&self) -> bool {
32+
todo!("build_rust_file in X86ArchitectureTest is not implemented")
33+
}
34+
35+
fn compare_outputs(&self) -> bool {
36+
todo!("compare_outputs in X86ArchitectureTest is not implemented")
37+
}
38+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
use super::intrinsic::X86IntrinsicType;
2+
use crate::common::cli::Language;
3+
use crate::common::intrinsic_helpers::IntrinsicTypeDefinition;
4+
5+
impl IntrinsicTypeDefinition for X86IntrinsicType {
6+
/// Gets a string containing the typename for this type in C format.
7+
fn c_type(&self) -> String {
8+
todo!("c_type for X86IntrinsicType needs to be implemented!");
9+
}
10+
11+
fn c_single_vector_type(&self) -> String {
12+
todo!("c_single_vector_type for X86IntrinsicType needs to be implemented!");
13+
}
14+
15+
fn rust_type(&self) -> String {
16+
todo!("rust_type for X86IntrinsicType needs to be implemented!");
17+
}
18+
19+
/// Determines the load function for this type.
20+
fn get_load_function(&self, language: Language) -> String {
21+
todo!("get_load_function for X86IntrinsicType needs to be implemented!");
22+
}
23+
24+
/// Determines the get lane function for this type.
25+
fn get_lane_function(&self) -> String {
26+
todo!("get_lane_function for X86IntrinsicType needs to be implemented!");
27+
}
28+
29+
fn from_c(s: &str, target: &String) -> Result<Self, String> {
30+
todo!("from_c for X86IntrinsicType needs to be implemented!");
31+
}
32+
}
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
use crate::common::{
2+
argument::Argument, intrinsic::Intrinsic, intrinsic_helpers::IntrinsicTypeDefinition,
3+
};
4+
use serde::{Deserialize, Deserializer};
5+
use std::path::Path;
6+
7+
use super::intrinsic::X86IntrinsicType;
8+
9+
// Custom deserializer function to convert "TRUE"/"FALSE" strings to boolean
10+
fn string_to_bool<'de, D>(deserializer: D) -> Result<bool, D::Error>
11+
where
12+
D: Deserializer<'de>,
13+
{
14+
let s = String::deserialize(deserializer)?;
15+
match s.as_str() {
16+
"TRUE" => Ok(true),
17+
"FALSE" => Ok(false),
18+
_ => Ok(false), // Default to false for any other value
19+
}
20+
}
21+
22+
#[derive(Deserialize)]
23+
struct Data {
24+
#[serde(rename = "intrinsic", default)]
25+
intrinsics: Vec<XMLIntrinsic>,
26+
}
27+
28+
#[derive(Deserialize)]
29+
struct XMLIntrinsic {
30+
#[serde(rename = "return")]
31+
return_data: Return,
32+
#[serde(rename = "@name")]
33+
name: String,
34+
#[serde(rename = "@tech")]
35+
tech: String,
36+
#[serde(rename = "CPUID", default)]
37+
cpuid: Vec<String>,
38+
#[serde(rename = "parameter", default)]
39+
parameters: Vec<Parameter>,
40+
#[serde(rename = "@sequence", default, deserialize_with = "string_to_bool")]
41+
generates_sequence: bool,
42+
#[serde(default)]
43+
instruction: Vec<Instruction>,
44+
}
45+
46+
#[derive(Deserialize)]
47+
struct Parameter {
48+
#[serde(rename = "@type")]
49+
type_data: String,
50+
#[serde(rename = "@etype", default)]
51+
etype: String,
52+
}
53+
54+
#[derive(Deserialize)]
55+
struct Return {
56+
#[serde(rename = "@type", default)]
57+
type_data: String,
58+
}
59+
60+
#[derive(Deserialize, Debug)]
61+
struct Instruction {
62+
#[serde(rename = "@name")]
63+
name: String,
64+
}
65+
66+
pub fn get_xml_intrinsics(
67+
filename: &Path,
68+
target: &String,
69+
) -> Result<Vec<Intrinsic<X86IntrinsicType>>, Box<dyn std::error::Error>> {
70+
let file = std::fs::File::open(filename)?;
71+
let reader = std::io::BufReader::new(file);
72+
let data: Data =
73+
quick_xml::de::from_reader(reader).expect("failed to deserialize the source XML file");
74+
75+
// println!("{} intrinsics found", data.intrinsics.len());
76+
let parsed_intrinsics: Vec<Intrinsic<X86IntrinsicType>> = data
77+
.intrinsics
78+
.into_iter()
79+
.filter_map(|intr| {
80+
Some(xml_to_intrinsic(intr, target).expect("Couldn't parse XML properly!"))
81+
})
82+
.collect();
83+
84+
Ok(parsed_intrinsics)
85+
}
86+
87+
pub fn xml_to_intrinsic(
88+
mut intr: XMLIntrinsic,
89+
target: &String,
90+
) -> Result<Intrinsic<X86IntrinsicType>, Box<dyn std::error::Error>> {
91+
let name = intr.name;
92+
let results = X86IntrinsicType::from_c(&intr.return_data.type_data, target)?;
93+
94+
let arguments: Vec<_> = intr
95+
.parameters
96+
.into_iter()
97+
.enumerate()
98+
.map(|(i, arg)| {
99+
// let arg_name = Argument::<X86IntrinsicType>::type_and_name_from_c(&arg).1;
100+
})
101+
.collect();
102+
103+
todo!("xml_to_intrinsic needs to collect the arguments properly!");
104+
}

0 commit comments

Comments
 (0)