Generate a binary op using Python fixed-width integer semantics. These may differ in overflow/rounding behavior from native/C ops. Args: type: Either int64_rprimitive or int32_rprimitive op: IntOp.* constant (e.g. IntOp.ADD)
(
self, type: RPrimitive, lhs: Value, rhs: Value, op: int, line: int
)
| 2537 | return self.int_op(lhs.type, lhs, rhs, IntOp.MUL, lhs.line) |
| 2538 | |
| 2539 | def fixed_width_int_op( |
| 2540 | self, type: RPrimitive, lhs: Value, rhs: Value, op: int, line: int |
| 2541 | ) -> Value: |
| 2542 | """Generate a binary op using Python fixed-width integer semantics. |
| 2543 | |
| 2544 | These may differ in overflow/rounding behavior from native/C ops. |
| 2545 | |
| 2546 | Args: |
| 2547 | type: Either int64_rprimitive or int32_rprimitive |
| 2548 | op: IntOp.* constant (e.g. IntOp.ADD) |
| 2549 | """ |
| 2550 | lhs = self.coerce(lhs, type, line) |
| 2551 | rhs = self.coerce(rhs, type, line) |
| 2552 | if op == IntOp.DIV: |
| 2553 | if isinstance(rhs, Integer) and rhs.value not in (-1, 0): |
| 2554 | if not type.is_signed: |
| 2555 | return self.int_op(type, lhs, rhs, IntOp.DIV, line) |
| 2556 | else: |
| 2557 | # Inline simple division by a constant, so that C |
| 2558 | # compilers can optimize more |
| 2559 | return self.inline_fixed_width_divide(type, lhs, rhs, line) |
| 2560 | if is_int64_rprimitive(type): |
| 2561 | prim = int64_divide_op |
| 2562 | elif is_int32_rprimitive(type): |
| 2563 | prim = int32_divide_op |
| 2564 | elif is_int16_rprimitive(type): |
| 2565 | prim = int16_divide_op |
| 2566 | elif is_uint8_rprimitive(type): |
| 2567 | self.check_for_zero_division(rhs, type, line) |
| 2568 | return self.int_op(type, lhs, rhs, op, line) |
| 2569 | else: |
| 2570 | assert False, type |
| 2571 | return self.call_c(prim, [lhs, rhs], line) |
| 2572 | if op == IntOp.MOD: |
| 2573 | if isinstance(rhs, Integer) and rhs.value not in (-1, 0): |
| 2574 | if not type.is_signed: |
| 2575 | return self.int_op(type, lhs, rhs, IntOp.MOD, line) |
| 2576 | else: |
| 2577 | # Inline simple % by a constant, so that C |
| 2578 | # compilers can optimize more |
| 2579 | return self.inline_fixed_width_mod(type, lhs, rhs, line) |
| 2580 | if is_int64_rprimitive(type): |
| 2581 | prim = int64_mod_op |
| 2582 | elif is_int32_rprimitive(type): |
| 2583 | prim = int32_mod_op |
| 2584 | elif is_int16_rprimitive(type): |
| 2585 | prim = int16_mod_op |
| 2586 | elif is_uint8_rprimitive(type): |
| 2587 | self.check_for_zero_division(rhs, type, line) |
| 2588 | return self.int_op(type, lhs, rhs, op, line) |
| 2589 | else: |
| 2590 | assert False, type |
| 2591 | return self.call_c(prim, [lhs, rhs], line) |
| 2592 | return self.int_op(type, lhs, rhs, op, line) |
| 2593 | |
| 2594 | def check_for_zero_division(self, rhs: Value, type: RType, line: int) -> None: |
| 2595 | err, ok = BasicBlock(), BasicBlock() |
no test coverage detected