call.lisp

来自「开源跨平台Lisp编译器」· LISP 代码 · 共 1,244 行 · 第 1/4 页

LISP
1,244
字号
     (:vop-var vop)     (:info ,@(unless (or variable (eq return :tail)) '(arg-locs))            ,@(unless variable '(nargs))            ,@(when (eq return :fixed) '(nvals))            step-instrumenting)     (:ignore #!+gengc ,@(unless (eq return :tail) '(return-pc-pass))              ,@(unless (or variable (eq return :tail)) '(arg-locs))              ,@(unless variable '(args))              ;; Step instrumentation for full calls not implemented yet.              ;; See the PPC backend for an example.              step-instrumenting)     (:temporary (:sc descriptor-reg                  :offset ocfp-offset                  :from (:argument 1)                  ,@(unless (eq return :fixed)                      '(:to :eval)))                 ocfp-pass)     (:temporary (:sc descriptor-reg                  :offset #!-gengc lra-offset #!+gengc ra-offset                  :from (:argument ,(if (eq return :tail) 2 1))                  :to :eval)                 return-pc-pass)     ,@(if named         `((:temporary (:sc descriptor-reg :offset fdefn-offset                        :from (:argument ,(if (eq return :tail) 0 1))                        :to :eval)                       name-pass))         `((:temporary (:sc descriptor-reg :offset lexenv-offset                        :from (:argument ,(if (eq return :tail) 0 1))                        :to :eval)                       lexenv)           #!-gengc           (:temporary (:scs (descriptor-reg) :from (:argument 0) :to :eval)                       function)))     (:temporary (:sc any-reg :offset nargs-offset :to :eval)                 nargs-pass)     ,@(when variable         (mapcar (lambda (name offset)                   `(:temporary (:sc descriptor-reg                                     :offset ,offset                                     :to :eval)                                ,name))                 register-arg-names *register-arg-offsets*))     ,@(when (eq return :fixed)         '((:temporary (:scs (descriptor-reg) :from :eval) move-temp)))     ,@(unless (eq return :tail)         '((:temporary (:scs (non-descriptor-reg)) temp)           (:temporary (:sc control-stack :offset nfp-save-offset) nfp-save)))     (:temporary (:sc interior-reg :offset lip-offset) entry-point)     (:generator ,(+ (if named 5 0)                     (if variable 19 1)                     (if (eq return :tail) 0 10)                     15                     (if (eq return :unknown) 25 0))       (let* ((cur-nfp (current-nfp-tn vop))              ,@(unless (eq return :tail)                  '((lra-label (gen-label))))              (filler               (remove nil                       (list :load-nargs                             ,@(if (eq return :tail)                                   '((unless (location= ocfp ocfp-pass)                                       :load-ocfp)                                     (unless (location= return-pc                                                        return-pc-pass)                                       :load-return-pc)                                     (when cur-nfp                                       :frob-nfp))                                   '(#!-gengc                                     :comp-lra                                     (when cur-nfp                                       :frob-nfp)                                     :save-fp                                     :load-fp))))))         (flet ((do-next-filler ()                  (let* ((next (pop filler))                         (what (if (consp next) (car next) next)))                    (ecase what                      (:load-nargs                       ,@(if variable                             `((inst subq csp-tn new-fp nargs-pass)                               ,@(let ((index -1))                                   (mapcar (lambda (name)                                             `(inst ldl ,name                                                    ,(ash (incf index)                                                          word-shift)                                                    new-fp))                                           register-arg-names)))                             '((inst li (fixnumize nargs) nargs-pass))))                      ,@(if (eq return :tail)                            '((:load-ocfp                               (sc-case ocfp                                 (any-reg                                  (inst move ocfp ocfp-pass))                                 (control-stack                                  (inst ldl ocfp-pass                                        (ash (tn-offset ocfp)                                             word-shift)                                        cfp-tn))))                              (:load-return-pc                               (sc-case return-pc                                 (#!-gengc descriptor-reg #!+gengc any-reg                                  (inst move return-pc return-pc-pass))                                 (control-stack                                  (inst ldl return-pc-pass                                        (ash (tn-offset return-pc)                                             word-shift)                                         cfp-tn))))                              (:frob-nfp                               (inst addq cur-nfp                                     (bytes-needed-for-non-descriptor-stack-frame)                                     nsp-tn)))                            `(#!-gengc                              (:comp-lra                               (inst compute-lra-from-code                                     return-pc-pass code-tn lra-label temp))                              (:frob-nfp                               (store-stack-tn nfp-save cur-nfp))                              (:save-fp                               (inst move cfp-tn ocfp-pass))                              (:load-fp                               ,(if variable                                    '(move new-fp cfp-tn)                                    '(if (> nargs register-arg-count)                                         (move new-fp cfp-tn)                                         (move csp-tn cfp-tn)))                               (trace-table-entry trace-table-call-site))))                      ((nil))))))           ,@(if named                 `((sc-case name                     (descriptor-reg (move name name-pass))                     (control-stack                      (inst ldl name-pass                            (ash (tn-offset name) word-shift) cfp-tn)                      (do-next-filler))                     (constant                      (inst ldl name-pass                            (- (ash (tn-offset name) word-shift)                               other-pointer-lowtag) code-tn)                      (do-next-filler)))                   (inst ldl entry-point                         (- (ash fdefn-raw-addr-slot word-shift)                            other-pointer-lowtag) name-pass)                   (do-next-filler))                 `((sc-case arg-fun                     (descriptor-reg (move arg-fun lexenv))                     (control-stack                      (inst ldl lexenv                            (ash (tn-offset arg-fun) word-shift) cfp-tn)                      (do-next-filler))                     (constant                      (inst ldl lexenv                            (- (ash (tn-offset arg-fun) word-shift)                               other-pointer-lowtag) code-tn)                      (do-next-filler)))                   #!-gengc                   (inst ldl function                         (- (ash closure-fun-slot word-shift)                            fun-pointer-lowtag) lexenv)                   #!-gengc                   (do-next-filler)                   #!-gengc                   (inst addq function                         (- (ash simple-fun-code-offset word-shift)                            fun-pointer-lowtag) entry-point)                   #!+gengc                   (inst ldl entry-point                         (- (ash closure-entry-point-slot word-shift)                            fun-pointer-lowtag) lexenv)                   #!+gengc                   (do-next-filler)))           (loop             (if (cdr filler)                 (do-next-filler)                 (return)))           (note-this-location vop :call-site)           (do-next-filler)           (inst jsr zero-tn entry-point))         ,@(ecase return             (:fixed              '((trace-table-entry trace-table-normal)                (emit-return-pc lra-label)                (default-unknown-values vop values nvals                                        move-temp temp lra-label)                (maybe-load-stack-nfp-tn cur-nfp nfp-save temp)))             (:unknown              '((trace-table-entry trace-table-normal)                (emit-return-pc lra-label)                (note-this-location vop :unknown-return)                (receive-unknown-values values-start nvals start count                                        lra-label temp)                (maybe-load-stack-nfp-tn cur-nfp nfp-save temp)))             (:tail))))))(define-full-call call nil :fixed nil)(define-full-call call-named t :fixed nil)(define-full-call multiple-call nil :unknown nil)(define-full-call multiple-call-named t :unknown nil)(define-full-call tail-call nil :tail nil)(define-full-call tail-call-named t :tail nil)(define-full-call call-variable nil :fixed t)(define-full-call multiple-call-variable nil :unknown t);;; This is defined separately, since it needs special code that blits;;; the arguments down.(define-vop (tail-call-variable)  (:args   (args-arg :scs (any-reg) :target args)   (function-arg :scs (descriptor-reg) :target lexenv)   (ocfp-arg :scs (any-reg) :target ocfp)   (lra-arg :scs (#!-gengc descriptor-reg #!+gengc any-reg) :target lra))  (:temporary (:sc any-reg :offset nl0-offset :from (:argument 0)) args)  (:temporary (:sc any-reg :offset lexenv-offset :from (:argument 1)) lexenv)  (:temporary (:sc any-reg :offset ocfp-offset :from (:argument 2)) ocfp)  (:temporary (:sc any-reg :offset #!-gengc lra-offset #!+gengc ra-offset                   :from (:argument 3)) lra)  (:temporary (:scs (non-descriptor-reg)) temp)  (:vop-var vop)  (:generator 75    ;; Move these into the passing locations if they are not already there.    (move args-arg args)    (move function-arg lexenv)    (move ocfp-arg ocfp)    (move lra-arg lra)    ;; Clear the number stack if anything is there.    (let ((cur-nfp (current-nfp-tn vop)))      (when cur-nfp        (inst addq cur-nfp (bytes-needed-for-non-descriptor-stack-frame)              nsp-tn)))    ;; And jump to the assembly-routine that does the bliting.    (inst li (make-fixup 'tail-call-variable :assembly-routine) temp)    (inst jmp zero-tn temp)));;;; unknown values return;;; Return a single value using the unknown-values convention.(define-vop (return-single)  (:args (ocfp :scs (any-reg))         #!-gengc (return-pc :scs (descriptor-reg))         #!+gengc (return-pc :scs (any-reg) :target ra)         (value))  (:ignore value)  #!-gengc (:temporary (:scs (interior-reg)) lip)  #!+gengc (:temporary (:sc any-reg :offset ra-offset :from (:argument 1)) ra)  #!+gengc (:temporary (:scs (any-reg) :from (:argument 1)) temp)  (:vop-var vop)  (:generator 6    ;; Clear the number stack.    (trace-table-entry trace-table-fun-epilogue)    (let ((cur-nfp (current-nfp-tn vop)))      (when cur-nfp        (inst addq cur-nfp (bytes-needed-for-non-descriptor-stack-frame)              nsp-tn)))    ;; Clear the control stack, and restore the frame pointer.    (move cfp-tn csp-tn)    (move ocfp cfp-tn)    ;; Out of here.    #!-gengc (lisp-return return-pc lip :offset 2)    #!+gengc    (progn      (inst addq return-pc (* 2 n-word-bytes) temp)      (unless (location= ra return-pc)        (inst move ra return-pc))      (inst ret zero-tn temp 1))    (trace-table-entry trace-table-normal)));;; Do unknown-values return of a fixed number of values. The Values;;; are required to be set up in the standard passing locations. Nvals;;; is the number of values returned.;;;;;; If returning a single value, then deallocate the current frame,;;; restore FP and jump to the single-value entry at Return-PC + 8.;;;;;; If returning other than one value, then load the number of values;;; returned, NIL out unsupplied values registers, restore FP and;;; return at Return-PC. When there are stack values, we must;;; initialize the argument pointer to point to the beginning of the;;; values block (which is the beginning of the current frame.)(define-vop (return)  (:args (ocfp :scs (any-reg))         (return-pc :scs (#!-gengc descriptor-reg #!+gengc any-reg)                    :to (:eval 1)                    #!+gengc :target #!+gengc ra)         (values :more t))  (:ignore values)  (:info nvals)  (:temporary (:sc descriptor-reg :offset a0-offset :from (:eval 0)) a0)  (:temporary (:sc descriptor-reg :offset a1-offset :from (:eval 0)) a1)  (:temporary (:sc descriptor-reg :offset a2-offset :from (:eval 0)) a2)  (:temporary (:sc descriptor-reg :offset a3-offset :from (:eval 0)) a3)  (:temporary (:sc descriptor-reg :offset a4-offset :from (:eval 0)) a4)

⌨️ 快捷键说明

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