⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 values.lisp

📁 开源跨平台Lisp编译器
💻 LISP
字号:
;;;; unknown-values VOPs for the x86 VM;;;; This software is part of the SBCL system. See the README file for;;;; more information.;;;;;;;; This software is derived from the CMU CL system, which was;;;; written at Carnegie Mellon University and released into the;;;; public domain. The software is in the public domain and is;;;; provided with absolutely no warranty. See the COPYING and CREDITS;;;; files for more information.(in-package "SB!VM")(define-vop (reset-stack-pointer)  (:args (ptr :scs (any-reg)))  (:generator 1    (move esp-tn ptr)))(define-vop (%%nip-values)  (:args (last-nipped-ptr :scs (any-reg) :target edi)         (last-preserved-ptr :scs (any-reg) :target esi)         (moved-ptrs :scs (any-reg) :more t))  (:results (r-moved-ptrs :scs (any-reg) :more t)            ;; same as MOVED-PTRS            )  (:temporary (:sc any-reg :offset esi-offset) esi)  (:temporary (:sc any-reg :offset edi-offset) edi)  (:ignore r-moved-ptrs)  (:generator 1    (move edi last-nipped-ptr)    (move esi last-preserved-ptr)    (inst sub esi n-word-bytes)    (inst sub edi n-word-bytes)    (inst cmp esp-tn esi)    (inst jmp :a done)    (inst std)    LOOP    (inst movs :dword)    (inst cmp esp-tn esi)    (inst jmp :be loop)    (inst cld)    DONE    (inst lea esp-tn (make-ea :dword :base edi :disp n-word-bytes))    (inst sub edi esi)    (loop for moved = moved-ptrs then (tn-ref-across moved)          while moved          do (inst add (tn-ref-tn moved) edi))));;; Push some values onto the stack, returning the start and number of values;;; pushed as results. It is assumed that the Vals are wired to the standard;;; argument locations. Nvals is the number of values to push.;;;;;; The generator cost is pseudo-random. We could get it right by defining a;;; bogus SC that reflects the costs of the memory-to-memory moves for each;;; operand, but this seems unworthwhile.(define-vop (push-values)  (:args (vals :more t))  (:temporary (:sc unsigned-reg :to (:result 0) :target start) temp)  (:results (start) (count))  (:info nvals)  (:generator 20    (move temp esp-tn)                  ; WARN pointing 1 below    (do ((val vals (tn-ref-across val)))        ((null val))      (inst push (tn-ref-tn val)))    (move start temp)    (inst mov count (fixnumize nvals))));;; Push a list of values on the stack, returning Start and Count as used in;;; unknown values continuations.(define-vop (values-list)  (:args (arg :scs (descriptor-reg) :target list))  (:arg-types list)  (:policy :fast-safe)  (:results (start :scs (any-reg))            (count :scs (any-reg)))  (:temporary (:sc descriptor-reg :from (:argument 0) :to (:result 1)) list)  (:temporary (:sc descriptor-reg :to (:result 1)) nil-temp)  (:temporary (:sc unsigned-reg :offset eax-offset :to (:result 1)) eax)  (:vop-var vop)  (:save-p :compute-only)  (:generator 0    (move list arg)    (move start esp-tn)                 ; WARN pointing 1 below    (inst mov nil-temp nil-value)    LOOP    (inst cmp list nil-temp)    (inst jmp :e done)    (pushw list cons-car-slot list-pointer-lowtag)    (loadw list list cons-cdr-slot list-pointer-lowtag)    (inst mov eax list)    (inst and al-tn lowtag-mask)    (inst cmp al-tn list-pointer-lowtag)    (inst jmp :e loop)    (error-call vop 'bogus-arg-to-values-list-error list)    DONE    (inst mov count start)              ; start is high address    (inst sub count esp-tn)))           ; stackp is low address;;; Copy the more arg block to the top of the stack so we can use them;;; as function arguments.;;;;;; Accepts a context as produced by more-arg-context; points to the first;;; value on the stack, not 4 bytes above as in other contexts.;;;;;; Return a context that is 4 bytes above the first value, suitable for;;; defining a new stack frame.(define-vop (%more-arg-values)  (:args (context :scs (descriptor-reg any-reg) :target src)         (skip :scs (any-reg immediate))         (num :scs (any-reg) :target count))  (:arg-types * positive-fixnum positive-fixnum)  (:temporary (:sc any-reg :offset esi-offset :from (:argument 0)) src)  (:temporary (:sc descriptor-reg :offset eax-offset) temp)  (:temporary (:sc unsigned-reg :offset ecx-offset) loop-index)  (:results (start :scs (any-reg))            (count :scs (any-reg)))  (:generator 20    (sc-case skip      (immediate       (cond ((zerop (tn-value skip))              (move src context)              (move count num))             (t              (inst lea src (make-ea :dword :base context                                     :disp (- (* (tn-value skip)                                                 n-word-bytes))))              (move count num)              (inst sub count (* (tn-value skip) n-word-bytes)))))      (any-reg       (move src context)       (inst sub src skip)       (move count num)       (inst sub count skip)))    (move loop-index count)    (inst mov start esp-tn)    (inst jecxz done)  ; check for 0 count?    (inst sub esp-tn count)    (inst sub src count)    LOOP    (inst mov temp (make-ea :dword :base src :index loop-index))    (inst sub loop-index n-word-bytes)    (inst mov (make-ea :dword :base esp-tn :index loop-index) temp)    (inst jmp :nz LOOP)    DONE    ))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -