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+
16use serde:: { Deserialize , Deserializer } ;
7+ use std:: path:: Path ;
28
9+ use super :: intrinsic:: X86IntrinsicType ;
310
411// Custom deserializer function to convert strings to u32
512fn 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