@@ -7,7 +7,6 @@ use crate::prelude::*;
7
7
pub ( crate ) fn maybe_codegen < ' tcx > (
8
8
fx : & mut FunctionCx < ' _ , ' _ , ' tcx > ,
9
9
bin_op : BinOp ,
10
- checked : bool ,
11
10
lhs : CValue < ' tcx > ,
12
11
rhs : CValue < ' tcx > ,
13
12
) -> Option < CValue < ' tcx > > {
@@ -22,69 +21,23 @@ pub(crate) fn maybe_codegen<'tcx>(
22
21
let is_signed = type_sign ( lhs. layout ( ) . ty ) ;
23
22
24
23
match bin_op {
25
- BinOp :: BitAnd | BinOp :: BitOr | BinOp :: BitXor => {
26
- assert ! ( !checked) ;
27
- None
28
- }
29
- BinOp :: Add | BinOp :: Sub if !checked => None ,
30
- BinOp :: Mul if !checked || is_signed => {
31
- if !checked {
32
- let args = [ lhs. load_scalar ( fx) , rhs. load_scalar ( fx) ] ;
33
- let ret_val = fx. lib_call (
34
- "__multi3" ,
35
- vec ! [ AbiParam :: new( types:: I128 ) , AbiParam :: new( types:: I128 ) ] ,
36
- vec ! [ AbiParam :: new( types:: I128 ) ] ,
37
- & args,
38
- ) [ 0 ] ;
39
- Some ( CValue :: by_val (
40
- ret_val,
41
- fx. layout_of ( if is_signed { fx. tcx . types . i128 } else { fx. tcx . types . u128 } ) ,
42
- ) )
43
- } else {
44
- let out_ty = fx. tcx . mk_tup ( & [ lhs. layout ( ) . ty , fx. tcx . types . bool ] ) ;
45
- let oflow = CPlace :: new_stack_slot ( fx, fx. layout_of ( fx. tcx . types . i32 ) ) ;
46
- let lhs = lhs. load_scalar ( fx) ;
47
- let rhs = rhs. load_scalar ( fx) ;
48
- let oflow_ptr = oflow. to_ptr ( ) . get_addr ( fx) ;
49
- let res = fx. lib_call_unadjusted (
50
- "__muloti4" ,
51
- vec ! [
52
- AbiParam :: new( types:: I128 ) ,
53
- AbiParam :: new( types:: I128 ) ,
54
- AbiParam :: new( fx. pointer_type) ,
55
- ] ,
56
- vec ! [ AbiParam :: new( types:: I128 ) ] ,
57
- & [ lhs, rhs, oflow_ptr] ,
58
- ) [ 0 ] ;
59
- let oflow = oflow. to_cvalue ( fx) . load_scalar ( fx) ;
60
- let oflow = fx. bcx . ins ( ) . ireduce ( types:: I8 , oflow) ;
61
- Some ( CValue :: by_val_pair ( res, oflow, fx. layout_of ( out_ty) ) )
62
- }
63
- }
64
- BinOp :: Add | BinOp :: Sub | BinOp :: Mul => {
65
- assert ! ( checked) ;
66
- let out_ty = fx. tcx . mk_tup ( & [ lhs. layout ( ) . ty , fx. tcx . types . bool ] ) ;
67
- let out_place = CPlace :: new_stack_slot ( fx, fx. layout_of ( out_ty) ) ;
68
- let param_types = vec ! [
69
- AbiParam :: special( fx. pointer_type, ArgumentPurpose :: StructReturn ) ,
70
- AbiParam :: new( types:: I128 ) ,
71
- AbiParam :: new( types:: I128 ) ,
72
- ] ;
73
- let args = [ out_place. to_ptr ( ) . get_addr ( fx) , lhs. load_scalar ( fx) , rhs. load_scalar ( fx) ] ;
74
- let name = match ( bin_op, is_signed) {
75
- ( BinOp :: Add , false ) => "__rust_u128_addo" ,
76
- ( BinOp :: Add , true ) => "__rust_i128_addo" ,
77
- ( BinOp :: Sub , false ) => "__rust_u128_subo" ,
78
- ( BinOp :: Sub , true ) => "__rust_i128_subo" ,
79
- ( BinOp :: Mul , false ) => "__rust_u128_mulo" ,
80
- _ => unreachable ! ( ) ,
81
- } ;
82
- fx. lib_call ( name, param_types, vec ! [ ] , & args) ;
83
- Some ( out_place. to_cvalue ( fx) )
24
+ BinOp :: BitAnd | BinOp :: BitOr | BinOp :: BitXor => None ,
25
+ BinOp :: Add | BinOp :: Sub => None ,
26
+ BinOp :: Mul => {
27
+ let args = [ lhs. load_scalar ( fx) , rhs. load_scalar ( fx) ] ;
28
+ let ret_val = fx. lib_call (
29
+ "__multi3" ,
30
+ vec ! [ AbiParam :: new( types:: I128 ) , AbiParam :: new( types:: I128 ) ] ,
31
+ vec ! [ AbiParam :: new( types:: I128 ) ] ,
32
+ & args,
33
+ ) [ 0 ] ;
34
+ Some ( CValue :: by_val (
35
+ ret_val,
36
+ fx. layout_of ( if is_signed { fx. tcx . types . i128 } else { fx. tcx . types . u128 } ) ,
37
+ ) )
84
38
}
85
39
BinOp :: Offset => unreachable ! ( "offset should only be used on pointers, not 128bit ints" ) ,
86
40
BinOp :: Div | BinOp :: Rem => {
87
- assert ! ( !checked) ;
88
41
let name = match ( bin_op, is_signed) {
89
42
( BinOp :: Div , false ) => "__udivti3" ,
90
43
( BinOp :: Div , true ) => "__divti3" ,
@@ -115,10 +68,72 @@ pub(crate) fn maybe_codegen<'tcx>(
115
68
Some ( CValue :: by_val ( ret_val, lhs. layout ( ) ) )
116
69
}
117
70
}
118
- BinOp :: Lt | BinOp :: Le | BinOp :: Eq | BinOp :: Ge | BinOp :: Gt | BinOp :: Ne => {
119
- assert ! ( !checked) ;
120
- None
121
- }
71
+ BinOp :: Lt | BinOp :: Le | BinOp :: Eq | BinOp :: Ge | BinOp :: Gt | BinOp :: Ne => None ,
122
72
BinOp :: Shl | BinOp :: Shr => None ,
123
73
}
124
74
}
75
+
76
+ pub ( crate ) fn maybe_codegen_checked < ' tcx > (
77
+ fx : & mut FunctionCx < ' _ , ' _ , ' tcx > ,
78
+ bin_op : BinOp ,
79
+ lhs : CValue < ' tcx > ,
80
+ rhs : CValue < ' tcx > ,
81
+ ) -> Option < CValue < ' tcx > > {
82
+ if lhs. layout ( ) . ty != fx. tcx . types . u128
83
+ && lhs. layout ( ) . ty != fx. tcx . types . i128
84
+ && rhs. layout ( ) . ty != fx. tcx . types . u128
85
+ && rhs. layout ( ) . ty != fx. tcx . types . i128
86
+ {
87
+ return None ;
88
+ }
89
+
90
+ let is_signed = type_sign ( lhs. layout ( ) . ty ) ;
91
+
92
+ match bin_op {
93
+ BinOp :: BitAnd | BinOp :: BitOr | BinOp :: BitXor => unreachable ! ( ) ,
94
+ BinOp :: Mul if is_signed => {
95
+ let out_ty = fx. tcx . mk_tup ( & [ lhs. layout ( ) . ty , fx. tcx . types . bool ] ) ;
96
+ let oflow = CPlace :: new_stack_slot ( fx, fx. layout_of ( fx. tcx . types . i32 ) ) ;
97
+ let lhs = lhs. load_scalar ( fx) ;
98
+ let rhs = rhs. load_scalar ( fx) ;
99
+ let oflow_ptr = oflow. to_ptr ( ) . get_addr ( fx) ;
100
+ let res = fx. lib_call_unadjusted (
101
+ "__muloti4" ,
102
+ vec ! [
103
+ AbiParam :: new( types:: I128 ) ,
104
+ AbiParam :: new( types:: I128 ) ,
105
+ AbiParam :: new( fx. pointer_type) ,
106
+ ] ,
107
+ vec ! [ AbiParam :: new( types:: I128 ) ] ,
108
+ & [ lhs, rhs, oflow_ptr] ,
109
+ ) [ 0 ] ;
110
+ let oflow = oflow. to_cvalue ( fx) . load_scalar ( fx) ;
111
+ let oflow = fx. bcx . ins ( ) . ireduce ( types:: I8 , oflow) ;
112
+ Some ( CValue :: by_val_pair ( res, oflow, fx. layout_of ( out_ty) ) )
113
+ }
114
+ BinOp :: Add | BinOp :: Sub | BinOp :: Mul => {
115
+ let out_ty = fx. tcx . mk_tup ( & [ lhs. layout ( ) . ty , fx. tcx . types . bool ] ) ;
116
+ let out_place = CPlace :: new_stack_slot ( fx, fx. layout_of ( out_ty) ) ;
117
+ let param_types = vec ! [
118
+ AbiParam :: special( fx. pointer_type, ArgumentPurpose :: StructReturn ) ,
119
+ AbiParam :: new( types:: I128 ) ,
120
+ AbiParam :: new( types:: I128 ) ,
121
+ ] ;
122
+ let args = [ out_place. to_ptr ( ) . get_addr ( fx) , lhs. load_scalar ( fx) , rhs. load_scalar ( fx) ] ;
123
+ let name = match ( bin_op, is_signed) {
124
+ ( BinOp :: Add , false ) => "__rust_u128_addo" ,
125
+ ( BinOp :: Add , true ) => "__rust_i128_addo" ,
126
+ ( BinOp :: Sub , false ) => "__rust_u128_subo" ,
127
+ ( BinOp :: Sub , true ) => "__rust_i128_subo" ,
128
+ ( BinOp :: Mul , false ) => "__rust_u128_mulo" ,
129
+ _ => unreachable ! ( ) ,
130
+ } ;
131
+ fx. lib_call ( name, param_types, vec ! [ ] , & args) ;
132
+ Some ( out_place. to_cvalue ( fx) )
133
+ }
134
+ BinOp :: Offset => unreachable ! ( "offset should only be used on pointers, not 128bit ints" ) ,
135
+ BinOp :: Div | BinOp :: Rem => unreachable ! ( ) ,
136
+ BinOp :: Lt | BinOp :: Le | BinOp :: Eq | BinOp :: Ge | BinOp :: Gt | BinOp :: Ne => unreachable ! ( ) ,
137
+ BinOp :: Shl | BinOp :: Shr => unreachable ! ( ) ,
138
+ }
139
+ }
0 commit comments