@@ -222,6 +222,39 @@ void verilog_typecheck_exprt::propagate_type(
222
222
223
223
/* ******************************************************************\
224
224
225
+ Function: zero_extend
226
+
227
+ Inputs:
228
+
229
+ Outputs:
230
+
231
+ Purpose:
232
+
233
+ \*******************************************************************/
234
+
235
+ static exprt zero_extend (const exprt &expr, const typet &type)
236
+ {
237
+ auto old_width = expr.type ().id () == ID_bool ? 1
238
+ : expr.type ().id () == ID_integer
239
+ ? 32
240
+ : to_bitvector_type (expr.type ()).get_width ();
241
+
242
+ // first make unsigned
243
+ typet tmp_type;
244
+
245
+ if (type.id () == ID_unsignedbv)
246
+ tmp_type = unsignedbv_typet{old_width};
247
+ else if (type.id () == ID_verilog_unsignedbv)
248
+ tmp_type = verilog_unsignedbv_typet{old_width};
249
+ else
250
+ PRECONDITION (false );
251
+
252
+ return typecast_exprt::conditional_cast (
253
+ typecast_exprt::conditional_cast (expr, tmp_type), type);
254
+ }
255
+
256
+ /* ******************************************************************\
257
+
225
258
Function: verilog_typecheck_exprt::downwards_type_progatation
226
259
227
260
Inputs:
@@ -241,95 +274,76 @@ void verilog_typecheck_exprt::downwards_type_propagation(
241
274
242
275
// Any context-determined operand of an operator shall be the
243
276
// same type and size as the result of the operator.
244
- // Exceptions:
245
- // * result type real -- just cast
246
- // * relational operators are always 1 bit unsigned
277
+ // As an exception, if the result type is real, the operands
278
+ // are just casted.
247
279
248
280
if (expr.type () == type)
249
281
return ;
250
282
251
- vtypet vt_from = vtypet (expr.type ());
252
- vtypet vt_to = vtypet (type);
253
-
254
- if (!vt_from.is_other () && !vt_to.is_other () && expr.has_operands ())
283
+ if (type.id () == ID_verilog_real || type.id () == ID_verilog_shortreal)
255
284
{
256
- // arithmetic
257
-
258
- if (
259
- expr.id () == ID_plus || expr.id () == ID_minus || expr.id () == ID_mult ||
260
- expr.id () == ID_div || expr.id () == ID_unary_minus ||
261
- expr.id () == ID_unary_plus)
262
- {
263
- if (type.id () != ID_bool)
264
- {
265
- Forall_operands (it, expr)
266
- propagate_type (*it, type);
267
-
268
- expr.type () = type;
269
-
270
- return ;
271
- }
272
- }
273
- else if (
274
- expr.id () == ID_bitand || expr.id () == ID_bitor ||
275
- expr.id () == ID_bitnand || expr.id () == ID_bitnor ||
276
- expr.id () == ID_bitxor || expr.id () == ID_bitxnor ||
277
- expr.id () == ID_bitnot)
278
- {
279
- Forall_operands (it, expr)
280
- propagate_type (*it, type);
281
-
282
- expr.type () = type;
285
+ expr = typecast_exprt{expr, type};
286
+ return ;
287
+ }
283
288
284
- if (type.id () == ID_bool)
285
- {
286
- if (expr.id () == ID_bitand)
287
- expr.id (ID_and);
288
- else if (expr.id () == ID_bitor)
289
- expr.id (ID_or);
290
- else if (expr.id () == ID_bitnand)
291
- expr.id (ID_nand);
292
- else if (expr.id () == ID_bitnor)
293
- expr.id (ID_nor);
294
- else if (expr.id () == ID_bitxor)
295
- expr.id (ID_xor);
296
- else if (expr.id () == ID_bitxnor)
297
- expr.id (ID_xnor);
298
- else if (expr.id () == ID_bitnot)
299
- expr.id (ID_not);
300
- }
289
+ // expressions with context-determined width, following
290
+ // 1800-2017 Table 11-21
291
+ if (
292
+ expr.id () == ID_plus || expr.id () == ID_minus || expr.id () == ID_mult ||
293
+ expr.id () == ID_div || expr.id () == ID_mod || expr.id () == ID_bitand ||
294
+ expr.id () == ID_bitor || expr.id () == ID_bitxor ||
295
+ expr.id () == ID_bitxnor || expr.id () == ID_unary_plus ||
296
+ expr.id () == ID_unary_minus || expr.id () == ID_bitnot)
297
+ {
298
+ // All operands are context-determined.
299
+ for (auto &op : expr.operands ())
300
+ downwards_type_propagation (op, type);
301
+ expr.type () = type;
302
+ return ;
303
+ }
304
+ else if (
305
+ expr.id () == ID_shl || expr.id () == ID_ashr || expr.id () == ID_lshr ||
306
+ expr.id () == ID_power)
307
+ {
308
+ // The LHS is context-determined, the RHS is self-determined
309
+ auto &binary_expr = to_binary_expr (expr);
310
+ downwards_type_propagation (binary_expr.lhs (), type);
311
+ expr.type () = type;
312
+ return ;
313
+ }
314
+ else if (expr.id () == ID_if)
315
+ {
316
+ // The first operand is self-determined, the others are context-determined
317
+ auto &if_expr = to_if_expr (expr);
318
+ downwards_type_propagation (if_expr.op1 (), type);
319
+ downwards_type_propagation (if_expr.op2 (), type);
320
+ expr.type () = type;
321
+ return ;
322
+ }
301
323
302
- return ;
303
- }
304
- else if (expr.id () == ID_if)
305
- {
306
- if (expr.operands ().size () == 3 )
307
- {
308
- propagate_type (to_if_expr (expr).true_case (), type);
309
- propagate_type (to_if_expr (expr).false_case (), type);
324
+ // Just cast the expression, leave any operands as they are.
310
325
311
- expr.type () = type;
312
- return ;
313
- }
314
- }
315
- else if (expr.id () == ID_shl) // does not work with shr
316
- {
317
- // does not work with boolean
318
- if (type.id () != ID_bool)
319
- {
320
- if (expr.operands ().size () == 2 )
321
- {
322
- propagate_type (to_binary_expr (expr).op0 (), type);
323
- // not applicable to second operand
326
+ bool is_constant = expr.is_constant ();
324
327
325
- expr.type () = type;
326
- return ;
327
- }
328
- }
329
- }
328
+ if (
329
+ (expr.type ().id () == ID_signedbv ||
330
+ expr.type ().id () == ID_verilog_signedbv) &&
331
+ (type.id () == ID_unsignedbv || type.id () == ID_verilog_unsignedbv) &&
332
+ get_width (expr.type ()) < get_width (type))
333
+ {
334
+ // "If the operand shall be extended, then it shall be sign-extended only
335
+ // if the propagated type is signed."
336
+ // A typecast from signed to a larger unsigned would sign extend.
337
+ expr = zero_extend (expr, type);
338
+ }
339
+ else
340
+ {
341
+ expr = typecast_exprt{expr, type};
330
342
}
331
343
332
- implicit_typecast (expr, type);
344
+ // fold constants
345
+ if (is_constant)
346
+ expr = verilog_simplifier (expr, ns);
333
347
}
334
348
335
349
/* ******************************************************************\
@@ -2439,39 +2453,6 @@ void verilog_typecheck_exprt::tc_binary_expr(
2439
2453
2440
2454
/* ******************************************************************\
2441
2455
2442
- Function: zero_extend
2443
-
2444
- Inputs:
2445
-
2446
- Outputs:
2447
-
2448
- Purpose:
2449
-
2450
- \*******************************************************************/
2451
-
2452
- static exprt zero_extend (const exprt &expr, const typet &type)
2453
- {
2454
- auto old_width = expr.type ().id () == ID_bool ? 1
2455
- : expr.type ().id () == ID_integer
2456
- ? 32
2457
- : to_bitvector_type (expr.type ()).get_width ();
2458
-
2459
- // first make unsigned
2460
- typet tmp_type;
2461
-
2462
- if (type.id () == ID_unsignedbv)
2463
- tmp_type = unsignedbv_typet{old_width};
2464
- else if (type.id () == ID_verilog_unsignedbv)
2465
- tmp_type = verilog_unsignedbv_typet{old_width};
2466
- else
2467
- PRECONDITION (false );
2468
-
2469
- return typecast_exprt::conditional_cast (
2470
- typecast_exprt::conditional_cast (expr, tmp_type), type);
2471
- }
2472
-
2473
- /* ******************************************************************\
2474
-
2475
2456
Function: verilog_typecheck_exprt::convert_relation
2476
2457
2477
2458
Inputs:
0 commit comments