... |
... |
@@ -963,19 +963,17 @@ |
963
|
963
|
(inst ,inst x y))
|
964
|
964
|
(descriptor-reg
|
965
|
965
|
(inst ,inst x (,ea y))))
|
966
|
|
- (cond (not-p
|
967
|
|
- ;; Instead of x > y, we're doing x <= y and want
|
968
|
|
- ;; to jmp when x <= y. If NaN occurrs we also
|
969
|
|
- ;; want to jump. x <= y means CF = 1 or ZF = 1.
|
970
|
|
- ;; When NaN occurs, ZF, PF, and CF are all set.
|
971
|
|
- ;; Hence, we can just test for x <= y.
|
972
|
|
- (inst jmp :be target))
|
973
|
|
- (t
|
974
|
|
- ;; If there's NaN, the ZF, PF, and CF bits are
|
975
|
|
- ;; set. We only want to jmp to the target when
|
976
|
|
- ;; x > y. This happens if CF = 0. Hence, we
|
977
|
|
- ;; will not jmp to the target if NaN occurred.
|
978
|
|
- (inst jmp :a target))))))))
|
|
966
|
+ ;; When a NaN occurs, comis sets ZF, PF, and CF = 1. In
|
|
967
|
+ ;; the normal case (not-p false), we want to jump to the
|
|
968
|
+ ;; target when x > y. This happens when CF = 0. Hence,
|
|
969
|
+ ;; we won't jump to the target when there's a NaN, as
|
|
970
|
+ ;; desired.
|
|
971
|
+ ;;
|
|
972
|
+ ;; For the not-p case, we want to jump to target when x
|
|
973
|
+ ;; <= y. This means CF = 1 or ZF = 1. But NaN sets
|
|
974
|
+ ;; these bits too, so we jump to the target for NaN or x
|
|
975
|
+ ;; <= y, as desired.
|
|
976
|
+ (inst jmp (if (not not-p) :a :be) target))))))
|
979
|
977
|
(frob > single comiss)
|
980
|
978
|
(frob > double comisd))
|
981
|
979
|
|
... |
... |
@@ -990,29 +988,22 @@ |
990
|
988
|
(sc-type (symbolicate size "-REG"))
|
991
|
989
|
(inherit (symbolicate size "-FLOAT-COMPARE")))
|
992
|
990
|
`(define-vop (,name ,inherit)
|
|
991
|
+ (:args (x :scs (,sc-type descriptor-reg))
|
|
992
|
+ (y :scs (,sc-type)))
|
993
|
993
|
(:translate ,op)
|
994
|
994
|
(:info target not-p)
|
995
|
|
- (:temporary (:sc ,sc-type) load-y)
|
|
995
|
+ (:temporary (:sc ,sc-type) load-x)
|
996
|
996
|
(:generator 3
|
997
|
|
- (sc-case y
|
|
997
|
+ ;; Note: x < y is the same as y > x. We reverse the
|
|
998
|
+ ;; args to reduce the number of jump instructions
|
|
999
|
+ ;; needed. Then the logic for the branches is the same
|
|
1000
|
+ ;; as for the case y > x above.
|
|
1001
|
+ (sc-case x
|
998
|
1002
|
(,sc-type
|
999
|
1003
|
(inst ,inst y x))
|
1000
|
1004
|
(descriptor-reg
|
1001
|
|
- (inst ,mover load-y (,ea y))
|
1002
|
|
- (inst ,inst load-y x)))
|
1003
|
|
- (cond (not-p
|
1004
|
|
- ;; Instead of x < y, we're doing x >= y and want
|
1005
|
|
- ;; to jmp when x >= y. But x >=y is the same as
|
1006
|
|
- ;; y <= x, so if we swap the args, we can apply
|
1007
|
|
- ;; the same logic we use for > not-p case above.
|
1008
|
|
- (inst jmp :be target))
|
1009
|
|
- (t
|
1010
|
|
- ;; We want to jump when x < y. This is the same
|
1011
|
|
- ;; as jumping when y > x. So if we reverse the
|
1012
|
|
- ;; args, we can apply the same logic as we did
|
1013
|
|
- ;; above for the > vop.
|
1014
|
|
-
|
1015
|
|
- (inst jmp :a target))))))))
|
|
1005
|
+ (inst ,inst y (,ea x))))
|
|
1006
|
+ (inst jmp (if (not not-p) :a :be) target))))))
|
1016
|
1007
|
(frob < single comiss movss)
|
1017
|
1008
|
(frob < double comisd movsd))
|
1018
|
1009
|
|