1.0.24.35: Flag-setting VOPs on x86[-64] and conditional moves
authorPaul Khuong <pvk@pvk.ca>
Sun, 11 Jan 2009 18:39:07 +0000 (18:39 +0000)
committerPaul Khuong <pvk@pvk.ca>
Sun, 11 Jan 2009 18:39:07 +0000 (18:39 +0000)
 * Most :CONDITIONAL VOPs only specify which condition flags they set

 * GENERIC-{EQL,=,<,>} are :CONDITIONAL VOPs, but don't show up as
   calls anymore

 * Values may be selected with CMOVcc if applicable (and :CMOV is
   in *backend-subfeatures*, for x86):
    - Values that are represented, unboxed, in GPRs are CMOVed using
      custom VOPs
    - Unboxed float and complex types aren't converted
    - Other types are assumed to be boxed and CMOVed as descriptors

 * A test to try and to cover an interesting cross-section of flags
   and values to move conditionally.

17 files changed:
src/assembly/x86-64/arith.lisp
src/assembly/x86/arith.lisp
src/compiler/x86-64/arith.lisp
src/compiler/x86-64/cell.lisp
src/compiler/x86-64/char.lisp
src/compiler/x86-64/float.lisp
src/compiler/x86-64/pred.lisp
src/compiler/x86-64/type-vops.lisp
src/compiler/x86/arith.lisp
src/compiler/x86/cell.lisp
src/compiler/x86/char.lisp
src/compiler/x86/float.lisp
src/compiler/x86/pred.lisp
src/compiler/x86/type-vops.lisp
tests/compiler.pure.lisp
tests/step.impure.lisp
version.lisp-expr

