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
+
1
6
use serde:: { Deserialize , Deserializer } ;
7
+ use std:: path:: Path ;
2
8
9
+ use super :: intrinsic:: X86IntrinsicType ;
3
10
4
11
// Custom deserializer function to convert strings to u32
5
12
fn string_to_u32 < ' de , D > ( deserializer : D ) -> Result < u32 , D :: Error >
@@ -43,3 +50,66 @@ pub struct Parameter {
43
50
#[ serde( rename = "@immtype" , default ) ]
44
51
pub imm_type : String ,
45
52
}
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