@@ -815,6 +815,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
815
815
| "atanf"
816
816
| "log1pf"
817
817
| "expm1f"
818
+ | "tgammaf"
818
819
=> {
819
820
let [ f] = this. check_shim ( abi, Abi :: C { unwind : false } , link_name, args) ?;
820
821
// FIXME: Using host floats.
@@ -830,6 +831,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
830
831
"atanf" => f. atan ( ) ,
831
832
"log1pf" => f. ln_1p ( ) ,
832
833
"expm1f" => f. exp_m1 ( ) ,
834
+ "tgammaf" => f. gamma ( ) ,
833
835
_ => bug ! ( ) ,
834
836
} ;
835
837
this. write_scalar ( Scalar :: from_u32 ( res. to_bits ( ) ) , dest) ?;
@@ -866,6 +868,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
866
868
| "atan"
867
869
| "log1p"
868
870
| "expm1"
871
+ | "tgamma"
869
872
=> {
870
873
let [ f] = this. check_shim ( abi, Abi :: C { unwind : false } , link_name, args) ?;
871
874
// FIXME: Using host floats.
@@ -881,6 +884,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
881
884
"atan" => f. atan ( ) ,
882
885
"log1p" => f. ln_1p ( ) ,
883
886
"expm1" => f. exp_m1 ( ) ,
887
+ "tgamma" => f. gamma ( ) ,
884
888
_ => bug ! ( ) ,
885
889
} ;
886
890
this. write_scalar ( Scalar :: from_u64 ( res. to_bits ( ) ) , dest) ?;
@@ -917,6 +921,53 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
917
921
let res = x. scalbn ( exp) ;
918
922
this. write_scalar ( Scalar :: from_f64 ( res) , dest) ?;
919
923
}
924
+ "lgammaf_r" => {
925
+ let [ x, signp] = this. check_shim ( abi, Abi :: C { unwind : false } , link_name, args) ?;
926
+ // FIXME: Using host floats.
927
+ let x = f32:: from_bits ( this. read_scalar ( x) ?. to_u32 ( ) ?) ;
928
+ let signp = this. deref_pointer ( signp) ?;
929
+
930
+ let ( res, sign) = x. ln_gamma ( ) ;
931
+ this. write_int ( sign, & signp) ?;
932
+ this. write_scalar ( Scalar :: from_u32 ( res. to_bits ( ) ) , dest) ?;
933
+ }
934
+ "lgamma_r" => {
935
+ let [ x, signp] = this. check_shim ( abi, Abi :: C { unwind : false } , link_name, args) ?;
936
+ // FIXME: Using host floats.
937
+ let x = f64:: from_bits ( this. read_scalar ( x) ?. to_u64 ( ) ?) ;
938
+ let signp = this. deref_pointer ( signp) ?;
939
+
940
+ let ( res, sign) = x. ln_gamma ( ) ;
941
+ this. write_int ( sign, & signp) ?;
942
+ this. write_scalar ( Scalar :: from_u64 ( res. to_bits ( ) ) , dest) ?;
943
+ }
944
+
945
+ "llvm.prefetch" => {
946
+ let [ p, rw, loc, ty] =
947
+ this. check_shim ( abi, Abi :: C { unwind : false } , link_name, args) ?;
948
+
949
+ let _ = this. read_pointer ( p) ?;
950
+ let rw = this. read_scalar ( rw) ?. to_i32 ( ) ?;
951
+ let loc = this. read_scalar ( loc) ?. to_i32 ( ) ?;
952
+ let ty = this. read_scalar ( ty) ?. to_i32 ( ) ?;
953
+
954
+ if ty == 1 {
955
+ // Data cache prefetch.
956
+ // Notably, we do not have to check the pointer, this operation is never UB!
957
+
958
+ if !matches ! ( rw, 0 | 1 ) {
959
+ throw_unsup_format ! ( "invalid `rw` value passed to `llvm.prefetch`: {}" , rw) ;
960
+ }
961
+ if !matches ! ( loc, 0 ..=3 ) {
962
+ throw_unsup_format ! (
963
+ "invalid `loc` value passed to `llvm.prefetch`: {}" ,
964
+ loc
965
+ ) ;
966
+ }
967
+ } else {
968
+ throw_unsup_format ! ( "unsupported `llvm.prefetch` type argument: {}" , ty) ;
969
+ }
970
+ }
920
971
921
972
// Architecture-specific shims
922
973
"llvm.x86.addcarry.64" if this. tcx . sess . target . arch == "x86_64" => {
@@ -970,6 +1021,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
970
1021
}
971
1022
}
972
1023
1024
+ name if name. starts_with ( "llvm.x86.sse." ) => {
1025
+ return shims:: x86:: sse:: EvalContextExt :: emulate_x86_sse_intrinsic (
1026
+ this, link_name, abi, args, dest,
1027
+ ) ;
1028
+ }
1029
+
973
1030
// Platform-specific shims
974
1031
_ =>
975
1032
return match this. tcx . sess . target . os . as_ref ( ) {
0 commit comments