@@ -115,6 +115,10 @@ impl IntrinsicTypeDefinition for X86IntrinsicType {
115
115
// if "type" starts with __m<num>{h/i/<null>},
116
116
// then use either _mm_set1_epi64,
117
117
// _mm256_set1_epi64 or _mm512_set1_epi64
118
+ if type_value. contains ( "__m64" ) {
119
+ return String :: from ( "*(__m64*)" ) ;
120
+ }
121
+
118
122
let type_val_filtered = type_value
119
123
. chars ( )
120
124
. filter ( |c| c. is_numeric ( ) )
@@ -126,12 +130,11 @@ impl IntrinsicTypeDefinition for X86IntrinsicType {
126
130
( Some ( bit_len @ ( 8 | 16 | 32 | 64 ) ) , TypeKind :: Int ( _) ) => {
127
131
format ! ( "epi{bit_len}" )
128
132
}
133
+ ( Some ( bit_len) , TypeKind :: Mask ) => format ! ( "epi{bit_len}" ) ,
129
134
( Some ( 16 ) , TypeKind :: Float ) => format ! ( "ph" ) ,
130
135
( Some ( 32 ) , TypeKind :: Float ) => format ! ( "ps" ) ,
131
136
( Some ( 64 ) , TypeKind :: Float ) => format ! ( "pd" ) ,
132
- ( Some ( 128 ) , TypeKind :: Vector ) => format ! ( "si128" ) ,
133
- ( Some ( 256 ) , TypeKind :: Vector ) => format ! ( "si256" ) ,
134
- ( Some ( 512 ) , TypeKind :: Vector ) => format ! ( "si512" ) ,
137
+ ( Some ( 128 | 256 | 512 ) , TypeKind :: Vector ) => format ! ( "epi32" ) ,
135
138
_ => unreachable ! ( "Invalid element type for a vector type! {:?}" , self . param) ,
136
139
} ;
137
140
format ! ( "_mm{type_val_filtered}_loadu_{suffix}" )
@@ -252,17 +255,18 @@ impl IntrinsicTypeDefinition for X86IntrinsicType {
252
255
}
253
256
254
257
fn rust_scalar_type ( & self ) -> String {
255
- let re = Regex :: new ( r"\__m\d+[a-z]*" ) . unwrap ( ) ;
256
- if let Some ( match_type) = re. find ( self . param . type_data . as_str ( ) ) {
257
- match_type. as_str ( ) . to_string ( )
258
- } else {
259
- let prefix = match self . data . kind {
260
- TypeKind :: Mask => String :: from ( "__mmask" ) ,
261
- _ => self . kind ( ) . rust_prefix ( ) . to_string ( ) ,
262
- } ;
258
+ let prefix = match self . data . kind {
259
+ TypeKind :: Mask => String :: from ( "__mmask" ) ,
260
+ TypeKind :: Vector => String :: from ( "i" ) ,
261
+ _ => self . kind ( ) . rust_prefix ( ) . to_string ( ) ,
262
+ } ;
263
263
264
- format ! ( "{prefix}{bits}" , bits = self . inner_size( ) )
265
- }
264
+ let bits = if self . inner_size ( ) >= 128 {
265
+ 32
266
+ } else {
267
+ self . inner_size ( )
268
+ } ;
269
+ format ! ( "{prefix}{bits}" )
266
270
}
267
271
}
268
272
@@ -311,6 +315,26 @@ impl X86IntrinsicType {
311
315
} )
312
316
}
313
317
318
+ pub fn update_simd_len ( & mut self ) {
319
+ let mut type_processed = self . param . type_data . clone ( ) ;
320
+ type_processed. retain ( |c| c. is_numeric ( ) ) ;
321
+
322
+ // check the param.type and extract numeric part if there are double
323
+ // underscores. divide this number with bit-len and set this as simd-len.
324
+ // Only __m<int> types can have a simd-len.
325
+ if self . param . type_data . contains ( "__m" ) && !self . param . type_data . contains ( "__mmask" ) {
326
+ self . data . simd_len = match str:: parse :: < u32 > ( type_processed. as_str ( ) ) {
327
+ // If bit_len is None, simd_len will be None.
328
+ // Else simd_len will be (num_bits / bit_len).
329
+ Ok ( num_bits) => self
330
+ . data
331
+ . bit_len
332
+ . and_then ( |bit_len| Some ( num_bits / bit_len) ) ,
333
+ Err ( _) => None ,
334
+ } ;
335
+ }
336
+ }
337
+
314
338
pub fn from_param ( param : & Parameter ) -> Result < Self , String > {
315
339
match Self :: from_c ( param. type_data . as_str ( ) ) {
316
340
Err ( message) => Err ( message) ,
@@ -350,22 +374,26 @@ impl X86IntrinsicType {
350
374
}
351
375
}
352
376
353
- if param. type_data . matches ( "__mmask" ) . next ( ) . is_some ( ) {
377
+ if param. type_data . contains ( "__mmask" ) {
354
378
data. bit_len = str:: parse :: < u32 > ( type_processed. as_str ( ) ) . ok ( ) ;
355
379
}
356
380
357
- // then check the param.type and extract numeric part if there are double
358
- // underscores. divide this number with bit-len and set this as simd-len.
359
- // Only __m<int> types can have a simd-len.
360
- if param. type_data . matches ( "__m" ) . next ( ) . is_some ( )
361
- && param. type_data . matches ( "__mmask" ) . next ( ) . is_none ( )
362
- {
363
- data. simd_len = match str:: parse :: < u32 > ( type_processed. as_str ( ) ) {
364
- // If bit_len is None, simd_len will be None.
365
- // Else simd_len will be (num_bits / bit_len).
366
- Ok ( num_bits) => data. bit_len . and_then ( |bit_len| Some ( num_bits / bit_len) ) ,
367
- Err ( _) => None ,
368
- } ;
381
+ if vec ! [ "M512" , "M256" , "M128" ] . contains ( & param. etype . as_str ( ) ) {
382
+ match param. type_data . chars ( ) . last ( ) {
383
+ Some ( 'i' ) => {
384
+ data. kind = TypeKind :: Int ( Sign :: Signed ) ;
385
+ data. bit_len = Some ( 32 ) ;
386
+ }
387
+ Some ( 'h' ) => {
388
+ data. kind = TypeKind :: Float ;
389
+ data. bit_len = Some ( 16 ) ;
390
+ }
391
+ Some ( 'd' ) => {
392
+ data. kind = TypeKind :: Float ;
393
+ data. bit_len = Some ( 64 ) ;
394
+ }
395
+ _ => ( ) ,
396
+ }
369
397
}
370
398
371
399
// default settings for "void *" parameters
@@ -381,22 +409,35 @@ impl X86IntrinsicType {
381
409
data. bit_len = Some ( 32 ) ;
382
410
}
383
411
384
- // default settings for IMM parameters
385
- if param. etype == "IMM" && param. imm_width > 0 {
386
- data. bit_len = Some ( param. imm_width ) ;
387
- }
388
-
389
412
if param. etype == "IMM" || param. imm_width > 0 || param. imm_type . len ( ) > 0 {
413
+ data. kind = TypeKind :: Int ( Sign :: Unsigned ) ;
390
414
data. constant = true ;
391
415
}
392
416
393
- // if param.etype == IMM, then it is a constant.
394
- // else it stays unchanged.
395
- data. constant |= param. etype == "IMM" ;
396
- Ok ( X86IntrinsicType {
417
+ // Rust defaults to signed variants, unless they are explicitly mentioned
418
+ // the `type` field are C++ types.
419
+ if data. kind == TypeKind :: Int ( Sign :: Unsigned )
420
+ && !( param. type_data . contains ( "unsigned" ) || param. type_data . contains ( "uint" ) )
421
+ {
422
+ data. kind = TypeKind :: Int ( Sign :: Signed )
423
+ }
424
+
425
+ // default settings for IMM parameters
426
+ if param. etype == "IMM" {
427
+ data. bit_len = if param. imm_width > 0 {
428
+ Some ( param. imm_width )
429
+ } else {
430
+ Some ( 8 )
431
+ }
432
+ }
433
+
434
+ let mut result = X86IntrinsicType {
397
435
data,
398
436
param : param. clone ( ) ,
399
- } )
437
+ } ;
438
+
439
+ result. update_simd_len ( ) ;
440
+ Ok ( result)
400
441
}
401
442
}
402
443
// Tile types won't currently reach here, since the intrinsic that involve them
0 commit comments