| [13075] | 1 | ;;; Copyright 2009 Clozure Associates
|
|---|
| 2 | ;;; This file is part of Clozure CL.
|
|---|
| 3 | ;;;
|
|---|
| 4 | ;;; Clozure CL is licensed under the terms of the Lisp Lesser GNU
|
|---|
| 5 | ;;; Public License , known as the LLGPL and distributed with Clozure
|
|---|
| 6 | ;;; CL as the file "LICENSE". The LLGPL consists of a preamble and
|
|---|
| 7 | ;;; the LGPL, which is distributed with Clozure CL as the file "LGPL".
|
|---|
| 8 | ;;; Where these conflict, the preamble takes precedence.
|
|---|
| 9 | ;;;
|
|---|
| 10 | ;;; Clozure CL is referenced in the preamble as the "LIBRARY."
|
|---|
| 11 | ;;;
|
|---|
| 12 | ;;; The LLGPL is also available online at
|
|---|
| 13 | ;;; http://opensource.franz.com/preamble.html
|
|---|
| 14 |
|
|---|
| [7998] | 15 | (in-package "CCL")
|
|---|
| 16 |
|
|---|
| 17 | (defx8632lapfunction %fixnum-signum ((number arg_z))
|
|---|
| 18 | (mov ($ '-1) (% temp0))
|
|---|
| 19 | (mov ($ '1) (% temp1))
|
|---|
| 20 | (test (% number) (% number))
|
|---|
| 21 | (cmovs (% temp0) (% arg_z))
|
|---|
| 22 | (cmovns (% temp1) (% arg_z))
|
|---|
| 23 | (single-value-return))
|
|---|
| 24 |
|
|---|
| 25 | ;;; see %logcount.
|
|---|
| 26 | (defx86lapfunction %ilogcount ((number arg_z))
|
|---|
| 27 | (mark-as-imm temp0)
|
|---|
| 28 | (let ((rshift imm0)
|
|---|
| 29 | (temp temp0))
|
|---|
| 30 | (unbox-fixnum number rshift)
|
|---|
| 31 | (xor (% arg_z) (% arg_z))
|
|---|
| 32 | (test (% rshift) (% rshift))
|
|---|
| 33 | (jmp @test)
|
|---|
| 34 | @next
|
|---|
| 35 | (lea (@ -1 (% rshift)) (% temp))
|
|---|
| 36 | (and (% temp) (% rshift)) ;sets flags
|
|---|
| 37 | (lea (@ '1 (% arg_z)) (% arg_z)) ;doesn't set flags
|
|---|
| 38 | @test
|
|---|
| 39 | (jne @next))
|
|---|
| 40 | (mark-as-node temp0)
|
|---|
| 41 | (single-value-return))
|
|---|
| 42 |
|
|---|
| 43 | ;;; might be able to get away with not marking ecx as imm.
|
|---|
| 44 | (defx8632lapfunction %iash ((number arg_y) (count arg_z))
|
|---|
| 45 | (mark-as-imm ecx) ;aka temp0
|
|---|
| 46 | (unbox-fixnum count ecx)
|
|---|
| 47 | (test (% count) (% count))
|
|---|
| 48 | (jge @left)
|
|---|
| 49 | (negb (% cl))
|
|---|
| 50 | (unbox-fixnum number imm0)
|
|---|
| 51 | (sar (% cl) (% imm0))
|
|---|
| 52 | (box-fixnum imm0 arg_z)
|
|---|
| 53 | (mark-as-node ecx)
|
|---|
| 54 | (single-value-return)
|
|---|
| 55 | @left
|
|---|
| 56 | (shl (% cl) (% number))
|
|---|
| 57 | (movl (% number) (% arg_z))
|
|---|
| 58 | (mark-as-node ecx)
|
|---|
| 59 | (single-value-return))
|
|---|
| 60 |
|
|---|
| 61 | (defparameter *double-float-zero* 0.0d0)
|
|---|
| 62 | (defparameter *short-float-zero* 0.0s0)
|
|---|
| 63 |
|
|---|
| 64 | (defx8632lapfunction %sfloat-hwords ((sfloat arg_z))
|
|---|
| 65 | (movl (% esp) (% temp0))
|
|---|
| 66 | (movzwl (@ (+ 2 x8632::misc-data-offset) (% sfloat)) (% imm0))
|
|---|
| 67 | (box-fixnum imm0 temp1)
|
|---|
| 68 | (pushl (% temp1)) ;high
|
|---|
| 69 | (movzwl (@ x8632::misc-data-offset (% sfloat)) (% imm0))
|
|---|
| 70 | (box-fixnum imm0 temp1)
|
|---|
| 71 | (pushl (% temp1)) ;low
|
|---|
| 72 | (set-nargs 2)
|
|---|
| 73 | (jmp-subprim .SPvalues))
|
|---|
| 74 |
|
|---|
| 75 | (defx8632lapfunction %fixnum-intlen ((number arg_z))
|
|---|
| 76 | (mark-as-imm temp0)
|
|---|
| 77 | (let ((imm1 temp0))
|
|---|
| 78 | (unbox-fixnum arg_z imm0)
|
|---|
| 79 | (mov (% imm0) (% imm1))
|
|---|
| 80 | (not (% imm1))
|
|---|
| 81 | (test (% imm0) (% imm0))
|
|---|
| 82 | (cmovs (% imm1) (% imm0))
|
|---|
| 83 | (bsrl (% imm0) (% imm0))
|
|---|
| 84 | (setne (%b imm1))
|
|---|
| 85 | (addb (%b imm1) (%b imm0))
|
|---|
| 86 | (box-fixnum imm0 arg_z))
|
|---|
| 87 | (mark-as-node temp0)
|
|---|
| 88 | (single-value-return))
|
|---|
| 89 |
|
|---|
| 90 | ;;; Caller guarantees that result fits in a fixnum.
|
|---|
| 91 | (defx8632lapfunction %truncate-double-float->fixnum ((arg arg_z))
|
|---|
| 92 | (get-double-float arg fp1)
|
|---|
| 93 | (cvttsd2si (% fp1) (% imm0))
|
|---|
| 94 | (box-fixnum imm0 arg_z)
|
|---|
| 95 | (single-value-return))
|
|---|
| 96 |
|
|---|
| 97 | (defx8632lapfunction %truncate-short-float->fixnum ((arg arg_z))
|
|---|
| 98 | (get-single-float arg fp1)
|
|---|
| 99 | (cvttss2si (% fp1) (% imm0))
|
|---|
| 100 | (box-fixnum imm0 arg_z)
|
|---|
| 101 | (single-value-return))
|
|---|
| 102 |
|
|---|
| 103 | ;;; DOES round to even
|
|---|
| 104 | (defx8632lapfunction %round-nearest-double-float->fixnum ((arg arg_z))
|
|---|
| 105 | (get-double-float arg fp1)
|
|---|
| 106 | (cvtsd2si (% fp1) (% imm0))
|
|---|
| 107 | (box-fixnum imm0 arg_z)
|
|---|
| 108 | (single-value-return))
|
|---|
| 109 |
|
|---|
| 110 | (defx8632lapfunction %round-nearest-short-float->fixnum ((arg arg_z))
|
|---|
| 111 | (get-single-float arg fp1)
|
|---|
| 112 | (cvtss2si (% fp1) (% imm0))
|
|---|
| 113 | (box-fixnum imm0 arg_z)
|
|---|
| 114 | (single-value-return))
|
|---|
| 115 |
|
|---|
| [13535] | 116 |
|
|---|
| 117 |
|
|---|
| [7998] | 118 | ;;; We'll get a SIGFPE if divisor is 0.
|
|---|
| 119 | (defx8632lapfunction %fixnum-truncate ((dividend arg_y) (divisor arg_z))
|
|---|
| [13535] | 120 | (cmpl ($ '-1) (% divisor))
|
|---|
| 121 | (je @neg)
|
|---|
| [7998] | 122 | (mark-as-imm temp0)
|
|---|
| 123 | (mark-as-imm temp1)
|
|---|
| 124 | (let ((imm2 temp0)
|
|---|
| 125 | (imm1 temp1)) ;edx
|
|---|
| 126 | (unbox-fixnum dividend imm0)
|
|---|
| 127 | (unbox-fixnum divisor imm2)
|
|---|
| 128 | (cltd) ;edx:eax = sign_extend(eax)
|
|---|
| 129 | (idivl (% imm2))
|
|---|
| 130 | (box-fixnum imm0 arg_z) ;quotient
|
|---|
| 131 | (box-fixnum imm1 arg_y)) ;remainder
|
|---|
| 132 | (mark-as-node temp0)
|
|---|
| 133 | (mark-as-node temp1)
|
|---|
| 134 | (movl (% esp) (% temp0))
|
|---|
| 135 | (push (% arg_z))
|
|---|
| 136 | (push (% arg_y))
|
|---|
| 137 | (set-nargs 2)
|
|---|
| [13535] | 138 | (jmp-subprim .SPvalues)
|
|---|
| 139 | @neg
|
|---|
| 140 | (negl (% dividend))
|
|---|
| 141 | (load-constant *least-positive-bignum* arg_z)
|
|---|
| 142 | (cmovol (@ x8632::symbol.vcell (% arg_z)) (% dividend))
|
|---|
| 143 | (movl (% esp) (% temp0))
|
|---|
| 144 | (pushl (% dividend))
|
|---|
| 145 | (pushl ($ 0))
|
|---|
| 146 | (set-nargs 2)
|
|---|
| [7998] | 147 | (jmp-subprim .SPvalues))
|
|---|
| 148 |
|
|---|
| 149 | (defx8632lapfunction called-for-mv-p ()
|
|---|
| 150 | (movl (@ x8632::lisp-frame.return-address (% ebp)) (% imm0))
|
|---|
| [10959] | 151 | (cmpl (% imm0) (@ (+ (target-nil-value) (x8632::kernel-global ret1valaddr))))
|
|---|
| 152 | (movl ($ (target-t-value)) (% imm0))
|
|---|
| 153 | (movl ($ (target-nil-value)) (% arg_z))
|
|---|
| [7998] | 154 | (cmove (% imm0) (% arg_z))
|
|---|
| 155 | (single-value-return))
|
|---|
| 156 |
|
|---|
| [8975] | 157 | (defx8632lapfunction %next-random-pair ((high arg_y) (low arg_z))
|
|---|
| 158 | ;; high: (unsigned-byte 15)
|
|---|
| 159 | ;; low: (unsigned-byte 16)
|
|---|
| 160 | (unbox-fixnum low imm0)
|
|---|
| 161 | ;; clear most significant bit
|
|---|
| 162 | (shll ($ (1+ (- 16 x8632::fixnumshift))) (% high))
|
|---|
| 163 | (shrl ($ 1) (% high))
|
|---|
| 164 | (orl (% high) (% imm0))
|
|---|
| 165 | (mark-as-imm edx)
|
|---|
| 166 | (movl ($ 48271) (% edx))
|
|---|
| 167 | (mul (% edx))
|
|---|
| 168 | (mark-as-node edx)
|
|---|
| 169 | (movl ($ (- #x10000)) (% high)) ;#xffff0000
|
|---|
| 170 | (andl (% imm0) (% high))
|
|---|
| 171 | (shrl ($ (- 16 x8632::fixnumshift)) (% high))
|
|---|
| 172 | (shll ($ 16) (% imm0))
|
|---|
| 173 | (shrl ($ (- 16 x8632::fixnumshift)) (% imm0))
|
|---|
| 174 | (movl (% imm0) (% low))
|
|---|
| 175 | (movl (% esp) (% temp0))
|
|---|
| 176 | (push (% high))
|
|---|
| 177 | (push (% low))
|
|---|
| 178 | (set-nargs 2)
|
|---|
| 179 | (jmp-subprim .SPvalues))
|
|---|
| 180 |
|
|---|
| [7998] | 181 | ;;; n1 and n2 must be positive (esp non zero)
|
|---|
| 182 | (defx86lapfunction %fixnum-gcd ((boxed-u arg_y) (boxed-v arg_z))
|
|---|
| 183 | (mark-as-imm temp0)
|
|---|
| 184 | (mark-as-imm temp1)
|
|---|
| 185 | (let ((u imm0)
|
|---|
| 186 | (v temp1)
|
|---|
| 187 | (k temp0)) ;temp0 = ecx
|
|---|
| 188 | (xorl (% k) (% k))
|
|---|
| 189 | (bsfl (% boxed-u) (% u))
|
|---|
| 190 | (bsfl (% boxed-v) (% v))
|
|---|
| 191 | (rcmp (% u) (% v))
|
|---|
| 192 | (cmovlel (%l u) (%l k))
|
|---|
| 193 | (cmovgl (%l v) (%l k))
|
|---|
| 194 | (unbox-fixnum boxed-u u)
|
|---|
| 195 | (unbox-fixnum boxed-v v)
|
|---|
| 196 | (subb ($ x8632::fixnumshift) (%b k))
|
|---|
| 197 | (jz @start)
|
|---|
| 198 | (shrl (% cl) (% u))
|
|---|
| 199 | (shrl (% cl) (% v))
|
|---|
| 200 | @start
|
|---|
| 201 | ;; At least one of u or v is odd at this point
|
|---|
| 202 | @loop
|
|---|
| 203 | ;; if u is even, shift it right one bit
|
|---|
| 204 | (testb ($ 1) (%b u))
|
|---|
| 205 | (jne @u-odd)
|
|---|
| 206 | (shrl ($ 1) (% u))
|
|---|
| 207 | (jmp @test)
|
|---|
| 208 | @u-odd
|
|---|
| 209 | ;; if v is even, shift it right one bit
|
|---|
| 210 | (testb ($ 1) (%b v))
|
|---|
| 211 | (jne @both-odd)
|
|---|
| 212 | (shrl ($ 1) (% v))
|
|---|
| 213 | (jmp @test-u)
|
|---|
| 214 | @both-odd
|
|---|
| 215 | (cmpl (% v) (% u))
|
|---|
| 216 | (jb @v>u)
|
|---|
| 217 | (subl (% v) (% u))
|
|---|
| 218 | (shrl ($ 1) (% u))
|
|---|
| 219 | (jmp @test)
|
|---|
| 220 | @v>u
|
|---|
| 221 | (subl (% u) (% v))
|
|---|
| 222 | (shrl ($ 1) (% v))
|
|---|
| 223 | @test-u
|
|---|
| 224 | (testl (% u) (% u))
|
|---|
| 225 | @test
|
|---|
| 226 | (ja @loop)
|
|---|
| 227 | (shll (% cl) (% v))
|
|---|
| 228 | (movb ($ 0) (% cl))
|
|---|
| 229 | (box-fixnum v arg_z))
|
|---|
| 230 | (mark-as-node temp0)
|
|---|
| 231 | (mark-as-node temp1)
|
|---|
| 232 | (single-value-return))
|
|---|
| 233 |
|
|---|