source: release/1.11/source/level-0/X86/X8632/x8632-float.lisp

Last change on this file was 16688, checked in by R. Matthew Emerson, 9 years ago

Merge copyright/license header changes to 1.11 release branch.

File size: 20.7 KB
RevLine 
[16688]1;;;
[13067]2;;; Copyright 2009 Clozure Associates
3;;;
[16688]4;;; Licensed under the Apache License, Version 2.0 (the "License");
5;;; you may not use this file except in compliance with the License.
6;;; You may obtain a copy of the License at
[13067]7;;;
[16688]8;;; http://www.apache.org/licenses/LICENSE-2.0
[13067]9;;;
[16688]10;;; Unless required by applicable law or agreed to in writing, software
11;;; distributed under the License is distributed on an "AS IS" BASIS,
12;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13;;; See the License for the specific language governing permissions and
14;;; limitations under the License.
[13067]15
[7984]16(in-package "CCL")
17
18(eval-when (:compile-toplevel :execute)
19 (require "NUMBER-MACROS")
20 (require "NUMBER-CASE-MACRO"))
21
22;;; make a float from hi - high 24 bits mantissa (ignore implied higher bit)
23;;; lo - low 28 bits mantissa
24;;; exp - take low 11 bits
25;;; sign - sign(sign) => result
26;;; hi result - 1 bit sign: 11 bits exp: 20 hi bits of hi arg
27;;; lo result - 4 lo bits of hi arg: 28 lo bits of lo arg
28;;; no error checks, no tweaks, no nuthin
29
30;;; sign is -1, 1, maybe zero
31
32(defx8632lapfunction %make-float-from-fixnums ((dfloat 12) (hi 8) (lo 4) #|(ra 0)|# (exp arg_y) (sign arg_z))
33 (mov (% sign) (% imm0))
34 (movl (@ dfloat (% esp)) (% arg_z))
35 (sar ($ 31) (% imm0))
36 (shl ($ 31) (% imm0)) ;insert sign
37 (shl ($ (- 20 x8632::fixnumshift)) (% exp))
38 (orl (% exp) (% imm0)) ;insert biased exponent
[7985]39 (movl (% imm0) (@ x8632::double-float.val-high (% arg_z)))
[7984]40 (movl (@ hi (% esp)) (% arg_y))
41 (andl ($ (ash (1- (ash 1 24)) x8632::fixnumshift)) (% arg_y))
42 (movl (% arg_y) (% imm0))
43 (shrl ($ (+ 4 x8632::fixnumshift)) (% imm0)) ;top 20 bits of hi
44 (orl (% imm0) (@ x8632::double-float.val-high (% arg_z))) ; into high word
45 ;; do low half
46 (movl (@ lo (% esp)) (% imm0))
47 (sar ($ x8632::fixnumshift) (% imm0))
48 (andl ($ (1- (ash 1 28))) (% imm0))
49 (shl ($ (- 28 x8632::fixnumshift)) (% arg_y)) ;position low 4 bits of hi
50 (orl (% arg_y) (% imm0))
51 (movl (% imm0) (@ x8632::double-float.value (% arg_z)))
52 (single-value-return 5))
53
54(defx8632lapfunction %make-short-float-from-fixnums ((sfloat 8) (significand 4) #|(ra 0)|# (biased-exp arg_y) (sign arg_z))
55 (movl (% sign) (% imm0))
56 (movl (@ sfloat (% esp)) (% arg_z))
57 (sarl ($ 31) (% imm0))
58 (shll ($ 31) (% imm0)) ;insert sign
59 (shll ($ (- ieee-single-float-exponent-offset x8632::fixnumshift)) (% biased-exp))
60 (or (% biased-exp) (% imm0)) ;insert biased exponent
61 (movl (% imm0) (@ x8632::single-float.value (% arg_z)))
62 (movl (@ significand (% esp)) (% imm0))
63 (sar ($ x8632::fixnumshift) (% imm0))
64 (andl ($ (1- (ash 1 ieee-single-float-hidden-bit))) (% imm0))
65 (or (% imm0) (@ x8632::single-float.value (% arg_z)))
66 (single-value-return 4))
67
68;;; Maybe we should trap - or something - on NaNs.
69(defx8632lapfunction %%double-float-abs! ((n arg_y) (val arg_z))
70 (get-double-float n fp1)
71 (put-double-float fp1 val)
72 (btrl ($ 31) (@ x8632::double-float.val-high (% val)))
73 (single-value-return))
74
75(defx8632lapfunction %%short-float-abs! ((n arg_y) (val arg_z))
76 (movl (@ x8632::single-float.value (% n)) (% imm0))
77 (btr ($ 31) (% imm0))
78 (movl (% imm0) (@ x8632::single-float.value (% val)))
79 (single-value-return))
80
81(defx8632lapfunction %double-float-negate! ((src arg_y) (res arg_z))
82 (get-double-float src fp1)
83 (put-double-float fp1 res)
84 (btcl ($ 31) (@ x8632::double-float.val-high (% res)))
85 (single-value-return))
86
87(defx8632lapfunction %short-float-negate! ((src arg_y) (res arg_z))
88 (movl (@ x8632::single-float.value (% src)) (% imm0))
89 (btcl ($ 31) (% imm0))
[7985]90 (movl (% imm0) (@ x8632::single-float.value (% res)))
[7984]91 (single-value-return))
92
93;;; return hi (25 bits) lo (28 bits) exp sign
94(defx8632lapfunction %integer-decode-double-float ((n arg_z))
95 (mark-as-imm temp0)
96 (let ((imm1 temp0)
97 (sign 0)
98 (exp 4)
99 (lo 8)
100 (hi 12))
101 (pushl ($ 0)) ;hi
102 (pushl ($ 0)) ;lo
103 (pushl ($ 0)) ;exp
104 (pushl ($ 0)) ;sign
105
106 (movl (@ x8632::double-float.val-high (% n)) (% imm1))
[9482]107 (movl ($ '1) (% arg_y))
108 (movl ($ '-1) (% imm0))
109 (btl ($ 31) (% imm1))
110 (cmovcl (% imm0) (% arg_y))
[7984]111 (movl (% arg_y) (@ sign (% esp)))
112
113 (movl (% imm1) (% imm0))
114 (andl ($ #x7ff00000) (% imm0)) ;exponent
[9482]115 (shrl ($ (- 20 x8632::fixnumshift)) (% imm0))
[7984]116 (movl (% imm0) (@ exp (% esp)))
117
118 (movl (@ x8632::double-float.value (% n)) (% imm0))
119 (andl ($ #x000fffff) (% imm1)) ;high 20 bits of fraction
120 (shldl ($ 4) (% imm0) (% imm1)) ;shift in 4 bits from low word
[9482]121 (cmpl ($ 0) (@ exp (% esp)))
122 (je @denorm)
123 (or ($ (ash 1 (- ieee-double-float-hidden-bit 28))) (% imm1))
[7984]124 @denorm
125 (box-fixnum imm1 arg_y)
126 (movl (% arg_y) (@ hi (% esp)))
127
128 (shll ($ 4) (% imm0)) ;shift out bits included in hi
[9482]129 (shrl ($ x8632::fixnumshift) (% imm0)) ;and box 28 low bits
[7984]130 (movl (% imm0) (@ lo (% esp))))
131 (mark-as-node temp0)
132 (set-nargs 4)
133 (leal (@ '4 (% esp)) (% temp0))
134 (jmp-subprim .SPvalues))
135
136;;; hi is 25 bits lo is 28 bits
137;;; big is 32 lo, 21 hi right justified
138(defx8632lapfunction make-big-53 ((hi 4) #|(ra 0)|# (lo arg_y) (big arg_z))
139 (mark-as-imm temp0)
140 (let ((imm1 temp0))
141 (movl (@ hi (% esp)) (% temp1))
142 (movl (% temp1) (% imm0))
143 (shll ($ (- 28 x8632::fixnumshift)) (% imm0))
144 (unbox-fixnum lo imm1)
145 (orl (% imm0) (% imm1))
[7985]146 (movl (% imm1) (@ x8632::misc-data-offset (% big))) ;low 32 bits
[7984]147 (movl (% temp1) (% imm0))
148 (sarl ($ (+ 4 x8632::fixnumshift)) (% imm0))
[7985]149 (movl (% imm0) (@ (+ 4 x8632::misc-data-offset) (% big)))) ;high 21 bits
[7984]150 (mark-as-node temp0)
151 (single-value-return 3))
152
153;;; dfloat must be non-zero
154(defx8632lapfunction dfloat-significand-zeros ((dfloat arg_z))
155 (mark-as-imm temp0)
156 (let ((imm1 temp0))
157 (movl (@ x8632::double-float.value (% dfloat)) (% imm0))
158 (movl (@ x8632::double-float.val-high (% dfloat)) (% imm1))
159 ;; shift imm1 left by count, shifting bits from imm0 in from the right
160 (shldl ($ (1+ ieee-double-float-exponent-width)) (% imm0) (% imm1))
161 (testl (% imm1) (% imm1))
162 (jz @low)
163 (bsrl (% imm1) (% imm0))
164 (xorl ($ (1- x8632::nbits-in-word)) (% imm0))
165 (jmp @done)
166 @low
167 (bsrl (% imm0) (% imm0))
168 (xorl ($ (1- x8632::nbits-in-word)) (% imm0))
169 ;; if we're here, the upper part of the fraction was all zeros,
170 ;; so add the count for those in.
171 (add ($ (- ieee-double-float-mantissa-width 32)) (% imm0))
172 @done
173 (box-fixnum imm0 arg_z))
174 (mark-as-node temp0)
175 (single-value-return))
176
177;;; sfloat must be non-zero
178(defx8632lapfunction sfloat-significand-zeros ((sfloat arg_z))
179 (movl (@ x8632::single-float.value (% sfloat)) (% imm0))
180 (shl ($ (1+ IEEE-single-float-exponent-width)) (% imm0))
181 (bsrl (% imm0) (% imm0))
182 (xorl ($ (1- x8632::nbits-in-word)) (% imm0))
183 (box-fixnum imm0 arg_z)
184 (single-value-return))
185
186(defx8632lapfunction %%scale-dfloat! ((dfloat 4) #|(ra 0)|# (int arg_y) (result arg_z))
187 (unbox-fixnum int imm0)
188 (movl (@ dfloat (% esp)) (% temp0))
189 (get-double-float temp0 fp1)
190 (shl ($ (- ieee-double-float-exponent-offset 32)) (% imm0))
191 (movl ($ 0) (@ x8632::double-float.value (% result)))
192 (movl (% imm0) (@ x8632::double-float.val-high (% result)))
193 (get-double-float result fp2)
194 (mulsd (% fp2) (% fp1))
195 (put-double-float fp1 result)
196 (single-value-return 3))
197
198(defx8632lapfunction %%scale-sfloat! ((sfloat 4) #|(ra 0)|# (int arg_y) (result arg_z))
199 (unbox-fixnum int imm0)
200 (movl (@ sfloat (% esp)) (% temp0))
201 (get-single-float temp0 fp1)
202 (shl ($ ieee-single-float-exponent-offset) (% imm0))
203 (movd (% imm0) (% fp2))
204 (mulss (% fp2) (% fp1))
205 (put-single-float fp1 arg_z)
206 (single-value-return 3))
207
208(defx8632lapfunction %copy-double-float ((f1 arg_y) (f2 arg_z))
209 (get-double-float f1 fp1)
210 (put-double-float fp1 f2)
211 (single-value-return))
212
213(defx8632lapfunction %copy-short-float ((f1 arg_y) (f2 arg_z))
214 (get-single-float f1 fp1)
215 (put-single-float fp1 f2)
216 (single-value-return))
217
218(defx8632lapfunction %double-float-exp ((n arg_z))
219 (movl (@ x8632::double-float.val-high (% n)) (% imm0))
220 (shll ($ 1) (% imm0))
221 (shrl ($ (1+ (- ieee-double-float-exponent-offset 32))) (% imm0))
[7985]222 (box-fixnum imm0 arg_z)
223 (single-value-return))
[7984]224
225(defx8632lapfunction set-%double-float-exp ((dfloat arg_y) (exp arg_z))
226 (movl (% exp) (% temp0))
227 (shll ($ (1+ (- 20 x8632::fixnumshift))) (% temp0))
228 (shrl ($ 1) (% temp0))
229 (movl (@ x8632::double-float.val-high (% dfloat)) (% imm0))
230 (andl ($ #x800fffff) (% imm0))
231 (orl (% temp0) (% imm0))
232 (movl (% imm0) (@ x8632::double-float.val-high (% dfloat)))
233 (single-value-return))
234
235(defx8632lapfunction %short-float-exp ((n arg_z))
236 (movl (@ x8632::single-float.value (% n)) (% imm0))
237 (shll ($ 1) (% imm0))
238 (shrl ($ (1+ ieee-single-float-exponent-offset)) (% imm0))
[7985]239 (box-fixnum imm0 arg_z)
240 (single-value-return))
[7984]241
242(defx8632lapfunction set-%short-float-exp ((sfloat arg_y) (exp arg_z))
243 (movl (% exp) (% temp0))
244 (shll ($ (1+ (- ieee-single-float-exponent-offset x8632::fixnumshift))) (% temp0))
245 (shrl ($ 1) (% temp0))
246 (movl (@ x8632::single-float.value (% sfloat)) (% imm0))
247 (andl ($ #x807fffff) (% imm0))
248 (orl (% temp0) (% imm0))
[7985]249 (movl (% imm0) (@ x8632::single-float.value (% sfloat)))
250 (single-value-return))
[7984]251
252(defx8632lapfunction %short-float->double-float ((src arg_y) (result arg_z))
253 (get-single-float src fp1)
254 (cvtss2sd (% fp1) (% fp1))
255 (put-double-float fp1 result)
256 (single-value-return))
257
[9482]258(defx8632lapfunction %double-float->short-float ((src arg_y) (result arg_z))
[7984]259 (get-double-float src fp1)
260 (cvtsd2ss (% fp1) (% fp1))
[9482]261 (put-single-float fp1 result)
[7984]262 (single-value-return))
263
264(defx8632lapfunction %int-to-sfloat! ((int arg_y) (sfloat arg_z))
265 (int-to-single int imm0 fp1)
266 (put-single-float fp1 arg_z)
267 (single-value-return))
268
[8214]269(defx8632lapfunction %int-to-dfloat ((int arg_y) (dfloat arg_z))
[7984]270 (int-to-double int imm0 fp1)
271 (put-double-float fp1 arg_z)
272 (single-value-return))
273
274
275
[7988]276
277;;; Manipulate the MXCSR. It'll fit in a fixnum, but we have to
278;;; load and store it through memory. On x8664, we can hide the
279;;; 32-bit MXCSR value in a fixnum on the stack; on a 32-bit x86,
[7984]280;;; we might need to use a scratch location in the TCR or something.
281
282;;; Return the MXCSR as a fixnum
[14619]283(defx8632lapfunction %get-mxcsr ()
284 (stmxcsr (:rcontext x8632::tcr.unboxed0))
[7984]285 (movl (:rcontext x8632::tcr.unboxed0) (% imm0))
286 (box-fixnum imm0 arg_z)
287 (single-value-return))
288
289;;; Store the fixnum in arg_z in the MXCSR. Just to be
290;;; on the safe side, mask the arg with X86::MXCSR-WRITE-MASK,
[8214]291;;; so that only known control and status bits are written to.
[7988]292(defx8632lapfunction %set-mxcsr ((val arg_z))
[7985]293 (unbox-fixnum val imm0)
[14619]294 (andl ($ x86::mxcsr-write-mask) (% imm0))
295 (movl (% imm0) (:rcontext x8632::tcr.unboxed0))
[7984]296 (ldmxcsr (:rcontext x8632::tcr.unboxed0))
297 (single-value-return))
298
299
300;;; Get the bits that contain exception masks and rounding mode.
301
302(defun %get-mxcsr-control ()
303 (logand x86::mxcsr-control-and-rounding-mask (the fixnum (%get-mxcsr))))
304
305;;; Get the bits that describe current exceptions.
306(defun %get-mxcsr-status ()
307 (logand x86::mxcsr-status-mask (the fixnum (%get-mxcsr))))
308
309;;; Set the bits that describe current exceptions, presumably to clear them.
310(defun %set-mxcsr-status (arg)
311 (%set-mxcsr
312 (logior (logand x86::mxcsr-status-mask arg)
313 (logandc2 (%get-mxcsr) x86::mxcsr-status-mask)))
314 arg)
315
316;;; Set the bits that mask/unmask exceptions and control rounding.
317;;; Clear the bits which describe current exceptions.
318(defun %set-mxcsr-control (arg)
319 (%set-mxcsr (logand x86::mxcsr-control-and-rounding-mask arg)))
320
[8214]321;;; Return the MXCSR value in effect after the last ff-call.
[7984]322(defx8632lapfunction %get-post-ffi-mxcsr ()
[10575]323 (xor (% arg_z) (% arg_z))
324 (movl (:rcontext x8632::tcr.ffi-exception) (%l imm0))
[7984]325 (movl (%l arg_z) (:rcontext x8632::tcr.ffi-exception))
326 (box-fixnum imm0 arg_z)
327 (single-value-return))
328
329;;; The next several defuns are copied verbatim from x8664-float.lisp.
330;;; It will probably be desirable to factor this code out into a new
331;;; x86-float.lisp, perhaps conditionalized via #+sse2 or something.
332;;; (Some day we may want to support x87 fp and we'll need
333;;; x87-specific versions of these functions.)
334
335;;; start duplicated code
336
337;;; Return the status bits from the last ff-call that represent
338;;; unmasked exceptions
339(defun %ffi-exception-status ()
340 (logior (%get-mxcsr-control)
341 (logand x86::mxcsr-status-mask (the fixnum (%get-post-ffi-mxcsr)))))
342
343;;; See if the binary double-float operation OP set any enabled
344;;; exception bits in the mxcsr
345(defun %df-check-exception-2 (operation op0 op1 fp-status)
346 (declare (type (unsigned-byte 6) fp-status))
347 (unless (zerop fp-status)
348 (%set-mxcsr-status 0)
349 ;; Ensure that operands are heap-consed
350 (%fp-error-from-status fp-status
351 operation
352 (%copy-double-float op0 (%make-dfloat))
353 (%copy-double-float op1 (%make-dfloat)))))
354
355(defun %sf-check-exception-2 (operation op0 op1 fp-status)
356 (declare (type (unsigned-byte 6) fp-status))
357 (unless (zerop fp-status)
358 (%set-mxcsr-status 0)
359 ;; Ensure that operands are heap-consed
360 (%fp-error-from-status fp-status
361 operation
362 #+32-bit-target
363 (%copy-short-float op0 (%make-sfloat))
364 #+64-bit-target op0
365 #+32-bit-target
366 (%copy-short-float op1 (%make-sfloat))
367 #+64-bit-target op1)))
368
369(defun %df-check-exception-1 (operation op0 fp-status)
370 (declare (fixnum fp-status))
371 (unless (zerop fp-status)
372 (%set-mxcsr-status 0)
373 ;; Ensure that operands are heap-consed
374 (%fp-error-from-status fp-status
375 operation
376 (%copy-double-float op0 (%make-dfloat)))))
377
378(defun %sf-check-exception-1 (operation op0 fp-status)
379 (declare (type (unsigned-byte 6) fp-status))
380 (unless (zerop fp-status)
381 (%set-mxcsr-status 0)
382 ;; Ensure that operands are heap-consed
383 (%fp-error-from-status fp-status
384 operation
385 #+32-bit-target
386 (%copy-short-float op0 (%make-sfloat))
387 #+64-bit-target op0)))
388
389
390(defun fp-condition-from-mxcsr (status-bits control-bits)
391 (declare (fixnum status-bits control-bits))
392 (cond
393 ((and (logbitp x86::mxcsr-ie-bit status-bits)
394 (not (logbitp x86::mxcsr-im-bit control-bits)))
395 'floating-point-invalid-operation)
396 ((and (logbitp x86::mxcsr-oe-bit status-bits)
397 (not (logbitp x86::mxcsr-om-bit control-bits)))
398 'floating-point-overflow)
399 ((and (logbitp x86::mxcsr-ue-bit status-bits)
400 (not (logbitp x86::mxcsr-um-bit control-bits)))
401 'floating-point-underflow)
402 ((and (logbitp x86::mxcsr-ze-bit status-bits)
403 (not (logbitp x86::mxcsr-zm-bit control-bits)))
404 'division-by-zero)
405 ((and (logbitp x86::mxcsr-pe-bit status-bits)
406 (not (logbitp x86::mxcsr-pm-bit control-bits)))
407 'floating-point-inexact)))
408
409(defun %fp-error-from-status (status-bits operation op0 &optional op1)
410 (declare (type (unsigned-byte 6) status-bits))
411 (let* ((condition-class (fp-condition-from-mxcsr status-bits (%get-mxcsr-control))))
412 (if condition-class
413 (let* ((operands (if op1 (list op0 op1) (list op0))))
414 (error (make-instance condition-class
415 :operation operation
416 :operands operands))))))
[9476]417
418(defvar *rounding-mode-alist*
419 '((:nearest . 0) (:zero . 1) (:positive . 2) (:negative . 3)))
420
421(defun get-fpu-mode (&optional (mode nil mode-p))
422 (let* ((flags (%get-mxcsr-control)))
423 (declare (fixnum flags))
424 (let* ((rounding-mode
425 (car (nth (+ (if (logbitp x86::mxcsr-rc0-bit flags) 1 0)
426 (if (logbitp x86::mxcsr-rc1-bit flags) 2 0))
427 *rounding-mode-alist*)))
428 (overflow (not (logbitp x86::mxcsr-om-bit flags)))
429 (underflow (not (logbitp x86::mxcsr-um-bit flags)))
430 (division-by-zero (not (logbitp x86::mxcsr-zm-bit flags)))
431 (invalid (not (logbitp x86::mxcsr-im-bit flags)))
432 (inexact (not (logbitp x86::mxcsr-pm-bit flags))))
433 (if mode-p
434 (ecase mode
435 (:rounding-mode rounding-mode)
436 (:overflow overflow)
437 (:underflow underflow)
438 (:division-by-zero division-by-zero)
439 (:invalid invalid)
440 (:inexact inexact))
441 `(:rounding-mode ,rounding-mode
442 :overflow ,overflow
443 :underflow ,underflow
444 :division-by-zero ,division-by-zero
445 :invalid ,invalid
446 :inexact ,inexact)))))
447
448;;; did we document this?
449(defun set-fpu-mode (&key (rounding-mode :nearest rounding-p)
450 (overflow t overflow-p)
451 (underflow t underflow-p)
452 (division-by-zero t zero-p)
453 (invalid t invalid-p)
454 (inexact t inexact-p))
455 (let* ((current (%get-mxcsr-control))
456 (new current))
457 (declare (fixnum current new))
458 (when rounding-p
459 (let* ((rc-bits (or
460 (cdr (assoc rounding-mode *rounding-mode-alist*))
461 (error "Unknown rounding mode: ~s" rounding-mode))))
462 (declare (fixnum rc-bits))
463 (if (logbitp 0 rc-bits)
464 (bitsetf x86::mxcsr-rc0-bit new)
465 (bitclrf x86::mxcsr-rc0-bit new))
466 (if (logbitp 1 rc-bits)
467 (bitsetf x86::mxcsr-rc1-bit new)
468 (bitclrf x86::mxcsr-rc1-bit new))))
469 (when invalid-p
470 (if invalid
471 (bitclrf x86::mxcsr-im-bit new)
472 (bitsetf x86::mxcsr-im-bit new)))
473 (when overflow-p
474 (if overflow
475 (bitclrf x86::mxcsr-om-bit new)
476 (bitsetf x86::mxcsr-om-bit new)))
477 (when underflow-p
478 (if underflow
479 (bitclrf x86::mxcsr-um-bit new)
480 (bitsetf x86::mxcsr-um-bit new)))
481 (when zero-p
482 (if division-by-zero
483 (bitclrf x86::mxcsr-zm-bit new)
484 (bitsetf x86::mxcsr-zm-bit new)))
485 (when inexact-p
486 (if inexact
487 (bitclrf x86::mxcsr-pm-bit new)
488 (bitsetf x86::mxcsr-pm-bit new)))
489 (unless (= current new)
490 (%set-mxcsr-control new))
491 (%get-mxcsr)))
[7984]492
493;;; end duplicated code
494
495;;; Don't we already have about 20 versions of this ?
496(defx8632lapfunction %double-float-from-macptr! ((ptr 4) #|(ra 0)|# (byte-offset arg_y) (dest arg_z))
497 (mark-as-imm temp0)
498 (let ((imm1 temp0))
499 (movl (@ ptr (% esp)) (% temp1))
500 (macptr-ptr temp1 imm0)
501 (unbox-fixnum byte-offset imm1)
502 (movsd (@ (% imm0) (% imm1)) (% fp1))
503 (put-double-float fp1 dest))
504 (mark-as-node temp0)
505 (single-value-return 3))
506
507;;; Copy a single float pointed at by the macptr in single
508;;; to a double float pointed at by the macptr in double
509(defx8632lapfunction %single-float-ptr->double-float-ptr ((single arg_y) (double arg_z))
510 (check-nargs 2)
511 (macptr-ptr single imm0)
512 (movss (@ (% imm0)) (% fp1))
513 (cvtss2sd (% fp1) (% fp1))
514 (macptr-ptr double imm0)
515 (movsd (% fp1) (@ (% imm0)))
516 (single-value-return))
517
518;;; Copy a double float pointed at by the macptr in double
519;;; to a single float pointed at by the macptr in single.
520(defx8632lapfunction %double-float-ptr->single-float-ptr ((double arg_y) (single arg_z))
521 (check-nargs 2)
522 (macptr-ptr double imm0)
523 (movsd (@ (% imm0)) (% fp1))
524 (cvtsd2ss (% fp1) (% fp1))
525 (macptr-ptr single imm0)
526 (movss (% fp1) (@ (% imm0)))
527 (single-value-return))
528
529(defx8632lapfunction %set-ieee-single-float-from-double ((src arg_y) (macptr arg_z))
530 (check-nargs 2)
531 (macptr-ptr macptr imm0)
532 (get-double-float src fp1)
533 (cvtsd2ss (% fp1) (% fp1))
534 (movss (% fp1) (@ (% imm0)))
535 (single-value-return))
536
537(defun host-single-float-from-unsigned-byte-32 (u32)
538 (let* ((f (%make-sfloat)))
539 (setf (uvref f x8632::single-float.value-cell) u32)
540 f))
541
542(defun single-float-bits (f)
543 (uvref f x8632::single-float.value-cell))
544
545(defun double-float-bits (f)
546 (values (uvref f target::double-float.val-high-cell)
547 (uvref f target::double-float.value-cell)))
548
549(defun double-float-from-bits (high low)
550 (let* ((f (%make-dfloat)))
551 (setf (uvref f target::double-float.val-high-cell) high
552 (uvref f target::double-float.value-cell) low)
553 f))
554
555;;; Return T if n is negative, else NIL.
556(defx8632lapfunction %double-float-sign ((n arg_z))
557 (movl (@ x8632::double-float.val-high (% n)) (% imm0))
[10959]558 (testl (% imm0) (% imm0))
559 (movl ($ (target-t-value)) (% imm0))
[7984]560 (movl ($ (target-nil-value)) (% arg_z))
561 (cmovll (% imm0) (% arg_z))
562 (single-value-return))
563
564(defx8632lapfunction %short-float-sign ((n arg_z))
565 (movl (@ x8632::single-float.value (% n)) (% imm0))
[10959]566 (testl (% imm0) (% imm0))
567 (movl ($ (target-t-value)) (% imm0))
[7984]568 (movl ($ (target-nil-value)) (% arg_z))
569 (cmovll (% imm0) (% arg_z))
570 (single-value-return))
571
572(defx8632lapfunction %double-float-sqrt! ((n arg_y) (result arg_z))
573 (get-double-float n fp0)
574 (sqrtsd (% fp0) (% fp0))
575 (put-double-float fp0 result)
576 (single-value-return))
577
578(defx8632lapfunction %single-float-sqrt! ((n arg_y) (result arg_z))
579 (get-single-float n fp0)
580 (sqrtss (% fp0) (% fp0))
581 (put-single-float fp0 arg_z)
582 (single-value-return))
583
584
585
Note: See TracBrowser for help on using the repository browser.