Corrections to disassembly of SHLD, SHRD and LEA on x86[-64].
authorLutz Euler <lutz.euler@freenet.de>
Wed, 14 Dec 2011 17:11:53 +0000 (18:11 +0100)
committerLutz Euler <lutz.euler@freenet.de>
Wed, 14 Dec 2011 17:11:53 +0000 (18:11 +0100)
The double shifts were wrongly matching the bit pattern of some CMOV
variants. Corrected by using another instruction format on x86-64 and
by adding a constraint on the WIDTH field on x86. This made it possible
to enable the variant with an immediate shift count. On x86-64, changed
the maximum immediate shift count from 31 to 63.

Also, on x86-64, one of the printers for LEA was missing a WIDTH field
restriction, thus wrongly matching a "MOV to segment register", too.

src/compiler/x86-64/insts.lisp
src/compiler/x86/insts.lisp

index 5fc70d6..09b7834 100644 (file)
   (op      :field (byte 8 8))
   (reg/mem :fields (list (byte 2 22) (byte 3 16))
                                 :type 'reg/mem)
-  (reg     :field (byte 3 19)   :type 'reg))
+  (reg     :field (byte 3 19)   :type 'reg)
+  ;; optional fields
+  (imm))
 
 (sb!disassem:define-instruction-format (rex-ext-reg-reg/mem-no-width 32
                                         :default-printer
               (error "bogus args to XCHG: ~S ~S" operand1 operand2)))))))
 
 (define-instruction lea (segment dst src)
-  (:printer rex-reg-reg/mem ((op #b1000110)))
+  (:printer rex-reg-reg/mem ((op #b1000110) (width 1)))
   (:printer reg-reg/mem ((op #b1000110) (width 1)))
   (:emitter
    (aver (or (dword-reg-p dst) (qword-reg-p dst)))
 
 (eval-when (:compile-toplevel :execute)
   (defun double-shift-inst-printer-list (op)
-    `(#+nil
-      (ext-reg-reg/mem-imm ((op ,(logior op #b100))
-                            (imm nil :type signed-imm-byte)))
-      (ext-reg-reg/mem ((op ,(logior op #b101)))
+    `((ext-reg-reg/mem-no-width ((op ,(logior op #b100))
+                                 (imm nil :type imm-byte)))
+      (ext-reg-reg/mem-no-width ((op ,(logior op #b101)))
          (:name :tab reg/mem ", " reg ", " 'cl)))))
 
 (define-instruction shld (segment dst src amt)
-  (:declare (type (or (member :cl) (mod 32)) amt))
+  (:declare (type (or (member :cl) (mod 64)) amt))
   (:printer-list (double-shift-inst-printer-list #b10100000))
   (:emitter
    (emit-double-shift segment #b0 dst src amt)))
 
 (define-instruction shrd (segment dst src amt)
-  (:declare (type (or (member :cl) (mod 32)) amt))
+  (:declare (type (or (member :cl) (mod 64)) amt))
   (:printer-list (double-shift-inst-printer-list #b10101000))
   (:emitter
    (emit-double-shift segment #b1 dst src amt)))
index 720ad62..5b56e0f 100644 (file)
 
 (eval-when (:compile-toplevel :execute)
   (defun double-shift-inst-printer-list (op)
-    `(#+nil
-      (ext-reg-reg/mem-imm ((op ,(logior op #b10))
-                            (imm nil :type signed-imm-byte)))
-      (ext-reg-reg/mem ((op ,(logior op #b10)))
+    `((ext-reg-reg/mem ((op ,(logior op #b10)) (width 0)
+                        (imm nil :type signed-imm-byte)))
+      (ext-reg-reg/mem ((op ,(logior op #b10)) (width 1))
          (:name :tab reg/mem ", " reg ", " 'cl))
-      (x66-ext-reg-reg/mem ((op ,(logior op #b10)))
+      (x66-ext-reg-reg/mem ((op ,(logior op #b10)) (width 1))
          (:name :tab reg/mem ", " reg ", " 'cl)))))
 
 (define-instruction shld (segment dst src amt)