@@ -1407,6 +1407,7 @@ bool eval_const_arithmetic(insn_t *insn)
1407
1407
int l = insn -> rs1 -> init_val , r = insn -> rs2 -> init_val ;
1408
1408
1409
1409
switch (insn -> opcode ) {
1410
+ /* Arithmetic operations */
1410
1411
case OP_add :
1411
1412
res = l + r ;
1412
1413
break ;
@@ -1417,11 +1418,65 @@ bool eval_const_arithmetic(insn_t *insn)
1417
1418
res = l * r ;
1418
1419
break ;
1419
1420
case OP_div :
1421
+ if (r == 0 )
1422
+ return false; /* Division by zero protection */
1420
1423
res = l / r ;
1421
1424
break ;
1422
1425
case OP_mod :
1426
+ if (r == 0 )
1427
+ return false; /* Modulo by zero protection */
1423
1428
res = l % r ;
1424
1429
break ;
1430
+
1431
+ /* Bitwise operations */
1432
+ case OP_bit_and :
1433
+ res = l & r ;
1434
+ break ;
1435
+ case OP_bit_or :
1436
+ res = l | r ;
1437
+ break ;
1438
+ case OP_bit_xor :
1439
+ res = l ^ r ;
1440
+ break ;
1441
+ case OP_lshift :
1442
+ if (r < 0 || r >= 32 )
1443
+ return false; /* Safe shift range */
1444
+ res = l << r ;
1445
+ break ;
1446
+ case OP_rshift :
1447
+ if (r < 0 || r >= 32 )
1448
+ return false; /* Safe shift range */
1449
+ res = l >> r ;
1450
+ break ;
1451
+
1452
+ /* Comparison operations */
1453
+ case OP_eq :
1454
+ res = (l == r ) ? 1 : 0 ;
1455
+ break ;
1456
+ case OP_neq :
1457
+ res = (l != r ) ? 1 : 0 ;
1458
+ break ;
1459
+ case OP_lt :
1460
+ res = (l < r ) ? 1 : 0 ;
1461
+ break ;
1462
+ case OP_leq :
1463
+ res = (l <= r ) ? 1 : 0 ;
1464
+ break ;
1465
+ case OP_gt :
1466
+ res = (l > r ) ? 1 : 0 ;
1467
+ break ;
1468
+ case OP_geq :
1469
+ res = (l >= r ) ? 1 : 0 ;
1470
+ break ;
1471
+
1472
+ /* Logical operations */
1473
+ case OP_log_and :
1474
+ res = (l && r ) ? 1 : 0 ;
1475
+ break ;
1476
+ case OP_log_or :
1477
+ res = (l || r ) ? 1 : 0 ;
1478
+ break ;
1479
+
1425
1480
default :
1426
1481
return false;
1427
1482
}
@@ -1434,12 +1489,47 @@ bool eval_const_arithmetic(insn_t *insn)
1434
1489
return true;
1435
1490
}
1436
1491
1492
+ bool eval_const_unary (insn_t * insn )
1493
+ {
1494
+ if (!insn -> rs1 )
1495
+ return false;
1496
+ if (!insn -> rs1 -> is_const )
1497
+ return false;
1498
+ if (insn -> rs2 ) /* Should be unary operation */
1499
+ return false;
1500
+
1501
+ int res ;
1502
+ int operand = insn -> rs1 -> init_val ;
1503
+
1504
+ switch (insn -> opcode ) {
1505
+ case OP_negate :
1506
+ res = - operand ;
1507
+ break ;
1508
+ case OP_bit_not :
1509
+ res = ~operand ;
1510
+ break ;
1511
+ case OP_log_not :
1512
+ res = !operand ? 1 : 0 ;
1513
+ break ;
1514
+ default :
1515
+ return false;
1516
+ }
1517
+
1518
+ insn -> rs1 = NULL ;
1519
+ insn -> rd -> is_const = 1 ;
1520
+ insn -> rd -> init_val = res ;
1521
+ insn -> opcode = OP_load_constant ;
1522
+ return true;
1523
+ }
1524
+
1437
1525
bool const_folding (insn_t * insn )
1438
1526
{
1439
1527
if (mark_const (insn ))
1440
1528
return true;
1441
1529
if (eval_const_arithmetic (insn ))
1442
1530
return true;
1531
+ if (eval_const_unary (insn ))
1532
+ return true;
1443
1533
return false;
1444
1534
}
1445
1535
0 commit comments