Low-level comparison op for integers and pointers. Both unsigned and signed comparisons are supported. Supports comparisons between fixed-width integer types and pointer types. The operands should have matching sizes. The result is always a bit (representing a boolean). Python
| 1473 | |
| 1474 | @final |
| 1475 | class ComparisonOp(RegisterOp): |
| 1476 | """Low-level comparison op for integers and pointers. |
| 1477 | |
| 1478 | Both unsigned and signed comparisons are supported. Supports |
| 1479 | comparisons between fixed-width integer types and pointer types. |
| 1480 | The operands should have matching sizes. |
| 1481 | |
| 1482 | The result is always a bit (representing a boolean). |
| 1483 | |
| 1484 | Python semantics, such as calling __eq__, are not supported. |
| 1485 | """ |
| 1486 | |
| 1487 | # Must be ERR_NEVER or ERR_FALSE. ERR_FALSE means that a false result |
| 1488 | # indicates that an exception has been raised and should be propagated. |
| 1489 | error_kind = ERR_NEVER |
| 1490 | |
| 1491 | # S for signed and U for unsigned |
| 1492 | EQ: Final = 100 |
| 1493 | NEQ: Final = 101 |
| 1494 | SLT: Final = 102 |
| 1495 | SGT: Final = 103 |
| 1496 | SLE: Final = 104 |
| 1497 | SGE: Final = 105 |
| 1498 | ULT: Final = 106 |
| 1499 | UGT: Final = 107 |
| 1500 | ULE: Final = 108 |
| 1501 | UGE: Final = 109 |
| 1502 | |
| 1503 | op_str: Final = { |
| 1504 | EQ: "==", |
| 1505 | NEQ: "!=", |
| 1506 | SLT: "<", |
| 1507 | SGT: ">", |
| 1508 | SLE: "<=", |
| 1509 | SGE: ">=", |
| 1510 | ULT: "<", |
| 1511 | UGT: ">", |
| 1512 | ULE: "<=", |
| 1513 | UGE: ">=", |
| 1514 | } |
| 1515 | |
| 1516 | signed_ops: Final = {"==": EQ, "!=": NEQ, "<": SLT, ">": SGT, "<=": SLE, ">=": SGE} |
| 1517 | unsigned_ops: Final = {"==": EQ, "!=": NEQ, "<": ULT, ">": UGT, "<=": ULE, ">=": UGE} |
| 1518 | |
| 1519 | def __init__(self, lhs: Value, rhs: Value, op: int, line: int = -1) -> None: |
| 1520 | super().__init__(line) |
| 1521 | self.type = bit_rprimitive |
| 1522 | self.lhs = lhs |
| 1523 | self.rhs = rhs |
| 1524 | self.op = op |
| 1525 | |
| 1526 | def sources(self) -> list[Value]: |
| 1527 | return [self.lhs, self.rhs] |
| 1528 | |
| 1529 | def set_sources(self, new: list[Value]) -> None: |
| 1530 | self.lhs, self.rhs = new |
| 1531 | |
| 1532 | def accept(self, visitor: OpVisitor[T]) -> T: |
no outgoing calls
searching dependent graphs…