Functions to read/write 32/64/128 bits into the XMM registers (to be used by non-VEX encoded 128-bit SIMD instructions)
These functions are meant to be used by instructions that do not use a VEX or EVEX prefix --- these functions preserve the upper bits of ZMM registers. For instructions that use these prefixes and zero out these bits instead, see ZMMs-Reads-and-Writes.
Note that the index for accessing the XMM registers is 4-bits wide (as opposed to the 5-bit index for ZMM registers --- see ZMMs-Reads-and-Writes) because only 16 XMM registers were supported initially in the 64-bit mode (and 8 in the 32-bit mode).
Source: Intel Vol. 2, Section 2.3.10 --- AVX Instructions and Upper 128-bits of YMM registers:
If an instruction with a destination XMM register is encoded with a VEX prefix, the processor zeroes the upper bits (above bit 128) of the equivalent YMM register. Legacy SSE instructions without VEX preserve the upper bits.
Functions rx32, rx64, and rx128 will read the contents of the XMMs (i.e., low 128 bits of ZMMs) as natural numbers.
Similarly, functions wx32, wx64, and wx128 are used to write natural numbers into the XMMs (and preserve the upper bits of ZMMs).
Function:
(defun rx32$inline (reg x86) (declare (xargs :stobjs (x86))) (declare (type (unsigned-byte 4) reg)) (rz32 reg x86))
Function:
(defun rx64$inline (reg x86) (declare (xargs :stobjs (x86))) (declare (type (unsigned-byte 4) reg)) (rz64 reg x86))
Function:
(defun rx128$inline (reg x86) (declare (xargs :stobjs (x86))) (declare (type (unsigned-byte 4) reg)) (rz128 reg x86))
Function:
(defun wx32$inline (reg val x86) (declare (xargs :stobjs (x86))) (declare (type (unsigned-byte 4) reg) (type (unsigned-byte 32) val)) (wz32 reg val x86 :regtype 1))
Function:
(defun wx64$inline (reg val x86) (declare (xargs :stobjs (x86))) (declare (type (unsigned-byte 4) reg) (type (unsigned-byte 64) val)) (wz64 reg val x86 :regtype 1))
Function:
(defun wx128$inline (reg val x86) (declare (xargs :stobjs (x86))) (declare (type (unsigned-byte 4) reg) (type (unsigned-byte 128) val)) (wz128 reg val x86 :regtype 1))
Function:
(defun xmmi-size$inline (nbytes index x86) (declare (xargs :stobjs (x86))) (declare (type (unsigned-byte 5) nbytes) (type (unsigned-byte 4) index)) (declare (xargs :guard (member nbytes '(4 8 16)))) (case nbytes (4 (rx32 index x86)) (8 (rx64 index x86)) (16 (rx128 index x86)) (otherwise 0)))
Theorem:
(defthm natp-of-xmmi-size (b* ((val (xmmi-size$inline nbytes index x86))) (natp val)) :rule-classes :type-prescription)
Function:
(defun !xmmi-size$inline (nbytes index val x86) (declare (xargs :stobjs (x86))) (declare (type (unsigned-byte 5) nbytes) (type (unsigned-byte 4) index) (type integer val)) (declare (xargs :guard (and (member nbytes '(4 8 16)) (unsigned-byte-p (ash nbytes 3) val)))) (case nbytes (4 (wx32 index val x86)) (8 (wx64 index val x86)) (16 (wx128 index val x86)) (otherwise x86)))
Theorem:
(defthm x86p-of-!xmmi-size (implies (x86p x86) (b* ((x86 (!xmmi-size$inline nbytes index val x86))) (x86p x86))) :rule-classes :rewrite)