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

📄 vm.lisp

📁 开源跨平台Lisp编译器
💻 LISP
📖 第 1 页 / 共 2 页
字号:
;;;; miscellaneous VM definition noise for the x86;;;; 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");;; the size of an INTEGER representation of a SYSTEM-AREA-POINTER, i.e.;;; size of a native memory address(deftype sap-int () '(unsigned-byte 32));;;; register specs(eval-when (:compile-toplevel :load-toplevel :execute)  (defvar *byte-register-names* (make-array 8 :initial-element nil))  (defvar *word-register-names* (make-array 16 :initial-element nil))  (defvar *dword-register-names* (make-array 16 :initial-element nil))  (defvar *float-register-names* (make-array 8 :initial-element nil)))(macrolet ((defreg (name offset size)             (let ((offset-sym (symbolicate name "-OFFSET"))                   (names-vector (symbolicate "*" size "-REGISTER-NAMES*")))               `(progn                  (eval-when (:compile-toplevel :load-toplevel :execute)                    ;; EVAL-WHEN is necessary because stuff like #.EAX-OFFSET                    ;; (in the same file) depends on compile-time evaluation                    ;; of the DEFCONSTANT. -- AL 20010224                    (def!constant ,offset-sym ,offset))                  (setf (svref ,names-vector ,offset-sym)                        ,(symbol-name name)))))           ;; FIXME: It looks to me as though DEFREGSET should also           ;; define the related *FOO-REGISTER-NAMES* variable.           (defregset (name &rest regs)             `(eval-when (:compile-toplevel :load-toplevel :execute)                (defparameter ,name                  (list ,@(mapcar (lambda (name)                                    (symbolicate name "-OFFSET"))                                  regs))))))  ;; byte registers  ;;  ;; Note: the encoding here is different than that used by the chip.  ;; We use this encoding so that the compiler thinks that AX (and  ;; EAX) overlap AL and AH instead of AL and CL.  (defreg al 0 :byte)  (defreg ah 1 :byte)  (defreg cl 2 :byte)  (defreg ch 3 :byte)  (defreg dl 4 :byte)  (defreg dh 5 :byte)  (defreg bl 6 :byte)  (defreg bh 7 :byte)  (defregset *byte-regs* al ah cl ch dl dh bl bh)  ;; word registers  (defreg ax 0 :word)  (defreg cx 2 :word)  (defreg dx 4 :word)  (defreg bx 6 :word)  (defreg sp 8 :word)  (defreg bp 10 :word)  (defreg si 12 :word)  (defreg di 14 :word)  (defregset *word-regs* ax cx dx bx si di)  ;; double word registers  (defreg eax 0 :dword)  (defreg ecx 2 :dword)  (defreg edx 4 :dword)  (defreg ebx 6 :dword)  (defreg esp 8 :dword)  (defreg ebp 10 :dword)  (defreg esi 12 :dword)  (defreg edi 14 :dword)  (defregset *dword-regs* eax ecx edx ebx esi edi)  ;; floating point registers  (defreg fr0 0 :float)  (defreg fr1 1 :float)  (defreg fr2 2 :float)  (defreg fr3 3 :float)  (defreg fr4 4 :float)  (defreg fr5 5 :float)  (defreg fr6 6 :float)  (defreg fr7 7 :float)  (defregset *float-regs* fr0 fr1 fr2 fr3 fr4 fr5 fr6 fr7)  ;; registers used to pass arguments  ;;  ;; the number of arguments/return values passed in registers  (def!constant  register-arg-count 3)  ;; names and offsets for registers used to pass arguments  (eval-when (:compile-toplevel :load-toplevel :execute)    (defparameter *register-arg-names* '(edx edi esi)))  (defregset    *register-arg-offsets* edx edi esi));;;; SB definitions;;; Despite the fact that there are only 8 different registers, we consider;;; them 16 in order to describe the overlap of byte registers. The only;;; thing we need to represent is what registers overlap. Therefore, we;;; consider bytes to take one unit, and words or dwords to take two. We;;; don't need to tell the difference between words and dwords, because;;; you can't put two words in a dword register.(define-storage-base registers :finite :size 16);;; jrd changed this from size 1 to size 8. It doesn't seem to make much;;; sense to use the 387's idea of a stack; 8 separate registers is easier;;; to deal with.;;; the old way:;;;   (define-storage-base float-registers :finite :size 1);;; the new way:(define-storage-base float-registers :finite :size 8)(define-storage-base stack :unbounded :size 8)(define-storage-base constant :non-packed)(define-storage-base immediate-constant :non-packed)(define-storage-base noise :unbounded :size 2);;;; SC definitions;;; a handy macro so we don't have to keep changing all the numbers whenever;;; we insert a new storage class;;;(defmacro !define-storage-classes (&rest classes)  (collect ((forms))    (let ((index 0))      (dolist (class classes)        (let* ((sc-name (car class))               (constant-name (symbolicate sc-name "-SC-NUMBER")))          (forms `(define-storage-class ,sc-name ,index                    ,@(cdr class)))          (forms `(def!constant ,constant-name ,index))          (incf index))))    `(progn       ,@(forms))));;; The DEFINE-STORAGE-CLASS call for CATCH-BLOCK refers to the size;;; of CATCH-BLOCK. The size of CATCH-BLOCK isn't calculated until;;; later in the build process, and the calculation is entangled with;;; code which has lots of predependencies, including dependencies on;;; the prior call of DEFINE-STORAGE-CLASS. The proper way to;;; unscramble this would be to untangle the code, so that the code;;; which calculates the size of CATCH-BLOCK can be separated from the;;; other lots-of-dependencies code, so that the code which calculates;;; the size of CATCH-BLOCK can be executed early, so that this value;;; is known properly at this point in compilation. However, that;;; would be a lot of editing of code that I (WHN 19990131) can't test;;; until the project is complete. So instead, I set the correct value;;; by hand here (a sort of nondeterministic guess of the right;;; answer:-) and add an assertion later, after the value is;;; calculated, that the original guess was correct.;;;;;; (What a KLUDGE! Anyone who wants to come in and clean up this mess;;; has my gratitude.) (FIXME: Maybe this should be me..)(eval-when (:compile-toplevel :load-toplevel :execute)  (def!constant kludge-nondeterministic-catch-block-size      #!-win32 6 #!+win32 8))(!define-storage-classes  ;; non-immediate constants in the constant pool  (constant constant)  ;; some FP constants can be generated in the i387 silicon  (fp-constant immediate-constant)  (immediate immediate-constant)  ;;  ;; the stacks  ;;  ;; the control stack  (control-stack stack)                 ; may be pointers, scanned by GC  ;; the non-descriptor stacks  (signed-stack stack)                  ; (signed-byte 32)  (unsigned-stack stack)                ; (unsigned-byte 32)  (character-stack stack)               ; non-descriptor characters.  (sap-stack stack)                     ; System area pointers.  (single-stack stack)                  ; single-floats  (double-stack stack :element-size 2)  ; double-floats.  #!+long-float  (long-stack stack :element-size 3)    ; long-floats.  (complex-single-stack stack :element-size 2)  ; complex-single-floats  (complex-double-stack stack :element-size 4)  ; complex-double-floats  #!+long-float  (complex-long-stack stack :element-size 6)    ; complex-long-floats  ;;  ;; magic SCs  ;;  (ignore-me noise)  ;;  ;; things that can go in the integer registers  ;;  ;; On the X86, we don't have to distinguish between descriptor and  ;; 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 #.*dword-regs*           :element-size 2;          :reserve-locations (#.eax-offset)           :constant-scs (immediate)           :save-p t           :alternate-scs (control-stack))  ;; pointer descriptor objects -- must be seen by GC  (descriptor-reg registers                  :locations #.*dword-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 #.*dword-regs*                 #!+sb-unicode #!+sb-unicode                 :element-size 2                 #!-sb-unicode #!-sb-unicode                 :reserve-locations (#.ah-offset #.al-offset)                 :constant-scs (immediate)                 :save-p t                 :alternate-scs (character-stack))  ;; non-descriptor SAPs (arbitrary pointers into address space)  (sap-reg registers           :locations #.*dword-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 #.*dword-regs*

⌨️ 快捷键说明

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