@@ -67,7 +67,7 @@ static TUPLE: Type = Type::Tuple;
67
67
static CPUID : Type = Type :: CpuidResult ;
68
68
static NEVER : Type = Type :: Never ;
69
69
70
- #[ derive( Debug ) ]
70
+ #[ derive( Debug , PartialEq , Copy , Clone ) ]
71
71
enum Type {
72
72
PrimFloat ( u8 ) ,
73
73
PrimSigned ( u8 ) ,
@@ -520,7 +520,7 @@ fn matches(rust: &Function, intel: &Intrinsic) -> Result<(), String> {
520
520
521
521
// Make sure we've got the right return type.
522
522
if let Some ( t) = rust. ret {
523
- equate ( t, & intel. return_ . type_ , "" , rust . name , false ) ?;
523
+ equate ( t, & intel. return_ . type_ , "" , intel , false ) ?;
524
524
} else if !intel. return_ . type_ . is_empty ( ) && intel. return_ . type_ != "void" {
525
525
bail ! (
526
526
"{} returns `{}` with intel, void in rust" ,
@@ -542,7 +542,7 @@ fn matches(rust: &Function, intel: &Intrinsic) -> Result<(), String> {
542
542
}
543
543
for ( i, ( a, b) ) in intel. parameters . iter ( ) . zip ( rust. arguments ) . enumerate ( ) {
544
544
let is_const = rust. required_const . contains ( & i) ;
545
- equate ( b, & a. type_ , & a. etype , & intel. name , is_const) ?;
545
+ equate ( b, & a. type_ , & a. etype , & intel, is_const) ?;
546
546
}
547
547
}
548
548
@@ -655,11 +655,59 @@ fn matches(rust: &Function, intel: &Intrinsic) -> Result<(), String> {
655
655
Ok ( ( ) )
656
656
}
657
657
658
+ fn pointed_type ( intrinsic : & Intrinsic ) -> Result < Type , String > {
659
+ Ok (
660
+ if intrinsic. tech == "AMX"
661
+ || intrinsic
662
+ . cpuid
663
+ . iter ( )
664
+ . any ( |cpuid| matches ! ( & * * cpuid, "KEYLOCKER" | "KEYLOCKER_WIDE" | "XSAVE" | "FXSR" ) )
665
+ {
666
+ // AMX, KEYLOCKER and XSAVE intrinsics should take `*u8`
667
+ U8
668
+ } else if intrinsic. name == "_mm_clflush" {
669
+ // Just a false match in the following logic
670
+ U8
671
+ } else if [ "_mm_storeu_si" , "_mm_loadu_si" ]
672
+ . iter ( )
673
+ . any ( |x| intrinsic. name . starts_with ( x) )
674
+ {
675
+ // These have already been stabilized, so cannot be changed anymore
676
+ U8
677
+ } else if intrinsic. name . ends_with ( "i8" ) {
678
+ I8
679
+ } else if intrinsic. name . ends_with ( "i16" ) {
680
+ I16
681
+ } else if intrinsic. name . ends_with ( "i32" ) {
682
+ I32
683
+ } else if intrinsic. name . ends_with ( "i64" ) {
684
+ I64
685
+ } else if intrinsic. name . ends_with ( "i128" ) {
686
+ M128I
687
+ } else if intrinsic. name . ends_with ( "i256" ) {
688
+ M256I
689
+ } else if intrinsic. name . ends_with ( "i512" ) {
690
+ M512I
691
+ } else if intrinsic. name . ends_with ( "h" ) {
692
+ F16
693
+ } else if intrinsic. name . ends_with ( "s" ) {
694
+ F32
695
+ } else if intrinsic. name . ends_with ( "d" ) {
696
+ F64
697
+ } else {
698
+ bail ! (
699
+ "Don't know what type of *void to use for {}" ,
700
+ intrinsic. name
701
+ ) ;
702
+ } ,
703
+ )
704
+ }
705
+
658
706
fn equate (
659
707
t : & Type ,
660
708
intel : & str ,
661
709
etype : & str ,
662
- intrinsic : & str ,
710
+ intrinsic : & Intrinsic ,
663
711
is_const : bool ,
664
712
) -> Result < ( ) , String > {
665
713
// Make pointer adjacent to the type: float * foo => float* foo
@@ -676,7 +724,7 @@ fn equate(
676
724
if etype == "IMM" || intel == "constexpr int" {
677
725
// The _bittest intrinsics claim to only accept immediates but actually
678
726
// accept run-time values as well.
679
- if !is_const && !intrinsic. starts_with ( "_bittest" ) {
727
+ if !is_const && !intrinsic. name . starts_with ( "_bittest" ) {
680
728
bail ! ( "argument required to be const but isn't" ) ;
681
729
}
682
730
} else {
@@ -723,7 +771,16 @@ fn equate(
723
771
( & Type :: MMASK16 , "__mmask16" ) => { }
724
772
( & Type :: MMASK8 , "__mmask8" ) => { }
725
773
726
- ( & Type :: MutPtr ( _) , "void*" ) => { }
774
+ ( & Type :: MutPtr ( _type) , "void*" ) | ( & Type :: ConstPtr ( _type) , "void const*" ) => {
775
+ let pointed_type = pointed_type ( intrinsic) ?;
776
+ if _type != & pointed_type {
777
+ bail ! (
778
+ "incorrect void pointer type {_type:?} in {}, should be pointer to {pointed_type:?}" ,
779
+ intrinsic. name,
780
+ ) ;
781
+ }
782
+ }
783
+
727
784
( & Type :: MutPtr ( & Type :: PrimFloat ( 32 ) ) , "float*" ) => { }
728
785
( & Type :: MutPtr ( & Type :: PrimFloat ( 64 ) ) , "double*" ) => { }
729
786
( & Type :: MutPtr ( & Type :: PrimSigned ( 8 ) ) , "char*" ) => { }
@@ -752,7 +809,6 @@ fn equate(
752
809
( & Type :: MutPtr ( & Type :: M512I ) , "__m512i*" ) => { }
753
810
( & Type :: MutPtr ( & Type :: M512D ) , "__m512d*" ) => { }
754
811
755
- ( & Type :: ConstPtr ( _) , "void const*" ) => { }
756
812
( & Type :: ConstPtr ( & Type :: PrimFloat ( 16 ) ) , "_Float16 const*" ) => { }
757
813
( & Type :: ConstPtr ( & Type :: PrimFloat ( 32 ) ) , "float const*" ) => { }
758
814
( & Type :: ConstPtr ( & Type :: PrimFloat ( 64 ) ) , "double const*" ) => { }
@@ -792,34 +848,32 @@ fn equate(
792
848
// This is a macro (?) in C which seems to mutate its arguments, but
793
849
// that means that we're taking pointers to arguments in rust
794
850
// as we're not exposing it as a macro.
795
- ( & Type :: MutPtr ( & Type :: M128 ) , "__m128" ) if intrinsic == "_MM_TRANSPOSE4_PS" => { }
851
+ ( & Type :: MutPtr ( & Type :: M128 ) , "__m128" ) if intrinsic. name == "_MM_TRANSPOSE4_PS" => { }
796
852
797
853
// The _rdtsc intrinsic uses a __int64 return type, but this is a bug in
798
854
// the intrinsics guide: https://github.com/rust-lang/stdarch/issues/559
799
855
// We have manually fixed the bug by changing the return type to `u64`.
800
- ( & Type :: PrimUnsigned ( 64 ) , "__int64" ) if intrinsic == "_rdtsc" => { }
856
+ ( & Type :: PrimUnsigned ( 64 ) , "__int64" ) if intrinsic. name == "_rdtsc" => { }
801
857
802
858
// The _bittest and _bittest64 intrinsics takes a mutable pointer in the
803
859
// intrinsics guide even though it never writes through the pointer:
804
- ( & Type :: ConstPtr ( & Type :: PrimSigned ( 32 ) ) , "__int32*" ) if intrinsic == "_bittest" => { }
805
- ( & Type :: ConstPtr ( & Type :: PrimSigned ( 64 ) ) , "__int64*" ) if intrinsic == "_bittest64" => { }
860
+ ( & Type :: ConstPtr ( & Type :: PrimSigned ( 32 ) ) , "__int32*" ) if intrinsic. name == "_bittest" => { }
861
+ ( & Type :: ConstPtr ( & Type :: PrimSigned ( 64 ) ) , "__int64*" ) if intrinsic. name == "_bittest64" => { }
806
862
// The _xrstor, _fxrstor, _xrstor64, _fxrstor64 intrinsics take a
807
863
// mutable pointer in the intrinsics guide even though they never write
808
864
// through the pointer:
809
865
( & Type :: ConstPtr ( & Type :: PrimUnsigned ( 8 ) ) , "void*" )
810
- if intrinsic == "_xrstor"
811
- || intrinsic == "_xrstor64"
812
- || intrinsic == "_fxrstor"
813
- || intrinsic == "_fxrstor64" => { }
866
+ if matches ! (
867
+ & * intrinsic. name ,
868
+ "_xrstor" | "_xrstor64" | "_fxrstor" | "_fxrstor64 "
869
+ ) => { }
814
870
// The _mm_stream_load_si128 intrinsic take a mutable pointer in the intrinsics
815
871
// guide even though they never write through the pointer
816
- ( & Type :: ConstPtr ( & Type :: M128I ) , "void*" ) if intrinsic == "_mm_stream_load_si128" => { }
872
+ ( & Type :: ConstPtr ( & Type :: M128I ) , "void*" ) if intrinsic. name == "_mm_stream_load_si128" => { }
817
873
818
874
_ => bail ! (
819
- "failed to equate: `{}` and {:?} for {}" ,
820
- intel,
821
- t,
822
- intrinsic
875
+ "failed to equate: `{intel}` and {t:?} for {}" ,
876
+ intrinsic. name
823
877
) ,
824
878
}
825
879
Ok ( ( ) )
0 commit comments