Writing to byte general-purpose registers
(wr08 reg rex byte x86) → x86
Note Intel Vol. 1 Sec. 3.4.1.1 p. 3-17, which says the following about 64-bit mode:
8-bit and 16-bit operands generate an 8-bit or 16-bit result. The upper 56 or 48 bits (respectively) of the destination general-purpose register are not modified by the operation.
This is also confirmed by AMD manual, Jun'15, Vol. 3, App. B.1, under ‘No Extension of 8-Bit and 16-Bit Results’.
In 32-bit mode, the upper 32 bits are undefined, as specified by the following quote from the same page as above:
Because the upper 32 bits of 64-bit general-purpose registers are undefined in 32-bit modes, the upper 32 bits of any general-purpose register are not preserved when switching from 64-bit mode to a 32-bit mode (to protected mode or compatibility mode). Software must not depend on these bits to maintain a value after a 64-bit to 32-bit mode switch.
In 32-bit mode, this function is called with 0 as REX. Since in 32-bit mode the high 32 bits of general-purpose registers are not accessible, it is fine for this function to leave those bits unchanged, as opposed to, for example, setting them to undefined values as done by the semantic functions of certain instructions for certain flags. The switching from 32-bit mode to 64-bit mode (when modeled) will set the high 32 bits of general-purpose registers to undefined values.
Function:
(defun wr08$inline (reg rex byte x86) (declare (xargs :stobjs (x86))) (declare (type (unsigned-byte 4) reg) (type (unsigned-byte 8) rex) (type (unsigned-byte 8) byte)) (declare (xargs :guard (reg-indexp reg rex))) (b* ((reg (mbe :logic (nfix reg) :exec reg))) (cond ((or (not (eql rex 0)) (< reg 4)) (let ((qword (the (signed-byte 64) (rgfi reg x86)))) (!rgfi reg (n64-to-i64 (mbe :logic (part-install byte (part-select qword :low 0 :width 64) :low 0 :width 8) :exec (the (unsigned-byte 64) (logior (the (unsigned-byte 64) (logand 18446744073709551360 qword)) byte)))) x86))) (t (let* ((index (the (unsigned-byte 4) (- (the (unsigned-byte 4) reg) 4))) (qword (the (signed-byte 64) (rgfi index x86)))) (!rgfi index (n64-to-i64 (mbe :logic (part-install byte (part-select qword :low 0 :width 64) :low 8 :width 8) :exec (the (unsigned-byte 64) (logior (the (unsigned-byte 64) (logand 18446744073709486335 qword)) (the (unsigned-byte 16) (ash byte 8)))))) x86))))))
Theorem:
(defthm x86p-wr08 (implies (x86p x86) (x86p (wr08 reg rex byte x86))))