44
55// cSpell:words cmpti divti modti mulodi muloti udivti umodti
66
7- use gccjit:: { BinaryOp , ComparisonOp , FunctionType , Location , RValue , ToRValue , Type , UnaryOp } ;
7+ use gccjit:: {
8+ BinaryOp , CType , ComparisonOp , FunctionType , Location , RValue , ToRValue , Type , UnaryOp ,
9+ } ;
810use rustc_abi:: { CanonAbi , Endian , ExternAbi } ;
911use rustc_codegen_ssa:: common:: { IntPredicate , TypeKind } ;
1012use rustc_codegen_ssa:: traits:: { BackendTypes , BaseTypeCodegenMethods , BuilderMethods , OverflowOp } ;
1113use rustc_middle:: ty:: { self , Ty } ;
1214use rustc_target:: callconv:: { ArgAbi , ArgAttributes , FnAbi , PassMode } ;
15+ use rustc_type_ir:: { Interner , TyKind } ;
1316
1417use crate :: builder:: { Builder , ToGccComp } ;
1518use crate :: common:: { SignType , TypeReflection } ;
@@ -167,9 +170,9 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
167170 if a_type. is_vector ( ) {
168171 // Vector types need to be bitcast.
169172 // TODO(antoyo): perhaps use __builtin_convertvector for vector casting.
170- b = self . context . new_bitcast ( self . location , b, a . get_type ( ) ) ;
173+ b = self . context . new_bitcast ( self . location , b, a_type ) ;
171174 } else {
172- b = self . context . new_cast ( self . location , b, a . get_type ( ) ) ;
175+ b = self . context . new_cast ( self . location , b, a_type ) ;
173176 }
174177 }
175178 self . context . new_binary_op ( self . location , operation, a_type, a, b)
@@ -216,13 +219,22 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
216219 operation_name : & str ,
217220 signed : bool ,
218221 a : RValue < ' gcc > ,
219- b : RValue < ' gcc > ,
222+ mut b : RValue < ' gcc > ,
220223 ) -> RValue < ' gcc > {
221224 let a_type = a. get_type ( ) ;
222225 let b_type = b. get_type ( ) ;
223226 if ( self . is_native_int_type_or_bool ( a_type) && self . is_native_int_type_or_bool ( b_type) )
224227 || ( a_type. is_vector ( ) && b_type. is_vector ( ) )
225228 {
229+ if !a_type. is_compatible_with ( b_type) {
230+ if a_type. is_vector ( ) {
231+ // Vector types need to be bitcast.
232+ // TODO(antoyo): perhaps use __builtin_convertvector for vector casting.
233+ b = self . context . new_bitcast ( self . location , b, a_type) ;
234+ } else {
235+ b = self . context . new_cast ( self . location , b, a_type) ;
236+ }
237+ }
226238 self . context . new_binary_op ( self . location , operation, a_type, a, b)
227239 } else {
228240 debug_assert ! ( a_type. dyncast_array( ) . is_some( ) ) ;
@@ -351,6 +363,11 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
351363 // TODO(antoyo): is it correct to use rhs type instead of the parameter typ?
352364 . new_local ( self . location , rhs. get_type ( ) , "binopResult" )
353365 . get_address ( self . location ) ;
366+ let new_type = type_kind_to_gcc_type ( new_kind) ;
367+ let new_type = self . context . new_c_type ( new_type) ;
368+ let lhs = self . context . new_cast ( self . location , lhs, new_type) ;
369+ let rhs = self . context . new_cast ( self . location , rhs, new_type) ;
370+ let res = self . context . new_cast ( self . location , res, new_type. make_pointer ( ) ) ;
354371 let overflow = self . overflow_call ( intrinsic, & [ lhs, rhs, res] , None ) ;
355372 ( res. dereference ( self . location ) . to_rvalue ( ) , overflow)
356373 }
@@ -477,11 +494,27 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
477494 let lhs_low = self . context . new_cast ( self . location , self . low ( lhs) , unsigned_type) ;
478495 let rhs_low = self . context . new_cast ( self . location , self . low ( rhs) , unsigned_type) ;
479496
497+ let mut lhs_high = self . high ( lhs) ;
498+ let mut rhs_high = self . high ( rhs) ;
499+
500+ match op {
501+ IntPredicate :: IntUGT
502+ | IntPredicate :: IntUGE
503+ | IntPredicate :: IntULT
504+ | IntPredicate :: IntULE => {
505+ lhs_high = self . context . new_cast ( self . location , lhs_high, unsigned_type) ;
506+ rhs_high = self . context . new_cast ( self . location , rhs_high, unsigned_type) ;
507+ }
508+ // TODO(antoyo): we probably need to handle signed comparison for unsigned
509+ // integers.
510+ _ => ( ) ,
511+ }
512+
480513 let condition = self . context . new_comparison (
481514 self . location ,
482515 ComparisonOp :: LessThan ,
483- self . high ( lhs ) ,
484- self . high ( rhs ) ,
516+ lhs_high ,
517+ rhs_high ,
485518 ) ;
486519 self . llbb ( ) . end_with_conditional ( self . location , condition, block1, block2) ;
487520
@@ -495,8 +528,8 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
495528 let condition = self . context . new_comparison (
496529 self . location ,
497530 ComparisonOp :: GreaterThan ,
498- self . high ( lhs ) ,
499- self . high ( rhs ) ,
531+ lhs_high ,
532+ rhs_high ,
500533 ) ;
501534 block2. end_with_conditional ( self . location , condition, block3, block4) ;
502535
@@ -620,14 +653,17 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
620653 }
621654 }
622655
623- pub fn gcc_xor ( & self , a : RValue < ' gcc > , b : RValue < ' gcc > ) -> RValue < ' gcc > {
656+ pub fn gcc_xor ( & self , a : RValue < ' gcc > , mut b : RValue < ' gcc > ) -> RValue < ' gcc > {
624657 let a_type = a. get_type ( ) ;
625658 let b_type = b. get_type ( ) ;
626659 if a_type. is_vector ( ) && b_type. is_vector ( ) {
627660 let b = self . bitcast_if_needed ( b, a_type) ;
628661 a ^ b
629662 } else if self . is_native_int_type_or_bool ( a_type) && self . is_native_int_type_or_bool ( b_type)
630663 {
664+ if !a_type. is_compatible_with ( b_type) {
665+ b = self . context . new_cast ( self . location , b, a_type) ;
666+ }
631667 a ^ b
632668 } else {
633669 self . concat_low_high_rvalues (
@@ -1042,3 +1078,25 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
10421078 self . context . new_array_constructor ( None , typ, & values)
10431079 }
10441080}
1081+
1082+ fn type_kind_to_gcc_type < I : Interner > ( kind : TyKind < I > ) -> CType {
1083+ use rustc_middle:: ty:: IntTy :: * ;
1084+ use rustc_middle:: ty:: UintTy :: * ;
1085+ use rustc_middle:: ty:: { Int , Uint } ;
1086+
1087+ match kind {
1088+ Int ( I8 ) => CType :: Int8t ,
1089+ Int ( I16 ) => CType :: Int16t ,
1090+ Int ( I32 ) => CType :: Int32t ,
1091+ Int ( I64 ) => CType :: Int64t ,
1092+ Int ( I128 ) => CType :: Int128t ,
1093+
1094+ Uint ( U8 ) => CType :: UInt8t ,
1095+ Uint ( U16 ) => CType :: UInt16t ,
1096+ Uint ( U32 ) => CType :: UInt32t ,
1097+ Uint ( U64 ) => CType :: UInt64t ,
1098+ Uint ( U128 ) => CType :: UInt128t ,
1099+
1100+ _ => unimplemented ! ( "Kind: {:?}" , kind) ,
1101+ }
1102+ }
0 commit comments