-(defmacro define-c-binop (translate cost untagged-cost tagged-type
- untagged-type inst)
- `(progn
- (define-vop (,(symbolicate "FAST-" translate "-C/FIXNUM=>FIXNUM")
- fast-fixnum-c-binop)
- (:arg-types tagged-num (:constant ,tagged-type))
- (:translate ,translate)
- (:generator ,cost
- (let ((y (fixnumize y)))
- ,inst)))
- (define-vop (,(symbolicate "FAST-" translate "-C/SIGNED=>SIGNED")
- fast-signed-c-binop)
- (:arg-types signed-num (:constant ,untagged-type))
- (:translate ,translate)
- (:generator ,untagged-cost
- ,inst))
- (define-vop (,(symbolicate "FAST-" translate "-C/UNSIGNED=>UNSIGNED")
- fast-unsigned-c-binop)
- (:arg-types unsigned-num (:constant ,untagged-type))
- (:translate ,translate)
- (:generator ,untagged-cost
- ,inst))))
-
-(define-c-binop + 1 3 (signed-byte 9) (signed-byte 11)
- (inst addi y x r))
-(define-c-binop - 1 3
- (integer #.(- (1- (ash 1 9))) #.(ash 1 9))
- (integer #.(- (1- (ash 1 11))) #.(ash 1 11))
- (inst addi (- y) x r))
-
-;;; Special case fixnum + and - that trap on overflow. Useful when we don't
-;;; know that the result is going to be a fixnum.
-
-(define-vop (fast-+/fixnum fast-+/fixnum=>fixnum)
- (:results (r :scs (any-reg descriptor-reg)))
- (:result-types (:or signed-num unsigned-num))
- (:note nil)
+(macrolet
+ ((define-binop (translate cost untagged-cost op arg-swap)
+ `(progn
+ (define-vop (,(symbolicate "FAST-" translate "/FIXNUM=>FIXNUM")
+ fast-fixnum-binop)
+ (:args (x :target r :scs (any-reg))
+ (y :target r :scs (any-reg)))
+ (:translate ,translate)
+ (:generator ,(1+ cost)
+ ,(if arg-swap
+ `(inst ,op y x r)
+ `(inst ,op x y r))))
+ (define-vop (,(symbolicate "FAST-" translate "/SIGNED=>SIGNED")
+ fast-signed-binop)
+ (:args (x :target r :scs (signed-reg))
+ (y :target r :scs (signed-reg)))
+ (:translate ,translate)
+ (:generator ,(1+ untagged-cost)
+ ,(if arg-swap
+ `(inst ,op y x r)
+ `(inst ,op x y r))))
+ (define-vop (,(symbolicate "FAST-" translate "/UNSIGNED=>UNSIGNED")
+ fast-unsigned-binop)
+ (:args (x :target r :scs (unsigned-reg))
+ (y :target r :scs (unsigned-reg)))
+ (:translate ,translate)
+ (:generator ,(1+ untagged-cost)
+ ,(if arg-swap
+ `(inst ,op y x r)
+ `(inst ,op x y r)))))))
+ (define-binop + 1 5 add nil)
+ (define-binop - 1 5 sub nil)
+ (define-binop logior 1 2 or nil)
+ (define-binop logand 1 2 and nil)
+ (define-binop logandc1 1 2 andcm t)
+ (define-binop logandc2 1 2 andcm nil)
+ (define-binop logxor 1 2 xor nil))
+
+(macrolet
+ ((define-c-binop (translate cost untagged-cost tagged-type untagged-type inst)
+ `(progn
+ (define-vop (,(symbolicate "FAST-" translate "-C/FIXNUM=>FIXNUM")
+ fast-fixnum-c-binop)
+ (:arg-types tagged-num (:constant ,tagged-type))
+ (:translate ,translate)
+ (:generator ,cost
+ (let ((y (fixnumize y)))
+ ,inst)))
+ (define-vop (,(symbolicate "FAST-" translate "-C/SIGNED=>SIGNED")
+ fast-signed-c-binop)
+ (:arg-types signed-num (:constant ,untagged-type))
+ (:translate ,translate)
+ (:generator ,untagged-cost
+ ,inst))
+ (define-vop (,(symbolicate "FAST-" translate "-C/UNSIGNED=>UNSIGNED")
+ fast-unsigned-c-binop)
+ (:arg-types unsigned-num (:constant ,untagged-type))
+ (:translate ,translate)
+ (:generator ,untagged-cost
+ ,inst)))))
+
+ (define-c-binop + 1 3 (signed-byte 9) (signed-byte 11)
+ (inst addi y x r))
+ (define-c-binop - 1 3
+ (integer #.(- 1 (ash 1 8)) #.(ash 1 8))
+ (integer #.(- 1 (ash 1 10)) #.(ash 1 10))
+ (inst addi (- y) x r)))
+
+(define-vop (fast-lognor/fixnum=>fixnum fast-fixnum-binop)
+ (:translate lognor)
+ (:args (x :target r :scs (any-reg))
+ (y :target r :scs (any-reg)))
+ (:temporary (:sc non-descriptor-reg) temp)