From ffjeld at common-lisp.net Sat Feb 2 00:33:04 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Fri, 1 Feb 2008 19:33:04 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080202003304.C04007C057@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv25422 Modified Files: asm.lisp Log Message: Add asm:*instruction-compute-extra-prefix-map* feature to assembler. --- /project/movitz/cvsroot/movitz/asm.lisp 2008/01/31 21:11:24 1.4 +++ /project/movitz/cvsroot/movitz/asm.lisp 2008/02/02 00:33:04 1.5 @@ -6,7 +6,7 @@ ;;;; Author: Frode Vatvedt Fjeld ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: asm.lisp,v 1.4 2008/01/31 21:11:24 ffjeld Exp $ +;;;; $Id: asm.lisp,v 1.5 2008/02/02 00:33:04 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -25,12 +25,14 @@ #:pc-relative-operand #:proglist-encode #:*pc* - #:*symtab*)) + #:*symtab* + #:*instruction-compute-extra-prefix-map*)) (in-package asm) (defvar *pc* nil "Current program counter.") (defvar *symtab* nil "Current symbol table.") +(defvar *instruction-compute-extra-prefix-map* nil) (deftype symbol-reference () '(cons (eql quote) (cons symbol null))) From ffjeld at common-lisp.net Sat Feb 2 00:33:06 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Fri, 1 Feb 2008 19:33:06 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080202003306.53B897C058@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv25445 Modified Files: asm-x86.lisp Log Message: Add asm:*instruction-compute-extra-prefix-map* feature to assembler. --- /project/movitz/cvsroot/movitz/asm-x86.lisp 2008/01/31 21:11:28 1.11 +++ /project/movitz/cvsroot/movitz/asm-x86.lisp 2008/02/02 00:33:06 1.12 @@ -6,7 +6,7 @@ ;;;; Author: Frode Vatvedt Fjeld ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: asm-x86.lisp,v 1.11 2008/01/31 21:11:28 ffjeld Exp $ +;;;; $Id: asm-x86.lisp,v 1.12 2008/02/02 00:33:06 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -72,7 +72,7 @@ (loop for b from 0 below (* 8 n) by 8 collect (ldb (byte 8 b) i))) -(defun encode-values-fun (prefixes rexes opcode mod reg rm scale index base displacement immediate operand-size address-size) +(defun encode-values-fun (operator legacy-prefixes prefixes rexes opcode mod reg rm scale index base displacement immediate operand-size address-size) (assert opcode) (when (or (and (eq address-size :32-bit) (eq *cpu-mode* :64-bit)) @@ -92,40 +92,43 @@ (eq *cpu-mode* :16-bit))) (pushnew :operand-size-override prefixes)) - (append (mapcar #'prefix-lookup (reverse prefixes)) - (rex-encode rexes :rm rm) - (when (< 16 (integer-length opcode)) - (list (ldb (byte 8 16) opcode))) - (when (< 8(integer-length opcode)) - (list (ldb (byte 8 8) opcode))) - (list (ldb (byte 8 0) opcode)) - (when (or mod reg rm) - (assert (and mod reg rm) (mod reg rm) - "Either all or none of mod, reg, and rm must be defined. mod=~S, reg=~S, rm=~S." mod reg rm) - (check-type mod (unsigned-byte 2)) - (list (logior (ash (ldb (byte 2 0) mod) - 6) - (ash (ldb (byte 3 0) reg) - 3) - (ash (ldb (byte 3 0) rm) - 0)))) - (when (or scale index base) - (assert (and scale index base) (scale index base) - "Either all or none of scale, index, and base must be defined. scale=~S, index=~S, base=~S." scale index base) - (check-type scale (unsigned-byte 2)) - (check-type index (unsigned-byte 4)) - (check-type base (unsigned-byte 4)) - (list (logior (ash (ldb (byte 2 0) scale) - 6) - (ash (ldb (byte 3 0) index) - 3) - (ash (ldb (byte 3 0) base) - 0)))) - displacement - immediate)) + (let ((code (append legacy-prefixes + (mapcar #'prefix-lookup (reverse prefixes)) + (rex-encode rexes :rm rm) + (when (< 16 (integer-length opcode)) + (list (ldb (byte 8 16) opcode))) + (when (< 8(integer-length opcode)) + (list (ldb (byte 8 8) opcode))) + (list (ldb (byte 8 0) opcode)) + (when (or mod reg rm) + (assert (and mod reg rm) (mod reg rm) + "Either all or none of mod, reg, and rm must be defined. mod=~S, reg=~S, rm=~S." mod reg rm) + (check-type mod (unsigned-byte 2)) + (list (logior (ash (ldb (byte 2 0) mod) + 6) + (ash (ldb (byte 3 0) reg) + 3) + (ash (ldb (byte 3 0) rm) + 0)))) + (when (or scale index base) + (assert (and scale index base) (scale index base) + "Either all or none of scale, index, and base must be defined. scale=~S, index=~S, base=~S." scale index base) + (check-type scale (unsigned-byte 2)) + (check-type index (unsigned-byte 4)) + (check-type base (unsigned-byte 4)) + (list (logior (ash (ldb (byte 2 0) scale) + 6) + (ash (ldb (byte 3 0) index) + 3) + (ash (ldb (byte 3 0) base) + 0)))) + displacement + immediate))) + (append (compute-extra-prefixes operator *pc* (length code)) + code))) (defmacro encode (values-form) - `(multiple-value-call #'encode-values-fun ,values-form)) + `(multiple-value-call #'encode-values-fun operator legacy-prefixes ,values-form)) (defmacro merge-encodings (form1 form2) @@ -184,44 +187,19 @@ instruction)) (destructuring-bind (operator &rest operands) instruction - (nconc (mapcar #'prefix-lookup legacy-prefixes) - (apply (or (gethash operator *instruction-encoders*) - (error "Unknown instruction operator ~S in ~S." operator instruction)) - operands))))) + (apply (or (gethash operator *instruction-encoders*) + (error "Unknown instruction operator ~S in ~S." operator instruction)) + operator + (mapcar #'prefix-lookup legacy-prefixes) + operands)))) -(defun encode-to-parts (instruction) - (multiple-value-bind (legacy-prefixes instruction) - (if (listp (car instruction)) - (values (car instruction) - (cdr instruction)) - (values nil - instruction)) - (destructuring-bind (operator &rest operands) - instruction - (multiple-value-bind (prefixes prefix rex opcode mod reg rm scale index base displacement immediate operand-size address-size) - (apply (or (gethash operator *instruction-encoders*) - (error "Unknown instruction operator ~S in ~S." operator instruction)) - operands) - (values (append legacy-prefixes prefixes) - prefix - rex - opcode - mod - reg - rm - scale - index - base - displacement - immediate - operand-size - address-size))))) (defmacro define-operator (operator lambda-list &body body) (check-type operator keyword) (let ((defun-name (intern (format nil "~A-~A" 'instruction-encoder operator)))) `(progn - (defun ,defun-name ,lambda-list + (defun ,defun-name (operator legacy-prefixes , at lambda-list) + (declare (ignorable operator)) (let ((operator-mode nil) (default-rex nil)) (declare (ignorable operator-mode default-rex)) @@ -669,34 +647,47 @@ :immediate (encode-integer immediate ',type)) (encode-reg/mem ,op-modrm operator-mode))))))) -(defun encode-pc-rel (opcode operand type &rest extras) + +(defun compute-extra-prefixes (operator pc size) + (let ((ff (assoc operator *instruction-compute-extra-prefix-map*))) + (when ff + (funcall (cdr ff) pc size)))) + +(defun encode-pc-rel (operator legacy-prefixes opcode operand type &rest extras) (when (typep operand '(or pc-relative-operand symbol-reference)) (assert *pc* (*pc*) "Cannot encode a pc-relative operand without a value for ~S." '*pc*) - (let* ((estimated-code-size (+ (type-octet-size type) - (opcode-octet-size opcode))) + (let* ((estimated-code-size-no-extras (+ (length legacy-prefixes) + (type-octet-size type) + (opcode-octet-size opcode))) + (estimated-extra-prefixes (compute-extra-prefixes operator *pc* estimated-code-size-no-extras)) + (estimated-code-size (+ estimated-code-size-no-extras + (length estimated-extra-prefixes))) (offset (let ((*pc* (+ *pc* estimated-code-size))) (resolve-pc-relative operand)))) (when (typep offset type) - (let ((code (encode (apply #'encoded-values - :opcode opcode - :displacement (encode-integer offset type) - extras)))) + (let ((code (let ((*instruction-compute-extra-prefix-map* nil)) + (encode (apply #'encoded-values + :opcode opcode + :displacement (encode-integer offset type) + extras))))) (if (= (length code) - estimated-code-size) - code + estimated-code-size-no-extras) + (append estimated-extra-prefixes code) (let* ((code-size (length code)) - (offset (let ((*pc* (+ *pc* code-size))) + (extra-prefixes (compute-extra-prefixes operator *pc* code-size)) + (offset (let ((*pc* (+ *pc* code-size (length extra-prefixes)))) (resolve-pc-relative operand)))) (when (typep offset type) - (let ((code (encode (apply #'encoded-values - :opcode opcode - :displacement (encode-integer offset type) - extras)))) + (let ((code (let ((*instruction-compute-extra-prefix-map* nil)) + (encode (apply #'encoded-values + :opcode opcode + :displacement (encode-integer offset type) + extras))))) (assert (= code-size (length code))) - code))))))))) + (append extra-prefixes code)))))))))) (defmacro pc-rel (opcode operand type &rest extras) - `(return-when (encode-pc-rel ,opcode ,operand ',type , at extras))) + `(return-when (encode-pc-rel operator legacy-prefixes ,opcode ,operand ',type , at extras))) (defmacro modrm (operand opcode digit) `(when (typep ,operand '(or register-operand indirect-operand)) @@ -707,7 +698,7 @@ :rex default-rex) (encode-reg/mem ,operand operator-mode))))) -(defun encode-reg-modrm (op-reg op-modrm opcode operator-mode default-rex &rest extras) +(defun encode-reg-modrm (operator legacy-prefixes op-reg op-modrm opcode operator-mode default-rex &rest extras) (let* ((reg-map (ecase operator-mode (:8-bit '(:al :cl :dl :bl :ah :ch :dh :bh)) (:16-bit '(:ax :cx :dx :bx :sp :bp :si :di)) @@ -726,10 +717,10 @@ (encode-reg/mem op-modrm operator-mode)))))) (defmacro reg-modrm (op-reg op-modrm opcode &rest extras) - `(return-when (encode-reg-modrm ,op-reg ,op-modrm ,opcode operator-mode default-rex , at extras))) + `(return-when (encode-reg-modrm operator legacy-prefixes ,op-reg ,op-modrm ,opcode operator-mode default-rex , at extras))) -(defun encode-reg-cr (op-reg op-cr opcode operator-mode default-rex &rest extras) +(defun encode-reg-cr (operator legacy-prefixes op-reg op-cr opcode operator-mode default-rex &rest extras) (let* ((reg-map (ecase operator-mode (:32-bit '(:eax :ecx :edx :ebx :esp :ebp :esi :edi)) (:64-bit '(:rax :rcx :rdx :rbx :rsp :rbp :rsi :rdi :r8 :r9 :r10 :r11 :r12 :r13 :r14 :r15)))) @@ -747,7 +738,7 @@ extras))))) (defmacro reg-cr (op-reg op-cr opcode &rest extras) - `(return-when (encode-reg-cr ,op-reg ,op-cr ,opcode operator-mode default-rex , at extras))) + `(return-when (encode-reg-cr operator legacy-prefixes ,op-reg ,op-cr ,opcode operator-mode default-rex , at extras))) (defmacro sreg-modrm (op-sreg op-modrm opcode) `(let* ((reg-map '(:es :cs :ss :ds :fs :gs)) @@ -782,7 +773,7 @@ (encoded-values :opcode ,opcode , at extras))) -(defun encode-opcode-reg (opcode op-reg operator-mode default-rex) +(defun encode-opcode-reg (operator legacy-prefixes opcode op-reg operator-mode default-rex) (let* ((reg-map (ecase operator-mode (:8-bit '(:al :cl :dl :bl :ah :ch :dh :bh)) (:16-bit '(:ax :cx :dx :bx :sp :bp :si :di)) @@ -802,9 +793,9 @@ (defmacro opcode-reg (opcode op-reg) `(return-when - (encode-opcode-reg ,opcode ,op-reg operator-mode default-rex))) + (encode-opcode-reg operator legacy-prefixes ,opcode ,op-reg operator-mode default-rex))) -(defun encode-opcode-reg-imm (opcode op-reg op-imm type operator-mode default-rex) +(defun encode-opcode-reg-imm (operator legacy-prefixes opcode op-reg op-imm type operator-mode default-rex) (when (immediate-p op-imm) (let ((immediate (resolve op-imm))) (when (typep immediate type) @@ -828,7 +819,7 @@ (defmacro opcode-reg-imm (opcode op-reg op-imm type) `(return-when - (encode-opcode-reg-imm ,opcode ,op-reg ,op-imm ',type operator-mode default-rex))) + (encode-opcode-reg-imm operator legacy-prefixes ,opcode ,op-reg ,op-imm ',type operator-mode default-rex))) ;;;;;;;;;;;;;;;; From ffjeld at common-lisp.net Sun Feb 3 10:23:05 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Sun, 3 Feb 2008 05:23:05 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080203102305.9B09D1F00C@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv15361 Modified Files: asm.lisp Log Message: Add support for *instruction-compute-extra-prefix-map* etc. --- /project/movitz/cvsroot/movitz/asm.lisp 2008/02/02 00:33:04 1.5 +++ /project/movitz/cvsroot/movitz/asm.lisp 2008/02/03 10:23:05 1.6 @@ -6,7 +6,7 @@ ;;;; Author: Frode Vatvedt Fjeld ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: asm.lisp,v 1.5 2008/02/02 00:33:04 ffjeld Exp $ +;;;; $Id: asm.lisp,v 1.6 2008/02/03 10:23:05 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -26,13 +26,15 @@ #:proglist-encode #:*pc* #:*symtab* - #:*instruction-compute-extra-prefix-map*)) + #:*instruction-compute-extra-prefix-map* + #:*position-independent-p*)) (in-package asm) (defvar *pc* nil "Current program counter.") (defvar *symtab* nil "Current symbol table.") (defvar *instruction-compute-extra-prefix-map* nil) +(defvar *position-independent-p* t) (deftype symbol-reference () '(cons (eql quote) (cons symbol null))) @@ -106,13 +108,26 @@ ((member previous-definition corrections) (cond ((> *pc* (cdr previous-definition)) +;; (warn "correcting ~S from ~D to ~D" instruction (cdr previous-definition) *pc*) (setf (cdr previous-definition) *pc*) (push previous-definition new-corrections)) ((< *pc* (cdr previous-definition)) - (error "Definition for ~S shrunk from ~S to ~S." - instruction - (cdr previous-definition) - *pc*)))) +;; (warn "Definition for ~S shrunk from ~S to ~S (corrections: ~{~D~}." +;; instruction +;; (cdr previous-definition) +;; *pc* +;; corrections) +;; (warn "prg: ~{~%~A~}" proglist) +;; (warn "Definition for ~S shrunk from ~S to ~S." +;; instruction +;; (cdr previous-definition) +;; *pc*) +;; (break "Definition for ~S shrunk from ~S to ~S." +;; instruction +;; (cdr previous-definition) +;; *pc*) + (setf (cdr previous-definition) *pc*) + (push previous-definition new-corrections)))) (t (error "Label ~S doubly defined. Old value: ~S, new value: ~S" instruction (cdr previous-definition) @@ -121,7 +136,8 @@ (cons (let ((code (handler-bind ((unresolved-symbol (lambda (c) - (let ((a (cons (unresolved-symbol c) 0))) + (let ((a (cons (unresolved-symbol c) *pc*))) +;; (warn "assuming ~S for ~S" (unresolved-symbol c) *pc*) (push a assumptions) (push a *symtab*) (invoke-restart 'retry-symbol-resolve))))) @@ -138,5 +154,5 @@ (return (proglist-encode proglist :start-pc start-pc :cpu-package cpu-package - :corrections new-corrections))))) + :corrections (nconc new-corrections corrections)))))) *symtab*))) From ffjeld at common-lisp.net Sun Feb 3 10:23:07 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Sun, 3 Feb 2008 05:23:07 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080203102307.AEB9F1F0FC@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv15379 Modified Files: asm-x86.lisp Log Message: Add support for *instruction-compute-extra-prefix-map* etc. --- /project/movitz/cvsroot/movitz/asm-x86.lisp 2008/02/02 00:33:06 1.12 +++ /project/movitz/cvsroot/movitz/asm-x86.lisp 2008/02/03 10:23:07 1.13 @@ -6,7 +6,7 @@ ;;;; Author: Frode Vatvedt Fjeld ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: asm-x86.lisp,v 1.12 2008/02/02 00:33:06 ffjeld Exp $ +;;;; $Id: asm-x86.lisp,v 1.13 2008/02/03 10:23:07 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -20,6 +20,9 @@ (defvar *instruction-encoders* (make-hash-table :test 'eq)) +(defvar *use-jcc-16-bit-p* nil + "Whether to use 16-bit JCC instructions in 32-bit mode.") + (defun prefix-lookup (prefix-name) (cdr (or (assoc prefix-name '((:operand-size-override . #x66) @@ -821,6 +824,7 @@ `(return-when (encode-opcode-reg-imm operator legacy-prefixes ,opcode ,op-reg ,op-imm ',type operator-mode default-rex))) + ;;;;;;;;;;;;;;;; (define-operator :nop () @@ -1057,17 +1061,17 @@ (define-operator/16 :cwd (reg1 reg2) (when (and (eq reg1 :ax) - (eq reg2 :dx)) + (eq reg2 :dx)) (opcode #x99))) (define-operator/32 :cdq (reg1 reg2) (when (and (eq reg1 :eax) - (eq reg2 :edx)) + (eq reg2 :edx)) (opcode #x99))) (define-operator/64 :cqo (reg1 reg2) (when (and (eq reg1 :rax) - (eq reg2 :rdx)) + (eq reg2 :rdx)) (opcode #x99))) ;;;;;;;;;;; DEC @@ -1091,7 +1095,7 @@ (define-operator* (:16 :divw :32 :divl :64 :divr) (divisor dividend1 dividend2) (when (and (eq dividend1 :ax-eax-rax) - (eq dividend2 :dx-edx-rdx)) + (eq dividend2 :dx-edx-rdx)) (modrm divisor #xf7 6))) ;;;;;;;;;;; HLT @@ -1103,12 +1107,12 @@ (define-operator/8 :idivb (divisor dividend1 dividend2) (when (and (eq dividend1 :al) - (eq dividend2 :ah)) + (eq dividend2 :ah)) (modrm divisor #xf6 7))) (define-operator* (:16 :idivw :32 :idivl :64 :idivr) (divisor dividend1 dividend2) (when (and (eq dividend1 :ax-eax-rax) - (eq dividend2 :dx-edx-rdx)) + (eq dividend2 :dx-edx-rdx)) (modrm divisor #xf7 7))) ;;;;;;;;;;; IMUL @@ -1117,7 +1121,7 @@ (when (not product2) (reg-modrm product1 factor #x0faf)) (when (and (eq product1 :eax) - (eq product2 :edx)) + (eq product2 :edx)) (modrm factor #xf7 5)) (typecase factor ((sint 8) @@ -1192,14 +1196,15 @@ (defmacro define-jcc (name opcode1 &optional (opcode2 (+ #x0f10 opcode1))) `(define-operator ,name (dst) (pc-rel ,opcode1 dst (sint 8)) - (case *cpu-mode* - ((:16-bit :32-bit) - (pc-rel ,opcode2 dst (sint 16) - :operand-size :16-bit))) + (when (or (and (eq *cpu-mode* :32-bit) + *use-jcc-16-bit-p*) + (eq *cpu-mode* :16-bit)) + (pc-rel ,opcode2 dst (sint 16) + :operand-size :16-bit)) (pc-rel ,opcode2 dst (sint 32) - :operand-size (case *cpu-mode* - ((:16-bit :32-bit) - :32-bit))))) + :operand-size (case *cpu-mode* + ((:16-bit :32-bit) + :32-bit))))) (define-jcc :ja #x77) (define-jcc :jae #x73) @@ -1243,7 +1248,9 @@ (define-operator :jmp (dst) (pc-rel #xeb dst (sint 8)) (pc-rel #xe9 dst (sint 32)) - (modrm dst #xff 4)) + (when (or (not *position-independent-p*) + (indirect-operand-p dst)) + (modrm dst #xff 4))) ;;;;;;;;;;; LAHF, LAR From ffjeld at common-lisp.net Mon Feb 4 07:45:09 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Mon, 4 Feb 2008 02:45:09 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080204074509.1292B2E1CA@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv14780 Modified Files: asm.lisp Log Message: Added support for sub-program operands. --- /project/movitz/cvsroot/movitz/asm.lisp 2008/02/03 10:23:05 1.6 +++ /project/movitz/cvsroot/movitz/asm.lisp 2008/02/04 07:45:08 1.7 @@ -6,7 +6,7 @@ ;;;; Author: Frode Vatvedt Fjeld ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: asm.lisp,v 1.6 2008/02/03 10:23:05 ffjeld Exp $ +;;;; $Id: asm.lisp,v 1.7 2008/02/04 07:45:08 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -27,7 +27,8 @@ #:*pc* #:*symtab* #:*instruction-compute-extra-prefix-map* - #:*position-independent-p*)) + #:*position-independent-p* + #:*sub-program-instructions*)) (in-package asm) @@ -35,16 +36,36 @@ (defvar *symtab* nil "Current symbol table.") (defvar *instruction-compute-extra-prefix-map* nil) (defvar *position-independent-p* t) +(defvar *sub-program-instructions* '(:jmp :ret) + "Instruction operators after which to insert sub-programs.") -(deftype symbol-reference () +(deftype simple-symbol-reference () '(cons (eql quote) (cons symbol null))) -(defun symbol-reference-p (expr) - (typep expr 'symbol-reference)) +(deftype sub-program-operand () + '(cons (eql quote) + (cons + (cons (eql :sub-program)) + null))) + +(deftype symbol-reference () + '(or simple-symbol-reference sub-program-operand)) + +(defun sub-program-operand-p (expr) + (typep expr 'sub-program-operand)) + +(defun sub-program-label (operand) + (car (cadadr operand))) + +(defun sub-program-program (operand) + (cddadr operand)) (defun symbol-reference-symbol (expr) - (check-type expr symbol-reference) - (second expr)) + (etypecase expr + (simple-symbol-reference + (second expr)) + (sub-program-operand + (sub-program-label expr)))) (deftype immediate-operand () '(or integer symbol-reference)) @@ -87,72 +108,90 @@ (*pc* start-pc) (*symtab* corrections) (assumptions nil) - (new-corrections nil)) - (values (loop for instruction in proglist - appending - (etypecase instruction - (symbol - (let ((previous-definition (assoc instruction *symtab*))) - (cond - ((null previous-definition) - (push (cons instruction *pc*) - *symtab*)) - ((assoc instruction new-corrections) - (error "prev-def in new-corrections?? new: ~S, old: ~S" - *pc* - (cdr (assoc instruction new-corrections)))) - ((member previous-definition assumptions) - (setf (cdr previous-definition) *pc*) - (setf assumptions (delete previous-definition assumptions)) - (push previous-definition new-corrections)) - ((member previous-definition corrections) - (cond - ((> *pc* (cdr previous-definition)) -;; (warn "correcting ~S from ~D to ~D" instruction (cdr previous-definition) *pc*) - (setf (cdr previous-definition) *pc*) - (push previous-definition new-corrections)) - ((< *pc* (cdr previous-definition)) -;; (warn "Definition for ~S shrunk from ~S to ~S (corrections: ~{~D~}." -;; instruction -;; (cdr previous-definition) -;; *pc* -;; corrections) -;; (warn "prg: ~{~%~A~}" proglist) -;; (warn "Definition for ~S shrunk from ~S to ~S." -;; instruction -;; (cdr previous-definition) -;; *pc*) -;; (break "Definition for ~S shrunk from ~S to ~S." -;; instruction -;; (cdr previous-definition) -;; *pc*) - (setf (cdr previous-definition) *pc*) - (push previous-definition new-corrections)))) - (t (error "Label ~S doubly defined. Old value: ~S, new value: ~S" - instruction - (cdr previous-definition) - *pc*)))) - nil) - (cons - (let ((code (handler-bind - ((unresolved-symbol (lambda (c) - (let ((a (cons (unresolved-symbol c) *pc*))) -;; (warn "assuming ~S for ~S" (unresolved-symbol c) *pc*) - (push a assumptions) - (push a *symtab*) - (invoke-restart 'retry-symbol-resolve))))) - (funcall encoder instruction)))) - (incf *pc* (length code)) - code))) - finally - (cond - ((not (null assumptions)) - (error "Undefined symbol~P: ~{~S~^, ~}" - (length assumptions) - (mapcar #'car assumptions))) - ((not (null new-corrections)) - (return (proglist-encode proglist - :start-pc start-pc - :cpu-package cpu-package - :corrections (nconc new-corrections corrections)))))) - *symtab*))) + (new-corrections nil) + (sub-programs nil)) + (flet ((process-instruction (instruction) + (etypecase instruction + (symbol + (let ((previous-definition (assoc instruction *symtab*))) + (cond + ((null previous-definition) + (push (cons instruction *pc*) + *symtab*)) + ((assoc instruction new-corrections) + (break "prev-def ~S in new-corrections?? new: ~S, old: ~S" + instruction + *pc* + (cdr (assoc instruction new-corrections)))) + ((member previous-definition assumptions) + (setf (cdr previous-definition) *pc*) + (setf assumptions (delete previous-definition assumptions)) + (push previous-definition new-corrections)) + ((member previous-definition corrections) + (cond + ((> *pc* (cdr previous-definition)) + ;; (warn "correcting ~S from ~D to ~D" instruction (cdr previous-definition) *pc*) + (setf (cdr previous-definition) *pc*) + (push previous-definition new-corrections)) + ((< *pc* (cdr previous-definition)) + ;; (warn "Definition for ~S shrunk from ~S to ~S (corrections: ~{~D~}." + ;; instruction + ;; (cdr previous-definition) + ;; *pc* + ;; corrections) + ;; (warn "prg: ~{~%~A~}" proglist) + ;; (warn "Definition for ~S shrunk from ~S to ~S." + ;; instruction + ;; (cdr previous-definition) + ;; *pc*) + ;; (break "Definition for ~S shrunk from ~S to ~S." + ;; instruction + ;; (cdr previous-definition) + ;; *pc*) + (setf (cdr previous-definition) *pc*) + (push previous-definition new-corrections)))) + (t (error "Label ~S doubly defined. Old value: ~S, new value: ~S" + instruction + (cdr previous-definition) + *pc*)))) + nil) + (cons + (let ((code (handler-bind + ((unresolved-symbol (lambda (c) + (let ((a (cons (unresolved-symbol c) *pc*))) + ;; (warn "assuming ~S for ~S" (unresolved-symbol c) *pc*) + (push a assumptions) + (push a *symtab*) + (invoke-restart 'retry-symbol-resolve))))) + (funcall encoder instruction)))) + (incf *pc* (length code)) + code))))) + (values (loop for instruction in proglist + for operands = (when (consp instruction) + instruction) + for operator = (when (consp instruction) + (let ((x (pop operands))) + (if (not (listp x)) x (pop operands)))) + append (process-instruction instruction) + do (loop for operand in operands + do (when (sub-program-operand-p operand) + (push (cons (sub-program-label operand) + (sub-program-program operand)) + sub-programs))) + when (and (not (null sub-programs)) + (member operator *sub-program-instructions*)) + append (loop for sub-program in (nreverse sub-programs) + append (mapcan #'process-instruction sub-program) + finally (setf sub-programs nil)) + finally + (cond + ((not (null assumptions)) + (error "Undefined symbol~P: ~{~S~^, ~}" + (length assumptions) + (mapcar #'car assumptions))) + ((not (null new-corrections)) + (return (proglist-encode proglist + :start-pc start-pc + :cpu-package cpu-package + :corrections (nconc new-corrections corrections)))))) + *symtab*)))) From ffjeld at common-lisp.net Mon Feb 4 07:45:19 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Mon, 4 Feb 2008 02:45:19 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080204074519.52455450B4@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv14852 Modified Files: asm-x86.lisp Log Message: Added support for sub-program operands. --- /project/movitz/cvsroot/movitz/asm-x86.lisp 2008/02/03 10:23:07 1.13 +++ /project/movitz/cvsroot/movitz/asm-x86.lisp 2008/02/04 07:45:12 1.14 @@ -6,7 +6,7 @@ ;;;; Author: Frode Vatvedt Fjeld ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: asm-x86.lisp,v 1.13 2008/02/03 10:23:07 ffjeld Exp $ +;;;; $Id: asm-x86.lisp,v 1.14 2008/02/04 07:45:12 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -207,7 +207,9 @@ (default-rex nil)) (declare (ignorable operator-mode default-rex)) (block operator - , at body))) + , at body + (error "Unable to encode ~S." (list operator ,@(remove #\& lambda-list + :key (lambda (x) (char (string x) 0)))))))) (setf (gethash ',operator *instruction-encoders*) ',defun-name) ',operator))) From ffjeld at common-lisp.net Mon Feb 4 08:33:41 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Mon, 4 Feb 2008 03:33:41 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080204083341.AC2EF5B069@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv24213 Modified Files: asm.lisp Log Message: Add support for incoming-symtab. --- /project/movitz/cvsroot/movitz/asm.lisp 2008/02/04 07:45:08 1.7 +++ /project/movitz/cvsroot/movitz/asm.lisp 2008/02/04 08:33:39 1.8 @@ -6,7 +6,7 @@ ;;;; Author: Frode Vatvedt Fjeld ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: asm.lisp,v 1.7 2008/02/04 07:45:08 ffjeld Exp $ +;;;; $Id: asm.lisp,v 1.8 2008/02/04 08:33:39 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -102,11 +102,11 @@ ;;;;;;;;;;;; -(defun proglist-encode (proglist &key corrections (start-pc 0) (cpu-package '#:asm-x86)) +(defun proglist-encode (proglist &key ((:symtab incoming-symtab) *symtab*) corrections (start-pc 0) (cpu-package '#:asm-x86)) "Encode a proglist, using instruction-encoder in symbol encode-instruction from cpu-package." (let ((encoder (find-symbol (string '#:encode-instruction) cpu-package)) (*pc* start-pc) - (*symtab* corrections) + (*symtab* (append incoming-symtab corrections)) (assumptions nil) (new-corrections nil) (sub-programs nil)) @@ -186,11 +186,13 @@ finally (cond ((not (null assumptions)) + (warn "prg: ~{~%~A~}" proglist) (error "Undefined symbol~P: ~{~S~^, ~}" (length assumptions) (mapcar #'car assumptions))) ((not (null new-corrections)) (return (proglist-encode proglist + :symtab incoming-symtab :start-pc start-pc :cpu-package cpu-package :corrections (nconc new-corrections corrections)))))) From ffjeld at common-lisp.net Mon Feb 4 10:08:25 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Mon, 4 Feb 2008 05:08:25 -0500 (EST) Subject: [movitz-cvs] CVS movitz/losp/muerte Message-ID: <20080204100825.749E11C003@common-lisp.net> Update of /project/movitz/cvsroot/movitz/losp/muerte In directory clnet:/tmp/cvs-serv12581 Modified Files: integers.lisp Log Message: assembly instruction je should be keyword. --- /project/movitz/cvsroot/movitz/losp/muerte/integers.lisp 2007/04/07 07:56:45 1.123 +++ /project/movitz/cvsroot/movitz/losp/muerte/integers.lisp 2008/02/04 10:08:18 1.124 @@ -9,7 +9,7 @@ ;;;; Created at: Wed Nov 8 18:44:57 2000 ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: integers.lisp,v 1.123 2007/04/07 07:56:45 ffjeld Exp $ +;;;; $Id: integers.lisp,v 1.124 2008/02/04 10:08:18 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -1899,26 +1899,26 @@ (:shrl 5 :ecx) ; compute msb bigit index/fixnum in ecx (:addl 4 :ecx) (:cmpw :cx (:ebx (:offset movitz-bignum length))) - (je '(:sub-program (equal-size-maybe-return-same) - (:testl :edx :edx) ; Can only return same if (zerop position). - (:jnz 'adjust-size) - (:movl :eax :ecx) ; size/fixnum - (:shrl ,movitz:+movitz-fixnum-shift+ :ecx) - (:andl 31 :ecx) - (:jz 'yes-return-same) - (:std) ; <================ - ;; we know EDX=0, now generate mask in EDX - (:addl 1 :edx) - (:shll :cl :edx) - (:movzxw (:ebx (:offset movitz-bignum length)) - :ecx) - (:cmpl :edx (:ebx :ecx (:offset movitz-bignum bigit0 -4))) - (:movl 0 :edx) ; Safe value, and correct if we need to go to adjust-size. - (:cld) ; =================> - (:jnc 'adjust-size) ; nope, we have to generate a new bignum. - yes-return-same - (:movl :ebx :eax) ; yep, we can return same bignum. - (:jmp 'ldb-done))) + (:je '(:sub-program (equal-size-maybe-return-same) + (:testl :edx :edx) ; Can only return same if (zerop position). + (:jnz 'adjust-size) + (:movl :eax :ecx) ; size/fixnum + (:shrl ,movitz:+movitz-fixnum-shift+ :ecx) + (:andl 31 :ecx) + (:jz 'yes-return-same) + (:std) ; <================ + ;; we know EDX=0, now generate mask in EDX + (:addl 1 :edx) + (:shll :cl :edx) + (:movzxw (:ebx (:offset movitz-bignum length)) + :ecx) + (:cmpl :edx (:ebx :ecx (:offset movitz-bignum bigit0 -4))) + (:movl 0 :edx) ; Safe value, and correct if we need to go to adjust-size. + (:cld) ; =================> + (:jnc 'adjust-size) ; nope, we have to generate a new bignum. + yes-return-same + (:movl :ebx :eax) ; yep, we can return same bignum. + (:jmp 'ldb-done))) (:jnc 'size-ok) ;; We now know that (+ size position) is beyond the size of the bignum. ;; So, if (zerop position), we can return the bignum as our result. From ffjeld at common-lisp.net Mon Feb 4 11:48:28 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Mon, 4 Feb 2008 06:48:28 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080204114828.2A5C84083@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv8206 Modified Files: asm-x86.lisp Log Message: Add MULL instruction. --- /project/movitz/cvsroot/movitz/asm-x86.lisp 2008/02/04 07:45:12 1.14 +++ /project/movitz/cvsroot/movitz/asm-x86.lisp 2008/02/04 11:48:27 1.15 @@ -6,7 +6,7 @@ ;;;; Author: Frode Vatvedt Fjeld ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: asm-x86.lisp,v 1.14 2008/02/04 07:45:12 ffjeld Exp $ +;;;; $Id: asm-x86.lisp,v 1.15 2008/02/04 11:48:27 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -1358,6 +1358,13 @@ (define-operator* (:32 :movzxw) (src dst) (reg-modrm dst src #x0fb7)) +;;;;;;;;;;; MUL + +(define-operator/32 :mull (factor product1 &optional product2) + (when (and (eq product1 :eax) + (eq product2 :edx)) + (modrm factor #xf7 4))) + ;;;;;;;;;;; NEG (define-operator/8 :negb (dst) From ffjeld at common-lisp.net Mon Feb 4 12:00:37 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Mon, 4 Feb 2008 07:00:37 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080204120037.0AE5B2E1CA@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv10217 Modified Files: asm.lisp Log Message: Support anonymous sub-programs. --- /project/movitz/cvsroot/movitz/asm.lisp 2008/02/04 08:33:39 1.8 +++ /project/movitz/cvsroot/movitz/asm.lisp 2008/02/04 12:00:36 1.9 @@ -6,7 +6,7 @@ ;;;; Author: Frode Vatvedt Fjeld ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: asm.lisp,v 1.8 2008/02/04 08:33:39 ffjeld Exp $ +;;;; $Id: asm.lisp,v 1.9 2008/02/04 12:00:36 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -39,6 +39,8 @@ (defvar *sub-program-instructions* '(:jmp :ret) "Instruction operators after which to insert sub-programs.") +(defvar *anonymous-sub-program-identities* nil) + (deftype simple-symbol-reference () '(cons (eql quote) (cons symbol null))) @@ -55,7 +57,13 @@ (typep expr 'sub-program-operand)) (defun sub-program-label (operand) - (car (cadadr operand))) + (let ((x (cadadr operand))) + (if (not (eq '() x)) + (car x) + (cdr (or (assoc operand *anonymous-sub-program-identities*) + (car (push (cons operand (gensym "sub-program-")) + *anonymous-sub-program-identities*))))))) + (defun sub-program-program (operand) (cddadr operand)) @@ -107,6 +115,7 @@ (let ((encoder (find-symbol (string '#:encode-instruction) cpu-package)) (*pc* start-pc) (*symtab* (append incoming-symtab corrections)) + (*anonymous-sub-program-identities* *anonymous-sub-program-identities*) (assumptions nil) (new-corrections nil) (sub-programs nil)) From ffjeld at common-lisp.net Mon Feb 4 12:11:00 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Mon, 4 Feb 2008 07:11:00 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080204121100.59CFE3C076@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv13579 Modified Files: asm-x86.lisp Log Message: Add PREFETCH instructions. --- /project/movitz/cvsroot/movitz/asm-x86.lisp 2008/02/04 11:48:27 1.15 +++ /project/movitz/cvsroot/movitz/asm-x86.lisp 2008/02/04 12:11:00 1.16 @@ -6,7 +6,7 @@ ;;;; Author: Frode Vatvedt Fjeld ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: asm-x86.lisp,v 1.15 2008/02/04 11:48:27 ffjeld Exp $ +;;;; $Id: asm-x86.lisp,v 1.16 2008/02/04 12:11:00 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -1445,6 +1445,20 @@ (define-operator* (:16 :popfw :32 :popfl :64 :popfr) () (opcode #x9d)) +;;;;;;;;;;; PRFETCH + +(define-operator :prefetch-nta (m8) + (modrm m8 #x0f18 0)) + +(define-operator :prefetch-t0 (m8) + (modrm m8 #x0f18 1)) + +(define-operator :prefetch-t1 (m8) + (modrm m8 #x0f18 2)) + +(define-operator :prefetch-t2 (m8) + (modrm m8 #x0f18 3)) + ;;;;;;;;;;; PUSH (define-operator* (:16 :pushw :32 :pushl) (src) From ffjeld at common-lisp.net Mon Feb 4 15:11:17 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Mon, 4 Feb 2008 10:11:17 -0500 (EST) Subject: [movitz-cvs] CVS movitz/losp/muerte Message-ID: <20080204151117.3267E3002F@common-lisp.net> Update of /project/movitz/cvsroot/movitz/losp/muerte In directory clnet:/tmp/cvs-serv26600 Modified Files: bignums.lisp Log Message: assembly instruction je should be keyword. --- /project/movitz/cvsroot/movitz/losp/muerte/bignums.lisp 2005/08/31 22:33:03 1.17 +++ /project/movitz/cvsroot/movitz/losp/muerte/bignums.lisp 2008/02/04 15:11:16 1.18 @@ -10,7 +10,7 @@ ;;;; Author: Frode Vatvedt Fjeld ;;;; Created at: Sat Jul 17 19:42:57 2004 ;;;; -;;;; $Id: bignums.lisp,v 1.17 2005/08/31 22:33:03 ffjeld Exp $ +;;;; $Id: bignums.lisp,v 1.18 2008/02/04 15:11:16 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -392,7 +392,7 @@ :eax) (:xorl :edx :edx) (:shldl :cl :eax :edx) - (jnz 'overflow) + (:jnz 'overflow) shift-short-loop (:movl (:ebx :esi (:offset movitz-bignum bigit0 -4)) :eax) From ffjeld at common-lisp.net Mon Feb 4 21:03:33 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Mon, 4 Feb 2008 16:03:33 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080204210333.3A37C2E1D2@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv32450 Modified Files: asm.lisp Log Message: Various bits and pieces, movitz now compiles (but won't boot). --- /project/movitz/cvsroot/movitz/asm.lisp 2008/02/04 12:00:36 1.9 +++ /project/movitz/cvsroot/movitz/asm.lisp 2008/02/04 21:03:32 1.10 @@ -6,7 +6,7 @@ ;;;; Author: Frode Vatvedt Fjeld ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: asm.lisp,v 1.9 2008/02/04 12:00:36 ffjeld Exp $ +;;;; $Id: asm.lisp,v 1.10 2008/02/04 21:03:32 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -20,6 +20,7 @@ #:indirect-operand-p #:indirect-operand #:register-operand + #:resolve-operand #:unresolved-symbol #:retry-symbol-resolve #:pc-relative-operand @@ -36,20 +37,32 @@ (defvar *symtab* nil "Current symbol table.") (defvar *instruction-compute-extra-prefix-map* nil) (defvar *position-independent-p* t) -(defvar *sub-program-instructions* '(:jmp :ret) +(defvar *sub-program-instructions* '(:jmp :ret :iretd) "Instruction operators after which to insert sub-programs.") (defvar *anonymous-sub-program-identities* nil) +(defun quotep (x) + "Is x a symbol (in any package) named 'quote'?" + ;; This is required because of Movitz package-fiddling. + (and (symbolp x) + (string= x 'quote))) + (deftype simple-symbol-reference () - '(cons (eql quote) (cons symbol null))) + '(cons (satisfies quotep) (cons symbol null))) (deftype sub-program-operand () - '(cons (eql quote) + '(cons (satisfies quotep) (cons (cons (eql :sub-program)) null))) +(deftype funcall-operand () + '(cons (satisfies quotep) + (cons + (cons (eql :funcall)) + null))) + (deftype symbol-reference () '(or simple-symbol-reference sub-program-operand)) @@ -64,7 +77,6 @@ (car (push (cons operand (gensym "sub-program-")) *anonymous-sub-program-identities*))))))) - (defun sub-program-program (operand) (cddadr operand)) @@ -75,8 +87,14 @@ (sub-program-operand (sub-program-label expr)))) +(defun funcall-operand-operator (operand) + (cadadr operand)) + +(defun funcall-operand-operands (operand) + (cddadr operand)) + (deftype immediate-operand () - '(or integer symbol-reference)) + '(or integer symbol-reference funcall-operand)) (defun immediate-p (expr) (typep expr 'immediate-operand)) @@ -88,7 +106,7 @@ (typep operand 'register-operand)) (deftype indirect-operand () - '(and cons (not (cons (eql quote))))) + '(and cons (not (cons (satisfies quotep))))) (defun indirect-operand-p (operand) (typep operand 'indirect-operand)) @@ -107,6 +125,21 @@ (format s "Unresolved symbol ~S." (unresolved-symbol c))))) + +(defun resolve-operand (operand) + (etypecase operand + (integer + operand) + (symbol-reference + (let ((s (symbol-reference-symbol operand))) + (loop (with-simple-restart (retry-symbol-resolve "Retry resolving ~S." s) + (return (cdr (or (assoc s *symtab*) + (error 'unresolved-symbol + :symbol s)))))))) + (funcall-operand + (apply (funcall-operand-operator operand) + (mapcar #'resolve-operand + (funcall-operand-operands operand)))))) ;;;;;;;;;;;; @@ -121,7 +154,7 @@ (sub-programs nil)) (flet ((process-instruction (instruction) (etypecase instruction - (symbol + ((or symbol integer) (let ((previous-definition (assoc instruction *symtab*))) (cond ((null previous-definition) @@ -139,24 +172,24 @@ ((member previous-definition corrections) (cond ((> *pc* (cdr previous-definition)) - ;; (warn "correcting ~S from ~D to ~D" instruction (cdr previous-definition) *pc*) +;; (warn "correcting ~S from ~D to ~D" instruction (cdr previous-definition) *pc*) (setf (cdr previous-definition) *pc*) (push previous-definition new-corrections)) ((< *pc* (cdr previous-definition)) - ;; (warn "Definition for ~S shrunk from ~S to ~S (corrections: ~{~D~}." - ;; instruction - ;; (cdr previous-definition) - ;; *pc* - ;; corrections) - ;; (warn "prg: ~{~%~A~}" proglist) - ;; (warn "Definition for ~S shrunk from ~S to ~S." - ;; instruction - ;; (cdr previous-definition) - ;; *pc*) - ;; (break "Definition for ~S shrunk from ~S to ~S." - ;; instruction - ;; (cdr previous-definition) - ;; *pc*) +;; (warn "Definition for ~S shrunk from ~S to ~S (corrections: ~{~D~}." +;; instruction +;; (cdr previous-definition) +;; *pc* +;; corrections) +;; (warn "prg: ~{~%~A~}" proglist) +;; (warn "Definition for ~S shrunk from ~S to ~S." +;; instruction +;; (cdr previous-definition) +;; *pc*) +;; (break "Definition for ~S shrunk from ~S to ~S." +;; instruction +;; (cdr previous-definition) +;; *pc*) (setf (cdr previous-definition) *pc*) (push previous-definition new-corrections)))) (t (error "Label ~S doubly defined. Old value: ~S, new value: ~S" @@ -168,7 +201,7 @@ (let ((code (handler-bind ((unresolved-symbol (lambda (c) (let ((a (cons (unresolved-symbol c) *pc*))) - ;; (warn "assuming ~S for ~S" (unresolved-symbol c) *pc*) +;; (warn "assuming ~S for ~S" (unresolved-symbol c) *pc*) (push a assumptions) (push a *symtab*) (invoke-restart 'retry-symbol-resolve))))) From ffjeld at common-lisp.net Mon Feb 4 21:03:40 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Mon, 4 Feb 2008 16:03:40 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080204210340.0AA6D49032@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv32467 Modified Files: asm-x86.lisp Log Message: Various bits and pieces, movitz now compiles (but won't boot). --- /project/movitz/cvsroot/movitz/asm-x86.lisp 2008/02/04 12:11:00 1.16 +++ /project/movitz/cvsroot/movitz/asm-x86.lisp 2008/02/04 21:03:35 1.17 @@ -6,7 +6,7 @@ ;;;; Author: Frode Vatvedt Fjeld ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: asm-x86.lisp,v 1.16 2008/02/04 12:11:00 ffjeld Exp $ +;;;; $Id: asm-x86.lisp,v 1.17 2008/02/04 21:03:35 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -182,19 +182,28 @@ address-size)) (defun encode-instruction (instruction) - (multiple-value-bind (legacy-prefixes instruction) + (multiple-value-bind (instruction legacy-prefixes options) (if (listp (car instruction)) - (values (car instruction) - (cdr instruction)) - (values nil - instruction)) + (values (cdr instruction) + (remove-if #'listp (car instruction)) + (remove-if #'keywordp (car instruction))) + (values instruction + nil + nil)) (destructuring-bind (operator &rest operands) instruction - (apply (or (gethash operator *instruction-encoders*) - (error "Unknown instruction operator ~S in ~S." operator instruction)) - operator - (mapcar #'prefix-lookup legacy-prefixes) - operands)))) + (let ((code (apply (or (gethash operator *instruction-encoders*) + (error "Unknown instruction operator ~S in ~S." operator instruction)) + operator + (mapcar #'prefix-lookup legacy-prefixes) + operands))) + (cond + ((null options) + code) + ((assoc :size options) + (assert (= (second (assoc :size options)) + (length code))) + code)))))) (defmacro define-operator (operator lambda-list &body body) @@ -202,7 +211,7 @@ (let ((defun-name (intern (format nil "~A-~A" 'instruction-encoder operator)))) `(progn (defun ,defun-name (operator legacy-prefixes , at lambda-list) - (declare (ignorable operator)) + (declare (ignorable operator legacy-prefixes)) (let ((operator-mode nil) (default-rex nil)) (declare (ignorable operator-mode default-rex)) @@ -281,16 +290,6 @@ ,(when |64| `(define-operator/64 ,|64| ,args , at body64))))) -(defun resolve (x) - (etypecase x - (integer - x) - (symbol-reference - (let ((s (symbol-reference-symbol x))) - (loop (with-simple-restart (retry-symbol-resolve "Retry resolving ~S." s) - (return (cdr (or (assoc s *symtab*) - (error 'unresolved-symbol - :symbol s)))))))))) (defun resolve-and-encode (x type &key size) (encode-integer (cond @@ -309,9 +308,9 @@ (etypecase operand ((cons (eql :pc+)) (reduce #'+ (cdr operand) - :key #'resolve)) + :key #'resolve-operand)) (symbol-reference - (- (resolve operand) + (- (resolve-operand operand) *pc*)))) (defun encode-integer (i type) @@ -382,7 +381,7 @@ (assert (or (not reg-scale) (and reg reg-scale))) (let ((offset (reduce #'+ offsets - :key #'resolve))) + :key #'resolve-operand))) (cond ((and (not reg) (eq mode :16-bit) @@ -631,7 +630,7 @@ (defmacro imm (imm-operand opcode imm-type &rest extras) `(when (immediate-p ,imm-operand) - (let ((immediate (resolve ,imm-operand))) + (let ((immediate (resolve-operand ,imm-operand))) (when (typep immediate ',imm-type) (return-values-when (encoded-values :opcode ,opcode @@ -642,7 +641,7 @@ (defmacro imm-modrm (op-imm op-modrm opcode digit type) `(when (immediate-p ,op-imm) - (let ((immediate (resolve ,op-imm))) + (let ((immediate (resolve-operand ,op-imm))) (when (typep immediate ',type) (return-values-when (merge-encodings (encoded-values :opcode ,opcode @@ -764,7 +763,7 @@ (return-values-when (encoded-values :opcode ,opcode :displacement (encode-integer (reduce #'+ offsets - :key #'resolve) + :key #'resolve-operand) ',type))))))) (defmacro opcode (opcode &rest extras) @@ -802,7 +801,7 @@ (defun encode-opcode-reg-imm (operator legacy-prefixes opcode op-reg op-imm type operator-mode default-rex) (when (immediate-p op-imm) - (let ((immediate (resolve op-imm))) + (let ((immediate (resolve-operand op-imm))) (when (typep immediate type) (let* ((reg-map (ecase operator-mode (:8-bit '(:al :cl :dl :bl :ah :ch :dh :bh)) @@ -827,10 +826,20 @@ (encode-opcode-reg-imm operator legacy-prefixes ,opcode ,op-reg ,op-imm ',type operator-mode default-rex))) -;;;;;;;;;;;;;;;; +;;;;;;;;;;; + +;;;;;;;;;;;;;;;; NOP + +(define-operator :% (op &rest data) + (case op + (:bytes + (let ((byte-size (pop data))) + (return-from operator + (loop for datum in data + append (loop for b from 0 below byte-size by 8 + collect (ldb (byte 8 b) + datum)))))))) -(define-operator :nop () - (opcode #x90)) ;;;;;;;;;;; ADC @@ -928,6 +937,9 @@ (define-operator/32 :callr (dest) (modrm dest #xff 2)) +(define-operator :call-segment (dest) + (modrm dest #xff 3)) + ;;;;;;;;;;; CLC, CLD, CLI, CLTS, CMC (define-operator :clc () (opcode #xf8)) @@ -1254,6 +1266,9 @@ (indirect-operand-p dst)) (modrm dst #xff 4))) +(define-operator* (:16 :jmpw-segment :32 :jmp-segment :64 :jmpr-segment) (addr) + (modrm addr #xff 5)) + ;;;;;;;;;;; LAHF, LAR (define-operator :lahf () @@ -1267,6 +1282,9 @@ ;;;;;;;;;;; LEA (define-operator* (:16 :leaw :32 :leal :64 :lear) (addr dst) + (when (and (equal addr '(:esp :edx)) ; REMOVEME: ia-x86 compat. hack!! + (eq dst :esp)) + (return-from operator '(#x8D #x64 #x14 #x00))) (reg-modrm dst addr #x8d)) ;;;;;;;;;;; LEAVE @@ -1276,10 +1294,10 @@ ;;;;;;;;;;; LGDT, LIDT -(define-operator* (:16 :lgdtw :32 :lgdtl :64 :lgdtr) (addr) +(define-operator* (:16 :lgdtw :32 :lgdt :64 :lgdtr) (addr) (modrm addr #x0f01 2)) -(define-operator* (:16 :lidtw :32 :lidtl :64 :lidtr) (addr) +(define-operator* (:16 :lidtw :32 :lidt :64 :lidtr) (addr) (modrm addr #x0f01 3)) ;;;;;;;;;;; LFENCE @@ -1373,6 +1391,11 @@ (define-operator* (:16 :negw :32 :negl :64 :negr) (dst) (modrm dst #xf7 3)) +;;;;;;;;;;;;;;;; NOP + +(define-operator :nop () + (opcode #x90)) + ;;;;;;;;;;; NOT (define-operator/8 :notb (dst) @@ -1527,6 +1550,11 @@ (reg-modrm dst subtrahend #x1b) (reg-modrm subtrahend dst #x19)) +;;;;;;;;;;; SGDT + +(define-operator/8 :sgdt (addr) + (modrm addr #x0f01 0)) + ;;;;;;;;;;; SHL (define-operator/8 :shlb (count dst) @@ -1547,7 +1575,7 @@ (when (eq :cl count) (reg-modrm dst1 dst2 #x0fa5)) (when (immediate-p count) - (let ((immediate (resolve count))) + (let ((immediate (resolve-operand count))) (when (typep immediate '(uint #x8)) (reg-modrm dst1 dst2 #x0fa4 :immediate (encode-integer count '(uint 8))))))) @@ -1572,7 +1600,7 @@ (when (eq :cl count) (reg-modrm dst1 dst2 #x0fad)) (when (immediate-p count) - (let ((immediate (resolve count))) + (let ((immediate (resolve-operand count))) (when (typep immediate '(uint #x8)) (reg-modrm dst1 dst2 #x0fac :immediate (encode-integer count '(uint 8))))))) @@ -1620,6 +1648,10 @@ (imm-modrm mask dst #xf7 0 :int-16-32-64) (reg-modrm mask dst #x85)) +;;;;;;;;;;; XCHG + +(define-operator :wrmsr () + (opcode #x0f30)) ;;;;;;;;;;; XCHG From ffjeld at common-lisp.net Mon Feb 4 21:04:51 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Mon, 4 Feb 2008 16:04:51 -0500 (EST) Subject: [movitz-cvs] CVS movitz/losp Message-ID: <20080204210451.E045F7213E@common-lisp.net> Update of /project/movitz/cvsroot/movitz/losp In directory clnet:/tmp/cvs-serv32704 Modified Files: scratch.lisp Log Message: scratch. --- /project/movitz/cvsroot/movitz/losp/scratch.lisp 2007/04/09 17:30:21 1.1 +++ /project/movitz/cvsroot/movitz/losp/scratch.lisp 2008/02/04 21:04:51 1.2 @@ -7,7 +7,7 @@ ;;;; Author: Frode Vatvedt Fjeld ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: scratch.lisp,v 1.1 2007/04/09 17:30:21 ffjeld Exp $ +;;;; $Id: scratch.lisp,v 1.2 2008/02/04 21:04:51 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -77,6 +77,21 @@ (warn "X: ~S" (memref-int bios32)) (warn "X: ~S" (= (memref-int bios32) #x5f32335f))) +(defun setfint (x o) + (setf (memref x o :type :unsigned-byte32) 0)) + +(defun fint (x) + (memref-int x :type :unsigned-byte32 :physicalp t)) + +(defun good () + (with-inline-assembly (:returns :untagged-fixnum-ecx) + ((:gs-override) :movl (#x1000000) :ecx))) + +(defun (setf good) (x) + (with-inline-assembly (:returns :untagged-fixnum-ecx) + (:compile-form (:result-mode :untagged-fixnum-ecx) x) + ((:gs-override) :movl :ecx (#x1000000)))) + (defun test2 () (funcall (compile @@ -862,8 +877,8 @@ Can be used to measure the overhead of primitive function." (with-inline-assembly (:returns :eax) (:load-lexical (:lexical-binding x) :eax) - (% bytes 8 #xff #x97) ; (:call-local-pf ret-trampoline) - (% bytes 32 #.(bt:slot-offset 'movitz::movitz-run-time-context 'movitz::ret-trampoline)))) + (:% :bytes 8 #xff #x97) ; (:call-local-pf ret-trampoline) + (:% :bytes 32 #.(bt:slot-offset 'movitz::movitz-run-time-context 'movitz::ret-trampoline)))) (defun my-test-labels (x) (labels (#+ignore (p () (print x)) From ffjeld at common-lisp.net Mon Feb 4 21:05:23 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Mon, 4 Feb 2008 16:05:23 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080204210523.90CEA4908B@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv480 Modified Files: load.lisp Log Message: add asm. --- /project/movitz/cvsroot/movitz/load.lisp 2004/12/09 14:05:52 1.11 +++ /project/movitz/cvsroot/movitz/load.lisp 2008/02/04 21:05:23 1.12 @@ -10,7 +10,7 @@ ;;;; Author: Frode Vatvedt Fjeld ;;;; Created at: Thu Jan 15 18:40:58 2004 ;;;; -;;;; $Id: load.lisp,v 1.11 2004/12/09 14:05:52 ffjeld Exp $ +;;;; $Id: load.lisp,v 1.12 2008/02/04 21:05:23 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -28,6 +28,10 @@ (load (compile-file #p"../binary-types/binary-types")) +(load (compile-file #p"asm")) ; these are here for now, because +(load (compile-file #p"asm-x86")) ; ia-x86 needs them while testing/migrating. + + (let ((*default-pathname-defaults* (merge-pathnames #p"../ia-x86/"))) #+(or cmu) (let ((pwd (ext:default-directory))) (progn From ffjeld at common-lisp.net Mon Feb 4 23:01:13 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Mon, 4 Feb 2008 18:01:13 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080204230113.ED20B5832E@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv32559 Modified Files: asm.lisp Log Message: Fixed a bug in proglist-encode: When assumptions were corrected via a recursive call, we didn't return the symtab from the recursive call, just the code. --- /project/movitz/cvsroot/movitz/asm.lisp 2008/02/04 21:03:32 1.10 +++ /project/movitz/cvsroot/movitz/asm.lisp 2008/02/04 23:01:11 1.11 @@ -6,7 +6,7 @@ ;;;; Author: Frode Vatvedt Fjeld ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: asm.lisp,v 1.10 2008/02/04 21:03:32 ffjeld Exp $ +;;;; $Id: asm.lisp,v 1.11 2008/02/04 23:01:11 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -154,7 +154,7 @@ (sub-programs nil)) (flet ((process-instruction (instruction) (etypecase instruction - ((or symbol integer) + ((or symbol integer) ; a label? (let ((previous-definition (assoc instruction *symtab*))) (cond ((null previous-definition) @@ -172,24 +172,14 @@ ((member previous-definition corrections) (cond ((> *pc* (cdr previous-definition)) -;; (warn "correcting ~S from ~D to ~D" instruction (cdr previous-definition) *pc*) + ;; (warn "correcting ~S from ~D to ~D" instruction (cdr previous-definition) *pc*) (setf (cdr previous-definition) *pc*) (push previous-definition new-corrections)) ((< *pc* (cdr previous-definition)) -;; (warn "Definition for ~S shrunk from ~S to ~S (corrections: ~{~D~}." -;; instruction -;; (cdr previous-definition) -;; *pc* -;; corrections) -;; (warn "prg: ~{~%~A~}" proglist) -;; (warn "Definition for ~S shrunk from ~S to ~S." -;; instruction -;; (cdr previous-definition) -;; *pc*) -;; (break "Definition for ~S shrunk from ~S to ~S." -;; instruction -;; (cdr previous-definition) -;; *pc*) + ;; (break "Definition for ~S shrunk from ~S to ~S." + ;; instruction + ;; (cdr previous-definition) + ;; *pc*) (setf (cdr previous-definition) *pc*) (push previous-definition new-corrections)))) (t (error "Label ~S doubly defined. Old value: ~S, new value: ~S" @@ -197,45 +187,43 @@ (cdr previous-definition) *pc*)))) nil) - (cons - (let ((code (handler-bind - ((unresolved-symbol (lambda (c) - (let ((a (cons (unresolved-symbol c) *pc*))) -;; (warn "assuming ~S for ~S" (unresolved-symbol c) *pc*) - (push a assumptions) - (push a *symtab*) - (invoke-restart 'retry-symbol-resolve))))) - (funcall encoder instruction)))) + (cons ; a bona fide instruction? + (let ((code (funcall encoder instruction))) (incf *pc* (length code)) code))))) - (values (loop for instruction in proglist - for operands = (when (consp instruction) - instruction) - for operator = (when (consp instruction) - (let ((x (pop operands))) - (if (not (listp x)) x (pop operands)))) - append (process-instruction instruction) - do (loop for operand in operands - do (when (sub-program-operand-p operand) - (push (cons (sub-program-label operand) - (sub-program-program operand)) - sub-programs))) - when (and (not (null sub-programs)) - (member operator *sub-program-instructions*)) - append (loop for sub-program in (nreverse sub-programs) - append (mapcan #'process-instruction sub-program) - finally (setf sub-programs nil)) - finally - (cond - ((not (null assumptions)) - (warn "prg: ~{~%~A~}" proglist) - (error "Undefined symbol~P: ~{~S~^, ~}" - (length assumptions) - (mapcar #'car assumptions))) - ((not (null new-corrections)) - (return (proglist-encode proglist - :symtab incoming-symtab - :start-pc start-pc - :cpu-package cpu-package - :corrections (nconc new-corrections corrections)))))) - *symtab*)))) + (handler-bind + ((unresolved-symbol (lambda (c) + (let ((a (cons (unresolved-symbol c) *pc*))) + ;; (warn "assuming ~S for ~S" (unresolved-symbol c) *pc*) + (push a assumptions) + (push a *symtab*) + (invoke-restart 'retry-symbol-resolve))))) + (let ((code (loop for instruction in proglist + for operands = (when (consp instruction) + instruction) + for operator = (when (consp instruction) + (let ((x (pop operands))) + (if (not (listp x)) x (pop operands)))) + append (process-instruction instruction) + do (loop for operand in operands + do (when (sub-program-operand-p operand) + (push (cons (sub-program-label operand) + (sub-program-program operand)) + sub-programs))) + when (and (not (null sub-programs)) + (member operator *sub-program-instructions*)) + append (loop for sub-program in (nreverse sub-programs) + append (mapcan #'process-instruction sub-program) + finally (setf sub-programs nil))))) + (cond + ((not (null assumptions)) + (error "Undefined symbol~P: ~{~S~^, ~}" + (length assumptions) + (mapcar #'car assumptions))) + ((not (null new-corrections)) + (proglist-encode proglist + :symtab incoming-symtab + :start-pc start-pc + :cpu-package cpu-package + :corrections (nconc new-corrections corrections))) + (t (values code *symtab*)))))))) From ffjeld at common-lisp.net Mon Feb 4 23:08:07 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Mon, 4 Feb 2008 18:08:07 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080204230807.04FF77914E@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv3222 Modified Files: compiler.lisp Log Message: Use new assembler. --- /project/movitz/cvsroot/movitz/compiler.lisp 2007/04/05 21:10:39 1.186 +++ /project/movitz/cvsroot/movitz/compiler.lisp 2008/02/04 23:08:07 1.187 @@ -8,7 +8,7 @@ ;;;; Created at: Wed Oct 25 12:30:49 2000 ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: compiler.lisp,v 1.186 2007/04/05 21:10:39 ffjeld Exp $ +;;;; $Id: compiler.lisp,v 1.187 2008/02/04 23:08:07 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -131,6 +131,22 @@ '(#x90 #x90 #x90) '(#x90))))) +(defun new-compute-call-extra-prefix (pc size) + (let* ((return-pointer-tag (ldb (byte 3 0) + (+ pc size)))) + (cond + ((or (= (tag :even-fixnum) return-pointer-tag) + (= (tag :odd-fixnum) return-pointer-tag)) + ;; Insert a NOP + '(#x90)) +;;; ((= 3 return-pointer-tag) +;;; ;; Insert two NOPs, 3 -> 5 +;;; '(#x90 #x90)) + ((= (tag :character) return-pointer-tag) + ;; Insert three NOPs, 2 -> 5 + '(#x90 #x90 #x90) + '(#x90))))) + (defun make-compiled-primitive (form environment top-level-p docstring) "Primitive functions have no funobj, no stack-frame, and no implied parameter/return value passing conventions." @@ -143,19 +159,24 @@ :top-level-p nil :result-mode :ignore)) ;; (ignmore (format t "~{~S~%~}" body-code)) - (resolved-code (finalize-code body-code nil nil)) - (function-code (ia-x86:read-proglist resolved-code))) + (resolved-code (finalize-code body-code nil nil))) + (multiple-value-bind (code-vector symtab) - (let ((ia-x86:*instruction-compute-extra-prefix-map* - '((:call . compute-call-extra-prefix)))) - (ia-x86:proglist-encode :octet-vector - :32-bit - #x00000000 - function-code - :symtab-lookup - #'(lambda (label) - (case label - (:nil-value (image-nil-word *image*)))))) + #+use-old-ia-x86 + (let ((ia-x86:*instruction-compute-extra-prefix-map* + '((:call . compute-call-extra-prefix)))) + (ia-x86:proglist-encode :octet-vector + :32-bit + #x00000000 + (ia-x86:read-proglist resolved-code) + :symtab-lookup (lambda (label) + (case label + (:nil-value (image-nil-word *image*)))))) + (let ((asm:*instruction-compute-extra-prefix-map* + '((:call . new-compute-call-extra-prefix)))) + (asm:proglist-encode (translate-program resolved-code :muerte.cl :cl) + :symtab (list (cons :nil-value (image-nil-word *image*))))) + (values (make-movitz-vector (length code-vector) :element-type 'code :initial-contents code-vector) @@ -1001,40 +1022,72 @@ funobj) +(defun diss (code) + (format nil "~&;; Diss: +~:{~4D: ~16<~{ ~2,'0X~}~;~> ~A~@[ ;~{ ~A~}~]~%~}" + (loop with code-position = 0 + for pc = 0 then code-position + for instruction = (ia-x86:decode-read-octet + #'(lambda () + (incf code-position) + (pop code))) + for cbyte = (and instruction + (ia-x86::instruction-original-datum instruction)) + until (null instruction) + collect (list pc + (ia-x86::cbyte-to-octet-list cbyte) + instruction + (comment-instruction instruction nil pc))))) + + (defun assemble-funobj (funobj combined-code) (multiple-value-bind (code-vector code-symtab) - (let ((ia-x86:*instruction-compute-extra-prefix-map* - '((:call . compute-call-extra-prefix)))) - (ia-x86:proglist-encode :octet-vector :32-bit #x00000000 - (ia-x86:read-proglist combined-code) - :symtab-lookup - (lambda (label) - (case label - (:nil-value (image-nil-word *image*)) - (t (let ((set (cdr (assoc label - (movitz-funobj-jumpers-map funobj))))) - (when set - (let ((pos (search set (movitz-funobj-const-list funobj) - :end2 (movitz-funobj-num-jumpers funobj)))) - (assert pos () - "Couldn't find for ~s set ~S in ~S." - label set (subseq (movitz-funobj-const-list funobj) - 0 (movitz-funobj-num-jumpers funobj))) - (* 4 pos))))))))) + #+use-old-ia-x86 + (let ((ia-x86:*instruction-compute-extra-prefix-map* + '((:call . compute-call-extra-prefix)))) + (ia-x86:proglist-encode :octet-vector :32-bit #x00000000 + (ia-x86:read-proglist combined-code) + :symtab-lookup + (lambda (label) + (case label + (:nil-value (image-nil-word *image*)) + (t (let ((set (cdr (assoc label + (movitz-funobj-jumpers-map funobj))))) + (when set + (let ((pos (search set (movitz-funobj-const-list funobj) + :end2 (movitz-funobj-num-jumpers funobj)))) + (assert pos () + "Couldn't find for ~s set ~S in ~S." + label set (subseq (movitz-funobj-const-list funobj) + 0 (movitz-funobj-num-jumpers funobj))) + (* 4 pos))))))))) + (let ((asm:*instruction-compute-extra-prefix-map* + '((:call . new-compute-call-extra-prefix)))) + (asm:proglist-encode combined-code + :symtab (list* (cons :nil-value (image-nil-word *image*)) + (loop for (label . set) in (movitz-funobj-jumpers-map funobj) + collect (cons label + (* 4 (or (search set (movitz-funobj-const-list funobj) + :end2 (movitz-funobj-num-jumpers funobj)) + (error "Jumper for ~S missing." label)))))))) + (setf (movitz-funobj-symtab funobj) code-symtab) - (let ((code-length (- (length code-vector) 3 -3))) + (let* ((code-length (- (length code-vector) 3 -3)) + (code-vector (make-array code-length + :initial-contents code-vector + :fill-pointer t))) (setf (fill-pointer code-vector) code-length) ;; debug info (setf (ldb (byte 1 5) (slot-value funobj 'debug-info)) - 1 #+ignore (if use-stack-frame-p 1 0)) + 1 #+ignore (if use-stack-frame-p 1 0)) (let ((x (cdr (assoc 'start-stack-frame-setup code-symtab)))) (cond - ((not x) - #+ignore (warn "No start-stack-frame-setup label for ~S." name)) - ((<= 0 x 30) - (setf (ldb (byte 5 0) (slot-value funobj 'debug-info)) x)) - (t (warn "Can't encode start-stack-frame-setup label ~D into debug-info for ~S." - x (movitz-funobj-name funobj))))) + ((not x) + #+ignore (warn "No start-stack-frame-setup label for ~S." name)) + ((<= 0 x 30) + (setf (ldb (byte 5 0) (slot-value funobj 'debug-info)) x)) + (t (warn "Can't encode start-stack-frame-setup label ~D into debug-info for ~S." + x (movitz-funobj-name funobj))))) (let* ((a (or (cdr (assoc 'entry%1op code-symtab)) 0)) (b (or (cdr (assoc 'entry%2op code-symtab)) a)) (c (or (cdr (assoc 'entry%3op code-symtab)) b))) @@ -1049,11 +1102,11 @@ (loop for ((entry-label slot-name)) on '((entry%1op code-vector%1op) (entry%2op code-vector%2op) (entry%3op code-vector%3op)) - do (cond + do (cond ((assoc entry-label code-symtab) (let ((offset (cdr (assoc entry-label code-symtab)))) (setf (slot-value funobj slot-name) - (cons offset funobj)) + (cons offset funobj)) #+ignore (when (< offset #x100) (vector-push offset code-vector)))) #+ignore @@ -1065,24 +1118,24 @@ (make-movitz-vector (length code-vector) :fill-pointer code-length :element-type 'code - :initial-contents code-vector)))) + :initial-contents code-vector))))) funobj) (defun check-locate-concistency (code-vector) (loop for x from 0 below (length code-vector) by 8 - do (when (and (= (tag :basic-vector) (aref code-vector x)) - (= (enum-value 'movitz-vector-element-type :code) (aref code-vector (1+ x))) - (or (<= #x4000 (length code-vector)) - (and (= (ldb (byte 8 0) (length code-vector)) - (aref code-vector (+ x 2))) - (= (ldb (byte 8 8) (length code-vector)) - (aref code-vector (+ x 3)))))) - (break "Code-vector (length #x~X) can break %find-code-vector at ~D: #x~2,'0X~2,'0X ~2,'0X~2,'0X." - (length code-vector) x - (aref code-vector (+ x 0)) - (aref code-vector (+ x 1)) - (aref code-vector (+ x 2)) - (aref code-vector (+ x 3))))) + do (when (and (= (tag :basic-vector) (aref code-vector x)) + (= (enum-value 'movitz-vector-element-type :code) (aref code-vector (1+ x))) + (or (<= #x4000 (length code-vector)) + (and (= (ldb (byte 8 0) (length code-vector)) + (aref code-vector (+ x 2))) + (= (ldb (byte 8 8) (length code-vector)) + (aref code-vector (+ x 3)))))) + (break "Code-vector (length #x~X) can break %find-code-vector at ~D: #x~2,'0X~2,'0X ~2,'0X~2,'0X." + (length code-vector) x + (aref code-vector (+ x 0)) + (aref code-vector (+ x 1)) + (aref code-vector (+ x 2)) + (aref code-vector (+ x 3))))) (values)) #+ignore From ffjeld at common-lisp.net Tue Feb 5 22:40:54 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Tue, 5 Feb 2008 17:40:54 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080205224054.D97B73C048@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv11463 Modified Files: asm-x86.lisp Log Message: Improve misc. instruction support. --- /project/movitz/cvsroot/movitz/asm-x86.lisp 2008/02/04 21:03:35 1.17 +++ /project/movitz/cvsroot/movitz/asm-x86.lisp 2008/02/05 22:40:54 1.18 @@ -6,12 +6,15 @@ ;;;; Author: Frode Vatvedt Fjeld ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: asm-x86.lisp,v 1.17 2008/02/04 21:03:35 ffjeld Exp $ +;;;; $Id: asm-x86.lisp,v 1.18 2008/02/05 22:40:54 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ (defpackage asm-x86 - (:use :common-lisp :asm)) + (:use :common-lisp :asm) + (:export #:encode-instruction + #:*cpu-mode* + #:*position-independent-p*)) (in-package asm-x86) @@ -133,7 +136,6 @@ (defmacro encode (values-form) `(multiple-value-call #'encode-values-fun operator legacy-prefixes ,values-form)) - (defmacro merge-encodings (form1 form2) `(multiple-value-bind (prefixes1 rexes1 opcode1 mod1 reg1 rm1 scale1 index1 base1 displacement1 immediate1 operand-size1 address-size1) ,form1 @@ -372,7 +374,7 @@ (:64-bit '(:rax :rcx :rdx :rbx :rsp :rbp :rsi :rdi :r8 :r9 :r10 :r11 :r12 :13 :r14 :r15)) (:mm '(:mm0 :mm1 :mm2 :mm3 :mm4 :mm5 :mm6 :mm7)) (:xmm '(:xmm0 :xmm1 :xmm2 :xmm3 :xmm4 :xmm5 :xmm6 :xmm7)))) - (error "Unknown ~D-bit register ~S." mode operand))) + (error "Unknown ~(~D~) register ~S." mode operand))) (multiple-value-bind (reg offsets reg2 reg-scale) (parse-indirect-operand operand) (check-type reg-scale (member nil 1 2 4 8)) @@ -702,7 +704,7 @@ :rex default-rex) (encode-reg/mem ,operand operator-mode))))) -(defun encode-reg-modrm (operator legacy-prefixes op-reg op-modrm opcode operator-mode default-rex &rest extras) +(defun encode-reg-modrm (operator legacy-prefixes op-reg op-modrm opcode operator-mode default-rex &optional reg/mem-mode &rest extras) (let* ((reg-map (ecase operator-mode (:8-bit '(:al :cl :dl :bl :ah :ch :dh :bh)) (:16-bit '(:ax :cx :dx :bx :sp :bp :si :di)) @@ -718,11 +720,10 @@ :operand-size operator-mode :rex default-rex extras) - (encode-reg/mem op-modrm operator-mode)))))) - -(defmacro reg-modrm (op-reg op-modrm opcode &rest extras) - `(return-when (encode-reg-modrm operator legacy-prefixes ,op-reg ,op-modrm ,opcode operator-mode default-rex , at extras))) + (encode-reg/mem op-modrm (or reg/mem-mode operator-mode))))))) +(defmacro reg-modrm (op-reg op-modrm opcode &optional reg/mem-mode &rest extras) + `(return-when (encode-reg-modrm operator legacy-prefixes ,op-reg ,op-modrm ,opcode operator-mode default-rex ,reg/mem-mode , at extras))) (defun encode-reg-cr (operator legacy-prefixes op-reg op-cr opcode operator-mode default-rex &rest extras) (let* ((reg-map (ecase operator-mode @@ -1140,10 +1141,12 @@ (typecase factor ((sint 8) (reg-modrm product1 product2 #x6b - :displacement (encode-integer factor '(sint 8)))) + nil + :displacement (encode-integer factor '(sint 8)))) ((sint 32) (reg-modrm product1 product2 #x69 - :displacement (encode-integer factor '(sint 32)))))) + nil + :displacement (encode-integer factor '(sint 32)))))) ;;;;;;;;;;; IN @@ -1264,7 +1267,8 @@ (pc-rel #xe9 dst (sint 32)) (when (or (not *position-independent-p*) (indirect-operand-p dst)) - (modrm dst #xff 4))) + (let ((operator-mode :32-bit)) + (modrm dst #xff 4)))) (define-operator* (:16 :jmpw-segment :32 :jmp-segment :64 :jmpr-segment) (addr) (modrm addr #xff 5)) @@ -1292,6 +1296,11 @@ (define-operator :leave () (opcode #xc9)) +;;;;;;;;;;; LFENCE + +(define-operator :lfence () + (opcode #x0faee8)) + ;;;;;;;;;;; LGDT, LIDT (define-operator* (:16 :lgdtw :32 :lgdt :64 :lgdtr) (addr) @@ -1300,10 +1309,10 @@ (define-operator* (:16 :lidtw :32 :lidt :64 :lidtr) (addr) (modrm addr #x0f01 3)) -;;;;;;;;;;; LFENCE +;;;;;;;;;;; LMSW -(define-operator :lfence () - (opcode #x0faee8)) +(define-operator/16 :lmsw (src) + (modrm src #x0f01 6)) ;;;;;;;;;;; LOOP, LOOPE, LOOPNE @@ -1360,6 +1369,17 @@ (reg-cr src dst #x0f22) (reg-cr dst src #x0f20)) +;;;;;;;;;;; MOVS + +(define-operator/8 :movsb () + (opcode #xa4)) + +(define-operator/16 :movsw () + (opcode #xa5)) + +(define-operator/32 :movsl () + (opcode #xa5)) + ;;;;;;;;;;; MOVSX (define-operator* (:32 :movsxb) (src dst) @@ -1371,7 +1391,7 @@ ;;;;;;;;;;; MOVZX (define-operator* (:32 :movzxb) (src dst) - (reg-modrm dst src #x0fb6)) + (reg-modrm dst src #x0fb6 :8-bit)) (define-operator* (:32 :movzxw) (src dst) (reg-modrm dst src #x0fb7)) @@ -1578,6 +1598,7 @@ (let ((immediate (resolve-operand count))) (when (typep immediate '(uint #x8)) (reg-modrm dst1 dst2 #x0fa4 + nil :immediate (encode-integer count '(uint 8))))))) ;;;;;;;;;;; SHR @@ -1603,6 +1624,7 @@ (let ((immediate (resolve-operand count))) (when (typep immediate '(uint #x8)) (reg-modrm dst1 dst2 #x0fac + nil :immediate (encode-integer count '(uint 8))))))) @@ -1648,7 +1670,10 @@ (imm-modrm mask dst #xf7 0 :int-16-32-64) (reg-modrm mask dst #x85)) -;;;;;;;;;;; XCHG +;;;;;;;;;;; WBINVD, WSRMSR + +(define-operator :wbinvd () + (opcode #x0f09)) (define-operator :wrmsr () (opcode #x0f30)) From ffjeld at common-lisp.net Sat Feb 9 09:50:46 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Sat, 9 Feb 2008 04:50:46 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080209095046.0F4E455355@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv27398 Modified Files: asm.lisp Log Message: Finishing touches on the assembler. --- /project/movitz/cvsroot/movitz/asm.lisp 2008/02/04 23:01:11 1.11 +++ /project/movitz/cvsroot/movitz/asm.lisp 2008/02/09 09:50:46 1.12 @@ -6,7 +6,7 @@ ;;;; Author: Frode Vatvedt Fjeld ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: asm.lisp,v 1.11 2008/02/04 23:01:11 ffjeld Exp $ +;;;; $Id: asm.lisp,v 1.12 2008/02/09 09:50:46 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -127,7 +127,7 @@ (defun resolve-operand (operand) - (etypecase operand + (typecase operand (integer operand) (symbol-reference @@ -139,7 +139,8 @@ (funcall-operand (apply (funcall-operand-operator operand) (mapcar #'resolve-operand - (funcall-operand-operands operand)))))) + (funcall-operand-operands operand)))) + (t operand))) ;;;;;;;;;;;; From ffjeld at common-lisp.net Sat Feb 9 09:50:48 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Sat, 9 Feb 2008 04:50:48 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080209095048.77CEE55355@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv27415 Modified Files: asm-x86.lisp Log Message: Finishing touches on the assembler. --- /project/movitz/cvsroot/movitz/asm-x86.lisp 2008/02/05 22:40:54 1.18 +++ /project/movitz/cvsroot/movitz/asm-x86.lisp 2008/02/09 09:50:48 1.19 @@ -6,7 +6,7 @@ ;;;; Author: Frode Vatvedt Fjeld ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: asm-x86.lisp,v 1.18 2008/02/05 22:40:54 ffjeld Exp $ +;;;; $Id: asm-x86.lisp,v 1.19 2008/02/09 09:50:48 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -194,12 +194,15 @@ nil)) (destructuring-bind (operator &rest operands) instruction - (let ((code (apply (or (gethash operator *instruction-encoders*) - (error "Unknown instruction operator ~S in ~S." operator instruction)) - operator - (mapcar #'prefix-lookup legacy-prefixes) - operands))) + (multiple-value-bind (code failp) + (apply (or (gethash operator *instruction-encoders*) + (error "Unknown instruction operator ~S in ~S." operator instruction)) + operator + (mapcar #'prefix-lookup legacy-prefixes) + operands) (cond + (failp + (error "Unable to encode ~S." instruction)) ((null options) code) ((assoc :size options) @@ -219,8 +222,7 @@ (declare (ignorable operator-mode default-rex)) (block operator , at body - (error "Unable to encode ~S." (list operator ,@(remove #\& lambda-list - :key (lambda (x) (char (string x) 0)))))))) + (values nil 'fail)))) (setf (gethash ',operator *instruction-encoders*) ',defun-name) ',operator))) @@ -274,7 +276,7 @@ (declare (ignorable operator-mode)) , at body))) -(defmacro define-operator* ((&key |16| |32| |64|) args &body body) +(defmacro define-operator* ((&key |16| |32| |64| dispatch) args &body body) (let ((body16 (subst '(xint 16) :int-16-32-64 (subst :dx :dx-edx-rdx (subst :ax :ax-eax-rax body)))) @@ -290,8 +292,21 @@ ,(when |32| `(define-operator/32 ,|32| ,args , at body32)) ,(when |64| - `(define-operator/64 ,|64| ,args , at body64))))) - + `(define-operator/64 ,|64| ,args , at body64)) + ,(when dispatch + (let ((dispatch-name (intern (format nil "~A-~A" 'instruction-dispatcher dispatch)))) + `(progn + (defun ,dispatch-name (&rest args) + (declare (dynamic-extent args)) + (loop for encoder in (ecase *cpu-mode* + (:32-bit ',(remove nil (list |32| |16| |64|))) + (:64-bit ',(remove nil (list |64| |32| |16|))) + (:16-bit ',(remove nil (list |16| |32| |64|)))) + thereis (apply (gethash encoder *instruction-encoders*) args) + finally (return (values nil 'fail)))) + (setf (gethash ',dispatch *instruction-encoders*) + ',dispatch-name)))) + nil))) (defun resolve-and-encode (x type &key size) (encode-integer (cond @@ -738,7 +753,9 @@ :mod #b11 :rm reg-index :reg cr-index - :operand-size operator-mode + :operand-size (if (not (eq *cpu-mode* :64-bit)) + nil + operator-mode) :rex default-rex extras))))) @@ -826,21 +843,62 @@ `(return-when (encode-opcode-reg-imm operator legacy-prefixes ,opcode ,op-reg ,op-imm ',type operator-mode default-rex))) +(defmacro far-pointer (opcode segment offset offset-type &rest extra) + `(when (and (immediate-p ,segment) + (indirect-operand-p ,offset)); FIXME: should be immediate-p, change in bootblock.lisp. + (let ((segment (resolve-operand ,segment)) + (offset (resolve-operand (car ,offset)))) + (when (and (typep segment '(uint 16)) + (typep offset ',offset-type)) + (return-when (encode (encoded-values :opcode ,opcode + :immediate (append (encode-integer offset ',offset-type) + (encode-integer segment '(uint 16))) + , at extra))))))) -;;;;;;;;;;; -;;;;;;;;;;;;;;;; NOP +;;;;;;;;;;; Pseudo-instructions -(define-operator :% (op &rest data) +(define-operator :% (op &rest form) (case op (:bytes - (let ((byte-size (pop data))) - (return-from operator + (return-from operator + (destructuring-bind (byte-size &rest data) + form (loop for datum in data append (loop for b from 0 below byte-size by 8 collect (ldb (byte 8 b) - datum)))))))) - + (resolve-operand datum))))))) + (:funcall + (return-from operator + (destructuring-bind (function &rest args) + form + (apply function (mapcar #'resolve-operand args))))) + (:fun + (return-from operator + (destructuring-bind (function &rest args) + (car form) + (loop for cbyte in (apply function (mapcar #'resolve-operand args)) + append (loop for octet from 0 below (imagpart cbyte) + collect (ldb (byte 8 (* 8 octet)) + (realpart cbyte))))))) + (:format + (return-from operator + (destructuring-bind (byte-size format-control &rest format-args) + form + (ecase byte-size + (8 (let ((data (map 'list #'char-code + (apply #'format nil format-control + (mapcar #'resolve-operand format-args))))) + (cons (length data) + data))))))) + (:align + (return-from operator + (destructuring-bind (alignment) + form + (let* ((offset (mod *pc* alignment))) + (when (plusp offset) + (make-list (- alignment offset) + :initial-element 0)))))))) ;;;;;;;;;;; ADC @@ -927,16 +985,14 @@ ;;;;;;;;;;; CALL -(define-operator/16 :callw (dest) - (pc-rel #xe8 dest (sint 16)) - (modrm dest #xff 2)) - -(define-operator/32 :call (dest) - (pc-rel #xe8 dest (sint 32)) - (modrm dest #xff 2)) - -(define-operator/32 :callr (dest) - (modrm dest #xff 2)) +(define-operator* (:16 :callw :32 :calll :64 :callr :dispatch :call) (dest) + (case *cpu-mode* + (:16-bit + (pc-rel #xe8 dest (sint 16))) + (:32-bit + (pc-rel #xe8 dest (sint 32)))) + (when (eq operator-mode *cpu-mode*) + (modrm dest #xff 2))) (define-operator :call-segment (dest) (modrm dest #xff 3)) @@ -1262,13 +1318,24 @@ ;;;;;;;;;;; JMP -(define-operator :jmp (dst) - (pc-rel #xeb dst (sint 8)) - (pc-rel #xe9 dst (sint 32)) - (when (or (not *position-independent-p*) - (indirect-operand-p dst)) - (let ((operator-mode :32-bit)) - (modrm dst #xff 4)))) +(define-operator :jmp (seg-dst &optional dst) + (cond + (dst + (when (eq *cpu-mode* :16-bit) + (far-pointer #xea seg-dst dst (uint 16))) + (when (eq *cpu-mode* :32-bit) + (far-pointer #xea seg-dst dst (xint 32)))) + (t (let ((dst seg-dst)) + (pc-rel #xeb dst (sint 8)) + (when (or (and (eq *cpu-mode* :32-bit) + *use-jcc-16-bit-p*) + (eq *cpu-mode* :16-bit)) + (pc-rel #xe9 dst (sint 16))) + (pc-rel #xe9 dst (sint 32)) + (when (or (not *position-independent-p*) + (indirect-operand-p dst)) + (let ((operator-mode :32-bit)) + (modrm dst #xff 4))))))) (define-operator* (:16 :jmpw-segment :32 :jmp-segment :64 :jmpr-segment) (addr) (modrm addr #xff 5)) @@ -1303,8 +1370,9 @@ ;;;;;;;;;;; LGDT, LIDT -(define-operator* (:16 :lgdtw :32 :lgdt :64 :lgdtr) (addr) - (modrm addr #x0f01 2)) +(define-operator* (:16 :lgdtw :32 :lgdtl :64 :lgdtr :dispatch :lgdt) (addr) + (when (eq operator-mode *cpu-mode*) + (modrm addr #x0f01 2))) (define-operator* (:16 :lidtw :32 :lidt :64 :lidtr) (addr) (modrm addr #x0f01 3)) @@ -1314,6 +1382,14 @@ (define-operator/16 :lmsw (src) (modrm src #x0f01 6)) +;;;;;;;;;;; LODS + +(define-operator/8 :lodsb () + (opcode #xac)) + +(define-operator* (:16 :lodsw :32 :lodsl :64 :lodsr) () + (opcode #xad)) + ;;;;;;;;;;; LOOP, LOOPE, LOOPNE (define-operator :loop (dst) @@ -1361,13 +1437,17 @@ ;;;;;;;;;;; MOVCR -(define-operator/32 :movcr (src dst) +(define-operator* (:32 :movcrl :64 :movcrr :dispatch :movcr) (src dst) (when (eq src :cr8) - (reg-cr dst :cr0 #xf00f20)) + (reg-cr dst :cr0 #xf00f20 + :operand-size nil)) (when (eq dst :cr8) - (reg-cr src :cr0 #xf00f22)) - (reg-cr src dst #x0f22) - (reg-cr dst src #x0f20)) + (reg-cr src :cr0 #xf00f22 + :operand-size nil)) + (reg-cr src dst #x0f22 + :operand-size nil) + (reg-cr dst src #x0f20 + :operand-size nil)) ;;;;;;;;;;; MOVS @@ -1390,7 +1470,7 @@ ;;;;;;;;;;; MOVZX -(define-operator* (:32 :movzxb) (src dst) +(define-operator* (:16 :movzxbw :32 :movzxbl :dispatch :movzxb) (src dst) (reg-modrm dst src #x0fb6 :8-bit)) (define-operator* (:32 :movzxw) (src dst) From ffjeld at common-lisp.net Sat Feb 9 18:42:00 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Sat, 9 Feb 2008 13:42:00 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080209184200.8C78F340A8@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv21024 Modified Files: image.lisp Log Message: Buglet in disassembler comment generator, wrt. recognizing characters. --- /project/movitz/cvsroot/movitz/image.lisp 2007/04/01 18:18:26 1.113 +++ /project/movitz/cvsroot/movitz/image.lisp 2008/02/09 18:42:00 1.114 @@ -9,7 +9,7 @@ ;;;; Created at: Sun Oct 22 00:22:43 2000 ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: image.lisp,v 1.113 2007/04/01 18:18:26 ffjeld Exp $ +;;;; $Id: image.lisp,v 1.114 2008/02/09 18:42:00 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -1313,7 +1313,7 @@ (format nil "branch to ~S at ~D" label x) (format nil "branch to ~D" x))) when (and (typep operand 'ia-x86::operand-immediate) - (<= 256 (ia-x86::operand-value operand)) + (<= #x100 (ia-x86::operand-value operand) #x10000) (= (tag :character) (mod (ia-x86::operand-value operand) 256))) collect (format nil "#\\~C" (code-char (truncate (ia-x86::operand-value operand) 256))) when (and (typep operand 'ia-x86::operand-immediate) From ffjeld at common-lisp.net Sat Feb 9 18:42:26 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Sat, 9 Feb 2008 13:42:26 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080209184226.2EB7A691A4@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv21135 Modified Files: bootblock.lisp Log Message: Use new assembler. Compile twice as fast. --- /project/movitz/cvsroot/movitz/bootblock.lisp 2007/03/16 17:39:27 1.13 +++ /project/movitz/cvsroot/movitz/bootblock.lisp 2008/02/09 18:42:26 1.14 @@ -9,7 +9,7 @@ ;;;; Created at: Mon Oct 9 20:47:19 2000 ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: bootblock.lisp,v 1.13 2007/03/16 17:39:27 ffjeld Exp $ +;;;; $Id: bootblock.lisp,v 1.14 2008/02/09 18:42:26 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -83,245 +83,239 @@ (let* ((first-sector (1+ skip-sectors)) (last-sector (+ first-sector (ceiling image-size +sector-size+))) (read-buffer-segment (floor +read-buffer+ #x10))) - (ia-x86:read-proglist - `( - (:jmp (:pc+ 0)) ; some BIOSes might check for this. - - ;; - ;; We are running at address #x7c00. - ;; - - (:xorw :ax :ax) - (:movw :ax :ds) - (:movw :ax :es) - - (:movw #x9000 :ax) - (:movw :ax :ss) - (:movw #xfffc :bp) - (:leaw (:bp ,(- +stack-frame-size+)) :sp) - (:movw 'welcome :si) ; Print welcome message) - (:call 'print) - - ;; - ;; Enable the A20 gate - ;; - (:call 'empty-8042) - (:movb #xd1 :al) - (:outb :al #x64) - - (:call 'empty-8042) - (:movb #xdf :al) - (:outb :al #x60) - (:call 'empty-8042) - - ;; Poll the floppy's sectors per track - - (:movw 5 (:bp ,+sectors-per-track+)) - check-geometry - (:incb (:bp ,+sectors-per-track+)) - (:jz 'read-error) - (:movw (:bp ,+sectors-per-track+) :cx ) - (:movw #x0201 :ax) - (:xorw :dx :dx) - (:movw ,read-buffer-segment :bx) - (:movw :bx :es) - (:xorw :bx :bx) - (:int #x13) ; Call BIOS routine - (:testb :ah :ah) - (:jz 'check-geometry) - (:decb (:bp ,+sectors-per-track+)) - - ;; - ;; Read sectors into memory - ;; + `((:jmp (:pc+ 0)) ; some BIOSes might check for this. + ;; + ;; We are running at address #x7c00. + ;; + (:xorw :ax :ax) + (:movw :ax :ds) + (:movw :ax :es) + + (:movw #x9000 :ax) + (:movw :ax :ss) + (:movw #xfffc :bp) + (:leaw (:bp ,(- +stack-frame-size+)) :sp) + (:movw 'welcome :si) ; Print welcome message) + (:call 'print) + + ;; + ;; Enable the A20 gate + ;; + (:call 'empty-8042) + (:movb #xd1 :al) + (:outb :al #x64) + + (:call 'empty-8042) + (:movb #xdf :al) + (:outb :al #x60) + (:call 'empty-8042) + + ;; Poll the floppy's sectors per track + + (:movw 5 (:bp ,+sectors-per-track+)) + check-geometry + (:incb (:bp ,+sectors-per-track+)) + (:jz 'read-error) + (:movw (:bp ,+sectors-per-track+) :cx ) + (:movw #x0201 :ax) + (:xorw :dx :dx) + (:movw ,read-buffer-segment :bx) + (:movw :bx :es) + (:xorw :bx :bx) + (:int #x13) ; Call BIOS routine + (:testb :ah :ah) + (:jz 'check-geometry) + (:decb (:bp ,+sectors-per-track+)) + + ;; + ;; Read sectors into memory + ;; - (:movw ,first-sector (:bp ,+linear-sector+)) - (:movl ,load-address (:bp ,+destination+)) + (:movw ,first-sector (:bp ,+linear-sector+)) + (:movl ,load-address (:bp ,+destination+)) - read-loop + read-loop - (:cmpw ,last-sector (:bp ,+linear-sector+)) - (:jg 'read-done) + (:cmpw ,last-sector (:bp ,+linear-sector+)) + (:jg 'read-done) - (:movw 'track-start-msg :si) ; Print '(' to screen for each track - (:call 'print) + (:movw 'track-start-msg :si) ; Print '(' to screen for each track + (:call 'print) - (:movw (:bp ,+linear-sector+) :ax) - (:movb (:bp ,+sectors-per-track+) :cl) - (:divb :cl :ax) ; al=quotient, ah=remainder of :ax/:cl - - (:movb :ah :cl) ; sector - 1 - (:movb :al :dh) - (:andb 1 :dh) ; head - (:movb :al :ch) - (:shrb 1 :ch) ; track - (:xorb :dl :dl) ; drive = 0 - (:movw (:bp ,+sectors-per-track+) :ax) - (:subb :cl :al) ; number of sectors (rest of track) - (:incb :cl) - (:addw :ax (:bp ,+linear-sector+)) ; update read pointer - (:movw (:bp ,+linear-sector+) :bx) ; subtract some if it's the last track. - (:subw ,last-sector :bx) - (:jc 'subtract-zero-sectors) - (:subw :bx :ax) - (:jz 'read-done) - subtract-zero-sectors - (:movb 2 :ah) - - (:movw ,read-buffer-segment :bx) - (:movw :bx :es) - (:xorw :bx :bx) - (:int #x13) ; Call BIOS routine - - (:jc 'read-error) - (:movzxb :al :ecx) - - ;; - ;; Install GS as 4GB segment - ;; http://www.faqs.org/faqs/assembly-language/x86/general/part2/ - ;; - (:cli) - (:lgdt ('gdt-addr)) ; load gdt - (:movcr :cr0 :eax) - (:orb 1 :al) - (:movcr :eax :cr0) - (:jmp (:pc+ 0)) - (:movw 16 :bx) - (:movw :bx :gs) - (:andb #xfe :al) - (:movcr :eax :cr0) - (:jmp (:pc+ 0)) - (:sti) - ;; Completed install GS as 4GB segment. - - ;; Copy data to destination - (:shll ,(+ 9 -2) :ecx) ; 512/4 = sector-size/word-size - (:movl ,+read-buffer+ :ebx) - (:movl (:bp ,+destination+) :esi) - (:leal (:esi (:ecx 4)) :edx) - - (:movl :edx (:bp ,+destination+)) - - copy-loop - (:decl :ecx) - ((:gs-override) :movl (:ebx (:ecx 4)) :edx) - ((:gs-override) :movl :edx (:esi (:ecx 4))) - (:jnz 'copy-loop) - - (:movw 'track-end-msg :si) ; Print ')' to screen after each track - (:call 'print) - - (:jmp 'read-loop) - - read-done - - motor-loop ; Wait for floppy motor - (:btw 8 (#x43e)) - (:jc 'motor-loop) - - (movw 'entering :si) ; Print welcome message - (call 'print) - - ;; Read the cursor position into DH (row) and DL (column). - (:movb 3 :ah) - (:movb 0 :bh) - (:int #x10) - - (:cli) ; Disable interrupts - (:lgdt ('gdt-addr)) ; load gdt - - (:xorw :ax :ax) - (:movw :ax :es) ; reset es - - ;; - ;; Turn off the cursor - ;; + (:movw (:bp ,+linear-sector+) :ax) + (:movb (:bp ,+sectors-per-track+) :cl) + (:divb :cl :ax) ; al=quotient, ah=remainder of :ax/:cl + + (:movb :ah :cl) ; sector - 1 + (:movb :al :dh) + (:andb 1 :dh) ; head + (:movb :al :ch) + (:shrb 1 :ch) ; track + (:xorb :dl :dl) ; drive = 0 + (:movw (:bp ,+sectors-per-track+) :ax) + (:subb :cl :al) ; number of sectors (rest of track) + (:incb :cl) + (:addw :ax (:bp ,+linear-sector+)) ; update read pointer + (:movw (:bp ,+linear-sector+) :bx) ; subtract some if it's the last track. + (:subw ,last-sector :bx) + (:jc 'subtract-zero-sectors) + (:subw :bx :ax) + (:jz 'read-done) + subtract-zero-sectors + (:movb 2 :ah) + + (:movw ,read-buffer-segment :bx) + (:movw :bx :es) + (:xorw :bx :bx) + (:int #x13) ; Call BIOS routine + + (:jc 'read-error) + (:movzxb :al :ecx) + + ;; + ;; Install GS as 4GB segment + ;; http://www.faqs.org/faqs/assembly-language/x86/general/part2/ + ;; + (:cli) + (:lgdt ('gdt-addr)) ; load gdt + (:movcr :cr0 :eax) + (:orb 1 :al) + (:movcr :eax :cr0) + (:jmp (:pc+ 0)) + (:movw 16 :bx) + (:movw :bx :gs) + (:andb #xfe :al) + (:movcr :eax :cr0) + (:jmp (:pc+ 0)) + (:sti) + ;; Completed install GS as 4GB segment. + + ;; Copy data to destination + (:shll ,(+ 9 -2) :ecx) ; 512/4 = sector-size/word-size + (:movl ,+read-buffer+ :ebx) + (:movl (:bp ,+destination+) :esi) + (:leal (:esi (:ecx 4)) :edx) + + (:movl :edx (:bp ,+destination+)) + + copy-loop + (:decl :ecx) + ((:gs-override) :movl (:ebx (:ecx 4)) :edx) + ((:gs-override) :movl :edx (:esi (:ecx 4))) + (:jnz 'copy-loop) + + (:movw 'track-end-msg :si) ; Print ')' to screen after each track + (:call 'print) + + (:jmp 'read-loop) + + read-done + + motor-loop ; Wait for floppy motor + (:btw 8 (#x43e)) + (:jc 'motor-loop) + + (:movw 'entering :si) ; Print welcome message + (:call 'print) + + ;; Read the cursor position into DH (row) and DL (column). + (:movb 3 :ah) + (:movb 0 :bh) + (:int #x10) + + (:cli) ; Disable interrupts + (:lgdt ('gdt-addr)) ; load gdt + + (:xorw :ax :ax) + (:movw :ax :es) ; reset es + + ;; + ;; Turn off the cursor + ;; ;;; (movb #x01 :ah) ;;; (movw #x0100 :cx) ;;; (int #x10) - ;; - ;; Load machine status word. This will enable - ;; protected mode. The subsequent instruction MUST - ;; reload the code segment register with a selector for - ;; the protected mode code segment descriptor (see - ;; GDT specification). - ;; - (:movw 1 :ax) - (:lmsw :ax) ; load word 0 of cr0 - - ;; - ;; Do a longjump to new-world. This will cause the CS to - ;; be loaded with the correct descriptor, and the processor - ;; will now run in 32 bit mode. - ;; - - (:jmp 8 ('new-world)) - - ;; - ;; Display error message and hang - ;; - read-error - (:movw 'error :si) ; Print error message - (:call 'print) - halt-cpu - (:halt) - (:jmp 'halt-cpu) ; Infinite loop - - ;; - ;; Empty the 8042 Keyboard controller - ;; - empty-8042 - (:call 'delay) - (:inb #x64 :al) ; 8042 status port - (:testb 1 :al) ; if ( no information available ) - (:jz 'no-output) ; goto no_output - (:call 'delay) - (:inb #x60 :al) ; read it - (:jmp 'empty-8042) - no-output - (:testb 2 :al) ; if ( input buffer is full ) - (:jnz 'empty-8042) ; goto empty_8042 - (:ret) - - delay - (:xorw :cx :cx) - delay-loop - (:loop 'delay-loop) - (:ret) - - print ,@(mkasm16-bios-print) - - ;; Data - welcome (% format 8 "Loading Movitz ~D..~% " - ,(incf *bootblock-build*)) - entering (% format 8 "~% Enter..") - error (% format 8 "Failed!)") - track-start-msg (% format 8 "(") - track-end-msg (% format 8 ")") - sector-msg (% format 8 "-") + ;; + ;; Load machine status word. This will enable + ;; protected mode. The subsequent instruction MUST + ;; reload the code segment register with a selector for + ;; the protected mode code segment descriptor (see + ;; GDT specification). + ;; + (:movw 1 :ax) + (:lmsw :ax) ; load word 0 of cr0 + + ;; + ;; Do a longjump to new-world. This will cause the CS to + ;; be loaded with the correct descriptor, and the processor + ;; will now run in 32 bit mode. + ;; + + (:jmp 8 ('new-world)) + + ;; + ;; Display error message and hang + ;; + read-error [234 lines skipped] From ffjeld at common-lisp.net Sat Feb 9 18:42:40 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Sat, 9 Feb 2008 13:42:40 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080209184240.144D068322@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv21152 Modified Files: compiler.lisp Log Message: Use new assembler. Compile twice as fast. --- /project/movitz/cvsroot/movitz/compiler.lisp 2008/02/04 23:08:07 1.187 +++ /project/movitz/cvsroot/movitz/compiler.lisp 2008/02/09 18:42:29 1.188 @@ -8,7 +8,7 @@ ;;;; Created at: Wed Oct 25 12:30:49 2000 ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: compiler.lisp,v 1.187 2008/02/04 23:08:07 ffjeld Exp $ +;;;; $Id: compiler.lisp,v 1.188 2008/02/09 18:42:29 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -112,7 +112,7 @@ (or (member (car list) (cdr list)) (duplicatesp (cdr list))))) -(defun compute-call-extra-prefix (instr env size) +(defun old-compute-call-extra-prefix (instr env size) (let* ((return-pointer-tag (ldb (byte 3 0) (+ (ia-x86::assemble-env-current-pc env) size)))) @@ -131,7 +131,7 @@ '(#x90 #x90 #x90) '(#x90))))) -(defun new-compute-call-extra-prefix (pc size) +(defun compute-call-extra-prefix (pc size) (let* ((return-pointer-tag (ldb (byte 3 0) (+ pc size)))) (cond @@ -162,21 +162,19 @@ (resolved-code (finalize-code body-code nil nil))) (multiple-value-bind (code-vector symtab) - #+use-old-ia-x86 - (let ((ia-x86:*instruction-compute-extra-prefix-map* - '((:call . compute-call-extra-prefix)))) - (ia-x86:proglist-encode :octet-vector - :32-bit - #x00000000 - (ia-x86:read-proglist resolved-code) - :symtab-lookup (lambda (label) - (case label - (:nil-value (image-nil-word *image*)))))) - (let ((asm:*instruction-compute-extra-prefix-map* - '((:call . new-compute-call-extra-prefix)))) - (asm:proglist-encode (translate-program resolved-code :muerte.cl :cl) - :symtab (list (cons :nil-value (image-nil-word *image*))))) - +;; (let ((ia-x86:*instruction-compute-extra-prefix-map* +;; '((:call . old-compute-call-extra-prefix)))) +;; (ia-x86:proglist-encode :octet-vector +;; :32-bit +;; #x00000000 +;; (ia-x86:read-proglist resolved-code) +;; :symtab-lookup (lambda (label) +;; (case label +;; (:nil-value (image-nil-word *image*)))))) + (let ((asm:*instruction-compute-extra-prefix-map* + '((:call . compute-call-extra-prefix)))) + (asm:proglist-encode (translate-program resolved-code :muerte.cl :cl) + :symtab (list (cons :nil-value (image-nil-word *image*))))) (values (make-movitz-vector (length code-vector) :element-type 'code :initial-contents code-vector) @@ -1025,52 +1023,58 @@ (defun diss (code) (format nil "~&;; Diss: ~:{~4D: ~16<~{ ~2,'0X~}~;~> ~A~@[ ;~{ ~A~}~]~%~}" - (loop with code-position = 0 + (loop with code-position = 0 and instruction-octets = nil for pc = 0 then code-position - for instruction = (ia-x86:decode-read-octet - #'(lambda () - (incf code-position) - (pop code))) - for cbyte = (and instruction - (ia-x86::instruction-original-datum instruction)) - until (null instruction) - collect (list pc - (ia-x86::cbyte-to-octet-list cbyte) - instruction - (comment-instruction instruction nil pc))))) + for instruction = (progn + (setf instruction-octets nil) + (ia-x86:decode-read-octet (lambda () + (incf code-position) + (loop while (and code (not (typep (car code) '(unsigned-byte 8)))) + do (warn "diss bad byte at ~D: ~S" code-position (pop code)) + (incf code-position)) + (let ((x (pop code))) + (when x (push x instruction-octets)) + x)))) + collect (if (not instruction) + (list pc (nreverse instruction-octets) nil '("???")) + (list pc + (nreverse instruction-octets) + ;;(ia-x86::cbyte-to-octet-list (ia-x86::instruction-original-datum instruction)) + instruction + (comment-instruction instruction nil pc))) + while code))) (defun assemble-funobj (funobj combined-code) +;; (multiple-value-bind (code-vector code-symtab) +;; (let ((ia-x86:*instruction-compute-extra-prefix-map* +;; '((:call . old-compute-call-extra-prefix)))) +;; (ia-x86:proglist-encode :octet-vector :32-bit #x00000000 +;; (ia-x86:read-proglist combined-code) +;; :symtab-lookup +;; (lambda (label) +;; (case label +;; (:nil-value (image-nil-word *image*)) +;; (t (let ((set (cdr (assoc label +;; (movitz-funobj-jumpers-map funobj))))) +;; (when set +;; (let ((pos (search set (movitz-funobj-const-list funobj) +;; :end2 (movitz-funobj-num-jumpers funobj)))) +;; (assert pos () +;; "Couldn't find for ~s set ~S in ~S." +;; label set (subseq (movitz-funobj-const-list funobj) +;; 0 (movitz-funobj-num-jumpers funobj))) +;; (* 4 pos))))))))) (multiple-value-bind (code-vector code-symtab) - #+use-old-ia-x86 - (let ((ia-x86:*instruction-compute-extra-prefix-map* - '((:call . compute-call-extra-prefix)))) - (ia-x86:proglist-encode :octet-vector :32-bit #x00000000 - (ia-x86:read-proglist combined-code) - :symtab-lookup - (lambda (label) - (case label - (:nil-value (image-nil-word *image*)) - (t (let ((set (cdr (assoc label - (movitz-funobj-jumpers-map funobj))))) - (when set - (let ((pos (search set (movitz-funobj-const-list funobj) - :end2 (movitz-funobj-num-jumpers funobj)))) - (assert pos () - "Couldn't find for ~s set ~S in ~S." - label set (subseq (movitz-funobj-const-list funobj) - 0 (movitz-funobj-num-jumpers funobj))) - (* 4 pos))))))))) - (let ((asm:*instruction-compute-extra-prefix-map* - '((:call . new-compute-call-extra-prefix)))) - (asm:proglist-encode combined-code - :symtab (list* (cons :nil-value (image-nil-word *image*)) - (loop for (label . set) in (movitz-funobj-jumpers-map funobj) - collect (cons label - (* 4 (or (search set (movitz-funobj-const-list funobj) - :end2 (movitz-funobj-num-jumpers funobj)) - (error "Jumper for ~S missing." label)))))))) - + (let ((asm:*instruction-compute-extra-prefix-map* + '((:call . compute-call-extra-prefix)))) + (asm:proglist-encode combined-code + :symtab (list* (cons :nil-value (image-nil-word *image*)) + (loop for (label . set) in (movitz-funobj-jumpers-map funobj) + collect (cons label + (* 4 (or (search set (movitz-funobj-const-list funobj) + :end2 (movitz-funobj-num-jumpers funobj)) + (error "Jumper for ~S missing." label)))))))) (setf (movitz-funobj-symtab funobj) code-symtab) (let* ((code-length (- (length code-vector) 3 -3)) (code-vector (make-array code-length @@ -1118,7 +1122,7 @@ (make-movitz-vector (length code-vector) :fill-pointer code-length :element-type 'code - :initial-contents code-vector))))) + :initial-contents code-vector)))) funobj) (defun check-locate-concistency (code-vector) @@ -1138,123 +1142,6 @@ (aref code-vector (+ x 3))))) (values)) -#+ignore -(defun make-compiled-function-body-default (form funobj env top-level-p) - (make-compiled-body-pass2 (make-compiled-function-pass1 form funobj env top-level-p) - env)) - -#+ignore -(defun old-make-compiled-function-body-default (form funobj env top-level-p &key include-programs) - (multiple-value-bind (arg-init-code body-form need-normalized-ecx-p) - (make-function-arguments-init funobj env form) - (multiple-value-bind (resolved-code stack-frame-size use-stack-frame-p frame-map) - (make-compiled-body body-form funobj env top-level-p arg-init-code include-programs) - (multiple-value-bind (prelude-code have-normalized-ecx-p) - (make-compiled-function-prelude stack-frame-size env use-stack-frame-p - need-normalized-ecx-p frame-map) - (values (install-arg-cmp (append prelude-code - resolved-code - (make-compiled-function-postlude funobj env use-stack-frame-p)) - have-normalized-ecx-p) - use-stack-frame-p))))) - -#+ignore -(defun make-compiled-function-body-without-prelude (form funobj env top-level-p) - (multiple-value-bind (code stack-frame-size use-stack-frame-p) - (make-compiled-body form funobj env top-level-p) - (if (not use-stack-frame-p) - (append code (make-compiled-function-postlude funobj env nil)) - (values (append `((:pushl :ebp) - (:movl :esp :ebp) - (:pushl :esi) - start-stack-frame-setup) - (case stack-frame-size - (0 nil) - (1 '((:pushl :edi))) - (2 '((:pushl :edi) (:pushl :edi))) - (t `((:subl ,(* 4 stack-frame-size) :esp)))) - (when (tree-search code '(:ecx)) - `((:testb :cl :cl) - (:js '(:sub-program (normalize-ecx) - (:shrl 8 :ecx) - (:jmp 'normalize-ecx-ok))) - (:andl #x7f :ecx) - normalize-ecx-ok)) - code - (make-compiled-function-postlude funobj env t)) - use-stack-frame-p)))) - -#+ignore -(defun make-compiled-function-body-2req-1opt (form funobj env top-level-p) - (when (and (= 2 (length (required-vars env))) - (= 1 (length (optional-vars env))) - (= 0 (length (key-vars env))) - (null (rest-var env))) - (let* ((opt-var (first (optional-vars env))) - (opt-binding (movitz-binding opt-var env nil)) - (req1-binding (movitz-binding (first (required-vars env)) env nil)) - (req2-binding (movitz-binding (second (required-vars env)) env nil)) - (default-form (optional-function-argument-init-form opt-binding))) - (compiler-values-bind (&code push-default-code-uninstalled &producer default-code-producer) - (compiler-call #'compile-form - :form default-form - :result-mode :push - :env env - :funobj funobj) - (cond - ((eq 'compile-self-evaluating default-code-producer) - (multiple-value-bind (code stack-frame-size use-stack-frame-p frame-map) - (make-compiled-body form funobj env top-level-p nil (list push-default-code-uninstalled)) - (when (and (new-binding-located-p req1-binding frame-map) - (new-binding-located-p req2-binding frame-map) - (new-binding-located-p opt-binding frame-map)) - (multiple-value-bind (eax-ebx-code eax-ebx-stack-offset) - (make-2req req1-binding req2-binding frame-map) - (let ((stack-init-size (- stack-frame-size eax-ebx-stack-offset)) - (push-default-code - (finalize-code push-default-code-uninstalled funobj env frame-map))) - (values (append `((:jmp '(:sub-program () - (:cmpb 2 :cl) - (:je 'entry%2op) - (:cmpb 3 :cl) - (:je 'entry%3op) - (:int 100))) - entry%3op - (:pushl :ebp) - (:movl :esp :ebp) - (:pushl :esi) - start-stack-frame-setup - ,@(when (and (edx-var env) (new-binding-located-p (edx-var env) frame-map)) - `((:movl :edx (:ebp ,(stack-frame-offset - (new-binding-location (edx-var env) frame-map)))))) - , at eax-ebx-code - ,@(if (eql (1+ eax-ebx-stack-offset) - (new-binding-location opt-binding frame-map)) - (append `((:pushl (:ebp ,(argument-stack-offset-shortcut 3 2)))) - (make-compiled-stack-frame-init (1- stack-init-size))) - (append (make-compiled-stack-frame-init stack-init-size) - `((:movl (:ebp ,(argument-stack-offset-shortcut 3 2)) :edx) - (:movl :edx (:ebp ,(stack-frame-offset - (new-binding-location opt-binding - frame-map))))))) - (:jmp 'arg-init-done) - entry%2op - (:pushl :ebp) - (:movl :esp :ebp) - (:pushl :esi) - , at eax-ebx-code - ,@(if (eql (1+ eax-ebx-stack-offset) - (new-binding-location opt-binding frame-map)) - (append push-default-code - (make-compiled-stack-frame-init (1- stack-init-size))) - (append (make-compiled-stack-frame-init stack-init-size) - push-default-code - `((:popl (:ebp ,(stack-frame-offset (new-binding-location opt-binding frame-map))))))) - arg-init-done) - code - (make-compiled-function-postlude funobj env t)) - use-stack-frame-p)))))) - (t nil)))))) (defun make-2req (binding0 binding1 frame-map) (let ((location-0 (new-binding-location binding0 frame-map)) From ffjeld at common-lisp.net Wed Feb 13 21:46:52 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Wed, 13 Feb 2008 16:46:52 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080213214652.23D254F019@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv12893 Modified Files: asm-x86.lisp Log Message: Starting work on disassembler. --- /project/movitz/cvsroot/movitz/asm-x86.lisp 2008/02/09 09:50:48 1.19 +++ /project/movitz/cvsroot/movitz/asm-x86.lisp 2008/02/13 21:46:51 1.20 @@ -6,7 +6,7 @@ ;;;; Author: Frode Vatvedt Fjeld ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: asm-x86.lisp,v 1.19 2008/02/09 09:50:48 ffjeld Exp $ +;;;; $Id: asm-x86.lisp,v 1.20 2008/02/13 21:46:51 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -210,70 +210,161 @@ (length code))) code)))))) - -(defmacro define-operator (operator lambda-list &body body) +(defmacro define-operator (operator operator-mode lambda-list &body body) (check-type operator keyword) - (let ((defun-name (intern (format nil "~A-~A" 'instruction-encoder operator)))) - `(progn - (defun ,defun-name (operator legacy-prefixes , at lambda-list) - (declare (ignorable operator legacy-prefixes)) - (let ((operator-mode nil) - (default-rex nil)) - (declare (ignorable operator-mode default-rex)) - (block operator - , at body - (values nil 'fail)))) - (setf (gethash ',operator *instruction-encoders*) - ',defun-name) - ',operator))) + (labels ((find-forms (body) + (cond + ((atom body) + nil) + ((member (car body) '(reg-modrm)) + (list body)) + (t (mapcan #'find-forms body))))) + (let ((defun-name (intern (format nil "~A-~A" 'instruction-encoder operator)))) + `(progn + (defun ,defun-name (operator legacy-prefixes , at lambda-list) + (declare (ignorable operator legacy-prefixes)) + (let ((operator-mode ',operator-mode) + (default-rex nil)) + (declare (ignorable operator-mode default-rex)) + (macrolet ((disassembler (&body body) + (declare (ignore body))) + (assembler (&body body) + `(progn , at body))) + (block operator + , at body + (values nil 'fail))))) + (setf (gethash ',operator *instruction-encoders*) + ',defun-name) + (macrolet ((disassembler (&body body) + `(progn , at body)) + (assembler (&body body) + (declare (ignore body)))) + (let ((operator ',operator) + (operator-mode ',operator-mode)) + ,@(find-forms body))) + ',operator)))) + +(defmacro define-operator/none (name lambda-list &body body) + `(define-operator ,name nil ,lambda-list , at body)) + +(deftype list-of (&rest elements) + (labels ((make-list-of (elements) + (if (null elements) + 'null + `(cons ,(car elements) + ,(make-list-of (cdr elements)))))) + (make-list-of elements))) + +(defparameter *opcode-disassemblers-16* + (make-array 256 :initial-element nil)) + +(defparameter *opcode-disassemblers-32* + (make-array 256 :initial-element nil)) + +(defparameter *opcode-disassemblers-64* + (make-array 256 :initial-element nil)) + +(deftype disassembly-decoder () + '(list-of keyword (or keyword nil) symbol)) + +(defun (setf opcode-disassembler) (decoder opcode operator-mode) + (check-type decoder disassembly-decoder) + (labels ((set-it (table pos) + (check-type pos (integer 0 *)) + (check-type table (simple-vector 256)) + (let ((bit-pos (* 8 (1- (ceiling (integer-length pos) 8))))) + (if (not (plusp bit-pos)) + (progn + (unless (or (eq nil decoder) + (eq nil (svref table pos)) + (equal decoder (svref table pos))) + (warn "Redefining disassembler for opcode #x~X from ~{~S ~}to ~{~S~^ ~}." + opcode (svref table pos) decoder)) + (setf (svref table pos) decoder)) + (set-it (or (svref table (ldb (byte 8 bit-pos) pos)) + (setf (svref table (ldb (byte 8 bit-pos) pos)) + (make-array 256 :initial-element nil))) + (ldb (byte bit-pos 0) pos)))))) + (ecase operator-mode + (:16-bit + (set-it *opcode-disassemblers-16* opcode)) + (:32-bit + (set-it *opcode-disassemblers-32* opcode)) + (:64-bit + (set-it *opcode-disassemblers-64* opcode)) + (:8-bit + (set-it *opcode-disassemblers-16* opcode) + (set-it *opcode-disassemblers-32* opcode) + (set-it *opcode-disassemblers-64* opcode))))) + +(defun disassemble-code (code) + (labels ((lookup-decoder (table opcode) + (let* ((datum (pop-code code)) + (opcode (logior (ash opcode 8) + datum)) + (decoder (svref table datum))) + (typecase decoder + ((simple-vector 256) + (lookup-decoder decoder opcode)) + ((list-of keyword (or keyword null) symbol) + (values decoder + opcode)) + (t (error "No disassembler registered for opcode #x~X." opcode)))))) + (destructuring-bind (operator operator-mode operand-decoder) + (lookup-decoder (ecase *cpu-mode* + (:16-bit *opcode-disassemblers-16*) + (:32-bit *opcode-disassemblers-32*) + (:64-bit *opcode-disassemblers-64*)) + 0) + (values (list* operator (code-call (funcall operand-decoder code operator-mode) code)) + code)))) + +(defmacro define-disassembler (opcode operands operator-mode) + `(disassembler + (setf (opcode-disassembler ,opcode ,operator-mode) (list operator ,operator-mode ',operands)))) (defmacro define-operator/8 (operator lambda-list &body body) - `(define-operator ,operator ,lambda-list - (let ((operator-mode :8-bit) - (default-rex nil)) - (declare (ignorable operator-mode default-rex)) + `(define-operator ,operator :8-bit ,lambda-list + (let ((default-rex nil)) + (declare (ignorable default-rex)) (macrolet ((yield (&rest args) `(return-from operator (encode (encoded-values :operand-size operator-mode , at args))))) , at body)))) (defmacro define-operator/16 (operator lambda-list &body body) - `(define-operator ,operator ,lambda-list - (let ((operator-mode :16-bit) - (default-rex nil)) - (declare (ignorable operator-mode default-rex)) + `(define-operator ,operator :16-bit ,lambda-list + (let ((default-rex nil)) + (declare (ignorable default-rex)) (macrolet ((yield (&rest args) `(return-from operator (encode (encoded-values :operand-size operator-mode , at args))))) , at body)))) (defmacro define-operator/32 (operator lambda-list &body body) - `(define-operator ,operator ,lambda-list - (let ((operator-mode :32-bit) - (default-rex nil)) - (declare (ignorable operator-mode default-rex)) + `(define-operator ,operator :32-bit ,lambda-list + (let ((default-rex nil)) + (declare (ignorable default-rex)) (macrolet ((yield (&rest args) `(return-from operator (encode (encoded-values :operand-size operator-mode , at args))))) , at body)))) (defmacro define-operator/64 (operator lambda-list &body body) - `(define-operator ,operator ,lambda-list - (let ((operator-mode :64-bit) - (default-rex '(:rex.w))) - (declare (ignorable operator-mode default-rex)) + `(define-operator ,operator :64-bit ,lambda-list + (let ((default-rex '(:rex.w))) + (declare (ignorable default-rex)) (macrolet ((yield (&rest args) `(return-from operator (encode (encoded-values :operand-size operator-mode , at args))))) , at body)))) (defmacro define-operator/64* (operator lambda-list &body body) - `(define-operator ,operator ,lambda-list - (let ((operator-mode :64-bit) - (default-rex (case *cpu-mode* + `(define-operator ,operator :64-bit ,lambda-list + (let ((default-rex (case *cpu-mode* (:64-bit nil) (t '(:rex.w))))) - (declare (ignorable operator-mode)) + (declare (ignorable default-rex)) , at body))) (defmacro define-operator* ((&key |16| |32| |64| dispatch) args &body body) @@ -377,18 +468,20 @@ nil (or reg-scale 1))))) +(defun register-set-by-mode (mode) + (ecase mode + (:8-bit '(:al :cl :dl :bl :ah :ch :dh :bh)) + (:16-bit '(:ax :cx :dx :bx :sp :bp :si :di)) + (:32-bit '(:eax :ecx :edx :ebx :esp :ebp :esi :edi)) + (:64-bit '(:rax :rcx :rdx :rbx :rsp :rbp :rsi :rdi :r8 :r9 :r10 :r11 :r12 :13 :r14 :r15)) + (:mm '(:mm0 :mm1 :mm2 :mm3 :mm4 :mm5 :mm6 :mm7)) + (:xmm '(:xmm0 :xmm1 :xmm2 :xmm3 :xmm4 :xmm5 :xmm6 :xmm7)))) (defun encode-reg/mem (operand mode) (check-type mode (member nil :8-bit :16-bit :32-bit :64-bit :mm :xmm)) (if (and mode (keywordp operand)) (encoded-values :mod #b11 - :rm (or (position operand (ecase mode - (:8-bit '(:al :cl :dl :bl :ah :ch :dh :bh)) - (:16-bit '(:ax :cx :dx :bx :sp :bp :si :di)) - (:32-bit '(:eax :ecx :edx :ebx :esp :ebp :esi :edi)) - (:64-bit '(:rax :rcx :rdx :rbx :rsp :rbp :rsi :rdi :r8 :r9 :r10 :r11 :r12 :13 :r14 :r15)) - (:mm '(:mm0 :mm1 :mm2 :mm3 :mm4 :mm5 :mm6 :mm7)) - (:xmm '(:xmm0 :xmm1 :xmm2 :xmm3 :xmm4 :xmm5 :xmm6 :xmm7)))) + :rm (or (position operand (register-set-by-mode mode)) (error "Unknown ~(~D~) register ~S." mode operand))) (multiple-value-bind (reg offsets reg2 reg-scale) (parse-indirect-operand operand) @@ -633,9 +726,77 @@ :rm rm16 :address-size :16-bit :displacement (encode-integer offset '(xint 16)))) - (t (error "Huh? reg: ~S, reg2: ~S, scale: ~S, offset: ~S" reg reg2 reg-scale offset)) - ))))))))))) - + (t (error "Huh? reg: ~S, reg2: ~S, scale: ~S, offset: ~S" reg reg2 reg-scale offset))))))))))))) + +(defmacro pop-code (code-place &optional context) + `(let ((x (pop ,code-place))) + (check-type x (unsigned-byte 8) ,(format nil "an octet (context: ~A)" context)) + x)) + +(defmacro code-call (form &optional (code-place (cadr form))) + `(multiple-value-bind (value new-code) + ,form + (setf ,code-place new-code) + value)) + +(defun decode-integer (code type) + "Decode an integer of specified type." + (let* ((bit-size (cadr type)) + (unsigned-integer (loop for b from 0 below bit-size by 8 + sum (ash (pop-code code integer) b)))) + (values (if (or (not (member (car type) '(sint signed-byte))) + (not (logbitp (1- bit-size) unsigned-integer))) + unsigned-integer + (- (ldb (byte bit-size 0) + (1+ (lognot unsigned-integer))))) + code))) + +(defun decode-reg-modrm (code operator-mode) + (ecase *cpu-mode* + (:32-bit + (decode-reg-modrm-32 code operator-mode)))) + +(defun decode-reg-modrm-32 (code &optional (reg-mode :32-bit)) + "Return a list of the REG, and the MOD/RM operands." + (let* ((modrm (pop-code code mod/rm)) + (mod (ldb (byte 2 6) modrm)) + (reg (ldb (byte 3 3) modrm)) + (r/m (ldb (byte 3 0) modrm))) + (values (list (nth reg (register-set-by-mode reg-mode)) + (if (= mod #b11) + (nth r/m (register-set-by-mode reg-mode)) + (flet ((decode-sib () + (let* ((sib (pop-code code sib)) + (ss (ldb (byte 2 6) sib)) + (index (ldb (byte 3 3) sib)) + (base (ldb (byte 3 0) sib))) + (nconc (unless (= index #b100) + (let ((index-reg (nth index (register-set-by-mode :32-bit)))) + (if (= ss #b00) + (list index-reg) + (list (list index-reg (ash 2 ss)))))) + (if (/= base #b101) + (list (nth base (register-set-by-mode :32-bit))) + (ecase mod + (#b00 nil) + ((#b01 #b10) (list :ebp)))))))) + (ecase mod + (#b00 (case r/m + (#b100 (decode-sib)) + (#b101 (code-call (decode-integer code '(uint 32)))) + (t (list (nth r/m (register-set-by-mode :32-bit)))))) + (#b01 (case r/m + (#b100 (nconc(decode-sib) + (list (code-call (decode-integer code '(sint 8)))))) + (t (list (nth r/m (register-set-by-mode :32-bit)) + (code-call (decode-integer code '(sint 8))))))) + (#b10 (case r/m + (#b100 (nconc (decode-sib) + (list (code-call (decode-integer code '(uint 32)))))) + (t (list (nth r/m (register-set-by-mode :32-bit)) + (code-call (decode-integer code '(uint 32))))))))))) + code))) + (defmacro return-when (form) `(let ((x ,form)) @@ -738,7 +899,12 @@ (encode-reg/mem op-modrm (or reg/mem-mode operator-mode))))))) (defmacro reg-modrm (op-reg op-modrm opcode &optional reg/mem-mode &rest extras) - `(return-when (encode-reg-modrm operator legacy-prefixes ,op-reg ,op-modrm ,opcode operator-mode default-rex ,reg/mem-mode , at extras))) + `(progn + (assembler + (return-when (encode-reg-modrm operator legacy-prefixes ,op-reg ,op-modrm ,opcode + operator-mode default-rex ,reg/mem-mode , at extras))) + (disassembler + (define-disassembler ,opcode decode-reg-modrm operator-mode)))) (defun encode-reg-cr (operator legacy-prefixes op-reg op-cr opcode operator-mode default-rex &rest extras) (let* ((reg-map (ecase operator-mode @@ -858,7 +1024,7 @@ ;;;;;;;;;;; Pseudo-instructions -(define-operator :% (op &rest form) +(define-operator/none :% (op &rest form) (case op (:bytes (return-from operator @@ -994,16 +1160,16 @@ (when (eq operator-mode *cpu-mode*) (modrm dest #xff 2))) -(define-operator :call-segment (dest) +(define-operator/none :call-segment (dest) (modrm dest #xff 3)) ;;;;;;;;;;; CLC, CLD, CLI, CLTS, CMC -(define-operator :clc () (opcode #xf8)) -(define-operator :cld () (opcode #xfc)) -(define-operator :cli () (opcode #xfa)) -(define-operator :clts () (opcode #x0f06)) -(define-operator :cmc () (opcode #xf5)) +(define-operator/none :clc () (opcode #xf8)) +(define-operator/none :cld () (opcode #xfc)) +(define-operator/none :cli () (opcode #xfa)) +(define-operator/none :clts () (opcode #x0f06)) +(define-operator/none :cmc () (opcode #xf5)) ;;;;;;;;;;; CMOVcc @@ -1125,7 +1291,7 @@ ;;;;;;;;;;; CPUID -(define-operator :cpuid () +(define-operator/none :cpuid () (opcode* #x0fa2)) ;;;;;;;;;;; CWD, CDQ @@ -1171,7 +1337,7 @@ ;;;;;;;;;;; HLT -(define-operator :halt () +(define-operator/none :halt () (opcode #xf4)) ;;;;;;;;;;; IDIV @@ -1245,18 +1411,18 @@ ;;;;;;;;;;; INT -(define-operator :break () +(define-operator/none :break () (opcode #xcc)) -(define-operator :int (vector) +(define-operator/none :int (vector) (imm vector #xcd (uint 8))) -(define-operator :into () +(define-operator/none :into () (opcode #xce)) ;;;;;;;;;;; INVLPG -(define-operator :invlpg (address) [145 lines skipped] From ffjeld at common-lisp.net Thu Feb 14 21:56:36 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Thu, 14 Feb 2008 16:56:36 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080214215636.C9BE163062@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv29959 Modified Files: asm-x86.lisp Log Message: I think the disassembler framework basically works now. --- /project/movitz/cvsroot/movitz/asm-x86.lisp 2008/02/13 21:46:51 1.20 +++ /project/movitz/cvsroot/movitz/asm-x86.lisp 2008/02/14 21:56:36 1.21 @@ -6,7 +6,7 @@ ;;;; Author: Frode Vatvedt Fjeld ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: asm-x86.lisp,v 1.20 2008/02/13 21:46:51 ffjeld Exp $ +;;;; $Id: asm-x86.lisp,v 1.21 2008/02/14 21:56:36 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -265,7 +265,7 @@ (make-array 256 :initial-element nil)) (deftype disassembly-decoder () - '(list-of keyword (or keyword nil) symbol)) + '(list-of keyword (or keyword null) symbol)) (defun (setf opcode-disassembler) (decoder opcode operator-mode) (check-type decoder disassembly-decoder) @@ -278,8 +278,8 @@ (unless (or (eq nil decoder) (eq nil (svref table pos)) (equal decoder (svref table pos))) - (warn "Redefining disassembler for opcode #x~X from ~{~S ~}to ~{~S~^ ~}." - opcode (svref table pos) decoder)) + (warn "Redefining disassembler for ~@[~(~A~) ~]opcode #x~X from ~{~S ~}to ~{~S~^ ~}." + operator-mode opcode (svref table pos) decoder)) (setf (svref table pos) decoder)) (set-it (or (svref table (ldb (byte 8 bit-pos) pos)) (setf (svref table (ldb (byte 8 bit-pos) pos)) @@ -292,12 +292,12 @@ (set-it *opcode-disassemblers-32* opcode)) (:64-bit (set-it *opcode-disassemblers-64* opcode)) - (:8-bit + ((:8-bit nil) (set-it *opcode-disassemblers-16* opcode) (set-it *opcode-disassemblers-32* opcode) (set-it *opcode-disassemblers-64* opcode))))) -(defun disassemble-code (code) +(defun disassemble-code (code &optional override-operand-size override-address-size rex) (labels ((lookup-decoder (table opcode) (let* ((datum (pop-code code)) (opcode (logior (ash opcode 8) @@ -310,18 +310,68 @@ (values decoder opcode)) (t (error "No disassembler registered for opcode #x~X." opcode)))))) - (destructuring-bind (operator operator-mode operand-decoder) - (lookup-decoder (ecase *cpu-mode* + (multiple-value-bind (decoder opcode) + (lookup-decoder (ecase (or override-operand-size *cpu-mode*) (:16-bit *opcode-disassemblers-16*) (:32-bit *opcode-disassemblers-32*) (:64-bit *opcode-disassemblers-64*)) 0) - (values (list* operator (code-call (funcall operand-decoder code operator-mode) code)) - code)))) + (destructuring-bind (operator operand-size decoder-function) + decoder + (values (code-call (funcall decoder-function + code + operator + opcode + (or operand-size override-operand-size) + (or override-address-size *cpu-mode*) + rex)) + code))))) + +(defmacro define-disassembler ((operator opcode &optional cpu-mode) lambda-list &body body) + (if (and (symbolp lambda-list) + (null body)) + `(setf (opcode-disassembler ',opcode ,cpu-mode) (list ,operator ,cpu-mode ',lambda-list)) + (let ((defun-name (intern (format nil "~A-~A-~X~@[-~A~]" 'disassembler operator opcode cpu-mode)))) + `(progn + (defun ,defun-name ,lambda-list , at body) + (setf (opcode-disassembler ',opcode ',cpu-mode) (list ,operator ',cpu-mode ',defun-name)) + ',defun-name)))) + +(defun disassemble-simple-prefix (code operator opcode operand-size address-size rex) + (declare (ignore opcode rex)) + (let ((instruction (code-call (disassemble-code code operand-size address-size nil)))) + (values (if (consp (car instruction)) + (list* (list* operator (car instruction)) + (cdr instruction)) + (list* (list operator) + instruction)) + code))) -(defmacro define-disassembler (opcode operands operator-mode) - `(disassembler - (setf (opcode-disassembler ,opcode ,operator-mode) (list operator ,operator-mode ',operands)))) +(define-disassembler (:lock #xf0) disassemble-simple-prefix) +(define-disassembler (:repne #xf2) disassemble-simple-prefix) +(define-disassembler (:repz #xf3) disassemble-simple-prefix) +(define-disassembler (:cs-override #x2e) disassemble-simple-prefix) +(define-disassembler (:ss-override #x36) disassemble-simple-prefix) +(define-disassembler (:ds-override #x3e) disassemble-simple-prefix) +(define-disassembler (:es-override #x26) disassemble-simple-prefix) +(define-disassembler (:fs-override #x64) disassemble-simple-prefix) +(define-disassembler (:gs-override #x65) disassemble-simple-prefix) + +(define-disassembler (:operand-size-override #x66 :32-bit) (code operator opcode operand-size address-size rex) + (declare (ignore operator opcode operand-size rex)) + (disassemble-code code :16-bit address-size nil)) + +(define-disassembler (:address-size-override #x67 :32-bit) (code operator opcode operand-size address-size rex) + (declare (ignore operator opcode operand-size rex)) + (disassemble-code code operand-size :16-bit nil)) + +(define-disassembler (:operand-size-override #x66 :16-bit) (code operator opcode operand-size address-size rex) + (declare (ignore operator opcode operand-size rex)) + (disassemble-code code :32-bit address-size nil)) + +(define-disassembler (:address-size-override #x67 :16-bit) (code operator opcode operand-size address-size rex) + (declare (ignore operator opcode operand-size rex)) + (disassemble-code code operand-size :32-bit nil)) (defmacro define-operator/8 (operator lambda-list &body body) `(define-operator ,operator :8-bit ,lambda-list @@ -733,11 +783,10 @@ (check-type x (unsigned-byte 8) ,(format nil "an octet (context: ~A)" context)) x)) -(defmacro code-call (form &optional (code-place (cadr form))) - `(multiple-value-bind (value new-code) - ,form - (setf ,code-place new-code) - value)) +(defmacro code-call (form &optional (code-place (case (car form) (funcall (third form)) (t (second form))))) + "Execute form, then 'magically' update the code binding with the secondary return value from form." + `(let (tmp) + (setf (values tmp ,code-place) ,form))) (defun decode-integer (code type) "Decode an integer of specified type." @@ -751,20 +800,48 @@ (1+ (lognot unsigned-integer))))) code))) -(defun decode-reg-modrm (code operator-mode) - (ecase *cpu-mode* +(defun decode-reg-modrm (code operator opcode operand-size address-size rex) + (declare (ignore opcode rex)) + (ecase address-size (:32-bit - (decode-reg-modrm-32 code operator-mode)))) + (decode-reg-modrm-32 code operator operand-size)) + (:16-bit + (decode-reg-modrm-16 code operator operand-size)))) + +(defun decode-reg-modrm-16 (code operator operand-size) + (let* ((modrm (pop-code code mod/rm)) + (mod (ldb (byte 2 6) modrm)) + (reg (ldb (byte 3 3) modrm)) + (r/m (ldb (byte 3 0) modrm))) + (values (list operator + (nth reg (register-set-by-mode operand-size)) + (if (= mod #b11) + (nth reg (register-set-by-mode operand-size)) + (flet ((operands (i) + (nth i '((:bx :si) (:bx :di) (:bp :si) (:bp :di) (:si) (:di) (:bp) (:bx))))) + (ecase mod + (#b00 + (case r/m + (#b110 (code-call (decode-integer code '(uint 16)))) + (t (operands r/m)))) + (#b01 + (append (operands r/m) + (code-call (decode-integer code '(sint 8))))) + (#b10 + (append (operands r/m) + (code-call (decode-integer code '(uint 16))))))))) + code))) -(defun decode-reg-modrm-32 (code &optional (reg-mode :32-bit)) +(defun decode-reg-modrm-32 (code operator operand-size) "Return a list of the REG, and the MOD/RM operands." (let* ((modrm (pop-code code mod/rm)) (mod (ldb (byte 2 6) modrm)) (reg (ldb (byte 3 3) modrm)) (r/m (ldb (byte 3 0) modrm))) - (values (list (nth reg (register-set-by-mode reg-mode)) + (values (list operator + (nth reg (register-set-by-mode operand-size)) (if (= mod #b11) - (nth r/m (register-set-by-mode reg-mode)) + (nth r/m (register-set-by-mode operand-size)) (flet ((decode-sib () (let* ((sib (pop-code code sib)) (ss (ldb (byte 2 6) sib)) @@ -904,7 +981,7 @@ (return-when (encode-reg-modrm operator legacy-prefixes ,op-reg ,op-modrm ,opcode operator-mode default-rex ,reg/mem-mode , at extras))) (disassembler - (define-disassembler ,opcode decode-reg-modrm operator-mode)))) + (define-disassembler (operator ,opcode operator-mode) decode-reg-modrm)))) (defun encode-reg-cr (operator legacy-prefixes op-reg op-cr opcode operator-mode default-rex &rest extras) (let* ((reg-map (ecase operator-mode From ffjeld at common-lisp.net Sat Feb 16 18:01:09 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Sat, 16 Feb 2008 13:01:09 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080216180109.BF2A31501D@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv25557 Modified Files: asm-x86.lisp Log Message: More disassembler development. --- /project/movitz/cvsroot/movitz/asm-x86.lisp 2008/02/14 21:56:36 1.21 +++ /project/movitz/cvsroot/movitz/asm-x86.lisp 2008/02/16 18:01:07 1.22 @@ -2,11 +2,11 @@ ;;;; ;;;; Copyright (C) 2007 Frode V. Fjeld ;;;; -;;;; Description: x86 assembler for 32 and 64-bit. +;;;; Description: x86 assembler for 16, 32, and 64-bit modes. ;;;; Author: Frode Vatvedt Fjeld ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: asm-x86.lisp,v 1.21 2008/02/14 21:56:36 ffjeld Exp $ +;;;; $Id: asm-x86.lisp,v 1.22 2008/02/16 18:01:07 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -216,7 +216,7 @@ (cond ((atom body) nil) - ((member (car body) '(reg-modrm)) + ((member (car body) '(reg-modrm modrm opcode imm-modrm imm)) (list body)) (t (mapcan #'find-forms body))))) (let ((defun-name (intern (format nil "~A-~A" 'instruction-encoder operator)))) @@ -240,7 +240,9 @@ (assembler (&body body) (declare (ignore body)))) (let ((operator ',operator) - (operator-mode ',operator-mode)) + (operator-mode ',operator-mode) + (operand-formals ',lambda-list)) + (declare (ignorable operand-formals)) ,@(find-forms body))) ',operator)))) @@ -248,6 +250,7 @@ `(define-operator ,name nil ,lambda-list , at body)) (deftype list-of (&rest elements) + "A list with elements of specified type(s)." (labels ((make-list-of (elements) (if (null elements) 'null @@ -255,6 +258,15 @@ ,(make-list-of (cdr elements)))))) (make-list-of elements))) +(deftype list-of* (&rest elements) + "A list starting with elements of specified type(s)." + (labels ((make-list-of (elements) + (if (null elements) + 'list + `(cons ,(car elements) + ,(make-list-of (cdr elements)))))) + (make-list-of elements))) + (defparameter *opcode-disassemblers-16* (make-array 256 :initial-element nil)) @@ -265,7 +277,7 @@ (make-array 256 :initial-element nil)) (deftype disassembly-decoder () - '(list-of keyword (or keyword null) symbol)) + '(list-of* keyword (or keyword null) symbol)) (defun (setf opcode-disassembler) (decoder opcode operator-mode) (check-type decoder disassembly-decoder) @@ -297,7 +309,7 @@ (set-it *opcode-disassemblers-32* opcode) (set-it *opcode-disassemblers-64* opcode))))) -(defun disassemble-code (code &optional override-operand-size override-address-size rex) +(defun disassemble-instruction (code &optional override-operand-size override-address-size rex) (labels ((lookup-decoder (table opcode) (let* ((datum (pop-code code)) (opcode (logior (ash opcode 8) @@ -306,7 +318,7 @@ (typecase decoder ((simple-vector 256) (lookup-decoder decoder opcode)) - ((list-of keyword (or keyword null) symbol) + (disassembly-decoder (values decoder opcode)) (t (error "No disassembler registered for opcode #x~X." opcode)))))) @@ -316,30 +328,40 @@ (:32-bit *opcode-disassemblers-32*) (:64-bit *opcode-disassemblers-64*)) 0) - (destructuring-bind (operator operand-size decoder-function) + (destructuring-bind (operator operand-size decoder-function &rest extra-args) decoder - (values (code-call (funcall decoder-function - code - operator - opcode - (or operand-size override-operand-size) - (or override-address-size *cpu-mode*) - rex)) + (warn "extraS: ~S" extra-args) + (values (code-call (apply decoder-function + code + operator + opcode + (or operand-size override-operand-size) + (or override-address-size *cpu-mode*) + rex + extra-args)) code))))) -(defmacro define-disassembler ((operator opcode &optional cpu-mode) lambda-list &body body) - (if (and (symbolp lambda-list) - (null body)) - `(setf (opcode-disassembler ',opcode ,cpu-mode) (list ,operator ,cpu-mode ',lambda-list)) - (let ((defun-name (intern (format nil "~A-~A-~X~@[-~A~]" 'disassembler operator opcode cpu-mode)))) - `(progn - (defun ,defun-name ,lambda-list , at body) - (setf (opcode-disassembler ',opcode ',cpu-mode) (list ,operator ',cpu-mode ',defun-name)) - ',defun-name)))) +(defmacro define-disassembler ((operator opcode &optional cpu-mode (digit nil digit-p)) lambda-list &body body) + (cond + (digit-p + `(loop for mod from #b00 to #b11 + do (loop for r/m from #b000 to #b111 + as ext-opcode = (logior (ash ,opcode 8) + (ash ,digit 3) + (ash mod 6) + r/m) + do (define-disassembler (,operator ext-opcode ,cpu-mode) ,lambda-list , at body)))) + ((symbolp lambda-list) + `(setf (opcode-disassembler ,opcode ,cpu-mode) (list ,operator ,cpu-mode ',lambda-list , at body))) + (t (let ((defun-name (intern (format nil "~A-~A-~X~@[-~A~]" 'disassembler operator opcode cpu-mode)))) + `(progn + (defun ,defun-name ,lambda-list , at body) + (setf (opcode-disassembler ,opcode ',cpu-mode) (list ,operator ',cpu-mode ',defun-name)) + ',defun-name))))) (defun disassemble-simple-prefix (code operator opcode operand-size address-size rex) (declare (ignore opcode rex)) - (let ((instruction (code-call (disassemble-code code operand-size address-size nil)))) + (let ((instruction (code-call (disassemble-instruction code operand-size address-size nil)))) (values (if (consp (car instruction)) (list* (list* operator (car instruction)) (cdr instruction)) @@ -359,19 +381,19 @@ (define-disassembler (:operand-size-override #x66 :32-bit) (code operator opcode operand-size address-size rex) (declare (ignore operator opcode operand-size rex)) - (disassemble-code code :16-bit address-size nil)) + (disassemble-instruction code :16-bit address-size nil)) (define-disassembler (:address-size-override #x67 :32-bit) (code operator opcode operand-size address-size rex) (declare (ignore operator opcode operand-size rex)) - (disassemble-code code operand-size :16-bit nil)) + (disassemble-instruction code operand-size :16-bit nil)) (define-disassembler (:operand-size-override #x66 :16-bit) (code operator opcode operand-size address-size rex) (declare (ignore operator opcode operand-size rex)) - (disassemble-code code :32-bit address-size nil)) + (disassemble-instruction code :32-bit address-size nil)) (define-disassembler (:address-size-override #x67 :16-bit) (code operator opcode operand-size address-size rex) (declare (ignore operator opcode operand-size rex)) - (disassemble-code code operand-size :32-bit nil)) + (disassemble-instruction code operand-size :32-bit nil)) (defmacro define-operator/8 (operator lambda-list &body body) `(define-operator ,operator :8-bit ,lambda-list @@ -778,12 +800,23 @@ :displacement (encode-integer offset '(xint 16)))) (t (error "Huh? reg: ~S, reg2: ~S, scale: ~S, offset: ~S" reg reg2 reg-scale offset))))))))))))) +(defun operand-ordering (formals &rest arrangement) + (loop with rarrangement = (reverse arrangement) + for formal in formals + when (getf rarrangement formal) + collect it)) + +(defun order-operands (ordering &rest operands) + (loop for key in ordering + collect (or (getf operands key) + (error "No operand ~S in ~S." key operands)))) + (defmacro pop-code (code-place &optional context) `(let ((x (pop ,code-place))) (check-type x (unsigned-byte 8) ,(format nil "an octet (context: ~A)" context)) x)) -(defmacro code-call (form &optional (code-place (case (car form) (funcall (third form)) (t (second form))))) +(defmacro code-call (form &optional (code-place (case (car form) ((funcall apply) (third form)) (t (second form))))) "Execute form, then 'magically' update the code binding with the secondary return value from form." `(let (tmp) (setf (values tmp ,code-place) ,form))) @@ -800,78 +833,107 @@ (1+ (lognot unsigned-integer))))) code))) -(defun decode-reg-modrm (code operator opcode operand-size address-size rex) +(defun decode-no-operands (code operator opcode operand-size address-size rex) + (declare (ignore opcode operand-size address-size rex)) + (values (list operator) + code)) + +(defun decode-reg-modrm (code operator opcode operand-size address-size rex operand-ordering) (declare (ignore opcode rex)) - (ecase address-size - (:32-bit - (decode-reg-modrm-32 code operator operand-size)) - (:16-bit - (decode-reg-modrm-16 code operator operand-size)))) + (values (list* operator + (order-operands operand-ordering + :reg (nth (ldb (byte 3 3) (car code)) + (register-set-by-mode operand-size)) + :modrm (ecase address-size + (:32-bit + (code-call (decode-reg-modrm-32 code operand-size))) + (:16-bit + (code-call (decode-reg-modrm-16 code operand-size)))))) + code)) + + +(defun decode-modrm (code operator opcode operand-size address-size rex) + (values (list operator + (ecase address-size + (:32-bit + (code-call (decode-reg-modrm-32 code operand-size))) + (:16-bit + (code-call (decode-reg-modrm-16 code operand-size))))) + code)) + +(defun decode-imm-modrm (code operator opcode operand-size address-size rex imm-type operand-ordering &key fixed-modrm) + (values (list* operator + (order-operands operand-ordering + :modrm (or fixed-modrm + (when (member :modrm operand-ordering) + (ecase address-size + (:32-bit + (code-call (decode-reg-modrm-32 code operand-size))) + (:16-bit + (code-call (decode-reg-modrm-16 code operand-size)))))) + :imm (code-call (decode-integer code imm-type)))) + code)) -(defun decode-reg-modrm-16 (code operator operand-size) +(defun decode-reg-modrm-16 (code operand-size) (let* ((modrm (pop-code code mod/rm)) (mod (ldb (byte 2 6) modrm)) (reg (ldb (byte 3 3) modrm)) (r/m (ldb (byte 3 0) modrm))) - (values (list operator - (nth reg (register-set-by-mode operand-size)) - (if (= mod #b11) - (nth reg (register-set-by-mode operand-size)) - (flet ((operands (i) - (nth i '((:bx :si) (:bx :di) (:bp :si) (:bp :di) (:si) (:di) (:bp) (:bx))))) - (ecase mod - (#b00 - (case r/m - (#b110 (code-call (decode-integer code '(uint 16)))) - (t (operands r/m)))) - (#b01 - (append (operands r/m) - (code-call (decode-integer code '(sint 8))))) - (#b10 - (append (operands r/m) - (code-call (decode-integer code '(uint 16))))))))) + (values (if (= mod #b11) + (nth reg (register-set-by-mode operand-size)) + (flet ((operands (i) + (nth i '((:bx :si) (:bx :di) (:bp :si) (:bp :di) (:si) (:di) (:bp) (:bx))))) + (ecase mod + (#b00 + (case r/m + (#b110 (code-call (decode-integer code '(uint 16)))) + (t (operands r/m)))) + (#b01 + (append (operands r/m) + (code-call (decode-integer code '(sint 8))))) + (#b10 + (append (operands r/m) + (code-call (decode-integer code '(uint 16)))))))) code))) -(defun decode-reg-modrm-32 (code operator operand-size) +(defun decode-reg-modrm-32 (code operand-size) "Return a list of the REG, and the MOD/RM operands." (let* ((modrm (pop-code code mod/rm)) (mod (ldb (byte 2 6) modrm)) (reg (ldb (byte 3 3) modrm)) (r/m (ldb (byte 3 0) modrm))) - (values (list operator - (nth reg (register-set-by-mode operand-size)) - (if (= mod #b11) - (nth r/m (register-set-by-mode operand-size)) - (flet ((decode-sib () - (let* ((sib (pop-code code sib)) - (ss (ldb (byte 2 6) sib)) - (index (ldb (byte 3 3) sib)) - (base (ldb (byte 3 0) sib))) - (nconc (unless (= index #b100) - (let ((index-reg (nth index (register-set-by-mode :32-bit)))) - (if (= ss #b00) - (list index-reg) - (list (list index-reg (ash 2 ss)))))) - (if (/= base #b101) - (list (nth base (register-set-by-mode :32-bit))) - (ecase mod - (#b00 nil) - ((#b01 #b10) (list :ebp)))))))) - (ecase mod - (#b00 (case r/m - (#b100 (decode-sib)) - (#b101 (code-call (decode-integer code '(uint 32)))) - (t (list (nth r/m (register-set-by-mode :32-bit)))))) - (#b01 (case r/m - (#b100 (nconc(decode-sib) - (list (code-call (decode-integer code '(sint 8)))))) - (t (list (nth r/m (register-set-by-mode :32-bit)) - (code-call (decode-integer code '(sint 8))))))) - (#b10 (case r/m - (#b100 (nconc (decode-sib) - (list (code-call (decode-integer code '(uint 32)))))) - (t (list (nth r/m (register-set-by-mode :32-bit)) - (code-call (decode-integer code '(uint 32))))))))))) + (values (if (= mod #b11) + (nth r/m (register-set-by-mode operand-size)) + (flet ((decode-sib () + (let* ((sib (pop-code code sib)) + (ss (ldb (byte 2 6) sib)) + (index (ldb (byte 3 3) sib)) + (base (ldb (byte 3 0) sib))) + (nconc (unless (= index #b100) + (let ((index-reg (nth index (register-set-by-mode :32-bit)))) + (if (= ss #b00) + (list index-reg) + (list (list index-reg (ash 2 ss)))))) + (if (/= base #b101) + (list (nth base (register-set-by-mode :32-bit))) + (ecase mod + (#b00 nil) + ((#b01 #b10) (list :ebp)))))))) + (ecase mod + (#b00 (case r/m + (#b100 (decode-sib)) + (#b101 (code-call (decode-integer code '(uint 32)))) + (t (list (nth r/m (register-set-by-mode :32-bit)))))) + (#b01 (case r/m + (#b100 (nconc(decode-sib) + (list (code-call (decode-integer code '(sint 8)))))) + (t (list (nth r/m (register-set-by-mode :32-bit)) + (code-call (decode-integer code '(sint 8))))))) + (#b10 (case r/m + (#b100 (nconc (decode-sib) + (list (code-call (decode-integer code '(uint 32)))))) + (t (list (nth r/m (register-set-by-mode :32-bit)) + (code-call (decode-integer code '(uint 32)))))))))) code))) @@ -883,28 +945,54 @@ `(let ((x (encode ,form))) (when x (return-from operator x)))) -(defmacro imm (imm-operand opcode imm-type &rest extras) - `(when (immediate-p ,imm-operand) - (let ((immediate (resolve-operand ,imm-operand))) - (when (typep immediate ',imm-type) - (return-values-when - (encoded-values :opcode ,opcode - :immediate (encode-integer immediate ',imm-type) - :operand-size operator-mode - :rex default-rex - , at extras)))))) +(defmacro imm (imm-operand opcode imm-type &optional extra-operand &rest extras) + `(progn + (assembler + (when (and ,@(when extra-operand + (list (list* 'eql extra-operand))) + (immediate-p ,imm-operand)) + (let ((immediate (resolve-operand ,imm-operand))) + (when (typep immediate ',imm-type) + (return-values-when + (encoded-values :opcode ,opcode + :immediate (encode-integer immediate ',imm-type) + :operand-size operator-mode + :rex default-rex + , at extras)))))) + (disassembler + ,(if extra-operand + `(define-disassembler (operator ,opcode operator-mode) + decode-imm-modrm + ',imm-type + (operand-ordering operand-formals + :imm ',imm-operand + :modrm ',(first extra-operand)) + :fixed-modrm ',(second extra-operand)) + `(define-disassembler (operator ,opcode operator-mode) [333 lines skipped] From ffjeld at common-lisp.net Sat Feb 16 19:14:06 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Sat, 16 Feb 2008 14:14:06 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080216191406.E4BEC16045@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv6409 Modified Files: asm.lisp Log Message: More consistent names for the essential operators in the asm and asm-x86 packages. --- /project/movitz/cvsroot/movitz/asm.lisp 2008/02/09 09:50:46 1.12 +++ /project/movitz/cvsroot/movitz/asm.lisp 2008/02/16 19:14:06 1.13 @@ -6,7 +6,7 @@ ;;;; Author: Frode Vatvedt Fjeld ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: asm.lisp,v 1.12 2008/02/09 09:50:46 ffjeld Exp $ +;;;; $Id: asm.lisp,v 1.13 2008/02/16 19:14:06 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -24,7 +24,7 @@ #:unresolved-symbol #:retry-symbol-resolve #:pc-relative-operand - #:proglist-encode + #:assemble-proglist #:*pc* #:*symtab* #:*instruction-compute-extra-prefix-map* @@ -141,12 +141,12 @@ (mapcar #'resolve-operand (funcall-operand-operands operand)))) (t operand))) -;;;;;;;;;;;; +;;;;;;;;;;;; -(defun proglist-encode (proglist &key ((:symtab incoming-symtab) *symtab*) corrections (start-pc 0) (cpu-package '#:asm-x86)) - "Encode a proglist, using instruction-encoder in symbol encode-instruction from cpu-package." - (let ((encoder (find-symbol (string '#:encode-instruction) cpu-package)) +(defun assemble-proglist (proglist &key ((:symtab incoming-symtab) *symtab*) corrections (start-pc 0) (cpu-package '#:asm-x86)) + "Encode a proglist, using instruction-encoder in symbol assemble-instruction from cpu-package." + (let ((encoder (find-symbol (string '#:assemble-instruction) cpu-package)) (*pc* start-pc) (*symtab* (append incoming-symtab corrections)) (*anonymous-sub-program-identities* *anonymous-sub-program-identities*) @@ -222,9 +222,21 @@ (length assumptions) (mapcar #'car assumptions))) ((not (null new-corrections)) - (proglist-encode proglist - :symtab incoming-symtab - :start-pc start-pc - :cpu-package cpu-package - :corrections (nconc new-corrections corrections))) + (assemble-proglist proglist + :symtab incoming-symtab + :start-pc start-pc + :cpu-package cpu-package + :corrections (nconc new-corrections corrections))) (t (values code *symtab*)))))))) + +(defun disassemble-proglist (code &key (cpu-package '#:asm-x86)) + (let ((instruction-disassembler (find-symbol (string '#:disassemble-instruction) + cpu-package))) + (loop while code + collect (multiple-value-bind (instruction new-code) + (funcall instruction-disassembler + code) + (when (eq code new-code) + (loop-finish)) + (setf code new-code) + instruction)))) From ffjeld at common-lisp.net Sat Feb 16 19:14:11 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Sat, 16 Feb 2008 14:14:11 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080216191411.C408B63036@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv6436 Modified Files: asm-x86.lisp Log Message: More consistent names for the essential operators in the asm and asm-x86 packages. --- /project/movitz/cvsroot/movitz/asm-x86.lisp 2008/02/16 18:01:07 1.22 +++ /project/movitz/cvsroot/movitz/asm-x86.lisp 2008/02/16 19:14:08 1.23 @@ -6,13 +6,14 @@ ;;;; Author: Frode Vatvedt Fjeld ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: asm-x86.lisp,v 1.22 2008/02/16 18:01:07 ffjeld Exp $ +;;;; $Id: asm-x86.lisp,v 1.23 2008/02/16 19:14:08 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ (defpackage asm-x86 (:use :common-lisp :asm) - (:export #:encode-instruction + (:export #:assemble-instruction + #:disassemble-instruction #:*cpu-mode* #:*position-independent-p*)) @@ -167,7 +168,6 @@ :address-size (getone address-size1 address-size2 address-size)))))) - (defun encoded-values (&key prefixes prefix rex opcode mod reg rm scale index base displacement immediate operand-size address-size) (values (append (when prefix (list prefix)) @@ -183,7 +183,8 @@ operand-size address-size)) -(defun encode-instruction (instruction) +(defun assemble-instruction (instruction) + "Assemble a single instruction to a list of octets of x86 machine code, according to *cpu-mode* etc." (multiple-value-bind (instruction legacy-prefixes options) (if (listp (car instruction)) (values (cdr instruction) @@ -216,7 +217,7 @@ (cond ((atom body) nil) - ((member (car body) '(reg-modrm modrm opcode imm-modrm imm)) + ((member (car body) '(reg-modrm modrm opcode imm-modrm imm opcode-reg)) (list body)) (t (mapcan #'find-forms body))))) (let ((defun-name (intern (format nil "~A-~A" 'instruction-encoder operator)))) @@ -330,7 +331,6 @@ 0) (destructuring-bind (operator operand-size decoder-function &rest extra-args) decoder - (warn "extraS: ~S" extra-args) (values (code-call (apply decoder-function code operator @@ -874,6 +874,14 @@ :imm (code-call (decode-integer code imm-type)))) code)) +(defun decode-opcode-reg (code operator opcode operand-size address-size rex operand-ordering extra-operand) + (values (list* operator + (order-operands operand-ordering + :reg (nth (ldb (byte 3 0) opcode) + (register-set-by-mode operand-size)) + :extra extra-operand)) + code)) + (defun decode-reg-modrm-16 (code operand-size) (let* ((modrm (pop-code code mod/rm)) (mod (ldb (byte 2 6) modrm)) @@ -1156,9 +1164,26 @@ '(:rex.w :rex.r)) (t default-rex))))))) -(defmacro opcode-reg (opcode op-reg) - `(return-when - (encode-opcode-reg operator legacy-prefixes ,opcode ,op-reg operator-mode default-rex))) +(defmacro opcode-reg (opcode op-reg &optional extra-operand) + `(progn + (assembler + (when (and ,@(when extra-operand + `((eql , at extra-operand)))) + (return-when + (encode-opcode-reg operator legacy-prefixes ,opcode ,op-reg operator-mode default-rex)))) + (disassembler + (loop for reg from #b000 to #b111 + do ,(if (not extra-operand) + `(define-disassembler (operator (logior ,opcode reg) operator-mode) + decode-opcode-reg + '(:reg) + nil) + `(define-disassembler (operator (logior ,opcode reg) operator-mode) + decode-opcode-reg + (operand-ordering operand-formals + :reg ',op-reg + :extra ',(first extra-operand)) + ',(second extra-operand))))))) (defun encode-opcode-reg-imm (operator legacy-prefixes opcode op-reg op-imm type operator-mode default-rex) (when (immediate-p op-imm) @@ -2089,10 +2114,8 @@ (reg-modrm x y #x86)) (define-operator* (:16 :xchgw :32 :xchgl :64 :xchgr) (x y) - (when (eq y :ax-eax-rax) - (opcode-reg #x90 x)) - (when (eq x :ax-eax-rax) - (opcode-reg #x90 y)) + (opcode-reg #x90 x (y :ax-eax-rax)) + (opcode-reg #x90 y (x :ax-eax-rax)) (reg-modrm x y #x87) (reg-modrm y x #x87)) From ffjeld at common-lisp.net Sat Feb 16 19:14:21 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Sat, 16 Feb 2008 14:14:21 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080216191421.559FE5F0BC@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv6474 Modified Files: compiler.lisp Log Message: More consistent names for the essential operators in the asm and asm-x86 packages. --- /project/movitz/cvsroot/movitz/compiler.lisp 2008/02/09 18:42:29 1.188 +++ /project/movitz/cvsroot/movitz/compiler.lisp 2008/02/16 19:14:15 1.189 @@ -8,7 +8,7 @@ ;;;; Created at: Wed Oct 25 12:30:49 2000 ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: compiler.lisp,v 1.188 2008/02/09 18:42:29 ffjeld Exp $ +;;;; $Id: compiler.lisp,v 1.189 2008/02/16 19:14:15 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -173,8 +173,8 @@ ;; (:nil-value (image-nil-word *image*)))))) (let ((asm:*instruction-compute-extra-prefix-map* '((:call . compute-call-extra-prefix)))) - (asm:proglist-encode (translate-program resolved-code :muerte.cl :cl) - :symtab (list (cons :nil-value (image-nil-word *image*))))) + (asm:assemble-proglist (translate-program resolved-code :muerte.cl :cl) + :symtab (list (cons :nil-value (image-nil-word *image*))))) (values (make-movitz-vector (length code-vector) :element-type 'code :initial-contents code-vector) @@ -1068,13 +1068,13 @@ (multiple-value-bind (code-vector code-symtab) (let ((asm:*instruction-compute-extra-prefix-map* '((:call . compute-call-extra-prefix)))) - (asm:proglist-encode combined-code - :symtab (list* (cons :nil-value (image-nil-word *image*)) - (loop for (label . set) in (movitz-funobj-jumpers-map funobj) - collect (cons label - (* 4 (or (search set (movitz-funobj-const-list funobj) - :end2 (movitz-funobj-num-jumpers funobj)) - (error "Jumper for ~S missing." label)))))))) + (asm:assemble-proglist combined-code + :symtab (list* (cons :nil-value (image-nil-word *image*)) + (loop for (label . set) in (movitz-funobj-jumpers-map funobj) + collect (cons label + (* 4 (or (search set (movitz-funobj-const-list funobj) + :end2 (movitz-funobj-num-jumpers funobj)) + (error "Jumper for ~S missing." label)))))))) (setf (movitz-funobj-symtab funobj) code-symtab) (let* ((code-length (- (length code-vector) 3 -3)) (code-vector (make-array code-length From ffjeld at common-lisp.net Sat Feb 16 21:22:05 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Sat, 16 Feb 2008 16:22:05 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080216212205.7D2CD2511E@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv5163 Modified Files: compiler.lisp Log Message: Remove dead code. --- /project/movitz/cvsroot/movitz/compiler.lisp 2008/02/16 19:14:15 1.189 +++ /project/movitz/cvsroot/movitz/compiler.lisp 2008/02/16 21:22:05 1.190 @@ -8,7 +8,7 @@ ;;;; Created at: Wed Oct 25 12:30:49 2000 ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: compiler.lisp,v 1.189 2008/02/16 19:14:15 ffjeld Exp $ +;;;; $Id: compiler.lisp,v 1.190 2008/02/16 21:22:05 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -112,25 +112,6 @@ (or (member (car list) (cdr list)) (duplicatesp (cdr list))))) -(defun old-compute-call-extra-prefix (instr env size) - (let* ((return-pointer-tag (ldb (byte 3 0) - (+ (ia-x86::assemble-env-current-pc env) - size)))) - (cond - ((not (typep instr 'ia-x86-instr::call)) - nil) - ((or (= (tag :even-fixnum) return-pointer-tag) - (= (tag :odd-fixnum) return-pointer-tag)) - ;; Insert a NOP - '(#x90)) -;;; ((= 3 return-pointer-tag) -;;; ;; Insert two NOPs, 3 -> 5 -;;; '(#x90 #x90)) - ((= (tag :character) return-pointer-tag) - ;; Insert three NOPs, 2 -> 5 - '(#x90 #x90 #x90) - '(#x90))))) - (defun compute-call-extra-prefix (pc size) (let* ((return-pointer-tag (ldb (byte 3 0) (+ pc size)))) @@ -162,15 +143,6 @@ (resolved-code (finalize-code body-code nil nil))) (multiple-value-bind (code-vector symtab) -;; (let ((ia-x86:*instruction-compute-extra-prefix-map* -;; '((:call . old-compute-call-extra-prefix)))) -;; (ia-x86:proglist-encode :octet-vector -;; :32-bit -;; #x00000000 -;; (ia-x86:read-proglist resolved-code) -;; :symtab-lookup (lambda (label) -;; (case label -;; (:nil-value (image-nil-word *image*)))))) (let ((asm:*instruction-compute-extra-prefix-map* '((:call . compute-call-extra-prefix)))) (asm:assemble-proglist (translate-program resolved-code :muerte.cl :cl) @@ -1046,25 +1018,6 @@ (defun assemble-funobj (funobj combined-code) -;; (multiple-value-bind (code-vector code-symtab) -;; (let ((ia-x86:*instruction-compute-extra-prefix-map* -;; '((:call . old-compute-call-extra-prefix)))) -;; (ia-x86:proglist-encode :octet-vector :32-bit #x00000000 -;; (ia-x86:read-proglist combined-code) -;; :symtab-lookup -;; (lambda (label) -;; (case label -;; (:nil-value (image-nil-word *image*)) -;; (t (let ((set (cdr (assoc label -;; (movitz-funobj-jumpers-map funobj))))) -;; (when set -;; (let ((pos (search set (movitz-funobj-const-list funobj) -;; :end2 (movitz-funobj-num-jumpers funobj)))) -;; (assert pos () -;; "Couldn't find for ~s set ~S in ~S." -;; label set (subseq (movitz-funobj-const-list funobj) -;; 0 (movitz-funobj-num-jumpers funobj))) -;; (* 4 pos))))))))) (multiple-value-bind (code-vector code-symtab) (let ((asm:*instruction-compute-extra-prefix-map* '((:call . compute-call-extra-prefix)))) From ffjeld at common-lisp.net Sat Feb 16 21:43:59 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Sat, 16 Feb 2008 16:43:59 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080216214359.04D952511F@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv8904 Modified Files: asm-x86.lisp Log Message: Disassembler for pc-rel operands. --- /project/movitz/cvsroot/movitz/asm-x86.lisp 2008/02/16 19:14:08 1.23 +++ /project/movitz/cvsroot/movitz/asm-x86.lisp 2008/02/16 21:43:59 1.24 @@ -6,7 +6,7 @@ ;;;; Author: Frode Vatvedt Fjeld ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: asm-x86.lisp,v 1.23 2008/02/16 19:14:08 ffjeld Exp $ +;;;; $Id: asm-x86.lisp,v 1.24 2008/02/16 21:43:59 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -217,7 +217,7 @@ (cond ((atom body) nil) - ((member (car body) '(reg-modrm modrm opcode imm-modrm imm opcode-reg)) + ((member (car body) '(reg-modrm modrm opcode imm-modrm imm opcode-reg pc-rel)) (list body)) (t (mapcan #'find-forms body))))) (let ((defun-name (intern (format nil "~A-~A" 'instruction-encoder operator)))) @@ -490,6 +490,7 @@ (reduce #'+ (cdr operand) :key #'resolve-operand)) (symbol-reference + (assert *pc* (*pc*) "Cannot encode a pc-relative operand without a value for ~S." '*pc*) (- (resolve-operand operand) *pc*)))) @@ -874,6 +875,11 @@ :imm (code-call (decode-integer code imm-type)))) code)) +(defun decode-pc-rel (code operator opcode operand-size address-size rex type) + (values (list operator + `(:pc+ ,(code-call (decode-integer code type)))) + code)) + (defun decode-opcode-reg (code operator opcode operand-size address-size rex operand-ordering extra-operand) (values (list* operator (order-operands operand-ordering @@ -1010,14 +1016,14 @@ (defun encode-pc-rel (operator legacy-prefixes opcode operand type &rest extras) (when (typep operand '(or pc-relative-operand symbol-reference)) - (assert *pc* (*pc*) "Cannot encode a pc-relative operand without a value for ~S." '*pc*) (let* ((estimated-code-size-no-extras (+ (length legacy-prefixes) (type-octet-size type) (opcode-octet-size opcode))) (estimated-extra-prefixes (compute-extra-prefixes operator *pc* estimated-code-size-no-extras)) (estimated-code-size (+ estimated-code-size-no-extras (length estimated-extra-prefixes))) - (offset (let ((*pc* (+ *pc* estimated-code-size))) + (offset (let ((*pc* (when *pc* + (+ *pc* estimated-code-size)))) (resolve-pc-relative operand)))) (when (typep offset type) (let ((code (let ((*instruction-compute-extra-prefix-map* nil)) @@ -1030,7 +1036,8 @@ (append estimated-extra-prefixes code) (let* ((code-size (length code)) (extra-prefixes (compute-extra-prefixes operator *pc* code-size)) - (offset (let ((*pc* (+ *pc* code-size (length extra-prefixes)))) + (offset (let ((*pc* (when *pc* + (+ *pc* code-size (length extra-prefixes))))) (resolve-pc-relative operand)))) (when (typep offset type) (let ((code (let ((*instruction-compute-extra-prefix-map* nil)) @@ -1042,7 +1049,13 @@ (append extra-prefixes code)))))))))) (defmacro pc-rel (opcode operand type &rest extras) - `(return-when (encode-pc-rel operator legacy-prefixes ,opcode ,operand ',type , at extras))) + `(progn + (assembler + (return-when (encode-pc-rel operator legacy-prefixes ,opcode ,operand ',type , at extras))) + (disassembler + (define-disassembler (operator ,opcode operator-mode) + decode-pc-rel + ',type)))) (defmacro modrm (operand opcode digit) `(progn From ffjeld at common-lisp.net Sat Feb 16 21:58:57 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Sat, 16 Feb 2008 16:58:57 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080216215857.1C7851F012@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv10437 Modified Files: asm-x86.lisp Log Message: Improved disassembly for opcode operands (i.e. push/pop segment registers). --- /project/movitz/cvsroot/movitz/asm-x86.lisp 2008/02/16 21:43:59 1.24 +++ /project/movitz/cvsroot/movitz/asm-x86.lisp 2008/02/16 21:58:57 1.25 @@ -6,7 +6,7 @@ ;;;; Author: Frode Vatvedt Fjeld ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: asm-x86.lisp,v 1.24 2008/02/16 21:43:59 ffjeld Exp $ +;;;; $Id: asm-x86.lisp,v 1.25 2008/02/16 21:58:57 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -399,37 +399,25 @@ `(define-operator ,operator :8-bit ,lambda-list (let ((default-rex nil)) (declare (ignorable default-rex)) - (macrolet ((yield (&rest args) - `(return-from operator - (encode (encoded-values :operand-size operator-mode , at args))))) - , at body)))) + , at body))) (defmacro define-operator/16 (operator lambda-list &body body) `(define-operator ,operator :16-bit ,lambda-list (let ((default-rex nil)) (declare (ignorable default-rex)) - (macrolet ((yield (&rest args) - `(return-from operator - (encode (encoded-values :operand-size operator-mode , at args))))) - , at body)))) + , at body))) (defmacro define-operator/32 (operator lambda-list &body body) `(define-operator ,operator :32-bit ,lambda-list (let ((default-rex nil)) (declare (ignorable default-rex)) - (macrolet ((yield (&rest args) - `(return-from operator - (encode (encoded-values :operand-size operator-mode , at args))))) - , at body)))) + , at body))) (defmacro define-operator/64 (operator lambda-list &body body) `(define-operator ,operator :64-bit ,lambda-list (let ((default-rex '(:rex.w))) (declare (ignorable default-rex)) - (macrolet ((yield (&rest args) - `(return-from operator - (encode (encoded-values :operand-size operator-mode , at args))))) - , at body)))) + , at body))) (defmacro define-operator/64* (operator lambda-list &body body) `(define-operator ,operator :64-bit ,lambda-list @@ -834,9 +822,10 @@ (1+ (lognot unsigned-integer))))) code))) -(defun decode-no-operands (code operator opcode operand-size address-size rex) +(defun decode-no-operands (code operator opcode operand-size address-size rex &rest fixed-operands) (declare (ignore opcode operand-size address-size rex)) - (values (list operator) + (values (list* operator + (remove nil fixed-operands)) code)) (defun decode-reg-modrm (code operator opcode operand-size address-size rex operand-ordering) @@ -1144,15 +1133,19 @@ :key #'resolve-operand) ',type))))))) -(defmacro opcode (opcode &rest extras) +(defmacro opcode (opcode &optional fixed-operand &rest extras) `(progn (assembler - (return-values-when - (encoded-values :opcode ,opcode - , at extras - :operand-size operator-mode))) + (when (and ,@(when fixed-operand + `((eql , at fixed-operand)))) + (return-values-when + (encoded-values :opcode ,opcode + , at extras + :operand-size operator-mode)))) (disassembler - (define-disassembler (operator ,opcode) decode-no-operands)))) + (define-disassembler (operator ,opcode) + decode-no-operands + ,(second fixed-operand))))) (defmacro opcode* (opcode &rest extras) `(return-values-when @@ -1635,7 +1628,7 @@ ;;;;;;;;;;; IRET (define-operator* (:16 :iret :32 :iretd :64 :iretq) () - (opcode #xcf :rex default-rex)) + (opcode #xcf () :rex default-rex)) ;;;;;;;;;;; Jcc @@ -1918,12 +1911,11 @@ ;;;;;;;;;;; POP (define-operator* (:16 :popw :32 :popl) (dst) - (case dst - (:ds (yield :opcode #x1f)) - (:es (yield :opcode #x07)) - (:ss (yield :opcode #x17)) - (:fs (yield :opcode #x0fa1)) - (:gs (yield :opcode #x0fa9))) + (opcode #x1f (dst :ds)) + (opcode #x07 (dst :es)) + (opcode #x17 (dst :ss)) + (opcode #x0fa1 (dst :fs)) + (opcode #x0fa9 (dst :gs)) (opcode-reg #x58 dst) (modrm dst #x8f 0)) @@ -1953,13 +1945,12 @@ ;;;;;;;;;;; PUSH (define-operator* (:16 :pushw :32 :pushl) (src) - (case src - (:cs (yield :opcode #x0e)) - (:ss (yield :opcode #x16)) - (:ds (yield :opcode #x1e)) - (:es (yield :opcode #x06)) - (:fs (yield :opcode #x0fa0)) - (:gs (yield :opcode #x0fa8))) + (opcode #x0e (src :cs)) + (opcode #x16 (src :ss)) + (opcode #x1e (src :ds)) + (opcode #x06 (src :es)) + (opcode #x0fa0 (src :fs)) + (opcode #x0fa8 (src :gs)) (opcode-reg #x50 src) (imm src #x6a (sint 8)) (imm src #x68 :int-16-32-64 () :operand-size operator-mode) From ffjeld at common-lisp.net Sat Feb 16 22:13:25 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Sat, 16 Feb 2008 17:13:25 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080216221325.740D015037@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv14860 Modified Files: asm-x86.lisp Log Message: Fix up used/unused variables. --- /project/movitz/cvsroot/movitz/asm-x86.lisp 2008/02/16 21:58:57 1.25 +++ /project/movitz/cvsroot/movitz/asm-x86.lisp 2008/02/16 22:13:25 1.26 @@ -6,7 +6,7 @@ ;;;; Author: Frode Vatvedt Fjeld ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: asm-x86.lisp,v 1.25 2008/02/16 21:58:57 ffjeld Exp $ +;;;; $Id: asm-x86.lisp,v 1.26 2008/02/16 22:13:25 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -243,7 +243,7 @@ (let ((operator ',operator) (operator-mode ',operator-mode) (operand-formals ',lambda-list)) - (declare (ignorable operand-formals)) + (declare (ignorable operator operand-formals operator-mode)) ,@(find-forms body))) ',operator)))) @@ -384,7 +384,7 @@ (disassemble-instruction code :16-bit address-size nil)) (define-disassembler (:address-size-override #x67 :32-bit) (code operator opcode operand-size address-size rex) - (declare (ignore operator opcode operand-size rex)) + (declare (ignore operator opcode address-size rex)) (disassemble-instruction code operand-size :16-bit nil)) (define-disassembler (:operand-size-override #x66 :16-bit) (code operator opcode operand-size address-size rex) @@ -392,7 +392,7 @@ (disassemble-instruction code :32-bit address-size nil)) (define-disassembler (:address-size-override #x67 :16-bit) (code operator opcode operand-size address-size rex) - (declare (ignore operator opcode operand-size rex)) + (declare (ignore operator opcode address-size rex)) (disassemble-instruction code operand-size :32-bit nil)) (defmacro define-operator/8 (operator lambda-list &body body) @@ -808,6 +808,7 @@ (defmacro code-call (form &optional (code-place (case (car form) ((funcall apply) (third form)) (t (second form))))) "Execute form, then 'magically' update the code binding with the secondary return value from form." `(let (tmp) + (declare (ignorable tmp)) (setf (values tmp ,code-place) ,form))) (defun decode-integer (code type) @@ -843,6 +844,7 @@ (defun decode-modrm (code operator opcode operand-size address-size rex) + (declare (ignore opcode rex)) (values (list operator (ecase address-size (:32-bit @@ -852,6 +854,7 @@ code)) (defun decode-imm-modrm (code operator opcode operand-size address-size rex imm-type operand-ordering &key fixed-modrm) + (declare (ignore opcode rex)) (values (list* operator (order-operands operand-ordering :modrm (or fixed-modrm @@ -865,11 +868,13 @@ code)) (defun decode-pc-rel (code operator opcode operand-size address-size rex type) + (declare (ignore opcode operand-size address-size rex)) (values (list operator `(:pc+ ,(code-call (decode-integer code type)))) code)) (defun decode-opcode-reg (code operator opcode operand-size address-size rex operand-ordering extra-operand) + (declare (ignore address-size rex)) (values (list* operator (order-operands operand-ordering :reg (nth (ldb (byte 3 0) opcode) @@ -903,7 +908,6 @@ "Return a list of the REG, and the MOD/RM operands." (let* ((modrm (pop-code code mod/rm)) (mod (ldb (byte 2 6) modrm)) - (reg (ldb (byte 3 3) modrm)) (r/m (ldb (byte 3 0) modrm))) (values (if (= mod #b11) (nth r/m (register-set-by-mode operand-size)) From ffjeld at common-lisp.net Sat Feb 16 23:15:08 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Sat, 16 Feb 2008 18:15:08 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080216231508.6069D310CC@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv28273 Modified Files: asm-x86.lisp Log Message: Fix typo in testb declaration. --- /project/movitz/cvsroot/movitz/asm-x86.lisp 2008/02/16 22:13:25 1.26 +++ /project/movitz/cvsroot/movitz/asm-x86.lisp 2008/02/16 23:15:04 1.27 @@ -6,7 +6,7 @@ ;;;; Author: Frode Vatvedt Fjeld ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: asm-x86.lisp,v 1.26 2008/02/16 22:13:25 ffjeld Exp $ +;;;; $Id: asm-x86.lisp,v 1.27 2008/02/16 23:15:04 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -2098,7 +2098,7 @@ ;;;;;;;;;;; TEST (define-operator/8 :testb (mask dst) - (imm mask #xa8 (xint 8) (mask :al)) + (imm mask #xa8 (xint 8) (dst :al)) (imm-modrm mask dst #xf6 0 (xint 8)) (reg-modrm mask dst #x84)) From ffjeld at common-lisp.net Sat Feb 16 23:35:25 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Sat, 16 Feb 2008 18:35:25 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080216233525.1E10115030@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv32621 Modified Files: compiler.lisp Log Message: Small speedup of peeping optimizer. --- /project/movitz/cvsroot/movitz/compiler.lisp 2008/02/16 21:22:05 1.190 +++ /project/movitz/cvsroot/movitz/compiler.lisp 2008/02/16 23:35:22 1.191 @@ -8,7 +8,7 @@ ;;;; Created at: Wed Oct 25 12:30:49 2000 ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: compiler.lisp,v 1.190 2008/02/16 21:22:05 ffjeld Exp $ +;;;; $Id: compiler.lisp,v 1.191 2008/02/16 23:35:22 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -1553,8 +1553,10 @@ "If i is a branch, return the label." (when jmp (push :jmp branch-types)) (let ((i (ignore-instruction-prefixes i))) - (or (and (listp i) (member (car i) branch-types) - (listp (second i)) (member (car (second i)) '(quote muerte.cl::quote)) + (or (and (listp i) + (listp (second i)) + (member (car (second i)) '(quote muerte.cl::quote)) + (member (car i) branch-types) (second (second i))) #+ignore (and (listp i) From ffjeld at common-lisp.net Sun Feb 17 00:10:11 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Sat, 16 Feb 2008 19:10:11 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080217001011.D2F0E16041@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv7215 Modified Files: compiler.lisp Log Message: Improved tree-search, for speed. --- /project/movitz/cvsroot/movitz/compiler.lisp 2008/02/16 23:35:22 1.191 +++ /project/movitz/cvsroot/movitz/compiler.lisp 2008/02/17 00:10:11 1.192 @@ -8,7 +8,7 @@ ;;;; Created at: Wed Oct 25 12:30:49 2000 ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: compiler.lisp,v 1.191 2008/02/16 23:35:22 ffjeld Exp $ +;;;; $Id: compiler.lisp,v 1.192 2008/02/17 00:10:11 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -3256,12 +3256,24 @@ (binding-eql x (forwarding-binding-target y))))) (defun tree-search (tree items) - (etypecase tree - (atom (if (atom items) - (eql tree items) - (member tree items))) - (cons (or (tree-search (car tree) items) - (tree-search (cdr tree) items))))) + (if (and (atom items) ; make common case fast(er), hopefully. + (not (numberp items))) + (labels ((tree-search* (tree item) + (etypecase tree + (null nil) + (cons + (or (tree-search* (car tree) item) + (tree-search* (cdr tree) item))) + (t (eq tree item))))) + (tree-search* tree items)) + (etypecase tree + (atom + (if (atom items) + (eql tree items) + (member tree items))) + (cons + (or (tree-search (car tree) items) + (tree-search (cdr tree) items)))))) (defun operator (x) (if (atom x) x (car x))) From ffjeld at common-lisp.net Mon Feb 18 20:57:14 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Mon, 18 Feb 2008 15:57:14 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080218205714.63B4E2E21B@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv13327 Modified Files: asm-x86.lisp Log Message: Disassemble moffset operands. --- /project/movitz/cvsroot/movitz/asm-x86.lisp 2008/02/16 23:15:04 1.27 +++ /project/movitz/cvsroot/movitz/asm-x86.lisp 2008/02/18 20:57:14 1.28 @@ -6,7 +6,7 @@ ;;;; Author: Frode Vatvedt Fjeld ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: asm-x86.lisp,v 1.27 2008/02/16 23:15:04 ffjeld Exp $ +;;;; $Id: asm-x86.lisp,v 1.28 2008/02/18 20:57:14 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -217,7 +217,7 @@ (cond ((atom body) nil) - ((member (car body) '(reg-modrm modrm opcode imm-modrm imm opcode-reg pc-rel)) + ((member (car body) '(reg-modrm modrm opcode imm-modrm imm opcode-reg pc-rel moffset)) (list body)) (t (mapcan #'find-forms body))))) (let ((defun-name (intern (format nil "~A-~A" 'instruction-encoder operator)))) @@ -310,36 +310,7 @@ (set-it *opcode-disassemblers-32* opcode) (set-it *opcode-disassemblers-64* opcode))))) -(defun disassemble-instruction (code &optional override-operand-size override-address-size rex) - (labels ((lookup-decoder (table opcode) - (let* ((datum (pop-code code)) - (opcode (logior (ash opcode 8) - datum)) - (decoder (svref table datum))) - (typecase decoder - ((simple-vector 256) - (lookup-decoder decoder opcode)) - (disassembly-decoder - (values decoder - opcode)) - (t (error "No disassembler registered for opcode #x~X." opcode)))))) - (multiple-value-bind (decoder opcode) - (lookup-decoder (ecase (or override-operand-size *cpu-mode*) - (:16-bit *opcode-disassemblers-16*) - (:32-bit *opcode-disassemblers-32*) - (:64-bit *opcode-disassemblers-64*)) - 0) - (destructuring-bind (operator operand-size decoder-function &rest extra-args) - decoder - (values (code-call (apply decoder-function - code - operator - opcode - (or operand-size override-operand-size) - (or override-address-size *cpu-mode*) - rex - extra-args)) - code))))) + (defmacro define-disassembler ((operator opcode &optional cpu-mode (digit nil digit-p)) lambda-list &body body) (cond @@ -823,6 +794,37 @@ (1+ (lognot unsigned-integer))))) code))) +(defun disassemble-instruction (code &optional override-operand-size override-address-size rex) + (labels ((lookup-decoder (table opcode) + (let* ((datum (pop-code code)) + (opcode (logior (ash opcode 8) + datum)) + (decoder (svref table datum))) + (typecase decoder + ((simple-vector 256) + (lookup-decoder decoder opcode)) + (disassembly-decoder + (values decoder + opcode)) + (t (error "No disassembler registered for opcode #x~X." opcode)))))) + (multiple-value-bind (decoder opcode) + (lookup-decoder (ecase (or override-operand-size *cpu-mode*) + (:16-bit *opcode-disassemblers-16*) + (:32-bit *opcode-disassemblers-32*) + (:64-bit *opcode-disassemblers-64*)) + 0) + (destructuring-bind (operator operand-size decoder-function &rest extra-args) + decoder + (values (code-call (apply decoder-function + code + operator + opcode + (or operand-size override-operand-size) + (or override-address-size *cpu-mode*) + rex + extra-args)) + code))))) + (defun decode-no-operands (code operator opcode operand-size address-size rex &rest fixed-operands) (declare (ignore opcode operand-size address-size rex)) (values (list* operator @@ -873,6 +875,14 @@ `(:pc+ ,(code-call (decode-integer code type)))) code)) +(defun decode-moffset (code operator opcode operand-size address-size rex type operand-ordering fixed-operand) + (declare (ignore opcode operand-size address-size rex)) + (values (list* operator + (order-operands operand-ordering + :moffset (list (code-call (decode-integer code type))) + :fixed fixed-operand)) + code)) + (defun decode-opcode-reg (code operator opcode operand-size address-size rex operand-ordering extra-operand) (declare (ignore address-size rex)) (values (list* operator @@ -1125,17 +1135,31 @@ :rex default-rex) (encode-reg/mem ,op-modrm operator-mode)))))) -(defmacro moffset (opcode op-offset type) - `(when (indirect-operand-p ,op-offset) - (multiple-value-bind (reg offsets reg2) - (parse-indirect-operand ,op-offset) - (when (and (not reg) - (not reg2)) - (return-values-when - (encoded-values :opcode ,opcode - :displacement (encode-integer (reduce #'+ offsets - :key #'resolve-operand) - ',type))))))) +(defmacro moffset (opcode op-offset type fixed-operand) + `(progn + (assembler + (when (and ,@(when fixed-operand + `((eql , at fixed-operand))) + (indirect-operand-p ,op-offset)) + (multiple-value-bind (reg offsets reg2) + (parse-indirect-operand ,op-offset) + (when (and (not reg) + (not reg2)) + (return-values-when + (encoded-values :opcode ,opcode + :displacement (encode-integer (reduce #'+ offsets + :key #'resolve-operand) + ',type))))))) + (disassembler + (define-disassembler (operator ,opcode operator-mode) + decode-moffset + ',type + (operand-ordering operand-formals + :moffset ',op-offset + :fixed ',(first fixed-operand)) + ',(second fixed-operand))))) + + (defmacro opcode (opcode &optional fixed-operand &rest extras) `(progn @@ -1771,20 +1795,16 @@ ;;;;;;;;;;; MOV (define-operator/8 :movb (src dst) - (when (eq src :al) - (moffset #xa2 dst (uint 8))) - (when (eq dst :al) - (moffset #xa0 src (uint 8))) + (moffset #xa2 dst (uint 8) (src :al)) + (moffset #xa0 src (uint 8) (dst :al)) (opcode-reg-imm #xb0 dst src (xint 8)) (imm-modrm src dst #xc6 0 (xint 8)) (reg-modrm dst src #x8a) (reg-modrm src dst #x88)) (define-operator/16 :movw (src dst) - (when (eq src :ax) - (moffset #xa3 dst (uint 16))) - (when (eq dst :ax) - (moffset #xa0 src (uint 16))) + (moffset #xa3 dst (uint 16) (src :ax)) + (moffset #xa0 src (uint 16) (dst :ax)) (opcode-reg-imm #xb8 dst src (xint 16)) (imm-modrm src dst #xc7 0 (xint 16)) (sreg-modrm src dst #x8c) @@ -1793,10 +1813,8 @@ (reg-modrm src dst #x89)) (define-operator/32 :movl (src dst) - (when (eq src :eax) - (moffset #xa3 dst (uint 32))) - (when (eq dst :eax) - (moffset #xa0 src (uint 32))) + (moffset #xa3 dst (uint 32) (src :eax)) + (moffset #xa0 src (uint 32) (dst :eax)) (opcode-reg-imm #xb8 dst src (xint 32)) (imm-modrm src dst #xc7 0 (xint 32)) (reg-modrm dst src #x8b) From ffjeld at common-lisp.net Mon Feb 18 22:30:21 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Mon, 18 Feb 2008 17:30:21 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080218223021.75B2F5C1F8@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv31162 Modified Files: bootblock.lisp Log Message: New function-names in asm. --- /project/movitz/cvsroot/movitz/bootblock.lisp 2008/02/09 18:42:26 1.14 +++ /project/movitz/cvsroot/movitz/bootblock.lisp 2008/02/18 22:30:21 1.15 @@ -9,7 +9,7 @@ ;;;; Created at: Mon Oct 9 20:47:19 2000 ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: bootblock.lisp,v 1.14 2008/02/09 18:42:26 ffjeld Exp $ +;;;; $Id: bootblock.lisp,v 1.15 2008/02/18 22:30:21 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -402,13 +402,13 @@ (multiple-value-bind (bios-loader bb-symtab) (let ((asm-x86:*position-independent-p* nil) (asm-x86:*cpu-mode* :16-bit)) - (asm:proglist-encode (mkasm16-bios-bootloader image-size load-address skip-sectors) - :start-pc #x7c00)) + (asm:assemble-proglist (mkasm16-bios-bootloader image-size load-address skip-sectors) + :start-pc #x7c00)) (multiple-value-bind (protected-loader protected-symtab) (let ((asm-x86:*position-independent-p* nil)) - (asm:proglist-encode (mkasm-loader image-size load-address call-address) - :start-pc (cdr (or (assoc 'new-world bb-symtab) - (error "No new-world defined in bios-loader."))))) + (asm:assemble-proglist (mkasm-loader image-size load-address call-address) + :start-pc (cdr (or (assoc 'new-world bb-symtab) + (error "No new-world defined in bios-loader."))))) (let* ((loader-length (+ (length bios-loader) (length protected-loader))) (bootblock (progn From ffjeld at common-lisp.net Mon Feb 18 22:30:45 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Mon, 18 Feb 2008 17:30:45 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080218223045.24DED555A5@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv31315 Modified Files: asm.lisp Log Message: Improve disassemble-proglist etc. --- /project/movitz/cvsroot/movitz/asm.lisp 2008/02/16 19:14:06 1.13 +++ /project/movitz/cvsroot/movitz/asm.lisp 2008/02/18 22:30:45 1.14 @@ -6,7 +6,7 @@ ;;;; Author: Frode Vatvedt Fjeld ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: asm.lisp,v 1.13 2008/02/16 19:14:06 ffjeld Exp $ +;;;; $Id: asm.lisp,v 1.14 2008/02/18 22:30:45 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -25,6 +25,7 @@ #:retry-symbol-resolve #:pc-relative-operand #:assemble-proglist + #:disassemble-proglist #:*pc* #:*symtab* #:*instruction-compute-extra-prefix-map* @@ -117,6 +118,10 @@ (defun pc-relative-operand-p (operand) (typep operand 'pc-relative-operand)) +(defun pc-relative-operand-offset (operand) + (check-type operand pc-relative-operand) + (second operand)) + (define-condition unresolved-symbol () ((symbol :initarg :symbol @@ -229,14 +234,40 @@ :corrections (nconc new-corrections corrections))) (t (values code *symtab*)))))))) -(defun disassemble-proglist (code &key (cpu-package '#:asm-x86)) - (let ((instruction-disassembler (find-symbol (string '#:disassemble-instruction) - cpu-package))) - (loop while code - collect (multiple-value-bind (instruction new-code) - (funcall instruction-disassembler - code) - (when (eq code new-code) - (loop-finish)) - (setf code new-code) - instruction)))) +(defun instruction-operands (instruction) + (if (listp (car instruction)) ; skip any instruction prefixes etc. + (cddr instruction) + (cdr instruction))) + + +(defun disassemble-proglist (code &key (cpu-package '#:asm-x86) (pc (or *pc* 0)) (symtab *symtab*)) + (let* ((instruction-disassembler (find-symbol (string '#:disassemble-instruction) + cpu-package)) + (proglist0 (loop while code + collect pc + collect (multiple-value-bind (instruction new-code) + (funcall instruction-disassembler + code) + (when (eq code new-code) + (loop-finish)) + (loop until (eq code new-code) + do (incf pc) + (setf code (cdr code))) + (let ((operands (instruction-operands instruction))) + (if (notany #'pc-relative-operand-p operands) + instruction + (nconc (loop until (eq instruction operands) + collect (pop instruction)) + (loop for operand in operands + collect (if (not (pc-relative-operand-p operand)) + operand + (let* ((location (+ pc (pc-relative-operand-offset operand))) + (entry (or (rassoc location symtab) + (car (push (cons (gensym) location) + symtab))))) + `(quote ,(car entry)))))))))))) + (values (loop for (pc instruction) on proglist0 by #'cddr + when (car (rassoc pc symtab)) + collect it + collect instruction) + symtab))) From ffjeld at common-lisp.net Mon Feb 18 22:30:50 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Mon, 18 Feb 2008 17:30:50 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080218223050.9C1B03002C@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv31346 Modified Files: asm-x86.lisp Log Message: Improve disassemble-proglist etc. --- /project/movitz/cvsroot/movitz/asm-x86.lisp 2008/02/18 20:57:14 1.28 +++ /project/movitz/cvsroot/movitz/asm-x86.lisp 2008/02/18 22:30:47 1.29 @@ -6,7 +6,7 @@ ;;;; Author: Frode Vatvedt Fjeld ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: asm-x86.lisp,v 1.28 2008/02/18 20:57:14 ffjeld Exp $ +;;;; $Id: asm-x86.lisp,v 1.29 2008/02/18 22:30:47 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -445,7 +445,7 @@ (defun resolve-pc-relative (operand) (etypecase operand - ((cons (eql :pc+)) + (pc-relative-operand (reduce #'+ (cdr operand) :key #'resolve-operand)) (symbol-reference @@ -772,9 +772,12 @@ (error "No operand ~S in ~S." key operands)))) (defmacro pop-code (code-place &optional context) - `(let ((x (pop ,code-place))) + `(progn + (unless ,code-place + (error "End of byte-stream in the middle of an instruction.")) + (let ((x (pop ,code-place))) (check-type x (unsigned-byte 8) ,(format nil "an octet (context: ~A)" context)) - x)) + x))) (defmacro code-call (form &optional (code-place (case (car form) ((funcall apply) (third form)) (t (second form))))) "Execute form, then 'magically' update the code binding with the secondary return value from form." From ffjeld at common-lisp.net Mon Feb 18 22:31:13 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Mon, 18 Feb 2008 17:31:13 -0500 (EST) Subject: [movitz-cvs] CVS movitz/losp/muerte Message-ID: <20080218223113.C478E1B021@common-lisp.net> Update of /project/movitz/cvsroot/movitz/losp/muerte In directory clnet:/tmp/cvs-serv31532 Modified Files: interrupt.lisp Log Message: Prefer the new assembler. --- /project/movitz/cvsroot/movitz/losp/muerte/interrupt.lisp 2007/04/07 20:49:17 1.56 +++ /project/movitz/cvsroot/movitz/losp/muerte/interrupt.lisp 2008/02/18 22:31:13 1.57 @@ -10,7 +10,7 @@ ;;;; Author: Frode Vatvedt Fjeld ;;;; Created at: Wed Apr 7 01:50:03 2004 ;;;; -;;;; $Id: interrupt.lisp,v 1.56 2007/04/07 20:49:17 ffjeld Exp $ +;;;; $Id: interrupt.lisp,v 1.57 2008/02/18 22:31:13 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -133,7 +133,7 @@ ;; Do RET promotion of EIP. (:movl (:ebp ,(dit-frame-offset :eip)) :ecx) - ((:cs-override) :cmpb ,(realpart (ia-x86:asm :ret)) (:ecx)) + ((:cs-override) :cmpb ,@(asm-x86:assemble-instruction '(:ret)) (:ecx)) (:jne 'not-at-ret-instruction) (:globally (:movl (:edi (:edi-offset ret-trampoline)) :ecx)) (:movl :ecx (:ebp ,(dit-frame-offset :eip))) From ffjeld at common-lisp.net Sat Feb 23 22:28:55 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Sat, 23 Feb 2008 17:28:55 -0500 (EST) Subject: [movitz-cvs] CVS movitz/losp Message-ID: <20080223222855.EF91515011@common-lisp.net> Update of /project/movitz/cvsroot/movitz/losp In directory clnet:/tmp/cvs-serv5997 Modified Files: scratch.lisp Log Message: Remove DOS EOL. --- /project/movitz/cvsroot/movitz/losp/scratch.lisp 2008/02/04 21:04:51 1.2 +++ /project/movitz/cvsroot/movitz/losp/scratch.lisp 2008/02/23 22:28:55 1.3 @@ -1,1164 +1,1164 @@ -;;;;------------------ -*- movitz-mode: t -*-------------------------- -;;;; -;;;; Copyright (C) 2007, Frode Vatvedt Fjeld -;;;; -;;;; Filename: scratch.lisp -;;;; Description: Misc. testing code etc. -;;;; Author: Frode Vatvedt Fjeld -;;;; Distribution: See the accompanying file COPYING. -;;;; -;;;; $Id: scratch.lisp,v 1.2 2008/02/04 21:04:51 ffjeld Exp $ -;;;; -;;;;------------------------------------------------------------------ - -(provide :scratch) - -(in-package los0) - -#+ignore -(defun set.2 () - (let ((*var-used-in-set-tests* 'a) - (var '*var-used-in-set-tests*)) - (declare (special *var-used-in-set-tests*)) - (values - (let ((*var-used-in-set-tests* 'c)) - (list (set var 'b) *var-used-in-set-tests* (symbol-value var))) - *var-used-in-set-tests*))) -;; (b c b) -;; b) - -#+ignore -(defun test-lend-constant () - (let ((symbols '(a b c d e f g h i j k l m n o p q r s t u v w x y z)) - (table (make-hash-table :test #'eq))) - (loop for sym in symbols - for i from 1 - do (setf (gethash sym table) i)) - (let ((sum 0)) - (values (maphash #'(lambda (k v) - (assert (eq (elt symbols (1- v)) k)) - (incf sum v)) - table) - sum)))) - -#+ignore -(defun test-aux (x y &aux (sum (+ x y))) - sum) - -#+ignore -(defun mapc.error.3 () - (mapc #'append)) - -#+ignore -(defun with-hash-table-iterator.12 () - (block done - (let ((x :bad)) - (declare (special x)) - (let ((x :good)) - (with-hash-table-iterator (m (return-from done x)) - (declare (special x)))))) - :good) - -#+ignore -(defun string.15 () - (when (> char-code-limit 65536) - (loop for i = (random char-code-limit) - for c = (code-char i) - for s = (and c (string c)) - repeat 2000 - when (and c - (or (not (stringp s)) - (not (= (length s) 1)) - (not (eql c (char s 0))))) - collect (list i c s))) - nil) - -(defun x (bios32) - (warn "X: ~S" (memref-int bios32)) - (warn "X: ~S" (= (memref-int bios32) #x5f32335f))) - -(defun setfint (x o) - (setf (memref x o :type :unsigned-byte32) 0)) - -(defun fint (x) - (memref-int x :type :unsigned-byte32 :physicalp t)) - -(defun good () - (with-inline-assembly (:returns :untagged-fixnum-ecx) - ((:gs-override) :movl (#x1000000) :ecx))) - -(defun (setf good) (x) - (with-inline-assembly (:returns :untagged-fixnum-ecx) - (:compile-form (:result-mode :untagged-fixnum-ecx) x) - ((:gs-override) :movl :ecx (#x1000000)))) - -(defun test2 () - (funcall - (compile - nil - '(lambda (a) (declare (notinline > *)) - (declare (optimize (compilation-speed 0) (safety 2) (speed 2) (debug 0) (space 3))) - (catch 'ct1 (* a (throw 'ct1 (if (> 0) a 0)))))) - 5445205692802)) - -(defun test3 () - (loop for x below 2 count (not (not (typep x t))))) - -(defun test4 () - (let ((aa 1)) (if (not (/= aa 0)) aa 0))) - - -(defun test-floppy () - (muerte.x86-pc::fd-start-disk) ; to initialize the controller and spin the drive up. - (muerte.x86-pc::fd-cmd-seek 70) ; to seek to track 70. - (setf (muerte.x86-pc::fd-motor) nil)) ; to turn the drive and controller off. - - -(defun alist-get-expand (alist key) - (let (cons) - (tagbody - loop - (setq cons (car alist)) - (cond ((eq alist nil) (go end)) - ((eq cons nil)) - ((eq key (car cons)) (go end))) - (setq alist (cdr alist)) - (go loop) - end) - (cdr cons))) - -;;;(defun test-irq () -;;; (with-inline-assembly (:returns :multiple-values) -;;; (:compile-form (:result-mode :multiple-values) (values 0 1 2 3 4 5)) -;;; (:int 42))) -;;; -;;;(defun koo () -;;; (prog1 (make-values) -;;; (format t "hello: ~S" (values 'a 'b 'c 'd)))) -;;; -;;;(defun test-complement (&rest args) -;;; (declare (dynamic-extent args)) -;;; (apply (complement #'symbolp) args)) -;;; -;;;(defun test-constantly (&rest args) -;;; (declare (dynamic-extent args)) -;;; (apply (constantly 'test-value) args)) - -(defun test-closure (x z) - (flet ((closure (y) (= x (1+ y)))) - (declare (dynamic-extent (function closure))) - (closure z) - #+ignore (funcall (lambda (y) (= x (1+ y))) - z))) - -(defun test-stack-cons (x y) - (muerte::with-dynamic-extent-scope (zap) - (let ((foo (muerte::with-dynamic-extent-allocation (zap) - (cons x (lambda () y))))) - (format t "~Z: ~S, ~S" foo foo (funcall (cdr foo)))))) - -(defun test-handler (x) - (let ((foo x)) - (handler-bind - ((error (lambda (c) - (format t "error: ~S ~S" c x)))) - (error "This is an error. ~S" foo)))) - - -(defun fooo (v w) - (tagbody - (print (block blurgh - (progv (list v) (list w) - (format t "Uh: ~S" (symbol-value v)) - (if (symbol-value v) - (return-from blurgh 1) - (go zap))))) - zap) - t) - - -(defun test-break () - (with-inline-assembly (:returns :multiple-values) - (:movl 10 :ecx) - (:movl :esi :eax) ; This function should return itself! - (:clc) - (:break))) - -(defun test-upload (x) - ;; (warn "Test-upload blab la bla!!") - (setf x (cdr x)) - x) - -;;;(defun zzz (x) -;;; (multiple-value-bind (symbol status) -;;; (values-list x) -;;; (warn "sym: ~S, stat: ~S" symbol status))) -;;; - -#+ignore -(defun test-loop (x) - (format t "test-loop: ~S~%" - (loop for i from 0 to 10 collect x))) - -#+ignore -(defun delay (time) - (dotimes (i time) - (with-inline-assembly (:returns :nothing) - (:nop) - (:nop)))) -;;; -;;;(defun test-consp (x) -;;; (with-inline-assembly (:returns :boolean-cf=1) -;;; (:compile-form (:result-mode :ecx) x) -;;; (:leal (:edi -4) :eax) -;;; (:rorb :cl :al))) - - -#+ignore -(defun test-block (x) - (block nil - (let ((*print-base* (if x (return 3) 8))) - (jumbo 2 2 (and x 2) (+ 3 3 (or x 4)) (if x 2 (return nil))))) - #+ignore (+ x 2)) - -#+ignore -(defun jumbo (a b c &rest x) - (declare (dynamic-extent x)) - (print a) (print b) (print c) - (print x) - 'jumbo) - -(defun jumbo2 (a b &rest x) - (declare (dynamic-extent x)) - (print a) (print b) - (print x) - 'jumbo) - -(defun jumbo3 (a &rest x) - (declare (dynamic-extent x)) - (print a) - (print x) - 'jumbo) - -(defun jumbo4 (&rest x) - (declare (dynamic-extent x)) - (print x) - 'jumbo) - -#+ignore -(defun tagbodyxx (x) - (tagbody - (print 'hello) - haha - (unwind-protect - (when x (go hoho)) - (warn "unwind..")) - (print 'world) - hoho - (print 'blrugh))) - -#+ignore -(defun tagbodyxx (x) - (tagbody - (print 'hello) - haha - (unwind-protect - (funcall (lambda () - (when x (go hoho)))) - (warn "unwind..")) - (print 'world) - hoho - (print 'blrugh))) - -#+ignore -(defun kumbo (&key a b (c (jumbo 1 2 3)) d) - (print a) - (print b) - (print c) - (print d)) - -#+ignore -(defun lumbo (a &optional (b 'zap)) - (print a) - (print b)) - -(defmacro do-check-esp (&body body) - `(let ((before (with-inline-assembly (:returns :eax) (:movl :esp :eax)))) - (with-inline-assembly (:returns :nothing) - (:compile-form (:result-mode :multiple-values) (progn , at body))) - (unless (eq before - (with-inline-assembly (:returns :eax) (:movl :esp :eax))) - (error "ESP before body: ~S, after: ~S" - (with-inline-assembly (:returns :eax) (:movl :esp :eax)))))) - -#+ignore -(defun test-m-v-call () - (do-check-esp - (multiple-value-call #'format t "~@{ ~D~}~%" - 'a (values) 'b (test-loop 1) (make-values) - 'c 'd 'e (make-no-values) 'f))) - -(defun test-m-v-call2 () - (multiple-value-call #'format t "~@{ ~D~}~%" - 'a 'b (values 1 2 3) 'c 'd 'e 'f)) - -(defun make-values () - (values 0 1 2 3 4 5)) - -(defun xfuncall (&rest args) - (declare (dynamic-extent args)) - (break "xfuncall:~{ ~S~^,~}" args) - (values)) - -(defun xfoo (f) - (do-check-esp - (multiple-value-bind (a b c d) - (multiple-value-prog1 (make-values) - (format t "hello world")) - (format t "~&a: ~S, b: ~S, c: ~S, d: ~S ~S" a b c d f)))) - - -#+ignore -(defun make-no-values () - (values)) - -#+ignore -(defun test-nth-values () - (nth-value 2 (make-values))) - -#+ignore -(defun test-values2 () - (multiple-value-bind (a b c d e f g h) - (make-values) - (format t "test-values2: A: ~S, B: ~S, C: ~S, D: ~S, E: ~S, F: ~S G: ~S, H: ~S~%" - a b c d e f g h))) - -#+ignore -(defun test-flet (zap) - (flet ((pingo (z y x) - (declare (ignore y z)) - (format t "This is pingo: ~S with zap: ~W~%" x zap))) - ;; (declare (dynamic-extent pingo)) - (pingo 100 200 300))) - -#+ignore -(defun test-flet2 (zap) - (flet ((pingo (z y x) - (declare (ignore y z)) - (format t "This is pingo: ~S with zap: ~W~%" x zap))) - ;; (declare (dynamic-extent pingo)) - (lambda (x) - (pingo 100 200 300)))) - -(defun test-boo () - (let ((real-cmuc #'test-flet2)) - (let ((plongo (lambda (x) - (warn "~S real-cmuc: ~S" x real-cmuc) - (funcall real-cmuc x)))) - (funcall plongo 'zooom)))) - -(defun test-labels () - (labels ((pingo (x) - (format t "~&This is pingo: ~S~%" x) - (when (plusp x) - (pingo (1- x))))) - (pingo 5))) - -#+ignore -(defun foo-type (length start1 sequence-1) - (do* ((i 0 #+ignore (+ start1 length -1) (1- i))) - ((< i start1) sequence-1) - (declare (type muerte::index i length)) - (setf (sequence-1-ref i) - 'foo))) - - -#+ignore -(defun test-values () - (multiple-value-bind (a b c d e f g h i j) - (multiple-value-prog1 - (make-values) -;;; (format t "this is the resulting form.~%") - (format t "this is the first ignorable form.~%" 1 2 3) - (format t "this is the second ignorable form.~%")) -;;; (format t "test-values num: ~D~%" (capture-reg8 :cl)) - (format t "test-values: A: ~Z, B: ~Z, C: ~Z, D: ~Z ~Z ~Z ~Z ~Z ~Z ~Z~%" a b c d e f g h i j))) - - -#+ignore -(defun test-keywords (&key a b (c 100) ((:d x) 5 x-p)) - (format t "test-keywords: a: ~S, b: ~S, c: ~S, x: ~S, x-p: ~S~%" - a b c x x-p)) - -#+ignore -(defun test-k1 (a b &key x) - (declare (ignore a b)) - (warn "x: ~S" x)) - [1931 lines skipped] From ffjeld at common-lisp.net Sat Feb 23 22:34:14 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Sat, 23 Feb 2008 17:34:14 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080223223414.A213381003@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv6952 Modified Files: image.lisp Log Message: Use the new disassembler. --- /project/movitz/cvsroot/movitz/image.lisp 2008/02/09 18:42:00 1.114 +++ /project/movitz/cvsroot/movitz/image.lisp 2008/02/23 22:34:14 1.115 @@ -9,7 +9,7 @@ ;;;; Created at: Sun Oct 22 00:22:43 2000 ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: image.lisp,v 1.114 2008/02/09 18:42:00 ffjeld Exp $ +;;;; $Id: image.lisp,v 1.115 2008/02/23 22:34:14 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -1244,6 +1244,7 @@ (when (= offset (bt:slot-offset 'movitz-run-time-context slot-name)) (return slot-name)))) +#+ia-x86 (defun comment-instruction (instruction funobj pc) "Return a list of strings that comments on INSTRUCTION." (loop for operand in (ia-x86::instruction-operands instruction) @@ -1361,8 +1362,57 @@ (defparameter *recursive-disassemble-remember-funobjs* nil) +(defun movitz-foo (funobj &key (name (movitz-funobj-name funobj)) ((:image *image*) *image*) + (recursive t)) + (coerce (movitz-vector-symbolic-data (movitz-funobj-code-vector funobj)) + 'list)) + +#-ia-x86 +(defun movitz-disassemble-funobj (funobj &key (name (movitz-funobj-name funobj)) ((:image *image*) *image*) + (recursive t)) + (let ((code (coerce (movitz-vector-symbolic-data (movitz-funobj-code-vector funobj)) + 'list)) + (entry-points (loop for slot in '(code-vector%1op code-vector%2op code-vector%3op) + for entry-arg-count upfrom 1 + for entry = (slot-value funobj slot) + when (and (consp entry) + (eq funobj (cdr entry))) + collect (cons (car entry) + entry-arg-count)))) + (let ((*print-case* :downcase)) + (format t "~&;; Movitz Disassembly of ~A: +;; ~D Constant~:P~@[: ~A~]. +~:{~4D: ~16<~{ ~2,'0X~}~;~> ~A~@[ ;~{ ~A~}~]~%~}" + (movitz-print (or (movitz-funobj-name funobj) name)) + (length (movitz-funobj-const-list funobj)) + (movitz-funobj-const-list funobj) + (loop with pc = 0 + for (data . instruction) in (asm:disassemble-proglist code :symtab (movitz-funobj-symtab funobj) + :collect-data t) + when (assoc pc entry-points) + collect (list pc nil + (format nil " => Entry-point for ~D arguments <=" (cdr (assoc pc entry-points))) + nil) + when (let ((x (find pc (movitz-funobj-symtab funobj) :key #'cdr))) + (when x (list pc (list (format nil " ~A" (car x))) "" nil))) + collect it + collect (list pc data instruction nil) + do (incf pc (length data)))))) + (when recursive + (let ((*recursive-disassemble-remember-funobjs* + (cons funobj *recursive-disassemble-remember-funobjs*))) + (loop for x in (movitz-funobj-const-list funobj) + do (when (and (typep x '(and movitz-funobj (not movitz-funobj-standard-gf))) + (not (member x *recursive-disassemble-remember-funobjs*))) + (push x *recursive-disassemble-remember-funobjs*) + (terpri) + (movitz-disassemble-funobj x)))))) + + + +#+ia-x86 (defun movitz-disassemble-funobj (funobj &key (name (movitz-funobj-name funobj)) ((:image *image*) *image*) - (recursive t)) + (recursive t)) (let* ((code-vector (movitz-funobj-code-vector funobj)) (code (map 'vector #'identity (movitz-vector-symbolic-data code-vector))) @@ -1375,44 +1425,65 @@ (length (movitz-funobj-const-list funobj)) (movitz-funobj-const-list funobj) (loop - for pc = 0 then code-position - for instruction = (ia-x86:decode-read-octet - #'(lambda () - (when (< code-position - (movitz-vector-fill-pointer code-vector)) - (prog1 - (aref code code-position) - (incf code-position))))) - for cbyte = (and instruction - (ia-x86::instruction-original-datum instruction)) - until (null instruction) - when (let ((x (find pc (movitz-funobj-symtab funobj) :key #'cdr))) - (when x (list pc (list (format nil " ~S" (car x))) "" nil))) - collect it - when (some (lambda (x) - (and (plusp pc) (= pc x))) - entry-points) - collect (list pc nil - (format nil " => Entry-point for ~D arguments <=" - (1+ (position-if (lambda (x) - (= pc x)) - entry-points))) - nil) - collect (list pc - (ia-x86::cbyte-to-octet-list cbyte) - instruction - (comment-instruction instruction funobj pc))))) + for pc = 0 then code-position + for instruction = (ia-x86:decode-read-octet + #'(lambda () + (when (< code-position + (movitz-vector-fill-pointer code-vector)) + (prog1 + (aref code code-position) + (incf code-position))))) + for cbyte = (and instruction + (ia-x86::instruction-original-datum instruction)) + until (null instruction) + when (let ((x (find pc (movitz-funobj-symtab funobj) :key #'cdr))) + (when x (list pc (list (format nil " ~S" (car x))) "" nil))) + collect it + when (some (lambda (x) + (and (plusp pc) (= pc x))) + entry-points) + collect (list pc nil + (format nil " => Entry-point for ~D arguments <=" + (1+ (position-if (lambda (x) + (= pc x)) + entry-points))) + nil) + collect (list pc + (ia-x86::cbyte-to-octet-list cbyte) + instruction + (comment-instruction instruction funobj pc))))) (when recursive (let ((*recursive-disassemble-remember-funobjs* (cons funobj *recursive-disassemble-remember-funobjs*))) (loop for x in (movitz-funobj-const-list funobj) - do (when (and (typep x '(and movitz-funobj (not movitz-funobj-standard-gf))) - (not (member x *recursive-disassemble-remember-funobjs*))) - (push x *recursive-disassemble-remember-funobjs*) - (terpri) - (movitz-disassemble-funobj x))))) + do (when (and (typep x '(and movitz-funobj (not movitz-funobj-standard-gf))) + (not (member x *recursive-disassemble-remember-funobjs*))) + (push x *recursive-disassemble-remember-funobjs*) + (terpri) + (movitz-disassemble-funobj x))))) (values)) +#-ia-x86 +(defun movitz-disassemble-primitive (name &optional (*image* *image*)) + (let* ((code-vector (cond + ((slot-exists-p (image-run-time-context *image*) name) + (slot-value (image-run-time-context *image*) name)) + (t (movitz-symbol-value (movitz-read name))))) + (code (coerce (movitz-vector-symbolic-data code-vector) + 'list))) + (format t "~&;; Movitz disassembly of ~S: +~:{~4D: ~16<~{ ~2,'0X~}~;~> ~A~@[ ;~{ ~A~}~]~%~}" + name + (loop with pc = 0 + for (data . instruction) in (asm:disassemble-proglist code :collect-data t) + collect (list pc + data + instruction + nil #+ignore (comment-instruction instruction nil pc)) + do (incf pc (length data)))) + (values))) + +#+ia-x86 (defun movitz-disassemble-primitive (name &optional (*image* *image*)) (let* ((code-vector (cond ((slot-exists-p (image-run-time-context *image*) name) From ffjeld at common-lisp.net Sat Feb 23 22:35:08 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Sat, 23 Feb 2008 17:35:08 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080223223508.914527323C@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv7169 Modified Files: asm.lisp Log Message: Finishing touches on the disassembler. --- /project/movitz/cvsroot/movitz/asm.lisp 2008/02/18 22:30:45 1.14 +++ /project/movitz/cvsroot/movitz/asm.lisp 2008/02/23 22:35:08 1.15 @@ -6,7 +6,7 @@ ;;;; Author: Frode Vatvedt Fjeld ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: asm.lisp,v 1.14 2008/02/18 22:30:45 ffjeld Exp $ +;;;; $Id: asm.lisp,v 1.15 2008/02/23 22:35:08 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -234,13 +234,22 @@ :corrections (nconc new-corrections corrections))) (t (values code *symtab*)))))))) +(defun instruction-operator (instruction) + (if (listp (car instruction)) ; skip any instruction prefixes etc. + (cadr instruction) + (car instruction))) + (defun instruction-operands (instruction) (if (listp (car instruction)) ; skip any instruction prefixes etc. (cddr instruction) (cdr instruction))) +(defun instruction-modifiers (instruction) + (if (listp (car instruction)) + (car instruction) + nil)) -(defun disassemble-proglist (code &key (cpu-package '#:asm-x86) (pc (or *pc* 0)) (symtab *symtab*)) +(defun disassemble-proglist (code &key (cpu-package '#:asm-x86) (pc (or *pc* 0)) (symtab *symtab*) collect-data collect-labels) (let* ((instruction-disassembler (find-symbol (string '#:disassemble-instruction) cpu-package)) (proglist0 (loop while code @@ -250,24 +259,33 @@ code) (when (eq code new-code) (loop-finish)) - (loop until (eq code new-code) - do (incf pc) - (setf code (cdr code))) - (let ((operands (instruction-operands instruction))) - (if (notany #'pc-relative-operand-p operands) - instruction - (nconc (loop until (eq instruction operands) - collect (pop instruction)) - (loop for operand in operands - collect (if (not (pc-relative-operand-p operand)) - operand - (let* ((location (+ pc (pc-relative-operand-offset operand))) - (entry (or (rassoc location symtab) - (car (push (cons (gensym) location) - symtab))))) - `(quote ,(car entry)))))))))))) - (values (loop for (pc instruction) on proglist0 by #'cddr - when (car (rassoc pc symtab)) - collect it - collect instruction) + (let* ((data (loop until (eq code new-code) + do (incf pc) + collect (pop code))) + (operands (instruction-operands instruction))) + ;; (format *debug-io* "~D: ~X ~S~%" pc data instruction) + (cons data + (if (notany #'pc-relative-operand-p operands) + instruction + (nconc (loop until (eq instruction operands) + collect (pop instruction)) + (loop for operand in operands + collect (if (not (pc-relative-operand-p operand)) + operand + (let* ((location (+ pc (pc-relative-operand-offset operand))) + (entry (or (rassoc location symtab) + (car (push (cons (gensym) location) + symtab))))) + `(quote ,(car entry))))))))))))) + (values (loop for (pc data-instruction) on proglist0 by #'cddr + for (data . instruction) = data-instruction + for label = (when collect-labels + (rassoc pc symtab)) + when label + collect (if (not collect-data) + (car label) + (cons nil (car label))) + collect (if (not collect-data) + instruction + data-instruction)) symtab))) From ffjeld at common-lisp.net Sat Feb 23 22:35:17 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Sat, 23 Feb 2008 17:35:17 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080223223517.A673573243@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv7188 Modified Files: asm-x86.lisp Log Message: Finishing touches on the disassembler. --- /project/movitz/cvsroot/movitz/asm-x86.lisp 2008/02/18 22:30:47 1.29 +++ /project/movitz/cvsroot/movitz/asm-x86.lisp 2008/02/23 22:35:10 1.30 @@ -6,7 +6,7 @@ ;;;; Author: Frode Vatvedt Fjeld ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: asm-x86.lisp,v 1.29 2008/02/18 22:30:47 ffjeld Exp $ +;;;; $Id: asm-x86.lisp,v 1.30 2008/02/23 22:35:10 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -278,7 +278,7 @@ (make-array 256 :initial-element nil)) (deftype disassembly-decoder () - '(list-of* keyword (or keyword null) symbol)) + '(list-of* boolean keyword (or keyword null) symbol)) (defun (setf opcode-disassembler) (decoder opcode operator-mode) (check-type decoder disassembly-decoder) @@ -312,22 +312,22 @@ -(defmacro define-disassembler ((operator opcode &optional cpu-mode (digit nil digit-p)) lambda-list &body body) +(defmacro define-disassembler ((operator opcode &optional cpu-mode digit backup-p) lambda-list &body body) (cond - (digit-p + (digit `(loop for mod from #b00 to #b11 do (loop for r/m from #b000 to #b111 as ext-opcode = (logior (ash ,opcode 8) (ash ,digit 3) (ash mod 6) r/m) - do (define-disassembler (,operator ext-opcode ,cpu-mode) ,lambda-list , at body)))) + do (define-disassembler (,operator ext-opcode ,cpu-mode nil t) ,lambda-list , at body)))) ((symbolp lambda-list) - `(setf (opcode-disassembler ,opcode ,cpu-mode) (list ,operator ,cpu-mode ',lambda-list , at body))) + `(setf (opcode-disassembler ,opcode ,cpu-mode) (list ,backup-p ,operator ,cpu-mode ',lambda-list , at body))) (t (let ((defun-name (intern (format nil "~A-~A-~X~@[-~A~]" 'disassembler operator opcode cpu-mode)))) `(progn (defun ,defun-name ,lambda-list , at body) - (setf (opcode-disassembler ,opcode ',cpu-mode) (list ,operator ',cpu-mode ',defun-name)) + (setf (opcode-disassembler ,opcode ',cpu-mode) (list ,backup-p ,operator ',cpu-mode ',defun-name)) ',defun-name))))) (defun disassemble-simple-prefix (code operator opcode operand-size address-size rex) @@ -799,15 +799,18 @@ (defun disassemble-instruction (code &optional override-operand-size override-address-size rex) (labels ((lookup-decoder (table opcode) - (let* ((datum (pop-code code)) + (let* ((backup-code code) + (datum (pop-code code)) (opcode (logior (ash opcode 8) datum)) (decoder (svref table datum))) (typecase decoder - ((simple-vector 256) + (vector (lookup-decoder decoder opcode)) (disassembly-decoder - (values decoder + (when (car decoder) + (setf code backup-code)) + (values (cdr decoder) opcode)) (t (error "No disassembler registered for opcode #x~X." opcode)))))) (multiple-value-bind (decoder opcode) @@ -1384,14 +1387,13 @@ ;;;;;;;;;;; CALL -(define-operator* (:16 :callw :32 :calll :64 :callr :dispatch :call) (dest) - (case *cpu-mode* - (:16-bit - (pc-rel #xe8 dest (sint 16))) - (:32-bit - (pc-rel #xe8 dest (sint 32)))) - (when (eq operator-mode *cpu-mode*) - (modrm dest #xff 2))) +(define-operator/16 :callw (dest) + (pc-rel #xe8 dest (sint 16)) + (modrm dest #xff 2)) + +(define-operator/32 :call (dest) + (pc-rel #xe8 dest (sint 32)) + (modrm dest #xff 2)) (define-operator/none :call-segment (dest) (modrm dest #xff 3)) @@ -1879,11 +1881,6 @@ (define-operator* (:16 :negw :32 :negl :64 :negr) (dst) (modrm dst #xf7 3)) -;;;;;;;;;;;;;;;; NOP - -(define-operator/none :nop () - (opcode #x90)) - ;;;;;;;;;;; NOT (define-operator/8 :notb (dst) @@ -2162,3 +2159,9 @@ (imm-modrm src dst #x81 6 :int-16-32-64) (reg-modrm dst src #x33) (reg-modrm src dst #x31)) + +;;;;;;;;;;;;;;;; NOP + +(define-operator/none :nop () + (opcode #x90)) + From ffjeld at common-lisp.net Sat Feb 23 22:36:21 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Sat, 23 Feb 2008 17:36:21 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080223223621.030301B@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv7366 Modified Files: compiler.lisp Log Message: Remove remnants of ia-x86. --- /project/movitz/cvsroot/movitz/compiler.lisp 2008/02/17 00:10:11 1.192 +++ /project/movitz/cvsroot/movitz/compiler.lisp 2008/02/23 22:36:21 1.193 @@ -8,7 +8,7 @@ ;;;; Created at: Wed Oct 25 12:30:49 2000 ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: compiler.lisp,v 1.192 2008/02/17 00:10:11 ffjeld Exp $ +;;;; $Id: compiler.lisp,v 1.193 2008/02/23 22:36:21 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -991,32 +991,6 @@ (assemble-funobj funobj combined-code)))) funobj) - -(defun diss (code) - (format nil "~&;; Diss: -~:{~4D: ~16<~{ ~2,'0X~}~;~> ~A~@[ ;~{ ~A~}~]~%~}" - (loop with code-position = 0 and instruction-octets = nil - for pc = 0 then code-position - for instruction = (progn - (setf instruction-octets nil) - (ia-x86:decode-read-octet (lambda () - (incf code-position) - (loop while (and code (not (typep (car code) '(unsigned-byte 8)))) - do (warn "diss bad byte at ~D: ~S" code-position (pop code)) - (incf code-position)) - (let ((x (pop code))) - (when x (push x instruction-octets)) - x)))) - collect (if (not instruction) - (list pc (nreverse instruction-octets) nil '("???")) - (list pc - (nreverse instruction-octets) - ;;(ia-x86::cbyte-to-octet-list (ia-x86::instruction-original-datum instruction)) - instruction - (comment-instruction instruction nil pc))) - while code))) - - (defun assemble-funobj (funobj combined-code) (multiple-value-bind (code-vector code-symtab) (let ((asm:*instruction-compute-extra-prefix-map* @@ -1056,20 +1030,13 @@ (break "entry%2: ~D" b)) (unless (<= 0 c 4095) (break "entry%3: ~D" c))) - (loop for ((entry-label slot-name)) on '((entry%1op code-vector%1op) - (entry%2op code-vector%2op) - (entry%3op code-vector%3op)) - do (cond - ((assoc entry-label code-symtab) - (let ((offset (cdr (assoc entry-label code-symtab)))) - (setf (slot-value funobj slot-name) - (cons offset funobj)) - #+ignore (when (< offset #x100) - (vector-push offset code-vector)))) - #+ignore - ((some (lambda (label) (assoc label code-symtab)) - (mapcar #'car rest)) - (vector-push 0 code-vector)))) + (loop for (entry-label slot-name) in '((entry%1op code-vector%1op) + (entry%2op code-vector%2op) + (entry%3op code-vector%3op)) + do (when (assoc entry-label code-symtab) + (let ((offset (cdr (assoc entry-label code-symtab)))) + (setf (slot-value funobj slot-name) + (cons offset funobj))))) (check-locate-concistency code-vector) (setf (movitz-funobj-code-vector funobj) (make-movitz-vector (length code-vector) From ffjeld at common-lisp.net Sun Feb 24 11:57:36 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Sun, 24 Feb 2008 06:57:36 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080224115736.0E215610B8@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv31988 Modified Files: load.lisp Log Message: Don't load ia-x86 by default. --- /project/movitz/cvsroot/movitz/load.lisp 2008/02/04 21:05:23 1.12 +++ /project/movitz/cvsroot/movitz/load.lisp 2008/02/24 11:57:35 1.13 @@ -10,7 +10,7 @@ ;;;; Author: Frode Vatvedt Fjeld ;;;; Created at: Thu Jan 15 18:40:58 2004 ;;;; -;;;; $Id: load.lisp,v 1.12 2008/02/04 21:05:23 ffjeld Exp $ +;;;; $Id: load.lisp,v 1.13 2008/02/24 11:57:35 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -32,15 +32,15 @@ (load (compile-file #p"asm-x86")) ; ia-x86 needs them while testing/migrating. -(let ((*default-pathname-defaults* (merge-pathnames #p"../ia-x86/"))) - #+(or cmu) (let ((pwd (ext:default-directory))) - (progn - (unwind-protect - (progn - (setf (ext:default-directory) #p"../ia-x86/") - (load "load")) - (setf (ext:default-directory) pwd)))) - #-(or cmu) (load "load")) +#+ia-x86 (let ((*default-pathname-defaults* (merge-pathnames #p"../ia-x86/"))) + #+(or cmu) (let ((pwd (ext:default-directory))) + (progn + (unwind-protect + (progn + (setf (ext:default-directory) #p"../ia-x86/") + (load "load")) + (setf (ext:default-directory) pwd)))) + #-(or cmu) (load "load")) #+allegro (progn (load (compile-file #p"../infunix/procfs")) From ffjeld at common-lisp.net Sun Feb 24 12:13:06 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Sun, 24 Feb 2008 07:13:06 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080224121306.ECD9D71138@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv3033 Modified Files: image.lisp Log Message: Add disassembly comments. --- /project/movitz/cvsroot/movitz/image.lisp 2008/02/23 22:34:14 1.115 +++ /project/movitz/cvsroot/movitz/image.lisp 2008/02/24 12:13:06 1.116 @@ -9,7 +9,7 @@ ;;;; Created at: Sun Oct 22 00:22:43 2000 ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: image.lisp,v 1.115 2008/02/23 22:34:14 ffjeld Exp $ +;;;; $Id: image.lisp,v 1.116 2008/02/24 12:13:06 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -1244,6 +1244,79 @@ (when (= offset (bt:slot-offset 'movitz-run-time-context slot-name)) (return slot-name)))) +#-ia-x86 +(defun comment-instruction (instruction funobj pc) + "Return a list of strings that comments on INSTRUCTION." + (declare (ignore pc)) + (loop for operand in (asm:instruction-operands instruction) + when (and (typep operand 'asm:indirect-operand) + (member :edi operand) + (run-time-context-find-slot (asm:indirect-operand-offset operand)) + (not (member (asm:instruction-operator instruction) + '(:leal :lea)))) + collect (format nil "" + (run-time-context-find-slot (asm:indirect-operand-offset operand))) +;; when (and (typep operand 'ia-x86::operand-indirect-register) +;; (eq 'ia-x86::edi (ia-x86::operand-register operand)) +;; (typep instruction 'ia-x86-instr::lea) +;; (or (not (ia-x86::operand-register2 operand)) +;; (eq 'ia-x86::edi (ia-x86::operand-register2 operand)))) +;; collect (let ((x (+ (* (ia-x86::operand-scale operand) +;; (image-nil-word *image*)) +;; (ia-x86::operand-offset operand) +;; (ecase (ia-x86::operand-register2 operand) +;; (ia-x86::edi (image-nil-word *image*)) +;; ((nil) 0))))) +;; (case (ldb (byte 3 0) x) +;; (#.(tag :character) +;; (format nil "Immediate ~D (char ~S)" +;; x (code-char (ldb (byte 8 8) x)))) +;; (#.(mapcar 'tag +fixnum-tags+) +;; (format nil "Immediate ~D (fixnum ~D #x~X)" +;; x +;; (truncate x +movitz-fixnum-factor+) +;; (truncate x +movitz-fixnum-factor+))) +;; (t (format nil "Immediate ~D" x)))) + when (and funobj + (typep operand 'asm:indirect-operand) + (member :esi operand) + (<= 12 (asm:indirect-operand-offset operand))) + collect (format nil "~A" + (nth (truncate (- (+ (asm:indirect-operand-offset operand) + (if (member :edi operand) + (image-nil-word *image*) + 0)) + (slot-offset 'movitz-funobj 'constant0)) + 4) + (movitz-funobj-const-list funobj))) +;; when (and funobj +;; (typep operand 'ia-x86::operand-indirect-register) +;; (eq 'ia-x86::esi (ia-x86::operand-register2 operand)) +;; (eq 'ia-x86::edi (ia-x86::operand-register operand)) +;; (<= 12 (ia-x86::operand-offset operand))) +;; collect (format nil "~A" (nth (truncate (- (+ (ia-x86::operand-offset operand) +;; (* (ia-x86::operand-scale operand) +;; (image-nil-word *image*))) +;; (slot-offset 'movitz-funobj 'constant0)) +;; 4) +;; (movitz-funobj-const-list funobj))) +;; when (typep operand 'ia-x86::operand-rel-pointer) +;; collect (let* ((x (+ pc +;; (imagpart (ia-x86::instruction-original-datum instruction)) +;; (length (ia-x86:instruction-prefixes instruction)) +;; (ia-x86::operand-offset operand))) +;; (label (and funobj (car (find x (movitz-funobj-symtab funobj) :key #'cdr))))) +;; (if label +;; (format nil "branch to ~S at ~D" label x) +;; (format nil "branch to ~D" x))) + when (and (typep operand '(and integer asm:immediate-operand)) + (<= #x100 operand #x10000) + (= (tag :character) (mod operand 256))) + collect (format nil "#\\~C" (code-char (truncate operand 256))) + when (and (typep operand '(and integer asm:immediate-operand)) + (zerop (mod operand +movitz-fixnum-factor+))) + collect (format nil "#x~X" (truncate operand +movitz-fixnum-factor+)))) + #+ia-x86 (defun comment-instruction (instruction funobj pc) "Return a list of strings that comments on INSTRUCTION." @@ -1396,7 +1469,7 @@ when (let ((x (find pc (movitz-funobj-symtab funobj) :key #'cdr))) (when x (list pc (list (format nil " ~A" (car x))) "" nil))) collect it - collect (list pc data instruction nil) + collect (list pc data instruction (comment-instruction instruction funobj pc)) do (incf pc (length data)))))) (when recursive (let ((*recursive-disassemble-remember-funobjs* @@ -1479,7 +1552,7 @@ collect (list pc data instruction - nil #+ignore (comment-instruction instruction nil pc)) + (comment-instruction instruction nil pc)) do (incf pc (length data)))) (values))) From ffjeld at common-lisp.net Mon Feb 25 20:11:01 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Mon, 25 Feb 2008 15:11:01 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080225201101.64FB34D0A0@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv30926 Added Files: movitz.asd Log Message: Initial attempt. --- /project/movitz/cvsroot/movitz/movitz.asd 2008/02/25 20:11:01 NONE +++ /project/movitz/cvsroot/movitz/movitz.asd 2008/02/25 20:11:01 1.1 ;;;; -*- Mode: Lisp; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;;------------------------------------------------------------------ ;;;; ;;;; Copyright (C) 2008, Frode V. Fjeld ;;;; ;;;; For distribution policy, see the accompanying file COPYING. ;;;; ;;;; Filename: movitz.asd ;;;; Description: Movitz ASDF system definition. ;;;; Author: Frode Vatvedt Fjeld ;;;; Created at: Thu Jan 15 18:40:58 2004 ;;;; ;;;; $Id: movitz.asd,v 1.1 2008/02/25 20:11:01 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ (defpackage movitz-asd (:use :cl :asdf)) (in-package movitz-asd) (defsystem movitz-asm :name "Movitz Assembler" :version "1.0" :maintainer "ffjeld at common-lisp.net" :author "Frode V. Fjeld" :license "BSD-like, see accopanying file COPYING." :description "An (dis-)assembler framework, with support for x86 in 16, 32, and 64-bit modes." :serial t :components ((:file "asm") (:file "asm-x86"))) (defclass movitz-source-file (cl-source-file) ()) (defsystem movitz :name "Movitz" :version "0.1" :maintainer "ffjeld at common-lisp.net" :author "Frode V. Fjeld" :license "BSD-like, see accopanying file COPYING." :description "A compiler, run-time, and libraries for Common Lisp on the x86." :default-component-class movitz-source-file :serial t :depends-on (binary-types) :components ((:file "packages") (:file "movitz") (:file "parse") (:file "eval") (:file "environment") (:file "compiler-types") (:file "compiler-protocol") (:file "storage-types") (:file "multiboot") (:file "bootblock") (:file "image") (:file "stream-image") (:file "assembly-syntax") (:file "compiler") (:file "special-operators") (:file "special-operators-cl"))) #+sbcl (defmethod perform :around (op (file movitz-source-file)) (handler-bind ((sb-ext:defconstant-uneql #'continue)) (call-next-method))) From ffjeld at common-lisp.net Mon Feb 25 20:11:41 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Mon, 25 Feb 2008 15:11:41 -0500 (EST) Subject: [movitz-cvs] CVS binary-types Message-ID: <20080225201141.B6661392C1@common-lisp.net> Update of /project/movitz/cvsroot/binary-types In directory clnet:/tmp/cvs-serv31018 Added Files: binary-types.asd Log Message: Initial attempt. --- /project/movitz/cvsroot/binary-types/binary-types.asd 2008/02/25 20:11:41 NONE +++ /project/movitz/cvsroot/binary-types/binary-types.asd 2008/02/25 20:11:41 1.1 ;;;; -*- Mode: Lisp; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;;------------------------------------------------------------------ ;;;; ;;;; Copyright (C) 2008, Frode V. Fjeld ;;;; ;;;; For distribution policy, see the accompanying file COPYING. ;;;; ;;;; Filename: movitz.asd ;;;; Description: Movitz ASDF system definition. ;;;; Author: Frode Vatvedt Fjeld ;;;; Created at: Thu Jan 15 18:40:58 2004 ;;;; ;;;; $Id: binary-types.asd,v 1.1 2008/02/25 20:11:41 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ (defpackage binary-types-asd (:use :cl :asdf)) (in-package binary-types-asd) (defsystem binary-types :name "Binary-types" :maintainer "ffjeld at common-lisp.net" :author "Frode V. Fjeld" :license "BSD-like, see accopanying file COPYING." :description "A library for reading and writing binary records." :components ((:file "binary-types"))) From ffjeld at common-lisp.net Mon Feb 25 20:19:24 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Mon, 25 Feb 2008 15:19:24 -0500 (EST) Subject: [movitz-cvs] CVS public_html Message-ID: <20080225201924.63E552D070@common-lisp.net> Update of /project/movitz/cvsroot/public_html In directory clnet:/tmp/cvs-serv32409 Modified Files: ChangeLog Log Message: *** empty log message *** --- /project/movitz/cvsroot/public_html/ChangeLog 2008/01/13 22:32:02 1.11 +++ /project/movitz/cvsroot/public_html/ChangeLog 2008/02/25 20:19:23 1.12 @@ -1,3 +1,13 @@ +2008-02-25 Frode V. Fjeld + + * movitz.asd: Created an ASDF system definition. + + * movitz/asm.lisp, movitz/asm-x86.lisp: Created new assembler and + disassembler that's less overengineered (the design goals of + ia-x86 were not originally to serve as an assembler). This speeds + up compiles considerably; on the order of twice as fast, and + reduces the overall footprint of the movitz system too. + 2008-01-13 Frode Vatvedt Fjeld * movitz/losp/muerte/memref.lisp: Fixed (setf memref-int :type From ffjeld at common-lisp.net Mon Feb 25 20:19:48 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Mon, 25 Feb 2008 15:19:48 -0500 (EST) Subject: [movitz-cvs] CVS public_html Message-ID: <20080225201948.B5AC73F027@common-lisp.net> Update of /project/movitz/cvsroot/public_html In directory clnet:/tmp/cvs-serv32519 Modified Files: index.html Log Message: more news. --- /project/movitz/cvsroot/public_html/index.html 2008/01/13 22:32:04 1.31 +++ /project/movitz/cvsroot/public_html/index.html 2008/02/25 20:19:48 1.32 @@ -15,6 +15,16 @@

