|
|
INSTRUCTION SET REFERENCE, M-U
RDPID-Read Processor ID
Opcode/
Op/
64/32-
CPUID
Description
Instruction
En
bit
Feature Flag
Mode
F3 0F C7 /7
R
N.E./V
RDPID
Read IA32_TSC_AUX into r32.
RDPID r32
F3 0F C7 /7
R
V/N.E.
RDPID
Read IA32_TSC_AUX into r64.
RDPID r64
Instruction Operand Encoding1
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
R
ModRM:r/m (w)
N/A
N/A
N/A
Description
Reads the value of the IA32_TSC_AUX MSR (address C0000103H) into the destination register. The value of CS.D
and operand-size prefixes (66H and REX.W) do not affect the behavior of the RDPID instruction.
Operation
DEST := IA32_TSC_AUX
Flags Affected
None.
Protected Mode Exceptions
#UD
If the LOCK prefix is used.
If CPUID.7H.0:ECX.RDPID[bit 22] = 0.
Real-Address Mode Exceptions
Same exceptions as in protected mode.
Virtual-8086 Mode Exceptions
Same exceptions as in protected mode.
Compatibility Mode Exceptions
Same exceptions as in protected mode.
64-Bit Mode Exceptions
Same exceptions as in protected mode.
1.ModRM.MOD = 011B required
RDPID-Read Processor ID
Vol. 2B
4-539
INSTRUCTION SET REFERENCE, M-U
RDPKRU-Read Protection Key Rights for User Pages
Opcode*
Instruction
Op/
64/32bit
CPUID
Description
En
Mode
Feature
Support
Flag
NP 0F 01 EE
RDPKRU
ZO
V/V
OSPKE
Reads PKRU into EAX.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
ZO
N/A
N/A
N/A
N/A
Description
Reads the value of PKRU into EAX and clears EDX. ECX must be 0 when RDPKRU is executed; otherwise, a general-
protection exception (#GP) occurs.
RDPKRU can be executed only if CR4.PKE = 1; otherwise, an invalid-opcode exception (#UD) occurs. Software can
discover the value of CR4.PKE by examining CPUID.(EAX=07H,ECX=0H):ECX.OSPKE [bit 4].
On processors that support the Intel 64 Architecture, the high-order 32-bits of RCX are ignored and the high-order
32-bits of RDX and RAX are cleared.
Operation
IF (ECX = 0)
THEN
EAX := PKRU;
EDX := 0;
ELSE #GP(0);
FI;
Flags Affected
None.
C/C++ Compiler Intrinsic Equivalent
RDPKRU uint32_t _rdpkru_u32(void);
Protected Mode Exceptions
#GP(0)
If ECX ≠ 0.
#UD
If the LOCK prefix is used.
If CR4.PKE = 0.
Real-Address Mode Exceptions
Same exceptions as in protected mode.
Virtual-8086 Mode Exceptions
Same exceptions as in protected mode.
Compatibility Mode Exceptions
Same exceptions as in protected mode.
4-540
Vol. 2B
RDPKRU-Read Protection Key Rights for User Pages
INSTRUCTION SET REFERENCE, M-U
64-Bit Mode Exceptions
Same exceptions as in protected mode.
RDPKRU-Read Protection Key Rights for User Pages
Vol. 2B
4-541
INSTRUCTION SET REFERENCE, M-U
RDPMC-Read Performance-Monitoring Counters
Opcode*
Instruction
Op/
64-Bit
Compat/
Description
En
Mode
Leg Mode
0F 33
RDPMC
ZO
Valid
Valid
Read performance-monitoring counter
specified by ECX into EDX:EAX.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
ZO
N/A
N/A
N/A
N/A
Description
Reads the contents of the performance monitoring counter (PMC) specified in ECX register into registers EDX:EAX.
(On processors that support the Intel 64 architecture, the high-order 32 bits of RCX are ignored.) The EDX register
is loaded with the high-order 32 bits of the PMC and the EAX register is loaded with the low-order 32 bits. (On
processors that support the Intel 64 architecture, the high-order 32 bits of each of RAX and RDX are cleared.) If
fewer than 64 bits are implemented in the PMC being read, unimplemented bits returned to EDX:EAX will have
value zero.
The width of PMCs on processors supporting architectural performance monitoring (CPUID.0AH:EAX[7:0] ≠ 0) are
reported by CPUID.0AH:EAX[23:16]. On processors that do not support architectural performance monitoring
(CPUID.0AH:EAX[7:0]=0), the width of general-purpose performance PMCs is 40 bits, while the widths of special-
purpose PMCs are implementation specific.
Use of ECX to specify a PMC depends on whether the processor supports architectural performance monitoring:
• If the processor does not support architectural performance monitoring (CPUID.0AH:EAX[7:0]=0), ECX[30:0]
specifies the index of the PMC to be read. Setting ECX[31] selects “fast” read mode if supported. In this mode,
RDPMC returns bits 31:0 of the PMC in EAX while clearing EDX to zero.
• If the processor does support architectural performance monitoring (CPUID.0AH:EAX[7:0] ≠ 0), ECX[31:16]
specifies type of PMC while ECX[15:0] specifies the index of the PMC to be read within that type. The following
PMC types are currently defined:
- General-purpose counters use type 0. The index x (to read IA32_PMCx) must be less than the value
enumerated by CPUID.0AH.EAX[15:8] (thus ECX[15:8] must be zero).
- Fixed-function counters use type 4000H. The index x (to read IA32_FIXED_CTRx) can be used if either
CPUID.0AH.EDX[4:0] > x or CPUID.0AH.ECX[x] = 1 (thus ECX[15:5] must be 0).
- Performance metrics use type 2000H. This type can be used only if IA32_PERF_CAPABILITIES.PERF_MET-
RICS_AVAILABLE[bit 15]=1. For this type, the index in ECX[15:0] is implementation specific.
Specifying an unsupported PMC encoding will cause a general protection exception #GP(0). For PMC details see
Chapter 20, “Performance Monitoring,” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual,
Volume 3B.
When in protected or virtual 8086 mode, the Performance-monitoring Counters Enabled (PCE) flag in register
CR4 restricts the use of the RDPMC instruction. When the PCE flag is set, the RDPMC instruction can be executed at
any privilege level; when the flag is clear, the instruction can only be executed at privilege level 0. (When in real-
address mode, the RDPMC instruction is always enabled.) The PMCs can also be read with the RDMSR instruction,
when executing at privilege level 0.
The RDPMC instruction is not a serializing instruction; that is, it does not imply that all the events caused by the
preceding instructions have been completed or that events caused by subsequent instructions have not begun. If
an exact event count is desired, software must insert a serializing instruction (such as the CPUID instruction)
before and/or after the RDPMC instruction.
Performing back-to-back fast reads are not guaranteed to be monotonic. To guarantee monotonicity on back-to-
back reads, a serializing instruction must be placed between the two RDPMC instructions.
The RDPMC instruction can execute in 16-bit addressing mode or virtual-8086 mode; however, the full contents of
the ECX register are used to select the PMC, and the event count is stored in the full EAX and EDX registers. The
4-542
Vol. 2B
RDPMC-Read Performance-Monitoring Counters
INSTRUCTION SET REFERENCE, M-U
RDPMC instruction was introduced into the IA-32 Architecture in the Pentium Pro processor and the Pentium
processor with MMX technology. The earlier Pentium processors have PMCs, but they must be read with the RDMSR
instruction.
Operation
MSCB = Most Significant Counter Bit (* Model-specific *)
IF (((CR4.PCE = 1) or (CPL = 0) or (CR0.PE = 0)) and (ECX indicates a supported counter))
THEN
EAX := counter[31:0];
EDX := ZeroExtend(counter[MSCB:32]);
ELSE (* ECX is not valid or CR4.PCE is 0 and CPL is 1, 2, or 3 and CR0.PE is 1 *)
#GP(0);
FI;
Flags Affected
None.
Protected Mode Exceptions
#GP(0)
If the current privilege level is not 0 and the PCE flag in the CR4 register is clear.
If an invalid performance counter index is specified.
#UD
If the LOCK prefix is used.
Real-Address Mode Exceptions
#GP
If an invalid performance counter index is specified.
#UD
If the LOCK prefix is used.
Virtual-8086 Mode Exceptions
#GP(0)
If the PCE flag in the CR4 register is clear.
If an invalid performance counter index is specified.
#UD
If the LOCK prefix is used.
Compatibility Mode Exceptions
Same exceptions as in protected mode.
64-Bit Mode Exceptions
#GP(0)
If the current privilege level is not 0 and the PCE flag in the CR4 register is clear.
If an invalid performance counter index is specified.
#UD
If the LOCK prefix is used.
RDPMC-Read Performance-Monitoring Counters
Vol. 2B
4-543
INSTRUCTION SET REFERENCE, M-U
RDRAND-Read Random Number
Opcode*/
Op/
64/32 bit
CPUID
Description
Instruction
En
Mode
Feature
Support
Flag
NFx 0F C7 /6
M
V/V
RDRAND
Read a 16-bit random number and store in the destination
register.
RDRAND r16
NFx 0F C7 /6
M
V/V
RDRAND
Read a 32-bit random number and store in the destination
register.
RDRAND r32
NFx REX.W + 0F C7 /6
M
V/I
RDRAND
Read a 64-bit random number and store in the destination
register.
RDRAND r64
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
M
ModRM:r/m (w)
N/A
N/A
N/A
Description
Loads a hardware generated random value and store it in the destination register. The size of the random value is
determined by the destination register size and operating mode. The Carry Flag indicates whether a random value
is available at the time the instruction is executed. CF=1 indicates that the data in the destination is valid. Other-
wise CF=0 and the data in the destination operand will be returned as zeros for the specified width. All other flags
are forced to 0 in either situation. Software must check the state of CF=1 for determining if a valid random value
has been returned, otherwise it is expected to loop and retry execution of RDRAND (see Intel® 64 and IA-32 Archi-
tectures Software Developer’s Manual, Volume 1, Section 7.3.17, “Random Number Generator Instructions”).
This instruction is available at all privilege levels.
In 64-bit mode, the instruction's default operand size is 32 bits. Using a REX prefix in the form of REX.B permits
access to additional registers (R8-R15). Using a REX prefix in the form of REX.W promotes operation to 64 bit oper-
ands. See the summary chart at the beginning of this section for encoding data and limits.
Operation
IF HW_RND_GEN.ready = 1
THEN
CASE of
operand size is 64: DEST[63:0] := HW_RND_GEN.data;
operand size is 32: DEST[31:0] := HW_RND_GEN.data;
operand size is 16: DEST[15:0] := HW_RND_GEN.data;
ESAC
CF := 1;
ELSE
CASE of
operand size is 64: DEST[63:0] := 0;
operand size is 32: DEST[31:0] := 0;
operand size is 16: DEST[15:0] := 0;
ESAC
CF := 0;
FI
OF, SF, ZF, AF, PF := 0;
Flags Affected
The CF flag is set according to the result (see the “Operation” section above). The OF, SF, ZF, AF, and PF flags are
set to 0.
4-544
Vol. 2B
RDRAND-Read Random Number
INSTRUCTION SET REFERENCE, M-U
Intel C/C++ Compiler Intrinsic Equivalent
RDRAND int _rdrand16_step( unsigned short * );
RDRAND int _rdrand32_step( unsigned int * );
RDRAND int _rdrand64_step( unsigned __int64 *);
Protected Mode Exceptions
#UD
If the LOCK prefix is used.
If CPUID.01H:ECX.RDRAND[bit 30] = 0.
Real-Address Mode Exceptions
Same exceptions as in protected mode.
Virtual-8086 Mode Exceptions
Same exceptions as in protected mode.
Compatibility Mode Exceptions
Same exceptions as in protected mode.
64-Bit Mode Exceptions
Same exceptions as in protected mode.
RDRAND-Read Random Number
Vol. 2B
4-545
INSTRUCTION SET REFERENCE, M-U
RDSEED-Read Random SEED
Opcode/
Op/
64/32 bit
CPUID
Description
Instruction
En
Mode
Feature Flag
Support
NFx 0F C7 /7
M
V/V
RDSEED
Read a 16-bit NIST SP800-90B & C compliant random value and
RDSEED r16
store in the destination register.
NFx 0F C7 /7
M
V/V
RDSEED
Read a 32-bit NIST SP800-90B & C compliant random value and
RDSEED r32
store in the destination register.
NFx REX.W + 0F C7 /7
M
V/I
RDSEED
Read a 64-bit NIST SP800-90B & C compliant random value and
RDSEED r64
store in the destination register.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
M
ModRM:r/m (w)
N/A
N/A
N/A
Description
Loads a hardware generated random value and store it in the destination register. The random value is generated
from an Enhanced NRBG (Non Deterministic Random Bit Generator) that is compliant to NIST SP800-90B and NIST
SP800-90C in the XOR construction mode. The size of the random value is determined by the destination register
size and operating mode. The Carry Flag indicates whether a random value is available at the time the instruction
is executed. CF=1 indicates that the data in the destination is valid. Otherwise CF=0 and the data in the destination
operand will be returned as zeros for the specified width. All other flags are forced to 0 in either situation. Software
must check the state of CF=1 for determining if a valid random seed value has been returned, otherwise it is
expected to loop and retry execution of RDSEED (see Section 1.2).
The RDSEED instruction is available at all privilege levels. The RDSEED instruction executes normally either inside
or outside a transaction region.
In 64-bit mode, the instruction's default operand size is 32 bits. Using a REX prefix in the form of REX.B permits
access to additional registers (R8-R15). Using a REX prefix in the form of REX.W promotes operation to 64 bit oper-
ands. See the summary chart at the beginning of this section for encoding data and limits.
Operation
IF HW_NRND_GEN.ready = 1
THEN
CASE of
operand size is 64: DEST[63:0] := HW_NRND_GEN.data;
operand size is 32: DEST[31:0] := HW_NRND_GEN.data;
operand size is 16: DEST[15:0] := HW_NRND_GEN.data;
ESAC;
CF := 1;
ELSE
CASE of
operand size is 64: DEST[63:0] := 0;
operand size is 32: DEST[31:0] := 0;
operand size is 16: DEST[15:0] := 0;
ESAC;
CF := 0;
FI;
OF, SF, ZF, AF, PF := 0;
4-546
Vol. 2B
RDSEED-Read Random SEED
INSTRUCTION SET REFERENCE, M-U
Flags Affected
The CF flag is set according to the result (see the “Operation” section above). The OF, SF, ZF, AF, and PF flags are
set to 0.
C/C++ Compiler Intrinsic Equivalent
RDSEED int _rdseed16_step( unsigned short * );
RDSEED int _rdseed32_step( unsigned int * );
RDSEED int _rdseed64_step( unsigned __int64 *);
Protected Mode Exceptions
#UD
If the LOCK prefix is used.
If CPUID.(EAX=07H, ECX=0H):EBX.RDSEED[bit 18] = 0.
Real-Address Mode Exceptions
#UD
If the LOCK prefix is used.
If CPUID.(EAX=07H, ECX=0H):EBX.RDSEED[bit 18] = 0.
Virtual-8086 Mode Exceptions
#UD
If the LOCK prefix is used.
If CPUID.(EAX=07H, ECX=0H):EBX.RDSEED[bit 18] = 0.
Compatibility Mode Exceptions
#UD
If the LOCK prefix is used.
If CPUID.(EAX=07H, ECX=0H):EBX.RDSEED[bit 18] = 0.
64-Bit Mode Exceptions
#UD
If the LOCK prefix is used.
If CPUID.(EAX=07H, ECX=0H):EBX.RDSEED[bit 18] = 0.
RDSEED-Read Random SEED
Vol. 2B
4-547
INSTRUCTION SET REFERENCE, M-U
RDSSPD/RDSSPQ-Read Shadow Stack Pointer
Opcode/
Op/
64/32 bit
CPUID
Description
Instruction
En
Mode
Feature Flag
Support
F3 0F 1E /1 (mod=11)
R
V/V
CET_SS
Copy low 32 bits of shadow stack pointer (SSP) to r32.
RDSSPD r32
F3 REX.W 0F 1E /1 (mod=11)
R
V/N.E.
CET_SS
Copies shadow stack pointer (SSP) to r64.
RDSSPQ r64
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
R
ModRM:r/m (w)
N/A
N/A
N/A
Description
Copies the current shadow stack pointer (SSP) register to the register destination. This opcode is a NOP when CET
shadow stacks are not enabled and on processors that do not support CET.
Operation
IF CPL = 3
IF CR4.CET & IA32_U_CET.SH_STK_EN
IF (operand size is 64 bit)
THEN
Dest := SSP;
ELSE
Dest := SSP[31:0];
FI;
FI;
ELSE
IF CR4.CET & IA32_S_CET.SH_STK_EN
IF (operand size is 64 bit)
THEN
Dest := SSP;
ELSE
Dest := SSP[31:0];
FI;
FI;
FI;
Flags Affected
None.
C/C++ Compiler Intrinsic Equivalent
RDSSPD__int32 _rdsspd_i32(void);
RDSSPQ__int64 _rdsspq_i64(void);
Protected Mode Exceptions
None.
4-548
Vol. 2B
RDSSPD/RDSSPQ-Read Shadow Stack Pointer
INSTRUCTION SET REFERENCE, M-U
Real-Address Mode Exceptions
None.
Virtual-8086 Mode Exceptions
None.
Compatibility Mode Exceptions
None.
64-Bit Mode Exceptions
None.
RDSSPD/RDSSPQ-Read Shadow Stack Pointer
Vol. 2B
4-549
INSTRUCTION SET REFERENCE, M-U
RDTSC-Read Time-Stamp Counter
Opcode*
Instruction
Op/
64-Bit
Compat/
Description
En
Mode
Leg Mode
0F 31
RDTSC
ZO
Valid
Valid
Read time-stamp counter into EDX:EAX.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
ZO
N/A
N/A
N/A
N/A
Description
Reads the current value of the processor’s time-stamp counter (a 64-bit MSR) into the EDX:EAX registers. The EDX
register is loaded with the high-order 32 bits of the MSR and the EAX register is loaded with the low-order 32 bits.
(On processors that support the Intel 64 architecture, the high-order 32 bits of each of RAX and RDX are cleared.)
The processor monotonically increments the time-stamp counter MSR every clock cycle and resets it to 0 whenever
the processor is reset. See “Time Stamp Counter” in Chapter 18 of the Intel® 64 and IA-32 Architectures Software
Developer’s Manual, Volume 3B, for specific details of the time stamp counter behavior.
The time stamp disable (TSD) flag in register CR4 restricts the use of the RDTSC instruction as follows. When the
flag is clear, the RDTSC instruction can be executed at any privilege level; when the flag is set, the instruction can
only be executed at privilege level 0.
The time-stamp counter can also be read with the RDMSR instruction, when executing at privilege level 0.
The RDTSC instruction is not a serializing instruction. It does not necessarily wait until all previous instructions
have been executed before reading the counter. Similarly, subsequent instructions may begin execution before the
read operation is performed. The following items may guide software seeking to order executions of RDTSC:
• If software requires RDTSC to be executed only after all previous instructions have executed and all previous
loads are globally visible,1 it can execute LFENCE immediately before RDTSC.
• If software requires RDTSC to be executed only after all previous instructions have executed and all previous
loads and stores are globally visible, it can execute the sequence MFENCE;LFENCE immediately before RDTSC.
• If software requires RDTSC to be executed prior to execution of any subsequent instruction (including any
memory accesses), it can execute the sequence LFENCE immediately after RDTSC.
This instruction was introduced by the Pentium processor.
See “Changes to Instruction Behavior in VMX Non-Root Operation” in Chapter 26 of the Intel® 64 and IA-32 Archi-
tectures Software Developer’s Manual, Volume 3C, for more information about the behavior of this instruction in
VMX non-root operation.
Operation
IF (CR4.TSD = 0) or (CPL = 0) or (CR0.PE = 0)
THEN EDX:EAX := TimeStampCounter;
ELSE (* CR4.TSD = 1 and (CPL = 1, 2, or 3) and CR0.PE = 1 *)
#GP(0);
FI;
Flags Affected
None.
1. A load is considered to become globally visible when the value to be loaded is determined.
4-550
Vol. 2B
RDTSC-Read Time-Stamp Counter
INSTRUCTION SET REFERENCE, M-U
Protected Mode Exceptions
#GP(0)
If the TSD flag in register CR4 is set and the CPL is greater than 0.
#UD
If the LOCK prefix is used.
Real-Address Mode Exceptions
#UD
If the LOCK prefix is used.
Virtual-8086 Mode Exceptions
#GP(0)
If the TSD flag in register CR4 is set.
#UD
If the LOCK prefix is used.
Compatibility Mode Exceptions
Same exceptions as in protected mode.
64-Bit Mode Exceptions
Same exceptions as in protected mode.
RDTSC-Read Time-Stamp Counter
Vol. 2B
4-551
INSTRUCTION SET REFERENCE, M-U
RDTSCP-Read Time-Stamp Counter and Processor ID
Opcode*
Instruction
Op/
64-Bit
Compat/
Description
En
Mode
Leg Mode
0F 01 F9
RDTSCP
ZO
Valid
Valid
Read 64-bit time-stamp counter and
IA32_TSC_AUX value into EDX:EAX and ECX.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
ZO
N/A
N/A
N/A
N/A
Description
Reads the current value of the processor’s time-stamp counter (a 64-bit MSR) into the EDX:EAX registers and also
reads the value of the IA32_TSC_AUX MSR (address C0000103H) into the ECX register. The EDX register is loaded
with the high-order 32 bits of the IA32_TSC MSR; the EAX register is loaded with the low-order 32 bits of the
IA32_TSC MSR; and the ECX register is loaded with the low-order 32-bits of IA32_TSC_AUX MSR. On processors
that support the Intel 64 architecture, the high-order 32 bits of each of RAX, RDX, and RCX are cleared.
The processor monotonically increments the time-stamp counter MSR every clock cycle and resets it to 0 whenever
the processor is reset. See “Time Stamp Counter” in Chapter 18 of the Intel® 64 and IA-32 Architectures Software
Developer’s Manual, Volume 3B, for specific details of the time stamp counter behavior.
The time stamp disable (TSD) flag in register CR4 restricts the use of the RDTSCP instruction as follows. When the
flag is clear, the RDTSCP instruction can be executed at any privilege level; when the flag is set, the instruction can
only be executed at privilege level 0.
The RDTSCP instruction is not a serializing instruction, but it does wait until all previous instructions have executed
and all previous loads are globally visible.1 But it does not wait for previous stores to be globally visible, and subse-
quent instructions may begin execution before the read operation is performed. The following items may guide
software seeking to order executions of RDTSCP:
• If software requires RDTSCP to be executed only after all previous stores are globally visible, it can execute
MFENCE immediately before RDTSCP.
• If software requires RDTSCP to be executed prior to execution of any subsequent instruction (including any
memory accesses), it can execute LFENCE immediately after RDTSCP.
See “Changes to Instruction Behavior in VMX Non-Root Operation” in Chapter 26 of the Intel® 64 and IA-32 Archi-
tectures Software Developer’s Manual, Volume 3C, for more information about the behavior of this instruction in
VMX non-root operation.
Operation
IF (CR4.TSD = 0) or (CPL = 0) or (CR0.PE = 0)
THEN
EDX:EAX := TimeStampCounter;
ECX := IA32_TSC_AUX[31:0];
ELSE (* CR4.TSD = 1 and (CPL = 1, 2, or 3) and CR0.PE = 1 *)
#GP(0);
FI;
Flags Affected
None.
1. A load is considered to become globally visible when the value to be loaded is determined.
4-552
Vol. 2B
RDTSCP-Read Time-Stamp Counter and Processor ID
INSTRUCTION SET REFERENCE, M-U
Protected Mode Exceptions
#GP(0)
If the TSD flag in register CR4 is set and the CPL is greater than 0.
#UD
If the LOCK prefix is used.
If CPUID.80000001H:EDX.RDTSCP[bit 27] = 0.
Real-Address Mode Exceptions
#UD
If the LOCK prefix is used.
If CPUID.80000001H:EDX.RDTSCP[bit 27] = 0.
Virtual-8086 Mode Exceptions
#GP(0)
If the TSD flag in register CR4 is set.
#UD
If the LOCK prefix is used.
If CPUID.80000001H:EDX.RDTSCP[bit 27] = 0.
Compatibility Mode Exceptions
Same exceptions as in protected mode.
64-Bit Mode Exceptions
Same exceptions as in protected mode.
RDTSCP-Read Time-Stamp Counter and Processor ID
Vol. 2B
4-553
INSTRUCTION SET REFERENCE, M-U
REP/REPE/REPZ/REPNE/REPNZ-Repeat String Operation Prefix
Opcode
Instruction
Op/
64-Bit
Compat/
Description
En
Mode
Leg Mode
F3 6C
REP INS m8, DX
ZO
Valid
Valid
Input (E)CX bytes from port DX into ES:[(E)DI].
F3 6C
REP INS m8, DX
ZO
Valid
N.E.
Input RCX bytes from port DX into [RDI].
F3 6D
REP INS m16, DX
ZO
Valid
Valid
Input (E)CX words from port DX into ES:[(E)DI.]
F3 6D
REP INS m32, DX
ZO
Valid
Valid
Input (E)CX doublewords from port DX into
ES:[(E)DI].
F3 6D
REP INS r/m32, DX
ZO
Valid
N.E.
Input RCX default size from port DX into [RDI].
F3 A4
REP MOVS m8, m8
ZO
Valid
Valid
Move (E)CX bytes from DS:[(E)SI] to ES:[(E)DI].
F3 REX.W A4
REP MOVS m8, m8
ZO
Valid
N.E.
Move RCX bytes from [RSI] to [RDI].
F3 A5
REP MOVS m16, m16
ZO
Valid
Valid
Move (E)CX words from DS:[(E)SI] to ES:[(E)DI].
F3 A5
REP MOVS m32, m32
ZO
Valid
Valid
Move (E)CX doublewords from DS:[(E)SI] to
ES:[(E)DI].
F3 REX.W A5
REP MOVS m64, m64
ZO
Valid
N.E.
Move RCX quadwords from [RSI] to [RDI].
F3 6E
REP OUTS DX, r/m8
ZO
Valid
Valid
Output (E)CX bytes from DS:[(E)SI] to port DX.
F3 REX.W 6E
REP OUTS DX, r/m81
ZO
Valid
N.E.
Output RCX bytes from [RSI] to port DX.
F3 6F
REP OUTS DX, r/m16
ZO
Valid
Valid
Output (E)CX words from DS:[(E)SI] to port DX.
F3 6F
REP OUTS DX, r/m32
ZO
Valid
Valid
Output (E)CX doublewords from DS:[(E)SI] to
port DX.
F3 REX.W 6F
REP OUTS DX, r/m32
ZO
Valid
N.E.
Output RCX default size from [RSI] to port DX.
F3 AC
REP LODS AL
ZO
Valid
Valid
Load (E)CX bytes from DS:[(E)SI] to AL.
F3 REX.W AC
REP LODS AL
ZO
Valid
N.E.
Load RCX bytes from [RSI] to AL.
F3 AD
REP LODS AX
ZO
Valid
Valid
Load (E)CX words from DS:[(E)SI] to AX.
F3 AD
REP LODS EAX
ZO
Valid
Valid
Load (E)CX doublewords from DS:[(E)SI] to
EAX.
F3 REX.W AD
REP LODS RAX
ZO
Valid
N.E.
Load RCX quadwords from [RSI] to RAX.
F3 AA
REP STOS m8
ZO
Valid
Valid
Fill (E)CX bytes at ES:[(E)DI] with AL.
F3 REX.W AA
REP STOS m8
ZO
Valid
N.E.
Fill RCX bytes at [RDI] with AL.
F3 AB
REP STOS m16
ZO
Valid
Valid
Fill (E)CX words at ES:[(E)DI] with AX.
F3 AB
REP STOS m32
ZO
Valid
Valid
Fill (E)CX doublewords at ES:[(E)DI] with EAX.
F3 REX.W AB
REP STOS m64
ZO
Valid
N.E.
Fill RCX quadwords at [RDI] with RAX.
F3 A6
REPE CMPS m8, m8
ZO
Valid
Valid
Find nonmatching bytes in ES:[(E)DI] and
DS:[(E)SI].
F3 REX.W A6
REPE CMPS m8, m8
ZO
Valid
N.E.
Find non-matching bytes in [RDI] and [RSI].
F3 A7
REPE CMPS m16, m16
ZO
Valid
Valid
Find nonmatching words in ES:[(E)DI] and
DS:[(E)SI].
F3 A7
REPE CMPS m32, m32
ZO
Valid
Valid
Find nonmatching doublewords in ES:[(E)DI]
and DS:[(E)SI].
F3 REX.W A7
REPE CMPS m64, m64
ZO
Valid
N.E.
Find non-matching quadwords in [RDI] and
[RSI].
F3 AE
REPE SCAS m8
ZO
Valid
Valid
Find non-AL byte starting at ES:[(E)DI].
F3 REX.W AE
REPE SCAS m8
ZO
Valid
N.E.
Find non-AL byte starting at [RDI].
F3 AF
REPE SCAS m16
ZO
Valid
Valid
Find non-AX word starting at ES:[(E)DI].
F3 AF
REPE SCAS m32
ZO
Valid
Valid
Find non-EAX doubleword starting at
ES:[(E)DI].
4-554
Vol. 2B
REP/REPE/REPZ/REPNE/REPNZ-Repeat String Operation Prefix
INSTRUCTION SET REFERENCE, M-U
Opcode
Instruction
Op/
64-Bit
Compat/
Description
En
Mode
Leg Mode
F3 REX.W AF
REPE SCAS m64
ZO
Valid
N.E.
Find non-RAX quadword starting at [RDI].
F2 A6
REPNE CMPS m8, m8
ZO
Valid
Valid
Find matching bytes in ES:[(E)DI] and DS:[(E)SI].
F2 REX.W A6
REPNE CMPS m8, m8
ZO
Valid
N.E.
Find matching bytes in [RDI] and [RSI].
F2 A7
REPNE CMPS m16, m16
ZO
Valid
Valid
Find matching words in ES:[(E)DI] and
DS:[(E)SI].
F2 A7
REPNE CMPS m32, m32
ZO
Valid
Valid
Find matching doublewords in ES:[(E)DI] and
DS:[(E)SI].
F2 REX.W A7
REPNE CMPS m64, m64
ZO
Valid
N.E.
Find matching doublewords in [RDI] and [RSI].
F2 AE
REPNE SCAS m8
ZO
Valid
Valid
Find AL, starting at ES:[(E)DI].
F2 REX.W AE
REPNE SCAS m8
ZO
Valid
N.E.
Find AL, starting at [RDI].
F2 AF
REPNE SCAS m16
ZO
Valid
Valid
Find AX, starting at ES:[(E)DI].
F2 AF
REPNE SCAS m32
ZO
Valid
Valid
Find EAX, starting at ES:[(E)DI].
F2 REX.W AF
REPNE SCAS m64
ZO
Valid
N.E.
Find RAX, starting at [RDI].
NOTES:
1. In 64-bit mode, r/m8 can not be encoded to access the following byte registers if a REX prefix is used: AH, BH, CH, DH.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
ZO
N/A
N/A
N/A
N/A
Description
Repeats a string instruction the number of times specified in the count register or until the indicated condition of
the ZF flag is no longer met. The REP (repeat), REPE (repeat while equal), REPNE (repeat while not equal), REPZ
(repeat while zero), and REPNZ (repeat while not zero) mnemonics are prefixes that can be added to one of the
string instructions. The REP prefix can be added to the INS, OUTS, MOVS, LODS, and STOS instructions, and the
REPE, REPNE, REPZ, and REPNZ prefixes can be added to the CMPS and SCAS instructions. (The REPZ and REPNZ
prefixes are synonymous forms of the REPE and REPNE prefixes, respectively.) The F3H prefix is defined for the
following instructions and undefined for the rest:
• F3H as REP/REPE/REPZ for string and input/output instruction.
• F3H is a mandatory prefix for POPCNT, LZCNT, and ADOX.
The REP prefixes apply only to one string instruction at a time. To repeat a block of instructions, use the LOOP
instruction or another looping construct. All of these repeat prefixes cause the associated instruction to be
repeated until the count in register is decremented to 0. See Table 4-17.
Table 4-17. Repeat Prefixes
Repeat Prefix
Termination Condition 1*
Termination Condition 2
REP
RCX or (E)CX = 0
None
REPE/REPZ
RCX or (E)CX = 0
ZF = 0
REPNE/REPNZ
RCX or (E)CX = 0
ZF = 1
NOTES:
* Count register is CX, ECX or RCX by default, depending on attributes of the operating modes.
REP/REPE/REPZ/REPNE/REPNZ-Repeat String Operation Prefix
Vol. 2B
4-555
INSTRUCTION SET REFERENCE, M-U
The REPE, REPNE, REPZ, and REPNZ prefixes also check the state of the ZF flag after each iteration and terminate
the repeat loop if the ZF flag is not in the specified state. When both termination conditions are tested, the cause
of a repeat termination can be determined either by testing the count register with a JECXZ instruction or by testing
the ZF flag (with a JZ, JNZ, or JNE instruction).
When the REPE/REPZ and REPNE/REPNZ prefixes are used, the ZF flag does not require initialization because both
the CMPS and SCAS instructions affect the ZF flag according to the results of the comparisons they make.
A repeating string operation can be suspended by an exception or interrupt. When this happens, the state of the
registers is preserved to allow the string operation to be resumed upon a return from the exception or interrupt
handler. The source and destination registers point to the next string elements to be operated on, the EIP register
points to the string instruction, and the ECX register has the value it held following the last successful iteration of
the instruction. This mechanism allows long string operations to proceed without affecting the interrupt response
time of the system.
When a fault occurs during the execution of a CMPS or SCAS instruction that is prefixed with REPE or REPNE, the
EFLAGS value is restored to the state prior to the execution of the instruction. Since the SCAS and CMPS instruc-
tions do not use EFLAGS as an input, the processor can resume the instruction after the page fault handler.
Use the REP INS and REP OUTS instructions with caution. Not all I/O ports can handle the rate at which these
instructions execute. Note that a REP STOS instruction is the fastest way to initialize a large block of memory.
In 64-bit mode, the operand size of the count register is associated with the address size attribute. Thus the default
count register is RCX; REX.W has no effect on the address size and the count register. In 64-bit mode, if 67H is used
to override address size attribute, the count register is ECX and any implicit source/destination operand will use the
corresponding 32-bit index register. See the summary chart at the beginning of this section for encoding data and
limits.
REP INS may read from the I/O port without writing to the memory location if an exception or VM exit occurs due
to the write (e.g., #PF). If this would be problematic, for example because the I/O port read has side-effects, soft-
ware should ensure the write to the memory location does not cause an exception or VM exit.
Operation
IF AddressSize = 16
THEN
Use CX for CountReg;
Implicit Source/Dest operand for memory use of SI/DI;
ELSE IF AddressSize = 64
THEN Use RCX for CountReg;
Implicit Source/Dest operand for memory use of RSI/RDI;
ELSE
Use ECX for CountReg;
Implicit Source/Dest operand for memory use of ESI/EDI;
FI;
WHILE CountReg ≠ 0
DO
Service pending interrupts (if any);
Execute associated string instruction;
CountReg := (CountReg - 1);
IF CountReg = 0
THEN exit WHILE loop; FI;
IF (Repeat prefix is REPZ or REPE) and (ZF = 0)
or (Repeat prefix is REPNZ or REPNE) and (ZF = 1)
THEN exit WHILE loop; FI;
OD;
Flags Affected
None; however, the CMPS and SCAS instructions do set the status flags in the EFLAGS register.
4-556
Vol. 2B
REP/REPE/REPZ/REPNE/REPNZ-Repeat String Operation Prefix
INSTRUCTION SET REFERENCE, M-U
Exceptions (All Operating Modes)
Exceptions may be generated by an instruction associated with the prefix.
64-Bit Mode Exceptions
#GP(0)
If the memory address is in a non-canonical form.
REP/REPE/REPZ/REPNE/REPNZ-Repeat String Operation Prefix
Vol. 2B
4-557
INSTRUCTION SET REFERENCE, M-U
RET-Return From Procedure
Opcode*
Instruction
Op/
64-Bit
Compat/
Description
En
Mode
Leg Mode
C3
RET
ZO
Valid
Valid
Near return to calling procedure.
CB
RET
ZO
Valid
Valid
Far return to calling procedure.
C2 iw
RET imm16
I
Valid
Valid
Near return to calling procedure and pop
imm16 bytes from stack.
CA iw
RET imm16
I
Valid
Valid
Far return to calling procedure and pop imm16
bytes from stack.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
ZO
N/A
N/A
N/A
N/A
I
imm16
N/A
N/A
N/A
Description
Transfers program control to a return address located on the top of the stack. The address is usually placed on the
stack by a CALL instruction, and the return is made to the instruction that follows the CALL instruction.
The optional source operand specifies the number of stack bytes to be released after the return address is popped;
the default is none. This operand can be used to release parameters from the stack that were passed to the called
procedure and are no longer needed. It must be used when the CALL instruction used to switch to a new procedure
uses a call gate with a non-zero word count to access the new procedure. Here, the source operand for the RET
instruction must specify the same number of bytes as is specified in the word count field of the call gate.
The RET instruction can be used to execute three different types of returns:
• Near return - A return to a calling procedure within the current code segment (the segment currently pointed
to by the CS register), sometimes referred to as an intrasegment return.
• Far return - A return to a calling procedure located in a different segment than the current code segment,
sometimes referred to as an intersegment return.
• Inter-privilege-level far return - A far return to a different privilege level than that of the currently
executing program or procedure.
The inter-privilege-level return type can only be executed in protected mode. See the section titled “Calling Proce-
dures Using Call and RET” in Chapter 6 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual,
Volume 1, for detailed information on near, far, and inter-privilege-level returns.
When executing a near return, the processor pops the return instruction pointer (offset) from the top of the stack
into the EIP register and begins program execution at the new instruction pointer. The CS register is unchanged.
When executing a far return, the processor pops the return instruction pointer from the top of the stack into the EIP
register, then pops the segment selector from the top of the stack into the CS register. The processor then begins
program execution in the new code segment at the new instruction pointer.
The mechanics of an inter-privilege-level far return are similar to an intersegment return, except that the processor
examines the privilege levels and access rights of the code and stack segments being returned to determine if the
control transfer is allowed to be made. The DS, ES, FS, and GS segment registers are cleared by the RET instruction
during an inter-privilege-level return if they refer to segments that are not allowed to be accessed at the new priv-
ilege level. Since a stack switch also occurs on an inter-privilege level return, the ESP and SS registers are loaded
from the stack.
If parameters are passed to the called procedure during an inter-privilege level call, the optional source operand
must be used with the RET instruction to release the parameters on the return. Here, the parameters are released
both from the called procedure’s stack and the calling procedure’s stack (that is, the stack being returned to).
In 64-bit mode, the default operation size of this instruction is the stack-address size, i.e., 64 bits. This applies to
near returns, not far returns; the default operation size of far returns is 32 bits.
4-558
Vol. 2B
RET-Return From Procedure
INSTRUCTION SET REFERENCE, M-U
Refer to Chapter 6, “Procedure Calls, Interrupts, and Exceptions‚” and Chapter 17, “Control-flow Enforcement
Technology (CET)‚” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for CET
details.
Instruction ordering. Instructions following a far return may be fetched from memory before earlier instructions
complete execution, but they will not execute (even speculatively) until all instructions prior to the far return have
completed execution (the later instructions may execute before data stored by the earlier instructions have
become globally visible).
Unlike near indirect CALL and near indirect JMP, the processor will not speculatively execute the next sequential
instruction after a near RET unless that instruction is also the target of a jump or is a target in a branch predictor.
Operation
(* Near return *)
IF instruction = near return
THEN;
IF OperandSize = 32
THEN
IF top 4 bytes of stack not within stack limits
THEN #SS(0); FI;
EIP := Pop();
IF ShadowStackEnabled(CPL)
tempSsEIP = ShadowStackPop4B();
IF EIP != TempSsEIP
THEN #CP(NEAR_RET); FI;
FI;
ELSE
IF OperandSize = 64
THEN
IF top 8 bytes of stack not within stack limits
THEN #SS(0); FI;
RIP := Pop();
IF ShadowStackEnabled(CPL)
tempSsEIP = ShadowStackPop8B();
IF RIP != tempSsEIP
THEN #CP(NEAR_RET); FI;
FI;
ELSE (* OperandSize = 16 *)
IF top 2 bytes of stack not within stack limits
THEN #SS(0); FI;
tempEIP := Pop();
tempEIP := tempEIP AND 0000FFFFH;
IF tempEIP not within code segment limits
THEN #GP(0); FI;
EIP := tempEIP;
IF ShadowStackEnabled(CPL)
tempSsEip = ShadowStackPop4B();
IF EIP != tempSsEIP
THEN #CP(NEAR_RET); FI;
FI;
FI;
FI;
IF instruction has immediate operand
THEN (* Release parameters from stack *)
IF StackAddressSize = 32
RET-Return From Procedure
Vol. 2B
4-559
INSTRUCTION SET REFERENCE, M-U
THEN
ESP := ESP + SRC;
ELSE
IF StackAddressSize = 64
THEN
RSP := RSP + SRC;
ELSE (* StackAddressSize = 16 *)
SP := SP + SRC;
FI;
FI;
FI;
FI;
(* Real-address mode or virtual-8086 mode *)
IF ((PE = 0) or (PE = 1 AND VM = 1)) and instruction = far return
THEN
IF OperandSize = 32
THEN
IF top 8 bytes of stack not within stack limits
THEN #SS(0); FI;
EIP := Pop();
CS := Pop(); (* 32-bit pop, high-order 16 bits discarded *)
ELSE (* OperandSize = 16 *)
IF top 4 bytes of stack not within stack limits
THEN #SS(0); FI;
tempEIP := Pop();
tempEIP := tempEIP AND 0000FFFFH;
IF tempEIP not within code segment limits
THEN #GP(0); FI;
EIP := tempEIP;
CS := Pop(); (* 16-bit pop *)
FI;
IF instruction has immediate operand
THEN (* Release parameters from stack *)
SP := SP + (SRC AND FFFFH);
FI;
FI;
(* Protected mode, not virtual-8086 mode *)
IF (PE = 1 and VM = 0 and IA32_EFER.LMA = 0) and instruction = far return
THEN
IF OperandSize = 32
THEN
IF second doubleword on stack is not within stack limits
THEN #SS(0); FI;
ELSE (* OperandSize = 16 *)
IF second word on stack is not within stack limits
THEN #SS(0); FI;
FI;
IF return code segment selector is NULL
THEN #GP(0); FI;
IF return code segment selector addresses descriptor beyond descriptor table limit
THEN #GP(selector); FI;
Obtain descriptor to which return code segment selector points from descriptor table;
4-560
Vol. 2B
RET-Return From Procedure
INSTRUCTION SET REFERENCE, M-U
IF return code segment descriptor is not a code segment
THEN #GP(selector); FI;
IF return code segment selector RPL < CPL
THEN #GP(selector); FI;
IF return code segment descriptor is conforming
and return code segment DPL > return code segment selector RPL
THEN #GP(selector); FI;
IF return code segment descriptor is non-conforming and return code
segment DPL ≠ return code segment selector RPL
THEN #GP(selector); FI;
IF return code segment descriptor is not present
THEN #NP(selector); FI:
IF return code segment selector RPL > CPL
THEN GOTO RETURN-TO-OUTER-PRIVILEGE-LEVEL;
ELSE GOTO RETURN-TO-SAME-PRIVILEGE-LEVEL;
FI;
FI;
RETURN-TO-SAME-PRIVILEGE-LEVEL:
IF the return instruction pointer is not within the return code segment limit
THEN #GP(0); FI;
IF OperandSize = 32
THEN
EIP := Pop();
CS := Pop(); (* 32-bit pop, high-order 16 bits discarded *)
ELSE (* OperandSize = 16 *)
EIP := Pop();
EIP := EIP AND 0000FFFFH;
CS := Pop(); (* 16-bit pop *)
FI;
IF instruction has immediate operand
THEN (* Release parameters from stack *)
IF StackAddressSize = 32
THEN
ESP := ESP + SRC;
ELSE (* StackAddressSize = 16 *)
SP := SP + SRC;
FI;
FI;
IF ShadowStackEnabled(CPL)
(* SSP must be 8 byte aligned *)
IF SSP AND 0x7 != 0
THEN #CP(FAR-RET/IRET); FI;
tempSsCS = shadow_stack_load 8 bytes from SSP+16;
tempSsLIP = shadow_stack_load 8 bytes from SSP+8;
prevSSP = shadow_stack_load 8 bytes from SSP;
SSP = SSP + 24;
(* do a 64 bit-compare to check if any bits beyond bit 15 are set *)
tempCS = CS; (* zero pad to 64 bit *)
IF tempCS != tempSsCS
THEN #CP(FAR-RET/IRET); FI;
(* do a 64 bit-compare; pad CSBASE+RIP with 0 for 32 bit LIP*)
IF CSBASE + RIP != tempSsLIP
THEN #CP(FAR-RET/IRET); FI;
RET-Return From Procedure
Vol. 2B
4-561
INSTRUCTION SET REFERENCE, M-U
(* prevSSP must be 4 byte aligned *)
IF prevSSP AND 0x3 != 0
THEN #CP(FAR-RET/IRET); FI;
(* In legacy mode SSP must be in low 4GB *)
IF prevSSP[63:32] != 0
THEN #GP(0); FI;
SSP := prevSSP
FI;
RETURN-TO-OUTER-PRIVILEGE-LEVEL:
IF top (16 + SRC) bytes of stack are not within stack limits (OperandSize = 32)
or top (8 + SRC) bytes of stack are not within stack limits (OperandSize = 16)
THEN #SS(0); FI;
Read return segment selector;
IF stack segment selector is NULL
THEN #GP(0); FI;
IF return stack segment selector index is not within its descriptor table limits
THEN #GP(selector); FI;
Read segment descriptor pointed to by return segment selector;
IF stack segment selector RPL ≠ RPL of the return code segment selector
or stack segment is not a writable data segment
or stack segment descriptor DPL ≠ RPL of the return code segment selector
THEN #GP(selector); FI;
IF stack segment not present
THEN #SS(StackSegmentSelector); FI;
IF the return instruction pointer is not within the return code segment limit
THEN #GP(0); FI;
IF OperandSize = 32
THEN
EIP := Pop();
CS := Pop(); (* 32-bit pop, high-order 16 bits discarded; segment descriptor loaded *)
CS(RPL) := ReturnCodeSegmentSelector(RPL);
IF instruction has immediate operand
THEN (* Release parameters from called procedure’s stack *)
IF StackAddressSize = 32
THEN
ESP := ESP + SRC;
ELSE (* StackAddressSize = 16 *)
SP := SP + SRC;
FI;
FI;
tempESP := Pop();
tempSS := Pop(); (* 32-bit pop, high-order 16 bits discarded; seg. descriptor loaded *)
ELSE (* OperandSize = 16 *)
EIP := Pop();
EIP := EIP AND 0000FFFFH;
CS := Pop(); (* 16-bit pop; segment descriptor loaded *)
CS(RPL) := ReturnCodeSegmentSelector(RPL);
IF instruction has immediate operand
THEN (* Release parameters from called procedure’s stack *)
IF StackAddressSize = 32
THEN
ESP := ESP + SRC;
ELSE (* StackAddressSize = 16 *)
4-562
Vol. 2B
RET-Return From Procedure
INSTRUCTION SET REFERENCE, M-U
SP := SP + SRC;
FI;
FI;
tempESP := Pop();
tempSS := Pop(); (* 16-bit pop; segment descriptor loaded *)
FI;
IF ShadowStackEnabled(CPL)
(* check if 8 byte aligned *)
IF SSP AND 0x7 != 0
THEN #CP(FAR-RET/IRET); FI;
IF ReturnCodeSegmentSelector(RPL) !=3
THEN
tempSsCS = shadow_stack_load 8 bytes from SSP+16;
tempSsLIP = shadow_stack_load 8 bytes from SSP+8;
tempSSP = shadow_stack_load 8 bytes from SSP;
SSP = SSP + 24;
(* Do 64 bit compare to detect bits beyond 15 being set *)
tempCS = CS; (* zero extended to 64 bit *)
IF tempCS != tempSsCS
THEN #CP(FAR-RET/IRET); FI;
(* Do 64 bit compare; pad CSBASE+RIP with 0 for 32 bit LA *)
IF CSBASE + RIP != tempSsLIP
THEN #CP(FAR-RET/IRET); FI;
(* check if 4 byte aligned *)
IF tempSSP AND 0x3 != 0
THEN #CP(FAR-RET/IRET); FI;
FI;
FI;
tempOldCPL = CPL;
CPL := ReturnCodeSegmentSelector(RPL);
ESP := tempESP;
SS := tempSS;
tempOldSSP = SSP;
IF ShadowStackEnabled(CPL)
IF CPL = 3
THEN tempSSP := IA32_PL3_SSP; FI;
IF tempSSP[63:32] != 0
THEN #GP(0); FI;
SSP := tempSSP
FI;
(* Now past all faulting points; safe to free the token. The token free is done using the old SSP
* and using a supervisor override as old CPL was a supervisor privilege level *)
IF ShadowStackEnabled(tempOldCPL)
expected_token_value = tempOldSSP | BUSY_BIT (* busy bit - bit position 0 - must be set *)
new_token_value = tempOldSSP
(* clear the busy bit *)
shadow_stack_lock_cmpxchg8b(tempOldSSP, new_token_value, expected_token_value)
FI;
FI;
FOR each SegReg in (ES, FS, GS, and DS)
DO
tempDesc := descriptor cache for SegReg (* hidden part of segment register *)
IF (SegmentSelector == NULL) OR (tempDesc(DPL) < CPL AND tempDesc(Type) is (data or non-conforming code)))
RET-Return From Procedure
Vol. 2B
4-563
INSTRUCTION SET REFERENCE, M-U
THEN (* Segment register invalid *)
SegmentSelector := 0; (*Segment selector becomes null*)
FI;
OD;
IF instruction has immediate operand
THEN (* Release parameters from calling procedure’s stack *)
IF StackAddressSize = 32
THEN
ESP := ESP + SRC;
ELSE (* StackAddressSize = 16 *)
SP := SP + SRC;
FI;
FI;
(* IA-32e Mode *)
IF (PE = 1 and VM = 0 and IA32_EFER.LMA = 1) and instruction = far return
THEN
IF OperandSize = 32
THEN
IF second doubleword on stack is not within stack limits
THEN #SS(0); FI;
IF first or second doubleword on stack is not in canonical space
THEN #SS(0); FI;
ELSE
IF OperandSize = 16
THEN
IF second word on stack is not within stack limits
THEN #SS(0); FI;
IF first or second word on stack is not in canonical space
THEN #SS(0); FI;
ELSE (* OperandSize = 64 *)
IF first or second quadword on stack is not in canonical space
THEN #SS(0); FI;
FI
FI;
IF return code segment selector is NULL
THEN GP(0); FI;
IF return code segment selector addresses descriptor beyond descriptor table limit
THEN GP(selector); FI;
IF return code segment selector addresses descriptor in non-canonical space
THEN GP(selector); FI;
Obtain descriptor to which return code segment selector points from descriptor table;
IF return code segment descriptor is not a code segment
THEN #GP(selector); FI;
IF return code segment descriptor has L-bit = 1 and D-bit = 1
THEN #GP(selector); FI;
IF return code segment selector RPL < CPL
THEN #GP(selector); FI;
IF return code segment descriptor is conforming
and return code segment DPL > return code segment selector RPL
THEN #GP(selector); FI;
IF return code segment descriptor is non-conforming
and return code segment DPL ≠ return code segment selector RPL
4-564
Vol. 2B
RET-Return From Procedure
INSTRUCTION SET REFERENCE, M-U
THEN #GP(selector); FI;
IF return code segment descriptor is not present
THEN #NP(selector); FI:
IF return code segment selector RPL > CPL
THEN GOTO IA-32E-MODE-RETURN-TO-OUTER-PRIVILEGE-LEVEL;
ELSE GOTO IA-32E-MODE-RETURN-TO-SAME-PRIVILEGE-LEVEL;
FI;
FI;
IA-32E-MODE-RETURN-TO-SAME-PRIVILEGE-LEVEL:
IF the return instruction pointer is not within the return code segment limit
THEN #GP(0); FI;
IF the return instruction pointer is not within canonical address space
THEN #GP(0); FI;
IF OperandSize = 32
THEN
EIP := Pop();
CS := Pop(); (* 32-bit pop, high-order 16 bits discarded *)
ELSE
IF OperandSize = 16
THEN
EIP := Pop();
EIP := EIP AND 0000FFFFH;
CS := Pop(); (* 16-bit pop *)
ELSE (* OperandSize = 64 *)
RIP := Pop();
CS := Pop(); (* 64-bit pop, high-order 48 bits discarded *)
FI;
FI;
IF instruction has immediate operand
THEN (* Release parameters from stack *)
IF StackAddressSize = 32
THEN
ESP := ESP + SRC;
ELSE
IF StackAddressSize = 16
THEN
SP := SP + SRC;
ELSE (* StackAddressSize = 64 *)
RSP := RSP + SRC;
FI;
FI;
FI;
IF ShadowStackEnabled(CPL)
IF SSP AND 0x7 != 0 (* check if aligned to 8 bytes *)
THEN #CP(FAR-RET/IRET); FI;
tempSsCS = shadow_stack_load 8 bytes from SSP+16;
tempSsLIP = shadow_stack_load 8 bytes from SSP+8;
tempSSP = shadow_stack_load 8 bytes from SSP;
SSP = SSP + 24;
tempCS = CS; (* zero padded to 64 bit *)
IF tempCS != tempSsCS (* 64 bit compare; CS zero padded to 64 bits *)
THEN #CP(FAR-RET/IRET); FI;
IF CSBASE + RIP != tempSsLIP (* 64 bit compare *)
RET-Return From Procedure
Vol. 2B
4-565
INSTRUCTION SET REFERENCE, M-U
THEN #CP(FAR-RET/IRET); FI;
IF tempSSP AND 0x3 != 0 (* check if aligned to 4 bytes *)
THEN #CP(FAR-RET/IRET); FI;
IF (CS.L = 0 AND tempSSP[63:32] != 0) OR
(CS.L = 1 AND tempSSP is not canonical relative to the current paging mode)
THEN #GP(0); FI;
SSP := tempSSP
FI;
IA-32E-MODE-RETURN-TO-OUTER-PRIVILEGE-LEVEL:
IF top (16 + SRC) bytes of stack are not within stack limits (OperandSize = 32)
or top (8 + SRC) bytes of stack are not within stack limits (OperandSize = 16)
THEN #SS(0); FI;
IF top (16 + SRC) bytes of stack are not in canonical address space (OperandSize =32)
or top (8 + SRC) bytes of stack are not in canonical address space (OperandSize = 16)
or top (32 + SRC) bytes of stack are not in canonical address space (OperandSize = 64)
THEN #SS(0); FI;
Read return stack segment selector;
IF stack segment selector is NULL
THEN
IF new CS descriptor L-bit = 0
THEN #GP(selector);
IF stack segment selector RPL = 3
THEN #GP(selector);
FI;
IF return stack segment descriptor is not within descriptor table limits
THEN #GP(selector); FI;
IF return stack segment descriptor is in non-canonical address space
THEN #GP(selector); FI;
Read segment descriptor pointed to by return segment selector;
IF stack segment selector RPL ≠ RPL of the return code segment selector
or stack segment is not a writable data segment
or stack segment descriptor DPL ≠ RPL of the return code segment selector
THEN #GP(selector); FI;
IF stack segment not present
THEN #SS(StackSegmentSelector); FI;
IF the return instruction pointer is not within the return code segment limit
THEN #GP(0); FI:
IF the return instruction pointer is not within canonical address space
THEN #GP(0); FI;
IF OperandSize = 32
THEN
EIP := Pop();
CS := Pop(); (* 32-bit pop, high-order 16 bits discarded, segment descriptor loaded *)
CS(RPL) := ReturnCodeSegmentSelector(RPL);
IF instruction has immediate operand
THEN (* Release parameters from called procedure’s stack *)
IF StackAddressSize = 32
THEN
ESP := ESP + SRC;
ELSE
IF StackAddressSize = 16
THEN
SP := SP + SRC;
4-566
Vol. 2B
RET-Return From Procedure
INSTRUCTION SET REFERENCE, M-U
ELSE (* StackAddressSize = 64 *)
RSP := RSP + SRC;
FI;
FI;
FI;
tempESP := Pop();
tempSS := Pop(); (* 32-bit pop, high-order 16 bits discarded, segment descriptor loaded *)
ELSE
IF OperandSize = 16
THEN
EIP := Pop();
EIP := EIP AND 0000FFFFH;
CS := Pop(); (* 16-bit pop; segment descriptor loaded *)
CS(RPL) := ReturnCodeSegmentSelector(RPL);
IF instruction has immediate operand
THEN (* Release parameters from called procedure’s stack *)
IF StackAddressSize = 32
THEN
ESP := ESP + SRC;
ELSE
IF StackAddressSize = 16
THEN
SP := SP + SRC;
ELSE (* StackAddressSize = 64 *)
RSP := RSP + SRC;
FI;
FI;
FI;
tempESP := Pop();
tempSS := Pop(); (* 16-bit pop; segment descriptor loaded *)
ELSE (* OperandSize = 64 *)
RIP := Pop();
CS := Pop(); (* 64-bit pop; high-order 48 bits discarded; seg. descriptor loaded *)
CS(RPL) := ReturnCodeSegmentSelector(RPL);
IF instruction has immediate operand
THEN (* Release parameters from called procedure’s stack *)
RSP := RSP + SRC;
FI;
tempESP := Pop();
tempSS := Pop(); (* 64-bit pop; high-order 48 bits discarded; seg. desc. loaded *)
FI;
FI;
IF ShadowStackEnabled(CPL)
(* check if 8 byte aligned *)
IF SSP AND 0x7 != 0
THEN #CP(FAR-RET/IRET); FI;
IF ReturnCodeSegmentSelector(RPL) !=3
THEN
tempSsCS = shadow_stack_load 8 bytes from SSP+16;
tempSsLIP = shadow_stack_load 8 bytes from SSP+8;
tempSSP = shadow_stack_load 8 bytes from SSP;
SSP = SSP + 24;
(* Do 64 bit compare to detect bits beyond 15 being set *)
RET-Return From Procedure
Vol. 2B
4-567
INSTRUCTION SET REFERENCE, M-U
tempCS = CS; (* zero padded to 64 bit *)
IF tempCS != tempSsCS
THEN #CP(FAR-RET/IRET); FI;
(* Do 64 bit compare; pad CSBASE+RIP with 0 for 32 bit LIP *)
IF CSBASE + RIP != tempSsLIP
THEN #CP(FAR-RET/IRET); FI;
(* check if 4 byte aligned *)
IF tempSSP AND 0x3 != 0
THEN #CP(FAR-RET/IRET); FI;
FI;
FI;
tempOldCPL = CPL;
CPL := ReturnCodeSegmentSelector(RPL);
ESP := tempESP;
SS := tempSS;
tempOldSSP = SSP;
IF ShadowStackEnabled(CPL)
IF CPL = 3
THEN tempSSP := IA32_PL3_SSP; FI;
IF (CS.L = 0 AND tempSSP[63:32] != 0) OR
(CS.L = 1 AND tempSSP is not canonical relative to the current paging mode)
THEN #GP(0); FI;
SSP := tempSSP
FI;
(* Now past all faulting points; safe to free the token. The token free is done using the old SSP
* and using a supervisor override as old CPL was a supervisor privilege level *)
IF ShadowStackEnabled(tempOldCPL)
expected_token_value = tempOldSSP | BUSY_BIT
(* busy bit - bit position 0 - must be set *)
new_token_value = tempOldSSP
(* clear the busy bit *)
shadow_stack_lock_cmpxchg8b(tempOldSSP, new_token_value, expected_token_value)
FI;
FOR each of segment register (ES, FS, GS, and DS)
DO
IF segment register points to data or non-conforming code segment
and CPL > segment descriptor DPL; (* DPL in hidden part of segment register *)
THEN SegmentSelector := 0; (* SegmentSelector invalid *)
FI;
OD;
IF instruction has immediate operand
THEN (* Release parameters from calling procedure’s stack *)
IF StackAddressSize = 32
THEN
ESP := ESP + SRC;
ELSE
IF StackAddressSize = 16
THEN
SP := SP + SRC;
ELSE (* StackAddressSize = 64 *)
RSP := RSP + SRC;
FI;
FI;
FI;
4-568
Vol. 2B
RET-Return From Procedure
INSTRUCTION SET REFERENCE, M-U
Flags Affected
None.
Protected Mode Exceptions
#GP(0)
If the return code or stack segment selector is NULL.
If the return instruction pointer is not within the return code segment limit.
If returning to 32-bit or compatibility mode and the previous SSP from shadow stack (when
returning to CPL <3) or from IA32_PL3_SSP (returning to CPL 3) is beyond 4GB.
#GP(selector)
If the RPL of the return code segment selector is less then the CPL.
If the return code or stack segment selector index is not within its descriptor table limits.
If the return code segment descriptor does not indicate a code segment.
If the return code segment is non-conforming and the segment selector’s DPL is not equal to
the RPL of the code segment’s segment selector
If the return code segment is conforming and the segment selector’s DPL greater than the RPL
of the code segment’s segment selector
If the stack segment is not a writable data segment.
If the stack segment selector RPL is not equal to the RPL of the return code segment selector.
If the stack segment descriptor DPL is not equal to the RPL of the return code segment
selector.
#SS(0)
If the top bytes of stack are not within stack limits.
If the return stack segment is not present.
#NP(selector)
If the return code segment is not present.
#PF(fault-code)
If a page fault occurs.
#AC(0)
If an unaligned memory access occurs when the CPL is 3 and alignment checking is enabled.
#CP(Far-RET/IRET) If the previous SSP from shadow stack (when returning to CPL <3) or from IA32_PL3_SSP
(returning to CPL 3) is not 4 byte aligned.
If return instruction pointer from stack and shadow stack do not match.
Real-Address Mode Exceptions
#GP
If the return instruction pointer is not within the return code segment limit
#SS
If the top bytes of stack are not within stack limits.
Virtual-8086 Mode Exceptions
#GP(0)
If the return instruction pointer is not within the return code segment limit
#SS(0)
If the top bytes of stack are not within stack limits.
#PF(fault-code)
If a page fault occurs.
#AC(0)
If an unaligned memory access occurs when alignment checking is enabled.
Compatibility Mode Exceptions
Same as 64-bit mode exceptions.
RET-Return From Procedure
Vol. 2B
4-569
INSTRUCTION SET REFERENCE, M-U
64-Bit Mode Exceptions
#GP(0)
If the return instruction pointer is non-canonical.
If the return instruction pointer is not within the return code segment limit.
If the stack segment selector is NULL going back to compatibility mode.
If the stack segment selector is NULL going back to CPL3 64-bit mode.
If a NULL stack segment selector RPL is not equal to CPL going back to non-CPL3 64-bit mode.
If the return code segment selector is NULL.
If returning to 32-bit or compatibility mode and the previous SSP from shadow stack (when
returning to CPL <3) or from IA32_PL3_SSP (returning to CPL 3) is beyond 4GB.
#GP(selector)
If the proposed segment descriptor for a code segment does not indicate it is a code segment.
If the proposed new code segment descriptor has both the D-bit and L-bit set.
If the DPL for a nonconforming-code segment is not equal to the RPL of the code segment
selector.
If CPL is greater than the RPL of the code segment selector.
If the DPL of a conforming-code segment is greater than the return code segment selector
RPL.
If a segment selector index is outside its descriptor table limits.
If a segment descriptor memory address is non-canonical.
If the stack segment is not a writable data segment.
If the stack segment descriptor DPL is not equal to the RPL of the return code segment
selector.
If the stack segment selector RPL is not equal to the RPL of the return code segment selector.
#SS(0)
If an attempt to pop a value off the stack violates the SS limit.
If an attempt to pop a value off the stack causes a non-canonical address to be referenced.
#NP(selector)
If the return code or stack segment is not present.
#PF(fault-code)
If a page fault occurs.
#AC(0)
If alignment checking is enabled and an unaligned memory reference is made while the
current privilege level is 3.
#CP(Far-RET/IRET) If the previous SSP from shadow stack (when returning to CPL <3) or from IA32_PL3_SSP
(returning to CPL 3) is not 4 byte aligned.
If return instruction pointer from stack and shadow stack do not match.
4-570
Vol. 2B
RET-Return From Procedure
INSTRUCTION SET REFERENCE, M-U
RORX - Rotate Right Logical Without Affecting Flags
Opcode/
Op/
64/32-
CPUID
Description
Instruction
En
bit
Feature
Mode
Flag
VEX.LZ.F2.0F3A.W0 F0 /r ib
RMI
V/V
BMI2
Rotate 32-bit r/m32 right imm8 times without affecting arithmetic
RORX r32, r/m32, imm8
flags.
VEX.LZ.F2.0F3A.W1 F0 /r ib
RMI
V/N.E.
BMI2
Rotate 64-bit r/m64 right imm8 times without affecting arithmetic
RORX r64, r/m64, imm8
flags.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
RMI
ModRM:reg (w)
ModRM:r/m (r)
imm8
N/A
Description
Rotates the bits of second operand right by the count value specified in imm8 without affecting arithmetic flags.
The RORX instruction does not read or write the arithmetic flags.
This instruction is not supported in real mode and virtual-8086 mode. The operand size is always 32 bits if not in
64-bit mode. In 64-bit mode operand size 64 requires VEX.W1. VEX.W1 is ignored in non-64-bit modes. An
attempt to execute this instruction with VEX.L not equal to 0 will cause #UD.
Operation
IF (OperandSize = 32)
y := imm8 AND 1FH;
DEST := (SRC >> y) | (SRC << (32-y));
ELSEIF (OperandSize = 64 )
y := imm8 AND 3FH;
DEST := (SRC >> y) | (SRC << (64-y));
FI;
Flags Affected
None.
Intel C/C++ Compiler Intrinsic Equivalent
Auto-generated from high-level language.
SIMD Floating-Point Exceptions
None.
Other Exceptions
See Table 2-29, “Type 13 Class Exception Conditions.”
RORX - Rotate Right Logical Without Affecting Flags
Vol. 2B
4-571
INSTRUCTION SET REFERENCE, M-U
ROUNDPD-Round Packed Double Precision Floating-Point Values
Opcode*/
Op/
64/32 bit
CPUID
Description
Instruction
En
Mode
Feature
Support
Flag
66 0F 3A 09 /r ib
RMI
V/V
SSE4_1
Round packed double precision floating-point
ROUNDPD xmm1, xmm2/m128, imm8
values in xmm2/m128 and place the result in
xmm1. The rounding mode is determined by
imm8.
VEX.128.66.0F3A.WIG 09 /r ib
RMI
V/V
AVX
Round packed double precision floating-point
VROUNDPD xmm1, xmm2/m128, imm8
values in xmm2/m128 and place the result in
xmm1. The rounding mode is determined by
imm8.
VEX.256.66.0F3A.WIG 09 /r ib
RMI
V/V
AVX
Round packed double precision floating-point
VROUNDPD ymm1, ymm2/m256, imm8
values in ymm2/m256 and place the result in
ymm1. The rounding mode is determined by
imm8.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
RMI
ModRM:reg (w)
ModRM:r/m (r)
imm8
N/A
Description
Round the 2 double precision floating-point values in the source operand (second operand) using the rounding
mode specified in the immediate operand (third operand) and place the results in the destination operand (first
operand). The rounding process rounds each input floating-point value to an integer value and returns the integer
result as a double precision floating-point value.
The immediate operand specifies control fields for the rounding operation, three bit fields are defined and shown in
Figure 4-24. Bit 3 of the immediate byte controls processor behavior for a precision exception, bit 2 selects the
source of rounding mode control. Bits 1:0 specify a non-sticky rounding-mode value (Table 4-18 lists the encoded
values for rounding-mode field).
The Precision Floating-Point Exception is signaled according to the immediate operand. If any source operand is an
SNaN then it will be converted to a QNaN. If DAZ is set to ‘1 then denormals will be converted to zero before
rounding.
128-bit Legacy SSE version: The second source can be an XMM register or 128-bit memory location. The destina-
tion is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding YMM
register destination are unmodified.
VEX.128 encoded version: the source operand second source operand or a 128-bit memory location. The destina-
tion operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding YMM register destination are
zeroed.
VEX.256 encoded version: The source operand is a YMM register or a 256-bit memory location. The destination
operand is a YMM register.
Note: In VEX-encoded versions, VEX.vvvv is reserved and must be 1111b, otherwise instructions will #UD.
4-572
Vol. 2B
ROUNDPD-Round Packed Double Precision Floating-Point Values
INSTRUCTION SET REFERENCE, M-U
8
3 2 1 0
Reserved
P - Precision Mask; 0: normal, 1: inexact
RS - Rounding select; 1: MXCSR.RC, 0: Imm8.RC
RC - Rounding mode
Figure 4-24. Bit Control Fields of Immediate Byte for ROUNDxx Instruction
Table 4-18. Rounding Modes and Encoding of Rounding Control (RC) Field
Rounding
RC Field
Description
Mode
Setting
Round to
00B
Rounded result is the closest to the infinitely precise result. If two values are equally close, the result is
nearest (even)
the even value (i.e., the integer value with the least-significant bit of zero).
Round down
01B
Rounded result is closest to but no greater than the infinitely precise result.
(toward -∞)
Round up
10B
Rounded result is closest to but no less than the infinitely precise result.
(toward +∞)
Round toward
11B
Rounded result is closest to but no greater in absolute value than the infinitely precise result.
zero (Truncate)
Operation
IF (imm[2] = ‘1)
THEN
// rounding mode is determined by MXCSR.RC
DEST[63:0] := ConvertDPFPToInteger_M(SRC[63:0]);
DEST[127:64] := ConvertDPFPToInteger_M(SRC[127:64]);
ELSE
// rounding mode is determined by IMM8.RC
DEST[63:0] := ConvertDPFPToInteger_Imm(SRC[63:0]);
DEST[127:64] := ConvertDPFPToInteger_Imm(SRC[127:64]);
FI
ROUNDPD (128-bit Legacy SSE Version)
DEST[63:0] := RoundToInteger(SRC[63:0]], ROUND_CONTROL)
DEST[127:64] := RoundToInteger(SRC[127:64]], ROUND_CONTROL)
DEST[MAXVL-1:128] (Unmodified)
VROUNDPD (VEX.128 Encoded Version)
DEST[63:0] := RoundToInteger(SRC[63:0]], ROUND_CONTROL)
DEST[127:64] := RoundToInteger(SRC[127:64]], ROUND_CONTROL)
DEST[MAXVL-1:128] := 0
VROUNDPD (VEX.256 Encoded Version)
DEST[63:0] := RoundToInteger(SRC[63:0], ROUND_CONTROL)
DEST[127:64] := RoundToInteger(SRC[127:64]], ROUND_CONTROL)
DEST[191:128] := RoundToInteger(SRC[191:128]], ROUND_CONTROL)
DEST[255:192] := RoundToInteger(SRC[255:192] ], ROUND_CONTROL)
ROUNDPD-Round Packed Double Precision Floating-Point Values
Vol. 2B
4-573
INSTRUCTION SET REFERENCE, M-U
Intel C/C++ Compiler Intrinsic Equivalent
__m128 _mm_round_pd(__m128d s1, int iRoundMode);
__m128 _mm_floor_pd(__m128d s1);
__m128 _mm_ceil_pd(__m128d s1)
__m256 _mm256_round_pd(__m256d s1, int iRoundMode);
__m256 _mm256_floor_pd(__m256d s1);
__m256 _mm256_ceil_pd(__m256d s1)
SIMD Floating-Point Exceptions
Invalid (signaled only if SRC = SNaN).
Precision (signaled only if imm[3] = ‘0; if imm[3] = ‘1, then the Precision Mask in the MXSCSR is ignored and preci-
sion exception is not signaled.)
Note that Denormal is not signaled by ROUNDPD.
Other Exceptions
See Table 2-19, “Type 2 Class Exception Conditions,” additionally:
#UD
If VEX.vvvv ≠ 1111B.
4-574
Vol. 2B
ROUNDPD-Round Packed Double Precision Floating-Point Values
INSTRUCTION SET REFERENCE, M-U
ROUNDPS-Round Packed Single Precision Floating-Point Values
Opcode*/
Op/
64/32 bit
CPUID
Description
Instruction
En
Mode
Feature
Support
Flag
66 0F 3A 08
RMI
V/V
SSE4_1
Round packed single precision floating-point
/r ib
values in xmm2/m128 and place the result in
ROUNDPS xmm1, xmm2/m128, imm8
xmm1. The rounding mode is determined by
imm8.
VEX.128.66.0F3A.WIG 08 /r ib
RMI
V/V
AVX
Round packed single precision floating-point
VROUNDPS xmm1, xmm2/m128, imm8
values in xmm2/m128 and place the result in
xmm1. The rounding mode is determined by
imm8.
VEX.256.66.0F3A.WIG 08 /r ib
RMI
V/V
AVX
Round packed single precision floating-point
VROUNDPS ymm1, ymm2/m256, imm8
values in ymm2/m256 and place the result in
ymm1. The rounding mode is determined by
imm8.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
RMI
ModRM:reg (w)
ModRM:r/m (r)
imm8
N/A
Description
Round the 4 single precision floating-point values in the source operand (second operand) using the rounding mode
specified in the immediate operand (third operand) and place the results in the destination operand (first operand).
The rounding process rounds each input floating-point value to an integer value and returns the integer result as a
single precision floating-point value.
The immediate operand specifies control fields for the rounding operation, three bit fields are defined and shown in
Figure 4-24. Bit 3 of the immediate byte controls processor behavior for a precision exception, bit 2 selects the
source of rounding mode control. Bits 1:0 specify a non-sticky rounding-mode value (Table 4-18 lists the encoded
values for rounding-mode field).
The Precision Floating-Point Exception is signaled according to the immediate operand. If any source operand is an
SNaN then it will be converted to a QNaN. If DAZ is set to ‘1 then denormals will be converted to zero before
rounding.
128-bit Legacy SSE version: The second source can be an XMM register or 128-bit memory location. The destina-
tion is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding YMM
register destination are unmodified.
VEX.128 encoded version: the source operand second source operand or a 128-bit memory location. The destina-
tion operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding YMM register destination are
zeroed.
VEX.256 encoded version: The source operand is a YMM register or a 256-bit memory location. The destination
operand is a YMM register.
Note: In VEX-encoded versions, VEX.vvvv is reserved and must be 1111b otherwise instructions will #UD.
Operation
IF (imm[2] = ‘1)
THEN
// rounding mode is determined by MXCSR.RC
DEST[31:0] := ConvertSPFPToInteger_M(SRC[31:0]);
DEST[63:32] := ConvertSPFPToInteger_M(SRC[63:32]);
DEST[95:64] := ConvertSPFPToInteger_M(SRC[95:64]);
DEST[127:96] := ConvertSPFPToInteger_M(SRC[127:96]);
ELSE
// rounding mode is determined by IMM8.RC
ROUNDPS-Round Packed Single Precision Floating-Point Values
Vol. 2B
4-575
INSTRUCTION SET REFERENCE, M-U
DEST[31:0] := ConvertSPFPToInteger_Imm(SRC[31:0]);
DEST[63:32] := ConvertSPFPToInteger_Imm(SRC[63:32]);
DEST[95:64] := ConvertSPFPToInteger_Imm(SRC[95:64]);
DEST[127:96] := ConvertSPFPToInteger_Imm(SRC[127:96]);
FI;
ROUNDPS(128-bit Legacy SSE Version)
DEST[31:0] := RoundToInteger(SRC[31:0], ROUND_CONTROL)
DEST[63:32] := RoundToInteger(SRC[63:32], ROUND_CONTROL)
DEST[95:64] := RoundToInteger(SRC[95:64]], ROUND_CONTROL)
DEST[127:96] := RoundToInteger(SRC[127:96]], ROUND_CONTROL)
DEST[MAXVL-1:128] (Unmodified)
VROUNDPS (VEX.128 Encoded Version)
DEST[31:0] := RoundToInteger(SRC[31:0], ROUND_CONTROL)
DEST[63:32] := RoundToInteger(SRC[63:32], ROUND_CONTROL)
DEST[95:64] := RoundToInteger(SRC[95:64]], ROUND_CONTROL)
DEST[127:96] := RoundToInteger(SRC[127:96]], ROUND_CONTROL)
DEST[MAXVL-1:128] := 0
VROUNDPS (VEX.256 Encoded Version)
DEST[31:0] := RoundToInteger(SRC[31:0], ROUND_CONTROL)
DEST[63:32] := RoundToInteger(SRC[63:32], ROUND_CONTROL)
DEST[95:64] := RoundToInteger(SRC[95:64]], ROUND_CONTROL)
DEST[127:96] := RoundToInteger(SRC[127:96]], ROUND_CONTROL)
DEST[159:128] := RoundToInteger(SRC[159:128]], ROUND_CONTROL)
DEST[191:160] := RoundToInteger(SRC[191:160]], ROUND_CONTROL)
DEST[223:192] := RoundToInteger(SRC[223:192] ], ROUND_CONTROL)
DEST[255:224] := RoundToInteger(SRC[255:224] ], ROUND_CONTROL)
Intel C/C++ Compiler Intrinsic Equivalent
__m128 _mm_round_ps(__m128 s1, int iRoundMode);
__m128 _mm_floor_ps(__m128 s1);
__m128 _mm_ceil_ps(__m128 s1)
__m256 _mm256_round_ps(__m256 s1, int iRoundMode);
__m256 _mm256_floor_ps(__m256 s1);
__m256 _mm256_ceil_ps(__m256 s1)
SIMD Floating-Point Exceptions
Invalid (signaled only if SRC = SNaN).
Precision (signaled only if imm[3] = ‘0; if imm[3] = ‘1, then the Precision Mask in the MXSCSR is ignored and preci-
sion exception is not signaled.)
Note that Denormal is not signaled by ROUNDPS.
Other Exceptions
See Table 2-19, “Type 2 Class Exception Conditions,” additionally:
#UD
If VEX.vvvv ≠ 1111B.
4-576
Vol. 2B
ROUNDPS-Round Packed Single Precision Floating-Point Values
INSTRUCTION SET REFERENCE, M-U
ROUNDSD-Round Scalar Double Precision Floating-Point Values
Opcode*/
Op/
64/32 bit
CPUID
Description
Instruction
En
Mode
Feature
Support
Flag
66 0F 3A 0B /r ib
RMI
V/V
SSE4_1
Round the low packed double precision
ROUNDSD xmm1, xmm2/m64, imm8
floating-point value in xmm2/m64 and place
the result in xmm1. The rounding mode is
determined by imm8.
VEX.LIG.66.0F3A.WIG 0B /r ib
RVMI
V/V
AVX
Round the low packed double precision
VROUNDSD xmm1, xmm2, xmm3/m64, imm8
floating-point value in xmm3/m64 and place
the result in xmm1. The rounding mode is
determined by imm8. Upper packed double
precision floating-point value (bits[127:64])
from xmm2 is copied to xmm1[127:64].
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
RMI
ModRM:reg (w)
ModRM:r/m (r)
imm8
N/A
RVMI
ModRM:reg (w)
VEX.vvvv (r)
ModRM:r/m (r)
imm8
Description
Round the double precision floating-point value in the lower qword of the source operand (second operand) using
the rounding mode specified in the immediate operand (third operand) and place the result in the destination
operand (first operand). The rounding process rounds a double precision floating-point input to an integer value
and returns the integer result as a double precision floating-point value in the lowest position. The upper double
precision floating-point value in the destination is retained.
The immediate operand specifies control fields for the rounding operation, three bit fields are defined and shown in
Figure 4-24. Bit 3 of the immediate byte controls processor behavior for a precision exception, bit 2 selects the
source of rounding mode control. Bits 1:0 specify a non-sticky rounding-mode value (Table 4-18 lists the encoded
values for rounding-mode field).
The Precision Floating-Point Exception is signaled according to the immediate operand. If any source operand is an
SNaN then it will be converted to a QNaN. If DAZ is set to ‘1 then denormals will be converted to zero before
rounding.
128-bit Legacy SSE version: The first source operand and the destination operand are the same. Bits (MAXVL-
1:64) of the corresponding YMM destination register remain unchanged.
VEX.128 encoded version: Bits (MAXVL-1:128) of the destination YMM register are zeroed.
Operation
IF (imm[2] = ‘1)
THEN
// rounding mode is determined by MXCSR.RC
DEST[63:0] := ConvertDPFPToInteger_M(SRC[63:0]);
ELSE
// rounding mode is determined by IMM8.RC
DEST[63:0] := ConvertDPFPToInteger_Imm(SRC[63:0]);
FI;
DEST[127:63] remains unchanged ;
ROUNDSD (128-bit Legacy SSE Version)
DEST[63:0] := RoundToInteger(SRC[63:0], ROUND_CONTROL)
DEST[MAXVL-1:64] (Unmodified)
ROUNDSD-Round Scalar Double Precision Floating-Point Values
Vol. 2B
4-577
INSTRUCTION SET REFERENCE, M-U
VROUNDSD (VEX.128 Encoded Version)
DEST[63:0] := RoundToInteger(SRC2[63:0], ROUND_CONTROL)
DEST[127:64] := SRC1[127:64]
DEST[MAXVL-1:128] := 0
Intel C/C++ Compiler Intrinsic Equivalent
ROUNDSD __m128d mm_round_sd(__m128d dst, __m128d s1, int iRoundMode);
ROUNDSD __m128d mm_floor_sd(__m128d dst, __m128d s1);
ROUNDSD __m128d mm_ceil_sd(__m128d dst, __m128d s1);
SIMD Floating-Point Exceptions
Invalid (signaled only if SRC = SNaN).
Precision (signaled only if imm[3] = ‘0; if imm[3] = ‘1, then the Precision Mask in the MXSCSR is ignored and preci-
sion exception is not signaled.)
Note that Denormal is not signaled by ROUNDSD.
Other Exceptions
See Table 2-20, “Type 3 Class Exception Conditions.”
4-578
Vol. 2B
ROUNDSD-Round Scalar Double Precision Floating-Point Values
INSTRUCTION SET REFERENCE, M-U
ROUNDSS-Round Scalar Single Precision Floating-Point Values
Opcode*/
Op/
64/32 bit
CPUID
Description
Instruction
En
Mode
Feature
Support
Flag
66 0F 3A 0A /r ib
RMI
V/V
SSE4_1
Round the low packed single precision floating-
ROUNDSS xmm1, xmm2/m32, imm8
point value in xmm2/m32 and place the result in
xmm1. The rounding mode is determined by imm8.
VEX.LIG.66.0F3A.WIG 0A /r ib
RVMI
V/V
AVX
Round the low packed single precision floating-
VROUNDSS xmm1, xmm2, xmm3/m32, imm8
point value in xmm3/m32 and place the result in
xmm1. The rounding mode is determined by imm8.
Also, upper packed single precision floating-point
values (bits[127:32]) from xmm2 are copied to
xmm1[127:32].
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
RMI
ModRM:reg (w)
ModRM:r/m (r)
imm8
N/A
RVMI
ModRM:reg (w)
VEX.vvvv (r)
ModRM:r/m (r)
imm8
Description
Round the single precision floating-point value in the lowest dword of the source operand (second operand) using
the rounding mode specified in the immediate operand (third operand) and place the result in the destination
operand (first operand). The rounding process rounds a single precision floating-point input to an integer value and
returns the result as a single precision floating-point value in the lowest position. The upper three single precision
floating-point values in the destination are retained.
The immediate operand specifies control fields for the rounding operation, three bit fields are defined and shown in
Figure 4-24. Bit 3 of the immediate byte controls processor behavior for a precision exception, bit 2 selects the
source of rounding mode control. Bits 1:0 specify a non-sticky rounding-mode value (Table 4-18 lists the encoded
values for rounding-mode field).
The Precision Floating-Point Exception is signaled according to the immediate operand. If any source operand is an
SNaN then it will be converted to a QNaN. If DAZ is set to ‘1 then denormals will be converted to zero before
rounding.
128-bit Legacy SSE version: The first source operand and the destination operand are the same. Bits (MAXVL-
1:32) of the corresponding YMM destination register remain unchanged.
VEX.128 encoded version: Bits (MAXVL-1:128) of the destination YMM register are zeroed.
Operation
IF (imm[2] = ‘1)
THEN
// rounding mode is determined by MXCSR.RC
DEST[31:0] := ConvertSPFPToInteger_M(SRC[31:0]);
ELSE
// rounding mode is determined by IMM8.RC
DEST[31:0] := ConvertSPFPToInteger_Imm(SRC[31:0]);
FI;
DEST[127:32] remains unchanged ;
ROUNDSS (128-bit Legacy SSE Version)
DEST[31:0] := RoundToInteger(SRC[31:0], ROUND_CONTROL)
DEST[MAXVL-1:32] (Unmodified)
ROUNDSS-Round Scalar Single Precision Floating-Point Values
Vol. 2B
4-579
INSTRUCTION SET REFERENCE, M-U
VROUNDSS (VEX.128 Encoded Version)
DEST[31:0] := RoundToInteger(SRC2[31:0], ROUND_CONTROL)
DEST[127:32] := SRC1[127:32]
DEST[MAXVL-1:128] := 0
Intel C/C++ Compiler Intrinsic Equivalent
ROUNDSS __m128 mm_round_ss(__m128 dst, __m128 s1, int iRoundMode);
ROUNDSS __m128 mm_floor_ss(__m128 dst, __m128 s1);
ROUNDSS __m128 mm_ceil_ss(__m128 dst, __m128 s1);
SIMD Floating-Point Exceptions
Invalid (signaled only if SRC = SNaN).
Precision (signaled only if imm[3] = ‘0; if imm[3] = ‘1, then the Precision Mask in the MXSCSR is ignored and preci-
sion exception is not signaled.)
Note that Denormal is not signaled by ROUNDSS.
Other Exceptions
See Table 2-20, “Type 3 Class Exception Conditions.”
4-580
Vol. 2B
ROUNDSS-Round Scalar Single Precision Floating-Point Values
INSTRUCTION SET REFERENCE, M-U
RSM-Resume From System Management Mode
Opcode*
Instruction
Op/
64-Bit
Compat/
Description
En
Mode
Leg Mode
0F AA
RSM
ZO
Valid
Valid
Resume operation of interrupted program.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
ZO
N/A
N/A
N/A
N/A
Description
Returns program control from system management mode (SMM) to the application program or operating-system
procedure that was interrupted when the processor received an SMM interrupt. The processor’s state is restored
from the dump created upon entering SMM. If the processor detects invalid state information during state resto-
ration, it enters the shutdown state. The following invalid information can cause a shutdown:
• Any reserved bit of CR4 is set to 1.
• Any illegal combination of bits in CR0, such as (PG=1 and PE=0) or (NW=1 and CD=0).
• (Intel Pentium and Intel486™ processors only.) The value stored in the state dump base field is not a 32-KByte
aligned address.
The contents of the model-specific registers are not affected by a return from SMM.
The SMM state map used by RSM supports resuming processor context for non-64-bit modes and 64-bit mode.
See Chapter 32, “System Management Mode,” in the Intel® 64 and IA-32 Architectures Software Developer’s
Manual, Volume 3C, for more information about SMM and the behavior of the RSM instruction.
Operation
ReturnFromSMM;
IF (IA-32e mode supported) or (CPUID DisplayFamily_DisplayModel = 06H_0CH )
THEN
ProcessorState := Restore(SMMDump(IA-32e SMM STATE MAP));
Else
ProcessorState := Restore(SMMDump(Non-32-Bit-Mode SMM STATE MAP));
FI
Flags Affected
All.
Protected Mode Exceptions
#UD
If an attempt is made to execute this instruction when the processor is not in SMM.
If the LOCK prefix is used.
Real-Address Mode Exceptions
Same exceptions as in protected mode.
Virtual-8086 Mode Exceptions
Same exceptions as in protected mode.
Compatibility Mode Exceptions
Same exceptions as in protected mode.
RSM-Resume From System Management Mode
Vol. 2B
4-581
INSTRUCTION SET REFERENCE, M-U
64-Bit Mode Exceptions
Same exceptions as in protected mode.
4-582
Vol. 2B
RSM-Resume From System Management Mode
INSTRUCTION SET REFERENCE, M-U
RSQRTPS-Compute Reciprocals of Square Roots of Packed Single Precision Floating-Point
Values
Opcode*/
Op/
64/32 bit
CPUID
Description
Instruction
En
Mode
Feature
Support
Flag
NP 0F 52 /r
RM
V/V
SSE
Computes the approximate reciprocals of the square
roots of the packed single precision floating-point
RSQRTPS xmm1, xmm2/m128
values in xmm2/m128 and stores the results in
xmm1.
VEX.128.0F.WIG 52 /r
RM
V/V
AVX
Computes the approximate reciprocals of the square
roots of packed single precision values in xmm2/mem
VRSQRTPS xmm1, xmm2/m128
and stores the results in xmm1.
VEX.256.0F.WIG 52 /r
RM
V/V
AVX
Computes the approximate reciprocals of the square
roots of packed single precision values in ymm2/mem
VRSQRTPS ymm1, ymm2/m256
and stores the results in ymm1.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
RM
ModRM:reg (w)
ModRM:r/m (r)
N/A
N/A
Description
Performs a SIMD computation of the approximate reciprocals of the square roots of the four packed single precision
floating-point values in the source operand (second operand) and stores the packed single precision floating-point
results in the destination operand. The source operand can be an XMM register or a 128-bit memory location. The
destination operand is an XMM register. See Figure 10-5 in the Intel® 64 and IA-32 Architectures Software Devel-
oper’s Manual, Volume 1, for an illustration of a SIMD single precision floating-point operation.
The relative error for this approximation is:
|Relative Error| ≤ 1.5 ∗ 2-12
The RSQRTPS instruction is not affected by the rounding control bits in the MXCSR register. When a source value is
a 0.0, an ∞ of the sign of the source value is returned. A denormal source value is treated as a 0.0 (of the same
sign). When a source value is a negative value (other than -0.0), a floating-point indefinite is returned. When a
source value is an SNaN or QNaN, the SNaN is converted to a QNaN or the source QNaN is returned.
In 64-bit mode, using a REX prefix in the form of REX.R permits this instruction to access additional registers
(XMM8-XMM15).
128-bit Legacy SSE version: The second source can be an XMM register or an 128-bit memory location. The desti-
nation is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding
YMM register destination are unmodified.
VEX.128 encoded version: the first source operand is an XMM register or 128-bit memory location. The destination
operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding YMM register destination are
zeroed.
VEX.256 encoded version: The first source operand is a YMM register. The second source operand can be a YMM
register or a 256-bit memory location. The destination operand is a YMM register.
Note: In VEX-encoded versions, VEX.vvvv is reserved and must be 1111b, otherwise instructions will #UD.
RSQRTPS-Compute Reciprocals of Square Roots of Packed Single Precision Floating-Point Values
Vol. 2B
4-583
INSTRUCTION SET REFERENCE, M-U
Operation
RSQRTPS (128-bit Legacy SSE Version)
DEST[31:0] := APPROXIMATE(1/SQRT(SRC[31:0]))
DEST[63:32] := APPROXIMATE(1/SQRT(SRC1[63:32]))
DEST[95:64] := APPROXIMATE(1/SQRT(SRC1[95:64]))
DEST[127:96] := APPROXIMATE(1/SQRT(SRC2[127:96]))
DEST[MAXVL-1:128] (Unmodified)
VRSQRTPS (VEX.128 Encoded Version)
DEST[31:0] := APPROXIMATE(1/SQRT(SRC[31:0]))
DEST[63:32] := APPROXIMATE(1/SQRT(SRC1[63:32]))
DEST[95:64] := APPROXIMATE(1/SQRT(SRC1[95:64]))
DEST[127:96] := APPROXIMATE(1/SQRT(SRC2[127:96]))
DEST[MAXVL-1:128] := 0
VRSQRTPS (VEX.256 Encoded Version)
DEST[31:0] := APPROXIMATE(1/SQRT(SRC[31:0]))
DEST[63:32] := APPROXIMATE(1/SQRT(SRC1[63:32]))
DEST[95:64] := APPROXIMATE(1/SQRT(SRC1[95:64]))
DEST[127:96] := APPROXIMATE(1/SQRT(SRC2[127:96]))
DEST[159:128] := APPROXIMATE(1/SQRT(SRC2[159:128]))
DEST[191:160] := APPROXIMATE(1/SQRT(SRC2[191:160]))
DEST[223:192] := APPROXIMATE(1/SQRT(SRC2[223:192]))
DEST[255:224] := APPROXIMATE(1/SQRT(SRC2[255:224]))
Intel C/C++ Compiler Intrinsic Equivalent
RSQRTPS __m128 _mm_rsqrt_ps(__m128 a)
RSQRTPS __m256 _mm256_rsqrt_ps (__m256 a);
SIMD Floating-Point Exceptions
None.
Other Exceptions
See Table 2-21, “Type 4 Class Exception Conditions,” additionally:
#UD
If VEX.vvvv ≠ 1111B.
4-584
Vol. 2B
RSQRTPS-Compute Reciprocals of Square Roots of Packed Single Precision Floating-Point Values
INSTRUCTION SET REFERENCE, M-U
RSQRTSS-Compute Reciprocal of Square Root of Scalar Single Precision Floating-Point Value
Opcode*/
Op/
64/32 bit
CPUID
Description
Instruction
En
Mode
Feature
Support
Flag
F3 0F 52 /r
RM
V/V
SSE
Computes the approximate reciprocal of the square
root of the low single precision floating-point value in
RSQRTSS xmm1, xmm2/m32
xmm2/m32 and stores the results in xmm1.
VEX.LIG.F3.0F.WIG 52 /r
RVM
V/V
AVX
Computes the approximate reciprocal of the square
VRSQRTSS xmm1, xmm2, xmm3/m32
root of the low single precision floating-point value in
xmm3/m32 and stores the results in xmm1. Also,
upper single precision floating-point values
(bits[127:32]) from xmm2 are copied to
xmm1[127:32].
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
RM
ModRM:reg (w)
ModRM:r/m (r)
N/A
N/A
RVM
ModRM:reg (w)
VEX.vvvv (r)
ModRM:r/m (r)
N/A
Description
Computes an approximate reciprocal of the square root of the low single precision floating-point value in the source
operand (second operand) stores the single precision floating-point result in the destination operand. The source
operand can be an XMM register or a 32-bit memory location. The destination operand is an XMM register. The
three high-order doublewords of the destination operand remain unchanged. See Figure 10-6 in the Intel® 64 and
IA-32 Architectures Software Developer’s Manual, Volume 1, for an illustration of a scalar single precision floating-
point operation.
The relative error for this approximation is:
|Relative Error| ≤ 1.5 ∗ 2-12
The RSQRTSS instruction is not affected by the rounding control bits in the MXCSR register. When a source value is
a 0.0, an ∞ of the sign of the source value is returned. A denormal source value is treated as a 0.0 (of the same
sign). When a source value is a negative value (other than -0.0), a floating-point indefinite is returned. When a
source value is an SNaN or QNaN, the SNaN is converted to a QNaN or the source QNaN is returned.
In 64-bit mode, using a REX prefix in the form of REX.R permits this instruction to access additional registers
(XMM8-XMM15).
128-bit Legacy SSE version: The first source operand and the destination operand are the same. Bits (MAXVL-
1:32) of the corresponding YMM destination register remain unchanged.
VEX.128 encoded version: Bits (MAXVL-1:128) of the destination YMM register are zeroed.
Operation
RSQRTSS (128-bit Legacy SSE Version)
DEST[31:0] := APPROXIMATE(1/SQRT(SRC2[31:0]))
DEST[MAXVL-1:32] (Unmodified)
VRSQRTSS (VEX.128 Encoded Version)
DEST[31:0] := APPROXIMATE(1/SQRT(SRC2[31:0]))
DEST[127:32] := SRC1[127:32]
DEST[MAXVL-1:128] := 0
RSQRTSS-Compute Reciprocal of Square Root of Scalar Single Precision Floating-Point Value
Vol. 2B
4-585
INSTRUCTION SET REFERENCE, M-U
Intel C/C++ Compiler Intrinsic Equivalent
RSQRTSS __m128 _mm_rsqrt_ss(__m128 a)
SIMD Floating-Point Exceptions
None.
Other Exceptions
See Table 2-22, “Type 5 Class Exception Conditions.”
4-586
Vol. 2B
RSQRTSS-Compute Reciprocal of Square Root of Scalar Single Precision Floating-Point Value
INSTRUCTION SET REFERENCE, M-U
RSTORSSP-Restore Saved Shadow Stack Pointer
Opcode/
Op/
64/32 bit
CPUID
Description
Instruction
En
Mode
Feature
Support
Flag
F3 0F 01 /5 (mod!=11, /5, memory only)
M
V/V
CET_SS
Restore SSP.
RSTORSSP m64
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
M
ModRM:r/m (r, w)
N/A
N/A
N/A
Description
Restores SSP from the shadow-stack-restore token pointed to by m64. If the SSP restore was successful then the
instruction replaces the shadow-stack-restore token with a previous-ssp token. The instruction sets the CF flag to
indicate whether the SSP address recorded in the shadow-stack-restore token that was processed was 4 byte
aligned, i.e., whether an alignment hole was created when the restore-shadow-stack token was pushed on this
shadow stack.
Following RSTORSSP if a restore-shadow-stack token needs to be saved on the previous shadow stack, use the
SAVEPREVSSP instruction.
If pushing a restore-shadow-stack token on the previous shadow stack is not required, the previous-ssp token can
be popped using the INCSSPQ instruction. If the CF flag was set to indicate presence of an alignment hole, an addi-
tional INCSSPD instruction is needed to advance the SSP past the alignment hole.
Operation
IF CPL = 3
IF (CR4.CET & IA32_U_CET.SH_STK_EN) = 0
THEN #UD; FI;
ELSE
IF (CR4.CET & IA32_S_CET.SH_STK_EN) = 0
THEN #UD; FI;
FI;
SSP_LA = Linear_Address(mem operand)
IF SSP_LA not aligned to 8 bytes
THEN #GP(0); FI;
previous_ssp_token = SSP | (IA32_EFER.LMA AND CS.L) | 0x02
Start Atomic Execution
restore_ssp_token = Locked shadow_stack_load 8 bytes from SSP_LA
fault = 0
IF ((restore_ssp_token & 0x03) != (IA32_EFER.LMA & CS.L))
THEN fault = 1; FI;
(* If L flag in token does not match IA32_EFER.LMA & CS.L or bit 1 is not 0 *)
IF ((IA32_EFER.LMA AND CS.L) = 0 AND restore_ssp_token[63:32] != 0)
THEN fault = 1; FI;
(* If compatibility/legacy mode and SSP to be restored not below 4G *)
TMP = restore_ssp_token & ~0x01
TMP = (TMP - 8)
TMP = TMP & ~0x07
IF TMP != SSP_LA
RSTORSSP-Restore Saved Shadow Stack Pointer
Vol. 2B
4-587
INSTRUCTION SET REFERENCE, M-U
THEN fault = 1; FI;
(* If address in token does not match the requested top of stack *)
TMP = (fault == 0) ? previous_ssp_token : restore_ssp_token
shadow_stack_store 8 bytes of TMP to SSP_LA and release lock
End Atomic Execution
IF fault == 1
THEN #CP(RSTORSSP); FI;
SSP = SSP_LA
// Set the CF if the SSP in the restore token was 4 byte aligned, i.e., there is an alignment hole
RFLAGS.CF = (restore_ssp_token & 0x04) ? 1 : 0;
RFLAGS.ZF,PF,AF,OF,SF := 0;
Flags Affected
CF is set to indicate if the shadow stack pointer in the restore token was 4 byte aligned, else it is cleared. ZF, PF, AF,
OF, and SF are cleared.
C/C++ Compiler Intrinsic Equivalent
RSTORSSP void _rstorssp(void *);
Protected Mode Exceptions
#UD
If the LOCK prefix is used.
If CR4.CET = 0.
IF CPL = 3 and IA32_U_CET.SH_STK_EN = 0.
IF CPL < 3 and IA32_S_CET.SH_STK_EN = 0.
#GP(0)
If linear address of memory operand not 8 byte aligned.
If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
If destination is located in a non-writeable segment.
If the DS, ES, FS, or GS register is used to access memory and it contains a NULL segment
selector.
#SS(0)
If a memory operand effective address is outside the SS segment limit.
#CP(rstorssp)
If L bit in token does not match (IA32_EFER.LMA & CS.L).
If address in token does not match linear address of memory operand.
If in 32-bit or compatibility mode and the address in token is not below 4G.
#PF(fault-code)
If a page fault occurs.
Real-Address Mode Exceptions
#UD
The RSTORSSP instruction is not recognized in real-address mode.
Virtual-8086 Mode Exceptions
#UD
The RSTORSSP instruction is not recognized in virtual-8086 mode.
Compatibility Mode Exceptions
Same as protected mode exceptions.
4-588
Vol. 2B
RSTORSSP-Restore Saved Shadow Stack Pointer
INSTRUCTION SET REFERENCE, M-U
64-Bit Mode Exceptions
#UD
If the LOCK prefix is used.
If CR4.CET = 0.
If CPL = 3 and IA32_U_CET.SH_STK_EN = 0.
If CPL < 3 and IA32_S_CET.SH_STK_EN = 0.
#GP(0)
If linear address of memory operand not 8 byte aligned.
If a memory address is in a non-canonical form.
#SS(0)
If a memory address referencing the SS segment is in a non-canonical form.
#CP(rstorssp)
If L bit in token does not match (IA32_EFER.LMA & CS.L).
If address in token does not match linear address of memory operand.
#PF(fault-code)
If a page fault occurs.
RSTORSSP-Restore Saved Shadow Stack Pointer
Vol. 2B
4-589
INSTRUCTION SET REFERENCE, M-U
SAHF-Store AH Into Flags
Opcode1
Instruction
Op/
64-Bit
Compat/
Description
En
Mode
Leg Mode
9E
SAHF
ZO
Invalid*
Valid
Loads SF, ZF, AF, PF, and CF from AH into the EFLAGS
register.
NOTES:
1. Valid in specific steppings. See Description section.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
ZO
N/A
N/A
N/A
N/A
Description
Loads the SF, ZF, AF, PF, and CF flags of the EFLAGS register with values from the corresponding bits in the AH
register (bits 7, 6, 4, 2, and 0, respectively). Bits 1, 3, and 5 of register AH are ignored; the corresponding reserved
bits (1, 3, and 5) in the EFLAGS register remain as shown in the “Operation” section below.
This instruction executes as described above in compatibility mode and legacy mode. It is valid in 64-bit mode only
if CPUID.80000001H:ECX.LAHF-SAHF[bit 0] = 1.
Operation
IF IA-64 Mode
THEN
IF CPUID.80000001H.ECX[0] = 1;
THEN
RFLAGS(SF:ZF:0:AF:0:PF:1:CF) := AH;
ELSE
#UD;
FI
ELSE
EFLAGS(SF:ZF:0:AF:0:PF:1:CF) := AH;
FI;
Flags Affected
The SF, ZF, AF, PF, and CF flags are loaded with values from the AH register. Bits 1, 3, and 5 of the EFLAGS register
are unaffected, with the values remaining 1, 0, and 0, respectively.
Protected Mode Exceptions
None.
Real-Address Mode Exceptions
None.
Virtual-8086 Mode Exceptions
None.
Compatibility Mode Exceptions
None.
4-590
Vol. 2B
SAHF-Store AH Into Flags
INSTRUCTION SET REFERENCE, M-U
64-Bit Mode Exceptions
#UD
If CPUID.80000001H.ECX[0] = 0.
If the LOCK prefix is used.
SAHF-Store AH Into Flags
Vol. 2B
4-591
INSTRUCTION SET REFERENCE, M-U
SAL/SAR/SHL/SHR-Shift
Opcode1
Instruction
Op/
64-Bit
Compat/
Description
En
Mode
Leg Mode
D0 /4
SAL r/m8, 1
M1
Valid
Valid
Multiply r/m8 by 2, once.
REX + D0 /4
SAL r/m82, 1
M1
Valid
N.E.
Multiply r/m8 by 2, once.
D2 /4
SAL r/m8, CL
MC
Valid
Valid
Multiply r/m8 by 2, CL times.
REX + D2 /4
SAL r/m82, CL
MC
Valid
N.E.
Multiply r/m8 by 2, CL times.
C0 /4 ib
SAL r/m8, imm8
MI
Valid
Valid
Multiply r/m8 by 2, imm8 times.
REX + C0 /4 ib
SAL r/m82, imm8
MI
Valid
N.E.
Multiply r/m8 by 2, imm8 times.
D1 /4
SAL r/m16, 1
M1
Valid
Valid
Multiply r/m16 by 2, once.
D3 /4
SAL r/m16, CL
MC
Valid
Valid
Multiply r/m16 by 2, CL times.
C1 /4 ib
SAL r/m16, imm8
MI
Valid
Valid
Multiply r/m16 by 2, imm8 times.
D1 /4
SAL r/m32, 1
M1
Valid
Valid
Multiply r/m32 by 2, once.
REX.W + D1 /4
SAL r/m64, 1
M1
Valid
N.E.
Multiply r/m64 by 2, once.
D3 /4
SAL r/m32, CL
MC
Valid
Valid
Multiply r/m32 by 2, CL times.
REX.W + D3 /4
SAL r/m64, CL
MC
Valid
N.E.
Multiply r/m64 by 2, CL times.
C1 /4 ib
SAL r/m32, imm8
MI
Valid
Valid
Multiply r/m32 by 2, imm8 times.
REX.W + C1 /4 ib
SAL r/m64, imm8
MI
Valid
N.E.
Multiply r/m64 by 2, imm8 times.
D0 /7
SAR r/m8, 1
M1
Valid
Valid
Signed divide3 r/m8 by 2, once.
REX + D0 /7
SAR r/m82, 1
M1
Valid
N.E.
Signed divide3 r/m8 by 2, once.
D2 /7
SAR r/m8, CL
MC
Valid
Valid
Signed divide3 r/m8 by 2, CL times.
REX + D2 /7
SAR r/m82, CL
MC
Valid
N.E.
Signed divide3 r/m8 by 2, CL times.
C0 /7 ib
SAR r/m8, imm8
MI
Valid
Valid
Signed divide3 r/m8 by 2, imm8 times.
REX + C0 /7 ib
SAR r/m82, imm8
MI
Valid
N.E.
Signed divide3 r/m8 by 2, imm8 times.
D1 /7
SAR r/m16,1
M1
Valid
Valid
Signed divide3 r/m16 by 2, once.
D3 /7
SAR r/m16, CL
MC
Valid
Valid
Signed divide3 r/m16 by 2, CL times.
C1 /7 ib
SAR r/m16, imm8
MI
Valid
Valid
Signed divide3 r/m16 by 2, imm8 times.
D1 /7
SAR r/m32, 1
M1
Valid
Valid
Signed divide3 r/m32 by 2, once.
REX.W + D1 /7
SAR r/m64, 1
M1
Valid
N.E.
Signed divide3 r/m64 by 2, once.
D3 /7
SAR r/m32, CL
MC
Valid
Valid
Signed divide3 r/m32 by 2, CL times.
REX.W + D3 /7
SAR r/m64, CL
MC
Valid
N.E.
Signed divide3 r/m64 by 2, CL times.
C1 /7 ib
SAR r/m32, imm8
MI
Valid
Valid
Signed divide3 r/m32 by 2, imm8 times.
REX.W + C1 /7 ib
SAR r/m64, imm8
MI
Valid
N.E.
Signed divide3 r/m64 by 2, imm8 times
D0 /4
SHL r/m8, 1
M1
Valid
Valid
Multiply r/m8 by 2, once.
REX + D0 /4
SHL r/m82, 1
M1
Valid
N.E.
Multiply r/m8 by 2, once.
D2 /4
SHL r/m8, CL
MC
Valid
Valid
Multiply r/m8 by 2, CL times.
REX + D2 /4
SHL r/m82, CL
MC
Valid
N.E.
Multiply r/m8 by 2, CL times.
C0 /4 ib
SHL r/m8, imm8
MI
Valid
Valid
Multiply r/m8 by 2, imm8 times.
REX + C0 /4 ib
SHL r/m82, imm8
MI
Valid
N.E.
Multiply r/m8 by 2, imm8 times.
D1 /4
SHL r/m16,1
M1
Valid
Valid
Multiply r/m16 by 2, once.
D3 /4
SHL r/m16, CL
MC
Valid
Valid
Multiply r/m16 by 2, CL times.
C1 /4 ib
SHL r/m16, imm8
MI
Valid
Valid
Multiply r/m16 by 2, imm8 times.
D1 /4
SHL r/m32,1
M1
Valid
Valid
Multiply r/m32 by 2, once.
4-592
Vol. 2B
SAL/SAR/SHL/SHR-Shift
INSTRUCTION SET REFERENCE, M-U
Opcode1
Instruction
Op/
64-Bit
Compat/
Description
En
Mode
Leg Mode
REX.W + D1 /4
SHL r/m64,1
M1
Valid
N.E.
Multiply r/m64 by 2, once.
D3 /4
SHL r/m32, CL
MC
Valid
Valid
Multiply r/m32 by 2, CL times.
REX.W + D3 /4
SHL r/m64, CL
MC
Valid
N.E.
Multiply r/m64 by 2, CL times.
C1 /4 ib
SHL r/m32, imm8
MI
Valid
Valid
Multiply r/m32 by 2, imm8 times.
REX.W + C1 /4 ib
SHL r/m64, imm8
MI
Valid
N.E.
Multiply r/m64 by 2, imm8 times.
D0 /5
SHR r/m8,1
M1
Valid
Valid
Unsigned divide r/m8 by 2, once.
REX + D0 /5
SHR r/m82, 1
M1
Valid
N.E.
Unsigned divide r/m8 by 2, once.
D2 /5
SHR r/m8, CL
MC
Valid
Valid
Unsigned divide r/m8 by 2, CL times.
REX + D2 /5
SHR r/m82, CL
MC
Valid
N.E.
Unsigned divide r/m8 by 2, CL times.
C0 /5 ib
SHR r/m8, imm8
MI
Valid
Valid
Unsigned divide r/m8 by 2, imm8 times.
REX + C0 /5 ib
SHR r/m82, imm8
MI
Valid
N.E.
Unsigned divide r/m8 by 2, imm8 times.
D1 /5
SHR r/m16, 1
M1
Valid
Valid
Unsigned divide r/m16 by 2, once.
D3 /5
SHR r/m16, CL
MC
Valid
Valid
Unsigned divide r/m16 by 2, CL times
C1 /5 ib
SHR r/m16, imm8
MI
Valid
Valid
Unsigned divide r/m16 by 2, imm8 times.
D1 /5
SHR r/m32, 1
M1
Valid
Valid
Unsigned divide r/m32 by 2, once.
REX.W + D1 /5
SHR r/m64, 1
M1
Valid
N.E.
Unsigned divide r/m64 by 2, once.
D3 /5
SHR r/m32, CL
MC
Valid
Valid
Unsigned divide r/m32 by 2, CL times.
REX.W + D3 /5
SHR r/m64, CL
MC
Valid
N.E.
Unsigned divide r/m64 by 2, CL times.
C1 /5 ib
SHR r/m32, imm8
MI
Valid
Valid
Unsigned divide r/m32 by 2, imm8 times.
REX.W + C1 /5 ib
SHR r/m64, imm8
MI
Valid
N.E.
Unsigned divide r/m64 by 2, imm8 times.
NOTES:
1. See the IA-32 Architecture Compatibility section below.
2. In 64-bit mode, r/m8 can not be encoded to access the following byte registers if a REX prefix is used: AH, BH, CH, DH.
3. Not the same form of division as IDIV; rounding is toward negative infinity.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
M1
ModRM:r/m (r, w)
1
N/A
N/A
MC
ModRM:r/m (r, w)
CL
N/A
N/A
MI
ModRM:r/m (r, w)
imm8
N/A
N/A
Description
Shifts the bits in the first operand (destination operand) to the left or right by the number of bits specified in the
second operand (count operand). Bits shifted beyond the destination operand boundary are first shifted into the CF
flag, then discarded. At the end of the shift operation, the CF flag contains the last bit shifted out of the destination
operand.
The destination operand can be a register or a memory location. The count operand can be an immediate value or
the CL register. The count is masked to 5 bits (or 6 bits with a 64-bit operand). The count range is limited to 0 to
31 (or 63 with a 64-bit operand). A special opcode encoding is provided for a count of 1.
The shift arithmetic left (SAL) and shift logical left (SHL) instructions perform the same operation; they shift the
bits in the destination operand to the left (toward more significant bit locations). For each shift count, the most
significant bit of the destination operand is shifted into the CF flag, and the least significant bit is cleared (see
Figure 7-7 in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1).
SAL/SAR/SHL/SHR-Shift
Vol. 2B
4-593
INSTRUCTION SET REFERENCE, M-U
The shift arithmetic right (SAR) and shift logical right (SHR) instructions shift the bits of the destination operand to
the right (toward less significant bit locations). For each shift count, the least significant bit of the destination
operand is shifted into the CF flag, and the most significant bit is either set or cleared depending on the instruction
type. The SHR instruction clears the most significant bit (see Figure 7-8 in the Intel® 64 and IA-32 Architectures
Software Developer’s Manual, Volume 1); the SAR instruction sets or clears the most significant bit to correspond
to the sign (most significant bit) of the original value in the destination operand. In effect, the SAR instruction fills
the empty bit position’s shifted value with the sign of the unshifted value (see Figure 7-9 in the Intel® 64 and IA-32
Architectures Software Developer’s Manual, Volume 1).
The SAR and SHR instructions can be used to perform signed or unsigned division, respectively, of the destination
operand by powers of 2. For example, using the SAR instruction to shift a signed integer 1 bit to the right divides
the value by 2.
Using the SAR instruction to perform a division operation does not produce the same result as the IDIV instruction.
The quotient from the IDIV instruction is rounded toward zero, whereas the “quotient” of the SAR instruction is
rounded toward negative infinity. This difference is apparent only for negative numbers. For example, when the
IDIV instruction is used to divide -9 by 4, the result is -2 with a remainder of -1. If the SAR instruction is used to
shift -9 right by two bits, the result is -3 and the “remainder” is +3; however, the SAR instruction stores only the
most significant bit of the remainder (in the CF flag).
The OF flag is affected only on 1-bit shifts. For left shifts, the OF flag is set to 0 if the most-significant bit of the
result is the same as the CF flag (that is, the top two bits of the original operand were the same); otherwise, it is
set to 1. For the SAR instruction, the OF flag is cleared for all 1-bit shifts. For the SHR instruction, the OF flag is set
to the most-significant bit of the original operand.
In 64-bit mode, the instruction’s default operation size is 32 bits and the mask width for CL is 5 bits. Using a REX
prefix in the form of REX.R permits access to additional registers (R8-R15). Using a REX prefix in the form of REX.W
promotes operation to 64-bits and sets the mask width for CL to 6 bits. See the summary chart at the beginning of
this section for encoding data and limits.
IA-32 Architecture Compatibility
The 8086 does not mask the shift count. However, all other IA-32 processors (starting with the Intel 286 processor)
do mask the shift count to 5 bits, resulting in a maximum count of 31. This masking is done in all operating modes
(including the virtual-8086 mode) to reduce the maximum execution time of the instructions.
Operation
IF OperandSize = 64
THEN
countMASK := 3FH;
ELSE
countMASK := 1FH;
FI
tempCOUNT := (COUNT AND countMASK);
tempDEST := DEST;
WHILE (tempCOUNT ≠ 0)
DO
IF instruction is SAL or SHL
THEN
CF := MSB(DEST);
ELSE (* Instruction is SAR or SHR *)
CF := LSB(DEST);
FI;
IF instruction is SAL or SHL
THEN
DEST := DEST ∗ 2;
ELSE
IF instruction is SAR
4-594
Vol. 2B
SAL/SAR/SHL/SHR-Shift
INSTRUCTION SET REFERENCE, M-U
THEN
DEST := DEST / 2; (* Signed divide, rounding toward negative infinity *)
ELSE (* Instruction is SHR *)
DEST := DEST / 2 ; (* Unsigned divide *)
FI;
FI;
tempCOUNT := tempCOUNT - 1;
OD;
(* Determine overflow for the various instructions *)
IF (COUNT and countMASK) = 1
THEN
IF instruction is SAL or SHL
THEN
OF := MSB(DEST) XOR CF;
ELSE
IF instruction is SAR
THEN
OF := 0;
ELSE (* Instruction is SHR *)
OF := MSB(tempDEST);
FI;
FI;
ELSE IF (COUNT AND countMASK) = 0
THEN
All flags unchanged;
ELSE (* COUNT not 1 or 0 *)
OF := undefined;
FI;
FI;
Flags Affected
The CF flag contains the value of the last bit shifted out of the destination operand; it is undefined for SHL and SHR
instructions where the count is greater than or equal to the size (in bits) of the destination operand. The OF flag is
affected only for 1-bit shifts (see “Description” above); otherwise, it is undefined. The SF, ZF, and PF flags are set
according to the result. If the count is 0, the flags are not affected. For a non-zero count, the AF flag is undefined.
Protected Mode Exceptions
#GP(0)
If the destination is located in a non-writable segment.
If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
If the DS, ES, FS, or GS register contains a NULL segment selector.
#SS(0)
If a memory operand effective address is outside the SS segment limit.
#PF(fault-code)
If a page fault occurs.
#AC(0)
If alignment checking is enabled and an unaligned memory reference is made while the
current privilege level is 3.
#UD
If the LOCK prefix is used.
Real-Address Mode Exceptions
#GP
If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#SS
If a memory operand effective address is outside the SS segment limit.
#UD
If the LOCK prefix is used.
SAL/SAR/SHL/SHR-Shift
Vol. 2B
4-595
INSTRUCTION SET REFERENCE, M-U
Virtual-8086 Mode Exceptions
#GP(0)
If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#SS(0)
If a memory operand effective address is outside the SS segment limit.
#PF(fault-code)
If a page fault occurs.
#AC(0)
If alignment checking is enabled and an unaligned memory reference is made.
#UD
If the LOCK prefix is used.
Compatibility Mode Exceptions
Same exceptions as in protected mode.
64-Bit Mode Exceptions
#SS(0)
If a memory address referencing the SS segment is in a non-canonical form.
#GP(0)
If the memory address is in a non-canonical form.
#PF(fault-code)
If a page fault occurs.
#AC(0)
If alignment checking is enabled and an unaligned memory reference is made while the
current privilege level is 3.
#UD
If the LOCK prefix is used.
4-596
Vol. 2B
SAL/SAR/SHL/SHR-Shift
INSTRUCTION SET REFERENCE, M-U
SARX/SHLX/SHRX-Shift Without Affecting Flags
Opcode/
Op/
64/32-
CPUID
Description
Instruction
En
bit Mode
Feature
Flag
VEX.LZ.F3.0F38.W0 F7 /r
RMV
V/V
BMI2
Shift r/m32 arithmetically right with count specified in r32b.
SARX r32a, r/m32, r32b
VEX.LZ.66.0F38.W0 F7 /r
RMV
V/V
BMI2
Shift r/m32 logically left with count specified in r32b.
SHLX r32a, r/m32, r32b
VEX.LZ.F2.0F38.W0 F7 /r
RMV
V/V
BMI2
Shift r/m32 logically right with count specified in r32b.
SHRX r32a, r/m32, r32b
VEX.LZ.F3.0F38.W1 F7 /r
RMV
V/N.E.
BMI2
Shift r/m64 arithmetically right with count specified in r64b.
SARX r64a, r/m64, r64b
VEX.LZ.66.0F38.W1 F7 /r
RMV
V/N.E.
BMI2
Shift r/m64 logically left with count specified in r64b.
SHLX r64a, r/m64, r64b
VEX.LZ.F2.0F38.W1 F7 /r
RMV
V/N.E.
BMI2
Shift r/m64 logically right with count specified in r64b.
SHRX r64a, r/m64, r64b
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
RMV
ModRM:reg (w)
ModRM:r/m (r)
VEX.vvvv (r)
N/A
Description
Shifts the bits of the first source operand (the second operand) to the left or right by a COUNT value specified in the
second source operand (the third operand). The result is written to the destination operand (the first operand).
The shift arithmetic right (SARX) and shift logical right (SHRX) instructions shift the bits of the destination operand
to the right (toward less significant bit locations), SARX keeps and propagates the most significant bit (sign bit)
while shifting.
The logical shift left (SHLX) shifts the bits of the destination operand to the left (toward more significant bit loca-
tions).
This instruction is not supported in real mode and virtual-8086 mode. The operand size is always 32 bits if not in
64-bit mode. In 64-bit mode operand size 64 requires VEX.W1. VEX.W1 is ignored in non-64-bit modes. An
attempt to execute this instruction with VEX.L not equal to 0 will cause #UD.
If the value specified in the first source operand exceeds OperandSize -1, the COUNT value is masked.
SARX,SHRX, and SHLX instructions do not update flags.
Operation
TEMP := SRC1;
IF VEX.W1 and CS.L = 1
THEN
countMASK := 3FH;
ELSE
countMASK := 1FH;
FI
COUNT := (SRC2 AND countMASK)
DEST[OperandSize -1] = TEMP[OperandSize -1];
DO WHILE (COUNT ≠ 0)
IF instruction is SHLX
THEN
SARX/SHLX/SHRX-Shift Without Affecting Flags
Vol. 2B
4-597
INSTRUCTION SET REFERENCE, M-U
DEST[] := DEST *2;
ELSE IF instruction is SHRX
THEN
DEST[] := DEST /2; //unsigned divide
ELSE
// SARX
DEST[] := DEST /2; // signed divide, round toward negative infinity
FI;
COUNT := COUNT - 1;
OD
Flags Affected
None.
Intel C/C++ Compiler Intrinsic Equivalent
Auto-generated from high-level language.
SIMD Floating-Point Exceptions
None.
Other Exceptions
See Table 2-29, “Type 13 Class Exception Conditions.”
4-598
Vol. 2B
SARX/SHLX/SHRX-Shift Without Affecting Flags
|
||
|
|
|