@@ -115,6 +115,10 @@ impl IntrinsicTypeDefinition for X86IntrinsicType {
115115 // if "type" starts with __m<num>{h/i/<null>},
116116 // then use either _mm_set1_epi64,
117117 // _mm256_set1_epi64 or _mm512_set1_epi64
118+ if type_value. contains ( "__m64" ) {
119+ return String :: from ( "*(__m64*)" ) ;
120+ }
121+
118122 let type_val_filtered = type_value
119123 . chars ( )
120124 . filter ( |c| c. is_numeric ( ) )
@@ -126,12 +130,11 @@ impl IntrinsicTypeDefinition for X86IntrinsicType {
126130 ( Some ( bit_len @ ( 8 | 16 | 32 | 64 ) ) , TypeKind :: Int ( _) ) => {
127131 format ! ( "epi{bit_len}" )
128132 }
133+ ( Some ( bit_len) , TypeKind :: Mask ) => format ! ( "epi{bit_len}" ) ,
129134 ( Some ( 16 ) , TypeKind :: Float ) => format ! ( "ph" ) ,
130135 ( Some ( 32 ) , TypeKind :: Float ) => format ! ( "ps" ) ,
131136 ( 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" ) ,
135138 _ => unreachable ! ( "Invalid element type for a vector type! {:?}" , self . param) ,
136139 } ;
137140 format ! ( "_mm{type_val_filtered}_loadu_{suffix}" )
@@ -252,17 +255,18 @@ impl IntrinsicTypeDefinition for X86IntrinsicType {
252255 }
253256
254257 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+ } ;
263263
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}" )
266270 }
267271}
268272
@@ -311,6 +315,26 @@ impl X86IntrinsicType {
311315 } )
312316 }
313317
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+
314338 pub fn from_param ( param : & Parameter ) -> Result < Self , String > {
315339 match Self :: from_c ( param. type_data . as_str ( ) ) {
316340 Err ( message) => Err ( message) ,
@@ -350,22 +374,26 @@ impl X86IntrinsicType {
350374 }
351375 }
352376
353- if param. type_data . matches ( "__mmask" ) . next ( ) . is_some ( ) {
377+ if param. type_data . contains ( "__mmask" ) {
354378 data. bit_len = str:: parse :: < u32 > ( type_processed. as_str ( ) ) . ok ( ) ;
355379 }
356380
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+ }
369397 }
370398
371399 // default settings for "void *" parameters
@@ -381,22 +409,35 @@ impl X86IntrinsicType {
381409 data. bit_len = Some ( 32 ) ;
382410 }
383411
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-
389412 if param. etype == "IMM" || param. imm_width > 0 || param. imm_type . len ( ) > 0 {
413+ data. kind = TypeKind :: Int ( Sign :: Unsigned ) ;
390414 data. constant = true ;
391415 }
392416
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 {
397435 data,
398436 param : param. clone ( ) ,
399- } )
437+ } ;
438+
439+ result. update_simd_len ( ) ;
440+ Ok ( result)
400441 }
401442 }
402443 // Tile types won't currently reach here, since the intrinsic that involve them
0 commit comments