@@ -421,34 +421,50 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
421
421
}
422
422
}
423
423
#[ rustfmt:: skip]
424
- "cast" | "as" => {
424
+ "cast" | "as" | "cast_ptr" | "expose_addr" | "from_exposed_addr" => {
425
425
let [ op] = check_arg_count ( args) ?;
426
426
let ( op, op_len) = this. operand_to_simd ( op) ?;
427
427
let ( dest, dest_len) = this. place_to_simd ( dest) ?;
428
428
429
429
assert_eq ! ( dest_len, op_len) ;
430
430
431
+ let unsafe_cast = intrinsic_name == "cast" ;
431
432
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" ;
432
436
433
437
for i in 0 ..dest_len {
434
438
let op = this. read_immediate ( & this. mplace_index ( & op, i) ?. into ( ) ) ?;
435
439
let dest = this. mplace_index ( & dest, i) ?;
436
440
437
441
let val = match ( op. layout . ty . kind ( ) , dest. layout . ty . kind ( ) ) {
438
442
// 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 =>
440
444
this. int_to_int_or_float ( & op, dest. layout . ty ) ?,
441
445
// Float-to-float: always safe
442
- ( ty:: Float ( _) , ty:: Float ( _) ) =>
446
+ ( ty:: Float ( _) , ty:: Float ( _) ) if safe_cast || unsafe_cast =>
443
447
this. float_to_float_or_int ( & op, dest. layout . ty ) ?,
444
448
// Float-to-int in safe mode
445
449
( ty:: Float ( _) , ty:: Int ( _) | ty:: Uint ( _) ) if safe_cast =>
446
450
this. float_to_float_or_int ( & op, dest. layout . ty ) ?,
447
451
// 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 =>
449
453
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 =>
451
455
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
452
468
_ =>
453
469
throw_unsup_format ! (
454
470
"Unsupported SIMD cast from element type {from_ty} to {to_ty}" ,
0 commit comments