@@ -13,18 +13,16 @@ impl IntrinsicTypeDefinition for X86IntrinsicType {
13
13
/// Gets a string containing the type in C format.
14
14
/// This function assumes that this value is present in the metadata hashmap.
15
15
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 ( )
20
17
}
21
18
22
19
fn c_single_vector_type ( & self ) -> String {
23
20
// matches __m128, __m256 and similar types
24
21
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" )
28
26
}
29
27
}
30
28
@@ -94,40 +92,43 @@ impl IntrinsicTypeDefinition for X86IntrinsicType {
94
92
95
93
/// Determines the load function for this type.
96
94
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 {
121
97
unimplemented ! ( "the value for key 'type' is not present!" ) ;
122
98
}
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
+
123
122
}
124
123
125
124
/// Determines the get lane function for this type.
126
125
fn get_lane_function ( & self ) -> String {
127
126
todo ! ( "get_lane_function for X86IntrinsicType needs to be implemented!" ) ;
128
127
}
128
+ }
129
129
130
- fn from_c ( s : & str ) -> Result < Self , String > {
130
+ impl X86IntrinsicType {
131
+ fn from_c ( s : & str ) -> Result < IntrinsicType , String > {
131
132
let mut s_copy = s. to_string ( ) ;
132
133
let mut metadata: HashMap < String , String > = HashMap :: new ( ) ;
133
134
metadata. insert ( "type" . to_string ( ) , s. to_string ( ) ) ;
@@ -162,33 +163,28 @@ impl IntrinsicTypeDefinition for X86IntrinsicType {
162
163
let constant = s. matches ( "const" ) . next ( ) . is_some ( ) ;
163
164
let ptr = s. matches ( "*" ) . next ( ) . is_some ( ) ;
164
165
165
- Ok ( X86IntrinsicType ( IntrinsicType {
166
+ Ok ( IntrinsicType {
166
167
ptr,
167
168
ptr_constant,
168
169
constant,
169
170
kind,
170
171
bit_len : None ,
171
172
simd_len : None ,
172
173
vec_len : None ,
173
- metadata,
174
- } ) )
174
+ } )
175
175
}
176
- }
177
-
178
- impl X86IntrinsicType {
176
+
179
177
pub fn from_param ( param : & Parameter ) -> Result < Self , String > {
180
178
match Self :: from_c ( param. type_data . as_str ( ) ) {
181
179
Err ( message) => Err ( message) ,
182
- Ok ( mut ret ) => {
180
+ Ok ( mut data ) => {
183
181
// First correct the type of the parameter using param.etype.
184
182
// The assumption is that the parameter of type void may have param.type
185
183
// 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 ( ) ) ;
188
184
if !param. etype . is_empty ( ) {
189
185
match TypeKind :: from_str ( param. etype . as_str ( ) ) {
190
186
Ok ( value) => {
191
- ret . kind = value;
187
+ data . kind = value;
192
188
}
193
189
Err ( _) => { }
194
190
} ;
@@ -202,9 +198,9 @@ impl X86IntrinsicType {
202
198
etype_processed. retain ( |c| c. is_numeric ( ) ) ;
203
199
204
200
match str:: parse :: < u32 > ( etype_processed. as_str ( ) ) {
205
- Ok ( value) => ret . bit_len = Some ( value) ,
201
+ Ok ( value) => data . bit_len = Some ( value) ,
206
202
Err ( _) => {
207
- ret . bit_len = match ret . kind ( ) {
203
+ data . bit_len = match data . kind ( ) {
208
204
TypeKind :: Char ( _) => Some ( 8 ) ,
209
205
TypeKind :: BFloat => Some ( 16 ) ,
210
206
TypeKind :: Int ( _) => Some ( 32 ) ,
@@ -222,26 +218,26 @@ impl X86IntrinsicType {
222
218
{
223
219
let mut type_processed = param. type_data . clone ( ) ;
224
220
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 ( ) ) {
226
222
// If bit_len is None, vec_len will be None.
227
223
// 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 ( ) ) ) ,
229
225
Err ( _) => None ,
230
226
} ;
231
227
}
232
228
233
229
// default settings for "void *" parameters
234
230
// 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 ) ;
238
234
}
239
235
240
236
// if param.etype == IMM, then it is a constant.
241
237
// else it stays unchanged.
242
- ret . constant |= param. etype == "IMM" ;
238
+ data . constant |= param. etype == "IMM" ;
243
239
244
- Ok ( ret )
240
+ Ok ( X86IntrinsicType { data , param : param . clone ( ) } )
245
241
}
246
242
}
247
243
// Tile types won't currently reach here, since the intrinsic that involve them
0 commit comments