@@ -1412,6 +1412,7 @@ bool eval_const_arithmetic(insn_t *insn)
1412
1412
int l = insn -> rs1 -> init_val , r = insn -> rs2 -> init_val ;
1413
1413
1414
1414
switch (insn -> opcode ) {
1415
+ /* Arithmetic operations */
1415
1416
case OP_add :
1416
1417
res = l + r ;
1417
1418
break ;
@@ -1422,11 +1423,65 @@ bool eval_const_arithmetic(insn_t *insn)
1422
1423
res = l * r ;
1423
1424
break ;
1424
1425
case OP_div :
1426
+ if (r == 0 )
1427
+ return false; /* Division by zero protection */
1425
1428
res = l / r ;
1426
1429
break ;
1427
1430
case OP_mod :
1431
+ if (r == 0 )
1432
+ return false; /* Modulo by zero protection */
1428
1433
res = l % r ;
1429
1434
break ;
1435
+
1436
+ /* Bitwise operations */
1437
+ case OP_bit_and :
1438
+ res = l & r ;
1439
+ break ;
1440
+ case OP_bit_or :
1441
+ res = l | r ;
1442
+ break ;
1443
+ case OP_bit_xor :
1444
+ res = l ^ r ;
1445
+ break ;
1446
+ case OP_lshift :
1447
+ if (r < 0 || r >= 32 )
1448
+ return false; /* Safe shift range */
1449
+ res = l << r ;
1450
+ break ;
1451
+ case OP_rshift :
1452
+ if (r < 0 || r >= 32 )
1453
+ return false; /* Safe shift range */
1454
+ res = l >> r ;
1455
+ break ;
1456
+
1457
+ /* Comparison operations */
1458
+ case OP_eq :
1459
+ res = (l == r );
1460
+ break ;
1461
+ case OP_neq :
1462
+ res = (l != r );
1463
+ break ;
1464
+ case OP_lt :
1465
+ res = (l < r );
1466
+ break ;
1467
+ case OP_leq :
1468
+ res = (l <= r );
1469
+ break ;
1470
+ case OP_gt :
1471
+ res = (l > r );
1472
+ break ;
1473
+ case OP_geq :
1474
+ res = (l >= r );
1475
+ break ;
1476
+
1477
+ /* Logical operations */
1478
+ case OP_log_and :
1479
+ res = (l && r );
1480
+ break ;
1481
+ case OP_log_or :
1482
+ res = (l || r );
1483
+ break ;
1484
+
1430
1485
default :
1431
1486
return false;
1432
1487
}
@@ -1439,12 +1494,47 @@ bool eval_const_arithmetic(insn_t *insn)
1439
1494
return true;
1440
1495
}
1441
1496
1497
+ bool eval_const_unary (insn_t * insn )
1498
+ {
1499
+ if (!insn -> rs1 )
1500
+ return false;
1501
+ if (!insn -> rs1 -> is_const )
1502
+ return false;
1503
+ if (insn -> rs2 ) /* Should be unary operation */
1504
+ return false;
1505
+
1506
+ int res ;
1507
+ int operand = insn -> rs1 -> init_val ;
1508
+
1509
+ switch (insn -> opcode ) {
1510
+ case OP_negate :
1511
+ res = - operand ;
1512
+ break ;
1513
+ case OP_bit_not :
1514
+ res = ~operand ;
1515
+ break ;
1516
+ case OP_log_not :
1517
+ res = !operand ;
1518
+ break ;
1519
+ default :
1520
+ return false;
1521
+ }
1522
+
1523
+ insn -> rs1 = NULL ;
1524
+ insn -> rd -> is_const = 1 ;
1525
+ insn -> rd -> init_val = res ;
1526
+ insn -> opcode = OP_load_constant ;
1527
+ return true;
1528
+ }
1529
+
1442
1530
bool const_folding (insn_t * insn )
1443
1531
{
1444
1532
if (mark_const (insn ))
1445
1533
return true;
1446
1534
if (eval_const_arithmetic (insn ))
1447
1535
return true;
1536
+ if (eval_const_unary (insn ))
1537
+ return true;
1448
1538
return false;
1449
1539
}
1450
1540
@@ -1984,22 +2074,22 @@ bool enhanced_const_fold(insn_t *insn)
1984
2074
result = l ^ r ;
1985
2075
break ;
1986
2076
case OP_eq :
1987
- result = (l == r ) ? 1 : 0 ;
2077
+ result = (l == r );
1988
2078
break ;
1989
2079
case OP_neq :
1990
- result = (l != r ) ? 1 : 0 ;
2080
+ result = (l != r );
1991
2081
break ;
1992
2082
case OP_lt :
1993
- result = (l < r ) ? 1 : 0 ;
2083
+ result = (l < r );
1994
2084
break ;
1995
2085
case OP_leq :
1996
- result = (l <= r ) ? 1 : 0 ;
2086
+ result = (l <= r );
1997
2087
break ;
1998
2088
case OP_gt :
1999
- result = (l > r ) ? 1 : 0 ;
2089
+ result = (l > r );
2000
2090
break ;
2001
2091
case OP_geq :
2002
- result = (l >= r ) ? 1 : 0 ;
2092
+ result = (l >= r );
2003
2093
break ;
2004
2094
default :
2005
2095
return false;
0 commit comments