More complete disassembly for XADD and CMPXCHG on x86-64
authorPaul Khuong <pvk@pvk.ca>
Mon, 29 Aug 2011 05:12:55 +0000 (01:12 -0400)
committerPaul Khuong <pvk@pvk.ca>
Mon, 29 Aug 2011 05:12:55 +0000 (01:12 -0400)
 The new patterns correctly handle REX bytes and operand size override
 bytes (#x66).

src/compiler/x86-64/insts.lisp

index 83f1e8d..5fc70d6 100644 (file)
   ;; optional fields
   (imm))
 
+(sb!disassem:define-instruction-format (x66-ext-reg-reg/mem 32
+                                        :default-printer
+                                        `(:name :tab reg ", " reg/mem))
+  (x66     :field (byte 8 0)    :type 'x66 :value #x66)
+  (prefix  :field (byte 8 8)    :value #b00001111)
+  (op      :field (byte 7 17))
+  (width   :field (byte 1 16)   :type 'width)
+  (reg/mem :fields (list (byte 2 30) (byte 3 24))
+                                :type 'reg/mem)
+  (reg     :field (byte 3 27)   :type 'reg)
+  ;; optional fields
+  (imm))
+
+(sb!disassem:define-instruction-format (rex-ext-reg-reg/mem 32
+                                        :default-printer
+                                        `(:name :tab reg ", " reg/mem))
+  (rex     :field (byte 4 4)    :value #b0100)
+  (wrxb    :field (byte 4 0)    :type 'wrxb)
+  (prefix  :field (byte 8 8)    :value #b00001111)
+  (op      :field (byte 7 17))
+  (width   :field (byte 1 16)   :type 'width)
+  (reg/mem :fields (list (byte 2 30) (byte 3 24))
+                                :type 'reg/mem)
+  (reg     :field (byte 3 27)   :type 'reg)
+  ;; optional fields
+  (imm))
+
+(sb!disassem:define-instruction-format (x66-rex-ext-reg-reg/mem 40
+                                        :default-printer
+                                        `(:name :tab reg ", " reg/mem))
+  (x66     :field (byte 8 0)    :type 'x66 :value #x66)
+  (rex     :field (byte 4 12)   :value #b0100)
+  (wrxb    :field (byte 4 8)    :type 'wrxb)
+  (prefix  :field (byte 8 16)   :value #b00001111)
+  (op      :field (byte 7 25))
+  (width   :field (byte 1 24)   :type 'width)
+  (reg/mem :fields (list (byte 2 38) (byte 3 32))
+                                :type 'reg/mem)
+  (reg     :field (byte 3 35)   :type 'reg)
+  ;; optional fields
+  (imm))
+
+(eval-when (:compile-toplevel :execute)
+  (defun ext-reg-reg/mem-printer-list (op &optional printer)
+    `((ext-reg-reg/mem         ((op ,op)) ,@(when printer (list printer)))
+      (x66-ext-reg-reg/mem     ((op ,op)) ,@(when printer (list printer)))
+      (rex-ext-reg-reg/mem     ((op ,op)) ,@(when printer (list printer)))
+      (x66-rex-ext-reg-reg/mem ((op ,op)) ,@(when printer (list printer))))))
+
 (sb!disassem:define-instruction-format (ext-reg-reg/mem-no-width 24
                                         :default-printer
                                         `(:name :tab reg ", " reg/mem))
 
 (define-instruction cmpxchg (segment dst src &optional prefix)
   ;; Register/Memory with Register.
-  (:printer ext-reg-reg/mem ((op #b1011000)) '(:name :tab reg/mem ", " reg))
+  (:printer-list (ext-reg-reg/mem-printer-list #b1011000
+                                               '(:name :tab reg/mem ", " reg)))
   (:emitter
    (aver (register-p src))
    (emit-prefix segment prefix)
 
 (define-instruction xadd (segment dst src &optional prefix)
   ;; Register/Memory with Register.
-  (:printer ext-reg-reg/mem ((op #b1100000)) '(:name :tab reg/mem ", " reg))
+  (:printer-list (ext-reg-reg/mem-printer-list #b1100000
+                                               '(:name :tab reg/mem ", " reg)))
   (:emitter
    (aver (register-p src))
    (emit-prefix segment prefix)
       (ext-reg-reg/mem-imm ((op ,(logior op #b100))
                             (imm nil :type signed-imm-byte)))
       (ext-reg-reg/mem ((op ,(logior op #b101)))
-         (:name :tab reg/mem ", " 'cl)))))
+         (:name :tab reg/mem ", " reg ", " 'cl)))))
 
 (define-instruction shld (segment dst src amt)
   (:declare (type (or (member :cl) (mod 32)) amt))