- (define-binop logand 2 and)
- (define-binop logior 2 or)
- (define-binop logxor 2 xor))
+
+ ;; The following have microoptimizations for some special cases
+ ;; not caught by the front end.
+
+ (define-binop logand 2 and
+ :c/unsigned=>unsigned
+ ((move r x)
+ (let ((y (constantize y)))
+ ;; ANDing with #xFFFF_FFFF_FFFF_FFFF is a no-op, other than
+ ;; the eflags state which we don't care about.
+ (unless (eql y -1) ; do nothing if this is true
+ (inst and r y)))))
+
+ (define-binop logior 2 or
+ :c/unsigned=>unsigned
+ ((let ((y (constantize y)))
+ (cond ((and (register-p r) (eql y -1)) ; special-case "OR reg, all-ones"
+ ;; I have yet to elicit this case. Can it happen?
+ (inst mov r -1))
+ (t
+ (move r x)
+ (inst or r y))))))
+
+ (define-binop logxor 2 xor
+ :c/unsigned=>unsigned
+ ((move r x)
+ (let ((y (constantize y)))
+ (if (eql y -1) ; special-case "XOR reg, [all-ones]"
+ (inst not r)
+ (inst xor r y))))))