@@ -2094,65 +2094,72 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
20942094 return Ok ( args[ 0 ] . immediate ( ) ) ;
20952095 }
20962096
2097+ #[ derive( Copy , Clone ) ]
2098+ enum Sign {
2099+ Unsigned ,
2100+ Signed ,
2101+ }
2102+ use Sign :: * ;
2103+
20972104 enum Style {
20982105 Float ,
2099- Int ( /* is signed? */ bool ) ,
2106+ Int ( Sign ) ,
21002107 Unsupported ,
21012108 }
21022109
21032110 let ( in_style, in_width) = match in_elem. kind ( ) {
21042111 // vectors of pointer-sized integers should've been
21052112 // disallowed before here, so this unwrap is safe.
21062113 ty:: Int ( i) => (
2107- Style :: Int ( true ) ,
2114+ Style :: Int ( Signed ) ,
21082115 i. normalize ( bx. tcx ( ) . sess . target . pointer_width ) . bit_width ( ) . unwrap ( ) ,
21092116 ) ,
21102117 ty:: Uint ( u) => (
2111- Style :: Int ( false ) ,
2118+ Style :: Int ( Unsigned ) ,
21122119 u. normalize ( bx. tcx ( ) . sess . target . pointer_width ) . bit_width ( ) . unwrap ( ) ,
21132120 ) ,
21142121 ty:: Float ( f) => ( Style :: Float , f. bit_width ( ) ) ,
21152122 _ => ( Style :: Unsupported , 0 ) ,
21162123 } ;
21172124 let ( out_style, out_width) = match out_elem. kind ( ) {
21182125 ty:: Int ( i) => (
2119- Style :: Int ( true ) ,
2126+ Style :: Int ( Signed ) ,
21202127 i. normalize ( bx. tcx ( ) . sess . target . pointer_width ) . bit_width ( ) . unwrap ( ) ,
21212128 ) ,
21222129 ty:: Uint ( u) => (
2123- Style :: Int ( false ) ,
2130+ Style :: Int ( Unsigned ) ,
21242131 u. normalize ( bx. tcx ( ) . sess . target . pointer_width ) . bit_width ( ) . unwrap ( ) ,
21252132 ) ,
21262133 ty:: Float ( f) => ( Style :: Float , f. bit_width ( ) ) ,
21272134 _ => ( Style :: Unsupported , 0 ) ,
21282135 } ;
21292136
21302137 match ( in_style, out_style) {
2131- ( Style :: Int ( in_is_signed ) , Style :: Int ( _) ) => {
2138+ ( Style :: Int ( sign ) , Style :: Int ( _) ) => {
21322139 return Ok ( match in_width. cmp ( & out_width) {
21332140 Ordering :: Greater => bx. trunc ( args[ 0 ] . immediate ( ) , llret_ty) ,
21342141 Ordering :: Equal => args[ 0 ] . immediate ( ) ,
2135- Ordering :: Less => {
2136- if in_is_signed {
2137- bx. sext ( args[ 0 ] . immediate ( ) , llret_ty)
2138- } else {
2139- bx. zext ( args[ 0 ] . immediate ( ) , llret_ty)
2140- }
2141- }
2142+ Ordering :: Less => match sign {
2143+ Sign :: Signed => bx. sext ( args[ 0 ] . immediate ( ) , llret_ty) ,
2144+ Sign :: Unsigned => bx. zext ( args[ 0 ] . immediate ( ) , llret_ty) ,
2145+ } ,
21422146 } ) ;
21432147 }
2144- ( Style :: Int ( in_is_signed) , Style :: Float ) => {
2145- return Ok ( if in_is_signed {
2146- bx. sitofp ( args[ 0 ] . immediate ( ) , llret_ty)
2147- } else {
2148- bx. uitofp ( args[ 0 ] . immediate ( ) , llret_ty)
2149- } ) ;
2148+ ( Style :: Int ( Sign :: Signed ) , Style :: Float ) => {
2149+ return Ok ( bx. sitofp ( args[ 0 ] . immediate ( ) , llret_ty) ) ;
21502150 }
2151- ( Style :: Float , Style :: Int ( out_is_signed) ) => {
2152- return Ok ( match ( out_is_signed, name == sym:: simd_as) {
2153- ( false , false ) => bx. fptoui ( args[ 0 ] . immediate ( ) , llret_ty) ,
2154- ( true , false ) => bx. fptosi ( args[ 0 ] . immediate ( ) , llret_ty) ,
2155- ( _, true ) => bx. cast_float_to_int ( out_is_signed, args[ 0 ] . immediate ( ) , llret_ty) ,
2151+ ( Style :: Int ( Sign :: Unsigned ) , Style :: Float ) => {
2152+ return Ok ( bx. uitofp ( args[ 0 ] . immediate ( ) , llret_ty) ) ;
2153+ }
2154+ ( Style :: Float , Style :: Int ( sign) ) => {
2155+ return Ok ( match ( sign, name == sym:: simd_as) {
2156+ ( Sign :: Unsigned , false ) => bx. fptoui ( args[ 0 ] . immediate ( ) , llret_ty) ,
2157+ ( Sign :: Signed , false ) => bx. fptosi ( args[ 0 ] . immediate ( ) , llret_ty) ,
2158+ ( _, true ) => bx. cast_float_to_int (
2159+ matches ! ( sign, Sign :: Signed ) ,
2160+ args[ 0 ] . immediate ( ) ,
2161+ llret_ty,
2162+ ) ,
21562163 } ) ;
21572164 }
21582165 ( Style :: Float , Style :: Float ) => {
0 commit comments