Mobile and Desktop Processors
Intel® Core™ processors, Intel Atom® processors, tools, and utilities
17287 Discussions

Pseudocode inconsistency: shift/rotate instructions missing zero-extension on count=0 path

rui314
Beginner
685 Views

Hi,

I'd like to report an inconsistency in the Intel 64 and IA-32 Architectures Software Developer's Manual between the pseudocode for Group 2 shift/rotate instructions and the general zero-extension rule for 32-bit operands in 64-bit mode.

The general rule (Vol. 1, Section 3.4.1.1, "General-Purpose Registers in 64-Bit Mode"):

"32-bit operands generate a 32-bit result, zero-extended to a 64-bit result in the destination general-purpose register."

The pseudocode (SAL/SAR/SHL/SHR, Vol. 2):

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
                THEN
                    DEST := DEST / 2;
                ELSE (* Instruction is SHR *)
                    DEST := DEST / 2;
            FI;
    FI;
    tempCOUNT := tempCOUNT - 1;
OD;
(* Determine overflow for the various instructions *)
IF (COUNT and countMASK) = 1
    THEN ...
    ELSE IF (COUNT AND countMASK) = 0
        THEN
            All flags unchanged; <--- (A)
        ELSE (* COUNT not 1 or 0 *)
            OF := undefined;
    FI;
FI;

When COUNT=0, the WHILE loop is never entered, so DEST is never assigned. The pseudocode falls through to (A), "All flags unchanged", and returns — treating this as a complete no-op.

The same pattern appears in the rotate pseudocode (ROL/ROR/RCL/RCR), where the WHILE loop is similarly skipped and DEST is never written when the masked count is zero.

The problem:

For SHL r/m32, 0 (or any of the other 7 instructions with r/m32 and count=0) in 64-bit mode, the pseudocode implies no write to DEST occurs. A reader following the pseudocode alone would conclude the upper 32 bits of the 64-bit register are preserved. However, Section 3.4.1.1 states that 32-bit results always zero-extend, and real hardware confirms this — the upper 32 bits are zeroed even when the shift count is 0.

Hardware test (x86 64-bit mode):

mov rax, 0xFFFFFFFF_00000001 ; upper 32 bits set
shl eax, 0 ; count = 0
; Result: RAX = 0x00000000_00000001 (upper 32 bits zeroed)

Suggested fix:

Add an explicit write-back of DEST on the count=0 path (e.g., DEST := tempDEST), or add a note clarifying that the 32-bit zero-extension rule from Section 3.4.1.1 still applies regardless of count.

This affects all eight Group 2 instructions: SAL, SAR, SHL, SHR, ROL, ROR, RCL, and RCR.

0 Kudos
1 Reply
CM_Intel
Moderator
653 Views

Hello rui314,

 

Thank you for joining this Community. Your question is regarding our Intel® Developer zone so we will transfer this to our Programs Support Team and they will contact you back via email as soon as possible.


Best regards,

CM

Intel Customer Support Technician


0 Kudos
Reply