📄 vm.lisp
字号:
;; non-descriptor registers, because of the conservative GC. ;; Therefore, we use different scs only to distinguish between ;; descriptor and non-descriptor values and to specify size. ;; immediate descriptor objects. Don't have to be seen by GC, but nothing ;; bad will happen if they are. (fixnums, characters, header values, etc). (any-reg registers :locations #.*qword-regs* :element-size 2 ; I think this is for the al/ah overlap thing :constant-scs (immediate) :save-p t :alternate-scs (control-stack)) ;; pointer descriptor objects -- must be seen by GC (descriptor-reg registers :locations #.*qword-regs* :element-size 2; :reserve-locations (#.eax-offset) :constant-scs (constant immediate) :save-p t :alternate-scs (control-stack)) ;; non-descriptor characters (character-reg registers :locations #!-sb-unicode #.*byte-regs* #!+sb-unicode #.*qword-regs* #!+sb-unicode #!+sb-unicode :element-size 2 #!-sb-unicode #!-sb-unicode :reserve-locations (#.al-offset) :constant-scs (immediate) :save-p t :alternate-scs (character-stack)) ;; non-descriptor SAPs (arbitrary pointers into address space) (sap-reg registers :locations #.*qword-regs* :element-size 2; :reserve-locations (#.eax-offset) :constant-scs (immediate) :save-p t :alternate-scs (sap-stack)) ;; non-descriptor (signed or unsigned) numbers (signed-reg registers :locations #.*qword-regs* :element-size 2 :constant-scs (immediate) :save-p t :alternate-scs (signed-stack)) (unsigned-reg registers :locations #.*qword-regs* :element-size 2 :constant-scs (immediate) :save-p t :alternate-scs (unsigned-stack)) ;; miscellaneous objects that must not be seen by GC. Used only as ;; temporaries. (word-reg registers :locations #.*word-regs* :element-size 2 ) (dword-reg registers :locations #.*dword-regs* :element-size 2 ) (byte-reg registers :locations #.*byte-regs* ) ;; that can go in the floating point registers ;; non-descriptor SINGLE-FLOATs (single-reg float-registers :locations #.(loop for i from 0 below 15 collect i) :constant-scs (fp-single-zero) :save-p t :alternate-scs (single-stack)) ;; non-descriptor DOUBLE-FLOATs (double-reg float-registers :locations #.(loop for i from 0 below 15 collect i) :constant-scs (fp-double-zero) :save-p t :alternate-scs (double-stack)) (complex-single-reg float-registers :locations #.(loop for i from 0 to 14 by 2 collect i) :element-size 2 :constant-scs () :save-p t :alternate-scs (complex-single-stack)) (complex-double-reg float-registers :locations #.(loop for i from 0 to 14 by 2 collect i) :element-size 2 :constant-scs () :save-p t :alternate-scs (complex-double-stack)) ;; a catch or unwind block (catch-block stack :element-size kludge-nondeterministic-catch-block-size))(eval-when (:compile-toplevel :load-toplevel :execute)(defparameter *byte-sc-names* '(#!-sb-unicode character-reg byte-reg #!-sb-unicode character-stack))(defparameter *word-sc-names* '(word-reg))(defparameter *dword-sc-names* '(dword-reg))(defparameter *qword-sc-names* '(any-reg descriptor-reg sap-reg signed-reg unsigned-reg control-stack signed-stack unsigned-stack sap-stack single-stack #!+sb-unicode character-reg #!+sb-unicode character-stack constant));;; added by jrd. I guess the right thing to do is to treat floats;;; as a separate size...;;;;;; These are used to (at least) determine operand size.(defparameter *float-sc-names* '(single-reg))(defparameter *double-sc-names* '(double-reg double-stack))) ; EVAL-WHEN;;;; miscellaneous TNs for the various registers(macrolet ((def-misc-reg-tns (sc-name &rest reg-names) (collect ((forms)) (dolist (reg-name reg-names) (let ((tn-name (symbolicate reg-name "-TN")) (offset-name (symbolicate reg-name "-OFFSET"))) ;; FIXME: It'd be good to have the special ;; variables here be named with the *FOO* ;; convention. (forms `(defparameter ,tn-name (make-random-tn :kind :normal :sc (sc-or-lose ',sc-name) :offset ,offset-name))))) `(progn ,@(forms))))) (def-misc-reg-tns unsigned-reg rax rbx rcx rdx rbp rsp rdi rsi r8 r9 r10 r11 r12 r13 r14 r15) (def-misc-reg-tns dword-reg eax ebx ecx edx ebp esp edi esi) (def-misc-reg-tns word-reg ax bx cx dx bp sp di si) (def-misc-reg-tns byte-reg al cl dl bl sil dil r8b r9b r10b r11b r12b r13b r14b r15b) (def-misc-reg-tns single-reg float0 float1 float2 float3 float4 float5 float6 float7 float8 float9 float10 float11 float12 float13 float14 float15));; A register that's never used by the code generator, and can therefore;; be used as an assembly temporary in cases where a VOP :TEMPORARY can't;; be used.(defparameter temp-reg-tn r11-tn);;; TNs for registers used to pass arguments(defparameter *register-arg-tns* (mapcar (lambda (register-arg-name) (symbol-value (symbolicate register-arg-name "-TN"))) *register-arg-names*))(defparameter thread-base-tn (make-random-tn :kind :normal :sc (sc-or-lose 'unsigned-reg ) :offset r12-offset))(defparameter fp-single-zero-tn (make-random-tn :kind :normal :sc (sc-or-lose 'single-reg) :offset 15))(defparameter fp-double-zero-tn (make-random-tn :kind :normal :sc (sc-or-lose 'double-reg) :offset 15));;; If value can be represented as an immediate constant, then return;;; the appropriate SC number, otherwise return NIL.(!def-vm-support-routine immediate-constant-sc (value) (typecase value ((or (integer #.sb!xc:most-negative-fixnum #.sb!xc:most-positive-fixnum) character) (sc-number-or-lose 'immediate)) (symbol (when (static-symbol-p value) (sc-number-or-lose 'immediate))) (single-float (if (eql value 0f0) (sc-number-or-lose 'fp-single-zero ) nil)) (double-float (if (eql value 0d0) (sc-number-or-lose 'fp-double-zero ) nil))));;;; miscellaneous function call parameters;;; offsets of special stack frame locations(def!constant ocfp-save-offset 0)(def!constant return-pc-save-offset 1)(def!constant code-save-offset 2)(def!constant lra-save-offset return-pc-save-offset) ; ?;;; This is used by the debugger.(def!constant single-value-return-byte-offset 3);;; This function is called by debug output routines that want a pretty name;;; for a TN's location. It returns a thing that can be printed with PRINC.(!def-vm-support-routine location-print-name (tn) (declare (type tn tn)) (let* ((sc (tn-sc tn)) (sb (sb-name (sc-sb sc))) (offset (tn-offset tn))) (ecase sb (registers (let* ((sc-name (sc-name sc)) (name-vec (cond ((member sc-name *byte-sc-names*) *byte-register-names*) ((member sc-name *word-sc-names*) *word-register-names*) ((member sc-name *dword-sc-names*) *dword-register-names*) ((member sc-name *qword-sc-names*) *qword-register-names*)))) (or (and name-vec (< -1 offset (length name-vec)) (svref name-vec offset)) ;; FIXME: Shouldn't this be an ERROR? (format nil "<unknown reg: off=~W, sc=~A>" offset sc-name)))) (float-registers (format nil "FLOAT~D" offset)) (stack (format nil "S~D" offset)) (constant (format nil "Const~D" offset)) (immediate-constant "Immed") (noise (symbol-name (sc-name sc))))));;; FIXME: Could this, and everything that uses it, be made #!+SB-SHOW?(defun dwords-for-quad (value) (let* ((lo (logand value (1- (ash 1 32)))) (hi (ash value -32))) (values lo hi)))(defun words-for-dword (value) (let* ((lo (logand value (1- (ash 1 16)))) (hi (ash value -16))) (values lo hi)))(def!constant cfp-offset rbp-offset) ; pfw - needed by stuff in /code(!def-vm-support-routine combination-implementation-style (node) (declare (type sb!c::combination node) (ignore node)) (values :default nil))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -