Draft: Address #156: Add vops for <= and >=
Add vops to handle the comparisons <=
and >=
for both 32-bit
signed and unsigned words and for single-float and double-float.
This isn't used by the compiler yet, but we can test this by compiling lisp and using the new lisp and compiling
(c::def-source-transform <= (&rest args) (c::multi-compare '<= args nil))
Then we can compile this test code:
(defun c<= (x y)
(declare (single-float x y))
(<= x y))
(defun si-<= (x y)
(declare (type (signed-byte 32) x y))
(<= x y))
(defun ui-<= (x y)
(declare (type (unsigned-byte 32) x y))
(<= x y))
The key parts of the disassembly are then:
* (disassemble 'c<=)
...
96: comiss xmm0, [edi-3] ; No-arg-parsing entry point
; [:non-local-entry]
9a: jp L0
9c: jbe L2
;;; [6] (<= X Y)
9e: L0: mov edx, 2800000b ; nil
; [:block-start]
a3: L1: mov ecx, dword ptr [ebp-8] ; [:block-start]
...
b2: L2: mov edx, 28000027 ; t
; [:block-start]
b7: jmp L1
...
For the word operations, we can see
* (disassemble 'si-<=)
...
ef4: L10: cmp ebx, edi ; No-arg-parsing entry point
; [:non-local-entry]
ef6: jle L12
...
* (disassemble 'ui-<=)
...
8f6: L18: cmp ebx, edi ; No-arg-parsing entry point
; [:non-local-entry]
8f8: jbe L20
...
To test handling of NaN, we have
* (set-floating-point-modes :traps nil)
* (defvar *sn* (* 0 ext:single-float-positive-infinity))
* (c<= 1.0 2.0)
T
* (c<= 2.0 2.0)
T
* (c<= 3.0 2.0)
NIL
* (c<= 1.0 *sn*)
NIL
* (c<= *sn* 1.0)
NIL
* (c<= *sn* *sn*)
NIL
This are the expected result when comparing with NaN.