@@ -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,42 @@ 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)
123121 }
124122
125123 /// Determines the get lane function for this type.
126124 fn get_lane_function ( & self ) -> String {
127125 todo ! ( "get_lane_function for X86IntrinsicType needs to be implemented!" ) ;
128126 }
127+ }
129128
130- fn from_c ( s : & str ) -> Result < Self , String > {
129+ impl X86IntrinsicType {
130+ fn from_c ( s : & str ) -> Result < IntrinsicType , String > {
131131 let mut s_copy = s. to_string ( ) ;
132132 let mut metadata: HashMap < String , String > = HashMap :: new ( ) ;
133133 metadata. insert ( "type" . to_string ( ) , s. to_string ( ) ) ;
@@ -162,33 +162,28 @@ impl IntrinsicTypeDefinition for X86IntrinsicType {
162162 let constant = s. matches ( "const" ) . next ( ) . is_some ( ) ;
163163 let ptr = s. matches ( "*" ) . next ( ) . is_some ( ) ;
164164
165- Ok ( X86IntrinsicType ( IntrinsicType {
165+ Ok ( IntrinsicType {
166166 ptr,
167167 ptr_constant,
168168 constant,
169169 kind,
170170 bit_len : None ,
171171 simd_len : None ,
172172 vec_len : None ,
173- metadata,
174- } ) )
173+ } )
175174 }
176- }
177175
178- impl X86IntrinsicType {
179176 pub fn from_param ( param : & Parameter ) -> Result < Self , String > {
180177 match Self :: from_c ( param. type_data . as_str ( ) ) {
181178 Err ( message) => Err ( message) ,
182- Ok ( mut ret ) => {
179+ Ok ( mut data ) => {
183180 // First correct the type of the parameter using param.etype.
184181 // The assumption is that the parameter of type void may have param.type
185182 // 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 ( ) ) ;
188183 if !param. etype . is_empty ( ) {
189184 match TypeKind :: from_str ( param. etype . as_str ( ) ) {
190185 Ok ( value) => {
191- ret . kind = value;
186+ data . kind = value;
192187 }
193188 Err ( _) => { }
194189 } ;
@@ -202,9 +197,9 @@ impl X86IntrinsicType {
202197 etype_processed. retain ( |c| c. is_numeric ( ) ) ;
203198
204199 match str:: parse :: < u32 > ( etype_processed. as_str ( ) ) {
205- Ok ( value) => ret . bit_len = Some ( value) ,
200+ Ok ( value) => data . bit_len = Some ( value) ,
206201 Err ( _) => {
207- ret . bit_len = match ret . kind ( ) {
202+ data . bit_len = match data . kind ( ) {
208203 TypeKind :: Char ( _) => Some ( 8 ) ,
209204 TypeKind :: BFloat => Some ( 16 ) ,
210205 TypeKind :: Int ( _) => Some ( 32 ) ,
@@ -222,26 +217,29 @@ impl X86IntrinsicType {
222217 {
223218 let mut type_processed = param. type_data . clone ( ) ;
224219 type_processed. retain ( |c| c. is_numeric ( ) ) ;
225- ret . vec_len = match str:: parse :: < u32 > ( type_processed. as_str ( ) ) {
220+ data . vec_len = match str:: parse :: < u32 > ( type_processed. as_str ( ) ) {
226221 // If bit_len is None, vec_len will be None.
227222 // Else vec_len will be (num_bits / bit_len).
228- Ok ( num_bits) => ret . bit_len . and ( Some ( num_bits / ret . bit_len . unwrap ( ) ) ) ,
223+ Ok ( num_bits) => data . bit_len . and ( Some ( num_bits / data . bit_len . unwrap ( ) ) ) ,
229224 Err ( _) => None ,
230225 } ;
231226 }
232227
233228 // default settings for "void *" parameters
234229 // 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 ) ;
230+ if data . kind == TypeKind :: Void && data . ptr {
231+ data . kind = TypeKind :: Int ( Sign :: Unsigned ) ;
232+ data . bit_len = Some ( 8 ) ;
238233 }
239234
240235 // if param.etype == IMM, then it is a constant.
241236 // else it stays unchanged.
242- ret . constant |= param. etype == "IMM" ;
237+ data . constant |= param. etype == "IMM" ;
243238
244- Ok ( ret)
239+ Ok ( X86IntrinsicType {
240+ data,
241+ param : param. clone ( ) ,
242+ } )
245243 }
246244 }
247245 // Tile types won't currently reach here, since the intrinsic that involve them
0 commit comments