| [7361] | 1 | ;;; -*- Mode: Lisp; Package: CCL -*-
|
|---|
| 2 | ;;;
|
|---|
| 3 | ;;; Copyright (C) 2006, Clozure Associates and contributors
|
|---|
| 4 | ;;; This file is part of OpenMCL.
|
|---|
| 5 | ;;;
|
|---|
| 6 | ;;; OpenMCL is licensed under the terms of the Lisp Lesser GNU Public
|
|---|
| 7 | ;;; License , known as the LLGPL and distributed with OpenMCL as the
|
|---|
| 8 | ;;; file "LICENSE". The LLGPL consists of a preamble and the LGPL,
|
|---|
| 9 | ;;; which is distributed with OpenMCL as the file "LGPL". Where these
|
|---|
| 10 | ;;; conflict, the preamble takes precedence.
|
|---|
| 11 | ;;;
|
|---|
| 12 | ;;; OpenMCL is referenced in the preamble as the "LIBRARY."
|
|---|
| 13 | ;;;
|
|---|
| 14 | ;;; The LLGPL is also available online at
|
|---|
| 15 | ;;; http://opensource.franz.com/preamble.html
|
|---|
| 16 |
|
|---|
| 17 | (in-package "CCL")
|
|---|
| 18 |
|
|---|
| [8857] | 19 | ;;; Use the offsets in a function's self-reference table to replace
|
|---|
| 20 | ;;; the :self in (movl ($ :self) (% fn)) wih the function's actual
|
|---|
| 21 | ;;; address.
|
|---|
| 22 | (defx8632lapfunction %update-self-references ((fun arg_z))
|
|---|
| 23 | (movzwl (@ x8632::misc-data-offset (% fun)) (% imm0)) ;imm word count
|
|---|
| 24 | (subl ($ 2) (% imm0))
|
|---|
| 25 | (box-fixnum imm0 temp0) ;byte offset of first self-ref offset
|
|---|
| [8906] | 26 | (jmp @load-offset)
|
|---|
| [8857] | 27 | @loop
|
|---|
| 28 | (movl (% fun) (@ x8632::misc-header-offset (% fun) (% imm0)))
|
|---|
| 29 | (subl ($ '1) (% temp0))
|
|---|
| [8906] | 30 | @load-offset
|
|---|
| [8857] | 31 | (movl (@ x8632::misc-data-offset (% fun) (% temp0)) (% imm0))
|
|---|
| 32 | (test (% imm0) (% imm0))
|
|---|
| 33 | (jne @loop)
|
|---|
| 34 | (single-value-return))
|
|---|
| 35 |
|
|---|
| [7963] | 36 | (defx8632lapfunction %function-code-words ((fun arg_z))
|
|---|
| [7361] | 37 | (trap-unless-typecode= fun x8632::subtag-function)
|
|---|
| [7430] | 38 | (movzwl (@ x8632::misc-data-offset (% fun)) (% imm0))
|
|---|
| [7361] | 39 | (box-fixnum imm0 arg_z)
|
|---|
| 40 | (single-value-return))
|
|---|
| 41 |
|
|---|
| [7963] | 42 | (defx8632lapfunction %nth-immediate ((fun arg_y) (n arg_z))
|
|---|
| [7361] | 43 | (trap-unless-typecode= fun x8632::subtag-function)
|
|---|
| [7430] | 44 | (movzwl (@ x8632::misc-data-offset (% fun)) (% imm0))
|
|---|
| [7361] | 45 | (lea (@ (% n) (% imm0) 4) (% imm0))
|
|---|
| 46 | (movl (@ x8632::misc-data-offset (% fun) (% imm0)) (% arg_z))
|
|---|
| 47 | (single-value-return))
|
|---|
| 48 |
|
|---|
| [7963] | 49 | (defx8632lapfunction %set-nth-immediate ((fun 4) #|(ra 0)|# (n arg_y) (new arg_z))
|
|---|
| 50 | (popl (@ 8 (% esp)))
|
|---|
| 51 | (popl (% temp0))
|
|---|
| 52 | (addl ($ 4) (% esp))
|
|---|
| [7361] | 53 | (trap-unless-typecode= temp0 x8632::subtag-function)
|
|---|
| [7963] | 54 | (movzwl (@ x8632::misc-data-offset (% temp0)) (% imm0))
|
|---|
| [7361] | 55 | (lea (@ (% n) (% imm0) 4) (% arg_y))
|
|---|
| 56 | ;; expects gvector in temp0
|
|---|
| 57 | (jmp-subprim .SPgvset))
|
|---|
| 58 |
|
|---|
| [7963] | 59 | (defx8632lapfunction %function-code-byte ((fun arg_y) (pc arg_z))
|
|---|
| [7361] | 60 | (unbox-fixnum pc imm0)
|
|---|
| 61 | (movzbl (@ (% fun) (% imm0)) (% imm0))
|
|---|
| 62 | (box-fixnum imm0 arg_z)
|
|---|
| 63 | (single-value-return))
|
|---|
| 64 |
|
|---|
| [9461] | 65 | (defx8632lapfunction %function-register-usage ((f arg_z))
|
|---|
| 66 | (check-nargs 1)
|
|---|
| 67 | (trap-unless-typecode= f x8632::subtag-function)
|
|---|
| 68 | (movl (% esp) (% temp0))
|
|---|
| 69 | (pushl ($ nil))
|
|---|
| 70 | (pushl ($ nil))
|
|---|
| 71 | (jmp-subprim .SPvalues))
|
|---|
| 72 |
|
|---|
| [9127] | 73 | ;;; XXX probably should unify these next two with the x8664 versions.
|
|---|
| 74 |
|
|---|
| 75 | ;;; Make a new function, with PROTO's code and the specified immediates.
|
|---|
| 76 | ;;; IMMEDIATES should contain lfun-bits as the last element.
|
|---|
| 77 | (defun %clone-x86-function (proto &rest immediates)
|
|---|
| 78 | (declare (dynamic-extent immediates))
|
|---|
| [9192] | 79 | (let* ((protov (function-to-function-vector proto))
|
|---|
| [9127] | 80 | (code-words (%function-code-words proto))
|
|---|
| 81 | (numimms (length immediates))
|
|---|
| 82 | (newv (allocate-typed-vector :function (the fixnum (+ code-words numimms)))))
|
|---|
| 83 | (declare (fixnum code-words numimms))
|
|---|
| 84 | (%copy-ivector-to-ivector protov 0 newv 0 (the fixnum (ash code-words target::word-shift)))
|
|---|
| 85 | (%update-self-references newv)
|
|---|
| 86 | (do* ((k code-words (1+ k))
|
|---|
| 87 | (imms immediates (cdr imms)))
|
|---|
| [9192] | 88 | ((null imms) (function-vector-to-function newv))
|
|---|
| [9127] | 89 | (declare (fixnum k) (list imms))
|
|---|
| 90 | (setf (%svref newv k) (car imms)))))
|
|---|
| 91 |
|
|---|
| [10267] | 92 | (defun %copy-function (proto &optional target)
|
|---|
| 93 | (let* ((protov (function-to-function-vector proto))
|
|---|
| 94 | (code-words (%function-code-words proto))
|
|---|
| 95 | (total-words (uvsize protov))
|
|---|
| 96 | (newv (if target
|
|---|
| 97 | (function-to-function-vector target)
|
|---|
| 98 | (allocate-typed-vector :function total-words))))
|
|---|
| 99 | (declare (fixnum code-words total-words))
|
|---|
| 100 | (when target
|
|---|
| 101 | (unless (and (eql code-words (%function-code-words target))
|
|---|
| 102 | (eql total-words (uvsize newv)))
|
|---|
| 103 | (error "Wrong size target ~s" target)))
|
|---|
| 104 | (%copy-ivector-to-ivector protov 0 newv 0 (the fixnum (ash code-words target::word-shift)))
|
|---|
| 105 | (loop for k fixnum from code-words below total-words
|
|---|
| 106 | do (setf (%svref newv k) (%svref protov k)))
|
|---|
| [11348] | 107 | (%update-self-references (function-vector-to-function newv))))
|
|---|
| [10267] | 108 |
|
|---|
| [9127] | 109 | (defun replace-function-code (target proto)
|
|---|
| 110 | (let* ((target-words (%function-code-words target))
|
|---|
| 111 | (proto-words (%function-code-words proto)))
|
|---|
| 112 | (declare (fixnum target-words proto-words))
|
|---|
| 113 | (if (= target-words proto-words)
|
|---|
| 114 | (progn
|
|---|
| [9192] | 115 | (%copy-ivector-to-ivector (function-to-function-vector proto)
|
|---|
| [9127] | 116 | 0
|
|---|
| [9192] | 117 | (function-to-function-vector target)
|
|---|
| [9127] | 118 | 0
|
|---|
| 119 | (the fixnum (ash target-words
|
|---|
| 120 | target::word-shift)))
|
|---|
| 121 | (%update-self-references target)
|
|---|
| 122 | target)
|
|---|
| 123 | (error "Code size mismatch: target = ~s, proto = ~s"
|
|---|
| 124 | target-words proto-words))))
|
|---|
| 125 |
|
|---|
| [7963] | 126 | (defx8632lapfunction %get-kernel-global-from-offset ((offset arg_z))
|
|---|
| [7361] | 127 | (check-nargs 1)
|
|---|
| 128 | (unbox-fixnum offset imm0)
|
|---|
| [10959] | 129 | (movl (@ (target-nil-value) (% imm0)) (% arg_z))
|
|---|
| [7361] | 130 | (single-value-return))
|
|---|
| 131 |
|
|---|
| [7963] | 132 | (defx8632lapfunction %set-kernel-global-from-offset ((offset arg_y)
|
|---|
| 133 | (new-value arg_z))
|
|---|
| [7361] | 134 | (check-nargs 2)
|
|---|
| 135 | (unbox-fixnum offset imm0)
|
|---|
| [10959] | 136 | (movl (% arg_z) (@ (target-nil-value) (% imm0)))
|
|---|
| [7361] | 137 | (single-value-return))
|
|---|
| 138 |
|
|---|
| [7963] | 139 | (defx8632lapfunction %get-kernel-global-ptr-from-offset ((offset arg_y)
|
|---|
| 140 | (ptr arg_z))
|
|---|
| [7361] | 141 | (check-nargs 2)
|
|---|
| 142 | (unbox-fixnum offset imm0)
|
|---|
| [10959] | 143 | (movl (@ (target-nil-value) (% imm0)) (% imm0))
|
|---|
| [7963] | 144 | (movl (% imm0) (@ x8632::macptr.address (% ptr)))
|
|---|
| [7361] | 145 | (single-value-return))
|
|---|
| 146 |
|
|---|
| [7963] | 147 | (defx8632lapfunction %fixnum-ref ((fixnum arg_y) #| &optional |# (offset arg_z))
|
|---|
| [7361] | 148 | (:arglist (fixnum &optional offset))
|
|---|
| 149 | (check-nargs 1 2)
|
|---|
| [8374] | 150 | (cmpl ($ x8632::fixnumone) (% nargs))
|
|---|
| [7361] | 151 | (jne @2-args)
|
|---|
| [7963] | 152 | (movl (% offset) (% fixnum))
|
|---|
| [7361] | 153 | (xorl (%l offset) (%l offset))
|
|---|
| 154 | @2-args
|
|---|
| 155 | (unbox-fixnum offset imm0)
|
|---|
| [7963] | 156 | (movl (@ (% fixnum) (% imm0)) (% arg_z))
|
|---|
| [7361] | 157 | (single-value-return))
|
|---|
| 158 |
|
|---|
| [7963] | 159 | (defx8632lapfunction %fixnum-ref-natural ((fixnum arg_y) #| &optional |# (offset arg_z))
|
|---|
| [7361] | 160 | (:arglist (fixnum &optional offset))
|
|---|
| 161 | (check-nargs 1 2)
|
|---|
| [8374] | 162 | (cmpl ($ x8632::fixnumone) (% nargs))
|
|---|
| [7361] | 163 | (jne @2-args)
|
|---|
| [7963] | 164 | (movl (% offset) (% fixnum))
|
|---|
| [7361] | 165 | (xorl (%l offset) (%l offset))
|
|---|
| 166 | @2-args
|
|---|
| 167 | (unbox-fixnum offset imm0)
|
|---|
| [7963] | 168 | (movl (@ (% fixnum) (% imm0)) (% imm0))
|
|---|
| 169 | (jmp-subprim .SPmakeu32))
|
|---|
| [7361] | 170 |
|
|---|
| [7963] | 171 | (defx8632lapfunction %fixnum-set ((fixnum 4) #|(ra 0)|# (offset arg_y) #| &optional |# (new-value arg_z))
|
|---|
| [7361] | 172 | (:arglist (fixnum offset &optional newval))
|
|---|
| 173 | (check-nargs 2 3)
|
|---|
| [8374] | 174 | (cmpl ($ '2) (% nargs))
|
|---|
| [7361] | 175 | (jne @3-args)
|
|---|
| [11152] | 176 | (movl (% new-value) (% offset))
|
|---|
| 177 | (single-value-return)
|
|---|
| [7361] | 178 | @3-args
|
|---|
| [11152] | 179 | (movl (@ fixnum (% esp)) (% temp0))
|
|---|
| [7361] | 180 | (unbox-fixnum offset imm0)
|
|---|
| [7963] | 181 | (movl (% new-value) (@ (% temp0) (% imm0)))
|
|---|
| 182 | (single-value-return 3))
|
|---|
| [7361] | 183 |
|
|---|
| 184 |
|
|---|
| [7963] | 185 | (defx8632lapfunction %fixnum-set-natural ((fixnum 4) #|(ra 0)|# (offset arg_y) #| &optional |# (new-value arg_z))
|
|---|
| [11152] | 186 | (:arglist (fixnum offsnet &optional newval))
|
|---|
| [7361] | 187 | (check-nargs 2 3)
|
|---|
| [8374] | 188 | (cmpl ($ '2) (% nargs))
|
|---|
| [7361] | 189 | (jne @3-args)
|
|---|
| [11152] | 190 | (save-simple-frame)
|
|---|
| [7963] | 191 | (movl (% offset) (% temp0))
|
|---|
| [11152] | 192 | (xorl (% offset) (% offset))
|
|---|
| 193 | (jmp @common)
|
|---|
| [7361] | 194 | @3-args
|
|---|
| [11152] | 195 | (movl (% ebp) (@ 8 (% esp)))
|
|---|
| 196 | (lea (@ 8 (% esp)) (% ebp))
|
|---|
| 197 | (popl (@ 4 (% ebp)))
|
|---|
| 198 | (popl (% temp0))
|
|---|
| 199 | @common
|
|---|
| [7963] | 200 | (call-subprim .SPgetu32) ;puts u32 in imm0
|
|---|
| 201 | (mark-as-imm temp1)
|
|---|
| 202 | (unbox-fixnum offset temp1)
|
|---|
| 203 | (movl (% imm0) (@ (% temp0) (% temp1)))
|
|---|
| 204 | (mark-as-node temp1)
|
|---|
| [7361] | 205 | (restore-simple-frame)
|
|---|
| [11152] | 206 | (single-value-return))
|
|---|
| [7361] | 207 |
|
|---|
| 208 |
|
|---|
| [7963] | 209 | (defx8632lapfunction %current-frame-ptr ()
|
|---|
| [7361] | 210 | (check-nargs 0)
|
|---|
| [7963] | 211 | (movl (% ebp) (% arg_z))
|
|---|
| [7361] | 212 | (single-value-return))
|
|---|
| 213 |
|
|---|
| 214 |
|
|---|
| [7963] | 215 | (defx8632lapfunction %current-tsp ()
|
|---|
| [7361] | 216 | (check-nargs 0)
|
|---|
| [10575] | 217 | (movl (:rcontext x8632::tcr.save-tsp) (% arg_z))
|
|---|
| [7361] | 218 | (single-value-return))
|
|---|
| 219 |
|
|---|
| 220 |
|
|---|
| [7963] | 221 | (defx8632lapfunction %%frame-backlink ((p arg_z))
|
|---|
| [7361] | 222 | (check-nargs 1)
|
|---|
| [7963] | 223 | (movl (@ (% arg_z)) (% arg_z))
|
|---|
| [7361] | 224 | (single-value-return))
|
|---|
| 225 |
|
|---|
| [7963] | 226 | ;;; Look for "movl $imm32,%fn at the tra; if present, then $imm32 is
|
|---|
| 227 | ;;; the address of the function.
|
|---|
| 228 | ;;;
|
|---|
| 229 | ;;; That is: #b10111111 <imm32>
|
|---|
| 230 | ;;; ^^^^
|
|---|
| 231 | ;;; operand size || register number (%fn/%edi)
|
|---|
| 232 |
|
|---|
| 233 | (defx8632lapfunction %return-address-function ((r arg_z))
|
|---|
| [9642] | 234 | (extract-fulltag r imm0)
|
|---|
| [7963] | 235 | (cmpb ($ x8632::fulltag-tra) (% imm0.b))
|
|---|
| [7361] | 236 | (jne @fail)
|
|---|
| [7963] | 237 | (cmpb ($ x8632::recover-fn-opcode-byte) (@ (% r)))
|
|---|
| [7361] | 238 | (jne @fail)
|
|---|
| [7963] | 239 | (movl (@ x8632::recover-fn-address-offset (% r)) (% arg_z))
|
|---|
| [7361] | 240 | (single-value-return)
|
|---|
| 241 | @fail
|
|---|
| [10959] | 242 | (movl ($ (target-nil-value)) (% arg_z))
|
|---|
| [7361] | 243 | (single-value-return))
|
|---|
| 244 |
|
|---|
| [7963] | 245 | (defx8632lapfunction %return-address-offset ((r arg_z))
|
|---|
| [9642] | 246 | (extract-fulltag r imm0)
|
|---|
| [7963] | 247 | (cmpb ($ x8632::fulltag-tra) (% imm0.b))
|
|---|
| [7361] | 248 | (jne @fail)
|
|---|
| [7963] | 249 | (cmpb ($ x8632::recover-fn-opcode-byte) (@ (% r)))
|
|---|
| [7361] | 250 | (jne @fail)
|
|---|
| [7963] | 251 | (movl (@ x8632::recover-fn-address-offset (% r)) (% imm0))
|
|---|
| [9643] | 252 | (subl (% arg_z) (% imm0))
|
|---|
| 253 | (negl (% imm0))
|
|---|
| [7963] | 254 | (box-fixnum imm0 arg_z)
|
|---|
| [9643] | 255 | (single-value-return)
|
|---|
| [7361] | 256 | @fail
|
|---|
| [10959] | 257 | (movl ($ (target-nil-value)) (% arg_z))
|
|---|
| [7361] | 258 | (single-value-return))
|
|---|
| 259 |
|
|---|
| 260 | ;;; It's always been the case that the function associated with a
|
|---|
| 261 | ;;; frame pointer is the caller of the function that "uses" that frame.
|
|---|
| 262 | (defun %cfp-lfun (p)
|
|---|
| [7963] | 263 | (let* ((ra (%fixnum-ref p x8632::lisp-frame.return-address)))
|
|---|
| [7361] | 264 | (if (eq ra (%get-kernel-global ret1valaddr))
|
|---|
| [7963] | 265 | (setq ra (%fixnum-ref p x8632::lisp-frame.xtra)))
|
|---|
| [7361] | 266 | (values (%return-address-function ra) (%return-address-offset ra))))
|
|---|
| 267 |
|
|---|
| [7963] | 268 | (defx8632lapfunction %uvector-data-fixnum ((uv arg_z))
|
|---|
| [7361] | 269 | (check-nargs 1)
|
|---|
| [7963] | 270 | (trap-unless-fulltag= arg_z x8632::fulltag-misc)
|
|---|
| 271 | (addl ($ x8632::misc-data-offset) (% arg_z))
|
|---|
| [7361] | 272 | (single-value-return))
|
|---|
| 273 |
|
|---|
| [7963] | 274 | (defx8632lapfunction %catch-top ((tcr arg_z))
|
|---|
| [7361] | 275 | (check-nargs 1)
|
|---|
| [10959] | 276 | (movl ($ (target-nil-value)) (% arg_y))
|
|---|
| [10575] | 277 | (movl (:rcontext x8632::tcr.catch-top) (% arg_z))
|
|---|
| [7361] | 278 | (testb (%b arg_z) (%b arg_z))
|
|---|
| [7963] | 279 | (cmovel (% arg_y) (% arg_z))
|
|---|
| [7361] | 280 | (single-value-return))
|
|---|
| 281 |
|
|---|
| [7963] | 282 | (defx8632lapfunction %catch-tsp ((catch arg_z))
|
|---|
| [7361] | 283 | (check-nargs 1)
|
|---|
| [7963] | 284 | (lea (@ (- (+ x8632::fulltag-misc
|
|---|
| 285 | (ash 1 (1+ x8632::word-shift)))) (% arg_z))
|
|---|
| [7361] | 286 | (% arg_z))
|
|---|
| 287 | (single-value-return))
|
|---|
| 288 |
|
|---|
| 289 | ;;; Same as %address-of, but doesn't cons any bignums
|
|---|
| 290 | ;;; It also left shift fixnums just like everything else.
|
|---|
| [7963] | 291 | (defx8632lapfunction %fixnum-address-of ((x arg_z))
|
|---|
| [7361] | 292 | (check-nargs 1)
|
|---|
| 293 | (box-fixnum x arg_z)
|
|---|
| 294 | (single-value-return))
|
|---|
| 295 |
|
|---|
| [7963] | 296 | (defx8632lapfunction %save-standard-binding-list ((bindings arg_z))
|
|---|
| 297 | (mark-as-imm temp0)
|
|---|
| [10575] | 298 | (movl (:rcontext x8632::tcr.vs-area) (% imm0))
|
|---|
| [7963] | 299 | (movl (@ x8632::area.high (% imm0)) (% temp0))
|
|---|
| 300 | (subl ($ x8632::node-size) (% temp0))
|
|---|
| 301 | (movl (% bindings) (@ (% temp0)))
|
|---|
| 302 | (mark-as-node temp0)
|
|---|
| [7361] | 303 | (single-value-return))
|
|---|
| 304 |
|
|---|
| [7963] | 305 | (defx8632lapfunction %saved-bindings-address ()
|
|---|
| 306 | (mark-as-imm temp0)
|
|---|
| [10575] | 307 | (movl (:rcontext x8632::tcr.vs-area) (% imm0))
|
|---|
| [7963] | 308 | (movl (@ x8632::area.high (% imm0)) (% temp0))
|
|---|
| 309 | (leal (@ (- x8632::node-size) (% temp0)) (% arg_z))
|
|---|
| 310 | (mark-as-node temp0)
|
|---|
| [7361] | 311 | (single-value-return))
|
|---|
| 312 |
|
|---|
| [7963] | 313 | (defx8632lapfunction %get-object ((macptr arg_y) (offset arg_z))
|
|---|
| [7361] | 314 | (check-nargs 2)
|
|---|
| [7963] | 315 | (trap-unless-typecode= macptr x8632::subtag-macptr)
|
|---|
| 316 | (trap-unless-lisptag= offset x8632::tag-fixnum)
|
|---|
| [7361] | 317 | (macptr-ptr macptr imm0)
|
|---|
| [7963] | 318 | (mark-as-imm temp0)
|
|---|
| 319 | (unbox-fixnum offset temp0)
|
|---|
| 320 | (movl (@ (% imm0) (% temp0)) (% arg_z))
|
|---|
| 321 | (mark-as-node temp0)
|
|---|
| [7361] | 322 | (single-value-return))
|
|---|
| 323 |
|
|---|
| [7963] | 324 | (defx8632lapfunction %set-object ((macptr 4) #|(ra 0)|# (offset arg_y) (value arg_z))
|
|---|
| [7361] | 325 | (check-nargs 3)
|
|---|
| [7963] | 326 | (movl (@ macptr (% esp)) (% temp1))
|
|---|
| 327 | (trap-unless-typecode= temp1 x8632::subtag-macptr)
|
|---|
| 328 | (trap-unless-lisptag= offset x8632::tag-fixnum)
|
|---|
| 329 | (macptr-ptr temp1 imm0)
|
|---|
| 330 | (mark-as-imm temp0)
|
|---|
| 331 | (unbox-fixnum offset temp0)
|
|---|
| 332 | (movl (% arg_z) (@ (% imm0) (% temp0)))
|
|---|
| 333 | (mark-as-node temp0)
|
|---|
| [8691] | 334 | (single-value-return 3))
|
|---|
| [7361] | 335 |
|
|---|
| [7963] | 336 | (defx8632lapfunction %apply-lexpr-with-method-context ((magic 4)
|
|---|
| 337 | #|(ra 0)|#
|
|---|
| 338 | (function arg_y)
|
|---|
| 339 | (args arg_z))
|
|---|
| [7361] | 340 | ;; Somebody's called (or tail-called) us.
|
|---|
| [9136] | 341 | ;; * Put magic arg in %rcontext:tcr.next-method-context
|
|---|
| 342 | ;; * Put function somewhere safe until we're ready to jump to it
|
|---|
| 343 | ;; * Set nargs to 0, then spread "args" on stack (clobbers regs)
|
|---|
| 344 | ;; * Jump to function (saved previously)
|
|---|
| [10575] | 345 | (popl (:rcontext x8632::tcr.save0)) ;return address
|
|---|
| 346 | (popl (:rcontext x8632::tcr.next-method-context)) ;magic arg
|
|---|
| [9146] | 347 | (discard-reserved-frame)
|
|---|
| [10575] | 348 | (movl (% function) (:rcontext x8632::tcr.save1))
|
|---|
| [8656] | 349 | (set-nargs 0)
|
|---|
| 350 | (movl (@ (% args)) (% temp0)) ;lexpr-count
|
|---|
| 351 | (movl (% temp0) (% nargs))
|
|---|
| 352 | (leal (@ x8632::node-size (% arg_z) (% temp0)) (% imm0))
|
|---|
| [9136] | 353 | (subl ($ '2) (% temp0))
|
|---|
| [7361] | 354 | (jbe @reg-only)
|
|---|
| [7963] | 355 | ;; Some args will be pushed; reserve a frame.
|
|---|
| 356 | (pushl ($ x8632::reserved-frame-marker))
|
|---|
| 357 | (pushl ($ x8632::reserved-frame-marker))
|
|---|
| [7361] | 358 | @pushloop
|
|---|
| [8656] | 359 | (pushl (@ (- x8632::node-size) (% imm0)))
|
|---|
| 360 | (subl ($ x8632::node-size) (% imm0))
|
|---|
| [7963] | 361 | (subl ($ x8632::node-size) (% temp0))
|
|---|
| [7361] | 362 | (jne @pushloop)
|
|---|
| 363 | @two
|
|---|
| [7963] | 364 | (movl (@ (* x8632::node-size 2) (% arg_z)) (% arg_y))
|
|---|
| [7361] | 365 | @one
|
|---|
| [7963] | 366 | (movl (@ (* x8632::node-size 1) (% arg_z)) (% arg_z))
|
|---|
| [7361] | 367 | (jmp @go)
|
|---|
| 368 | @reg-only
|
|---|
| [9136] | 369 | (rcmp (% nargs) ($ '1))
|
|---|
| [7963] | 370 | (je @one)
|
|---|
| 371 | (jb @go)
|
|---|
| 372 | (jmp @two)
|
|---|
| [7361] | 373 | @go
|
|---|
| [10575] | 374 | (pushl (:rcontext x8632::tcr.save0)) ;return address
|
|---|
| 375 | (movl (:rcontext x8632::tcr.save1) (% temp0)) ;function
|
|---|
| 376 | (movapd (% fpzero) (:rcontext x8632::tcr.save0)) ;clear spill area
|
|---|
| [9136] | 377 | (jmp (% temp0)))
|
|---|
| [7361] | 378 |
|
|---|
| [7963] | 379 | (defx8632lapfunction %apply-with-method-context ((magic 4)
|
|---|
| 380 | #|(ra 0)|#
|
|---|
| 381 | (function arg_y)
|
|---|
| 382 | (args arg_z))
|
|---|
| 383 | ;; Similar to above.
|
|---|
| [10575] | 384 | (popl (:rcontext x8632::tcr.save0)) ;save return address
|
|---|
| 385 | (popl (:rcontext x8632::tcr.next-method-context)) ;
|
|---|
| [9146] | 386 | (discard-reserved-frame)
|
|---|
| [10575] | 387 | (movl (% args) (:rcontext x8632::tcr.save2)) ;in case of error
|
|---|
| [10489] | 388 | (set-nargs 0)
|
|---|
| 389 | (pushl ($ target::reserved-frame-marker)) ;reserve frame (might discard it
|
|---|
| 390 | (pushl ($ target::reserved-frame-marker)) ;if nothing is passed on stack)
|
|---|
| [7361] | 391 | (cmp-reg-to-nil arg_z)
|
|---|
| 392 | (je @done)
|
|---|
| 393 | @loop
|
|---|
| [10489] | 394 | (extract-fulltag arg_z imm0)
|
|---|
| 395 | (cmpb ($ x8632::fulltag-cons) (% imm0.b)) ;nil is a cons on x8632, but we
|
|---|
| [7963] | 396 | (jne @bad) ; checked for it already.
|
|---|
| [10490] | 397 | (add ($ '1) (% nargs)) ;shorter than lea (imm0 is eax)
|
|---|
| 398 | (pushl (@ target::cons.car (% arg_z)))
|
|---|
| [7361] | 399 | (%cdr arg_z arg_z)
|
|---|
| 400 | (cmp-reg-to-nil arg_z)
|
|---|
| 401 | (jne @loop)
|
|---|
| 402 | @done
|
|---|
| [10490] | 403 | ;; arg_y about to get clobbered; put function into temp0
|
|---|
| 404 | (movl (% function) (% temp0))
|
|---|
| [10489] | 405 | ;; temp1 (aka nargs) contains number of args just pushed
|
|---|
| 406 | (test (% nargs) (% nargs))
|
|---|
| [7361] | 407 | (jne @pop)
|
|---|
| 408 | @discard-and-go
|
|---|
| 409 | (discard-reserved-frame)
|
|---|
| 410 | (jmp @go)
|
|---|
| 411 | @pop
|
|---|
| [7963] | 412 | (cmpl ($ '1) (% nargs))
|
|---|
| [7361] | 413 | (pop (% arg_z))
|
|---|
| 414 | (je @discard-and-go)
|
|---|
| [7963] | 415 | (cmpl ($ '2) (% nargs))
|
|---|
| [7361] | 416 | (pop (% arg_y))
|
|---|
| 417 | (je @discard-and-go)
|
|---|
| 418 | @go
|
|---|
| [10575] | 419 | (pushl (:rcontext x8632::tcr.save0)) ;return address
|
|---|
| 420 | (movapd (% fpzero) (:rcontext x8632::tcr.save0)) ;clear out spill area
|
|---|
| [10490] | 421 | (jmp (% temp0))
|
|---|
| [7361] | 422 | @bad
|
|---|
| [10489] | 423 | (addl (% nargs) (% esp))
|
|---|
| [10575] | 424 | (movl (:rcontext x8632::tcr.save1) (% arg_z)) ;saved args
|
|---|
| 425 | (movapd (% fpzero) (:rcontext x8632::tcr.save0)) ;clear out spill area
|
|---|
| [7963] | 426 | (movl ($ '#.$XNOSPREAD) (% arg_y))
|
|---|
| [7361] | 427 | (set-nargs 2)
|
|---|
| 428 | (jmp-subprim .SPksignalerr))
|
|---|
| 429 |
|
|---|
| 430 | ;;; The idea here is to call METHOD in the same stack frame in
|
|---|
| 431 | ;;; which the lexpr was originally called. The lexpr can't
|
|---|
| 432 | ;;; have had any required arguments, %APPLY-LEXPR-TAIL-WISE
|
|---|
| 433 | ;;; must have been tail-called, and the frame built on lexpr
|
|---|
| 434 | ;;; entry must be in %rbp.
|
|---|
| [7963] | 435 | (defx8632lapfunction %apply-lexpr-tail-wise ((method arg_y) (args arg_z))
|
|---|
| 436 | (addl ($ x8632::node-size) (% esp)) ; discard extra return address
|
|---|
| 437 | (movl (% method) (% xfn)) ;temp1
|
|---|
| 438 | (movl (% args) (% esp))
|
|---|
| 439 | (popl (% imm0)) ;nargs
|
|---|
| 440 | (movl (@ x8632::lisp-frame.return-address (% ebp)) (% temp0))
|
|---|
| 441 | (movl (@ 0 (% ebp)) (% ebp))
|
|---|
| [9127] | 442 | (rcmpl (% imm0) ($ '2))
|
|---|
| [7361] | 443 | (jbe @pop-regs)
|
|---|
| [7963] | 444 | ;; More than 2 args; some must have been pushed by caller,
|
|---|
| [7361] | 445 | ;; so retain the reserved frame.
|
|---|
| 446 | (pop (% arg_z))
|
|---|
| 447 | (pop (% arg_y))
|
|---|
| 448 | (jmp @popped)
|
|---|
| 449 | @pop-regs
|
|---|
| [9127] | 450 | (rcmpl (% imm0) ($ '1))
|
|---|
| [7361] | 451 | (jb @discard)
|
|---|
| 452 | (ja @pop2)
|
|---|
| 453 | (pop (% arg_z))
|
|---|
| 454 | (jmp @discard)
|
|---|
| 455 | @pop2
|
|---|
| 456 | (pop (% arg_z))
|
|---|
| 457 | (pop (% arg_y))
|
|---|
| 458 | @discard
|
|---|
| 459 | (discard-reserved-frame)
|
|---|
| 460 | @popped
|
|---|
| [7963] | 461 | (push (% temp0)) ;return address
|
|---|
| [9127] | 462 | (movl (% xfn) (% temp0)) ;temp1 is also nargs
|
|---|
| 463 | (movl (% imm0) (% nargs))
|
|---|
| 464 | (jmp (% temp0)))
|
|---|
| [7361] | 465 |
|
|---|
| [7963] | 466 | (defun closure-function (fun)
|
|---|
| 467 | (while (and (functionp fun) (not (compiled-function-p fun)))
|
|---|
| 468 | (setq fun (%nth-immediate fun 0))
|
|---|
| 469 | (when (vectorp fun)
|
|---|
| 470 | (setq fun (svref fun 0))))
|
|---|
| 471 | fun)
|
|---|
| [7361] | 472 |
|
|---|
| 473 | ;;; For use by (setf (apply ...) ...)
|
|---|
| 474 | ;;; (apply+ f butlast last) = (apply f (append butlast (list last)))
|
|---|
| 475 |
|
|---|
| 476 | (defun apply+ (&lap function arg1 arg2 &rest other-args)
|
|---|
| 477 | (x86-lap-function apply+ ()
|
|---|
| 478 | (:arglist (function arg1 arg2 &rest other-args))
|
|---|
| 479 | (check-nargs 3 nil)
|
|---|
| [10575] | 480 | (popl (:rcontext x8632::tcr.save0)) ;save return address
|
|---|
| [7963] | 481 | ;; only two arg regs on x8632, so the caller will always push a frame
|
|---|
| 482 | (movl (% arg_z) (% temp0)) ; last
|
|---|
| 483 | (movl (% arg_y) (% arg_z)) ; butlast
|
|---|
| [8374] | 484 | (subl ($ '2) (% nargs)) ; remove count for butlast & last
|
|---|
| [8656] | 485 | (movd (% temp1) (% mm0)) ;save nargs (aka temp1) for later
|
|---|
| [7361] | 486 | ;; Do .SPspreadargz inline here
|
|---|
| [8656] | 487 | (xorl (%l temp1) (%l temp1))
|
|---|
| [10575] | 488 | (movl (% arg_z) (:rcontext x8632::tcr.save1)) ; save in case of error
|
|---|
| [7361] | 489 | (cmp-reg-to-nil arg_z)
|
|---|
| 490 | (je @done)
|
|---|
| [8656] | 491 | ;;(mark-as-imm temp1)
|
|---|
| [7361] | 492 | @loop
|
|---|
| [8656] | 493 | (extract-fulltag arg_z imm0)
|
|---|
| 494 | (cmpb ($ x8632::fulltag-cons) (%b imm0))
|
|---|
| [7361] | 495 | (jne @bad)
|
|---|
| [7963] | 496 | (%car arg_z arg_y)
|
|---|
| [7361] | 497 | (%cdr arg_z arg_z)
|
|---|
| [8656] | 498 | (addl ($ '1) (%l temp1))
|
|---|
| [7361] | 499 | (cmp-reg-to-nil arg_z)
|
|---|
| [7963] | 500 | (push (% arg_y))
|
|---|
| [7361] | 501 | (jne @loop)
|
|---|
| 502 | @done
|
|---|
| 503 | ;; nargs was at least 1 when we started spreading, and can't have gotten
|
|---|
| 504 | ;; any smaller.
|
|---|
| [7963] | 505 | (movd (% mm0) (% arg_y)) ;nargs from before loop
|
|---|
| [8656] | 506 | (addl (% arg_y) (% temp1)) ;did I mention nargs is temp1?
|
|---|
| [7963] | 507 | (movl (% temp0) (% arg_z))
|
|---|
| [7361] | 508 | (pop (% arg_y))
|
|---|
| [8374] | 509 | (addl ($ '1) (% nargs))
|
|---|
| [7361] | 510 | (load-constant funcall temp0)
|
|---|
| [10575] | 511 | (pushl (:rcontext x8632::tcr.save0)) ;return address
|
|---|
| 512 | (movapd (% fpzero) (:rcontext x8632::tcr.save0)) ;clear out spill area
|
|---|
| [7361] | 513 | (jmp-subprim .SPfuncall)
|
|---|
| [8656] | 514 | @bad ;error spreading list.
|
|---|
| 515 | (add (% temp1) (% esp)) ;discard whatever's been pushed
|
|---|
| [10575] | 516 | (movl (:rcontext x8632::tcr.save1) (% arg_z))
|
|---|
| 517 | (movapd (% fpzero) (:rcontext x8632::tcr.save0)) ;clear out spill area
|
|---|
| [7963] | 518 | (movl ($ '#.$XNOSPREAD) (% arg_y))
|
|---|
| [7361] | 519 | (set-nargs 2)
|
|---|
| 520 | (jmp-subprim .SPksignalerr) ))
|
|---|
| 521 |
|
|---|
| 522 |
|
|---|
| 523 |
|
|---|
| 524 | ;;; This needs to:
|
|---|
| [12084] | 525 | ;;; (a) call the .SPffcall subprimitive, which will discard the foreign
|
|---|
| 526 | ;;; stack frame allocated by WITH-VARIABLE-C-FRAME in %FF-CALL
|
|---|
| 527 | ;;; (b) re-establish the same foreign stack frame and store the results
|
|---|
| 528 | ;;; there.
|
|---|
| 529 | ;;;
|
|---|
| 530 | ;;; The flags argument tells us what/where the result is:
|
|---|
| 531 | ;;;
|
|---|
| 532 | ;;;; flags meaning
|
|---|
| 533 | ;;; 0 32-bit value in EAX
|
|---|
| 534 | ;;; 1 single-float value on x87 stack
|
|---|
| 535 | ;;; 2 double-float value on x87 stack
|
|---|
| 536 | ;;; 3 64-bit value with low half in EAX, high half in tcr.unboxed1
|
|---|
| [8906] | 537 |
|
|---|
| [9679] | 538 | (defx8632lapfunction %do-ff-call ((flags 4) #|(ra 0)|# (frame arg_y) (entry arg_z))
|
|---|
| [12084] | 539 | (save-stackargs-frame 1)
|
|---|
| [9679] | 540 | (push (% arg_y))
|
|---|
| 541 | (push (% arg_z))
|
|---|
| [7361] | 542 | (call-subprim .SPffcall)
|
|---|
| [9679] | 543 | ;; there might be an fp result on x87 stack, so don't use
|
|---|
| 544 | ;; any mmx instructions until the result has been read.
|
|---|
| [10575] | 545 | (movd (:rcontext x8632::tcr.foreign-sp) (% xmm0))
|
|---|
| [9679] | 546 | (movd (% xmm0) (@ (% frame)))
|
|---|
| [10575] | 547 | (movl (% frame) (:rcontext x8632::tcr.foreign-sp))
|
|---|
| [12084] | 548 | (cmpl ($ 0) (@ -4 (% ebp)))
|
|---|
| 549 | (jne @fp-or-doubleword)
|
|---|
| [8656] | 550 | (movl (% eax) (@ 4 (% frame)))
|
|---|
| [12084] | 551 | @done
|
|---|
| 552 | (movl ($ nil) (% arg_z))
|
|---|
| 553 | (restore-simple-frame)
|
|---|
| 554 | (single-value-return)
|
|---|
| 555 | @fp-or-doubleword
|
|---|
| 556 | (cmpl ($ '2) (@ -4 (% ebp)))
|
|---|
| 557 | (jl @single)
|
|---|
| 558 | (je @double)
|
|---|
| 559 | ;; high 32 bits in tcr.unboxed1 (see .SPffcall)
|
|---|
| 560 | (movl (% eax) (@ 4 (% frame)))
|
|---|
| 561 | (movl (:rcontext x8632::tcr.unboxed1) (% eax))
|
|---|
| 562 | (movl (% eax) (@ 8 (% frame)))
|
|---|
| [9679] | 563 | (jmp @done)
|
|---|
| 564 | @single
|
|---|
| 565 | (fstps (@ 4 (% frame)))
|
|---|
| 566 | (jmp @done)
|
|---|
| 567 | @double
|
|---|
| 568 | (fstpl (@ 4 (% frame)))
|
|---|
| [12084] | 569 | (jmp @done))
|
|---|
| 570 |
|
|---|
| [7361] | 571 | (defun %ff-call (entry &rest specs-and-vals)
|
|---|
| 572 | (declare (dynamic-extent specs-and-vals))
|
|---|
| 573 | (let* ((len (length specs-and-vals))
|
|---|
| 574 | (total-words 0))
|
|---|
| 575 | (declare (fixnum len total-words))
|
|---|
| 576 | (let* ((result-spec (or (car (last specs-and-vals)) :void))
|
|---|
| [8656] | 577 | (nargs (ash (the fixnum (1- len)) -1)))
|
|---|
| 578 | (declare (fixnum nargs))
|
|---|
| [7361] | 579 | (ecase result-spec
|
|---|
| [8656] | 580 | ((:address :unsigned-doubleword :signed-doubleword
|
|---|
| 581 | :single-float :double-float
|
|---|
| 582 | :signed-fullword :unsigned-fullword
|
|---|
| 583 | :signed-halfword :unsigned-halfword
|
|---|
| 584 | :signed-byte :unsigned-byte
|
|---|
| 585 | :void)
|
|---|
| 586 | (do* ((i 0 (1+ i))
|
|---|
| 587 | (specs specs-and-vals (cddr specs))
|
|---|
| 588 | (spec (car specs) (car specs)))
|
|---|
| 589 | ((= i nargs))
|
|---|
| 590 | (declare (fixnum i))
|
|---|
| 591 | (case spec
|
|---|
| [8906] | 592 | (:registers
|
|---|
| 593 | (error "don't know what to do with argspec ~s" spec))
|
|---|
| [8656] | 594 | ((:double-float :unsigned-doubleword :signed-doubleword)
|
|---|
| 595 | (incf total-words 2))
|
|---|
| 596 | ((:address :single-float
|
|---|
| 597 | :signed-fullword :unsigned-fullword
|
|---|
| 598 | :signed-halfword :unsigned-halfword
|
|---|
| 599 | :signed-byte :unsigned-byte)
|
|---|
| [7361] | 600 | (incf total-words))
|
|---|
| [8656] | 601 | (t (if (typep spec 'unsigned-byte)
|
|---|
| 602 | (incf total-words spec)
|
|---|
| 603 | (error "Invalid argument spec ~s" spec)))))
|
|---|
| 604 | ;; It's necessary to ensure that the C frame is the youngest thing on
|
|---|
| 605 | ;; the foreign stack here.
|
|---|
| 606 | (with-macptrs ((argptr))
|
|---|
| 607 | (with-variable-c-frame
|
|---|
| 608 | total-words frame
|
|---|
| 609 | (%setf-macptr-to-object argptr frame)
|
|---|
| [10560] | 610 | (let* ((offset 8))
|
|---|
| [8656] | 611 | (do* ((i 0 (1+ i))
|
|---|
| 612 | (specs specs-and-vals (cddr specs))
|
|---|
| 613 | (spec (car specs) (car specs))
|
|---|
| 614 | (val (cadr specs) (cadr specs)))
|
|---|
| 615 | ((= i nargs))
|
|---|
| 616 | (declare (fixnum i))
|
|---|
| 617 | (case spec
|
|---|
| 618 | (:double-float
|
|---|
| 619 | (setf (%get-double-float argptr offset) val)
|
|---|
| 620 | (incf offset 8))
|
|---|
| 621 | (:single-float
|
|---|
| 622 | (setf (%get-single-float argptr offset) val)
|
|---|
| 623 | (incf offset 4))
|
|---|
| 624 | (:signed-doubleword
|
|---|
| 625 | (setf (%%get-signed-longlong argptr offset) val)
|
|---|
| 626 | (incf offset 8))
|
|---|
| 627 | (:unsigned-doubleword
|
|---|
| 628 | (setf (%%get-unsigned-longlong argptr offset) val)
|
|---|
| 629 | (incf offset 8))
|
|---|
| 630 | (:address
|
|---|
| 631 | (setf (%get-ptr argptr offset) val)
|
|---|
| 632 | (incf offset 4))
|
|---|
| 633 | ((:signed-fullword :signed-halfword :signed-byte)
|
|---|
| 634 | (setf (%get-signed-natural argptr offset) val)
|
|---|
| 635 | (incf offset 4))
|
|---|
| 636 | ((:unsigned-fullword :unsigned-halfword :unsigned-byte)
|
|---|
| 637 | (setf (%get-natural argptr offset) val)
|
|---|
| 638 | (incf offset 4))
|
|---|
| 639 | (t
|
|---|
| 640 | (let* ((p 0))
|
|---|
| 641 | (declare (fixnum p))
|
|---|
| 642 | (dotimes (i (the fixnum spec))
|
|---|
| 643 | (setf (%get-ptr argptr offset) (%get-ptr val p))
|
|---|
| 644 | (incf p 4)
|
|---|
| 645 | (incf offset 4))))))
|
|---|
| [9679] | 646 | (let ((flags (case result-spec
|
|---|
| 647 | (:single-float 1)
|
|---|
| 648 | (:double-float 2)
|
|---|
| [12084] | 649 | ((:signed-doubleword :unsigned-doubleword) 3)
|
|---|
| [9679] | 650 | (t 0))))
|
|---|
| 651 | (%do-ff-call flags frame entry))
|
|---|
| [8656] | 652 | (ecase result-spec
|
|---|
| 653 | (:void nil)
|
|---|
| 654 | (:address (%get-ptr argptr 4))
|
|---|
| 655 | (:unsigned-byte (%get-unsigned-byte argptr 4))
|
|---|
| 656 | (:signed-byte (%get-signed-byte argptr 4))
|
|---|
| 657 | (:unsigned-halfword (%get-unsigned-word argptr 4))
|
|---|
| 658 | (:signed-halfword (%get-signed-word argptr 4))
|
|---|
| 659 | (:unsigned-fullword (%get-natural argptr 4))
|
|---|
| 660 | (:signed-fullword (%get-signed-natural argptr 4))
|
|---|
| 661 | (:unsigned-doubleword (%%get-unsigned-longlong argptr 4))
|
|---|
| 662 | (:signed-doubleword (%%get-signed-longlong argptr 4))
|
|---|
| [9679] | 663 | (:single-float (%get-single-float argptr 4))
|
|---|
| 664 | (:double-float (%get-double-float argptr 4)))))))))))
|
|---|
| [7361] | 665 |
|
|---|
| 666 | ;;; end of x86-def.lisp
|
|---|