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