1.0.4.44: More x86 disassembler work
authorlisphacker <lisphacker>
Sun, 8 Apr 2007 05:23:48 +0000 (05:23 +0000)
committerlisphacker <lisphacker>
Sun, 8 Apr 2007 05:23:48 +0000 (05:23 +0000)
  * Added a prefix instruction for operand-size-prefix, making MOV
    [EDX], AX (for example) disassemble correctly.

  * Hacked up map-segment-instructions to work for prefix instructions
    again.

src/compiler/target-disassem.lisp
src/compiler/x86/insts.lisp
version.lisp-expr

index 3339a73..b34a6a1 100644 (file)
            (type (or null stream) stream))
 
   (let ((ispace (get-inst-space))
-        (prefix-p nil)) ; just processed a prefix inst
+        (prefix-p nil) ; just processed a prefix inst
+        (prefix-len 0)) ; length of any prefix instruction(s)
 
     (rewind-current-segment dstate segment)
 
                             (when prefilter
                               (funcall prefilter chunk dstate))
 
+                            (setf prefix-p (null (inst-printer inst)))
+
                             ;; print any instruction bytes recognized by the prefilter which calls read-suffix
                             ;; and updates next-offs
                             (when stream
                               (let ((suffix-len (- (dstate-next-offs dstate) orig-next)))
                                 (when (plusp suffix-len)
                                   (print-inst suffix-len stream dstate :offset (inst-length inst) :trailing-space nil))
-                              (dotimes (i (- *disassem-inst-column-width* (* 2 (+ (inst-length inst) suffix-len))))
-                                (write-char #\space stream)))
-                              (write-char #\space stream))
+                                (unless prefix-p
+                                  (dotimes (i (- *disassem-inst-column-width* (* 2 (+ (inst-length inst) suffix-len prefix-len))))
+                                    (write-char #\space stream))
+                                  (write-char #\space stream))
 
-                            (funcall function chunk inst)
+                                (setf prefix-len (+ (inst-length inst) suffix-len))))
 
-                            (setf prefix-p (null (inst-printer inst)))
+                            (funcall function chunk inst)
 
                             (when control
                               (funcall control chunk inst stream dstate))
 
       (unless (null stream)
         (unless prefix-p
+          (setf prefix-len 0)
           (print-notes-and-newline stream dstate))
         (setf (dstate-output-state dstate) nil)))))
 \f
index 132224e..ce271e6 100644 (file)
      (emit-word segment value))
     (:dword
      (emit-dword segment value))))
+
+(defun toggle-word-width (chunk inst stream dstate)
+  (declare (ignore chunk inst stream))
+  (let ((word-width (or (sb!disassem:dstate-get-prop dstate 'word-width)
+                        +default-operand-size+)))
+    (setf (sb!disassem:dstate-get-prop dstate 'word-width)
+          (ecase word-width
+            (:word :dword)
+            (:dword :word)))))
+
+;;; This is a "prefix" instruction, which means that it modifies the
+;;; following instruction in some way without having an actual
+;;; mnemonic of its own.
+(define-instruction operand-size-prefix (segment)
+  (:printer byte ((op +operand-size-prefix-byte+))
+            nil                         ; don't actually print it
+            :control #'toggle-word-width))
 \f
 ;;;; general data transfer
 
index b1cdf70..5dec045 100644 (file)
@@ -17,4 +17,4 @@
 ;;; checkins which aren't released. (And occasionally for internal
 ;;; versions, especially for internal versions off the main CVS
 ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)
-"1.0.4.43"
+"1.0.4.44"