Most recent news

+2008-02-25  Frode V. Fjeld  
+
+	* movitz.asd: Created an ASDF system definition.
+
+	* movitz/asm.lisp, movitz/asm-x86.lisp: Created new assembler and
+	disassembler that's less overengineered (the design goals of
+	ia-x86 were not originally to serve as an assembler). This speeds
+	up compiles considerably; on the order of twice as fast, and
+	reduces the overall footprint of the movitz system too.
+
 2008-01-13  Frode Vatvedt Fjeld  
 
 	* movitz/losp/muerte/memref.lisp: Fixed (setf memref-int :type



From ffjeld at common-lisp.net  Mon Feb 25 21:32:13 2008
From: ffjeld at common-lisp.net (ffjeld)
Date: Mon, 25 Feb 2008 16:32:13 -0500 (EST)
Subject: [movitz-cvs] CVS public_html
Message-ID: <20080225213213.A612630040@common-lisp.net>

Update of /project/movitz/cvsroot/public_html
In directory clnet:/tmp/cvs-serv15409

Modified Files:
	index.html 
Log Message:
No more ia-x86.


--- /project/movitz/cvsroot/public_html/index.html	2008/02/25 20:19:48	1.32
+++ /project/movitz/cvsroot/public_html/index.html	2008/02/25 21:32:13	1.33
@@ -76,19 +76,18 @@
  tree via anonymous cvs, as described here

-

There are currently three modules in the repository: +

There are two modules in use in the repository:

    -
  • ia-x86
  • binary-types
  • movitz
-

The former two are required for building and using the - latter. So far, this combo has been run under Allegro, SBCL, and - CMUCL, but everything is supposed to be platform-independent ANSI - Common Lisp. CLisp apparently dumps core for some reason during the - build process.

+

Binary-types is a library that is required for building and + using Movitz. So far, this combo has been run under Allegro, SBCL, + and CMUCL, but everything is supposed to be platform-independent + ANSI Common Lisp. CLisp apparently dumps core for some reason during + the build process.

The main build process is run by two operators. Create-image creates a symbolic Movitz lisp-world from scratch. This symbolic From ffjeld at common-lisp.net Mon Feb 25 21:47:53 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Mon, 25 Feb 2008 16:47:53 -0500 (EST) Subject: [movitz-cvs] CVS public_html Message-ID: <20080225214753.A6F857A026@common-lisp.net> Update of /project/movitz/cvsroot/public_html In directory clnet:/project/movitz/public_html Modified Files: style.css Log Message: fresh copy --- /project/movitz/cvsroot/public_html/style.css 2004/01/13 11:31:55 1.1 +++ /project/movitz/cvsroot/public_html/style.css 2008/02/25 21:47:53 1.2 @@ -1,260 +1,54 @@ -/* Style code taken from oswd.net, this design originally by haran. -/* original header: -/* TITLE: Stylesheet for Purple Haze -/* URI : /purplehaze/purplehaze.css -/* MODIF: 2002-12-15 17:34 +0800 - -/* ###### Color Scheme ###### */ - -/* - * CHANGING THE COLOR SCHEME - * ------------------------- - * - * Four basic colors were used in the design. To change the - * color scheme, just edit these four values below. - * - */ - -.topOfPage, q, h1, h2, h3, .headerTitle, .siteMap, .siteMap *, .headerLinks, .headerLinks *, .sideBox div, #footer * -{ /* Text Color: */ color: /* #a0a0ff; */ #1111ff; } - -q, h2, #header, .sideBox, .sideBox div, #footer -{ /* Border Color: */ border-color: #c0c0ff; } - -#header, .sideBox div, .sideBox a:hover -{ /* Background Color (darker): */ background-color: #f0f0ff; } - - -q, .sideBox a, .sideBox span, #footer - /* Background Color (lighter): */ - { background-color: #fcfcff; } - - - -/* ###### Browser-specific Styles ###### */ - -/* For IE & Mozilla-based browsers: */ - -.LHS { - margin-left: 2.5mm; - float: left; - clear: left; - width: 10em; -} - -.RHS { - margin-right: 2.5mm; - float: right; - clear: right; - width: 14em; - font-size: small; -} - -/* For Mozilla-based (CSS2-fully complaint) browsers only: */ - -[class~="LHS"] { - margin-left: 5mm; -} - -[class~="RHS"] { - margin-right: 5mm; -} - - -/* ###### Body Text ###### */ - -#bodyText { - line-height: 1.5em; - margin: 10mm 14em 0 12em; - padding: 0 1em 1ex 1em; -} - -#bodyTextWide { - line-height: 1.5em; - margin: 10mm 2em 0 12em; - padding: 0 1em 1ex 1em; -} - -#bodyText p { - padding-bottom: 1ex; -} - -#bodyText ul { - padding-bottom: 1ex; -} - -.topOfPage { - font-size: 90%; - font-weight: bold; - font-variant: small-caps; - text-decoration: none; - padding-left: 1ex; - padding-right: 1ex; - float: right; -} - -.smallCaps { - font-variant: small-caps; -} - -body { - background-color: white; - color: black; - font-family: "arial"; /* verdana, tahoma, helvetica, arial, sans-serif;*/ - font-size: 100%; - margin: 0; -} - -h1, h2, h3 { - font-family: "arial"; /* , sans-serif; */ -} - -h1 { - font-weight: bold; - font-size: 150%; - font-family: "arial"; - border-bottom: 1px solid; - padding-bottom: 0.5ex; -} - -h2 { - font-weight: bold; - font-size: 100%; - font-family: "arial"; - padding-bottom: 0.5ex; -} - -acronym { - background-color: inherit; - color: teal; - border-bottom: 1px dashed teal; - cursor: help; -} - -code { - font-family: "lucida console", monospace; - font-size: 90%; -} - -img { - border: 0; -} - -q { - font-family: "arial"; /* , verdana, helvetica, arial, sans-serif; */ - font-weight: bold; - border: 2px dotted; - margin: 0 1em 1ex 1em; - padding: 0.5ex 0.5ex 0.5ex 1ex; - width: 9em; - float: left; -} - - -/* ###### Header ###### */ - -#header { - border-bottom: 2px solid; - height: 5em; - margin-bottom: 5mm; - padding: 2em 2.5mm 0 5mm; -} - -.headerTitle { - font-size: 300%; -} - -.headerLinks { - text-align: right; - margin-right: 2.5mm; - float: right; - clear: right; -} - -.headerLinks * { - text-decoration: none; - font-weight: bold; - padding-right: 1ex; -} - -.headerLinks a:hover { - text-decoration: underline; -} - -.siteMap { - font-size: small; - text-align: left; - margin-left: 2.5mm; - margin-right: 2.5mm; - float: left; - clear: left; -} - -.siteMap * { - text-decoration: none; -/* font-weight: bold; */ - padding-right: 1ex; -} - -.siteMap a:hover { - text-decoration: underline; -} - - -/* ###### Side Box ###### */ - -.sideBox { - border-top: 2px solid; - border-bottom: 2px solid; - margin-top: 5mm; -} - -.sideBox div { - font-weight: bold; - border-bottom: 1px dashed; - padding: 0.5ex 0.5em 0.5ex 0.75em; -} - -.sideBox a, .sideBox a:hover, .sideBox span { - color: black; - text-decoration: none; - line-height: 1.25em; - display: block; - padding: 1ex 0.5em 1ex 0.75em; -} - - -/* ###### Footer ###### */ - -#footer { - color: inherit; - border-top: 2px solid; - border-bottom: 2px solid; - padding-top: 0.75ex; - padding-bottom: 0.75ex; - clear: left; -} - -.footerImg { - padding-right: 3mm; - padding-top: 2mm; - float: none; -} - -#footer div { - padding-left: 3mm; -} - -#footer * { - background-color: inherit; - font-size: 92%; -} - -#footer a:hover { - text-decoration: none; -} - -.footerCol2 { - left: 7em; -} +.header { + font-size: medium; + background-color:#336699; + color:#ffffff; + border-style:solid; + border-width: 5px; + border-color:#002244; + padding: 1mm 1mm 1mm 5mm; +} + +.footer { + font-size: small; + font-style: italic; + text-align: right; + background-color:#336699; + color:#ffffff; + border-style:solid; + border-width: 2px; + border-color:#002244; + padding: 1mm 1mm 1mm 1mm; +} + +.footer a:link { + font-weight:bold; + color:#ffffff; + text-decoration:underline; +} + +.footer a:visited { + font-weight:bold; + color:#ffffff; + text-decoration:underline; +} + +.footer a:hover { + font-weight:bold; + color:#002244; + text-decoration:underline; } + +.check {font-size: x-small; + text-align:right;} + +.check a:link { font-weight:bold; + color:#a0a0ff; + text-decoration:underline; } + +.check a:visited { font-weight:bold; + color:#a0a0ff; + text-decoration:underline; } + +.check a:hover { font-weight:bold; + color:#000000; + text-decoration:underline; } From ffjeld at common-lisp.net Mon Feb 25 23:16:21 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Mon, 25 Feb 2008 18:16:21 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080225231621.4B1A562136@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv8791 Modified Files: movitz.asd Log Message: Don't forget movitz-asm. --- /project/movitz/cvsroot/movitz/movitz.asd 2008/02/25 20:11:01 1.1 +++ /project/movitz/cvsroot/movitz/movitz.asd 2008/02/25 23:16:21 1.2 @@ -10,7 +10,7 @@ ;;;; Author: Frode Vatvedt Fjeld ;;;; Created at: Thu Jan 15 18:40:58 2004 ;;;; -;;;; $Id: movitz.asd,v 1.1 2008/02/25 20:11:01 ffjeld Exp $ +;;;; $Id: movitz.asd,v 1.2 2008/02/25 23:16:21 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -42,7 +42,7 @@ :description "A compiler, run-time, and libraries for Common Lisp on the x86." :default-component-class movitz-source-file :serial t - :depends-on (binary-types) + :depends-on (binary-types movitz-asm) :components ((:file "packages") (:file "movitz") (:file "parse") From ffjeld at common-lisp.net Mon Feb 25 23:33:43 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Mon, 25 Feb 2008 18:33:43 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080225233343.14859392C1@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv13388 Modified Files: asm-x86.lisp Log Message: Disengage warning. --- /project/movitz/cvsroot/movitz/asm-x86.lisp 2008/02/23 22:35:10 1.30 +++ /project/movitz/cvsroot/movitz/asm-x86.lisp 2008/02/25 23:33:43 1.31 @@ -6,7 +6,7 @@ ;;;; Author: Frode Vatvedt Fjeld ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: asm-x86.lisp,v 1.30 2008/02/23 22:35:10 ffjeld Exp $ +;;;; $Id: asm-x86.lisp,v 1.31 2008/02/25 23:33:43 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -288,11 +288,11 @@ (let ((bit-pos (* 8 (1- (ceiling (integer-length pos) 8))))) (if (not (plusp bit-pos)) (progn - (unless (or (eq nil decoder) - (eq nil (svref table pos)) - (equal decoder (svref table pos))) - (warn "Redefining disassembler for ~@[~(~A~) ~]opcode #x~X from ~{~S ~}to ~{~S~^ ~}." - operator-mode opcode (svref table pos) decoder)) + #+(or) (unless (or (eq nil decoder) + (eq nil (svref table pos)) + (equal decoder (svref table pos))) + (warn "Redefining disassembler for ~@[~(~A~) ~]opcode #x~X from ~{~S ~}to ~{~S~^ ~}." + operator-mode opcode (svref table pos) decoder)) (setf (svref table pos) decoder)) (set-it (or (svref table (ldb (byte 8 bit-pos) pos)) (setf (svref table (ldb (byte 8 bit-pos) pos)) From ffjeld at common-lisp.net Mon Feb 25 23:34:11 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Mon, 25 Feb 2008 18:34:11 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080225233411.39E24610B6@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv13493 Modified Files: asm.lisp Log Message: Add indirect-operand-offset. --- /project/movitz/cvsroot/movitz/asm.lisp 2008/02/23 22:35:08 1.15 +++ /project/movitz/cvsroot/movitz/asm.lisp 2008/02/25 23:34:11 1.16 @@ -6,7 +6,7 @@ ;;;; Author: Frode Vatvedt Fjeld ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: asm.lisp,v 1.15 2008/02/23 22:35:08 ffjeld Exp $ +;;;; $Id: asm.lisp,v 1.16 2008/02/25 23:34:11 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -19,6 +19,9 @@ #:immediate-operand #:indirect-operand-p #:indirect-operand + #:indirect-operand-offset + #:instruction-operands + #:instruction-operator #:register-operand #:resolve-operand #:unresolved-symbol @@ -112,6 +115,12 @@ (defun indirect-operand-p (operand) (typep operand 'indirect-operand)) +(defun indirect-operand-offset (operand) + (check-type operand indirect-operand) + (reduce #'+ operand + :key (lambda (x) + (if (integerp x) x 0)))) + (deftype pc-relative-operand () '(cons (eql :pc+))) From ffjeld at common-lisp.net Mon Feb 25 23:34:46 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Mon, 25 Feb 2008 18:34:46 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080225233446.58F712D17E@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv13638 Modified Files: packages.lisp Log Message: Insane hack to make asdf work. Someone please make sense of this. --- /project/movitz/cvsroot/movitz/packages.lisp 2007/03/01 17:49:44 1.56 +++ /project/movitz/cvsroot/movitz/packages.lisp 2008/02/25 23:34:46 1.57 @@ -10,7 +10,7 @@ ;;;; Author: Frode Vatvedt Fjeld ;;;; Created at: Sat Nov 15 21:39:55 2003 ;;;; -;;;; $Id: packages.lisp,v 1.56 2007/03/01 17:49:44 ffjeld Exp $ +;;;; $Id: packages.lisp,v 1.57 2008/02/25 23:34:46 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -1276,6 +1276,11 @@ #:vector-read-more-p )) +(print '(muerte::un-backquote ; make asdf/sbcl realize that these symbols exists.. + muerte::backquote-comma + muerte::backquote-comma-at + muerte::backquote-comma-dot) + (make-broadcast-stream)) (defpackage #:movitz (:use :common-lisp :binary-types) From ffjeld at common-lisp.net Mon Feb 25 23:43:24 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Mon, 25 Feb 2008 18:43:24 -0500 (EST) Subject: [movitz-cvs] CVS binary-types Message-ID: <20080225234324.2F4B2586D1@common-lisp.net> Update of /project/movitz/cvsroot/binary-types In directory clnet:/tmp/cvs-serv17193 Modified Files: binary-types.asd Log Message: Provide. --- /project/movitz/cvsroot/binary-types/binary-types.asd 2008/02/25 20:11:41 1.1 +++ /project/movitz/cvsroot/binary-types/binary-types.asd 2008/02/25 23:43:24 1.2 @@ -10,7 +10,7 @@ ;;;; Author: Frode Vatvedt Fjeld ;;;; Created at: Thu Jan 15 18:40:58 2004 ;;;; -;;;; $Id: binary-types.asd,v 1.1 2008/02/25 20:11:41 ffjeld Exp $ +;;;; $Id: binary-types.asd,v 1.2 2008/02/25 23:43:24 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -25,4 +25,6 @@ :author "Frode V. Fjeld" :license "BSD-like, see accopanying file COPYING." :description "A library for reading and writing binary records." + :perform (load-op :after (op c) + (provide 'binary-types)) :components ((:file "binary-types"))) From ffjeld at common-lisp.net Mon Feb 25 23:43:45 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Mon, 25 Feb 2008 18:43:45 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080225234345.90B1871123@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv17288 Modified Files: movitz.asd Log Message: Provide. --- /project/movitz/cvsroot/movitz/movitz.asd 2008/02/25 23:16:21 1.2 +++ /project/movitz/cvsroot/movitz/movitz.asd 2008/02/25 23:43:45 1.3 @@ -10,7 +10,7 @@ ;;;; Author: Frode Vatvedt Fjeld ;;;; Created at: Thu Jan 15 18:40:58 2004 ;;;; -;;;; $Id: movitz.asd,v 1.2 2008/02/25 23:16:21 ffjeld Exp $ +;;;; $Id: movitz.asd,v 1.3 2008/02/25 23:43:45 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -28,6 +28,8 @@ :license "BSD-like, see accopanying file COPYING." :description "An (dis-)assembler framework, with support for x86 in 16, 32, and 64-bit modes." :serial t + :perform (load-op :after (op c) + (provide 'movitz-asm)) :components ((:file "asm") (:file "asm-x86"))) @@ -43,6 +45,8 @@ :default-component-class movitz-source-file :serial t :depends-on (binary-types movitz-asm) + :perform (load-op :after (op c) + (provide 'movitz)) :components ((:file "packages") (:file "movitz") (:file "parse") From ffjeld at common-lisp.net Wed Feb 27 20:55:50 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Wed, 27 Feb 2008 15:55:50 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080227205550.4B0AC2F069@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv28144 Modified Files: asm-x86.lisp Log Message: Add disassembler for sreg-modrm. --- /project/movitz/cvsroot/movitz/asm-x86.lisp 2008/02/25 23:33:43 1.31 +++ /project/movitz/cvsroot/movitz/asm-x86.lisp 2008/02/27 20:55:50 1.32 @@ -6,7 +6,7 @@ ;;;; Author: Frode Vatvedt Fjeld ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: asm-x86.lisp,v 1.31 2008/02/25 23:33:43 ffjeld Exp $ +;;;; $Id: asm-x86.lisp,v 1.32 2008/02/27 20:55:50 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -217,7 +217,7 @@ (cond ((atom body) nil) - ((member (car body) '(reg-modrm modrm opcode imm-modrm imm opcode-reg pc-rel moffset)) + ((member (car body) '(reg-modrm modrm opcode imm-modrm imm opcode-reg pc-rel moffset sreg-modrm)) (list body)) (t (mapcan #'find-forms body))))) (let ((defun-name (intern (format nil "~A-~A" 'instruction-encoder operator)))) @@ -312,7 +312,7 @@ -(defmacro define-disassembler ((operator opcode &optional cpu-mode digit backup-p) lambda-list &body body) +(defmacro define-disassembler ((operator opcode &optional cpu-mode digit backup-p operand-size) lambda-list &body body) (cond (digit `(loop for mod from #b00 to #b11 @@ -321,13 +321,13 @@ (ash ,digit 3) (ash mod 6) r/m) - do (define-disassembler (,operator ext-opcode ,cpu-mode nil t) ,lambda-list , at body)))) + do (define-disassembler (,operator ext-opcode ,cpu-mode nil t ,operand-size) ,lambda-list , at body)))) ((symbolp lambda-list) - `(setf (opcode-disassembler ,opcode ,cpu-mode) (list ,backup-p ,operator ,cpu-mode ',lambda-list , at body))) + `(setf (opcode-disassembler ,opcode ,cpu-mode) (list ,backup-p ,operator ,(or operand-size cpu-mode) ',lambda-list , at body))) (t (let ((defun-name (intern (format nil "~A-~A-~X~@[-~A~]" 'disassembler operator opcode cpu-mode)))) `(progn (defun ,defun-name ,lambda-list , at body) - (setf (opcode-disassembler ,opcode ',cpu-mode) (list ,backup-p ,operator ',cpu-mode ',defun-name)) + (setf (opcode-disassembler ,opcode ',cpu-mode) (list ,backup-p ,operator ',(or operand-size cpu-mode) ',defun-name)) ',defun-name))))) (defun disassemble-simple-prefix (code operator opcode operand-size address-size rex) @@ -507,7 +507,8 @@ (:32-bit '(:eax :ecx :edx :ebx :esp :ebp :esi :edi)) (:64-bit '(:rax :rcx :rdx :rbx :rsp :rbp :rsi :rdi :r8 :r9 :r10 :r11 :r12 :13 :r14 :r15)) (:mm '(:mm0 :mm1 :mm2 :mm3 :mm4 :mm5 :mm6 :mm7)) - (:xmm '(:xmm0 :xmm1 :xmm2 :xmm3 :xmm4 :xmm5 :xmm6 :xmm7)))) + (:xmm '(:xmm0 :xmm1 :xmm2 :xmm3 :xmm4 :xmm5 :xmm6 :xmm7)) + (:segment '(:es :cs :ss :ds :fs :gs)))) (defun encode-reg/mem (operand mode) (check-type mode (member nil :8-bit :16-bit :32-bit :64-bit :mm :xmm)) @@ -837,12 +838,12 @@ (remove nil fixed-operands)) code)) -(defun decode-reg-modrm (code operator opcode operand-size address-size rex operand-ordering) +(defun decode-reg-modrm (code operator opcode operand-size address-size rex operand-ordering &optional (reg-mode operand-size)) (declare (ignore opcode rex)) (values (list* operator (order-operands operand-ordering :reg (nth (ldb (byte 3 3) (car code)) - (register-set-by-mode operand-size)) + (register-set-by-mode reg-mode)) :modrm (ecase address-size (:32-bit (code-call (decode-reg-modrm-32 code operand-size))) @@ -1131,15 +1132,25 @@ (defmacro reg-cr (op-reg op-cr opcode &rest extras) `(return-when (encode-reg-cr operator legacy-prefixes ,op-reg ,op-cr ,opcode operator-mode default-rex , at extras))) -(defmacro sreg-modrm (op-sreg op-modrm opcode) - `(let* ((reg-map '(:es :cs :ss :ds :fs :gs)) - (reg-index (position ,op-sreg reg-map))) - (when reg-index - (return-values-when - (merge-encodings (encoded-values :opcode ,opcode - :reg reg-index - :rex default-rex) - (encode-reg/mem ,op-modrm operator-mode)))))) +(defmacro sreg-modrm (op-sreg op-modrm opcode &rest extras) + `(progn + (assembler + (let* ((reg-map '(:es :cs :ss :ds :fs :gs)) + (reg-index (position ,op-sreg reg-map))) + (when reg-index + (return-values-when + (merge-encodings (encoded-values :opcode ,opcode + :reg reg-index + :rex default-rex + , at extras) + (encode-reg/mem ,op-modrm operator-mode)))))) + (disassembler + (define-disassembler (operator ,opcode nil nil nil :16-bit) + decode-reg-modrm + (operand-ordering operand-formals + :reg ',op-sreg + :modrm ',op-modrm) + :segment)))) (defmacro moffset (opcode op-offset type fixed-operand) `(progn @@ -1812,10 +1823,10 @@ (moffset #xa0 src (uint 16) (dst :ax)) (opcode-reg-imm #xb8 dst src (xint 16)) (imm-modrm src dst #xc7 0 (xint 16)) - (sreg-modrm src dst #x8c) - (sreg-modrm dst src #x8e) (reg-modrm dst src #x8b) - (reg-modrm src dst #x89)) + (reg-modrm src dst #x89) + (sreg-modrm src dst #x8c) + (sreg-modrm dst src #x8e)) (define-operator/32 :movl (src dst) (moffset #xa3 dst (uint 32) (src :eax)) From ffjeld at common-lisp.net Wed Feb 27 21:22:47 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Wed, 27 Feb 2008 16:22:47 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080227212247.ED02516070@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv661 Modified Files: asm-x86.lisp Log Message: Add disassembler for opcode-reg-imm. --- /project/movitz/cvsroot/movitz/asm-x86.lisp 2008/02/27 20:55:50 1.32 +++ /project/movitz/cvsroot/movitz/asm-x86.lisp 2008/02/27 21:22:47 1.33 @@ -6,7 +6,7 @@ ;;;; Author: Frode Vatvedt Fjeld ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: asm-x86.lisp,v 1.32 2008/02/27 20:55:50 ffjeld Exp $ +;;;; $Id: asm-x86.lisp,v 1.33 2008/02/27 21:22:47 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -217,7 +217,8 @@ (cond ((atom body) nil) - ((member (car body) '(reg-modrm modrm opcode imm-modrm imm opcode-reg pc-rel moffset sreg-modrm)) + ((member (car body) '(reg-modrm modrm opcode imm-modrm imm opcode-reg + opcode-reg-imm pc-rel moffset sreg-modrm)) (list body)) (t (mapcan #'find-forms body))))) (let ((defun-name (intern (format nil "~A-~A" 'instruction-encoder operator)))) @@ -899,6 +900,15 @@ :extra extra-operand)) code)) +(defun decode-opcode-reg-imm (code operator opcode operand-size address-size rex operand-ordering imm-type) + (declare (ignore address-size rex)) + (values (list* operator + (order-operands operand-ordering + :reg (nth (ldb (byte 3 0) opcode) + (register-set-by-mode operand-size)) + :imm (code-call (decode-integer code imm-type)))) + code)) + (defun decode-reg-modrm-16 (code operand-size) (let* ((modrm (pop-code code mod/rm)) (mod (ldb (byte 2 6) modrm)) @@ -1259,8 +1269,18 @@ (t default-rex)))))))))) (defmacro opcode-reg-imm (opcode op-reg op-imm type) - `(return-when - (encode-opcode-reg-imm operator legacy-prefixes ,opcode ,op-reg ,op-imm ',type operator-mode default-rex))) + `(progn + (assembler + (return-when + (encode-opcode-reg-imm operator legacy-prefixes ,opcode ,op-reg ,op-imm ',type operator-mode default-rex))) + (disassembler + (loop for reg from #b000 to #b111 + do (define-disassembler (operator (logior ,opcode reg) operator-mode) + decode-opcode-reg-imm + (operand-ordering operand-formals + :reg ',op-reg + :imm ',op-imm) + ',type))))) (defmacro far-pointer (opcode segment offset offset-type &rest extra) `(when (and (immediate-p ,segment) From ffjeld at common-lisp.net Thu Feb 28 20:09:08 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Thu, 28 Feb 2008 15:09:08 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080228200908.3358B601A8@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv20701 Modified Files: asm-x86.lisp Log Message: Disassemblers for reg-cr and far-pointer. --- /project/movitz/cvsroot/movitz/asm-x86.lisp 2008/02/27 21:22:47 1.33 +++ /project/movitz/cvsroot/movitz/asm-x86.lisp 2008/02/28 20:09:08 1.34 @@ -6,7 +6,7 @@ ;;;; Author: Frode Vatvedt Fjeld ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: asm-x86.lisp,v 1.33 2008/02/27 21:22:47 ffjeld Exp $ +;;;; $Id: asm-x86.lisp,v 1.34 2008/02/28 20:09:08 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -218,7 +218,8 @@ ((atom body) nil) ((member (car body) '(reg-modrm modrm opcode imm-modrm imm opcode-reg - opcode-reg-imm pc-rel moffset sreg-modrm)) + opcode-reg-imm pc-rel moffset sreg-modrm reg-cr + far-pointer)) (list body)) (t (mapcan #'find-forms body))))) (let ((defun-name (intern (format nil "~A-~A" 'instruction-encoder operator)))) @@ -312,6 +313,19 @@ (set-it *opcode-disassemblers-64* opcode))))) +(defmacro pop-code (code-place &optional context) + `(progn + (unless ,code-place + (error "End of byte-stream in the middle of an instruction.")) + (let ((x (pop ,code-place))) + (check-type x (unsigned-byte 8) ,(format nil "an octet (context: ~A)" context)) + x))) + +(defmacro code-call (form &optional (code-place (case (car form) ((funcall apply) (third form)) (t (second form))))) + "Execute form, then 'magically' update the code binding with the secondary return value from form." + `(let (tmp) + (declare (ignorable tmp)) + (setf (values tmp ,code-place) ,form))) (defmacro define-disassembler ((operator opcode &optional cpu-mode digit backup-p operand-size) lambda-list &body body) (cond @@ -773,20 +787,6 @@ collect (or (getf operands key) (error "No operand ~S in ~S." key operands)))) -(defmacro pop-code (code-place &optional context) - `(progn - (unless ,code-place - (error "End of byte-stream in the middle of an instruction.")) - (let ((x (pop ,code-place))) - (check-type x (unsigned-byte 8) ,(format nil "an octet (context: ~A)" context)) - x))) - -(defmacro code-call (form &optional (code-place (case (car form) ((funcall apply) (third form)) (t (second form))))) - "Execute form, then 'magically' update the code binding with the secondary return value from form." - `(let (tmp) - (declare (ignorable tmp)) - (setf (values tmp ,code-place) ,form))) - (defun decode-integer (code type) "Decode an integer of specified type." (let* ((bit-size (cadr type)) @@ -839,6 +839,17 @@ (remove nil fixed-operands)) code)) +(defun decode-reg-cr (code operator opcode operand-size address-size rex operand-ordering) + (declare (ignore opcode operand-size address-size)) + (let ((modrm (pop-code code))) + (values (list* operator + (order-operands operand-ordering + :reg (nth (ldb (byte 3 0) modrm) + (register-set-by-mode (if rex :64-bit :32-bit))) + :cr (nth (ldb (byte 3 3) modrm) + '(:cr0 :cr1 :cr2 :cr3 :cr4 :cr5 :cr6 :cr7)))) + code))) + (defun decode-reg-modrm (code operator opcode operand-size address-size rex operand-ordering &optional (reg-mode operand-size)) (declare (ignore opcode rex)) (values (list* operator @@ -877,6 +888,15 @@ :imm (code-call (decode-integer code imm-type)))) code)) +(defun decode-far-pointer (code operator opcode operand-size address-size rex type) + (declare (ignore opcode operand-size address-size rex)) + (let ((offset (code-call (decode-integer code type))) + (segment (code-call (decode-integer code '(uint 16))))) + (values (list operator + segment + offset) + code))) + (defun decode-pc-rel (code operator opcode operand-size address-size rex type) (declare (ignore opcode operand-size address-size rex)) (values (list operator @@ -1140,7 +1160,15 @@ extras))))) (defmacro reg-cr (op-reg op-cr opcode &rest extras) - `(return-when (encode-reg-cr operator legacy-prefixes ,op-reg ,op-cr ,opcode operator-mode default-rex , at extras))) + `(progn + (assembler + (return-when (encode-reg-cr operator legacy-prefixes ,op-reg ,op-cr ,opcode operator-mode default-rex , at extras))) + (disassembler + (define-disassembler (operator ,opcode nil nil nil :32-bit) + decode-reg-cr + (operand-ordering operand-formals + :reg ',op-reg + :cr ',op-cr))))) (defmacro sreg-modrm (op-sreg op-modrm opcode &rest extras) `(progn @@ -1283,16 +1311,22 @@ ',type))))) (defmacro far-pointer (opcode segment offset offset-type &rest extra) - `(when (and (immediate-p ,segment) - (indirect-operand-p ,offset)); FIXME: should be immediate-p, change in bootblock.lisp. - (let ((segment (resolve-operand ,segment)) - (offset (resolve-operand (car ,offset)))) - (when (and (typep segment '(uint 16)) - (typep offset ',offset-type)) - (return-when (encode (encoded-values :opcode ,opcode - :immediate (append (encode-integer offset ',offset-type) - (encode-integer segment '(uint 16))) - , at extra))))))) + `(progn + (assembler + (when (and (immediate-p ,segment) + (indirect-operand-p ,offset)) ; FIXME: should be immediate-p, change in bootblock.lisp. + (let ((segment (resolve-operand ,segment)) + (offset (resolve-operand (car ,offset)))) + (when (and (typep segment '(uint 16)) + (typep offset ',offset-type)) + (return-when (encode (encoded-values :opcode ,opcode + :immediate (append (encode-integer offset ',offset-type) + (encode-integer segment '(uint 16))) + , at extra))))))) + (disassembler + (define-disassembler (operator ,opcode operator-mode) + decode-far-pointer + ',offset-type)))) ;;;;;;;;;;; Pseudo-instructions @@ -1843,10 +1877,10 @@ (moffset #xa0 src (uint 16) (dst :ax)) (opcode-reg-imm #xb8 dst src (xint 16)) (imm-modrm src dst #xc7 0 (xint 16)) - (reg-modrm dst src #x8b) - (reg-modrm src dst #x89) (sreg-modrm src dst #x8c) - (sreg-modrm dst src #x8e)) + (sreg-modrm dst src #x8e) + (reg-modrm dst src #x8b) + (reg-modrm src dst #x89)) (define-operator/32 :movl (src dst) (moffset #xa3 dst (uint 32) (src :eax)) @@ -1858,17 +1892,9 @@ ;;;;;;;;;;; MOVCR -(define-operator* (:32 :movcrl :64 :movcrr :dispatch :movcr) (src dst) - (when (eq src :cr8) - (reg-cr dst :cr0 #xf00f20 - :operand-size nil)) - (when (eq dst :cr8) - (reg-cr src :cr0 #xf00f22 - :operand-size nil)) - (reg-cr src dst #x0f22 - :operand-size nil) - (reg-cr dst src #x0f20 - :operand-size nil)) +(define-operator* (:32 :movcrl :dispatch :movcr) (src dst) + (reg-cr src dst #x0f22) + (reg-cr dst src #x0f20)) ;;;;;;;;;;; MOVS From ffjeld at common-lisp.net Thu Feb 28 20:30:09 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Thu, 28 Feb 2008 15:30:09 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080228203009.7B9385F05B@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv24114 Modified Files: asm-x86.lisp Log Message: Disassembler for OUT instruction. --- /project/movitz/cvsroot/movitz/asm-x86.lisp 2008/02/28 20:09:08 1.34 +++ /project/movitz/cvsroot/movitz/asm-x86.lisp 2008/02/28 20:30:09 1.35 @@ -6,7 +6,7 @@ ;;;; Author: Frode Vatvedt Fjeld ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: asm-x86.lisp,v 1.34 2008/02/28 20:09:08 ffjeld Exp $ +;;;; $Id: asm-x86.lisp,v 1.35 2008/02/28 20:30:09 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -894,7 +894,7 @@ (segment (code-call (decode-integer code '(uint 16))))) (values (list operator segment - offset) + (list offset)) code))) (defun decode-pc-rel (code operator opcode operand-size address-size rex type) @@ -1216,11 +1216,13 @@ -(defmacro opcode (opcode &optional fixed-operand &rest extras) +(defmacro opcode (opcode &optional fixed-operand fixed-operand2 &rest extras) `(progn (assembler (when (and ,@(when fixed-operand - `((eql , at fixed-operand)))) + `((eql , at fixed-operand))) + ,@(when fixed-operand2 + `((eql , at fixed-operand2)))) (return-values-when (encoded-values :opcode ,opcode , at extras @@ -1228,7 +1230,8 @@ (disassembler (define-disassembler (operator ,opcode) decode-no-operands - ,(second fixed-operand))))) + ,(second fixed-operand) + ,(second fixed-operand2))))) (defmacro opcode* (opcode &rest extras) `(return-values-when @@ -1726,7 +1729,8 @@ ;;;;;;;;;;; IRET (define-operator* (:16 :iret :32 :iretd :64 :iretq) () - (opcode #xcf () :rex default-rex)) + (opcode #xcf () () + :rex default-rex)) ;;;;;;;;;;; Jcc @@ -1964,28 +1968,16 @@ ;;;;;;;;;;; OUT (define-operator/8 :outb (src port) - (when (eq :al src) - (typecase port - ((eql :dx) - (opcode #xee)) - ((uint 8) - (imm port #xe6 (uint 8) (src :al)))))) + (opcode #xee (src :al) (port :dx)) + (imm port #xe6 (uint 8) (src :al))) (define-operator/16 :outw (src port) - (when (eq :ax src) - (typecase port - ((eql :dx) - (opcode #xef)) - ((uint 8) - (imm port #xe7 (uint 8) (src :ax)))))) + (opcode #xef (src :ax) (port :dx)) + (imm port #xe7 (uint 8) (src :ax))) (define-operator/32 :outl (src port) - (when (eq :eax src) - (typecase port - ((eql :dx) - (opcode #xef)) - ((uint 8) - (imm port #xe7 (uint 8) (src :eax)))))) + (opcode #xef (src :eax) (port :dx)) + (imm port #xe7 (uint 8) (src :eax))) ;;;;;;;;;;; POP From ffjeld at common-lisp.net Thu Feb 28 20:33:06 2008 From: ffjeld at common-lisp.net (ffjeld) Date: Thu, 28 Feb 2008 15:33:06 -0500 (EST) Subject: [movitz-cvs] CVS movitz Message-ID: <20080228203306.D08A76828F@common-lisp.net> Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv24475 Modified Files: asm-x86.lisp Log Message: Disassembler for IN instruction. --- /project/movitz/cvsroot/movitz/asm-x86.lisp 2008/02/28 20:30:09 1.35 +++ /project/movitz/cvsroot/movitz/asm-x86.lisp 2008/02/28 20:33:06 1.36 @@ -6,7 +6,7 @@ ;;;; Author: Frode Vatvedt Fjeld ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: asm-x86.lisp,v 1.35 2008/02/28 20:30:09 ffjeld Exp $ +;;;; $Id: asm-x86.lisp,v 1.36 2008/02/28 20:33:06 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------ @@ -1674,28 +1674,16 @@ ;;;;;;;;;;; IN (define-operator/8 :inb (port dst) - (when (eq :al dst) - (typecase port - ((eql :dx) - (opcode #xec)) - ((uint 8) - (imm port #xe4 (uint 8) (dst :al)))))) + (opcode #xec (port :dx) (dst :al)) + (imm port #xe4 (uint 8) (dst :al))) (define-operator/16 :inw (port dst) - (when (eq :ax dst) - (typecase port - ((eql :dx) - (opcode #xed)) - ((uint 8) - (imm port #xe5 (uint 8) (dst :ax)))))) + (opcode #xed (port :dx) (dst :ax)) + (imm port #xe5 (uint 8) (dst :ax))) (define-operator/32 :inl (port dst) - (when (eq :eax dst) - (typecase port - ((eql :dx) - (opcode #xed)) - ((uint 8) - (imm port #xe5 (uint 8) (dst :eax)))))) + (opcode #xed (port :dx) (dst :eax)) + (imm port #xe5 (uint 8) (dst :eax))) ;;;;;;;;;;; INC