Fused Multiply-Add Scalar Single (4-iterations)

Summary: 4-way FMA for Neural Nets (Scalar).

XMM register pair (consecutive even+odd registers)

Performs four iterations of fused multiply-add on scalar single-precision floating-point operands, accumulating results into the low dword of xmm1. The instruction reads from a consecutive XMM register pair (xmm2:xmm3) and a 128-bit memory operand, computing four parallel multiply-accumulate operations into the scalar. Masked by k1; floating-point exceptions may be signaled; rounding is per MXCSR; high 96 bits of xmm1 are cleared.


Fused Negative Multiply-Add Packed Single (4-iterations)

Summary: 4-way Negative FMA for Neural Nets (Single).

ZMM register pair (consecutive even+odd registers, for 4-iteration FMA)

Performs four iterations of fused negative multiply-add on packed single-precision floating-point operands, computing -(zmm2×m128) + zmm1, accumulating results into zmm1. The instruction reads from a consecutive ZMM register pair (zmm2:zmm3) and a 128-bit memory operand, executing four parallel negated multiply-accumulate chains. Masked by k1; floating-point exceptions may be signaled; rounding is per MXCSR.


Fused Negative Multiply-Add Scalar Single (4-iterations)

Summary: 4-way Negative FMA for Neural Nets (Scalar).

Performs four iterations of fused negative multiply-add on scalar single-precision floating-point values, computing -(src1[i] * src2[i]) + dest for four pairs of operands. This instruction is specialized for neural network operations and executes within a single macro-op, improving throughput for repeated FMA patterns. All MXCSR exception flags may be set based on intermediate results; the result is written to dest with optional write-masking via k1.

for i in 0 to 3:
  temp ← -(xmm2[i] * m128[i])
  xmm1[i] ← temp + xmm1[i]
  update_MXCSR_flags(temp, xmm1[i])


Convert Packed Doubleword to Packed Single

Summary: Converts four 32-bit integers to floats.

src

256-bit YMM AVX register or Memory operand

Converts four packed 32-bit signed doubleword integers to four packed single-precision floating-point values. The conversion uses the current MXCSR rounding mode; inexact results may set the PE (precision exception) flag in MXCSR. Available in 128-bit (XMM) and 256-bit (YMM) variants; the 256-bit form converts eight integers. No legacy flags are modified.

if VEX.L = 0:
  for i in 0 to 1:
    xmm1[i] ← convert_dword_to_float(xmm2[i])
else:
  for i in 0 to 3:
    ymm1[i] ← convert_dword_to_float(ymm2[i])
update_MXCSR_flags()


Convert Packed Single to Packed Doubleword

Summary: Converts four floats to 32-bit integers (Rounded).

Converts four packed single-precision floating-point values to four packed 32-bit signed doubleword integers using the current MXCSR rounding mode. Overflowing results saturate to INT32_MIN or INT32_MAX; inexact results may set the PE flag in MXCSR. Available in 128-bit (XMM) and 256-bit (YMM) variants; the 256-bit form converts eight floats. No legacy x86 flags are modified.

if VEX.L = 0:
  for i in 0 to 1:
    xmm1[i] ← convert_float_to_dword_rounded(xmm2[i])
else:
  for i in 0 to 3:
    ymm1[i] ← convert_float_to_dword_rounded(ymm2[i])
update_MXCSR_flags()


Convert with Truncation Packed Single to Doubleword

Summary: Converts four floats to 32-bit integers (Truncated).

Converts four packed single-precision floating-point values to four packed 32-bit signed doubleword integers by truncating toward zero (ignoring MXCSR rounding mode). Overflowing results saturate to INT32_MIN or INT32_MAX; inexact results may set the PE flag in MXCSR. Available in 128-bit (XMM) and 256-bit (YMM) variants; the 256-bit form converts eight floats. No legacy x86 flags are modified.

if VEX.L = 0:
  for i in 0 to 1:
    xmm1[i] ← convert_float_to_dword_truncate(xmm2[i])
else:
  for i in 0 to 3:
    ymm1[i] ← convert_float_to_dword_truncate(ymm2[i])
update_MXCSR_flags()


Summary: Returns from an interrupt, exception, or task handler.

Returns from an interrupt handler, exception handler, or nested task by popping the return address and EFLAGS from the stack and resuming execution at the interrupted instruction. In protected mode, also restores CPL and task context; in 64-bit mode (IRETQ), pops a 64-bit return address. This instruction performs memory serialization and may reload segment registers, making it a heavy-weight operation that flushes pending stores.

if OperandSize = 16:
  temp_IP ← [SP]; SP ← SP + 2
  temp_CS ← [SP]; SP ← SP + 2
  EFLAGS ← [SP]; SP ← SP + 2
else if OperandSize = 32:
  temp_EIP ← [ESP]; ESP ← ESP + 4
  temp_CS ← [ESP]; ESP ← ESP + 4
  EFLAGS ← [ESP]; ESP ← ESP + 4
else if OperandSize = 64:
  temp_RIP ← [RSP]; RSP ← RSP + 8
  temp_CS ← [RSP]; RSP ← RSP + 8
  EFLAGS ← [RSP]; RSP ← RSP + 8
CS ← temp_CS
IP/EIP/RIP ← temp_IP/EIP/RIP


Summary: Returns from interrupt (32-bit operand size).

Returns from an interrupt handler by explicitly using 32-bit operand size, popping the 32-bit return address (EIP) and EFLAGS from the stack. In protected mode, also restores the code segment (CS) and CPL; in real mode, only pops EIP and EFLAGS. This instruction serializes memory and may trigger privilege-level transitions or task switches, causing pipeline flushing.

temp_EIP ← [ESP]; ESP ← ESP + 4
temp_CS ← [ESP]; ESP ← ESP + 4
temp_EFLAGS ← [ESP]; ESP ← ESP + 4
CS ← temp_CS
EIP ← temp_EIP
EFLAGS ← temp_EFLAGS


Summary: Returns from interrupt (64-bit operand size).

Returns from an interrupt handler using 64-bit operand size, popping the 64-bit return address (RIP), code segment (CS), and RFLAGS from the stack. Exclusively available in 64-bit long mode; enables return to user-mode code and handles CPL transitions. This is a heavy-weight serializing instruction that flushes pending operations and may reload hidden segment state.

temp_RIP ← [RSP]; RSP ← RSP + 8
temp_CS ← [RSP]; RSP ← RSP + 8
temp_RFLAGS ← [RSP]; RSP ← RSP + 8
CS ← temp_CS
RIP ← temp_RIP
RFLAGS ← temp_RFLAGS


Summary: Reads data from I/O port specified in DX.

dest

Implicit accumulator: AL, AX, or EAX (depends on operand size)

Reads 8, 16, or 32 bits from an I/O port whose address is specified in the DX register and stores the result in the AL, AX, or EAX accumulator respectively. The port number in DX is zero-extended to a full I/O address; I/O addressing and privilege checks are performed according to the IOPL field and TSS I/O bitmap. This instruction does not modify any flag bits and may have side effects on the I/O device.

port_address ← DX
if operand_size = 8:
  AL ← I/O_Read(port_address, 1)
else if operand_size = 16:
  AX ← I/O_Read(port_address, 2)
else if operand_size = 32:
  EAX ← I/O_Read(port_address, 4)


Summary: Writes data to I/O port specified in DX.

Writes data from the accumulator (AL, AX, or EAX depending on operand size) to an I/O port whose address is specified in the DX register. This instruction is used for legacy port-based I/O and requires I/O privilege level (IOPL) in protected/long modes. No CPU flags are affected.

port_address ← DX; if (operand_size == 8) { I/O[port_address] ← AL; } else if (operand_size == 16) { I/O[port_address] ← AX; } else if (operand_size == 32) { I/O[port_address] ← EAX; }


Summary: Counts set bits in each quadword element.

src

512-bit ZMM AVX-512 register or Memory operand

Counts the number of set bits (population count) in each 64-bit quadword element of the source operand and stores the result in the destination ZMM register. This is an AVX-512-VPOPCNTDQ instruction that operates on 512-bit vectors (8 quadwords). Masking via the opmask register k1 can selectively update or zero destination elements; no CPU arithmetic flags are modified.

for i ← 0 to 7 do { if (k1[i] or not_masked) { dst.qword[i] ← popcount(src.qword[i]); } else { dst.qword[i] ← 0; } }


Summary: Counts set bits in each word element.

Counts the number of set bits (population count) in each 16-bit word element of the source operand and stores the result in the destination ZMM register. This is an AVX-512-BITALG instruction that operates on 512-bit vectors (32 words). Masking via opmask register k1 allows selective element updates; no CPU arithmetic flags are modified.

for i ← 0 to 31 do { if (k1[i] or not_masked) { dst.word[i] ← popcount(src.word[i]); } else { dst.word[i] ← 0; } }


Summary: Compresses active words from ZMM to memory.

Compresses active 16-bit word elements from the source ZMM register into contiguous locations in memory, guided by the opmask register k1. Only elements where the corresponding mask bit is set are written to memory in order; unmasked elements are skipped. This is an AVX-512-VBMI2 instruction; no CPU flags are affected.

mem_offset ← 0; for i ← 0 to 31 do { if (k1[i]) { [dest + mem_offset] ← src.word[i]; mem_offset ← mem_offset + 2; } }


Summary: Expands words from memory into sparse locations in ZMM.

Expands 16-bit word elements from memory into sparse positions within the destination ZMM register, guided by the opmask register k1. Words are read sequentially from memory and written to destination positions where the corresponding mask bit is set. This is an AVX-512-VBMI2 instruction; no CPU flags are affected.

mem_offset ← 0; for i ← 0 to 31 do { if (k1[i]) { dst.word[i] ← [src + mem_offset]; mem_offset ← mem_offset + 2; } else { dst.word[i] ← 0; } }


Summary: Funnel shift left of words.

VPSHLDW zmm1 {k1}, zmm2, zmm3/m512, imm8

Performs a funnel (concatenate and shift) left operation on pairs of 16-bit word elements: the result is (src1 || src2) shifted left by the count specified in imm8 modulo 16. This is an AVX-512-VBMI2 instruction operating on 32 word elements per 512-bit vector. Masking via k1 allows selective updates; no CPU arithmetic flags are modified.

for i ← 0 to 31 do { if (k1[i] or not_masked) { combined ← (src1.word[i] << 16) | src2.word[i]; shift_count ← imm8 & 0xF; dst.word[i] ← (combined >> (16 - shift_count)) & 0xFFFF; } }


Summary: Funnel shift left of quadwords.

VPSHLDQ zmm1 {k1}, zmm2, zmm3/m512, imm8

Performs a funnel (concatenate and shift) left operation on pairs of 64-bit quadword elements: the result is (src1 || src2) shifted left by the count specified in imm8 modulo 64. This is an AVX-512-VBMI2 instruction operating on 8 quadword elements per 512-bit vector. Masking via k1 allows selective updates; no CPU arithmetic flags are modified.

for i ← 0 to 7 do { if (k1[i] or not_masked) { combined_hi ← src1.qword[i]; combined_lo ← src2.qword[i]; shift_count ← imm8 & 0x3F; if (shift_count == 0) { dst.qword[i] ← combined_lo; } else if (shift_count < 64) { dst.qword[i] ← (combined_lo >> (64 - shift_count)) | (combined_hi << shift_count); } else { dst.qword[i] ← combined_hi << (shift_count - 64); } } }


Summary: Funnel shift right of words.

VPSHRDW zmm1 {k1}, zmm2, zmm3/m512, imm8

Performs a funnel (concatenate and shift) right operation on pairs of 16-bit word elements: the result is (src1 || src2) shifted right by the count specified in imm8 modulo 16. This is an AVX-512-VBMI2 instruction operating on 32 word elements per 512-bit vector. Masking via k1 allows selective updates; no CPU arithmetic flags are modified.

for i ← 0 to 31 do { if (k1[i] or not_masked) { combined ← (src1.word[i] << 16) | src2.word[i]; shift_count ← imm8 & 0xF; dst.word[i] ← (combined >> shift_count) & 0xFFFF; } }


Summary: Funnel shift right of quadwords.

VPSHRDQ zmm1 {k1}, zmm2, zmm3/m512, imm8

Performs a funnel shift right operation on packed 64-bit quadwords across two source operands. Each 64-bit element in zmm2 is concatenated with the corresponding element in zmm3/m512, and the result is shifted right by the amount specified in imm8 (modulo 64), with the lower bits written to zmm1. No flags are affected by this instruction.

