@@ -421,34 +421,50 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
421421 }
422422 }
423423 #[ rustfmt:: skip]
424- "cast" | "as" => {
424+ "cast" | "as" | "cast_ptr" | "expose_addr" | "from_exposed_addr" => {
425425 let [ op] = check_arg_count ( args) ?;
426426 let ( op, op_len) = this. operand_to_simd ( op) ?;
427427 let ( dest, dest_len) = this. place_to_simd ( dest) ?;
428428
429429 assert_eq ! ( dest_len, op_len) ;
430430
431+ let unsafe_cast = intrinsic_name == "cast" ;
431432 let safe_cast = intrinsic_name == "as" ;
433+ let ptr_cast = intrinsic_name == "cast_ptr" ;
434+ let expose_cast = intrinsic_name == "expose_addr" ;
435+ let from_exposed_cast = intrinsic_name == "from_exposed_addr" ;
432436
433437 for i in 0 ..dest_len {
434438 let op = this. read_immediate ( & this. mplace_index ( & op, i) ?. into ( ) ) ?;
435439 let dest = this. mplace_index ( & dest, i) ?;
436440
437441 let val = match ( op. layout . ty . kind ( ) , dest. layout . ty . kind ( ) ) {
438442 // Int-to-(int|float): always safe
439- ( ty:: Int ( _) | ty:: Uint ( _) , ty:: Int ( _) | ty:: Uint ( _) | ty:: Float ( _) ) =>
443+ ( ty:: Int ( _) | ty:: Uint ( _) , ty:: Int ( _) | ty:: Uint ( _) | ty:: Float ( _) ) if safe_cast || unsafe_cast =>
440444 this. int_to_int_or_float ( & op, dest. layout . ty ) ?,
441445 // Float-to-float: always safe
442- ( ty:: Float ( _) , ty:: Float ( _) ) =>
446+ ( ty:: Float ( _) , ty:: Float ( _) ) if safe_cast || unsafe_cast =>
443447 this. float_to_float_or_int ( & op, dest. layout . ty ) ?,
444448 // Float-to-int in safe mode
445449 ( ty:: Float ( _) , ty:: Int ( _) | ty:: Uint ( _) ) if safe_cast =>
446450 this. float_to_float_or_int ( & op, dest. layout . ty ) ?,
447451 // Float-to-int in unchecked mode
448- ( ty:: Float ( FloatTy :: F32 ) , ty:: Int ( _) | ty:: Uint ( _) ) if !safe_cast =>
452+ ( ty:: Float ( FloatTy :: F32 ) , ty:: Int ( _) | ty:: Uint ( _) ) if unsafe_cast =>
449453 this. float_to_int_unchecked ( op. to_scalar ( ) . to_f32 ( ) ?, dest. layout . ty ) ?. into ( ) ,
450- ( ty:: Float ( FloatTy :: F64 ) , ty:: Int ( _) | ty:: Uint ( _) ) if !safe_cast =>
454+ ( ty:: Float ( FloatTy :: F64 ) , ty:: Int ( _) | ty:: Uint ( _) ) if unsafe_cast =>
451455 this. float_to_int_unchecked ( op. to_scalar ( ) . to_f64 ( ) ?, dest. layout . ty ) ?. into ( ) ,
456+ // Ptr-to-ptr cast
457+ ( ty:: RawPtr ( ..) , ty:: RawPtr ( ..) ) if ptr_cast => {
458+ this. ptr_to_ptr ( & op, dest. layout . ty ) ?
459+ }
460+ // Ptr/Int casts
461+ ( ty:: RawPtr ( ..) , ty:: Int ( _) | ty:: Uint ( _) ) if expose_cast => {
462+ this. pointer_expose_address_cast ( & op, dest. layout . ty ) ?
463+ }
464+ ( ty:: Int ( _) | ty:: Uint ( _) , ty:: RawPtr ( ..) ) if from_exposed_cast => {
465+ this. pointer_from_exposed_address_cast ( & op, dest. layout . ty ) ?
466+ }
467+ // Error otherwise
452468 _ =>
453469 throw_unsup_format ! (
454470 "Unsupported SIMD cast from element type {from_ty} to {to_ty}" ,
0 commit comments