@@ -436,6 +436,141 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
436436 return Ok ( bx. vector_select ( args[ 0 ] . immediate ( ) , args[ 1 ] . immediate ( ) , args[ 2 ] . immediate ( ) ) ) ;
437437 }
438438
439+ if name == sym:: simd_cast_ptr {
440+ require_simd ! ( ret_ty, InvalidMonomorphization :: SimdReturn { span, name, ty: ret_ty } ) ;
441+ let ( out_len, out_elem) = ret_ty. simd_size_and_type ( bx. tcx ( ) ) ;
442+
443+ require ! (
444+ in_len == out_len,
445+ InvalidMonomorphization :: ReturnLengthInputType {
446+ span,
447+ name,
448+ in_len,
449+ in_ty,
450+ ret_ty,
451+ out_len
452+ }
453+ ) ;
454+
455+ match * in_elem. kind ( ) {
456+ ty:: RawPtr ( p_ty, _) => {
457+ let metadata = p_ty. ptr_metadata_ty ( bx. tcx , |ty| {
458+ bx. tcx . normalize_erasing_regions ( ty:: ParamEnv :: reveal_all ( ) , ty)
459+ } ) ;
460+ require ! (
461+ metadata. is_unit( ) ,
462+ InvalidMonomorphization :: CastFatPointer { span, name, ty: in_elem }
463+ ) ;
464+ }
465+ _ => {
466+ return_error ! ( InvalidMonomorphization :: ExpectedPointer { span, name, ty: in_elem } )
467+ }
468+ }
469+ match * out_elem. kind ( ) {
470+ ty:: RawPtr ( p_ty, _) => {
471+ let metadata = p_ty. ptr_metadata_ty ( bx. tcx , |ty| {
472+ bx. tcx . normalize_erasing_regions ( ty:: ParamEnv :: reveal_all ( ) , ty)
473+ } ) ;
474+ require ! (
475+ metadata. is_unit( ) ,
476+ InvalidMonomorphization :: CastFatPointer { span, name, ty: out_elem }
477+ ) ;
478+ }
479+ _ => {
480+ return_error ! ( InvalidMonomorphization :: ExpectedPointer { span, name, ty: out_elem } )
481+ }
482+ }
483+
484+ let arg = args[ 0 ] . immediate ( ) ;
485+ let elem_type = llret_ty. dyncast_vector ( ) . expect ( "vector return type" ) . get_element_type ( ) ;
486+ let values: Vec < _ > = ( 0 ..in_len)
487+ . map ( |i| {
488+ let idx = bx. gcc_int ( bx. usize_type , i as _ ) ;
489+ let value = bx. extract_element ( arg, idx) ;
490+ bx. pointercast ( value, elem_type)
491+ } )
492+ . collect ( ) ;
493+ return Ok ( bx. context . new_rvalue_from_vector ( bx. location , llret_ty, & values) ) ;
494+ }
495+
496+ if name == sym:: simd_expose_provenance {
497+ require_simd ! ( ret_ty, InvalidMonomorphization :: SimdReturn { span, name, ty: ret_ty } ) ;
498+ let ( out_len, out_elem) = ret_ty. simd_size_and_type ( bx. tcx ( ) ) ;
499+
500+ require ! (
501+ in_len == out_len,
502+ InvalidMonomorphization :: ReturnLengthInputType {
503+ span,
504+ name,
505+ in_len,
506+ in_ty,
507+ ret_ty,
508+ out_len
509+ }
510+ ) ;
511+
512+ match * in_elem. kind ( ) {
513+ ty:: RawPtr ( _, _) => { }
514+ _ => {
515+ return_error ! ( InvalidMonomorphization :: ExpectedPointer { span, name, ty: in_elem } )
516+ }
517+ }
518+ match * out_elem. kind ( ) {
519+ ty:: Uint ( ty:: UintTy :: Usize ) => { }
520+ _ => return_error ! ( InvalidMonomorphization :: ExpectedUsize { span, name, ty: out_elem } ) ,
521+ }
522+
523+ let arg = args[ 0 ] . immediate ( ) ;
524+ let elem_type = llret_ty. dyncast_vector ( ) . expect ( "vector return type" ) . get_element_type ( ) ;
525+ let values: Vec < _ > = ( 0 ..in_len)
526+ . map ( |i| {
527+ let idx = bx. gcc_int ( bx. usize_type , i as _ ) ;
528+ let value = bx. extract_element ( arg, idx) ;
529+ bx. ptrtoint ( value, elem_type)
530+ } )
531+ . collect ( ) ;
532+ return Ok ( bx. context . new_rvalue_from_vector ( bx. location , llret_ty, & values) ) ;
533+ }
534+
535+ if name == sym:: simd_with_exposed_provenance {
536+ require_simd ! ( ret_ty, InvalidMonomorphization :: SimdReturn { span, name, ty: ret_ty } ) ;
537+ let ( out_len, out_elem) = ret_ty. simd_size_and_type ( bx. tcx ( ) ) ;
538+
539+ require ! (
540+ in_len == out_len,
541+ InvalidMonomorphization :: ReturnLengthInputType {
542+ span,
543+ name,
544+ in_len,
545+ in_ty,
546+ ret_ty,
547+ out_len
548+ }
549+ ) ;
550+
551+ match * in_elem. kind ( ) {
552+ ty:: Uint ( ty:: UintTy :: Usize ) => { }
553+ _ => return_error ! ( InvalidMonomorphization :: ExpectedUsize { span, name, ty: in_elem } ) ,
554+ }
555+ match * out_elem. kind ( ) {
556+ ty:: RawPtr ( _, _) => { }
557+ _ => {
558+ return_error ! ( InvalidMonomorphization :: ExpectedPointer { span, name, ty: out_elem } )
559+ }
560+ }
561+
562+ let arg = args[ 0 ] . immediate ( ) ;
563+ let elem_type = llret_ty. dyncast_vector ( ) . expect ( "vector return type" ) . get_element_type ( ) ;
564+ let values: Vec < _ > = ( 0 ..in_len)
565+ . map ( |i| {
566+ let idx = bx. gcc_int ( bx. usize_type , i as _ ) ;
567+ let value = bx. extract_element ( arg, idx) ;
568+ bx. inttoptr ( value, elem_type)
569+ } )
570+ . collect ( ) ;
571+ return Ok ( bx. context . new_rvalue_from_vector ( bx. location , llret_ty, & values) ) ;
572+ }
573+
439574 #[ cfg( feature = "master" ) ]
440575 if name == sym:: simd_cast || name == sym:: simd_as {
441576 require_simd ! ( ret_ty, InvalidMonomorphization :: SimdReturn { span, name, ty: ret_ty } ) ;
0 commit comments