for i = 0 to 7 {
  concatenated = (zmm3[i+1] << 64) | zmm2[i];
  zmm1[i] = (concatenated >> (imm8 % 64)) & 0xFFFFFFFFFFFFFFFF;
}


Summary: Computes intersection of two ZMM registers into mask pair.

dest

Opmask register pair (k1 and the next adjacent register)

Computes the intersection of two sets of 64-bit quadwords, producing a pair of opmask registers (k1 and k1+1) indicating which elements from the first operand have matches in the second operand. The instruction uses special hardware logic to compare quadwords and set mask bits accordingly. No arithmetic flags are affected.

for i = 0 to 7 {
  found_in_src2 = 0;
  for j = 0 to 7 {
    if (zmm2[i] == zmm3[j]) {
      found_in_src2 = 1;
      break;
    }
  }
  if (found_in_src2) k1[i] = 1; else k1[i] = 0;
  // k1+1 contains further comparison results or inverted results
}


Tile Dot Product Byte Unsigned Unsigned Doubleword

Summary: Matrix multiply (Unsigned * Unsigned) accumulating to Int32.

Performs a tile-based dot product operation on 8×32 unsigned byte matrix tmm2 and 32×8 unsigned byte matrix tmm3, accumulating the 32-bit unsigned results into 8×8 doubleword tile tmm1. The instruction uses specialized AMX hardware for fast matrix multiplication without affecting EFLAGS.

for i = 0 to 7 {
  for j = 0 to 7 {
    product = 0;
    for k = 0 to 31 {
      product += (unsigned)tmm2[i][k] * (unsigned)tmm3[k][j];
    }
    tmm1[i][j] += product;
  }
}


Tile Dot Product Byte Unsigned Signed Doubleword

Summary: Matrix multiply (Unsigned * Signed) accumulating to Int32.

Performs a tile-based dot product operation multiplying 8×32 unsigned byte matrix tmm2 by 32×8 signed byte matrix tmm3, accumulating the 32-bit signed results into 8×8 doubleword tile tmm1. This is the unsigned-by-signed variant of tile dot product, useful for mixed-precision neural network operations without affecting EFLAGS.

for i = 0 to 7 {
  for j = 0 to 7 {
    product = 0;
    for k = 0 to 31 {
      product += (unsigned)tmm2[i][k] * (signed)tmm3[k][j];
    }
    tmm1[i][j] += product;
  }
}


Summary: Loads data into an AMX tile register with T1 hint.

Loads tile data from memory into an AMX tile register with a T1 (temporal) cache hint, indicating the data is likely to be used soon. The memory operand is typically addressed via a base register and optional displacement, and the tile dimensions are pre-configured via TILECONFIG. No flags are affected.

tmm1 = load_from_memory_with_t1_hint(m);
// Tile shape determined by previously configured palette and TILECFG register


Summary: Decrypts 8 blocks using 128-bit Key Locker handle.

Decrypts 8 AES blocks (128 bits each) in parallel using a 128-bit Key Locker encrypted key handle stored at the memory operand. The ciphertext blocks are implicit in XMM0-XMM7 (input) and plaintext results are written back to XMM0-XMM7 (output). The ZF flag is set to 0 on success or 1 if the key handle is invalid.

key_handle = load_from_memory_128bit(m128);
if (key_handle_invalid(key_handle)) {
  ZF = 1;
} else {
  for i = 0 to 7 {
    XMM[i] = AES_decrypt_block(XMM[i], key_handle);
  }
  ZF = 0;
}


Summary: Decrypts 8 blocks using 256-bit Key Locker handle.

Decrypts 8 AES blocks (128 bits each) in parallel using a 256-bit Key Locker encrypted key handle stored at the memory operand. The ciphertext blocks are implicit in XMM0-XMM7 (input) and plaintext results are written back to XMM0-XMM7 (output). The ZF flag is set to 0 on success or 1 if the key handle is invalid.

key_handle = load_from_memory_128bit(m128);
if (key_handle_invalid(key_handle)) {
  ZF = 1;
} else {
  for i = 0 to 7 {
    XMM[i] = AES_decrypt_block_256bit_key(XMM[i], key_handle);
  }
  ZF = 0;
}


Summary: Wraps a 256-bit AES key into a handle.

32-bit general-purpose register (e.g. EAX)

