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