@@ -13,18 +13,16 @@ impl IntrinsicTypeDefinition for X86IntrinsicType {
1313 /// Gets a string containing the type in C format.
1414 /// This function assumes that this value is present in the metadata hashmap.
1515 fn c_type ( & self ) -> String {
16- self . metadata
17- . get ( "type" )
18- . expect ( "Failed to extract the C typename in X86!" )
19- . to_string ( )
16+ self . param . type_data . clone ( )
2017 }
2118
2219 fn c_single_vector_type ( & self ) -> String {
2320 // matches __m128, __m256 and similar types
2421 let re = Regex :: new ( r"\__m\d+\" ) . unwrap ( ) ;
25- match self . metadata . get ( "type" ) {
26- Some ( type_data) if re. is_match ( type_data) => type_data. to_string ( ) ,
27- _ => unreachable ! ( "Shouldn't be called on this type" ) ,
22+ if re. is_match ( self . param . type_data . as_str ( ) ) {
23+ self . param . type_data . clone ( )
24+ } else {
25+ unreachable ! ( "Shouldn't be called on this type" )
2826 }
2927 }
3028
@@ -94,40 +92,43 @@ impl IntrinsicTypeDefinition for X86IntrinsicType {
9492
9593 /// Determines the load function for this type.
9694 fn get_load_function ( & self , _language : Language ) -> String {
97- if let Some ( type_value) = self . metadata . get ( "type" ) {
98- if type_value. starts_with ( "__mmask" ) {
99- // no need of loads, since they work directly
100- // with hex constants
101- String :: from ( "*" )
102- } else if type_value. starts_with ( "__m" ) {
103- // the structure is like the follows:
104- // if "type" starts with __m<num>{h/i/<null>},
105- // then use either _mm_set1_epi64,
106- // _mm256_set1_epi64 or _mm512_set1_epi64
107- let type_val_filtered = type_value
108- . chars ( )
109- . filter ( |c| c. is_numeric ( ) )
110- . join ( "" )
111- . replace ( "128" , "" ) ;
112- format ! ( "_mm{type_val_filtered}_set1_epi64" )
113- } else {
114- // if it is a pointer, then rely on type conversion
115- // If it is not any of the above type (__int<num>, __bfloat16, unsigned short, etc)
116- // then typecast it.
117- format ! ( "({type_value})" )
118- }
119- // Look for edge cases (constexpr, literal, etc)
120- } else {
95+ let type_value = self . param . type_data . clone ( ) ;
96+ if type_value. len ( ) == 0 {
12197 unimplemented ! ( "the value for key 'type' is not present!" ) ;
12298 }
99+ if type_value. starts_with ( "__mmask" ) {
100+ // no need of loads, since they work directly
101+ // with hex constants
102+ String :: from ( "*" )
103+ } else if type_value. starts_with ( "__m" ) {
104+ // the structure is like the follows:
105+ // if "type" starts with __m<num>{h/i/<null>},
106+ // then use either _mm_set1_epi64,
107+ // _mm256_set1_epi64 or _mm512_set1_epi64
108+ let type_val_filtered = type_value
109+ . chars ( )
110+ . filter ( |c| c. is_numeric ( ) )
111+ . join ( "" )
112+ . replace ( "128" , "" ) ;
113+ format ! ( "_mm{type_val_filtered}_set1_epi64" )
114+ } else {
115+ // if it is a pointer, then rely on type conversion
116+ // If it is not any of the above type (__int<num>, __bfloat16, unsigned short, etc)
117+ // then typecast it.
118+ format ! ( "({type_value})" )
119+ }
120+ // Look for edge cases (constexpr, literal, etc)
121+
123122 }
124123
125124 /// Determines the get lane function for this type.
126125 fn get_lane_function ( & self ) -> String {
127126 todo ! ( "get_lane_function for X86IntrinsicType needs to be implemented!" ) ;
128127 }
128+ }
129129
130- fn from_c ( s : & str ) -> Result < Self , String > {
130+ impl X86IntrinsicType {
131+ fn from_c ( s : & str ) -> Result < IntrinsicType , String > {
131132 let mut s_copy = s. to_string ( ) ;
132133 let mut metadata: HashMap < String , String > = HashMap :: new ( ) ;
133134 metadata. insert ( "type" . to_string ( ) , s. to_string ( ) ) ;
@@ -162,33 +163,28 @@ impl IntrinsicTypeDefinition for X86IntrinsicType {
162163 let constant = s. matches ( "const" ) . next ( ) . is_some ( ) ;
163164 let ptr = s. matches ( "*" ) . next ( ) . is_some ( ) ;
164165
165- Ok ( X86IntrinsicType ( IntrinsicType {
166+ Ok ( IntrinsicType {
166167 ptr,
167168 ptr_constant,
168169 constant,
169170 kind,
170171 bit_len : None ,
171172 simd_len : None ,
172173 vec_len : None ,
173- metadata,
174- } ) )
174+ } )
175175 }
176- }
177-
178- impl X86IntrinsicType {
176+
179177 pub fn from_param ( param : & Parameter ) -> Result < Self , String > {
180178 match Self :: from_c ( param. type_data . as_str ( ) ) {
181179 Err ( message) => Err ( message) ,
182- Ok ( mut ret ) => {
180+ Ok ( mut data ) => {
183181 // First correct the type of the parameter using param.etype.
184182 // The assumption is that the parameter of type void may have param.type
185183 // as "__m128i", "__mmask8" and the like.
186- ret. set_metadata ( "etype" . to_string ( ) , param. etype . clone ( ) ) ;
187- ret. set_metadata ( "memwidth" . to_string ( ) , param. memwidth . to_string ( ) ) ;
188184 if !param. etype . is_empty ( ) {
189185 match TypeKind :: from_str ( param. etype . as_str ( ) ) {
190186 Ok ( value) => {
191- ret . kind = value;
187+ data . kind = value;
192188 }
193189 Err ( _) => { }
194190 } ;
@@ -202,9 +198,9 @@ impl X86IntrinsicType {
202198 etype_processed. retain ( |c| c. is_numeric ( ) ) ;
203199
204200 match str:: parse :: < u32 > ( etype_processed. as_str ( ) ) {
205- Ok ( value) => ret . bit_len = Some ( value) ,
201+ Ok ( value) => data . bit_len = Some ( value) ,
206202 Err ( _) => {
207- ret . bit_len = match ret . kind ( ) {
203+ data . bit_len = match data . kind ( ) {
208204 TypeKind :: Char ( _) => Some ( 8 ) ,
209205 TypeKind :: BFloat => Some ( 16 ) ,
210206 TypeKind :: Int ( _) => Some ( 32 ) ,
@@ -222,26 +218,26 @@ impl X86IntrinsicType {
222218 {
223219 let mut type_processed = param. type_data . clone ( ) ;
224220 type_processed. retain ( |c| c. is_numeric ( ) ) ;
225- ret . vec_len = match str:: parse :: < u32 > ( type_processed. as_str ( ) ) {
221+ data . vec_len = match str:: parse :: < u32 > ( type_processed. as_str ( ) ) {
226222 // If bit_len is None, vec_len will be None.
227223 // Else vec_len will be (num_bits / bit_len).
228- Ok ( num_bits) => ret . bit_len . and ( Some ( num_bits / ret . bit_len . unwrap ( ) ) ) ,
224+ Ok ( num_bits) => data . bit_len . and ( Some ( num_bits / data . bit_len . unwrap ( ) ) ) ,
229225 Err ( _) => None ,
230226 } ;
231227 }
232228
233229 // default settings for "void *" parameters
234230 // often used by intrinsics to denote memory address or so.
235- if ret . kind == TypeKind :: Void && ret . ptr {
236- ret . kind = TypeKind :: Int ( Sign :: Unsigned ) ;
237- ret . bit_len = Some ( 8 ) ;
231+ if data . kind == TypeKind :: Void && data . ptr {
232+ data . kind = TypeKind :: Int ( Sign :: Unsigned ) ;
233+ data . bit_len = Some ( 8 ) ;
238234 }
239235
240236 // if param.etype == IMM, then it is a constant.
241237 // else it stays unchanged.
242- ret . constant |= param. etype == "IMM" ;
238+ data . constant |= param. etype == "IMM" ;
243239
244- Ok ( ret )
240+ Ok ( X86IntrinsicType { data , param : param . clone ( ) } )
245241 }
246242 }
247243 // Tile types won't currently reach here, since the intrinsic that involve them
0 commit comments