From b83ac6ca16d5c9ee7aa6f261959035accf697681 Mon Sep 17 00:00:00 2001 From: Lutz Euler Date: Wed, 14 Dec 2011 18:11:53 +0100 Subject: [PATCH] Corrections to disassembly of SHLD, SHRD and LEA on x86[-64]. 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 | 17 +++++++++-------- src/compiler/x86/insts.lisp | 9 ++++----- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/compiler/x86-64/insts.lisp b/src/compiler/x86-64/insts.lisp index 5fc70d6..09b7834 100644 --- a/src/compiler/x86-64/insts.lisp +++ b/src/compiler/x86-64/insts.lisp @@ -883,7 +883,9 @@ (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 @@ -1989,7 +1991,7 @@ (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))) @@ -2428,20 +2430,19 @@ (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))) diff --git a/src/compiler/x86/insts.lisp b/src/compiler/x86/insts.lisp index 720ad62..5b56e0f 100644 --- a/src/compiler/x86/insts.lisp +++ b/src/compiler/x86/insts.lisp @@ -1742,12 +1742,11 @@ (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) -- 1.7.10.4