@@ -1407,6 +1407,7 @@ bool eval_const_arithmetic(insn_t *insn)
14071407 int l = insn -> rs1 -> init_val , r = insn -> rs2 -> init_val ;
14081408
14091409 switch (insn -> opcode ) {
1410+ /* Arithmetic operations */
14101411 case OP_add :
14111412 res = l + r ;
14121413 break ;
@@ -1417,11 +1418,65 @@ bool eval_const_arithmetic(insn_t *insn)
14171418 res = l * r ;
14181419 break ;
14191420 case OP_div :
1421+ if (r == 0 )
1422+ return false; /* Division by zero protection */
14201423 res = l / r ;
14211424 break ;
14221425 case OP_mod :
1426+ if (r == 0 )
1427+ return false; /* Modulo by zero protection */
14231428 res = l % r ;
14241429 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+
14251480 default :
14261481 return false;
14271482 }
@@ -1434,12 +1489,47 @@ bool eval_const_arithmetic(insn_t *insn)
14341489 return true;
14351490}
14361491
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+
14371525bool const_folding (insn_t * insn )
14381526{
14391527 if (mark_const (insn ))
14401528 return true;
14411529 if (eval_const_arithmetic (insn ))
14421530 return true;
1531+ if (eval_const_unary (insn ))
1532+ return true;
14431533 return false;
14441534}
14451535
0 commit comments