11use std:: str:: FromStr ;
22
3+ use itertools:: Itertools ;
4+
35use super :: intrinsic:: X86IntrinsicType ;
46use crate :: common:: cli:: Language ;
57use crate :: common:: intrinsic_helpers:: { IntrinsicType , IntrinsicTypeDefinition , TypeKind } ;
@@ -11,15 +13,9 @@ impl IntrinsicTypeDefinition for X86IntrinsicType {
1113 let part_1 = match self . kind {
1214 TypeKind :: Int ( false ) => "unsigned int" ,
1315 TypeKind :: Char ( false ) => "unsigned char" ,
14- TypeKind :: Short ( false ) => "unsigned short" ,
15- TypeKind :: Short ( true ) => "short" ,
1616 _ => self . kind . c_prefix ( ) ,
1717 } ;
18- let part_2 = if self . ptr {
19- if self . ptr_constant { "* const" } else { "*" }
20- } else {
21- ""
22- } ;
18+ let part_2 = if self . ptr { "*" } else { "" } ;
2319
2420 String :: from ( vec ! [ part_0, part_1, part_2] . join ( " " ) . trim ( ) )
2521 }
@@ -46,6 +42,7 @@ impl IntrinsicTypeDefinition for X86IntrinsicType {
4642 let mut s_copy = s. to_string ( ) ;
4743 s_copy = s_copy
4844 . replace ( "*" , "" )
45+ . replace ( "_" , "" )
4946 . replace ( "constexpr" , "" )
5047 . replace ( "const" , "" )
5148 . replace ( "literal" , "" ) ;
@@ -55,30 +52,25 @@ impl IntrinsicTypeDefinition for X86IntrinsicType {
5552 . filter_map ( |s| if s. len ( ) == 0 { None } else { Some ( s) } )
5653 . last ( ) ;
5754
58- // TODO: add more intrinsics by modifying
59- // functionality below this line.
60- // Currently all the intrinsics that have an "_"
61- // is ignored.
62- if let Some ( _) = s. matches ( "_" ) . next ( ) {
63- return Err ( String :: from ( "This functionality needs to be implemented" ) ) ;
64- } ;
55+ let s_split = s_split. map ( |s| s. chars ( ) . filter ( |c| !c. is_numeric ( ) ) . join ( "" ) ) ;
6556
6657 // TODO: make the unwrapping safe
67- let kind = TypeKind :: from_str ( s_split. unwrap ( ) ) . expect ( "Unable to parse type!" ) ;
68- let mut ptr_constant = false ;
69- let mut constant = false ;
70- let mut ptr = false ;
58+ let kind = TypeKind :: from_str ( s_split. unwrap ( ) . trim ( ) ) . unwrap_or ( TypeKind :: Void ) ;
7159
72- if let Some ( _ ) = s . matches ( "const* ") . next ( ) {
73- ptr_constant = true ;
74- } ;
75- if let Some ( _) = s . matches ( "const" ) . next ( ) {
76- constant = true ;
77- } ;
78- if let Some ( _ ) = s . matches ( "*" ) . next ( ) {
79- ptr = true ;
60+ let kind = if s . find ( "unsigned ") . is_some ( ) {
61+ match kind {
62+ TypeKind :: Int ( _ ) => TypeKind :: Int ( false ) ,
63+ TypeKind :: Char ( _) => TypeKind :: Char ( false ) ,
64+ a => a ,
65+ }
66+ } else {
67+ kind
8068 } ;
8169
70+ let ptr_constant = false ;
71+ let constant = s. matches ( "const" ) . next ( ) . is_some ( ) ;
72+ let ptr = s. matches ( "*" ) . next ( ) . is_some ( ) ;
73+
8274 Ok ( X86IntrinsicType ( IntrinsicType {
8375 ptr,
8476 ptr_constant,
@@ -91,3 +83,67 @@ impl IntrinsicTypeDefinition for X86IntrinsicType {
9183 } ) )
9284 }
9385}
86+
87+ impl X86IntrinsicType {
88+ pub fn from_param ( param : & Parameter ) -> Result < Self , String > {
89+ match Self :: from_c ( param. type_data . as_str ( ) ) {
90+ Err ( message) => Err ( message) ,
91+ Ok ( mut ret) => {
92+ // First correct the type of the parameter using param.etype.
93+ // The assumption is that the parameter of type void may have param.type
94+ // as "__m128i", "__mmask8" and the like.
95+ ret. set_metadata ( "etype" . to_string ( ) , param. etype . clone ( ) ) ;
96+ if !param. etype . is_empty ( ) {
97+ match TypeKind :: from_str ( param. etype . as_str ( ) ) {
98+ Ok ( value) => {
99+ ret. kind = value;
100+ }
101+ Err ( _) => { }
102+ } ;
103+ }
104+
105+ // check for param.etype.
106+ // extract the numeric part and set as bit-len
107+ // If param.etype is not present, guess the default bit-len
108+
109+ let mut etype_processed = param. etype . clone ( ) ;
110+ etype_processed. retain ( |c| c. is_numeric ( ) ) ;
111+
112+ match str:: parse :: < u32 > ( etype_processed. as_str ( ) ) {
113+ Ok ( value) => ret. bit_len = Some ( value) ,
114+ Err ( _) => {
115+ ret. bit_len = match ret. kind ( ) {
116+ TypeKind :: Char ( _) => Some ( 8 ) ,
117+ TypeKind :: BFloat => Some ( 16 ) ,
118+ TypeKind :: Int ( _) => Some ( 32 ) ,
119+ TypeKind :: Float => Some ( 32 ) ,
120+ _ => None ,
121+ } ;
122+ }
123+ }
124+
125+ // then check the param.type and extract numeric part if there are double
126+ // underscores. divide this number with bit-len and set this as simd-len.
127+
128+ let mut type_processed = param. etype . clone ( ) ;
129+ type_processed. retain ( |c| c. is_numeric ( ) ) ;
130+
131+ ret. vec_len = match str:: parse :: < u32 > ( etype_processed. as_str ( ) ) {
132+ // If bit_len is None, vec_len will be None.
133+ // Else vec_len will be (num_bits / bit_len).
134+ Ok ( num_bits) => ret. bit_len . and ( Some ( num_bits / ret. bit_len . unwrap ( ) ) ) ,
135+ Err ( _) => None ,
136+ } ;
137+
138+ // if param.etype == IMM, then it is a constant.
139+ // else it stays unchanged.
140+ ret. constant |= param. etype == "IMM" ;
141+
142+ Ok ( ret)
143+ }
144+ }
145+ // Tile types won't currently reach here, since the intrinsic that involve them
146+ // often return "null" type. Such intrinsics are not tested in `intrinsic-test`
147+ // currently and are filtered out at `mod.rs`.
148+ }
149+ }
0 commit comments