📄 insts.lisp
字号:
(eval-when (:compile-toplevel :execute) (defun swap-if (direction field1 separator field2) `(:if (,direction :constant 0) (,field1 ,separator ,field2) (,field2 ,separator ,field1))))(sb!disassem:define-instruction-format (byte 8 :default-printer '(:name)) (op :field (byte 8 0)) ;; optional fields (accum :type 'accum) (imm))(sb!disassem:define-instruction-format (simple 8) (op :field (byte 7 1)) (width :field (byte 1 0) :type 'width) ;; optional fields (accum :type 'accum) (imm))(sb!disassem:define-instruction-format (two-bytes 16 :default-printer '(:name)) (op :fields (list (byte 8 0) (byte 8 8))));;; Same as simple, but with direction bit(sb!disassem:define-instruction-format (simple-dir 8 :include 'simple) (op :field (byte 6 2)) (dir :field (byte 1 1)));;; Same as simple, but with the immediate value occurring by default,;;; and with an appropiate printer.(sb!disassem:define-instruction-format (accum-imm 8 :include 'simple :default-printer '(:name :tab accum ", " imm)) (imm :type 'imm-data))(sb!disassem:define-instruction-format (reg-no-width 8 :default-printer '(:name :tab reg)) (op :field (byte 5 3)) (reg :field (byte 3 0) :type 'word-reg) ;; optional fields (accum :type 'word-accum) (imm));;; adds a width field to reg-no-width(sb!disassem:define-instruction-format (reg 8 :default-printer '(:name :tab reg)) (op :field (byte 4 4)) (width :field (byte 1 3) :type 'width) (reg :field (byte 3 0) :type 'reg) ;; optional fields (accum :type 'accum) (imm) );;; Same as reg, but with direction bit(sb!disassem:define-instruction-format (reg-dir 8 :include 'reg) (op :field (byte 3 5)) (dir :field (byte 1 4)))(sb!disassem:define-instruction-format (two-bytes 16 :default-printer '(:name)) (op :fields (list (byte 8 0) (byte 8 8))))(sb!disassem:define-instruction-format (reg-reg/mem 16 :default-printer `(:name :tab reg ", " reg/mem)) (op :field (byte 7 1)) (width :field (byte 1 0) :type 'width) (reg/mem :fields (list (byte 2 14) (byte 3 8)) :type 'reg/mem) (reg :field (byte 3 11) :type 'reg) ;; optional fields (imm));;; same as reg-reg/mem, but with direction bit(sb!disassem:define-instruction-format (reg-reg/mem-dir 16 :include 'reg-reg/mem :default-printer `(:name :tab ,(swap-if 'dir 'reg/mem ", " 'reg))) (op :field (byte 6 2)) (dir :field (byte 1 1)));;; Same as reg-rem/mem, but uses the reg field as a second op code.(sb!disassem:define-instruction-format (reg/mem 16 :default-printer '(:name :tab reg/mem)) (op :fields (list (byte 7 1) (byte 3 11))) (width :field (byte 1 0) :type 'width) (reg/mem :fields (list (byte 2 14) (byte 3 8)) :type 'sized-reg/mem) ;; optional fields (imm));;; Same as reg/mem, but with the immediate value occurring by default,;;; and with an appropiate printer.(sb!disassem:define-instruction-format (reg/mem-imm 16 :include 'reg/mem :default-printer '(:name :tab reg/mem ", " imm)) (reg/mem :type 'sized-reg/mem) (imm :type 'imm-data));;; Same as reg/mem, but with using the accumulator in the default printer(sb!disassem:define-instruction-format (accum-reg/mem 16 :include 'reg/mem :default-printer '(:name :tab accum ", " reg/mem)) (reg/mem :type 'reg/mem) ; don't need a size (accum :type 'accum));;; Same as reg-reg/mem, but with a prefix of #b00001111(sb!disassem:define-instruction-format (ext-reg-reg/mem 24 :default-printer `(:name :tab reg ", " reg/mem)) (prefix :field (byte 8 0) :value #b00001111) (op :field (byte 7 9)) (width :field (byte 1 8) :type 'width) (reg/mem :fields (list (byte 2 22) (byte 3 16)) :type 'reg/mem) (reg :field (byte 3 19) :type 'reg) ;; optional fields (imm));;; Same as reg/mem, but with a prefix of #b00001111(sb!disassem:define-instruction-format (ext-reg/mem 24 :default-printer '(:name :tab reg/mem)) (prefix :field (byte 8 0) :value #b00001111) (op :fields (list (byte 7 9) (byte 3 19))) (width :field (byte 1 8) :type 'width) (reg/mem :fields (list (byte 2 22) (byte 3 16)) :type 'sized-reg/mem) ;; optional fields (imm))(sb!disassem:define-instruction-format (ext-reg/mem-imm 24 :include 'ext-reg/mem :default-printer '(:name :tab reg/mem ", " imm)) (imm :type 'imm-data));;;; This section was added by jrd, for fp instructions.;;; regular fp inst to/from registers/memory(sb!disassem:define-instruction-format (floating-point 16 :default-printer `(:name :tab reg/mem)) (prefix :field (byte 5 3) :value #b11011) (op :fields (list (byte 3 0) (byte 3 11))) (reg/mem :fields (list (byte 2 14) (byte 3 8)) :type 'reg/mem));;; fp insn to/from fp reg(sb!disassem:define-instruction-format (floating-point-fp 16 :default-printer `(:name :tab fp-reg)) (prefix :field (byte 5 3) :value #b11011) (suffix :field (byte 2 14) :value #b11) (op :fields (list (byte 3 0) (byte 3 11))) (fp-reg :field (byte 3 8) :type 'fp-reg));;; fp insn to/from fp reg, with the reversed source/destination flag.(sb!disassem:define-instruction-format (floating-point-fp-d 16 :default-printer `(:name :tab ,(swap-if 'd "ST0" ", " 'fp-reg))) (prefix :field (byte 5 3) :value #b11011) (suffix :field (byte 2 14) :value #b11) (op :fields (list (byte 2 0) (byte 3 11))) (d :field (byte 1 2)) (fp-reg :field (byte 3 8) :type 'fp-reg));;; (added by (?) pfw);;; fp no operand isns(sb!disassem:define-instruction-format (floating-point-no 16 :default-printer '(:name)) (prefix :field (byte 8 0) :value #b11011001) (suffix :field (byte 3 13) :value #b111) (op :field (byte 5 8)))(sb!disassem:define-instruction-format (floating-point-3 16 :default-printer '(:name)) (prefix :field (byte 5 3) :value #b11011) (suffix :field (byte 2 14) :value #b11) (op :fields (list (byte 3 0) (byte 6 8))))(sb!disassem:define-instruction-format (floating-point-5 16 :default-printer '(:name)) (prefix :field (byte 8 0) :value #b11011011) (suffix :field (byte 3 13) :value #b111) (op :field (byte 5 8)))(sb!disassem:define-instruction-format (floating-point-st 16 :default-printer '(:name)) (prefix :field (byte 8 0) :value #b11011111) (suffix :field (byte 3 13) :value #b111) (op :field (byte 5 8)))(sb!disassem:define-instruction-format (string-op 8 :include 'simple :default-printer '(:name width)))(sb!disassem:define-instruction-format (short-cond-jump 16) (op :field (byte 4 4)) (cc :field (byte 4 0) :type 'condition-code) (label :field (byte 8 8) :type 'displacement))(sb!disassem:define-instruction-format (short-jump 16 :default-printer '(:name :tab label)) (const :field (byte 4 4) :value #b1110) (op :field (byte 4 0)) (label :field (byte 8 8) :type 'displacement))(sb!disassem:define-instruction-format (near-cond-jump 16) (op :fields (list (byte 8 0) (byte 4 12)) :value '(#b00001111 #b1000)) (cc :field (byte 4 8) :type 'condition-code) ;; The disassembler currently doesn't let you have an instruction > 32 bits ;; long, so we fake it by using a prefilter to read the offset. (label :type 'displacement :prefilter (lambda (value dstate) (declare (ignore value)) ; always nil anyway (sb!disassem:read-signed-suffix 32 dstate))))(sb!disassem:define-instruction-format (near-jump 8 :default-printer '(:name :tab label)) (op :field (byte 8 0)) ;; The disassembler currently doesn't let you have an instruction > 32 bits ;; long, so we fake it by using a prefilter to read the address. (label :type 'displacement :prefilter (lambda (value dstate) (declare (ignore value)) ; always nil anyway (sb!disassem:read-signed-suffix 32 dstate))))(sb!disassem:define-instruction-format (cond-set 24 :default-printer '('set cc :tab reg/mem)) (prefix :field (byte 8 0) :value #b00001111) (op :field (byte 4 12) :value #b1001) (cc :field (byte 4 8) :type 'condition-code) (reg/mem :fields (list (byte 2 22) (byte 3 16)) :type 'byte-reg/mem) (reg :field (byte 3 19) :value #b000))(sb!disassem:define-instruction-format (cond-move 24 :default-printer '('cmov cc :tab reg ", " reg/mem)) (prefix :field (byte 8 0) :value #b00001111) (op :field (byte 4 12) :value #b0100) (cc :field (byte 4 8) :type 'condition-code) (reg/mem :fields (list (byte 2 22) (byte 3 16)) :type 'reg/mem) (reg :field (byte 3 19) :type 'reg))(sb!disassem:define-instruction-format (enter-format 32 :default-printer '(:name :tab disp (:unless (:constant 0) ", " level))) (op :field (byte 8 0)) (disp :field (byte 16 8)) (level :field (byte 8 24)))(sb!disassem:define-instruction-format (prefetch 24 :default-printer '(:name ", " reg/mem)) (prefix :field (byte 8 0) :value #b00001111) (op :field (byte 8 8) :value #b00011000) (reg/mem :fields (list (byte 2 22) (byte 3 16)) :type 'byte-reg/mem) (reg :field (byte 3 19) :type 'reg));;; Single byte instruction with an immediate byte argument.(sb!disassem:define-instruction-format (byte-imm 16 :default-printer '(:name :tab code)) (op :field (byte 8 0)) (code :field (byte 8 8)));;; Two byte instruction with an immediate byte argument.;;;(sb!disassem:define-instruction-format (word-imm 24 :default-printer '(:name :tab code)) (op :field (byte 16 0)) (code :field (byte 8 16)));;;; primitive emitters(define-bitfield-emitter emit-word 16 (byte 16 0))(define-bitfield-emitter emit-dword 32 (byte 32 0))(define-bitfield-emitter emit-byte-with-reg 8 (byte 5 3) (byte 3 0))(define-bitfield-emitter emit-mod-reg-r/m-byte 8 (byte 2 6) (byte 3 3) (byte 3 0))(define-bitfield-emitter emit-sib-byte 8 (byte 2 6) (byte 3 3) (byte 3 0));;;; fixup emitters(defun emit-absolute-fixup (segment fixup) (note-fixup segment :absolute fixup) (let ((offset (fixup-offset fixup))) (if (label-p offset) (emit-back-patch segment 4 ; FIXME: n-word-bytes (lambda (segment posn) (declare (ignore posn)) (emit-dword segment (- (+ (component-header-length) (or (label-position offset) 0)) other-pointer-lowtag)))) (emit-dword segment (or offset 0)))))(defun emit-relative-fixup (segment fixup) (note-fixup segment :relative fixup) (emit-dword segment (or (fixup-offset fixup) 0)));;;; the effective-address (ea) structure(defun reg-tn-encoding (tn) (declare (type tn tn)) (aver (eq (sb-name (sc-sb (tn-sc tn))) 'registers)) (let ((offset (tn-offset tn))) (logior (ash (logand offset 1) 2) (ash offset -1))))(defstruct (ea (:constructor make-ea (size &key base index scale disp)) (:copier nil)) (size nil :type (member :byte :word :dword)) (base nil :type (or tn null)) (index nil :type (or tn null)) (scale 1 :type (member 1 2 4 8)) (disp 0 :type (or (unsigned-byte 32) (signed-byte 32) fixup)))(def!method print-object ((ea ea) stream) (cond ((or *print-escape* *print-readably*) (print-unreadable-object (ea stream :type t) (format stream "~S~@[ base=~S~]~@[ index=~S~]~@[ scale=~S~]~@[ disp=~S~]" (ea-size ea) (ea-base ea) (ea-index ea) (let ((scale (ea-scale ea))) (if (= scale 1) nil scale)) (ea-disp ea)))) (t (format stream "~A PTR [" (symbol-name (ea-size ea))) (when (ea-base ea) (write-string (sb!c::location-print-name (ea-base ea)) stream) (when (ea-index ea) (write-string "+" stream))) (when (ea-index ea) (write-string (sb!c::location-print-name (ea-index ea)) stream)) (unless (= (ea-scale ea) 1) (format stream "*~A" (ea-scale ea))) (typecase (ea-disp ea) (null) (integer (format stream "~@D" (ea-disp ea)))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -