Picking a mandatory prefix
When should we interpret a SIMD prefix (
Here are some decoding rules for SIMD mandatory prefixes; note that these
do NOT apply for VEX/EVEX-encoded instructions because the mandatory prefixes
are explicitly stated there. All the examples listed below are from Intel's
XED (x86 Encoder Decoder:
For opcodes that can take mandatory prefixes,
Examples:
(1) xed -64 -d 660f6f00 ;; movdqa xmm0, xmmword ptr [rax] (2) xed -64 -d f30f6f00 ;; movdqu xmm0, xmmword ptr [rax] (3) xed -64 -d 66f30f6f00 ;; movdqu xmm0, xmmword ptr [rax] (same as (2)) (4) xed -64 -d f3660f6f00 ;; movdqu xmm0, xmmword ptr [rax] (same as (2))
For opcodes that can take mandatory prefixes, the presence of an unsupported SIMD prefix translates to a reserved instruction; such a prefix does NOT act as a modifier prefix.
Examples: Opcode
(1) xed -64 -d 0f6b00 ;; packssdw mmx0, qword ptr [rax] (2) xed -64 -d 660f6b00 ;; packssdw xmm0, xmmword ptr [rax] (3) xed -64 -d f3660f6b00 ;; GENERAL_ERROR Could not decode...
Function:
(defun 64-bit-compute-mandatory-prefix-for-two-byte-opcode$inline (opcode prefixes) (declare (type (unsigned-byte 8) opcode) (type (unsigned-byte 52) prefixes)) (declare (xargs :guard (prefixes-p prefixes))) (let ((__function__ '64-bit-compute-mandatory-prefix-for-two-byte-opcode)) (declare (ignorable __function__)) (let ((rep-pfx (the (unsigned-byte 8) (prefixes->rep prefixes)))) (if (not (eql rep-pfx 0)) (if (or (and (equal rep-pfx 243) (aref1 '64-bit-mode-two-byte-f3-ok *64-bit-mode-two-byte-f3-ok-ar* opcode)) (and (equal rep-pfx 242) (aref1 '64-bit-mode-two-byte-f2-ok *64-bit-mode-two-byte-f2-ok-ar* opcode))) rep-pfx 0) (let ((opr-pfx (the (unsigned-byte 8) (prefixes->opr prefixes)))) (if (not (eql opr-pfx 0)) (if (aref1 '64-bit-mode-two-byte-66-ok *64-bit-mode-two-byte-66-ok-ar* opcode) opr-pfx 0) 0))))))
Theorem:
(defthm return-type-of-64-bit-compute-mandatory-prefix-for-two-byte-opcode (b* ((mandatory-prefix (64-bit-compute-mandatory-prefix-for-two-byte-opcode$inline opcode prefixes))) (unsigned-byte-p 8 mandatory-prefix)) :rule-classes :rewrite)
Function:
(defun 32-bit-compute-mandatory-prefix-for-two-byte-opcode$inline (opcode prefixes) (declare (type (unsigned-byte 8) opcode) (type (unsigned-byte 52) prefixes)) (declare (xargs :guard (prefixes-p prefixes))) (let ((__function__ '32-bit-compute-mandatory-prefix-for-two-byte-opcode)) (declare (ignorable __function__)) (let ((rep-pfx (the (unsigned-byte 8) (prefixes->rep prefixes)))) (if (not (eql rep-pfx 0)) (if (or (and (equal rep-pfx 243) (aref1 '32-bit-mode-two-byte-f3-ok *32-bit-mode-two-byte-f3-ok-ar* opcode)) (and (equal rep-pfx 242) (aref1 '32-bit-mode-two-byte-f2-ok *32-bit-mode-two-byte-f2-ok-ar* opcode))) rep-pfx 0) (let ((opr-pfx (the (unsigned-byte 8) (prefixes->opr prefixes)))) (if (not (eql opr-pfx 0)) (if (aref1 '32-bit-mode-two-byte-66-ok *32-bit-mode-two-byte-66-ok-ar* opcode) opr-pfx 0) 0))))))
Theorem:
(defthm return-type-of-32-bit-compute-mandatory-prefix-for-two-byte-opcode (b* ((mandatory-prefix (32-bit-compute-mandatory-prefix-for-two-byte-opcode$inline opcode prefixes))) (unsigned-byte-p 8 mandatory-prefix)) :rule-classes :rewrite)
Function:
(defun 64-bit-compute-mandatory-prefix-for-0f-38-three-byte-opcode$inline (opcode prefixes) (declare (type (unsigned-byte 8) opcode) (type (unsigned-byte 52) prefixes)) (declare (xargs :guard (prefixes-p prefixes))) (let ((__function__ '64-bit-compute-mandatory-prefix-for-0f-38-three-byte-opcode)) (declare (ignorable __function__)) (let ((rep-pfx (the (unsigned-byte 8) (prefixes->rep prefixes)))) (if (not (eql rep-pfx 0)) (if (or (and (equal rep-pfx 243) (aref1 '64-bit-mode-0f-38-three-byte-f3-ok *64-bit-mode-0f-38-three-byte-f3-ok-ar* opcode)) (and (equal rep-pfx 242) (aref1 '64-bit-mode-0f-38-three-byte-f2-ok *64-bit-mode-0f-38-three-byte-f2-ok-ar* opcode))) rep-pfx 0) (let ((opr-pfx (the (unsigned-byte 8) (prefixes->opr prefixes)))) (if (not (eql opr-pfx 0)) (if (aref1 '64-bit-mode-0f-38-three-byte-66-ok *64-bit-mode-0f-38-three-byte-66-ok-ar* opcode) opr-pfx 0) 0))))))
Theorem:
(defthm return-type-of-64-bit-compute-mandatory-prefix-for-0f-38-three-byte-opcode (b* ((mandatory-prefix (64-bit-compute-mandatory-prefix-for-0f-38-three-byte-opcode$inline opcode prefixes))) (unsigned-byte-p 8 mandatory-prefix)) :rule-classes :rewrite)
Function:
(defun 32-bit-compute-mandatory-prefix-for-0f-38-three-byte-opcode$inline (opcode prefixes) (declare (type (unsigned-byte 8) opcode) (type (unsigned-byte 52) prefixes)) (declare (xargs :guard (prefixes-p prefixes))) (let ((__function__ '32-bit-compute-mandatory-prefix-for-0f-38-three-byte-opcode)) (declare (ignorable __function__)) (let ((rep-pfx (the (unsigned-byte 8) (prefixes->rep prefixes)))) (if (not (eql rep-pfx 0)) (if (or (and (equal rep-pfx 243) (aref1 '32-bit-mode-0f-38-three-byte-f3-ok *32-bit-mode-0f-38-three-byte-f3-ok-ar* opcode)) (and (equal rep-pfx 242) (aref1 '32-bit-mode-0f-38-three-byte-f2-ok *32-bit-mode-0f-38-three-byte-f2-ok-ar* opcode))) rep-pfx 0) (let ((opr-pfx (the (unsigned-byte 8) (prefixes->opr prefixes)))) (if (not (eql opr-pfx 0)) (if (aref1 '32-bit-mode-0f-38-three-byte-66-ok *32-bit-mode-0f-38-three-byte-66-ok-ar* opcode) opr-pfx 0) 0))))))
Theorem:
(defthm return-type-of-32-bit-compute-mandatory-prefix-for-0f-38-three-byte-opcode (b* ((mandatory-prefix (32-bit-compute-mandatory-prefix-for-0f-38-three-byte-opcode$inline opcode prefixes))) (unsigned-byte-p 8 mandatory-prefix)) :rule-classes :rewrite)
Function:
(defun 64-bit-compute-mandatory-prefix-for-0f-3a-three-byte-opcode$inline (opcode prefixes) (declare (type (unsigned-byte 8) opcode) (type (unsigned-byte 52) prefixes)) (declare (xargs :guard (prefixes-p prefixes))) (let ((__function__ '64-bit-compute-mandatory-prefix-for-0f-3a-three-byte-opcode)) (declare (ignorable __function__)) (let ((rep-pfx (the (unsigned-byte 8) (prefixes->rep prefixes)))) (if (not (eql rep-pfx 0)) (if (or (and (equal rep-pfx 243) (aref1 '64-bit-mode-0f-3a-three-byte-f3-ok *64-bit-mode-0f-3a-three-byte-f3-ok-ar* opcode)) (and (equal rep-pfx 242) (aref1 '64-bit-mode-0f-3a-three-byte-f2-ok *64-bit-mode-0f-3a-three-byte-f2-ok-ar* opcode))) rep-pfx 0) (let ((opr-pfx (the (unsigned-byte 8) (prefixes->opr prefixes)))) (if (not (eql opr-pfx 0)) (if (aref1 '64-bit-mode-0f-3a-three-byte-66-ok *64-bit-mode-0f-3a-three-byte-66-ok-ar* opcode) opr-pfx 0) 0))))))
Theorem:
(defthm return-type-of-64-bit-compute-mandatory-prefix-for-0f-3a-three-byte-opcode (b* ((mandatory-prefix (64-bit-compute-mandatory-prefix-for-0f-3a-three-byte-opcode$inline opcode prefixes))) (unsigned-byte-p 8 mandatory-prefix)) :rule-classes :rewrite)
Function:
(defun 32-bit-compute-mandatory-prefix-for-0f-3a-three-byte-opcode$inline (opcode prefixes) (declare (type (unsigned-byte 8) opcode) (type (unsigned-byte 52) prefixes)) (declare (xargs :guard (prefixes-p prefixes))) (let ((__function__ '32-bit-compute-mandatory-prefix-for-0f-3a-three-byte-opcode)) (declare (ignorable __function__)) (let ((rep-pfx (the (unsigned-byte 8) (prefixes->rep prefixes)))) (if (not (eql rep-pfx 0)) (if (or (and (equal rep-pfx 243) (aref1 '32-bit-mode-0f-3a-three-byte-f3-ok *32-bit-mode-0f-3a-three-byte-f3-ok-ar* opcode)) (and (equal rep-pfx 242) (aref1 '32-bit-mode-0f-3a-three-byte-f2-ok *32-bit-mode-0f-3a-three-byte-f2-ok-ar* opcode))) rep-pfx 0) (let ((opr-pfx (the (unsigned-byte 8) (prefixes->opr prefixes)))) (if (not (eql opr-pfx 0)) (if (aref1 '32-bit-mode-0f-3a-three-byte-66-ok *32-bit-mode-0f-3a-three-byte-66-ok-ar* opcode) opr-pfx 0) 0))))))
Theorem:
(defthm return-type-of-32-bit-compute-mandatory-prefix-for-0f-3a-three-byte-opcode (b* ((mandatory-prefix (32-bit-compute-mandatory-prefix-for-0f-3a-three-byte-opcode$inline opcode prefixes))) (unsigned-byte-p 8 mandatory-prefix)) :rule-classes :rewrite)
Function:
(defun compute-mandatory-prefix-for-two-byte-opcode$inline (proc-mode opcode prefixes) (declare (type (integer 0 4) proc-mode) (type (unsigned-byte 8) opcode) (type (unsigned-byte 52) prefixes)) (case proc-mode (0 (64-bit-compute-mandatory-prefix-for-two-byte-opcode opcode prefixes)) (otherwise (32-bit-compute-mandatory-prefix-for-two-byte-opcode opcode prefixes))))
Theorem:
(defthm return-type-of-compute-mandatory-prefix-for-two-byte-opcode (b* ((mandatory-prefix (compute-mandatory-prefix-for-two-byte-opcode$inline proc-mode opcode prefixes))) (unsigned-byte-p 8 mandatory-prefix)) :rule-classes :rewrite)
Function:
(defun compute-mandatory-prefix-for-0f-38-three-byte-opcode$inline (proc-mode opcode prefixes) (declare (type (integer 0 4) proc-mode) (type (unsigned-byte 8) opcode) (type (unsigned-byte 52) prefixes)) (case proc-mode (0 (64-bit-compute-mandatory-prefix-for-0f-38-three-byte-opcode opcode prefixes)) (otherwise (32-bit-compute-mandatory-prefix-for-0f-38-three-byte-opcode opcode prefixes))))
Theorem:
(defthm return-type-of-compute-mandatory-prefix-for-0f-38-three-byte-opcode (b* ((mandatory-prefix (compute-mandatory-prefix-for-0f-38-three-byte-opcode$inline proc-mode opcode prefixes))) (unsigned-byte-p 8 mandatory-prefix)) :rule-classes :rewrite)
Function:
(defun compute-mandatory-prefix-for-0f-3a-three-byte-opcode$inline (proc-mode opcode prefixes) (declare (type (integer 0 4) proc-mode) (type (unsigned-byte 8) opcode) (type (unsigned-byte 52) prefixes)) (case proc-mode (0 (64-bit-compute-mandatory-prefix-for-0f-3a-three-byte-opcode opcode prefixes)) (otherwise (32-bit-compute-mandatory-prefix-for-0f-3a-three-byte-opcode opcode prefixes))))
Theorem:
(defthm return-type-of-compute-mandatory-prefix-for-0f-3a-three-byte-opcode (b* ((mandatory-prefix (compute-mandatory-prefix-for-0f-3a-three-byte-opcode$inline proc-mode opcode prefixes))) (unsigned-byte-p 8 mandatory-prefix)) :rule-classes :rewrite)
Function:
(defun compute-mandatory-prefix-for-three-byte-opcode$inline (proc-mode second-escape-byte opcode prefixes) (declare (type (integer 0 4) proc-mode) (type (unsigned-byte 8) second-escape-byte) (type (unsigned-byte 8) opcode) (type (unsigned-byte 52) prefixes)) (declare (xargs :guard (or (equal second-escape-byte 56) (equal second-escape-byte 58)))) (case second-escape-byte (56 (compute-mandatory-prefix-for-0f-38-three-byte-opcode proc-mode opcode prefixes)) (58 (compute-mandatory-prefix-for-0f-3a-three-byte-opcode proc-mode opcode prefixes)) (otherwise 0)))
Theorem:
(defthm return-type-of-compute-mandatory-prefix-for-three-byte-opcode (b* ((mandatory-prefix (compute-mandatory-prefix-for-three-byte-opcode$inline proc-mode second-escape-byte opcode prefixes))) (unsigned-byte-p 8 mandatory-prefix)) :rule-classes :rewrite)