Wraps a 256-bit AES key (provided in XMM registers via the second operand's implicit XMM context) into an encrypted handle stored in memory. This instruction is part of Intel Key Locker and requires the KEYLOCKER CPU feature. It performs cryptographic key material encoding that protects against certain side-channel attacks. No flags are modified.

handle ← AES_KW_Wrap_256bit(key_material)
dest ← handle
// XMM registers implicitly contain the 256-bit key to be encoded


Summary: Encrypts data using 256-bit Key Locker handle.

Encrypts a 128-bit plaintext block (from XMM register) using a 256-bit Key Locker handle (from memory), storing the ciphertext back into the XMM register. This requires KEYLOCKER support and performs AES-256 encryption with hardware-protected key material. Sets ZF to indicate success/failure of the operation; other flags undefined.

handle ← [dest]
ciphertext ← AES_Encrypt_256(plaintext=src, key_handle=handle)
src ← ciphertext
ZF ← (operation_successful ? 0 : 1)


Summary: Decrypts data using 256-bit Key Locker handle.

Decrypts a 128-bit ciphertext block (from XMM register) using a 256-bit Key Locker handle (from memory), storing the plaintext back into the XMM register. This requires KEYLOCKER support and performs AES-256 decryption with hardware-protected key material. Sets ZF to indicate success/failure of the operation; other flags undefined.

handle ← [dest]
plaintext ← AES_Decrypt_256(ciphertext=src, key_handle=handle)
src ← plaintext
ZF ← (operation_successful ? 0 : 1)


Summary: Writes a command to a device (Supervisor mode).

Enqueues a 512-bit command descriptor to a device queue in supervisor mode only (requires CPL=0). The command is read from memory and written to a device via a memory-mapped queue; requires ENQCMD CPU feature. Sets ZF and CF flags: ZF=1 if queue is full, CF=1 if access denied or invalid descriptor format. Other flags undefined.

if (CPL != 0) { fault ← true; return; }
descriptor ← [src]
status ← enqueue_device_command(descriptor)
dest ← status
ZF ← (queue_full ? 1 : 0)
CF ← (access_denied_or_invalid ? 1 : 0)


Summary: Suspends tracking of load addresses in a TSX suspend-tracking region (resumed with XRESLDTRK).

Suspends or resumes tracking of load operations within a TSX (Transactional Synchronization Extensions) transaction. Requires TSX support and TSX_LDTRK feature flag. Does not modify any flags. This instruction helps fine-tune transaction conflict detection by toggling whether loads are monitored for abort conditions.

if (in_transaction) {
  TSX_load_tracking_enabled ← !TSX_load_tracking_enabled
}


Summary: Fast call to privilege level 0 system procedures.

Fast low-latency call to a privilege level 0 system procedure (64-bit mode only). Loads the system call target address from IA32_LSTAR MSR, saves the return address (RIP+2) into RCX, and sets RFLAGS according to IA32_FMASK MSR. Does not set any condition flags; acts as a serializing operation. Requires 64-bit mode and supervisor software setup.

RCX ← RIP + 2
RIP ← IA32_LSTAR
RFLAGS ← RFLAGS & ~IA32_FMASK
// Transition to CPL 0 with user code segment


Summary: Fast return to privilege level 3 user code.

Fast return from a system call invoked via SYSCALL, transitioning from CPL 0 back to CPL 3. Restores the user RIP from RCX and re-enables interrupts/flags as appropriate. Requires 64-bit mode and can only be executed at CPL 0. Does not modify condition flags; serializes instruction stream.

RIP ← RCX
// Transition to CPL 3 with user code segment
// Restore RFLAGS state (interrupts re-enabled per IA32_FMASK)


Summary: Shifts bits left (Alias for SHL).

Shifts the bits of the destination operand left by the count specified (immediate or ECX). Each shifted-out bit is moved into CF; vacated bits are filled with zeros. Sets OF if the sign bit changed after the shift, CF from the last shifted bit, ZF and SF based on the result, and PF is undefined. Available in 8/16/32/64-bit variants across all modes.

if (count > 0) {
  temp_cf ← dest >> (operand_width - count)
  dest ← (dest << count) & ((1 << operand_width) - 1)
  CF ← temp_cf
  ZF ← (dest == 0 ? 1 : 0)
  SF ← (dest >> (operand_width - 1)) & 1
  if (count == 1) { OF ← (SF != CF ? 1 : 0) }
  else { OF ← undefined }
  PF ← undefined
}


Summary: Compares word at [ESI] with [EDI].

First memory operand at DS:ESI (source index register, typically data segment).

Second memory operand at ES:EDI (destination index register, typically extra segment).

Compares a word (16-bit) at memory address [ESI] with a word at [EDI] by performing an implicit subtraction ([ESI] - [EDI]), updates the EFLAGS register with the result, and increments or decrements both ESI and EDI by 2 depending on the direction flag (DF). The comparison affects OF, SF, ZF, AF, PF, and CF flags but does not modify either operand. Often used with repeat prefixes (REP, REPE, REPNE) for string comparison operations.

temp ← [ESI] - [EDI];
OF ← overflow of subtraction;
SF ← temp[15];
ZF ← (temp == 0);
AF ← auxiliary carry of subtraction;
PF ← parity of temp;
CF ← borrow;
if (DF == 0) {
  ESI ← ESI + 2;
  EDI ← EDI + 2;
} else {
  ESI ← ESI - 2;
  EDI ← EDI - 2;
}


Summary: Compares doubleword at [ESI] with [EDI].

First memory operand at DS:ESI (source index register).

Second memory operand at ES:EDI (destination index register).

Compares a doubleword (32-bit) at memory address [ESI] with a doubleword at [EDI] by performing an implicit subtraction ([ESI] - [EDI]), updates the EFLAGS register with the result, and increments or decrements both ESI and EDI by 4 depending on the direction flag (DF). The comparison affects OF, SF, ZF, AF, PF, and CF flags but does not modify either operand. Commonly used in 32-bit protected mode or with repeat prefixes for string operations.

temp ← [ESI] - [EDI];
OF ← overflow of subtraction;
SF ← temp[31];
ZF ← (temp == 0);
AF ← auxiliary carry of subtraction;
PF ← parity of temp;
CF ← borrow;
if (DF == 0) {
  ESI ← ESI + 4;
  EDI ← EDI + 4;
} else {
  ESI ← ESI - 4;
  EDI ← EDI - 4;
}


Summary: Compares quadword at [RSI] with [RDI].

First memory operand at DS:RSI (source index register in 64-bit mode).

Second memory operand at DS:RDI (destination index register in 64-bit mode).

Compares a quadword (64-bit) at memory address [RSI] with a quadword at [RDI] by performing an implicit subtraction ([RSI] - [RDI]), updates the EFLAGS register with the result, and increments or decrements both RSI and RDI by 8 depending on the direction flag (DF). The comparison affects OF, SF, ZF, AF, PF, and CF flags but does not modify either operand. Available only in 64-bit mode; operand size defaults to 64 bits.

temp ← [RSI] - [RDI];
OF ← overflow of subtraction;
SF ← temp[63];
ZF ← (temp == 0);
AF ← auxiliary carry of subtraction;
PF ← parity of temp;
CF ← borrow;
if (DF == 0) {
  RSI ← RSI + 8;
  RDI ← RDI + 8;
} else {
  RSI ← RSI - 8;
  RDI ← RDI - 8;
}


Summary: Compares AX with memory at [EDI].

AX

Implicit source register (accumulator) containing the value to be compared.

Memory operand at ES:EDI (destination index register) to be compared against AX.

Compares the word in AX with a word at memory address [EDI] by performing an implicit subtraction (AX - [EDI]), updates the EFLAGS register with the result, and increments or decrements EDI by 2 depending on the direction flag (DF). The comparison affects OF, SF, ZF, AF, PF, and CF flags but does not modify either operand. Often used with repeat prefixes (REPE, REPNE) for scanning strings in memory.

temp ← AX - [EDI];
OF ← overflow of subtraction;
SF ← temp[15];
ZF ← (temp == 0);
AF ← auxiliary carry of subtraction;
PF ← parity of temp;
CF ← borrow;
if (DF == 0) {
  EDI ← EDI + 2;
} else {
  EDI ← EDI - 2;
}


Summary: Compares EAX with memory at [EDI].

Memory operand at ES:EDI (destination index register) to be compared against EAX.

Compares the doubleword in EAX with a doubleword at memory address [EDI] by performing an implicit subtraction (EAX - [EDI]), updates the EFLAGS register with the result, and increments or decrements EDI by 4 depending on the direction flag (DF). The comparison affects OF, SF, ZF, AF, PF, and CF flags but does not modify either operand. Commonly used in 32-bit protected mode with repeat prefixes for memory scanning.

temp ← EAX - [EDI];
OF ← overflow of subtraction;
SF ← temp[31];
ZF ← (temp == 0);
AF ← auxiliary carry of subtraction;
PF ← parity of temp;
CF ← borrow;
if (DF == 0) {
  EDI ← EDI + 4;
} else {
  EDI ← EDI - 4;
}


Summary: Compares RAX with memory at [RDI].

RAX

Implicit source register (accumulator in 64-bit mode) containing the value to be compared.

Memory operand at DS:RDI (destination index register in 64-bit mode) to be compared against RAX.

Compares the quadword in RAX with a quadword at memory address [RDI] by performing an implicit subtraction (RAX - [RDI]), updates the EFLAGS register with the result, and increments or decrements RDI by 8 depending on the direction flag (DF). The comparison affects OF, SF, ZF, AF, PF, and CF flags but does not modify either operand. Available only in 64-bit mode; commonly used with repeat prefixes for scanning 64-bit values in memory.

temp ← RAX - [RDI];
OF ← overflow of subtraction;
SF ← temp[63];
ZF ← (temp == 0);
AF ← auxiliary carry of subtraction;
PF ← parity of temp;
CF ← borrow;
if (DF == 0) {
  RDI ← RDI + 8;
} else {
  RDI ← RDI - 8;
}


Summary: Loads word from [ESI] into AX.

AX

Implicit destination register (accumulator) where the loaded word is stored.

Memory operand at DS:ESI (source index register) from which the word is loaded.

Loads a word (16-bit) from memory at address [ESI] into the AX register, then increments or decrements ESI by 2 depending on the direction flag (DF). No flags are affected by this instruction. Often used with repeat prefix (REP) to load successive words from memory into AX, though the repeat would only load the final value.

AX ← [ESI];
if (DF == 0) {
  ESI ← ESI + 2;
} else {
  ESI ← ESI - 2;
}


Summary: Loads doubleword from [ESI] into EAX.

EAX

Implicit destination register (accumulator) where the loaded doubleword is stored.

Memory operand at DS:ESI (source index register) from which the doubleword is loaded.

Loads a doubleword (32-bit) from memory at address [ESI] into the EAX register, then increments or decrements ESI by 4 depending on the direction flag (DF). No flags are affected by this instruction. Commonly used in 32-bit protected mode or with repeat prefix (REP) to load successive doublewords, though the repeat would only retain the final value in EAX.

EAX ← [ESI];
if (DF == 0) {
  ESI ← ESI + 4;
} else {
  ESI ← ESI - 4;
}


Summary: Loads quadword from [RSI] into RAX.

Loads a 64-bit value from memory at [RSI] into RAX, then adjusts RSI by ±8 based on the direction flag (DF). This is a string primitive operation commonly used in loops with REP prefix. No flags are affected by this instruction itself.

RAX ← [RSI];
if (DF == 0) RSI ← RSI + 8;
else RSI ← RSI - 8;


Summary: Stores AX to memory at [EDI].

Stores the 16-bit value in AX to memory at [EDI], then adjusts EDI by ±2 based on the direction flag (DF). This is a string primitive typically used with REP prefix for bulk memory fills. No flags are affected.

[EDI] ← AX;
if (DF == 0) EDI ← EDI + 2;
else EDI ← EDI - 2;


Summary: Stores EAX to memory at [EDI].

Stores the 32-bit value in EAX to memory at [EDI], then adjusts EDI by ±4 based on the direction flag (DF). This is a string primitive commonly used with REP prefix for fast memory initialization. No flags are affected.

[EDI] ← EAX;
if (DF == 0) EDI ← EDI + 4;
else EDI ← EDI - 4;


Summary: Stores RAX to memory at [RDI].

Stores the 64-bit value in RAX to memory at [RDI], then adjusts RDI by ±8 based on the direction flag (DF). Available only in 64-bit mode, this is a string primitive typically used with REP prefix for bulk memory operations. No flags are affected.

[RDI] ← RAX;
if (DF == 0) RDI ← RDI + 8;
else RDI ← RDI - 8;


Summary: Moves word from [ESI] to [EDI].

Copies a 16-bit word from memory at [ESI] to memory at [EDI], then adjusts both ESI and EDI by ±2 based on the direction flag (DF). This is a string primitive commonly used with REP prefix for memory-to-memory block moves. No flags are affected.

[EDI] ← [ESI];
if (DF == 0) { ESI ← ESI + 2; EDI ← EDI + 2; }
else { ESI ← ESI - 2; EDI ← EDI - 2; }


Summary: Moves doubleword from [ESI] to [EDI].

Copies a 32-bit doubleword from memory at [ESI] to memory at [EDI], then adjusts both ESI and EDI by ±4 based on the direction flag (DF). This is a string primitive frequently used with REP prefix for fast memory copy operations. No flags are affected.

[EDI] ← [ESI];
if (DF == 0) { ESI ← ESI + 4; EDI ← EDI + 4; }
else { ESI ← ESI - 4; EDI ← EDI - 4; }


Summary: Moves quadword from [RSI] to [RDI].

Copies a 64-bit quadword from memory at [RSI] to memory at [RDI], then adjusts both RSI and RDI by ±8 based on the direction flag (DF). Available only in 64-bit mode, this string primitive is commonly used with REP prefix for optimized memory block copies. No flags are affected.

[RDI] ← [RSI];
if (DF == 0) { RSI ← RSI + 8; RDI ← RDI + 8; }
else { RSI ← RSI - 8; RDI ← RDI - 8; }


Summary: Reads word from I/O port to memory at [EDI].

Reads a 16-bit word from the I/O port specified in DX into memory at [EDI], then adjusts EDI by ±2 based on the direction flag (DF). This instruction is privileged and typically used with REP prefix for bulk I/O input operations. No flags are affected.

[EDI] ← IO_PORT[DX];
if (DF == 0) EDI ← EDI + 2;
else EDI ← EDI - 2;


Summary: Reads doubleword from I/O port to memory at [EDI].

DX

The 16-bit port address register, implicitly selects the I/O port.

EDI

The destination memory address register; auto-incremented or auto-decremented based on DF.

Reads a 32-bit doubleword from the I/O port specified by the DX register and stores it in memory at the linear address [EDI]. The EDI register is then incremented or decremented based on the DF (Direction Flag); DF=0 increments EDI by 4, DF=1 decrements by 4. This instruction is typically used within a REP prefix loop for block I/O transfers and requires I/O privilege level in protected mode.

memory[EDI] ← IO_PORT[DX];
if (DF == 0) {
  EDI ← EDI + 4;
} else {
  EDI ← EDI - 4;
}


Summary: Writes word from memory at [ESI] to I/O port.

ESI

The source memory address register; auto-incremented or auto-decremented based on DF.

Reads a 16-bit word from memory at the linear address [ESI] and writes it to the I/O port specified by the DX register. The ESI register is then incremented or decremented based on the DF flag; DF=0 increments ESI by 2, DF=1 decrements by 2. This instruction is typically used within a REP prefix loop for block I/O transfers and requires I/O privilege level in protected mode.

IO_PORT[DX] ← memory[ESI];
if (DF == 0) {
  ESI ← ESI + 2;
} else {
  ESI ← ESI - 2;
}


Summary: Writes doubleword from memory at [ESI] to I/O port.

Reads a 32-bit doubleword from memory at the linear address [ESI] and writes it to the I/O port specified by the DX register. The ESI register is then incremented or decremented based on the DF flag; DF=0 increments ESI by 4, DF=1 decrements by 4. This instruction is typically used within a REP prefix loop for block I/O transfers and requires I/O privilege level in protected mode.

IO_PORT[DX] ← memory[ESI];
if (DF == 0) {
  ESI ← ESI + 4;
} else {
  ESI ← ESI - 4;
}


Summary: Pushes +1.0 onto the FPU register stack.

Decrements the FPU stack pointer (ST(7)→ST(0)), then loads the constant +1.0 (extended precision double) into the top of the x87 FPU register stack (ST(0)). The instruction sets the C1 flag to 0 and leaves other status flags unchanged unless a stack overflow occurs (C0, C2, C3 may be set on exception). No CPU integer flags are affected.

FPU_TOP ← FPU_TOP - 1;
if (FPU_TOP overflow) {
  raise FPU_EXCEPTION;
}
ST(0) ← +1.0;


Summary: Pushes +0.0 onto the FPU register stack.

Decrements the FPU stack pointer (ST(7)→ST(0)), then loads the constant +0.0 (extended precision double) into the top of the x87 FPU register stack (ST(0)). The instruction sets the C1 flag to 0 and leaves other status flags unchanged unless a stack overflow occurs. No CPU integer flags are affected.

FPU_TOP ← FPU_TOP - 1;
if (FPU_TOP overflow) {
  raise FPU_EXCEPTION;
}
ST(0) ← +0.0;


Summary: Pushes Pi onto the FPU register stack.

Decrements the FPU stack pointer (ST(7)→ST(0)), then loads the constant Pi (π ≈ 3.14159265..., extended precision) into the top of the x87 FPU register stack (ST(0)). The instruction sets the C1 flag to 0 and leaves other status flags unchanged unless a stack overflow occurs. No CPU integer flags are affected.

FPU_TOP ← FPU_TOP - 1;
if (FPU_TOP overflow) {
  raise FPU_EXCEPTION;
}
ST(0) ← π;


Summary: Pushes log2(e) onto the FPU register stack.

Decrements the FPU stack pointer (ST(7)→ST(0)), then loads the constant log₂(e) (≈ 1.44269504..., extended precision) into the top of the x87 FPU register stack (ST(0)). This constant is useful for logarithm and exponential calculations. The instruction sets the C1 flag to 0 and leaves other status flags unchanged unless a stack overflow occurs.

FPU_TOP ← FPU_TOP - 1;
if (FPU_TOP overflow) {
  raise FPU_EXCEPTION;
}
ST(0) ← log₂(e);


Summary: Pushes log2(10) onto the FPU register stack.

Decrements the FPU stack pointer (ST(7)→ST(0)), then loads the constant log₂(10) (≈ 3.32192809..., extended precision) into the top of the x87 FPU register stack (ST(0)). This constant is useful for base-10 logarithm calculations. The instruction sets the C1 flag to 0 and leaves other status flags unchanged unless a stack overflow occurs.

FPU_TOP ← FPU_TOP - 1;
if (FPU_TOP overflow) {
  raise FPU_EXCEPTION;
}
ST(0) ← log₂(10);


Summary: Pushes log10(2) onto the FPU register stack.

Pushes the constant log₁₀(2) ≈ 0.30103 onto the FPU register stack, incrementing the stack pointer (TOP). This is a zero-operand x87 FPU instruction that loads a precomputed constant into ST(0). No flags are modified by this instruction.

TOP ← (TOP - 1) mod 8; ST(0) ← log10(2);


Summary: Pushes ln(2) onto the FPU register stack.

Pushes the constant ln(2) ≈ 0.69315 onto the FPU register stack, incrementing the stack pointer (TOP). This is a zero-operand x87 FPU instruction that loads a precomputed constant into ST(0). No flags are modified by this instruction.


Summary: Increments the TOP field in the FPU status word.

Increments the TOP field (bits 13:11) of the x87 FPU status word, rotating the register stack pointer forward by one position. This is a zero-operand instruction that does not modify CPU EFLAGS. It is used to manually adjust the FPU stack pointer without popping data.


Summary: Decrements the TOP field in the FPU status word.

Decrements the TOP field (bits 13:11) of the x87 FPU status word, rotating the register stack pointer backward by one position. This is a zero-operand instruction that does not modify CPU EFLAGS. It is used to manually adjust the FPU stack pointer without pushing data.


Summary: Sets the tag for ST(i) to empty.

Sets the tag bits for the specified FPU register to 11b (empty), marking it as unused without removing its value from the register. This instruction does not pop the stack or modify EFLAGS. It is commonly used to release floating-point registers for reuse.


Floating-Point Conditional Move If Below

Summary: Moves ST(i) to ST(0) if CF=1.

Conditionally moves ST(i) to ST(0) if the carry flag (CF) is set, based on a prior integer comparison or EFLAGS state. This x87 instruction available on Pentium Pro and later does not modify EFLAGS; it only reads CF to determine whether to execute the move. If CF=0, no move occurs and ST(0) remains unchanged.


Floating-Point Conditional Move If Equal

Summary: Moves ST(i) to ST(0) if ZF=1.

Conditionally moves ST(i) to ST(0) if the zero flag (ZF) is set, based on a prior integer comparison or EFLAGS state. This x87 instruction available on Pentium Pro and later does not modify EFLAGS; it only reads ZF to determine whether to execute the move. If ZF=0, no move occurs and ST(0) remains unchanged.


Floating-Point Conditional Move If Below or Equal

Summary: Moves ST(i) to ST(0) if CF=1 or ZF=1.

Conditionally moves ST(i) to ST(0) if the carry flag (CF) is set or the zero flag (ZF) is set, based on a prior integer comparison or EFLAGS state. This x87 instruction available on Pentium Pro and later does not modify EFLAGS; it only reads CF and ZF to determine whether to execute the move. If neither CF nor ZF is set, no move occurs.


Floating-Point Conditional Move If Unordered

Summary: Moves ST(i) to ST(0) if PF=1.

Conditionally moves the value in ST(i) to ST(0) if the parity flag (PF) is set, indicating an unordered comparison result (one or both operands are NaN). This instruction is part of the x87 FPU conditional move family introduced in P6 and later processors. No flags are modified by this instruction.


Floating-Point Conditional Move If Not Below

Summary: Moves ST(i) to ST(0) if CF=0.

Conditionally moves the value in ST(i) to ST(0) if the carry flag (CF) is clear, indicating the first operand is not below the second in an x87 FPU comparison context. This is part of the x87 conditional move instruction set available on P6 and later processors. No flags are modified by this instruction.


Floating-Point Conditional Move If Not Equal

Summary: Moves ST(i) to ST(0) if ZF=0.

Conditionally moves the value in ST(i) to ST(0) if the zero flag (ZF) is clear, indicating the operands are not equal in an x87 FPU comparison context. This instruction is part of the x87 conditional move family on P6 and later processors. No flags are modified by this instruction.


Floating-Point Conditional Move If Not Below or Equal

Summary: Moves ST(i) to ST(0) if CF=0 and ZF=0.

Conditionally moves the value in ST(i) to ST(0) if both the carry flag (CF) and zero flag (ZF) are clear, indicating the first operand is greater than the second in an x87 FPU comparison context. This instruction is part of the x87 conditional move set on P6 and later processors. No flags are modified by this instruction.


Floating-Point Conditional Move If Not Unordered

Summary: Moves ST(i) to ST(0) if PF=0.

Conditionally moves the value in ST(i) to ST(0) if the parity flag (PF) is clear, indicating an ordered comparison result (neither operand is NaN) in x87 FPU context. This instruction is part of the x87 conditional move family on P6 and later processors. No flags are modified by this instruction.


Pack with Unsigned Saturation Word to Byte

Summary: Converts signed words to unsigned bytes with saturation.

Converts four signed 16-bit words from each of two XMM registers or memory into eight unsigned 8-bit bytes with unsigned saturation, storing the result in the destination XMM register. Values greater than 255 saturate to 255, and negative values saturate to 0. No flags are affected by this instruction; it is an SSE2 SIMD operation.


Summary: Interleaves high bytes from two sources.

Interleaves the high-order bytes from corresponding positions in the destination and source XMM registers, storing bytes from the destination in even-indexed positions and source bytes in odd-indexed positions of the result. This SSE2 instruction performs no flag modifications and operates on 128-bit packed data.


Summary: Interleaves high words.

Interleaves the high-order words from corresponding positions in the destination and source XMM registers, storing words from the destination in even-indexed positions and source words in odd-indexed positions of the result. This SSE2 instruction performs no flag modifications and operates on 128-bit packed data.


Summary: Interleaves high doublewords.

Unpacks and interleaves the high-order 32-bit doublewords from the destination and source XMM registers into the destination. The instruction treats the 128-bit XMM register as four 32-bit elements, selects elements 1 and 3 (the high two), and interleaves them as [src[3], dest[3], src[1], dest[1]]. No flags are affected.


Summary: Interleaves high quadwords.

Unpacks and interleaves the high-order 64-bit quadwords from the destination and source XMM registers into the destination. The instruction treats the 128-bit XMM register as two 64-bit elements, selects element 1 (the high half), and interleaves them as [src[1], dest[1]]. No flags are affected.


Summary: Computes absolute differences of bytes and sums them to words.

Computes the absolute value of the difference for each of 16 packed unsigned bytes in the destination and source, then sums those differences within 64-bit groups and stores the results as two 64-bit values. Useful for motion estimation and SAD (Sum of Absolute Differences) operations. No flags are affected.

sum_low ← 0
sum_high ← 0
for i in 0..7:
  sum_low ← sum_low + abs(dest[i*8 + 7:i*8] - src[i*8 + 7:i*8])
for i in 8..15:
  sum_high ← sum_high + abs(dest[i*8 + 7:i*8] - src[i*8 + 7:i*8])
dest[0:63] ← sum_low
dest[64:127] ← sum_high


Maximum of Packed Unsigned Byte Integers

Summary: Returns maximum of unsigned bytes.

Compares each of 16 packed unsigned bytes in the destination and source registers and stores the maximum value of each pair into the destination. This is an element-wise unsigned 8-bit maximum operation. No flags are affected.


Minimum of Packed Unsigned Byte Integers

Summary: Returns minimum of unsigned bytes.

Compares each of 16 packed unsigned bytes in the destination and source registers and stores the minimum value of each pair into the destination. This is an element-wise unsigned 8-bit minimum operation. No flags are affected.


Summary: Returns maximum of signed words.

Compares each of 8 packed signed words in the destination and source registers and stores the maximum value of each pair into the destination. This is an element-wise signed 16-bit maximum operation. No flags are affected.


Summary: Returns minimum of signed words.

Compares each of 8 packed signed words in the destination and source registers and stores the minimum value of each pair into the destination. This is an element-wise signed 16-bit minimum operation. No flags are affected.


Summary: Averages packed unsigned bytes (rounded up).

Computes the average of each pair of 16 packed unsigned bytes in the destination and source registers, rounding up (toward positive infinity), and stores the results into the destination. The formula is (a + b + 1) >> 1 for each byte pair. No flags are affected.


Summary: Averages packed unsigned words (rounded up).

Averages packed unsigned 16-bit integers element-wise, rounding up by adding 1 before shifting right. Each pair of corresponding 16-bit words from the destination and source are averaged independently and stored back in the destination. No flags are affected; this is a data-parallel operation with no special side effects.

for i = 0 to 7:
  dest.word[i] ← (dest.word[i] + src.word[i] + 1) >> 1


Summary: Multiplies unsigned words, keeps high 16 bits.

Multiplies packed unsigned 16-bit integers and stores the high 16 bits of each 32-bit product. Each pair of corresponding 16-bit unsigned words from destination and source are multiplied (producing 32-bit results), and only the upper 16 bits are retained. No flags are affected.

for i = 0 to 7:
  product ← (uint32_t)dest.word[i] * (uint32_t)src.word[i]
  dest.word[i] ← (uint16_t)(product >> 16)


Summary: Multiplies signed words, keeps high 16 bits.

Multiplies packed signed 16-bit integers and stores the high 16 bits of each 32-bit product. Each pair of corresponding 16-bit signed words from destination and source are multiplied (producing 32-bit results), and only the upper 16 bits are retained. No flags are affected.

for i = 0 to 7:
  product ← (int32_t)dest.sword[i] * (int32_t)src.sword[i]
  dest.sword[i] ← (int16_t)(product >> 16)


Summary: Subtracts packed quadwords.

Subtracts packed 64-bit integers element-wise without saturation. The two 64-bit integers in the destination are each subtracted from by the corresponding 64-bit integers in the source, and results wrap on overflow. No flags are affected; wrapping behavior is identical to 64-bit integer subtraction.

for i = 0 to 1:
  dest.quad[i] ← dest.quad[i] - src.quad[i]


Multiply Packed Unsigned Doubleword Integers

Summary: Multiplies low 32-bits of each 64-bit chunk to 64-bit result.

Multiplies the low 32-bit doublewords of packed unsigned integers, producing 64-bit products. The even-indexed 32-bit elements (0, 2) from destination and source are multiplied, and the 64-bit results are written back to the even positions. No flags are affected.

dest.quad[0] ← (uint64_t)dest.dword[0] * (uint64_t)src.dword[0]
dest.quad[1] ← (uint64_t)dest.dword[2] * (uint64_t)src.dword[2]


Summary: Shifts the entire 128-bit register left by bytes.

Shifts the entire 128-bit value in the destination XMM register left by a byte count, filling with zeros from the right. The shift count is specified as an 8-bit immediate and is applied to the whole register as a unit, not element-wise. No flags are affected.

shift_count ← imm8
if shift_count >= 16:
  dest ← 0
else:
  dest ← dest << (shift_count * 8)


Summary: Shifts the entire 128-bit register right by bytes.

Shifts the entire 128-bit value in the destination XMM register right by a byte count, filling with zeros from the left. The shift count is specified as an 8-bit immediate and is applied to the whole register as a unit, not element-wise. No flags are affected.

shift_count ← imm8
if shift_count >= 16:
  dest ← 0
else:
  dest ← dest >> (shift_count * 8)


Convert Packed Doubleword Integers to Packed Single-Precision

Summary: Converts four 32-bit integers to floats.

Converts four packed 32-bit signed doubleword integers to four packed single-precision floating-point values. Conversion uses the current rounding mode from MXCSR. Precision may be lost for very large integers; no flags are explicitly set, but the instruction may generate floating-point exceptions via MXCSR.

for i = 0 to 3:
  dest.float[i] ← (float)src.dword[i]


Convert Packed Single-Precision to Packed Doubleword Integers

Summary: Converts four floats to 32-bit integers (Rounded).

Converts four packed single-precision floating-point values to four packed signed 32-bit integers using the rounding mode specified in MXCSR. If any input is NaN, the result is the minimum signed 32-bit integer (0x80000000). Operates on 128-bit XMM registers and sets ZF, PF, CF based on rounding exceptions in MXCSR.

dest[0:31] ← RoundToNearest(src[0:31]); dest[32:63] ← RoundToNearest(src[32:63]); dest[64:95] ← RoundToNearest(src[64:95]); dest[96:127] ← RoundToNearest(src[96:127]);


Convert with Truncation Packed Single-Precision to Packed Doubleword Integers

Summary: Converts four floats to 32-bit integers (Truncated).

Converts four packed single-precision floating-point values to four packed signed 32-bit integers by truncating toward zero (discarding fractional part). If any input is NaN or out of range, the result is 0x80000000. Operates on 128-bit XMM registers without using MXCSR rounding mode.


Summary: Extracts sign bits from four floats into low 4 bits of register.

Extracts the sign bit (bit 31) from each of four packed single-precision floating-point values in an XMM register and packs them into the low 4 bits of a general-purpose 32-bit register. The upper 28 bits of the destination are cleared. No flags are modified.

dest ← 0; dest[0] ← src[31]; dest[1] ← src[63]; dest[2] ← src[95]; dest[3] ← src[127];


Summary: Extracts sign bits from two doubles into low 2 bits of register.

Extracts the sign bit (bit 63) from each of two packed double-precision floating-point values in an XMM register and packs them into the low 2 bits of a general-purpose 32-bit register. The upper 30 bits of the destination are cleared. No flags are modified.

dest ← 0; dest[0] ← src[63]; dest[1] ← src[127];


Summary: Compares low float and sets EFLAGS (Signaling NaN raises exception).

Performs an ordered comparison of the low single-precision floating-point values in two XMM registers or memory, setting EFLAGS (ZF, PF, CF) accordingly. Signals invalid operation exception if either operand is a signaling NaN; quiet NaNs set ZF=1, PF=1, CF=1. Does not modify the XMM registers.

src1_val ← src1[0:31] (as float); src2_val ← src2[0:31] (as float); if (IsNaN(src1_val) || IsNaN(src2_val)) { ZF ← 1; PF ← 1; CF ← 1; OF ← 0; AF ← 0; SF ← 0; } else if (src1_val < src2_val) { CF ← 1; ZF ← 0; PF ← 0; OF ← 0; AF ← 0; SF ← 0; } else if (src1_val == src2_val) { ZF ← 1; CF ← 0; PF ← 0; OF ← 0; AF ← 0; SF ← 0; } else { ZF ← 0; CF ← 0; PF ← 0; OF ← 0; AF ← 0; SF ← 0; }


Summary: Compares low double and sets EFLAGS (Signaling NaN raises exception).

Performs an ordered comparison of the low double-precision floating-point values in two XMM registers or memory, setting EFLAGS (ZF, PF, CF) accordingly. Signals invalid operation exception if either operand is a signaling NaN; quiet NaNs set ZF=1, PF=1, CF=1. Does not modify the XMM registers.

src1_val ← src1[0:63] (as double); src2_val ← src2[0:63] (as double); if (IsNaN(src1_val) || IsNaN(src2_val)) { ZF ← 1; PF ← 1; CF ← 1; OF ← 0; AF ← 0; SF ← 0; } else if (src1_val < src2_val) { CF ← 1; ZF ← 0; PF ← 0; OF ← 0; AF ← 0; SF ← 0; } else if (src1_val == src2_val) { ZF ← 1; CF ← 0; PF ← 0; OF ← 0; AF ← 0; SF ← 0; } else { ZF ← 0; CF ← 0; PF ← 0; OF ← 0; AF ← 0; SF ← 0; }


Summary: Interleaves low doubles from two sources.

Unpacks and interleaves the low-order 64-bit double-precision values from the destination and source XMM registers, placing the result back in the destination. Destination element 0 receives the low double from dest, element 1 receives the low double from src. No flags are modified.


Summary: Interleaves high doubles from two sources.

Unpacks and interleaves the high-order 64-bit double-precision values from the destination and source XMM registers, placing the result back in the destination. Destination element 0 receives the high double from dest, element 1 receives the high double from src. No flags are modified.


Move Packed Single-FP High and Duplicate

Summary: Duplicates high element of each qword pair.

Moves and duplicates the high 32-bit single-precision FP value from each 64-bit pair in the source to both elements of the corresponding pair in the destination. This SSE3 instruction operates on 128-bit XMM registers and does not modify flags. It is used for efficient duplication of high elements in packed FP data.


Summary: Duplicates low element of each qword pair.

Moves and duplicates the low 32-bit single-precision FP value from each 64-bit pair in the source to both elements of the corresponding pair in the destination. This SSE3 instruction operates on 128-bit XMM registers and does not modify flags. It is the complement to MOVSHDUP, duplicating low rather than high elements.


Summary: Subtracts adjacent 16-bit integers horizontally.

Subtracts horizontally adjacent 16-bit signed integers within each 128-bit operand, producing 16-bit results. This SSSE3 instruction performs eight parallel subtractions (higher element minus lower element in each pair) and does not modify EFLAGS. Results that overflow wrap with two's-complement semantics.


Summary: Subtracts adjacent 32-bit integers horizontally.

Subtracts horizontally adjacent 32-bit signed integers within each 128-bit operand, producing 32-bit results. This SSSE3 instruction performs four parallel subtractions (higher element minus lower element in each pair) and does not modify EFLAGS. Results wrap with two's-complement semantics on overflow.


Multiply and Add Packed Signed and Unsigned Bytes

Summary: Multiplies signed/unsigned bytes and adds pairs to words.

Multiplies unsigned bytes from the destination by signed bytes from the source, then adds the products pairwise to produce signed 16-bit results with saturation. This SSSE3 instruction performs eight parallel multiply-add operations on byte pairs and does not modify EFLAGS. Results are clamped to the signed 16-bit range [-32768, 32767].

for i = 0 to 7:
  prod0 ← (uint8_t)dest[8*i+7:8*i] × (int8_t)src[8*i+7:8*i];
  prod1 ← (uint8_t)dest[8*i+15:8*i+8] × (int8_t)src[8*i+15:8*i+8];
  sum ← (int32_t)prod0 + (int32_t)prod1;
  dest[16*i+15:16*i] ← saturate_to_i16(sum);


Summary: Finds minimum word and its index.

Finds the minimum unsigned 16-bit word among eight packed values and returns the minimum value in the low word of the destination with its index (0-7) in bits 16-18. This SSE4.1 instruction clears bits 19-127 of the destination and does not modify EFLAGS. It is useful for finding the position of minimum values in packed word arrays.

min_val ← src[15:0];
min_idx ← 0;
for i = 1 to 7:
  if (uint16_t)src[16*i+15:16*i] < min_val:
    min_val ← (uint16_t)src[16*i+15:16*i];
    min_idx ← i;
dest[15:0] ← min_val;
dest[18:16] ← min_idx;
dest[127:19] ← 0;


Compute Multiple Sums of Absolute Differences

Summary: Computes multiple SADs of byte blocks.

Computes multiple sums of absolute differences between corresponding bytes of two blocks selected by an immediate operand. This SSE4.1 instruction computes four parallel SADs, each summing the absolute differences across a byte block, and produces four 16-bit results. EFLAGS is not modified.

offset_dest ← (sel & 0x4) ? 4 : 0;
offset_src ← (sel & 0x3) ? 4 * (sel & 0x3) : 0;
for k = 0 to 3:
  sum ← 0;
  for j = 0 to 3:
    idx_d ← offset_dest + 8*k + 8*j;
    idx_s ← offset_src + 8*j;
    sum ← sum + |dest[idx_d+7:idx_d] - src[idx_s+7:idx_s]|;
  dest[16*k+15:16*k] ← sum;


Packed Move with Sign Extend Byte to Quadword

Summary: Sign extends 8-bit integers to 64-bit.

Sign-extends the low four bytes of the source to four 64-bit signed integers in the destination. This SSE4.1 instruction operates on 128-bit XMM registers and does not modify EFLAGS. The source may be a 16-bit memory operand or an XMM register; destination bits are filled with the sign bit of each source byte.


Packed Move with Sign Extend Word to Doubleword

Summary: Sign extends 16-bit integers to 32-bit.

Sign-extends four packed 16-bit signed integers from the source operand to four packed 32-bit signed integers in the destination XMM register. The source is a 64-bit value (lower 64 bits of XMM or 64-bit memory location) containing four 16-bit elements; the destination is an 128-bit XMM register. No flags are affected.


Packed Move with Sign Extend Word to Quadword

Summary: Sign extends 16-bit integers to 64-bit.

Sign-extends two packed 16-bit signed integers from the source operand to two packed 64-bit signed integers in the destination XMM register. The source is a 32-bit value (lower 32 bits of XMM or 32-bit memory location) containing two 16-bit elements; the destination is an 128-bit XMM register. No flags are affected.


Packed Move with Sign Extend Doubleword to Quadword

Summary: Sign extends 32-bit integers to 64-bit.

Sign-extends two packed 32-bit signed integers from the source operand to two packed 64-bit signed integers in the destination XMM register. The source is a 64-bit value (lower 64 bits of XMM or 64-bit memory location) containing two 32-bit elements; the destination is an 128-bit XMM register. No flags are affected.


Packed Move with Zero Extend Byte to Doubleword

Summary: Zero extends 8-bit integers to 32-bit.

Zero-extends four packed 8-bit unsigned integers from the source operand to four packed 32-bit unsigned integers in the destination XMM register. The source is a 32-bit value (lower 32 bits of XMM or 32-bit memory location) containing four 8-bit elements; the destination is an 128-bit XMM register. No flags are affected.


Packed Move with Zero Extend Byte to Quadword

Summary: Zero extends 8-bit integers to 64-bit.

Zero-extends two packed 8-bit unsigned integers from the source operand to two packed 64-bit unsigned integers in the destination XMM register. The source is a 16-bit value (lower 16 bits of XMM or 16-bit memory location) containing two 8-bit elements; the destination is an 128-bit XMM register. No flags are affected.


Packed Move with Zero Extend Word to Doubleword

Summary: Zero extends 16-bit integers to 32-bit.

Zero-extends four packed 16-bit unsigned integers from the source operand to four packed 32-bit unsigned integers in the destination XMM register. The source is a 64-bit value (lower 64 bits of XMM or 64-bit memory location) containing four 16-bit elements; the destination is an 128-bit XMM register. No flags are affected.


Packed Move with Zero Extend Word to Quadword

Summary: Zero extends 16-bit integers to 64-bit.

Zero-extends two packed 16-bit unsigned integers from the source operand to two packed 64-bit unsigned integers in the destination XMM register. The source is a 32-bit value (lower 32 bits of XMM or 32-bit memory location) containing two 16-bit elements; the destination is an 128-bit XMM register. No flags are affected.


Packed Move with Zero Extend Doubleword to Quadword

Summary: Zero extends 32-bit integers to 64-bit.

Zero-extends two packed 32-bit unsigned integers from the source operand to two packed 64-bit unsigned integers in the destination XMM register. The source is a 64-bit value (lower 64 bits of XMM or 64-bit memory location) containing two 32-bit elements; the destination is an 128-bit XMM register. No flags are affected.


Summary: Broadcasts a double to all elements of YMM.

dest

Destination YMM register; all four 64-bit lanes receive the value

src

64-bit memory location holding the double-precision value to broadcast

Broadcasts a 64-bit double-precision floating-point value from memory to all four 64-bit elements of a 256-bit YMM register. This is a non-temporal data movement that replicates a single FP64 value across the entire YMM destination. No flags are affected.


Summary: Broadcasts 128-bit FP block to YMM.

Broadcasts a 128-bit floating-point block from memory to both 128-bit halves of a 256-bit YMM register, replicating the 16-byte XMM-sized value twice. This instruction operates on floating-point data and does not affect any flags. Available in AVX mode and higher.


Summary: Broadcasts 128-bit integer block to YMM.

Broadcasts a 128-bit integer block from memory to both 128-bit halves of a 256-bit YMM register, replicating the 16-byte value as integer data. This is the integer-domain equivalent of VBROADCASTF128 and does not affect any CPU flags.


Summary: Broadcasts a word to all elements of YMM.

Broadcasts a 16-bit word value from either an XMM register or memory to all 16-bit elements of a YMM register (16 copies total). The source operand can be a 16-bit memory location or the low word of an XMM register. No flags are modified.

val ← (src[15:0])
for i ← 0 to 15 do
  ymm1[i*16+15:i*16] ← val
end for


Summary: Broadcasts a quadword to all elements of YMM.

Broadcasts a 64-bit quadword value from either an XMM register or memory to all 64-bit elements of a YMM register (four copies total). The source can be a 64-bit memory location or the low quadword of an XMM register. No flags are affected.

val ← (src[63:0])
for i ← 0 to 3 do
  ymm1[i*64+63:i*64] ← val
end for


Conditional Move Packed Single-Precision

Summary: Conditionally loads/stores floats based on mask.

Conditionally loads single-precision floating-point values from memory into a YMM register based on per-element mask bits; unset mask bits leave destination elements unchanged. This is a masked memory read operation where the high bit of each 32-bit mask element controls whether the corresponding FP32 is loaded. No flags are modified.

for i ← 0 to 7 do
  if ymm2[i*32+31] == 1 then
    ymm1[i*32+31:i*32] ← [memory_address + i*4]
  end if
end for


Conditional Move Packed Double-Precision

Summary: Conditionally loads/stores doubles based on mask.

Conditionally loads double-precision floating-point values from memory into a YMM register based on per-element mask bits; unset mask bits leave destination elements unchanged. This is the FP64 variant of VMASKMOVPS where the high bit of each 64-bit mask element controls the corresponding load. No flags are affected.

for i ← 0 to 3 do
  if ymm2[i*64+63] == 1 then
    ymm1[i*64+63:i*64] ← [memory_address + i*8]
  end if
end for


Gather Packed Doubleword with Signed Doubleword Indices

Summary: Gathers 32-bit integers using 32-bit indices.

VPGATHERDD ymm1, [base+ymm_idx*scale], ymm_mask

Gathers four doubleword (32-bit) integers from memory using 32-bit sign-extended indices in a YMM register, with per-element masking to conditionally perform each load. Each element of the destination YMM is loaded from [base + ymm_index[i] * scale] if the corresponding mask bit is set; mask elements are zeroed after a successful gather. This instruction serializes memory operations and sets mask elements to zero for loaded lanes.

for i ← 0 to 3 do
  if mask_ymm[i*32+31] == 1 then
    ymm1[i*32+31:i*32] ← [base + sign_extend(ymm_idx[i*32+31:i*32]) * scale]
    mask_ymm[i*32+31:i*32] ← 0
  end if
end for


Gather Packed Quadword with Signed Doubleword Indices

Summary: Gathers 64-bit integers using 32-bit indices.

VPGATHERDQ ymm1, [base+xmm_idx*scale], ymm_mask

Gathers eight 64-bit integers from memory using four 32-bit signed indices packed in an XMM register, with scale and base address, into a YMM destination. The mask register (YMM) controls which elements are gathered; masked-out elements in the destination are zeroed. All memory access and mask updates occur in parallel, and the instruction serializes the CPU pipeline during execution.

for i in 0 to 3:
  if mask[2*i+1:2*i] == all_ones_64bit:
    addr ← base + sign_extend_32_to_64(index[i*32+31:i*32]) * scale
    dest[64*i+63:64*i] ← [addr]
    mask[64*i+63:64*i] ← all_ones_64bit
  else:
    dest[64*i+63:64*i] ← 0
    mask[64*i+63:64*i] ← 0


Gather Packed Doubleword with Signed Quadword Indices

Summary: Gathers 32-bit integers using 64-bit indices.

VPGATHERQD xmm1, [base+ymm_idx*scale], xmm_mask

Gathers four 32-bit integers from memory using four 64-bit signed indices packed in a YMM register, with scale and base address, into an XMM destination (lower half). The mask register (XMM) controls which elements are gathered; masked-out elements are zeroed and their corresponding mask bits are cleared. The instruction serializes execution and performs all memory accesses in parallel.

for i in 0 to 3:
  if mask[32*i+31:32*i] == all_ones_32bit:
    addr ← base + index[64*i+63:64*i] * scale
    dest[32*i+31:32*i] ← [addr]
    mask[32*i+31:32*i] ← all_ones_32bit
  else:
    dest[32*i+31:32*i] ← 0
    mask[32*i+31:32*i] ← 0


Gather Packed Quadword with Signed Quadword Indices

Summary: Gathers 64-bit integers using 64-bit indices.

VPGATHERQQ ymm1, [base+ymm_idx*scale], ymm_mask

Gathers four 64-bit integers from memory using four 64-bit signed indices packed in a YMM register, with scale and base address, into a YMM destination. The mask register (YMM) controls which elements are gathered; masked-out elements are zeroed and their corresponding mask bits are cleared. All memory accesses execute in parallel, and the instruction causes pipeline serialization.

for i in 0 to 3:
  if mask[64*i+63:64*i] == all_ones_64bit:
    addr ← base + index[64*i+63:64*i] * scale
    dest[64*i+63:64*i] ← [addr]
    mask[64*i+63:64*i] ← all_ones_64bit
  else:
    dest[64*i+63:64*i] ← 0
    mask[64*i+63:64*i] ← 0


Summary: Computes absolute value of 64-bit integers.

Computes the absolute value of eight packed 64-bit signed integers from the source operand, storing the results in the destination ZMM register. Opmask register k1 selectively updates destination elements (merging or zeroing based on the mask mode). The operation handles the extreme case where abs(INT64_MIN) = INT64_MIN with wraparound; no overflow flags are set.

for i in 0 to 7:
  if k1[i] or not masked:
    src_val ← src[64*i+63:64*i]
    if src_val < 0:
      dest[64*i+63:64*i] ← -src_val
    else:
      dest[64*i+63:64*i] ← src_val
  else if zeroing:
    dest[64*i+63:64*i] ← 0


Maximum of Packed Signed Quadword Integers

Summary: Returns maximum of signed 64-bit integers.

Computes the element-wise maximum of eight packed 64-bit signed integers from two source operands, storing results in the destination ZMM register. Opmask register k1 selectively updates destination elements. The operation compares signed values and has no effect on EFLAGS; results are computed in parallel.

for i in 0 to 7:
  if k1[i] or not masked:
    src1_val ← src1[64*i+63:64*i]
    src2_val ← src2[64*i+63:64*i]
    if src1_val >_signed src2_val:
      dest[64*i+63:64*i] ← src1_val
    else:
      dest[64*i+63:64*i] ← src2_val
  else if zeroing:
    dest[64*i+63:64*i] ← 0


Maximum of Packed Unsigned Quadword Integers

Summary: Returns maximum of unsigned 64-bit integers.

Computes the element-wise maximum of eight packed 64-bit unsigned integers from two source operands, storing results in the destination ZMM register. Opmask register k1 selectively updates destination elements. The operation compares unsigned values and does not affect EFLAGS; all comparisons execute in parallel.

for i in 0 to 7:
  if k1[i] or not masked:
    src1_val ← src1[64*i+63:64*i]
    src2_val ← src2[64*i+63:64*i]
    if src1_val >_unsigned src2_val:
      dest[64*i+63:64*i] ← src1_val
    else:
      dest[64*i+63:64*i] ← src2_val
  else if zeroing:
    dest[64*i+63:64*i] ← 0


Minimum of Packed Signed Quadword Integers

Summary: Returns minimum of signed 64-bit integers.

Computes the element-wise minimum of eight packed 64-bit signed integers from two source operands, storing results in the destination ZMM register. Opmask register k1 selectively updates destination elements. The operation compares signed values and does not modify EFLAGS; all comparisons are performed in parallel.

for i in 0 to 7:
  if k1[i] or not masked:
    src1_val ← src1[64*i+63:64*i]
    src2_val ← src2[64*i+63:64*i]
    if src1_val <_signed src2_val:
      dest[64*i+63:64*i] ← src1_val
    else:
      dest[64*i+63:64*i] ← src2_val
  else if zeroing:
    dest[64*i+63:64*i] ← 0


Minimum of Packed Unsigned Quadword Integers

Summary: Returns minimum of unsigned 64-bit integers.

Computes the element-wise minimum of eight packed 64-bit unsigned integers from two source operands, storing results in the destination ZMM register. Opmask register k1 selectively updates destination elements. The operation compares unsigned values and leaves EFLAGS unchanged; all comparisons execute in parallel.

for i in 0 to 7:
  if k1[i] or not masked:
    src1_val ← src1[64*i+63:64*i]
    src2_val ← src2[64*i+63:64*i]
    if src1_val <_unsigned src2_val:
      dest[64*i+63:64*i] ← src1_val
    else:
      dest[64*i+63:64*i] ← src2_val
  else if zeroing:
    dest[64*i+63:64*i] ← 0


Summary: Rotates 64-bit integers left.

Rotates each 64-bit quadword in the source ZMM register left by an immediate count, writing the result to the destination ZMM register under write-mask control. This is a vectorized rotate-left operation with no effect on EFLAGS. Available only in 64-bit mode and requires AVX-512F support.


Summary: Rotates 64-bit integers right.

Rotates each 64-bit quadword in the source ZMM register right by an immediate count, writing the result to the destination ZMM register under write-mask control. This is a vectorized rotate-right operation with no effect on EFLAGS. Available only in 64-bit mode and requires AVX-512F support.


Summary: Down-converts 16-bit integers to 8-bit signed saturate.

Truncates 16-bit signed words from a ZMM register to 8-bit signed bytes with saturation, storing the result in an XMM register or 128-bit memory location under write-mask control. Out-of-range values saturate to the signed byte limits (-128 to 127). No flags are affected. This instruction requires AVX-512F and operates only in 64-bit mode.

for i = 0 to 31:
  temp ← zmm2[16*i : 16*i+15]
  if temp > 127:
    xmm1[8*i : 8*i+7] ← 127 (under mask k1[i])
  else if temp < -128:
    xmm1[8*i : 8*i+7] ← -128 (under mask k1[i])
  else:
    xmm1[8*i : 8*i+7] ← temp[7:0] (under mask k1[i])
  if not k1[i] and zeroing:
    xmm1[8*i : 8*i+7] ← 0


Summary: Down-converts 64-bit integers to 8-bit signed saturate.

Truncates 64-bit signed quadwords from a ZMM register to 8-bit signed bytes with saturation, storing the result in an XMM register or 128-bit memory location under write-mask control. Out-of-range values saturate to signed byte limits (-128 to 127). No flags are affected. This instruction requires AVX-512F and operates only in 64-bit mode.

for i = 0 to 7:
  temp ← zmm2[64*i : 64*i+63]
  if temp > 127:
    xmm1[8*i : 8*i+7] ← 127 (under mask k1[i])
  else if temp < -128:
    xmm1[8*i : 8*i+7] ← -128 (under mask k1[i])
  else:
    xmm1[8*i : 8*i+7] ← temp[7:0] (under mask k1[i])
  if not k1[i] and zeroing:
    xmm1[8*i : 8*i+7] ← 0


Summary: Down-converts 16-bit integers to 8-bit unsigned saturate.

Truncates 16-bit unsigned words from a ZMM register to 8-bit unsigned bytes with saturation, storing the result in an XMM register or 128-bit memory location under write-mask control. Out-of-range values saturate to the unsigned byte limit (0 to 255). No flags are affected. This instruction requires AVX-512F and operates only in 64-bit mode.

for i = 0 to 31:
  temp ← zmm2[16*i : 16*i+15]
  if temp > 255:
    xmm1[8*i : 8*i+7] ← 255 (under mask k1[i])
  else:
    xmm1[8*i : 8*i+7] ← temp[7:0] (under mask k1[i])
  if not k1[i] and zeroing:
    xmm1[8*i : 8*i+7] ← 0


Summary: Down-converts 64-bit integers to 8-bit unsigned saturate.

Truncates 64-bit unsigned quadwords from a ZMM register to 8-bit unsigned bytes with saturation, storing the result in an XMM register or 128-bit memory location under write-mask control. Out-of-range values saturate to the unsigned byte limit (0 to 255). No flags are affected. This instruction requires AVX-512F and operates only in 64-bit mode.

for i = 0 to 7:
  temp ← zmm2[64*i : 64*i+63]
  if temp > 255:
    xmm1[8*i : 8*i+7] ← 255 (under mask k1[i])
  else:
    xmm1[8*i : 8*i+7] ← temp[7:0] (under mask k1[i])
  if not k1[i] and zeroing:
    xmm1[8*i : 8*i+7] ← 0


Summary: Adds two 16-bit mask registers.

Adds two 16-bit mask registers and stores the result in a third 16-bit mask register, with write-mask control applied. The addition is performed on the full 16-bit width of each mask operand; no carry is defined beyond bit 15. No EFLAGS are modified. This instruction requires AVX-512DQ and operates only in 64-bit mode.


Summary: Adds two 8-bit mask registers.

Adds two 8-bit mask registers and stores the result in a third 8-bit mask register, with write-mask control applied. The addition is performed on the full 8-bit width of each mask operand; no carry is defined beyond bit 7. No EFLAGS are modified. This instruction requires AVX-512DQ and operates only in 64-bit mode.


Unpack and Interleave Masks Byte to Word

Summary: Interleaves 8-bit masks into 16-bit mask.

Unpacks and interleaves two 8-bit mask register values into a 16-bit mask register. The operation treats the 8-bit sources as packed bit fields and expands them with interleaving to produce a 16-bit result. No flags are affected by this operation.


Summary: Adds scalar single precision (EVEX encoded with masking).

Adds the low 32-bit single-precision floating-point operands of xmm2 and xmm3/m32, stores the result in xmm1, and leaves bits 127:32 of xmm1 unchanged. Supports EVEX encoding with optional write-mask (k1) and zeroing behavior. No integer flags are affected.


Summary: Multiplies scalar single precision (EVEX encoded with masking).

Multiplies the low 32-bit single-precision floating-point operands of xmm2 and xmm3/m32, stores the result in xmm1, and leaves bits 127:32 of xmm1 unchanged. Supports EVEX encoding with optional write-mask (k1) and zeroing behavior. No integer flags are affected.


Save Processor Extended States Optimized

Summary: Saves state components (optimized for Modified state).

Saves processor extended state components (FPU, SSE, AVX, etc.) to the memory location specified by EDX:EAX, using an optimized algorithm that tracks which state components have been modified. Requires XSAVEOPT feature support (CPUID EAX=0DH:EAX bit 0). No flags are modified; this instruction serializes execution and may cause VM exits in virtualized environments.

mem[EDX:EAX] ← XSTATE_COMPONENTS_PER_XCRF_BITMASK(ECX)
XSTATE_HEADER[EDX:EAX + 512] ← MODIFIED_STATE_TRACKING


Save Processor Extended States with Compaction

Summary: Saves state components using compaction.

Saves processor extended state components to the memory location specified by EDX:EAX using compaction, removing unused state and reducing the saved data size. Requires XSAVEC feature support (CPUID EAX=0DH, ECX=1:EAX bit 1). No flags are modified; this instruction serializes execution and may trigger VM exits in virtualized environments.

mem[EDX:EAX] ← COMPACT_XSTATE_COMPONENTS()
XSTATE_HEADER[EDX:EAX + 512] ← COMPACTED_SIZE_AND_LAYOUT


Summary: Invoke VM function specified in EAX.

Invokes a VM function as specified by the function number in EAX and additional parameters in ECX. Only valid in VMX non-root operation (guest mode) and transitions control to the host via VM exit. Privilege level: VMX non-root; will raise #UD if not in VMX operation or if called in root mode.

FUNC_NUM ← EAX
FUNC_PARAM ← ECX
INVOKE_VMFUNCTION(FUNC_NUM, FUNC_PARAM)
VMEXIT_TO_HOST


Summary: Generates invalid opcode exception.

Generates an invalid opcode exception (#UD). This instruction is reserved for generating intentional undefined instruction exceptions in all processor modes, useful for debugging and kernel routines. No flags are modified; execution terminates with a #UD fault.


Summary: Performs stage 1 address translation for current EL.

Performs stage 1 address translation for a virtual address in the current execution level, treating the access as a read. The translation result (physical address and attributes) is written to the PAR_EL1 register. No condition flags are affected. This is an AArch64-only instruction that requires appropriate privilege level to access the address translation system registers.

address ← Xt
translation_result ← TranslateAddress(address, S1E1R, current_EL)
PAR_EL1 ← translation_result


Summary: Performs stage 1 address translation for write permission.

Performs stage 1 address translation for a virtual address in the current execution level, treating the access as a write. The translation result (physical address and attributes) is written to the PAR_EL1 register. No condition flags are affected. This is an AArch64-only instruction that requires appropriate privilege level to access the address translation system registers.

address ← Xt
translation_result ← TranslateAddress(address, S1E1W, current_EL)
PAR_EL1 ← translation_result


Summary: Invalidates all TLB entries in the inner shareable domain.

Invalidates all TLB entries in the inner shareable domain, affecting all PEs in the shareable domain. This is an AArch64-only instruction requiring EL1 or higher privilege. No condition flags are affected; the instruction generates an exception if executed at EL0.


Summary: Invalidates TLB entries by Virtual Address.

Invalidates TLB entries matching the virtual address supplied in the register operand, at the current exception level. This is an AArch64-only instruction requiring EL1 or higher privilege. No condition flags are affected; the instruction generates an exception if executed at EL0.

TLBInvalidateByVA(Xt, EL1); DSB(SY); ISB()


Summary: Writes a general-purpose register to a coprocessor register (e.g., CP15).

MCR<c> <coproc>, <opc1>, <Rt>, <CRn>, <CRm>{, <opc2>}

cond | 1110 | opc1 | 0 | CRn | Rt | 111 | coproc<0> | opc2 | 1 | CRm

Rt

Transfer general-purpose register (load/store)

Moves data from a general-purpose register into a coprocessor register (typically CP15 for system control). The instruction is conditional and executes only if the condition code is satisfied. No ARM condition flags (N, Z, C, V) are modified by this instruction. This is an A32-only instruction with implementation-specific side effects depending on the target coprocessor register.

if ConditionPassed(cond) then
  CP[coproc, opc1, CRn, CRm, opc2] ← Rt


Summary: Reads a coprocessor register into a general-purpose register.

MRC<c> <coproc>, <opc1>, <Rt>, <CRn>, <CRm>{, <opc2>}

cond | 1110 | opc1 | 1 | CRn | Rt | 111 | coproc<0> | opc2 | 1 | CRm

Moves data from a coprocessor register (typically CP15 for system control) into a general-purpose register. The instruction is conditional and executes only if the condition code is satisfied. The N, Z, C, V flags may be modified depending on the coprocessor register being read. This is an A32-only instruction with implementation-specific behavior depending on the source coprocessor register.

if ConditionPassed(cond) then
  Rt ← CP[coproc, opc1, CRn, CRm, opc2]
  condition_flags may be updated by coprocessor


Move to Coprocessor from Two Registers (A32)

Summary: Writes two general-purpose registers to a coprocessor (64-bit transfer).

MCRR<c> <coproc>, <opc1>, <Rt>, <Rt2>, <CRm>

Second transfer register (load/store pair)

Moves data from two consecutive general-purpose registers into a coprocessor (64-bit data transfer). The instruction is conditional and executes only if the condition code is satisfied. No ARM condition flags are modified. This is an A32-only instruction; the two source registers are treated as a 64-bit value with Rt containing the lower 32 bits.

if ConditionPassed(cond) then
  CP64[coproc, opc1, CRm] ← (Rt2:Rt)
  // Rt holds bits [31:0], Rt2 holds bits [63:32]


Move to Two Registers from Coprocessor (A32)

Summary: Reads a coprocessor register into two general-purpose registers.

MRRC<c> <coproc>, <opc1>, <Rt>, <Rt2>, <CRm>

Moves data from a coprocessor into two consecutive general-purpose registers (64-bit data transfer). The instruction is conditional and executes only if the condition code is satisfied. No ARM condition flags are modified by this instruction itself, though the coprocessor may affect them. This is an A32-only instruction; the 64-bit result is split with Rt receiving the lower 32 bits and Rt2 the upper 32 bits.

if ConditionPassed(cond) then
  data64 ← CP64[coproc, opc1, CRm]
  Rt ← data64[31:0]
  Rt2 ← data64[63:32]


Summary: Loads memory into a coprocessor.

Rn

First source / base general-purpose register

Loads data from memory into a coprocessor register, with pre/post-indexed addressing. This is an A32-only instruction that executes conditionally based on the condition field. The base register Rn is updated if the write-back bit W is set; no condition flags are affected by this instruction.

if ConditionPassed(cond) then
  address ← if P then (Rn + (imm8 << 2)) else Rn
  if U then address ← Rn + (imm8 << 2) else address ← Rn - (imm8 << 2)
  Coproc_load(address, CRd)
  if W then Rn ← address


Summary: Stores coprocessor contents to memory.

Stores coprocessor register contents to memory, with pre/post-indexed addressing. This is an A32-only instruction that executes conditionally based on the condition field. The base register Rn is updated if the write-back bit W is set; no condition flags are affected by this instruction.

if ConditionPassed(cond) then
  address ← if P then (Rn + (imm8 << 2)) else Rn
  if U then address ← Rn + (imm8 << 2) else address ← Rn - (imm8 << 2)
  [address] ← Coproc_store(CRd)
  if W then Rn ← address


Summary: Reads a VFP system register (like FPSCR).

Reads a VFP system register (typically FPSCR) and transfers its value to a general-purpose register or the APSR condition flags. This is an A32/T32 instruction that executes conditionally. If Rt is R15, the N, Z, C, V flags are updated from FPSCR bits; otherwise no flags are modified.

if ConditionPassed(cond) then
  if Rt == 15 then
    APSR_nzcv ← FPSCR[31:28]
  else
    Rt ← FPSCR


Summary: Writes to a VFP system register.

Writes a general-purpose register value to a VFP system register (typically FPSCR). This is an A32/T32 instruction that executes conditionally. If Rt is R15, the APSR condition flags are written to FPSCR; the instruction may modify exception flags and rounding modes in FPSCR.

if ConditionPassed(cond) then
  if Rt == 15 then
    FPSCR[31:28] ← APSR_nzcv
  else
    FPSCR ← Rt


Summary: Loads a byte and marks address as exclusive.

Loads a byte from memory into a register and marks the address as exclusive for synchronization. The byte is zero-extended to 32 bits in the destination register. No condition flags are modified. This is an A32-only instruction that atomically acquires an exclusive lock on the target byte address; the lock is released by a matching STREXB or other exclusive store.

if ConditionPassed(cond) then
  address ← Rn
  Rt ← ZeroExtend([address], 8)
  SetExclusiveMonitor(address, 1)


Summary: Stores a byte if address is still exclusive.

Conditionally stores a byte to memory if the address is still marked as exclusive, returning a status in Rd (0=success, 1=failure). No condition flags are modified by the store result; success/failure is reported only in Rd. This is an A32-only instruction that atomically releases the exclusive lock and performs the write only if the lock is still held from a prior LDREXB.

if ConditionPassed(cond) then
  address ← Rn
  byte_value ← Rt[7:0]
  if ExclusiveMonitorSet(address, 1) then
    [address] ← byte_value
    Rd ← 0
    ClearExclusiveMonitor(address, 1)
  else
    Rd ← 1


Summary: Loads a halfword and marks address as exclusive.

Loads a 16-bit value from memory at the address in Rn and marks that address as exclusive for the current processor. The loaded halfword is zero-extended and placed in Rt. No condition flags are affected. This A32 instruction requires a matching STREXH to conditionally store; if the exclusive monitor is cleared, a subsequent STREXH will fail.

address ← Rn; Rt ← ZeroExtend(MemU[address, 2]); ExclusiveMonitorsMarkExclusive(address, ProcessorID(), 2);


Summary: Stores a halfword if address is still exclusive.

Conditionally stores a 16-bit value from Rt to memory at the address in Rn if that address is still marked exclusive by the current processor. Writes 0 to Rd if the store succeeds, or 1 if it fails due to loss of exclusivity. No condition flags are affected by the instruction result itself; the exclusive monitor behavior determines success/failure.

address ← Rn; if ExclusiveMonitorsCheckExclusive(address, ProcessorID(), 2) then MemU[address, 2] ← Rt[15:0]; Rd ← 0; ExclusiveMonitorsClearExclusive(ProcessorID()); else Rd ← 1;


Summary: Loads a doubleword and marks address as exclusive.

Loads a 64-bit doubleword from memory at the address in Rn and marks that address as exclusive for the current processor. The loaded value is split across Rt (lower 32 bits) and Rt2 (upper 32 bits). No condition flags are affected. This A32 instruction requires matching STREXD for conditional storage; Rt and Rt2 must be consecutive registers.

address ← Rn; value ← MemU[address, 8]; Rt ← value[31:0]; Rt2 ← value[63:32]; ExclusiveMonitorsMarkExclusive(address, ProcessorID(), 8);


Summary: Stores a doubleword if address is still exclusive.

Conditionally stores a 64-bit doubleword from Rt and Rt2 to memory at the address in Rn if that address is still marked exclusive by the current processor. Writes 0 to Rd on success or 1 on failure. No condition flags are affected; exclusive monitor state determines the outcome.

address ← Rn; if ExclusiveMonitorsCheckExclusive(address, ProcessorID(), 8) then MemU[address, 8] ← Rt || Rt2; Rd ← 0; ExclusiveMonitorsClearExclusive(ProcessorID()); else Rd ← 1;


Summary: Switches execution to EL1 (Debug).

Changes PE execution state to EL1 for debugging purposes. This is an A32-only instruction that immediately changes exception level and may update execution state; it does not return (implicit branch to debug handler). Condition flags are not affected by the instruction itself but are context-switched at the target exception level.

DebugChangeEL(EL1); // Changes exception level and branches to debug handler


Summary: Switches execution to EL2 (Debug).

Changes PE execution state to EL2 for debugging purposes. This is an A32-only instruction that immediately changes exception level and may update execution state; it does not return (implicit branch to debug handler). Condition flags are not affected by the instruction itself but are context-switched at the target exception level.

DebugChangeEL(EL2); // Changes exception level and branches to debug handler


Summary: Switches execution to EL3 (Debug).

Debug Change PE State to EL3 switches the processor to Exception Level 3 (EL3) in debug state without saving the current processor state. This instruction is used by debuggers to enter the highest privilege level. It is available only in A32 instruction set and requires debug authentication. No condition flags are modified.

CurrentEL ← EL3; PSTATE.EL ← '11'; PSTATE.SS ← '0';


Summary: Enables/Disables PAN (Prevents kernel accessing user memory).

Set Privileged Access Never enables or disables the PAN (Privileged Access Never) control bit, which prevents privileged software from accessing user-mode memory. When PAN is enabled (imm=1), privileged accesses to user memory are trapped; when disabled (imm=0), such accesses are permitted. This instruction is available in A32 and requires appropriate privilege level. No condition flags are modified.


Summary: Synchronizes system errors (v8.2).

Error Synchronization Barrier (v8.2) for RAS (Reliability, Availability, and Serviceability) synchronizes system error handling, ensuring that error detection and processing operations complete in order. This instruction is essential in fault-tolerance and error recovery scenarios and does not modify general-purpose registers or condition flags. Available in A32 instruction set.

// Synchronize error handling
ErrorSynchronizationBarrier()
// All pending error detection and processing operations complete


Consumption of Speculative Data Barrier (A32)

Summary: Prevents speculative data consumption (v8.0).

Consumption of Speculative Data Barrier (v8.0) prevents the CPU from using speculatively-loaded data in subsequent operations, protecting against attacks that exploit speculative data consumption side channels. Instructions following CSDB cannot use data speculatively loaded before this barrier. Available in A32 instruction set; does not modify condition flags.

// Prevent consumption of speculatively-loaded data
ConsumptionBarrier()
// Subsequent instructions cannot use data obtained through speculative execution prior to this barrier


Summary: Loads multiple VFP registers from memory.

Vector Load Multiple loads multiple consecutive double-precision or single-precision floating-point registers from memory using the address in a general-purpose base register. The base register can be optionally auto-incremented by the total bytes loaded. Condition flags (N, Z, C, V) are unaffected unless an exception occurs.

address ← Rn; for i = 0 to (list_count - 1) do; Driestlist[i] ← [address]; address ← address + (register_size / 8); end; if !(!) then Rn ← address;


Summary: Stores multiple VFP registers to memory.

Vector Store Multiple stores multiple consecutive double-precision or single-precision floating-point registers to memory using the address in a general-purpose base register. The base register can be optionally auto-incremented by the total bytes stored. Condition flags (N, Z, C, V) are unaffected unless an exception occurs.

address ← Rn; for i = 0 to (list_count - 1) do; [address] ← Vriestlist[i]; address ← address + (register_size / 8); end; if !(!) then Rn ← address;


Summary: Compares a floating-point value with #0.0.

Sd

Destination 32-bit floating-point register

Vector Compare Zero compares a single-precision floating-point value against zero and updates the VFP condition flags (FPSCR bits 28-31) based on the result. The comparison sets flags for signed magnitude comparison: N, Z, C, V flags in FPSCR are updated; FPSCR.E bit may be set if an exception occurs. Available in A32 VFP extension.

result ← Sd - 0.0; UpdateFPSCRConditionFlags(result); if exception then SetFPSCRException();


Summary: Divides two double-precision registers.

Divides the 64-bit double-precision value in Dn by the value in Dm and places the floating-point result in Dd. The operation follows IEEE 754 semantics for rounding and exception handling. FPSCR condition flags (N, Z, C, V) may be set based on the result and any exceptions; this instruction is available only in A32 and T32 with VFP support.

Dd ← FPDiv(Dn, Dm); FPSCR.N ← Dd[63]; FPSCR.Z ← (Dd == 0.0); FPSCR.C ← FPExceptionRaised(); FPSCR.V ← FPInvalidOp();


Summary: Absolute value of double-precision register.

Vector Absolute Value computes the absolute value of a 64-bit double-precision floating-point register and stores the result in the destination register. The sign bit is cleared while the exponent and significand are preserved. Condition flags are unaffected unless an exception occurs. Available in A32 VFP extension.

Dd.sign ← 0; Dd.exponent ← Dm.exponent; Dd.fraction ← Dm.fraction;


Summary: Negates double-precision register.

Negates a double-precision floating-point value in the source register and stores the result in the destination register. This is a unary VFP operation that inverts the sign bit of the IEEE 754 double-precision number. No condition flags are affected. Requires VFP extension and executes only in A32 instruction set.


Summary: Square root of double-precision register.

Computes the square root of a double-precision floating-point value and stores the result in the destination register. This is a unary VFP operation that performs IEEE 754 compliant square-root computation; if the source is negative (excluding -0), the result is NaN. FPSCR exception flags may be set based on input and result. Requires VFP extension and executes only in A32 instruction set.

Dd ← sqrt(Dm)
FPSCR.IOC ← 1 if Dm < 0.0 and Dm ≠ -0.0 (invalid operation)
FPSCR.UFC ← 1 if result is subnormal (underflow)
FPSCR.OFC ← 1 if result overflows
FPSCR.IXC ← 1 if result is inexact


Vector Fused Multiply Accumulate (Double)

Summary: Fused multiply-add (Double).

Performs a fused multiply-accumulate operation on two double-precision values with a third double-precision accumulator value: Qd ← Qd + (Qn × Qm). The operation is a single fused operation with one rounding step, providing higher precision than separate multiply and add instructions. FPSCR exception flags may be set. Requires VFPv4 extension and executes only in A32 instruction set.

Qd ← Qd + (Qn × Qm)
FPSCR.IOC ← 1 if invalid operand
FPSCR.UFC ← 1 if result underflows
FPSCR.OFC ← 1 if result overflows
FPSCR.IXC ← 1 if result is inexact


Summary: Fused multiply-subtract (Double).

Performs a fused multiply-subtract on 128-bit NEON registers: computes Qd = Qd - (Qn × Qm) for double-precision (F64) elements with a single rounding step. This VFPv4 instruction is more accurate than separate multiply and subtract operations. Floating-point exception flags in FPSCR may be set; condition codes N, Z, C, V are not directly modified.


Summary: Compares two double-precision values.

Compares two double-precision floating-point values and sets the FPSCR condition flags based on the comparison result (equal, less than, greater than, or unordered). The instruction does not produce a destination register value; it only updates FPSCR flags (N, Z, C, V). Requires VFP extension and executes only in A32 instruction set.

result ← Dd - Dm
FPSCR.N ← sign bit of result
FPSCR.Z ← 1 if values equal
FPSCR.C ← 1 if Dd ≥ Dm
FPSCR.V ← 1 if either operand is NaN (unordered)


Summary: Moves data between Double registers.

Copies a 64-bit double-precision floating-point value from Dm to Dd with no arithmetic or rounding. This is a register-to-register move within the VFP register file. No condition flags are affected, and this instruction executes unconditionally (though it respects the condition code in A32/T32).


Summary: Moves a Double register to/from two Core registers.

Transfers a 64-bit value between a VFP double-precision register (Dm) and two consecutive ARM core registers (Rt for bits [31:0], Rt2 for bits [63:32]). Direction is determined by the opcode bit pattern: from core to VFP or VFP to core. No condition flags are affected.

if direction == 'core_to_vfp' then Dm ← Rt2 || Rt; else Rt ← Dm[31:0]; Rt2 ← Dm[63:32];


Vector Convert to Integer (Nearest, Double)

Summary: Converts double to integer, rounding to nearest.

Converts a 64-bit double-precision floating-point value to a 32-bit integer, rounding to nearest (away from zero on tie). Executes conditionally in A32 and writes the integer result to a 32-bit floating-point register. No condition flags are affected by this instruction.

if ConditionPassed() then
  Sd = ConvertToInt(Dm, RoundingMode=RoundToNearest)


Vector Convert to Integer (Nearest Even, Double)

Summary: Converts double to integer, rounding to nearest even.

Converts a 64-bit double-precision floating-point value to a 32-bit integer, rounding to nearest even (banker's rounding). Executes conditionally in A32 and writes the integer result to a 32-bit floating-point register. No condition flags are affected by this instruction.

if ConditionPassed() then
  Sd = ConvertToInt(Dm, RoundingMode=RoundToNearestEven)


Summary: Converts between floating-point and fixed-point.

Converts between floating-point and fixed-point formats in 128-bit SIMD registers with a specified number of fractional bits. This is a NEON instruction that operates element-wise on the vector operands. No condition flags are affected.

if ConditionPassed() then
  for i = 0 to elements-1
    if Tm == F32 then
      Qd[i] = FixedPointConvert(Qm[i], fbits)
    else
      Qd[i] = FloatingPointConvert(Qm[i], fbits)


Summary: Adds an immediate to an address, modifying the Allocation Tag (MTE).

ADDG <Xd|SP>, <Xn|SP>, #<uimm6>, #<uimm4>

Xn

First source / base 64-bit integer register

Adds a scaled immediate offset (uimm6 × 16) to an address in the source register and simultaneously updates the Memory Tagging Extension (MTE) Allocation Tag in bits [59:56] by adding uimm4. The result is stored in the destination register. This is an AArch64-only instruction that modifies both address and tag atomically. No condition flags are affected.

address_offset ← uimm6 × 16
tag_offset ← uimm4
if Xn == SP then
  Xd ← (Xn + address_offset)[63:0]
  Xd[59:56] ← (Xn[59:56] + tag_offset) AND 0xF
else
  Xd ← (Xn + address_offset)[63:0]
  Xd[59:56] ← (Xn[59:56] + tag_offset) AND 0xF


Summary: Subtracts an immediate from an address, modifying the Allocation Tag (MTE).

SUBG <Xd|SP>, <Xn|SP>, #<uimm6>, #<uimm4>

Subtracts a scaled immediate offset (uimm6 × 16) from an address in the source register and simultaneously updates the Memory Tagging Extension (MTE) Allocation Tag in bits [59:56] by adding uimm4. The result is stored in the destination register. This is an AArch64-only instruction that modifies both address and tag atomically. No condition flags are affected.

address_offset ← uimm6 × 16
tag_offset ← uimm4
if Xn == SP then
  Xd ← (Xn - address_offset)[63:0]
  Xd[59:56] ← (Xn[59:56] + tag_offset) AND 0xF
else
  Xd ← (Xn - address_offset)[63:0]
  Xd[59:56] ← (Xn[59:56] + tag_offset) AND 0xF


Summary: Prevents speculation from determining that the instruction is executed.

Call Out Speculation: prevents speculation from reaching instructions beyond this point until the operand register is committed. This instruction is part of the CSV3 speculation control feature and executes in AArch64 state only. It does not affect any condition flags and requires the source register value to be resolved before execution can proceed speculatively.

if FEAT_CSV3 == '0' then
  UNDEFINED
else
  CommitSpeculation(X[t])


Summary: Prevents cache prefetch prediction past this instruction.

Prevents cache prefetch prediction from reordering beyond this instruction, allowing precise control over cache prefetch behavior. This is an AArch64-only instruction requiring FEAT_CPP (Cache Prefetch Prediction). The source register Xt is ignored; the instruction acts as a prefetch prediction barrier. No condition flags are affected.


Summary: Atomically swaps a 128-bit register pair with a checked descriptor in memory (Translation Hardening).

Atomically reads a 128-bit translation table descriptor from memory, checks its validity, and conditionally writes it back with hardening constraints (FEAT_THE). The instruction requires 128-bit alignment and is available only in AArch64. Acquire-Release semantics are not applied; results are returned in a pair of 64-bit registers with status flags.

address ← Xn; data ← Mem[address, 16]; ValidateAndProcess(data); if validated then Mem[address, 16] ← data; Xt ← data[63:0]; Xt+1 ← data[127:64];


Summary: Loads bytes speculatively; suppresses faults after the first active element.

Zt

Transfer scalable vector register (SVE load/store)

Loads bytes from memory into a scalable vector register with first-fault semantics; subsequent faults are suppressed if any active element has already been loaded. Only elements where the predicate is true are loaded. This instruction is AArch64-only and requires SVE. No condition flags are set.

for i ← 0 to (VL/8 - 1) do if Pg[i] then Zt[i*8+7:i*8] ← [Xn + i]; faulted ← false; end if; if fault_occurs and faulted then suppress_fault; faulted ← true; end if; end for


SVE Load First-Fault Contiguous Halfwords

Summary: Loads halfwords speculatively; suppresses faults after the first active element.

Loads halfwords from memory into a scalable vector register with first-fault semantics; subsequent faults are suppressed if any active element has already been loaded. Only elements where the predicate is true are loaded. This instruction is AArch64-only and requires SVE. No condition flags are set.

for i ← 0 to (VL/16 - 1) do if Pg[i] then Zt[i*16+15:i*16] ← [Xn + i*2]; faulted ← false; end if; if fault_occurs and faulted then suppress_fault; faulted ← true; end if; end for


Summary: Loads words speculatively; suppresses faults after the first active element.

Loads words from memory into a scalable vector register with first-fault semantics; subsequent faults are suppressed if any active element has already been loaded. Only elements where the predicate is true are loaded. This instruction is AArch64-only and requires SVE. No condition flags are set.

for i ← 0 to (VL/32 - 1) do if Pg[i] then Zt[i*32+31:i*32] ← [Xn + i*4]; faulted ← false; end if; if fault_occurs and faulted then suppress_fault; faulted ← true; end if; end for


SVE Load First-Fault Contiguous Doublewords

Summary: Loads doublewords speculatively; suppresses faults after the first active element.

Loads doublewords from memory into a scalable vector register with first-fault semantics; subsequent faults are suppressed if any active element has already been loaded. Only elements where the predicate is true are loaded. This instruction is AArch64-only and requires SVE. No condition flags are set.

for i ← 0 to (VL/64 - 1) do if Pg[i] then Zt[i*64+63:i*64] ← [Xn + i*8]; faulted ← false; end if; if fault_occurs and faulted then suppress_fault; faulted ← true; end if; end for


Summary: Loads bytes without faulting; returns 0 if fault occurs.

Loads bytes from memory into a scalable vector register without raising faults; elements that would fault are loaded as zero. Only elements where the predicate is true are accessed. This instruction is AArch64-only and requires SVE. No condition flags are set.

for i ← 0 to (VL/8 - 1) do if Pg[i] then if fault_would_occur then Zt[i*8+7:i*8] ← 0; else Zt[i*8+7:i*8] ← [Xn + i]; end if; end if; end for