1 ;;;; floating point support for the ARM
3 ;;;; This software is part of the SBCL system. See the README file for
6 ;;;; This software is derived from the CMU CL system, which was
7 ;;;; written at Carnegie Mellon University and released into the
8 ;;;; public domain. The software is in the public domain and is
9 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
10 ;;;; files for more information.
16 (define-move-fun (load-single 1) (vop x y
)
17 ((single-stack) (single-reg))
18 (inst flds y
(@ (current-nfp-tn vop
) (* (tn-offset x
) n-word-bytes
))))
20 (define-move-fun (store-single 1) (vop x y
)
21 ((single-reg) (single-stack))
22 (inst fsts x
(@ (current-nfp-tn vop
) (* (tn-offset y
) n-word-bytes
))))
24 (define-move-fun (load-double 2) (vop x y
)
25 ((double-stack) (double-reg))
26 (let ((nfp (current-nfp-tn vop
))
27 (offset (* (tn-offset x
) n-word-bytes
)))
28 (inst fldd y
(@ nfp offset
))))
30 (define-move-fun (store-double 2) (vop x y
)
31 ((double-reg) (double-stack))
32 (let ((nfp (current-nfp-tn vop
))
33 (offset (* (tn-offset y
) n-word-bytes
)))
34 (inst fstd x
(@ nfp offset
))))
38 (macrolet ((frob (vop sc move-macro
)
43 :load-if
(not (location= x y
))))
44 (:results
(y :scs
(,sc
)
45 :load-if
(not (location= x y
))))
49 (define-move-vop ,vop
:move
(,sc
) (,sc
)))))
50 (frob single-move single-reg move-single
)
51 (frob double-move double-reg move-double
))
53 (define-vop (move-from-float)
56 (:note
"float to pointer coercion")
57 (:temporary
(:sc non-descriptor-reg
:offset ocfp-offset
) pa-flag
)
58 (:temporary
(:sc interior-reg
) lip
)
59 (:variant-vars double-p size type data
)
61 (with-fixed-allocation (y pa-flag type size
)
62 (inst sub lip y other-pointer-lowtag
)
64 (inst fstd x
(@ lip
(* data n-word-bytes
)))
65 (inst fsts x
(@ lip
(* data n-word-bytes
)))))))
67 (macrolet ((frob (name sc
&rest args
)
69 (define-vop (,name move-from-float
)
70 (:args
(x :scs
(,sc
) :to
:save
))
71 (:results
(y :scs
(descriptor-reg)))
73 (define-move-vop ,name
:move
(,sc
) (descriptor-reg)))))
74 (frob move-from-single single-reg
75 nil single-float-size single-float-widetag single-float-value-slot
)
76 (frob move-from-double double-reg
77 t double-float-size double-float-widetag double-float-value-slot
))
79 (macrolet ((frob (name sc double-p value
)
82 (:args
(x :scs
(descriptor-reg)))
83 (:results
(y :scs
(,sc
)))
84 (:temporary
(:sc interior-reg
) lip
)
85 (:note
"pointer to float coercion")
87 (inst sub lip x other-pointer-lowtag
)
88 (inst ,(if double-p
'fldd
'flds
) y
89 (@ lip
(* ,value n-word-bytes
)))))
90 (define-move-vop ,name
:move
(descriptor-reg) (,sc
)))))
91 (frob move-to-single single-reg nil single-float-value-slot
)
92 (frob move-to-double double-reg t double-float-value-slot
))
94 (macrolet ((frob (name sc stack-sc double-p
)
97 (:args
(x :scs
(,sc
) :target y
)
99 :load-if
(not (sc-is y
,sc
))))
101 (:note
"float arg move")
102 (:generator
,(if double-p
2 1)
105 (,(if double-p
'move-double
'move-single
) y x
))
107 (let ((offset (* (tn-offset y
) n-word-bytes
)))
108 (inst ,(if double-p
'fstd
'fsts
) x
(@ nfp offset
)))))))
109 (define-move-vop ,name
:move-arg
110 (,sc descriptor-reg
) (,sc
)))))
111 (frob move-single-float-arg single-reg single-stack nil
)
112 (frob move-double-float-arg double-reg double-stack t
))
114 ;;;; Complex float move functions
116 (defun complex-single-reg-real-tn (x)
117 (make-random-tn :kind
:normal
:sc
(sc-or-lose 'single-reg
)
118 :offset
(tn-offset x
)))
119 (defun complex-single-reg-imag-tn (x)
120 (make-random-tn :kind
:normal
:sc
(sc-or-lose 'single-reg
)
121 :offset
(1+ (tn-offset x
))))
123 (defun complex-double-reg-real-tn (x)
124 (make-random-tn :kind
:normal
:sc
(sc-or-lose 'double-reg
)
125 :offset
(tn-offset x
)))
126 (defun complex-double-reg-imag-tn (x)
127 (make-random-tn :kind
:normal
:sc
(sc-or-lose 'double-reg
)
128 :offset
(+ 2 (tn-offset x
))))
131 (define-move-fun (load-complex-single 2) (vop x y
)
132 ((complex-single-stack) (complex-single-reg))
133 (let ((nfp (current-nfp-tn vop
))
134 (offset (* (tn-offset x
) n-word-bytes
)))
135 (inst add lr-tn nfp offset
)
136 (inst load-complex-single y
(@ lr-tn
))))
138 (define-move-fun (store-complex-single 2) (vop x y
)
139 ((complex-single-reg) (complex-single-stack))
140 (let ((nfp (current-nfp-tn vop
))
141 (offset (* (tn-offset y
) n-word-bytes
)))
142 (inst add lr-tn nfp offset
)
143 (inst store-complex-single x
(@ lr-tn
))))
145 (define-move-fun (load-complex-double 4) (vop x y
)
146 ((complex-double-stack) (complex-double-reg))
147 (let ((nfp (current-nfp-tn vop
))
148 (offset (* (tn-offset x
) n-word-bytes
)))
149 (inst add lr-tn nfp offset
)
150 (inst load-complex-double y
(@ lr-tn
))))
152 (define-move-fun (store-complex-double 4) (vop x y
)
153 ((complex-double-reg) (complex-double-stack))
154 (let ((nfp (current-nfp-tn vop
))
155 (offset (* (tn-offset y
) n-word-bytes
)))
156 (inst add lr-tn nfp offset
)
157 (inst store-complex-double x
(@ lr-tn
))))
160 ;;; Complex float register to register moves.
163 (define-vop (complex-single-move)
164 (:args
(x :scs
(complex-single-reg) :target y
165 :load-if
(not (location= x y
))))
166 (:results
(y :scs
(complex-single-reg) :load-if
(not (location= x y
))))
167 (:note
"complex single float move")
169 (move-complex-single y x
)))
170 (define-move-vop complex-single-move
:move
171 (complex-single-reg) (complex-single-reg))
173 (define-vop (complex-double-move)
174 (:args
(x :scs
(complex-double-reg)
175 :target y
:load-if
(not (location= x y
))))
176 (:results
(y :scs
(complex-double-reg) :load-if
(not (location= x y
))))
177 (:note
"complex double float move")
179 (move-complex-double y x
)))
180 (define-move-vop complex-double-move
:move
181 (complex-double-reg) (complex-double-reg))
185 ;;; Move from a complex float to a descriptor register allocating a
186 ;;; new complex float object in the process.
188 (define-vop (move-from-complex-single)
189 (:args
(x :scs
(complex-single-reg) :to
:save
))
190 (:results
(y :scs
(descriptor-reg)))
191 (:temporary
(:sc non-descriptor-reg
:offset ocfp-offset
) pa-flag
)
192 (:note
"complex single float to pointer coercion")
194 (with-fixed-allocation (y pa-flag complex-single-float-widetag
195 complex-single-float-size
)
196 (inst sub pa-flag y
(- other-pointer-lowtag
197 (* complex-single-float-real-slot
199 (inst store-complex-single x
(@ pa-flag
)))))
200 (define-move-vop move-from-complex-single
:move
201 (complex-single-reg) (descriptor-reg))
203 (define-vop (move-from-complex-double)
204 (:args
(x :scs
(complex-double-reg) :to
:save
))
205 (:results
(y :scs
(descriptor-reg)))
206 (:temporary
(:sc non-descriptor-reg
:offset ocfp-offset
) pa-flag
)
207 (:note
"complex double float to pointer coercion")
209 (with-fixed-allocation (y pa-flag complex-double-float-widetag
210 complex-double-float-size
)
211 (inst add pa-flag y
(- (* complex-double-float-real-slot
213 other-pointer-lowtag
))
214 (inst store-complex-double x
(@ pa-flag
)))))
215 (define-move-vop move-from-complex-double
:move
216 (complex-double-reg) (descriptor-reg))
220 ;;; Move from a descriptor to a complex float register
222 (define-vop (move-to-complex-single)
223 (:args
(x :scs
(descriptor-reg)))
224 (:results
(y :scs
(complex-single-reg)))
225 (:temporary
(:sc interior-reg
) lip
)
226 (:note
"pointer to complex float coercion")
228 (inst sub lip x
(- other-pointer-lowtag
229 (* complex-single-float-real-slot
231 (inst load-complex-single y
(@ lip
))))
232 (define-move-vop move-to-complex-single
:move
233 (descriptor-reg) (complex-single-reg))
235 (define-vop (move-to-complex-double)
236 (:args
(x :scs
(descriptor-reg)))
237 (:results
(y :scs
(complex-double-reg)))
238 (:temporary
(:sc interior-reg
) lip
)
239 (:note
"pointer to complex float coercion")
241 (inst add lip x
(- (* complex-double-float-real-slot
243 other-pointer-lowtag
))
244 (inst load-complex-double y
(@ lip
))))
245 (define-move-vop move-to-complex-double
:move
246 (descriptor-reg) (complex-double-reg))
250 ;;; Complex float move-arg vop
252 (define-vop (move-complex-single-float-arg)
253 (:args
(x :scs
(complex-single-reg) :target y
)
254 (nfp :scs
(any-reg) :load-if
(not (sc-is y complex-single-reg
))))
256 (:temporary
(:sc interior-reg
) lip
)
257 (:note
"complex single-float arg move")
261 (move-complex-single y x
))
262 (complex-single-stack
263 (let ((offset (* (tn-offset y
) n-word-bytes
)))
264 (inst add lip nfp offset
)
265 (inst store-complex-single x
(@ lip
)))))))
266 (define-move-vop move-complex-single-float-arg
:move-arg
267 (complex-single-reg descriptor-reg
) (complex-single-reg))
269 (define-vop (move-complex-double-float-arg)
270 (:args
(x :scs
(complex-double-reg) :target y
)
271 (nfp :scs
(any-reg) :load-if
(not (sc-is y complex-double-reg
))))
273 (:temporary
(:sc interior-reg
) lip
)
274 (:note
"complex double-float arg move")
278 (move-complex-double y x
))
279 (complex-double-stack
280 (let ((offset (* (tn-offset y
) n-word-bytes
)))
281 (inst add lip nfp offset
)
282 (inst store-complex-double x
(@ lip
)))))))
283 (define-move-vop move-complex-double-float-arg
:move-arg
284 (complex-double-reg descriptor-reg
) (complex-double-reg))
286 ;;;; Unboxed-to-boxed MOVE-ARG handling:
288 ;; This little gem here says to use the VOP MOVE-ARG to move any float
289 ;; registers to boxed data. MOVE-ARG only takes boxed data as input,
290 ;; which means that the :MOVE VOPs will be used to do the appropriate
292 (define-move-vop move-arg
:move-arg
293 (single-reg double-reg complex-single-reg complex-double-reg
)
296 ;;;; Arithmetic VOPs:
298 (define-vop (float-op)
302 (:note
"inline float arithmetic")
304 (:save-p
:compute-only
))
306 (macrolet ((frob (name sc ptype
)
307 `(define-vop (,name float-op
)
308 (:args
(x :scs
(,sc
))
310 (:results
(r :scs
(,sc
)))
311 (:arg-types
,ptype
,ptype
)
312 (:result-types
,ptype
))))
313 (frob single-float-op single-reg single-float
)
314 (frob double-float-op double-reg double-float
))
316 (macrolet ((frob (op sinst sname scost dinst dname dcost
)
318 (define-vop (,sname single-float-op
)
321 (inst ,sinst r x y
)))
322 (define-vop (,dname double-float-op
)
325 (inst ,dinst r x y
))))))
326 (frob + fadds
+/single-float
2 faddd
+/double-float
2)
327 (frob - fsubs -
/single-float
2 fsubd -
/double-float
2)
328 (frob * fmuls
*/single-float
4 fmuld
*/double-float
5)
329 (frob / fdivs
//single-float
12 fdivd
//double-float
19))
331 (macrolet ((frob (name inst translate sc type
)
333 (:args
(x :scs
(,sc
)))
334 (:results
(y :scs
(,sc
)))
335 (:translate
,translate
)
338 (:result-types
,type
)
339 (:note
"inline float arithmetic")
341 (:save-p
:compute-only
)
343 (note-this-location vop
:internal-error
)
345 (frob abs
/single-float fabss abs single-reg single-float
)
346 (frob abs
/double-float fabsd abs double-reg double-float
)
347 (frob %negate
/single-float fnegs %negate single-reg single-float
)
348 (frob %negate
/double-float fnegd %negate double-reg double-float
))
351 (:args
(x :scs
(double-reg)))
352 (:results
(y :scs
(double-reg)))
355 (:arg-types double-float
)
356 (:result-types double-float
)
357 (:note
"inline float arithmetic")
358 (:save-p
:compute-only
)
363 (:args
(x :scs
(single-reg)))
364 (:results
(y :scs
(single-reg)))
367 (:arg-types single-float
)
368 (:result-types single-float
)
369 (:note
"inline float arithmetic")
370 (:save-p
:compute-only
)
376 (define-vop (float-compare)
378 (:variant-vars format is-
=)
380 (:note
"inline float comparison")
382 (:save-p
:compute-only
)
384 (note-this-location vop
:internal-error
)
396 (macrolet ((frob (name sc ptype
)
397 `(define-vop (,name float-compare
)
398 (:args
(x :scs
(,sc
))
400 (:arg-types
,ptype
,ptype
))))
401 (frob single-float-compare single-reg single-float
)
402 (frob double-float-compare double-reg double-float
))
404 (macrolet ((frob (translate cond sname dname is-
=)
406 (define-vop (,sname single-float-compare
)
407 (:translate
,translate
)
409 (:variant
:single
,is-
=))
410 (define-vop (,dname double-float-compare
)
411 (:translate
,translate
)
413 (:variant
:double
,is-
=)))))
414 (frob < :mi
</single-float
</double-float nil
)
415 (frob > :gt
>/single-float
>/double-float nil
)
416 (frob = :eq eql
/single-float eql
/double-float t
))
418 (define-vop (float-compare-zero)
422 (:variant-vars format is-
=)
424 (:note
"inline float comparison")
426 (:save-p
:compute-only
)
428 (note-this-location vop
:internal-error
)
440 (macrolet ((frob (name sc ptype constant-type
)
441 `(define-vop (,name float-compare-zero
)
442 (:args
(x :scs
(,sc
)))
443 (:arg-types
,ptype
(:constant
, constant-type
)))))
444 (frob single-float-compare-zero single-reg single-float
445 (single-float -
0s0
0s0
))
446 (frob double-float-compare-zero double-reg double-float
447 (double-float -
0d0
0d0
)))
449 (macrolet ((frob (translate cond sname dname is-
=)
451 (define-vop (,sname single-float-compare-zero
)
452 (:translate
,translate
)
454 (:variant
:single
,is-
=))
455 (define-vop (,dname double-float-compare-zero
)
456 (:translate
,translate
)
458 (:variant
:double
,is-
=)))))
459 (frob < :mi
</single-float-zero
</double-float-zero nil
)
460 (frob > :gt
>/single-float-zero
>/double-float-zero nil
)
461 (frob = :eq eql
/single-float-zero eql
/double-float-zero t
))
465 (macrolet ((frob (name translate inst from-sc from-type to-sc to-type
)
467 (:args
(x :scs
(,from-sc
)))
468 (:temporary
(:scs
(single-reg)) rtemp
)
469 (:results
(y :scs
(,to-sc
)))
470 (:arg-types
,from-type
)
471 (:result-types
,to-type
)
473 (:note
"inline float coercion")
474 (:translate
,translate
)
476 (:save-p
:compute-only
)
479 (inst ,inst y rtemp
)))))
480 (frob %single-float
/signed %single-float fsitos
481 signed-reg signed-num single-reg single-float
)
482 (frob %double-float
/signed %double-float fsitod
483 signed-reg signed-num double-reg double-float
)
484 (frob %single-float
/unsigned %single-float fuitos
485 unsigned-reg unsigned-num single-reg single-float
)
486 (frob %double-float
/unsigned %double-float fuitod
487 unsigned-reg unsigned-num double-reg double-float
))
489 (macrolet ((frob (name translate inst from-sc from-type to-sc to-type
)
491 (:args
(x :scs
(,from-sc
)))
492 (:results
(y :scs
(,to-sc
)))
493 (:arg-types
,from-type
)
494 (:result-types
,to-type
)
496 (:note
"inline float coercion")
497 (:translate
,translate
)
499 (:save-p
:compute-only
)
501 (note-this-location vop
:internal-error
)
503 (frob %single-float
/double-float %single-float fcvtsd
504 double-reg double-float single-reg single-float
)
505 (frob %double-float
/single-float %double-float fcvtds
506 single-reg single-float double-reg double-float
))
508 (macrolet ((frob (trans from-sc from-type inst
)
509 `(define-vop (,(symbolicate trans
"/" from-type
))
510 (:args
(x :scs
(,from-sc
) :target temp
))
511 (:temporary
(:from
(:argument
0) :sc single-reg
) temp
)
512 (:results
(y :scs
(signed-reg)))
513 (:arg-types
,from-type
)
514 (:result-types signed-num
)
517 (:note
"inline float truncate")
519 (:save-p
:compute-only
)
521 (note-this-location vop
:internal-error
)
523 (inst fmrs y temp
)))))
524 (frob %unary-truncate
/single-float single-reg single-float ftosizs
)
525 (frob %unary-truncate
/double-float double-reg double-float ftosizd
)
526 (frob %unary-round single-reg single-float ftosis
)
527 (frob %unary-round double-reg double-float ftosid
))
529 (define-vop (make-single-float)
530 (:args
(bits :scs
(signed-reg) :target res
531 :load-if
(not (sc-is bits signed-stack
))))
532 (:results
(res :scs
(single-reg)
533 :load-if
(not (sc-is res single-stack
))))
534 (:temporary
(:scs
(signed-reg) :from
(:argument
0) :to
(:result
0)) temp
)
535 (:arg-types signed-num
)
536 (:result-types single-float
)
537 (:translate make-single-float
)
545 (inst fmsr res bits
))
547 (storew bits
(current-nfp-tn vop
) (tn-offset res
)))))
552 (@ (current-nfp-tn vop
)
553 (* (tn-offset bits
) n-word-bytes
))))
555 (unless (location= bits res
)
556 (loadw temp
(current-nfp-tn vop
) (tn-offset bits
))
557 (storew temp
(current-nfp-tn vop
) (tn-offset res
)))))))))
559 (define-vop (make-double-float)
560 (:args
(hi-bits :scs
(signed-reg))
561 (lo-bits :scs
(unsigned-reg)))
562 (:results
(res :scs
(double-reg)
563 :load-if
(not (sc-is res double-stack
))))
564 (:arg-types signed-num unsigned-num
)
565 (:result-types double-float
)
566 (:translate make-double-float
)
572 (inst fmdrr res lo-bits hi-bits
))
575 ((eq *backend-byte-order
* :big-endian
)
576 (storew hi-bits
(current-nfp-tn vop
) (tn-offset res
))
577 (storew lo-bits
(current-nfp-tn vop
) (1+ (tn-offset res
))))
579 (storew lo-bits
(current-nfp-tn vop
) (tn-offset res
))
580 (storew hi-bits
(current-nfp-tn vop
) (1+ (tn-offset res
)))))))))
582 (define-vop (single-float-bits)
583 (:args
(float :scs
(single-reg descriptor-reg
)
584 :load-if
(not (sc-is float single-stack
))))
585 (:results
(bits :scs
(signed-reg)
586 :load-if
(or (sc-is float descriptor-reg single-stack
)
587 (not (sc-is bits signed-stack
)))))
588 (:arg-types single-float
)
589 (:result-types signed-num
)
590 (:translate single-float-bits
)
598 (inst fmrs bits float
))
600 (loadw bits
(current-nfp-tn vop
) (tn-offset float
)))
602 (loadw bits float single-float-value-slot other-pointer-lowtag
))))
606 (inst fsts float
(@ (current-nfp-tn vop
)
607 (* (tn-offset bits
) n-word-bytes
))))
608 ((single-stack descriptor-reg
)
609 ;; Fun and games: This also affects PPC, silently.
610 ;; Hopefully it's a non-issue, but I'd rather have the
611 ;; explicit error than a silent miscompilation.
612 (bug "Unable to extract single-float bits from ~S to ~S" float bits
)))))))
614 (define-vop (double-float-high-bits)
615 (:args
(float :scs
(double-reg descriptor-reg
)
616 :load-if
(not (sc-is float double-stack
))))
617 (:results
(hi-bits :scs
(signed-reg)))
618 (:arg-types double-float
)
619 (:result-types signed-num
)
620 (:translate double-float-high-bits
)
626 (inst fmrdh hi-bits float
))
628 (loadw hi-bits
(current-nfp-tn vop
)
630 (if (eq *backend-byte-order
* :big-endian
)
633 (loadw hi-bits float
(+ double-float-value-slot
634 (if (eq *backend-byte-order
* :big-endian
)
636 other-pointer-lowtag
)))))
638 (define-vop (double-float-low-bits)
639 (:args
(float :scs
(double-reg descriptor-reg
)
640 :load-if
(not (sc-is float double-stack
))))
641 (:results
(lo-bits :scs
(unsigned-reg)))
642 (:arg-types double-float
)
643 (:result-types unsigned-num
)
644 (:translate double-float-low-bits
)
650 (inst fmrdl lo-bits float
))
652 (loadw lo-bits
(current-nfp-tn vop
)
654 (if (eq *backend-byte-order
* :big-endian
)
657 (loadw lo-bits float
(+ double-float-value-slot
658 (if (eq *backend-byte-order
* :big-endian
)
660 other-pointer-lowtag
)))))
662 ;;;; Float mode hackery:
664 (sb!xc
:deftype float-modes
() '(unsigned-byte 32))
665 (defknown floating-point-modes
() float-modes
(flushable))
666 (defknown ((setf floating-point-modes
)) (float-modes)
669 (define-vop (floating-point-modes)
670 (:results
(res :scs
(unsigned-reg)))
671 (:result-types unsigned-num
)
672 (:translate floating-point-modes
)
675 (inst fmrx res
:fpscr
)))
677 (define-vop (set-floating-point-modes)
678 (:args
(new :scs
(unsigned-reg) :target res
))
679 (:results
(res :scs
(unsigned-reg)))
680 (:arg-types unsigned-num
)
681 (:result-types unsigned-num
)
682 (:translate
(setf floating-point-modes
))
685 (inst fmxr
:fpscr new
)
688 ;;;; Complex float VOPs
690 (define-vop (make-complex-single-float)
692 (:args
(real :scs
(single-reg) :target r
693 :load-if
(not (location= real r
)))
694 (imag :scs
(single-reg) :to
:save
))
695 (:arg-types single-float single-float
)
696 (:results
(r :scs
(complex-single-reg) :from
(:argument
0)
697 :load-if
(not (sc-is r complex-single-stack
))))
698 (:result-types complex-single-float
)
699 (:note
"inline complex single-float creation")
705 (let ((r-real (complex-single-reg-real-tn r
)))
706 (move-single r-real real
))
707 (let ((r-imag (complex-single-reg-imag-tn r
)))
708 (move-single r-imag imag
)))
709 (complex-single-stack
710 (let ((nfp (current-nfp-tn vop
))
711 (offset (* (tn-offset r
) n-word-bytes
)))
712 (unless (location= real r
)
713 (inst fsts real
(@ nfp offset
)))
714 (inst fsts imag
(@ nfp
(+ offset n-word-bytes
))))))))
716 (define-vop (make-complex-double-float)
718 (:args
(real :scs
(double-reg) :target r
719 :load-if
(not (location= real r
)))
720 (imag :scs
(double-reg) :to
:save
))
721 (:arg-types double-float double-float
)
722 (:results
(r :scs
(complex-double-reg) :from
(:argument
0)
723 :load-if
(not (sc-is r complex-double-stack
))))
724 (:result-types complex-double-float
)
725 (:note
"inline complex double-float creation")
731 (let ((r-real (complex-double-reg-real-tn r
)))
732 (move-double r-real real
))
733 (let ((r-imag (complex-double-reg-imag-tn r
)))
734 (move-double r-imag imag
)))
735 (complex-double-stack
736 (let ((nfp (current-nfp-tn vop
))
737 (offset (* (tn-offset r
) n-word-bytes
)))
738 (unless (location= real r
)
739 (inst fstd real
(@ nfp offset
)))
740 (inst fstd imag
(@ nfp
(+ offset
(* 2 n-word-bytes
)))))))))
743 (define-vop (complex-single-float-value)
744 (:args
(x :scs
(complex-single-reg) :target r
745 :load-if
(not (sc-is x complex-single-stack
))))
746 (:arg-types complex-single-float
)
747 (:results
(r :scs
(single-reg)))
748 (:result-types single-float
)
755 (let ((value-tn (ecase slot
756 (:real
(complex-single-reg-real-tn x
))
757 (:imag
(complex-single-reg-imag-tn x
)))))
758 (move-single r value-tn
)))
759 (complex-single-stack
760 (inst flds r
(@ (current-nfp-tn vop
)
761 (* (+ (ecase slot
(:real
0) (:imag
1))
765 (define-vop (realpart/complex-single-float complex-single-float-value
)
766 (:translate realpart
)
767 (:note
"complex single float realpart")
770 (define-vop (imagpart/complex-single-float complex-single-float-value
)
771 (:translate imagpart
)
772 (:note
"complex single float imagpart")
775 (define-vop (complex-double-float-value)
776 (:args
(x :scs
(complex-double-reg) :target r
777 :load-if
(not (sc-is x complex-double-stack
))))
778 (:arg-types complex-double-float
)
779 (:results
(r :scs
(double-reg)))
780 (:result-types double-float
)
787 (let ((value-tn (ecase slot
788 (:real
(complex-double-reg-real-tn x
))
789 (:imag
(complex-double-reg-imag-tn x
)))))
790 (move-double r value-tn
)))
791 (complex-double-stack
792 (inst fldd r
(@ (current-nfp-tn vop
)
793 (* (+ (ecase slot
(:real
0) (:imag
2))
797 (define-vop (realpart/complex-double-float complex-double-float-value
)
798 (:translate realpart
)
799 (:note
"complex double float realpart")
802 (define-vop (imagpart/complex-double-float complex-double-float-value
)
803 (:translate imagpart
)
804 (:note
"complex double float imagpart")