| [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 |
|
|---|