index 3e83992..d47b720 100644 (file)
 ;;;; comparison
 
 (macrolet ((define-cond-assem-rtn (name translate static-fn test)
 ;;;; comparison
 
 (macrolet ((define-cond-assem-rtn (name translate static-fn test)
+               (declare (ignorable translate static-fn))
+             #+sb-assembling
              `(define-assembly-routine (,name
              `(define-assembly-routine (,name
-                                        (:cost 10)
-                                        (:return-style :full-call)
-                                        (:policy :safe)
-                                        (:translate ,translate)
-                                        (:save-p t))
-                ((:arg x (descriptor-reg any-reg) rdx-offset)
-                 (:arg y (descriptor-reg any-reg) rdi-offset)
-
-                 (:res res descriptor-reg rdx-offset)
+                                        (:return-style :none))
+                  ((:arg x (descriptor-reg any-reg) rdx-offset)
+                   (:arg y (descriptor-reg any-reg) rdi-offset)
 
 
-                 (:temp eax unsigned-reg rax-offset)
-                 (:temp ecx unsigned-reg rcx-offset))
+                   (:temp rcx unsigned-reg rcx-offset))
 
 
-                (inst mov ecx x)
-                (inst or ecx y)
-                (inst test ecx fixnum-tag-mask)
+                (inst mov rcx x)
+                (inst or rcx y)
+                (inst test rcx fixnum-tag-mask)
                 (inst jmp :nz DO-STATIC-FUN)
 
                 (inst cmp x y)
                 (inst jmp :nz DO-STATIC-FUN)
 
                 (inst cmp x y)
-                (load-symbol res t)
-                (inst mov eax nil-value)
-                (inst cmov ,test res eax)
-                (inst clc)   ; single-value return
                 (inst ret)
 
                 DO-STATIC-FUN
                 (inst ret)
 
                 DO-STATIC-FUN
-                (inst pop eax)
-                (inst push rbp-tn)
-                (inst lea rbp-tn (make-ea :qword
-                                          :base rsp-tn
-                                          :disp n-word-bytes))
-                (inst sub rsp-tn (fixnumize 2)) ; FIXME: Push 2 words on stack,
-                                                ; weirdly?
-                (inst push eax)
-                (inst mov ecx (fixnumize 2)) ; FIXME: FIXNUMIZE and
-                                        ; SINGLE-FLOAT-BITS are parallel,
-                                        ; should be named parallelly.
-                (inst jmp (make-ea :qword
-                                   :disp (+ nil-value
-                                            (static-fun-offset ',static-fn)))))))
-
-  (define-cond-assem-rtn generic-< < two-arg-< :ge)
-  (define-cond-assem-rtn generic-> > two-arg-> :le))
-
+                (move rcx rsp-tn)
+                (inst sub rsp-tn (fixnumize 3))
+                (inst mov (make-ea :qword
+                                   :base rcx
+                                   :disp (fixnumize -1))
+                      rbp-tn)
+                (move rbp-tn rcx)
+                (inst mov rcx (fixnumize 2))
+                (inst call (make-ea :qword
+                                    :disp (+ nil-value
+                                             (static-fun-offset ',static-fn))))
+                ;; HACK: We depend on NIL having the lowest address of all
+                ;; static symbols (including T)
+                ,@(ecase test
+                    (:l `((inst mov y (1+ nil-value))
+                          (inst cmp y x)))
+                    (:g `((inst cmp x (1+ nil-value)))))
+                (inst ret))
+             #-sb-assembling
+             `(define-vop (,name)
+                (:translate ,translate)
+                (:policy :safe)
+                (:save-p t)
+                (:args (x :scs (descriptor-reg any-reg) :target rdx)
+                       (y :scs (descriptor-reg any-reg) :target rdi))
+
+                (:temporary (:sc unsigned-reg :offset rdx-offset
+                                 :from (:argument 0))
+                            rdx)
+                (:temporary (:sc unsigned-reg :offset rdi-offset
+                                 :from (:argument 1))
+                            rdi)
+
+                (:temporary (:sc unsigned-reg :offset rcx-offset
+                                 :from :eval)
+                            rcx)
+                (:conditional ,test)
+                (:generator 10
+                   (move rdx x)
+                   (move rdi y)
+                   (inst lea rcx (make-ea :qword
+                                          :disp (make-fixup ',name :assembly-routine)))
+                   (inst call rcx)))))
+
+  (define-cond-assem-rtn generic-< < two-arg-< :l)
+  (define-cond-assem-rtn generic-> > two-arg-> :g))
+
+#+sb-assembling
 (define-assembly-routine (generic-eql
 (define-assembly-routine (generic-eql
-                          (:cost 10)
-                          (:return-style :full-call)
-                          (:policy :safe)
-                          (:translate eql)
-                          (:save-p t))
+                          (:return-style :none))
                          ((:arg x (descriptor-reg any-reg) rdx-offset)
                           (:arg y (descriptor-reg any-reg) rdi-offset)
 
                          ((:arg x (descriptor-reg any-reg) rdx-offset)
                           (:arg y (descriptor-reg any-reg) rdi-offset)
 
-                          (:res res descriptor-reg rdx-offset)
-
-                          (:temp rax unsigned-reg rax-offset)
                           (:temp rcx unsigned-reg rcx-offset))
                           (:temp rcx unsigned-reg rcx-offset))
+
   (inst mov rcx x)
   (inst and rcx y)
   (inst test rcx fixnum-tag-mask)
   (inst mov rcx x)
   (inst and rcx y)
   (inst test rcx fixnum-tag-mask)
 
   ;; At least one fixnum
   (inst cmp x y)
 
   ;; At least one fixnum
   (inst cmp x y)
-  (load-symbol res t)
-  (inst mov rax nil-value)
-  (inst cmov :ne res rax)
-  (inst clc)
   (inst ret)
 
   DO-STATIC-FUN
   (inst ret)
 
   DO-STATIC-FUN
-  (inst pop rax)
-  (inst push rbp-tn)
-  (inst lea rbp-tn (make-ea :qword :base rsp-tn :disp n-word-bytes))
-  (inst sub rsp-tn (fixnumize 2))
-  (inst push rax)
+  (move rcx rsp-tn)
+  (inst sub rsp-tn (fixnumize 3))
+  (inst mov (make-ea :qword
+                     :base rcx
+                     :disp (fixnumize -1))
+        rbp-tn)
+  (move rbp-tn rcx)
   (inst mov rcx (fixnumize 2))
   (inst mov rcx (fixnumize 2))
-  (inst jmp (make-ea :qword
-                     :disp (+ nil-value (static-fun-offset 'eql)))))
-
+  (inst call (make-ea :qword
+                      :disp (+ nil-value (static-fun-offset 'eql))))
+  (load-symbol y t)
+  (inst cmp x y)
+  (inst ret))
+
+#-sb-assembling
+(define-vop (generic-eql)
+  (:translate eql)
+  (:policy :safe)
+  (:save-p t)
+  (:args (x :scs (descriptor-reg any-reg) :target rdx)
+         (y :scs (descriptor-reg any-reg) :target rdi))
+
+  (:temporary (:sc unsigned-reg :offset rdx-offset
+               :from (:argument 0))
+              rdx)
+  (:temporary (:sc unsigned-reg :offset rdi-offset
+               :from (:argument 1))
+              rdi)
+
+  (:temporary (:sc unsigned-reg :offset rcx-offset
+               :from :eval)
+              rcx)
+  (:conditional :e)
+  (:generator 10
+    (move rdx x)
+    (move rdi y)
+    (inst lea rcx (make-ea :qword
+                           :disp (make-fixup 'generic-eql :assembly-routine)))
+    (inst call rcx)))
+
+#+sb-assembling
 (define-assembly-routine (generic-=
 (define-assembly-routine (generic-=
-                          (:cost 10)
-                          (:return-style :full-call)
-                          (:policy :safe)
-                          (:translate =)
-                          (:save-p t))
+                          (:return-style :none))
                          ((:arg x (descriptor-reg any-reg) rdx-offset)
                           (:arg y (descriptor-reg any-reg) rdi-offset)
 
                          ((:arg x (descriptor-reg any-reg) rdx-offset)
                           (:arg y (descriptor-reg any-reg) rdi-offset)
 
-                          (:res res descriptor-reg rdx-offset)
-
-                          (:temp rax unsigned-reg rax-offset)
                           (:temp rcx unsigned-reg rcx-offset))
   (inst mov rcx x)
   (inst or rcx y)
                           (:temp rcx unsigned-reg rcx-offset))
   (inst mov rcx x)
   (inst or rcx y)
 
   ;; Both fixnums
   (inst cmp x y)
 
   ;; Both fixnums
   (inst cmp x y)
-  (load-symbol res t)
-  (inst mov rax nil-value)
-  (inst cmov :ne res rax)
-  (inst clc)
   (inst ret)
 
   DO-STATIC-FUN
   (inst ret)
 
   DO-STATIC-FUN
-  (inst pop rax)
-  (inst push rbp-tn)
-  (inst lea rbp-tn (make-ea :qword :base rsp-tn :disp n-word-bytes))
-  (inst sub rsp-tn (fixnumize 2))
-  (inst push rax)
+  (move rcx rsp-tn)
+  (inst sub rsp-tn (fixnumize 3))
+  (inst mov (make-ea :qword
+                     :base rcx
+                     :disp (fixnumize -1))
+        rbp-tn)
+  (move rbp-tn rcx)
   (inst mov rcx (fixnumize 2))
   (inst mov rcx (fixnumize 2))
-  (inst jmp (make-ea :qword
-                     :disp (+ nil-value (static-fun-offset 'two-arg-=)))))
-
-
+  (inst call (make-ea :qword
+                      :disp (+ nil-value (static-fun-offset 'two-arg-=))))
+  (load-symbol y t)
+  (inst cmp x y)
+  (inst ret))
+
+#-sb-assembling
+(define-vop (generic-=)
+  (:translate =)
+  (:policy :safe)
+  (:save-p t)
+  (:args (x :scs (descriptor-reg any-reg) :target rdx)
+         (y :scs (descriptor-reg any-reg) :target rdi))
+
+  (:temporary (:sc unsigned-reg :offset rdx-offset
+               :from (:argument 0))
+              rdx)
+  (:temporary (:sc unsigned-reg :offset rdi-offset
+               :from (:argument 1))
+              rdi)
+
+  (:temporary (:sc unsigned-reg :offset rcx-offset
+               :from :eval)
+              rcx)
+  (:conditional :e)
+  (:generator 10
+    (move rdx x)
+    (move rdi y)
+    (inst lea rcx (make-ea :qword
+                           :disp (make-fixup 'generic-= :assembly-routine)))
+    (inst call rcx)))
index 535e023..f3081f8 100644 (file)
 ;;;; comparison
 
 (macrolet ((define-cond-assem-rtn (name translate static-fn test)
 ;;;; comparison
 
 (macrolet ((define-cond-assem-rtn (name translate static-fn test)
+             #+sb-assembling
              `(define-assembly-routine (,name
              `(define-assembly-routine (,name
-                                        (:cost 10)
-                                        (:return-style :full-call)
-                                        (:policy :safe)
-                                        (:translate ,translate)
-                                        (:save-p t))
+                                        (:return-style :none))
                 ((:arg x (descriptor-reg any-reg) edx-offset)
                  (:arg y (descriptor-reg any-reg) edi-offset)
 
                 ((:arg x (descriptor-reg any-reg) edx-offset)
                  (:arg y (descriptor-reg any-reg) edi-offset)
 
-                 (:res res descriptor-reg edx-offset)
-
-                 (:temp eax unsigned-reg eax-offset)
                  (:temp ecx unsigned-reg ecx-offset))
 
                 (inst mov ecx x)
                  (:temp ecx unsigned-reg ecx-offset))
 
                 (inst mov ecx x)
                 (inst jmp :nz DO-STATIC-FUN)  ; are both fixnums?
 
                 (inst cmp x y)
                 (inst jmp :nz DO-STATIC-FUN)  ; are both fixnums?
 
                 (inst cmp x y)
-                (cond ((member :cmov *backend-subfeatures*)
-                       (load-symbol res t)
-                       (inst mov eax nil-value)
-                       (inst cmov ,test res eax))
-                      (t
-                       (inst mov res nil-value)
-                       (inst jmp ,test RETURN)
-                       (load-symbol res t)))
-                RETURN
-                (inst clc)     ; single-value return
                 (inst ret)
 
                 DO-STATIC-FUN
                 (inst ret)
 
                 DO-STATIC-FUN
-                (inst pop eax)
-                (inst push ebp-tn)
-                (inst lea ebp-tn (make-ea :dword
-                                          :base esp-tn
-                                          :disp n-word-bytes))
-                (inst sub esp-tn (fixnumize 2)) ; FIXME: Push 2 words on stack,
-                                                ; weirdly?
-                (inst push eax)
-                (inst mov ecx (fixnumize 2)) ; FIXME: FIXNUMIZE and
-                                        ; SINGLE-FLOAT-BITS are parallel,
-                                        ; should be named parallelly.
-                (inst jmp (make-ea :dword
-                                   :disp (+ nil-value
-                                            (static-fun-offset ',static-fn)))))))
-
-  (define-cond-assem-rtn generic-< < two-arg-< :ge)
-  (define-cond-assem-rtn generic-> > two-arg-> :le))
-
+                (move ecx esp-tn)
+                (inst sub esp-tn (fixnumize 3))
+                (inst mov (make-ea :dword
+                                   :base ecx :disp (fixnumize -1))
+                      ebp-tn)
+                (move ebp-tn ecx)
+                (inst mov ecx (fixnumize 2))
+                (inst call (make-ea :dword
+                                    :disp (+ nil-value
+                                             (static-fun-offset ',static-fn))))
+                ;; HACK: We depend on NIL having the lowest address of all
+                ;; static symbols (including T)
+                ,@(ecase test
+                    (:l `((inst mov y (1+ nil-value))
+                          (inst cmp y x)))
+                    (:g `((inst cmp x (1+ nil-value)))))
+                (inst ret))
+             #-sb-assembling
+                          `(define-vop (,name)
+                (:translate ,translate)
+                (:policy :safe)
+                (:save-p t)
+                (:args (x :scs (descriptor-reg any-reg) :target edx)
+                       (y :scs (descriptor-reg any-reg) :target edi))
+
+                (:temporary (:sc unsigned-reg :offset edx-offset
+                                 :from (:argument 0))
+                            edx)
+                (:temporary (:sc unsigned-reg :offset edi-offset
+                                 :from (:argument 1))
+                            edi)
+
+                (:temporary (:sc unsigned-reg :offset ecx-offset
+                                 :from :eval)
+                            ecx)
+                (:conditional ,test)
+                (:generator 10
+                   (move edx x)
+                   (move edi y)
+                   (inst lea ecx (make-ea :dword
+                                          :disp (make-fixup ',name :assembly-routine)))
+                   (inst call ecx)))))
+
+  (define-cond-assem-rtn generic-< < two-arg-< :l)
+  (define-cond-assem-rtn generic-> > two-arg-> :g))
+
+#+sb-assembling
 (define-assembly-routine (generic-eql
 (define-assembly-routine (generic-eql
-                          (:cost 10)
-                          (:return-style :full-call)
-                          (:policy :safe)
-                          (:translate eql)
-                          (:save-p t))
+                          (:return-style :none))
                          ((:arg x (descriptor-reg any-reg) edx-offset)
                           (:arg y (descriptor-reg any-reg) edi-offset)
 
                          ((:arg x (descriptor-reg any-reg) edx-offset)
                           (:arg y (descriptor-reg any-reg) edi-offset)
 
-                          (:res res descriptor-reg edx-offset)
-
-                          (:temp eax unsigned-reg eax-offset)
                           (:temp ecx unsigned-reg ecx-offset))
   (inst mov ecx x)
   (inst and ecx y)
                           (:temp ecx unsigned-reg ecx-offset))
   (inst mov ecx x)
   (inst and ecx y)
-  (inst test ecx fixnum-tag-mask)
-  (inst jmp :nz DO-STATIC-FUN)
+  (inst and ecx lowtag-mask)
+  (inst cmp ecx other-pointer-lowtag)
+  (inst jmp :e DO-STATIC-FUN)
 
 
-  ;; At least one fixnum
+  ;; Not both other pointers
   (inst cmp x y)
   (inst cmp x y)
-  (load-symbol res t)
-  (cond ((member :cmov *backend-subfeatures*)
-         (inst mov eax nil-value)
-         (inst cmov :ne res eax))
-        (t
-         (inst jmp :e RETURN)
-         (inst mov res nil-value)))
-  RETURN
-  (inst clc)
+  RET
   (inst ret)
 
   (inst ret)
 
-  ;; FIXME: We could handle all non-numbers here easily enough: go to
-  ;; TWO-ARG-EQL only if lowtags and widetags match, lowtag is
-  ;; other-pointer-lowtag and widetag is < code-header-widetag.
   DO-STATIC-FUN
   DO-STATIC-FUN
-  (inst pop eax)
-  (inst push ebp-tn)
-  (inst lea ebp-tn (make-ea :dword :base esp-tn :disp n-word-bytes))
-  (inst sub esp-tn (fixnumize 2))
-  (inst push eax)
+  ;; Might as well fast path that...
+  (inst cmp x y)
+  (inst jmp :e RET)
+
+  (move ecx esp-tn)
+  (inst sub esp-tn (fixnumize 3))
+  (inst mov (make-ea :dword
+                     :base ecx
+                     :disp (fixnumize -1))
+        ebp-tn)
+  (move ebp-tn ecx)
   (inst mov ecx (fixnumize 2))
   (inst mov ecx (fixnumize 2))
-  (inst jmp (make-ea :dword
-                     :disp (+ nil-value (static-fun-offset 'eql)))))
+  (inst call (make-ea :dword
+                      :disp (+ nil-value (static-fun-offset 'eql))))
+  (load-symbol y t)
+  (inst cmp x y)
+  (inst ret))
 
 
+#-sb-assembling
+(define-vop (generic-eql)
+  (:translate eql)
+  (:policy :safe)
+  (:save-p t)
+  (:args (x :scs (descriptor-reg any-reg) :target edx)
+         (y :scs (descriptor-reg any-reg) :target edi))
+
+  (:temporary (:sc unsigned-reg :offset edx-offset
+               :from (:argument 0))
+              edx)
+  (:temporary (:sc unsigned-reg :offset edi-offset
+               :from (:argument 1))
+              edi)
+
+  (:temporary (:sc unsigned-reg :offset ecx-offset
+               :from :eval)
+              ecx)
+  (:conditional :e)
+  (:generator 10
+    (move edx x)
+    (move edi y)
+    (inst lea ecx (make-ea :dword
+                           :disp (make-fixup 'generic-eql :assembly-routine)))
+    (inst call ecx)))
+
+#+sb-assembling
 (define-assembly-routine (generic-=
 (define-assembly-routine (generic-=
-                          (:cost 10)
-                          (:return-style :full-call)
-                          (:policy :safe)
-                          (:translate =)
-                          (:save-p t))
+                          (:return-style :none))
                          ((:arg x (descriptor-reg any-reg) edx-offset)
                           (:arg y (descriptor-reg any-reg) edi-offset)
 
                          ((:arg x (descriptor-reg any-reg) edx-offset)
                           (:arg y (descriptor-reg any-reg) edi-offset)
 
-                          (:res res descriptor-reg edx-offset)
-
-                          (:temp eax unsigned-reg eax-offset)
                           (:temp ecx unsigned-reg ecx-offset))
   (inst mov ecx x)
   (inst or ecx y)
                           (:temp ecx unsigned-reg ecx-offset))
   (inst mov ecx x)
   (inst or ecx y)
-  (inst test ecx fixnum-tag-mask)        ; both fixnums?
+  (inst test ecx fixnum-tag-mask)
   (inst jmp :nz DO-STATIC-FUN)
 
   (inst jmp :nz DO-STATIC-FUN)
 
+  ;; Both fixnums
   (inst cmp x y)
   (inst cmp x y)
-  (load-symbol res t)
-  (cond ((member :cmov *backend-subfeatures*)
-         (inst mov eax nil-value)
-         (inst cmov :ne res eax))
-        (t
-         (inst jmp :e RETURN)
-         (inst mov res nil-value)))
-  RETURN
-  (inst clc)
   (inst ret)
 
   DO-STATIC-FUN
   (inst ret)
 
   DO-STATIC-FUN
-  (inst pop eax)
-  (inst push ebp-tn)
-  (inst lea ebp-tn (make-ea :dword :base esp-tn :disp n-word-bytes))
-  (inst sub esp-tn (fixnumize 2))
-  (inst push eax)
+  (move ecx esp-tn)
+  (inst sub esp-tn (fixnumize 3))
+  (inst mov (make-ea :dword
+                     :base ecx
+                     :disp (fixnumize -1))
+        ebp-tn)
+  (move ebp-tn ecx)
   (inst mov ecx (fixnumize 2))
   (inst mov ecx (fixnumize 2))
-  (inst jmp (make-ea :dword
-                     :disp (+ nil-value (static-fun-offset 'two-arg-=)))))
+  (inst call (make-ea :dword
+                      :disp (+ nil-value (static-fun-offset 'two-arg-=))))
+  (load-symbol y t)
+  (inst cmp x y)
+  (inst ret))
+
+#-sb-assembling
+(define-vop (generic-=)
+  (:translate =)
+  (:policy :safe)
+  (:save-p t)
+  (:args (x :scs (descriptor-reg any-reg) :target edx)
+         (y :scs (descriptor-reg any-reg) :target edi))
+
+  (:temporary (:sc unsigned-reg :offset edx-offset
+               :from (:argument 0))
+              edx)
+  (:temporary (:sc unsigned-reg :offset edi-offset
+               :from (:argument 1))
+              edi)
+
+  (:temporary (:sc unsigned-reg :offset ecx-offset
+               :from :eval)
+              ecx)
+  (:conditional :e)
+  (:generator 10
+    (move edx x)
+    (move edi y)
+    (inst lea ecx (make-ea :dword
+                           :disp (make-fixup 'generic-= :assembly-routine)))
+    (inst call ecx)))
 
 \f
 ;;; Support for the Mersenne Twister, MT19937, random number generator
 
 \f
 ;;; Support for the Mersenne Twister, MT19937, random number generator
index d0436d5..9e14550 100644 (file)
 ;;;; binary conditional VOPs
 
 (define-vop (fast-conditional)
 ;;;; binary conditional VOPs
 
 (define-vop (fast-conditional)
-  (:conditional)
-  (:info target not-p)
+  (:conditional :e)
+  (:info)
   (:effects)
   (:affected)
   (:policy :fast-safe))
   (:effects)
   (:affected)
   (:policy :fast-safe))
 (define-vop (fast-conditional-c/fixnum fast-conditional/fixnum)
   (:args (x :scs (any-reg control-stack)))
   (:arg-types tagged-num (:constant (signed-byte 29)))
 (define-vop (fast-conditional-c/fixnum fast-conditional/fixnum)
   (:args (x :scs (any-reg control-stack)))
   (:arg-types tagged-num (:constant (signed-byte 29)))
-  (:info target not-p y))
+  (:info y))
 
 (define-vop (fast-conditional/signed fast-conditional)
   (:args (x :scs (signed-reg)
 
 (define-vop (fast-conditional/signed fast-conditional)
   (:args (x :scs (signed-reg)
 (define-vop (fast-conditional-c/signed fast-conditional/signed)
   (:args (x :scs (signed-reg signed-stack)))
   (:arg-types signed-num (:constant (signed-byte 31)))
 (define-vop (fast-conditional-c/signed fast-conditional/signed)
   (:args (x :scs (signed-reg signed-stack)))
   (:arg-types signed-num (:constant (signed-byte 31)))
-  (:info target not-p y))
+  (:info y))
 
 (define-vop (fast-conditional/unsigned fast-conditional)
   (:args (x :scs (unsigned-reg)
 
 (define-vop (fast-conditional/unsigned fast-conditional)
   (:args (x :scs (unsigned-reg)
 (define-vop (fast-conditional-c/unsigned fast-conditional/unsigned)
   (:args (x :scs (unsigned-reg unsigned-stack)))
   (:arg-types unsigned-num (:constant (unsigned-byte 31)))
 (define-vop (fast-conditional-c/unsigned fast-conditional/unsigned)
   (:args (x :scs (unsigned-reg unsigned-stack)))
   (:arg-types unsigned-num (:constant (unsigned-byte 31)))
-  (:info target not-p y))
+  (:info y))
 
 (macrolet ((define-conditional-vop (tran cond unsigned not-cond not-unsigned)
              `(progn
 
 (macrolet ((define-conditional-vop (tran cond unsigned not-cond not-unsigned)
              `(progn
                                      (format nil "~:@(FAST-CONDITIONAL~A~)"
                                              suffix)))
                         (:translate ,tran)
                                      (format nil "~:@(FAST-CONDITIONAL~A~)"
                                              suffix)))
                         (:translate ,tran)
+                        (:conditional ,(if signed cond unsigned))
                         (:generator ,cost
                                     (inst cmp x
                                           ,(if (eq suffix '-c/fixnum)
                                                '(fixnumize y)
                         (:generator ,cost
                                     (inst cmp x
                                           ,(if (eq suffix '-c/fixnum)
                                                '(fixnumize y)
-                                               'y))
-                                    (inst jmp (if not-p
-                                                  ,(if signed
-                                                       not-cond
-                                                       not-unsigned)
-                                                  ,(if signed
-                                                       cond
-                                                       unsigned))
-                                          target))))
+                                               'y)))))
                    '(/fixnum -c/fixnum /signed -c/signed /unsigned -c/unsigned)
 ;                  '(/fixnum  /signed  /unsigned)
                    '(4 3 6 5 6 5)
                    '(/fixnum -c/fixnum /signed -c/signed /unsigned -c/unsigned)
 ;                  '(/fixnum  /signed  /unsigned)
                    '(4 3 6 5 6 5)
 (define-vop (fast-if-eql/signed fast-conditional/signed)
   (:translate eql)
   (:generator 6
 (define-vop (fast-if-eql/signed fast-conditional/signed)
   (:translate eql)
   (:generator 6
-    (inst cmp x y)
-    (inst jmp (if not-p :ne :e) target)))
+    (inst cmp x y)))
 
 (define-vop (fast-if-eql-c/signed fast-conditional-c/signed)
   (:translate eql)
 
 (define-vop (fast-if-eql-c/signed fast-conditional-c/signed)
   (:translate eql)
     (cond ((and (sc-is x signed-reg) (zerop y))
            (inst test x x))  ; smaller instruction
           (t
     (cond ((and (sc-is x signed-reg) (zerop y))
            (inst test x x))  ; smaller instruction
           (t
-           (inst cmp x y)))
-    (inst jmp (if not-p :ne :e) target)))
+           (inst cmp x y)))))
 
 (define-vop (fast-if-eql/unsigned fast-conditional/unsigned)
   (:translate eql)
   (:generator 6
 
 (define-vop (fast-if-eql/unsigned fast-conditional/unsigned)
   (:translate eql)
   (:generator 6
-    (inst cmp x y)
-    (inst jmp (if not-p :ne :e) target)))
+    (inst cmp x y)))
 
 (define-vop (fast-if-eql-c/unsigned fast-conditional-c/unsigned)
   (:translate eql)
 
 (define-vop (fast-if-eql-c/unsigned fast-conditional-c/unsigned)
   (:translate eql)
     (cond ((and (sc-is x unsigned-reg) (zerop y))
            (inst test x x))  ; smaller instruction
           (t
     (cond ((and (sc-is x unsigned-reg) (zerop y))
            (inst test x x))  ; smaller instruction
           (t
-           (inst cmp x y)))
-    (inst jmp (if not-p :ne :e) target)))
+           (inst cmp x y)))))
 
 ;;; EQL/FIXNUM is funny because the first arg can be of any type, not just a
 ;;; known fixnum.
 
 ;;; EQL/FIXNUM is funny because the first arg can be of any type, not just a
 ;;; known fixnum.
   (:note "inline fixnum comparison")
   (:translate eql)
   (:generator 4
   (:note "inline fixnum comparison")
   (:translate eql)
   (:generator 4
-    (inst cmp x y)
-    (inst jmp (if not-p :ne :e) target)))
+    (inst cmp x y)))
+
 (define-vop (generic-eql/fixnum fast-eql/fixnum)
   (:args (x :scs (any-reg descriptor-reg)
             :load-if (not (and (sc-is x control-stack)
 (define-vop (generic-eql/fixnum fast-eql/fixnum)
   (:args (x :scs (any-reg descriptor-reg)
             :load-if (not (and (sc-is x control-stack)
   (:arg-types * tagged-num)
   (:variant-cost 7))
 
   (:arg-types * tagged-num)
   (:variant-cost 7))
 
-
 (define-vop (fast-eql-c/fixnum fast-conditional/fixnum)
   (:args (x :scs (any-reg control-stack)))
   (:arg-types tagged-num (:constant (signed-byte 29)))
 (define-vop (fast-eql-c/fixnum fast-conditional/fixnum)
   (:args (x :scs (any-reg control-stack)))
   (:arg-types tagged-num (:constant (signed-byte 29)))
-  (:info target not-p y)
+  (:info y)
   (:translate eql)
   (:generator 2
     (cond ((and (sc-is x any-reg) (zerop y))
            (inst test x x))  ; smaller instruction
           (t
   (:translate eql)
   (:generator 2
     (cond ((and (sc-is x any-reg) (zerop y))
            (inst test x x))  ; smaller instruction
           (t
-           (inst cmp x (fixnumize y))))
-    (inst jmp (if not-p :ne :e) target)))
+           (inst cmp x (fixnumize y))))))
 
 (define-vop (generic-eql-c/fixnum fast-eql-c/fixnum)
   (:args (x :scs (any-reg descriptor-reg control-stack)))
 
 (define-vop (generic-eql-c/fixnum fast-eql-c/fixnum)
   (:args (x :scs (any-reg descriptor-reg control-stack)))
   (:policy :fast-safe)
   (:args (digit :scs (unsigned-reg)))
   (:arg-types unsigned-num)
   (:policy :fast-safe)
   (:args (digit :scs (unsigned-reg)))
   (:arg-types unsigned-num)
-  (:conditional)
-  (:info target not-p)
+  (:conditional :ns)
   (:generator 3
   (:generator 3
-    (inst or digit digit)
-    (inst jmp (if not-p :s :ns) target)))
+    (inst or digit digit)))
 
 
 ;;; For add and sub with carry the sc of carry argument is any-reg so
 
 
 ;;; For add and sub with carry the sc of carry argument is any-reg so
index d90f81b..e82cdd4 100644 (file)
   (:translate boundp)
   (:policy :fast-safe)
   (:args (object :scs (descriptor-reg)))
   (:translate boundp)
   (:policy :fast-safe)
   (:args (object :scs (descriptor-reg)))
-  (:conditional)
-  (:info target not-p)
+  (:conditional :ne)
   (:temporary (:sc descriptor-reg #+nil(:from (:argument 0))) value)
   (:generator 9
     (let ((check-unbound-label (gen-label)))
   (:temporary (:sc descriptor-reg #+nil(:from (:argument 0))) value)
   (:generator 9
     (let ((check-unbound-label (gen-label)))
       (inst jmp :ne check-unbound-label)
       (loadw value object symbol-value-slot other-pointer-lowtag)
       (emit-label check-unbound-label)
       (inst jmp :ne check-unbound-label)
       (loadw value object symbol-value-slot other-pointer-lowtag)
       (emit-label check-unbound-label)
-      (inst cmp value unbound-marker-widetag)
-      (inst jmp (if not-p :e :ne) target))))
+      (inst cmp value unbound-marker-widetag))))
 
 #!-sb-thread
 (define-vop (boundp)
   (:translate boundp)
   (:policy :fast-safe)
   (:args (object :scs (descriptor-reg)))
 
 #!-sb-thread
 (define-vop (boundp)
   (:translate boundp)
   (:policy :fast-safe)
   (:args (object :scs (descriptor-reg)))
-  (:conditional)
-  (:info target not-p)
+  (:conditional :ne)
   (:generator 9
     (inst cmp (make-ea-for-object-slot object symbol-value-slot
                                        other-pointer-lowtag)
   (:generator 9
     (inst cmp (make-ea-for-object-slot object symbol-value-slot
                                        other-pointer-lowtag)
-          unbound-marker-widetag)
-    (inst jmp (if not-p :e :ne) target)))
+          unbound-marker-widetag)))
 
 
 (define-vop (symbol-hash)
 
 
 (define-vop (symbol-hash)
index f7ef502..8e92290 100644 (file)
             :load-if (not (and (sc-is x character-reg)
                                (sc-is y character-stack)))))
   (:arg-types character character)
             :load-if (not (and (sc-is x character-reg)
                                (sc-is y character-stack)))))
   (:arg-types character character)
-  (:conditional)
-  (:info target not-p)
+  (:info)
   (:policy :fast-safe)
   (:note "inline comparison")
   (:policy :fast-safe)
   (:note "inline comparison")
-  (:variant-vars condition not-condition)
   (:generator 3
   (:generator 3
-    (inst cmp x y)
-    (inst jmp (if not-p not-condition condition) target)))
+    (inst cmp x y)))
 
 (define-vop (fast-char=/character character-compare)
   (:translate char=)
 
 (define-vop (fast-char=/character character-compare)
   (:translate char=)
-  (:variant :e :ne))
+  (:conditional :e))
 
 (define-vop (fast-char</character character-compare)
   (:translate char<)
 
 (define-vop (fast-char</character character-compare)
   (:translate char<)
-  (:variant :b :nb))
+  (:conditional :b))
 
 (define-vop (fast-char>/character character-compare)
   (:translate char>)
 
 (define-vop (fast-char>/character character-compare)
   (:translate char>)
-  (:variant :a :na))
+  (:conditional :a))
 
 (define-vop (character-compare/c)
   (:args (x :scs (character-reg character-stack)))
   (:arg-types character (:constant character))
 
 (define-vop (character-compare/c)
   (:args (x :scs (character-reg character-stack)))
   (:arg-types character (:constant character))
-  (:conditional)
-  (:info target not-p y)
+  (:info y)
   (:policy :fast-safe)
   (:note "inline constant comparison")
   (:policy :fast-safe)
   (:note "inline constant comparison")
-  (:variant-vars condition not-condition)
   (:generator 2
   (:generator 2
-    (inst cmp x (sb!xc:char-code y))
-    (inst jmp (if not-p not-condition condition) target)))
+    (inst cmp x (sb!xc:char-code y))))
 
 (define-vop (fast-char=/character/c character-compare/c)
   (:translate char=)
 
 (define-vop (fast-char=/character/c character-compare/c)
   (:translate char=)
-  (:variant :e :ne))
+  (:conditional :e))
 
 (define-vop (fast-char</character/c character-compare/c)
   (:translate char<)
 
 (define-vop (fast-char</character/c character-compare/c)
   (:translate char<)
-  (:variant :b :nb))
+  (:conditional :b))
 
 (define-vop (fast-char>/character/c character-compare/c)
   (:translate char>)
 
 (define-vop (fast-char>/character/c character-compare/c)
   (:translate char>)
-  (:variant :a :na))
+  (:conditional :a))
index f1b7f41..b642b5c 100644 (file)
 ;;;; comparison
 
 (define-vop (float-compare)
 ;;;; comparison
 
 (define-vop (float-compare)
-  (:conditional)
-  (:info target not-p)
   (:policy :fast-safe)
   (:vop-var vop)
   (:save-p :compute-only)
   (:policy :fast-safe)
   (:vop-var vop)
   (:save-p :compute-only)
 
 (define-vop (single-float-compare float-compare)
   (:args (x :scs (single-reg)) (y :scs (single-reg)))
 
 (define-vop (single-float-compare float-compare)
   (:args (x :scs (single-reg)) (y :scs (single-reg)))
-  (:conditional)
   (:arg-types single-float single-float))
 (define-vop (double-float-compare float-compare)
   (:args (x :scs (double-reg)) (y :scs (double-reg)))
   (:arg-types single-float single-float))
 (define-vop (double-float-compare float-compare)
   (:args (x :scs (double-reg)) (y :scs (double-reg)))
-  (:conditional)
   (:arg-types double-float double-float))
 
 (define-vop (=/single-float single-float-compare)
     (:translate =)
   (:arg-types double-float double-float))
 
 (define-vop (=/single-float single-float-compare)
     (:translate =)
-  (:info target not-p)
+  (:info)
+  (:conditional not :p :ne)
   (:vop-var vop)
   (:generator 3
     (note-this-location vop :internal-error)
     (inst comiss x y)
     ;; if PF&CF, there was a NaN involved => not equal
     ;; otherwise, ZF => equal
   (:vop-var vop)
   (:generator 3
     (note-this-location vop :internal-error)
     (inst comiss x y)
     ;; if PF&CF, there was a NaN involved => not equal
     ;; otherwise, ZF => equal
-    (cond (not-p
-           (inst jmp :p target)
-           (inst jmp :ne target))
-          (t
-           (let ((not-lab (gen-label)))
-             (inst jmp :p not-lab)
-             (inst jmp :e target)
-             (emit-label not-lab))))))
+    ))
 
 (define-vop (=/double-float double-float-compare)
     (:translate =)
 
 (define-vop (=/double-float double-float-compare)
     (:translate =)
-  (:info target not-p)
+  (:info)
+  (:conditional not :p :ne)
   (:vop-var vop)
   (:generator 3
     (note-this-location vop :internal-error)
   (:vop-var vop)
   (:generator 3
     (note-this-location vop :internal-error)
-    (inst comisd x y)
-    (cond (not-p
-           (inst jmp :p target)
-           (inst jmp :ne target))
-          (t
-           (let ((not-lab (gen-label)))
-             (inst jmp :p not-lab)
-             (inst jmp :e target)
-             (emit-label not-lab))))))
+    (inst comisd x y)))
 
 (define-vop (<double-float double-float-compare)
   (:translate <)
 
 (define-vop (<double-float double-float-compare)
   (:translate <)
-  (:info target not-p)
+  (:info)
+  (:conditional not :p :nc)
   (:generator 3
   (:generator 3
-    (inst comisd x y)
-    (cond (not-p
-           (inst jmp :p target)
-           (inst jmp :nc target))
-          (t
-           (let ((not-lab (gen-label)))
-             (inst jmp :p not-lab)
-             (inst jmp :c target)
-             (emit-label not-lab))))))
+    (inst comisd x y)))
 
 (define-vop (<single-float single-float-compare)
   (:translate <)
 
 (define-vop (<single-float single-float-compare)
   (:translate <)
-  (:info target not-p)
+  (:info)
+  (:conditional not :p :nc)
   (:generator 3
   (:generator 3
-    (inst comiss x y)
-    (cond (not-p
-           (inst jmp :p target)
-           (inst jmp :nc target))
-          (t
-           (let ((not-lab (gen-label)))
-             (inst jmp :p not-lab)
-             (inst jmp :c target)
-             (emit-label not-lab))))))
+    (inst comiss x y)))
 
 (define-vop (>double-float double-float-compare)
   (:translate >)
 
 (define-vop (>double-float double-float-compare)
   (:translate >)
-  (:info target not-p)
+  (:info)
+  (:conditional not :p :na)
   (:generator 3
   (:generator 3
-    (inst comisd x y)
-    (cond (not-p
-           (inst jmp :p target)
-           (inst jmp :na target))
-          (t
-           (let ((not-lab (gen-label)))
-             (inst jmp :p not-lab)
-             (inst jmp :a target)
-             (emit-label not-lab))))))
+    (inst comisd x y)))
 
 (define-vop (>single-float single-float-compare)
   (:translate >)
 
 (define-vop (>single-float single-float-compare)
   (:translate >)
-  (:info target not-p)
+  (:info)
+  (:conditional not :p :na)
   (:generator 3
   (:generator 3
-    (inst comiss x y)
-    (cond (not-p
-           (inst jmp :p target)
-           (inst jmp :na target))
-          (t
-           (let ((not-lab (gen-label)))
-             (inst jmp :p not-lab)
-             (inst jmp :a target)
-             (emit-label not-lab))))))
+    (inst comiss x y)))
 
 
 \f
 
 
 \f
index 23c932e..c74ed60 100644 (file)
 
 ;;; The generic conditional branch, emitted immediately after test
 ;;; VOPs that only set flags.
 
 ;;; The generic conditional branch, emitted immediately after test
 ;;; VOPs that only set flags.
+;;;
+;;; FLAGS is a list of condition descriptors. If the first descriptor
+;;; is CL:NOT, the test was true if all the remaining conditions are
+;;; false. Otherwise, the test was true if any of the conditions is.
+;;;
+;;; NOT-P flips the meaning of the test, as with regular :CONDITIONAL
+;;; VOP. If NOT-P is true, the code must branch to dest if the test was
+;;; false. Otherwise, the code must branch to dest if the test was true.
 
 (define-vop (branch-if)
   (:info dest flags not-p)
 
 (define-vop (branch-if)
   (:info dest flags not-p)
-  (:ignore dest flags not-p)
   (:generator 0
   (:generator 0
-     (error "BRANCH-IF not yet implemented")))
+     (when (eq (car flags) 'not)
+       (pop flags)
+       (setf not-p (not not-p)))
+     (flet ((negate-condition (name)
+              (let ((code (logxor 1 (conditional-opcode name))))
+                (aref *condition-name-vec* code))))
+       (cond ((null (rest flags))
+              (inst jmp
+                    (if not-p
+                        (negate-condition (first flags))
+                        (first flags))
+                    dest))
+             (not-p
+              (let ((not-lab (gen-label))
+                    (last    (car (last flags))))
+                (dolist (flag (butlast flags))
+                  (inst jmp flag not-lab))
+                (inst jmp (negate-condition last) dest)
+                (emit-label not-lab)))
+             (t
+              (dolist (flag flags)
+                (inst jmp flag dest)))))))
+
+(defvar *cmov-ptype-representation-vop*
+  (mapcan (lambda (entry)
+            (destructuring-bind (ptypes &optional sc vop)
+                entry
+              (unless (listp ptypes)
+                (setf ptypes (list ptypes)))
+              (mapcar (if (and vop sc)
+                          (lambda (ptype)
+                            (list ptype sc vop))
+                          #'list)
+                      ptypes)))
+          '((t descriptor-reg move-if/t)
+
+            ((fixnum positive-fixnum)
+             any-reg move-if/fx)
+            ((unsigned-byte-64 unsigned-byte-63)
+             unsigned-reg move-if/unsigned)
+            (signed-byte-64 signed-reg move-if/signed)
+            (character character-reg move-if/char)
+
+            ((single-float complex-single-float
+              double-float complex-double-float))
+
+            (system-area-pointer sap-reg move-if/sap)))
+  "Alist of primitive type -> (storage-class-name VOP-name)
+   if values of such a type should be cmoved, and NIL otherwise.
+
+   storage-class-name is the name of the storage class to use for
+   the values, and VOP-name the name of the VOP that will be used
+   to execute the conditional move.")
 
 (!def-vm-support-routine
     convert-conditional-move-p (node dst-tn x-tn y-tn)
 
 (!def-vm-support-routine
     convert-conditional-move-p (node dst-tn x-tn y-tn)
-  (declare (ignore node dst-tn x-tn y-tn))
-  nil)
+  (declare (ignore node))
+  (let* ((ptype (sb!c::tn-primitive-type dst-tn))
+         (name  (sb!c::primitive-type-name ptype))
+         (param (cdr (or (assoc name *cmov-ptype-representation-vop*)
+                         '(t descriptor-reg move-if/t)))))
+    (when param
+      (destructuring-bind (representation vop) param
+        (let ((scn (sc-number-or-lose representation)))
+          (labels ((make-tn ()
+                     (make-representation-tn ptype scn))
+                   (immediate-tn-p (tn)
+                     (and (eq (sb!c::tn-kind tn) :constant)
+                          (eq (sb!c::immediate-constant-sc (tn-value tn))
+                              (sc-number-or-lose 'immediate))))
+                   (frob-tn (tn)
+                     (if (immediate-tn-p tn)
+                         tn
+                         (make-tn))))
+            (values vop
+                    (frob-tn x-tn) (frob-tn y-tn)
+                    (make-tn)
+                    nil)))))))
+
+(define-vop (move-if)
+  (:args (then) (else))
+  (:results (res))
+  (:info flags)
+  (:generator 0
+     (let ((not-p (eq (first flags) 'not)))
+       (when not-p (pop flags))
+       (flet ((negate-condition (name)
+                (let ((code (logxor 1 (conditional-opcode name))))
+                  (aref *condition-name-vec* code)))
+              (load-immediate (dst constant-tn
+                                   &optional (sc (sc-name (tn-sc dst))))
+                (let ((val (tn-value constant-tn)))
+                  (etypecase val
+                    (integer
+                       (if (memq sc '(any-reg descriptor-reg))
+                           (inst mov dst (fixnumize val))
+                           (inst mov dst val)))
+                    (symbol
+                       (aver (eq sc 'descriptor-reg))
+                       (load-symbol dst val))
+                    (character
+                       (if (eq sc 'descriptor-reg)
+                           (inst mov dst (logior (ash (char-code val) n-widetag-bits)
+                                                 character-widetag))
+                           (inst mov dst (char-code val))))))))
+         (cond ((null (rest flags))
+                (if (sc-is else immediate)
+                    (load-immediate res else)
+                    (move res else))
+                (when (sc-is then immediate)
+                  (load-immediate temp-reg-tn then (sc-name (tn-sc res)))
+                  (setf then temp-reg-tn))
+                (inst cmov (if not-p
+                               (negate-condition (first flags))
+                               (first flags))
+                      res
+                      then))
+               (not-p
+                (cond ((sc-is then immediate)
+                       (when (location= else res)
+                         (inst mov temp-reg-tn else)
+                         (setf else temp-reg-tn))
+                       (load-immediate res then))
+                      ((location= else res)
+                       (inst xchg else then)
+                       (rotatef else then))
+                      (t
+                       (move res then)))
+                (when (sc-is else immediate)
+                  (load-immediate temp-reg-tn else (sc-name (tn-sc res)))
+                  (setf else temp-reg-tn))
+                (dolist (flag flags)
+                  (inst cmov flag res else)))
+               (t
+                (if (sc-is else immediate)
+                    (load-immediate res else)
+                    (move res else))
+                (when (sc-is then immediate)
+                  (load-immediate temp-reg-tn then (sc-name (tn-sc res)))
+                  (setf then temp-reg-tn))
+                (dolist (flag flags)
+                  (inst cmov flag res then))))))))
+
+(macrolet ((def-move-if (name type reg &optional stack)
+               (when stack (setf stack (list stack)))
+
+               `(define-vop (,name move-if)
+                  (:args (then :scs (immediate ,reg ,@stack) :to :eval
+                               :load-if (not (or (sc-is then immediate)
+                                                 (and (sc-is then ,@stack)
+                                                      (not (location= else res))))))
+                         (else :scs (immediate ,reg ,@stack) :target res
+                               :load-if (not (sc-is else immediate ,@stack))))
+                  (:arg-types ,type ,type)
+                  (:results (res :scs (,reg)
+                                 :from (:argument 1)))
+                  (:result-types ,type))))
+  (def-move-if move-if/t
+      t descriptor-reg control-stack)
+  (def-move-if move-if/fx
+      tagged-num any-reg control-stack)
+  (def-move-if move-if/unsigned
+      unsigned-num unsigned-reg unsigned-stack)
+  (def-move-if move-if/signed
+      signed-num signed-reg signed-stack)
+  (def-move-if move-if/char
+      character character-reg character-stack)
+  (def-move-if move-if/sap
+      system-area-pointer sap-reg sap-stack))
 
 \f
 ;;;; conditional VOPs
 
 \f
 ;;;; conditional VOPs
             :load-if (not (and (sc-is x any-reg descriptor-reg immediate)
                                (sc-is y control-stack constant)))))
   (:temporary (:sc descriptor-reg) temp)
             :load-if (not (and (sc-is x any-reg descriptor-reg immediate)
                                (sc-is y control-stack constant)))))
   (:temporary (:sc descriptor-reg) temp)
-  (:conditional)
-  (:info target not-p)
+  (:conditional :e)
   (:policy :fast-safe)
   (:translate eq)
   (:generator 3
   (:policy :fast-safe)
   (:translate eq)
   (:generator 3
            (inst cmp y (logior (ash (char-code val) n-widetag-bits)
                                character-widetag))))))
       (t
            (inst cmp y (logior (ash (char-code val) n-widetag-bits)
                                character-widetag))))))
       (t
-       (inst cmp x y)))
-
-    (inst jmp (if not-p :ne :e) target)))
+       (inst cmp x y)))))
index 450a6a4..491444e 100644 (file)
   (:arg-types unsigned-num)
   (:translate fixnump)
   (:temporary (:sc unsigned-reg) tmp)
   (:arg-types unsigned-num)
   (:translate fixnump)
   (:temporary (:sc unsigned-reg) tmp)
+  (:info)
+  (:conditional :z)
   (:generator 5
     (inst mov tmp value)
   (:generator 5
     (inst mov tmp value)
-    (inst shr tmp n-positive-fixnum-bits)
-    (inst jmp (if not-p :nz :z) target)))
+    (inst shr tmp n-positive-fixnum-bits)))
 
 ;;; A (SIGNED-BYTE 64) can be represented with either fixnum or a bignum with
 ;;; exactly one digit.
 
 ;;; A (SIGNED-BYTE 64) can be represented with either fixnum or a bignum with
 ;;; exactly one digit.
index 4731c26..d557048 100644 (file)
 ;;;; binary conditional VOPs
 
 (define-vop (fast-conditional)
 ;;;; binary conditional VOPs
 
 (define-vop (fast-conditional)
-  (:conditional)
-  (:info target not-p)
+  (:conditional :e)
   (:effects)
   (:affected)
   (:policy :fast-safe))
   (:effects)
   (:affected)
   (:policy :fast-safe))
 (define-vop (fast-conditional-c/fixnum fast-conditional/fixnum)
   (:args (x :scs (any-reg control-stack)))
   (:arg-types tagged-num (:constant (signed-byte 30)))
 (define-vop (fast-conditional-c/fixnum fast-conditional/fixnum)
   (:args (x :scs (any-reg control-stack)))
   (:arg-types tagged-num (:constant (signed-byte 30)))
-  (:info target not-p y))
+  (:info y))
 
 (define-vop (fast-conditional/signed fast-conditional)
   (:args (x :scs (signed-reg)
 
 (define-vop (fast-conditional/signed fast-conditional)
   (:args (x :scs (signed-reg)
 (define-vop (fast-conditional-c/signed fast-conditional/signed)
   (:args (x :scs (signed-reg signed-stack)))
   (:arg-types signed-num (:constant (signed-byte 32)))
 (define-vop (fast-conditional-c/signed fast-conditional/signed)
   (:args (x :scs (signed-reg signed-stack)))
   (:arg-types signed-num (:constant (signed-byte 32)))
-  (:info target not-p y))
+  (:info y))
 
 (define-vop (fast-conditional/unsigned fast-conditional)
   (:args (x :scs (unsigned-reg)
 
 (define-vop (fast-conditional/unsigned fast-conditional)
   (:args (x :scs (unsigned-reg)
 (define-vop (fast-conditional-c/unsigned fast-conditional/unsigned)
   (:args (x :scs (unsigned-reg unsigned-stack)))
   (:arg-types unsigned-num (:constant (unsigned-byte 32)))
 (define-vop (fast-conditional-c/unsigned fast-conditional/unsigned)
   (:args (x :scs (unsigned-reg unsigned-stack)))
   (:arg-types unsigned-num (:constant (unsigned-byte 32)))
-  (:info target not-p y))
+  (:info y))
 
 (macrolet ((define-logtest-vops ()
              `(progn
 
 (macrolet ((define-logtest-vops ()
              `(progn
                        `(define-vop (,(symbolicate "FAST-LOGTEST" suffix)
                                      ,(symbolicate "FAST-CONDITIONAL" suffix))
                          (:translate logtest)
                        `(define-vop (,(symbolicate "FAST-LOGTEST" suffix)
                                      ,(symbolicate "FAST-CONDITIONAL" suffix))
                          (:translate logtest)
+                         (:conditional :ne)
                          (:generator ,cost
                           (emit-optimized-test-inst x
                                                     ,(if (eq suffix '-c/fixnum)
                                                          '(fixnumize y)
                          (:generator ,cost
                           (emit-optimized-test-inst x
                                                     ,(if (eq suffix '-c/fixnum)
                                                          '(fixnumize y)
-                                                         'y))
-                          (inst jmp (if not-p :e :ne) target)))))))
+                                                         'y))))))))
   (define-logtest-vops))
 
 (defknown %logbitp (integer unsigned-byte) boolean
   (define-logtest-vops))
 
 (defknown %logbitp (integer unsigned-byte) boolean
 ;;; too much work to do the non-constant case (maybe?)
 (define-vop (fast-logbitp-c/fixnum fast-conditional-c/fixnum)
   (:translate %logbitp)
 ;;; too much work to do the non-constant case (maybe?)
 (define-vop (fast-logbitp-c/fixnum fast-conditional-c/fixnum)
   (:translate %logbitp)
+  (:conditional :c)
   (:arg-types tagged-num (:constant (integer 0 29)))
   (:generator 4
   (:arg-types tagged-num (:constant (integer 0 29)))
   (:generator 4
-    (inst bt x (+ y n-fixnum-tag-bits))
-    (inst jmp (if not-p :nc :c) target)))
+    (inst bt x (+ y n-fixnum-tag-bits))))
 
 (define-vop (fast-logbitp/signed fast-conditional/signed)
   (:args (x :scs (signed-reg signed-stack))
          (y :scs (signed-reg)))
   (:translate %logbitp)
 
 (define-vop (fast-logbitp/signed fast-conditional/signed)
   (:args (x :scs (signed-reg signed-stack))
          (y :scs (signed-reg)))
   (:translate %logbitp)
+  (:conditional :c)
   (:generator 6
   (:generator 6
-    (inst bt x y)
-    (inst jmp (if not-p :nc :c) target)))
+    (inst bt x y)))
 
 (define-vop (fast-logbitp-c/signed fast-conditional-c/signed)
   (:translate %logbitp)
 
 (define-vop (fast-logbitp-c/signed fast-conditional-c/signed)
   (:translate %logbitp)
+  (:conditional :c)
   (:arg-types signed-num (:constant (integer 0 31)))
   (:generator 5
   (:arg-types signed-num (:constant (integer 0 31)))
   (:generator 5
-    (inst bt x y)
-    (inst jmp (if not-p :nc :c) target)))
+    (inst bt x y)))
 
 (define-vop (fast-logbitp/unsigned fast-conditional/unsigned)
   (:args (x :scs (unsigned-reg unsigned-stack))
          (y :scs (unsigned-reg)))
   (:translate %logbitp)
 
 (define-vop (fast-logbitp/unsigned fast-conditional/unsigned)
   (:args (x :scs (unsigned-reg unsigned-stack))
          (y :scs (unsigned-reg)))
   (:translate %logbitp)
+  (:conditional :c)
   (:generator 6
   (:generator 6
-    (inst bt x y)
-    (inst jmp (if not-p :nc :c) target)))
+    (inst bt x y)))
 
 (define-vop (fast-logbitp-c/unsigned fast-conditional-c/unsigned)
   (:translate %logbitp)
 
 (define-vop (fast-logbitp-c/unsigned fast-conditional-c/unsigned)
   (:translate %logbitp)
+  (:conditional :c)
   (:arg-types unsigned-num (:constant (integer 0 31)))
   (:generator 5
   (:arg-types unsigned-num (:constant (integer 0 31)))
   (:generator 5
-    (inst bt x y)
-    (inst jmp (if not-p :nc :c) target)))
+    (inst bt x y)))
 
 
-(macrolet ((define-conditional-vop (tran cond unsigned not-cond not-unsigned)
+(macrolet ((define-conditional-vop (tran cond unsigned)
              `(progn
                 ,@(mapcar
                    (lambda (suffix cost signed)
              `(progn
                 ,@(mapcar
                    (lambda (suffix cost signed)
                                      (format nil "~:@(FAST-CONDITIONAL~A~)"
                                              suffix)))
                         (:translate ,tran)
                                      (format nil "~:@(FAST-CONDITIONAL~A~)"
                                              suffix)))
                         (:translate ,tran)
+                        (:conditional ,(if signed
+                                           cond
+                                           unsigned))
                         (:generator ,cost
                                     (inst cmp x
                                           ,(if (eq suffix '-c/fixnum)
                                                '(fixnumize y)
                         (:generator ,cost
                                     (inst cmp x
                                           ,(if (eq suffix '-c/fixnum)
                                                '(fixnumize y)
-                                               'y))
-                                    (inst jmp (if not-p
-                                                  ,(if signed
-                                                       not-cond
-                                                       not-unsigned)
-                                                  ,(if signed
-                                                       cond
-                                                       unsigned))
-                                          target))))
+                                               'y)))))
                    '(/fixnum -c/fixnum /signed -c/signed /unsigned -c/unsigned)
                    '(4 3 6 5 6 5)
                    '(t t t t nil nil)))))
 
                    '(/fixnum -c/fixnum /signed -c/signed /unsigned -c/unsigned)
                    '(4 3 6 5 6 5)
                    '(t t t t nil nil)))))
 
-  (define-conditional-vop < :l :b :ge :ae)
-  (define-conditional-vop > :g :a :le :be))
+  (define-conditional-vop < :l :b)
+  (define-conditional-vop > :g :a))
 
 (define-vop (fast-if-eql/signed fast-conditional/signed)
   (:translate eql)
   (:generator 6
 
 (define-vop (fast-if-eql/signed fast-conditional/signed)
   (:translate eql)
   (:generator 6
-    (inst cmp x y)
-    (inst jmp (if not-p :ne :e) target)))
+    (inst cmp x y)))
 
 (define-vop (fast-if-eql-c/signed fast-conditional-c/signed)
   (:translate eql)
 
 (define-vop (fast-if-eql-c/signed fast-conditional-c/signed)
   (:translate eql)
     (cond ((and (sc-is x signed-reg) (zerop y))
            (inst test x x))  ; smaller instruction
           (t
     (cond ((and (sc-is x signed-reg) (zerop y))
            (inst test x x))  ; smaller instruction
           (t
-           (inst cmp x y)))
-    (inst jmp (if not-p :ne :e) target)))
+           (inst cmp x y)))))
 
 (define-vop (fast-if-eql/unsigned fast-conditional/unsigned)
   (:translate eql)
   (:generator 6
 
 (define-vop (fast-if-eql/unsigned fast-conditional/unsigned)
   (:translate eql)
   (:generator 6
-    (inst cmp x y)
-    (inst jmp (if not-p :ne :e) target)))
+    (inst cmp x y)))
 
 (define-vop (fast-if-eql-c/unsigned fast-conditional-c/unsigned)
   (:translate eql)
 
 (define-vop (fast-if-eql-c/unsigned fast-conditional-c/unsigned)
   (:translate eql)
     (cond ((and (sc-is x unsigned-reg) (zerop y))
            (inst test x x))  ; smaller instruction
           (t
     (cond ((and (sc-is x unsigned-reg) (zerop y))
            (inst test x x))  ; smaller instruction
           (t
-           (inst cmp x y)))
-    (inst jmp (if not-p :ne :e) target)))
+           (inst cmp x y)))))
 
 ;;; EQL/FIXNUM is funny because the first arg can be of any type, not just a
 ;;; known fixnum.
 
 ;;; EQL/FIXNUM is funny because the first arg can be of any type, not just a
 ;;; known fixnum.
   (:note "inline fixnum comparison")
   (:translate eql)
   (:generator 4
   (:note "inline fixnum comparison")
   (:translate eql)
   (:generator 4
-    (inst cmp x y)
-    (inst jmp (if not-p :ne :e) target)))
+    (inst cmp x y)))
 (define-vop (generic-eql/fixnum fast-eql/fixnum)
   (:args (x :scs (any-reg descriptor-reg)
             :load-if (not (and (sc-is x control-stack)
 (define-vop (generic-eql/fixnum fast-eql/fixnum)
   (:args (x :scs (any-reg descriptor-reg)
             :load-if (not (and (sc-is x control-stack)
 (define-vop (fast-eql-c/fixnum fast-conditional/fixnum)
   (:args (x :scs (any-reg control-stack)))
   (:arg-types tagged-num (:constant (signed-byte 30)))
 (define-vop (fast-eql-c/fixnum fast-conditional/fixnum)
   (:args (x :scs (any-reg control-stack)))
   (:arg-types tagged-num (:constant (signed-byte 30)))
-  (:info target not-p y)
+  (:info y)
   (:translate eql)
   (:generator 2
     (cond ((and (sc-is x any-reg) (zerop y))
            (inst test x x))  ; smaller instruction
           (t
   (:translate eql)
   (:generator 2
     (cond ((and (sc-is x any-reg) (zerop y))
            (inst test x x))  ; smaller instruction
           (t
-           (inst cmp x (fixnumize y))))
-    (inst jmp (if not-p :ne :e) target)))
+           (inst cmp x (fixnumize y))))))
 (define-vop (generic-eql-c/fixnum fast-eql-c/fixnum)
   (:args (x :scs (any-reg descriptor-reg control-stack)))
   (:arg-types * (:constant (signed-byte 30)))
 (define-vop (generic-eql-c/fixnum fast-eql-c/fixnum)
   (:args (x :scs (any-reg descriptor-reg control-stack)))
   (:arg-types * (:constant (signed-byte 30)))
   (:policy :fast-safe)
   (:args (digit :scs (unsigned-reg)))
   (:arg-types unsigned-num)
   (:policy :fast-safe)
   (:args (digit :scs (unsigned-reg)))
   (:arg-types unsigned-num)
-  (:conditional)
-  (:info target not-p)
+  (:conditional :ns)
   (:generator 3
   (:generator 3
-    (inst or digit digit)
-    (inst jmp (if not-p :s :ns) target)))
+    (inst or digit digit)))
 
 
 ;;; For add and sub with carry the sc of carry argument is any-reg so
 
 
 ;;; For add and sub with carry the sc of carry argument is any-reg so
index a049fcd..1fa2dcb 100644 (file)
   (:translate boundp)
   (:policy :fast-safe)
   (:args (object :scs (descriptor-reg)))
   (:translate boundp)
   (:policy :fast-safe)
   (:args (object :scs (descriptor-reg)))
-  (:conditional)
-  (:info target not-p)
+  (:conditional :ne)
   (:temporary (:sc descriptor-reg #+nil(:from (:argument 0))) value)
   (:generator 9
     (let ((check-unbound-label (gen-label)))
   (:temporary (:sc descriptor-reg #+nil(:from (:argument 0))) value)
   (:generator 9
     (let ((check-unbound-label (gen-label)))
       (inst jmp :ne check-unbound-label)
       (loadw value object symbol-value-slot other-pointer-lowtag)
       (emit-label check-unbound-label)
       (inst jmp :ne check-unbound-label)
       (loadw value object symbol-value-slot other-pointer-lowtag)
       (emit-label check-unbound-label)
-      (inst cmp value unbound-marker-widetag)
-      (inst jmp (if not-p :e :ne) target))))
+      (inst cmp value unbound-marker-widetag))))
 
 #!-sb-thread
 (define-vop (boundp)
   (:translate boundp)
   (:policy :fast-safe)
   (:args (object :scs (descriptor-reg)))
 
 #!-sb-thread
 (define-vop (boundp)
   (:translate boundp)
   (:policy :fast-safe)
   (:args (object :scs (descriptor-reg)))
-  (:conditional)
-  (:info target not-p)
+  (:conditional :ne)
   (:generator 9
     (inst cmp (make-ea-for-object-slot object symbol-value-slot
                                        other-pointer-lowtag)
   (:generator 9
     (inst cmp (make-ea-for-object-slot object symbol-value-slot
                                        other-pointer-lowtag)
-          unbound-marker-widetag)
-    (inst jmp (if not-p :e :ne) target)))
+          unbound-marker-widetag)))
 
 
 (define-vop (symbol-hash)
 
 
 (define-vop (symbol-hash)
index 39cb78a..0230678 100644 (file)
             :load-if (not (and (sc-is x character-reg)
                                (sc-is y character-stack)))))
   (:arg-types character character)
             :load-if (not (and (sc-is x character-reg)
                                (sc-is y character-stack)))))
   (:arg-types character character)
-  (:conditional)
-  (:info target not-p)
   (:policy :fast-safe)
   (:note "inline comparison")
   (:policy :fast-safe)
   (:note "inline comparison")
-  (:variant-vars condition not-condition)
   (:generator 3
   (:generator 3
-    (inst cmp x y)
-    (inst jmp (if not-p not-condition condition) target)))
+    (inst cmp x y)))
 
 (define-vop (fast-char=/character character-compare)
   (:translate char=)
 
 (define-vop (fast-char=/character character-compare)
   (:translate char=)
-  (:variant :e :ne))
+  (:conditional :e))
 
 (define-vop (fast-char</character character-compare)
   (:translate char<)
 
 (define-vop (fast-char</character character-compare)
   (:translate char<)
-  (:variant :b :nb))
+  (:conditional :b))
 
 (define-vop (fast-char>/character character-compare)
   (:translate char>)
 
 (define-vop (fast-char>/character character-compare)
   (:translate char>)
-  (:variant :a :na))
+  (:conditional :a))
 
 (define-vop (character-compare/c)
   (:args (x :scs (character-reg character-stack)))
   (:arg-types character (:constant character))
 
 (define-vop (character-compare/c)
   (:args (x :scs (character-reg character-stack)))
   (:arg-types character (:constant character))
-  (:conditional)
-  (:info target not-p y)
+  (:info y)
   (:policy :fast-safe)
   (:note "inline constant comparison")
   (:policy :fast-safe)
   (:note "inline constant comparison")
-  (:variant-vars condition not-condition)
   (:generator 2
   (:generator 2
-    (inst cmp x (sb!xc:char-code y))
-    (inst jmp (if not-p not-condition condition) target)))
+    (inst cmp x (sb!xc:char-code y))))
 
 (define-vop (fast-char=/character/c character-compare/c)
   (:translate char=)
 
 (define-vop (fast-char=/character/c character-compare/c)
   (:translate char=)
-  (:variant :e :ne))
+  (:conditional :e))
 
 (define-vop (fast-char</character/c character-compare/c)
   (:translate char<)
 
 (define-vop (fast-char</character/c character-compare/c)
   (:translate char<)
-  (:variant :b :nb))
+  (:conditional :b))
 
 (define-vop (fast-char>/character/c character-compare/c)
   (:translate char>)
 
 (define-vop (fast-char>/character/c character-compare/c)
   (:translate char>)
-  (:variant :a :na))
+  (:conditional :a))
index fd69f80..9e10b3c 100644 (file)
 (define-vop (=/float)
   (:args (x) (y))
   (:temporary (:sc word-reg :offset eax-offset :from :eval) temp)
 (define-vop (=/float)
   (:args (x) (y))
   (:temporary (:sc word-reg :offset eax-offset :from :eval) temp)
-  (:conditional)
-  (:info target not-p)
+  (:conditional :e)
   (:policy :fast-safe)
   (:vop-var vop)
   (:save-p :compute-only)
   (:policy :fast-safe)
   (:vop-var vop)
   (:save-p :compute-only)
        (inst fxch x)))
      (inst fnstsw)                      ; status word to ax
      (inst and ah-tn #x45)              ; C3 C2 C0
        (inst fxch x)))
      (inst fnstsw)                      ; status word to ax
      (inst and ah-tn #x45)              ; C3 C2 C0
-     (inst cmp ah-tn #x40)
-     (inst jmp (if not-p :ne :e) target)))
+     (inst cmp ah-tn #x40)))
 
 (define-vop (=/single-float =/float)
   (:translate =)
 
 (define-vop (=/single-float =/float)
   (:translate =)
   (:arg-types single-float single-float)
   (:temporary (:sc single-reg :offset fr0-offset :from :eval) fr0)
   (:temporary (:sc word-reg :offset eax-offset :from :eval) temp)
   (:arg-types single-float single-float)
   (:temporary (:sc single-reg :offset fr0-offset :from :eval) fr0)
   (:temporary (:sc word-reg :offset eax-offset :from :eval) temp)
-  (:conditional)
-  (:info target not-p)
+  (:conditional :e)
   (:policy :fast-safe)
   (:note "inline float comparison")
   (:ignore temp)
   (:policy :fast-safe)
   (:note "inline float comparison")
   (:ignore temp)
            (inst fcom (ea-for-sf-desc y)))))
       (inst fnstsw)                     ; status word to ax
       (inst and ah-tn #x45)             ; C3 C2 C0
            (inst fcom (ea-for-sf-desc y)))))
       (inst fnstsw)                     ; status word to ax
       (inst and ah-tn #x45)             ; C3 C2 C0
-      (inst cmp ah-tn #x01)))
-    (inst jmp (if not-p :ne :e) target)))
+      (inst cmp ah-tn #x01)))))
 
 (define-vop (<double-float)
   (:translate <)
 
 (define-vop (<double-float)
   (:translate <)
   (:arg-types double-float double-float)
   (:temporary (:sc double-reg :offset fr0-offset :from :eval) fr0)
   (:temporary (:sc word-reg :offset eax-offset :from :eval) temp)
   (:arg-types double-float double-float)
   (:temporary (:sc double-reg :offset fr0-offset :from :eval) fr0)
   (:temporary (:sc word-reg :offset eax-offset :from :eval) temp)
-  (:conditional)
-  (:info target not-p)
+  (:conditional :e)
   (:policy :fast-safe)
   (:note "inline float comparison")
   (:ignore temp)
   (:policy :fast-safe)
   (:note "inline float comparison")
   (:ignore temp)
            (inst fcomd (ea-for-df-desc y)))))
       (inst fnstsw)                     ; status word to ax
       (inst and ah-tn #x45)             ; C3 C2 C0
            (inst fcomd (ea-for-df-desc y)))))
       (inst fnstsw)                     ; status word to ax
       (inst and ah-tn #x45)             ; C3 C2 C0
-      (inst cmp ah-tn #x01)))
-    (inst jmp (if not-p :ne :e) target)))
+      (inst cmp ah-tn #x01)))))
 
 #!+long-float
 (define-vop (<long-float)
 
 #!+long-float
 (define-vop (<long-float)
          (y :scs (long-reg)))
   (:arg-types long-float long-float)
   (:temporary (:sc word-reg :offset eax-offset :from :eval) temp)
          (y :scs (long-reg)))
   (:arg-types long-float long-float)
   (:temporary (:sc word-reg :offset eax-offset :from :eval) temp)
-  (:conditional)
-  (:info target not-p)
+  (:conditional :e)
   (:policy :fast-safe)
   (:note "inline float comparison")
   (:ignore temp)
   (:policy :fast-safe)
   (:note "inline float comparison")
   (:ignore temp)
        (inst fcomd x)
        (inst fxch y)
        (inst fnstsw)                    ; status word to ax
        (inst fcomd x)
        (inst fxch y)
        (inst fnstsw)                    ; status word to ax
-       (inst and ah-tn #x45)))          ; C3 C2 C0
-    (inst jmp (if not-p :ne :e) target)))
+       (inst and ah-tn #x45)))))        ; C3 C2 C0
+
 
 (define-vop (>single-float)
   (:translate >)
 
 (define-vop (>single-float)
   (:translate >)
   (:arg-types single-float single-float)
   (:temporary (:sc single-reg :offset fr0-offset :from :eval) fr0)
   (:temporary (:sc word-reg :offset eax-offset :from :eval) temp)
   (:arg-types single-float single-float)
   (:temporary (:sc single-reg :offset fr0-offset :from :eval) fr0)
   (:temporary (:sc word-reg :offset eax-offset :from :eval) temp)
-  (:conditional)
-  (:info target not-p)
+  (:conditional :e)
   (:policy :fast-safe)
   (:note "inline float comparison")
   (:ignore temp)
   (:policy :fast-safe)
   (:note "inline float comparison")
   (:ignore temp)
              (inst fcom (ea-for-sf-stack y))
            (inst fcom (ea-for-sf-desc y)))))
       (inst fnstsw)                     ; status word to ax
              (inst fcom (ea-for-sf-stack y))
            (inst fcom (ea-for-sf-desc y)))))
       (inst fnstsw)                     ; status word to ax
-      (inst and ah-tn #x45)))
-    (inst jmp (if not-p :ne :e) target)))
+      (inst and ah-tn #x45)))))
 
 (define-vop (>double-float)
   (:translate >)
 
 (define-vop (>double-float)
   (:translate >)
   (:arg-types double-float double-float)
   (:temporary (:sc double-reg :offset fr0-offset :from :eval) fr0)
   (:temporary (:sc word-reg :offset eax-offset :from :eval) temp)
   (:arg-types double-float double-float)
   (:temporary (:sc double-reg :offset fr0-offset :from :eval) fr0)
   (:temporary (:sc word-reg :offset eax-offset :from :eval) temp)
-  (:conditional)
-  (:info target not-p)
+  (:conditional :e)
   (:policy :fast-safe)
   (:note "inline float comparison")
   (:ignore temp)
   (:policy :fast-safe)
   (:note "inline float comparison")
   (:ignore temp)
              (inst fcomd (ea-for-df-stack y))
            (inst fcomd (ea-for-df-desc y)))))
       (inst fnstsw)                     ; status word to ax
              (inst fcomd (ea-for-df-stack y))
            (inst fcomd (ea-for-df-desc y)))))
       (inst fnstsw)                     ; status word to ax
-      (inst and ah-tn #x45)))
-    (inst jmp (if not-p :ne :e) target)))
+      (inst and ah-tn #x45)))))
 
 #!+long-float
 (define-vop (>long-float)
 
 #!+long-float
 (define-vop (>long-float)
          (y :scs (long-reg)))
   (:arg-types long-float long-float)
   (:temporary (:sc word-reg :offset eax-offset :from :eval) temp)
          (y :scs (long-reg)))
   (:arg-types long-float long-float)
   (:temporary (:sc word-reg :offset eax-offset :from :eval) temp)
-  (:conditional)
-  (:info target not-p)
+  (:conditional :e)
   (:policy :fast-safe)
   (:note "inline float comparison")
   (:ignore temp)
   (:policy :fast-safe)
   (:note "inline float comparison")
   (:ignore temp)
        (inst fcomd y)
        (inst fxch x)
        (inst fnstsw)                    ; status word to ax
        (inst fcomd y)
        (inst fxch x)
        (inst fnstsw)                    ; status word to ax
-       (inst and ah-tn #x45)))
-    (inst jmp (if not-p :ne :e) target)))
+       (inst and ah-tn #x45)))))
 
 ;;; Comparisons with 0 can use the FTST instruction.
 
 (define-vop (float-test)
   (:args (x))
   (:temporary (:sc word-reg :offset eax-offset :from :eval) temp)
 
 ;;; Comparisons with 0 can use the FTST instruction.
 
 (define-vop (float-test)
   (:args (x))
   (:temporary (:sc word-reg :offset eax-offset :from :eval) temp)
-  (:conditional)
-  (:info target not-p y)
+  (:conditional :e)
+  (:info y)
   (:variant-vars code)
   (:policy :fast-safe)
   (:vop-var vop)
   (:variant-vars code)
   (:policy :fast-safe)
   (:vop-var vop)
      (inst fnstsw)                      ; status word to ax
      (inst and ah-tn #x45)              ; C3 C2 C0
      (unless (zerop code)
      (inst fnstsw)                      ; status word to ax
      (inst and ah-tn #x45)              ; C3 C2 C0
      (unless (zerop code)
-        (inst cmp ah-tn code))
-     (inst jmp (if not-p :ne :e) target)))
+        (inst cmp ah-tn code))))
 
 (define-vop (=0/single-float float-test)
   (:translate =)
 
 (define-vop (=0/single-float float-test)
   (:translate =)
index e756b3b..ce13f2b 100644 (file)
 
 ;;; The generic conditional branch, emitted immediately after test
 ;;; VOPs that only set flags.
 
 ;;; The generic conditional branch, emitted immediately after test
 ;;; VOPs that only set flags.
+;;;
+;;; FLAGS is a list of condition descriptors. If the first descriptor
+;;; is CL:NOT, the test was true if all the remaining conditions are
+;;; false. Otherwise, the test was true if any of the conditions is.
+;;;
+;;; NOT-P flips the meaning of the test, as with regular :CONDITIONAL
+;;; VOP. If NOT-P is true, the code must branch to dest if the test was
+;;; false. Otherwise, the code must branch to dest if the test was true.
 
 (define-vop (branch-if)
   (:info dest flags not-p)
 
 (define-vop (branch-if)
   (:info dest flags not-p)
-  (:ignore dest flags not-p)
   (:generator 0
   (:generator 0
-     (error "BRANCH-IF not yet implemented")))
+     (flet ((negate-condition (name)
+              (let ((code (logxor 1 (conditional-opcode name))))
+                (aref *condition-name-vec* code))))
+       (aver (null (rest flags)))
+       (inst jmp
+             (if not-p
+                 (negate-condition (first flags))
+                 (first flags))
+             dest))))
+
+(defvar *cmov-ptype-representation-vop*
+  (mapcan (lambda (entry)
+            (destructuring-bind (ptypes &optional sc vop)
+                entry
+              (unless (listp ptypes)
+                (setf ptypes (list ptypes)))
+              (mapcar (if (and vop sc)
+                          (lambda (ptype)
+                            (list ptype sc vop))
+                          #'list)
+                      ptypes)))
+          '((t descriptor-reg move-if/t)
+
+            ((fixnum positive-fixnum)
+             any-reg move-if/fx)
+            ((unsigned-byte-32 unsigned-byte-31)
+             unsigned-reg move-if/unsigned)
+            (signed-byte-32 signed-reg move-if/signed)
+            (character character-reg move-if/char)
+
+            ((single-float complex-single-float
+              double-float complex-double-float))
+
+            (system-area-pointer sap-reg move-if/sap)))
+  "Alist of primitive type -> (storage-class-name VOP-name)
+   if values of such a type should be cmoved, and NIL otherwise.
+
+   storage-class-name is the name of the storage class to use for
+   the values, and VOP-name the name of the VOP that will be used
+   to execute the conditional move.")
 
 (!def-vm-support-routine
     convert-conditional-move-p (node dst-tn x-tn y-tn)
 
 (!def-vm-support-routine
     convert-conditional-move-p (node dst-tn x-tn y-tn)
-  (declare (ignore node dst-tn x-tn y-tn))
-  nil)
+  (declare (ignore node))
+  (let* ((ptype (sb!c::tn-primitive-type dst-tn))
+         (name  (sb!c::primitive-type-name ptype))
+         (param (and (memq :cmov *backend-subfeatures*)
+                     (cdr (or (assoc name *cmov-ptype-representation-vop*)
+                              '(t descriptor-reg move-if/t))))))
+    (when param
+      (destructuring-bind (representation vop) param
+        (let ((scn (sc-number-or-lose representation)))
+          (labels ((make-tn ()
+                     (make-representation-tn ptype scn))
+                   (immediate-tn-p (tn)
+                     (and (eq (sb!c::tn-kind tn) :constant)
+                          (eq (sb!c::immediate-constant-sc (tn-value tn))
+                              (sc-number-or-lose 'immediate))))
+                   (frob-tn (tn)
+                     (if (immediate-tn-p tn)
+                         tn
+                         (make-tn))))
+            (values vop
+                    (frob-tn x-tn) (frob-tn y-tn)
+                    (make-tn)
+                    nil)))))))
+
+(define-vop (move-if)
+  (:args (then) (else))
+  (:temporary (:sc unsigned-reg :from :eval) temp)
+  (:results (res))
+  (:info flags)
+  (:generator 0
+     (flet ((load-immediate (dst constant-tn
+                                 &optional (sc (sc-name (tn-sc dst))))
+              (let ((val (tn-value constant-tn)))
+                (etypecase val
+                  (integer
+                     (if (memq sc '(any-reg descriptor-reg))
+                         (inst mov dst (fixnumize val))
+                         (inst mov dst val)))
+                  (symbol
+                     (aver (eq sc 'descriptor-reg))
+                     (load-symbol dst val))
+                  (character
+                     (cond ((memq sc '(any-reg descriptor-reg))
+                            (inst mov dst
+                                  (logior (ash (char-code val) n-widetag-bits)
+                                          character-widetag)))
+                           (t
+                            (aver (eq sc 'character-reg))
+                            (inst mov dst (char-code val)))))))))
+       (aver (null (rest flags)))
+       (if (sc-is else immediate)
+           (load-immediate res else)
+           (move res else))
+       (when (sc-is then immediate)
+         (load-immediate temp then (sc-name (tn-sc res)))
+         (setf then temp))
+       (inst cmov (first flags) res then))))
+
+(macrolet ((def-move-if (name type reg &optional stack)
+               (when stack (setf stack (list stack)))
+
+               `(define-vop (,name move-if)
+                  (:args (then :scs (immediate ,reg ,@stack) :to :eval
+                               :target temp
+                               :load-if (not (or (sc-is then immediate)
+                                                 (and (sc-is then ,@stack)
+                                                      (not (location= else res))))))
+                         (else :scs (immediate ,reg ,@stack) :target res
+                               :load-if (not (sc-is else immediate ,@stack))))
+                  (:arg-types ,type ,type)
+                  (:results (res :scs (,reg)
+                                 :from (:argument 1)))
+                  (:result-types ,type))))
+  (def-move-if move-if/t
+      t descriptor-reg control-stack)
+  (def-move-if move-if/fx
+      tagged-num any-reg control-stack)
+  (def-move-if move-if/unsigned
+      unsigned-num unsigned-reg unsigned-stack)
+  (def-move-if move-if/signed
+      signed-num signed-reg signed-stack)
+  (def-move-if move-if/char
+      character character-reg character-stack)
+  (def-move-if move-if/sap
+      system-area-pointer sap-reg sap-stack))
 
 \f
 ;;;; conditional VOPs
 
 \f
 ;;;; conditional VOPs
          (y :scs (any-reg descriptor-reg immediate)
             :load-if (not (and (sc-is x any-reg descriptor-reg immediate)
                                (sc-is y control-stack constant)))))
          (y :scs (any-reg descriptor-reg immediate)
             :load-if (not (and (sc-is x any-reg descriptor-reg immediate)
                                (sc-is y control-stack constant)))))
-  (:conditional)
-  (:info target not-p)
+  (:conditional :e)
+  (:info)
   (:policy :fast-safe)
   (:translate eq)
   (:generator 3
   (:policy :fast-safe)
   (:translate eq)
   (:generator 3
         ;; An encoded value (literal integer) has to be the second argument.
         ((sc-is x immediate) (inst cmp y x-val))
 
         ;; An encoded value (literal integer) has to be the second argument.
         ((sc-is x immediate) (inst cmp y x-val))
 
-        (t (inst cmp x y-val))))
-
-    (inst jmp (if not-p :ne :e) target)))
+        (t (inst cmp x y-val))))))
index d0e5f0e..9d53fe9 100644 (file)
 
 (define-vop (fixnump/unsigned-byte-32 simple-type-predicate)
   (:args (value :scs (unsigned-reg)))
 
 (define-vop (fixnump/unsigned-byte-32 simple-type-predicate)
   (:args (value :scs (unsigned-reg)))
+  (:info)
+  (:conditional :be)
   (:arg-types unsigned-num)
   (:translate fixnump)
   (:generator 5
   (:arg-types unsigned-num)
   (:translate fixnump)
   (:generator 5
-    (inst cmp value #.sb!xc:most-positive-fixnum)
-    (inst jmp (if not-p :a :be) target)))
+    (inst cmp value #.sb!xc:most-positive-fixnum)))
 
 ;;; A (SIGNED-BYTE 32) can be represented with either fixnum or a bignum with
 ;;; exactly one digit.
 
 ;;; A (SIGNED-BYTE 32) can be represented with either fixnum or a bignum with
 ;;; exactly one digit.
index 7dcc183..165c17b 100644 (file)
                          (typep ch 'base-char))
                        t)
               t)))
                          (typep ch 'base-char))
                        t)
               t)))
+
+;;; Attempt to test a decent cross section of conditions
+;;; and values types to move conditionally.
+(macrolet
+    ((test-comparison (comparator type x y)
+       `(progn
+          ,@(loop for (result-type a b)
+                    in '((nil t   nil)
+                         (nil 0   1)
+                         (nil 0.0 1.0)
+                         (nil 0d0 0d0)
+                         (nil 0.0 0d0)
+                         (nil #c(1.0 1.0) #c(2.0 2.0))
+
+                         (t      t  nil)
+                         (fixnum 0 1)
+                         ((unsigned-byte #.sb-vm:n-word-bits)
+                          (1+ most-positive-fixnum)
+                          (+ 2 most-positive-fixnum))
+                         ((signed-byte #.sb-vm:n-word-bits)
+                          -1 (* 2 most-negative-fixnum))
+                         (single-float 0.0 1.0)
+                         (double-float 0d0 1d0))
+                  for lambda = (if result-type
+                                   `(lambda (x y a b)
+                                      (declare (,type x y)
+                                               (,result-type a b))
+                                      (if (,comparator x y)
+                                          a b))
+                                   `(lambda (x y)
+                                      (declare (,type x y))
+                                      (if (,comparator x y)
+                                          ,a ,b)))
+                  for args = `(,x ,y ,@(and result-type
+                                            `(,a ,b)))
+                  collect
+                  `(progn
+                     (eql (funcall (compile nil ',lambda)
+                                   ,@args)
+                          (eval '(,lambda ,@args))))))))
+  (sb-vm::with-float-traps-masked
+      (:divide-by-zero :overflow :inexact :invalid)
+    (let ((sb-ext:*evaluator-mode* :interpret))
+      (declare (sb-ext:muffle-conditions style-warning))
+      (test-comparison eql t t nil)
+      (test-comparison eql t t t)
+
+      (test-comparison =   t 1 0)
+      (test-comparison =   t 1 1)
+      (test-comparison =   t (1+ most-positive-fixnum) (+ 2 most-positive-fixnum))
+      (test-comparison =   fixnum 1 0)
+      (test-comparison =   fixnum 0 0)
+      (test-comparison =   (unsigned-byte #.sb-vm:n-word-bits) 1 0)
+      (test-comparison =   (unsigned-byte #.sb-vm:n-word-bits) 0 0)
+      (test-comparison =   (signed-byte #.sb-vm:n-word-bits)   1 0)
+      (test-comparison =   (signed-byte #.sb-vm:n-word-bits)   1 1)
+
+      (test-comparison =   single-float 0.0 1.0)
+      (test-comparison =   single-float 1.0 1.0)
+      (test-comparison =   single-float (/ 1.0 0.0) (/ 1.0 0.0))
+      (test-comparison =   single-float (/ 1.0 0.0) 1.0)
+      (test-comparison =   single-float (/ 0.0 0.0) (/ 0.0 0.0))
+      (test-comparison =   single-float (/ 0.0 0.0) 0.0)
+
+      (test-comparison =   double-float 0d0 1d0)
+      (test-comparison =   double-float 1d0 1d0)
+      (test-comparison =   double-float (/ 1d0 0d0) (/ 1d0 0d0))
+      (test-comparison =   double-float (/ 1d0 0d0) 1d0)
+      (test-comparison =   double-float (/ 0d0 0d0) (/ 0d0 0d0))
+      (test-comparison =   double-float (/ 0d0 0d0) 0d0)
+
+      (test-comparison <   t 1 0)
+      (test-comparison <   t 0 1)
+      (test-comparison <   t 1 1)
+      (test-comparison <   t (1+ most-positive-fixnum)  (+ 2 most-positive-fixnum))
+      (test-comparison <   t (+ 2 most-positive-fixnum) (1+ most-positive-fixnum))
+      (test-comparison <   fixnum 1 0)
+      (test-comparison <   fixnum 0 1)
+      (test-comparison <   fixnum 0 0)
+      (test-comparison <   (unsigned-byte #.sb-vm:n-word-bits) 1 0)
+      (test-comparison <   (unsigned-byte #.sb-vm:n-word-bits) 0 1)
+      (test-comparison <   (unsigned-byte #.sb-vm:n-word-bits) 0 0)
+      (test-comparison <   (signed-byte #.sb-vm:n-word-bits)   1 0)
+      (test-comparison <   (signed-byte #.sb-vm:n-word-bits)   0 1)
+      (test-comparison <   (signed-byte #.sb-vm:n-word-bits)   1 1)
+
+      (test-comparison <   single-float 0.0 1.0)
+      (test-comparison <   single-float 1.0 0.0)
+      (test-comparison <   single-float 1.0 1.0)
+      (test-comparison <   single-float (/ 1.0 0.0) (/ 1.0 0.0))
+      (test-comparison <   single-float (/ 1.0 0.0) 1.0)
+      (test-comparison <   single-float 1.0 (/ 1.0 0.0))
+      (test-comparison <   single-float (/ 0.0 0.0) (/ 0.0 0.0))
+      (test-comparison <   single-float (/ 0.0 0.0) 0.0)
+
+      (test-comparison <   double-float 0d0 1d0)
+      (test-comparison <   double-float 1d0 0d0)
+      (test-comparison <   double-float 1d0 1d0)
+      (test-comparison <   double-float (/ 1d0 0d0) (/ 1d0 0d0))
+      (test-comparison <   double-float (/ 1d0 0d0) 1d0)
+      (test-comparison <   double-float 1d0 (/ 1d0 0d0))
+      (test-comparison <   double-float (/ 0d0 0d0) (/ 0d0 0d0))
+      (test-comparison <   double-float (/ 0d0 0d0) 0d0)
+      (test-comparison <   double-float 0d0 (/ 0d0 0d0))
+
+      (test-comparison >   t 1 0)
+      (test-comparison >   t 0 1)
+      (test-comparison >   t 1 1)
+      (test-comparison >   t (1+ most-positive-fixnum)  (+ 2 most-positive-fixnum))
+      (test-comparison >   t (+ 2 most-positive-fixnum) (1+ most-positive-fixnum))
+      (test-comparison >   fixnum 1 0)
+      (test-comparison >   fixnum 0 1)
+      (test-comparison >   fixnum 0 0)
+      (test-comparison >   (unsigned-byte #.sb-vm:n-word-bits) 1 0)
+      (test-comparison >   (unsigned-byte #.sb-vm:n-word-bits) 0 1)
+      (test-comparison >   (unsigned-byte #.sb-vm:n-word-bits) 0 0)
+      (test-comparison >   (signed-byte #.sb-vm:n-word-bits)   1 0)
+      (test-comparison >   (signed-byte #.sb-vm:n-word-bits)   0 1)
+      (test-comparison >   (signed-byte #.sb-vm:n-word-bits)   1 1)
+
+      (test-comparison >   single-float 0.0 1.0)
+      (test-comparison >   single-float 1.0 0.0)
+      (test-comparison >   single-float 1.0 1.0)
+      (test-comparison >   single-float (/ 1.0 0.0) (/ 1.0 0.0))
+      (test-comparison >   single-float (/ 1.0 0.0) 1.0)
+      (test-comparison >   single-float 1.0 (/ 1.0 0.0))
+      (test-comparison >   single-float (/ 0.0 0.0) (/ 0.0 0.0))
+      (test-comparison >   single-float (/ 0.0 0.0) 0.0)
+
+      (test-comparison >   double-float 0d0 1d0)
+      (test-comparison >   double-float 1d0 0d0)
+      (test-comparison >   double-float 1d0 1d0)
+      (test-comparison >   double-float (/ 1d0 0d0) (/ 1d0 0d0))
+      (test-comparison >   double-float (/ 1d0 0d0) 1d0)
+      (test-comparison >   double-float 1d0 (/ 1d0 0d0))
+      (test-comparison >   double-float (/ 0d0 0d0) (/ 0d0 0d0))
+      (test-comparison >   double-float (/ 0d0 0d0) 0d0)
+      (test-comparison >   double-float 0d0 (/ 0d0 0d0)))))
+
index ef42033..0f5e874 100644 (file)
 
 (defun test-step-into ()
   (let* ((results nil)
 
 (defun test-step-into ()
   (let* ((results nil)
-         (expected '(("(< X 2)" :unknown)
-                     ("(- X 1)" :unknown)
-                     ("(FIB (1- X))" (2))
-                     ("(< X 2)" :unknown)
-                     ("(- X 1)" :unknown)
-                     ("(FIB (1- X))" (1))
-                     ("(< X 2)" :unknown)
-                     ("(- X 2)" :unknown)
-                     ("(FIB (- X 2))" (0))
-                     ("(< X 2)" :unknown)
-                     ("(+ (FIB (1- X)) (FIB (- X 2)))" :unknown)
-                     ("(- X 2)" :unknown)
-                     ("(FIB (- X 2))" (1))
-                     ("(< X 2)" :unknown)
-                     ("(+ (FIB (1- X)) (FIB (- X 2)))" :unknown)))
+         ;; The generic-< VOP on x86oids doesn't emit a full call
+         (expected
+          #-(or x86 x86-64)
+           '(("(< X 2)" :unknown)
+             ("(- X 1)" :unknown)
+             ("(FIB (1- X))" (2))
+             ("(< X 2)" :unknown)
+             ("(- X 1)" :unknown)
+             ("(FIB (1- X))" (1))
+             ("(< X 2)" :unknown)
+             ("(- X 2)" :unknown)
+             ("(FIB (- X 2))" (0))
+             ("(< X 2)" :unknown)
+             ("(+ (FIB (1- X)) (FIB (- X 2)))" :unknown)
+             ("(- X 2)" :unknown)
+             ("(FIB (- X 2))" (1))
+             ("(< X 2)" :unknown)
+             ("(+ (FIB (1- X)) (FIB (- X 2)))" :unknown))
+           #+(or x86 x86-64)
+           '(("(- X 1)" :unknown)
+             ("(FIB (1- X))" (2))
+             ("(- X 1)" :unknown)
+             ("(FIB (1- X))" (1))
+             ("(- X 2)" :unknown)
+             ("(FIB (- X 2))" (0))
+             ("(+ (FIB (1- X)) (FIB (- X 2)))" :unknown)
+             ("(- X 2)" :unknown)
+             ("(FIB (- X 2))" (1))
+             ("(+ (FIB (1- X)) (FIB (- X 2)))" :unknown)))
          (*stepper-hook* (lambda (condition)
                            (typecase condition
                              (step-form-condition
          (*stepper-hook* (lambda (condition)
                            (typecase condition
                              (step-form-condition
 
 (defun test-step-next ()
   (let* ((results nil)
 
 (defun test-step-next ()
   (let* ((results nil)
-         (expected '(("(< X 2)" :unknown)
-                     ("(- X 1)" :unknown)
-                     ("(FIB (1- X))" (2))
-                     ("(< X 2)" :unknown)
-                     ("(- X 1)" :unknown)
-                     ("(FIB (1- X))" (1))
-                     ("(- X 2)" :unknown)
-                     ("(FIB (- X 2))" (0))
-                     ("(+ (FIB (1- X)) (FIB (- X 2)))" :unknown)
-                     ("(- X 2)" :unknown)
-                     ("(FIB (- X 2))" (1))
-                     ("(+ (FIB (1- X)) (FIB (- X 2)))" :unknown)))
+         (expected
+          #-(or x86 x86-64)
+          '(("(< X 2)" :unknown)
+            ("(- X 1)" :unknown)
+            ("(FIB (1- X))" (2))
+            ("(< X 2)" :unknown)
+            ("(- X 1)" :unknown)
+            ("(FIB (1- X))" (1))
+            ("(- X 2)" :unknown)
+            ("(FIB (- X 2))" (0))
+            ("(+ (FIB (1- X)) (FIB (- X 2)))" :unknown)
+            ("(- X 2)" :unknown)
+            ("(FIB (- X 2))" (1))
+            ("(+ (FIB (1- X)) (FIB (- X 2)))" :unknown))
+          #+(or x86 x86-64)
+          '(("(- X 1)" :unknown)
+            ("(FIB (1- X))" (2))
+            ("(- X 1)" :unknown)
+            ("(FIB (1- X))" (1))
+            ("(- X 2)" :unknown)
+            ("(FIB (- X 2))" (0))
+            ("(+ (FIB (1- X)) (FIB (- X 2)))" :unknown)
+            ("(- X 2)" :unknown)
+            ("(FIB (- X 2))" (1))
+            ("(+ (FIB (1- X)) (FIB (- X 2)))" :unknown)))
          (count 0)
          (*stepper-hook* (lambda (condition)
                            (typecase condition
          (count 0)
          (*stepper-hook* (lambda (condition)
                            (typecase condition
 
 (defun test-step-out ()
   (let* ((results nil)
 
 (defun test-step-out ()
   (let* ((results nil)
-         (expected '(("(< X 2)" :unknown)
-                     ("(- X 1)" :unknown)
-                     ("(FIB (1- X))" (2))
-                     ("(< X 2)" :unknown)
-                     ("(- X 2)" :unknown)
-                     ("(FIB (- X 2))" (1))
-                     ("(< X 2)" :unknown)
-                     ("(+ (FIB (1- X)) (FIB (- X 2)))" :unknown)))
+         (expected
+          #-(or x86 x86-64)
+          '(("(< X 2)" :unknown)
+            ("(- X 1)" :unknown)
+            ("(FIB (1- X))" (2))
+            ("(< X 2)" :unknown)
+            ("(- X 2)" :unknown)
+            ("(FIB (- X 2))" (1))
+            ("(< X 2)" :unknown)
+            ("(+ (FIB (1- X)) (FIB (- X 2)))" :unknown))
+          #+(or x86 x86-64)
+          '(("(- X 1)" :unknown)
+            ("(FIB (1- X))" (2))
+            ("(- X 1)" :unknown)
+            ("(FIB (1- X))" (1))
+            ("(- X 2)" :unknown)
+            ("(FIB (- X 2))" (1))
+            ("(+ (FIB (1- X)) (FIB (- X 2)))" :unknown)))
          (count 0)
          (*stepper-hook* (lambda (condition)
                            (typecase condition
          (count 0)
          (*stepper-hook* (lambda (condition)
                            (typecase condition
 
 (defun test-step-start-from-break ()
   (let* ((results nil)
 
 (defun test-step-start-from-break ()
   (let* ((results nil)
-         (expected '(("(- X 2)" :unknown)
-                     ("(FIB-BREAK (- X 2))" (0))
-                     ("(< X 2)" :unknown)
-                     ("(+ (FIB-BREAK (1- X)) (FIB-BREAK (- X 2)))" :unknown)
-                     ("(- X 2)" :unknown)
-                     ("(FIB-BREAK (- X 2))" (1))
-                     ("(< X 2)" :unknown)
-                     ("(+ (FIB-BREAK (1- X)) (FIB-BREAK (- X 2)))" :unknown)))
+         (expected
+          #-(or x86 x86-64)
+          '(("(- X 2)" :unknown)
+            ("(FIB-BREAK (- X 2))" (0))
+            ("(< X 2)" :unknown)
+            ("(+ (FIB-BREAK (1- X)) (FIB-BREAK (- X 2)))" :unknown)
+            ("(- X 2)" :unknown)
+            ("(FIB-BREAK (- X 2))" (1))
+            ("(< X 2)" :unknown)
+            ("(+ (FIB-BREAK (1- X)) (FIB-BREAK (- X 2)))" :unknown))
+          #+(or x86 x86-64)
+          '(("(- X 2)" :unknown)
+            ("(FIB-BREAK (- X 2))" (0))
+            ("(+ (FIB-BREAK (1- X)) (FIB-BREAK (- X 2)))" :unknown)
+            ("(- X 2)" :unknown)
+            ("(FIB-BREAK (- X 2))" (1))
+            ("(+ (FIB-BREAK (1- X)) (FIB-BREAK (- X 2)))" :unknown)))
          (count 0)
          (*stepper-hook* (lambda (condition)
                            (typecase condition
          (count 0)
          (*stepper-hook* (lambda (condition)
                            (typecase condition
                                 (incf count)
                                 (invoke-restart 'step-next)))))))
     (step (fib 3))
                                 (incf count)
                                 (invoke-restart 'step-next)))))))
     (step (fib 3))
-    (assert (= count 6))))
+    (assert (= count #-(or x86 x86-64) 6 #+(or x86 x86-64) 5))))
 
 (defun test-step-backtrace ()
   (let* ((*stepper-hook* (lambda (condition)
 
 (defun test-step-backtrace ()
   (let* ((*stepper-hook* (lambda (condition)
index 63330b3..263560b 100644 (file)
@@ -17,4 +17,4 @@
 ;;; checkins which aren't released. (And occasionally for internal
 ;;; versions, especially for internal versions off the main CVS
 ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)
 ;;; checkins which aren't released. (And occasionally for internal
 ;;; versions, especially for internal versions off the main CVS
 ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)
-"1.0.24.33"
+"1.0.24.35"