@@ -456,6 +456,80 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
456456 }
457457 }
458458
459+ fn checked_binop (
460+ & mut self ,
461+ oop : OverflowOp ,
462+ ty : Ty ,
463+ lhs : Self :: Value ,
464+ rhs : Self :: Value ,
465+ ) -> ( Self :: Value , Self :: Value ) {
466+ use syntax:: ast:: IntTy :: * ;
467+ use syntax:: ast:: UintTy :: * ;
468+ use rustc:: ty:: { Int , Uint } ;
469+
470+ let new_sty = match ty. sty {
471+ Int ( Isize ) => Int ( self . cx ( ) . tcx . sess . target . isize_ty ) ,
472+ Uint ( Usize ) => Uint ( self . cx ( ) . tcx . sess . target . usize_ty ) ,
473+ ref t @ Uint ( _) | ref t @ Int ( _) => t. clone ( ) ,
474+ _ => panic ! ( "tried to get overflow intrinsic for op applied to non-int type" )
475+ } ;
476+
477+ let name = match oop {
478+ OverflowOp :: Add => match new_sty {
479+ Int ( I8 ) => "llvm.sadd.with.overflow.i8" ,
480+ Int ( I16 ) => "llvm.sadd.with.overflow.i16" ,
481+ Int ( I32 ) => "llvm.sadd.with.overflow.i32" ,
482+ Int ( I64 ) => "llvm.sadd.with.overflow.i64" ,
483+ Int ( I128 ) => "llvm.sadd.with.overflow.i128" ,
484+
485+ Uint ( U8 ) => "llvm.uadd.with.overflow.i8" ,
486+ Uint ( U16 ) => "llvm.uadd.with.overflow.i16" ,
487+ Uint ( U32 ) => "llvm.uadd.with.overflow.i32" ,
488+ Uint ( U64 ) => "llvm.uadd.with.overflow.i64" ,
489+ Uint ( U128 ) => "llvm.uadd.with.overflow.i128" ,
490+
491+ _ => unreachable ! ( ) ,
492+ } ,
493+ OverflowOp :: Sub => match new_sty {
494+ Int ( I8 ) => "llvm.ssub.with.overflow.i8" ,
495+ Int ( I16 ) => "llvm.ssub.with.overflow.i16" ,
496+ Int ( I32 ) => "llvm.ssub.with.overflow.i32" ,
497+ Int ( I64 ) => "llvm.ssub.with.overflow.i64" ,
498+ Int ( I128 ) => "llvm.ssub.with.overflow.i128" ,
499+
500+ Uint ( U8 ) => "llvm.usub.with.overflow.i8" ,
501+ Uint ( U16 ) => "llvm.usub.with.overflow.i16" ,
502+ Uint ( U32 ) => "llvm.usub.with.overflow.i32" ,
503+ Uint ( U64 ) => "llvm.usub.with.overflow.i64" ,
504+ Uint ( U128 ) => "llvm.usub.with.overflow.i128" ,
505+
506+ _ => unreachable ! ( ) ,
507+ } ,
508+ OverflowOp :: Mul => match new_sty {
509+ Int ( I8 ) => "llvm.smul.with.overflow.i8" ,
510+ Int ( I16 ) => "llvm.smul.with.overflow.i16" ,
511+ Int ( I32 ) => "llvm.smul.with.overflow.i32" ,
512+ Int ( I64 ) => "llvm.smul.with.overflow.i64" ,
513+ Int ( I128 ) => "llvm.smul.with.overflow.i128" ,
514+
515+ Uint ( U8 ) => "llvm.umul.with.overflow.i8" ,
516+ Uint ( U16 ) => "llvm.umul.with.overflow.i16" ,
517+ Uint ( U32 ) => "llvm.umul.with.overflow.i32" ,
518+ Uint ( U64 ) => "llvm.umul.with.overflow.i64" ,
519+ Uint ( U128 ) => "llvm.umul.with.overflow.i128" ,
520+
521+ _ => unreachable ! ( ) ,
522+ } ,
523+ } ;
524+
525+ let intrinsic = self . cx ( ) . get_intrinsic ( & name) ;
526+ let res = self . call ( intrinsic, & [ lhs, rhs] , None ) ;
527+ (
528+ self . extract_value ( res, 0 ) ,
529+ self . extract_value ( res, 1 ) ,
530+ )
531+ }
532+
459533 fn alloca ( & mut self , ty : & ' ll Type , name : & str , align : Align ) -> & ' ll Value {
460534 let mut bx = Builder :: with_cx ( self . cx ) ;
461535 bx. position_at_start ( unsafe {
0 commit comments