@@ -224,39 +224,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
224
224
match int_type_width_signed ( ty, self ) {
225
225
Some ( ( width, signed) ) => match name {
226
226
sym:: ctlz | sym:: cttz => {
227
- let func = self . current_func . borrow ( ) . expect ( "func" ) ;
228
- let then_block = func. new_block ( "then" ) ;
229
- let else_block = func. new_block ( "else" ) ;
230
- let after_block = func. new_block ( "after" ) ;
231
-
232
- let arg = args[ 0 ] . immediate ( ) ;
233
- let result = func. new_local ( None , self . u32_type , "zeros" ) ;
234
- let zero = self . cx . gcc_zero ( arg. get_type ( ) ) ;
235
- let cond = self . gcc_icmp ( IntPredicate :: IntEQ , arg, zero) ;
236
- self . llbb ( ) . end_with_conditional ( None , cond, then_block, else_block) ;
237
-
238
- let zero_result = self . cx . gcc_uint ( self . u32_type , width) ;
239
- then_block. add_assignment ( None , result, zero_result) ;
240
- then_block. end_with_jump ( None , after_block) ;
241
-
242
- // NOTE: since jumps were added in a place
243
- // count_leading_zeroes() does not expect, the current block
244
- // in the state need to be updated.
245
- self . switch_to_block ( else_block) ;
246
-
247
- let zeros = match name {
248
- sym:: ctlz => self . count_leading_zeroes ( width, arg) ,
249
- sym:: cttz => self . count_trailing_zeroes ( width, arg) ,
250
- _ => unreachable ! ( ) ,
251
- } ;
252
- self . llbb ( ) . add_assignment ( None , result, zeros) ;
253
- self . llbb ( ) . end_with_jump ( None , after_block) ;
254
-
255
- // NOTE: since jumps were added in a place rustc does not
256
- // expect, the current block in the state need to be updated.
257
- self . switch_to_block ( after_block) ;
258
-
259
- result. to_rvalue ( )
227
+ self . checked_bitcount_intrinsic ( name, args[ 0 ] . immediate ( ) , width)
260
228
}
261
229
sym:: ctlz_nonzero => self . count_leading_zeroes ( width, args[ 0 ] . immediate ( ) ) ,
262
230
sym:: cttz_nonzero => self . count_trailing_zeroes ( width, args[ 0 ] . immediate ( ) ) ,
@@ -712,7 +680,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
712
680
self . gcc_int_cast ( result, result_type)
713
681
}
714
682
715
- fn count_leading_zeroes ( & mut self , width : u64 , arg : RValue < ' gcc > ) -> RValue < ' gcc > {
683
+ pub fn count_leading_zeroes ( & mut self , width : u64 , arg : RValue < ' gcc > ) -> RValue < ' gcc > {
716
684
// TODO(antoyo): use width?
717
685
let arg_type = arg. get_type ( ) ;
718
686
let result_type = self . u32_type ;
@@ -743,15 +711,16 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
743
711
let one = self . context . new_rvalue_one ( self . usize_type ) ;
744
712
let two = self . context . new_rvalue_from_long ( self . usize_type , 2 ) ;
745
713
746
- let clzll = self . context . get_builtin_function ( "__builtin_clzll" ) ;
747
-
748
714
let first_elem = self . context . new_array_access ( None , result, zero) ;
749
- let first_value = self . gcc_int_cast ( self . context . new_call ( None , clzll, & [ high] ) , arg_type) ;
715
+ let high_ctlz = self . checked_bitcount_intrinsic ( sym:: ctlz, high, 64 ) ;
716
+ let first_value = self . gcc_int_cast ( high_ctlz, arg_type) ;
750
717
self . llbb ( )
751
718
. add_assignment ( self . location , first_elem, first_value) ;
752
719
753
720
let second_elem = self . context . new_array_access ( self . location , result, one) ;
754
- let cast = self . gcc_int_cast ( self . context . new_call ( self . location , clzll, & [ low] ) , arg_type) ;
721
+
722
+ let low_ctlz = self . checked_bitcount_intrinsic ( sym:: ctlz, low, 64 ) ;
723
+ let cast = self . gcc_int_cast ( low_ctlz, arg_type) ;
755
724
let second_value = self . add ( cast, sixty_four) ;
756
725
self . llbb ( )
757
726
. add_assignment ( self . location , second_elem, second_value) ;
@@ -788,7 +757,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
788
757
self . context . new_cast ( self . location , res, result_type)
789
758
}
790
759
791
- fn count_trailing_zeroes ( & mut self , _width : u64 , arg : RValue < ' gcc > ) -> RValue < ' gcc > {
760
+ pub fn count_trailing_zeroes ( & mut self , _width : u64 , arg : RValue < ' gcc > ) -> RValue < ' gcc > {
792
761
let arg_type = arg. get_type ( ) ;
793
762
let result_type = self . u32_type ;
794
763
let arg = if arg_type. is_signed ( self . cx ) {
@@ -826,15 +795,15 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
826
795
let one = self . context . new_rvalue_one ( self . usize_type ) ;
827
796
let two = self . context . new_rvalue_from_long ( self . usize_type , 2 ) ;
828
797
829
- let ctzll = self . context . get_builtin_function ( "__builtin_ctzll" ) ;
830
-
831
798
let first_elem = self . context . new_array_access ( self . location , result, zero) ;
832
- let first_value = self . gcc_int_cast ( self . context . new_call ( self . location , ctzll, & [ low] ) , arg_type) ;
799
+ let low_ctzll = self . checked_bitcount_intrinsic ( sym:: cttz, low , 64 ) ;
800
+ let first_value = self . gcc_int_cast ( low_ctzll, arg_type) ;
833
801
self . llbb ( )
834
802
. add_assignment ( self . location , first_elem, first_value) ;
835
803
836
804
let second_elem = self . context . new_array_access ( self . location , result, one) ;
837
- let second_value = self . gcc_add ( self . gcc_int_cast ( self . context . new_call ( self . location , ctzll, & [ high] ) , arg_type) , sixty_four) ;
805
+ let high_ctzll = self . checked_bitcount_intrinsic ( sym:: cttz, high , 64 ) ;
806
+ let second_value = self . gcc_add ( self . gcc_int_cast ( high_ctzll, arg_type) , sixty_four) ;
838
807
self . llbb ( )
839
808
. add_assignment ( self . location , second_elem, second_value) ;
840
809
0 commit comments