New P6 OpCodes: CMOV


CMOV - 0F 4x - Conditional Move


                                                             CMOV
Flags:                                      Conditional MOVE data
+-+-+-+-+-+-+-+-+-+         +----------+----------+-------------+
|O|D|I|T|S|Z|A|P|C|         | 00001111 | 0100cccc | mod,reg,r/m |
+-+-+-+-+-+-+-+-+-+         +----------+----------+-------------+
| | | | | | | | | |         |    0F    |    4x    |      xx     |
+-+-+-+-+-+-+-+-+-+         +----------+----------+-------------+

Syntax:

    CMOVcc      r16,r/m16
    CMOVcc      r32,r/m32

Operation:

CMOV {
    IF source_operand = mem {
        TEMP = [mem];              /* This may cause a #GP or other fault */
        IF condition {
            DEST = TEMP;
        }
    } ELSE {
        IF condition {
            DEST = SOURCE;
        }
    }
}

Description:

If the condition specified in the opcode (cc) is met, then the source operand is written to the destination operand. If the source operand is a memory operand, then regardless of the condition, the memory operand is read. This indicates that if the memory read operation would generate a fault (#GP or #PG), then even though the condition may be false, the fault occurs. The source and destination operands are always 16 or 32-bit. There is no provisions for an 8-bit version of this instruction. Naturally, the operand size is determined by the current operating mode, and subject to an operand size override.

The conditions specified in the condition bits (cc) follow the same format as those of the conditional jump instructions (Jcc) and conditional set instructions (SETcc).

Example:

The first example is the operation performed as if CMOV didn't exist. The second example gives the same results, but uses CMOV.

    XOR     EBX,EBX                ; Clear register for later
    ADD     ECX,[SMALL_COUNT]      ; Adjusts by some small counter value
    JNC     Continue               ; If ECX didn't overflow, continue
    MOV     ECX,EBX                ; Reinitialize ECX if it overflowed
Continue:

Using CMOV:

    XOR     EBX,EBX                ; Clear register for later
    ADD     ECX,[SMALL_COUNT]      ; Adjusts by some small counter value
    CMOVC   ECX,EBX                ; If ECX overflowed, reinitialize to EBX

As you can see from this example, the goal was to reinitialize ECX to 0, if it overflowed during an ADD operation. Since this was the only condition where we wanted to reinitialize ECX, the branch would be taken almost all of the time, until an overflow occurs. By using the CMOV instruction, the JMP is avoided virtually all of the time.

Flags affected:

None.

Exceptions:

If the source operand is a memory operand, then it is always read, regardless of whether or not the condition is met. This means that whatever exception would have been generated from the memory read, will get generated. If the memory read would have caused a #GP or #PG, then so be it.


Get description of        [AAM]        [AAD]        [UMOV]       [LOADALL]
New P6 OpCodes            [FCMOV]      [FCOMI]      [RDPMC]
                          [INT01]      [SALC]       [UD2]