7a82135b922b4e8ccfd79fe0dead86f3fb4758a9
[projects/cmucl/cmucl.git] / src / compiler / float-tran.lisp
1 ;;; -*- Mode: Lisp; Package: C; Log: code.log -*-
2 ;;;
3 ;;; **********************************************************************
4 ;;; This code was written as part of the CMU Common Lisp project at
5 ;;; Carnegie Mellon University, and has been placed in the public domain.
6 ;;;
7 (ext:file-comment
8   "$Header: src/compiler/float-tran.lisp $")
9 ;;;
10 ;;; **********************************************************************
11 ;;;
12 ;;; This file contains floating-point specific transforms, and may be somewhat
13 ;;; implementation dependent in its assumptions of what the formats are.
14 ;;;
15 ;;; Author: Rob MacLachlan
16 ;;; 
17 (in-package "C")
18 (intl:textdomain "cmucl")
19
20 \f
21 ;;;; Coercions:
22
23 (defknown %single-float (real) single-float (movable foldable flushable))
24 (defknown %double-float (real) double-float (movable foldable flushable))
25
26 (deftransform float ((n prototype) (* single-float) * :when :both)
27   '(%single-float n))
28
29 (deftransform float ((n prototype) (* double-float) * :when :both)
30   '(%double-float n))
31
32 (deftransform float ((n) *)
33   `(if (floatp n) n (%single-float n)))
34
35 (deftransform %single-float ((n) (single-float) * :when :both)
36   'n)
37
38 (deftransform %double-float ((n) (double-float) * :when :both)
39   'n)
40
41 #+double-double
42 (progn
43 (defknown %double-double-float (real)
44   double-double-float
45   (movable foldable flushable))
46
47 (deftransform float ((n prototype) (* double-double-float) * :when :both)
48   '(%double-double-float n))
49
50 (deftransform %double-float ((n) (double-double-float) * :when :both)
51   '(double-double-hi n))
52
53 (deftransform %single-float ((n) (double-double-float) * :when :both)
54   '(float (double-double-hi n) 1f0))
55
56 (deftransform %double-double-float ((n) (double-double-float) * :when :both)
57   'n)
58
59 #+nil
60 (defun %double-double-float (n)
61   (make-double-double-float (float n 1d0) 0d0))
62
63 ;; Moved to code/float.lisp, because we need this relatively early in
64 ;; the build process to handle float and real types.
65 #+nil
66 (defun %double-double-float (n)
67   (typecase n
68     (fixnum
69      (%make-double-double-float (float n 1d0) 0d0))
70     (single-float
71      (%make-double-double-float (float n 1d0) 0d0))
72     (double-float
73      (%make-double-double-float (float n 1d0) 0d0))
74     (double-double-float
75      n)
76     (bignum
77      (bignum:bignum-to-float n 'double-double-float))
78     (ratio
79      (kernel::float-ratio n 'double-double-float))))
80 ); progn
81
82 (defknown %complex-single-float (number) (complex single-float)
83   (movable foldable flushable))
84 (defknown %complex-double-float (number) (complex double-float)
85   (movable foldable flushable))
86 (defknown %complex-double-double-float (number) (complex double-double-float)
87   (movable foldable flushable))
88
89 (macrolet
90     ((frob (type)
91        (let ((name (symbolicate "%COMPLEX-" type "-FLOAT"))
92              (convert (symbolicate "%" type "-FLOAT")))
93          `(progn
94             (defun ,name (n)
95               (declare (number n))
96               (etypecase n
97                 (real
98                  (complex (,convert n)))
99                 (complex
100                  (complex (,convert (realpart n))
101                           (,convert (imagpart n))))))
102             (deftransform ,name ((n) ((complex ,(symbolicate type "-FLOAT"))) * :when :both)
103               'n)))))
104   (frob single)
105   (frob double)
106   #+double-double
107   (frob double-double))
108
109
110 (deftransform coerce ((n type) (* *) * :when :both)
111   (unless (constant-continuation-p type)
112     (give-up))
113   `(the ,(continuation-value type)
114         ,(let ( (tspec (specifier-type (continuation-value type))) )
115            (cond #+double-double
116                  ((csubtypep tspec (specifier-type 'double-double-float))
117                   '(%double-double-float n))
118                  ((csubtypep tspec (specifier-type 'double-float))      
119                   '(%double-float n))   
120                  ((csubtypep tspec (specifier-type 'float))
121                   '(%single-float n))
122                  #+double-double
123                  ((csubtypep tspec (specifier-type '(complex double-double-float)))
124                   '(%complex-double-double-float n))
125                  ((csubtypep tspec (specifier-type '(complex double-float)))
126                   '(%complex-double-float n))
127                  ((csubtypep tspec (specifier-type '(complex single-float)))
128                   '(%complex-single-float n))
129                  (t
130                   (give-up))))))
131
132 ;;; Not strictly float functions, but primarily useful on floats:
133 ;;;
134 (macrolet ((frob (fun ufun)
135              `(progn
136                 (defknown ,ufun (real) integer (movable foldable flushable))
137                 (deftransform ,fun ((x &optional by)
138                                     (* &optional
139                                        (constant-argument (member 1))))
140                   '(let ((res (,ufun x)))
141                      (values res (- x res)))))))
142   (frob round %unary-round))
143
144 (defknown %unary-truncate (real) integer
145           (movable foldable flushable))
146
147 ;; Convert (truncate x y) to the obvious implementation.  We only want
148 ;; this when under certain conditions and let the generic truncate
149 ;; handle the rest.  (Note: if y = 1, the divide and multiply by y
150 ;; should be removed by other deftransforms.)
151
152 (deftransform truncate ((x &optional y)
153                         (float &optional (or float integer)))
154   '(let ((res (%unary-truncate (/ x y))))
155      (values res (- x (* y res)))))
156
157 (deftransform floor ((number &optional divisor)
158                      (float &optional (or integer float)))
159   '(multiple-value-bind (tru rem) (truncate number divisor)
160     (if (and (not (zerop rem))
161              (if (minusp divisor)
162                  (plusp number)
163                  (minusp number)))
164         (values (1- tru) (+ rem divisor))
165         (values tru rem))))
166
167 (deftransform ceiling ((number &optional divisor)
168                        (float &optional (or integer float)))
169   '(multiple-value-bind (tru rem) (truncate number divisor)
170     (if (and (not (zerop rem))
171              (if (minusp divisor)
172                  (minusp number)
173                  (plusp number)))
174         (values (1+ tru) (- rem divisor))
175         (values tru rem))))
176
177 (defknown %unary-ftruncate/single-float (single-float) single-float
178           (movable foldable flushable))
179 (defknown %unary-ftruncate/double-float (double-float) double-float
180           (movable foldable flushable))
181
182 (defknown %unary-ftruncate (real) float
183           (movable foldable flushable))
184
185 ;; Convert (ftruncate x y) to the obvious implementation.  We only
186 ;; want this under certain conditions and let the generic ftruncate
187 ;; handle the rest.  (Note: if y = 1, the divide and multiply by y
188 ;; should be removed by other deftransforms.)
189
190 (deftransform ftruncate ((x &optional (y 1))
191                          (float &optional (or float integer)))
192   '(let ((res (%unary-ftruncate (/ x y))))
193      (values res (- x (* y res)))))
194
195 #+sparc
196 (defknown fast-unary-ftruncate ((or single-float double-float))
197   (or single-float double-float)
198   (movable foldable flushable))
199
200 #+sparc
201 (defoptimizer (fast-unary-ftruncate derive-type) ((f))
202   (one-arg-derive-type f
203                        #'(lambda (n)
204                            (ftruncate-derive-type-quot-aux n
205                                                            (specifier-type '(integer 1 1))
206                                                            nil))
207                        #'ftruncate))
208
209 ;; Convert %unary-ftruncate to unary-ftruncate/{single,double}-float
210 ;; if x is known to be of the right type.  Also, if the result is
211 ;; known to fit in the same range as a (signed-byte 32), convert this
212 ;; to %unary-truncate, which might be a single instruction, and float
213 ;; the result.  However, for sparc, we have a vop to do this so call
214 ;; that, and for Sparc V9, we can actually handle a 64-bit integer
215 ;; range.
216
217 (macrolet ((frob (ftype func)
218              `(deftransform %unary-ftruncate ((x) (,ftype))
219                (let* ((x-type (continuation-type x))
220                       (lo (bound-value (numeric-type-low x-type)))
221                       (hi (bound-value (numeric-type-high x-type)))
222                       (limit-lo (- (ash 1 #-sparc-v9 31 #+sparc-v9 63)))
223                       (limit-hi (ash 1 #-sparc-v9 31 #+sparc-v9 63)))
224                  (if (and (numberp lo) (numberp hi)
225                           (< limit-lo lo)
226                           (< hi limit-hi))
227                      #-sparc '(let ((result (coerce (%unary-truncate x) ',ftype)))
228                                 (if (zerop result)
229                                     (* result x)
230                                     result))
231                      #+sparc '(let ((result (fast-unary-ftruncate x)))
232                                 (if (zerop result)
233                                     (* result x)
234                                     result))
235                      '(,func x))))))
236   (frob single-float %unary-ftruncate/single-float)
237   (frob double-float %unary-ftruncate/double-float))
238
239 ;;; FROUND
240 #-x87
241 (progn
242 (deftransform fround ((x &optional (y 1))
243                       ((or single-float double-float)
244                        &optional (or single-float double-float integer)))
245   '(let ((res (%unary-fround (/ x y))))
246     (values res (- x (* y res)))))
247
248 (defknown %unary-fround (real) float
249   (movable foldable flushable))
250
251 (defknown %unary-fround/single-float (single-float) single-float
252   (movable foldable flushable))
253
254 (defknown %unary-fround/double-float (double-float) double-float
255   (movable foldable flushable))
256
257 (deftransform %unary-fround ((x) (single-float))
258   '(%unary-fround/single-float x))
259
260 (deftransform %unary-fround ((x) (double-float))
261   '(%unary-fround/double-float x))
262
263 ); not x87
264
265 ;;; Random:
266 ;;;
267 (macrolet ((frob (fun type)
268              `(deftransform random ((num &optional state)
269                                     (,type &optional *) *
270                                     :when :both)
271                 "use inline float operations"
272                 '(,fun num (or state *random-state*)))))
273   (frob %random-single-float single-float)
274   (frob %random-double-float double-float))
275
276 #-(or new-random random-mt19937)
277 (deftransform random ((num &optional state)
278                       ((integer 1 #.random-fixnum-max) &optional *))
279   _N"use inline fixnum operations"
280   '(rem (random-chunk (or state *random-state*)) num))
281
282 ;;; With the latest propagate-float-type code the compiler can inline
283 ;;; truncate (signed-byte 32) allowing 31 bits, and (unsigned-byte 32)
284 ;;; 32 bits on the x86. When not using the propagate-float-type
285 ;;; feature the best size that can be inlined is 29 bits.  The choice
286 ;;; shouldn't cause bootstrap problems just slow code.
287 #+new-random
288 (deftransform random ((num &optional state)
289                       ((integer 1
290                                 #+x86 #xffffffff
291                                 #-x86 #x7fffffff
292                                 )
293                        &optional *))
294   #+x86 (intl:gettext "use inline (unsigned-byte 32) operations")
295   #-x86 (intl:gettext "use inline (signed-byte 32) operations")
296   '(values (truncate (%random-double-float (coerce num 'double-float)
297                       (or state *random-state*)))))
298
299 #+random-mt19937
300 (deftransform random ((num &optional state)
301                       ((integer 1 #.(expt 2 32)) &optional *))
302   _N"use inline (unsigned-byte 32) operations"
303   (let* ((num-type (continuation-type num))
304          (num-high (cond ((numeric-type-p num-type)
305                           (numeric-type-high num-type))
306                          ((union-type-p num-type)
307                           ;; Find the maximum of the union type.  We
308                           ;; know this works because if we're in this
309                           ;; routine, NUM must be a subtype of
310                           ;; (INTEGER 1 2^32), so each member of the
311                           ;; union must be a subtype too.
312                           (reduce #'max (union-type-types num-type)
313                                   :key #'numeric-type-high))
314                          (t
315                           (give-up)))))
316     ;; Rather than doing (rem (random-chunk) num-high), we do,
317     ;; essentially, (rem (* num-high (random-chunk)) #x100000000).  I
318     ;; (rtoy) believe this approach doesn't have the bias issue with
319     ;; doing rem.  This method works by treating (random-chunk) as if
320     ;; it were a 32-bit fraction between 0 and 1, exclusive.  Multiply
321     ;; this by num-high to get a random number between 0 and num-high,
322     ;; This should have no bias.
323     (cond ((constant-continuation-p num)
324            (if (= num-high (expt 2 32))
325                '(random-chunk (or state *random-state*))
326                '(values (bignum::%multiply 
327                          (random-chunk (or state *random-state*))
328                          num))))
329           ((< num-high (expt 2 32))
330            '(values (bignum::%multiply (random-chunk (or state *random-state*))
331                      num)))
332           ((= num-high (expt 2 32))
333            '(if (= num (expt 2 32))
334                 (random-chunk (or state *random-state*))
335                 (values (bignum::%multiply (random-chunk (or state *random-state*))
336                                            num))))
337           (t
338            (error (intl:gettext "Shouldn't happen"))))))
339
340 \f
341 ;;;; Float accessors:
342
343 (defknown make-single-float ((signed-byte 32)) single-float
344   (movable foldable flushable))
345
346 (defknown make-double-float ((signed-byte 32) (unsigned-byte 32)) double-float
347   (movable foldable flushable))
348
349 (defknown single-float-bits (single-float) (signed-byte 32)
350   (movable foldable flushable))
351
352 (defknown double-float-high-bits (double-float) (signed-byte 32)
353   (movable foldable flushable))
354
355 (defknown double-float-low-bits (double-float) (unsigned-byte 32)
356   (movable foldable flushable))
357
358 #+(or sparc ppc)
359 (defknown double-float-bits (double-float)
360   (values (signed-byte 32) (unsigned-byte 32))
361   (movable foldable flushable))
362
363 #+double-double
364 (progn
365 (defknown double-double-float-p (t)
366   boolean
367   (movable foldable flushable))
368
369 (defknown %make-double-double-float (double-float double-float)
370   double-double-float
371   (movable foldable flushable))
372
373
374 (defknown double-double-hi (double-double-float)
375   double-float
376   (movable foldable flushable))
377
378 (defknown double-double-lo (double-double-float)
379   double-float
380   (movable foldable flushable))
381
382 ) ; progn
383
384 (deftransform float-sign ((float &optional float2)
385                           (single-float &optional single-float) *)
386   (if float2
387       (let ((temp (gensym)))
388         `(let ((,temp (abs float2)))
389           (if (minusp (single-float-bits float)) (- ,temp) ,temp)))
390       '(if (minusp (single-float-bits float)) -1f0 1f0)))
391
392 (deftransform float-sign ((float &optional float2)
393                           (double-float &optional double-float) *)
394   (if float2
395       (let ((temp (gensym)))
396         `(let ((,temp (abs float2)))
397           (if (minusp (double-float-high-bits float)) (- ,temp) ,temp)))
398       '(if (minusp (double-float-high-bits float)) -1d0 1d0)))
399
400 #+double-double
401 (deftransform float-sign ((float &optional float2)
402                           (double-double-float &optional double-double-float) *)
403   (if float2
404       (let ((temp (gensym)))
405         `(let ((,temp (abs float2)))
406            (if (minusp (float-sign (double-double-hi float)))
407                (- ,temp)
408                ,temp)))
409       '(if (minusp (float-sign (double-double-hi float))) -1w0 1w0)))
410
411   
412 \f
413 ;;;; DECODE-FLOAT, INTEGER-DECODE-FLOAT, SCALE-FLOAT:
414 ;;;
415 ;;;    Convert these operations to format specific versions when the format is
416 ;;; known.
417 ;;;
418
419 (deftype single-float-exponent ()
420   `(integer ,(- vm:single-float-normal-exponent-min vm:single-float-bias
421                 vm:single-float-digits)
422             ,(- vm:single-float-normal-exponent-max vm:single-float-bias)))
423
424 (deftype double-float-exponent ()
425   `(integer ,(- vm:double-float-normal-exponent-min vm:double-float-bias
426                 vm:double-float-digits)
427             ,(- vm:double-float-normal-exponent-max vm:double-float-bias)))
428
429
430 (deftype single-float-int-exponent ()
431   `(integer ,(- vm:single-float-normal-exponent-min vm:single-float-bias
432                 (* vm:single-float-digits 2))
433             ,(- vm:single-float-normal-exponent-max vm:single-float-bias
434                 vm:single-float-digits)))
435
436 (deftype double-float-int-exponent ()
437   `(integer ,(- vm:double-float-normal-exponent-min vm:double-float-bias
438                 (* vm:double-float-digits 2))
439             ,(- vm:double-float-normal-exponent-max vm:double-float-bias
440                 vm:double-float-digits)))
441
442 (deftype single-float-significand ()
443   `(integer 0 (,(ash 1 vm:single-float-digits))))
444
445 (deftype double-float-significand ()
446   `(integer 0 (,(ash 1 vm:double-float-digits))))
447
448 (defknown decode-single-float (single-float)
449   (values (single-float 0.5f0 (1f0))
450           single-float-exponent
451           (member -1f0 1f0))
452   (movable foldable flushable))
453
454 (defknown decode-double-float (double-float)
455   (values (double-float 0.5d0 (1d0))
456           double-float-exponent
457           (member -1d0 1d0))
458   (movable foldable flushable))
459
460 (defknown integer-decode-single-float (single-float)
461   (values single-float-significand single-float-int-exponent (integer -1 1))
462   (movable foldable flushable))
463
464 (defknown integer-decode-double-float (double-float)
465   (values double-float-significand double-float-int-exponent (integer -1 1))
466   (movable foldable flushable))
467
468 (defknown scale-single-float (single-float fixnum) single-float
469   (movable foldable flushable))
470
471 (defknown scale-double-float (double-float fixnum) double-float
472   (movable foldable flushable))
473
474 (deftransform decode-float ((x) (single-float) * :when :both)
475   '(decode-single-float x))
476
477 (deftransform decode-float ((x) (double-float) * :when :both)
478   '(decode-double-float x))
479
480 (deftransform integer-decode-float ((x) (single-float) * :when :both)
481   '(integer-decode-single-float x))
482
483 (deftransform integer-decode-float ((x) (double-float) * :when :both)
484   '(integer-decode-double-float x))
485
486 (deftransform scale-float ((f ex) (single-float *) * :when :both)
487   (if (and (backend-featurep :x86)
488            (not (backend-featurep :sse2))
489            (csubtypep (continuation-type ex)
490                       (specifier-type '(signed-byte 32)))
491            (not (byte-compiling)))
492       '(coerce (%scalbn (coerce f 'double-float) ex) 'single-float)
493       '(scale-single-float f ex)))
494
495 (deftransform scale-float ((f ex) (double-float *) * :when :both)
496   (if (and (backend-featurep :x86)
497            (not (backend-featurep :sse2))
498            (csubtypep (continuation-type ex)
499                       (specifier-type '(signed-byte 32))))
500       '(%scalbn f ex)
501       '(scale-double-float f ex)))
502
503 ;;; toy@rtp.ericsson.se:
504 ;;;
505 ;;; Optimizers for scale-float.  If the float has bounds, new bounds
506 ;;; are computed for the result, if possible.
507
508 (defun scale-float-derive-type-aux (f ex same-arg)
509   (declare (ignore same-arg))
510   (flet ((scale-bound (x n)
511            ;; We need to be a bit careful here and catch any overflows
512            ;; that might occur.  We can ignore underflows which become
513            ;; zeros.
514            (set-bound
515             (let ((value (handler-case
516                              (scale-float (bound-value x) n)
517                            (floating-point-overflow ()
518                              nil))))
519               ;; This check is necessary for ppc because the current
520               ;; implementation on ppc doesn't signal floating-point
521               ;; overflow.  (How many other places do we need to check
522               ;; for this?)
523               (if (and (floatp value) (float-infinity-p value))
524                   nil
525                   value))
526             (consp x))))
527     (when (and (numeric-type-p f) (numeric-type-p ex))
528       (let ((f-lo (numeric-type-low f))
529             (f-hi (numeric-type-high f))
530             (ex-lo (numeric-type-low ex))
531             (ex-hi (numeric-type-high ex))
532             (new-lo nil)
533             (new-hi nil))
534         (when (and f-hi ex-hi)
535           (setf new-hi (scale-bound f-hi ex-hi)))
536         (when (and f-lo ex-lo)
537           (setf new-lo (scale-bound f-lo ex-lo)))
538         ;; We're computing bounds for scale-float.  Assume the bounds
539         ;; on f are fl and fh, and the bounds on ex are nl and nh.
540         ;; The resulting bound should be fl*2^nl and fh*2^nh.
541         ;; However, if fh is negative, and we get an underflow, we
542         ;; might get bounds like 0 and fh*2^nh < 0.  Our bounds are
543         ;; backwards.  Thus, swap the bounds to get the correct
544         ;; bounds.
545         (when (and new-lo new-hi (< (bound-value new-hi)
546                                     (bound-value new-lo)))
547           (rotatef new-lo new-hi))
548         (make-numeric-type :class (numeric-type-class f)
549                            :format (numeric-type-format f)
550                            :complexp :real
551                            :low new-lo
552                            :high new-hi)))))
553 ;;;
554 (defoptimizer (scale-float derive-type) ((f ex))
555   (two-arg-derive-type f ex #'scale-float-derive-type-aux
556                        #'scale-float t))
557              
558 ;;; toy@rtp.ericsson.se:
559 ;;;
560 ;;; Defoptimizers for %single-float and %double-float.  This makes the
561 ;;; FLOAT function return the correct ranges if the input has some
562 ;;; defined range.  Quite useful if we want to convert some type of
563 ;;; bounded integer into a float.
564
565 (macrolet
566     ((frob (fun type)
567        (let ((aux-name (symbolicate fun "-DERIVE-TYPE-AUX")))
568          `(progn
569            (defun ,aux-name (num)
570              ;; When converting a number to a float, the limits are
571              ;; the "same."  
572              (let* ((lo (bound-func #'(lambda (x)
573                                         ;; If we can't coerce it, we
574                                         ;; return a NIL for the bound.
575                                         ;; (Is IGNORE-ERRORS too
576                                         ;; heavy-handed?  Should we
577                                         ;; try to do something more
578                                         ;; fine-grained?)
579                                         (ignore-errors (coerce x ',type)))
580                                     (numeric-type-low num)))
581                     (hi (bound-func #'(lambda (x)
582                                         (ignore-errors (coerce x ',type)))
583                                     (numeric-type-high num))))
584                (specifier-type `(,',type ,(or lo '*) ,(or hi '*)))))
585            
586            (defoptimizer (,fun derive-type) ((num))
587              (one-arg-derive-type num #',aux-name #',fun))))))
588   (frob %single-float single-float)
589   (frob %double-float double-float))
590
591 \f
592 ;;;; Float contagion:
593
594 ;;; FLOAT-CONTAGION-ARG1, ARG2  --  Internal
595 ;;;
596 ;;;    Do some stuff to recognize when the loser is doing mixed float and
597 ;;; rational arithmetic, or different float types, and fix it up.  If we don't,
598 ;;; he won't even get so much as an efficency note.
599 ;;;
600 (deftransform float-contagion-arg1 ((x y) * * :defun-only t :node node)
601   `(,(continuation-function-name (basic-combination-fun node))
602     (float x y) y))
603 ;;;
604 (deftransform float-contagion-arg2 ((x y) * * :defun-only t :node node)
605   `(,(continuation-function-name (basic-combination-fun node))
606     x (float y x)))
607
608 (dolist (x '(+ * / -))
609   (%deftransform x '(function (rational float) *) #'float-contagion-arg1)
610   (%deftransform x '(function (float rational) *) #'float-contagion-arg2))
611
612 (dolist (x '(= < > + * / -))
613   (%deftransform x '(function (single-float double-float) *)
614                  #'float-contagion-arg1)
615   (%deftransform x '(function (double-float single-float) *)
616                  #'float-contagion-arg2))
617
618
619 ;;; Prevent zerop, plusp, minusp from losing horribly.  We can't in general
620 ;;; float rational args to comparison, since Common Lisp semantics says we are
621 ;;; supposed to compare as rationals, but we can do it for any rational that
622 ;;; has a precise representation as a float (such as 0).
623 ;;;
624 (macrolet ((frob (op)
625              `(deftransform ,op ((x y) (float rational) * :when :both)
626                 (unless (constant-continuation-p y)
627                   (give-up (intl:gettext "Can't open-code float to rational comparison.")))
628                 (let ((val (continuation-value y)))
629                   (unless (eql (rational (float val)) val)
630                     (give-up (intl:gettext "~S doesn't have a precise float representation.")
631                              val)))
632                 `(,',op x (float y x)))))
633   (frob <)
634   (frob >)
635   (frob =))
636
637 \f
638 ;;;; Irrational transforms:
639
640 (defknown (%tan %sinh %asinh %atanh %log %logb %log10 #+x87 %tan-quick)
641           (double-float) double-float
642   (movable foldable flushable))
643
644 (defknown (%sin %cos %tanh #+x87 %sin-quick #+x87 %cos-quick)
645     (double-float) (double-float -1.0d0 1.0d0)
646     (movable foldable flushable))
647
648 (defknown (%asin %atan)
649     (double-float) (double-float #.(- (/ pi 2)) #.(/ pi 2))
650     (movable foldable flushable))
651     
652 (defknown (%acos)
653     (double-float) (double-float 0.0d0 #.pi)
654     (movable foldable flushable))
655     
656 (defknown (%cosh)
657     (double-float) (double-float 1.0d0)
658     (movable foldable flushable))
659
660 (defknown (%acosh %exp %sqrt)
661     (double-float) (double-float 0.0d0)
662     (movable foldable flushable))
663
664 (defknown %expm1
665     (double-float) (double-float -1d0)
666     (movable foldable flushable))
667
668 (defknown (%hypot)
669     (double-float double-float) (double-float 0d0)
670   (movable foldable flushable))
671
672 (defknown (%pow)
673     (double-float double-float) double-float
674   (movable foldable flushable))
675
676 (defknown (%atan2)
677     (double-float double-float) (double-float #.(- pi) #.pi)
678   (movable foldable flushable))
679
680 (defknown (%scalb)
681     (double-float double-float) double-float
682   (movable foldable flushable))
683
684 (defknown (%scalbn)
685     (double-float (signed-byte 32)) double-float
686     (movable foldable flushable))
687
688 (defknown (%log1p)
689     (double-float) double-float
690     (movable foldable flushable))
691
692 (dolist (stuff '((exp %exp *)
693                  (log %log float)
694                  (sqrt %sqrt float)
695                  (asin %asin float)
696                  (acos %acos float)
697                  (atan %atan *)
698                  (sinh %sinh *)
699                  (cosh %cosh *)
700                  (tanh %tanh *)
701                  (asinh %asinh *)
702                  (acosh %acosh float)
703                  (atanh %atanh float)))
704   (destructuring-bind (name prim rtype) stuff
705     (deftransform name ((x) '(single-float) rtype :eval-name t)
706       `(coerce (,prim (coerce x 'double-float)) 'single-float))
707     (deftransform name ((x) '(double-float) rtype :eval-name t :when :both)
708       `(,prim x))))
709
710 ;;; The argument range is limited on the x86 FP trig. functions. A
711 ;;; post-test can detect a failure (and load a suitable result), but
712 ;;; this test is avoided if possible.
713 ;;;
714 ;;; Simple tests show that sin/cos produce numbers greater than 1 when
715 ;;; the arg >= 2^63.  tan produces floating-point invalid exceptions
716 ;;; for arg >= 2^62.  So limit these to that range.
717 #+x87
718 (dolist (stuff '((sin %sin %sin-quick 63)
719                  (cos %cos %cos-quick 63)
720                  (tan %tan %tan-quick 62)))
721   (destructuring-bind (name prim prim-quick limit)
722       stuff
723     (deftransform name ((x) '(single-float) '* :eval-name t)
724       (if (and (backend-featurep :x86)
725                (not (backend-featurep :sse2)))
726           (cond ((csubtypep (continuation-type x)
727                             (specifier-type `(single-float
728                                               (,(- (expt 2f0 limit)))
729                                               (,(expt 2f0 limit)))))
730                  `(coerce (,prim-quick (coerce x 'double-float))
731                    'single-float))
732                 (t 
733                  (compiler-note
734                   _N"Unable to avoid inline argument range check~@
735                       because the argument range (~s) was not within 2^~D"
736                   (type-specifier (continuation-type x))
737                   limit)
738                  `(coerce (,prim (coerce x 'double-float)) 'single-float)))
739           `(coerce (,prim (coerce x 'double-float)) 'single-float)))
740     (deftransform name ((x) '(double-float) '* :eval-name t :when :both)
741       (if (and (backend-featurep :x86)
742                (not (backend-featurep :sse2)))
743           (cond ((csubtypep (continuation-type x)
744                             (specifier-type `(double-float
745                                               (,(- (expt 2d0 limit)))
746                                               (,(expt 2d0 limit)))))
747                  `(,prim-quick x))
748                 (t 
749                  (compiler-note
750                   _N"Unable to avoid inline argument range check~@
751                    because the argument range (~s) was not within 2^~D"
752                   (type-specifier (continuation-type x))
753                   limit)
754                  `(,prim x)))
755           `(,prim x)))))
756
757 (deftransform atan ((x y) (single-float single-float) *)
758   `(coerce (%atan2 (coerce x 'double-float) (coerce y 'double-float))
759     'single-float))
760 (deftransform atan ((x y) (double-float double-float) * :when :both)
761   `(%atan2 x y))
762
763 (deftransform expt ((x y) ((single-float 0f0) single-float) *)
764   `(coerce (%pow (coerce x 'double-float) (coerce y 'double-float))
765     'single-float))
766 (deftransform expt ((x y) ((double-float 0d0) double-float) * :when :both)
767   `(%pow x y))
768 (deftransform expt ((x y) ((single-float 0f0) (signed-byte 32)) *)
769   `(coerce (%pow (coerce x 'double-float) (coerce y 'double-float))
770     'single-float))
771 (deftransform expt ((x y) ((double-float 0d0) (signed-byte 32)) * :when :both)
772   `(%pow x (coerce y 'double-float)))
773
774 ;;; ANSI says log with base zero returns zero.
775 (deftransform log ((x y) (float float) float)
776   '(if (zerop y) y (/ (log x) (log y))))
777
778 \f
779 ;;; Handle some simple transformations
780   
781 (deftransform abs ((x) ((complex double-float)) double-float :when :both)
782   '(%hypot (realpart x) (imagpart x)))
783
784 (deftransform abs ((x) ((complex single-float)) single-float)
785   '(coerce (%hypot (coerce (realpart x) 'double-float)
786                    (coerce (imagpart x) 'double-float))
787           'single-float))
788
789 (deftransform abs ((x) (real) real)
790   (let ((x-type (continuation-type x)))
791     ;; If the arg is known to non-negative, we can just return the
792     ;; arg.  However, (abs -0.0) is 0.0, so this transform only works
793     ;; on floats that are known not to include negative zero.
794     (if (csubtypep x-type (specifier-type '(or (rational 0) (float (0d0)) (member 0f0 0d0))))
795         'x
796         (give-up))))
797
798 (deftransform phase ((x) ((complex double-float)) double-float :when :both)
799   '(%atan2 (imagpart x) (realpart x)))
800
801 (deftransform phase ((x) ((complex single-float)) single-float)
802   '(coerce (%atan2 (coerce (imagpart x) 'double-float)
803                    (coerce (realpart x) 'double-float))
804           'single-float))
805
806 (deftransform phase ((x) ((float)) float :when :both)
807   '(if (minusp (float-sign x))
808        (float pi x)
809        (float 0 x)))
810
811 ;;; The number is of type REAL.
812 (declaim (inline numeric-type-real-p))
813 (defun numeric-type-real-p (type)
814   (and (numeric-type-p type)
815        (eq (numeric-type-complexp type) :real)))
816
817 ;;; Coerce a numeric type bound to the given type while handling
818 ;;; exclusive bounds.
819 (defun coerce-numeric-bound (bound type)
820   (when bound
821     (if (consp bound)
822         (list (coerce (car bound) type))
823         (coerce bound type))))
824
825
826 ;;;; Optimizers for elementary functions
827 ;;;;
828 ;;;; These optimizers compute the output range of the elementary
829 ;;;; function, based on the domain of the input.
830 ;;;;
831
832 ;;; Generate a specifier for a complex type specialized to the same
833 ;;; type as the argument.
834 (defun complex-float-type (arg)
835   (declare (type numeric-type arg))
836   (let* ((format (case (numeric-type-class arg)
837                    ((integer rational) 'single-float)
838                    (t (numeric-type-format arg))))
839          (float-type (or format 'float)))
840     (specifier-type `(complex ,float-type))))
841
842 ;;; Compute a specifier like '(or float (complex float)), except float
843 ;;; should be the right kind of float.  Allow bounds for the float
844 ;;; part too.
845 (defun float-or-complex-float-type (arg &optional lo hi)
846   (declare (type numeric-type arg))
847   (let* ((format (case (numeric-type-class arg)
848                    ((integer rational) 'single-float)
849                    (t (numeric-type-format arg))))
850          (float-type (or format 'float))
851          (lo (coerce-numeric-bound lo float-type))
852          (hi (coerce-numeric-bound hi float-type)))
853     (specifier-type `(or (,float-type ,(or lo '*) ,(or hi '*))
854                          (complex ,float-type)))))
855
856 ;;; Domain-Subtype
857 ;;;
858 ;;; Test if the numeric-type ARG is within in domain specified by
859 ;;; DOMAIN-LOW and DOMAIN-HIGH, consider negative and positive zero to
860 ;;; be distinct as for the :negative-zero-is-not-zero feature. Note
861 ;;; that only inclusive and open domain limits are handled as these
862 ;;; are the only types of limits currently used. With the
863 ;;; :negative-zero-is-not-zero feature this could be handled by the
864 ;;; numeric subtype code in type.lisp.
865 ;;;
866 (defun domain-subtypep (arg domain-low domain-high)
867   (declare (type numeric-type arg)
868            (type (or real null) domain-low domain-high))
869   (let* ((arg-lo (numeric-type-low arg))
870          (arg-lo-val (bound-value arg-lo))
871          (arg-hi (numeric-type-high arg))
872          (arg-hi-val (bound-value arg-hi)))
873     ;; Check that the ARG bounds are correctly canonicalised.
874     (when (and arg-lo (floatp arg-lo-val) (zerop arg-lo-val) (consp arg-lo)
875                (minusp (float-sign arg-lo-val)))
876       (compiler-note _N"Float zero bound ~s not correctly canonicalised?" arg-lo)
877       (setq arg-lo 0l0 arg-lo-val 0l0))
878     (when (and arg-hi (zerop arg-hi-val) (floatp arg-hi-val) (consp arg-hi)
879                (plusp (float-sign arg-hi-val)))
880       (compiler-note _N"Float zero bound ~s not correctly canonicalised?" arg-hi)
881       (setq arg-hi -0l0 arg-hi-val -0l0))
882     (flet ((fp-neg-zero-p (f)   ; Is F -0.0?
883              (and (floatp f) (zerop f) (minusp (float-sign f))))
884            (fp-pos-zero-p (f)   ; Is F +0.0? 
885              (and (floatp f) (zerop f) (plusp (float-sign f)))))
886       (and (or (null domain-low)
887                (and arg-lo (>= arg-lo-val domain-low)
888                     (not (and (fp-pos-zero-p domain-low)
889                               (fp-neg-zero-p arg-lo)))))
890            (or (null domain-high)
891                (and arg-hi (<= arg-hi-val domain-high)
892                     (not (and (fp-neg-zero-p domain-high)
893                               (fp-pos-zero-p arg-hi)))))))))
894
895 ;;; Elfun-Derive-Type-Simple
896 ;;; 
897 ;;; Handle monotonic functions of a single variable whose domain is
898 ;;; possibly part of the real line.  ARG is the variable, FCN is the
899 ;;; function, and DOMAIN is a specifier that gives the (real) domain
900 ;;; of the function.  If ARG is a subset of the DOMAIN, we compute the
901 ;;; bounds directly.  Otherwise, we compute the bounds for the
902 ;;; intersection between ARG and DOMAIN, and then append a complex
903 ;;; result, which occurs for the parts of ARG not in the DOMAIN.
904 ;;;
905 ;;; Negative and positive zero are considered distinct within
906 ;;; DOMAIN-LOW and DOMAIN-HIGH, as for the :negative-zero-is-not-zero
907 ;;; feature.
908 ;;;
909 ;;; DEFAULT-LOW and DEFAULT-HIGH are the lower and upper bounds if we
910 ;;; can't compute the bounds using FCN.
911 ;;;
912 (defun elfun-derive-type-simple (arg fcn domain-low domain-high
913                                      default-low default-high
914                                      &optional (increasingp t))
915   (declare (type (or null real) domain-low domain-high))
916   (etypecase arg
917     (numeric-type
918      (cond ((eq (numeric-type-complexp arg) :complex)
919             (complex-float-type arg))
920            ((numeric-type-real-p arg)
921             ;; The argument is real, so let's find the intersection
922             ;; between the argument and the domain of the function.
923             ;; We compute the bounds on the intersection, and for
924             ;; everything else, we return a complex number of the
925             ;; appropriate type.
926             (multiple-value-bind (intersection difference)
927                 (interval-intersection/difference
928                  (numeric-type->interval arg)
929                  (make-interval :low domain-low :high domain-high))
930               (cond
931                 (intersection
932                  ;; Process the intersection.
933                  (let* ((low (interval-low intersection))
934                         (high (interval-high intersection))
935                         (res-lo (or (bound-func fcn (if increasingp low high))
936                                     default-low))
937                         (res-hi (or (bound-func fcn (if increasingp high low))
938                                     default-high))
939                         ;; Result specifier type.
940                         (format (case (numeric-type-class arg)
941                                   ((integer rational) 'single-float)
942                                   (t (numeric-type-format arg))))
943                         (bound-type (or format 'float))
944                         (result-type 
945                          (make-numeric-type
946                           :class 'float
947                           :format format
948                           :low (coerce-numeric-bound res-lo bound-type)
949                           :high (coerce-numeric-bound res-hi bound-type))))
950                    ;; If the ARG is a subset of the domain, we don't
951                    ;; have to worry about the difference, because that
952                    ;; can't occur.
953                    (if (or (null difference)
954                            ;; Check if the arg is within the domain.
955                            (domain-subtypep arg domain-low domain-high))
956                        result-type
957                        (list result-type
958                              (specifier-type `(complex ,bound-type))))))
959                 (t
960                  ;; No intersection so the result must be purely complex.
961                  (complex-float-type arg)))))
962            (t
963             (float-or-complex-float-type arg default-low default-high))))))
964
965 (macrolet
966     ((frob (name domain-low domain-high def-low-bnd def-high-bnd
967                  &key (increasingp t))
968        (let ((num (gensym)))
969          `(defoptimizer (,name derive-type) ((,num))
970            (one-arg-derive-type
971             ,num
972             #'(lambda (arg)
973                 (elfun-derive-type-simple arg #',name
974                                           ,domain-low ,domain-high
975                                           ,def-low-bnd ,def-high-bnd
976                                           ,increasingp))
977             #',name)))))
978   ;; These functions are easy because they are defined for the whole
979   ;; real line.
980   (frob exp nil nil 0 nil)
981   (frob sinh nil nil nil nil)
982   (frob tanh nil nil -1 1)
983   (frob asinh nil nil nil nil)
984
985   ;; These functions are only defined for part of the real line.  The
986   ;; condition selects the desired part of the line.  
987   (frob asin -1d0 1d0 (- (/ pi 2)) (/ pi 2))
988   ;; Acos is monotonic decreasing, so we need to swap the function
989   ;; values at the lower and upper bounds of the input domain.
990   (frob acos -1d0 1d0 0 pi :increasingp nil)
991   (frob acosh 1d0 nil nil nil)
992   (frob atanh -1d0 1d0 -1 1)
993   ;; Kahan says that (sqrt -0.0) is -0.0, so use a specifier that
994   ;; includes -0.0.
995   (frob sqrt -0d0 nil 0 nil))
996  
997 ;;; Compute bounds for (expt x y).  This should be easy since (expt x
998 ;;; y) = (exp (* y (log x))).  However, computations done this way
999 ;;; have too much roundoff.  Thus we have to do it the hard way.
1000 ;;;  
1001 (defun safe-expt (x y)
1002   (handler-case
1003       (expt x y)
1004     (error ()
1005       nil)))
1006
1007 ;;; Handle the case when x >= 1
1008 (defun interval-expt-> (x y)
1009   (case (c::interval-range-info y 0d0)
1010     ('+
1011      ;; Y is positive and log X >= 0.  The range of exp(y * log(x)) is
1012      ;; obviously non-negative.  We just have to be careful for
1013      ;; infinite bounds (given by nil).
1014      (let ((lo (safe-expt (c::bound-value (c::interval-low x))
1015                           (c::bound-value (c::interval-low y))))
1016            (hi (safe-expt (c::bound-value (c::interval-high x))
1017                           (c::bound-value (c::interval-high y)))))
1018        (list (c::make-interval :low (or lo 1) :high hi))))
1019     ('-
1020      ;; Y is negative and log x >= 0.  The range of exp(y * log(x)) is
1021      ;; obviously [0, 1].  However, underflow (nil) means 0 is the
1022      ;; result
1023      (let ((lo (safe-expt (c::bound-value (c::interval-high x))
1024                           (c::bound-value (c::interval-low y))))
1025            (hi (safe-expt (c::bound-value (c::interval-low x))
1026                           (c::bound-value (c::interval-high y)))))
1027        (list (c::make-interval :low (or lo 0) :high (or hi 1)))))
1028     (t
1029      ;; Split the interval in half
1030      (destructuring-bind (y- y+)
1031          (c::interval-split 0 y t)
1032        (list (interval-expt-> x y-)
1033              (interval-expt-> x y+))))))
1034
1035 ;;; Handle the case when x < 0, and when y is known to be an integer.
1036 ;;; In this case, we can do something useful because the x^y is still
1037 ;;; a real number if x and y are.
1038 (defun interval-expt-<-0 (x y)
1039   #+(or)
1040   (progn
1041     (format t "x = ~A~%" x)
1042     (format t "range-info y (~A) = ~A~%" y (interval-range-info y)))
1043   (flet ((handle-positive-power-0 (x y)
1044            ;; -1 <= X <= 0 and Y is positive.  We need to consider if
1045            ;; Y contains an odd integer or not.  Find the smallest
1046            ;; even and odd integer (if possible) contained in Y.
1047            (let* ((y-lo (bound-value (interval-low y)))
1048                   (min-odd (if (oddp y-lo)
1049                                y-lo
1050                                (let ((y-odd (1+ y-lo)))
1051                                  (if (interval-contains-p y-odd y)
1052                                      y-odd
1053                                      nil))))
1054                   (min-even (if (evenp y-lo)
1055                                 y-lo
1056                                 (let ((y-even (1+ y-lo)))
1057                                   (if (interval-contains-p y-even y)
1058                                       y-even
1059                                       nil)))))
1060              (cond ((and min-odd min-even)
1061                     ;; The Y interval contains both even and odd
1062                     ;; integers.  Then the lower bound is (least
1063                     ;; x)^(least positive odd), because this
1064                     ;; creates the most negative value.  The upper
1065                     ;; is (most x)^(least positive even), because
1066                     ;; this is the most positive number.
1067                     ;;
1068                     ;; (Recall that if |x|<1, |x|^y gets smaller as y
1069                     ;; increases.)
1070                     (let ((lo (safe-expt (bound-value (interval-low x))
1071                                          min-odd))
1072                           (hi (safe-expt (bound-value (interval-high x))
1073                                          min-even)))
1074                       (list (make-interval :low lo :high hi))))
1075                    (min-odd
1076                     ;; Y consists of just one odd integer.
1077                     (assert (oddp min-odd))
1078                     (let ((lo (safe-expt (bound-value (interval-low x))
1079                                          min-odd))
1080                           (hi (safe-expt (bound-value (interval-high x))
1081                                          min-odd)))
1082                       (list (make-interval :low lo :high hi))))
1083                    (min-even
1084                     ;; Y consists of just one even integer.
1085                     (assert (evenp min-even))
1086                     (let ((lo (safe-expt (bound-value (interval-high x))
1087                                          min-even))
1088                           (hi (safe-expt (bound-value (interval-low x))
1089                                          min-even)))
1090                       (list (make-interval :low lo :high hi))))
1091                    (t
1092                     ;; No mininum even or odd integer, so Y has no
1093                     ;; lower bound
1094                     (list (make-interval :low nil :high nil))))))
1095          (handle-positive-power-1 (x y)
1096            ;; X <= -1, Y is a positive integer.  Find the largest even
1097            ;; and odd integer contained in Y, if possible.
1098            (let* ((y-hi (bound-value (interval-high y)))
1099                   (max-odd (if y-hi
1100                                (if (oddp y-hi)
1101                                    y-hi
1102                                    (let ((y-odd (1- y-hi)))
1103                                      (if (interval-contains-p y-odd y)
1104                                          y-odd
1105                                          nil)))
1106                                nil))
1107                   (max-even (if y-hi
1108                                 (if (evenp y-hi)
1109                                     y-hi
1110                                     (let ((y-even (1- y-hi)))
1111                                       (if (interval-contains-p y-even y)
1112                                           y-even
1113                                           nil)))
1114                                 nil)))
1115              ;; At least one of max-odd and max-even must be non-NIL!
1116              (cond ((and max-odd max-even)
1117                     ;; The Y interval contains both even and odd
1118                     ;; integers.  Then the lower bound is (least
1119                     ;; x)^(most positive odd), because this
1120                     ;; creates the most negative value.  The upper
1121                     ;; is (least x)^(most positive even), because
1122                     ;; this is the most positive number.
1123                     ;;
1124                     (let ((lo (safe-expt (bound-value (interval-low x))
1125                                          max-odd))
1126                           (hi (safe-expt (bound-value (interval-low x))
1127                                          max-even)))
1128                       (list (make-interval :low lo :high hi))))
1129                    (max-odd
1130                     ;; Y consists of just one odd integer.
1131                     (assert (oddp max-odd))
1132                     (let ((lo (safe-expt (bound-value (interval-low x))
1133                                          max-odd))
1134                           (hi (safe-expt (bound-value (interval-high x))
1135                                          max-odd)))
1136                       (list (make-interval :low lo :high hi))))
1137                    (max-even
1138                     ;; Y consists of just one even integer.
1139                     (assert (evenp max-even))
1140                     (let ((lo (safe-expt (bound-value (interval-high x))
1141                                          max-even))
1142                           (hi (safe-expt (bound-value (interval-low x))
1143                                          max-even)))
1144                       (list (make-interval :low lo :high hi))))
1145                    (t
1146                     ;; No maximum even or odd integer, which means y
1147                     ;; is no upper bound.
1148                     (list (make-interval :low nil :high nil)))))))
1149     ;; We need to split into x < -1 and -1 <= x <= 0, first.
1150     (case (interval-range-info x -1)
1151       ('+
1152        ;; -1 <= x <= 0
1153        #+(or)
1154        (format t "x range +~%")
1155        (case (interval-range-info y 0)
1156          ('+
1157           (handle-positive-power-0 x y))
1158          ('-
1159           ;; Y is negative.  We should do something better
1160           ;; than this because there's an extra rounding which
1161           ;; we shouldn't do.
1162           #+(or)
1163           (format t "Handle y neg~%")
1164           (let ((unit (make-interval :low 1 :high 1))
1165                 (result (handle-positive-power-0 x (interval-neg y))))
1166             #+(or)
1167             (format t "result = ~A~%" result)
1168             (mapcar #'(lambda (r)
1169                         (interval-div unit r))
1170                     result)))
1171          (t
1172           ;; Split the interval and try again.  Since we know y is an
1173           ;; integer, we don't need interval-split.  Also we want to
1174           ;; handle an exponent of 0 ourselves as a special case.
1175           (multiple-value-bind (y- y+)
1176               (values (make-interval :low (interval-low y)
1177                                      :high -1)
1178                       (make-interval :low 1
1179                                      :high (interval-high y)))
1180             (append (list (make-interval :low 1 :high 1))
1181                     (interval-expt-<-0 x y-)
1182                     (interval-expt-<-0 x y+))))))
1183       ('-
1184        ;; x < -1
1185        (case (c::interval-range-info y)
1186          ('+
1187           ;; Y is positive.  We need to consider if Y contains an
1188           ;; odd integer or not.
1189           ;;
1190           (handle-positive-power-1 x y))
1191          ('-
1192           ;; Y is negative.  Do this in a better way
1193           (let ((unit (make-interval :low 1 :high 1))
1194                 (result (handle-positive-power-1 x (interval-neg y))))
1195             (mapcar #'(lambda (r)
1196                         (interval-div unit r))
1197                     result)))
1198          (t
1199           ;; Split the interval and try again.
1200           #+(or)
1201           (format t "split y ~A~%" y)
1202           (multiple-value-bind (y- y+)
1203               (values (make-interval :low (interval-low y) :high -1)
1204                       (make-interval :low 1 :high (interval-high y)))
1205             (append (list (make-interval :low 1 :high 1))
1206                     (interval-expt-<-0 x y-)
1207                     (interval-expt-<-0 x y+))))))
1208       (t
1209        #+(or)
1210        (format t "splitting x ~A~%" x)
1211        (destructuring-bind (neg pos)
1212            (interval-split -1 x t t)
1213          (append (interval-expt-<-0 neg y)
1214                  (interval-expt-<-0 pos y)))))))
1215
1216 ;;; Handle the case when x <= 1
1217 (defun interval-expt-< (x y &optional integer-power-p)
1218   (case (c::interval-range-info x 0d0)
1219     ('+
1220      ;; The case of 0 <= x <= 1 is easy
1221      (case (c::interval-range-info y)
1222        ('+
1223         ;; Y is positive and log X <= 0.  The range of exp(y * log(x)) is
1224         ;; obviously [0, 1].  We just have to be careful for infinite bounds
1225         ;; (given by nil).
1226         (let ((lo (safe-expt (c::bound-value (c::interval-low x))
1227                              (c::bound-value (c::interval-high y))))
1228               (hi (safe-expt (c::bound-value (c::interval-high x))
1229                              (c::bound-value (c::interval-low y)))))
1230           ;; If the low bound, LO, is NIL, that means the we have
1231           ;; +0.0^inf, which is +0.0, but NIL is returned by
1232           ;; SAFE-EXPT.  That means the result is includes +0.0.  Make
1233           ;; it so by returning a member type and an exclusive
1234           ;; interval.
1235           (if lo
1236               (list (c::make-interval :low lo :high (or hi 1)))
1237               (list (c::make-interval :low (list 0) :high (or hi 1))
1238                     (c::make-member-type :members (list 0))))))
1239        ('-
1240         ;; Y is negative and log x <= 0.  The range of exp(y * log(x)) is
1241         ;; obviously [1, inf].
1242         (let ((hi (safe-expt (c::bound-value (c::interval-low x))
1243                              (c::bound-value (c::interval-low y))))
1244               (lo (safe-expt (c::bound-value (c::interval-high x))
1245                              (c::bound-value (c::interval-high y)))))
1246           (list (c::make-interval :low (or lo 1) :high hi))))
1247        (t
1248         ;; Split the interval in half
1249         (destructuring-bind (y- y+)
1250             (c::interval-split 0 y t)
1251           (list (interval-expt-< x y- integer-power-p)
1252                 (interval-expt-< x y+ integer-power-p))))))
1253     ('-
1254      ;; The case where x <= 0.
1255      (cond (integer-power-p
1256             (interval-expt-<-0 x y))
1257            (t
1258             ;; Y is not an integer.  Just give up and return an
1259             ;; unbounded interval.
1260             (list (c::make-interval :low nil :high nil)))))
1261     (t
1262      (destructuring-bind (neg pos)
1263          (interval-split 0 x t t)
1264        (append (interval-expt-< neg y integer-power-p)
1265                (interval-expt-< pos y integer-power-p))))))
1266
1267 ;;; Compute bounds for (expt x y)
1268
1269 (defun interval-expt (x y &optional integer-power-p)
1270   (case (interval-range-info x 1)
1271     ('+
1272      ;; X >= 1
1273          (interval-expt-> x y))
1274     ('-
1275      ;; X <= 1
1276      (interval-expt-< x y integer-power-p))
1277     (t
1278      (destructuring-bind (left right)
1279          (interval-split 1 x t t)
1280        (append (interval-expt left y integer-power-p)
1281                (interval-expt right y integer-power-p))))))
1282
1283 (defun fixup-interval-expt (bnd x-int y-int x-type y-type)
1284   (declare (ignore x-int))
1285   ;; Figure out what the return type should be, given the argument
1286   ;; types and bounds and the result type and bounds.
1287   (flet ((low-bnd (b)
1288            (etypecase b
1289              (member-type
1290               (reduce #'min (member-type-members b)))
1291              (interval
1292               (interval-low b))))
1293          (hi-bnd (b)
1294            (etypecase b
1295              (member-type
1296               (reduce #'max (member-type-members b)))
1297              (interval
1298               (interval-high b)))))
1299     (cond ((csubtypep x-type (specifier-type 'integer))
1300            ;; An integer to some power.  Cases to consider:
1301            (case (numeric-type-class y-type)
1302              (integer
1303               ;; Positive integer to an integer power is either an
1304               ;; integer or a rational.
1305               (let ((lo (or (low-bnd bnd) '*))
1306                     (hi (or (hi-bnd bnd) '*)))
1307                 (if (and (interval-low y-int)
1308                          (>= (bound-value (interval-low y-int)) 0))
1309                     (specifier-type `(integer ,lo ,hi))
1310                     (specifier-type `(rational ,lo ,hi)))))
1311              (rational
1312               ;; Positive integer to rational power is either a rational
1313               ;; or a single-float.
1314               (let* ((lo (low-bnd bnd))
1315                      (hi (hi-bnd bnd))
1316                      (int-lo (if lo
1317                                  (floor (bound-value lo))
1318                                  '*))
1319                      (int-hi (if hi
1320                                  (ceiling (bound-value hi))
1321                                  '*))
1322                      (f-lo (if lo
1323                                (bound-func #'float lo)
1324                                '*))
1325                      (f-hi (if hi
1326                                (bound-func #'float hi)
1327                                '*)))
1328                 (specifier-type `(or (rational ,int-lo ,int-hi)
1329                                      (single-float ,f-lo, f-hi)))))
1330              (float
1331               ;; Positive integer to a float power is a float of the
1332               ;; same type.
1333               (let* ((res (copy-numeric-type y-type))
1334                      (lo (low-bnd bnd))
1335                      (hi (hi-bnd bnd))
1336                      (f-lo (if lo
1337                                (coerce lo (numeric-type-format res))
1338                                nil))
1339                      (f-hi (if hi
1340                                (coerce hi (numeric-type-format res))
1341                                nil)))
1342                 (setf (numeric-type-low res) f-lo)
1343                 (setf (numeric-type-high res) f-hi)
1344                 res))
1345              (t
1346               ;; Positive integer to a number is a number (for now)
1347               (specifier-type 'number))))
1348           ((csubtypep x-type (specifier-type 'rational))
1349            ;; A rational to some power
1350            (case (numeric-type-class y-type)
1351              (integer
1352               ;; Positive rational to an integer power is always a rational
1353               (specifier-type `(rational ,(or (low-bnd bnd) '*)
1354                                          ,(or (hi-bnd bnd) '*))))
1355              (rational
1356               ;; Positive rational to rational power is either a rational
1357               ;; or a single-float.
1358               (let* ((lo (low-bnd bnd))
1359                      (hi (hi-bnd bnd))
1360                      (int-lo (if lo
1361                                  (floor (bound-value lo))
1362                                  '*))
1363                      (int-hi (if hi
1364                                  (ceiling (bound-value hi))
1365                                  '*))
1366                      (f-lo (if lo
1367                                (bound-func #'float lo)
1368                                '*))
1369                      (f-hi (if hi
1370                                (bound-func #'float hi)
1371                                '*)))
1372                 (specifier-type `(or (rational ,int-lo ,int-hi)
1373                                      (single-float ,f-lo, f-hi)))))
1374              (float
1375               ;; Positive rational to a float power is a float
1376               (let ((res (copy-numeric-type y-type)))
1377                 (setf (numeric-type-low res) (low-bnd bnd))
1378                 (setf (numeric-type-high res) (hi-bnd bnd))
1379                 res))
1380              (t
1381               ;; Positive rational to a number is a number (for now)
1382               (specifier-type 'number))))
1383           ((csubtypep x-type (specifier-type 'float))
1384            ;; A float to some power
1385            (flet ((make-result (type)
1386                     (let ((res-type (or type 'float)))
1387                       (etypecase bnd
1388                         (member-type
1389                          ;; Coerce all elements to the appropriate float
1390                          ;; type.
1391                          (make-member-type :members (mapcar #'(lambda (x)
1392                                                                 (coerce x res-type))
1393                                                             (member-type-members bnd))))
1394                         (interval
1395                          (make-numeric-type
1396                           :class 'float
1397                           :format type
1398                           :low (coerce-numeric-bound (low-bnd bnd) res-type)
1399                           :high (coerce-numeric-bound (hi-bnd bnd) res-type)))))))
1400              (case (numeric-type-class y-type)
1401                ((or integer rational)
1402                 ;; Positive float to an integer or rational power is always a float
1403                 (make-result (numeric-type-format x-type)))
1404                (float
1405                 ;; Positive float to a float power is a float of the higher type
1406                 (make-result (float-format-max (numeric-type-format x-type)
1407                                                (numeric-type-format y-type))))
1408                (t
1409                 ;; Positive float to a number is a number (for now)
1410                 (specifier-type 'number)))))
1411           (t
1412            ;; A number to some power is a number.
1413            (specifier-type 'number)))))
1414   
1415 (defun merged-interval-expt (x y &optional integer-power-p)
1416   (let* ((x-int (numeric-type->interval x))
1417          (y-int (numeric-type->interval y)))
1418     (mapcar #'(lambda (type)
1419                 (fixup-interval-expt type x-int y-int x y))
1420             (flatten-list (interval-expt x-int y-int integer-power-p)))))
1421
1422 (defun expt-derive-type-aux (x y same-arg)
1423   (declare (ignore same-arg))
1424   (cond ((or (not (numeric-type-real-p x))
1425              (not (numeric-type-real-p y)))
1426          ;; Use numeric contagion if either is not real
1427          (numeric-contagion x y))
1428         ((csubtypep y (specifier-type 'integer))
1429          ;; A real raised to an integer power is well-defined
1430          (merged-interval-expt x y t))
1431         (t
1432          ;; A real raised to a non-integral power is complicated....
1433          (cond ((or (csubtypep x (specifier-type '(rational 0)))
1434                     (csubtypep x (specifier-type '(float (0d0)))))
1435                 ;; A positive real to any power is well-defined.
1436                 (merged-interval-expt x y))
1437                ((and (csubtypep x (specifier-type 'rational))
1438                      (csubtypep x (specifier-type 'rational)))
1439                 ;; A rational to a rational power can be a rational or
1440                 ;; a single-float or a complex single-float.
1441                 (specifier-type '(or rational single-float (complex single-float))))
1442                (t
1443                 ;; A real to some power.  The result could be a real
1444                 ;; or a complex.
1445                 (float-or-complex-float-type (numeric-contagion x y)))))))
1446
1447 (defoptimizer (expt derive-type) ((x y))
1448   (two-arg-derive-type x y #'expt-derive-type-aux #'expt))
1449
1450
1451 ;;; Note must assume that a type including 0.0 may also include -0.0
1452 ;;; and thus the result may be complex -infinity + i*pi.
1453 ;;;
1454 (defun log-derive-type-aux-1 (x)
1455   (elfun-derive-type-simple x #'log 0d0 nil nil nil))
1456
1457 (defun log-derive-type-aux-2 (x y same-arg)
1458   (let ((log-x (log-derive-type-aux-1 x))
1459         (log-y (log-derive-type-aux-1 y))
1460         (result '()))
1461     ;; log-x or log-y might be union types.  We need to run through
1462     ;; the union types ourselves because /-derive-type-aux doesn't.
1463     (dolist (x-type (prepare-arg-for-derive-type log-x))
1464       (dolist (y-type (prepare-arg-for-derive-type log-y))
1465         (push (/-derive-type-aux x-type y-type same-arg) result)))
1466     (setf result (flatten-list result))
1467     (if (rest result)
1468         (make-union-type result)
1469         (first result))))
1470
1471 (defoptimizer (log derive-type) ((x &optional y))
1472   (if y
1473       (two-arg-derive-type x y #'log-derive-type-aux-2 #'log)
1474       (one-arg-derive-type x #'log-derive-type-aux-1 #'log)))
1475
1476
1477 (defun atan-derive-type-aux-1 (y)
1478   (elfun-derive-type-simple y #'atan nil nil (- (/ pi 2)) (/ pi 2)))
1479
1480 (defun atan-derive-type-aux-2 (y x same-arg)
1481   (declare (ignore same-arg))
1482   ;; The hard case with two args.  We just return the max bounds.
1483   (let ((result-type (numeric-contagion y x)))
1484     (cond ((and (numeric-type-real-p x)
1485                 (numeric-type-real-p y))
1486            (let* ((format (case (numeric-type-class result-type)
1487                             ((integer rational) 'single-float)
1488                             (t (numeric-type-format result-type))))
1489                   (bound-format (or format 'float)))
1490              (make-numeric-type :class 'float
1491                                 :format format
1492                                 :complexp :real
1493                                 :low (coerce (- pi) bound-format)
1494                                 :high (coerce pi bound-format))))
1495           (t
1496            ;; The result is a float or a complex number
1497            (float-or-complex-float-type result-type)))))
1498
1499 (defoptimizer (atan derive-type) ((y &optional x))
1500   (if x
1501       (two-arg-derive-type y x #'atan-derive-type-aux-2 #'atan)
1502       (one-arg-derive-type y #'atan-derive-type-aux-1 #'atan)))
1503
1504
1505 (defun cosh-derive-type-aux (x)
1506   ;; We note that cosh x = cosh |x| for all real x.
1507   (elfun-derive-type-simple
1508    (if (numeric-type-real-p x)
1509        (abs-derive-type-aux x)
1510        x)
1511    #'cosh nil nil 0 nil))
1512
1513 (defoptimizer (cosh derive-type) ((num))
1514   (one-arg-derive-type num #'cosh-derive-type-aux #'cosh))
1515
1516
1517 (defun phase-derive-type-aux (arg)
1518   (let* ((format (case (numeric-type-class arg)
1519                    ((integer rational) 'single-float)
1520                    (t (numeric-type-format arg))))
1521          (bound-type (or format 'float)))
1522     (cond ((numeric-type-real-p arg)
1523            (case (interval-range-info (numeric-type->interval arg) 0.0)
1524              ('+
1525               ;; The number is positive, so the phase is 0.
1526               (make-numeric-type :class 'float
1527                                  :format format
1528                                  :complexp :real
1529                                  :low (coerce 0 bound-type)
1530                                  :high (coerce 0 bound-type)))
1531              ('-
1532               ;; The number is always negative, so the phase is pi
1533               (make-numeric-type :class 'float
1534                                  :format format
1535                                  :complexp :real
1536                                  :low (coerce pi bound-type)
1537                                  :high (coerce pi bound-type)))
1538              (t
1539               ;; We can't tell.  The result is 0 or pi.  Use a union
1540               ;; type for this
1541               (list
1542                (make-numeric-type :class 'float
1543                                   :format format
1544                                   :complexp :real
1545                                   :low (coerce 0 bound-type)
1546                                   :high (coerce 0 bound-type))
1547                (make-numeric-type :class 'float
1548                                   :format format
1549                                   :complexp :real
1550                                   :low (coerce pi bound-type)
1551                                   :high (coerce pi bound-type))))))
1552           (t
1553            ;; We have a complex number.  The answer is the range -pi
1554            ;; to pi.  (-pi is included because we have -0.)
1555            (make-numeric-type :class 'float
1556                               :format format
1557                               :complexp :real
1558                               :low (coerce (- pi) bound-type)
1559                               :high (coerce pi bound-type))))))
1560
1561 (defoptimizer (phase derive-type) ((num))
1562   (one-arg-derive-type num #'phase-derive-type-aux #'phase))
1563
1564
1565 (deftransform realpart ((x) ((complex rational)) *)
1566   '(kernel:%realpart x))
1567 (deftransform imagpart ((x) ((complex rational)) *)
1568   '(kernel:%imagpart x))
1569
1570 ;;; Make REALPART and IMAGPART return the appropriate types.  This
1571 ;;; should help a lot in optimized code.
1572
1573 (defun realpart-derive-type-aux (type)
1574   (let ((class (numeric-type-class type))
1575         (format (numeric-type-format type)))
1576     (cond ((numeric-type-real-p type)
1577            ;; The realpart of a real has the same type and range as
1578            ;; the input.
1579            (make-numeric-type :class class
1580                               :format format
1581                               :complexp :real
1582                               :low (numeric-type-low type)
1583                               :high (numeric-type-high type)))
1584           (t
1585            ;; We have a complex number.  The result has the same type
1586            ;; as the real part, except that it's real, not complex,
1587            ;; obviously.
1588            (make-numeric-type :class class
1589                               :format format
1590                               :complexp :real
1591                               :low (numeric-type-low type)
1592                               :high (numeric-type-high type))))))
1593
1594 (defoptimizer (realpart derive-type) ((num))
1595   (one-arg-derive-type num #'realpart-derive-type-aux #'realpart))
1596
1597 (defun imagpart-derive-type-aux (type)
1598   (let ((class (numeric-type-class type))
1599         (format (numeric-type-format type)))
1600     (cond ((numeric-type-real-p type)
1601            ;; The imagpart of a real has the same type as the input,
1602            ;; except that it's zero
1603            (let ((bound-format (or format class 'real)))
1604              (make-numeric-type :class class
1605                                 :format format
1606                                 :complexp :real
1607                                 :low (coerce 0 bound-format)
1608                                 :high (coerce 0 bound-format))))
1609           (t
1610            ;; We have a complex number.  The result has the same type as
1611            ;; the imaginary part, except that it's real, not complex,
1612            ;; obviously.
1613            (make-numeric-type :class class
1614                               :format format
1615                               :complexp :real
1616                               :low (numeric-type-low type)
1617                               :high (numeric-type-high type))))))
1618
1619 (defoptimizer (imagpart derive-type) ((num))
1620   (one-arg-derive-type num #'imagpart-derive-type-aux #'imagpart))
1621
1622 (defun complex-derive-type-aux-1 (re-type)
1623   (if (numeric-type-p re-type)
1624       (make-numeric-type :class (numeric-type-class re-type)
1625                          :format (numeric-type-format re-type)
1626                          :complexp (if (csubtypep re-type
1627                                                   (specifier-type 'rational))
1628                                        :real
1629                                        :complex)
1630                          :low (numeric-type-low re-type)
1631                          :high (numeric-type-high re-type))
1632       (specifier-type 'complex)))
1633
1634 (defun complex-derive-type-aux-2 (re-type im-type same-arg)
1635   (declare (ignore same-arg))
1636   (if (and (numeric-type-p re-type)
1637            (numeric-type-p im-type))
1638       ;; Need to check to make sure numeric-contagion returns the
1639       ;; right type for what we want here.
1640       
1641       ;; Also, what about rational canonicalization, like (complex 5 0)
1642       ;; is 5?  So, if the result must be complex, we make it so.
1643       ;; If the result might be complex, which happens only if the
1644       ;; arguments are rational, we make it a union type of (or
1645       ;; rational (complex rational)).
1646       (let* ((element-type (numeric-contagion re-type im-type))
1647              (rat-result-p (csubtypep element-type
1648                                       (specifier-type 'rational))))
1649         (if rat-result-p
1650             (make-union-type
1651              (list element-type
1652                    (specifier-type 
1653                     `(complex ,(numeric-type-class element-type)))))
1654             (make-numeric-type :class (numeric-type-class element-type)
1655                                :format (numeric-type-format element-type)
1656                                :complexp (if rat-result-p
1657                                              :real
1658                                              :complex))))
1659       (specifier-type 'complex)))
1660
1661 (defoptimizer (complex derive-type) ((re &optional im))
1662   (if im
1663       (two-arg-derive-type re im #'complex-derive-type-aux-2 #'complex)
1664       (one-arg-derive-type re #'complex-derive-type-aux-1 #'complex)))
1665
1666
1667 ;;; Define some transforms for complex operations.  We do this in lieu
1668 ;;; of complex operation VOPs.  Some architectures have vops, though.
1669 ;;;
1670 (macrolet
1671     ((frob (type &optional (real-type type))
1672        ;; These are functions for which we normally would want to
1673        ;; write vops for.
1674        `(progn
1675           (deftransform %negate ((z) ((complex ,type)) *)
1676             ;; Negation
1677             '(complex (%negate (realpart z)) (%negate (imagpart z))))
1678           (deftransform + ((w z) ((complex ,type) (complex ,type)) *)
1679             ;; Complex + complex
1680             '(complex (+ (realpart w) (realpart z))
1681                       (+ (imagpart w) (imagpart z))))
1682           (deftransform - ((w z) ((complex ,type) (complex ,type)) *)
1683             ;; Complex - complex
1684             '(complex (- (realpart w) (realpart z))
1685                       (- (imagpart w) (imagpart z))))
1686           (deftransform + ((w z) ((complex ,type) ,real-type) *)
1687             ;; Complex + real
1688             '(complex (+ (realpart w) z) (+ 0 (imagpart w))))
1689           (deftransform - ((w z) ((complex ,type) ,real-type) *)
1690             ;; Complex - real
1691             '(complex (- (realpart w) z) (- (imagpart w) 0)))
1692           (deftransform * ((x y) ((complex ,type) (complex ,type)) *)
1693             ;; Complex * complex
1694             '(let* ((rx (realpart x))
1695                     (ix (imagpart x))
1696                     (ry (realpart y))
1697                     (iy (imagpart y)))
1698                (complex (- (* rx ry) (* ix iy))
1699                         (+ (* rx iy) (* ix ry)))))
1700           ;; SSE2 can use a special transform
1701           #-(and sse2 complex-fp-vops)
1702           (deftransform / ((x y) ((complex ,type) (complex ,type)) *
1703                            :policy (> speed space))
1704             ;; Complex / complex
1705             '(let* ((rx (realpart x))
1706                     (ix (imagpart x))
1707                     (ry (realpart y))
1708                     (iy (imagpart y)))
1709               (if (> (abs ry) (abs iy))
1710                   (let* ((r (/ iy ry))
1711                          (dn (+ ry (* r iy))))
1712                     (complex (/ (+ rx (* ix r)) dn)
1713                              (/ (- ix (* rx r)) dn)))
1714                   (let* ((r (/ ry iy))
1715                          (dn (+ iy (* r ry))))
1716                     (complex (/ (+ (* rx r) ix) dn)
1717                              (/ (- (* ix r) rx) dn))))))
1718           (deftransform * ((w z) ((complex ,type) ,real-type) *)
1719             ;; Complex*real
1720             '(complex (* (realpart w) z) (* (imagpart w) z)))
1721           (deftransform / ((w z) ((complex ,type) ,real-type) *)
1722             ;; Complex/real
1723             '(complex (/ (realpart w) z) (/ (imagpart w) z)))
1724           )))
1725
1726   #-complex-fp-vops
1727   (frob single-float)
1728   #-complex-fp-vops
1729   (frob double-float)
1730   #+double-double
1731   (frob double-double-float real))
1732
1733 (macrolet
1734     ((frob (type &optional (real-type type))
1735        ;; These are functions for which we probably wouldn't want to
1736        ;; write vops for.
1737        `(progn
1738          #-complex-fp-vops
1739          (deftransform conjugate ((z) ((complex ,type)) *)
1740            ;; Conjugate of complex number
1741            '(complex (realpart z) (- (imagpart z))))
1742          #-complex-fp-vops
1743          (deftransform - ((z w) (,real-type (complex ,type)) *)
1744            ;; Real - complex.  The 0 for the imaginary part is
1745            ;; needed so we get the correct signed zero.
1746            '(- (complex z (coerce 0 ',real-type)) w))
1747          #-complex-fp-vops
1748          (deftransform + ((z w) (,real-type (complex ,type)) *)
1749            ;; Real + complex.  The 0 for the imaginary part is
1750            ;; needed so we get the correct signed zero.
1751            '(+ (complex z (coerce 0 ',real-type)) w))
1752          #-complex-fp-vops
1753          (deftransform * ((z w) (,real-type (complex ,type)) *)
1754            ;; Real * complex
1755            '(complex (* z (realpart w)) (* z (imagpart w))))
1756          (deftransform cis ((z) ((,type)) *)
1757            ;; Cis.
1758            '(complex (cos z) (sin z)))
1759          (deftransform / ((rx y) (,real-type (complex ,type)) *)
1760            ;; Real/complex
1761            '(let* ((ry (realpart y))
1762                    (iy (imagpart y)))
1763              (if (> (abs ry) (abs iy))
1764                  (let* ((r (/ iy ry))
1765                         (dn (+ ry (* r iy))))
1766                    (complex (/ rx dn)
1767                             (/ (- (* rx r)) dn)))
1768                  (let* ((r (/ ry iy))
1769                         (dn (+ iy (* r ry))))
1770                    (complex (/ (* rx r) dn)
1771                             (/ (- rx) dn))))))
1772          ;; Comparison
1773          (deftransform = ((w z) ((complex ,type) (complex ,type)) *)
1774            '(and (= (realpart w) (realpart z))
1775                  (= (imagpart w) (imagpart z))))
1776          (deftransform = ((w z) ((complex ,type) ,type) *)
1777            '(and (= (realpart w) z) (zerop (imagpart w))))
1778          (deftransform = ((w z) (,type (complex ,type)) *)
1779            '(and (= (realpart z) w) (zerop (imagpart z))))
1780          )))
1781   (frob single-float)
1782   (frob double-float)
1783   #+double-double
1784   (frob double-double-float))
1785   
1786 #+(and sse2 complex-fp-vops)
1787 (macrolet
1788     ((frob (type one)
1789        `(deftransform / ((x y) (,type ,type) *
1790                          :policy (> speed space))
1791           ;; Divide a complex by a complex
1792
1793           ;; Here's how we do a complex division
1794           ;;
1795           ;; Compute (xr + i*xi)/(yr + i*yi)
1796           ;;
1797           ;; Assume |yi| < |yr|.  Then
1798           ;;
1799           ;; (xr + i*xi)      (xr + i*xi)
1800           ;; ----------- = -----------------
1801           ;; (yr + i*yi)   yr*(1 + i*(yi/yr))
1802           ;;
1803           ;;               (xr + i*xi)*(1 - i*(yi/yr))
1804           ;;             = ---------------------------
1805           ;;                   yr*(1 + (yi/yr)^2)
1806           ;;
1807           ;;               (xr + i*xi)*(1 - i*(yi/yr))
1808           ;;             = ---------------------------
1809           ;;                   yr + (yi/yr)*yi
1810           ;;
1811           ;; This allows us to use a fast complex multiply followed by
1812           ;; a real division.
1813           '(let* ((ry (realpart y))
1814                   (iy (imagpart y)))
1815             (if (> (abs ry) (abs iy))
1816                 (let* ((r (/ iy ry))
1817                        (dn (+ ry (* r iy))))
1818                   (/ (* x (complex ,one r))
1819                      dn))
1820                 (let* ((r (/ ry iy))
1821                        (dn (+ iy (* r ry))))
1822                   (/ (* x (complex r ,(- one)))
1823                      dn)))))))
1824   (frob (complex single-float) 1f0)
1825   (frob (complex double-float) 1d0))
1826
1827 ;;;; Complex contagion:
1828
1829 (progn
1830 ;;; COMPLEX-CONTAGION-ARG1, ARG2
1831 ;;;
1832 ;;;    Handles complex contagion of two complex numbers of different types.
1833 (deftransform complex-contagion-arg1 ((x y) * * :defun-only t :node node)
1834   ;;(format t "complex-contagion arg1~%")
1835   `(,(continuation-function-name (basic-combination-fun node))
1836     (coerce x ',(type-specifier (continuation-type y))) y))
1837 ;;;
1838 (deftransform complex-contagion-arg2 ((x y) * * :defun-only t :node node)
1839   ;;(format t "complex-contagion arg2~%")
1840   `(,(continuation-function-name (basic-combination-fun node))
1841     x (coerce y ',(type-specifier (continuation-type x)))))
1842
1843 (dolist (x '(= + * / -))
1844   (%deftransform x '(function ((complex single-float) (complex double-float)) *)
1845                  #'complex-contagion-arg1)
1846   (%deftransform x '(function ((complex double-float) (complex single-float)) *)
1847                  #'complex-contagion-arg2))
1848
1849 ;;; COMPLEX-REAL-CONTAGION-ARG1, ARG2
1850 ;;;
1851 ;;;   Handles the case of mixed complex and real numbers.  We assume
1852 ;;; the real number doesn't cause complex number to increase in
1853 ;;; precision.
1854 (deftransform complex-real-contagion-arg1 ((x y) * * :defun-only t :node node)
1855   ;;(format t "complex-real-contagion-arg1~%")
1856   `(,(continuation-function-name (basic-combination-fun node))
1857      (coerce x ',(numeric-type-format (continuation-type y)))
1858      y))
1859 ;;;
1860 (deftransform complex-real-contagion-arg2 ((x y) * * :defun-only t :node node)
1861   ;;(format t "complex-real-contagion-arg2~%")
1862   `(,(continuation-function-name (basic-combination-fun node))
1863      x
1864      (coerce y ',(numeric-type-format (continuation-type x)))))
1865
1866
1867 (dolist (x '(= + * / -))
1868   (%deftransform x '(function ((or rational single-float) (complex double-float)) *)
1869                  #'complex-real-contagion-arg1)
1870   (%deftransform x '(function ((complex double-float) (or rational single-float)) *)
1871                  #'complex-real-contagion-arg2)
1872   (%deftransform x '(function (rational (complex single-float)) *)
1873                  #'complex-real-contagion-arg1)
1874   (%deftransform x '(function ((complex single-float) rational) *)
1875                  #'complex-real-contagion-arg2))
1876
1877 ;;; UPGRADED-COMPLEX-REAL-CONTAGION-ARG1, ARG2
1878 ;;;
1879 ;;;   Handles the case of mixed complex and real numbers.  We assume
1880 ;;; the real number is more precise than the complex, so that the
1881 ;;; complex number needs to be coerced to a more precise complex.
1882 (deftransform upgraded-complex-real-contagion-arg1 ((x y) * * :defun-only t :node node)
1883   ;;(format t "upgraded-complex-real-contagion-arg1~%")
1884   `(,(continuation-function-name (basic-combination-fun node))
1885      (coerce x '(complex ,(type-specifier (continuation-type y))))
1886      y))
1887 ;;;
1888 (deftransform upgraded-complex-real-contagion-arg2 ((x y) * * :defun-only t :node node)
1889   #+nil
1890   (format t "upgraded-complex-real-contagion-arg2: ~A ~A~%"
1891           (continuation-type x) (continuation-type y))
1892   `(,(continuation-function-name (basic-combination-fun node))
1893      x
1894      (coerce y '(complex ,(type-specifier (continuation-type x))))))
1895
1896
1897 (dolist (x '(= + * / -))
1898   (%deftransform x '(function ((or (complex single-float) (complex rational))
1899                                double-float) *)
1900                  #'upgraded-complex-real-contagion-arg1)
1901   (%deftransform x '(function (double-float
1902                                (or (complex single-float) (complex rational))) *)
1903                  #'upgraded-complex-real-contagion-arg2))
1904 )
1905 \f
1906 ;;; Here are simple optimizers for sin, cos, and tan.  They do not
1907 ;;; produce a minimal range for the result; the result is the widest
1908 ;;; possible answer.  This gets around the problem of doing range
1909 ;;; reduction correctly but still provides useful results when the
1910 ;;; inputs are union types.
1911
1912 (defun trig-derive-type-aux (arg domain fcn
1913                                  &optional def-lo def-hi (increasingp t))
1914   (etypecase arg
1915     (numeric-type
1916      (cond ((eq (numeric-type-complexp arg) :complex)
1917             (complex-float-type arg))
1918            ((numeric-type-real-p arg)
1919             (let* ((format (case (numeric-type-class arg)
1920                              ((integer rational) 'single-float)
1921                              (t (numeric-type-format arg))))
1922                    (bound-type (or format 'float)))
1923               ;; If the argument is a subset of the "principal" domain
1924               ;; of the function, we can compute the bounds because
1925               ;; the function is monotonic.  We can't do this in
1926               ;; general for these periodic functions because we can't
1927               ;; (and don't want to) do the argument reduction in
1928               ;; exactly the same way as the functions themselves do
1929               ;; it.
1930               (if (csubtypep arg domain)
1931                   (let ((res-lo (bound-func fcn (numeric-type-low arg)))
1932                         (res-hi (bound-func fcn (numeric-type-high arg))))
1933                     (unless increasingp
1934                       (rotatef res-lo res-hi))
1935                     (make-numeric-type
1936                      :class 'float
1937                      :format format
1938                      :low (coerce-numeric-bound res-lo bound-type)
1939                      :high (coerce-numeric-bound res-hi bound-type)))
1940                   (make-numeric-type
1941                    :class 'float
1942                    :format format
1943                    :low (and def-lo (coerce def-lo bound-type))
1944                    :high (and def-hi (coerce def-hi bound-type))))))
1945            (t
1946             (float-or-complex-float-type arg def-lo def-hi))))))
1947
1948 (defoptimizer (sin derive-type) ((num))
1949   (one-arg-derive-type
1950    num
1951    #'(lambda (arg)
1952        ;; Derive the bounds if the arg is in [-pi/2, pi/2]
1953        (trig-derive-type-aux
1954         arg
1955         (specifier-type `(float ,(- (/ pi 2)) ,(/ pi 2)))
1956         #'sin
1957         -1 1))
1958    #'sin))
1959        
1960 (defoptimizer (cos derive-type) ((num))
1961   (one-arg-derive-type
1962    num
1963    #'(lambda (arg)
1964        ;; Derive the bounds if the arg is in [0, pi]
1965        (trig-derive-type-aux arg
1966                              (specifier-type `(float 0d0 ,pi))
1967                              #'cos
1968                              -1 1
1969                              nil))
1970    #'cos))
1971
1972 (defoptimizer (tan derive-type) ((num))
1973   (one-arg-derive-type
1974    num
1975    #'(lambda (arg)
1976        ;; Derive the bounds if the arg is in [-pi/2, pi/2]
1977        (trig-derive-type-aux arg
1978                              (specifier-type `(float ,(- (/ pi 2)) ,(/ pi 2)))
1979                              #'tan
1980                              nil nil))
1981    #'tan))
1982
1983 ;;; conjugate always returns the same type as the input type  
1984 (defoptimizer (conjugate derive-type) ((num))
1985   (continuation-type num))
1986
1987 (defoptimizer (cis derive-type) ((num))
1988   (one-arg-derive-type num
1989      #'(lambda (arg)
1990          (specifier-type `(complex ,(or (numeric-type-format arg) 'float))))
1991      #'cis))
1992
1993 \f
1994 ;;; Support for double-double floats
1995 ;;;
1996 ;;; The algorithms contained herein are based on the code written by
1997 ;;; Yozo Hida.  See http://www.cs.berkeley.edu/~yozo/ for more
1998 ;;; information.
1999
2000 #+double-double
2001 (progn
2002   
2003 (declaim (inline quick-two-sum))
2004 (defun quick-two-sum (a b)
2005   "Computes fl(a+b) and err(a+b), assuming |a| >= |b|"
2006   (declare (double-float a b))
2007   (let* ((s (+ a b))
2008          (e (- b (- s a))))
2009     (values s e)))
2010
2011 (declaim (inline two-sum))
2012 (defun two-sum (a b)
2013   "Computes fl(a+b) and err(a+b)"
2014   (declare (double-float a b))
2015   (let* ((s (+ a b))
2016          (v (- s a))
2017          (e (+ (- a (- s v))
2018                (- b v))))
2019     (locally
2020         (declare (optimize (inhibit-warnings 3)))
2021       (values s e))))
2022
2023 (declaim (maybe-inline add-dd))
2024 (defun add-dd (a0 a1 b0 b1)
2025   "Add the double-double A0,A1 to the double-double B0,B1"
2026   (declare (double-float a0 a1 b0 b1)
2027            (optimize (speed 3)
2028                      (inhibit-warnings 3)))
2029   (multiple-value-bind (s1 s2)
2030       (two-sum a0 b0)
2031     (declare (double-float s1 s2))
2032     (when (float-infinity-p s1)
2033       (return-from add-dd (values s1 0d0)))
2034     (multiple-value-bind (t1 t2)
2035         (two-sum a1 b1)
2036       (declare (double-float t1 t2))
2037       (incf s2 t1)
2038       (multiple-value-bind (s1 s2)
2039           (quick-two-sum s1 s2)
2040         (declare (double-float s1 s2))
2041         (incf s2 t2)
2042         (multiple-value-bind (r1 r2)
2043             (quick-two-sum s1 s2)
2044           (if (and (zerop a0) (zerop b0))
2045               ;; Handle sum of signed zeroes here.
2046               (values (float-sign (+ a0 b0) 0d0)
2047                       0d0)
2048               (values r1 r2)))))))
2049
2050 (deftransform + ((a b) (vm::double-double-float vm::double-double-float)
2051                  * :node node)
2052   `(multiple-value-bind (hi lo)
2053        (add-dd (kernel:double-double-hi a) (kernel:double-double-lo a)
2054                (kernel:double-double-hi b) (kernel:double-double-lo b))
2055      (truly-the ,(type-specifier (node-derived-type node))
2056                 (kernel:%make-double-double-float hi lo))))
2057
2058 (declaim (inline quick-two-diff))
2059 (defun quick-two-diff (a b)
2060   "Compute fl(a-b) and err(a-b), assuming |a| >= |b|"
2061   (declare (double-float a b))
2062   (let ((s (- a b)))
2063     (values s (- (- a s) b))))
2064
2065 (declaim (inline two-diff))
2066 (defun two-diff (a b)
2067   "Compute fl(a-b) and err(a-b)"
2068   (declare (double-float a b))
2069   (let* ((s (- a b))
2070          (v (- s a))
2071          (e (- (- a (- s v))
2072                (+ b v))))
2073     (locally
2074         (declare (optimize (inhibit-warnings 3)))
2075       (values s e))))
2076
2077 (declaim (maybe-inline sub-dd))
2078 (defun sub-dd (a0 a1 b0 b1)
2079   "Subtract the double-double B0,B1 from A0,A1"
2080   (declare (double-float a0 a1 b0 b1)
2081            (optimize (speed 3)
2082                      (inhibit-warnings 3)))
2083   (multiple-value-bind (s1 s2)
2084       (two-diff a0 b0)
2085     (declare (double-float s2))
2086     (when (float-infinity-p s1)
2087       (return-from sub-dd (values s1 0d0)))
2088     (multiple-value-bind (t1 t2)
2089         (two-diff a1 b1)
2090       (incf s2 t1)
2091       (multiple-value-bind (s1 s2)
2092           (quick-two-sum s1 s2)
2093         (declare (double-float s2))
2094         (incf s2 t2)
2095         (multiple-value-bind (r1 r2)
2096             (quick-two-sum s1 s2)
2097           (if (and (zerop a0) (zerop b0))
2098               (values (float-sign (- a0 b0) 0d0)
2099                       0d0)
2100               (values r1 r2)))))))
2101
2102 (declaim (maybe-inline sub-d-dd))
2103 (defun sub-d-dd (a b0 b1)
2104   "Compute double-double = double - double-double"
2105   (declare (double-float a b0 b1)
2106            (optimize (speed 3) (safety 0)
2107                      (inhibit-warnings 3)))
2108   (multiple-value-bind (s1 s2)
2109       (two-diff a b0)
2110     (declare (double-float s2))
2111     (when (float-infinity-p s1)
2112       (return-from sub-d-dd (values s1 0d0)))
2113     (decf s2 b1)
2114     (multiple-value-bind (r1 r2)
2115         (quick-two-sum s1 s2)
2116       (if (and (zerop a) (zerop b0))
2117         (values (float-sign (- a b0) 0d0) 0d0)
2118         (values r1 r2)))))
2119
2120 (declaim (maybe-inline sub-dd-d))
2121 (defun sub-dd-d (a0 a1 b)
2122   "Subtract the double B from the double-double A0,A1"
2123   (declare (double-float a0 a1 b)
2124            (optimize (speed 3) (safety 0)
2125                      (inhibit-warnings 3)))
2126   (multiple-value-bind (s1 s2)
2127       (two-diff a0 b)
2128     (declare (double-float s2))
2129     (when (float-infinity-p s1)
2130       (return-from sub-dd-d (values s1 0d0)))
2131     (incf s2 a1)
2132     (multiple-value-bind (r1 r2)
2133         (quick-two-sum s1 s2)
2134       (if (and (zerop a0) (zerop b))
2135         (values (float-sign (- a0 b) 0d0) 0d0)
2136         (values r1 r2)))))
2137
2138 (deftransform - ((a b) (vm::double-double-float vm::double-double-float)
2139                  * :node node)
2140   `(multiple-value-bind (hi lo)
2141       (sub-dd (kernel:double-double-hi a) (kernel:double-double-lo a)
2142               (kernel:double-double-hi b) (kernel:double-double-lo b))
2143      (truly-the ,(type-specifier (node-derived-type node))
2144                 (kernel:%make-double-double-float hi lo))))
2145
2146 (deftransform - ((a b) (double-float vm::double-double-float)
2147                  * :node node)
2148   `(multiple-value-bind (hi lo)
2149        (sub-d-dd a
2150                  (kernel:double-double-hi b) (kernel:double-double-lo b))
2151      (truly-the ,(type-specifier (node-derived-type node))
2152                 (kernel:%make-double-double-float hi lo))))
2153
2154 (deftransform - ((a b) (vm::double-double-float double-float)
2155                  * :node node)
2156   `(multiple-value-bind (hi lo)
2157        (sub-dd-d (kernel:double-double-hi a) (kernel:double-double-lo a)
2158                  b)
2159      (truly-the ,(type-specifier (node-derived-type node))
2160                 (kernel:%make-double-double-float hi lo))))
2161
2162 (declaim (maybe-inline split))
2163 ;; This algorithm is the version given by Yozo Hida.  It has problems
2164 ;; with overflow because we multiply by 1+2^27.
2165 ;;
2166 ;; But be very careful about replacing this with a new algorithm.  The
2167 ;; values computed here are very important to get the rounding right.
2168 ;; If you change this, the rounding may be different, which will
2169 ;; affect other parts of the algorithm.
2170 ;;
2171 ;; I (rtoy) tried a different algorithm that split the number in two
2172 ;; as described, but without overflow.  However, that caused
2173 ;; -9.4294948327242751340284975915175w0/1w14 to return a value that
2174 ;; wasn't really close to -9.4294948327242751340284975915175w-14.
2175 ;;
2176 ;; This also means we can't print numbers like 1w308 with the current
2177 ;; printing algorithm, or even divide 1w308 by 10.
2178 #+nil
2179 (defun split (a)
2180   "Split the double-float number a into a-hi and a-lo such that a =
2181   a-hi + a-lo and a-hi contains the upper 26 significant bits of a and
2182   a-lo contains the lower 26 bits."
2183   (declare (double-float a))
2184   (let* ((tmp (* a (+ 1 (expt 2 27))))
2185          (a-hi (- tmp (- tmp a)))
2186          (a-lo (- a a-hi)))
2187     (values a-hi a-lo)))
2188
2189 ;; +split-limit+ is the largest number for which Yozo's algorithm
2190 ;; still works.  Basically we want a*(1+2^27) <=
2191 ;; most-positive-double-float < 2^1024. Therefore, a < 2^1024/(1+2^27)
2192 ;; If we calculate that, we get a = 1.3393857490036326d300.  A quick
2193 ;; test shows that this would cause overflow, but previous float would
2194 ;; not.  This is the value we want.
2195 (defconstant +split-limit+
2196   (scale-float (/ (float (1+ (expt 2 27)) 1d0)) 1024))
2197
2198 (defun split (a)
2199   "Split the double-float number a into a-hi and a-lo such that a =
2200   a-hi + a-lo and a-hi contains the upper 26 significant bits of a and
2201   a-lo contains the lower 26 bits."
2202   (declare (double-float a)
2203            (optimize (speed 3)
2204                      (inhibit-warnings 3)))
2205   ;; This splits the number a into 2 parts of 27 and 26 bits each, but
2206   ;; the parts are, I think, supposed to be properly rounded in an
2207   ;; IEEE fashion.
2208   ;;
2209   ;; For numbers that are very large, we use a different algorithm.
2210   ;; For smaller numbers, we can use the original algorithm of Yozo
2211   ;; Hida.
2212   (if (>= (abs a) +split-limit+)
2213       ;; I've tested this algorithm against Yozo's method for 1
2214       ;; billion randomly generated double-floats between 2^(-995) and
2215       ;; 2^996, and identical results are obtained.  For numbers that
2216       ;; are very small, this algorithm produces different numbers
2217       ;; because of underflow.  For very large numbers, we, of course
2218       ;; produce different results because Yozo's method causes
2219       ;; overflow.
2220       (let* ((tmp (* a (+ 1 (scale-float 1d0 -27))))
2221              (as (* a (scale-float 1d0 -27)))
2222              (a-hi (* (- tmp (- tmp as)) (expt 2 27)))
2223              (a-lo (- a a-hi)))
2224         (values a-hi a-lo))
2225       ;; Yozo's algorithm.
2226       (let* ((tmp (* a (+ 1 (expt 2 27))))
2227              (a-hi (- tmp (- tmp a)))
2228              (a-lo (- a a-hi)))
2229         (values a-hi a-lo))))
2230
2231
2232 (declaim (inline two-prod))
2233 #-ppc
2234 (defun two-prod (a b)
2235   _N"Compute fl(a*b) and err(a*b)"
2236   (declare (double-float a b))
2237   (let ((p (* a b)))
2238     (multiple-value-bind (a-hi a-lo)
2239         (split a)
2240       ;;(format t "a-hi, a-lo = ~S ~S~%" a-hi a-lo)
2241       (multiple-value-bind (b-hi b-lo)
2242           (split b)
2243         ;;(format t "b-hi, b-lo = ~S ~S~%" b-hi b-lo)
2244         (let ((e (+ (+ (- (* a-hi b-hi) p)
2245                        (* a-hi b-lo)
2246                        (* a-lo b-hi))
2247                     (* a-lo b-lo))))
2248           (locally 
2249               (declare (optimize (inhibit-warnings 3)))
2250             (values p e)))))))
2251
2252 #+ppc
2253 (defun two-prod (a b)
2254   _N"Compute fl(a*b) and err(a*b)"
2255   (declare (double-float a b))
2256   ;; PPC has a fused multiply-subtract instruction that can be used
2257   ;; here, so use it.
2258   (let* ((p (* a b))
2259          (err (vm::fused-multiply-subtract a b p)))
2260     (values p err)))
2261
2262 (declaim (inline two-sqr))
2263 #-ppc
2264 (defun two-sqr (a)
2265   _N"Compute fl(a*a) and err(a*b).  This is a more efficient
2266   implementation of two-prod"
2267   (declare (double-float a))
2268   (let ((q (* a a)))
2269     (multiple-value-bind (a-hi a-lo)
2270         (split a)
2271       (locally
2272           (declare (optimize (inhibit-warnings 3)))
2273         (values q (+ (+ (- (* a-hi a-hi) q)
2274                         (* 2 a-hi a-lo))
2275                      (* a-lo a-lo)))))))
2276
2277 #+ppc
2278 (defun two-sqr (a)
2279   _N"Compute fl(a*a) and err(a*b).  This is a more efficient
2280   implementation of two-prod"
2281   (declare (double-float a))
2282   (let ((q (* a a)))
2283     (values q (vm::fused-multiply-subtract a a q))))
2284
2285 (declaim (maybe-inline mul-dd-d))
2286 (defun mul-dd-d (a0 a1 b)
2287   (declare (double-float a0 a1 b)
2288            (optimize (speed 3)
2289                      (inhibit-warnings 3)))
2290   (multiple-value-bind (p1 p2)
2291       (two-prod a0 b)
2292     (declare (double-float p2))
2293     (when (float-infinity-p p1)
2294       (return-from mul-dd-d (values p1 0d0)))
2295     ;;(format t "mul-dd-d p1,p2 = ~A ~A~%" p1 p2)
2296     (incf p2 (* a1 b))
2297     ;;(format t "mul-dd-d p2 = ~A~%" p2)
2298     (multiple-value-bind (r1 r2)
2299         (quick-two-sum p1 p2)
2300       (when (zerop r1)
2301         (setf r1 (float-sign p1 0d0))
2302         (setf r2 p1))
2303       (values r1 r2))))
2304
2305 (declaim (maybe-inline mul-dd))
2306 (defun mul-dd (a0 a1 b0 b1)
2307   "Multiply the double-double A0,A1 with B0,B1"
2308   (declare (double-float a0 a1 b0 b1)
2309            (optimize (speed 3)
2310                      (inhibit-warnings 3)))
2311   (multiple-value-bind (p1 p2)
2312       (two-prod a0 b0)
2313     (declare (double-float p1 p2))
2314     (when (float-infinity-p p1)
2315       (return-from mul-dd (values p1 0d0)))
2316     (incf p2 (* a0 b1))
2317     (incf p2 (* a1 b0))
2318     (multiple-value-bind (r1 r2)
2319         (quick-two-sum p1 p2)
2320       (if (zerop r1)
2321         (values (float-sign p1 0d0) 0d0)
2322         (values r1 r2)))))
2323
2324 (declaim (maybe-inline add-dd-d))
2325 (defun add-dd-d (a0 a1 b)
2326   "Add the double-double A0,A1 to the double B"
2327   (declare (double-float a0 a1 b)
2328            (optimize (speed 3)
2329                      (inhibit-warnings 3)))
2330   (multiple-value-bind (s1 s2)
2331       (two-sum a0 b)
2332     (declare (double-float s1 s2))
2333     (when (float-infinity-p s1)
2334       (return-from add-dd-d (values s1 0d0)))
2335     (incf s2 a1)
2336     (multiple-value-bind (r1 r2)
2337         (quick-two-sum s1 s2)
2338       (if (and (zerop a0) (zerop b))
2339         (values (float-sign (+ a0 b) 0d0) 0d0)
2340         (values r1 r2)))))
2341
2342 (declaim (maybe-inline sqr-dd))
2343 (defun sqr-dd (a0 a1)
2344   (declare (double-float a0 a1)
2345            (optimize (speed 3)
2346                      (inhibit-warnings 3)))
2347   (multiple-value-bind (p1 p2)
2348       (two-sqr a0)
2349     (declare (double-float p1 p2))
2350     (incf p2 (* 2 a0 a1))
2351     ;; Hida's version of sqr (qd-2.1.210) has the following line for
2352     ;; the sqr function.  But if you compare this with mul-dd, this
2353     ;; doesn't exist there, and if you leave it in, it produces
2354     ;; results that are different from using mul-dd to square a value.
2355     #+nil
2356     (incf p2 (* a1 a1))
2357     (quick-two-sum p1 p2)))
2358
2359 (deftransform + ((a b) (vm::double-double-float (or integer single-float double-float))
2360                  * :node node)
2361   `(multiple-value-bind (hi lo)
2362        (add-dd-d (kernel:double-double-hi a) (kernel:double-double-lo a)
2363                  (float b 1d0))
2364      (truly-the ,(type-specifier (node-derived-type node))
2365                 (kernel:%make-double-double-float hi lo))))
2366
2367 (deftransform + ((a b) ((or integer single-float double-float) vm::double-double-float)
2368                  * :node node)
2369   `(multiple-value-bind (hi lo)
2370       (add-dd-d (kernel:double-double-hi b) (kernel:double-double-lo b)
2371                 (float a 1d0))
2372      (truly-the ,(type-specifier (node-derived-type node))
2373                 (kernel:%make-double-double-float hi lo))))
2374
2375 (deftransform * ((a b) (vm::double-double-float vm::double-double-float)
2376                  * :node node)
2377   ;; non-const-same-leaf-ref-p is stolen from two-arg-derive-type.
2378   (flet ((non-const-same-leaf-ref-p (x y)
2379            ;; Just like same-leaf-ref-p, but we don't care if the
2380            ;; value of the leaf is constant or not.
2381            (declare (type continuation x y))
2382            (let ((x-use (continuation-use x))
2383                  (y-use (continuation-use y)))
2384              (and (ref-p x-use)
2385                   (ref-p y-use)
2386                   (eq (ref-leaf x-use) (ref-leaf y-use))))))
2387     (destructuring-bind (arg1 arg2)
2388         (combination-args node)
2389       ;; If the two args to * are the same, we square the number
2390       ;; instead of multiply.  Squaring is simpler than a full
2391       ;; multiply.
2392       (if (non-const-same-leaf-ref-p arg1 arg2)
2393           `(multiple-value-bind (hi lo)
2394                (sqr-dd (kernel:double-double-hi a) (kernel:double-double-lo a))
2395              (truly-the ,(type-specifier (node-derived-type node))
2396                         (kernel:%make-double-double-float hi lo)))
2397           `(multiple-value-bind (hi lo)
2398                (mul-dd (kernel:double-double-hi a) (kernel:double-double-lo a)
2399                        (kernel:double-double-hi b) (kernel:double-double-lo b))
2400              (truly-the ,(type-specifier (node-derived-type node))
2401                         (kernel:%make-double-double-float hi lo)))))))
2402
2403 (deftransform * ((a b) (vm::double-double-float (or integer single-float double-float))
2404                  * :node node)
2405   `(multiple-value-bind (hi lo)
2406        (mul-dd-d (kernel:double-double-hi a) (kernel:double-double-lo a)
2407                  (float b 1d0))
2408      (truly-the ,(type-specifier (node-derived-type node))
2409                 (kernel:%make-double-double-float hi lo))))
2410
2411 (deftransform * ((a b) ((or integer single-float double-float) vm::double-double-float)
2412                  * :node node)
2413   `(multiple-value-bind (hi lo)
2414        (mul-dd-d (kernel:double-double-hi b) (kernel:double-double-lo b)
2415                  (float a 1d0))
2416      (truly-the ,(type-specifier (node-derived-type node))
2417                 (kernel:%make-double-double-float hi lo))))
2418
2419 (declaim (maybe-inline div-dd))
2420 (defun div-dd (a0 a1 b0 b1)
2421   "Divide the double-double A0,A1 by B0,B1"
2422   (declare (double-float a0 a1 b0 b1)
2423            (optimize (speed 3)
2424                      (inhibit-warnings 3))
2425            (inline sub-dd))
2426   (let ((q1 (/ a0 b0)))
2427     (when (float-infinity-p q1)
2428       (return-from div-dd (values q1 0d0)))
2429     ;; (q1b0, q1b1) = q1*(b0,b1)
2430     ;;(format t "q1 = ~A~%" q1)
2431     (multiple-value-bind (q1b0 q1b1)
2432         (mul-dd-d b0 b1 q1)
2433       ;;(format t "q1*b = ~A ~A~%" q1b0 q1b1)
2434       (multiple-value-bind (r0 r1)
2435           ;; r = a - q1 * b
2436           (sub-dd a0 a1 q1b0 q1b1)
2437         ;;(format t "r = ~A ~A~%" r0 r1)
2438         (let ((q2 (/ r0 b0)))
2439           (multiple-value-bind (q2b0 q2b1)
2440               (mul-dd-d b0 b1 q2)
2441             (multiple-value-bind (r0 r1)
2442                 ;; r = r - (q2*b)
2443                 (sub-dd r0 r1 q2b0 q2b1)
2444               (declare (ignore r1))
2445               (let ((q3 (/ r0 b0)))
2446                 (multiple-value-bind (q1 q2)
2447                     (quick-two-sum q1 q2)
2448                   (add-dd-d q1 q2 q3))))))))))
2449
2450 (declaim (maybe-inline div-dd-d))
2451 (defun div-dd-d (a0 a1 b)
2452   (declare (double-float a0 a1 b)
2453            (optimize (speed 3)
2454                      (inhibit-warnings 3)))
2455   (let ((q1 (/ a0 b)))
2456     ;; q1 = approx quotient
2457     ;; Now compute a - q1 * b
2458     (multiple-value-bind (p1 p2)
2459         (two-prod q1 b)
2460       (multiple-value-bind (s e)
2461           (two-diff a0 p1)
2462         (declare (double-float e))
2463         (incf e a1)
2464         (decf e p2)
2465         ;; Next approx
2466         (let ((q2 (/ (+ s e) b)))
2467           (quick-two-sum q1 q2))))))
2468
2469 (deftransform / ((a b) (vm::double-double-float vm::double-double-float)
2470                  * :node node)
2471   `(multiple-value-bind (hi lo)
2472       (div-dd (kernel:double-double-hi a) (kernel:double-double-lo a)
2473               (kernel:double-double-hi b) (kernel:double-double-lo b))
2474      (truly-the ,(type-specifier (node-derived-type node))
2475                 (kernel:%make-double-double-float hi lo))))
2476
2477 (deftransform / ((a b) (vm::double-double-float (or integer single-float double-float))
2478                  * :node node)
2479   `(multiple-value-bind (hi lo)
2480        (div-dd-d (kernel:double-double-hi a) (kernel:double-double-lo a)
2481                  (float b 1d0))
2482      (truly-the ,(type-specifier (node-derived-type node))
2483                 (kernel:%make-double-double-float hi lo))))
2484
2485 (declaim (inline sqr-d))
2486 (defun sqr-d (a)
2487   "Square"
2488   (declare (double-float a)
2489            (optimize (speed 3)
2490                      (inhibit-warnings 3)))
2491   (two-sqr a))
2492
2493 (declaim (inline mul-d-d))
2494 (defun mul-d-d (a b)
2495   (two-prod a b))
2496
2497 (declaim (maybe-inline sqrt-dd))
2498 (defun sqrt-dd (a0 a1)
2499   (declare (type (double-float 0d0) a0)
2500            (double-float a1)
2501            (optimize (speed 3)
2502                      (inhibit-warnings 3)))
2503   ;; Strategy: Use Karp's trick: if x is an approximation to sqrt(a),
2504   ;; then
2505   ;;
2506   ;; y = a*x + (a-(a*x)^2)*x/2
2507   ;;
2508   ;; is an approximation that is accurate to twice the accuracy of x.
2509   ;; Also, the multiplication (a*x) and [-]*x can be done with only
2510   ;; half the precision.
2511   (if (and (zerop a0) (zerop a1))
2512       (values a0 a1)
2513       (let* ((x (/ (sqrt a0)))
2514              (ax (* a0 x)))
2515         (multiple-value-bind (s0 s1)
2516             (sqr-d ax)
2517           (multiple-value-bind (s2)
2518               (sub-dd a0 a1 s0 s1)
2519             (multiple-value-bind (p0 p1)
2520                 (mul-d-d s2 (* x 0.5d0))
2521               (add-dd-d p0 p1 ax)))))))
2522
2523 (deftransform sqrt ((a) ((vm::double-double-float 0w0))
2524                     * :node node)
2525   `(multiple-value-bind (hi lo)
2526        (sqrt-dd (kernel:double-double-hi a) (kernel:double-double-lo a))
2527      (truly-the ,(type-specifier (node-derived-type node))
2528                 (kernel:%make-double-double-float hi lo))))
2529
2530 (declaim (inline neg-dd))
2531 (defun neg-dd (a0 a1)
2532   (declare (double-float a0 a1)
2533            (optimize (speed 3)
2534                      (inhibit-warnings 3)))
2535   (values (- a0) (- a1)))
2536
2537 (declaim (inline abs-dd))
2538 (defun abs-dd (a0 a1)
2539   (declare (double-float a0 a1)
2540            (optimize (speed 3)
2541                      (inhibit-warnings 3)))
2542   (if (minusp a0)
2543       (neg-dd a0 a1)
2544       (values a0 a1)))
2545
2546 (deftransform abs ((a) (vm::double-double-float)
2547                    * :node node)
2548   `(multiple-value-bind (hi lo)
2549        (abs-dd (kernel:double-double-hi a) (kernel:double-double-lo a))
2550      (truly-the ,(type-specifier (node-derived-type node))
2551                 (kernel:%make-double-double-float hi lo))))
2552
2553 (deftransform %negate ((a) (vm::double-double-float)
2554                        * :node node)
2555   `(multiple-value-bind (hi lo)
2556        (neg-dd (kernel:double-double-hi a) (kernel:double-double-lo a))
2557      (truly-the ,(type-specifier (node-derived-type node))
2558                 (kernel:%make-double-double-float hi lo))))
2559
2560 (declaim (inline dd=))
2561 (defun dd= (a0 a1 b0 b1)
2562   (and (= a0 b0)
2563        (= a1 b1)))
2564   
2565 (declaim (inline dd<))
2566 (defun dd< (a0 a1 b0 b1)
2567   (or (< a0 b0)
2568        (and (= a0 b0)
2569             (< a1 b1))))
2570
2571 (declaim (inline dd>))
2572 (defun dd> (a0 a1 b0 b1)
2573   (or (> a0 b0)
2574        (and (= a0 b0)
2575             (> a1 b1))))
2576   
2577 (deftransform = ((a b) (vm::double-double-float vm::double-double-float) *)
2578   `(dd= (kernel:double-double-hi a)
2579         (kernel:double-double-lo a)
2580         (kernel:double-double-hi b)
2581         (kernel:double-double-lo b)))
2582
2583
2584 (deftransform < ((a b) (vm::double-double-float vm::double-double-float) *)
2585   `(dd< (kernel:double-double-hi a)
2586         (kernel:double-double-lo a)
2587         (kernel:double-double-hi b)
2588         (kernel:double-double-lo b)))
2589
2590
2591 (deftransform > ((a b) (vm::double-double-float vm::double-double-float) *)
2592   `(dd> (kernel:double-double-hi a)
2593         (kernel:double-double-lo a)
2594         (kernel:double-double-hi b)
2595         (kernel:double-double-lo b)))
2596
2597 ) ; progn double-double