Optimize (mod FIXNUM) type-checks on x86oids.
[sbcl.git] / src / compiler / x86-64 / type-vops.lisp
index 04fa745..5c54135 100644 (file)
 
       (emit-label yep)
       (move result value))))
+
+(define-vop (check-mod-fixnum check-type)
+  (:info type)
+  (:temporary (:sc any-reg) temp)
+  (:generator 30
+     (let* ((low (numeric-type-low type))
+            (hi (fixnumize (numeric-type-high type)))
+            (error (gen-label)))
+       ;; FIXME: abstract
+       (assemble (*elsewhere*)
+         (emit-label error)
+         (inst mov temp hi)
+         (emit-error-break vop error-trap
+                           (error-number-or-lose 'object-not-mod-error)
+                           (list value temp)))
+       (aver (zerop low))
+       (cond
+         ;; Handle powers of two specially
+         ;; The higher bits and the fixnum tag can be tested in one go
+         ((= (logcount (1+ hi)) 1)
+          (inst test value
+                (constantize (lognot hi)))
+          (inst jmp :ne error))
+         (t
+          (generate-fixnum-test value)
+          (inst jmp :ne error)
+          (inst cmp value (constantize hi))
+          (inst jmp :a error)))
+       (move result value))))
+
 \f
 ;;;; list/symbol types
 ;;;
 (progn
   (!define-type-vops simd-pack-p nil nil nil (simd-pack-widetag))
 
-  #!+x86-64
   (define-vop (check-simd-pack check-type)
     (:args (value :target result
                   :scs (any-reg descriptor-reg