mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-20 11:40:18 +02:00
Add logsub op.
* libguile/vm-engine.c (logsub): New op. * module/language/cps/effects-analysis.scm (logsub): * module/language/cps/types.scm (logsub): * module/system/vm/assembler.scm (system): Add support for the new op. * module/language/tree-il/compile-cps.scm (canonicalize): Rewrite (logand x (lognot y)) to (logsub x y).
This commit is contained in:
parent
8c75a5eb1b
commit
82085252ec
5 changed files with 58 additions and 1 deletions
|
@ -3482,7 +3482,27 @@ VM_NAME (scm_i_thread *thread, struct scm_vm *vp,
|
|||
NEXT (1);
|
||||
}
|
||||
|
||||
VM_DEFINE_OP (161, unused_161, NULL, NOP)
|
||||
/* logsub dst:8 a:8 b:8
|
||||
*
|
||||
* Place the bitwise AND of A and the bitwise NOT of B into DST.
|
||||
*/
|
||||
VM_DEFINE_OP (161, logsub, "logsub", OP1 (X8_S8_S8_S8) | OP_DST)
|
||||
{
|
||||
ARGS2 (x, y);
|
||||
|
||||
if (SCM_I_INUMP (x) && SCM_I_INUMP (y))
|
||||
{
|
||||
scm_t_signed_bits a, b;
|
||||
|
||||
a = SCM_I_INUM (x);
|
||||
b = SCM_I_INUM (y);
|
||||
|
||||
RETURN (SCM_I_MAKINUM (a & ~b));
|
||||
}
|
||||
|
||||
RETURN_EXP (scm_logand (x, scm_lognot (y)));
|
||||
}
|
||||
|
||||
VM_DEFINE_OP (162, unused_162, NULL, NOP)
|
||||
VM_DEFINE_OP (163, unused_163, NULL, NOP)
|
||||
VM_DEFINE_OP (164, unused_164, NULL, NOP)
|
||||
|
|
|
@ -465,6 +465,7 @@ is or might be a read or a write to the same location as A."
|
|||
((logand . _) &type-check)
|
||||
((logior . _) &type-check)
|
||||
((logxor . _) &type-check)
|
||||
((logsub . _) &type-check)
|
||||
((lognot . _) &type-check)
|
||||
((logtest a b) &type-check)
|
||||
((logbit? a b) &type-check)
|
||||
|
|
|
@ -1212,6 +1212,31 @@ minimum, and maximum."
|
|||
(logand-min (&min a) (&min b))
|
||||
(logand-max (&max a) (&max b))))
|
||||
|
||||
(define-simple-type-checker (logsub &exact-integer &exact-integer))
|
||||
(define-type-inferrer (logsub a b result)
|
||||
(define (logsub-bounds min-a max-a min-b max-b)
|
||||
(cond
|
||||
((negative? max-b)
|
||||
;; Sign bit always set on B, so result will never be negative.
|
||||
;; If A might be negative (all leftmost bits 1), we don't know
|
||||
;; how positive the result might be.
|
||||
(values 0 (if (negative? min-a) +inf.0 max-a)))
|
||||
((negative? min-b)
|
||||
;; Sign bit might be set on B.
|
||||
(values min-a (if (negative? min-a) +inf.0 max-a)))
|
||||
((negative? min-a)
|
||||
;; Sign bit never set on B -- result will have the sign of A.
|
||||
(values min-a (if (negative? max-a) -1 max-a)))
|
||||
(else
|
||||
;; Sign bit never set on A and never set on B -- the nice case.
|
||||
(values 0 max-a))))
|
||||
(restrict! a &exact-integer -inf.0 +inf.0)
|
||||
(restrict! b &exact-integer -inf.0 +inf.0)
|
||||
(call-with-values (lambda ()
|
||||
(logsub-bounds (&min a) (&max a) (&min b) (&max b)))
|
||||
(lambda (min max)
|
||||
(define! result &exact-integer min max))))
|
||||
|
||||
(define-simple-type-checker (logior &exact-integer &exact-integer))
|
||||
(define-type-inferrer (logior a b result)
|
||||
;; Saturate all bits of val.
|
||||
|
|
|
@ -1012,6 +1012,16 @@ integer."
|
|||
(make-lexical-ref src 'v v)))
|
||||
(make-lexical-ref src 'v v)))))
|
||||
|
||||
;; Lower (logand x (lognot y)) to (logsub x y). We do it here
|
||||
;; instead of in CPS because it gets rid of the lognot entirely;
|
||||
;; if type folding can't prove Y to be an exact integer, then DCE
|
||||
;; would have to leave it in the program for its possible
|
||||
;; effects.
|
||||
(($ <primcall> src 'logand (x ($ <primcall> _ 'lognot (y))))
|
||||
(make-primcall src 'logsub (list x y)))
|
||||
(($ <primcall> src 'logand (($ <primcall> _ 'lognot (y)) x))
|
||||
(make-primcall src 'logsub (list x y)))
|
||||
|
||||
(($ <prompt> src escape-only? tag body
|
||||
($ <lambda> hsrc hmeta
|
||||
($ <lambda-case> _ hreq #f hrest #f () hsyms hbody #f)))
|
||||
|
|
|
@ -152,6 +152,7 @@
|
|||
(emit-logand* . emit-logand)
|
||||
(emit-logior* . emit-logior)
|
||||
(emit-logxor* . emit-logxor)
|
||||
(emit-logsub* . emit-logsub)
|
||||
(emit-make-vector* . emit-make-vector)
|
||||
(emit-make-vector/immediate* . emit-make-vector/immediate)
|
||||
(emit-vector-length* . emit-vector-length)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue