Selecting the operand size for general-purpose instructions
(select-operand-size proc-mode byte-operand? rex-byte imm? prefixes default64? ignore-rex? ignore-p3-64? x86) → size
This function was written by referring to the following:
The first image above has been captured from Volume 1: Basic Architecture, Intel(R) 64 and IA-32 Architectures Software Developer's Manual, Order Number: 253665-062US, March 2017.
The second image above has been captured from Volume 1: Basic Architecture, Intel(R) 64 and IA-32 Architectures Software Developer's Manual, Combined Volumes: 1, 2A, 2B, 2C, 3A, 3B and 3C, Order Number: 325462-054US, April 2015.This function also includes three additional boolean parameters that serve to accommodate instructions that do not quite follow the general rules specified by the table above:
Function:
(defun select-operand-size$inline (proc-mode byte-operand? rex-byte imm? prefixes default64? ignore-rex? ignore-p3-64? x86) (declare (xargs :stobjs (x86))) (declare (type (integer 0 4) proc-mode) (type (or t nil) byte-operand?) (type (unsigned-byte 8) rex-byte) (type (or t nil) imm?) (type (unsigned-byte 52) prefixes) (type (or t nil) default64?) (type (or t nil) ignore-rex?) (type (or t nil) ignore-p3-64?)) (declare (xargs :guard (x86p x86))) (declare (xargs :guard (prefixes-p prefixes))) (if byte-operand? 1 (if (equal proc-mode 0) (if (and (logbitp 3 rex-byte) (not ignore-rex?)) (if imm? 4 8) (if (and (eql 102 (the (unsigned-byte 8) (prefixes->opr prefixes))) (not ignore-p3-64?)) 2 (if default64? 8 4))) (b* (((the (unsigned-byte 16) cs-attr) (seg-hidden-attri 1 x86)) (cs.d (code-segment-descriptor-attributesbits->d cs-attr)) (p3? (eql 102 (the (unsigned-byte 8) (prefixes->opr prefixes))))) (if (= cs.d 1) (if p3? 2 4) (if p3? 4 2))))))
Theorem:
(defthm natp-of-select-operand-size (b* ((size (select-operand-size$inline proc-mode byte-operand? rex-byte imm? prefixes default64? ignore-rex? ignore-p3-64? x86))) (natp size)) :rule-classes :type-prescription)
Theorem:
(defthm select-operand-size-range (and (<= 1 (select-operand-size proc-mode byte-operand? rex-byte imm? prefixes default64? ignore-rex? ignore-p3-64? x86)) (<= (select-operand-size proc-mode byte-operand? rex-byte imm? prefixes default64? ignore-rex? ignore-p3-64? x86) 8)) :rule-classes :linear)
Theorem:
(defthm select-operand-size-values (or (equal (select-operand-size proc-mode byte-operand? rex-byte imm? prefixes default64? ignore-rex? ignore-p3-64? x86) 1) (equal (select-operand-size proc-mode byte-operand? rex-byte imm? prefixes default64? ignore-rex? ignore-p3-64? x86) 2) (equal (select-operand-size proc-mode byte-operand? rex-byte imm? prefixes default64? ignore-rex? ignore-p3-64? x86) 4) (equal (select-operand-size proc-mode byte-operand? rex-byte imm? prefixes default64? ignore-rex? ignore-p3-64? x86) 8)))