@@ -79,82 +79,96 @@ bvt boolbvt::convert_floatbv_op(const exprt &expr)
79
79
if (operands.size ()!=3 )
80
80
throw " operator " +expr.id_string ()+" takes three operands" ;
81
81
82
- const exprt &op0= expr.op0 (); // first operand
83
- const exprt &op1= expr.op1 (); // second operand
84
- const exprt &op2= expr.op2 (); // rounding mode
82
+ const exprt &lhs = expr.op0 ();
83
+ const exprt &rhs = expr.op1 ();
84
+ const exprt &rounding_mode = expr.op2 ();
85
85
86
- bvt bv0= convert_bv (op0 );
87
- bvt bv1= convert_bv (op1 );
88
- bvt bv2= convert_bv (op2 );
86
+ bvt lhs_as_bv = convert_bv (lhs );
87
+ bvt rhs_as_bv = convert_bv (rhs );
88
+ bvt rounding_mode_as_bv = convert_bv (rounding_mode );
89
89
90
- const typet &type=ns.follow (expr.type ());
91
- DATA_INVARIANT (
92
- op0.type () == type && op1.type () == type,
93
- " float op with mixed types:\n " + expr.pretty ());
90
+ const typet &resolved_type = ns.follow (expr.type ());
91
+ DATA_INVARIANT_WITH_DIAGNOSTICS (
92
+ lhs.type () == resolved_type && rhs.type () == resolved_type,
93
+ " both operands of a floating point operator must have the same type" ,
94
+ irep_pretty_diagnosticst{expr});
94
95
95
96
float_utilst float_utils (prop);
96
97
97
- float_utils.set_rounding_mode (bv2 );
98
+ float_utils.set_rounding_mode (rounding_mode_as_bv );
98
99
99
- if (type .id ()== ID_floatbv)
100
+ if (resolved_type .id () == ID_floatbv)
100
101
{
101
102
float_utils.spec =ieee_float_spect (to_floatbv_type (expr.type ()));
102
103
103
104
if (expr.id ()==ID_floatbv_plus)
104
- return float_utils.add_sub (bv0, bv1 , false );
105
+ return float_utils.add_sub (lhs_as_bv, rhs_as_bv , false );
105
106
else if (expr.id ()==ID_floatbv_minus)
106
- return float_utils.add_sub (bv0, bv1 , true );
107
+ return float_utils.add_sub (lhs_as_bv, rhs_as_bv , true );
107
108
else if (expr.id ()==ID_floatbv_mult)
108
- return float_utils.mul (bv0, bv1 );
109
+ return float_utils.mul (lhs_as_bv, rhs_as_bv );
109
110
else if (expr.id ()==ID_floatbv_div)
110
- return float_utils.div (bv0, bv1 );
111
+ return float_utils.div (lhs_as_bv, rhs_as_bv );
111
112
else if (expr.id ()==ID_floatbv_rem)
112
- return float_utils.rem (bv0, bv1 );
113
+ return float_utils.rem (lhs_as_bv, rhs_as_bv );
113
114
else
114
- throw " unexpected operator " +expr. id_string () ;
115
+ UNREACHABLE ;
115
116
}
116
- else if (type .id ()== ID_vector || type .id ()== ID_complex)
117
+ else if (resolved_type .id () == ID_vector || resolved_type .id () == ID_complex)
117
118
{
118
- const typet &subtype= ns.follow (type .subtype ());
119
+ const typet &subtype = ns.follow (resolved_type .subtype ());
119
120
120
121
if (subtype.id ()==ID_floatbv)
121
122
{
122
123
float_utils.spec =ieee_float_spect (to_floatbv_type (subtype));
123
124
124
- std::size_t width= boolbv_width (type );
125
+ std::size_t width = boolbv_width (resolved_type );
125
126
std::size_t sub_width=boolbv_width (subtype);
126
127
127
- if (sub_width==0 || width%sub_width!=0 )
128
- throw " convert_floatbv_op: unexpected vector operand width" ;
128
+ DATA_INVARIANT (
129
+ sub_width > 0 && width % sub_width == 0 ,
130
+ " width of a vector subtype must be positive and evenly divide the "
131
+ " width of the vector" );
129
132
130
133
std::size_t size=width/sub_width;
131
- bvt bv ;
132
- bv .resize (width);
134
+ bvt result_bv ;
135
+ result_bv .resize (width);
133
136
134
137
for (std::size_t i=0 ; i<size; i++)
135
138
{
136
- bvt tmp_bv0, tmp_bv1, tmp_bv ;
139
+ bvt lhs_sub_bv, rhs_sub_bv, sub_result_bv ;
137
140
138
- tmp_bv0.assign (bv0.begin ()+i*sub_width, bv0.begin ()+(i+1 )*sub_width);
139
- tmp_bv1.assign (bv1.begin ()+i*sub_width, bv1.begin ()+(i+1 )*sub_width);
141
+ lhs_sub_bv.assign (
142
+ lhs_as_bv.begin () + i * sub_width,
143
+ lhs_as_bv.begin () + (i + 1 ) * sub_width);
144
+ rhs_sub_bv.assign (
145
+ rhs_as_bv.begin () + i * sub_width,
146
+ rhs_as_bv.begin () + (i + 1 ) * sub_width);
140
147
141
148
if (expr.id ()==ID_floatbv_plus)
142
- tmp_bv= float_utils.add_sub (tmp_bv0, tmp_bv1 , false );
149
+ sub_result_bv = float_utils.add_sub (lhs_sub_bv, rhs_sub_bv , false );
143
150
else if (expr.id ()==ID_floatbv_minus)
144
- tmp_bv= float_utils.add_sub (tmp_bv0, tmp_bv1 , true );
151
+ sub_result_bv = float_utils.add_sub (lhs_sub_bv, rhs_sub_bv , true );
145
152
else if (expr.id ()==ID_floatbv_mult)
146
- tmp_bv= float_utils.mul (tmp_bv0, tmp_bv1 );
153
+ sub_result_bv = float_utils.mul (lhs_sub_bv, rhs_sub_bv );
147
154
else if (expr.id ()==ID_floatbv_div)
148
- tmp_bv= float_utils.div (tmp_bv0, tmp_bv1 );
155
+ sub_result_bv = float_utils.div (lhs_sub_bv, rhs_sub_bv );
149
156
else
150
- assert (false );
151
-
152
- assert (tmp_bv.size ()==sub_width);
153
- assert (i*sub_width+sub_width-1 <bv.size ());
154
- std::copy (tmp_bv.begin (), tmp_bv.end (), bv.begin ()+i*sub_width);
157
+ UNREACHABLE;
158
+
159
+ INVARIANT (
160
+ sub_result_bv.size () == sub_width,
161
+ " we constructed a new vector of the right size" );
162
+ INVARIANT (
163
+ i * sub_width + sub_width - 1 < result_bv.size (),
164
+ " the sub-bitvector fits into the result bitvector" );
165
+ std::copy (
166
+ sub_result_bv.begin (),
167
+ sub_result_bv.end (),
168
+ result_bv.begin () + i * sub_width);
155
169
}
156
170
157
- return bv ;
171
+ return result_bv ;
158
172
}
159
173
else
160
174
return conversion_failed (expr);
0 commit comments