| | 1476 | |
| | 1477 | ;;; Modular arithmetic |
| | 1478 | ;;; logical operations |
| | 1479 | #+modular-arith |
| | 1480 | (progn |
| | 1481 | (c::define-modular-fun lognot-mod32 (x) lognot 32) |
| | 1482 | (define-vop (lognot-mod32/unsigned=>unsigned) |
| | 1483 | (:translate lognot-mod32) |
| | 1484 | (:args (x :scs (unsigned-reg unsigned-stack) :target r |
| | 1485 | :load-if (not (and (sc-is x unsigned-stack) |
| | 1486 | (sc-is r unsigned-stack) |
| | 1487 | (location= x r))))) |
| | 1488 | (:arg-types unsigned-num) |
| | 1489 | (:results (r :scs (unsigned-reg) |
| | 1490 | :load-if (not (and (sc-is x unsigned-stack) |
| | 1491 | (sc-is r unsigned-stack) |
| | 1492 | (location= x r))))) |
| | 1493 | (:result-types unsigned-num) |
| | 1494 | (:policy :fast-safe) |
| | 1495 | (:generator 1 |
| | 1496 | (move r x) |
| | 1497 | (inst not r))) |
| | 1498 | |
| | 1499 | (c::define-modular-fun logxor-mod32 (x y) logxor 32) |
| | 1500 | (define-vop (fast-logxor-mod32/unsigned=>unsigned |
| | 1501 | fast-logxor/unsigned=>unsigned) |
| | 1502 | (:translate logxor-mod32)) |
| | 1503 | (define-vop (fast-logxor-mod32-c/unsigned=>unsigned |
| | 1504 | fast-logxor-c/unsigned=>unsigned) |
| | 1505 | (:translate logxor-mod32)) |
| | 1506 | |
| | 1507 | (c::def-source-transform logeqv (&rest args) |
| | 1508 | (if (oddp (length args)) |
| | 1509 | `(logxor ,@args) |
| | 1510 | `(lognot (logxor ,@args)))) |
| | 1511 | (c::def-source-transform logandc1 (x y) |
| | 1512 | `(logand (lognot ,x) ,y)) |
| | 1513 | (c::def-source-transform logandc2 (x y) |
| | 1514 | `(logand ,x (lognot ,y))) |
| | 1515 | (c::def-source-transform logorc1 (x y) |
| | 1516 | `(logior (lognot ,x) ,y)) |
| | 1517 | (c::def-source-transform logorc2 (x y) |
| | 1518 | `(logior ,x (lognot ,y))) |
| | 1519 | (c::def-source-transform lognor (x y) |
| | 1520 | `(lognot (logior ,x ,y))) |
| | 1521 | (c::def-source-transform lognand (x y) |
| | 1522 | `(lognot (logand ,x ,y))) |
| | 1523 | |
| | 1524 | ;;;; Modular functions |
| | 1525 | |
| | 1526 | (c::define-modular-fun +-mod32 (x y) + 32) |
| | 1527 | (define-vop (fast-+-mod32/unsigned=>unsigned fast-+/unsigned=>unsigned) |
| | 1528 | (:translate +-mod32)) |
| | 1529 | (define-vop (fast-+-mod32-c/unsigned=>unsigned fast-+-c/unsigned=>unsigned) |
| | 1530 | (:translate +-mod32)) |
| | 1531 | (c::define-modular-fun --mod32 (x y) - 32) |
| | 1532 | (define-vop (fast---mod32/unsigned=>unsigned fast--/unsigned=>unsigned) |
| | 1533 | (:translate --mod32)) |
| | 1534 | (define-vop (fast---mod32-c/unsigned=>unsigned fast---c/unsigned=>unsigned) |
| | 1535 | (:translate --mod32)) |
| | 1536 | |
| | 1537 | (c::define-modular-fun *-mod32 (x y) * 32) |
| | 1538 | (define-vop (fast-*-mod32/unsigned=>unsigned fast-*/unsigned=>unsigned) |
| | 1539 | (:translate *-mod32)) |
| | 1540 | ;;; (no -C variant as x86 MUL instruction doesn't take an immediate) |
| | 1541 | |
| | 1542 | (defknown vm::ash-left-mod32 (integer (integer 0)) |
| | 1543 | (unsigned-byte 32) |
| | 1544 | (foldable flushable movable)) |
| | 1545 | |
| | 1546 | (define-vop (fast-ash-left-mod32-c/unsigned=>unsigned |
| | 1547 | fast-ash-c/unsigned=>unsigned) |
| | 1548 | (:translate ash-left-mod32)) |
| | 1549 | ) |
| | 1550 | |
| | 1551 | (in-package :C) |
| | 1552 | #+modular-arith |
| | 1553 | (progn |
| | 1554 | (define-modular-fun-optimizer ash ((integer count) :width width) |
| | 1555 | ;; The count needs to be (unsigned-byte 32) because the Sparc shift |
| | 1556 | ;; instruction takes the count modulo 32. (NOTE: Should we make |
| | 1557 | ;; this work on Ultrasparcs? We could then use the sllx instruction |
| | 1558 | ;; which takes the count mod 64. Then a left shift of 32 or more |
| | 1559 | ;; will produce 0 in the lower 32 bits of the register, which is |
| | 1560 | ;; what we want.) |
| | 1561 | (when (and (<= width 32) |
| | 1562 | (csubtypep (continuation-type count) (specifier-type '(unsigned-byte 5)))) |
| | 1563 | (cut-to-width integer width) |
| | 1564 | 'vm::ash-left-mod32)) |
| | 1565 | |
| | 1566 | ;; This should only get called when the ash modular function optimizer |
| | 1567 | ;; succeeds, which is for a count of 0-31, which is just right for |
| | 1568 | ;; %ashl. |
| | 1569 | (defun vm::ash-left-mod32 (integer count) |
| | 1570 | (bignum::%ashl (ldb (byte 32 0) integer) count)) |
| | 1571 | |
| | 1572 | ) |